MaterialAsset.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  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. #pragma once
  23. #ifndef MATERIALASSET_H
  24. #define MATERIALASSET_H
  25. #ifndef _ASSET_BASE_H_
  26. #include "assets/assetBase.h"
  27. #endif
  28. #ifndef _ASSET_DEFINITION_H_
  29. #include "assets/assetDefinition.h"
  30. #endif
  31. #ifndef _STRINGUNIT_H_
  32. #include "string/stringUnit.h"
  33. #endif
  34. #ifndef _ASSET_FIELD_TYPES_H_
  35. #include "assets/assetFieldTypes.h"
  36. #endif
  37. #ifndef _GFXDEVICE_H_
  38. #include "gfx/gfxDevice.h"
  39. #endif
  40. #ifndef _NETCONNECTION_H_
  41. #include "sim/netConnection.h"
  42. #endif
  43. #ifndef _GUI_INSPECTOR_TYPES_H_
  44. #include "gui/editor/guiInspectorTypes.h"
  45. #endif
  46. #include "materials/matTextureTarget.h"
  47. #include "materials/materialDefinition.h"
  48. #include "materials/customMaterialDefinition.h"
  49. #include "materials/materialManager.h"
  50. #include "assetMacroHelpers.h"
  51. #include <gui/controls/guiBitmapCtrl.h>
  52. //-----------------------------------------------------------------------------
  53. class MaterialAsset : public AssetBase
  54. {
  55. typedef AssetBase Parent;
  56. typedef AssetPtr<MaterialAsset> ConcreteAssetPtr;
  57. String mShaderGraphFile;
  58. StringTableEntry mScriptFile;
  59. StringTableEntry mScriptPath;
  60. StringTableEntry mMatDefinitionName;
  61. SimObjectPtr<Material> mMaterialDefinition;
  62. public:
  63. static StringTableEntry smNoMaterialAssetFallback;
  64. enum MaterialAssetErrCode
  65. {
  66. ScriptLoaded = AssetErrCode::Extended,
  67. DefinitionAlreadyExists,
  68. EmbeddedDefinition,
  69. Extended
  70. };
  71. static const String mErrCodeStrings[U32(MaterialAssetErrCode::Extended) - U32(Parent::Extended) + 1];
  72. static U32 getAssetErrCode(ConcreteAssetPtr checkAsset) { if (checkAsset) return checkAsset->mLoadedState; else return 0; }
  73. static String getAssetErrstrn(U32 errCode)
  74. {
  75. if (errCode < Parent::Extended) return Parent::getAssetErrstrn(errCode);
  76. if (errCode > MaterialAssetErrCode::Extended) return "undefined error";
  77. return mErrCodeStrings[errCode - Parent::Extended];
  78. };
  79. public:
  80. MaterialAsset();
  81. virtual ~MaterialAsset();
  82. /// Set up some global script interface stuff.
  83. static void consoleInit();
  84. /// Engine.
  85. static void initPersistFields();
  86. void copyTo(SimObject* object) override;
  87. U32 load() override;
  88. StringTableEntry getMaterialDefinitionName() { return mMatDefinitionName; }
  89. SimObjectPtr<Material> getMaterialDefinition() { return mMaterialDefinition; }
  90. void setScriptFile(const char* pScriptFile);
  91. inline StringTableEntry getScriptFile(void) const { return mScriptFile; };
  92. inline StringTableEntry getScriptPath(void) const { return mScriptPath; };
  93. /// <summary>
  94. /// Looks for any assets that uses the provided Material Definition name.
  95. /// If none are found, attempts to auto-import the material definition if the
  96. /// material definition exists.
  97. /// </summary>
  98. /// <param name="matName">Material Definition name to look for</param>
  99. /// <returns>AssetId of matching asset.</returns>
  100. static StringTableEntry getAssetIdByMaterialName(StringTableEntry matName);
  101. static U32 getAssetById(StringTableEntry assetId, AssetPtr<MaterialAsset>* materialAsset);
  102. static SimObjectPtr<Material> findMaterialDefinitionByAssetId(StringTableEntry assetId);
  103. static U32 getAssetByMaterialName(StringTableEntry matName, AssetPtr<MaterialAsset>* matAsset);
  104. /// Declare Console Object.
  105. DECLARE_CONOBJECT(MaterialAsset);
  106. protected:
  107. void initializeAsset() override;
  108. void onAssetRefresh(void) override;
  109. static bool setScriptFile(void *obj, const char *index, const char *data)
  110. {
  111. static_cast<MaterialAsset*>(obj)->setScriptFile(data);
  112. return false;
  113. }
  114. static const char* getScriptFile(void* obj, const char* data) { return static_cast<MaterialAsset*>(obj)->getScriptFile(); }
  115. };
  116. DefineConsoleType(TypeMaterialAssetPtr, MaterialAsset)
  117. DefineConsoleType(TypeMaterialAssetId, String)
  118. #ifdef TORQUE_TOOLS
  119. //-----------------------------------------------------------------------------
  120. // TypeAssetId GuiInspectorField Class
  121. //-----------------------------------------------------------------------------
  122. class GuiInspectorTypeMaterialAssetPtr : public GuiInspectorTypeFileName
  123. {
  124. typedef GuiInspectorTypeFileName Parent;
  125. public:
  126. GuiTextCtrl* mLabel;
  127. GuiBitmapButtonCtrl* mPreviewBorderButton;
  128. GuiBitmapCtrl* mPreviewImage;
  129. GuiButtonCtrl* mEditButton;
  130. DECLARE_CONOBJECT(GuiInspectorTypeMaterialAssetPtr);
  131. static void consoleInit();
  132. GuiControl* constructEditControl() override;
  133. bool updateRects() override;
  134. void updateValue() override;
  135. void updatePreviewImage();
  136. void setPreviewImage(StringTableEntry assetId);
  137. };
  138. class GuiInspectorTypeMaterialAssetId : public GuiInspectorTypeMaterialAssetPtr
  139. {
  140. typedef GuiInspectorTypeMaterialAssetPtr Parent;
  141. public:
  142. DECLARE_CONOBJECT(GuiInspectorTypeMaterialAssetId);
  143. static void consoleInit();
  144. };
  145. #endif
  146. #pragma region Singular Asset Macros
  147. //Singular assets
  148. /// <Summary>
  149. /// Declares an material asset
  150. /// This establishes the assetId, asset and legacy filepath fields, along with supplemental getter and setter functions
  151. /// </Summary>
  152. #define DECLARE_MATERIALASSET(className, name) public: \
  153. StringTableEntry m##name##Name;\
  154. StringTableEntry m##name##AssetId;\
  155. AssetPtr<MaterialAsset> m##name##Asset;\
  156. SimObjectPtr<Material> m##name;\
  157. public: \
  158. const StringTableEntry get##name##File() const { return m##name##Name; }\
  159. void set##name##Name(const FileName &_in) { m##name##Name = StringTable->insert(_in.c_str());}\
  160. const AssetPtr<MaterialAsset> & get##name##Asset() const { return m##name##Asset; }\
  161. void set##name##Asset(const AssetPtr<MaterialAsset> &_in) { m##name##Asset = _in;}\
  162. \
  163. bool _set##name(StringTableEntry _in)\
  164. {\
  165. if(m##name##AssetId != _in || m##name##Name != _in)\
  166. {\
  167. if (_in == NULL || _in == StringTable->EmptyString())\
  168. {\
  169. m##name##Name = StringTable->EmptyString();\
  170. m##name##AssetId = StringTable->EmptyString();\
  171. m##name##Asset = NULL;\
  172. m##name = NULL;\
  173. return true;\
  174. }\
  175. \
  176. if (AssetDatabase.isDeclaredAsset(_in))\
  177. {\
  178. m##name##AssetId = _in;\
  179. \
  180. U32 assetState = MaterialAsset::getAssetById(m##name##AssetId, &m##name##Asset);\
  181. \
  182. if (MaterialAsset::Ok == assetState)\
  183. {\
  184. m##name##Name = StringTable->EmptyString();\
  185. }\
  186. }\
  187. else\
  188. {\
  189. StringTableEntry assetId = MaterialAsset::getAssetIdByMaterialName(_in);\
  190. if (assetId != StringTable->EmptyString())\
  191. {\
  192. m##name##AssetId = assetId;\
  193. if (MaterialAsset::getAssetById(m##name##AssetId, &m##name##Asset) == MaterialAsset::Ok)\
  194. {\
  195. m##name##Name = StringTable->EmptyString();\
  196. }\
  197. }\
  198. else\
  199. {\
  200. m##name##Name = _in;\
  201. m##name##AssetId = StringTable->EmptyString();\
  202. m##name##Asset = NULL;\
  203. }\
  204. }\
  205. }\
  206. if (get##name() != StringTable->EmptyString() && m##name##Asset.notNull())\
  207. {\
  208. if (m##name && String(m##name##Asset->getMaterialDefinitionName()).equal(m##name->getName(), String::NoCase))\
  209. return false;\
  210. \
  211. Material* tempMat = nullptr;\
  212. \
  213. if (!Sim::findObject(m##name##Asset->getMaterialDefinitionName(), tempMat))\
  214. Con::errorf("%s::_set%s() - Material %s was not found.", macroText(className), macroText(name), m##name##Asset->getMaterialDefinitionName());\
  215. m##name = tempMat;\
  216. }\
  217. else\
  218. {\
  219. m##name = NULL;\
  220. }\
  221. \
  222. if(get##name() == StringTable->EmptyString())\
  223. return true;\
  224. \
  225. if (m##name##Asset.notNull() && m##name##Asset->getStatus() != MaterialAsset::Ok)\
  226. {\
  227. Con::errorf("%s::_set%s() - material asset failure\"%s\" due to [%s]", macroText(className), macroText(name), _in, MaterialAsset::getAssetErrstrn(m##name##Asset->getStatus()).c_str());\
  228. return false; \
  229. }\
  230. else if (!m##name)\
  231. {\
  232. Con::errorf("%s::_set%s() - Couldn't load material \"%s\"", macroText(className), macroText(name), _in);\
  233. return false;\
  234. }\
  235. return true;\
  236. }\
  237. \
  238. const StringTableEntry get##name() const\
  239. {\
  240. if (m##name##Asset && (m##name##Asset->getMaterialDefinitionName() != StringTable->EmptyString()))\
  241. return m##name##Asset->getMaterialDefinitionName();\
  242. else if (m##name##AssetId != StringTable->EmptyString())\
  243. return m##name##AssetId;\
  244. else if (m##name##Name != StringTable->EmptyString())\
  245. return m##name##Name;\
  246. else\
  247. return StringTable->EmptyString();\
  248. }\
  249. SimObjectPtr<Material> get##name##Resource() \
  250. {\
  251. return m##name;\
  252. }\
  253. bool is##name##Valid() {return (get##name() != StringTable->EmptyString() && m##name##Asset->getStatus() == AssetBase::Ok); }
  254. #ifdef TORQUE_SHOW_LEGACY_FILE_FIELDS
  255. #define INITPERSISTFIELD_MATERIALASSET(name, consoleClass, docs) \
  256. addProtectedField(#name, TypeMaterialName, Offset(m##name##Name, consoleClass), _set##name##Data, &defaultProtectedGetFn,assetDoc(name, docs)); \
  257. addProtectedField(assetText(name, Asset), TypeMaterialAssetId, Offset(m##name##AssetId, consoleClass), _set##name##Data, &defaultProtectedGetFn, assetDoc(name, asset docs.));
  258. #else
  259. #define INITPERSISTFIELD_MATERIALASSET(name, consoleClass, docs) \
  260. addProtectedField(#name, TypeMaterialName, Offset(m##name##Name, consoleClass), _set##name##Data, &defaultProtectedGetFn,assetDoc(name, docs), AbstractClassRep::FIELD_HideInInspectors); \
  261. addProtectedField(assetText(name, Asset), TypeMaterialAssetId, Offset(m##name##AssetId, consoleClass), _set##name##Data, &defaultProtectedGetFn, assetDoc(name, asset docs.));
  262. #endif // SHOW_LEGACY_FILE_FIELDS
  263. #define LOAD_MATERIALASSET(name)\
  264. if (m##name##AssetId != StringTable->EmptyString())\
  265. {\
  266. S32 assetState = MaterialAsset::getAssetById(m##name##AssetId, &m##name##Asset);\
  267. if (assetState == MaterialAsset::Ok )\
  268. {\
  269. m##name##Name = StringTable->EmptyString();\
  270. }\
  271. else Con::warnf("Warning: %s::LOAD_MATERIALASSET(%s)-%s", mClassName, m##name##AssetId, MaterialAsset::getAssetErrstrn(assetState).c_str());\
  272. }
  273. #pragma endregion
  274. #endif // _ASSET_BASE_H_