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