From 8585278fe4821de1bca55637d7e2d3a1a418b6b3 Mon Sep 17 00:00:00 2001 From: Areloch Date: Tue, 5 Jan 2021 00:58:18 -0600 Subject: [PATCH] Adds autoimport logic for materials if the materialDefinition already exists Adds some additional utility functions to AssetImporter for easier access to setup Corrects handling for legacy field names with meshRoad --- Engine/source/T3D/assets/MaterialAsset.cpp | 79 ++++++++++++++++++++++ Engine/source/T3D/assets/assetImporter.cpp | 53 ++++++++------- Engine/source/T3D/assets/assetImporter.h | 10 +++ Engine/source/environment/meshRoad.cpp | 11 ++- 4 files changed, 127 insertions(+), 26 deletions(-) diff --git a/Engine/source/T3D/assets/MaterialAsset.cpp b/Engine/source/T3D/assets/MaterialAsset.cpp index be38e35e8..177b524ed 100644 --- a/Engine/source/T3D/assets/MaterialAsset.cpp +++ b/Engine/source/T3D/assets/MaterialAsset.cpp @@ -19,6 +19,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. //----------------------------------------------------------------------------- +#pragma once #ifndef MATERIALASSET_H #include "MaterialAsset.h" @@ -40,6 +41,8 @@ #include "assets/assetPtr.h" #endif +#include "T3D\assets\assetImporter.h" + //----------------------------------------------------------------------------- IMPLEMENT_CONOBJECT(MaterialAsset); @@ -231,6 +234,82 @@ StringTableEntry MaterialAsset::getAssetIdByMaterialName(StringTableEntry matNam materialAssetId = matAsset->getAssetId(); break; } + AssetDatabase.releaseAsset(query->mAssetList[i]); //cleanup if that's not the one we needed + } + + if (materialAssetId == StringTable->EmptyString()) + { + //Try auto-importing it if it exists already + BaseMaterialDefinition* baseMatDef; + if (!Sim::findObject(matName, baseMatDef)) + { + //Not even a real material, apparently? + //return back a blank + return StringTable->EmptyString(); + } + + //Ok, a real mat def, we can work with this +#if TORQUE_DEBUG + Con::warnf("MaterialAsset::getAssetIdByMaterialName - Attempted to in-place import a material(%s) that had no associated asset", matName); +#endif + + AssetImporter* autoAssetImporter; + if (!Sim::findObject("autoAssetImporter", autoAssetImporter)) + { + autoAssetImporter = new AssetImporter(); + autoAssetImporter->registerObject("autoAssetImporter"); + } + + autoAssetImporter->resetImportSession(true); + + String originalMaterialDefFile = Torque::Path(baseMatDef->getFilename()).getPath(); + + autoAssetImporter->setTargetPath(originalMaterialDefFile); + + autoAssetImporter->resetImportConfig(); + + AssetImportObject* assetObj = autoAssetImporter->addImportingAsset("MaterialAsset", originalMaterialDefFile, nullptr, matName); + + //Find out if the filepath has an associated module to it. If we're importing in-place, it needs to be within a module's directory + ModuleDefinition* targetModuleDef = AssetImporter::getModuleFromPath(originalMaterialDefFile); + + if (targetModuleDef == nullptr) + { + return StringTable->EmptyString(); + } + else + { + autoAssetImporter->setTargetModuleId(targetModuleDef->getModuleId()); + } + + autoAssetImporter->processImportAssets(); + + bool hasIssues = autoAssetImporter->validateAssets(); + + if (hasIssues) + { + //log it + Con::errorf("Error! Import process of Material(%s) has failed due to issues discovered during validation!", matName); + return StringTable->EmptyString(); + } + else + { + autoAssetImporter->importAssets(); + } + +#if TORQUE_DEBUG + autoAssetImporter->dumpActivityLog(); +#endif + + if (hasIssues) + { + return StringTable->EmptyString(); + } + else + { + String assetId = autoAssetImporter->getTargetModuleId() + ":" + assetObj->assetName; + return StringTable->insert(assetId.c_str()); + } } } diff --git a/Engine/source/T3D/assets/assetImporter.cpp b/Engine/source/T3D/assets/assetImporter.cpp index 3331f7afd..af0f2f9f5 100644 --- a/Engine/source/T3D/assets/assetImporter.cpp +++ b/Engine/source/T3D/assets/assetImporter.cpp @@ -2282,6 +2282,32 @@ void AssetImporter::resolveAssetItemIssues(AssetImportObject* assetItem) } } +void AssetImporter::resetImportConfig() +{ + //use a default import config + if (activeImportConfig == nullptr) + { + activeImportConfig = new AssetImportConfig(); + activeImportConfig->registerObject(); + } + + bool foundConfig = false; + Settings* editorSettings; + //See if we can get our editor settings + if (Sim::findObject("EditorSettings", editorSettings)) + { + String defaultImportConfig = editorSettings->value("Assets/AssetImporDefaultConfig"); + + //If we found it, grab the import configs + Settings* importConfigs; + if (Sim::findObject("AssetImportSettings", importConfigs)) + { + //Now load the editor setting-deigned config! + activeImportConfig->loadImportConfig(importConfigs, defaultImportConfig.c_str()); + } + } +} + // // Importing // @@ -2322,28 +2348,7 @@ StringTableEntry AssetImporter::autoImportFile(Torque::Path filePath) //set our path targetPath = filePath.getPath(); - //use a default import config - if (activeImportConfig == nullptr) - { - activeImportConfig = new AssetImportConfig(); - activeImportConfig->registerObject(); - } - - bool foundConfig = false; - Settings* editorSettings; - //See if we can get our editor settings - if (Sim::findObject("EditorSettings", editorSettings)) - { - String defaultImportConfig = editorSettings->value("Assets/AssetImporDefaultConfig"); - - //If we found it, grab the import configs - Settings* importConfigs; - if (Sim::findObject("AssetImportSettings", importConfigs)) - { - //Now load the editor setting-deigned config! - activeImportConfig->loadImportConfig(importConfigs, defaultImportConfig.c_str()); - } - } + resetImportConfig(); AssetImportObject* assetItem = addImportingAsset(assetType, filePath, nullptr, ""); @@ -2767,7 +2772,9 @@ Torque::Path AssetImporter::importMaterialAsset(AssetImportObject* assetItem) assetFieldName = mapFieldName + "Asset[0]"; mapFieldName += "[0]"; - existingMat->writeField(mapFieldName.c_str(), path.c_str()); + //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; diff --git a/Engine/source/T3D/assets/assetImporter.h b/Engine/source/T3D/assets/assetImporter.h index 25c57e5fd..16a84a463 100644 --- a/Engine/source/T3D/assets/assetImporter.h +++ b/Engine/source/T3D/assets/assetImporter.h @@ -847,6 +847,12 @@ public: activeImportConfig = importConfig; } + /// + /// Resets the active import config to whatever the default is. Either a clean slate if one isn't defined + /// or loading one if defined via the editor config + /// + void resetImportConfig(); + // static String getTrueFilename(const String& fileName); @@ -881,4 +887,8 @@ public: return qualifiedFilePath; } + + // + void setTargetModuleId(const String& moduleId) { targetModuleId = moduleId; } + const String& getTargetModuleId() { return targetModuleId; } }; diff --git a/Engine/source/environment/meshRoad.cpp b/Engine/source/environment/meshRoad.cpp index 6c7aaf015..e162e8cf5 100644 --- a/Engine/source/environment/meshRoad.cpp +++ b/Engine/source/environment/meshRoad.cpp @@ -937,9 +937,14 @@ void MeshRoad::initPersistFields() { addGroup( "MeshRoad" ); - scriptBindMaterialAsset(TopMaterial, MeshRoad, "Material for the upper surface of the road."); - scriptBindMaterialAsset(BottomMaterial, MeshRoad, "Material for the bottom surface of the road."); - scriptBindMaterialAsset(SideMaterial, MeshRoad, "Material for the left, right, front, and back surfaces of the road."); + addProtectedField("TopMaterial", TypeMaterialName, Offset(mTopMaterialName, MeshRoad), MeshRoad::_setTopMaterialName, & defaultProtectedGetFn, "Material for the upper surface of the road.", AbstractClassRep::FIELD_HideInInspectors); \ + addProtectedField("TopMaterialAsset", TypeMaterialAssetId, Offset(mTopMaterialAssetId, MeshRoad), MeshRoad::_setTopMaterialAsset, & defaultProtectedGetFn, "Material for the upper surface of the road."); + + addProtectedField("BottomMaterial", TypeMaterialName, Offset(mBottomMaterialName, MeshRoad), MeshRoad::_setBottomMaterialName, & defaultProtectedGetFn, "Material for the bottom surface of the road.", AbstractClassRep::FIELD_HideInInspectors); \ + addProtectedField("BottomMaterialAsset", TypeMaterialAssetId, Offset(mBottomMaterialAssetId, MeshRoad), MeshRoad::_setBottomMaterialAsset, & defaultProtectedGetFn, "Material for the bottom surface of the road."); + + addProtectedField("SideMaterial", TypeMaterialName, Offset(mSideMaterialName, MeshRoad), MeshRoad::_setSideMaterialName, & defaultProtectedGetFn, "Material for the left, right, front, and back surfaces of the road.", AbstractClassRep::FIELD_HideInInspectors); \ + addProtectedField("SideMaterialAsset", TypeMaterialAssetId, Offset(mSideMaterialAssetId, MeshRoad), MeshRoad::_setSideMaterialAsset, & defaultProtectedGetFn, "Material for the left, right, front, and back surfaces of the road."); addField( "textureLength", TypeF32, Offset( mTextureLength, MeshRoad ), "The length in meters of textures mapped to the MeshRoad." );