ImageAsset.cpp

Engine/source/T3D/assets/ImageAsset.cpp

More...

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