TerrainAsset.cpp
Engine/source/T3D/assets/TerrainAsset.cpp
Public Functions
ConsoleDocClass(GuiInspectorTypeTerrainAssetId , "@brief Inspector field type <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Shapes\n\n</a>" "Editor use <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">only.\n\n</a>" "@internal" )
ConsoleDocClass(GuiInspectorTypeTerrainAssetPtr , "@brief Inspector field type <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/class/classmaterial/">Material</a> Asset <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Objects\n\n</a>" "Editor use <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">only.\n\n</a>" "@internal" )
ConsoleSetType(TypeTerrainAssetId )
ConsoleSetType(TypeTerrainAssetPtr )
ConsoleType(assetIdString , TypeTerrainAssetId , String , ASSET_ID_FIELD_PREFIX )
ConsoleType(TerrainAssetPtr , TypeTerrainAssetPtr , TerrainAsset , ASSET_ID_FIELD_PREFIX )
Detailed Description
Public Functions
ConsoleDocClass(GuiInspectorTypeTerrainAssetId , "@brief Inspector field type <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Shapes\n\n</a>" "Editor use <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">only.\n\n</a>" "@internal" )
ConsoleDocClass(GuiInspectorTypeTerrainAssetPtr , "@brief Inspector field type <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/class/classmaterial/">Material</a> Asset <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Objects\n\n</a>" "Editor use <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">only.\n\n</a>" "@internal" )
ConsoleSetType(TypeTerrainAssetId )
ConsoleSetType(TypeTerrainAssetPtr )
ConsoleType(assetIdString , TypeTerrainAssetId , String , ASSET_ID_FIELD_PREFIX )
ConsoleType(TerrainAssetPtr , TypeTerrainAssetPtr , TerrainAsset , ASSET_ID_FIELD_PREFIX )
IMPLEMENT_CONOBJECT(GuiInspectorTypeTerrainAssetId )
IMPLEMENT_CONOBJECT(GuiInspectorTypeTerrainAssetPtr )
IMPLEMENT_CONOBJECT(TerrainAsset )
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2013 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#ifndef TERRAINASSET_H 25#include "TerrainAsset.h" 26#endif 27 28#ifndef _ASSET_MANAGER_H_ 29#include "assets/assetManager.h" 30#endif 31 32#ifndef _CONSOLETYPES_H_ 33#include "console/consoleTypes.h" 34#endif 35 36#ifndef _TAML_ 37#include "persistence/taml/taml.h" 38#endif 39 40#ifndef _ASSET_PTR_H_ 41#include "assets/assetPtr.h" 42#endif 43 44#include "T3D/assets/TerrainMaterialAsset.h" 45 46#include "assetImporter.h" 47 48//----------------------------------------------------------------------------- 49 50IMPLEMENT_CONOBJECT(TerrainAsset); 51 52ConsoleType(TerrainAssetPtr, TypeTerrainAssetPtr, TerrainAsset, ASSET_ID_FIELD_PREFIX) 53 54//----------------------------------------------------------------------------- 55 56ConsoleGetType(TypeTerrainAssetPtr) 57{ 58 // Fetch asset Id. 59 return (*((AssetPtr<TerrainAsset>*)dptr)).getAssetId(); 60} 61 62//----------------------------------------------------------------------------- 63 64ConsoleSetType(TypeTerrainAssetPtr) 65{ 66 // Was a single argument specified? 67 if (argc == 1) 68 { 69 // Yes, so fetch field value. 70 const char* pFieldValue = argv[0]; 71 72 // Fetch asset pointer. 73 AssetPtr<TerrainAsset>* pAssetPtr = dynamic_cast<AssetPtr<TerrainAsset>*>((AssetPtrBase*)(dptr)); 74 75 // Is the asset pointer the correct type? 76 if (pAssetPtr == NULL) 77 { 78 // No, so fail. 79 //Con::warnf("(TypeMaterialAssetPtr) - Failed to set asset Id '%d'.", pFieldValue); 80 return; 81 } 82 83 // Set asset. 84 pAssetPtr->setAssetId(pFieldValue); 85 86 return; 87 } 88 89 // Warn. 90 Con::warnf("(TypeTerrainAssetPtr) - Cannot set multiple args to a single asset."); 91} 92 93 94//----------------------------------------------------------------------------- 95ConsoleType(assetIdString, TypeTerrainAssetId, String, ASSET_ID_FIELD_PREFIX) 96 97ConsoleGetType(TypeTerrainAssetId) 98{ 99 // Fetch asset Id. 100 return *((const char**)(dptr)); 101} 102 103ConsoleSetType(TypeTerrainAssetId) 104{ 105 // Was a single argument specified? 106 if (argc == 1) 107 { 108 // Yes, so fetch field value. 109 const char* pFieldValue = argv[0]; 110 111 // Fetch asset Id. 112 StringTableEntry* assetId = (StringTableEntry*)(dptr); 113 114 // Update asset value. 115 *assetId = StringTable->insert(pFieldValue); 116 117 return; 118 } 119 120 // Warn. 121 Con::warnf("(TypeAssetId) - Cannot set multiple args to a single asset."); 122} 123 124//----------------------------------------------------------------------------- 125 126TerrainAsset::TerrainAsset() 127{ 128 mTerrainFileName = StringTable->EmptyString(); 129 mTerrainFilePath = StringTable->EmptyString(); 130} 131 132//----------------------------------------------------------------------------- 133 134TerrainAsset::~TerrainAsset() 135{ 136} 137 138//----------------------------------------------------------------------------- 139 140void TerrainAsset::initPersistFields() 141{ 142 // Call parent. 143 Parent::initPersistFields(); 144 145 //addField("shaderGraph", TypeRealString, Offset(mShaderGraphFile, TerrainAsset), ""); 146 addProtectedField("terrainFile", TypeAssetLooseFilePath, Offset(mTerrainFileName, TerrainAsset), 147 &setTerrainFileName, &getTerrainFileName, "Path to the file containing the terrain data."); 148} 149 150void TerrainAsset::setDataField(StringTableEntry slotName, const char* array, const char* value) 151{ 152 Parent::setDataField(slotName, array, value); 153 154 //Now, if it's a material slot of some fashion, set it up 155 StringTableEntry matSlotName = StringTable->insert("terrainMaterialAsset"); 156 if (String(slotName).startsWith(matSlotName)) 157 { 158 StringTableEntry matId = StringTable->insert(value); 159 160 mTerrMaterialAssetIds.push_back(matId); 161 } 162} 163 164void TerrainAsset::initializeAsset() 165{ 166 // Call parent. 167 Parent::initializeAsset(); 168 169 mTerrainFilePath = expandAssetFilePath(mTerrainFileName); 170 171 loadTerrain(); 172} 173 174void TerrainAsset::onAssetRefresh() 175{ 176 mTerrainFilePath = expandAssetFilePath(mTerrainFileName); 177 178 loadTerrain(); 179} 180 181void TerrainAsset::setTerrainFileName(const char* pScriptFile) 182{ 183 // Sanity! 184 AssertFatal(pScriptFile != NULL, "Cannot use a NULL script file."); 185 186 // Fetch image file. 187 pScriptFile = StringTable->insert(pScriptFile); 188 189 // Update. 190 mTerrainFileName = pScriptFile; 191 192 // Refresh the asset. 193 refreshAsset(); 194} 195 196bool TerrainAsset::loadTerrain() 197{ 198 if (!Platform::isFile(mTerrainFilePath)) 199 return false; 200 201 mTerrMaterialAssets.clear(); 202 mTerrMaterialAssetIds.clear(); 203 204 StringTableEntry terrainMatAssetType = StringTable->insert("TerrainMaterialAsset"); 205 206 //First, load any material, animation, etc assets we may be referencing in our asset 207 // Find any asset dependencies. 208 AssetManager::typeAssetDependsOnHash::Iterator assetDependenciesItr = mpOwningAssetManager->getDependedOnAssets()->find(mpAssetDefinition->mAssetId); 209 210 // Does the asset have any dependencies? 211 if (assetDependenciesItr != mpOwningAssetManager->getDependedOnAssets()->end()) 212 { 213 // Iterate all dependencies. 214 while (assetDependenciesItr != mpOwningAssetManager->getDependedOnAssets()->end() && assetDependenciesItr->key == mpAssetDefinition->mAssetId) 215 { 216 StringTableEntry assetType = mpOwningAssetManager->getAssetType(assetDependenciesItr->value); 217 218 if (assetType == terrainMatAssetType) 219 { 220 StringTableEntry assetId = StringTable->insert(assetDependenciesItr->value); 221 mTerrMaterialAssetIds.push_front(assetId); 222 223 //Force the asset to become initialized if it hasn't been already 224 AssetPtr<TerrainMaterialAsset> matAsset = assetId; 225 mTerrMaterialAssets.push_front(matAsset); 226 } 227 228 // Next dependency. 229 assetDependenciesItr++; 230 } 231 } 232 233 mTerrainFile = ResourceManager::get().load(mTerrainFilePath); 234 235 if (mTerrainFile) 236 return true; 237 238 return false; 239} 240 241//------------------------------------------------------------------------------ 242//------------------------------------------------------------------------------ 243//Utility function to 'fill out' bindings and resources with a matching asset if one exists 244bool TerrainAsset::getAssetByFilename(StringTableEntry fileName, AssetPtr<TerrainAsset>* shapeAsset) 245{ 246 AssetQuery query; 247 S32 foundAssetcount = AssetDatabase.findAssetLooseFile(&query, fileName); 248 if (foundAssetcount == 0) 249 { 250 //Didn't find any assets 251 //If possible, see if we can run an in-place import and the get the asset from that 252#if TORQUE_DEBUG 253 Con::warnf("TerrainAsset::getAssetByFilename - Attempted to in-place import a terrainFile(%s) that had no associated asset", fileName); 254#endif 255 256 Torque::Path terrFilePath = fileName; 257 258 TerrainAsset* newTerrainAsset = new TerrainAsset(); 259 260 String assetName = terrFilePath.getFileName(); 261 assetName.replace(" ", "_"); 262 263 newTerrainAsset->setAssetName(assetName.c_str()); 264 String terrainPathBind = terrFilePath.getFileName() + terrFilePath.getExtension(); 265 266 newTerrainAsset->mTerrainFileName = StringTable->insert(terrainPathBind.c_str()); 267 268 newTerrainAsset->saveAsset(); 269 270 Taml taml; 271 272 // Yes, so set it. 273 taml.setFormatMode(Taml::getFormatModeEnum("xml")); 274 275 // Turn-off auto-formatting. 276 taml.setAutoFormat(false); 277 278 String tamlPath = terrFilePath.getFullPath() + "/" + assetName + ".asset.taml"; 279 280 // Read object. 281 bool success = taml.write(newTerrainAsset, tamlPath.c_str()); 282 283 if (!success) 284 { 285 Con::printf("TerrainAsset::getAssetByFilename() - failed to auto-import terrainfile(%s) as an TerrainAsset", fileName); 286 return false; 287 } 288 289 ModuleDefinition* targetModuleDef = AssetImporter::getModuleFromPath(fileName); 290 291 if (!targetModuleDef) 292 { 293 Con::printf("TerrainAsset::getAssetByFilename() - failed to auto-import terrainfile(%s) as an TerrainAsset, unable to find a valid Module for the filePath", fileName); 294 return false; 295 } 296 297 success = AssetDatabase.addDeclaredAsset(targetModuleDef, tamlPath.c_str()); 298 299 if (!success) 300 { 301 Con::printf("TerrainAsset::getAssetByFilename() - failed to auto-import terrainfile(%s) as an TerrainAsset, unable to find a register asset with path", tamlPath.c_str()); 302 return false; 303 } 304 305 String assetId = targetModuleDef->getModuleId(); 306 assetId += ":"; 307 assetId += assetName.c_str(); 308 309 StringTableEntry resultingAssetId = StringTable->insert(assetId.c_str()); 310 311 if (resultingAssetId != StringTable->EmptyString()) 312 { 313 shapeAsset->setAssetId(resultingAssetId); 314 315 if (!shapeAsset->isNull()) 316 return true; 317 } 318 319 //That didn't work, so fail out 320 return false; 321 } 322 else 323 { 324 //acquire and bind the asset, and return it out 325 shapeAsset->setAssetId(query.mAssetList[0]); 326 return true; 327 } 328} 329 330StringTableEntry TerrainAsset::getAssetIdByFilename(StringTableEntry fileName) 331{ 332 if (fileName == StringTable->EmptyString()) 333 return StringTable->EmptyString(); 334 335 StringTableEntry shapeAssetId = StringTable->EmptyString(); 336 337 AssetQuery query; 338 S32 foundAssetcount = AssetDatabase.findAssetLooseFile(&query, fileName); 339 if (foundAssetcount == 0) 340 { 341 //Didn't find any assets 342 //If possible, see if we can run an in-place import and the get the asset from that 343#if TORQUE_DEBUG 344 Con::warnf("TerrainAsset::getAssetByFilename - Attempted to in-place import a terrainFile(%s) that had no associated asset", fileName); 345#endif 346 347 Torque::Path terrFilePath = fileName; 348 349 TerrainAsset* newTerrainAsset = new TerrainAsset(); 350 351 String assetName = terrFilePath.getFileName(); 352 assetName.replace(" ", "_"); 353 354 newTerrainAsset->setAssetName(assetName.c_str()); 355 String terrainPathBind = terrFilePath.getFileName() + "." + terrFilePath.getExtension(); 356 357 newTerrainAsset->mTerrainFileName = StringTable->insert(terrainPathBind.c_str()); 358 359 newTerrainAsset->saveAsset(); 360 361 Taml taml; 362 363 // Yes, so set it. 364 taml.setFormatMode(Taml::getFormatModeEnum("xml")); 365 366 // Turn-off auto-formatting. 367 taml.setAutoFormat(false); 368 369 String tamlPath = terrFilePath.getPath() + "/" + assetName + ".asset.taml"; 370 371 // Read object. 372 bool success = taml.write(newTerrainAsset, tamlPath.c_str()); 373 374 if (!success) 375 { 376 Con::printf("TerrainAsset::getAssetIdByFilename() - failed to auto-import terrainfile(%s) as an TerrainAsset", fileName); 377 return StringTable->EmptyString(); 378 } 379 380 ModuleDefinition* targetModuleDef = AssetImporter::getModuleFromPath(fileName); 381 382 if (!targetModuleDef) 383 { 384 Con::printf("TerrainAsset::getAssetIdByFilename() - failed to auto-import terrainfile(%s) as an TerrainAsset, unable to find a valid Module for the filePath", fileName); 385 return StringTable->EmptyString(); 386 } 387 388 success = AssetDatabase.addDeclaredAsset(targetModuleDef, tamlPath.c_str()); 389 390 if (!success) 391 { 392 Con::printf("TerrainAsset::getAssetIdByFilename() - failed to auto-import terrainfile(%s) as an TerrainAsset, unable to find a register asset with path", tamlPath.c_str()); 393 return StringTable->EmptyString(); 394 } 395 396 String assetId = targetModuleDef->getModuleId(); 397 assetId += ":"; 398 assetId += assetName.c_str(); 399 400 StringTableEntry resultingAssetId = StringTable->insert(assetId.c_str()); 401 402 if (resultingAssetId != StringTable->EmptyString()) 403 { 404 shapeAssetId = resultingAssetId; 405 return shapeAssetId; 406 } 407 } 408 else 409 { 410 //acquire and bind the asset, and return it out 411 shapeAssetId = query.mAssetList[0]; 412 } 413 414 return shapeAssetId; 415} 416 417bool TerrainAsset::getAssetById(StringTableEntry assetId, AssetPtr<TerrainAsset>* shapeAsset) 418{ 419 (*shapeAsset) = assetId; 420 421 if (!shapeAsset->isNull()) 422 return true; 423 424 return false; 425} 426 427//------------------------------------------------------------------------------ 428void TerrainAsset::copyTo(SimObject* object) 429{ 430 // Call to parent. 431 Parent::copyTo(object); 432} 433 434//----------------------------------------------------------------------------- 435// GuiInspectorTypeAssetId 436//----------------------------------------------------------------------------- 437 438IMPLEMENT_CONOBJECT(GuiInspectorTypeTerrainAssetPtr); 439 440ConsoleDocClass(GuiInspectorTypeTerrainAssetPtr, 441 "@brief Inspector field type for Material Asset Objects\n\n" 442 "Editor use only.\n\n" 443 "@internal" 444); 445 446void GuiInspectorTypeTerrainAssetPtr::consoleInit() 447{ 448 Parent::consoleInit(); 449 450 ConsoleBaseType::getType(TypeTerrainAssetPtr)->setInspectorFieldType("GuiInspectorTypeTerrainAssetPtr"); 451} 452 453GuiControl* GuiInspectorTypeTerrainAssetPtr::constructEditControl() 454{ 455 // Create base filename edit controls 456 GuiControl* retCtrl = Parent::constructEditControl(); 457 if (retCtrl == NULL) 458 return retCtrl; 459 460 // Change filespec 461 char szBuffer[512]; 462 dSprintf(szBuffer, sizeof(szBuffer), "AssetBrowser.showDialog(\"TerrainAsset\", \"AssetBrowser.changeAsset\", %s, %s);", 463 mInspector->getInspectObject()->getIdString(), mCaption); 464 mBrowseButton->setField("Command", szBuffer); 465 466 const char* id = mInspector->getInspectObject()->getIdString(); 467 468 setDataField(StringTable->insert("targetObject"), NULL, mInspector->getInspectObject()->getIdString()); 469 470 // Create "Open in ShapeEditor" button 471 mShapeEdButton = new GuiBitmapButtonCtrl(); 472 473 mShapeEdButton->setField("Command", "EditorGui.setEditor(TerrainEditorPlugin);"); 474 475 char bitmapName[512] = "tools/worldEditor/images/toolbar/shape-editor"; 476 mShapeEdButton->setBitmap(bitmapName); 477 478 mShapeEdButton->setDataField(StringTable->insert("Profile"), NULL, "GuiButtonProfile"); 479 mShapeEdButton->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile"); 480 mShapeEdButton->setDataField(StringTable->insert("hovertime"), NULL, "1000"); 481 mShapeEdButton->setDataField(StringTable->insert("tooltip"), NULL, "Open this file in the Shape Editor"); 482 483 mShapeEdButton->registerObject(); 484 addObject(mShapeEdButton); 485 486 return retCtrl; 487} 488 489bool GuiInspectorTypeTerrainAssetPtr::updateRects() 490{ 491 S32 dividerPos, dividerMargin; 492 mInspector->getDivider(dividerPos, dividerMargin); 493 Point2I fieldExtent = getExtent(); 494 Point2I fieldPos = getPosition(); 495 496 mCaptionRect.set(0, 0, fieldExtent.x - dividerPos - dividerMargin, fieldExtent.y); 497 mEditCtrlRect.set(fieldExtent.x - dividerPos + dividerMargin, 1, dividerPos - dividerMargin - 34, fieldExtent.y); 498 499 bool resized = mEdit->resize(mEditCtrlRect.point, mEditCtrlRect.extent); 500 if (mBrowseButton != NULL) 501 { 502 mBrowseRect.set(fieldExtent.x - 32, 2, 14, fieldExtent.y - 4); 503 resized |= mBrowseButton->resize(mBrowseRect.point, mBrowseRect.extent); 504 } 505 506 if (mShapeEdButton != NULL) 507 { 508 RectI shapeEdRect(fieldExtent.x - 16, 2, 14, fieldExtent.y - 4); 509 resized |= mShapeEdButton->resize(shapeEdRect.point, shapeEdRect.extent); 510 } 511 512 return resized; 513} 514 515IMPLEMENT_CONOBJECT(GuiInspectorTypeTerrainAssetId); 516 517ConsoleDocClass(GuiInspectorTypeTerrainAssetId, 518 "@brief Inspector field type for Shapes\n\n" 519 "Editor use only.\n\n" 520 "@internal" 521); 522 523void GuiInspectorTypeTerrainAssetId::consoleInit() 524{ 525 Parent::consoleInit(); 526 527 ConsoleBaseType::getType(TypeTerrainAssetId)->setInspectorFieldType("GuiInspectorTypeTerrainAssetId"); 528} 529