• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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