ImageAsset.cpp
Engine/source/T3D/assets/ImageAsset.cpp
Public Variables
Public Functions
ConsoleDocClass(GuiInspectorTypeImageAssetId , "@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(GuiInspectorTypeImageAssetPtr , "@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" )
ConsoleSetType(TypeImageAssetId )
ConsoleSetType(TypeImageAssetPtr )
ConsoleType(assetIdString , TypeImageAssetId , String , ASSET_ID_FIELD_PREFIX )
ConsoleType(ImageAssetPtr , TypeImageAssetPtr , String , ASSET_ID_FIELD_PREFIX )
DefineEngineMethod(ImageAsset , getImageInfo , const char * , () , "Creates an instance of the given GameObject given the asset <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">definition.\n</a>" "@return The GameObject entity created from the asset." )
DefineEngineMethod(ImageAsset , getImagePath , const char * , () , "Creates an instance of the given GameObject given the asset <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">definition.\n</a>" "@return The GameObject entity created from the asset." )
ImplementEnumType(ImageAssetType , "Type of mesh data available in <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">shape.\n</a>" "@ingroup gameObjects" )
Detailed Description
Public Variables
EndImplementEnumType
Public Functions
ConsoleDocClass(GuiInspectorTypeImageAssetId , "@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(GuiInspectorTypeImageAssetPtr , "@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" )
ConsoleSetType(TypeImageAssetId )
ConsoleSetType(TypeImageAssetPtr )
ConsoleType(assetIdString , TypeImageAssetId , String , ASSET_ID_FIELD_PREFIX )
ConsoleType(ImageAssetPtr , TypeImageAssetPtr , String , ASSET_ID_FIELD_PREFIX )
DefineEngineMethod(ImageAsset , getImageInfo , const char * , () , "Creates an instance of the given GameObject given the asset <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">definition.\n</a>" "@return The GameObject entity created from the asset." )
DefineEngineMethod(ImageAsset , getImagePath , const char * , () , "Creates an instance of the given GameObject given the asset <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">definition.\n</a>" "@return The GameObject entity created from the asset." )
IMPLEMENT_CONOBJECT(GuiInspectorTypeImageAssetId )
IMPLEMENT_CONOBJECT(GuiInspectorTypeImageAssetPtr )
IMPLEMENT_CONOBJECT(ImageAsset )
ImplementEnumType(ImageAssetType , "Type of mesh data available in <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">shape.\n</a>" "@ingroup gameObjects" )
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 IMAGE_ASSET_H 25#include "ImageAsset.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 "gfx/gfxStringEnumTranslate.h" 45 46// Debug Profiling. 47#include "platform/profiler.h" 48 49#include "T3D/assets/assetImporter.h" 50 51//----------------------------------------------------------------------------- 52 53IMPLEMENT_CONOBJECT(ImageAsset); 54 55ConsoleType(ImageAssetPtr, TypeImageAssetPtr, String, ASSET_ID_FIELD_PREFIX) 56 57//----------------------------------------------------------------------------- 58 59ConsoleGetType(TypeImageAssetPtr) 60{ 61 // Fetch asset Id. 62 return *((StringTableEntry*)dptr); 63} 64 65//----------------------------------------------------------------------------- 66 67ConsoleSetType(TypeImageAssetPtr) 68{ 69 // Was a single argument specified? 70 if (argc == 1) 71 { 72 // Yes, so fetch field value. 73 const char* pFieldValue = argv[0]; 74 75 // Fetch asset Id. 76 StringTableEntry* assetId = (StringTableEntry*)(dptr); 77 78 // Update asset value. 79 *assetId = StringTable->insert(pFieldValue); 80 81 return; 82 } 83 84 // Warn. 85 Con::warnf("(TypeImageAssetPtr) - Cannot set multiple args to a single asset."); 86} 87 88ConsoleType(assetIdString, TypeImageAssetId, String, ASSET_ID_FIELD_PREFIX) 89 90ConsoleGetType(TypeImageAssetId) 91{ 92 // Fetch asset Id. 93 return *((const char**)(dptr)); 94} 95 96ConsoleSetType(TypeImageAssetId) 97{ 98 // Was a single argument specified? 99 if (argc == 1) 100 { 101 // Yes, so fetch field value. 102 const char* pFieldValue = argv[0]; 103 104 // Fetch asset Id. 105 StringTableEntry* assetId = (StringTableEntry*)(dptr); 106 107 // Update asset value. 108 *assetId = StringTable->insert(pFieldValue); 109 110 return; 111 } 112 113 // Warn. 114 Con::warnf("(TypeAssetId) - Cannot set multiple args to a single asset."); 115} 116//----------------------------------------------------------------------------- 117 118ImplementEnumType(ImageAssetType, 119 "Type of mesh data available in a shape.\n" 120 "@ingroup gameObjects") 121 { ImageAsset::Albedo, "Albedo", "" }, 122 { ImageAsset::Normal, "Normal", "" }, 123 { ImageAsset::ORMConfig, "ORMConfig", "" }, 124 { ImageAsset::GUI, "GUI", "" }, 125 { ImageAsset::Roughness, "Roughness", "" }, 126 { ImageAsset::AO, "AO", "" }, 127 { ImageAsset::Metalness, "Metalness", "" }, 128 { ImageAsset::Glow, "Glow", "" }, 129 { ImageAsset::Particle, "Particle", "" }, 130 { ImageAsset::Decal, "Decal", "" }, 131 { ImageAsset::Cubemap, "Cubemap", "" }, 132 133EndImplementEnumType; 134 135 136//----------------------------------------------------------------------------- 137ImageAsset::ImageAsset() : AssetBase(), mImage(nullptr), mUseMips(true), mIsHDRImage(false), mIsValidImage(false), mImageType(Albedo) 138{ 139 mImageFileName = StringTable->EmptyString(); 140 mImagePath = StringTable->EmptyString(); 141} 142 143//----------------------------------------------------------------------------- 144 145ImageAsset::~ImageAsset() 146{ 147} 148 149//----------------------------------------------------------------------------- 150 151void ImageAsset::initPersistFields() 152{ 153 // Call parent. 154 Parent::initPersistFields(); 155 156 addProtectedField("imageFile", TypeAssetLooseFilePath, Offset(mImageFileName, ImageAsset), 157 &setImageFileName, &getImageFileName, "Path to the image file."); 158 159 addField("useMips", TypeBool, Offset(mUseMips, ImageAsset), "Should the image use mips? (Currently unused)."); 160 addField("isHDRImage", TypeBool, Offset(mIsHDRImage, ImageAsset), "Is the image in an HDR format? (Currently unused)"); 161 162 addField("imageType", TypeImageAssetType, Offset(mImageType, ImageAsset), "What the main use-case for the image is for."); 163} 164 165//------------------------------------------------------------------------------ 166//Utility function to 'fill out' bindings and resources with a matching asset if one exists 167bool ImageAsset::getAssetByFilename(StringTableEntry fileName, AssetPtr<ImageAsset>* imageAsset) 168{ 169 AssetQuery query; 170 S32 foundAssetcount = AssetDatabase.findAssetLooseFile(&query, fileName); 171 if (foundAssetcount == 0) 172 { 173 //Didn't find any assets 174 //If possible, see if we can run an in-place import and the get the asset from that 175#if TORQUE_DEBUG 176 Con::warnf("ImageAsset::getAssetByFilename - Attempted to in-place import a image file(%s) that had no associated asset", fileName); 177#endif 178 179 AssetImporter* autoAssetImporter; 180 if (!Sim::findObject("autoAssetImporter", autoAssetImporter)) 181 { 182 autoAssetImporter = new AssetImporter(); 183 autoAssetImporter->registerObject("autoAssetImporter"); 184 } 185 186 StringTableEntry resultingAssetId = autoAssetImporter->autoImportFile(fileName); 187 188 if (resultingAssetId != StringTable->EmptyString()) 189 { 190 imageAsset->setAssetId(resultingAssetId); 191 192 if (!imageAsset->isNull()) 193 return true; 194 } 195 196 //Didn't work, so have us fall back to a placeholder asset 197 imageAsset->setAssetId(StringTable->insert("Core_Rendering:noImage")); 198 199 if (!imageAsset->isNull()) 200 return true; 201 202 //That didn't work, so fail out 203 return false; 204 } 205 else 206 { 207 //acquire and bind the asset, and return it out 208 imageAsset->setAssetId(query.mAssetList[0]); 209 return true; 210 } 211} 212 213StringTableEntry ImageAsset::getAssetIdByFilename(StringTableEntry fileName) 214{ 215 StringTableEntry imageAssetId = StringTable->EmptyString(); 216 217 AssetQuery query; 218 S32 foundAssetcount = AssetDatabase.findAssetLooseFile(&query, fileName); 219 if (foundAssetcount == 0) 220 { 221 //Didn't find any assets 222 //If possible, see if we can run an in-place import and the get the asset from that 223#if TORQUE_DEBUG 224 Con::warnf("ImageAsset::getAssetByFilename - Attempted to in-place import a image file(%s) that had no associated asset", fileName); 225#endif 226 227 AssetImporter* autoAssetImporter; 228 if (!Sim::findObject("autoAssetImporter", autoAssetImporter)) 229 { 230 autoAssetImporter = new AssetImporter(); 231 autoAssetImporter->registerObject("autoAssetImporter"); 232 } 233 234 StringTableEntry resultingAssetId = autoAssetImporter->autoImportFile(fileName); 235 236 if (resultingAssetId != StringTable->EmptyString()) 237 { 238 imageAssetId = resultingAssetId; 239 return imageAssetId; 240 } 241 242 //Didn't work, so have us fall back to a placeholder asset 243 imageAssetId = StringTable->insert("Core_Rendering:noImage"); 244 } 245 else 246 { 247 //acquire and bind the asset, and return it out 248 imageAssetId = query.mAssetList[0]; 249 } 250 251 return imageAssetId; 252} 253 254bool ImageAsset::getAssetById(StringTableEntry assetId, AssetPtr<ImageAsset>* imageAsset) 255{ 256 (*imageAsset) = assetId; 257 258 if (!imageAsset->isNull()) 259 return true; 260 261 //Didn't work, so have us fall back to a placeholder asset 262 StringTableEntry noImageId = StringTable->insert("Core_Rendering:noMaterial"); 263 imageAsset->setAssetId(noImageId); 264 265 if (!imageAsset->isNull()) 266 return true; 267 268 return false; 269} 270//------------------------------------------------------------------------------ 271void ImageAsset::copyTo(SimObject* object) 272{ 273 // Call to parent. 274 Parent::copyTo(object); 275} 276 277void ImageAsset::loadImage() 278{ 279 SAFE_DELETE(mImage); 280 281 if (mImagePath) 282 { 283 if (!Platform::isFile(mImagePath)) 284 { 285 Con::errorf("ImageAsset::initializeAsset: Attempted to load file %s but it was not valid!", mImageFileName); 286 return; 287 } 288 289 mImage.set(mImagePath, &GFXStaticTextureSRGBProfile, avar("%s() - mImage (line %d)", __FUNCTION__, __LINE__)); 290 291 if (mImage) 292 { 293 mIsValidImage = true; 294 return; 295 } 296 } 297 298 mIsValidImage = false; 299} 300 301void ImageAsset::initializeAsset() 302{ 303 mImagePath = expandAssetFilePath(mImageFileName); 304 305 loadImage(); 306} 307 308void ImageAsset::onAssetRefresh() 309{ 310 mImagePath = expandAssetFilePath(mImageFileName); 311 312 loadImage(); 313} 314 315void ImageAsset::setImageFileName(const char* pScriptFile) 316{ 317 // Sanity! 318 AssertFatal(pScriptFile != NULL, "Cannot use a NULL image file."); 319 320 // Update. 321 mImageFileName = StringTable->insert(pScriptFile); 322} 323 324GFXTexHandle ImageAsset::getImage(GFXTextureProfile requestedProfile) 325{ 326 /*if (mResourceMap.contains(requestedProfile)) 327 { 328 return mResourceMap.find(requestedProfile)->value; 329 } 330 else 331 { 332 //If we don't have an existing map case to the requested format, we'll just create it and insert it in 333 GFXTexHandle newImage; 334 newImage.set(mImageFileName, &requestedProfile, avar("%s() - mImage (line %d)", __FUNCTION__, __LINE__)); 335 mResourceMap.insert(requestedProfile, newImage); 336 337 return newImage; 338 }*/ 339 340 if (mImage.isValid()) 341 return mImage; 342 343 return nullptr; 344} 345 346const char* ImageAsset::getImageInfo() 347{ 348 if (mIsValidImage) 349 { 350 static const U32 bufSize = 2048; 351 char* returnBuffer = Con::getReturnBuffer(bufSize); 352 dSprintf(returnBuffer, bufSize, "%s %d %d %d", GFXStringTextureFormat[mImage.getFormat()], mImage.getHeight(), mImage.getWidth(), mImage.getDepth()); 353 354 return returnBuffer; 355 } 356 357 return ""; 358} 359 360const char* ImageAsset::getImageTypeNameFromType(ImageAsset::ImageTypes type) 361{ 362 // must match ImageTypes order 363 static const char* _names[] = { 364 "Albedo", 365 "Normal", 366 "ORMConfig", 367 "GUI", 368 "Roughness", 369 "AO", 370 "Metalness", 371 "Glow", 372 "Particle", 373 "Decal", 374 "Cubemap" 375 }; 376 377 if (type < 0 || type >= ImageTypeCount) 378 { 379 Con::errorf("ImageAsset::getAdapterNameFromType - Invalid ImageType, defaulting to Albedo"); 380 return _names[Albedo]; 381 } 382 383 return _names[type]; 384} 385 386ImageAsset::ImageTypes ImageAsset::getImageTypeFromName(const char* name) 387{ 388 S32 ret = -1; 389 for (S32 i = 0; i < ImageTypeCount; i++) 390 { 391 if (!dStricmp(getImageTypeNameFromType((ImageTypes)i), name)) 392 ret = i; 393 } 394 395 if (ret == -1) 396 { 397 Con::errorf("ImageAsset::getImageTypeFromName - Invalid ImageType name, defaulting to Albedo"); 398 ret = Albedo; 399 } 400 401 return (ImageTypes)ret; 402} 403 404DefineEngineMethod(ImageAsset, getImagePath, const char*, (), , 405 "Creates an instance of the given GameObject given the asset definition.\n" 406 "@return The GameObject entity created from the asset.") 407{ 408 return object->getImagePath(); 409} 410 411DefineEngineMethod(ImageAsset, getImageInfo, const char*, (), , 412 "Creates an instance of the given GameObject given the asset definition.\n" 413 "@return The GameObject entity created from the asset.") 414{ 415 return object->getImageInfo(); 416} 417 418//----------------------------------------------------------------------------- 419// GuiInspectorTypeAssetId 420//----------------------------------------------------------------------------- 421 422IMPLEMENT_CONOBJECT(GuiInspectorTypeImageAssetPtr); 423 424ConsoleDocClass(GuiInspectorTypeImageAssetPtr, 425 "@brief Inspector field type for Shapes\n\n" 426 "Editor use only.\n\n" 427 "@internal" 428); 429 430void GuiInspectorTypeImageAssetPtr::consoleInit() 431{ 432 Parent::consoleInit(); 433 434 ConsoleBaseType::getType(TypeImageAssetPtr)->setInspectorFieldType("GuiInspectorTypeImageAssetPtr"); 435} 436 437GuiControl* GuiInspectorTypeImageAssetPtr::constructEditControl() 438{ 439 // Create base filename edit controls 440 GuiControl* retCtrl = Parent::constructEditControl(); 441 if (retCtrl == NULL) 442 return retCtrl; 443 444 // Change filespec 445 char szBuffer[512]; 446 dSprintf(szBuffer, sizeof(szBuffer), "AssetBrowser.showDialog(\"ImageAsset\", \"AssetBrowser.changeAsset\", %s, %s);", 447 mInspector->getInspectObject()->getIdString(), mCaption); 448 mBrowseButton->setField("Command", szBuffer); 449 450 const char* id = mInspector->getInspectObject()->getIdString(); 451 452 setDataField(StringTable->insert("targetObject"), NULL, mInspector->getInspectObject()->getIdString()); 453 454 // Create "Open in ShapeEditor" button 455 mImageEdButton = new GuiBitmapButtonCtrl(); 456 457 dSprintf(szBuffer, sizeof(szBuffer), "ShapeEditorPlugin.openShapeAssetId(%d.getText());", retCtrl->getId()); 458 mImageEdButton->setField("Command", szBuffer); 459 460 char bitmapName[512] = "tools/worldEditor/images/toolbar/shape-editor"; 461 mImageEdButton->setBitmap(bitmapName); 462 463 mImageEdButton->setDataField(StringTable->insert("Profile"), NULL, "GuiButtonProfile"); 464 mImageEdButton->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile"); 465 mImageEdButton->setDataField(StringTable->insert("hovertime"), NULL, "1000"); 466 mImageEdButton->setDataField(StringTable->insert("tooltip"), NULL, "Open this file in the Shape Editor"); 467 468 mImageEdButton->registerObject(); 469 addObject(mImageEdButton); 470 471 return retCtrl; 472} 473 474bool GuiInspectorTypeImageAssetPtr::updateRects() 475{ 476 S32 dividerPos, dividerMargin; 477 mInspector->getDivider(dividerPos, dividerMargin); 478 Point2I fieldExtent = getExtent(); 479 Point2I fieldPos = getPosition(); 480 481 mCaptionRect.set(0, 0, fieldExtent.x - dividerPos - dividerMargin, fieldExtent.y); 482 mEditCtrlRect.set(fieldExtent.x - dividerPos + dividerMargin, 1, dividerPos - dividerMargin - 34, fieldExtent.y); 483 484 bool resized = mEdit->resize(mEditCtrlRect.point, mEditCtrlRect.extent); 485 if (mBrowseButton != NULL) 486 { 487 mBrowseRect.set(fieldExtent.x - 32, 2, 14, fieldExtent.y - 4); 488 resized |= mBrowseButton->resize(mBrowseRect.point, mBrowseRect.extent); 489 } 490 491 if (mImageEdButton != NULL) 492 { 493 RectI shapeEdRect(fieldExtent.x - 16, 2, 14, fieldExtent.y - 4); 494 resized |= mImageEdButton->resize(shapeEdRect.point, shapeEdRect.extent); 495 } 496 497 return resized; 498} 499 500IMPLEMENT_CONOBJECT(GuiInspectorTypeImageAssetId); 501 502ConsoleDocClass(GuiInspectorTypeImageAssetId, 503 "@brief Inspector field type for Shapes\n\n" 504 "Editor use only.\n\n" 505 "@internal" 506); 507 508void GuiInspectorTypeImageAssetId::consoleInit() 509{ 510 Parent::consoleInit(); 511 512 ConsoleBaseType::getType(TypeImageAssetId)->setInspectorFieldType("GuiInspectorTypeImageAssetId"); 513} 514