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> 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 */ SetRenderSortLayerOrder(uint8_t order)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 */ SetAABBMin(const BASE_NS::Math::Vec3& min)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 */ SetAABBMax(const BASE_NS::Math::Vec3& max)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 */ SetMaterial(SCENE_NS::IMaterial::Ptr material)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) 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 */ Mesh(const INode::Ptr& node)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) const206 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) 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 */ SetInstanceCount(size_t count)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