SceneLoader.cpp 64 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557
  1. #include <utility>
  2. #include <vector>
  3. #include "ComponentConstructorInfo.h"
  4. #include "PropertyLoader.h"
  5. #include "SceneLoader.h"
  6. SceneLoader::SceneLoader(const EngineStateType p_engineStateType) : m_engineStateType(p_engineStateType)
  7. {
  8. m_changeController = nullptr;
  9. m_loadInBackground = false;
  10. m_loadingStatus = true;
  11. m_firstLoad = true;
  12. for(int i = 0; i < Systems::NumberOfSystems; i++)
  13. m_systemScenes[i] = g_nullSystemBase.createScene(this, EngineStateType::EngineStateType_Default);
  14. }
  15. SceneLoader::~SceneLoader()
  16. {
  17. }
  18. ErrorCode SceneLoader::loadFromProperties(const PropertySet &p_sceneProperties)
  19. {
  20. ErrorCode returnError = ErrorCode::Success;
  21. EntitiesConstructionInfo constructionInfo;
  22. // Get systems property set
  23. auto &systemProperties = p_sceneProperties.getPropertySetByID(Properties::Systems);
  24. // Iterate over all systems scenes
  25. for(int sysIndex = 0; sysIndex < Systems::NumberOfSystems; sysIndex++)
  26. {
  27. // Create an empty property set, in case there is none in the loaded file, because a system scene setup must be called either way
  28. PropertySet scenePropertySet;
  29. PropertySet systemropertySet;
  30. // Iterate over each system property set
  31. for(decltype(systemProperties.getNumPropertySets()) propIndex = 0, propSize = systemProperties.getNumPropertySets(); propIndex < propSize; propIndex++)
  32. {
  33. // If the system scene property matches in the loaded file, retrieve it so it can be passed to the corresponding scene
  34. if(Systems::SystemNames[m_systemScenes[sysIndex]->getSystemType()] == GetString(systemProperties.getPropertySetUnsafe(propIndex).getPropertyID()))
  35. {
  36. scenePropertySet = systemProperties.getPropertySetUnsafe(propIndex).getPropertySetByID(Properties::Scene);
  37. systemropertySet = systemProperties.getPropertySetUnsafe(propIndex).getPropertySetByID(Properties::System);
  38. }
  39. }
  40. // Pass the scene and system propertySet parameters
  41. m_systemScenes[sysIndex]->getSystem()->setup(systemropertySet);
  42. m_systemScenes[sysIndex]->setup(scenePropertySet);
  43. }
  44. // Get Game Objects
  45. auto &gameObjects = p_sceneProperties.getPropertySetByID(Properties::GameObject);
  46. if(gameObjects)
  47. {
  48. // Reserve enough room for all the game objects
  49. constructionInfo.resize(gameObjects.getNumPropertySets());
  50. // Iterate over all game objects
  51. for(decltype(gameObjects.getNumPropertySets()) objIndex = 0, objSize = gameObjects.getNumPropertySets(); objIndex < objSize; objIndex++)
  52. {
  53. // Import the game object data from PropertySets to EntitiesConstructionInfo
  54. importFromProperties(constructionInfo[objIndex], gameObjects.getPropertySetUnsafe(objIndex));
  55. }
  56. // Get the world scene required for creating entities
  57. WorldScene *worldScene = static_cast<WorldScene *>(m_systemScenes[Systems::World]);
  58. // Go over each entity and create it
  59. for(decltype(constructionInfo.size()) i = 0, size = constructionInfo.size(); i < size; i++)
  60. {
  61. worldScene->createEntity(constructionInfo[i], false);
  62. }
  63. }
  64. else
  65. {
  66. // GameObject property set is missing
  67. returnError = ErrorCode::GameObjects_missing;
  68. ErrHandlerLoc().get().log(ErrorCode::GameObjects_missing, ErrorSource::Source_SceneLoader);
  69. }
  70. // Check if the scene should be loaded in background
  71. if(p_sceneProperties.getPropertyByID(Properties::LoadInBackground).getBool())
  72. {
  73. m_loadInBackground = true;
  74. // Start loading in background threads in all scenes
  75. for(int i = 0; i < Systems::NumberOfSystems; i++)
  76. m_systemScenes[i]->loadInBackground();
  77. }
  78. else
  79. {
  80. m_loadInBackground = false;
  81. // Preload all scenes sequentially
  82. for(int i = 0; i < Systems::NumberOfSystems; i++)
  83. m_systemScenes[i]->preload();
  84. }
  85. // Make sure to clear the memory of contructionInfo
  86. for(decltype(constructionInfo.size()) i = 0, size = constructionInfo.size(); i < size; i++)
  87. constructionInfo[i].deleteConstructionInfo();
  88. return returnError;
  89. }
  90. ErrorCode SceneLoader::loadFromFile(const std::string &p_filename)
  91. {
  92. ErrorCode returnError = ErrorCode::Success;
  93. m_filename = p_filename;
  94. EntitiesConstructionInfo constructionInfo;
  95. // Load properties from file
  96. PropertyLoader loadedProperties(Config::filepathVar().map_path + p_filename);
  97. returnError = loadedProperties.loadFromFile();
  98. // Check if loading was successful, return an error, if not
  99. if(returnError != ErrorCode::Success)
  100. {
  101. ErrHandlerLoc().get().log(returnError, ErrorSource::Source_SceneLoader);
  102. }
  103. else
  104. {
  105. returnError = loadFromProperties(loadedProperties.getPropertySet());
  106. }
  107. return returnError;
  108. }
  109. ErrorCode SceneLoader::saveToFile(const std::string p_filename)
  110. {
  111. std::string filename;
  112. if(!p_filename.empty())
  113. filename = Config::filepathVar().map_path + p_filename;
  114. else
  115. filename = m_filename;
  116. if(!filename.empty())
  117. {
  118. // Get the world scene required for getting the entity registry
  119. WorldScene *worldScene = static_cast<WorldScene *>(m_systemScenes[Systems::World]);
  120. // Get the entity registry
  121. auto &entityRegistry = worldScene->getEntityRegistry();
  122. // Add root property set for the whole file
  123. PropertySet rootPropertySet(Properties::Default);
  124. // Add root property set game objects
  125. auto &gameObjects = rootPropertySet.addPropertySet(Properties::GameObject);
  126. // An array holding all of the entities
  127. std::vector<EntityID> allEntities;
  128. // Add all entities to the array
  129. for(auto entity : entityRegistry.view<EntityID>())
  130. allEntities.push_back(entity);
  131. // Sort the entities so they are written to file in order
  132. std::sort(allEntities.begin(), allEntities.end());
  133. // Iterate every entity
  134. for(auto &entity : allEntities)
  135. {
  136. // Create an array entry for the entity
  137. auto &gameObjectEntry = gameObjects.addPropertySet(Properties::ArrayEntry);
  138. // Export the entity to the Construction Info
  139. ComponentsConstructionInfo constructionInfo;
  140. worldScene->exportEntity(entity, constructionInfo);
  141. // Export the Construction Info to the Property Set
  142. exportToProperties(constructionInfo, gameObjectEntry);
  143. }
  144. // Add scene loaded properties
  145. rootPropertySet.addProperty(Properties::LoadInBackground, m_loadInBackground);
  146. // Add root property set for systems
  147. auto &rootSystemsPropertySet = rootPropertySet.addPropertySet(Properties::Systems);
  148. // Add each system's properties
  149. for(size_t systemType = 0; systemType < Systems::NumberOfSystems; systemType++)
  150. {
  151. // Convert TypeID to PropertyID
  152. Properties::PropertyID systemTypeProperty = Properties::Null;
  153. switch(systemType)
  154. {
  155. case Systems::TypeID::Audio:
  156. systemTypeProperty = Properties::Audio;
  157. break;
  158. case Systems::TypeID::Graphics:
  159. systemTypeProperty = Properties::Graphics;
  160. break;
  161. case Systems::TypeID::GUI:
  162. systemTypeProperty = Properties::GUI;
  163. break;
  164. case Systems::TypeID::Physics:
  165. systemTypeProperty = Properties::Physics;
  166. break;
  167. case Systems::TypeID::Script:
  168. systemTypeProperty = Properties::Script;
  169. break;
  170. case Systems::TypeID::World:
  171. systemTypeProperty = Properties::World;
  172. break;
  173. }
  174. // Add system type entry
  175. auto &systemPropertyIDentry = rootSystemsPropertySet.addPropertySet(systemTypeProperty);
  176. // Add scene and system settings
  177. m_systemScenes[systemType]->exportSetup(systemPropertyIDentry.addPropertySet(Properties::Scene));
  178. m_systemScenes[systemType]->getSystem()->exportSetup(systemPropertyIDentry.addPropertySet(Properties::System));
  179. }
  180. // Save properties to a file
  181. PropertyLoader savedProperties(filename);
  182. ErrorCode loaderError = savedProperties.saveToFile(rootPropertySet);
  183. // Check if loading was successful, return an error, if not
  184. if(loaderError != ErrorCode::Success)
  185. return loaderError;
  186. ErrHandlerLoc().get().log(ErrorType::Info, ErrorSource::Source_PropertyLoader, "File has been exported: " + filename);
  187. }
  188. // TODO ERROR empty filename
  189. return ErrorCode::Failure;
  190. }
  191. ErrorCode SceneLoader::importPrefab(ComponentsConstructionInfo &p_constructionInfo, const std::string &p_filename, const bool p_forceReload)
  192. {
  193. ErrorCode returnError = ErrorCode::Success;
  194. // Check if the given filename isn't empty
  195. if(!p_filename.empty())
  196. {
  197. // Search for the given prefab (it might have been loaded before, already)
  198. auto prefabIterator = m_prefabs.find(p_filename);
  199. // If the prefab was already imported and exists in the map, use it
  200. if(prefabIterator != m_prefabs.end())
  201. {
  202. if(p_forceReload)
  203. returnError = importFromFile(p_constructionInfo, Config::filepathVar().prefab_path + p_filename);
  204. else
  205. p_constructionInfo.completeCopy(prefabIterator->second);
  206. }
  207. else // If the prefab doesn't exist in the map, import it
  208. {
  209. // Make sure calls from other threads are locked, while current call is in progress
  210. // This is needed as the prefab that is being requested might be currently being imported
  211. // Mutex prevents duplicate prefabs being loaded, and same data being changed.
  212. SpinWait::Lock lock(m_mutex);
  213. // Search for the prefab again, as it might have been imported from another thread call before mutex lock was released
  214. auto prefabIteratorNew = m_prefabs.find(p_filename);
  215. if(prefabIteratorNew != m_prefabs.end())
  216. {
  217. if(p_forceReload)
  218. returnError = importFromFile(p_constructionInfo, Config::filepathVar().prefab_path + p_filename);
  219. else
  220. p_constructionInfo.completeCopy(prefabIterator->second);
  221. }
  222. else
  223. {
  224. // Load properties from file
  225. PropertyLoader loadedProperties(Config::filepathVar().prefab_path + p_filename);
  226. returnError = loadedProperties.loadFromFile();
  227. if(returnError == ErrorCode::Success)
  228. {
  229. // Insert a new prefab into the map
  230. ComponentsConstructionInfo &constructionInfo = m_prefabs.try_emplace(p_filename).first->second;
  231. // Populate the newly imported prefab
  232. importFromProperties(constructionInfo, loadedProperties.getPropertySet());
  233. p_constructionInfo.completeCopy(constructionInfo);
  234. }
  235. }
  236. }
  237. }
  238. else
  239. returnError = ErrorCode::Filename_empty;
  240. return returnError;
  241. }
  242. ErrorCode SceneLoader::importFromFile(ComponentsConstructionInfo &p_constructionInfo, const std::string &p_filename)
  243. {
  244. ErrorCode returnError = ErrorCode::Success;
  245. // Load properties from file
  246. PropertyLoader loadedProperties(p_filename);
  247. returnError = loadedProperties.loadFromFile();
  248. if(returnError == ErrorCode::Success)
  249. importFromProperties(p_constructionInfo, loadedProperties.getPropertySet());
  250. return returnError;
  251. }
  252. void SceneLoader::importFromProperties(ComponentsConstructionInfo &p_constructionInfo, const PropertySet &p_properties)
  253. {
  254. // Load Prefab first
  255. auto &prefabProperty = p_properties.getPropertyByID(Properties::Prefab);
  256. if(prefabProperty)
  257. {
  258. std::string prefabName = prefabProperty.getString();
  259. importPrefab(p_constructionInfo, prefabName);
  260. p_constructionInfo.m_prefab = prefabName;
  261. }
  262. // Variable for the object name
  263. std::string name;
  264. // Load property data
  265. for(decltype(p_properties.getNumProperties()) i = 0, size = p_properties.getNumProperties(); i < size; i++)
  266. {
  267. switch(p_properties[i].getPropertyID())
  268. {
  269. case Properties::ID:
  270. {
  271. // Get the desired ID of the entity
  272. p_constructionInfo.m_id = (EntityID)p_properties[i].getInt();
  273. }
  274. break;
  275. case Properties::Name:
  276. {
  277. // Get the entity name
  278. name = p_properties[i].getString();
  279. }
  280. break;
  281. case Properties::Parent:
  282. {
  283. // Get the entity ID if the parent object
  284. p_constructionInfo.m_parent = (EntityID)p_properties[i].getInt();
  285. }
  286. break;
  287. }
  288. }
  289. // If the name property is missing, generate a unique name based on the entity ID
  290. if(name.empty())
  291. if(p_constructionInfo.m_name.empty())
  292. name = GetString(Properties::GameObject) + Utilities::toString(p_constructionInfo.m_id);
  293. else
  294. name = p_constructionInfo.m_name + Utilities::toString(p_constructionInfo.m_id);
  295. // Make sure to assign values after the Prefab has been imported (if there was one)
  296. p_constructionInfo.m_name = name;
  297. // Load audio components
  298. {
  299. auto &sceneProperty = p_properties.getPropertySetByID(Properties::Audio);
  300. if(sceneProperty)
  301. {
  302. for(decltype(sceneProperty.getNumPropertySets()) i = 0, size = sceneProperty.getNumPropertySets(); i < size; i++)
  303. {
  304. importFromProperties(p_constructionInfo.m_audioComponents, sceneProperty.getPropertySet(i), name);
  305. }
  306. }
  307. }
  308. // Load graphics components
  309. {
  310. auto &sceneProperty = p_properties.getPropertySetByID(Properties::Graphics);
  311. if(sceneProperty)
  312. {
  313. for(decltype(sceneProperty.getNumPropertySets()) i = 0, size = sceneProperty.getNumPropertySets(); i < size; i++)
  314. {
  315. importFromProperties(p_constructionInfo.m_graphicsComponents, sceneProperty.getPropertySet(i), name);
  316. }
  317. }
  318. }
  319. // Load GUI components
  320. {
  321. auto &sceneProperty = p_properties.getPropertySetByID(Properties::GUI);
  322. if(sceneProperty)
  323. {
  324. for(decltype(sceneProperty.getNumPropertySets()) i = 0, size = sceneProperty.getNumPropertySets(); i < size; i++)
  325. {
  326. importFromProperties(p_constructionInfo.m_guiComponents, sceneProperty.getPropertySet(i), name);
  327. }
  328. }
  329. }
  330. // Load physics components
  331. {
  332. auto &sceneProperty = p_properties.getPropertySetByID(Properties::Physics);
  333. if(sceneProperty)
  334. {
  335. for(decltype(sceneProperty.getNumPropertySets()) i = 0, size = sceneProperty.getNumPropertySets(); i < size; i++)
  336. {
  337. importFromProperties(p_constructionInfo.m_physicsComponents, sceneProperty.getPropertySet(i), name);
  338. }
  339. }
  340. }
  341. // Load script components
  342. {
  343. auto &sceneProperty = p_properties.getPropertySetByID(Properties::Script);
  344. if(sceneProperty)
  345. {
  346. for(decltype(sceneProperty.getNumPropertySets()) i = 0, size = sceneProperty.getNumPropertySets(); i < size; i++)
  347. {
  348. importFromProperties(p_constructionInfo.m_scriptComponents, sceneProperty.getPropertySet(i), name);
  349. }
  350. }
  351. }
  352. // Load world components
  353. {
  354. auto &sceneProperty = p_properties.getPropertySetByID(Properties::World);
  355. if(sceneProperty)
  356. {
  357. for(decltype(sceneProperty.getNumPropertySets()) i = 0, size = sceneProperty.getNumPropertySets(); i < size; i++)
  358. {
  359. importFromProperties(p_constructionInfo.m_worldComponents, sceneProperty.getPropertySet(i), name);
  360. }
  361. }
  362. }
  363. }
  364. void SceneLoader::importFromProperties(AudioComponentsConstructionInfo &p_constructionInfo, const PropertySet &p_properties, const std::string &p_name)
  365. {
  366. // Check if property set node is present
  367. if(p_properties)
  368. {
  369. switch(p_properties.getPropertyID())
  370. {
  371. case Properties::PropertyID::SoundComponent:
  372. {
  373. if(p_constructionInfo.m_soundConstructionInfo == nullptr)
  374. p_constructionInfo.m_soundConstructionInfo = new SoundComponent::SoundComponentConstructionInfo();
  375. p_constructionInfo.m_soundConstructionInfo->m_name = p_name + Config::componentVar().component_name_separator + GetString(Properties::PropertyID::SoundComponent);
  376. // Load property data
  377. for(decltype(p_properties.getNumProperties()) i = 0, size = p_properties.getNumProperties(); i < size; i++)
  378. {
  379. switch(p_properties[i].getPropertyID())
  380. {
  381. case Properties::Active:
  382. p_constructionInfo.m_soundConstructionInfo->m_active = p_properties[i].getBool();
  383. break;
  384. case Properties::Loop:
  385. p_constructionInfo.m_soundConstructionInfo->m_loop = p_properties[i].getBool();
  386. break;
  387. case Properties::Name:
  388. p_constructionInfo.m_soundConstructionInfo->m_soundName = p_properties[i].getString();
  389. break;
  390. case Properties::Source:
  391. switch(p_properties[i].getID())
  392. {
  393. case Properties::Event:
  394. p_constructionInfo.m_soundConstructionInfo->m_soundSourceType = SoundComponent::SoundSourceType::SoundSourceType_Event;
  395. break;
  396. case Properties::File:
  397. p_constructionInfo.m_soundConstructionInfo->m_soundSourceType = SoundComponent::SoundSourceType::SoundSourceType_File;
  398. break;
  399. }
  400. break;
  401. case Properties::Spatialized:
  402. p_constructionInfo.m_soundConstructionInfo->m_spatialized = p_properties[i].getBool();
  403. break;
  404. case Properties::StartPlaying:
  405. p_constructionInfo.m_soundConstructionInfo->m_startPlaying = p_properties[i].getBool();
  406. break;
  407. case Properties::Type:
  408. switch(p_properties[i].getID())
  409. {
  410. case Properties::Ambient:
  411. p_constructionInfo.m_soundConstructionInfo->m_soundType = SoundComponent::SoundType::SoundType_Ambient;
  412. break;
  413. case Properties::Music:
  414. p_constructionInfo.m_soundConstructionInfo->m_soundType = SoundComponent::SoundType::SoundType_Music;
  415. break;
  416. case Properties::SoundEffect:
  417. p_constructionInfo.m_soundConstructionInfo->m_soundType = SoundComponent::SoundType::SoundType_SoundEffect;
  418. break;
  419. default:
  420. ErrHandlerLoc().get().log(ErrorCode::Property_missing_type, p_name, ErrorSource::Source_SoundComponent);
  421. break;
  422. }
  423. break;
  424. case Properties::Volume:
  425. p_constructionInfo.m_soundConstructionInfo->m_volume = p_properties[i].getFloat();
  426. break;
  427. }
  428. }
  429. // Make sure the sound name was set
  430. if(p_constructionInfo.m_soundConstructionInfo->m_soundName.empty())
  431. {
  432. ErrHandlerLoc().get().log(ErrorCode::Property_no_filename, p_name, ErrorSource::Source_SoundComponent);
  433. delete p_constructionInfo.m_soundConstructionInfo;
  434. p_constructionInfo.m_soundConstructionInfo = nullptr;
  435. }
  436. }
  437. break;
  438. case Properties::PropertyID::SoundListenerComponent:
  439. {
  440. if(p_constructionInfo.m_soundListenerConstructionInfo == nullptr)
  441. p_constructionInfo.m_soundListenerConstructionInfo = new SoundListenerComponent::SoundListenerComponentConstructionInfo();
  442. p_constructionInfo.m_soundListenerConstructionInfo->m_name = p_name + Config::componentVar().component_name_separator + GetString(Properties::PropertyID::SoundListenerComponent);
  443. p_properties.getValueByID(Properties::PropertyID::ID, p_constructionInfo.m_soundListenerConstructionInfo->m_listenerID);
  444. p_properties.getValueByID(Properties::PropertyID::Active, p_constructionInfo.m_soundListenerConstructionInfo->m_active);
  445. }
  446. break;
  447. }
  448. }
  449. }
  450. void SceneLoader::importFromProperties(GraphicsComponentsConstructionInfo &p_constructionInfo, const PropertySet &p_properties, const std::string &p_name)
  451. {
  452. // Check if property set node is present
  453. if(p_properties)
  454. {
  455. switch(p_properties.getPropertyID())
  456. {
  457. case Properties::PropertyID::CameraComponent:
  458. {
  459. if(p_constructionInfo.m_cameraConstructionInfo == nullptr)
  460. p_constructionInfo.m_cameraConstructionInfo = new CameraComponent::CameraComponentConstructionInfo();
  461. p_constructionInfo.m_cameraConstructionInfo->m_name = p_name + Config::componentVar().component_name_separator + GetString(Properties::PropertyID::CameraComponent);
  462. p_properties.getValueByID(Properties::Active, p_constructionInfo.m_cameraConstructionInfo->m_active);
  463. // Load property data
  464. for(decltype(p_properties.getNumProperties()) i = 0, size = p_properties.getNumProperties(); i < size; i++)
  465. {
  466. switch(p_properties[i].getPropertyID())
  467. {
  468. case Properties::CameraID:
  469. p_constructionInfo.m_cameraConstructionInfo->m_cameraID = p_properties[i].getInt();
  470. break;
  471. case Properties::FOV:
  472. p_constructionInfo.m_cameraConstructionInfo->m_fov = p_properties[i].getFloat();
  473. break;
  474. case Properties::ZFar:
  475. p_constructionInfo.m_cameraConstructionInfo->m_zFar = p_properties[i].getFloat();
  476. break;
  477. case Properties::ZNear:
  478. p_constructionInfo.m_cameraConstructionInfo->m_zNear = p_properties[i].getFloat();
  479. break;
  480. }
  481. }
  482. }
  483. break;
  484. case Properties::PropertyID::LightComponent:
  485. {
  486. if(p_constructionInfo.m_lightConstructionInfo == nullptr)
  487. p_constructionInfo.m_lightConstructionInfo = new LightComponent::LightComponentConstructionInfo();
  488. p_constructionInfo.m_lightConstructionInfo->m_name = p_name + Config::componentVar().component_name_separator + GetString(Properties::PropertyID::LightComponent);
  489. p_properties.getValueByID(Properties::Active, p_constructionInfo.m_lightConstructionInfo->m_active);
  490. // Get the light type
  491. auto const &type = p_properties.getPropertyByID(Properties::Type).getID();
  492. // Load values based on the type of light
  493. switch(type)
  494. {
  495. case Properties::DirectionalLight:
  496. p_constructionInfo.m_lightConstructionInfo->m_lightComponentType = LightComponent::LightComponentType::LightComponentType_directional;
  497. p_properties.getValueByID(Properties::Color, p_constructionInfo.m_lightConstructionInfo->m_color);
  498. p_properties.getValueByID(Properties::Intensity, p_constructionInfo.m_lightConstructionInfo->m_intensity);
  499. break;
  500. case Properties::PointLight:
  501. p_constructionInfo.m_lightConstructionInfo->m_lightComponentType = LightComponent::LightComponentType::LightComponentType_point;
  502. p_properties.getValueByID(Properties::Color, p_constructionInfo.m_lightConstructionInfo->m_color);
  503. p_properties.getValueByID(Properties::Intensity, p_constructionInfo.m_lightConstructionInfo->m_intensity);
  504. break;
  505. case Properties::SpotLight:
  506. p_constructionInfo.m_lightConstructionInfo->m_lightComponentType = LightComponent::LightComponentType::LightComponentType_spot;
  507. p_properties.getValueByID(Properties::Color, p_constructionInfo.m_lightConstructionInfo->m_color);
  508. p_properties.getValueByID(Properties::CutoffAngle, p_constructionInfo.m_lightConstructionInfo->m_cutoffAngle);
  509. p_properties.getValueByID(Properties::Intensity, p_constructionInfo.m_lightConstructionInfo->m_intensity);
  510. break;
  511. default:
  512. ErrHandlerLoc().get().log(ErrorType::Warning, ErrorSource::Source_LightComponent, p_name + " - missing \'Type\' identifier");
  513. delete p_constructionInfo.m_lightConstructionInfo;
  514. p_constructionInfo.m_lightConstructionInfo = nullptr;
  515. break;
  516. }
  517. }
  518. break;
  519. case Properties::PropertyID::ModelComponent:
  520. {
  521. if(p_constructionInfo.m_modelConstructionInfo == nullptr)
  522. p_constructionInfo.m_modelConstructionInfo = new ModelComponent::ModelComponentConstructionInfo();
  523. p_constructionInfo.m_modelConstructionInfo->m_name = p_name + Config::componentVar().component_name_separator + GetString(Properties::PropertyID::ModelComponent);
  524. p_properties.getValueByID(Properties::Active, p_constructionInfo.m_modelConstructionInfo->m_active);
  525. bool modelDataPresent = false;
  526. auto &modelsProperty = p_properties.getPropertySetByID(Properties::Models);
  527. if(modelsProperty)
  528. {
  529. if(modelsProperty.getNumPropertySets() > 0)
  530. p_constructionInfo.m_modelConstructionInfo->m_modelsProperties.m_models.clear();
  531. // Loop over each model entry in the node
  532. for(decltype(modelsProperty.getNumPropertySets()) iModel = 0, numModels = modelsProperty.getNumPropertySets(); iModel < numModels; iModel++)
  533. {
  534. // Get model filename
  535. auto modelName = modelsProperty.getPropertySet(iModel).getPropertyByID(Properties::Filename).getString();
  536. // Continue only of the model filename is not empty
  537. if(!modelName.empty())
  538. {
  539. modelDataPresent = true;
  540. // Add a new model data entry, and get a reference to it
  541. p_constructionInfo.m_modelConstructionInfo->m_modelsProperties.m_models.push_back(ModelComponent::MeshProperties());
  542. auto &newModelEntry = p_constructionInfo.m_modelConstructionInfo->m_modelsProperties.m_models.back();
  543. // Assign the model filename
  544. newModelEntry.m_modelName = modelName;
  545. // Get meshes property
  546. auto &meshesProperty = modelsProperty.getPropertySet(iModel).getPropertySetByID(Properties::Meshes);
  547. // Check if the meshes array node is present;
  548. // If it is present, only add the meshes included in the meshes node
  549. // If it is not present, add all the meshes included in the model
  550. if(meshesProperty)
  551. {
  552. if(meshesProperty.getNumPropertySets() > 0)
  553. {
  554. // Loop over each mesh entry in the model node
  555. for(decltype(meshesProperty.getNumPropertySets()) iMesh = 0, numMeshes = meshesProperty.getNumPropertySets(); iMesh < numMeshes; iMesh++)
  556. {
  557. // Try to get the mesh index property node and check if it is present
  558. if(auto &meshIndexProperty = meshesProperty.getPropertySet(iMesh).getPropertyByID(Properties::Index); meshIndexProperty)
  559. {
  560. // Get the mesh index, check if it is valid and within the range of mesh array that was loaded from the model
  561. const int meshDataIndex = meshIndexProperty.getInt();
  562. // Make sure the meshMaterials vector can fit the given mesh index
  563. if(meshDataIndex >= newModelEntry.m_meshData.size())
  564. {
  565. newModelEntry.resize(meshDataIndex + 1);
  566. newModelEntry.m_meshData[meshDataIndex].m_present = true;
  567. }
  568. // Get the active flag, if it is present
  569. if(auto activeProperty = meshesProperty.getPropertySet(iMesh).getPropertyByID(Properties::Active); activeProperty)
  570. newModelEntry.m_meshData[meshDataIndex].m_active = activeProperty.getBool();
  571. // Get material alpha threshold value, if it is present
  572. if(auto alphaThresholdProperty = meshesProperty.getPropertySet(iMesh).getPropertyByID(Properties::AlphaThreshold); alphaThresholdProperty)
  573. newModelEntry.m_meshData[meshDataIndex].m_alphaThreshold = alphaThresholdProperty.getFloat();
  574. // Get emissive intensity, if it is present
  575. if(auto emissiveIntensityProperty = meshesProperty.getPropertySet(iMesh).getPropertyByID(Properties::EmissiveIntensity); emissiveIntensityProperty)
  576. newModelEntry.m_meshData[meshDataIndex].m_emissiveIntensity = emissiveIntensityProperty.getFloat();
  577. // Get material height scale value, if it is present
  578. if(auto heightScaleProperty = meshesProperty.getPropertySet(iMesh).getPropertyByID(Properties::HeightScale); heightScaleProperty)
  579. newModelEntry.m_meshData[meshDataIndex].m_heightScale = heightScaleProperty.getFloat();
  580. // Get stochastic sampling flag, if it is present
  581. if(auto stochasticSamplingProperty = meshesProperty.getPropertySet(iMesh).getPropertyByID(Properties::StochasticSampling); stochasticSamplingProperty)
  582. newModelEntry.m_meshData[meshDataIndex].m_stochasticSampling = stochasticSamplingProperty.getBool();
  583. // Get stochastic sampling scale value, if it is present
  584. if(auto stochasticSamplingScaleProperty = meshesProperty.getPropertySet(iMesh).getPropertyByID(Properties::StochasticSamplingScale); stochasticSamplingScaleProperty)
  585. newModelEntry.m_meshData[meshDataIndex].m_stochasticSamplingScale = stochasticSamplingScaleProperty.getFloat();
  586. // Get material wrap mode
  587. if(auto wrapModeProperty = meshesProperty.getPropertySet(iMesh).getPropertyByID(Properties::WrapMode); wrapModeProperty)
  588. {
  589. switch(wrapModeProperty.getID())
  590. {
  591. case Properties::ClampToBorder:
  592. newModelEntry.m_meshData[meshDataIndex].m_textureWrapMode = TextureWrapType::TextureWrapType_ClampToBorder;
  593. break;
  594. case Properties::ClampToEdge:
  595. newModelEntry.m_meshData[meshDataIndex].m_textureWrapMode = TextureWrapType::TextureWrapType_ClampToEdge;
  596. break;
  597. case Properties::MirroredClampToEdge:
  598. newModelEntry.m_meshData[meshDataIndex].m_textureWrapMode = TextureWrapType::TextureWrapType_MirroredClampToEdge;
  599. break;
  600. case Properties::MirroredRepeat:
  601. newModelEntry.m_meshData[meshDataIndex].m_textureWrapMode = TextureWrapType::TextureWrapType_MirroredRepeat;
  602. break;
  603. case Properties::Repeat:
  604. default:
  605. newModelEntry.m_meshData[meshDataIndex].m_textureWrapMode = TextureWrapType::TextureWrapType_Repeat;
  606. break;
  607. }
  608. }
  609. // Get material properties
  610. auto materialsProperty = meshesProperty.getPropertySet(iMesh).getPropertySetByID(Properties::Materials);
  611. // Define material data and material properties
  612. MaterialData materials[MaterialType::MaterialType_NumOfTypes];
  613. PropertySet materialProperties[MaterialType::MaterialType_NumOfTypes] =
  614. {
  615. materialsProperty.getPropertySetByID(Properties::Diffuse),
  616. materialsProperty.getPropertySetByID(Properties::Normal),
  617. materialsProperty.getPropertySetByID(Properties::Emissive),
  618. materialsProperty.getPropertySetByID(Properties::RMHAO)
  619. };
  620. // Go over each material type
  621. for(unsigned int iMatType = 0; iMatType < MaterialType::MaterialType_NumOfTypes; iMatType++)
  622. {
  623. // Check if an entry for the current material type was present within the properties
  624. if(materialProperties[iMatType])
  625. {
  626. // Get texture filename property, check if it is valid
  627. auto filenameProperty = materialProperties[iMatType].getPropertyByID(Properties::Filename);
  628. if(filenameProperty.isVariableTypeString())
  629. {
  630. // Get texture filename string, check if it is valid
  631. newModelEntry.m_meshData[meshDataIndex].m_meshMaterials[iMatType] = filenameProperty.getString();
  632. }
  633. // Get texture scale property, check if it is valid
  634. auto scaleProperty = materialProperties[iMatType].getPropertyByID(Properties::TextureScale);
  635. if(scaleProperty)
  636. newModelEntry.m_meshData[meshDataIndex].m_meshMaterialsScales[iMatType] = scaleProperty.getVec2f();
  637. }
  638. }
  639. }
  640. }
  641. }
  642. }
  643. }
  644. }
  645. }
  646. if(p_properties.getNumPropertySets() == 0 || !modelDataPresent)
  647. {
  648. ErrHandlerLoc().get().log(ErrorType::Info, ErrorSource::Source_ModelComponent, p_name + " - missing model data");
  649. delete p_constructionInfo.m_modelConstructionInfo;
  650. p_constructionInfo.m_modelConstructionInfo = nullptr;
  651. }
  652. }
  653. break;
  654. case Properties::PropertyID::ShaderComponent:
  655. {
  656. if(p_constructionInfo.m_shaderConstructionInfo == nullptr)
  657. p_constructionInfo.m_shaderConstructionInfo = new ShaderComponent::ShaderComponentConstructionInfo();
  658. p_constructionInfo.m_shaderConstructionInfo->m_name = p_name + Config::componentVar().component_name_separator + GetString(Properties::PropertyID::ShaderComponent);
  659. // Get nodes for different shader types
  660. auto geometryShaderNode = p_properties.getPropertyByID(Properties::GeometryShader);
  661. auto vertexShaderNode = p_properties.getPropertyByID(Properties::VertexShader);
  662. auto fragmentShaderNode = p_properties.getPropertyByID(Properties::FragmentShader);
  663. if(geometryShaderNode)
  664. p_constructionInfo.m_shaderConstructionInfo->m_geometryShaderFilename = geometryShaderNode.getString();
  665. if(vertexShaderNode)
  666. p_constructionInfo.m_shaderConstructionInfo->m_vetexShaderFilename = vertexShaderNode.getString();
  667. if(fragmentShaderNode)
  668. p_constructionInfo.m_shaderConstructionInfo->m_fragmentShaderFilename = fragmentShaderNode.getString();
  669. }
  670. break;
  671. }
  672. }
  673. }
  674. void SceneLoader::importFromProperties(GUIComponentsConstructionInfo &p_constructionInfo, const PropertySet &p_properties, const std::string &p_name)
  675. {
  676. // Check if property set node is present
  677. if(p_properties)
  678. {
  679. switch(p_properties.getPropertyID())
  680. {
  681. case Properties::PropertyID::GUISequenceComponent:
  682. {
  683. if(p_constructionInfo.m_guiSequenceConstructionInfo == nullptr)
  684. p_constructionInfo.m_guiSequenceConstructionInfo = new GUISequenceComponent::GUISequenceComponentConstructionInfo();
  685. p_constructionInfo.m_guiSequenceConstructionInfo->m_name = p_name + Config::componentVar().component_name_separator + GetString(Properties::PropertyID::GUISequenceComponent);
  686. }
  687. break;
  688. }
  689. }
  690. }
  691. void SceneLoader::importFromProperties(PhysicsComponentsConstructionInfo &p_constructionInfo, const PropertySet &p_properties, const std::string &p_name)
  692. {
  693. // Check if property set node is present
  694. if(p_properties)
  695. {
  696. switch(p_properties.getPropertyID())
  697. {
  698. case Properties::PropertyID::RigidBodyComponent:
  699. {
  700. if(p_constructionInfo.m_rigidBodyConstructionInfo == nullptr)
  701. p_constructionInfo.m_rigidBodyConstructionInfo = new RigidBodyComponent::RigidBodyComponentConstructionInfo();
  702. p_constructionInfo.m_rigidBodyConstructionInfo->m_name = p_name + Config::componentVar().component_name_separator + GetString(Properties::PropertyID::RigidBodyComponent);
  703. p_properties.getValueByID(Properties::Active, p_constructionInfo.m_rigidBodyConstructionInfo->m_active);
  704. // --------------------
  705. // Load collision shape
  706. // --------------------
  707. auto const &collisionShapeProperty = p_properties.getPropertySetByID(Properties::CollisionShape);
  708. if(collisionShapeProperty)
  709. {
  710. // Get the type of the collision shape and load the data based on it
  711. auto const &typeProperty = collisionShapeProperty.getPropertyByID(Properties::Type);
  712. if(typeProperty)
  713. {
  714. switch(typeProperty.getID())
  715. {
  716. case Properties::Box:
  717. {
  718. // Get the size property
  719. auto const &sizeProperty = collisionShapeProperty.getPropertyByID(Properties::Size);
  720. // If the size was not given, leave it to a default 0.5f all around (so it gets to the final 1.0/1.0/1.0 dimension)
  721. if(sizeProperty)
  722. p_constructionInfo.m_rigidBodyConstructionInfo->m_collisionShapeSize = sizeProperty.getVec3f();
  723. else
  724. ErrHandlerLoc().get().log(ErrorCode::Property_missing_size, p_name, ErrorSource::Source_RigidBodyComponent);
  725. p_constructionInfo.m_rigidBodyConstructionInfo->m_collisionShapeType = RigidBodyComponent::CollisionShapeType::CollisionShapeType_Box;
  726. }
  727. break;
  728. case Properties::Sphere:
  729. {
  730. // Get the size property
  731. auto const &sizeProperty = collisionShapeProperty.getPropertyByID(Properties::Size);
  732. // If the size was not given, leave it to a default radius of 0.5f (which makes the sphere diameter equal to 1.0)
  733. if(sizeProperty)
  734. p_constructionInfo.m_rigidBodyConstructionInfo->m_collisionShapeSize = sizeProperty.getVec3f();
  735. else
  736. ErrHandlerLoc().get().log(ErrorCode::Property_missing_radius, p_name, ErrorSource::Source_RigidBodyComponent);
  737. p_constructionInfo.m_rigidBodyConstructionInfo->m_collisionShapeType = RigidBodyComponent::CollisionShapeType::CollisionShapeType_Sphere;
  738. }
  739. break;
  740. default:
  741. // If this is reached, the collision shape type was not valid
  742. ErrHandlerLoc().get().log(ErrorCode::Collision_invalid, p_name, ErrorSource::Source_RigidBodyComponent);
  743. break;
  744. }
  745. }
  746. else
  747. {
  748. // Missing the Type property entirely
  749. ErrHandlerLoc().get().log(ErrorCode::Property_missing_type, p_name, ErrorSource::Source_RigidBodyComponent);
  750. }
  751. }
  752. // -----------------------------
  753. // Load individual property data
  754. // -----------------------------
  755. for(decltype(p_properties.getNumProperties()) i = 0, size = p_properties.getNumProperties(); i < size; i++)
  756. {
  757. switch(p_properties[i].getPropertyID())
  758. {
  759. case Properties::Friction:
  760. p_constructionInfo.m_rigidBodyConstructionInfo->m_friction = p_properties[i].getFloat();
  761. break;
  762. case Properties::Kinematic:
  763. p_constructionInfo.m_rigidBodyConstructionInfo->m_kinematic = p_properties[i].getBool();
  764. break;
  765. case Properties::Mass:
  766. p_constructionInfo.m_rigidBodyConstructionInfo->m_mass = p_properties[i].getFloat();
  767. break;
  768. case Properties::Restitution:
  769. p_constructionInfo.m_rigidBodyConstructionInfo->m_restitution = p_properties[i].getFloat();
  770. break;
  771. case Properties::RollingFriction:
  772. p_constructionInfo.m_rigidBodyConstructionInfo->m_rollingFriction = p_properties[i].getFloat();
  773. break;
  774. case Properties::SpinningFriction:
  775. p_constructionInfo.m_rigidBodyConstructionInfo->m_spinningFriction = p_properties[i].getFloat();
  776. break;
  777. case Properties::Velocity:
  778. p_constructionInfo.m_rigidBodyConstructionInfo->m_linearVelocity = p_properties[i].getVec3f();
  779. break;
  780. }
  781. }
  782. }
  783. break;
  784. }
  785. }
  786. }
  787. void SceneLoader::importFromProperties(ScriptComponentsConstructionInfo &p_constructionInfo, const PropertySet &p_properties, const std::string &p_name)
  788. {
  789. // Check if property set node is present
  790. if(p_properties)
  791. {
  792. switch(p_properties.getPropertyID())
  793. {
  794. case Properties::PropertyID::LuaComponent:
  795. {
  796. if(p_constructionInfo.m_luaConstructionInfo == nullptr)
  797. p_constructionInfo.m_luaConstructionInfo = new LuaComponent::LuaComponentConstructionInfo();
  798. p_constructionInfo.m_luaConstructionInfo->m_name = p_name + Config::componentVar().component_name_separator + GetString(Properties::PropertyID::LuaComponent);
  799. p_properties.getValueByID(Properties::Active, p_constructionInfo.m_luaConstructionInfo->m_active);
  800. if(auto const &pauseInEditorProperty = p_properties.getPropertyByID(Properties::PauseInEditor); pauseInEditorProperty)
  801. p_constructionInfo.m_luaConstructionInfo->m_pauseInEditor = pauseInEditorProperty.getBool();
  802. auto const &luaFilenameProperty = p_properties.getPropertyByID(Properties::Filename);
  803. auto const &luaVariablesProperty = p_properties.getPropertySetByID(Properties::Variables);
  804. if(luaFilenameProperty)
  805. {
  806. std::string luaFilename = luaFilenameProperty.getString();
  807. if(!luaFilename.empty())
  808. {
  809. p_constructionInfo.m_luaConstructionInfo->m_luaScriptFilename = luaFilename;
  810. if(luaVariablesProperty)
  811. {
  812. // Loop over each variable entry in the node
  813. for(decltype(luaVariablesProperty.getNumPropertySets()) iVariable = 0, numVariables = luaVariablesProperty.getNumPropertySets(); iVariable < numVariables; iVariable++)
  814. {
  815. // Add the variable
  816. p_constructionInfo.m_luaConstructionInfo->m_variables.emplace_back(
  817. luaVariablesProperty.getPropertySet(iVariable).getPropertyByID(Properties::Name).getString(),
  818. luaVariablesProperty.getPropertySet(iVariable).getPropertyByID(Properties::Value));
  819. }
  820. }
  821. }
  822. else
  823. {
  824. ErrHandlerLoc().get().log(ErrorCode::Property_no_filename, p_name, ErrorSource::Source_SceneLoader);
  825. }
  826. }
  827. else
  828. {
  829. ErrHandlerLoc().get().log(ErrorCode::Property_no_filename, p_name, ErrorSource::Source_SceneLoader);
  830. }
  831. }
  832. break;
  833. }
  834. }
  835. }
  836. void SceneLoader::importFromProperties(WorldComponentsConstructionInfo &p_constructionInfo, const PropertySet &p_properties, const std::string &p_name)
  837. {
  838. // Check if property set node is present
  839. if(p_properties)
  840. {
  841. switch(p_properties.getPropertyID())
  842. {
  843. case Properties::PropertyID::ObjectMaterialComponent:
  844. {
  845. if(p_constructionInfo.m_objectMaterialConstructionInfo == nullptr)
  846. p_constructionInfo.m_objectMaterialConstructionInfo = new ObjectMaterialComponent::ObjectMaterialComponentConstructionInfo();
  847. p_constructionInfo.m_objectMaterialConstructionInfo->m_name = p_name + Config::componentVar().component_name_separator + GetString(Properties::PropertyID::ObjectMaterialComponent);
  848. p_properties.getValueByID(Properties::Active, p_constructionInfo.m_objectMaterialConstructionInfo->m_active);
  849. // Get the type property representing the object material type
  850. auto const &typeProperty = p_properties.getPropertyByID(Properties::Type);
  851. // Check if the property exists
  852. if(typeProperty)
  853. {
  854. // Define the type based on the imported property
  855. switch(typeProperty.getID())
  856. {
  857. case Properties::Concrete:
  858. default:
  859. p_constructionInfo.m_objectMaterialConstructionInfo->m_materialType = ObjectMaterialType::Concrete;
  860. break;
  861. case Properties::Glass:
  862. p_constructionInfo.m_objectMaterialConstructionInfo->m_materialType = ObjectMaterialType::Glass;
  863. break;
  864. case Properties::Metal:
  865. p_constructionInfo.m_objectMaterialConstructionInfo->m_materialType = ObjectMaterialType::Metal;
  866. break;
  867. case Properties::Plastic:
  868. p_constructionInfo.m_objectMaterialConstructionInfo->m_materialType = ObjectMaterialType::Plastic;
  869. break;
  870. case Properties::Rock:
  871. p_constructionInfo.m_objectMaterialConstructionInfo->m_materialType = ObjectMaterialType::Rock;
  872. break;
  873. case Properties::Rubber:
  874. p_constructionInfo.m_objectMaterialConstructionInfo->m_materialType = ObjectMaterialType::Rubber;
  875. break;
  876. case Properties::Wood:
  877. p_constructionInfo.m_objectMaterialConstructionInfo->m_materialType = ObjectMaterialType::Wood;
  878. break;
  879. // If this is reached, the object material type was not valid
  880. ErrHandlerLoc().get().log(ErrorCode::Property_missing_type, p_name, ErrorSource::Source_ObjectMaterialComponent);
  881. break;
  882. }
  883. }
  884. else
  885. {
  886. // Missing the Type property entirely
  887. ErrHandlerLoc().get().log(ErrorCode::Property_missing_type, p_name, ErrorSource::Source_ObjectMaterialComponent);
  888. }
  889. }
  890. break;
  891. case Properties::PropertyID::SpatialComponent:
  892. {
  893. if(p_constructionInfo.m_spatialConstructionInfo == nullptr)
  894. p_constructionInfo.m_spatialConstructionInfo = new SpatialComponent::SpatialComponentConstructionInfo();
  895. p_constructionInfo.m_spatialConstructionInfo->m_name = p_name + Config::componentVar().component_name_separator + GetString(Properties::PropertyID::SpatialComponent);
  896. p_properties.getValueByID(Properties::Active, p_constructionInfo.m_spatialConstructionInfo->m_active);
  897. // Load property data
  898. for(decltype(p_properties.getNumProperties()) i = 0, size = p_properties.getNumProperties(); i < size; i++)
  899. {
  900. switch(p_properties[i].getPropertyID())
  901. {
  902. case Properties::LocalPosition:
  903. p_constructionInfo.m_spatialConstructionInfo->m_localPosition = p_properties[i].getVec3f();
  904. break;
  905. case Properties::LocalRotation:
  906. p_constructionInfo.m_spatialConstructionInfo->m_localRotationEuler = p_properties[i].getVec3f();
  907. break;
  908. case Properties::LocalRotationQuaternion:
  909. p_constructionInfo.m_spatialConstructionInfo->m_localRotationQuaternion = Math::toGlmQuat(p_properties[i].getVec4f());
  910. break;
  911. case Properties::LocalScale:
  912. p_constructionInfo.m_spatialConstructionInfo->m_localScale = p_properties[i].getVec3f();
  913. break;
  914. }
  915. }
  916. }
  917. break;
  918. }
  919. }
  920. }
  921. void SceneLoader::exportToProperties(const ComponentsConstructionInfo &p_constructionInfo, PropertySet &p_properties)
  922. {
  923. p_properties.addProperty(Properties::PropertyID::Name, p_constructionInfo.m_name);
  924. p_properties.addProperty(Properties::PropertyID::ID, (int)p_constructionInfo.m_id);
  925. p_properties.addProperty(Properties::PropertyID::Parent, (int)p_constructionInfo.m_parent);
  926. if(!p_constructionInfo.m_prefab.empty())
  927. p_properties.addProperty(Properties::PropertyID::Prefab, p_constructionInfo.m_prefab);
  928. // Export audio components
  929. exportToProperties(p_constructionInfo.m_audioComponents, p_properties);
  930. // Export graphics components
  931. exportToProperties(p_constructionInfo.m_graphicsComponents, p_properties);
  932. // Export GUI components
  933. exportToProperties(p_constructionInfo.m_guiComponents, p_properties);
  934. // Export physics components
  935. exportToProperties(p_constructionInfo.m_physicsComponents, p_properties);
  936. // Export script components
  937. exportToProperties(p_constructionInfo.m_scriptComponents, p_properties);
  938. // Export world components
  939. exportToProperties(p_constructionInfo.m_worldComponents, p_properties);
  940. }
  941. void SceneLoader::exportToProperties(const AudioComponentsConstructionInfo &p_constructionInfo, PropertySet &p_properties)
  942. {
  943. if( p_constructionInfo.m_soundConstructionInfo != nullptr ||
  944. p_constructionInfo.m_soundListenerConstructionInfo != nullptr)
  945. {
  946. // Add Audio entry
  947. auto &propertySet = p_properties.addPropertySet(Properties::PropertyID::Audio);
  948. // Export SoundComponent
  949. if(p_constructionInfo.m_soundConstructionInfo != nullptr)
  950. {
  951. // Convert SoundSourceType to PropertyID
  952. Properties::PropertyID soundSourceType = Properties::PropertyID::File;
  953. switch(p_constructionInfo.m_soundConstructionInfo->m_soundSourceType)
  954. {
  955. case SoundComponent::SoundSourceType::SoundSourceType_Event:
  956. soundSourceType = Properties::PropertyID::Event;
  957. break;
  958. case SoundComponent::SoundSourceType::SoundSourceType_File:
  959. soundSourceType = Properties::PropertyID::File;
  960. break;
  961. }
  962. // Convert SoundType to PropertyID
  963. Properties::PropertyID soundType = Properties::PropertyID::SoundEffect;
  964. switch(p_constructionInfo.m_soundConstructionInfo->m_soundType)
  965. {
  966. case SoundComponent::SoundType::SoundType_Ambient:
  967. soundType = Properties::PropertyID::Ambient;
  968. break;
  969. case SoundComponent::SoundType::SoundType_Music:
  970. soundType = Properties::PropertyID::Music;
  971. break;
  972. case SoundComponent::SoundType::SoundType_SoundEffect:
  973. soundType = Properties::PropertyID::SoundEffect;
  974. break;
  975. }
  976. // Add SoundComponent entry
  977. auto &componentPropertySet = propertySet.addPropertySet(Properties::PropertyID::SoundComponent);
  978. // Add SoundComponent properties
  979. componentPropertySet.addProperty(Properties::PropertyID::Active, p_constructionInfo.m_soundConstructionInfo->m_active);
  980. componentPropertySet.addProperty(Properties::PropertyID::Loop, p_constructionInfo.m_soundConstructionInfo->m_loop);
  981. componentPropertySet.addProperty(Properties::PropertyID::Name, p_constructionInfo.m_soundConstructionInfo->m_soundName);
  982. componentPropertySet.addProperty(Properties::PropertyID::Source, soundSourceType);
  983. componentPropertySet.addProperty(Properties::PropertyID::Spatialized, p_constructionInfo.m_soundConstructionInfo->m_spatialized);
  984. componentPropertySet.addProperty(Properties::PropertyID::StartPlaying, p_constructionInfo.m_soundConstructionInfo->m_startPlaying);
  985. componentPropertySet.addProperty(Properties::PropertyID::Type, soundType);
  986. componentPropertySet.addProperty(Properties::PropertyID::Volume, p_constructionInfo.m_soundConstructionInfo->m_volume);
  987. }
  988. // Export SoundListenerComponent
  989. if(p_constructionInfo.m_soundListenerConstructionInfo != nullptr)
  990. {
  991. // Add SoundListenerComponent entry
  992. auto &componentPropertySet = propertySet.addPropertySet(Properties::PropertyID::SoundListenerComponent);
  993. // Add SoundListenerComponent properties
  994. componentPropertySet.addProperty(Properties::PropertyID::Active, p_constructionInfo.m_soundListenerConstructionInfo->m_active);
  995. componentPropertySet.addProperty(Properties::PropertyID::ID, p_constructionInfo.m_soundListenerConstructionInfo->m_listenerID);
  996. }
  997. }
  998. }
  999. void SceneLoader::exportToProperties(const GraphicsComponentsConstructionInfo &p_constructionInfo, PropertySet &p_properties)
  1000. {
  1001. if(p_constructionInfo.m_cameraConstructionInfo != nullptr ||
  1002. p_constructionInfo.m_lightConstructionInfo != nullptr ||
  1003. p_constructionInfo.m_modelConstructionInfo != nullptr ||
  1004. p_constructionInfo.m_shaderConstructionInfo != nullptr)
  1005. {
  1006. auto &propertySet = p_properties.addPropertySet(Properties::PropertyID::Graphics);
  1007. // Export CameraComponent
  1008. if(p_constructionInfo.m_cameraConstructionInfo != nullptr)
  1009. {
  1010. auto &componentPropertySet = propertySet.addPropertySet(Properties::PropertyID::CameraComponent);
  1011. componentPropertySet.addProperty(Properties::PropertyID::Active, p_constructionInfo.m_cameraConstructionInfo->m_active);
  1012. componentPropertySet.addProperty(Properties::PropertyID::CameraID, p_constructionInfo.m_cameraConstructionInfo->m_cameraID);
  1013. componentPropertySet.addProperty(Properties::PropertyID::FOV, p_constructionInfo.m_cameraConstructionInfo->m_fov);
  1014. componentPropertySet.addProperty(Properties::PropertyID::ZFar, p_constructionInfo.m_cameraConstructionInfo->m_zFar);
  1015. componentPropertySet.addProperty(Properties::PropertyID::ZNear, p_constructionInfo.m_cameraConstructionInfo->m_zNear);
  1016. }
  1017. // Export LightComponent
  1018. if(p_constructionInfo.m_lightConstructionInfo != nullptr)
  1019. {
  1020. auto &componentPropertySet = propertySet.addPropertySet(Properties::PropertyID::LightComponent);
  1021. componentPropertySet.addProperty(Properties::PropertyID::Active, p_constructionInfo.m_lightConstructionInfo->m_active);
  1022. switch(p_constructionInfo.m_lightConstructionInfo->m_lightComponentType)
  1023. {
  1024. case LightComponent::LightComponentType::LightComponentType_directional:
  1025. componentPropertySet.addProperty(Properties::PropertyID::Type, Properties::PropertyID::DirectionalLight);
  1026. componentPropertySet.addProperty(Properties::PropertyID::Color, p_constructionInfo.m_lightConstructionInfo->m_color);
  1027. componentPropertySet.addProperty(Properties::PropertyID::Intensity, p_constructionInfo.m_lightConstructionInfo->m_intensity);
  1028. break;
  1029. case LightComponent::LightComponentType::LightComponentType_point:
  1030. componentPropertySet.addProperty(Properties::PropertyID::Type, Properties::PropertyID::PointLight);
  1031. componentPropertySet.addProperty(Properties::PropertyID::Color, p_constructionInfo.m_lightConstructionInfo->m_color);
  1032. componentPropertySet.addProperty(Properties::PropertyID::Intensity, p_constructionInfo.m_lightConstructionInfo->m_intensity);
  1033. break;
  1034. case LightComponent::LightComponentType::LightComponentType_spot:
  1035. componentPropertySet.addProperty(Properties::PropertyID::Type, Properties::PropertyID::SpotLight);
  1036. componentPropertySet.addProperty(Properties::PropertyID::Color, p_constructionInfo.m_lightConstructionInfo->m_color);
  1037. componentPropertySet.addProperty(Properties::PropertyID::Intensity, p_constructionInfo.m_lightConstructionInfo->m_intensity);
  1038. componentPropertySet.addProperty(Properties::PropertyID::CutoffAngle, p_constructionInfo.m_lightConstructionInfo->m_cutoffAngle);
  1039. break;
  1040. }
  1041. }
  1042. // Export ModelComponent
  1043. if(p_constructionInfo.m_modelConstructionInfo != nullptr)
  1044. {
  1045. // Create ModelComponent entry
  1046. auto &componentPropertySet = propertySet.addPropertySet(Properties::PropertyID::ModelComponent);
  1047. // Add active flag
  1048. componentPropertySet.addProperty(Properties::PropertyID::Active, p_constructionInfo.m_modelConstructionInfo->m_active);
  1049. // Create Models entry
  1050. auto &modelsPropertySet = componentPropertySet.addPropertySet(Properties::PropertyID::Models);
  1051. // Go over each model
  1052. for(auto &model : p_constructionInfo.m_modelConstructionInfo->m_modelsProperties.m_models)
  1053. {
  1054. auto &modelPropertyArrayEntry = modelsPropertySet.addPropertySet(Properties::ArrayEntry);
  1055. // Add model data
  1056. modelPropertyArrayEntry.addProperty(Properties::PropertyID::Filename, model.m_modelName);
  1057. // Create Meshes entry
  1058. auto &meshesPropertySet = modelPropertyArrayEntry.addPropertySet(Properties::PropertyID::Meshes);
  1059. // Go over each mesh
  1060. for(decltype(model.m_meshData.size()) i = 0, size = model.m_meshData.size(); i < size; i++)
  1061. {
  1062. // Make sure the mesh data is present
  1063. if(model.m_meshData[i].m_present)
  1064. {
  1065. auto &meshPropertyArrayEntry = meshesPropertySet.addPropertySet(Properties::ArrayEntry);
  1066. // Add mesh data
  1067. meshPropertyArrayEntry.addProperty(Properties::PropertyID::Index, (int)i);
  1068. meshPropertyArrayEntry.addProperty(Properties::PropertyID::Active, model.m_meshData[i].m_active);
  1069. meshPropertyArrayEntry.addProperty(Properties::PropertyID::AlphaThreshold, model.m_meshData[i].m_alphaThreshold);
  1070. meshPropertyArrayEntry.addProperty(Properties::PropertyID::EmissiveIntensity, model.m_meshData[i].m_emissiveIntensity);
  1071. meshPropertyArrayEntry.addProperty(Properties::PropertyID::HeightScale, model.m_meshData[i].m_heightScale);
  1072. meshPropertyArrayEntry.addProperty(Properties::PropertyID::StochasticSampling, model.m_meshData[i].m_stochasticSampling);
  1073. meshPropertyArrayEntry.addProperty(Properties::PropertyID::StochasticSamplingScale, model.m_meshData[i].m_stochasticSamplingScale);
  1074. switch(model.m_meshData[i].m_textureWrapMode)
  1075. {
  1076. case TextureWrapType::TextureWrapType_ClampToBorder:
  1077. meshPropertyArrayEntry.addProperty(Properties::PropertyID::WrapMode, Properties::PropertyID::ClampToBorder);
  1078. break;
  1079. case TextureWrapType::TextureWrapType_ClampToEdge:
  1080. meshPropertyArrayEntry.addProperty(Properties::PropertyID::WrapMode, Properties::PropertyID::ClampToEdge);
  1081. break;
  1082. case TextureWrapType::TextureWrapType_MirroredClampToEdge:
  1083. meshPropertyArrayEntry.addProperty(Properties::PropertyID::WrapMode, Properties::PropertyID::MirroredClampToEdge);
  1084. break;
  1085. case TextureWrapType::TextureWrapType_MirroredRepeat:
  1086. meshPropertyArrayEntry.addProperty(Properties::PropertyID::WrapMode, Properties::PropertyID::MirroredRepeat);
  1087. break;
  1088. case TextureWrapType::TextureWrapType_Repeat:
  1089. meshPropertyArrayEntry.addProperty(Properties::PropertyID::WrapMode, Properties::PropertyID::Repeat);
  1090. break;
  1091. }
  1092. auto &materialsPropertySet = meshPropertyArrayEntry.addPropertySet(Properties::Materials);
  1093. // Go over each material
  1094. for(unsigned int materialType = 0; materialType < MaterialType::MaterialType_NumOfTypes; materialType++)
  1095. {
  1096. // Make sure the material filename is not empty
  1097. if(!model.m_meshData[i].m_meshMaterials[materialType].empty())
  1098. {
  1099. Properties::PropertyID materialPropertyID = Properties::Null;
  1100. // Convert MaterialType to PropertyID
  1101. switch(materialType)
  1102. {
  1103. case MaterialType_Diffuse:
  1104. materialPropertyID = Properties::Diffuse;
  1105. break;
  1106. case MaterialType_Normal:
  1107. materialPropertyID = Properties::Normal;
  1108. break;
  1109. case MaterialType_Emissive:
  1110. materialPropertyID = Properties::Emissive;
  1111. break;
  1112. case MaterialType_Combined:
  1113. materialPropertyID = Properties::RMHAO;
  1114. break;
  1115. }
  1116. auto &materialPropertySet = materialsPropertySet.addPropertySet(materialPropertyID);
  1117. // Add material data
  1118. materialPropertySet.addProperty(Properties::PropertyID::Filename, model.m_meshData[i].m_meshMaterials[materialType]);
  1119. materialPropertySet.addProperty(Properties::PropertyID::TextureScale, model.m_meshData[i].m_meshMaterialsScales[materialType]);
  1120. }
  1121. }
  1122. }
  1123. }
  1124. }
  1125. }
  1126. // Export ShaderComponent
  1127. if(p_constructionInfo.m_shaderConstructionInfo != nullptr)
  1128. {
  1129. auto &componentPropertySet = propertySet.addPropertySet(Properties::PropertyID::ShaderComponent);
  1130. componentPropertySet.addProperty(Properties::PropertyID::Active, p_constructionInfo.m_shaderConstructionInfo->m_active);
  1131. // Add shader data, making sure isn't not empty before adding it
  1132. if(!p_constructionInfo.m_shaderConstructionInfo->m_fragmentShaderFilename.empty())
  1133. componentPropertySet.addProperty(Properties::PropertyID::FragmentShader, p_constructionInfo.m_shaderConstructionInfo->m_fragmentShaderFilename);
  1134. if(!p_constructionInfo.m_shaderConstructionInfo->m_vetexShaderFilename.empty())
  1135. componentPropertySet.addProperty(Properties::PropertyID::VertexShader, p_constructionInfo.m_shaderConstructionInfo->m_vetexShaderFilename);
  1136. if(!p_constructionInfo.m_shaderConstructionInfo->m_geometryShaderFilename.empty())
  1137. componentPropertySet.addProperty(Properties::PropertyID::GeometryShader, p_constructionInfo.m_shaderConstructionInfo->m_geometryShaderFilename);
  1138. }
  1139. }
  1140. }
  1141. void SceneLoader::exportToProperties(const GUIComponentsConstructionInfo &p_constructionInfo, PropertySet &p_properties)
  1142. {
  1143. if(p_constructionInfo.m_guiSequenceConstructionInfo != nullptr)
  1144. {
  1145. auto &propertySet = p_properties.addPropertySet(Properties::PropertyID::GUI);
  1146. // Export GUISequenceComponent
  1147. if(p_constructionInfo.m_guiSequenceConstructionInfo != nullptr)
  1148. {
  1149. auto &componentPropertySet = propertySet.addPropertySet(Properties::PropertyID::GUISequenceComponent);
  1150. // Add GUI sequence data
  1151. componentPropertySet.addProperty(Properties::PropertyID::Active, p_constructionInfo.m_guiSequenceConstructionInfo->m_active);
  1152. componentPropertySet.addProperty(Properties::PropertyID::Static, p_constructionInfo.m_guiSequenceConstructionInfo->m_staticSequence);
  1153. }
  1154. }
  1155. }
  1156. void SceneLoader::exportToProperties(const PhysicsComponentsConstructionInfo &p_constructionInfo, PropertySet &p_properties)
  1157. {
  1158. if(p_constructionInfo.m_rigidBodyConstructionInfo != nullptr)
  1159. {
  1160. auto &propertySet = p_properties.addPropertySet(Properties::PropertyID::Physics);
  1161. // Export RigidBodyComponent
  1162. if(p_constructionInfo.m_rigidBodyConstructionInfo != nullptr)
  1163. {
  1164. auto &componentPropertySet = propertySet.addPropertySet(Properties::PropertyID::RigidBodyComponent);
  1165. // Add rigid body data
  1166. componentPropertySet.addProperty(Properties::PropertyID::Active, p_constructionInfo.m_rigidBodyConstructionInfo->m_active);
  1167. componentPropertySet.addProperty(Properties::PropertyID::Friction, p_constructionInfo.m_rigidBodyConstructionInfo->m_friction);
  1168. componentPropertySet.addProperty(Properties::PropertyID::Kinematic, p_constructionInfo.m_rigidBodyConstructionInfo->m_kinematic);
  1169. componentPropertySet.addProperty(Properties::PropertyID::Mass, p_constructionInfo.m_rigidBodyConstructionInfo->m_mass);
  1170. componentPropertySet.addProperty(Properties::PropertyID::Restitution, p_constructionInfo.m_rigidBodyConstructionInfo->m_restitution);
  1171. componentPropertySet.addProperty(Properties::PropertyID::RollingFriction, p_constructionInfo.m_rigidBodyConstructionInfo->m_rollingFriction);
  1172. componentPropertySet.addProperty(Properties::PropertyID::SpinningFriction, p_constructionInfo.m_rigidBodyConstructionInfo->m_spinningFriction);
  1173. // Convert CollisionShapeType to PropertyID
  1174. Properties::PropertyID collisionShapeType = Properties::Null;
  1175. switch(p_constructionInfo.m_rigidBodyConstructionInfo->m_collisionShapeType)
  1176. {
  1177. case RigidBodyComponent::CollisionShapeType_Box:
  1178. collisionShapeType = Properties::Box;
  1179. break;
  1180. case RigidBodyComponent::CollisionShapeType_Capsule:
  1181. collisionShapeType = Properties::Capsule;
  1182. break;
  1183. case RigidBodyComponent::CollisionShapeType_Cone:
  1184. collisionShapeType = Properties::Cone;
  1185. break;
  1186. case RigidBodyComponent::CollisionShapeType_ConvexHull:
  1187. collisionShapeType = Properties::ConvexHull;
  1188. break;
  1189. case RigidBodyComponent::CollisionShapeType_Cylinder:
  1190. collisionShapeType = Properties::Cylinder;
  1191. break;
  1192. case RigidBodyComponent::CollisionShapeType_Sphere:
  1193. collisionShapeType = Properties::Sphere;
  1194. break;
  1195. }
  1196. // Add collision shape data, if it's valid
  1197. if(collisionShapeType != Properties::Null)
  1198. {
  1199. auto &collisionShapePropertySet = componentPropertySet.addPropertySet(Properties::PropertyID::CollisionShape);
  1200. collisionShapePropertySet.addProperty(Properties::PropertyID::Type, collisionShapeType);
  1201. collisionShapePropertySet.addProperty(Properties::PropertyID::Size, p_constructionInfo.m_rigidBodyConstructionInfo->m_collisionShapeSize);
  1202. }
  1203. }
  1204. }
  1205. }
  1206. void SceneLoader::exportToProperties(const ScriptComponentsConstructionInfo &p_constructionInfo, PropertySet &p_properties)
  1207. {
  1208. if(p_constructionInfo.m_luaConstructionInfo != nullptr)
  1209. {
  1210. auto &propertySet = p_properties.addPropertySet(Properties::PropertyID::Script);
  1211. // Export LuaComponent
  1212. if(p_constructionInfo.m_luaConstructionInfo != nullptr)
  1213. {
  1214. auto &componentPropertySet = propertySet.addPropertySet(Properties::PropertyID::LuaComponent);
  1215. // Add pause-in-editor flag
  1216. componentPropertySet.addProperty(Properties::PropertyID::PauseInEditor, p_constructionInfo.m_luaConstructionInfo->m_pauseInEditor);
  1217. // Add LUA component data
  1218. if(!p_constructionInfo.m_luaConstructionInfo->m_luaScriptFilename.empty())
  1219. {
  1220. componentPropertySet.addProperty(Properties::PropertyID::Active, p_constructionInfo.m_luaConstructionInfo->m_active);
  1221. componentPropertySet.addProperty(Properties::PropertyID::Filename, p_constructionInfo.m_luaConstructionInfo->m_luaScriptFilename);
  1222. if(!p_constructionInfo.m_luaConstructionInfo->m_variables.empty())
  1223. {
  1224. auto &variablesPropertySet = componentPropertySet.addPropertySet(Properties::PropertyID::Variables);
  1225. // Go over each variable
  1226. for(auto &variable : p_constructionInfo.m_luaConstructionInfo->m_variables)
  1227. {
  1228. // Make sure variable type is valid
  1229. if(variable.second.getVariableType() != Property::PropertyVariableType::Type_null)
  1230. {
  1231. auto &variableArrayEntry = variablesPropertySet.addPropertySet(Properties::PropertyID::ArrayEntry);
  1232. // Add variable data
  1233. variableArrayEntry.addProperty(Properties::PropertyID::Name, variable.first);
  1234. // Add the appropriate data based on the variable's data type
  1235. switch(variable.second.getVariableType())
  1236. {
  1237. case Property::PropertyVariableType::Type_bool:
  1238. variableArrayEntry.addProperty(Properties::PropertyID::Value, variable.second.getBool());
  1239. break;
  1240. case Property::PropertyVariableType::Type_int:
  1241. variableArrayEntry.addProperty(Properties::PropertyID::Value, variable.second.getInt());
  1242. break;
  1243. case Property::PropertyVariableType::Type_float:
  1244. variableArrayEntry.addProperty(Properties::PropertyID::Value, variable.second.getFloat());
  1245. break;
  1246. case Property::PropertyVariableType::Type_double:
  1247. variableArrayEntry.addProperty(Properties::PropertyID::Value, variable.second.getDouble());
  1248. break;
  1249. case Property::PropertyVariableType::Type_vec2i:
  1250. variableArrayEntry.addProperty(Properties::PropertyID::Value, variable.second.getVec2i());
  1251. break;
  1252. case Property::PropertyVariableType::Type_vec2f:
  1253. variableArrayEntry.addProperty(Properties::PropertyID::Value, variable.second.getVec2f());
  1254. break;
  1255. case Property::PropertyVariableType::Type_vec3f:
  1256. variableArrayEntry.addProperty(Properties::PropertyID::Value, variable.second.getVec3f());
  1257. break;
  1258. case Property::PropertyVariableType::Type_vec4f:
  1259. variableArrayEntry.addProperty(Properties::PropertyID::Value, variable.second.getVec4f());
  1260. break;
  1261. case Property::PropertyVariableType::Type_string:
  1262. variableArrayEntry.addProperty(Properties::PropertyID::Value, variable.second.getString());
  1263. break;
  1264. case Property::PropertyVariableType::Type_propertyID:
  1265. variableArrayEntry.addProperty(Properties::PropertyID::Value, variable.second.getID());
  1266. break;
  1267. }
  1268. }
  1269. }
  1270. }
  1271. }
  1272. }
  1273. }
  1274. std::string m_luaScriptFilename;
  1275. std::vector<std::pair<std::string, Property>> m_variables;
  1276. }
  1277. void SceneLoader::exportToProperties(const WorldComponentsConstructionInfo &p_constructionInfo, PropertySet &p_properties)
  1278. {
  1279. if( p_constructionInfo.m_objectMaterialConstructionInfo != nullptr ||
  1280. p_constructionInfo.m_spatialConstructionInfo != nullptr)
  1281. {
  1282. auto &propertySet = p_properties.addPropertySet(Properties::PropertyID::World);
  1283. // Export ObjectMaterialComponent
  1284. if(p_constructionInfo.m_objectMaterialConstructionInfo != nullptr)
  1285. {
  1286. // Convert ObjectMaterialType to PropertyID
  1287. Properties::PropertyID objectMaterialType = Properties::Null;
  1288. switch(p_constructionInfo.m_objectMaterialConstructionInfo->m_materialType)
  1289. {
  1290. case Concrete:
  1291. objectMaterialType = Properties::Concrete;
  1292. break;
  1293. case Glass:
  1294. objectMaterialType = Properties::Glass;
  1295. break;
  1296. case Metal:
  1297. objectMaterialType = Properties::Metal;
  1298. break;
  1299. case Plastic:
  1300. objectMaterialType = Properties::Plastic;
  1301. break;
  1302. case Rock:
  1303. objectMaterialType = Properties::Rock;
  1304. break;
  1305. case Rubber:
  1306. objectMaterialType = Properties::Rubber;
  1307. break;
  1308. case Wood:
  1309. objectMaterialType = Properties::Wood;
  1310. break;
  1311. }
  1312. // Add object material data, if it's valid
  1313. if(objectMaterialType != Properties::Null)
  1314. {
  1315. auto &componentPropertySet = propertySet.addPropertySet(Properties::PropertyID::ObjectMaterialComponent);
  1316. componentPropertySet.addProperty(Properties::PropertyID::Active, p_constructionInfo.m_objectMaterialConstructionInfo->m_active);
  1317. componentPropertySet.addProperty(Properties::PropertyID::Type, objectMaterialType);
  1318. }
  1319. }
  1320. // Export SpatialComponent
  1321. if(p_constructionInfo.m_spatialConstructionInfo != nullptr)
  1322. {
  1323. auto &componentPropertySet = propertySet.addPropertySet(Properties::PropertyID::SpatialComponent);
  1324. // Add spatial data
  1325. componentPropertySet.addProperty(Properties::PropertyID::Active, p_constructionInfo.m_spatialConstructionInfo->m_active);
  1326. componentPropertySet.addProperty(Properties::PropertyID::LocalPosition, p_constructionInfo.m_spatialConstructionInfo->m_localPosition);
  1327. componentPropertySet.addProperty(Properties::PropertyID::LocalRotation, p_constructionInfo.m_spatialConstructionInfo->m_localRotationEuler);
  1328. componentPropertySet.addProperty(Properties::PropertyID::LocalRotationQuaternion, Math::toGlmVec4(p_constructionInfo.m_spatialConstructionInfo->m_localRotationQuaternion));
  1329. componentPropertySet.addProperty(Properties::PropertyID::LocalScale, p_constructionInfo.m_spatialConstructionInfo->m_localScale);
  1330. }
  1331. }
  1332. }