Scene.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. //
  2. // Copyright (c) 2008-2017 the Urho3D project.
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to deal
  6. // in the Software without restriction, including without limitation the rights
  7. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. // copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. // THE SOFTWARE.
  21. //
  22. #pragma once
  23. #include "../Container/HashSet.h"
  24. #include "../Core/Mutex.h"
  25. #include "../Resource/XMLElement.h"
  26. #include "../Resource/JSONFile.h"
  27. #include "../Scene/Node.h"
  28. #include "../Scene/SceneResolver.h"
  29. namespace Atomic
  30. {
  31. class File;
  32. class PackageFile;
  33. // ATOMIC BEGIN
  34. class Texture2D;
  35. // ATOMIC END
  36. static const unsigned FIRST_REPLICATED_ID = 0x1;
  37. static const unsigned LAST_REPLICATED_ID = 0xffffff;
  38. static const unsigned FIRST_LOCAL_ID = 0x01000000;
  39. static const unsigned LAST_LOCAL_ID = 0xffffffff;
  40. /// Asynchronous scene loading mode.
  41. enum LoadMode
  42. {
  43. /// Preload resources used by a scene or object prefab file, but do not load any scene content.
  44. LOAD_RESOURCES_ONLY = 0,
  45. /// Load scene content without preloading. Resources will be requested synchronously when encountered.
  46. LOAD_SCENE,
  47. /// Default mode: preload resources used by the scene first, then load the scene content.
  48. LOAD_SCENE_AND_RESOURCES
  49. };
  50. /// Asynchronous loading progress of a scene.
  51. struct AsyncProgress
  52. {
  53. /// File for binary mode.
  54. SharedPtr<File> file_;
  55. /// XML file for XML mode.
  56. SharedPtr<XMLFile> xmlFile_;
  57. /// JSON file for JSON mode
  58. SharedPtr<JSONFile> jsonFile_;
  59. /// Current XML element for XML mode.
  60. XMLElement xmlElement_;
  61. /// Current JSON child array and for JSON mode
  62. unsigned jsonIndex_;
  63. /// Current load mode.
  64. LoadMode mode_;
  65. /// Resource name hashes left to load.
  66. HashSet<StringHash> resources_;
  67. /// Loaded resources.
  68. unsigned loadedResources_;
  69. /// Total resources.
  70. unsigned totalResources_;
  71. /// Loaded root-level nodes.
  72. unsigned loadedNodes_;
  73. /// Total root-level nodes.
  74. unsigned totalNodes_;
  75. };
  76. /// Root scene node, represents the whole scene.
  77. class ATOMIC_API Scene : public Node
  78. {
  79. ATOMIC_OBJECT(Scene, Node);
  80. using Node::GetComponent;
  81. using Node::SaveXML;
  82. using Node::SaveJSON;
  83. public:
  84. /// Construct.
  85. Scene(Context* context);
  86. /// Destruct.
  87. virtual ~Scene();
  88. /// Register object factory. Node must be registered first.
  89. static void RegisterObject(Context* context);
  90. /// Load from binary data. Removes all existing child nodes and components first. Return true if successful.
  91. virtual bool Load(Deserializer& source, bool setInstanceDefault = false);
  92. /// Save to binary data. Return true if successful.
  93. virtual bool Save(Serializer& dest) const;
  94. /// Load from XML data. Removes all existing child nodes and components first. Return true if successful.
  95. virtual bool LoadXML(const XMLElement& source, bool setInstanceDefault = false);
  96. /// Load from JSON data. Removes all existing child nodes and components first. Return true if successful.
  97. virtual bool LoadJSON(const JSONValue& source, bool setInstanceDefault = false);
  98. /// Mark for attribute check on the next network update.
  99. virtual void MarkNetworkUpdate();
  100. /// Add a replication state that is tracking this scene.
  101. virtual void AddReplicationState(NodeReplicationState* state);
  102. /// Load from an XML file. Return true if successful.
  103. bool LoadXML(Deserializer& source);
  104. /// Load from a JSON file. Return true if successful.
  105. bool LoadJSON(Deserializer& source);
  106. /// Save to an XML file. Return true if successful.
  107. bool SaveXML(Serializer& dest, const String& indentation = "\t") const;
  108. /// Save to a JSON file. Return true if successful.
  109. bool SaveJSON(Serializer& dest, const String& indentation = "\t") const;
  110. /// 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.
  111. bool LoadAsync(File* file, LoadMode mode = LOAD_SCENE_AND_RESOURCES);
  112. /// 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.
  113. bool LoadAsyncXML(File* file, LoadMode mode = LOAD_SCENE_AND_RESOURCES);
  114. /// 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.
  115. bool LoadAsyncJSON(File* file, LoadMode mode = LOAD_SCENE_AND_RESOURCES);
  116. /// Stop asynchronous loading.
  117. void StopAsyncLoading();
  118. /// Instantiate scene content from binary data. Return root node if successful.
  119. Node* Instantiate(Deserializer& source, const Vector3& position, const Quaternion& rotation, CreateMode mode = REPLICATED);
  120. /// Instantiate scene content from XML data. Return root node if successful.
  121. Node* InstantiateXML
  122. (const XMLElement& source, const Vector3& position, const Quaternion& rotation, CreateMode mode = REPLICATED);
  123. /// Instantiate scene content from XML data. Return root node if successful.
  124. Node* InstantiateXML(Deserializer& source, const Vector3& position, const Quaternion& rotation, CreateMode mode = REPLICATED);
  125. /// Instantiate scene content from JSON data. Return root node if successful.
  126. Node* InstantiateJSON
  127. (const JSONValue& source, const Vector3& position, const Quaternion& rotation, CreateMode mode = REPLICATED);
  128. /// Instantiate scene content from JSON data. Return root node if successful.
  129. Node* InstantiateJSON(Deserializer& source, const Vector3& position, const Quaternion& rotation, CreateMode mode = REPLICATED);
  130. /// Clear scene completely of either replicated, local or all nodes and components.
  131. void Clear(bool clearReplicated = true, bool clearLocal = true);
  132. /// Enable or disable scene update.
  133. void SetUpdateEnabled(bool enable);
  134. /// Set update time scale. 1.0 = real time (default.)
  135. void SetTimeScale(float scale);
  136. /// Set elapsed time in seconds. This can be used to prevent inaccuracy in the timer if the scene runs for a long time.
  137. void SetElapsedTime(float time);
  138. /// Set network client motion smoothing constant.
  139. void SetSmoothingConstant(float constant);
  140. /// Set network client motion smoothing snap threshold.
  141. void SetSnapThreshold(float threshold);
  142. /// Set maximum milliseconds per frame to spend on async scene loading.
  143. void SetAsyncLoadingMs(int ms);
  144. /// Add a required package file for networking. To be called on the server.
  145. void AddRequiredPackageFile(PackageFile* package);
  146. /// Clear required package files.
  147. void ClearRequiredPackageFiles();
  148. /// Register a node user variable hash reverse mapping (for editing.)
  149. void RegisterVar(const String& name);
  150. /// Unregister a node user variable hash reverse mapping.
  151. void UnregisterVar(const String& name);
  152. /// Clear all registered node user variable hash reverse mappings.
  153. void UnregisterAllVars();
  154. /// Return node from the whole scene by ID, or null if not found.
  155. Node* GetNode(unsigned id) const;
  156. /// Return component from the whole scene by ID, or null if not found.
  157. Component* GetComponent(unsigned id) const;
  158. /// Get nodes with specific tag from the whole scene, return false if empty.
  159. bool GetNodesWithTag(PODVector<Node*>& dest, const String& tag) const;
  160. /// Return whether updates are enabled.
  161. bool IsUpdateEnabled() const { return updateEnabled_; }
  162. /// Return whether an asynchronous loading operation is in progress.
  163. bool IsAsyncLoading() const { return asyncLoading_; }
  164. /// Return asynchronous loading progress between 0.0 and 1.0, or 1.0 if not in progress.
  165. float GetAsyncProgress() const;
  166. /// Return the load mode of the current asynchronous loading operation.
  167. LoadMode GetAsyncLoadMode() const { return asyncProgress_.mode_; }
  168. /// Return source file name.
  169. const String& GetFileName() const { return fileName_; }
  170. /// Return source file checksum.
  171. unsigned GetChecksum() const { return checksum_; }
  172. /// Return update time scale.
  173. float GetTimeScale() const { return timeScale_; }
  174. /// Return elapsed time in seconds.
  175. float GetElapsedTime() const { return elapsedTime_; }
  176. /// Return motion smoothing constant.
  177. float GetSmoothingConstant() const { return smoothingConstant_; }
  178. /// Return motion smoothing snap threshold.
  179. float GetSnapThreshold() const { return snapThreshold_; }
  180. /// Return maximum milliseconds per frame to spend on async loading.
  181. int GetAsyncLoadingMs() const { return asyncLoadingMs_; }
  182. /// Return required package files.
  183. const Vector<SharedPtr<PackageFile> >& GetRequiredPackageFiles() const { return requiredPackageFiles_; }
  184. /// Return a node user variable name, or empty if not registered.
  185. const String& GetVarName(StringHash hash) const;
  186. /// Update scene. Called by HandleUpdate.
  187. void Update(float timeStep);
  188. /// Begin a threaded update. During threaded update components can choose to delay dirty processing.
  189. void BeginThreadedUpdate();
  190. /// End a threaded update. Notify components that marked themselves for delayed dirty processing.
  191. void EndThreadedUpdate();
  192. /// Add a component to the delayed dirty notify queue. Is thread-safe.
  193. void DelayedMarkedDirty(Component* component);
  194. /// Return threaded update flag.
  195. bool IsThreadedUpdate() const { return threadedUpdate_; }
  196. /// Get free node ID, either non-local or local.
  197. unsigned GetFreeNodeID(CreateMode mode);
  198. /// Get free component ID, either non-local or local.
  199. unsigned GetFreeComponentID(CreateMode mode);
  200. /// Cache node by tag if tag not zero, no checking if already added. Used internaly in Node::AddTag.
  201. void NodeTagAdded(Node* node, const String& tag);
  202. /// Cache node by tag if tag not zero.
  203. void NodeTagRemoved(Node* node, const String& tag);
  204. /// Node added. Assign scene pointer and add to ID map.
  205. void NodeAdded(Node* node);
  206. /// Node removed. Remove from ID map.
  207. void NodeRemoved(Node* node);
  208. /// Component added. Add to ID map.
  209. void ComponentAdded(Component* component);
  210. /// Component removed. Remove from ID map.
  211. void ComponentRemoved(Component* component);
  212. /// Set node user variable reverse mappings.
  213. void SetVarNamesAttr(const String& value);
  214. /// Return node user variable reverse mappings.
  215. String GetVarNamesAttr() const;
  216. /// Prepare network update by comparing attributes and marking replication states dirty as necessary.
  217. void PrepareNetworkUpdate();
  218. /// Clean up all references to a network connection that is about to be removed.
  219. void CleanupConnection(Connection* connection);
  220. /// Mark a node for attribute check on the next network update.
  221. void MarkNetworkUpdate(Node* node);
  222. /// Mark a component for attribute check on the next network update.
  223. void MarkNetworkUpdate(Component* component);
  224. /// Mark a node dirty in scene replication states. The node does not need to have own replication state yet.
  225. void MarkReplicationDirty(Node* node);
  226. // ATOMIC BEGIN
  227. void LoadLightmaps(bool reload = false);
  228. void SetLightmapTexture(unsigned id);
  229. // ATOMIC END
  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. // ATOMIC BEGIN
  250. Vector<SharedPtr<Texture2D>> lightmaps_;
  251. // ATOMIC END
  252. /// Replicated scene nodes by ID.
  253. HashMap<unsigned, Node*> replicatedNodes_;
  254. /// Local scene nodes by ID.
  255. HashMap<unsigned, Node*> localNodes_;
  256. /// Replicated components by ID.
  257. HashMap<unsigned, Component*> replicatedComponents_;
  258. /// Local components by ID.
  259. HashMap<unsigned, Component*> localComponents_;
  260. /// Cached tagged nodes by tag.
  261. HashMap<StringHash, PODVector<Node*> > taggedNodes_;
  262. /// Asynchronous loading progress.
  263. AsyncProgress asyncProgress_;
  264. /// Node and component ID resolver for asynchronous loading.
  265. SceneResolver resolver_;
  266. /// Source file name.
  267. mutable String fileName_;
  268. /// Required package files for networking.
  269. Vector<SharedPtr<PackageFile> > requiredPackageFiles_;
  270. /// Registered node user variable reverse mappings.
  271. HashMap<StringHash, String> varNames_;
  272. /// Nodes to check for attribute changes on the next network update.
  273. HashSet<unsigned> networkUpdateNodes_;
  274. /// Components to check for attribute changes on the next network update.
  275. HashSet<unsigned> networkUpdateComponents_;
  276. /// Delayed dirty notification queue for components.
  277. PODVector<Component*> delayedDirtyComponents_;
  278. /// Mutex for the delayed dirty notification queue.
  279. Mutex sceneMutex_;
  280. /// Preallocated event data map for smoothing update events.
  281. VariantMap smoothingData_;
  282. /// Next free non-local node ID.
  283. unsigned replicatedNodeID_;
  284. /// Next free non-local component ID.
  285. unsigned replicatedComponentID_;
  286. /// Next free local node ID.
  287. unsigned localNodeID_;
  288. /// Next free local component ID.
  289. unsigned localComponentID_;
  290. /// Scene source file checksum.
  291. mutable unsigned checksum_;
  292. /// Maximum milliseconds per frame to spend on async scene loading.
  293. int asyncLoadingMs_;
  294. /// Scene update time scale.
  295. float timeScale_;
  296. /// Elapsed time accumulator.
  297. float elapsedTime_;
  298. /// Motion smoothing constant.
  299. float smoothingConstant_;
  300. /// Motion smoothing snap threshold.
  301. float snapThreshold_;
  302. /// Update enabled flag.
  303. bool updateEnabled_;
  304. /// Asynchronous loading flag.
  305. bool asyncLoading_;
  306. /// Threaded update flag.
  307. bool threadedUpdate_;
  308. };
  309. /// Register Scene library objects.
  310. void ATOMIC_API RegisterSceneLibrary(Context* context);
  311. }