• 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 <regex>
19 
20 #include "custom/custom_render_descriptor.h"
21 #include "custom/shader_input_buffer.h"
22 #include "data_type/constants.h"
23 #include "data_type/geometry/cone.h"
24 #include "data_type/geometry/cube.h"
25 #include "data_type/geometry/sphere.h"
26 #include "data_type/light.h"
27 
28 #include "base/geometry/quaternion.h"
29 #include "base/geometry/vec3.h"
30 #include "core/components_ng/base/view_stack_model.h"
31 #include "core/components_ng/pattern/model/model_view_ng.h"
32 #include "frameworks/bridge/declarative_frontend/engine/functions/js_click_function.h"
33 #include "frameworks/bridge/declarative_frontend/view_stack_processor.h"
34 
35 namespace OHOS::Ace {
36 
37 std::unique_ptr<ModelView> ModelView::instance_ = nullptr;
38 std::mutex ModelView::mutex_;
39 
GetInstance()40 ModelView* ModelView::GetInstance()
41 {
42     if (!instance_) {
43         std::lock_guard<std::mutex> lock(mutex_);
44         if (!instance_) {
45 #ifdef NG_BUILD
46             instance_.reset(new NG::ModelViewNG());
47 #else
48             if (Container::IsCurrentUseNewPipeline()) {
49                 instance_.reset(new NG::ModelViewNG());
50             } else {
51                 LOGW("ModelView::GetInstance() NOT NG Pipeline not support");
52             }
53 #endif
54         }
55     }
56     return instance_.get();
57 }
58 
59 } // namespace OHOS::Ace
60 
61 namespace OHOS::Ace::Framework {
62 static const std::regex MODEL_RES_ID_REGEX(R"(^resource://\w+/([0-9]+)\.\w+$)", std::regex::icase);
63 static const std::regex MODEL_APP_RES_PATH_REGEX(R"(^resource://RAWFILE/(.*)$)");
64 static const std::regex MODEL_APP_RES_ID_REGEX(R"(^resource://.*/([0-9]+)\.\w+$)", std::regex::icase);
65 static const std::regex MODEL_RES_NAME_REGEX(R"(^resource://.*/(\w+)\.\w+$)", std::regex::icase);
66 static constexpr uint32_t MODEL_RESOURCE_MATCH_SIZE = 2;
67 
GetResourceId(const std::string & uri,uint32_t & resId)68 bool GetResourceId(const std::string& uri, uint32_t& resId)
69 {
70     std::smatch matches;
71     if (std::regex_match(uri, matches, MODEL_RES_ID_REGEX) && matches.size() == MODEL_RESOURCE_MATCH_SIZE) {
72         resId = static_cast<uint32_t>(std::stoul(matches[1].str()));
73         return true;
74     }
75 
76     std::smatch appMatches;
77     if (std::regex_match(uri, appMatches, MODEL_APP_RES_ID_REGEX) && appMatches.size() == MODEL_RESOURCE_MATCH_SIZE) {
78         resId = static_cast<uint32_t>(std::stoul(appMatches[1].str()));
79         return true;
80     }
81     return false;
82 }
83 
GetResourceId(const std::string & uri,std::string & path)84 bool GetResourceId(const std::string& uri, std::string& path)
85 {
86     std::smatch matches;
87     if (std::regex_match(uri, matches, MODEL_APP_RES_PATH_REGEX) && matches.size() == MODEL_RESOURCE_MATCH_SIZE) {
88         path = matches[1].str();
89         return true;
90     }
91     return false;
92 }
93 
GetResourceName(const std::string & uri,std::string & resName)94 bool GetResourceName(const std::string& uri, std::string& resName)
95 {
96     std::smatch matches;
97     if (std::regex_match(uri, matches, MODEL_RES_NAME_REGEX) && matches.size() == MODEL_RESOURCE_MATCH_SIZE) {
98         resName = matches[1].str();
99         return true;
100     }
101     return false;
102 }
103 
SetOhosPath(const std::string & uri,std::string & ohosPath)104 bool SetOhosPath(const std::string& uri, std::string& ohosPath)
105 {
106     if (GetResourceId(uri, ohosPath)) {
107         ohosPath = "OhosRawFile://" + ohosPath;
108         return true;
109     }
110 
111     uint32_t resId = 0;
112     if (GetResourceId(uri, resId)) {
113         ohosPath = "OhosRawFile://" + std::to_string(resId);
114         return true;
115     }
116 
117     if (GetResourceName(uri, ohosPath)) {
118         ohosPath = "OhosRawFile://" + ohosPath;
119         return true;
120     }
121     ohosPath = "OhosRawFile://" + ohosPath;
122     return false;
123 }
124 
125 // get Number data
126 template<typename T>
GetModelProperty(const JSRef<JSObject> & jsValue,const std::string & propertyName,std::unordered_map<std::string,T> & propertyData)127 bool GetModelProperty(
128     const JSRef<JSObject>& jsValue, const std::string& propertyName, std::unordered_map<std::string, T>& propertyData)
129 {
130     auto item = jsValue->GetProperty(propertyName.c_str());
131     if (item->IsObject()) {
132         JSRef<JSObject> itemObj = JSRef<JSObject>::Cast(item);
133         for (auto iter = propertyData.begin(); iter != propertyData.end(); ++iter) {
134             JSRef<JSVal> itemData = itemObj->GetProperty((iter->first).c_str());
135             if (itemData->IsNumber()) {
136                 iter->second = itemData->ToNumber<T>();
137                 continue;
138             }
139             if (itemData->IsBoolean()) {
140                 iter->second = itemData->ToBoolean();
141                 continue;
142             }
143             return false;
144         }
145         return true;
146     }
147     return false;
148 }
149 
JsSetHandleCameraMove(const JSCallbackInfo & info)150 void JSSceneView::JsSetHandleCameraMove(const JSCallbackInfo& info)
151 {
152     if (info.Length() < 1) {
153         return;
154     }
155 
156     if (!info[0]->IsBoolean()) {
157         return;
158     }
159 
160     bool value = info[0]->ToBoolean();
161     ModelView::GetInstance()->SetHandleCameraMove(value);
162 }
163 
Create(const JSCallbackInfo & info)164 void JSSceneView::Create(const JSCallbackInfo& info)
165 {
166     const auto& length = info.Length();
167     std::string srcPath("");
168     int surfaceData = 0;
169     std::string bundleName;
170     std::string moduleName;
171 
172     Render3D::SurfaceType surfaceType = OHOS::Render3D::SurfaceType::SURFACE_TEXTURE;
173     if (length == 2) { // 2: info size
174         surfaceData = info[1]->ToNumber<int32_t>();
175         ParseJsMedia(info[0], srcPath);
176         GetJsMediaBundleInfo(info[0], bundleName, moduleName);
177     } else if (length == 1) {
178         if (!ParseJsMedia(info[0], srcPath)) {
179             // SceneOptions
180             JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
181             auto scene = jsObj->GetProperty("scene");
182             if (!scene->IsNull()) {
183                 ParseJsMedia(scene, srcPath);
184                 GetJsMediaBundleInfo(scene, bundleName, moduleName);
185             }
186             auto type = jsObj->GetProperty("modelType");
187             if (!type->IsNull()) {
188                 surfaceData = type->ToNumber<int32_t>();
189             }
190         }
191     }
192 
193     surfaceType = (surfaceData == 0) ? OHOS::Render3D::SurfaceType::SURFACE_TEXTURE :
194         OHOS::Render3D::SurfaceType::SURFACE_WINDOW;
195 
196     std::string ohosPath("");
197     SetOhosPath(srcPath, ohosPath);
198     LOGD("srcPath after ParseJsMedia(): %s bundleName: %s, moduleName %s", ohosPath.c_str(),
199         bundleName.c_str(), moduleName.c_str());
200     ModelView::GetInstance()->Create(bundleName, moduleName, surfaceType);
201     ModelView::GetInstance()->SetModelSource(ohosPath);
202 }
203 
JsCamera(const JSCallbackInfo & info)204 void JSSceneView::JsCamera(const JSCallbackInfo& info)
205 {
206     // Parse the info object.
207     if (info.Length() <= 0 || !info[0]->IsObject()) {
208         return;
209     }
210 
211     AnimationOption animOption = ViewStackModel::GetInstance()->GetImplicitAnimationOption();
212     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
213     std::unordered_map<std::string, float> perspect { { "zNear", 0.5f }, { "zFar", 50.0f }, { "yFov", 60.0f } };
214     GetModelProperty(jsObj, "perspective", perspect);
215     ModelView::GetInstance()->SetCameraFrustum(perspect["zNear"], perspect["zFar"], perspect["yFov"]);
216     // cameraSpace
217     std::unordered_map<std::string, float> positionAng { { "theta", 0.0f }, { "phi", 0.0f }, { "radius", 4.0f } };
218     std::unordered_map<std::string, float> position { { "x", 0.0f }, { "y", 0.0f }, { "z", 4.0f } };
219     std::unordered_map<std::string, float> front { { "x", 0.0f }, { "y", 0.0f }, { "z", 0.0f } };
220     std::unordered_map<std::string, float> up { { "x", 0.0f }, { "y", 0.0f }, { "z", 0.0f } };
221     if (GetModelProperty(jsObj, "cameraSpace", positionAng)) {
222         ModelView::GetInstance()->SetCameraPosition(AnimatableFloat(positionAng["theta"], animOption),
223             AnimatableFloat(0, animOption), AnimatableFloat(positionAng["phi"], animOption),
224             AnimatableFloat(positionAng["radius"], animOption), true);
225         return;
226     }
227     auto itemCameraSpace = jsObj->GetProperty("cameraSpace");
228     if (itemCameraSpace->IsObject()) {
229         JSRef<JSObject> spaceObj = JSRef<JSObject>::Cast(itemCameraSpace);
230         // position
231         GetModelProperty(spaceObj, "position", position);
232         // front
233         GetModelProperty(spaceObj, "front", front);
234         // up
235         GetModelProperty(spaceObj, "up", up);
236     }
237     ModelView::GetInstance()->SetCameraPosition(AnimatableFloat(position["x"], animOption),
238         AnimatableFloat(position["y"], animOption), AnimatableFloat(position["z"], animOption),
239         AnimatableFloat(0.0f, animOption), false);
240     Vec3 lookVec(front["x"], front["y"], front["z"]);
241     ModelView::GetInstance()->SetCameraLookAt(lookVec);
242     Vec3 upVec(up["x"], up["y"], up["z"]);
243     ModelView::GetInstance()->SetCameraUp(upVec);
244 }
245 
JsSetTransparent(const JSCallbackInfo & info)246 void JSSceneView::JsSetTransparent(const JSCallbackInfo& info)
247 {
248     if (info.Length() < 1) {
249         return;
250     }
251 
252     if (!info[0]->IsBoolean()) {
253         return;
254     }
255 
256     bool value = info[0]->ToBoolean();
257     ModelView::GetInstance()->SetTransparent(value);
258 }
259 
JsSetBackground(const JSCallbackInfo & info)260 void JSSceneView::JsSetBackground(const JSCallbackInfo& info)
261 {
262     if (info.Length() < 1) {
263         return;
264     }
265 
266     std::string srcPath;
267     auto parseOk = ParseJsMedia(info[0], srcPath);
268     if (!parseOk) {
269         return;
270     }
271     std::string ohosPath("");
272     SetOhosPath(srcPath, ohosPath);
273     ModelView::GetInstance()->SetBackground(ohosPath);
274 }
275 
JsLight(const JSCallbackInfo & info)276 void JSSceneView::JsLight(const JSCallbackInfo& info)
277 {
278     // Parse the info object.
279     if (info.Length() <= 0 || !info[0]->IsObject()) {
280         return;
281     }
282 
283     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
284     JSRef<JSVal> itemType = jsObj->GetProperty("type");
285     JSRef<JSVal> itemIntensity = jsObj->GetProperty("intensity");
286     JSRef<JSVal> itemShadow = jsObj->GetProperty("shadow");
287     auto type = static_cast<NG::ModelLightType>((itemType->IsNumber()) ? itemType->ToNumber<int32_t>() : 1);
288     int intensity = (itemIntensity->IsNumber()) ? itemIntensity->ToNumber<int32_t>() : 10;
289     bool shadow = (itemShadow->IsBoolean()) ? itemShadow->ToBoolean() : false;
290     JSRef<JSVal> lightColor = jsObj->GetProperty("color");
291     Color color(0xffffffff); // red:255, green:255, blue:255
292     ParseJsColor(lightColor, color);
293     AnimationOption animOption = ViewStackModel::GetInstance()->GetImplicitAnimationOption();
294     Vec3 inputColor = Vec3(color.GetRed() / 255.0f, color.GetGreen() / 255.0f, color.GetBlue() / 255.0f, animOption);
295     OHOS::Ace::NG::ModelPosition position;
296     double maxInvalid = std::numeric_limits<double>::max();
297     Quaternion rotation = Quaternion(maxInvalid, maxInvalid, maxInvalid, maxInvalid);
298     std::unordered_map<std::string, float> positionAng { { "theta", 0.0f }, { "phi", 0.0f }, { "radius", 4.0f } };
299     std::unordered_map<std::string, float> pos { { "x", 0.0f }, { "y", 1.0f }, { "z", 0.0f } };
300     std::unordered_map<std::string, float> quat { { "x", 0.0f }, { "y", 1.0f }, { "z", 0.0f }, { "w", 1.0f } };
301     if (GetModelProperty(jsObj, "lightSpace", positionAng)) {
302         position.Set({ AnimatableFloat(positionAng["theta"], animOption), AnimatableFloat(0.0f, animOption),
303                          AnimatableFloat(positionAng["phi"], animOption) },
304             AnimatableFloat(positionAng["radius"], animOption), true);
305         ModelView::GetInstance()->AddLight(AceType::MakeRefPtr<NG::ModelLight>(
306             type, inputColor, AnimatableFloat(intensity, animOption), shadow, position, rotation));
307         return;
308     }
309     auto itemLightSpace = jsObj->GetProperty("lightSpace");
310     if (itemLightSpace->IsObject()) {
311         JSRef<JSObject> spaceObj = JSRef<JSObject>::Cast(itemLightSpace);
312         GetModelProperty(spaceObj, "position", pos);
313         position.Set({ AnimatableFloat(pos["x"], animOption), AnimatableFloat(pos["y"], animOption),
314                          AnimatableFloat(pos["z"], animOption) },
315             AnimatableFloat(0.0f, animOption), false);
316         GetModelProperty(spaceObj, "rotation", quat);
317         rotation = Quaternion(quat["x"], quat["y"], quat["z"], quat["w"]);
318     }
319     ModelView::GetInstance()->AddLight(AceType::MakeRefPtr<NG::ModelLight>(
320         type, inputColor, AnimatableFloat(intensity, animOption), shadow, position, rotation));
321 }
322 
JsAddCube(const JSCallbackInfo & info)323 void JSSceneView::JsAddCube(const JSCallbackInfo& info)
324 {
325     // Parse the info object.
326     if (info.Length() <= 0 || !info[0]->IsObject()) {
327         return;
328     }
329 
330     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
331     auto name = jsObj->GetPropertyValue<std::string>("name", "");
332     auto width = jsObj->GetPropertyValue<double>("width", 0.0);
333     auto height = jsObj->GetPropertyValue<double>("height", 0.0);
334     auto depth = jsObj->GetPropertyValue<double>("depth", 0.0);
335 
336     OHOS::Render3D::Vec3 position(0.0f, 0.0f, 0.0f);
337     if (jsObj->HasProperty("position")) {
338         JSRef<JSVal> positionArgs = jsObj->GetProperty("position");
339         if (positionArgs->IsObject()) {
340             JSRef<JSObject> posObj = JSRef<JSObject>::Cast(positionArgs);
341             position.SetX(posObj->GetPropertyValue<double>("x", 0.0));
342             position.SetY(posObj->GetPropertyValue<double>("y", 0.0));
343             position.SetZ(posObj->GetPropertyValue<double>("z", 0.0));
344         }
345     }
346 
347     ModelView::GetInstance()->AddGeometry(
348         std::make_shared<OHOS::Render3D::Cube>(name.c_str(), width, height, depth, position));
349 }
350 
JsAddSphere(const JSCallbackInfo & info)351 void JSSceneView::JsAddSphere(const JSCallbackInfo& info)
352 {
353     // Parse the info object.
354     if (info.Length() <= 0 || !info[0]->IsObject()) {
355         return;
356     }
357 
358     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
359     auto name = jsObj->GetPropertyValue<std::string>("name", "");
360     auto radius = jsObj->GetPropertyValue<double>("radius", 0.0);
361     auto rings = jsObj->GetPropertyValue<int32_t>("rings", 0);
362     auto sectors = jsObj->GetPropertyValue<int32_t>("sectors", 0);
363 
364     OHOS::Render3D::Vec3 position(0.0f, 0.0f, 0.0f);
365     if (jsObj->HasProperty("position")) {
366         JSRef<JSVal> positionArgs = jsObj->GetProperty("position");
367         if (positionArgs->IsObject()) {
368             JSRef<JSObject> posObj = JSRef<JSObject>::Cast(positionArgs);
369             position.SetX(posObj->GetPropertyValue<double>("x", 0.0));
370             position.SetY(posObj->GetPropertyValue<double>("y", 0.0));
371             position.SetZ(posObj->GetPropertyValue<double>("z", 0.0));
372         }
373     }
374 
375     ModelView::GetInstance()->AddGeometry(
376         std::make_shared<OHOS::Render3D::Sphere>(name.c_str(), radius, rings, sectors, position));
377 }
378 
JsAddCone(const JSCallbackInfo & info)379 void JSSceneView::JsAddCone(const JSCallbackInfo& info)
380 {
381     // Parse the info object.
382     if (info.Length() <= 0 || !info[0]->IsObject()) {
383         return;
384     }
385 
386     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
387     auto name = jsObj->GetPropertyValue<std::string>("name", "");
388     auto radius = jsObj->GetPropertyValue<double>("radius", 0.0);
389     auto length = jsObj->GetPropertyValue<int32_t>("length", 0);
390     auto sectors = jsObj->GetPropertyValue<int32_t>("sectors", 0);
391 
392     OHOS::Render3D::Vec3 position(0.0f, 0.0f, 0.0f);
393     if (jsObj->HasProperty("position")) {
394         JSRef<JSVal> positionArgs = jsObj->GetProperty("position");
395         if (positionArgs->IsObject()) {
396             JSRef<JSObject> posObj = JSRef<JSObject>::Cast(positionArgs);
397             position.SetX(posObj->GetPropertyValue<double>("x", 0.0));
398             position.SetY(posObj->GetPropertyValue<double>("y", 0.0));
399             position.SetZ(posObj->GetPropertyValue<double>("z", 0.0));
400         }
401     }
402 
403     ModelView::GetInstance()->AddGeometry(
404         std::make_shared<OHOS::Render3D::Cone>(name.c_str(), radius, length, sectors, position));
405 }
406 
JsGLTFAnimation(const JSCallbackInfo & info)407 void JSSceneView::JsGLTFAnimation(const JSCallbackInfo& info)
408 {
409     // Parse the info object.
410     if (info.Length() < 1 || !info[0]->IsObject()) {
411         return;
412     }
413 
414     JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
415     JSRef<JSVal> itemName = jsObj->GetProperty("name");
416     std::string name = (itemName->IsString()) ? itemName->ToString() : "";
417     JSRef<JSVal> itemState = jsObj->GetProperty("state");
418     auto state = (itemState->IsNumber()) ? itemState->ToNumber<int32_t>() : 0;
419     JSRef<JSVal> itemRepeat = jsObj->GetProperty("repeatCount");
420     auto repeatCount = (itemRepeat->IsNumber()) ? itemRepeat->ToNumber<int32_t>() : -1;
421     JSRef<JSVal> itemSpeed = jsObj->GetProperty("speed");
422     auto speed = (itemSpeed->IsNumber()) ? itemSpeed->ToNumber<float>() : 1.0f;
423     JSRef<JSVal> itemDuration = jsObj->GetProperty("duration");
424     auto duration = (itemDuration->IsNumber()) ? itemDuration->ToNumber<float>() : -1.0f;
425     JSRef<JSVal> itemReverse = jsObj->GetProperty("reverse");
426     auto reverse = (itemReverse->IsBoolean()) ? itemReverse->ToBoolean() : false;
427 
428     ModelView::GetInstance()->AddGLTFAnimation(std::make_shared<Render3D::GLTFAnimation>(
429         name, static_cast<Render3D::AnimationState>(state), repeatCount, speed, duration, reverse));
430 }
431 
JsAddCustomRender(const JSCallbackInfo & info)432 void JSSceneView::JsAddCustomRender(const JSCallbackInfo& info)
433 {
434     if (info.Length() != 2) {
435         return;
436     }
437 
438     if (info[1]->IsNull() || !info[1]->IsBoolean()) {
439         return;
440     }
441 
442     std::string uri;
443     auto parseOk = ParseJsMedia(info[0], uri);
444     if (!parseOk) {
445         return;
446     }
447 
448     std::string ohosPath("");
449     SetOhosPath(uri, ohosPath);
450     auto desc = std::make_shared<Render3D::CustomRenderDescriptor>(ohosPath, info[1]->ToBoolean());
451     ModelView::GetInstance()->AddCustomRender(desc);
452 }
453 
JsWidth(const JSCallbackInfo & info)454 void JSSceneView::JsWidth(const JSCallbackInfo& info)
455 {
456     if (info.Length() < 1) {
457         return;
458     }
459 
460     CalcDimension value;
461     if (!ParseJsDimensionVp(info[0], value)) {
462         return;
463     }
464 
465     if (LessNotEqual(value.Value(), 0.0)) {
466         value.SetValue(0.0);
467     }
468     ModelView::GetInstance()->SetWidth(value);
469 }
470 
JsHeight(const JSCallbackInfo & info)471 void JSSceneView::JsHeight(const JSCallbackInfo& info)
472 {
473     if (info.Length() < 1) {
474         return;
475     }
476 
477     CalcDimension value;
478     if (!ParseJsDimensionVp(info[0], value)) {
479         return;
480     }
481 
482     if (LessNotEqual(value.Value(), 0.0)) {
483         value.SetValue(0.0);
484     }
485     ModelView::GetInstance()->SetHeight(value);
486 }
487 
JsRenderWidth(const JSCallbackInfo & info)488 void JSSceneView::JsRenderWidth(const JSCallbackInfo& info)
489 {
490     if (info.Length() < 1) {
491         return;
492     }
493     CalcDimension value;
494     if (!ParseJsDimensionVp(info[0], value)) {
495         value.SetValue(1.0f);
496         return;
497     }
498 
499     if (info[0]->IsNumber() || info[0]->IsObject()) {
500         value.SetValue(1.0f);
501     }
502 
503     if (LessNotEqual(value.Value(), 0.0f)) {
504         value.SetValue(0.0f);
505     }
506     ModelView::GetInstance()->SetRenderWidth(value);
507 }
508 
JsRenderHeight(const JSCallbackInfo & info)509 void JSSceneView::JsRenderHeight(const JSCallbackInfo& info)
510 {
511     if (info.Length() < 1) {
512         return;
513     }
514     CalcDimension value;
515     if (!ParseJsDimensionVp(info[0], value)) {
516         LOGE("invalid args for render height");
517         value.SetValue(1.0f);
518         return;
519     }
520 
521     if (info[0]->IsNumber() || info[0]->IsObject()) {
522         value.SetValue(1.0f);
523     }
524 
525     if (LessNotEqual(value.Value(), 0.0f)) {
526         value.SetValue(0.0f);
527     }
528     ModelView::GetInstance()->SetRenderHeight(value);
529 }
530 
JsRenderFrameRate(const JSCallbackInfo & info)531 void JSSceneView::JsRenderFrameRate(const JSCallbackInfo& info) {}
532 
JsShader(const JSCallbackInfo & info)533 void JSSceneView::JsShader(const JSCallbackInfo& info)
534 {
535     if (info.Length() != 1) {
536         return;
537     }
538 
539     std::string shaderPath;
540     auto parseOk = ParseJsMedia(info[0], shaderPath);
541     if (!parseOk) {
542         return;
543     }
544 
545     std::string ohosPath("");
546     SetOhosPath(shaderPath, ohosPath);
547     ModelView::GetInstance()->SetShader(ohosPath);
548 }
549 
JsShaderImageTexture(const JSCallbackInfo & info)550 void JSSceneView::JsShaderImageTexture(const JSCallbackInfo& info)
551 {
552     if (info.Length() != 1) {
553         return;
554     }
555 
556     std::string texturePath;
557     auto parseOk = ParseJsMedia(info[0], texturePath);
558     if (!parseOk) {
559         return;
560     }
561 
562     std::string ohosPath("");
563     SetOhosPath(texturePath, ohosPath);
564     ModelView::GetInstance()->AddShaderImageTexture(ohosPath);
565 }
566 
JsShaderInputBuffer(const JSCallbackInfo & info)567 void JSSceneView::JsShaderInputBuffer(const JSCallbackInfo& info)
568 {
569     if (info.Length() != 1 || !info[0]->IsArray()) {
570         return;
571     }
572 
573     JSRef<JSArray> array = JSRef<JSArray>::Cast(info[0]);
574     int32_t length = static_cast<int32_t>(array->Length());
575     if (length <= 0) {
576         return;
577     }
578 
579     auto modelView = ModelView::GetInstance();
580     std::shared_ptr<OHOS::Render3D::ShaderInputBuffer> buffer = nullptr;
581 
582     // same shader input buffer would be rejected to update for nearEqual check
583     buffer = std::make_shared<OHOS::Render3D::ShaderInputBuffer>();
584     if (!buffer->Alloc(length)) {
585         return;
586     }
587 
588     for (uint32_t i = 0; i < static_cast<uint32_t>(length); i++) {
589         JSRef<JSVal> jsValue = array->GetValueAt(i);
590         if (jsValue->IsNumber()) {
591             buffer->Update(jsValue->ToNumber<float>(), i);
592         } else {
593             return;
594         }
595     }
596 
597     modelView->AddShaderInputBuffer(buffer);
598 }
599 
JsOnError(const JSCallbackInfo & info)600 void JSSceneView::JsOnError(const JSCallbackInfo& info) {}
601 
JSBind(BindingTarget globalObj)602 void JSSceneView::JSBind(BindingTarget globalObj)
603 {
604     JSClass<JSSceneView>::Declare("Component3D");
605     MethodOptions opt = MethodOptions::NONE;
606     JSClass<JSSceneView>::StaticMethod("create", &JSSceneView::Create, opt);
607     JSClass<JSSceneView>::StaticMethod("gestureAccess", &JSSceneView::JsSetHandleCameraMove);
608     JSClass<JSSceneView>::StaticMethod("camera", &JSSceneView::JsCamera);
609     JSClass<JSSceneView>::StaticMethod("transparent", &JSSceneView::JsSetTransparent);
610     JSClass<JSSceneView>::StaticMethod("environment", &JSSceneView::JsSetBackground);
611     JSClass<JSSceneView>::StaticMethod("light", &JSSceneView::JsLight);
612     JSClass<JSSceneView>::StaticMethod("cube", &JSSceneView::JsAddCube);
613     JSClass<JSSceneView>::StaticMethod("sphere", &JSSceneView::JsAddSphere);
614     JSClass<JSSceneView>::StaticMethod("cone", &JSSceneView::JsAddCone);
615     JSClass<JSSceneView>::StaticMethod("modelAnimation", &JSSceneView::JsGLTFAnimation);
616     JSClass<JSSceneView>::StaticMethod("customRender", &JSSceneView::JsAddCustomRender);
617     JSClass<JSSceneView>::StaticMethod("width", &JSSceneView::JsWidth);
618     JSClass<JSSceneView>::StaticMethod("height", &JSSceneView::JsHeight);
619     JSClass<JSSceneView>::StaticMethod("shader", &JSSceneView::JsShader);
620     JSClass<JSSceneView>::StaticMethod("renderWidth", &JSSceneView::JsRenderWidth);
621     JSClass<JSSceneView>::StaticMethod("renderHeight", &JSSceneView::JsRenderHeight);
622     JSClass<JSSceneView>::StaticMethod("renderFrameRateHint", &JSSceneView::JsRenderFrameRate);
623     JSClass<JSSceneView>::StaticMethod("shaderImageTexture", &JSSceneView::JsShaderImageTexture);
624     JSClass<JSSceneView>::StaticMethod("shaderInputBuffer", &JSSceneView::JsShaderInputBuffer);
625     JSClass<JSSceneView>::StaticMethod("OnError", &JSSceneView::JsOnError);
626     JSClass<JSSceneView>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
627     JSClass<JSSceneView>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
628     JSClass<JSSceneView>::StaticMethod("onClick", &JSInteractableView::JsOnClick);
629     JSClass<JSSceneView>::InheritAndBind<JSViewAbstract>(globalObj);
630 }
631 
632 } // namespace OHOS::Ace::Framework
633