Scene.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. // Copyright (c) 2008-2023 the Urho3D project
  2. // License: MIT
  3. /// \file
  4. #pragma once
  5. #include "../Container/HashSet.h"
  6. #include "../Core/Mutex.h"
  7. #include "../Resource/XMLElement.h"
  8. #include "../Resource/JSONFile.h"
  9. #include "../Scene/Node.h"
  10. #include "../Scene/SceneResolver.h"
  11. namespace Urho3D
  12. {
  13. class File;
  14. class PackageFile;
  15. inline constexpr id32 FIRST_REPLICATED_ID = 0x1;
  16. inline constexpr id32 LAST_REPLICATED_ID = 0xffffff;
  17. inline constexpr id32 FIRST_LOCAL_ID = 0x01000000;
  18. inline constexpr id32 LAST_LOCAL_ID = 0xffffffff;
  19. /// Asynchronous scene loading mode.
  20. enum LoadMode
  21. {
  22. /// Preload resources used by a scene or object prefab file, but do not load any scene content.
  23. LOAD_RESOURCES_ONLY = 0,
  24. /// Load scene content without preloading. Resources will be requested synchronously when encountered.
  25. LOAD_SCENE,
  26. /// Default mode: preload resources used by the scene first, then load the scene content.
  27. LOAD_SCENE_AND_RESOURCES
  28. };
  29. /// Asynchronous loading progress of a scene.
  30. struct AsyncProgress
  31. {
  32. /// File for binary mode.
  33. SharedPtr<File> file_;
  34. /// XML file for XML mode.
  35. SharedPtr<XMLFile> xmlFile_;
  36. /// JSON file for JSON mode.
  37. SharedPtr<JSONFile> jsonFile_;
  38. /// Current XML element for XML mode.
  39. XMLElement xmlElement_;
  40. /// Current JSON child array and for JSON mode.
  41. i32 jsonIndex_;
  42. /// Current load mode.
  43. LoadMode mode_;
  44. /// Resource name hashes left to load.
  45. HashSet<StringHash> resources_;
  46. /// Loaded resources.
  47. i32 loadedResources_;
  48. /// Total resources.
  49. i32 totalResources_;
  50. /// Loaded root-level nodes.
  51. i32 loadedNodes_;
  52. /// Total root-level nodes.
  53. i32 totalNodes_;
  54. };
  55. /// Root scene node, represents the whole scene.
  56. class URHO3D_API Scene : public Node
  57. {
  58. URHO3D_OBJECT(Scene, Node);
  59. public:
  60. /// @manualbind
  61. using Node::GetComponent;
  62. /// @manualbind
  63. using Node::SaveXML;
  64. /// @manualbind
  65. using Node::SaveJSON;
  66. /// Construct.
  67. explicit Scene(Context* context);
  68. /// Destruct.
  69. ~Scene() override;
  70. /// Register object factory. Node must be registered first.
  71. /// @nobind
  72. static void RegisterObject(Context* context);
  73. /// Load from binary data. Removes all existing child nodes and components first. Return true if successful.
  74. bool Load(Deserializer& source) override;
  75. /// Save to binary data. Return true if successful.
  76. bool Save(Serializer& dest) const override;
  77. /// Load from XML data. Removes all existing child nodes and components first. Return true if successful.
  78. bool LoadXML(const XMLElement& source) override;
  79. /// Load from JSON data. Removes all existing child nodes and components first. Return true if successful.
  80. bool LoadJSON(const JSONValue& source) override;
  81. /// Mark for attribute check on the next network update.
  82. void MarkNetworkUpdate() override;
  83. /// Add a replication state that is tracking this scene.
  84. void AddReplicationState(NodeReplicationState* state) override;
  85. /// Load from an XML file. Return true if successful.
  86. bool LoadXML(Deserializer& source);
  87. /// Load from a JSON file. Return true if successful.
  88. bool LoadJSON(Deserializer& source);
  89. /// Save to an XML file. Return true if successful.
  90. bool SaveXML(Serializer& dest, const String& indentation = "\t") const;
  91. /// Save to a JSON file. Return true if successful.
  92. bool SaveJSON(Serializer& dest, const String& indentation = "\t") const;
  93. /// Load from a binary file asynchronously. Return true if started successfully. The LOAD_RESOURCES_ONLY mode can also be used to preload resources from object prefab files.
  94. bool LoadAsync(File* file, LoadMode mode = LOAD_SCENE_AND_RESOURCES);
  95. /// Load from an XML file asynchronously. Return true if started successfully. The LOAD_RESOURCES_ONLY mode can also be used to preload resources from object prefab files.
  96. bool LoadAsyncXML(File* file, LoadMode mode = LOAD_SCENE_AND_RESOURCES);
  97. /// Load from a JSON file asynchronously. Return true if started successfully. The LOAD_RESOURCES_ONLY mode can also be used to preload resources from object prefab files.
  98. bool LoadAsyncJSON(File* file, LoadMode mode = LOAD_SCENE_AND_RESOURCES);
  99. /// Stop asynchronous loading.
  100. void StopAsyncLoading();
  101. /// Instantiate scene content from binary data. Return root node if successful.
  102. Node* Instantiate(Deserializer& source, const Vector3& position, const Quaternion& rotation, CreateMode mode = REPLICATED);
  103. /// Instantiate scene content from XML data. Return root node if successful.
  104. Node* InstantiateXML
  105. (const XMLElement& source, const Vector3& position, const Quaternion& rotation, CreateMode mode = REPLICATED);
  106. /// Instantiate scene content from XML data. Return root node if successful.
  107. Node* InstantiateXML(Deserializer& source, const Vector3& position, const Quaternion& rotation, CreateMode mode = REPLICATED);
  108. /// Instantiate scene content from JSON data. Return root node if successful.
  109. Node* InstantiateJSON
  110. (const JSONValue& source, const Vector3& position, const Quaternion& rotation, CreateMode mode = REPLICATED);
  111. /// Instantiate scene content from JSON data. Return root node if successful.
  112. Node* InstantiateJSON(Deserializer& source, const Vector3& position, const Quaternion& rotation, CreateMode mode = REPLICATED);
  113. /// Clear scene completely of either replicated, local or all nodes and components.
  114. void Clear(bool clearReplicated = true, bool clearLocal = true);
  115. /// Enable or disable scene update.
  116. /// @property
  117. void SetUpdateEnabled(bool enable);
  118. /// Set update time scale. 1.0 = real time (default).
  119. /// @property
  120. void SetTimeScale(float scale);
  121. /// Set elapsed time in seconds. This can be used to prevent inaccuracy in the timer if the scene runs for a long time.
  122. /// @property
  123. void SetElapsedTime(float time);
  124. /// Set network client motion smoothing constant.
  125. /// @property
  126. void SetSmoothingConstant(float constant);
  127. /// Set network client motion smoothing snap threshold.
  128. /// @property
  129. void SetSnapThreshold(float threshold);
  130. /// Set maximum milliseconds per frame to spend on async scene loading.
  131. /// @property
  132. void SetAsyncLoadingMs(int ms);
  133. /// Add a required package file for networking. To be called on the server.
  134. void AddRequiredPackageFile(PackageFile* package);
  135. /// Clear required package files.
  136. void ClearRequiredPackageFiles();
  137. /// Register a node user variable hash reverse mapping (for editing).
  138. void RegisterVar(const String& name);
  139. /// Unregister a node user variable hash reverse mapping.
  140. void UnregisterVar(const String& name);
  141. /// Clear all registered node user variable hash reverse mappings.
  142. void UnregisterAllVars();
  143. /// Return node from the whole scene by ID, or null if not found.
  144. Node* GetNode(NodeId id) const;
  145. /// Return component from the whole scene by ID, or null if not found.
  146. Component* GetComponent(ComponentId id) const;
  147. /// Get nodes with specific tag from the whole scene, return false if empty.
  148. bool GetNodesWithTag(Vector<Node*>& dest, const String& tag) const;
  149. /// Return whether updates are enabled.
  150. /// @property
  151. bool IsUpdateEnabled() const { return updateEnabled_; }
  152. /// Return whether an asynchronous loading operation is in progress.
  153. /// @property
  154. bool IsAsyncLoading() const { return asyncLoading_; }
  155. /// Return asynchronous loading progress between 0.0 and 1.0, or 1.0 if not in progress.
  156. /// @property
  157. float GetAsyncProgress() const;
  158. /// Return the load mode of the current asynchronous loading operation.
  159. /// @property
  160. LoadMode GetAsyncLoadMode() const { return asyncProgress_.mode_; }
  161. /// Return source file name.
  162. /// @property
  163. const String& GetFileName() const { return fileName_; }
  164. /// Return source file checksum.
  165. /// @property
  166. hash32 GetChecksum() const { return checksum_; }
  167. /// Return update time scale.
  168. /// @property
  169. float GetTimeScale() const { return timeScale_; }
  170. /// Return elapsed time in seconds.
  171. /// @property
  172. float GetElapsedTime() const { return elapsedTime_; }
  173. /// Return motion smoothing constant.
  174. /// @property
  175. float GetSmoothingConstant() const { return smoothingConstant_; }
  176. /// Return motion smoothing snap threshold.
  177. /// @property
  178. float GetSnapThreshold() const { return snapThreshold_; }
  179. /// Return maximum milliseconds per frame to spend on async loading.
  180. /// @property
  181. int GetAsyncLoadingMs() const { return asyncLoadingMs_; }
  182. /// Return required package files.
  183. /// @property
  184. const Vector<SharedPtr<PackageFile>>& GetRequiredPackageFiles() const { return requiredPackageFiles_; }
  185. /// Return a node user variable name, or empty if not registered.
  186. const String& GetVarName(StringHash hash) const;
  187. /// Update scene. Called by HandleUpdate.
  188. void Update(float timeStep);
  189. /// Begin a threaded update. During threaded update components can choose to delay dirty processing.
  190. void BeginThreadedUpdate();
  191. /// End a threaded update. Notify components that marked themselves for delayed dirty processing.
  192. void EndThreadedUpdate();
  193. /// Add a component to the delayed dirty notify queue. Is thread-safe.
  194. void DelayedMarkedDirty(Component* component);
  195. /// Return threaded update flag.
  196. bool IsThreadedUpdate() const { return threadedUpdate_; }
  197. /// Get free node ID, either non-local or local.
  198. NodeId GetFreeNodeID(CreateMode mode);
  199. /// Get free component ID, either non-local or local.
  200. ComponentId GetFreeComponentID(CreateMode mode);
  201. /// Return whether the specified id is a replicated id.
  202. static bool IsReplicatedID(id32 id) { return id < FIRST_LOCAL_ID; }
  203. /// Cache node by tag if tag not zero, no checking if already added. Used internaly in Node::AddTag.
  204. void NodeTagAdded(Node* node, const String& tag);
  205. /// Cache node by tag if tag not zero.
  206. void NodeTagRemoved(Node* node, const String& tag);
  207. /// Node added. Assign scene pointer and add to ID map.
  208. void NodeAdded(Node* node);
  209. /// Node removed. Remove from ID map.
  210. void NodeRemoved(Node* node);
  211. /// Component added. Add to ID map.
  212. void ComponentAdded(Component* component);
  213. /// Component removed. Remove from ID map.
  214. void ComponentRemoved(Component* component);
  215. /// Set node user variable reverse mappings.
  216. void SetVarNamesAttr(const String& value);
  217. /// Return node user variable reverse mappings.
  218. String GetVarNamesAttr() const;
  219. /// Prepare network update by comparing attributes and marking replication states dirty as necessary.
  220. void PrepareNetworkUpdate();
  221. /// Clean up all references to a network connection that is about to be removed.
  222. /// @manualbind
  223. void CleanupConnection(Connection* connection);
  224. /// Mark a node for attribute check on the next network update.
  225. void MarkNetworkUpdate(Node* node);
  226. /// Mark a component for attribute check on the next network update.
  227. void MarkNetworkUpdate(Component* component);
  228. /// Mark a node dirty in scene replication states. The node does not need to have own replication state yet.
  229. void MarkReplicationDirty(Node* node);
  230. private:
  231. /// Handle the logic update event to update the scene, if active.
  232. void HandleUpdate(StringHash eventType, VariantMap& eventData);
  233. /// Handle a background loaded resource completing.
  234. void HandleResourceBackgroundLoaded(StringHash eventType, VariantMap& eventData);
  235. /// Update asynchronous loading.
  236. void UpdateAsyncLoading();
  237. /// Finish asynchronous loading.
  238. void FinishAsyncLoading();
  239. /// Finish loading. Sets the scene filename and checksum.
  240. void FinishLoading(Deserializer* source);
  241. /// Finish saving. Sets the scene filename and checksum.
  242. void FinishSaving(Serializer* dest) const;
  243. /// Preload resources from a binary scene or object prefab file.
  244. void PreloadResources(File* file, bool isSceneFile);
  245. /// Preload resources from an XML scene or object prefab file.
  246. void PreloadResourcesXML(const XMLElement& element);
  247. /// Preload resources from a JSON scene or object prefab file.
  248. void PreloadResourcesJSON(const JSONValue& value);
  249. /// Replicated scene nodes by ID.
  250. HashMap<NodeId, Node*> replicatedNodes_;
  251. /// Local scene nodes by ID.
  252. HashMap<NodeId, Node*> localNodes_;
  253. /// Replicated components by ID.
  254. HashMap<ComponentId, Component*> replicatedComponents_;
  255. /// Local components by ID.
  256. HashMap<ComponentId, Component*> localComponents_;
  257. /// Cached tagged nodes by tag.
  258. HashMap<StringHash, Vector<Node*>> taggedNodes_;
  259. /// Asynchronous loading progress.
  260. AsyncProgress asyncProgress_;
  261. /// Node and component ID resolver for asynchronous loading.
  262. SceneResolver resolver_;
  263. /// Source file name.
  264. mutable String fileName_;
  265. /// Required package files for networking.
  266. Vector<SharedPtr<PackageFile>> requiredPackageFiles_;
  267. /// Registered node user variable reverse mappings.
  268. HashMap<StringHash, String> varNames_;
  269. /// Nodes to check for attribute changes on the next network update.
  270. HashSet<NodeId> networkUpdateNodes_;
  271. /// Components to check for attribute changes on the next network update.
  272. HashSet<ComponentId> networkUpdateComponents_;
  273. /// Delayed dirty notification queue for components.
  274. Vector<Component*> delayedDirtyComponents_;
  275. /// Mutex for the delayed dirty notification queue.
  276. Mutex sceneMutex_;
  277. /// Preallocated event data map for smoothing update events.
  278. VariantMap smoothingData_;
  279. /// Next free non-local node ID.
  280. NodeId replicatedNodeID_;
  281. /// Next free non-local component ID.
  282. ComponentId replicatedComponentID_;
  283. /// Next free local node ID.
  284. NodeId localNodeID_;
  285. /// Next free local component ID.
  286. ComponentId localComponentID_;
  287. /// Scene source file checksum.
  288. mutable hash32 checksum_;
  289. /// Maximum milliseconds per frame to spend on async scene loading.
  290. int asyncLoadingMs_;
  291. /// Scene update time scale.
  292. float timeScale_;
  293. /// Elapsed time accumulator.
  294. float elapsedTime_;
  295. /// Motion smoothing constant.
  296. float smoothingConstant_;
  297. /// Motion smoothing snap threshold.
  298. float snapThreshold_;
  299. /// Update enabled flag.
  300. bool updateEnabled_;
  301. /// Asynchronous loading flag.
  302. bool asyncLoading_;
  303. /// Threaded update flag.
  304. bool threadedUpdate_;
  305. };
  306. /// Register Scene library objects.
  307. /// @nobind
  308. void URHO3D_API RegisterSceneLibrary(Context* context);
  309. }