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 SCENE_HOLDER_H
17 #define SCENE_HOLDER_H
18 
19 #include <ComponentTools/component_query.h>
20 #include <scene_plugin/interface/intf_asset_manager.h>
21 #include <scene_plugin/interface/intf_bitmap.h>
22 #include <scene_plugin/interface/intf_ecs_scene.h>
23 #include <scene_plugin/interface/intf_entity_collection.h>
24 #include <scene_plugin/interface/intf_nodes.h>
25 #include <scene_plugin/interface/intf_scene.h>
26 
27 #include <3d/ecs/components/animation_component.h>
28 #include <3d/ecs/components/camera_component.h>
29 #include <3d/ecs/components/environment_component.h>
30 #include <3d/ecs/components/layer_component.h>
31 #include <3d/ecs/components/light_component.h>
32 #include <3d/ecs/components/material_component.h>
33 #include <3d/ecs/components/mesh_component.h>
34 #include <3d/ecs/components/name_component.h>
35 #include <3d/ecs/components/node_component.h>
36 #include <3d/ecs/components/render_handle_component.h>
37 #include <3d/ecs/components/render_mesh_component.h>
38 #include <3d/ecs/components/transform_component.h>
39 #include <3d/ecs/components/uri_component.h>
40 #include <3d/ecs/systems/intf_node_system.h>
41 #include <3d/gltf/gltf.h>
42 #include <3d/intf_graphics_context.h>
43 #include <3d/util/intf_picking.h>
44 #include <base/containers/string.h>
45 #include <base/util/uid.h>
46 #include <core/ecs/intf_ecs.h>
47 #include <core/intf_engine.h>
48 #include <render/intf_render_context.h>
49 
50 #include <meta/interface/intf_task_queue.h>
51 
52 #include "ecs_listener.h"
53 
54 class SceneHolder {
55 public:
56     using Ptr = BASE_NS::shared_ptr<SceneHolder>;
57     using WeakPtr = BASE_NS::weak_ptr<SceneHolder>;
58 
59     class ISceneInitialized : public META_NS::ICallable {
60     public:
61         constexpr static BASE_NS::Uid UID { "bd0405c7-bb97-4230-b893-1cd242909dd0" };
62         using Ptr = BASE_NS::shared_ptr<ISceneInitialized>;
63         virtual void Invoke(const BASE_NS::string& rootId, const BASE_NS::string& cameraId) = 0;
64         using FunctionType = void(const BASE_NS::string& rootId, const BASE_NS::string& cameraId);
65 
66     protected:
67         friend Ptr;
68         META_NO_COPY_MOVE_INTERFACE(ISceneInitialized)
69     };
70 
71     class ISceneLoaded : public META_NS::ICallable {
72     public:
73         constexpr static BASE_NS::Uid UID { "004304d0-63bf-4e63-928d-7349a337ec35" };
74         using Ptr = BASE_NS::shared_ptr<ISceneLoaded>;
75         virtual void Invoke(uint32_t loadingStatus) = 0;
76         using FunctionType = void(uint32_t loadingStatus);
77 
78     protected:
79         friend Ptr;
80         META_NO_COPY_MOVE_INTERFACE(ISceneLoaded)
81     };
82 
83     class ISceneUpdated : public META_NS::ICallable {
84     public:
85         constexpr static BASE_NS::Uid UID { "41cb396a-e628-43c3-a0eb-2fc7144674da" };
86         using Ptr = BASE_NS::shared_ptr<ISceneUpdated>;
87         virtual void Invoke(
88             RENDER_NS::RenderHandleReference image, uint64_t handle, uint32_t width, uint32_t height) = 0;
89         using FunctionType = void(
90             RENDER_NS::RenderHandleReference image, uint64_t handle, uint32_t width, uint32_t height);
91 
92     protected:
93         friend Ptr;
94         META_NO_COPY_MOVE_INTERFACE(ISceneUpdated)
95     };
96 
97     class ISceneUninitialized : public META_NS::ICallable {
98     public:
99         constexpr static BASE_NS::Uid UID { "99422a62-1963-4543-a17f-8539e5f58fb1" };
100         using Ptr = BASE_NS::shared_ptr<ISceneUninitialized>;
101         // return false from task to stop, otherwise it will be called again after
102         // the defined delay.
103         virtual void Invoke() = 0;
104         using FunctionType = void();
105 
106     protected:
107         friend Ptr;
108         META_NO_COPY_MOVE_INTERFACE(ISceneUninitialized)
109     };
110 
111     SceneHolder(META_NS::InstanceId uid, META_NS::IObjectRegistry& registry,
112         const BASE_NS::shared_ptr<RENDER_NS::IRenderContext>& gc, META_NS::ITaskQueue::Ptr appQueue,
113         META_NS::ITaskQueue::Ptr engineQueue);
114     virtual ~SceneHolder();
115 
116     void Initialize(WeakPtr self);
117     void Uninitialize();
118 
119     void Load(const BASE_NS::string& uri);
120 
121     void SetRenderSize(uint32_t width, uint32_t height, uint64_t cameraHandle);
122     void SetSystemGraphUri(const BASE_NS::string& uri);
123 
124     void SetCameraTarget(
125         const SCENE_NS::ICamera::Ptr& camera,  BASE_NS::Math::UVec2 size, RENDER_NS::RenderHandleReference ref);
126 
127     void SetInitializeCallback(ISceneInitialized::Ptr callback, WeakPtr self);
128     void SetSceneLoadedCallback(ISceneLoaded::Ptr callback, WeakPtr self);
129     void SetUninitializeCallback(ISceneUninitialized::Ptr callback, WeakPtr self);
130 
131     CORE_NS::IEcs::Ptr GetEcs();
132 
133     void ChangeCamera(SCENE_NS::ICamera::Ptr camera);
134 
135     void SaveScene(const BASE_NS::string& fileName);
136 
137     META_NS::ITaskQueue::Token QueueEngineTask(
138         const META_NS::ITaskQueue::CallableType::Ptr& task, bool runDeferred = true)
139     {
140         if (!isAsync_ && !runDeferred) {
141             if (task->Invoke()) {
142                 // task requested async retry, give it
143                 return engineTaskQueue_->AddTask(task);
144             }
145             return META_NS::ITaskQueue::Token {};
146         } else {
147             return engineTaskQueue_->AddTask(task);
148         }
149     }
150     META_NS::ITaskQueue::Token QueueApplicationTask(
151         const META_NS::ITaskQueue::CallableType::Ptr& task, bool runDeferred = true)
152     {
153         if (!isAsync_ && !runDeferred) {
154             if (task->Invoke()) {
155                 return appTaskQueue_->AddTask(task);
156             }
157             return META_NS::ITaskQueue::Token {};
158         } else {
159             return appTaskQueue_->AddTask(task);
160         }
161     }
162 
SetOperationMode(bool async)163     void SetOperationMode(bool async)
164     {
165         isAsync_ = async;
166     }
167 
IsAsync()168     bool IsAsync() const
169     {
170         return isAsync_;
171     }
172 
CancelEngineTask(META_NS::ITaskQueue::Token token)173     void CancelEngineTask(META_NS::ITaskQueue::Token token)
174     {
175         engineTaskQueue_->CancelTask(token);
176     }
177 
CancelAppTask(META_NS::ITaskQueue::Token token)178     void CancelAppTask(META_NS::ITaskQueue::Token token)
179     {
180         appTaskQueue_->CancelTask(token);
181     }
182 
GetEntityCollection()183     SCENE_NS::IEntityCollection* GetEntityCollection()
184     {
185         return scene_.get();
186     }
187 
GetAssetManager()188     SCENE_NS::IAssetManager* GetAssetManager()
189     {
190         return assetManager_.get();
191     }
192 
193     // Set Uri to load scene
194     void LoadScene(const BASE_NS::string& uri);
195 
196     // Actual loading code, can take place through several paths
197     void LoadScene();
198 
199     // Run component queries for materials and meshes
200     void IntrospectNodeless();
201 
202     // Find animation entity based on name
203     bool FindAnimation(const BASE_NS::string_view name, const BASE_NS::string_view fullPath, CORE_NS::Entity& entity);
204 
205     // Find material entity based on name
206     bool FindMaterial(const BASE_NS::string_view name, const BASE_NS::string_view fullPath, CORE_NS::Entity& entity);
207 
208     // Find mesh entity based on name
209     bool FindMesh(const BASE_NS::string_view name, const BASE_NS::string_view fullPath, CORE_NS::Entity& entity);
210 
211     // Find resource entity based on name using the scene-entity collection
212     bool FindResource(const BASE_NS::string_view name, const BASE_NS::string_view fullPath, CORE_NS::Entity& entity);
213 
214     BASE_NS::shared_ptr<BASE_NS::vector<BASE_NS::string_view>> ListMaterialNames();
215     BASE_NS::shared_ptr<BASE_NS::vector<BASE_NS::string_view>> ListMeshNames();
216 
217     // Find resource identifier based on entity
218     BASE_NS::string GetResourceId(CORE_NS::Entity entity);
219 
220     // Set given mesh to target entity
221     void SetMesh(CORE_NS::Entity targetEntity, CORE_NS::Entity mesh);
222 
223     // Read the name component of the mesh in the given entity
224     BASE_NS::string_view GetMeshName(CORE_NS::Entity referringEntity);
225 
226     // Get Mesh entity from submesh
227     CORE_NS::Entity GetMaterial(CORE_NS::Entity meshEntity, int64_t submeshIndex);
228 
229     // Resolve material name from submesh
230     BASE_NS::string_view GetMaterialName(CORE_NS::Entity meshEntity, int64_t submeshIndex);
231 
232     // Assign material to the given entity
233     void SetMaterial(CORE_NS::Entity targetEntity, CORE_NS::Entity material, int64_t submeshIndex = -1);
234 
235     // Prepares a bitmap for 3D use
236     CORE_NS::EntityReference BindUIBitmap(SCENE_NS::IBitmap::Ptr bitmap, bool createNew);
237 
238     // Set submesh render sort order
239     void SetSubmeshRenderSortOrder(CORE_NS::Entity meshEntity, int64_t submeshIndex, uint8_t value);
240 
241     // Set submesh aabb min
242     void SetSubmeshAABBMin(CORE_NS::Entity targetEntity, int64_t submeshIndex, const BASE_NS::Math::Vec3& vec);
243 
244     // Set submesh aabb max
245     void SetSubmeshAABBMax(CORE_NS::Entity targetEntity, int64_t submeshIndex, const BASE_NS::Math::Vec3& vec);
246 
247     // Remove submesh(es)
248     void RemoveSubmesh(CORE_NS::Entity targetEntity, int64_t submeshIndex);
249 
250     // Set texture to a given index on texture array
251     void SetTexture(size_t index, CORE_NS::Entity targetEntity, CORE_NS::EntityReference imageEntity);
252 
253     enum UriHandleType {
254         HANDLE_TYPE_DO_NOT_CARE = 0,
255         HANDLE_TYPE_SHADER,
256     };
257 
258     // Get handle for a shader
259     BASE_NS::string GetHandleUri(
260         RENDER_NS::RenderHandleReference renderHandleReference, UriHandleType type = HANDLE_TYPE_DO_NOT_CARE);
261 
262     // Set and get shader and graphics state to/from the given material
263     enum ShaderType : uint8_t { MATERIAL_SHADER, DEPTH_SHADER };
264     void SetShader(CORE_NS::Entity materialEntity, ShaderType type, SCENE_NS::IShader::Ptr shader);
265     void SetGraphicsState(CORE_NS::Entity materialEntity, ShaderType type, SCENE_NS::IGraphicsState::Ptr state);
266     SCENE_NS::IShader::Ptr GetShader(CORE_NS::Entity materialEntity, ShaderType type);
267     SCENE_NS::IGraphicsState::Ptr GetGraphicsState(CORE_NS::Entity materialEntity, ShaderType type);
268 
269     // for state raw access
270     void SetGraphicsState(CORE_NS::Entity materialEntity, ShaderType type, const RENDER_NS::GraphicsState& state);
271     bool GetGraphicsState(
272         CORE_NS::Entity materialEntity, ShaderType type, const SCENE_NS::IShaderGraphicsState::Ptr& ret);
273 
274     // Get handle for a sampler
275     CORE_NS::Entity LoadSampler(BASE_NS::string_view uri);
276 
277     // Get handle for a image
278     CORE_NS::EntityReference LoadImage(BASE_NS::string_view uri, RENDER_NS::RenderHandleReference rh = {});
279 
280     // Set (and create if needed) sampler to a given index on texture array
281     void SetSampler(size_t index, CORE_NS::Entity targetEntity, SCENE_NS::ITextureInfo::SamplerId samplerId);
282 
283     // Enable evironment component on the entity.
284     void EnableEnvironmentComponent(CORE_NS::Entity entity);
285 
286     // Enable layer component on the entity. This is called for every node that scene creates or binds
287     void EnableLayerComponent(CORE_NS::Entity entity);
288 
289     // Enable light component on the entity.
290     void EnableLightComponent(CORE_NS::Entity entity);
291 
292     // Enable canvas component on the entity.
293     // Create new node
294     CORE3D_NS::ISceneNode* CreateNode(const BASE_NS::string& name);
295     CORE3D_NS::ISceneNode* CreateNode(const BASE_NS::string& path, const BASE_NS::string& name);
296 
297     // Create new material entity
298     CORE_NS::Entity CreateMaterial(const BASE_NS::string& name);
299 
300     // Create new node with a camera component, by default no flag bits are set.
301     CORE_NS::Entity CreateCamera(const BASE_NS::string& name, uint32_t flagBits);
302     CORE_NS::Entity CreateCamera(const BASE_NS::string& path, const BASE_NS::string& name, uint32_t flagBits);
303 
304     CORE_NS::Entity CreatePostProcess();
305     CORE_NS::Entity CreateRenderConfiguration();
306 
307     // Rename the entity name component
308     void RenameEntity(CORE_NS::Entity entity, const BASE_NS::string& name);
309 
310     // Clone the entity, reference will be stored
311     CORE_NS::Entity CloneEntity(CORE_NS::Entity entity, const BASE_NS::string& name, bool storeWithUniqueId);
312 
313     // Destroy entity
314     void DestroyEntity(CORE_NS::Entity entity);
315 
316     void SetEntityActive(CORE_NS::Entity entity, bool active);
317 
318     // Find and re-parent node. Does not find nodeless entities
319     const CORE3D_NS::ISceneNode* ReparentEntity(const BASE_NS::string& parentPath, const BASE_NS::string& name);
320 
321     bool ReparentEntity(CORE_NS::Entity entity, const BASE_NS::string& parentPath, size_t index);
322 
323     // Create mesh from raw data
324     template<typename IndicesType>
325     CORE_NS::Entity CreateMeshFromArrays(const BASE_NS::string& name,
326         SCENE_NS::MeshGeometryArrayPtr<IndicesType> arrays, RENDER_NS::IndexType indexType,
327         CORE_NS::Entity existingEntity = {}, bool append = false);
328 
329     void SetMultiviewCamera(CORE_NS::Entity target, CORE_NS::Entity source);
330     void RemoveMultiviewCamera(CORE_NS::Entity target, CORE_NS::Entity source);
331 
332     // Copy submesh from another mesh entity
333     void CopySubMesh(CORE_NS::Entity target, CORE_NS::Entity source, size_t index);
334 
335     // Create new multi-mesh batch
336     CORE_NS::Entity CreateMultiMeshInstance(CORE_NS::Entity baseComponent);
337 
338     // Set mesh to multi-mesh
339     void SetMeshMultimeshArray(CORE_NS::Entity target, CORE_NS::Entity mesh);
340 
341     // Set override material to multi-mesh
342     BASE_NS::vector<CORE_NS::Entity> SetOverrideMaterialMultimeshArray(
343         CORE_NS::Entity target, CORE_NS::Entity material);
344     void ResetOverrideMaterialMultimeshArray(CORE_NS::Entity target, BASE_NS::vector<CORE_NS::Entity>& in);
345     // Set instance count to multi-mesh
346     void SetInstanceCountMultimeshArray(CORE_NS::Entity target, size_t count);
347 
348     // Set visible count to multi-mesh
349     void SetVisibleCountMultimeshArray(CORE_NS::Entity target, size_t count);
350 
351     // Set custom data to multi-mesh index
352     void SetCustomData(CORE_NS::Entity target, size_t index, const BASE_NS::Math::Vec4& data);
353 
354     // Set transformation to multi-mesh index
355     void SetTransformation(CORE_NS::Entity target, size_t index, const BASE_NS::Math::Mat4X4& transform);
356 
357     // Reposition a node within its parent
358     void ReindexEntity(CORE_NS::Entity target, size_t index);
359 
360     bool GetImageEntity(CORE_NS::Entity material, size_t index, CORE_NS::Entity& entity);
361     bool SetEntityUri(const CORE_NS::Entity& entity, const BASE_NS::string& nameString);
362     bool GetEntityUri(const CORE_NS::Entity& entity, BASE_NS::string& nameString);
363     bool GetEntityName(const CORE_NS::Entity& entity, BASE_NS::string& nameString);
364     bool GetImageHandle(
365         const CORE_NS::Entity& entity, RENDER_NS::RenderHandleReference& handle, RENDER_NS::GpuImageDesc& desc);
366     bool GetRenderHandleUri(const RENDER_NS::RenderHandle& handle, BASE_NS::string& uriString);
367     void SetRenderHandle(const CORE_NS::Entity& target, const CORE_NS::Entity& source);
368 
369     CORE_NS::Entity GetEntityByUri(BASE_NS::string_view uriString);
370 
371     // Get common ECS listener to avoid overhead of all properties using their own
GetCommonEcsListener()372     BASE_NS::shared_ptr<SCENE_NS::EcsListener> GetCommonEcsListener()
373     {
374         return ecsListener_;
375     }
376 
377     // Set a callback that fires when the ecs has been created, but not yet initialized.
378     // Needs to be handled synchronously. Return value from callback is ignored currently.
SetEcsInitializationCallback(SCENE_NS::IEcsScene::IPrepareSceneForInitialization::WeakPtr ecsInitializationCallback)379     void SetEcsInitializationCallback(
380         SCENE_NS::IEcsScene::IPrepareSceneForInitialization::WeakPtr ecsInitializationCallback)
381     {
382         ecsInitializationCallback_ = ecsInitializationCallback;
383     }
384 
385     void ReleaseOwnership(CORE_NS::Entity entity);
386 
387     struct CameraData {
388         using Ptr = BASE_NS::shared_ptr<CameraData>;
CreateCameraData389         static Ptr Create(const CORE_NS::Entity& entity)
390         {
391             return Ptr { new CameraData(entity) };
392         }
CameraDataCameraData393         explicit CameraData(const CORE_NS::Entity& cameraEntity) : entity(cameraEntity) {}
394         CORE_NS::Entity entity;
395         bool ownsColorImage = true;
396         RENDER_NS::RenderHandleReference colorImage;
397         RENDER_NS::RenderHandleReference depthImage;
398         uint32_t width = 128;
399         uint32_t height = 128;
400         bool resized = true;
401         bool updateTargets = true;
402     };
403 
404     void UpdateAttachments(SCENE_NS::IEcsObject::Ptr& ecsObject);
405     void ResolveAnimations();
406 
407     // Not particulally happy with this
GetObjectRegistry()408     META_NS::IObjectRegistry& GetObjectRegistry()
409     {
410         return objectRegistry_;
411     }
412 
GetFileManager()413     CORE_NS::IFileManager* GetFileManager()
414     {
415         if (graphicsContext3D_) {
416             auto& engine = graphicsContext3D_->GetRenderContext().GetEngine();
417             return &engine.GetFileManager();
418         }
419         return nullptr;
420     }
421 
GetAnimation(const CORE_NS::Entity & entity)422     SCENE_NS::IEcsAnimation::Ptr GetAnimation(const CORE_NS::Entity& entity)
423     {
424         if (auto animation = animations_.find(entity.id); animation != animations_.cend()) {
425             return animation->second;
426         }
427         return SCENE_NS::IEcsAnimation::Ptr {};
428     }
429 
GetAnimation(const BASE_NS::string & name)430     SCENE_NS::IEcsAnimation::Ptr GetAnimation(const BASE_NS::string& name)
431     {
432         for (auto& animation : animations_) {
433             if (auto named = interface_pointer_cast<META_NS::INamed>(animation.second)) {
434                 if (META_NS::GetValue(named->Name()) == name) {
435                     return animation.second;
436                 }
437             }
438         }
439         return SCENE_NS::IEcsAnimation::Ptr {};
440     }
441 
GetAnimations()442     BASE_NS::vector<SCENE_NS::IEcsAnimation::Ptr> GetAnimations() const
443     {
444         BASE_NS::vector<SCENE_NS::IEcsAnimation::Ptr> res;
445         for (auto& animation : animations_) {
446             res.push_back(animation.second);
447         }
448         return res;
449     }
450 
SetRenderMode(uint8_t renderMode)451     void SetRenderMode(uint8_t renderMode)
452     {
453         if (renderMode != renderMode_) {
454             renderMode_ = (CORE_NS::IEcs::RenderMode)renderMode;
455             if (ecs_) {
456                 ecs_->SetRenderMode(renderMode_);
457             }
458         }
459     }
460 
461     bool GetWorldMatrixComponentAABB(SCENE_NS::IPickingResult::Ptr, CORE_NS::Entity entity, bool isRecursive);
462     bool GetTransformComponentAABB(SCENE_NS::IPickingResult::Ptr, CORE_NS::Entity entity, bool isRecursive);
463     bool GetWorldAABB(SCENE_NS::IPickingResult::Ptr, const BASE_NS::Math::Mat4X4& world,
464         const BASE_NS::Math::Vec3& aabbMin, const BASE_NS::Math::Vec3& aabbMax);
465     bool RayCast(SCENE_NS::IRayCastResult::Ptr, const BASE_NS::Math::Vec3& start, const BASE_NS::Math::Vec3& direction);
466     bool RayCast(SCENE_NS::IRayCastResult::Ptr, const BASE_NS::Math::Vec3& start, const BASE_NS::Math::Vec3& direction,
467         uint64_t layerMask);
468     bool ScreenToWorld(SCENE_NS::IPickingResult::Ptr, CORE_NS::Entity camera, BASE_NS::Math::Vec3 screenCoordinate);
469 
470     bool WorldToScreen(SCENE_NS::IPickingResult::Ptr, CORE_NS::Entity camera, BASE_NS::Math::Vec3 worldCoordinate);
471 
472     bool RayCastFromCamera(SCENE_NS::IRayCastResult::Ptr, CORE_NS::Entity camera, const BASE_NS::Math::Vec2& screenPos);
473 
474     bool RayCastFromCamera(SCENE_NS::IRayCastResult::Ptr, CORE_NS::Entity camera, const BASE_NS::Math::Vec2& screenPos,
475         uint64_t layerMask);
476 
477     bool RayFromCamera(SCENE_NS::IPickingResult::Ptr ret, CORE_NS::Entity camera, BASE_NS::Math::Vec2 screenCoordinate);
478 
479     void ProcessEvents();
480 
481     void AddCamera(const CORE_NS::Entity& entity);
482     void RemoveCamera(const CORE_NS::Entity& entity);
483 
484     void SetMainCamera(const CORE_NS::Entity& entity);
485 
486     void ActivateCamera(const CORE_NS::Entity& entity) const;
487     void DeactivateCamera(const CORE_NS::Entity& cameraEntity) const;
488     bool IsCameraActive(const CORE_NS::Entity& cameraEntity) const;
489 
490     BASE_NS::vector<CORE_NS::Entity> RenderCameras();
491 
492 private:
493     void RemoveUriComponentsFromMeshes();
494 
495     bool InitializeScene();
496     bool UninitializeScene();
497 
498     bool CreateDefaultEcs();
499     void SetDefaultCamera();
500 
501     void UpdateViewportSize(uint32_t width, uint32_t height, uint64_t cameraHandle);
502 
503     void RecreateOutputTexture(CameraData::Ptr camera);
504     bool UpdateCameraRenderTarget(CameraData::Ptr camera);
505 
506     void RequestReload();
507     void ResetScene(bool initialize = false);
508 
509     void SetSceneSystemGraph(const BASE_NS::string& uri);
510 
511     BASE_NS::string GetUniqueName();
512 
513     bool IsMultiMeshChild(const CORE3D_NS::ISceneNode* child);
514 
515     CORE_NS::Entity FindCachedRelatedEntity(const CORE_NS::Entity& entity);
516 
517     BASE_NS::vector<CameraData::Ptr> cameras_;
518     CameraData::Ptr mainCamera_ {};
519 
520     // Data for Engine thread.
521     META_NS::ITaskQueue::Token updateTaskToken_ {};
522     META_NS::ITaskQueue::Token redrawTaskToken_ {};
523 
524     BASE_NS::shared_ptr<RENDER_NS::IRenderContext> renderContext_;
525     CORE3D_NS::IGraphicsContext::Ptr graphicsContext3D_;
526     CORE_NS::IEcs::Ptr ecs_;
527 
528     CORE_NS::Entity defaultCameraEntity_;
529 
530     CORE_NS::Entity sceneEntity_;
531 
532     CORE3D_NS::GLTFResourceData gltfResourceData_;
533 
534     CORE3D_NS::ISceneNode* rootNode_ { nullptr };
535 
536     BASE_NS::unordered_map<uint64_t, bool> isReadyForNewFrame_;
537 
538     META_NS::InstanceId instanceId_;
539 
540     ISceneInitialized::Ptr sceneInitializedCallback_;
541     ISceneLoaded::Ptr sceneLoadedCallback_;
542     ISceneUpdated::Ptr sceneUpdatedCallback_;
543     ISceneUninitialized::Ptr sceneUninitializedCallback_;
544     SCENE_NS::IEcsScene::IPrepareSceneForInitialization::WeakPtr ecsInitializationCallback_;
545 
546     META_NS::ITaskQueue::Ptr appTaskQueue_;
547     META_NS::ITaskQueue::Ptr engineTaskQueue_;
548 
549     SCENE_NS::IAssetManager::Ptr assetManager_ {};
550     SCENE_NS::IEntityCollection::Ptr scene_ {};
551     uint64_t instanceNumber_ = 0;
552 
553     BASE_NS::string sceneSystemGraphUri_ { "project://assets/config/system_graph.json" };
554     BASE_NS::string sceneUri_;
555     META_NS::TimeSpan refreshInterval_ { META_NS::TimeSpan::Microseconds(16667) };
556     bool scenePrepared_ { false };
557     WeakPtr me_;
558 
559     BASE_NS::unique_ptr<CORE_NS::ComponentQuery> meshQuery_ {};
560     BASE_NS::unique_ptr<CORE_NS::ComponentQuery> materialQuery_ {};
561     BASE_NS::unique_ptr<CORE_NS::ComponentQuery> animationQuery_ {};
562 
563     CORE3D_NS::IAnimationComponentManager* animationComponentManager_ {};
564     CORE3D_NS::ICameraComponentManager* cameraComponentManager_ {};
565 
566     CORE3D_NS::IEnvironmentComponentManager* envComponentManager_ {};
567     CORE3D_NS::ILayerComponentManager* layerComponentManager_ {};
568     CORE3D_NS::ILightComponentManager* lightComponentManager_ {};
569     CORE3D_NS::IMaterialComponentManager* materialComponentManager_ {};
570     CORE3D_NS::IMeshComponentManager* meshComponentManager_ {};
571     CORE3D_NS::INameComponentManager* nameComponentManager_ {};
572     CORE3D_NS::INodeComponentManager* nodeComponentManager_ {};
573     CORE3D_NS::IRenderMeshComponentManager* renderMeshComponentManager_ {};
574     CORE3D_NS::IRenderHandleComponentManager* rhComponentManager_ {};
575     CORE3D_NS::ITransformComponentManager* transformComponentManager_ {};
576     CORE3D_NS::IUriComponentManager* uriComponentManager_ {};
577 
578     // Not used regularly, perhaps we don't want to maintain the ptrs
579     // CORE3D_NS::IRenderConfigurationComponentManager* rcComponentManager_{};
580 
581     CORE3D_NS::INodeSystem* nodeSystem_ {};
582     BASE_NS::shared_ptr<SCENE_NS::EcsListener> ecsListener_;
583 
584     BASE_NS::unordered_map<uint64_t, SCENE_NS::IEcsAnimation::Ptr> animations_;
585 
586     META_NS::IObjectRegistry& objectRegistry_;
587 
588     bool isAsync_ { false };
589     bool reloadPending_ { false };   // this may occur if switching between sync and async modes on fly
590     bool loadSceneFailed_ { false }; // a corner case where request to reload a scene takes place before initialization
591     CORE_NS::IEcs::RenderMode renderMode_ { CORE_NS::IEcs::RENDER_IF_DIRTY };
592 
593     CORE3D_NS::IPicking* picking_ { nullptr };
594 
595     bool isRunningFrame_ { false };
596     bool requiresEventProcessing_ { false };
597 
598     uint64_t firstTime_ { ~0u };
599     uint64_t previousFrameTime_ { ~0u };
600     uint64_t deltaTime_ { 1 };
601 };
602 
603 static constexpr BASE_NS::string_view MULTI_MESH_CHILD_PREFIX("multi_mesh_child");
604 
605 META_TYPE(SceneHolder::Ptr);
606 META_TYPE(SceneHolder::WeakPtr);
607 
608 #endif
609