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 #ifndef SCENEPLUGIN_INTF_SCENE_H 16 #define SCENEPLUGIN_INTF_SCENE_H 17 18 #include <scene_plugin/interface/intf_camera.h> 19 #include <scene_plugin/interface/intf_ecs_animation.h> 20 #include <scene_plugin/interface/intf_ecs_object.h> 21 #include <scene_plugin/interface/intf_material.h> 22 #include <scene_plugin/interface/intf_mesh.h> 23 #include <scene_plugin/interface/intf_node.h> 24 #include <scene_plugin/interface/intf_render_configuration.h> 25 #include <scene_plugin/interface/mesh_arrays.h> 26 27 #include <core/ecs/intf_ecs.h> 28 29 #include <meta/api/animation/animation.h> 30 #include <meta/base/types.h> 31 32 SCENE_BEGIN_NAMESPACE() 33 34 /** 35 * @brief Scene interface, implemented by SCENE_NS::ClassId::Scene 36 */ 37 REGISTER_INTERFACE(IScene, "49df31df-eea6-4d61-a8f1-46aa1f516a18") 38 class IScene : public META_NS::INamed { 39 META_INTERFACE(META_NS::INamed, IScene, InterfaceId::IScene) 40 public: 41 /** 42 * @brief The SCENE_STATE enum 43 */ 44 enum SCENE_STATE { 45 SCENE_STATUS_UNINITIALIZED = 0, 46 SCENE_STATUS_LOADING = 1, 47 SCENE_STATUS_READY = 2, 48 SCENE_STATUS_LOADING_FAILED = 3, 49 }; 50 51 /** 52 * @brief Status of the scene. Reflects to main scene file, not prefabs and such. 53 * @return Pointer to the property. 54 */ 55 META_READONLY_PROPERTY(uint32_t, Status) 56 57 /** 58 * @brief Root node of 3D scene. Populated asynchronously when scene loads. 59 * @return Pointer to the property. 60 */ 61 META_READONLY_PROPERTY(INode::Ptr, RootNode) 62 63 /** 64 * @brief Default camera of the scene. Populated asynchronously when scene loads. 65 * @return Pointer to the property. 66 */ 67 META_PROPERTY(ICamera::Ptr, DefaultCamera) 68 69 /** 70 * @brief Scene Uri, refers to the main scene file. 71 * @return Pointer to the property. 72 */ 73 META_PROPERTY(BASE_NS::string, Uri) 74 75 /** 76 * @brief Render configuration. 77 * @return 78 */ 79 META_PROPERTY(IRenderConfiguration::Ptr, RenderConfiguration) 80 81 /** 82 * @brief Operation mode. If set true, all communication towards scene takes place through task queues. 83 * In practice this means that when ever the new elements are introduced on the scene, yield of some sort 84 * needs to take place in order to scene set up the bindings. Multithreading requires this to be on. 85 * Changing the operation mode is possible only before the main scene is loaded, otherwise the behavior is undefined 86 * @return Pointer to the property. 87 */ 88 META_PROPERTY(bool, Asynchronous) 89 90 /** 91 * @brief Access to all user-created materials in the scene. 92 * @return Pointer to the property. 93 */ 94 META_ARRAY_PROPERTY(IMaterial::Ptr, Materials) 95 96 /** 97 * @brief Event which is invoked once the scene has been successfully loaded. 98 * @return Event that is used to add handlers for the scene loading. 99 */ 100 META_EVENT(META_NS::IOnChanged, OnLoaded) 101 102 103 /** 104 * @brief Create an empty scene. 105 */ 106 virtual void CreateEmpty() = 0; 107 108 /** 109 * @brief Load the scene from a file. It is possible to extend the scene after it has been loaded. 110 * @param file The file defining the scene. 111 * @return Synchronous reply if the loading was started. Use OnLoaded event and Status property for better control. 112 */ 113 virtual bool Load(const BASE_NS::string_view file) = 0; 114 115 /** 116 * @brief Returns a node from the scene with a given path (e.g. something like "view/camera_1"). Uses flat cache, 117 * but creates a new node if the previous instance does not exist. 118 * @param path Path defining the node on 3d scene. 119 * @param classId Optional, if the creation type of the node instance is known, it should be provided. Otherwise the 120 * system tries to guess it. 121 * @return Returns always a node. If the respective 3d element does not exists yet, holds the values but does not 122 * post OnLoaded event. 123 */ 124 virtual INode::Ptr GetNode(const BASE_NS::string_view path, BASE_NS::Uid classId = META_NS::IObject::UID, 125 INode::BuildBehavior buildBehavior = INode::BuildBehavior::NODE_BUILD_CHILDREN_GRADUAL) = 0; 126 127 /** 128 * @brief Add material to scene, this makes scene to take ownership of the material. 129 * @param material Material instance 130 */ 131 virtual void AddMaterial(IMaterial::Ptr) = 0; 132 133 /** 134 * @brief Remove material from scene, after this scene no longer owns the material. 135 * @param material Material instance 136 */ 137 virtual void RemoveMaterial(IMaterial::Ptr) = 0; 138 139 /** 140 * @brief Returns all materials from the scene. 141 * @return Returns a vector of material objects. 142 */ 143 virtual BASE_NS::vector<IMaterial::Ptr> GetMaterials() const = 0; 144 145 /** 146 * @brief Returns a material from the scene with a given name. Materials are typically nodeless elements, and thus 147 * the path is flat. Uses flat cache, but creates a new material if the previous instance does not exist. 148 * @param name Name of the material entity. 149 * @return Returns always an instance. If the respective material does not exists yet, holds the set values but does 150 * not complete OnLoaded. 151 */ 152 virtual IMaterial::Ptr GetMaterial(const BASE_NS::string_view name) = 0; 153 154 /** 155 * @brief Loads a material from uri. 156 * @param uri Uri to the material file. 157 * @return Deserializes material from URI and returns the material instance if successful. 158 */ 159 virtual IMaterial::Ptr LoadMaterial(const BASE_NS::string_view uri) = 0; 160 161 /** 162 * @brief Returns all meshes from the scene. 163 * @return Returns a vector of mesh objects. 164 */ 165 virtual BASE_NS::vector<IMesh::Ptr> GetMeshes() const = 0; 166 167 /** 168 * @brief Returns a mesh from the scene with a given name. Meshes are typically nodeless elements, and thus 169 * the path is flat. Uses flat cache, but creates a new mesh if the previous instance does not exist. 170 * @param name Name of the mesh entity. 171 * @return Returns always an instance. If the respective mesh does not exists yet, holds the set values but does 172 * not complete OnLoaded. 173 */ 174 virtual IMesh::Ptr GetMesh(const BASE_NS::string_view name) = 0; 175 176 /** 177 * @brief Returns a new mesh constructed from the arrays. 16 bit indices. 178 * @param name of the mesh instance to be created. Should be unique. 179 * @param arrays defining the mesh, see MeshGeometryArray. 180 * @return Returns always an instance. if the creation fails, the engine side may not be accessible. 181 */ 182 virtual IMesh::Ptr CreateMeshFromArraysI16( 183 const BASE_NS::string_view name, MeshGeometryArrayPtr<uint16_t> arrays) = 0; 184 185 /** 186 * @brief Returns a new mesh constructed from the arrays. 32 bit indices. 187 * @param name of the mesh instance to be created. Should be unique. 188 * @param arrays defining the mesh, see MeshGeometryArray. 189 * @return Returns always an instance. if the creation fails, the engine side may not be accessible. 190 */ 191 virtual IMesh::Ptr CreateMeshFromArraysI32( 192 const BASE_NS::string_view name, MeshGeometryArrayPtr<uint32_t> arrays) = 0; 193 194 /** 195 * @brief Create an empty node. 196 * @param path Path to which add or find the engine component. 197 * @param createEngineObject The boolean defining whether the 3d element should exist or be created by us. 198 * @param classId The type of the node implementation, should be provided if known. 199 * @return Newly created instance. 200 */ 201 virtual INode::Ptr CreateNode(const BASE_NS::string_view path, bool createEngineObject = true, 202 META_NS::ObjectId classId = META_NS::IObject::UID, 203 INode::BuildBehavior buildBehavior = INode::BuildBehavior::NODE_BUILD_CHILDREN_GRADUAL) = 0; 204 205 /** 206 * @brief Release INode reference from flat cache. It is possible that someone else will hold a reference and the 207 * resource is not freed. 208 * @param name or path of the node. 209 * @return The strong pointer to the resource that was removed from cache. 210 */ 211 virtual INode::Ptr ReleaseNode(const BASE_NS::string_view name) = 0; 212 213 /** 214 * @brief Release INode reference from flat cache. caller will still own the reference. 215 * @param node to be released. 216 */ 217 virtual void ReleaseNode(const INode::Ptr& node) = 0; 218 219 /** 220 * @brief Release IMaterial reference from flat cache. It is possible that someone else will hold a reference and 221 * the resource is not freed. 222 * @param name or path of the material. 223 * @return The strong pointer to the resource that was removed from cache. 224 */ 225 virtual IMaterial::Ptr ReleaseMaterial(const BASE_NS::string_view name) = 0; 226 227 /** 228 * @brief Release IMesh reference from flat cache. It is possible that someone else will hold a reference and 229 * the resource is not freed. 230 * @param name or path of the mesh. 231 * @return The strong pointer to the resource that was removed from cache. 232 */ 233 virtual IMesh::Ptr ReleaseMesh(const BASE_NS::string_view name) = 0; 234 235 /** 236 * @brief Release IAnimation reference from flat cache. It is possible that someone else will hold a reference and 237 * the resource is not freed. 238 * @param name or path of the animation. 239 * @return The strong pointer to the resource that was removed from cache. 240 */ 241 virtual META_NS::IAnimation::Ptr ReleaseAnimation(const BASE_NS::string_view name) = 0; 242 243 /** 244 * @brief Returns all animations from the scene. 245 * @return Returns a vector of animation objects. 246 */ 247 virtual BASE_NS::vector<META_NS::IAnimation::Ptr> GetAnimations() = 0; 248 249 /** 250 * @brief Returns the ecs animation from the scene with the given path. 251 * @param name The name of the animation. 252 * @return The strong pointer to an animation. 253 */ 254 virtual META_NS::IAnimation::Ptr GetAnimation(const BASE_NS::string_view name) = 0; 255 256 /** 257 * @brief Controls the 3d scene System Graph Uri. Changing the value resets the loaded scene completely. 258 * @return Pointer to the property. 259 */ META_PROPERTY(BASE_NS::string,SystemGraphUri)260 META_PROPERTY(BASE_NS::string, SystemGraphUri) 261 262 static constexpr BASE_NS::string_view MATERIALS_PREFIX { "materials" }; 263 static constexpr BASE_NS::string_view MESHES_PREFIX { "meshes" }; 264 static constexpr BASE_NS::string_view ANIMATIONS_PREFIX { "animations" }; 265 266 /** 267 * @brief Update INode cache reference when node is moved to another parent or renamed. 268 * @param node that has changed. 269 */ 270 virtual void UpdateCachedReference(const INode::Ptr& node) = 0; 271 272 virtual void UpdateCachedNodePath(const SCENE_NS::INode::Ptr& node) = 0; 273 virtual void SetCacheEnabled(const SCENE_NS::INode::Ptr& node, bool enabled) = 0; 274 275 /** 276 * @brief Helper for returning a node with a given type. 277 * @param path The path of the 3D element. 278 * @return Returns always an instance. Use INode::Status and INode::OnLoaded to check the status of the node before 279 * reading the 3d values. 280 */ 281 template<class T> GetNode(const BASE_NS::string_view path)282 typename T::Ptr GetNode(const BASE_NS::string_view path) 283 { 284 const auto uid = T::UID; 285 return interface_pointer_cast<T>(GetNode(path, uid)); 286 } 287 288 /** 289 * @brief Create an empty node. 290 * @param path Path to which add or find the engine component. 291 * @param createEngineObject The boolean defining whether the 3d element should exist or be created by us. 292 * @return Newly created instance. 293 */ 294 template<class T> 295 typename T::Ptr CreateNode(const BASE_NS::string_view path, bool createEngineObject = true) 296 { 297 const auto uid = T::UID; 298 return interface_pointer_cast<T>(CreateNode(path, createEngineObject, uid)); 299 } 300 301 /** 302 * @brief Create an empty material instance. 303 * @param name Name of the new material. 304 * @return Newly created instance. 305 */ CreateMaterial(const BASE_NS::string_view name)306 IMaterial::Ptr CreateMaterial(const BASE_NS::string_view name) 307 { 308 return CreateNode<IMaterial>(name); 309 } 310 311 // Internals, to be forked to some other interface 312 313 /** This can be used to access the scene default camera without known handle*/ 314 static constexpr uint64_t DEFAULT_CAMERA { 0 }; 315 316 /** 317 * @brief Get the latest bitmap from the engine. If the bitmap for the camera handle does not exist, it will be 318 * created. 319 * @param notifyFrameDrawn Tell engine that a frame was consumed. 320 * @param cameraHandle Specify if we are interested on some specific camera. 321 * @return Pointer to bitmap 322 */ 323 virtual SCENE_NS::IBitmap::Ptr GetBitmap(bool notifyFrameDrawn, const ICamera::Ptr& camera) = 0; 324 325 /** 326 * @brief Set bitmap for the engine updates. 327 * @param bitmap 328 * @param cameraHandle Specify if we are interested on some specific camera. 329 */ 330 virtual void SetBitmap(const SCENE_NS::IBitmap::Ptr& bitmap, const ICamera::Ptr& camera) = 0; 331 332 /** 333 * @brief Set Render Size for target bitmap in pixels. Subject of redesign to use the property in ICamera instead. 334 * @param width The width of the image. 335 * @param height The height of the image. 336 * @param cameraHandle Specify if we are interested on some specific camera, 0 is system default. 337 */ 338 virtual void SetRenderSize(uint32_t width, uint32_t height, const ICamera::Ptr& camera) = 0; 339 340 /** 341 * Load all material proxies on the current scene. 342 */ 343 virtual void InstantiateMaterialProxies() = 0; 344 345 /** 346 * Load all material proxies on the current scene. 347 */ 348 virtual void InstantiateMeshProxies() = 0; 349 350 /** Calculates a world space AABB from local min max values. */ 351 virtual IPickingResult::Ptr GetWorldAABB( 352 const BASE_NS::Math::Mat4X4& world, const BASE_NS::Math::Vec3& aabbMin, const BASE_NS::Math::Vec3& aabbMax) = 0; 353 354 /** 355 * Get all nodes hit by ray. 356 * @param start Starting point of the ray. 357 * @param direction Direction of the ray. 358 * @return Array of raycast results that describe node that was hit and distance to intersection (ordered by 359 * distance). 360 */ 361 virtual IRayCastResult::Ptr RayCast(const BASE_NS::Math::Vec3& start, const BASE_NS::Math::Vec3& direction) = 0; 362 363 /** 364 * Get nodes hit by ray. Only entities included in the given layer mask are in the result. Entities without 365 * LayerComponent default to LayerConstants::DEFAULT_LAYER_MASK. 366 * @param start Starting point of the ray. 367 * @param direction Direction of the ray. 368 * @param layerMask Layer mask for limiting the returned result. 369 * @return Array of raycast results that describe node that was hit and distance to intersection (ordered by 370 * distance). 371 */ 372 virtual IRayCastResult::Ptr RayCast( 373 const BASE_NS::Math::Vec3& start, const BASE_NS::Math::Vec3& direction, uint64_t layerMask) = 0; 374 375 /** 376 * Activate rendering of camera in scene. 377 * @param camera The camera to be used in rendering 378 */ 379 virtual void ActivateCamera(const ICamera::Ptr& camera) = 0; 380 381 /** 382 * Deactivates rendering of camera in scene. 383 * @param camera The camera to be deactivated. 384 */ 385 virtual void DeactivateCamera(const ICamera::Ptr& camera) = 0; 386 387 virtual bool IsCameraActive(const ICamera::Ptr& camera) = 0; 388 389 /** 390 * @brief Returns all cameras from the scene. 391 * @return Returns a vector of camera objects. 392 */ 393 virtual BASE_NS::vector<ICamera::Ptr> GetCameras() const = 0; 394 395 // returns a list of camera entities that were updated. 396 virtual BASE_NS::vector<CORE_NS::Entity> RenderCameras() = 0; 397 }; 398 399 SCENE_END_NAMESPACE() 400 401 META_TYPE(SCENE_NS::IScene::WeakPtr); 402 META_TYPE(SCENE_NS::IScene::Ptr); 403 404 #endif // SCENEPLUGIN_INTF_SCENE_H 405