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 #ifndef SCENEPLUGINAPI_MESH_H
17 #define SCENEPLUGINAPI_MESH_H
18
19 #include <scene_plugin/api/material.h>
20 #include <scene_plugin/api/mesh_uid.h>
21 #include <scene_plugin/interface/intf_scene.h>
22
23 #include <meta/api/internal/object_api.h>
SCENE_BEGIN_NAMESPACE()24 SCENE_BEGIN_NAMESPACE()
25
26 class SubMesh final : public META_NS::Internal::ObjectInterfaceAPI<SubMesh, ClassId::SubMesh> {
27 META_API(SubMesh)
28 META_API_OBJECT_CONVERTIBLE(ISubMesh)
29 META_API_CACHE_INTERFACE(ISubMesh, SubMesh)
30 public:
31 // ToDo: The properties mirror the values from entity system, but setting the values
32 // needs to happen using setter methods below (even the properties are not marked
33 // ReadOnly
34 META_API_INTERFACE_PROPERTY_CACHED(SubMesh, Material, SCENE_NS::IMaterial::Ptr)
35 META_API_INTERFACE_PROPERTY_CACHED(SubMesh, AABBMin, BASE_NS::Math::Vec3)
36 META_API_INTERFACE_PROPERTY_CACHED(SubMesh, AABBMax, BASE_NS::Math::Vec3)
37 META_API_INTERFACE_PROPERTY_CACHED(SubMesh, RenderSortLayerOrder, uint8_t)
38
39 /**
40 * @brief Within a render slot, a layer can define a sort layer order for a submesh.
41 * There are 0-63 values available. Default id value is 32.
42 * 0 first, 63 last
43 * 1. Typical use case is to set render sort layer to objects which render with depth test without depth write.
44 * 2. Typical use case is to always render character and/or camera object first to cull large parts of the view.
45 * 3. Sort e.g. plane layers.
46 * @param index The selected submesh index.
47 * @param value The layer order number.
48 */
49 void SetRenderSortLayerOrder(uint8_t order)
50 {
51 if (auto submesh = META_API_CACHED_INTERFACE(SubMesh)) {
52 submesh->SetRenderSortLayerOrder(order);
53 }
54 }
55
56 /**
57 * @brief Set axis aligned bounding box min to the submesh.
58 */
59 void SetAABBMin(const BASE_NS::Math::Vec3& min)
60 {
61 if (auto submesh = META_API_CACHED_INTERFACE(SubMesh)) {
62 submesh->SetAABBMin(min);
63 }
64 }
65
66 /**
67 * @brief Set axis aligned bounding box max to the submesh.
68 */
69 void SetAABBMax(const BASE_NS::Math::Vec3& max)
70 {
71 if (auto submesh = META_API_CACHED_INTERFACE(SubMesh)) {
72 submesh->SetAABBMax(max);
73 }
74 }
75
76 /**
77 * @brief Set material to the submesh.
78 */
79 void SetMaterial(SCENE_NS::IMaterial::Ptr material)
80 {
81 if (auto submesh = META_API_CACHED_INTERFACE(SubMesh)) {
82 submesh->SetMaterial(material);
83 }
84 }
85 };
86
87 /**
88 * @brief Mesh class wraps IMesh interface. It keeps the referenced object alive using strong ref.
89 * The construction of the object is asynchronous, the properties of the engine may not be available
90 * right after the object instantiation, but OnLoaded() event can be used to observe the state changes.
91 * Mesh object may not implement Node interfaces on Engine side, so container operations and
92 * transform operations are not applicable as such.
93 */
94 class Mesh final : public META_NS::Internal::ObjectInterfaceAPI<Mesh, ClassId::Mesh> {
95 META_API(Mesh)
META_API_OBJECT_CONVERTIBLE(IMesh)96 META_API_OBJECT_CONVERTIBLE(IMesh)
97 META_API_CACHE_INTERFACE(IMesh, Mesh)
98 META_API_OBJECT_CONVERTIBLE(INode)
99 META_API_CACHE_INTERFACE(INode, Node)
100 public:
101 // From Node
102 META_API_INTERFACE_PROPERTY_CACHED(Node, Name, BASE_NS::string)
103 META_API_INTERFACE_READONLY_ARRAY_PROPERTY_CACHED(Mesh, SubMeshes, SCENE_NS::ISubMesh::Ptr)
104 META_API_INTERFACE_READONLY_PROPERTY_CACHED(Mesh, AABBMin, BASE_NS::Math::Vec3)
105 META_API_INTERFACE_READONLY_PROPERTY_CACHED(Mesh, AABBMax, BASE_NS::Math::Vec3)
106
107 public:
108 /**
109 * @brief Construct Mesh instance from INode strong pointer.
110 * @param node the object pointed by interface is kept alive
111 */
112 explicit Mesh(const INode::Ptr& node)
113 {
114 Initialize(interface_pointer_cast<META_NS::IObject>(node));
115 }
116
117 /**
118 * @brief Construct Mesh instance from IMesh strong pointer.
119 * @param node the object pointed by interface is kept alive
120 */
Mesh(const IMesh::Ptr & node)121 Mesh(const IMesh::Ptr& node)
122 {
123 Initialize(interface_pointer_cast<META_NS::IObject>(node));
124 }
125
126 /**
127 * @brief Gets OnLoaded event from INode-interface
128 * @return INode::OnLoaded
129 */
OnLoaded()130 auto OnLoaded()
131 {
132 return META_API_CACHED_INTERFACE(Node)->OnLoaded();
133 }
134
135 /**
136 * @brief Runs a callback once the mesh is loaded. If mesh is already initialized, callback will not run.
137 * @param callback Code to run, if strong reference is passed, it will keep the instance alive
138 * causing engine to report memory leak on application exit.
139 * @return reference to this instance of Mesh.
140 */
141 template<class Callback>
OnLoaded(Callback && callback)142 auto& OnLoaded(Callback&& callback)
143 {
144 OnLoaded()->AddHandler(META_NS::MakeCallback<META_NS::IOnChanged>(callback));
145 return *this;
146 }
147
148 /**
149 * @brief Get the material from the selected submesh. The returned object is constructed asynchronously.
150 * @param index The selected submesh index.
151 * @return If the given index is valid, an object referencing the selected material.
152 */
GetMaterial(size_t index)153 Material GetMaterial(size_t index)
154 {
155 IMaterial::Ptr ret {};
156 if (auto mesh = META_API_CACHED_INTERFACE(Mesh)) {
157 ret = mesh->GetMaterial(index);
158 }
159 return Material(ret);
160 }
161
162 /**
163 * @brief Set given material for all the submeshes.
164 * @material The material to be set.
165 */
SetMaterial(const IMaterial::Ptr material)166 void SetMaterial(const IMaterial::Ptr material)
167 {
168 if (auto mesh = META_API_CACHED_INTERFACE(Mesh)) {
169 mesh->SetMaterial(-1, material);
170 }
171 }
172
173 /**
174 * @brief Set material for the spesific submesh.
175 * @material The material to be set.
176 * @param index The selected submesh index.
177 */
SetMaterial(size_t index,const IMaterial::Ptr material)178 void SetMaterial(size_t index, const IMaterial::Ptr material)
179 {
180 if (auto mesh = META_API_CACHED_INTERFACE(Mesh)) {
181 mesh->SetMaterial(index, material);
182 }
183 }
184
185 /**
186 * @brief Within a render slot, a layer can define a sort layer order for a submesh.
187 * There are 0-63 values available. Default id value is 32.
188 * 0 first, 63 last
189 * 1. Typical use case is to set render sort layer to objects which render with depth test without depth write.
190 * 2. Typical use case is to always render character and/or camera object first to cull large parts of the view.
191 * 3. Sort e.g. plane layers. * @param index The selected submesh index.
192 * @param index The selected submesh index.
193 * @param value The layer order number.
194 */
SetRenderSortLayerOrder(size_t index,uint8_t value)195 void SetRenderSortLayerOrder(size_t index, uint8_t value)
196 {
197 if (auto mesh = META_API_CACHED_INTERFACE(Mesh)) {
198 mesh->SetRenderSortLayerOrder(index, value);
199 }
200 }
201
202 /**
203 * @brief Get render sort layer order for selected submesh
204 * @return The layer order for selected index, if the index is not present, returns 0u.
205 */
GetRenderSortLayerOrder(size_t index)206 uint8_t GetRenderSortLayerOrder(size_t index) const
207 {
208 if (auto mesh = META_API_CACHED_INTERFACE(Mesh)) {
209 return mesh->GetRenderSortLayerOrder(index);
210 }
211 return 0u;
212 }
213
214 /**
215 * @brief Update mesh data from the arrays. 16 bit indices.
216 * @param arrays defining the mesh, see MeshGeometryArray.
217 */
UpdateMeshFromArraysI16(MeshGeometryArrayPtr<uint16_t> arrays)218 void UpdateMeshFromArraysI16(MeshGeometryArrayPtr<uint16_t> arrays)
219 {
220 if (auto mesh = META_API_CACHED_INTERFACE(Mesh)) {
221 mesh->UpdateMeshFromArraysI16(arrays);
222 }
223 }
224
225 /**
226 * @brief Update mesh data from the arrays. 32 bit indices.
227 * @param arrays defining the mesh, see MeshGeometryArray.
228 */
UpdateMeshFromArraysI32(MeshGeometryArrayPtr<uint32_t> arrays)229 void UpdateMeshFromArraysI32(MeshGeometryArrayPtr<uint32_t> arrays)
230 {
231 if (auto mesh = META_API_CACHED_INTERFACE(Mesh)) {
232 mesh->UpdateMeshFromArraysI32(arrays);
233 }
234 }
235
236 /**
237 * @brief Add submesh data from the arrays. 16 bit indices.
238 * @param arrays defining the mesh, see MeshGeometryArray.
239 */
AddSubmeshesFromArrayI16(MeshGeometryArrayPtr<uint16_t> arrays)240 void AddSubmeshesFromArrayI16(MeshGeometryArrayPtr<uint16_t> arrays)
241 {
242 if (auto mesh = META_API_CACHED_INTERFACE(Mesh)) {
243 mesh->AddSubmeshesFromArrayI16(arrays);
244 }
245 }
246
247 /**
248 * @brief Add submesh data from the arrays. 32 bit indices.
249 * @param arrays defining the mesh, see MeshGeometryArray.
250 */
AddSubmeshesFromArraysI32(MeshGeometryArrayPtr<uint32_t> arrays)251 void AddSubmeshesFromArraysI32(MeshGeometryArrayPtr<uint32_t> arrays)
252 {
253 if (auto mesh = META_API_CACHED_INTERFACE(Mesh)) {
254 mesh->AddSubmeshesFromArraysI32(arrays);
255 }
256 }
257
258 /**
259 * @brief Copy the contents of the submesh into this mesh instance.
260 */
CloneSubmesh(ISubMesh::Ptr submesh)261 void CloneSubmesh(ISubMesh::Ptr submesh)
262 {
263 if (auto mesh = META_API_CACHED_INTERFACE(Mesh)) {
264 mesh->CloneSubmesh(submesh);
265 }
266 }
267
268 /**
269 * @brief Remove the submesh from this mesh instance.
270 */
RemoveSubMesh(size_t index)271 void RemoveSubMesh(size_t index)
272 {
273 if (auto mesh = META_API_CACHED_INTERFACE(Mesh)) {
274 mesh->RemoveSubMesh(index);
275 }
276 }
277
278 /**
279 * @brief Remove all the submeshes from this mesh instance.
280 */
RemoveAllSubmeshes()281 void RemoveAllSubmeshes()
282 {
283 if (auto mesh = META_API_CACHED_INTERFACE(Mesh)) {
284 mesh->RemoveAllSubmeshes();
285 }
286 }
287 };
288
289 class MultiMeshProxy final : public META_NS::Internal::ObjectInterfaceAPI<MultiMeshProxy, ClassId::MultiMeshProxy> {
290 META_API(MultiMeshProxy)
META_API_OBJECT_CONVERTIBLE(IMultiMeshProxy)291 META_API_OBJECT_CONVERTIBLE(IMultiMeshProxy)
292 META_API_CACHE_INTERFACE(IMultiMeshProxy, MultiMeshProxy)
293 public:
294 META_API_INTERFACE_PROPERTY_CACHED(MultiMeshProxy, MaterialOverride, SCENE_NS::IMaterial::Ptr)
295 META_API_INTERFACE_PROPERTY_CACHED(MultiMeshProxy, Mesh, SCENE_NS::IMesh::Ptr)
296 META_API_INTERFACE_PROPERTY_CACHED(MultiMeshProxy, VisibleInstanceCount, size_t)
297 META_API_INTERFACE_ARRAY_PROPERTY_CACHED(MultiMeshProxy, CustomData, BASE_NS::Math::Vec4)
298 META_API_INTERFACE_ARRAY_PROPERTY_CACHED(MultiMeshProxy, Transforms, BASE_NS::Math::Mat4X4)
299
300 /**
301 * @brief Set the capacity of the proxy and reset properties to the whole batch
302 */
303 void SetInstanceCount(size_t count)
304 {
305 if (auto mmesh = META_API_CACHED_INTERFACE(MultiMeshProxy)) {
306 mmesh->SetInstanceCount(count);
307 }
308 }
309 };
310
311 SCENE_END_NAMESPACE()
312
313 #endif // SCENEPLUGINAPI_MESH_H
314