Scene.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554
  1. //
  2. // Urho3D Engine
  3. // Copyright (c) 2008-2011 Lasse Öörni
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy
  6. // of this software and associated documentation files (the "Software"), to deal
  7. // in the Software without restriction, including without limitation the rights
  8. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the Software is
  10. // furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in
  13. // all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. // THE SOFTWARE.
  22. //
  23. #include "Precompiled.h"
  24. #include "Component.h"
  25. #include "Context.h"
  26. #include "CoreEvents.h"
  27. #include "File.h"
  28. #include "Log.h"
  29. #include "PackageFile.h"
  30. #include "Profiler.h"
  31. #include "Scene.h"
  32. #include "SceneEvents.h"
  33. #include "XMLFile.h"
  34. static const int ASYNC_LOAD_MIN_FPS = 50;
  35. static const int ASYNC_LOAD_MAX_MSEC = (int)(1000.0f / ASYNC_LOAD_MIN_FPS);
  36. static const float DEFAULT_SMOOTHING_CONSTANT = 50.0f;
  37. static const float DEFAULT_SNAP_THRESHOLD = 1.0f;
  38. OBJECTTYPESTATIC(Scene);
  39. Scene::Scene(Context* context) :
  40. Node(context),
  41. replicatedNodeID_(FIRST_REPLICATED_ID),
  42. replicatedComponentID_(FIRST_REPLICATED_ID),
  43. localNodeID_(FIRST_LOCAL_ID),
  44. localComponentID_(FIRST_LOCAL_ID),
  45. smoothingConstant_(DEFAULT_SMOOTHING_CONSTANT),
  46. snapThreshold_(DEFAULT_SNAP_THRESHOLD),
  47. checksum_(0),
  48. active_(true),
  49. asyncLoading_(false)
  50. {
  51. // Assign an ID to self so that nodes can refer to this node as a parent
  52. SetID(GetFreeNodeID(REPLICATED));
  53. NodeAdded(this);
  54. SubscribeToEvent(E_UPDATE, HANDLER(Scene, HandleUpdate));
  55. }
  56. Scene::~Scene()
  57. {
  58. // Remove scene reference and owner from all nodes that still exist
  59. for (Map<unsigned, Node*>::Iterator i = allNodes_.Begin(); i != allNodes_.End(); ++i)
  60. {
  61. i->second_->SetScene(0);
  62. i->second_->SetOwner(0);
  63. }
  64. }
  65. void Scene::RegisterObject(Context* context)
  66. {
  67. context->RegisterFactory<Scene>();
  68. context->CopyBaseAttributes<Node, Scene>();
  69. ATTRIBUTE(Scene, VAR_INT, "Next Replicated Node ID", replicatedNodeID_, FIRST_REPLICATED_ID, AM_DEFAULT);
  70. ATTRIBUTE(Scene, VAR_INT, "Next Replicated Component ID", replicatedComponentID_, FIRST_REPLICATED_ID, AM_DEFAULT);
  71. ATTRIBUTE(Scene, VAR_INT, "Next Local Node ID", localNodeID_, FIRST_LOCAL_ID, AM_DEFAULT);
  72. ATTRIBUTE(Scene, VAR_INT, "Next Local Component ID", localComponentID_, FIRST_LOCAL_ID, AM_DEFAULT);
  73. ATTRIBUTE(Scene, VAR_FLOAT, "Motion Smoothing Constant", smoothingConstant_, DEFAULT_SMOOTHING_CONSTANT, AM_DEFAULT);
  74. ATTRIBUTE(Scene, VAR_FLOAT, "Motion Snap Threshold", snapThreshold_, DEFAULT_SNAP_THRESHOLD, AM_DEFAULT);
  75. }
  76. bool Scene::Load(Deserializer& source)
  77. {
  78. StopAsyncLoading();
  79. // Check ID
  80. if (source.ReadID() != "USCN")
  81. {
  82. LOGERROR(source.GetName() + " is not a valid scene file");
  83. return false;
  84. }
  85. LOGINFO("Loading scene from " + source.GetName());
  86. // Load the whole scene, then perform post-load if successfully loaded
  87. if (Node::Load(source))
  88. {
  89. FinishLoading(&source);
  90. return true;
  91. }
  92. else
  93. return false;
  94. }
  95. bool Scene::Save(Serializer& dest)
  96. {
  97. // Write ID first
  98. if (!dest.WriteID("USCN"))
  99. {
  100. LOGERROR("Could not save scene, writing to stream failed");
  101. return false;
  102. }
  103. Deserializer* ptr = dynamic_cast<Deserializer*>(&dest);
  104. if (ptr)
  105. LOGINFO("Saving scene to " + ptr->GetName());
  106. return Node::Save(dest);
  107. }
  108. bool Scene::LoadXML(const XMLElement& source)
  109. {
  110. StopAsyncLoading();
  111. // Load the whole scene, then perform post-load if successfully loaded
  112. // Note: the scene filename and checksum can not be set, as we only used an XML element
  113. if (Node::LoadXML(source))
  114. {
  115. FinishLoading(0);
  116. return true;
  117. }
  118. else
  119. return false;
  120. }
  121. bool Scene::LoadXML(Deserializer& source)
  122. {
  123. StopAsyncLoading();
  124. SharedPtr<XMLFile> xml(new XMLFile(context_));
  125. if (!xml->Load(source))
  126. return false;
  127. LOGINFO("Loading scene from " + source.GetName());
  128. // Load the whole scene, then perform post-load if successfully loaded
  129. if (Node::LoadXML(xml->GetRoot()))
  130. {
  131. FinishLoading(&source);
  132. return true;
  133. }
  134. else
  135. return false;
  136. }
  137. bool Scene::SaveXML(Serializer& dest)
  138. {
  139. SharedPtr<XMLFile> xml(new XMLFile(context_));
  140. XMLElement rootElem = xml->CreateRoot("scene");
  141. if (!SaveXML(rootElem))
  142. return false;
  143. Deserializer* ptr = dynamic_cast<Deserializer*>(&dest);
  144. if (ptr)
  145. LOGINFO("Saving scene to " + ptr->GetName());
  146. return xml->Save(dest);
  147. }
  148. bool Scene::LoadAsync(File* file)
  149. {
  150. if (!file)
  151. {
  152. LOGERROR("Null file for async loading");
  153. return false;
  154. }
  155. StopAsyncLoading();
  156. // Check ID
  157. if (file->ReadID() != "USCN")
  158. {
  159. LOGERROR(file->GetName() + " is not a valid scene file");
  160. return false;
  161. }
  162. LOGINFO("Loading scene from " + file->GetName());
  163. // Clear the previous scene and load the root level components first
  164. Clear();
  165. if (!Node::Load(*file, false))
  166. return false;
  167. // Then prepare for loading all root level child nodes in the async update
  168. asyncLoading_ = true;
  169. asyncProgress_.file_ = file;
  170. asyncProgress_.xmlFile_.Reset();
  171. asyncProgress_.xmlElement_ = XMLElement();
  172. asyncProgress_.loadedNodes_ = 0;
  173. asyncProgress_.totalNodes_ = file->ReadVLE();
  174. return true;
  175. }
  176. bool Scene::LoadAsyncXML(File* file)
  177. {
  178. if (!file)
  179. {
  180. LOGERROR("Null file for async loading");
  181. return false;
  182. }
  183. StopAsyncLoading();
  184. SharedPtr<XMLFile> xmlFile(new XMLFile(context_));
  185. if (!xmlFile->Load(*file))
  186. return false;
  187. LOGINFO("Loading scene from " + file->GetName());
  188. // Clear the previous scene and load the root level components first
  189. Clear();
  190. XMLElement rootElement = xmlFile->GetRoot();
  191. if (!Node::LoadXML(rootElement, false))
  192. return false;
  193. // Then prepare for loading all root level child nodes in the async update
  194. XMLElement childNodeElement = rootElement.GetChild("node");
  195. asyncLoading_ = true;
  196. asyncProgress_.file_ = file;
  197. asyncProgress_.xmlFile_ = xmlFile;
  198. asyncProgress_.xmlElement_ = childNodeElement;
  199. asyncProgress_.loadedNodes_ = 0;
  200. asyncProgress_.totalNodes_ = 0;
  201. // Count the amount of child nodes
  202. while (childNodeElement)
  203. {
  204. ++asyncProgress_.totalNodes_;
  205. childNodeElement = childNodeElement.GetNext("node");
  206. }
  207. return true;
  208. }
  209. void Scene::StopAsyncLoading()
  210. {
  211. asyncLoading_ = false;
  212. asyncProgress_.file_.Reset();
  213. asyncProgress_.xmlFile_.Reset();
  214. asyncProgress_.xmlElement_ = XMLElement();
  215. }
  216. void Scene::Clear()
  217. {
  218. StopAsyncLoading();
  219. RemoveAllChildren();
  220. RemoveAllComponents();
  221. fileName_ = String();
  222. checksum_ = 0;
  223. }
  224. void Scene::SetActive(bool enable)
  225. {
  226. active_ = enable;
  227. }
  228. void Scene::SetSmoothingConstant(float constant)
  229. {
  230. smoothingConstant_ = Max(constant, M_EPSILON);
  231. }
  232. void Scene::SetSnapThreshold(float threshold)
  233. {
  234. snapThreshold_ = Max(threshold, 0.0f);
  235. }
  236. void Scene::AddRequiredPackageFile(PackageFile* package)
  237. {
  238. // Do not add packages that failed to load
  239. if (!package || !package->GetNumFiles())
  240. return;
  241. requiredPackageFiles_.Push(SharedPtr<PackageFile>(package));
  242. }
  243. void Scene::ClearRequiredPackageFiles()
  244. {
  245. requiredPackageFiles_.Clear();
  246. }
  247. void Scene::ResetOwner(Connection* owner)
  248. {
  249. for (Map<unsigned, Node*>::Iterator i = allNodes_.Begin(); i != allNodes_.End(); ++i)
  250. {
  251. if (i->second_->GetOwner() == owner)
  252. i->second_->SetOwner(0);
  253. }
  254. }
  255. Node* Scene::GetNodeByID(unsigned id) const
  256. {
  257. Map<unsigned, Node*>::ConstIterator i = allNodes_.Find(id);
  258. if (i != allNodes_.End())
  259. return i->second_;
  260. else
  261. return 0;
  262. }
  263. Component* Scene::GetComponentByID(unsigned id) const
  264. {
  265. Map<unsigned, Component*>::ConstIterator i = allComponents_.Find(id);
  266. if (i != allComponents_.End())
  267. return i->second_;
  268. else
  269. return 0;
  270. }
  271. float Scene::GetAsyncProgress() const
  272. {
  273. if (!asyncLoading_ || !asyncProgress_.totalNodes_)
  274. return 1.0f;
  275. else
  276. return (float)asyncProgress_.loadedNodes_ / (float)asyncProgress_.totalNodes_;
  277. }
  278. void Scene::Update(float timeStep)
  279. {
  280. if (asyncLoading_)
  281. {
  282. UpdateAsyncLoading();
  283. return;
  284. }
  285. PROFILE(UpdateScene);
  286. using namespace SceneUpdate;
  287. VariantMap eventData;
  288. eventData[P_SCENE] = (void*)this;
  289. eventData[P_TIMESTEP] = timeStep;
  290. // Update variable timestep logic
  291. SendEvent(E_SCENEUPDATE, eventData);
  292. // Update scene subsystems. If a physics world is present, it will be updated, triggering fixed timestep logic updates
  293. SendEvent(E_SCENESUBSYSTEMUPDATE, eventData);
  294. // Update smoothing if enabled (network client scenes)
  295. if (IsSmoothed())
  296. {
  297. PROFILE(UpdateSmoothing);
  298. float constant = 1.0f - Clamp(powf(2.0f, -timeStep * smoothingConstant_), 0.0f, 1.0f);
  299. float squaredSnapThreshold = snapThreshold_ * snapThreshold_;
  300. for (Map<unsigned, Node*>::ConstIterator i = allNodes_.Begin(); i != allNodes_.End() && i->first_ < FIRST_LOCAL_ID; ++i)
  301. i->second_->UpdateSmoothing(constant, squaredSnapThreshold);
  302. }
  303. // Post-update variable timestep logic
  304. SendEvent(E_SCENEPOSTUPDATE, eventData);
  305. }
  306. unsigned Scene::GetFreeNodeID(CreateMode mode)
  307. {
  308. if (mode == REPLICATED)
  309. {
  310. for (;;)
  311. {
  312. if (allNodes_.Find(replicatedNodeID_) == allNodes_.End())
  313. return replicatedNodeID_;
  314. if (replicatedNodeID_ != LAST_REPLICATED_ID)
  315. ++replicatedNodeID_;
  316. else
  317. replicatedNodeID_ = FIRST_REPLICATED_ID;
  318. }
  319. }
  320. else
  321. {
  322. for (;;)
  323. {
  324. if (allNodes_.Find(localNodeID_) == allNodes_.End())
  325. return localNodeID_;
  326. if (localNodeID_ != LAST_LOCAL_ID)
  327. ++localNodeID_;
  328. else
  329. localNodeID_ = FIRST_LOCAL_ID;
  330. }
  331. }
  332. }
  333. unsigned Scene::GetFreeComponentID(CreateMode mode)
  334. {
  335. if (mode == REPLICATED)
  336. {
  337. for (;;)
  338. {
  339. if (allComponents_.Find(replicatedComponentID_) == allComponents_.End())
  340. return replicatedComponentID_;
  341. if (replicatedComponentID_ != LAST_REPLICATED_ID)
  342. ++replicatedComponentID_;
  343. else
  344. replicatedComponentID_ = FIRST_REPLICATED_ID;
  345. }
  346. }
  347. else
  348. {
  349. for (;;)
  350. {
  351. if (allComponents_.Find(localComponentID_) == allComponents_.End())
  352. return localComponentID_;
  353. if (localComponentID_ != LAST_LOCAL_ID)
  354. ++localComponentID_;
  355. else
  356. localComponentID_ = FIRST_LOCAL_ID;
  357. }
  358. }
  359. }
  360. void Scene::NodeAdded(Node* node)
  361. {
  362. if (!node || node->GetScene())
  363. return;
  364. node->SetScene(this);
  365. // If we already have an existing node with the same ID, must remove the scene reference from it
  366. unsigned id = node->GetID();
  367. Map<unsigned, Node*>::Iterator i = allNodes_.Find(id);
  368. if (i != allNodes_.End() && i->second_ != node)
  369. {
  370. LOGWARNING("Overwriting node with ID " + String(id));
  371. i->second_->SetScene(0);
  372. i->second_->SetOwner(0);
  373. }
  374. allNodes_[id] = node;
  375. }
  376. void Scene::NodeRemoved(Node* node)
  377. {
  378. if (!node || node->GetScene() != this)
  379. return;
  380. allNodes_.Erase(node->GetID());
  381. node->SetID(0);
  382. node->SetScene(0);
  383. }
  384. void Scene::ComponentAdded(Component* component)
  385. {
  386. if (!component)
  387. return;
  388. allComponents_[component->GetID()] = component;
  389. }
  390. void Scene::ComponentRemoved(Component* component)
  391. {
  392. if (!component)
  393. return;
  394. allComponents_.Erase(component->GetID());
  395. component->SetID(0);
  396. }
  397. void Scene::HandleUpdate(StringHash eventType, VariantMap& eventData)
  398. {
  399. using namespace Update;
  400. if (active_)
  401. Update(eventData[P_TIMESTEP].GetFloat());
  402. }
  403. void Scene::UpdateAsyncLoading()
  404. {
  405. PROFILE(UpdateAsyncLoading);
  406. Timer asyncLoadTimer;
  407. for (;;)
  408. {
  409. if (asyncProgress_.loadedNodes_ >= asyncProgress_.totalNodes_)
  410. {
  411. FinishAsyncLoading();
  412. return;
  413. }
  414. // Read one child node either from binary or XML
  415. if (!asyncProgress_.xmlFile_)
  416. {
  417. Node* newNode = CreateChild(asyncProgress_.file_->ReadUInt(), REPLICATED);
  418. newNode->Load(*asyncProgress_.file_);
  419. }
  420. else
  421. {
  422. Node* newNode = CreateChild(asyncProgress_.xmlElement_.GetInt("id"), REPLICATED);
  423. newNode->LoadXML(asyncProgress_.xmlElement_);
  424. asyncProgress_.xmlElement_ = asyncProgress_.xmlElement_.GetNext("node");
  425. }
  426. ++asyncProgress_.loadedNodes_;
  427. // Break if time limit exceeded, so that we keep sufficient FPS
  428. if (asyncLoadTimer.GetMSec(false) >= ASYNC_LOAD_MAX_MSEC)
  429. break;
  430. }
  431. using namespace AsyncLoadProgress;
  432. VariantMap eventData;
  433. eventData[P_SCENE] = (void*)this;
  434. eventData[P_PROGRESS] = (float)asyncProgress_.loadedNodes_ / (float)asyncProgress_.totalNodes_;
  435. eventData[P_LOADEDNODES] = asyncProgress_.loadedNodes_;
  436. eventData[P_TOTALNODES] = asyncProgress_.totalNodes_;
  437. SendEvent(E_ASYNCLOADPROGRESS, eventData);
  438. }
  439. void Scene::FinishAsyncLoading()
  440. {
  441. FinishLoading(asyncProgress_.file_);
  442. StopAsyncLoading();
  443. using namespace AsyncLoadFinished;
  444. VariantMap eventData;
  445. eventData[P_SCENE] = (void*)this;
  446. SendEvent(E_ASYNCLOADFINISHED, eventData);
  447. }
  448. void Scene::FinishLoading(Deserializer* source)
  449. {
  450. FinishUpdate();
  451. if (source)
  452. {
  453. fileName_ = source->GetName();
  454. checksum_ = source->GetChecksum();
  455. }
  456. }
  457. void RegisterSceneLibrary(Context* context)
  458. {
  459. Node::RegisterObject(context);
  460. Scene::RegisterObject(context);
  461. }