1 /*
2 * Copyright (C) 2024 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 "MeshJS.h"
17
18 #include <meta/api/make_callback.h>
19 #include <meta/interface/intf_task_queue.h>
20 #include <meta/interface/intf_task_queue_registry.h>
21 #include <scene_plugin/api/camera_uid.h>
22 #include <scene_plugin/interface/intf_camera.h>
23 #include <scene_plugin/interface/intf_scene.h>
24
GetInstanceImpl(uint32_t id)25 void* MeshJS::GetInstanceImpl(uint32_t id)
26 {
27 if (id == MeshJS::ID) {
28 return this;
29 }
30 return SceneResourceImpl::GetInstanceImpl(id);
31 }
DisposeNative()32 void MeshJS::DisposeNative()
33 {
34 // do nothing for now..
35 LOG_F("MeshJS::DisposeNative");
36 scene_.Reset();
37 }
Init(napi_env env,napi_value exports)38 void MeshJS::Init(napi_env env, napi_value exports)
39 {
40 BASE_NS::vector<napi_property_descriptor> node_props;
41 SceneResourceImpl::GetPropertyDescs(node_props);
42
43 using namespace NapiApi;
44 node_props.push_back(GetProperty<Object, MeshJS, &MeshJS::GetSubmesh>("subMeshes"));
45 node_props.push_back(GetProperty<Object, MeshJS, &MeshJS::GetAABB>("aabb"));
46 node_props.push_back(
47 GetSetProperty<Object, MeshJS, &MeshJS::GetMaterialOverride, &MeshJS::SetMaterialOverride>("materialOverride"));
48
49 napi_value func;
50 auto status = napi_define_class(env, "Mesh", NAPI_AUTO_LENGTH, BaseObject::ctor<MeshJS>(), nullptr,
51 node_props.size(), node_props.data(), &func);
52
53 NapiApi::MyInstanceState* mis;
54 napi_get_instance_data(env, (void**)&mis);
55 mis->StoreCtor("Mesh", func);
56 }
57
MeshJS(napi_env e,napi_callback_info i)58 MeshJS::MeshJS(napi_env e, napi_callback_info i) : BaseObject<MeshJS>(e, i), SceneResourceImpl(SceneResourceImpl::MESH)
59 {
60 NapiApi::FunctionContext<NapiApi::Object, NapiApi::Object> fromJs(e, i);
61 if (!fromJs) {
62 // okay internal create. we will receive the object after.
63 return;
64 }
65 NapiApi::Object scene = fromJs.Arg<0>();
66 scene_ = scene;
67 if (!GetNativeMeta<SCENE_NS::IScene>(scene_.GetObject())) {
68 CORE_LOG_F("INVALID SCENE!");
69 }
70 }
~MeshJS()71 MeshJS::~MeshJS()
72 {
73 LOG_F("MeshJS -- ");
74 }
75
GetSubmesh(NapiApi::FunctionContext<> & ctx)76 napi_value MeshJS::GetSubmesh(NapiApi::FunctionContext<>& ctx)
77 {
78 auto node = interface_pointer_cast<SCENE_NS::IMesh>(GetThisNativeObject(ctx));
79 if (!node) {
80 // return undefined.. as no actual node.
81 napi_value undef;
82 napi_get_undefined(ctx, &undef);
83 return undef;
84 }
85
86 BASE_NS::vector<SCENE_NS::ISubMesh::Ptr> subs;
87 ExecSyncTask([node, &subs]() {
88 subs = node->SubMeshes()->GetValue();
89 return META_NS::IAny::Ptr {};
90 });
91
92 napi_value tmp;
93 auto status = napi_create_array_with_length(ctx, subs.size(), &tmp);
94 size_t i = 0;
95 for (const auto& node : subs) {
96 NapiApi::Object argJS(ctx);
97 napi_value args[] = { scene_.GetValue(), argJS };
98
99 napi_value val = CreateFromNativeInstance(
100 ctx, interface_pointer_cast<META_NS::IObject>(node), false, BASE_NS::countof(args), args);
101 status = napi_set_element(ctx, tmp, i++, val);
102 }
103
104 return tmp;
105 }
106
GetAABB(NapiApi::FunctionContext<> & ctx)107 napi_value MeshJS::GetAABB(NapiApi::FunctionContext<>& ctx)
108 {
109 napi_value undef;
110 napi_get_undefined(ctx, &undef);
111 auto node = interface_pointer_cast<SCENE_NS::IMesh>(GetThisNativeObject(ctx));
112 if (!node) {
113 // return undefined.. as no actual node.
114 return undef;
115 }
116 BASE_NS::Math::Vec3 aabmin;
117 BASE_NS::Math::Vec3 aabmax;
118 ExecSyncTask([node, &aabmin, &aabmax]() {
119 aabmin = node->AABBMin()->GetValue();
120 aabmax = node->AABBMax()->GetValue();
121 return META_NS::IAny::Ptr {};
122 });
123 NapiApi::Object res(ctx);
124
125 NapiApi::Object min(ctx);
126 min.Set("x", NapiApi::Value<float> { ctx, aabmin.x });
127 min.Set("y", NapiApi::Value<float> { ctx, aabmin.y });
128 min.Set("z", NapiApi::Value<float> { ctx, aabmin.z });
129 res.Set("aabbMin", min);
130
131 NapiApi::Object max(ctx);
132 max.Set("x", NapiApi::Value<float> { ctx, aabmax.x });
133 max.Set("y", NapiApi::Value<float> { ctx, aabmax.y });
134 max.Set("z", NapiApi::Value<float> { ctx, aabmax.z });
135 res.Set("aabbMax", max);
136 return res;
137 }
138
GetMaterialOverride(NapiApi::FunctionContext<> & ctx)139 napi_value MeshJS::GetMaterialOverride(NapiApi::FunctionContext<>& ctx)
140 {
141 napi_value undef;
142 napi_get_undefined(ctx, &undef);
143 auto sm = interface_pointer_cast<SCENE_NS::IMesh>(GetThisNativeObject(ctx));
144 if (!sm) {
145 // return undefined.. as submesh bound.
146 return undef;
147 }
148 META_NS::IObject::Ptr obj;
149 ExecSyncTask([sm, &obj]() {
150 auto material = sm->MaterialOverride()->GetValue();
151 obj = interface_pointer_cast<META_NS::IObject>(material);
152 return META_NS::IAny::Ptr {};
153 });
154
155 if (obj == nullptr) {
156 return ctx.GetUndefined();
157 }
158 if (auto cached = FetchJsObj(obj)) {
159 // always return the same js object.
160 return cached;
161 }
162 napi_value args[] = { ctx.This() };
163 return CreateFromNativeInstance(ctx, obj, false /*these are owned by the scene*/, BASE_NS::countof(args), args);
164 }
165
SetMaterialOverride(NapiApi::FunctionContext<NapiApi::Object> & ctx)166 void MeshJS::SetMaterialOverride(NapiApi::FunctionContext<NapiApi::Object>& ctx)
167 {
168 auto sm = interface_pointer_cast<SCENE_NS::IMesh>(GetThisNativeObject(ctx));
169 if (!sm) {
170 // return undefined.. as no actual node.
171 return;
172 }
173 NapiApi::Object obj = ctx.Arg<0>();
174 auto new_material = GetNativeMeta<SCENE_NS::IMaterial>(obj);
175 ExecSyncTask([sm, &new_material]() {
176 sm->MaterialOverride()->SetValue(new_material);
177 return META_NS::IAny::Ptr {};
178 });
179 }
180