1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "frameworks/bridge/declarative_frontend/jsview/js_sceneview.h"
17
18 #include "base/geometry/quaternion.h"
19 #include "base/geometry/vec3.h"
20 #include "bridge/declarative_frontend/jsview/models/model_view_impl.h"
21 #include "core/components_ng/base/view_stack_model.h"
22 #include "core/components_ng/pattern/model/model_view_ng.h"
23 #include "core/components/scene_viewer/scene_viewer_component.h"
24 #include "frameworks/bridge/declarative_frontend/engine/functions/js_click_function.h"
25 #include "frameworks/bridge/declarative_frontend/view_stack_processor.h"
26 #include "foundation/graphic/graphic_3d/3d_widget_adapter/include/custom/custom_render_descriptor.h"
27 #include "foundation/graphic/graphic_3d/3d_widget_adapter/include/data_type/geometry/cone.h"
28 #include "foundation/graphic/graphic_3d/3d_widget_adapter/include/data_type/geometry/cube.h"
29 #include "foundation/graphic/graphic_3d/3d_widget_adapter/include/data_type/geometry/sphere.h"
30 #include "foundation/graphic/graphic_3d/3d_widget_adapter/include/data_type/shader_input_buffer.h"
31
32 namespace OHOS::Ace {
33
34 std::unique_ptr<ModelView> ModelView::instance_ = nullptr;
35 std::mutex ModelView::mutex_;
36
GetInstance()37 ModelView* ModelView::GetInstance()
38 {
39 if (!instance_) {
40 std::lock_guard<std::mutex> lock(mutex_);
41 if (!instance_) {
42 #ifdef NG_BUILD
43 instance_.reset(new NG::ModelViewNG());
44 #else
45 if (Container::IsCurrentUseNewPipeline()) {
46 LOGD("ModelView::GetInstance() NG Pipeline");
47 instance_.reset(new NG::ModelViewNG());
48 } else {
49 LOGD("ModelView::GetInstance() NOT NG Pipeline");
50 instance_.reset(new Framework::ModelViewImpl());
51 }
52 #endif
53 }
54 }
55 return instance_.get();
56 }
57
58 } // namespace OHOS::Ace
59
60 namespace OHOS::Ace::Framework {
61
JsOnClick(const JSCallbackInfo & info)62 void JSSceneView::JsOnClick(const JSCallbackInfo& info)
63 {
64 LOGD("JSSceneView JsOnClick");
65 if (info[0]->IsFunction()) {
66 RefPtr<JsClickFunction> jsOnClickFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(info[0]));
67 auto onClickId = EventMarker(
68 [execCtx = info.GetExecutionContext(), func = std::move(jsOnClickFunc)]() {
69 JAVASCRIPT_EXECUTION_SCOPE(execCtx);
70 LOGD("About to call onclick method on js");
71 func->Execute();
72 });
73 auto top = ViewStackProcessor::GetInstance()->GetMainComponent();
74 auto component = AceType::DynamicCast<OHOS::Ace::SceneViewerComponent>(top);
75
76 if (!component) {
77 LOGE("Cannot assign click handler. Component is not SceneViewComponent");
78 return;
79 }
80 component->SetClickedEventId(onClickId);
81 }
82 }
83
JsSetHandleCameraMove(const JSCallbackInfo & info)84 void JSSceneView::JsSetHandleCameraMove(const JSCallbackInfo& info)
85 {
86 if (info.Length() < 1) {
87 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
88 return;
89 }
90
91 if (!info[0]->IsBoolean()) {
92 LOGE("arg is not Boolean.");
93 return;
94 }
95
96 bool value = info[0]->ToBoolean();
97 ModelView::GetInstance()->SetHandleCameraMove(value);
98 }
99
Create(const JSCallbackInfo & info)100 void JSSceneView::Create(const JSCallbackInfo& info)
101 {
102 LOGD("JSSceneView::Create()");
103 if (info.Length() < 1) {
104 LOGE("JSSceneView: info is invalid.");
105 return;
106 }
107
108 std::string srcPath;
109 auto parseOk = ParseJsMedia(info[0], srcPath);
110 if (!parseOk) {
111 LOGW("JSSceneView::Create() arg parsing failed.");
112 return;
113 }
114
115 LOGD("srcPath after ParseJsMedia(): %s", srcPath.c_str());
116 ModelView::GetInstance()->Create(srcPath);
117 }
118
JsCamera(const JSCallbackInfo & info)119 void JSSceneView::JsCamera(const JSCallbackInfo& info)
120 {
121 // Parse the info object.
122 if (info.Length() <= 0 || !info[0]->IsObject()) {
123 LOGE("JSSceneView: arg is invalid.");
124 return;
125 }
126
127 LOGD("info[0]->ToString().c_str(): %s", info[0]->ToString().c_str());
128 auto argsPtrItem = JsonUtil::ParseJsonString(info[0]->ToString());
129 if (!argsPtrItem || argsPtrItem->IsNull()) {
130 LOGE("Js Parse object failed. argsPtr is null. %s", info[0]->ToString().c_str());
131 return;
132 }
133
134 // Using single/same animation option for both Position and Rotation currently.
135 AnimationOption animOption = ViewStackModel::GetInstance()->GetImplicitAnimationOption();
136 LOGD("JSCamera() animOption: %d", animOption.GetDuration());
137
138 // Default Camera zNear, zFar, fovDegrees.
139 auto zNear = 0.5f;
140 auto zFar = 50.0f;
141 auto fovD = 60.0f;
142 if (argsPtrItem->Contains("zNear")) {
143 zNear = argsPtrItem->GetDouble("zNear", zNear);
144 LOGD("zNear: %f", zNear);
145 }
146
147 if (argsPtrItem->Contains("zFar")) {
148 zFar = argsPtrItem->GetDouble("zFar", zFar);
149 LOGD("zFar: %f", zFar);
150 }
151
152 if (argsPtrItem->Contains("fovD")) {
153 fovD = argsPtrItem->GetDouble("fovD", fovD);
154 LOGD("fovD: %f", fovD);
155 }
156
157 ModelView::GetInstance()->SetCameraFrustum(zNear, zFar, fovD);
158
159 // positionInAngles
160 if (argsPtrItem->Contains("positionInAngles")) {
161 auto positionArgs = argsPtrItem->GetObject("positionInAngles");
162 auto x = positionArgs->GetDouble("x", 0.0);
163 auto y = positionArgs->GetDouble("y", 0.0);
164 auto z = positionArgs->GetDouble("z", 0.0);
165 auto distance = positionArgs->GetDouble("distance", 4.0);
166 LOGD("positionInAngles: x: %f, y: %f, z: %f, distance: %f,", x, y, z, distance);
167 bool isAngularPosition = true;
168 // Angles and distance are animatable.
169 ModelView::GetInstance()->SetCameraPosition(
170 AnimatableFloat(x, animOption), AnimatableFloat(y, animOption),
171 AnimatableFloat(z, animOption), AnimatableFloat(distance, animOption), isAngularPosition);
172 }
173
174 // position (Not positionInAngles)
175 if (!argsPtrItem->Contains("positionInAngles") && argsPtrItem->Contains("position")) {
176 auto positionArgs = argsPtrItem->GetObject("position");
177 auto x = positionArgs->GetDouble("x", 0.0);
178 auto y = positionArgs->GetDouble("y", 0.0);
179 auto z = positionArgs->GetDouble("z", 0.0);
180 LOGD("position: x: %f, y: %f, z: %f", x, y, z);
181 bool isAngularPosition = false;
182 // Angles and distance are animatable.
183 ModelView::GetInstance()->SetCameraPosition(
184 AnimatableFloat(x, animOption), AnimatableFloat(y, animOption),
185 AnimatableFloat(z, animOption), AnimatableFloat(0.0, animOption), isAngularPosition);
186 }
187
188 // rotation: { x : number, y : number, z : number, w : number}
189 if (argsPtrItem->Contains("rotation")) {
190 auto rotationArgs = argsPtrItem->GetObject("rotation");
191 auto x = rotationArgs->GetDouble("x", 0.0);
192 auto y = rotationArgs->GetDouble("y", 0.0);
193 auto z = rotationArgs->GetDouble("z", 0.0);
194 auto w = rotationArgs->GetDouble("w", 1.0);
195 LOGD("rotation: x: %f, y: %f, z: %f, w: %f", x, y, z, w);
196 Quaternion rotation(x, y, z, w);
197 ModelView::GetInstance()->SetCameraRotation(rotation);
198 }
199
200 // lookAt / target : {x : number, y : number, z : number }
201 if (argsPtrItem->Contains("lookAt")) {
202 auto lookatArgs = argsPtrItem->GetObject("lookAt");
203 auto x = lookatArgs->GetDouble("x", 0.0);
204 auto y = lookatArgs->GetDouble("y", 0.0);
205 auto z = lookatArgs->GetDouble("z", 0.0);
206 LOGD("lookAt: x: %f, y: %f, z: %f", x, y, z);
207 Vec3 lookVec(x, y, z);
208 ModelView::GetInstance()->SetCameraLookAt(lookVec);
209 }
210
211 // up: {x : number, y : number, z : number } (Default: 0,1,0)
212 if (argsPtrItem->Contains("up")) {
213 auto upArgs = argsPtrItem->GetObject("up");
214 auto x = upArgs->GetDouble("x", 0.0);
215 auto y = upArgs->GetDouble("y", 1.0);
216 auto z = upArgs->GetDouble("z", 0.0);
217 LOGD("upArgs: x: %f, y: %f, z: %f", x, y, z);
218 Vec3 upVec(x, y, z);
219 ModelView::GetInstance()->SetCameraUp(upVec);
220 }
221 }
222
JsSetTransparent(const JSCallbackInfo & info)223 void JSSceneView::JsSetTransparent(const JSCallbackInfo& info)
224 {
225 if (info.Length() < 1) {
226 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
227 return;
228 }
229
230 if (!info[0]->IsBoolean()) {
231 LOGE("arg is not Boolean.");
232 return;
233 }
234
235 bool value = info[0]->ToBoolean();
236 LOGD("JSSceneView::JsSetTransparentBackground(%s)", value ? "true" : "false");
237 ModelView::GetInstance()->SetTransparent(value);
238 }
239
JsSetBackground(const JSCallbackInfo & info)240 void JSSceneView::JsSetBackground(const JSCallbackInfo& info)
241 {
242 LOGD("JSSceneView::JsSetBackground()");
243 if (info.Length() < 1) {
244 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
245 return;
246 }
247
248 std::string srcPath;
249 auto parseOk = ParseJsMedia(info[0], srcPath);
250 if (!parseOk) {
251 LOGE("JSSceneView::JsSetBackground() arg parsing failed.");
252 return;
253 }
254
255 LOGD("srcPath after ParseJsMedia(): %s", srcPath.c_str());
256 ModelView::GetInstance()->SetBackground(srcPath);
257 }
258
JsLight(const JSCallbackInfo & info)259 void JSSceneView::JsLight(const JSCallbackInfo& info)
260 {
261 // Parse the info object.
262 if (info.Length() <= 0 || !info[0]->IsObject()) {
263 LOGE("JSSceneView: arg is invalid.");
264 return;
265 }
266
267 LOGD("JSLight() info[0]: %s", info[0]->ToString().c_str());
268 auto argsPtrItem = JsonUtil::ParseJsonString(info[0]->ToString());
269 if (!argsPtrItem || argsPtrItem->IsNull()) {
270 LOGE("Js Parse object failed. argsPtr is null. %s", info[0]->ToString().c_str());
271 return;
272 }
273
274 AnimationOption animOption = ViewStackModel::GetInstance()->GetImplicitAnimationOption();
275 LOGD("JSLight() animOption: %d", animOption.GetDuration());
276
277 auto type = argsPtrItem->GetInt("type", 1);
278 auto intensity = argsPtrItem->GetDouble("intensity", 10.0);
279 auto shadow = argsPtrItem->GetBool("shadow", false);
280 LOGD("type: %d, intensity: %f, shadow: %d", type, intensity, shadow);
281
282 Vec3 color = Vec3(1.0, 1.0, 1.0, animOption);
283 if (argsPtrItem->Contains("color")) {
284 LOGD("JSLight color");
285 auto colorArgs = argsPtrItem->GetObject("color");
286 if (!colorArgs || colorArgs->IsNull()) {
287 LOGE("Js Parse object failed. light color is null. %s", colorArgs->ToString().c_str());
288 } else {
289 auto r = colorArgs->GetDouble("x", 1.0);
290 auto g = colorArgs->GetDouble("y", 1.0);
291 auto b = colorArgs->GetDouble("z", 1.0);
292 color = Vec3(r, g, b, animOption);
293 LOGD("color r: %f, g: %f, b: %f", color.GetX(), color.GetY(), color.GetZ());
294 }
295 }
296
297 OHOS::Render3D::Position position;
298 // positionInAngles
299 if (argsPtrItem->Contains("positionInAngles")) {
300 auto positionArgs = argsPtrItem->GetObject("positionInAngles");
301 auto x = positionArgs->GetDouble("x", 0.0);
302 auto y = positionArgs->GetDouble("y", 0.0);
303 auto z = positionArgs->GetDouble("z", 0.0);
304 auto distance = positionArgs->GetDouble("distance", 4.0);
305 bool isAngularPosition = true;
306 LOGD("positionInAngles: x: %f, y: %f, z: %f, distance: %f,", x, y, z, distance);
307 position.Set(AnimatableFloat(x, animOption), AnimatableFloat(y, animOption),
308 AnimatableFloat(z, animOption), AnimatableFloat(distance, animOption), isAngularPosition);
309 }
310
311 // position (Not positionInAngles)
312 if (!argsPtrItem->Contains("positionInAngles") && argsPtrItem->Contains("position")) {
313 auto positionArgs = argsPtrItem->GetObject("position");
314 auto x = positionArgs->GetDouble("x", 0.0);
315 auto y = positionArgs->GetDouble("y", 0.0);
316 auto z = positionArgs->GetDouble("z", 0.0);
317 LOGD("position: x: %f, y: %f, z: %f", x, y, z);
318 bool isAngularPosition = false;
319 position.Set(AnimatableFloat(x, animOption), AnimatableFloat(y, animOption),
320 AnimatableFloat(z, animOption), AnimatableFloat(0.0, animOption), isAngularPosition);
321 }
322
323 double maxInvalid = std::numeric_limits<double>::max();
324 Quaternion rotation = Quaternion(maxInvalid, maxInvalid, maxInvalid, maxInvalid);
325 // rotation: { x : number, y : number, z : number, w : number}
326 if (argsPtrItem->Contains("rotation")) {
327 auto rotationArgs = argsPtrItem->GetObject("rotation");
328 auto x = rotationArgs->GetDouble("x", 0.0);
329 auto y = rotationArgs->GetDouble("y", 0.0);
330 auto z = rotationArgs->GetDouble("z", 0.0);
331 auto w = rotationArgs->GetDouble("w", 1.0);
332 LOGD("rotation: x: %f, y: %f, z: %f, w: %f", x, y, z, w);
333 rotation = Quaternion(x, y, z, w);
334 }
335
336 ModelView::GetInstance()->AddLight(AceType::MakeRefPtr<OHOS::Render3D::SVLight>(
337 type, color, AnimatableFloat(intensity, animOption), shadow, position, rotation));
338 }
339
JsAddCube(const JSCallbackInfo & info)340 void JSSceneView::JsAddCube(const JSCallbackInfo& info)
341 {
342 // Parse the info object.
343 if (info.Length() <= 0 || !info[0]->IsObject()) {
344 LOGE("JSSceneView: arg is invalid.");
345 return;
346 }
347
348 LOGD("JSAddCube() info[0]: %s", info[0]->ToString().c_str());
349 auto argsPtrItem = JsonUtil::ParseJsonString(info[0]->ToString());
350 if (!argsPtrItem || argsPtrItem->IsNull()) {
351 LOGE("Js Parse object failed. argsPtr is null. %s", info[0]->ToString().c_str());
352 return;
353 }
354
355 auto name = argsPtrItem->GetString("name");
356 auto width = argsPtrItem->GetDouble("width", 0.0);
357 auto height = argsPtrItem->GetDouble("height", 0.0);
358 auto depth = argsPtrItem->GetDouble("depth", 0.0);
359
360 OHOS::Render3D::Vec3 position(0.0f, 0.0f, 0.0f);
361 if (argsPtrItem->Contains("position")) {
362 LOGD("Cube position");
363 auto positionArgs = argsPtrItem->GetObject("position");
364 position.SetX(positionArgs->GetDouble("x", 0.0));
365 position.SetY(positionArgs->GetDouble("y", 0.0));
366 position.SetZ(positionArgs->GetDouble("z", 0.0));
367 }
368
369 LOGD("JSAddCube(%s, %.2f, %.2f, %.2f)", name.c_str(), width, height, depth);
370 ModelView::GetInstance()->AddGeometry(
371 AceType::MakeRefPtr<OHOS::Render3D::SVCube>(name.c_str(), width, height, depth, position));
372 }
373
JsAddSphere(const JSCallbackInfo & info)374 void JSSceneView::JsAddSphere(const JSCallbackInfo& info)
375 {
376 // Parse the info object.
377 if (info.Length() <= 0 || !info[0]->IsObject()) {
378 LOGE("JSSceneView: arg is invalid.");
379 return;
380 }
381
382 LOGD("JSAddSphere() info[0]: %s", info[0]->ToString().c_str());
383 auto argsPtrItem = JsonUtil::ParseJsonString(info[0]->ToString());
384 if (!argsPtrItem || argsPtrItem->IsNull()) {
385 LOGE("Js Parse object failed. argsPtr is null. %s", info[0]->ToString().c_str());
386 return;
387 }
388
389 auto name = argsPtrItem->GetString("name");
390 auto radius = argsPtrItem->GetDouble("radius", 0.0);
391 auto rings = argsPtrItem->GetInt("rings", 0);
392 auto sectors = argsPtrItem->GetInt("sectors", 0);
393
394 OHOS::Render3D::Vec3 position(0.0f, 0.0f, 0.0f);
395 if (argsPtrItem->Contains("position")) {
396 LOGD("Cube position");
397 auto positionArgs = argsPtrItem->GetObject("position");
398 position.SetX(positionArgs->GetDouble("x", 0.0));
399 position.SetY(positionArgs->GetDouble("y", 0.0));
400 position.SetZ(positionArgs->GetDouble("z", 0.0));
401 }
402
403 LOGD("JSAddSphere(%s, %.2f, %d, %d)", name.c_str(), radius, rings, sectors);
404 ModelView::GetInstance()->AddGeometry(
405 AceType::MakeRefPtr<OHOS::Render3D::SVSphere>(name.c_str(), radius, rings, sectors, position));
406 }
407
JsAddCone(const JSCallbackInfo & info)408 void JSSceneView::JsAddCone(const JSCallbackInfo& info)
409 {
410 // Parse the info object.
411 if (info.Length() <= 0 || !info[0]->IsObject()) {
412 LOGE("JSSceneView: arg is invalid.");
413 return;
414 }
415
416 LOGD("JSAddCone() info[0]: %s", info[0]->ToString().c_str());
417 auto argsPtrItem = JsonUtil::ParseJsonString(info[0]->ToString());
418 if (!argsPtrItem || argsPtrItem->IsNull()) {
419 LOGE("Js Parse object failed. argsPtr is null. %s", info[0]->ToString().c_str());
420 return;
421 }
422
423 auto name = argsPtrItem->GetString("name");
424 auto radius = argsPtrItem->GetDouble("radius", 0.0);
425 auto length = argsPtrItem->GetInt("length", 0);
426 auto sectors = argsPtrItem->GetInt("sectors", 0);
427
428 OHOS::Render3D::Vec3 position(0.0f, 0.0f, 0.0f);
429 if (argsPtrItem->Contains("position")) {
430 LOGD("Cube position");
431 auto positionArgs = argsPtrItem->GetObject("position");
432 position.SetX(positionArgs->GetDouble("x", 0.0));
433 position.SetY(positionArgs->GetDouble("y", 0.0));
434 position.SetZ(positionArgs->GetDouble("z", 0.0));
435 }
436
437 LOGD("JSAddCone(%s, %.2f, %d, %d)", name.c_str(), radius, length, sectors);
438 ModelView::GetInstance()->AddGeometry(
439 AceType::MakeRefPtr<OHOS::Render3D::SVCone>(name.c_str(), radius, length, sectors, position));
440 }
441
JsGLTFAnimation(const JSCallbackInfo & info)442 void JSSceneView::JsGLTFAnimation(const JSCallbackInfo& info)
443 {
444 // Parse the info object.
445 if (info.Length() < 1 || !info[0]->IsObject()) {
446 LOGE("JSSceneView JSGLTFAnimation: arg is invalid.");
447 return;
448 }
449
450 LOGD("JSGLTFAnimation() info[0]: %s", info[0]->ToString().c_str());
451 auto argsPtrItem = JsonUtil::ParseJsonString(info[0]->ToString());
452 if (!argsPtrItem || argsPtrItem->IsNull()) {
453 LOGE("Js Parse object failed. argsPtr is null. %s", info[0]->ToString().c_str());
454 return;
455 }
456
457 auto name = argsPtrItem->GetString("name", "");
458 auto state = argsPtrItem->GetInt("state", 0); // PLAY
459 auto repeatCount = argsPtrItem->GetInt("repeatCount", -1); // -1 is Infinite
460 auto speed = argsPtrItem->GetDouble("speed", 1.0);
461 auto duration = argsPtrItem->GetDouble("duration", -1.0); // Invalid.
462 auto reverse = argsPtrItem->GetBool("reverse", false);
463
464 ModelView::GetInstance()->AddGLTFAnimation(AceType::MakeRefPtr<OHOS::Render3D::GLTFAnimation>(
465 name, static_cast<OHOS::Render3D::AnimationState>(state), repeatCount, speed, duration, reverse));
466 }
467
JsAddCustomRender(const JSCallbackInfo & info)468 void JSSceneView::JsAddCustomRender(const JSCallbackInfo& info)
469 {
470 if (info.Length() != 2) {
471 LOGE("customRender() invocation error - two arguments required");
472 return;
473 }
474
475 if (info[1]->IsNull() || !info[1]->IsBoolean()) {
476 LOGE("customRender() invocation error - Needs frame callback flag. Must be a Boolean");
477 return;
478 }
479
480 std::string uri;
481 auto parseOk = ParseJsMedia(info[0], uri);
482 if (!parseOk) {
483 LOGE("JSSceneView::JsAddCustomRender() arg parsing failed.");
484 return;
485 }
486
487 RefPtr<OHOS::Render3D::SVCustomRenderDescriptor> desc =
488 AceType::MakeRefPtr<OHOS::Render3D::SVCustomRenderDescriptor>(uri, "", info[1]->ToBoolean());
489 LOGE("JsAddCustomRender(%s, %s)", desc->GetUri().c_str(), (desc->NeedsFrameCallback() ? "true" : "false"));
490 ModelView::GetInstance()->AddCustomRender(desc);
491 }
492
JsWidth(const JSCallbackInfo & info)493 void JSSceneView::JsWidth(const JSCallbackInfo& info)
494 {
495 if (info.Length() < 1) {
496 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
497 return;
498 }
499
500 CalcDimension value;
501 if (!ParseJsDimensionVp(info[0], value)) {
502 return;
503 }
504
505 if (LessNotEqual(value.Value(), 0.0)) {
506 value.SetValue(0.0);
507 }
508 ModelView::GetInstance()->SetWidth(value);
509 }
510
JsHeight(const JSCallbackInfo & info)511 void JSSceneView::JsHeight(const JSCallbackInfo& info)
512 {
513 if (info.Length() < 1) {
514 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
515 return;
516 }
517
518 CalcDimension value;
519 if (!ParseJsDimensionVp(info[0], value)) {
520 return;
521 }
522
523 if (LessNotEqual(value.Value(), 0.0)) {
524 value.SetValue(0.0);
525 }
526 ModelView::GetInstance()->SetHeight(value);
527 }
528
JsShader(const JSCallbackInfo & info)529 void JSSceneView::JsShader(const JSCallbackInfo& info)
530 {
531 if (info.Length() != 1) {
532 LOGE("The arg is wrong, it is supposed to have 1 argument");
533 return;
534 }
535
536 std::string shaderPath;
537 auto parseOk = ParseJsMedia(info[0], shaderPath);
538 if (!parseOk) {
539 LOGE("JSSceneView::JsShader() arg parsing failed.");
540 return;
541 }
542
543 LOGD("shaderPath after ParseJsMedia(): %s", shaderPath.c_str());
544 ModelView::GetInstance()->SetShader(shaderPath);
545 }
546
JsShaderImageTexture(const JSCallbackInfo & info)547 void JSSceneView::JsShaderImageTexture(const JSCallbackInfo& info)
548 {
549 if (info.Length() != 1) {
550 LOGE("The arg is wrong, it is supposed to have 1 argument");
551 return;
552 }
553
554 std::string texturePath;
555 auto parseOk = ParseJsMedia(info[0], texturePath);
556 if (!parseOk) {
557 LOGE("JSSceneView::JsShaderImageTexture() arg parsing failed.");
558 return;
559 }
560
561 LOGD("texturePath after ParseJsMedia(): %s", texturePath.c_str());
562 ModelView::GetInstance()->AddShaderImageTexture(texturePath);
563 }
564
JsShaderInputBuffer(const JSCallbackInfo & info)565 void JSSceneView::JsShaderInputBuffer(const JSCallbackInfo& info)
566 {
567 if (info.Length() != 1 || !info[0]->IsArray()) {
568 LOGE("JsShaderInputBuffer() Invalid args.");
569 return;
570 }
571
572 JSRef<JSArray> array = JSRef<JSArray>::Cast(info[0]);
573 int32_t length = static_cast<int32_t>(array->Length());
574 if (length <= 0) {
575 LOGE("JsShaderInputBuffer() Buffer is empty.");
576 return;
577 }
578
579 std::vector<float> shaderBuffer;
580 for (int32_t i = 0; i < length; i++) {
581 JSRef<JSVal> jsValue = array->GetValueAt(i);
582 if (jsValue->IsNumber()) {
583 shaderBuffer.emplace_back(jsValue->ToNumber<float>());
584 } else {
585 LOGE("JsShaderInputBuffer() Invalid data.");
586 return;
587 }
588 }
589
590 RefPtr<OHOS::Render3D::ShaderInputBuffer> buffer =
591 AceType::MakeRefPtr<OHOS::Render3D::ShaderInputBuffer>(shaderBuffer);
592 ModelView::GetInstance()->AddShaderInputBuffer(buffer);
593 }
594
JSBind(BindingTarget globalObj)595 void JSSceneView::JSBind(BindingTarget globalObj)
596 {
597 LOGD("JSSceneView::JSBind()");
598 JSClass<JSSceneView>::Declare("Model");
599 MethodOptions opt = MethodOptions::NONE;
600 JSClass<JSSceneView>::StaticMethod("create", &JSSceneView::Create, opt);
601 JSClass<JSSceneView>::StaticMethod("onClick", &JSSceneView::JsOnClick);
602 JSClass<JSSceneView>::StaticMethod("gestureAccess", &JSSceneView::JsSetHandleCameraMove);
603 JSClass<JSSceneView>::StaticMethod("camera", &JSSceneView::JsCamera);
604 JSClass<JSSceneView>::StaticMethod("transparent", &JSSceneView::JsSetTransparent);
605 JSClass<JSSceneView>::StaticMethod("background", &JSSceneView::JsSetBackground);
606 JSClass<JSSceneView>::StaticMethod("light", &JSSceneView::JsLight);
607 JSClass<JSSceneView>::StaticMethod("cube", &JSSceneView::JsAddCube);
608 JSClass<JSSceneView>::StaticMethod("sphere", &JSSceneView::JsAddSphere);
609 JSClass<JSSceneView>::StaticMethod("cone", &JSSceneView::JsAddCone);
610 JSClass<JSSceneView>::StaticMethod("glTFAnimation", &JSSceneView::JsGLTFAnimation);
611 JSClass<JSSceneView>::StaticMethod("customRender", &JSSceneView::JsAddCustomRender);
612 JSClass<JSSceneView>::StaticMethod("width", &JSSceneView::JsWidth);
613 JSClass<JSSceneView>::StaticMethod("height", &JSSceneView::JsHeight);
614 JSClass<JSSceneView>::StaticMethod("shader", &JSSceneView::JsShader);
615 JSClass<JSSceneView>::StaticMethod("shaderImageTexture", &JSSceneView::JsShaderImageTexture);
616 JSClass<JSSceneView>::StaticMethod("shaderInputBuffer", &JSSceneView::JsShaderInputBuffer);
617 JSClass<JSSceneView>::InheritAndBind<JSViewAbstract>(globalObj);
618 }
619
620 } // namespace OHOS::Ace::Framework
621