Scene.cpp 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648
  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. #include "../Precompiled.h"
  23. #include "../Core/Context.h"
  24. #include "../Core/CoreEvents.h"
  25. #include "../Core/Profiler.h"
  26. #include "../Core/WorkQueue.h"
  27. #include "../IO/File.h"
  28. #include "../IO/Log.h"
  29. #include "../IO/PackageFile.h"
  30. #include "../Resource/ResourceCache.h"
  31. #include "../Resource/ResourceEvents.h"
  32. #include "../Resource/XMLFile.h"
  33. #include "../Resource/JSONFile.h"
  34. #include "../Scene/Component.h"
  35. #include "../Scene/ObjectAnimation.h"
  36. #include "../Scene/ReplicationState.h"
  37. #include "../Scene/Scene.h"
  38. #include "../Scene/SceneEvents.h"
  39. #include "../Scene/SmoothedTransform.h"
  40. #include "../Scene/SplinePath.h"
  41. #include "../Scene/UnknownComponent.h"
  42. #include "../Scene/ValueAnimation.h"
  43. #include "../DebugNew.h"
  44. // ATOMIC BEGIN
  45. #include "../Graphics/Graphics.h"
  46. #include "../Graphics/Texture2D.h"
  47. #include "../Graphics/StaticModel.h"
  48. #include "../IO/FileSystem.h"
  49. #include "PrefabComponent.h"
  50. // ATOMIC END
  51. namespace Atomic
  52. {
  53. const char* SCENE_CATEGORY = "Scene";
  54. const char* LOGIC_CATEGORY = "Logic";
  55. const char* SUBSYSTEM_CATEGORY = "Subsystem";
  56. static const float DEFAULT_SMOOTHING_CONSTANT = 50.0f;
  57. static const float DEFAULT_SNAP_THRESHOLD = 5.0f;
  58. Scene::Scene(Context* context) :
  59. Node(context),
  60. replicatedNodeID_(FIRST_REPLICATED_ID),
  61. replicatedComponentID_(FIRST_REPLICATED_ID),
  62. localNodeID_(FIRST_LOCAL_ID),
  63. localComponentID_(FIRST_LOCAL_ID),
  64. checksum_(0),
  65. asyncLoadingMs_(5),
  66. timeScale_(1.0f),
  67. elapsedTime_(0),
  68. smoothingConstant_(DEFAULT_SMOOTHING_CONSTANT),
  69. snapThreshold_(DEFAULT_SNAP_THRESHOLD),
  70. updateEnabled_(true),
  71. asyncLoading_(false),
  72. threadedUpdate_(false)
  73. {
  74. // Assign an ID to self so that nodes can refer to this node as a parent
  75. SetID(GetFreeNodeID(REPLICATED));
  76. NodeAdded(this);
  77. SubscribeToEvent(E_UPDATE, ATOMIC_HANDLER(Scene, HandleUpdate));
  78. SubscribeToEvent(E_RESOURCEBACKGROUNDLOADED, ATOMIC_HANDLER(Scene, HandleResourceBackgroundLoaded));
  79. }
  80. Scene::~Scene()
  81. {
  82. // Remove root-level components first, so that scene subsystems such as the octree destroy themselves. This will speed up
  83. // the removal of child nodes' components
  84. RemoveAllComponents();
  85. RemoveAllChildren();
  86. // Remove scene reference and owner from all nodes that still exist
  87. for (HashMap<unsigned, Node*>::Iterator i = replicatedNodes_.Begin(); i != replicatedNodes_.End(); ++i)
  88. i->second_->ResetScene();
  89. for (HashMap<unsigned, Node*>::Iterator i = localNodes_.Begin(); i != localNodes_.End(); ++i)
  90. i->second_->ResetScene();
  91. }
  92. void Scene::RegisterObject(Context* context)
  93. {
  94. context->RegisterFactory<Scene>();
  95. ATOMIC_ACCESSOR_ATTRIBUTE("Name", GetName, SetName, String, String::EMPTY, AM_DEFAULT);
  96. ATOMIC_ACCESSOR_ATTRIBUTE("Time Scale", GetTimeScale, SetTimeScale, float, 1.0f, AM_DEFAULT);
  97. ATOMIC_ACCESSOR_ATTRIBUTE("Smoothing Constant", GetSmoothingConstant, SetSmoothingConstant, float, DEFAULT_SMOOTHING_CONSTANT,
  98. AM_DEFAULT);
  99. ATOMIC_ACCESSOR_ATTRIBUTE("Snap Threshold", GetSnapThreshold, SetSnapThreshold, float, DEFAULT_SNAP_THRESHOLD, AM_DEFAULT);
  100. ATOMIC_ACCESSOR_ATTRIBUTE("Elapsed Time", GetElapsedTime, SetElapsedTime, float, 0.0f, AM_FILE);
  101. ATOMIC_ATTRIBUTE("Next Replicated Node ID", unsigned, replicatedNodeID_, FIRST_REPLICATED_ID, AM_FILE | AM_NOEDIT);
  102. ATOMIC_ATTRIBUTE("Next Replicated Component ID", unsigned, replicatedComponentID_, FIRST_REPLICATED_ID, AM_FILE | AM_NOEDIT);
  103. ATOMIC_ATTRIBUTE("Next Local Node ID", unsigned, localNodeID_, FIRST_LOCAL_ID, AM_FILE | AM_NOEDIT);
  104. ATOMIC_ATTRIBUTE("Next Local Component ID", unsigned, localComponentID_, FIRST_LOCAL_ID, AM_FILE | AM_NOEDIT);
  105. ATOMIC_ATTRIBUTE("Variables", VariantMap, vars_, Variant::emptyVariantMap, AM_FILE); // Network replication of vars uses custom data
  106. ATOMIC_MIXED_ACCESSOR_ATTRIBUTE("Variable Names", GetVarNamesAttr, SetVarNamesAttr, String, String::EMPTY, AM_FILE | AM_NOEDIT);
  107. }
  108. bool Scene::Load(Deserializer& source, bool setInstanceDefault)
  109. {
  110. ATOMIC_PROFILE(LoadScene);
  111. StopAsyncLoading();
  112. // Check ID
  113. if (source.ReadFileID() != "USCN")
  114. {
  115. ATOMIC_LOGERROR(source.GetName() + " is not a valid scene file");
  116. return false;
  117. }
  118. ATOMIC_LOGINFO("Loading scene from " + source.GetName());
  119. Clear();
  120. // Load the whole scene, then perform post-load if successfully loaded
  121. if (Node::Load(source, setInstanceDefault))
  122. {
  123. FinishLoading(&source);
  124. return true;
  125. }
  126. else
  127. return false;
  128. }
  129. bool Scene::Save(Serializer& dest) const
  130. {
  131. ATOMIC_PROFILE(SaveScene);
  132. // Write ID first
  133. if (!dest.WriteFileID("USCN"))
  134. {
  135. ATOMIC_LOGERROR("Could not save scene, writing to stream failed");
  136. return false;
  137. }
  138. Deserializer* ptr = dynamic_cast<Deserializer*>(&dest);
  139. if (ptr)
  140. ATOMIC_LOGINFO("Saving scene to " + ptr->GetName());
  141. if (Node::Save(dest))
  142. {
  143. FinishSaving(&dest);
  144. return true;
  145. }
  146. else
  147. return false;
  148. }
  149. bool Scene::LoadXML(const XMLElement& source, bool setInstanceDefault)
  150. {
  151. ATOMIC_PROFILE(LoadSceneXML);
  152. StopAsyncLoading();
  153. // Load the whole scene, then perform post-load if successfully loaded
  154. // Note: the scene filename and checksum can not be set, as we only used an XML element
  155. if (Node::LoadXML(source, setInstanceDefault))
  156. {
  157. FinishLoading(0);
  158. return true;
  159. }
  160. else
  161. return false;
  162. }
  163. bool Scene::LoadJSON(const JSONValue& source, bool setInstanceDefault)
  164. {
  165. ATOMIC_PROFILE(LoadSceneJSON);
  166. StopAsyncLoading();
  167. // Load the whole scene, then perform post-load if successfully loaded
  168. // Note: the scene filename and checksum can not be set, as we only used an XML element
  169. if (Node::LoadJSON(source, setInstanceDefault))
  170. {
  171. FinishLoading(0);
  172. return true;
  173. }
  174. else
  175. return false;
  176. }
  177. void Scene::MarkNetworkUpdate()
  178. {
  179. if (!networkUpdate_)
  180. {
  181. MarkNetworkUpdate(this);
  182. networkUpdate_ = true;
  183. }
  184. }
  185. void Scene::AddReplicationState(NodeReplicationState* state)
  186. {
  187. Node::AddReplicationState(state);
  188. // This is the first update for a new connection. Mark all replicated nodes dirty
  189. for (HashMap<unsigned, Node*>::ConstIterator i = replicatedNodes_.Begin(); i != replicatedNodes_.End(); ++i)
  190. state->sceneState_->dirtyNodes_.Insert(i->first_);
  191. }
  192. bool Scene::LoadXML(Deserializer& source)
  193. {
  194. ATOMIC_PROFILE(LoadSceneXML);
  195. StopAsyncLoading();
  196. SharedPtr<XMLFile> xml(new XMLFile(context_));
  197. if (!xml->Load(source))
  198. return false;
  199. ATOMIC_LOGINFO("Loading scene from " + source.GetName());
  200. Clear();
  201. if (Node::LoadXML(xml->GetRoot()))
  202. {
  203. FinishLoading(&source);
  204. return true;
  205. }
  206. else
  207. return false;
  208. }
  209. bool Scene::LoadJSON(Deserializer& source)
  210. {
  211. ATOMIC_PROFILE(LoadSceneJSON);
  212. StopAsyncLoading();
  213. SharedPtr<JSONFile> json(new JSONFile(context_));
  214. if (!json->Load(source))
  215. return false;
  216. ATOMIC_LOGINFO("Loading scene from " + source.GetName());
  217. Clear();
  218. if (Node::LoadJSON(json->GetRoot()))
  219. {
  220. FinishLoading(&source);
  221. return true;
  222. }
  223. else
  224. return false;
  225. }
  226. bool Scene::SaveXML(Serializer& dest, const String& indentation) const
  227. {
  228. ATOMIC_PROFILE(SaveSceneXML);
  229. SharedPtr<XMLFile> xml(new XMLFile(context_));
  230. XMLElement rootElem = xml->CreateRoot("scene");
  231. if (!SaveXML(rootElem))
  232. return false;
  233. Deserializer* ptr = dynamic_cast<Deserializer*>(&dest);
  234. if (ptr)
  235. ATOMIC_LOGINFO("Saving scene to " + ptr->GetName());
  236. if (xml->Save(dest, indentation))
  237. {
  238. FinishSaving(&dest);
  239. return true;
  240. }
  241. else
  242. return false;
  243. }
  244. bool Scene::SaveJSON(Serializer& dest, const String& indentation) const
  245. {
  246. ATOMIC_PROFILE(SaveSceneJSON);
  247. SharedPtr<JSONFile> json(new JSONFile(context_));
  248. JSONValue rootVal;
  249. if (!SaveJSON(rootVal))
  250. return false;
  251. Deserializer* ptr = dynamic_cast<Deserializer*>(&dest);
  252. if (ptr)
  253. ATOMIC_LOGINFO("Saving scene to " + ptr->GetName());
  254. json->GetRoot() = rootVal;
  255. if (json->Save(dest, indentation))
  256. {
  257. FinishSaving(&dest);
  258. return true;
  259. }
  260. else
  261. return false;
  262. }
  263. bool Scene::LoadAsync(File* file, LoadMode mode)
  264. {
  265. if (!file)
  266. {
  267. ATOMIC_LOGERROR("Null file for async loading");
  268. return false;
  269. }
  270. StopAsyncLoading();
  271. // Check ID
  272. bool isSceneFile = file->ReadFileID() == "USCN";
  273. if (!isSceneFile)
  274. {
  275. // In resource load mode can load also object prefabs, which have no identifier
  276. if (mode > LOAD_RESOURCES_ONLY)
  277. {
  278. ATOMIC_LOGERROR(file->GetName() + " is not a valid scene file");
  279. return false;
  280. }
  281. else
  282. file->Seek(0);
  283. }
  284. if (mode > LOAD_RESOURCES_ONLY)
  285. {
  286. ATOMIC_LOGINFO("Loading scene from " + file->GetName());
  287. Clear();
  288. }
  289. asyncLoading_ = true;
  290. asyncProgress_.file_ = file;
  291. asyncProgress_.mode_ = mode;
  292. asyncProgress_.loadedNodes_ = asyncProgress_.totalNodes_ = asyncProgress_.loadedResources_ = asyncProgress_.totalResources_ = 0;
  293. asyncProgress_.resources_.Clear();
  294. if (mode > LOAD_RESOURCES_ONLY)
  295. {
  296. // Preload resources if appropriate, then return to the original position for loading the scene content
  297. if (mode != LOAD_SCENE)
  298. {
  299. ATOMIC_PROFILE(FindResourcesToPreload);
  300. unsigned currentPos = file->GetPosition();
  301. PreloadResources(file, isSceneFile);
  302. file->Seek(currentPos);
  303. }
  304. // Store own old ID for resolving possible root node references
  305. unsigned nodeID = file->ReadUInt();
  306. resolver_.AddNode(nodeID, this);
  307. // Load root level components first
  308. if (!Node::Load(*file, resolver_, false))
  309. {
  310. StopAsyncLoading();
  311. return false;
  312. }
  313. // Then prepare to load child nodes in the async updates
  314. asyncProgress_.totalNodes_ = file->ReadVLE();
  315. }
  316. else
  317. {
  318. ATOMIC_PROFILE(FindResourcesToPreload);
  319. ATOMIC_LOGINFO("Preloading resources from " + file->GetName());
  320. PreloadResources(file, isSceneFile);
  321. }
  322. return true;
  323. }
  324. bool Scene::LoadAsyncXML(File* file, LoadMode mode)
  325. {
  326. if (!file)
  327. {
  328. ATOMIC_LOGERROR("Null file for async loading");
  329. return false;
  330. }
  331. StopAsyncLoading();
  332. SharedPtr<XMLFile> xml(new XMLFile(context_));
  333. if (!xml->Load(*file))
  334. return false;
  335. if (mode > LOAD_RESOURCES_ONLY)
  336. {
  337. ATOMIC_LOGINFO("Loading scene from " + file->GetName());
  338. Clear();
  339. }
  340. asyncLoading_ = true;
  341. asyncProgress_.xmlFile_ = xml;
  342. asyncProgress_.file_ = file;
  343. asyncProgress_.mode_ = mode;
  344. asyncProgress_.loadedNodes_ = asyncProgress_.totalNodes_ = asyncProgress_.loadedResources_ = asyncProgress_.totalResources_ = 0;
  345. asyncProgress_.resources_.Clear();
  346. if (mode > LOAD_RESOURCES_ONLY)
  347. {
  348. XMLElement rootElement = xml->GetRoot();
  349. // Preload resources if appropriate
  350. if (mode != LOAD_SCENE)
  351. {
  352. ATOMIC_PROFILE(FindResourcesToPreload);
  353. PreloadResourcesXML(rootElement);
  354. }
  355. // Store own old ID for resolving possible root node references
  356. unsigned nodeID = rootElement.GetUInt("id");
  357. resolver_.AddNode(nodeID, this);
  358. // Load the root level components first
  359. if (!Node::LoadXML(rootElement, resolver_, false))
  360. return false;
  361. // Then prepare for loading all root level child nodes in the async update
  362. XMLElement childNodeElement = rootElement.GetChild("node");
  363. asyncProgress_.xmlElement_ = childNodeElement;
  364. // Count the amount of child nodes
  365. while (childNodeElement)
  366. {
  367. ++asyncProgress_.totalNodes_;
  368. childNodeElement = childNodeElement.GetNext("node");
  369. }
  370. }
  371. else
  372. {
  373. ATOMIC_PROFILE(FindResourcesToPreload);
  374. ATOMIC_LOGINFO("Preloading resources from " + file->GetName());
  375. PreloadResourcesXML(xml->GetRoot());
  376. }
  377. return true;
  378. }
  379. bool Scene::LoadAsyncJSON(File* file, LoadMode mode)
  380. {
  381. if (!file)
  382. {
  383. ATOMIC_LOGERROR("Null file for async loading");
  384. return false;
  385. }
  386. StopAsyncLoading();
  387. SharedPtr<JSONFile> json(new JSONFile(context_));
  388. if (!json->Load(*file))
  389. return false;
  390. if (mode > LOAD_RESOURCES_ONLY)
  391. {
  392. ATOMIC_LOGINFO("Loading scene from " + file->GetName());
  393. Clear();
  394. }
  395. asyncLoading_ = true;
  396. asyncProgress_.jsonFile_ = json;
  397. asyncProgress_.file_ = file;
  398. asyncProgress_.mode_ = mode;
  399. asyncProgress_.loadedNodes_ = asyncProgress_.totalNodes_ = asyncProgress_.loadedResources_ = asyncProgress_.totalResources_ = 0;
  400. asyncProgress_.resources_.Clear();
  401. if (mode > LOAD_RESOURCES_ONLY)
  402. {
  403. JSONValue rootVal = json->GetRoot();
  404. // Preload resources if appropriate
  405. if (mode != LOAD_SCENE)
  406. {
  407. ATOMIC_PROFILE(FindResourcesToPreload);
  408. PreloadResourcesJSON(rootVal);
  409. }
  410. // Store own old ID for resolving possible root node references
  411. unsigned nodeID = rootVal.Get("id").GetUInt();
  412. resolver_.AddNode(nodeID, this);
  413. // Load the root level components first
  414. if (!Node::LoadJSON(rootVal, resolver_, false))
  415. return false;
  416. // Then prepare for loading all root level child nodes in the async update
  417. JSONArray childrenArray = rootVal.Get("children").GetArray();
  418. asyncProgress_.jsonIndex_ = 0;
  419. // Count the amount of child nodes
  420. asyncProgress_.totalNodes_ = childrenArray.Size();
  421. }
  422. else
  423. {
  424. ATOMIC_PROFILE(FindResourcesToPreload);
  425. ATOMIC_LOGINFO("Preloading resources from " + file->GetName());
  426. PreloadResourcesJSON(json->GetRoot());
  427. }
  428. return true;
  429. }
  430. void Scene::StopAsyncLoading()
  431. {
  432. asyncLoading_ = false;
  433. asyncProgress_.file_.Reset();
  434. asyncProgress_.xmlFile_.Reset();
  435. asyncProgress_.jsonFile_.Reset();
  436. asyncProgress_.xmlElement_ = XMLElement::EMPTY;
  437. asyncProgress_.jsonIndex_ = 0;
  438. asyncProgress_.resources_.Clear();
  439. resolver_.Reset();
  440. }
  441. Node* Scene::Instantiate(Deserializer& source, const Vector3& position, const Quaternion& rotation, CreateMode mode)
  442. {
  443. ATOMIC_PROFILE(Instantiate);
  444. SceneResolver resolver;
  445. unsigned nodeID = source.ReadUInt();
  446. // Rewrite IDs when instantiating
  447. Node* node = CreateChild(0, mode);
  448. resolver.AddNode(nodeID, node);
  449. if (node->Load(source, resolver, true, true, mode))
  450. {
  451. resolver.Resolve();
  452. node->SetTransform(position, rotation);
  453. node->ApplyAttributes();
  454. return node;
  455. }
  456. else
  457. {
  458. node->Remove();
  459. return 0;
  460. }
  461. }
  462. Node* Scene::InstantiateXML(const XMLElement& source, const Vector3& position, const Quaternion& rotation, CreateMode mode)
  463. {
  464. ATOMIC_PROFILE(InstantiateXML);
  465. SceneResolver resolver;
  466. unsigned nodeID = source.GetUInt("id");
  467. // Rewrite IDs when instantiating
  468. Node* node = CreateChild(0, mode);
  469. resolver.AddNode(nodeID, node);
  470. if (node->LoadXML(source, resolver, true, true, mode))
  471. {
  472. resolver.Resolve();
  473. node->SetTransform(position, rotation);
  474. node->ApplyAttributes();
  475. return node;
  476. }
  477. else
  478. {
  479. node->Remove();
  480. return 0;
  481. }
  482. }
  483. Node* Scene::InstantiateJSON(const JSONValue& source, const Vector3& position, const Quaternion& rotation, CreateMode mode)
  484. {
  485. ATOMIC_PROFILE(InstantiateJSON);
  486. SceneResolver resolver;
  487. unsigned nodeID = source.Get("id").GetUInt();
  488. // Rewrite IDs when instantiating
  489. Node* node = CreateChild(0, mode);
  490. resolver.AddNode(nodeID, node);
  491. if (node->LoadJSON(source, resolver, true, true, mode))
  492. {
  493. resolver.Resolve();
  494. node->SetTransform(position, rotation);
  495. node->ApplyAttributes();
  496. return node;
  497. }
  498. else
  499. {
  500. node->Remove();
  501. return 0;
  502. }
  503. }
  504. Node* Scene::InstantiateXML(Deserializer& source, const Vector3& position, const Quaternion& rotation, CreateMode mode)
  505. {
  506. SharedPtr<XMLFile> xml(new XMLFile(context_));
  507. if (!xml->Load(source))
  508. return 0;
  509. return InstantiateXML(xml->GetRoot(), position, rotation, mode);
  510. }
  511. Node* Scene::InstantiateJSON(Deserializer& source, const Vector3& position, const Quaternion& rotation, CreateMode mode)
  512. {
  513. SharedPtr<JSONFile> json(new JSONFile(context_));
  514. if (!json->Load(source))
  515. return 0;
  516. return InstantiateJSON(json->GetRoot(), position, rotation, mode);
  517. }
  518. void Scene::Clear(bool clearReplicated, bool clearLocal)
  519. {
  520. StopAsyncLoading();
  521. RemoveChildren(clearReplicated, clearLocal, true);
  522. RemoveComponents(clearReplicated, clearLocal);
  523. // Only clear name etc. if clearing completely
  524. if (clearReplicated && clearLocal)
  525. {
  526. UnregisterAllVars();
  527. SetName(String::EMPTY);
  528. fileName_.Clear();
  529. checksum_ = 0;
  530. }
  531. // Reset ID generators
  532. if (clearReplicated)
  533. {
  534. replicatedNodeID_ = FIRST_REPLICATED_ID;
  535. replicatedComponentID_ = FIRST_REPLICATED_ID;
  536. }
  537. if (clearLocal)
  538. {
  539. localNodeID_ = FIRST_LOCAL_ID;
  540. localComponentID_ = FIRST_LOCAL_ID;
  541. }
  542. }
  543. void Scene::SetUpdateEnabled(bool enable)
  544. {
  545. updateEnabled_ = enable;
  546. }
  547. void Scene::SetTimeScale(float scale)
  548. {
  549. timeScale_ = Max(scale, M_EPSILON);
  550. Node::MarkNetworkUpdate();
  551. }
  552. void Scene::SetSmoothingConstant(float constant)
  553. {
  554. smoothingConstant_ = Max(constant, M_EPSILON);
  555. Node::MarkNetworkUpdate();
  556. }
  557. void Scene::SetSnapThreshold(float threshold)
  558. {
  559. snapThreshold_ = Max(threshold, 0.0f);
  560. Node::MarkNetworkUpdate();
  561. }
  562. void Scene::SetAsyncLoadingMs(int ms)
  563. {
  564. asyncLoadingMs_ = Max(ms, 1);
  565. }
  566. void Scene::SetElapsedTime(float time)
  567. {
  568. elapsedTime_ = time;
  569. }
  570. void Scene::AddRequiredPackageFile(PackageFile* package)
  571. {
  572. // Do not add packages that failed to load
  573. if (!package || !package->GetNumFiles())
  574. return;
  575. requiredPackageFiles_.Push(SharedPtr<PackageFile>(package));
  576. }
  577. void Scene::ClearRequiredPackageFiles()
  578. {
  579. requiredPackageFiles_.Clear();
  580. }
  581. void Scene::RegisterVar(const String& name)
  582. {
  583. varNames_[name] = name;
  584. }
  585. void Scene::UnregisterVar(const String& name)
  586. {
  587. varNames_.Erase(name);
  588. }
  589. void Scene::UnregisterAllVars()
  590. {
  591. varNames_.Clear();
  592. }
  593. Node* Scene::GetNode(unsigned id) const
  594. {
  595. if (id < FIRST_LOCAL_ID)
  596. {
  597. HashMap<unsigned, Node*>::ConstIterator i = replicatedNodes_.Find(id);
  598. return i != replicatedNodes_.End() ? i->second_ : 0;
  599. }
  600. else
  601. {
  602. HashMap<unsigned, Node*>::ConstIterator i = localNodes_.Find(id);
  603. return i != localNodes_.End() ? i->second_ : 0;
  604. }
  605. }
  606. bool Scene::GetNodesWithTag(PODVector<Node*>& dest, const String& tag) const
  607. {
  608. dest.Clear();
  609. HashMap<StringHash, PODVector<Node*> >::ConstIterator it = taggedNodes_.Find(tag);
  610. if (it != taggedNodes_.End())
  611. {
  612. dest = it->second_;
  613. return true;
  614. }
  615. else
  616. return false;
  617. }
  618. Component* Scene::GetComponent(unsigned id) const
  619. {
  620. if (id < FIRST_LOCAL_ID)
  621. {
  622. HashMap<unsigned, Component*>::ConstIterator i = replicatedComponents_.Find(id);
  623. return i != replicatedComponents_.End() ? i->second_ : 0;
  624. }
  625. else
  626. {
  627. HashMap<unsigned, Component*>::ConstIterator i = localComponents_.Find(id);
  628. return i != localComponents_.End() ? i->second_ : 0;
  629. }
  630. }
  631. float Scene::GetAsyncProgress() const
  632. {
  633. return !asyncLoading_ || asyncProgress_.totalNodes_ + asyncProgress_.totalResources_ == 0 ? 1.0f :
  634. (float)(asyncProgress_.loadedNodes_ + asyncProgress_.loadedResources_) /
  635. (float)(asyncProgress_.totalNodes_ + asyncProgress_.totalResources_);
  636. }
  637. const String& Scene::GetVarName(StringHash hash) const
  638. {
  639. HashMap<StringHash, String>::ConstIterator i = varNames_.Find(hash);
  640. return i != varNames_.End() ? i->second_ : String::EMPTY;
  641. }
  642. void Scene::Update(float timeStep)
  643. {
  644. if (asyncLoading_)
  645. {
  646. UpdateAsyncLoading();
  647. // If only preloading resources, scene update can continue
  648. if (asyncProgress_.mode_ > LOAD_RESOURCES_ONLY)
  649. return;
  650. }
  651. ATOMIC_PROFILE(UpdateScene);
  652. timeStep *= timeScale_;
  653. using namespace SceneUpdate;
  654. VariantMap& eventData = GetEventDataMap();
  655. eventData[P_SCENE] = this;
  656. eventData[P_TIMESTEP] = timeStep;
  657. // Update variable timestep logic
  658. SendEvent(E_SCENEUPDATE, eventData);
  659. // Update scene attribute animation.
  660. SendEvent(E_ATTRIBUTEANIMATIONUPDATE, eventData);
  661. // Update scene subsystems. If a physics world is present, it will be updated, triggering fixed timestep logic updates
  662. SendEvent(E_SCENESUBSYSTEMUPDATE, eventData);
  663. // Update transform smoothing
  664. {
  665. ATOMIC_PROFILE(UpdateSmoothing);
  666. float constant = 1.0f - Clamp(powf(2.0f, -timeStep * smoothingConstant_), 0.0f, 1.0f);
  667. float squaredSnapThreshold = snapThreshold_ * snapThreshold_;
  668. using namespace UpdateSmoothing;
  669. smoothingData_[P_CONSTANT] = constant;
  670. smoothingData_[P_SQUAREDSNAPTHRESHOLD] = squaredSnapThreshold;
  671. SendEvent(E_UPDATESMOOTHING, smoothingData_);
  672. }
  673. // Post-update variable timestep logic
  674. SendEvent(E_SCENEPOSTUPDATE, eventData);
  675. // Note: using a float for elapsed time accumulation is inherently inaccurate. The purpose of this value is
  676. // primarily to update material animation effects, as it is available to shaders. It can be reset by calling
  677. // SetElapsedTime()
  678. elapsedTime_ += timeStep;
  679. }
  680. void Scene::BeginThreadedUpdate()
  681. {
  682. // Check the work queue subsystem whether it actually has created worker threads. If not, do not enter threaded mode.
  683. if (GetSubsystem<WorkQueue>()->GetNumThreads())
  684. threadedUpdate_ = true;
  685. }
  686. void Scene::EndThreadedUpdate()
  687. {
  688. if (!threadedUpdate_)
  689. return;
  690. threadedUpdate_ = false;
  691. if (!delayedDirtyComponents_.Empty())
  692. {
  693. ATOMIC_PROFILE(EndThreadedUpdate);
  694. for (PODVector<Component*>::ConstIterator i = delayedDirtyComponents_.Begin(); i != delayedDirtyComponents_.End(); ++i)
  695. (*i)->OnMarkedDirty((*i)->GetNode());
  696. delayedDirtyComponents_.Clear();
  697. }
  698. }
  699. void Scene::DelayedMarkedDirty(Component* component)
  700. {
  701. MutexLock lock(sceneMutex_);
  702. delayedDirtyComponents_.Push(component);
  703. }
  704. unsigned Scene::GetFreeNodeID(CreateMode mode)
  705. {
  706. if (mode == REPLICATED)
  707. {
  708. for (;;)
  709. {
  710. unsigned ret = replicatedNodeID_;
  711. if (replicatedNodeID_ < LAST_REPLICATED_ID)
  712. ++replicatedNodeID_;
  713. else
  714. replicatedNodeID_ = FIRST_REPLICATED_ID;
  715. if (!replicatedNodes_.Contains(ret))
  716. return ret;
  717. }
  718. }
  719. else
  720. {
  721. for (;;)
  722. {
  723. unsigned ret = localNodeID_;
  724. if (localNodeID_ < LAST_LOCAL_ID)
  725. ++localNodeID_;
  726. else
  727. localNodeID_ = FIRST_LOCAL_ID;
  728. if (!localNodes_.Contains(ret))
  729. return ret;
  730. }
  731. }
  732. }
  733. unsigned Scene::GetFreeComponentID(CreateMode mode)
  734. {
  735. if (mode == REPLICATED)
  736. {
  737. for (;;)
  738. {
  739. unsigned ret = replicatedComponentID_;
  740. if (replicatedComponentID_ < LAST_REPLICATED_ID)
  741. ++replicatedComponentID_;
  742. else
  743. replicatedComponentID_ = FIRST_REPLICATED_ID;
  744. if (!replicatedComponents_.Contains(ret))
  745. return ret;
  746. }
  747. }
  748. else
  749. {
  750. for (;;)
  751. {
  752. unsigned ret = localComponentID_;
  753. if (localComponentID_ < LAST_LOCAL_ID)
  754. ++localComponentID_;
  755. else
  756. localComponentID_ = FIRST_LOCAL_ID;
  757. if (!localComponents_.Contains(ret))
  758. return ret;
  759. }
  760. }
  761. }
  762. void Scene::NodeAdded(Node* node)
  763. {
  764. if (!node || node->GetScene() == this)
  765. return;
  766. // Remove from old scene first
  767. Scene* oldScene = node->GetScene();
  768. if (oldScene)
  769. oldScene->NodeRemoved(node);
  770. node->SetScene(this);
  771. // If the new node has an ID of zero (default), assign a replicated ID now
  772. unsigned id = node->GetID();
  773. if (!id)
  774. {
  775. id = GetFreeNodeID(REPLICATED);
  776. node->SetID(id);
  777. }
  778. // If node with same ID exists, remove the scene reference from it and overwrite with the new node
  779. if (id < FIRST_LOCAL_ID)
  780. {
  781. HashMap<unsigned, Node*>::Iterator i = replicatedNodes_.Find(id);
  782. if (i != replicatedNodes_.End() && i->second_ != node)
  783. {
  784. ATOMIC_LOGWARNING("Overwriting node with ID " + String(id));
  785. NodeRemoved(i->second_);
  786. }
  787. replicatedNodes_[id] = node;
  788. MarkNetworkUpdate(node);
  789. MarkReplicationDirty(node);
  790. }
  791. else
  792. {
  793. HashMap<unsigned, Node*>::Iterator i = localNodes_.Find(id);
  794. if (i != localNodes_.End() && i->second_ != node)
  795. {
  796. ATOMIC_LOGWARNING("Overwriting node with ID " + String(id));
  797. NodeRemoved(i->second_);
  798. }
  799. localNodes_[id] = node;
  800. }
  801. // Cache tag if already tagged.
  802. if (!node->GetTags().Empty())
  803. {
  804. const StringVector& tags = node->GetTags();
  805. for (unsigned i = 0; i < tags.Size(); ++i)
  806. taggedNodes_[tags[i]].Push(node);
  807. }
  808. // Add already created components and child nodes now
  809. const Vector<SharedPtr<Component> >& components = node->GetComponents();
  810. for (Vector<SharedPtr<Component> >::ConstIterator i = components.Begin(); i != components.End(); ++i)
  811. ComponentAdded(*i);
  812. const Vector<SharedPtr<Node> >& children = node->GetChildren();
  813. for (Vector<SharedPtr<Node> >::ConstIterator i = children.Begin(); i != children.End(); ++i)
  814. NodeAdded(*i);
  815. }
  816. void Scene::NodeTagAdded(Node* node, const String& tag)
  817. {
  818. taggedNodes_[tag].Push(node);
  819. }
  820. void Scene::NodeTagRemoved(Node* node, const String& tag)
  821. {
  822. taggedNodes_[tag].Remove(node);
  823. }
  824. void Scene::NodeRemoved(Node* node)
  825. {
  826. if (!node || node->GetScene() != this)
  827. return;
  828. unsigned id = node->GetID();
  829. if (id < FIRST_LOCAL_ID)
  830. {
  831. replicatedNodes_.Erase(id);
  832. MarkReplicationDirty(node);
  833. }
  834. else
  835. localNodes_.Erase(id);
  836. node->ResetScene();
  837. // Remove node from tag cache
  838. if (!node->GetTags().Empty())
  839. {
  840. const StringVector& tags = node->GetTags();
  841. for (unsigned i = 0; i < tags.Size(); ++i)
  842. taggedNodes_[tags[i]].Remove(node);
  843. }
  844. // Remove components and child nodes as well
  845. const Vector<SharedPtr<Component> >& components = node->GetComponents();
  846. for (Vector<SharedPtr<Component> >::ConstIterator i = components.Begin(); i != components.End(); ++i)
  847. ComponentRemoved(*i);
  848. const Vector<SharedPtr<Node> >& children = node->GetChildren();
  849. for (Vector<SharedPtr<Node> >::ConstIterator i = children.Begin(); i != children.End(); ++i)
  850. NodeRemoved(*i);
  851. }
  852. void Scene::ComponentAdded(Component* component)
  853. {
  854. if (!component)
  855. return;
  856. unsigned id = component->GetID();
  857. // If the new component has an ID of zero (default), assign a replicated ID now
  858. if (!id)
  859. {
  860. id = GetFreeComponentID(REPLICATED);
  861. component->SetID(id);
  862. }
  863. if (id < FIRST_LOCAL_ID)
  864. {
  865. HashMap<unsigned, Component*>::Iterator i = replicatedComponents_.Find(id);
  866. if (i != replicatedComponents_.End() && i->second_ != component)
  867. {
  868. ATOMIC_LOGWARNING("Overwriting component with ID " + String(id));
  869. ComponentRemoved(i->second_);
  870. }
  871. replicatedComponents_[id] = component;
  872. }
  873. else
  874. {
  875. HashMap<unsigned, Component*>::Iterator i = localComponents_.Find(id);
  876. if (i != localComponents_.End() && i->second_ != component)
  877. {
  878. ATOMIC_LOGWARNING("Overwriting component with ID " + String(id));
  879. ComponentRemoved(i->second_);
  880. }
  881. localComponents_[id] = component;
  882. }
  883. component->OnSceneSet(this);
  884. }
  885. void Scene::ComponentRemoved(Component* component)
  886. {
  887. if (!component)
  888. return;
  889. unsigned id = component->GetID();
  890. if (id < FIRST_LOCAL_ID)
  891. replicatedComponents_.Erase(id);
  892. else
  893. localComponents_.Erase(id);
  894. component->SetID(0);
  895. component->OnSceneSet(0);
  896. }
  897. void Scene::SetVarNamesAttr(const String& value)
  898. {
  899. Vector<String> varNames = value.Split(';');
  900. varNames_.Clear();
  901. for (Vector<String>::ConstIterator i = varNames.Begin(); i != varNames.End(); ++i)
  902. varNames_[*i] = *i;
  903. }
  904. String Scene::GetVarNamesAttr() const
  905. {
  906. String ret;
  907. if (!varNames_.Empty())
  908. {
  909. for (HashMap<StringHash, String>::ConstIterator i = varNames_.Begin(); i != varNames_.End(); ++i)
  910. ret += i->second_ + ";";
  911. ret.Resize(ret.Length() - 1);
  912. }
  913. return ret;
  914. }
  915. void Scene::PrepareNetworkUpdate()
  916. {
  917. for (HashSet<unsigned>::Iterator i = networkUpdateNodes_.Begin(); i != networkUpdateNodes_.End(); ++i)
  918. {
  919. Node* node = GetNode(*i);
  920. if (node)
  921. node->PrepareNetworkUpdate();
  922. }
  923. for (HashSet<unsigned>::Iterator i = networkUpdateComponents_.Begin(); i != networkUpdateComponents_.End(); ++i)
  924. {
  925. Component* component = GetComponent(*i);
  926. if (component)
  927. component->PrepareNetworkUpdate();
  928. }
  929. networkUpdateNodes_.Clear();
  930. networkUpdateComponents_.Clear();
  931. }
  932. void Scene::CleanupConnection(Connection* connection)
  933. {
  934. Node::CleanupConnection(connection);
  935. for (HashMap<unsigned, Node*>::Iterator i = replicatedNodes_.Begin(); i != replicatedNodes_.End(); ++i)
  936. i->second_->CleanupConnection(connection);
  937. for (HashMap<unsigned, Component*>::Iterator i = replicatedComponents_.Begin(); i != replicatedComponents_.End(); ++i)
  938. i->second_->CleanupConnection(connection);
  939. }
  940. void Scene::MarkNetworkUpdate(Node* node)
  941. {
  942. if (node)
  943. {
  944. if (!threadedUpdate_)
  945. networkUpdateNodes_.Insert(node->GetID());
  946. else
  947. {
  948. MutexLock lock(sceneMutex_);
  949. networkUpdateNodes_.Insert(node->GetID());
  950. }
  951. }
  952. }
  953. void Scene::MarkNetworkUpdate(Component* component)
  954. {
  955. if (component)
  956. {
  957. if (!threadedUpdate_)
  958. networkUpdateComponents_.Insert(component->GetID());
  959. else
  960. {
  961. MutexLock lock(sceneMutex_);
  962. networkUpdateComponents_.Insert(component->GetID());
  963. }
  964. }
  965. }
  966. void Scene::MarkReplicationDirty(Node* node)
  967. {
  968. unsigned id = node->GetID();
  969. if (id < FIRST_LOCAL_ID && networkState_)
  970. {
  971. for (PODVector<ReplicationState*>::Iterator i = networkState_->replicationStates_.Begin();
  972. i != networkState_->replicationStates_.End(); ++i)
  973. {
  974. NodeReplicationState* nodeState = static_cast<NodeReplicationState*>(*i);
  975. nodeState->sceneState_->dirtyNodes_.Insert(id);
  976. }
  977. }
  978. }
  979. void Scene::HandleUpdate(StringHash eventType, VariantMap& eventData)
  980. {
  981. if (!updateEnabled_)
  982. return;
  983. using namespace Update;
  984. Update(eventData[P_TIMESTEP].GetFloat());
  985. }
  986. void Scene::HandleResourceBackgroundLoaded(StringHash eventType, VariantMap& eventData)
  987. {
  988. using namespace ResourceBackgroundLoaded;
  989. if (asyncLoading_)
  990. {
  991. Resource* resource = static_cast<Resource*>(eventData[P_RESOURCE].GetPtr());
  992. if (asyncProgress_.resources_.Contains(resource->GetNameHash()))
  993. {
  994. asyncProgress_.resources_.Erase(resource->GetNameHash());
  995. ++asyncProgress_.loadedResources_;
  996. }
  997. }
  998. }
  999. void Scene::UpdateAsyncLoading()
  1000. {
  1001. ATOMIC_PROFILE(UpdateAsyncLoading);
  1002. // If resources left to load, do not load nodes yet
  1003. if (asyncProgress_.loadedResources_ < asyncProgress_.totalResources_)
  1004. return;
  1005. HiresTimer asyncLoadTimer;
  1006. for (;;)
  1007. {
  1008. if (asyncProgress_.loadedNodes_ >= asyncProgress_.totalNodes_)
  1009. {
  1010. FinishAsyncLoading();
  1011. return;
  1012. }
  1013. // Read one child node with its full sub-hierarchy either from binary, JSON, or XML
  1014. /// \todo Works poorly in scenes where one root-level child node contains all content
  1015. if (asyncProgress_.xmlFile_)
  1016. {
  1017. unsigned nodeID = asyncProgress_.xmlElement_.GetUInt("id");
  1018. Node* newNode = CreateChild(nodeID, nodeID < FIRST_LOCAL_ID ? REPLICATED : LOCAL);
  1019. resolver_.AddNode(nodeID, newNode);
  1020. newNode->LoadXML(asyncProgress_.xmlElement_, resolver_);
  1021. asyncProgress_.xmlElement_ = asyncProgress_.xmlElement_.GetNext("node");
  1022. }
  1023. else if (asyncProgress_.jsonFile_) // Load from JSON
  1024. {
  1025. const JSONValue& childValue = asyncProgress_.jsonFile_->GetRoot().Get("children").GetArray().At(asyncProgress_.jsonIndex_);
  1026. unsigned nodeID =childValue.Get("id").GetUInt();
  1027. Node* newNode = CreateChild(nodeID, nodeID < FIRST_LOCAL_ID ? REPLICATED : LOCAL);
  1028. resolver_.AddNode(nodeID, newNode);
  1029. newNode->LoadJSON(childValue, resolver_);
  1030. ++asyncProgress_.jsonIndex_;
  1031. }
  1032. else // Load from binary
  1033. {
  1034. unsigned nodeID = asyncProgress_.file_->ReadUInt();
  1035. Node* newNode = CreateChild(nodeID, nodeID < FIRST_LOCAL_ID ? REPLICATED : LOCAL);
  1036. resolver_.AddNode(nodeID, newNode);
  1037. newNode->Load(*asyncProgress_.file_, resolver_);
  1038. }
  1039. ++asyncProgress_.loadedNodes_;
  1040. // Break if time limit exceeded, so that we keep sufficient FPS
  1041. if (asyncLoadTimer.GetUSec(false) >= asyncLoadingMs_ * 1000)
  1042. break;
  1043. }
  1044. using namespace AsyncLoadProgress;
  1045. VariantMap& eventData = GetEventDataMap();
  1046. eventData[P_SCENE] = this;
  1047. eventData[P_PROGRESS] = GetAsyncProgress();
  1048. eventData[P_LOADEDNODES] = asyncProgress_.loadedNodes_;
  1049. eventData[P_TOTALNODES] = asyncProgress_.totalNodes_;
  1050. eventData[P_LOADEDRESOURCES] = asyncProgress_.loadedResources_;
  1051. eventData[P_TOTALRESOURCES] = asyncProgress_.totalResources_;
  1052. SendEvent(E_ASYNCLOADPROGRESS, eventData);
  1053. }
  1054. void Scene::FinishAsyncLoading()
  1055. {
  1056. if (asyncProgress_.mode_ > LOAD_RESOURCES_ONLY)
  1057. {
  1058. resolver_.Resolve();
  1059. ApplyAttributes();
  1060. FinishLoading(asyncProgress_.file_);
  1061. }
  1062. StopAsyncLoading();
  1063. using namespace AsyncLoadFinished;
  1064. VariantMap& eventData = GetEventDataMap();
  1065. eventData[P_SCENE] = this;
  1066. SendEvent(E_ASYNCLOADFINISHED, eventData);
  1067. }
  1068. void Scene::FinishLoading(Deserializer* source)
  1069. {
  1070. if (source)
  1071. {
  1072. fileName_ = source->GetName();
  1073. checksum_ = source->GetChecksum();
  1074. }
  1075. // ATOMIC BEGIN
  1076. if (fileName_.Length())
  1077. {
  1078. LoadLightmaps();
  1079. }
  1080. // ATOMIC END
  1081. }
  1082. void Scene::FinishSaving(Serializer* dest) const
  1083. {
  1084. Deserializer* ptr = dynamic_cast<Deserializer*>(dest);
  1085. if (ptr)
  1086. {
  1087. fileName_ = ptr->GetName();
  1088. checksum_ = ptr->GetChecksum();
  1089. }
  1090. }
  1091. void Scene::PreloadResources(File* file, bool isSceneFile)
  1092. {
  1093. // If not threaded, can not background load resources, so rather load synchronously later when needed
  1094. #ifdef ATOMIC_THREADING
  1095. ResourceCache* cache = GetSubsystem<ResourceCache>();
  1096. // Read node ID (not needed)
  1097. /*unsigned nodeID = */file->ReadUInt();
  1098. // Read Node or Scene attributes; these do not include any resources
  1099. const Vector<AttributeInfo>* attributes = context_->GetAttributes(isSceneFile ? Scene::GetTypeStatic() : Node::GetTypeStatic());
  1100. assert(attributes);
  1101. for (unsigned i = 0; i < attributes->Size(); ++i)
  1102. {
  1103. const AttributeInfo& attr = attributes->At(i);
  1104. if (!(attr.mode_ & AM_FILE))
  1105. continue;
  1106. /*Variant varValue = */file->ReadVariant(attr.type_);
  1107. }
  1108. // Read component attributes
  1109. unsigned numComponents = file->ReadVLE();
  1110. for (unsigned i = 0; i < numComponents; ++i)
  1111. {
  1112. VectorBuffer compBuffer(*file, file->ReadVLE());
  1113. StringHash compType = compBuffer.ReadStringHash();
  1114. // Read component ID (not needed)
  1115. /*unsigned compID = */compBuffer.ReadUInt();
  1116. attributes = context_->GetAttributes(compType);
  1117. if (attributes)
  1118. {
  1119. for (unsigned j = 0; j < attributes->Size(); ++j)
  1120. {
  1121. const AttributeInfo& attr = attributes->At(j);
  1122. if (!(attr.mode_ & AM_FILE))
  1123. continue;
  1124. Variant varValue = compBuffer.ReadVariant(attr.type_);
  1125. if (attr.type_ == VAR_RESOURCEREF)
  1126. {
  1127. const ResourceRef& ref = varValue.GetResourceRef();
  1128. // Sanitate resource name beforehand so that when we get the background load event, the name matches exactly
  1129. String name = cache->SanitateResourceName(ref.name_);
  1130. bool success = cache->BackgroundLoadResource(ref.type_, name);
  1131. if (success)
  1132. {
  1133. ++asyncProgress_.totalResources_;
  1134. asyncProgress_.resources_.Insert(StringHash(name));
  1135. }
  1136. }
  1137. else if (attr.type_ == VAR_RESOURCEREFLIST)
  1138. {
  1139. const ResourceRefList& refList = varValue.GetResourceRefList();
  1140. for (unsigned k = 0; k < refList.names_.Size(); ++k)
  1141. {
  1142. String name = cache->SanitateResourceName(refList.names_[k]);
  1143. bool success = cache->BackgroundLoadResource(refList.type_, name);
  1144. if (success)
  1145. {
  1146. ++asyncProgress_.totalResources_;
  1147. asyncProgress_.resources_.Insert(StringHash(name));
  1148. }
  1149. }
  1150. }
  1151. }
  1152. }
  1153. }
  1154. // Read child nodes
  1155. unsigned numChildren = file->ReadVLE();
  1156. for (unsigned i = 0; i < numChildren; ++i)
  1157. PreloadResources(file, false);
  1158. #endif
  1159. }
  1160. void Scene::PreloadResourcesXML(const XMLElement& element)
  1161. {
  1162. // If not threaded, can not background load resources, so rather load synchronously later when needed
  1163. #ifdef ATOMIC_THREADING
  1164. ResourceCache* cache = GetSubsystem<ResourceCache>();
  1165. // Node or Scene attributes do not include any resources; therefore skip to the components
  1166. XMLElement compElem = element.GetChild("component");
  1167. while (compElem)
  1168. {
  1169. String typeName = compElem.GetAttribute("type");
  1170. const Vector<AttributeInfo>* attributes = context_->GetAttributes(StringHash(typeName));
  1171. if (attributes)
  1172. {
  1173. XMLElement attrElem = compElem.GetChild("attribute");
  1174. unsigned startIndex = 0;
  1175. while (attrElem)
  1176. {
  1177. String name = attrElem.GetAttribute("name");
  1178. unsigned i = startIndex;
  1179. unsigned attempts = attributes->Size();
  1180. while (attempts)
  1181. {
  1182. const AttributeInfo& attr = attributes->At(i);
  1183. if ((attr.mode_ & AM_FILE) && !attr.name_.Compare(name, true))
  1184. {
  1185. if (attr.type_ == VAR_RESOURCEREF)
  1186. {
  1187. ResourceRef ref = attrElem.GetVariantValue(attr.type_).GetResourceRef();
  1188. String name = cache->SanitateResourceName(ref.name_);
  1189. bool success = cache->BackgroundLoadResource(ref.type_, name);
  1190. if (success)
  1191. {
  1192. ++asyncProgress_.totalResources_;
  1193. asyncProgress_.resources_.Insert(StringHash(name));
  1194. }
  1195. }
  1196. else if (attr.type_ == VAR_RESOURCEREFLIST)
  1197. {
  1198. ResourceRefList refList = attrElem.GetVariantValue(attr.type_).GetResourceRefList();
  1199. for (unsigned k = 0; k < refList.names_.Size(); ++k)
  1200. {
  1201. String name = cache->SanitateResourceName(refList.names_[k]);
  1202. bool success = cache->BackgroundLoadResource(refList.type_, name);
  1203. if (success)
  1204. {
  1205. ++asyncProgress_.totalResources_;
  1206. asyncProgress_.resources_.Insert(StringHash(name));
  1207. }
  1208. }
  1209. }
  1210. startIndex = (i + 1) % attributes->Size();
  1211. break;
  1212. }
  1213. else
  1214. {
  1215. i = (i + 1) % attributes->Size();
  1216. --attempts;
  1217. }
  1218. }
  1219. attrElem = attrElem.GetNext("attribute");
  1220. }
  1221. }
  1222. compElem = compElem.GetNext("component");
  1223. }
  1224. XMLElement childElem = element.GetChild("node");
  1225. while (childElem)
  1226. {
  1227. PreloadResourcesXML(childElem);
  1228. childElem = childElem.GetNext("node");
  1229. }
  1230. #endif
  1231. }
  1232. void Scene::PreloadResourcesJSON(const JSONValue& value)
  1233. {
  1234. // If not threaded, can not background load resources, so rather load synchronously later when needed
  1235. #ifdef ATOMIC_THREADING
  1236. ResourceCache* cache = GetSubsystem<ResourceCache>();
  1237. // Node or Scene attributes do not include any resources; therefore skip to the components
  1238. JSONArray componentArray = value.Get("components").GetArray();
  1239. for (unsigned i = 0; i < componentArray.Size(); i++)
  1240. {
  1241. const JSONValue& compValue = componentArray.At(i);
  1242. String typeName = compValue.Get("type").GetString();
  1243. const Vector<AttributeInfo>* attributes = context_->GetAttributes(StringHash(typeName));
  1244. if (attributes)
  1245. {
  1246. JSONArray attributesArray = compValue.Get("attributes").GetArray();
  1247. unsigned startIndex = 0;
  1248. for (unsigned j = 0; j < attributesArray.Size(); j++)
  1249. {
  1250. const JSONValue& attrVal = attributesArray.At(j);
  1251. String name = attrVal.Get("name").GetString();
  1252. unsigned i = startIndex;
  1253. unsigned attempts = attributes->Size();
  1254. while (attempts)
  1255. {
  1256. const AttributeInfo& attr = attributes->At(i);
  1257. if ((attr.mode_ & AM_FILE) && !attr.name_.Compare(name, true))
  1258. {
  1259. if (attr.type_ == VAR_RESOURCEREF)
  1260. {
  1261. ResourceRef ref = attrVal.Get("value").GetVariantValue(attr.type_).GetResourceRef();
  1262. String name = cache->SanitateResourceName(ref.name_);
  1263. bool success = cache->BackgroundLoadResource(ref.type_, name);
  1264. if (success)
  1265. {
  1266. ++asyncProgress_.totalResources_;
  1267. asyncProgress_.resources_.Insert(StringHash(name));
  1268. }
  1269. }
  1270. else if (attr.type_ == VAR_RESOURCEREFLIST)
  1271. {
  1272. ResourceRefList refList = attrVal.Get("value").GetVariantValue(attr.type_).GetResourceRefList();
  1273. for (unsigned k = 0; k < refList.names_.Size(); ++k)
  1274. {
  1275. String name = cache->SanitateResourceName(refList.names_[k]);
  1276. bool success = cache->BackgroundLoadResource(refList.type_, name);
  1277. if (success)
  1278. {
  1279. ++asyncProgress_.totalResources_;
  1280. asyncProgress_.resources_.Insert(StringHash(name));
  1281. }
  1282. }
  1283. }
  1284. startIndex = (i + 1) % attributes->Size();
  1285. break;
  1286. }
  1287. else
  1288. {
  1289. i = (i + 1) % attributes->Size();
  1290. --attempts;
  1291. }
  1292. }
  1293. }
  1294. }
  1295. }
  1296. JSONArray childrenArray = value.Get("children").GetArray();
  1297. for (unsigned i = 0; i < childrenArray.Size(); i++)
  1298. {
  1299. const JSONValue& childVal = childrenArray.At(i);
  1300. PreloadResourcesJSON(childVal);
  1301. }
  1302. #endif
  1303. }
  1304. void RegisterSceneLibrary(Context* context)
  1305. {
  1306. ValueAnimation::RegisterObject(context);
  1307. ObjectAnimation::RegisterObject(context);
  1308. Node::RegisterObject(context);
  1309. Scene::RegisterObject(context);
  1310. SmoothedTransform::RegisterObject(context);
  1311. UnknownComponent::RegisterObject(context);
  1312. SplinePath::RegisterObject(context);
  1313. // ATOMIC BEGIN
  1314. PrefabComponent::RegisterObject(context);
  1315. // ATOMIC END
  1316. }
  1317. // ATOMIC BEGIN
  1318. void Scene::LoadLightmaps(bool reload)
  1319. {
  1320. // If we're running headless, don't load lightmap textures
  1321. if (!GetSubsystem<Graphics>())
  1322. {
  1323. return;
  1324. }
  1325. if (lightmaps_.Size() && !reload)
  1326. {
  1327. return;
  1328. }
  1329. lightmaps_.Clear();
  1330. PODVector<StaticModel*> staticModels;
  1331. GetComponents<StaticModel>(staticModels, true);
  1332. int maxLightMap = -1;
  1333. for (int i = 0; i < (int) staticModels.Size(); i++)
  1334. {
  1335. StaticModel* staticModel = staticModels[i];
  1336. if (!staticModel->GetLightmap())
  1337. continue;
  1338. int lightmapIndex = (int) staticModel->GetLightmapIndex();
  1339. if (lightmapIndex > maxLightMap)
  1340. {
  1341. maxLightMap = lightmapIndex;
  1342. }
  1343. }
  1344. if (maxLightMap < 0)
  1345. return;
  1346. ResourceCache* cache = GetSubsystem<ResourceCache>();
  1347. String sceneName = Atomic::GetFileName(GetFileName());
  1348. String lightmapFolder = ToString("AtomicGlow/Scenes/%s/Lightmaps/", sceneName.CString());
  1349. for (int i = 0; i < maxLightMap + 1; i++)
  1350. {
  1351. String textureName = ToString("%sLightmap%i.png", lightmapFolder.CString(), i);
  1352. Texture2D* texture = cache->GetResource<Texture2D>(textureName);
  1353. if (!texture)
  1354. {
  1355. ATOMIC_LOGWARNINGF("Scene::PreloadLightmaps() - Unable to load texture %s", textureName.CString());
  1356. lightmaps_.Push(SharedPtr<Texture2D>((Texture2D*)0));
  1357. continue;
  1358. }
  1359. // FILTER_NEAREST is good for testing lightmap, without bilinear artifacts
  1360. // texture->SetFilterMode(FILTER_NEAREST);
  1361. texture->SetNumLevels(1); // No mipmaps
  1362. texture->SetAddressMode(COORD_U, ADDRESS_CLAMP);
  1363. texture->SetAddressMode(COORD_V, ADDRESS_CLAMP);
  1364. lightmaps_.Push(SharedPtr<Texture2D>(texture));
  1365. }
  1366. }
  1367. void Scene::SetLightmapTexture(unsigned id)
  1368. {
  1369. // Store graphics subsystem into static variable for speed
  1370. // NOTE: If Atomic needs to support changing graphics subsystem on the fly
  1371. // this will need to be changed
  1372. static Graphics* graphics = GetSubsystem<Graphics>();
  1373. if (id >= lightmaps_.Size())
  1374. {
  1375. graphics->SetTexture(TU_EMISSIVE, 0);
  1376. return;
  1377. }
  1378. graphics->SetTexture(TU_EMISSIVE, lightmaps_[id]);
  1379. }
  1380. // ATOMIC END
  1381. }