LevelAsset.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2013 GarageGames, LLC
  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
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell 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
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #ifndef LEVEL_ASSET_H
  23. #include "LevelAsset.h"
  24. #endif
  25. #ifndef _ASSET_MANAGER_H_
  26. #include "assets/assetManager.h"
  27. #endif
  28. #ifndef _CONSOLETYPES_H_
  29. #include "console/consoleTypes.h"
  30. #endif
  31. #ifndef _TAML_
  32. #include "persistence/taml/taml.h"
  33. #endif
  34. #ifndef _ASSET_PTR_H_
  35. #include "assets/assetPtr.h"
  36. #endif
  37. // Debug Profiling.
  38. #include "platform/profiler.h"
  39. #include "gfx/gfxDrawUtil.h"
  40. #include "T3D/SubScene.h"
  41. //-----------------------------------------------------------------------------
  42. IMPLEMENT_CONOBJECT(LevelAsset);
  43. ConsoleType(LevelAssetPtr, TypeLevelAssetPtr, const char*, "")
  44. //-----------------------------------------------------------------------------
  45. ConsoleGetType(TypeLevelAssetPtr)
  46. {
  47. // Fetch asset Id.
  48. return *((const char**)(dptr));
  49. }
  50. //-----------------------------------------------------------------------------
  51. ConsoleSetType(TypeLevelAssetPtr)
  52. {
  53. // Was a single argument specified?
  54. if (argc == 1)
  55. {
  56. // Yes, so fetch field value.
  57. *((const char**)dptr) = StringTable->insert(argv[0]);
  58. return;
  59. }
  60. // Warn.
  61. Con::warnf("(TypeLevelAssetPtr) - Cannot set multiple args to a single asset.");
  62. }
  63. //-----------------------------------------------------------------------------
  64. ConsoleType(assetIdString, TypeLevelAssetId, const char*, "")
  65. ConsoleGetType(TypeLevelAssetId)
  66. {
  67. // Fetch asset Id.
  68. return *((const char**)(dptr));
  69. }
  70. ConsoleSetType(TypeLevelAssetId)
  71. {
  72. // Was a single argument specified?
  73. if (argc == 1)
  74. {
  75. *((const char**)dptr) = StringTable->insert(argv[0]);
  76. return;
  77. }
  78. // Warn.
  79. Con::warnf("(TypeLevelAssetId) - Cannot set multiple args to a single asset.");
  80. }
  81. //-----------------------------------------------------------------------------
  82. LevelAsset::LevelAsset() : AssetBase(), mIsSubLevel(false)
  83. {
  84. mLevelName = StringTable->EmptyString();
  85. mLevelFile = StringTable->EmptyString();
  86. mPostFXPresetFile = StringTable->EmptyString();
  87. mDecalsFile = StringTable->EmptyString();
  88. mForestFile = StringTable->EmptyString();
  89. mNavmeshFile = StringTable->EmptyString();
  90. mLevelPath = StringTable->EmptyString();
  91. mPostFXPresetPath = StringTable->EmptyString();
  92. mDecalsPath = StringTable->EmptyString();
  93. mForestPath = StringTable->EmptyString();
  94. mNavmeshPath = StringTable->EmptyString();
  95. mGameModesNames = StringTable->EmptyString();
  96. mMainLevelAsset = StringTable->EmptyString();
  97. mEditorFile = StringTable->EmptyString();
  98. mBakedSceneFile = StringTable->EmptyString();
  99. mPreviewImageAssetId = StringTable->EmptyString();
  100. mPreviewImageAsset = StringTable->EmptyString();
  101. }
  102. //-----------------------------------------------------------------------------
  103. LevelAsset::~LevelAsset()
  104. {
  105. }
  106. //-----------------------------------------------------------------------------
  107. void LevelAsset::initPersistFields()
  108. {
  109. docsURL;
  110. // Call parent.
  111. Parent::initPersistFields();
  112. addProtectedField("LevelFile", TypeAssetLooseFilePath, Offset(mLevelFile, LevelAsset),
  113. &setLevelFile, &getLevelFile, "Path to the actual level file.");
  114. addField("LevelName", TypeString, Offset(mLevelName, LevelAsset), "Human-friendly name for the level.");
  115. addProtectedField("PostFXPresetFile", TypeAssetLooseFilePath, Offset(mPostFXPresetFile, LevelAsset),
  116. &setPostFXPresetFile, &getPostFXPresetFile, "Path to the level's postFXPreset.");
  117. addProtectedField("DecalsFile", TypeAssetLooseFilePath, Offset(mDecalsFile, LevelAsset),
  118. &setDecalsFile, &getDecalsFile, "Path to the decals cache file.");
  119. addProtectedField("ForestFile", TypeAssetLooseFilePath, Offset(mForestFile, LevelAsset),
  120. &setForestFile, &getForestFile, "Path to the Forest cache file.");
  121. addProtectedField("NavmeshFile", TypeAssetLooseFilePath, Offset(mNavmeshFile, LevelAsset),
  122. &setNavmeshFile, &getNavmeshFile, "Path to the navmesh file.");
  123. addProtectedField("EditorFile", TypeAssetLooseFilePath, Offset(mEditorFile, LevelAsset),
  124. &setEditorFile, &getEditorFile, "Path to the level file with objects that were removed as part of the baking process. Loaded when the editor is loaded for ease of editing.");
  125. addProtectedField("BakedSceneFile", TypeAssetLooseFilePath, Offset(mBakedSceneFile, LevelAsset),
  126. &setBakedSceneFile, &getBakedSceneFile, "Path to the level file with the objects generated as part of the baking process");
  127. addField("isSubScene", TypeBool, Offset(mIsSubLevel, LevelAsset), "Is this a sublevel to another Scene");
  128. addField("gameModesNames", TypeString, Offset(mGameModesNames, LevelAsset), "Name of the Game Mode to be used with this level");
  129. }
  130. //------------------------------------------------------------------------------
  131. void LevelAsset::copyTo(SimObject* object)
  132. {
  133. // Call to parent.
  134. Parent::copyTo(object);
  135. }
  136. //
  137. void LevelAsset::initializeAsset()
  138. {
  139. // Call parent.
  140. Parent::initializeAsset();
  141. loadAsset();
  142. }
  143. void LevelAsset::onAssetRefresh(void)
  144. {
  145. loadAsset();
  146. }
  147. void LevelAsset::loadAsset()
  148. {
  149. // Ensure the image-file is expanded.
  150. mLevelPath = getOwned() ? expandAssetFilePath(mLevelFile) : mLevelPath;
  151. mPostFXPresetPath = getOwned() ? expandAssetFilePath(mPostFXPresetFile) : mPostFXPresetPath;
  152. mDecalsPath = getOwned() ? expandAssetFilePath(mDecalsFile) : mDecalsPath;
  153. mForestPath = getOwned() ? expandAssetFilePath(mForestFile) : mForestPath;
  154. mNavmeshPath = getOwned() ? expandAssetFilePath(mNavmeshFile) : mNavmeshPath;
  155. StringTableEntry previewImageAssetId = getAssetDependencyField("previewImageAsset");
  156. if (previewImageAssetId != StringTable->EmptyString())
  157. {
  158. mPreviewImageAssetId = previewImageAssetId;
  159. mPreviewImageAsset = mPreviewImageAssetId;
  160. }
  161. }
  162. //
  163. void LevelAsset::setLevelFile(const char* pLevelFile)
  164. {
  165. // Sanity!
  166. AssertFatal(pLevelFile != NULL, "Cannot use a NULL level file.");
  167. // Fetch image file.
  168. pLevelFile = StringTable->insert(pLevelFile, true);
  169. // Ignore no change,
  170. if (pLevelFile == mLevelFile)
  171. return;
  172. // Update.
  173. mLevelFile = getOwned() ? expandAssetFilePath(pLevelFile) : pLevelFile;
  174. // Refresh the asset.
  175. refreshAsset();
  176. }
  177. StringTableEntry LevelAsset::getPreviewImageAsset() const
  178. {
  179. return mPreviewImageAssetId;
  180. }
  181. StringTableEntry LevelAsset::getPreviewImagePath(void) const
  182. {
  183. if (mPreviewImageAsset.notNull() && mPreviewImageAsset->isAssetValid())
  184. {
  185. return mPreviewImageAsset->getImagePath();
  186. }
  187. return StringTable->EmptyString();
  188. }
  189. void LevelAsset::setEditorFile(const char* pEditorFile)
  190. {
  191. // Sanity!
  192. AssertFatal(pEditorFile != NULL, "Cannot use a NULL level file.");
  193. // Fetch image file.
  194. pEditorFile = StringTable->insert(pEditorFile, true);
  195. // Ignore no change,
  196. if (pEditorFile == mEditorFile)
  197. return;
  198. // Update.
  199. mEditorFile = getOwned() ? expandAssetFilePath(pEditorFile) : pEditorFile;
  200. // Refresh the asset.
  201. refreshAsset();
  202. }
  203. void LevelAsset::setBakedSceneFile(const char* pBakedSceneFile)
  204. {
  205. // Sanity!
  206. AssertFatal(pBakedSceneFile != NULL, "Cannot use a NULL level file.");
  207. // Fetch image file.
  208. pBakedSceneFile = StringTable->insert(pBakedSceneFile, true);
  209. // Ignore no change,
  210. if (pBakedSceneFile == mBakedSceneFile)
  211. return;
  212. // Update.
  213. mBakedSceneFile = getOwned() ? expandAssetFilePath(pBakedSceneFile) : pBakedSceneFile;
  214. // Refresh the asset.
  215. refreshAsset();
  216. }
  217. void LevelAsset::setPostFXPresetFile(const char* pPostFXPresetFile)
  218. {
  219. // Sanity!
  220. AssertFatal(pPostFXPresetFile != NULL, "Cannot use a NULL postFX preset file.");
  221. // Fetch file.
  222. pPostFXPresetFile = StringTable->insert(pPostFXPresetFile, true);
  223. // Ignore no change,
  224. if (pPostFXPresetFile == mPostFXPresetFile)
  225. return;
  226. // Update.
  227. mPostFXPresetFile = getOwned() ? expandAssetFilePath(pPostFXPresetFile) : pPostFXPresetFile;
  228. // Refresh the asset.
  229. refreshAsset();
  230. }
  231. void LevelAsset::setDecalsFile(const char* pDecalsFile)
  232. {
  233. // Sanity!
  234. AssertFatal(pDecalsFile != NULL, "Cannot use a NULL decals file.");
  235. // Fetch file.
  236. pDecalsFile = StringTable->insert(pDecalsFile, true);
  237. // Ignore no change,
  238. if (pDecalsFile == mDecalsFile)
  239. return;
  240. // Update.
  241. mDecalsFile = getOwned() ? expandAssetFilePath(pDecalsFile) : pDecalsFile;
  242. // Refresh the asset.
  243. refreshAsset();
  244. }
  245. void LevelAsset::setForestFile(const char* pForestFile)
  246. {
  247. // Sanity!
  248. AssertFatal(pForestFile != NULL, "Cannot use a NULL decals file.");
  249. // Fetch file.
  250. pForestFile = StringTable->insert(pForestFile, true);
  251. // Ignore no change,
  252. if (pForestFile == mForestFile)
  253. return;
  254. // Update.
  255. mForestFile = getOwned() ? expandAssetFilePath(pForestFile) : pForestFile;
  256. // Refresh the asset.
  257. refreshAsset();
  258. }
  259. void LevelAsset::setNavmeshFile(const char* pNavmeshFile)
  260. {
  261. // Sanity!
  262. AssertFatal(pNavmeshFile != NULL, "Cannot use a NULL Navmesh file.");
  263. // Fetch file.
  264. pNavmeshFile = StringTable->insert(pNavmeshFile, true);
  265. // Ignore no change,
  266. if (pNavmeshFile == mNavmeshFile)
  267. return;
  268. // Update.
  269. mNavmeshFile = getOwned() ? expandAssetFilePath(pNavmeshFile) : pNavmeshFile;
  270. // Refresh the asset.
  271. refreshAsset();
  272. }
  273. void LevelAsset::loadDependencies()
  274. {
  275. //First, load any material, animation, etc assets we may be referencing in our asset
  276. // Find any asset dependencies.
  277. AssetManager::typeAssetDependsOnHash::Iterator assetDependenciesItr = mpOwningAssetManager->getDependedOnAssets()->find(mpAssetDefinition->mAssetId);
  278. // Does the asset have any dependencies?
  279. if (assetDependenciesItr != mpOwningAssetManager->getDependedOnAssets()->end())
  280. {
  281. // Iterate all dependencies.
  282. while (assetDependenciesItr != mpOwningAssetManager->getDependedOnAssets()->end() && assetDependenciesItr->key == mpAssetDefinition->mAssetId)
  283. {
  284. //Force it to be loaded by acquiring it
  285. StringTableEntry assetId = assetDependenciesItr->value;
  286. mAssetDependencies.push_back(AssetDatabase.acquireAsset<AssetBase>(assetId));
  287. // Next dependency.
  288. assetDependenciesItr++;
  289. }
  290. }
  291. }
  292. void LevelAsset::unloadDependencies()
  293. {
  294. for (U32 i = 0; i < mAssetDependencies.size(); i++)
  295. {
  296. AssetBase* assetDef = mAssetDependencies[i];
  297. AssetDatabase.releaseAsset(assetDef->getAssetId());
  298. }
  299. }
  300. DefineEngineMethod(LevelAsset, getLevelPath, const char*, (), ,
  301. "Gets the full path of the asset's defined level file.\n"
  302. "@return The string result of the level path")
  303. {
  304. return object->getLevelPath();
  305. }
  306. DefineEngineMethod(LevelAsset, getPreviewImageAsset, const char*, (), ,
  307. "Gets the full path of the asset's defined preview image file.\n"
  308. "@return The string result of the level preview image path")
  309. {
  310. return object->getPreviewImageAsset();
  311. }
  312. DefineEngineMethod(LevelAsset, getPreviewImagePath, const char*, (), ,
  313. "Gets the full path of the asset's defined preview image file.\n"
  314. "@return The string result of the level preview image path")
  315. {
  316. return object->getPreviewImagePath();
  317. }
  318. DefineEngineMethod(LevelAsset, getPostFXPresetPath, const char*, (), ,
  319. "Gets the full path of the asset's defined postFX preset file.\n"
  320. "@return The string result of the postFX preset path")
  321. {
  322. return object->getPostFXPresetPath();
  323. }
  324. DefineEngineMethod(LevelAsset, getDecalsPath, const char*, (), ,
  325. "Gets the full path of the asset's defined decal file.\n"
  326. "@return The string result of the decal path")
  327. {
  328. return object->getDecalsPath();
  329. }
  330. DefineEngineMethod(LevelAsset, getForestPath, const char*, (), ,
  331. "Gets the full path of the asset's defined forest file.\n"
  332. "@return The string result of the forest path")
  333. {
  334. return object->getForestPath();
  335. }
  336. DefineEngineMethod(LevelAsset, getNavmeshPath, const char*, (), ,
  337. "Gets the full path of the asset's defined navmesh file.\n"
  338. "@return The string result of the navmesh path")
  339. {
  340. return object->getNavmeshPath();
  341. }
  342. DefineEngineMethod(LevelAsset, loadDependencies, void, (), ,
  343. "Initiates the loading of asset dependencies for this level.")
  344. {
  345. return object->loadDependencies();
  346. }
  347. DefineEngineMethod(LevelAsset, unloadDependencies, void, (), ,
  348. "Initiates the unloading of previously loaded asset dependencies for this level.")
  349. {
  350. return object->unloadDependencies();
  351. }
  352. //-----------------------------------------------------------------------------
  353. // GuiInspectorTypeAssetId
  354. //-----------------------------------------------------------------------------
  355. IMPLEMENT_CONOBJECT(GuiInspectorTypeLevelAssetPtr);
  356. ConsoleDocClass(GuiInspectorTypeLevelAssetPtr,
  357. "@brief Inspector field type for Shapes\n\n"
  358. "Editor use only.\n\n"
  359. "@internal"
  360. );
  361. void GuiInspectorTypeLevelAssetPtr::consoleInit()
  362. {
  363. Parent::consoleInit();
  364. ConsoleBaseType::getType(TypeLevelAssetPtr)->setInspectorFieldType("GuiInspectorTypeLevelAssetPtr");
  365. }
  366. GuiControl* GuiInspectorTypeLevelAssetPtr::constructEditControl()
  367. {
  368. // Create base filename edit controls
  369. GuiControl* retCtrl = Parent::constructEditControl();
  370. if (retCtrl == NULL)
  371. return retCtrl;
  372. // Change filespec
  373. char szBuffer[512];
  374. dSprintf(szBuffer, sizeof(szBuffer), "AssetBrowser.showDialog(\"LevelAsset\", \"AssetBrowser.changeAsset\", %s, \"\");",
  375. getIdString());
  376. mBrowseButton->setField("Command", szBuffer);
  377. setDataField(StringTable->insert("targetObject"), NULL, mInspector->getInspectObject()->getIdString());
  378. // Create "Open in Editor" button
  379. mEditButton = new GuiBitmapButtonCtrl();
  380. String setSubSceneValue = "$createLevelAssetIsSubScene = \"\";";
  381. if(dynamic_cast<SubScene*>(mInspector->getInspectObject()) != NULL)
  382. {
  383. setSubSceneValue = "$createLevelAssetIsSubScene = true;";
  384. }
  385. dSprintf(szBuffer, sizeof(szBuffer), "$createAndAssignField = %s; %s AssetBrowser.setupCreateNewAsset(\"LevelAsset\", AssetBrowser.selectedModule, \"createAndAssignLevelAsset\");",
  386. getIdString(),
  387. setSubSceneValue.c_str());
  388. mEditButton->setField("Command", szBuffer);
  389. char bitmapName[512] = "ToolsModule:iconAdd_image";
  390. mEditButton->setBitmap(StringTable->insert(bitmapName));
  391. mEditButton->setDataField(StringTable->insert("Profile"), NULL, "GuiButtonProfile");
  392. mEditButton->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile");
  393. mEditButton->setDataField(StringTable->insert("hovertime"), NULL, "1000");
  394. mEditButton->setDataField(StringTable->insert("tooltip"), NULL, "Test play this sound");
  395. mEditButton->registerObject();
  396. addObject(mEditButton);
  397. return retCtrl;
  398. }
  399. bool GuiInspectorTypeLevelAssetPtr::updateRects()
  400. {
  401. S32 dividerPos, dividerMargin;
  402. mInspector->getDivider(dividerPos, dividerMargin);
  403. Point2I fieldExtent = getExtent();
  404. Point2I fieldPos = getPosition();
  405. mCaptionRect.set(0, 0, fieldExtent.x - dividerPos - dividerMargin, fieldExtent.y);
  406. mEditCtrlRect.set(fieldExtent.x - dividerPos + dividerMargin, 1, dividerPos - dividerMargin - 34, fieldExtent.y);
  407. bool resized = mEdit->resize(mEditCtrlRect.point, mEditCtrlRect.extent);
  408. if (mBrowseButton != NULL)
  409. {
  410. mBrowseRect.set(fieldExtent.x - 32, 2, 14, fieldExtent.y - 4);
  411. resized |= mBrowseButton->resize(mBrowseRect.point, mBrowseRect.extent);
  412. }
  413. if (mEditButton != NULL)
  414. {
  415. RectI shapeEdRect(fieldExtent.x - 16, 2, 14, fieldExtent.y - 4);
  416. resized |= mEditButton->resize(shapeEdRect.point, shapeEdRect.extent);
  417. }
  418. return resized;
  419. }
  420. IMPLEMENT_CONOBJECT(GuiInspectorTypeLevelAssetId);
  421. ConsoleDocClass(GuiInspectorTypeLevelAssetId,
  422. "@brief Inspector field type for Levels\n\n"
  423. "Editor use only.\n\n"
  424. "@internal"
  425. );
  426. void GuiInspectorTypeLevelAssetId::consoleInit()
  427. {
  428. Parent::consoleInit();
  429. ConsoleBaseType::getType(TypeLevelAssetId)->setInspectorFieldType("GuiInspectorTypeLevelAssetId");
  430. }