diff --git a/Engine/source/T3D/assets/ImageAsset.cpp b/Engine/source/T3D/assets/ImageAsset.cpp index 2c5f9f341..d49cfbf85 100644 --- a/Engine/source/T3D/assets/ImageAsset.cpp +++ b/Engine/source/T3D/assets/ImageAsset.cpp @@ -58,7 +58,7 @@ StringTableEntry ImageAsset::smNoImageAssetFallback = NULL; IMPLEMENT_CONOBJECT(ImageAsset); -ConsoleType(ImageAssetPtr, TypeImageAssetPtr, const char*, ASSET_ID_FIELD_PREFIX) +ConsoleType(ImageAssetPtr, TypeImageAssetPtr, const char*, "") //----------------------------------------------------------------------------- @@ -85,7 +85,7 @@ ConsoleSetType(TypeImageAssetPtr) Con::warnf("(TypeImageAssetPtr) - Cannot set multiple args to a single asset."); } -ConsoleType(assetIdString, TypeImageAssetId, const char*, ASSET_ID_FIELD_PREFIX) +ConsoleType(assetIdString, TypeImageAssetId, const char*, "") ConsoleGetType(TypeImageAssetId) { diff --git a/Engine/source/T3D/assets/MaterialAsset.cpp b/Engine/source/T3D/assets/MaterialAsset.cpp index f2197cf01..6eb4ea200 100644 --- a/Engine/source/T3D/assets/MaterialAsset.cpp +++ b/Engine/source/T3D/assets/MaterialAsset.cpp @@ -154,8 +154,9 @@ void MaterialAsset::initPersistFields() Parent::initPersistFields(); //addField("shaderGraph", TypeRealString, Offset(mShaderGraphFile, MaterialAsset), ""); - addProtectedField("scriptFile", TypeAssetLooseFilePath, Offset(mScriptFile, MaterialAsset), - &setScriptFile, &getScriptFile, "Path to the file containing the material definition."); + //addProtectedField("scriptFile", TypeAssetLooseFilePath, Offset(mScriptFile, MaterialAsset), + // &setScriptFile, &getScriptFile, "Path to the file containing the material definition."); + addField("scriptFile", TypeAssetLooseFilePath, Offset(mScriptFile, MaterialAsset), ""); addField("materialDefinitionName", TypeString, Offset(mMatDefinitionName, MaterialAsset), "Name of the material definition this asset is for."); } @@ -173,7 +174,16 @@ void MaterialAsset::initializeAsset() return; } - if (Torque::FS::IsScriptFile(mScriptPath)) + if (mMatDefinitionName == StringTable->insert("DetailBlue")) + { + bool asdfsd = true; + } + + if (size() != 0 && mScriptPath == StringTable->EmptyString()) + { + mLoadedState = EmbeddedDefinition; + } + else if (Torque::FS::IsScriptFile(mScriptPath)) { if (!Sim::findObject(mMatDefinitionName)) { @@ -230,7 +240,6 @@ void MaterialAsset::setScriptFile(const char* pScriptFile) // Sanity! AssertFatal(pScriptFile != NULL, "Cannot use a NULL script file."); - // Fetch image file. pScriptFile = StringTable->insert(pScriptFile, true); // Update. @@ -245,9 +254,28 @@ void MaterialAsset::setScriptFile(const char* pScriptFile) void MaterialAsset::loadMaterial() { if (mMaterialDefinition) - SAFE_DELETE(mMaterialDefinition); + { + mMaterialDefinition->safeDeleteObject(); + } - if ((mLoadedState == ScriptLoaded || mLoadedState == DefinitionAlreadyExists) && mMatDefinitionName != StringTable->EmptyString()) + if (mLoadedState == EmbeddedDefinition) + { + if (size() != 0) + { + for (U32 i = 0; i < size(); i++) + { + mMaterialDefinition = dynamic_cast(getObject(i)); + if (mMaterialDefinition) + { + mLoadedState = Ok; + mMaterialDefinition->setInternalName(getAssetId()); + mMaterialDefinition->reload(); + return; + } + } + } + } + else if ((mLoadedState == ScriptLoaded || mLoadedState == DefinitionAlreadyExists) && mMatDefinitionName != StringTable->EmptyString()) { Material* matDef; if (!Sim::findObject(mMatDefinitionName, matDef)) @@ -260,7 +288,7 @@ void MaterialAsset::loadMaterial() mMaterialDefinition = matDef; mLoadedState = Ok; - + mMaterialDefinition->setInternalName(getAssetId()); mMaterialDefinition->reload(); return; } @@ -296,11 +324,11 @@ U32 MaterialAsset::getAssetByMaterialName(StringTableEntry matName, AssetPtrmLoadedState == BadFileReference) { - Con::warnf("ShapeAsset::getAssetByMaterialName - Finding of associated with aterial name %s failed, and fallback asset reported error of Bad File Reference.", matName); + Con::warnf("MaterialAsset::getAssetByMaterialName - Finding of associated with aterial name %s failed, and fallback asset reported error of Bad File Reference.", matName); return AssetErrCode::BadFileReference; } - Con::warnf("ShapeAsset::getAssetByMaterialName - Finding of associated with aterial name %s failed, utilizing fallback asset", matName); + Con::warnf("MaterialAsset::getAssetByMaterialName - Finding of associated with aterial name %s failed, utilizing fallback asset", matName); (*matAsset)->mLoadedState = AssetErrCode::UsingFallback; return AssetErrCode::UsingFallback; @@ -388,6 +416,17 @@ U32 MaterialAsset::getAssetById(StringTableEntry assetId, AssetPtr MaterialAsset::findMaterialDefinitionByAssetId(StringTableEntry assetId) +{ + SimSet* matSet = MATMGR->getMaterialSet(); + if (matSet) + { + SimObjectPtr matDef = dynamic_cast(matSet->findObjectByInternalName(assetId)); + return matDef; + } + return nullptr; +} + #ifdef TORQUE_TOOLS DefineEngineStaticMethod(MaterialAsset, getAssetIdByMaterialName, const char*, (const char* materialName), (""), "Queries the Asset Database to see if any asset exists that is associated with the provided material name.\n" @@ -396,6 +435,19 @@ DefineEngineStaticMethod(MaterialAsset, getAssetIdByMaterialName, const char*, ( return MaterialAsset::getAssetIdByMaterialName(StringTable->insert(materialName)); } +//MaterialAsset::findMaterialDefinitionByAssetId("Prototyping:Detail") +DefineEngineStaticMethod(MaterialAsset, findMaterialDefinitionByAssetId, S32, (const char* assetId), (""), + "Queries the MaterialSet to see if any MaterialDefinition exists that is associated to the provided assetId.\n" + "@return The MaterialDefinition Id associated to the assetId, if any") +{ + SimObjectPtr matDef = MaterialAsset::findMaterialDefinitionByAssetId(StringTable->insert(assetId)); + if (matDef.isNull()) + return SimObjectId(0); + else + return matDef->getId(); +} + + DefineEngineMethod(MaterialAsset, getScriptPath, const char*, (), , "Queries the Asset Database to see if any asset exists that is associated with the provided material name.\n" "@return The AssetId of the associated asset, if any.") diff --git a/Engine/source/T3D/assets/MaterialAsset.h b/Engine/source/T3D/assets/MaterialAsset.h index a6dff23c8..561f02fe5 100644 --- a/Engine/source/T3D/assets/MaterialAsset.h +++ b/Engine/source/T3D/assets/MaterialAsset.h @@ -48,7 +48,9 @@ #include "sim/netConnection.h" #endif +#ifndef _GUI_INSPECTOR_TYPES_H_ #include "gui/editor/guiInspectorTypes.h" +#endif #include "materials/matTextureTarget.h" #include "materials/materialDefinition.h" @@ -75,6 +77,7 @@ public: { ScriptLoaded = AssetErrCode::Extended, DefinitionAlreadyExists, + EmbeddedDefinition, Extended }; @@ -108,6 +111,7 @@ public: /// AssetId of matching asset. static StringTableEntry getAssetIdByMaterialName(StringTableEntry matName); static U32 getAssetById(StringTableEntry assetId, AssetPtr* materialAsset); + static SimObjectPtr findMaterialDefinitionByAssetId(StringTableEntry assetId); static U32 getAssetByMaterialName(StringTableEntry matName, AssetPtr* matAsset); /// Declare Console Object. diff --git a/Engine/source/T3D/assets/TerrainMaterialAsset.cpp b/Engine/source/T3D/assets/TerrainMaterialAsset.cpp index ee5a36004..3ef54d856 100644 --- a/Engine/source/T3D/assets/TerrainMaterialAsset.cpp +++ b/Engine/source/T3D/assets/TerrainMaterialAsset.cpp @@ -40,6 +40,10 @@ #include "assets/assetPtr.h" #endif +#include "T3D/assets/assetImporter.h" + +StringTableEntry TerrainMaterialAsset::smNoTerrainMaterialAssetFallback = NULL; + //----------------------------------------------------------------------------- IMPLEMENT_CONOBJECT(TerrainMaterialAsset); @@ -85,6 +89,35 @@ ConsoleSetType(TypeTerrainMaterialAssetPtr) Con::warnf("(TypeTerrainMaterialAssetPtr) - Cannot set multiple args to a single asset."); } + +ConsoleType(assetIdString, TypeTerrainMaterialAssetId, const char*, ASSET_ID_FIELD_PREFIX) + +ConsoleGetType(TypeTerrainMaterialAssetId) +{ + // Fetch asset Id. + return *((const char**)(dptr)); +} + +ConsoleSetType(TypeTerrainMaterialAssetId) +{ + // Was a single argument specified? + if (argc == 1) + { + // Yes, so fetch field value. + const char* pFieldValue = argv[0]; + + // Fetch asset Id. + StringTableEntry* assetId = (StringTableEntry*)(dptr); + + // Update asset value. + *assetId = StringTable->insert(pFieldValue); + + return; + } + + // Warn. + Con::warnf("(TypeTerrainMaterialAssetId) - Cannot set multiple args to a single asset."); +} //----------------------------------------------------------------------------- TerrainMaterialAsset::TerrainMaterialAsset() @@ -92,24 +125,41 @@ TerrainMaterialAsset::TerrainMaterialAsset() mScriptFile = StringTable->EmptyString(); mScriptPath = StringTable->EmptyString(); mMatDefinitionName = StringTable->EmptyString(); + mMaterialDefinition = nullptr; + mFXMaterialDefinition = nullptr; } //----------------------------------------------------------------------------- TerrainMaterialAsset::~TerrainMaterialAsset() { + if (mMaterialDefinition) + mMaterialDefinition->safeDeleteObject(); + if (mFXMaterialDefinition) + mFXMaterialDefinition->safeDeleteObject(); } //----------------------------------------------------------------------------- +void TerrainMaterialAsset::consoleInit() +{ + Parent::consoleInit(); + Con::addVariable("$Core::NoTerrainMaterialAssetFallback", TypeString, &smNoTerrainMaterialAssetFallback, + "The assetId of the material to display when the requested material asset is missing.\n" + "@ingroup GFX\n"); + + smNoTerrainMaterialAssetFallback = StringTable->insert(Con::getVariable("$Core::NoTerrainMaterialAssetFallback")); +} + void TerrainMaterialAsset::initPersistFields() { // Call parent. Parent::initPersistFields(); //addField("shaderGraph", TypeRealString, Offset(mShaderGraphFile, TerrainMaterialAsset), ""); - addProtectedField("scriptFile", TypeAssetLooseFilePath, Offset(mScriptFile, TerrainMaterialAsset), - &setScriptFile, &getScriptFile, "Path to the file containing the material definition."); + //addProtectedField("scriptFile", TypeAssetLooseFilePath, Offset(mScriptFile, TerrainMaterialAsset), + // &setScriptFile, &getScriptFile, "Path to the file containing the material definition."); + addField("scriptFile", TypeAssetLooseFilePath, Offset(mScriptFile, TerrainMaterialAsset), ""); addField("materialDefinitionName", TypeString, Offset(mMatDefinitionName, TerrainMaterialAsset), "Name of the material definition this asset is for."); } @@ -121,28 +171,71 @@ void TerrainMaterialAsset::initializeAsset() mScriptPath = getOwned() ? expandAssetFilePath(mScriptFile) : mScriptPath; - if (Torque::FS::IsScriptFile(mScriptPath)) - Con::executeFile(mScriptPath, false, false); + if (mMatDefinitionName == StringTable->EmptyString()) + { + mLoadedState = Failed; + return; + } + + if (mMatDefinitionName == StringTable->insert("DetailBlue")) + { + bool asdfsd = true; + } + + if (size() != 0 && mScriptPath == StringTable->EmptyString()) + { + mLoadedState = EmbeddedDefinition; + } + else if (Torque::FS::IsScriptFile(mScriptPath)) + { + if (!Sim::findObject(mMatDefinitionName)) + { + if (Con::executeFile(mScriptPath, false, false)) + { + mLoadedState = ScriptLoaded; + } + else + { + mLoadedState = Failed; + } + } + else + { + mLoadedState = DefinitionAlreadyExists; + } + } + + loadMaterial(); } void TerrainMaterialAsset::onAssetRefresh() { mScriptPath = getOwned() ? expandAssetFilePath(mScriptFile) : mScriptPath; - if (Torque::FS::IsScriptFile(mScriptPath)) - Con::executeFile(mScriptPath, false, false); - - if (mMatDefinitionName != StringTable->EmptyString()) + if (mMatDefinitionName == StringTable->EmptyString()) { - TerrainMaterial* matDef; - if (!Sim::findObject(mMatDefinitionName, matDef)) - { - Con::errorf("TerrainMaterialAsset: Unable to find the Material %s", mMatDefinitionName); + mLoadedState = Failed; return; } - //matDef->reload(); + if (Torque::FS::IsScriptFile(mScriptPath)) + { + //Since we're refreshing, we can assume that the file we're executing WILL have an existing definition. + //But that definition, whatever it is, is the 'correct' one, so we enable the Replace Existing behavior + //when the engine encounters a named object conflict. + String redefineBehaviorPrev = Con::getVariable("$Con::redefineBehavior"); + Con::setVariable("$Con::redefineBehavior", "replaceExisting"); + + if (Con::executeFile(mScriptPath, false, false)) + mLoadedState = ScriptLoaded; + else + mLoadedState = Failed; + + //And now that we've executed, switch back to the prior behavior + Con::setVariable("$Con::redefineBehavior", redefineBehaviorPrev.c_str()); } + + loadMaterial(); } void TerrainMaterialAsset::setScriptFile(const char* pScriptFile) @@ -152,10 +245,6 @@ void TerrainMaterialAsset::setScriptFile(const char* pScriptFile) pScriptFile = StringTable->insert(pScriptFile, true); - // Ignore no change, - if (pScriptFile == mScriptFile) - return; - // Update. mScriptFile = getOwned() ? expandAssetFilePath(pScriptFile) : pScriptFile; @@ -165,41 +254,185 @@ void TerrainMaterialAsset::setScriptFile(const char* pScriptFile) //------------------------------------------------------------------------------ +void TerrainMaterialAsset::loadMaterial() +{ + if (mMaterialDefinition) + mMaterialDefinition->safeDeleteObject(); + if (mFXMaterialDefinition) + mFXMaterialDefinition->safeDeleteObject(); + + if (mLoadedState == EmbeddedDefinition) + { + if (size() != 0) + { + for (U32 i = 0; i < size(); i++) + { + mMaterialDefinition = dynamic_cast(getObject(i)); + if (mMaterialDefinition) + { + mLoadedState = Ok; + mMaterialDefinition->setInternalName(getAssetId()); + continue; + } + + //Otherwise, check if it's our FX material + mFXMaterialDefinition = dynamic_cast(getObject(i)); + if (mFXMaterialDefinition) + { + //mMaterialDefinition->setInternalName(getAssetId()); + mFXMaterialDefinition->reload(); + continue; + } + + } + } + } + else if ((mLoadedState == ScriptLoaded || mLoadedState == DefinitionAlreadyExists) && mMatDefinitionName != StringTable->EmptyString()) + { + TerrainMaterial* matDef; + if (!Sim::findObject(mMatDefinitionName, matDef)) + { + Con::errorf("TerrainMaterialAsset: Unable to find the Material %s", mMatDefinitionName); + mLoadedState = BadFileReference; + return; + } + + mMaterialDefinition = matDef; + + mLoadedState = Ok; + mMaterialDefinition->setInternalName(getAssetId()); + return; + } + + mLoadedState = Failed; +} + +//------------------------------------------------------------------------------ + void TerrainMaterialAsset::copyTo(SimObject* object) { // Call to parent. Parent::copyTo(object); } -StringTableEntry TerrainMaterialAsset::getAssetIdByMaterialName(StringTableEntry matName) +//------------------------------------------------------------------------------ +U32 TerrainMaterialAsset::getAssetByMaterialName(StringTableEntry matName, AssetPtr* matAsset) { - StringTableEntry materialAssetId = StringTable->EmptyString(); - - AssetQuery* query = new AssetQuery(); - U32 foundCount = AssetDatabase.findAssetType(query, "TerrainMaterialAsset"); - if (foundCount == 0) + AssetQuery query; + U32 foundAssetcount = AssetDatabase.findAssetType(&query, "TerrainMaterialAsset"); + if (foundAssetcount == 0) { //Didn't work, so have us fall back to a placeholder asset - materialAssetId = StringTable->insert("Core_Rendering:noMaterial"); + matAsset->setAssetId(TerrainMaterialAsset::smNoTerrainMaterialAssetFallback); + + if (matAsset->isNull()) + { + //Well that's bad, loading the fallback failed. + Con::warnf("TerrainMaterialAsset::getAssetByMaterialName - Finding of asset associated with material name %s failed with no fallback asset", matName); + return AssetErrCode::Failed; + } + + //handle noshape not being loaded itself + if ((*matAsset)->mLoadedState == BadFileReference) + { + Con::warnf("TerrainMaterialAsset::getAssetByMaterialName - Finding of associated with aterial name %s failed, and fallback asset reported error of Bad File Reference.", matName); + return AssetErrCode::BadFileReference; + } + + Con::warnf("TerrainMaterialAsset::getAssetByMaterialName - Finding of associated with aterial name %s failed, utilizing fallback asset", matName); + + (*matAsset)->mLoadedState = AssetErrCode::UsingFallback; + return AssetErrCode::UsingFallback; } else + { + for (U32 i = 0; i < foundAssetcount; i++) + { + TerrainMaterialAsset* tMatAsset = AssetDatabase.acquireAsset(query.mAssetList[i]); + if (tMatAsset && tMatAsset->getMaterialDefinitionName() == matName) + { + matAsset->setAssetId(query.mAssetList[i]); + AssetDatabase.releaseAsset(query.mAssetList[i]); + return (*matAsset)->mLoadedState; + } + AssetDatabase.releaseAsset(query.mAssetList[i]); //cleanup if that's not the one we needed + } + } + + //Somehow we failed to bind an asset, so just use the fallback and mark the failure + matAsset->setAssetId(TerrainMaterialAsset::smNoTerrainMaterialAssetFallback); + (*matAsset)->mLoadedState = AssetErrCode::UsingFallback; + return AssetErrCode::UsingFallback; + +} + +StringTableEntry TerrainMaterialAsset::getAssetIdByMaterialName(StringTableEntry matName) +{ + if (matName == StringTable->EmptyString()) + return StringTable->EmptyString(); + + StringTableEntry materialAssetId = TerrainMaterialAsset::smNoTerrainMaterialAssetFallback; + + AssetQuery query; + U32 foundCount = AssetDatabase.findAssetType(&query, "TerrainMaterialAsset"); + if (foundCount != 0) { for (U32 i = 0; i < foundCount; i++) { - TerrainMaterialAsset* matAsset = AssetDatabase.acquireAsset(query->mAssetList[i]); + TerrainMaterialAsset* matAsset = AssetDatabase.acquireAsset(query.mAssetList[i]); if (matAsset && matAsset->getMaterialDefinitionName() == matName) { materialAssetId = matAsset->getAssetId(); - AssetDatabase.releaseAsset(query->mAssetList[i]); + AssetDatabase.releaseAsset(query.mAssetList[i]); break; } - AssetDatabase.releaseAsset(query->mAssetList[i]); + AssetDatabase.releaseAsset(query.mAssetList[i]); } } return materialAssetId; } +U32 TerrainMaterialAsset::getAssetById(StringTableEntry assetId, AssetPtr* materialAsset) +{ + (*materialAsset) = assetId; + if (materialAsset->notNull()) + { + return (*materialAsset)->mLoadedState; + } + else + { + //Didn't work, so have us fall back to a placeholder asset + materialAsset->setAssetId(TerrainMaterialAsset::smNoTerrainMaterialAssetFallback); + if (materialAsset->isNull()) + { + //Well that's bad, loading the fallback failed. + Con::warnf("TerrainMaterialAsset::getAssetById - Finding of asset with id %s failed with no fallback asset", assetId); + return AssetErrCode::Failed; + } + //handle noshape not being loaded itself + if ((*materialAsset)->mLoadedState == BadFileReference) + { + Con::warnf("TerrainMaterialAsset::getAssetById - Finding of asset with id %s failed, and fallback asset reported error of Bad File Reference.", assetId); + return AssetErrCode::BadFileReference; + } + Con::warnf("TerrainMaterialAsset::getAssetById - Finding of asset with id %s failed, utilizing fallback asset", assetId); + (*materialAsset)->mLoadedState = AssetErrCode::UsingFallback; + return AssetErrCode::UsingFallback; + } +} +SimObjectPtr TerrainMaterialAsset::findMaterialDefinitionByAssetId(StringTableEntry assetId) +{ + SimSet* terrainMatSet; + if (!Sim::findObject("TerrainMaterialSet", terrainMatSet)) + { + return nullptr; + } + + SimObjectPtr matDef = dynamic_cast(terrainMatSet->findObjectByInternalName(assetId)); + return matDef; +} + #ifdef TORQUE_TOOLS DefineEngineStaticMethod(TerrainMaterialAsset, getAssetIdByMaterialName, const char*, (const char* materialName), (""), "Queries the Asset Database to see if any asset exists that is associated with the provided material name.\n" @@ -207,6 +440,26 @@ DefineEngineStaticMethod(TerrainMaterialAsset, getAssetIdByMaterialName, const c { return TerrainMaterialAsset::getAssetIdByMaterialName(StringTable->insert(materialName)); } + +//MaterialAsset::findMaterialDefinitionByAssetId("Prototyping:Detail") +DefineEngineStaticMethod(TerrainMaterialAsset, findMaterialDefinitionByAssetId, S32, (const char* assetId), (""), + "Queries the MaterialSet to see if any MaterialDefinition exists that is associated to the provided assetId.\n" + "@return The MaterialDefinition Id associated to the assetId, if any") +{ + SimObjectPtr matDef = TerrainMaterialAsset::findMaterialDefinitionByAssetId(StringTable->insert(assetId)); + if (matDef.isNull()) + return SimObjectId(0); + else + return matDef->getId(); +} + + +DefineEngineMethod(TerrainMaterialAsset, getScriptPath, const char*, (), , + "Queries the Asset Database to see if any asset exists that is associated with the provided material name.\n" + "@return The AssetId of the associated asset, if any.") +{ + return object->getScriptPath(); +} #endif //----------------------------------------------------------------------------- // GuiInspectorTypeAssetId @@ -343,3 +596,18 @@ DefineEngineMethod(GuiInspectorTypeTerrainMaterialAssetPtr, setMaterialAsset, vo return object->setMaterialAsset(assetId); } + +IMPLEMENT_CONOBJECT(GuiInspectorTypeTerrainMaterialAssetId); + +ConsoleDocClass(GuiInspectorTypeTerrainMaterialAssetId, + "@brief Inspector field type for Terrain Material Assets\n\n" + "Editor use only.\n\n" + "@internal" +); + +void GuiInspectorTypeTerrainMaterialAssetId::consoleInit() +{ + Parent::consoleInit(); + + ConsoleBaseType::getType(TypeTerrainMaterialAssetId)->setInspectorFieldType("GuiInspectorTypeTerrainMaterialAssetId"); +} diff --git a/Engine/source/T3D/assets/TerrainMaterialAsset.h b/Engine/source/T3D/assets/TerrainMaterialAsset.h index e0a60e391..dfa3c3ef1 100644 --- a/Engine/source/T3D/assets/TerrainMaterialAsset.h +++ b/Engine/source/T3D/assets/TerrainMaterialAsset.h @@ -47,7 +47,13 @@ #include "gui/editor/guiInspectorTypes.h" #endif +#ifndef _TERRMATERIAL_H_ #include "terrain/terrMaterial.h" +#endif + +#ifndef _MATERIALDEFINITION_H_ +#include "materials/materialDefinition.h" +#endif //----------------------------------------------------------------------------- class TerrainMaterialAsset : public AssetBase @@ -58,23 +64,53 @@ class TerrainMaterialAsset : public AssetBase StringTableEntry mScriptPath; StringTableEntry mMatDefinitionName; + SimObjectPtr mMaterialDefinition; + + SimObjectPtr mFXMaterialDefinition; + +public: + static StringTableEntry smNoTerrainMaterialAssetFallback; + + enum TerrainMaterialAssetErrCode + { + ScriptLoaded = AssetErrCode::Extended, + DefinitionAlreadyExists, + EmbeddedDefinition, + Extended + }; + public: TerrainMaterialAsset(); virtual ~TerrainMaterialAsset(); + /// Set up some global script interface stuff. + static void consoleInit(); /// Engine. static void initPersistFields(); virtual void copyTo(SimObject* object); - static StringTableEntry getAssetIdByMaterialName(StringTableEntry matName); + void loadMaterial(); StringTableEntry getMaterialDefinitionName() { return mMatDefinitionName; } + SimObjectPtr getMaterialDefinition() { return mMaterialDefinition; } void setScriptFile(const char* pScriptFile); inline StringTableEntry getScriptFile(void) const { return mScriptFile; }; inline StringTableEntry getScriptPath(void) const { return mScriptPath; }; + /// + /// Looks for any assets that uses the provided Material Definition name. + /// If none are found, attempts to auto-import the material definition if the + /// material definition exists. + /// + /// Material Definition name to look for + /// AssetId of matching asset. + static StringTableEntry getAssetIdByMaterialName(StringTableEntry matName); + static U32 getAssetById(StringTableEntry assetId, AssetPtr* materialAsset); + static SimObjectPtr findMaterialDefinitionByAssetId(StringTableEntry assetId); + static U32 getAssetByMaterialName(StringTableEntry matName, AssetPtr* matAsset); + /// Declare Console Object. DECLARE_CONOBJECT(TerrainMaterialAsset); @@ -82,11 +118,16 @@ protected: virtual void initializeAsset(); virtual void onAssetRefresh(void); - static bool setScriptFile(void *obj, const char *index, const char *data) { static_cast(obj)->setScriptFile(data); return false; } + static bool setScriptFile(void *obj, const char *index, const char *data) + { + static_cast(obj)->setScriptFile(data); + return false; + } static const char* getScriptFile(void* obj, const char* data) { return static_cast(obj)->getScriptFile(); } }; DefineConsoleType(TypeTerrainMaterialAssetPtr, TerrainMaterialAsset) +DefineConsoleType(TypeMaterialAssetId, String) //----------------------------------------------------------------------------- // TypeAssetId GuiInspectorField Class @@ -107,6 +148,14 @@ public: virtual bool updateRects(); void setMaterialAsset(String assetId); }; +class GuiInspectorTypeTerrainMaterialAssetId : public GuiInspectorTypeTerrainMaterialAssetPtr +{ + typedef GuiInspectorTypeTerrainMaterialAssetPtr Parent; +public: + + DECLARE_CONOBJECT(GuiInspectorTypeTerrainMaterialAssetId); + static void consoleInit(); +}; #endif // _ASSET_BASE_H_ diff --git a/Engine/source/T3D/assets/assetImporter.cpp b/Engine/source/T3D/assets/assetImporter.cpp index de603d1fc..f965bd42c 100644 --- a/Engine/source/T3D/assets/assetImporter.cpp +++ b/Engine/source/T3D/assets/assetImporter.cpp @@ -609,14 +609,32 @@ AssetImportObject* AssetImporter::addImportingAsset(String assetType, Torque::Pa assetImportObj->registerObject(); //sanitize - assetName.replace(' ', '_'); - assetName.replace('~', '_'); - assetName.replace('`', '_'); - assetName.replace('-', '_'); - assetName.replace('*', '_'); - assetName.replace('-', '_'); - assetName.replace('+', '_'); - assetName.replace('&', '_'); + String processedString = assetName; + + U32 start; + U32 end; + String firstNumber = String::GetFirstNumber(processedString, start, end); + if (!firstNumber.isEmpty() && processedString.startsWith(firstNumber.c_str())) + processedString = processedString.replace(firstNumber, ""); + + processedString = processedString.replace(" ", "_"); + + U32 len = processedString.length() + 1; + char* sanitizedStr = Con::getReturnBuffer(len); + dStrcpy(sanitizedStr, processedString.c_str(), len); + + U32 pos = dStrcspn(sanitizedStr, "-+*/%$&�=()[].?\\\"#,;!~<>|�^{}"); + while (pos < dStrlen(sanitizedStr)) + { + dStrcpy(sanitizedStr + pos, sanitizedStr + pos + 1, len - pos); + pos = dStrcspn(sanitizedStr, "-+*/%$&�=()[].?\\\"#,;!~<>|�^{}"); + } + + //If we did, indeed, modify the name, update it now + if (String(sanitizedStr) != assetName) + { + assetName = sanitizedStr; + } assetImportObj->assetType = assetType; assetImportObj->filePath = filePath; @@ -2725,8 +2743,6 @@ Torque::Path AssetImporter::importMaterialAsset(AssetImportObject* assetItem) StringTableEntry assetName = StringTable->insert(assetItem->assetName.c_str()); String tamlPath = targetPath + "/" + assetName + ".asset.taml"; - String scriptName = assetItem->assetName + "." TORQUE_SCRIPT_EXTENSION; - String scriptPath = targetPath + "/" + scriptName; String originalPath = assetItem->filePath.getFullPath().c_str(); char qualifiedFromFile[2048]; @@ -2734,10 +2750,8 @@ Torque::Path AssetImporter::importMaterialAsset(AssetImportObject* assetItem) Platform::makeFullPathName(originalPath.c_str(), qualifiedFromFile, sizeof(qualifiedFromFile)); newAsset->setAssetName(assetName); - newAsset->setScriptFile(scriptName.c_str()); newAsset->setDataField(StringTable->insert("originalFilePath"), nullptr, qualifiedFromFile); newAsset->setDataField(StringTable->insert("materialDefinitionName"), nullptr, assetName); - //iterate through and write out the material maps dependencies S32 dependencySlotId = 0; @@ -2759,16 +2773,6 @@ Torque::Path AssetImporter::importMaterialAsset(AssetImportObject* assetItem) dependencySlotId++; } - Taml tamlWriter; - bool importSuccessful = tamlWriter.write(newAsset, tamlPath.c_str()); - - if (!importSuccessful) - { - dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Unable to write asset taml file %s", tamlPath.c_str()); - activityLog.push_back(importLogBuffer); - return ""; - } - //build the ORMConfig file if we're flagged to and have valid image maps if (activeImportConfig->CreateORMConfig) { @@ -2807,109 +2811,12 @@ Torque::Path AssetImporter::importMaterialAsset(AssetImportObject* assetItem) } } - FileObject* file = new FileObject(); - file->registerObject(); - - if (activeImportConfig->UseExistingMaterials && Platform::isFile(qualifiedFromFile)) + //If we're not using existing materials, or the material in question doesn't actually already exist, spool it up + if (!activeImportConfig->UseExistingMaterials || !Sim::findObject(assetName)) { - //Now write the script file containing our material out - //There's 2 ways to do this. If we're in-place importing an existing asset, we can see if the definition existed already, like in an old - //materials.tscript file. if it does, we can just find the object by name, and save it out to our new file - //If not, we'll just generate one - Material* existingMat = MATMGR->getMaterialDefinitionByName(assetName); - - //It's also possible that, for legacy models, the material hooks in via the material's mapTo field, and the material name is something completely different - //So we'll check for that as well if we didn't find it by name up above - if (existingMat == nullptr) - existingMat = MATMGR->getMaterialDefinitionByMapTo(assetName); - - if (existingMat == nullptr && assetItem->assetName != assetItem->cleanAssetName) - { - existingMat = MATMGR->getMaterialDefinitionByName(assetItem->cleanAssetName); - if (existingMat == nullptr) - existingMat = MATMGR->getMaterialDefinitionByMapTo(assetItem->cleanAssetName); - } - - if (existingMat) - { - PersistenceManager* persistMgr; - if (Sim::findObject("ImageAssetValidator", persistMgr)) - { - for (U32 i = 0; i < assetItem->childAssetItems.size(); i++) - { - AssetImportObject* childItem = assetItem->childAssetItems[i]; - - if (childItem->canImport() || childItem->assetType.compare("ImageAsset") != 0) - continue; - - String path = childItem->filePath.getFullFileName(); - - String mapFieldName = ""; - String assetFieldName = ""; - - ImageAsset::ImageTypes imageType = ImageAsset::getImageTypeFromName(childItem->imageSuffixType); - - if (imageType == ImageAsset::ImageTypes::Albedo || childItem->imageSuffixType.isEmpty()) - { - mapFieldName = "DiffuseMap"; - } - else if (imageType == ImageAsset::ImageTypes::Normal) - { - mapFieldName = "NormalMap"; - } - else if (imageType == ImageAsset::ImageTypes::ORMConfig) - { - mapFieldName = "ORMConfig"; - } - else if (imageType == ImageAsset::ImageTypes::Metalness) - { - mapFieldName = "MetalMap"; - } - else if (imageType == ImageAsset::ImageTypes::AO) - { - mapFieldName = "AOMap"; - } - else if (imageType == ImageAsset::ImageTypes::Roughness) - { - mapFieldName = "RoughMap"; - } - - assetFieldName = mapFieldName + "Asset[0]"; - mapFieldName += "[0]"; - - //If there's already an existing image map file on the material definition in this slot, don't override it - if (!path.isEmpty()) - existingMat->writeField(mapFieldName.c_str(), path.c_str()); - - String targetAsset = targetModuleId + ":" + childItem->assetName; - - existingMat->writeField(assetFieldName.c_str(), targetAsset.c_str()); - } - - persistMgr->setDirty(existingMat); - } - else - { - Con::errorf("ImageAssetValidator not found!"); - } - } - else - { - dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Failed to find original material definition %s!", assetName); - activityLog.push_back(importLogBuffer); - return tamlPath; - } - } - else if (file->openForWrite(scriptPath.c_str())) - { - file->writeLine((U8*)"//--- OBJECT WRITE BEGIN ---"); - - char lineBuffer[1024]; - dSprintf(lineBuffer, 1024, "singleton Material(%s) {", assetName); - file->writeLine((U8*)lineBuffer); - - dSprintf(lineBuffer, 1024, " mapTo=\"%s\";", assetName); - file->writeLine((U8*)lineBuffer); + Material* newMat = new Material(); + newMat->registerObject(assetName); + newMat->mMapTo = assetName; bool hasRoughness = false; for (U32 i = 0; i < assetItem->childAssetItems.size(); i++) @@ -2919,63 +2826,58 @@ Torque::Path AssetImporter::importMaterialAsset(AssetImportObject* assetItem) if ((!childItem->canImport() && childItem->importStatus != AssetImportObject::UseForDependencies) || childItem->assetType.compare("ImageAsset") != 0) continue; - String mapFieldName = ""; - - String assetFieldName = ""; - ImageAsset::ImageTypes imageType = ImageAsset::getImageTypeFromName(childItem->imageSuffixType); + String assetMapFillIn = targetModuleId + ":" + childItem->assetName; + StringTableEntry assetMapFillInStr = StringTable->insert(assetMapFillIn.c_str()); + if (imageType == ImageAsset::ImageTypes::Albedo || childItem->imageSuffixType.isEmpty()) { - mapFieldName = "DiffuseMap"; + newMat->mDiffuseMapAssetId[0] = assetMapFillInStr; } else if (imageType == ImageAsset::ImageTypes::Normal) { - mapFieldName = "NormalMap"; + newMat->mNormalMapAssetId[0] = assetMapFillInStr; } else if (imageType == ImageAsset::ImageTypes::ORMConfig) { - mapFieldName = "ORMConfigMap"; + newMat->mORMConfigMapAssetId[0] = assetMapFillInStr; } else if (imageType == ImageAsset::ImageTypes::Metalness) { - mapFieldName = "MetalMap"; + newMat->mMetalMapAssetId[0] = assetMapFillInStr; } else if (imageType == ImageAsset::ImageTypes::AO) { - mapFieldName = "AOMap"; + newMat->mAOMapAssetId[0] = assetMapFillInStr; } else if (imageType == ImageAsset::ImageTypes::Roughness) { - mapFieldName = "RoughMap"; + newMat->mRoughMapAssetId[0] = assetMapFillInStr; hasRoughness = true; } - - assetFieldName = mapFieldName + "Asset"; - assetFieldName += "[0]"; - - //String path = childItem->filePath.getFullFileName(); - //dSprintf(lineBuffer, 1024, " %s = \"%s\";", mapFieldName.c_str(), path.c_str()); - //file->writeLine((U8*)lineBuffer); - - dSprintf(lineBuffer, 1024, " %s = \"%s:%s\";", assetFieldName.c_str(), targetModuleId.c_str(), childItem->assetName.c_str()); - file->writeLine((U8*)lineBuffer); } if (hasRoughness) { - file->writeLine((U8*)" invertSmoothness = true;"); - + newMat->mInvertRoughness[0] = true; } - file->writeLine((U8*)"};"); - file->writeLine((U8*)"//--- OBJECT WRITE END ---"); - - file->close(); + newAsset->addObject(newMat); } - else + else { - dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Unable to write asset script file %s", scriptPath.c_str()); + dSprintf(importLogBuffer, sizeof(importLogBuffer), "Set to use an existing material, so avoiding writing a material definition to new asset definition for material: %s", assetName); + activityLog.push_back(importLogBuffer); + return ""; + } + + Taml tamlWriter; + bool importSuccessful = tamlWriter.write(newAsset, tamlPath.c_str()); + + if (!importSuccessful) + { + dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Unable to write asset taml file %s", tamlPath.c_str()); activityLog.push_back(importLogBuffer); return ""; } diff --git a/Engine/source/assets/assetBase.h b/Engine/source/assets/assetBase.h index d4efc6a8a..516376663 100644 --- a/Engine/source/assets/assetBase.h +++ b/Engine/source/assets/assetBase.h @@ -55,11 +55,11 @@ extern StringTableEntry assetAutoUnloadField; //#define ASSET_BASE_AUTOUNLOAD_FIELD "AssetAutoUnload" //----------------------------------------------------------------------------- -class AssetBase : public SimObject +class AssetBase : public SimGroup { friend class AssetManager; - typedef SimObject Parent; + typedef SimGroup Parent; protected: AssetManager* mpOwningAssetManager; diff --git a/Engine/source/assets/assetDefinition.h b/Engine/source/assets/assetDefinition.h index 0d3b1c964..fb5720394 100644 --- a/Engine/source/assets/assetDefinition.h +++ b/Engine/source/assets/assetDefinition.h @@ -35,8 +35,8 @@ #include "console/sim.h" #endif -#ifndef _SIMOBJECT_H_ -#include "console/simObject.h" +#ifndef _SIMSET_H_ +#include "console/simset.h" #endif #ifndef _CONSOLEOBJECT_H_ diff --git a/Engine/source/console/simObject.cpp b/Engine/source/console/simObject.cpp index 3d485354c..3552f4dd1 100644 --- a/Engine/source/console/simObject.cpp +++ b/Engine/source/console/simObject.cpp @@ -77,6 +77,7 @@ SimObject::SimObject() mObjectName = NULL; mOriginalName = NULL; mInternalName = NULL; + mInheritFrom = NULL; nextNameObject = nullptr; nextManagerNameObject = nullptr; nextIdObject = NULL; @@ -154,6 +155,9 @@ void SimObject::initPersistFields() addProtectedField( "name", TypeName, Offset(mObjectName, SimObject), &setProtectedName, &defaultProtectedGetFn, "Optional global name of this object." ); + + addProtectedField("inheritFrom", TypeString, Offset(mInheritFrom, SimObject), &setInheritFrom, &defaultProtectedGetFn, + "Optional Name of object to inherit from as a parent."); endGroup( "Ungrouped" ); @@ -300,6 +304,10 @@ bool SimObject::writeField(StringTableEntry fieldname, const char* value) void SimObject::writeFields(Stream &stream, U32 tabStop) { // Write static fields. + + // Create a default object of the same type + ConsoleObject* defaultConObject = ConsoleObject::create(getClassName()); + SimObject* defaultObject = dynamic_cast(defaultConObject); const AbstractClassRep::FieldList &list = getFieldList(); @@ -328,6 +336,11 @@ void SimObject::writeFields(Stream &stream, U32 tabStop) if (!writeField(f->pFieldname, valCopy)) continue; + //If the field hasn't been changed from the default value, then don't bother writing it out + const char* defaultValueCheck = defaultObject->getDataField(f->pFieldname, array); + if (defaultValueCheck != '\0' && dStricmp(defaultValueCheck, valCopy) == 0) + continue; + val = valCopy; U32 expandedBufferSize = ( nBufferSize * 2 ) + dStrlen(f->pFieldname) + 32; @@ -362,6 +375,9 @@ void SimObject::writeFields(Stream &stream, U32 tabStop) if(mFieldDictionary && mCanSaveFieldDictionary) mFieldDictionary->writeFields(this, stream, tabStop); + + // Cleanup our created default object + delete defaultConObject; } //----------------------------------------------------------------------------- @@ -1133,7 +1149,7 @@ const char *SimObject::getPrefixedDataField(StringTableEntry fieldName, const ch //----------------------------------------------------------------------------- -void SimObject::setPrefixedDataField(StringTableEntry fieldName, const char *array, const char *value) +void SimObject::setPrefixedDataField(StringTableEntry fieldName, const char *_array, const char *value) { // Sanity! AssertFatal(fieldName != NULL, "Cannot set object field value with NULL field name."); @@ -1142,7 +1158,7 @@ void SimObject::setPrefixedDataField(StringTableEntry fieldName, const char *arr // Set value without prefix if there's no value. if (*value == 0) { - setDataField(fieldName, NULL, value); + setDataField(fieldName, _array, value); return; } @@ -1156,7 +1172,7 @@ void SimObject::setPrefixedDataField(StringTableEntry fieldName, const char *arr if (fieldPrefix == StringTable->EmptyString()) { // No, so set the data field in the usual way. - setDataField(fieldName, NULL, value); + setDataField(fieldName, _array, value); return; } @@ -1167,23 +1183,23 @@ void SimObject::setPrefixedDataField(StringTableEntry fieldName, const char *arr if (dStrnicmp(value, fieldPrefix, fieldPrefixLength) != 0) { // No, so set the data field in the usual way. - setDataField(fieldName, NULL, value); + setDataField(fieldName, _array, value); return; } // Yes, so set the data excluding the prefix. - setDataField(fieldName, NULL, value + fieldPrefixLength); + setDataField(fieldName, _array, value + fieldPrefixLength); } //----------------------------------------------------------------------------- -const char *SimObject::getPrefixedDynamicDataField(StringTableEntry fieldName, const char *array, const S32 fieldType) +const char *SimObject::getPrefixedDynamicDataField(StringTableEntry fieldName, const char *_array, const S32 fieldType) { // Sanity! AssertFatal(fieldName != NULL, "Cannot get field value with NULL field name."); // Fetch field value. - const char* pFieldValue = getDataField(fieldName, array); + const char* pFieldValue = getDataField(fieldName, _array); // Sanity. AssertFatal(pFieldValue != NULL, "Field value cannot be NULL."); @@ -2235,10 +2251,10 @@ bool SimObject::setProtectedName(void *obj, const char *index, const char *data) { if (preventNameChanging) return false; - SimObject *object = static_cast(obj); - - if ( object->isProperlyAdded() ) - object->assignName( data ); + SimObject* object = static_cast(obj); + + if (object->isProperlyAdded()) + object->assignName(data); // always return false because we assign the name here return false; @@ -2246,6 +2262,31 @@ bool SimObject::setProtectedName(void *obj, const char *index, const char *data) //----------------------------------------------------------------------------- +bool SimObject::setInheritFrom(void* obj, const char* index, const char* data) +{ + SimObject* object = static_cast(obj); + + SimObject* parent; + if (Sim::findObject(data, parent)) + { + object->setCopySource(parent); + object->assignFieldsFrom(parent); + + // copy any substitution statements + SimDataBlock* parent_db = dynamic_cast(parent); + if (parent_db) + { + SimDataBlock* currentNewObject_db = dynamic_cast(object); + if (currentNewObject_db) + currentNewObject_db->copySubstitutionsFrom(parent_db); + } + } + + return true; +} + +//----------------------------------------------------------------------------- + void SimObject::inspectPreApply() { } diff --git a/Engine/source/console/simObject.h b/Engine/source/console/simObject.h index 9cef85f0f..05a9353dc 100644 --- a/Engine/source/console/simObject.h +++ b/Engine/source/console/simObject.h @@ -299,6 +299,8 @@ class SimObject: public ConsoleObject, public TamlCallbacks SimObject* nextManagerNameObject; SimObject* nextIdObject; + StringTableEntry mInheritFrom; + /// SimGroup we're contained in, if any. SimGroup* mGroup; @@ -380,6 +382,9 @@ class SimObject: public ConsoleObject, public TamlCallbacks // Object name protected set method static bool setProtectedName(void *object, const char *index, const char *data); + // Sets object to inherit default values from + static bool setInheritFrom(void* object, const char* index, const char* data); + public: inline void setProgenitorFile(const char* pFile) { mProgenitorFile = StringTable->insert(pFile); } inline StringTableEntry getProgenitorFile(void) const { return mProgenitorFile; } diff --git a/Engine/source/materials/materialDefinition.cpp b/Engine/source/materials/materialDefinition.cpp index 5d009004a..7b3d2c7de 100644 --- a/Engine/source/materials/materialDefinition.cpp +++ b/Engine/source/materials/materialDefinition.cpp @@ -516,7 +516,8 @@ bool Material::writeField(StringTableEntry fieldname, const char* value) fieldname == StringTable->insert("overlayTex") || fieldname == StringTable->insert("bumpTex") || fieldname == StringTable->insert("envTex") || - fieldname == StringTable->insert("colorMultiply")) + fieldname == StringTable->insert("colorMultiply") || + fieldname == StringTable->insert("internalName")) return false; return Parent::writeField(fieldname, value); diff --git a/Engine/source/persistence/taml/taml.cpp b/Engine/source/persistence/taml/taml.cpp index 2bfd104b9..5200dcf28 100644 --- a/Engine/source/persistence/taml/taml.cpp +++ b/Engine/source/persistence/taml/taml.cpp @@ -217,11 +217,6 @@ ImplementEnumType(_TamlFormatMode, FileStream stream; - if (StringTable->insert("c://.asset.taml") == StringTable->insert(mFilePathBuffer)) - { - bool asdfasdf = true; - } - // File opened? if (!stream.open(mFilePathBuffer, Torque::FS::File::Write)) { @@ -643,6 +638,19 @@ ImplementEnumType(_TamlFormatMode, // Fetch field count. const U32 fieldCount = fieldList.size(); + ConsoleObject* defaultConObject; + SimObject* defaultObject; + if (!getWriteDefaults()) + { + // Create a default object of the same type + defaultConObject = ConsoleObject::create(pSimObject->getClassName()); + defaultObject = dynamic_cast(defaultConObject); + + // ***Really*** shouldn't happen + if (!defaultObject) + return; + } + // Iterate fields. U8 arrayDepth = 0; TamlCustomNode* currentArrayNode = NULL; @@ -709,9 +717,6 @@ ImplementEnumType(_TamlFormatMode, if (!pFieldValue) pFieldValue = StringTable->EmptyString(); - if (pField->type == TypeBool) - pFieldValue = dAtob(pFieldValue) ? "true" : "false"; - U32 nBufferSize = dStrlen(pFieldValue) + 1; FrameTemp valueCopy(nBufferSize); dStrcpy((char *)valueCopy, pFieldValue, nBufferSize); @@ -720,9 +725,20 @@ ImplementEnumType(_TamlFormatMode, if (!pSimObject->writeField(fieldName, valueCopy)) continue; + if (!getWriteDefaults()) + { + //If the field hasn't been changed from the default value, then don't bother writing it out + const char* fieldData = defaultObject->getDataField(fieldName, indexBuffer); + if (fieldData != '\0' && dStricmp(fieldData, pFieldValue) == 0) + continue; + } + // Reassign field value. pFieldValue = valueCopy; + if (pField->type == TypeBool) + pFieldValue = dAtob(pFieldValue) ? "true" : "false"; + // Detect and collapse relative path information char fnBuf[1024]; if ((S32)pField->type == TypeFilename) @@ -741,6 +757,12 @@ ImplementEnumType(_TamlFormatMode, } } } + + if (!getWriteDefaults()) + { + // Cleanup our created default object + delete defaultConObject; + } } //----------------------------------------------------------------------------- diff --git a/Engine/source/persistence/taml/xml/tamlXmlReader.cpp b/Engine/source/persistence/taml/xml/tamlXmlReader.cpp index 320248b6f..fb8814260 100644 --- a/Engine/source/persistence/taml/xml/tamlXmlReader.cpp +++ b/Engine/source/persistence/taml/xml/tamlXmlReader.cpp @@ -293,8 +293,22 @@ void TamlXmlReader::parseAttributes( tinyxml2::XMLElement* pXmlElement, SimObjec attributeName == tamlNamedObjectName ) continue; - // Set the field. - pSimObject->setPrefixedDataField(attributeName, NULL, pAttribute->Value()); + //See if we have any sort of array index + S32 suffixNum; + String trimmedName = String::GetTrailingNumber(attributeName, suffixNum); + if (!trimmedName.equal(attributeName)) + { + char arrayIndexStr[32]; + dItoa(suffixNum, arrayIndexStr); + + // Set the field. + pSimObject->setPrefixedDataField(StringTable->insert(trimmedName.c_str()), arrayIndexStr, pAttribute->Value()); + } + else + { + // Set the field. + pSimObject->setPrefixedDataField(attributeName, NULL, pAttribute->Value()); + } } } diff --git a/Templates/BaseGame/game/tools/assetBrowser/assetImportConfigs.xml b/Templates/BaseGame/game/tools/assetBrowser/assetImportConfigs.xml index faa7ab1e6..3cfa5da83 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/assetImportConfigs.xml +++ b/Templates/BaseGame/game/tools/assetBrowser/assetImportConfigs.xml @@ -47,7 +47,7 @@ 0 1 1 - DefaultMaterial + DefaultMaterial,ColorEffect* 1 1 1 @@ -130,6 +130,7 @@ 1 1 1 + DefaultMaterial,ColorEffect* 1 1 1 diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript index bd7c78f90..c385a5f0c 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetBrowser.tscript @@ -2444,7 +2444,6 @@ function AssetBrowserFilterTree::onControlDropped( %this, %payload, %position ) function AssetBrowserFilterTree::onDragDropped( %this ) { - %asdgadfhg =true; } function AssetBrowser::hasLooseFilesInDir(%this) diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript index d70c6a4a5..18305b920 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript @@ -8,7 +8,6 @@ function AssetBrowser::createMaterialAsset(%this) %assetPath = AssetBrowser.dirHandler.currentAddress @ "/"; %tamlpath = %assetPath @ %assetName @ ".asset.taml"; - %scriptPath = %assetPath @ %assetName @ "." @ $TorqueScriptFileExtension; %asset = new MaterialAsset() { @@ -16,13 +15,13 @@ function AssetBrowser::createMaterialAsset(%this) versionId = 1; materialDefinitionName = %assetName; scriptFile = %assetName @ "." @ $TorqueScriptFileExtension; + + new Material(%assetName) { + }; }; TamlWrite(%asset, %tamlpath); - %mat = new Material(%assetName); - %mat.save(%scriptPath); - %moduleDef = ModuleDatabase.findModule(%moduleName, 1); AssetDatabase.addDeclaredAsset(%moduleDef, %tamlpath); @@ -42,6 +41,7 @@ function AssetBrowser::editMaterialAsset(%this, %assetDef) EditorGui.setEditor(MaterialEditorPlugin); + MaterialEditorGui.currentMaterialAsset = %assetDef.getAssetId(); MaterialEditorGui.currentMaterial = %assetDef.materialDefinitionName; MaterialEditorGui.setActiveMaterial( %assetDef.materialDefinitionName ); diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/terrainMaterial.tscript b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/terrainMaterial.tscript index 51bc88d54..ad1212e11 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/terrainMaterial.tscript +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/terrainMaterial.tscript @@ -15,10 +15,37 @@ function AssetBrowser::createTerrainMaterialAsset(%this) { AssetName = %assetName; versionId = 1; - scriptFile = %assetName @ "." @ $TorqueScriptFileExtension; materialDefinitionName = %assetName; }; + %matDef = new TerrainMaterial(%assetName) + { + internalName = %moduleName @ ":" @ %assetName; + diffuseMap = ""; + detailMap = ""; + detailSize = "10"; + isManaged = "1"; + detailBrightness = "1"; + Enabled = "1"; + diffuseSize = "200"; + }; + + %fxMatDef = new Material("TerrainFX_" @ %assetName) + { + mapTo = %assetName; + footstepSoundId = 0; + terrainMaterials = "1"; + ShowDust = "1"; + showFootprints = "1"; + materialTag0 = "Terrain"; + effectColor[0] = "0.42 0.42 0 1"; + effectColor[1] = "0.42 0.42 0 1"; + impactSoundId = "0"; + }; + + %asset.add(%matDef); + %asset.add(%fxMatDef); + TamlWrite(%asset, %tamlpath); %moduleDef = ModuleDatabase.findModule(%moduleName, 1); @@ -28,35 +55,6 @@ function AssetBrowser::createTerrainMaterialAsset(%this) AssetBrowser.refresh(); - //AssetBrowserFilterTree.onSelect(%smItem); - - %file = new FileObject(); - %templateFile = new FileObject(); - - %templateFilePath = %this.templateFilesPath @ "terrainMaterial." @ $TorqueScriptFileExtension @ ".template"; - - if(%file.openForWrite(%scriptPath) && %templateFile.openForRead(%templateFilePath)) - { - while( !%templateFile.isEOF() ) - { - %line = %templateFile.readline(); - %line = strreplace( %line, "@", %assetName ); - - %file.writeline(%line); - //echo(%line); - } - - %file.close(); - %templateFile.close(); - } - else - { - %file.close(); - %templateFile.close(); - - warnf("CreateNewTerrainMaterialAsset - Something went wrong and we couldn't write thescript file!"); - } - //If we've got the terrain mat editor open, go ahead and update it all TerrainMaterialDlg.onWake(); diff --git a/Templates/BaseGame/game/tools/materialEditor/scripts/materialEditor.ed.tscript b/Templates/BaseGame/game/tools/materialEditor/scripts/materialEditor.ed.tscript index 2af4b9795..882ec9dc2 100644 --- a/Templates/BaseGame/game/tools/materialEditor/scripts/materialEditor.ed.tscript +++ b/Templates/BaseGame/game/tools/materialEditor/scripts/materialEditor.ed.tscript @@ -269,6 +269,7 @@ function SubMaterialSelector::onSelect( %this ) } else { + MaterialEditorGui.currentMaterialAsset = %material; %assetDef = AssetDatabase.acquireAsset(%material); %material = %assetDef.materialDefinitionName; } @@ -1906,6 +1907,7 @@ function MaterialEditorGui::saveDialogDontSave( %this, %material ) if(AssetDatabase.isDeclaredAsset(%material)) { + MaterialEditorGui.currentMaterialAsset = %material; %material = AssetDatabase.acquireAsset(%material).materialDefinitionName; } @@ -1916,6 +1918,7 @@ function MaterialEditorGui::saveDialogSave( %this, %material ) { if(AssetDatabase.isDeclaredAsset(%material)) { + MaterialEditorGui.currentMaterialAsset = %material; %material = AssetDatabase.acquireAsset(%material).materialDefinitionName; } @@ -1945,8 +1948,18 @@ function MaterialEditorGui::save( %this ) if( %currentMaterial.isAutoGenerated() ) %currentMaterial.setAutoGenerated( false ); - // Save the material using the persistence manager - matEd_PersistMan.saveDirty(); + if(MaterialEditorGui.currentMaterialAsset !$= "") + { + MaterialEditorGui.copyMaterials( materialEd_previewMaterial, notDirtyMaterial ); + + %assetDef = AssetDatabase.acquireAsset(MaterialEditorGui.currentMaterialAsset); + %assetDef.saveAsset(); //write it out + } + else + { + // Save the material using the persistence manager + matEd_PersistMan.saveDirty(); + } // Clean up the Material Editor MaterialEditorGui.copyMaterials( materialEd_previewMaterial, notDirtyMaterial ); @@ -2211,6 +2224,7 @@ function MaterialEditorGui::changeMaterial(%this, %fromMaterial, %toMaterial) if(AssetDatabase.isDeclaredAsset(%toMaterial)) { %isMatAsset = true; + MaterialEditorGui.currentMaterialAsset = %toMaterial; %assetDef = AssetDatabase.acquireAsset(%toMaterial); %toMaterialDefinition = %assetDef.materialDefinitionName; %filename = %assetDef.getScriptPath(); diff --git a/Templates/BaseGame/game/tools/projectImporter/importers/pre40/T3Dpre4ProjectImporter.tscript b/Templates/BaseGame/game/tools/projectImporter/importers/pre40/T3Dpre4ProjectImporter.tscript index c494c5029..c6ac5c2b2 100644 --- a/Templates/BaseGame/game/tools/projectImporter/importers/pre40/T3Dpre4ProjectImporter.tscript +++ b/Templates/BaseGame/game/tools/projectImporter/importers/pre40/T3Dpre4ProjectImporter.tscript @@ -200,7 +200,7 @@ function T3Dpre4ProjectImporter::writeImportingFiles(%this) if($ProjectImporter::useExistingModule) { //clean up legact files if they've been renamed or whatnot - if(%file !$= %rootFileSectionObject.fileDestination) + if(makeRelativePath(%file) !$= %rootFileSectionObject.fileDestination) { fileDelete(%file); } @@ -659,8 +659,6 @@ function T3Dpre4ProjectImporter::processAssetFile(%this, %assetObj) if(!isObject(%assetObj)) return; - %assetObj.echo(); - //really, we only care here about ensuring the file extensions are cleaned up for(%l=0; %l < %assetObj.count(); %l++) { @@ -691,6 +689,9 @@ function T3Dpre4ProjectImporter::beginAssetAndModuleImport(%this) if(%fileExt $= ".module") { + if(%rootFileSectionObject.skip) + continue; + projectImporterLog("T3Dpre4ProjectImporter::beginAssetAndModuleImport() - processing file: " @ %file); $ProjectImporter::currentFilePath = filePath(%rootFileSectionObject.fileDestination) @ "/"; %this.processModuleFile(%rootFileSectionObject); @@ -698,6 +699,9 @@ function T3Dpre4ProjectImporter::beginAssetAndModuleImport(%this) } else if(%fileExt $= ".asset.taml") { + if(%rootFileSectionObject.skip) + continue; + projectImporterLog("T3Dpre4ProjectImporter::beginAssetAndModuleImport() - processing file: " @ %file); $ProjectImporter::currentFilePath = filePath(%rootFileSectionObject.fileDestination) @ "/"; %this.processAssetFile(%rootFileSectionObject); @@ -888,6 +892,77 @@ T3Dpre4ProjectImporter::genProcessor("Material", $MaterialEntriesList); //============================================================================== function T3Dpre4ProjectImporter::processMaterialObject(%this, %fileObject, %objectName) { + //first, lets do a bit of use-case checking. Materials are sometimes companion to + //a terrain material for effects and game physics behavior and may not be immediately + //obviously assocated. Lets check for that first before processing this as a regular material + %mapTo = findObjectField(%fileObject, "mapTo"); + if(%mapTo !$= "") + { + %terrainMatAsset = ""; + %terrainMat = ""; + if(isObject(%mapTo) && %mapTo.getClassName() $= "TerrainMaterial") + { + //If the terrain material already exists as a full object, look up it's + //asset to associate this FX material to it + %terrainMatAsset = TerrainMaterialAsset::getAssetIdByMaterialName(%mapTo.getName()); + + //Now we make our scripted definition "real", and append it to our asset + //so it is serialized. + %objectDefinition = ""; + for(%l=0; %l < %fileObject.count(); %l++) + { + %objectLine = %fileObject.getKey(%l); + if(!isObject(%objectLine)) + { + %objectDefinition = %objectDefinition @ %objectLine; + } + } + + eval(%objectDefinition); + + if(isObject(%objectName)) + { + %terrainMatAsset.add(%objectName); + + %terrainMatAsset.saveAsset(); + %fileObject.processed = true; + %fileObject.skip = true; //don't write the def back out to script, it's not needed now + } + + return false; + } + else + { + //No existing object, so probably incoming with the import, so lets go + //look for it + %terrMatList = getObjectsInFilesByClass("TerrainMaterial"); + for(%i=0; %i < getFieldCount(%terrMatList); %i++) + { + %terrainMatObj = getField(%terrMatList, %i); + if(%terrainMatObj.objectName $= %mapTo) + { + %terrainMat = %terrainMatObj; + } + else + { + %terrainObjIntName = findObjectField(%terrainMatObj, "internalName"); + if(%terrainObjIntName $= %mapTo) + { + %terrainMat = %terrainMatObj; + } + } + + if(%terrainMat !$= "") + { + //found it, not imported yet, so mark it for later + %terrainMat.FXMaterial = %fileObject; + + return false; + } + } + } + } + %matAsset = MaterialAsset::getAssetIdByMaterialName(%objectName); if(%matAsset $= "" || %matAsset $= "Core_Rendering:NoMaterial") @@ -913,12 +988,11 @@ function T3Dpre4ProjectImporter::processMaterialObject(%this, %fileObject, %obje versionId = 1; shaderData = ""; materialDefinitionName = %assetName; - scriptFile = fileBase(%scriptPath); }; //Now we make our scripted definition "real", and append it to our asset //so it is serialized. - /*%objectDefinition = ""; + %objectDefinition = ""; for(%l=0; %l < %fileObject.count(); %l++) { %objectLine = %fileObject.getKey(%l); @@ -932,8 +1006,14 @@ function T3Dpre4ProjectImporter::processMaterialObject(%this, %fileObject, %obje if(isObject(%objectName)) { + //if we created it successfully, set up inheritance for serialization if needed + if(%fileObject.parentName !$= "") + { + %objectName.setFieldValue("inheritFrom",%fileObject.parentName); + } + %asset.add(%objectName); - }*/ + } if(!isDirectory(%assetPath)) { @@ -943,26 +1023,6 @@ function T3Dpre4ProjectImporter::processMaterialObject(%this, %fileObject, %obje %success = false; if(TamlWrite(%asset, %tamlpath)) { - //now write the script file - if ( $ProjectImporter::fileObject.openForWrite( %scriptPath ) ) - { - for(%i=0; %i < %fileObject.count(); %i++) - { - %objectLine = %fileObject.getKey(%i); - if(isObject(%objectLine)) - { - %defineLine = %fileObject.getKey(0); - $ProjectImporter::fileObject.writeLine(%defineLine); - } - else - { - $ProjectImporter::fileObject.writeLine(%objectLine); - } - } - - $ProjectImporter::fileObject.close(); - } - %moduleDef = ModuleDatabase.findModule(%moduleName, 1); %success = AssetDatabase.addDeclaredAsset(%moduleDef, %tamlpath); @@ -971,6 +1031,43 @@ function T3Dpre4ProjectImporter::processMaterialObject(%this, %fileObject, %obje if(!%success) return false; } + else + { + //process an existing material asset, if needbe + %assetDef = AssetDatabase.acquireAsset(%matAsset); + + %assetScriptPath = %assetDef.getScriptPath(); + + if(isFile(%assetScriptPath) && isObject(%objectName)) + { + //Regular material in a companion file, so we'll want to write it to the + //asset def file instead of the loose file + %assetDef.scriptFile = ""; //clear the old script path reference + %assetDef.add(%objectName); //child the definition to the asset def + + if(%fileObject.parentName !$= "") + { + %objectName.setFieldValue("inheritFrom",%fileObject.parentName); + } + + if(%assetDef.saveAsset()) + { + %fileObject.processed = true; + %fileObject.skip = true; //don't write the def back out to script, it's not needed now + + %assetFileObj = findFileInImporting(makeFullPath(AssetDatabase.getAssetFilePath(%matAsset))); + + echo(%assetFileObj.fileDestination); + %assetFileObj.processed = true; + %assetFileObj.skip = true; //this asset definition has been processed + //so nothing else need be done + } + else + { + projectImporterLog("T3Dpre4ProjectImporter::processMaterialObject() - failed to save out modified material asset for: " @ %matAsset); + } + } + } return false; } @@ -1017,9 +1114,98 @@ function T3Dpre4ProjectImporter::processTerrainMaterialObject(%this, %fileObject versionId = 1; shaderData = ""; materialDefinitionName = %objectName; - scriptFile = fileName(%scriptPath); }; + renameObjectName(%fileObject, %objectName); + + //Now we make our scripted definition "real", and append it to our asset + //so it is serialized. + %objectDefinition = ""; + for(%l=0; %l < %fileObject.count(); %l++) + { + %objectLine = %fileObject.getKey(%l); + if(!isObject(%objectLine)) + { + %objectDefinition = %objectDefinition @ %objectLine; + } + } + + eval(%objectDefinition); + + if(isObject(%objectName)) + { + //if we created it successfully, set up inheritance for serialization if needed + if(%fileObject.parentName !$= "") + { + %objectName.setFieldValue("inheritFrom",%fileObject.parentName); + } + + %asset.add(%objectName); + } + else + { + error("T3Dpre4ProjectImporter::processTerrainMaterialObject() - failed to parse terrainmat object: "); + echo(%objectDefinition); + } + + if(%fileObject.FXMaterial $= "") + { + //on the off-chance it exists, try scanning for FX materials associated + //to this terrain material + %fxMat = findObjectInFiles("TerrainFX_" @ %objectName); + if(%fxMat !$= "" && %objectName.classType $= "Material") + { + %fileObject.FXMaterial = %fxMat; + } + else + { + %fxMatList = getObjectsInFilesByClass("Material"); + for(%i=0; %i < getFieldCount(%fxMatList); %i++) + { + %fxMatObj = getField(%fxMatList, %i); + %fxMatObjMapTo = findObjectField(%fxMatObj, "mapTo"); + if(%fxMatObjMapTo $= %objectName) + { + %fileObject.FXMaterial = %fxMatObj; + break; + } + } + } + } + + if(%fileObject.FXMaterial !$= "") + { + //Ensure our mapto is up to date for any name sanitize/tweaks + setObjectField(%fileObject.FXMaterial, "mapTo", %objectName); + + //we associated to an FX material, so process that now + %objectDefinition = ""; + for(%l=0; %l < %fileObject.FXMaterial.count(); %l++) + { + %objectLine = %fileObject.FXMaterial.getKey(%l); + if(!isObject(%objectLine)) + { + %objectDefinition = %objectDefinition @ %objectLine; + } + } + + eval(%objectDefinition); + + if(isObject(%fileObject.FXMaterial.objectName)) + { + //if we created it successfully, set up inheritance for serialization if needed + if(%fileObject.FXMaterial.parentName !$= "") + { + %fileObject.FXMaterial.setFieldValue("inheritFrom",%fileObject.FXMaterial.parentName); + } + + %asset.add(%fileObject.FXMaterial.objectName); + } + + %fileObject.FXMaterial.processed = true; + %fileObject.FXMaterial.skip = true; + } + %success = false; if(TamlWrite(%asset, %tamlpath)) { @@ -1031,6 +1217,43 @@ function T3Dpre4ProjectImporter::processTerrainMaterialObject(%this, %fileObject if(!%success) return false; } + else + { + //process an existing material asset, if needbe + %assetDef = AssetDatabase.acquireAsset(%matAsset); + + %assetScriptPath = %assetDef.getScriptPath(); + + if(isFile(%assetScriptPath) && isObject(%objectName)) + { + //Regular material in a companion file, so we'll want to write it to the + //asset def file instead of the loose file + %assetDef.scriptFile = ""; //clear the old script path reference + %assetDef.add(%objectName); //child the definition to the asset def + + if(%fileObject.parentName !$= "") + { + %objectName.setFieldValue("inheritFrom",%fileObject.parentName); + } + + if(%assetDef.saveAsset()) + { + %fileObject.processed = true; + %fileObject.skip = true; //don't write the def back out to script, it's not needed now + + %assetFileObj = findFileInImporting(makeFullPath(AssetDatabase.getAssetFilePath(%matAsset))); + + echo(%assetFileObj.fileDestination); + %assetFileObj.processed = true; + %assetFileObj.skip = true; //this asset definition has been processed + //so nothing else need be done + } + else + { + projectImporterLog("T3Dpre4ProjectImporter::processTerrainMaterialObject() - failed to save out modified material asset for: " @ %matAsset); + } + } + } return false; } @@ -1122,25 +1345,12 @@ function T3Dpre4ProjectImporter::processSFXProfileObject(%this, %file, %objectNa } else { - %objFileFinder = ""; - //first check our cache - if(isObject($ProjectImporter::SFXDescriptionCache) && - $ProjectImporter::SFXDescriptionCache.getIndexFromKey(%descriptionName) !$= "") - { - %key = $ProjectImporter::SFXDescriptionCache.getIndexFromKey(%descriptionName); - %objFileFinder = $ProjectImporter::SFXDescriptionCache.getValue(%key); - } - else - { - %objFileFinder = findObjectInFiles(%descriptionName); - } + %fileObj = findObjectInFiles(%descriptionName); - if(%objFileFinder !$= "") + if(%fileObj !$= "") { %valueArray = new ArrayObject(); - %fileObj = getField(%objFileFinder, 0); - %valueArray.add("sourceGroup" SPC findObjectField(%fileObj, "sourceGroup")); %valueArray.add("volume" SPC findObjectField(%fileObj, "volume")); %valueArray.add("pitch" SPC findObjectField(%fileObj, "pitch")); @@ -1157,10 +1367,7 @@ function T3Dpre4ProjectImporter::processSFXProfileObject(%this, %file, %objectNa %valueArray.add("rolloffFactor" SPC findObjectField(%fileObj, "rolloffFactor")); %valueArray.add("isStreaming" SPC findObjectField(%fileObj, "isStreaming")); - if(isObject($ProjectImporter::SFXDescriptionCache)) - { - $ProjectImporter::SFXDescriptionCache.add(%descriptionName, %objFileFinder); - } + %fileObj.skip = true; for(%v=0; %v < %valueArray.Count(); %v++) { diff --git a/Templates/BaseGame/game/tools/projectImporter/importers/pre40/pre40ImporterGuis.tscript b/Templates/BaseGame/game/tools/projectImporter/importers/pre40/pre40ImporterGuis.tscript index 816b5cf80..10b7fb96a 100644 --- a/Templates/BaseGame/game/tools/projectImporter/importers/pre40/pre40ImporterGuis.tscript +++ b/Templates/BaseGame/game/tools/projectImporter/importers/pre40/pre40ImporterGuis.tscript @@ -37,7 +37,7 @@ function Pre40ImporterPage0::openPage(%this) %sanitizedFilename = sanitizeString(%fileBase); if(startsWith(%sanitizedFilename, "_")) { - %sanitizedFilename = substr(%sanitizedFilename, 1, -1); + %sanitizedFilename = getSubstr(%sanitizedFilename, 1, -1); } if(%sanitizedFilename !$= %fileBase) { diff --git a/Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript b/Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript index ab47a18a9..2e98c9b03 100644 --- a/Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript +++ b/Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript @@ -242,7 +242,7 @@ function ProjectImportWizardPage3::openPage(%this) %dataFullPath = makeFullPath("data/"); %coreFullPath = makeFullPath("core/"); %toolsFullPath = makeFullPath("tools/"); - if(startsWith(makeFullPath("data/"), $ProjectImporter::sourceContentFolder)) + if(startsWith($ProjectImporter::sourceContentFolder, makeFullPath("data/"))) { %moduleDef = AssetBrowser.dirHandler.getModuleFromAddress(makeRelativePath($ProjectImporter::sourceContentFolder)); if(isObject(%moduleDef)) @@ -254,8 +254,8 @@ function ProjectImportWizardPage3::openPage(%this) ProjectImportWindow.setStep(4); } } - else if(startsWith(makeFullPath("core/"), $ProjectImporter::sourceContentFolder) || - startsWith(makeFullPath("tools/"), $ProjectImporter::sourceContentFolder)) + else if(startsWith($ProjectImporter::sourceContentFolder, makeFullPath("core/")) || + startsWith($ProjectImporter::sourceContentFolder, makeFullPath("tools/"))) { ProjectImportWindow.setStep(5); } @@ -476,7 +476,7 @@ function preprocessImportingFiles() { %line = $ProjectImporter::fileObject.readLine(); - if(strIsMatchExpr("*new*(*)*", %line) && !strIsMatchExpr("*\"*new*(*)*\"*", %line)) + if(strIsMatchExpr("* new*(*)*", %line)) { %start = strpos(%line, "new "); %end = strpos(%line, "(", %start); @@ -490,9 +490,11 @@ function preprocessImportingFiles() %objectName = getSubStr(%line, %end+1, %nameEnd-%end-1); + %parentName = ""; %inheritanceSplit = strpos(%objectName, ":"); if(%inheritanceSplit != -1) { + %parentName = getSubStr(%objectName, %inheritanceSplit + 1); %objectName = getSubStr(%objectName, 0, %inheritanceSplit); } @@ -502,6 +504,7 @@ function preprocessImportingFiles() %currentFileSectionObject.elementType = "object"; %currentFileSectionObject.classType = %className; %currentFileSectionObject.objectName = %objectName; + %currentFileSectionObject.parentName = %parentName; %currentFileSectionObject.fileName = %file; %currentFileSectionObject.skip = false; %currentFileSectionObject.fileDestination = %rootFileSectionObject.fileDestination; @@ -510,6 +513,7 @@ function preprocessImportingFiles() %currentFileSectionObject.add(%line); %parentFileSectionObject.add(%currentFileSectionObject); + %currentFileSectionObject.parentElement = %parentFileSectionObject; //Now for a sanity check, see if we kill the object on the same line as we make it //sometimes people try and be 'efficient' with their code linecount wise @@ -526,7 +530,7 @@ function preprocessImportingFiles() %insideObjectBlock = true; } } - else if(strIsMatchExpr("*datablock*(*)*", %line)) + else if(strIsMatchExpr("* datablock*(*)*", %line)) { %start = strpos(%line, "datablock "); %end = strpos(%line, "(", %start); @@ -540,9 +544,11 @@ function preprocessImportingFiles() %objectName = getSubStr(%line, %end+1, %nameEnd-%end-1); + %parentName = ""; %inheritanceSplit = strpos(%objectName, ":"); if(%inheritanceSplit != -1) { + %parentName = getSubStr(%objectName, %inheritanceSplit + 1); %objectName = getSubStr(%objectName, 0, %inheritanceSplit); } @@ -552,6 +558,7 @@ function preprocessImportingFiles() %currentFileSectionObject.elementType = "object"; %currentFileSectionObject.classType = %className; %currentFileSectionObject.objectName = %objectName; + %currentFileSectionObject.parentName = %parentName; %currentFileSectionObject.fileName = %file; %currentFileSectionObject.skip = false; %currentFileSectionObject.fileDestination = %rootFileSectionObject.fileDestination; @@ -560,6 +567,7 @@ function preprocessImportingFiles() %currentFileSectionObject.add(%line); %parentFileSectionObject.add(%currentFileSectionObject); + %currentFileSectionObject.parentElement = %parentFileSectionObject; //Now for a sanity check, see if we kill the object on the same line as we make it //sometimes people try and be 'efficient' with their code linecount wise @@ -576,7 +584,7 @@ function preprocessImportingFiles() %insideObjectBlock = true; } } - else if(strIsMatchExpr("*singleton*(*)*", %line)) + else if(strIsMatchExpr("* singleton*(*)*", %line)) { %start = strpos(%line, "singleton "); %end = strpos(%line, "(", %start); @@ -590,9 +598,11 @@ function preprocessImportingFiles() %objectName = getSubStr(%line, %end+1, %nameEnd-%end-1); + %parentName = ""; %inheritanceSplit = strpos(%objectName, ":"); if(%inheritanceSplit != -1) { + %parentName = getSubStr(%objectName, %inheritanceSplit + 1); %objectName = getSubStr(%objectName, 0, %inheritanceSplit); } @@ -602,6 +612,7 @@ function preprocessImportingFiles() %currentFileSectionObject.elementType = "object"; %currentFileSectionObject.classType = %className; %currentFileSectionObject.objectName = %objectName; + %currentFileSectionObject.parentName = %parentName; %currentFileSectionObject.fileName = %file; %currentFileSectionObject.skip = false; %currentFileSectionObject.fileDestination = %rootFileSectionObject.fileDestination; @@ -610,6 +621,7 @@ function preprocessImportingFiles() %currentFileSectionObject.add(%line); %parentFileSectionObject.add(%currentFileSectionObject); + %currentFileSectionObject.parentElement = %parentFileSectionObject; //Now for a sanity check, see if we kill the object on the same line as we make it //sometimes people try and be 'efficient' with their code linecount wise @@ -650,6 +662,7 @@ function preprocessImportingFiles() %currentFileSectionObject.add(%line); %parentFileSectionObject.add(%currentFileSectionObject); + %currentFileSectionObject.parentElement = %parentFileSectionObject; if(strIsMatchExpr("*{*", %line)) { @@ -838,6 +851,104 @@ function isImportingFile(%checkFile) return false; } +//============================================================================== +// Returns the file object of the file in question is part of our pre-scanned list of importing files +//============================================================================== +function findFileInImporting(%checkFile) +{ + for(%i=0; %i < $ProjectImporter::FileList.count(); %i++) + { + %file = $ProjectImporter::FileList.getKey(%i); + + if(%file $= %checkFile) + return $ProjectImporter::FileList.getValue(%i); + } + + return ""; +} + +//============================================================================== +// Checks if the object in question is defined in any of our pre-scanned list of importing files +//============================================================================== +function findObjectInFilesRecurse(%objectName, %arrayObj) +{ + for(%i=0; %i < %arrayObj.count(); %i++) + { + %objectLine = %arrayObj.getKey(%i); + if(isObject(%objectLine)) + { + if(%objectLine.objectName $= %objectName) + return %objectLine; + + //If this object isn't it, try recursing any children + %result = findObjectInFilesRecurse(%objectName, %objectLine); + if(%result !$= "") + return %result; + } + } + + return ""; +} + +function findObjectInFiles(%objectName) +{ + for(%i=0; %i < $ProjectImporter::FileList.count(); %i++) + { + %objectLine = $ProjectImporter::FileList.getValue(%i); + if(isObject(%objectLine)) + { + if(%objectLine.objectName $= %objectName) + return %objectLine; + + //If this object isn't it, try recursing any children + %result = findObjectInFilesRecurse(%objectName, %objectLine); + if(%result !$= "") + return %result; + } + } + + return ""; +} + +//============================================================================== +// Checks if the object in question is defined in any of our pre-scanned list of importing files +//============================================================================== +function getObjectsInFilesByClassRecurse(%className, %arrayObj) +{ + for(%i=0; %i < %arrayObj.count(); %i++) + { + %objectLine = %arrayObj.getKey(%i); + if(isObject(%objectLine)) + { + if(%objectLine.classType $= %className) + $ProjectImporter::queryList = $ProjectImporter::queryList TAB %objectLine; + + //If this object isn't it, try recursing any children + getObjectsInFilesByClassRecurse(%className, %objectLine); + } + } +} + +function getObjectsInFilesByClass(%className) +{ + $ProjectImporter::queryList = ""; + + for(%i=0; %i < $ProjectImporter::FileList.count(); %i++) + { + %objectLine = $ProjectImporter::FileList.getValue(%i); + if(isObject(%objectLine)) + { + if(%objectLine.classType $= %className) + $ProjectImporter::queryList = $ProjectImporter::queryList TAB %objectLine; + + //If this object isn't it, try recursing any children + getObjectsInFilesByClassRecurse(%className, %objectLine); + } + } + + return ltrim($ProjectImporter::queryList); +} + //============================================================================== // Takes a filename lacking an extension and then checks common file extensions // to see if we can find the actual file in question @@ -1055,18 +1166,30 @@ function renameObjectName(%object, %newName) %objectLine = %object.getKey(%e); if(!isObject(%objectLine)) { - if(strIsMatchExpr("*singleton*(*)*", %objectLine) && - strIsMatchExpr("*new*(*)*", %objectLine) && + if(strIsMatchExpr("*singleton*(*)*", %objectLine) || + strIsMatchExpr("*new*(*)*", %objectLine) || strIsMatchExpr("*datablock*(*)*", %objectLine)) { - %newLine = strreplace(%object.objectName, %newName); - - echo("renameObjectName() - lines changed from:"); - echo(%objectLine); - echo("to:"); - echo(%newLine); + if(%object.objectName $= "") + { + %start = strpos(%objectLine, "("); + %end = strpos(%objectLine, ")", %start); + + %preString = getSubStr(%objectLine, 0, %start+1); + %postString = getSubStr(%objectLine, %end); + + %renamedString = %preString @ %newName @ %postString; + + %newLine = %renamedString; + } + else + { + %newLine = strreplace(%objectLine, %object.objectName, %newName); + } %object.setKey(%newLine, %e); + + %object.objectName = %newName; } } } @@ -1203,6 +1326,28 @@ function setObjectField(%object, %fieldName, %newValue) } } +//============================================================================== +// Inserts a new field to an object's block in the preprocessed data +//============================================================================== +function insertObjectLine(%object, %newLine) +{ + for(%e=0; %e < %object.count(); %e++) + { + %objectLine = %object.getKey(%e); + + if(strIsMatchExpr("*{*", %objectLine) || + strIsMatchExpr("*singleton*(*)*", %objectLine) || + strIsMatchExpr("*new*(*)*", %objectLine) || + strIsMatchExpr("*datablock*(*)*", %objectLine)) + { + continue; + } + + %object.insert(%newLine, "", %e); + return; + } +} + //============================================================================== // Takes a string and adds it to the importer's log. Optionally can print the line // directly to console for debugging purposes @@ -1215,6 +1360,32 @@ function projectImporterLog(%line) $ProjectImporter::log.add(%line); } +//============================================================================== +// Traverses the object delcaration stack backwards to find the root file object +//============================================================================== +function getParentFileObjectFromObject(%object) +{ + while(%object.parentElement !$= "") + { + %object = %object.parentElement; + } + + return %object; +} + +//============================================================================== +// Traverses the object delcaration stack backwards to find the root file object +//============================================================================== +function getParentFileObjectFromObject(%object) +{ + while(%object.parentElement !$= "") + { + %object = %object.parentElement; + } + + return %object; +} + //============================================================================== //Shape Importing //============================================================================== diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.tscript b/Templates/BaseGame/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.tscript index 5429008ea..b49cef39a 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.tscript +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.tscript @@ -77,9 +77,6 @@ function TerrainMaterialDlg::showByObjectId( %this, %matObjectId, %onApplyCallba function TerrainMaterialDlg::onWake( %this ) { - if( !isObject( ETerrainMaterialPersistMan ) ) - new PersistenceManager( ETerrainMaterialPersistMan ); - if( !isObject( TerrainMaterialDlgNewGroup ) ) new SimGroup( TerrainMaterialDlgNewGroup ); if( !isObject( TerrainMaterialDlgDeleteGroup ) ) @@ -156,9 +153,6 @@ function TerrainMaterialDlg::dialogApply( %this ) // Make sure we save any changes to the current selection. %this.saveDirtyMaterial( %this.activeMat ); - // Save all changes. - ETerrainMaterialPersistMan.saveDirty(); - // Delete the snapshot. TerrainMaterialDlgSnapshot.delete(); @@ -191,10 +185,6 @@ function TerrainMaterialDlg::closeDialog( %this ) %this.restoreMaterials(); - // Clear the persistence manager state. - - ETerrainMaterialPersistMan.clearAll(); - // Delete all new object we have created. TerrainMaterialDlgNewGroup.clear(); @@ -599,17 +589,9 @@ function TerrainMaterialDlg::saveDirtyMaterial( %this, %mat ) %mat.isSRGB = %isSRGB; %mat.invertRoughness = %invertRoughness; - // Mark the material as dirty and needing saving. - - %fileName = %mat.getFileName(); - if( %fileName $= "" ) - { - error("TerrainMaterialDlg::saveDirtyMaterial() - terrain material doesn't have a fileName set to save to."); - return; - //%fileName = "data/terrains/materials." @ $TorqueScriptFileExtension; - } - - ETerrainMaterialPersistMan.setDirty( %mat, %fileName ); + //Save the material asset + %assetDef = AssetDatabase.acquireAsset(%mat.internalName); + %assetDef.saveAsset(); } //-----------------------------------------------------------------------------