From b3342ff7e6709eaee86b3bf311d635270a8104ff Mon Sep 17 00:00:00 2001 From: JeffR Date: Sun, 20 Mar 2022 03:17:31 -0500 Subject: [PATCH] Adds handling for import of files marked as ShapeAnimationAsset Adds filetype handling of dsqs for importing Improves logic checks to prevent incorrectly redundantly processing incoming assets for collisions, which could mark all assets as colliding instead of all but the first. Adds better handling for assets marked as for dependency usage when importing Improves rules for writing originalFilePath only if it's actually from an external directory, and the file actually exists to prevent polluting in redundant or garbage data Fixes issue where MaterialEditor was not tracking the currently material assetId if the material was changed via the dropdown selector Adds a sanity check to shapeAnimationAsset load so if the resource does not load properly it doesn't hard crash but instead logs the error and returns safely. --- .../source/T3D/assets/ShapeAnimationAsset.cpp | 2 +- Engine/source/T3D/assets/assetImporter.cpp | 117 ++++++++++++++++-- Engine/source/T3D/assets/assetImporter.h | 18 ++- .../tools/assetBrowser/assetImportConfigs.xml | 2 +- .../assetBrowser/scripts/assetImport.tscript | 3 +- .../scripts/assetTypes/image.tscript | 7 +- .../scripts/assetTypes/material.tscript | 8 +- .../scripts/assetTypes/shape.tscript | 7 +- .../scripts/materialEditor.ed.tscript | 10 ++ .../scripts/projectImporter.tscript | 3 + 10 files changed, 160 insertions(+), 17 deletions(-) diff --git a/Engine/source/T3D/assets/ShapeAnimationAsset.cpp b/Engine/source/T3D/assets/ShapeAnimationAsset.cpp index 50d668a1f..f7e1b6aa5 100644 --- a/Engine/source/T3D/assets/ShapeAnimationAsset.cpp +++ b/Engine/source/T3D/assets/ShapeAnimationAsset.cpp @@ -151,7 +151,7 @@ void ShapeAnimationAsset::initializeAsset(void) mSourceShape = ResourceManager::get().load(mFilePath); - if (!mSourceShape->addSequence("ambient", "", mAnimationName, mStartFrame, mEndFrame, mPadRotation, mPadTransforms)) + if (!mSourceShape || !mSourceShape->addSequence("ambient", "", mAnimationName, mStartFrame, mEndFrame, mPadRotation, mPadTransforms)) { Con::errorf("ShapeAnimationAsset::initializeAsset - Unable to do initial setup of the animation clip named %s for asset %s", mAnimationName, getAssetName()); return; diff --git a/Engine/source/T3D/assets/assetImporter.cpp b/Engine/source/T3D/assets/assetImporter.cpp index f965bd42c..932874fbd 100644 --- a/Engine/source/T3D/assets/assetImporter.cpp +++ b/Engine/source/T3D/assets/assetImporter.cpp @@ -79,6 +79,8 @@ AssetImportConfig::AssetImportConfig() : SeparateAnimationPrefix(""), animTiming("FrameCount"), animFPS(false), + AlwaysAddShapeAnimationSuffix(true), + AddedShapeAnimationSuffix("_anim"), GenerateCollisions(false), GenCollisionType(""), CollisionMeshPrefix(""), @@ -190,6 +192,8 @@ void AssetImportConfig::initPersistFields() addField("SeparateAnimationPrefix", TypeRealString, Offset(SeparateAnimationPrefix, AssetImportConfig), "If separating animations out from a source file, what prefix should be added to the names for grouping association"); addField("animTiming", TypeRealString, Offset(animTiming, AssetImportConfig), "Defines the animation timing for the given animation sequence. Options are FrameTime, Seconds, Milliseconds"); addField("animFPS", TypeBool, Offset(animFPS, AssetImportConfig), "The FPS of the animation sequence"); + addField("AlwaysAddShapeAnimationSuffix", TypeBool, Offset(AlwaysAddShapeAnimationSuffix, AssetImportConfig), "When importing a shape animation, this indicates if it should automatically add a standard suffix onto the name"); + addField("AddedShapeAnimationSuffix", TypeString, Offset(AddedShapeAnimationSuffix, AssetImportConfig), " If AlwaysAddShapeAnimationSuffix is on, this is the suffix to be added"); endGroup("Animation"); addGroup("Collision"); @@ -287,6 +291,8 @@ void AssetImportConfig::loadImportConfig(Settings* configSettings, String config SeparateAnimationPrefix = configSettings->value(String(configName + "/Animations/SeparateAnimationPrefix").c_str()); animTiming = configSettings->value(String(configName + "/Animations/animTiming").c_str()); animFPS = dAtof(configSettings->value(String(configName + "/Animations/animFPS").c_str())); + AlwaysAddShapeAnimationSuffix = dAtob(configSettings->value(String(configName + "/Animations/AlwaysAddShapeAnimationSuffix").c_str())); + AddedShapeAnimationSuffix = configSettings->value(String(configName + "/Animations/AddedShapeAnimationSuffix").c_str()); //Collisions GenerateCollisions = dAtob(configSettings->value(String(configName + "/Collision/GenerateCollisions").c_str())); @@ -379,6 +385,8 @@ void AssetImportConfig::CopyTo(AssetImportConfig* target) const target->SeparateAnimationPrefix = SeparateAnimationPrefix; target->animTiming = animTiming; target->animFPS = animFPS; + target->AlwaysAddShapeAnimationSuffix = AlwaysAddShapeAnimationSuffix; + target->AddedShapeAnimationSuffix = AddedShapeAnimationSuffix; //Collisions target->GenerateCollisions = GenerateCollisions; @@ -1531,13 +1539,15 @@ void AssetImporter::processImportAssets(AssetImportObject* assetItem) { processMaterialAsset(item); } - /*else if (item->assetType == String("ShapeAnimationAsset")) - ShapeAnimationAsset::prepareAssetForImport(this, item);*/ + else if (item->assetType == String("ShapeAnimationAsset")) + { + processShapeAnimationAsset(item); + } else { String processCommand = "process"; processCommand += item->assetType; - if(isMethod(processCommand.c_str())) + if (isMethod(processCommand.c_str())) Con::executef(this, processCommand.c_str(), item); } @@ -2048,6 +2058,73 @@ void AssetImporter::processShapeAsset(AssetImportObject* assetItem) assetItem->importStatus = AssetImportObject::Processed; } +void AssetImporter::processShapeAnimationAsset(AssetImportObject* assetItem) +{ + dSprintf(importLogBuffer, sizeof(importLogBuffer), "Preparing Shape Animation for Import: %s", assetItem->assetName.c_str()); + activityLog.push_back(importLogBuffer); + + String filePath = assetItem->filePath.getFullPath(); + String fileName = assetItem->filePath.getFileName(); + String fileExt = assetItem->filePath.getExtension(); + + if (assetItem->shapeInfo == nullptr) + { + GuiTreeViewCtrl* shapeInfo = new GuiTreeViewCtrl(); + shapeInfo->registerObject(); + + if (fileExt.compare("dae") == 0) + { + enumColladaForImport(filePath, shapeInfo, false); + } + else if (fileExt.compare("dts") == 0 || fileExt.compare("dsq") == 0) + { + enumDTSForImport(filePath, shapeInfo); + } + else + { + // Check if a cached DTS is available => no need to import the source file + // if we can load the DTS instead + + AssimpShapeLoader loader; + loader.fillGuiTreeView(filePath.c_str(), shapeInfo); + } + + assetItem->shapeInfo = shapeInfo; + } + + if (activeImportConfig->AlwaysAddShapeAnimationSuffix) + { + assetItem->assetName += activeImportConfig->AddedShapeAnimationSuffix; + assetItem->cleanAssetName = assetItem->assetName; + } + + S32 animCount = dAtoi(assetItem->shapeInfo->getDataField(StringTable->insert("_animCount"), nullptr)); + + dSprintf(importLogBuffer, sizeof(importLogBuffer), " Shape Animation Info: Anim Count: %i", animCount); + activityLog.push_back(importLogBuffer); + + AssetImportConfig* cachedConfig = new AssetImportConfig();; + cachedConfig->registerObject(); + activeImportConfig->CopyTo(cachedConfig); + + if (!activeImportConfig->UseManualShapeConfigRules) + { + //Try and load a sis file if it exists for this format + activeImportConfig->loadSISFile(assetItem->filePath); + } + + if (activeImportConfig->ImportAnimations && animCount > 0) + { + + } + + //restore the cached version just in case we loaded a sis file + cachedConfig->CopyTo(activeImportConfig); + cachedConfig->deleteObject(); + + assetItem->importStatus = AssetImportObject::Processed; +} + void AssetImporter::processShapeMaterialInfo(AssetImportObject* assetItem, S32 materialItemId) { String matName = assetItem->shapeInfo->getItemText(materialItemId); @@ -2188,9 +2265,20 @@ bool AssetImporter::validateAssets() void AssetImporter::validateAsset(AssetImportObject* assetItem) { - if (assetItem->importStatus == AssetImportObject::Skipped || assetItem->importStatus == AssetImportObject::NotProcessed) + if (assetItem->importStatus == AssetImportObject::Skipped || assetItem->importStatus == AssetImportObject::NotProcessed + || assetItem->importStatus == AssetImportObject::UseForDependencies) return; + //If this item's already been marked as being in error, don't bother with it. It knows what it did. + //This avoids running collision checks on an item already known to have a collision, which could erroneously + //mark the original, not-colliding item as colliding with this item, invaliding both + if (assetItem->status == String("Error") || assetItem->statusType.isNotEmpty()) + { + importIssues = true; + return; + } + + //Runm this item against our other importing assets and check for any collisions if (checkAssetForCollision(assetItem)) { importIssues = true; @@ -2294,7 +2382,7 @@ bool AssetImporter::checkAssetForCollision(AssetImportObject* assetItemToCheck, { AssetImportObject* importingAsset = itemList[i]; - if (importingAsset->importStatus == AssetImportObject::Skipped) + if (importingAsset->importStatus == AssetImportObject::Skipped || importingAsset->importStatus == AssetImportObject::UseForDependencies) continue; if ((assetItemToCheck->assetName.compare(importingAsset->assetName) == 0) && (assetItemToCheck->getId() != importingAsset->getId())) @@ -2584,6 +2672,10 @@ void AssetImporter::importAssets(AssetImportObject* assetItem) { assetPath = importMaterialAsset(item); } + else if (item->assetType == String("ShapeAnimationAsset")) + { + assetPath = importShapeAnimationAsset(item); + } else { finalImportedAssetPath = String::EmptyString; @@ -2625,7 +2717,7 @@ void AssetImporter::importAssets(AssetImportObject* assetItem) else { //Any special-case post-reg stuff here - if (item->assetType == String("ShapeAsset")) + if (item->assetType == String("ShapeAsset") || item->assetType == String("ShapeAnimationAsset")) { //forcefully update it's shape constructor TSShapeConstructor* tss = TSShapeConstructor::findShapeConstructorByAssetId(assetId); @@ -2692,7 +2784,7 @@ Torque::Path AssetImporter::importImageAsset(AssetImportObject* assetItem) //If it's not a re-import, check that the file isn't being in-place imported. If it isn't, store off the original //file path for reimporting support later - if (!isReimport && String::compare(qualifiedFromFile, qualifiedToFile)) + if (!isReimport && String::compare(qualifiedFromFile, qualifiedToFile) && Platform::isFile(qualifiedFromFile)) { newAsset->setDataField(StringTable->insert("originalFilePath"), nullptr, qualifiedFromFile); } @@ -2750,7 +2842,12 @@ Torque::Path AssetImporter::importMaterialAsset(AssetImportObject* assetItem) Platform::makeFullPathName(originalPath.c_str(), qualifiedFromFile, sizeof(qualifiedFromFile)); newAsset->setAssetName(assetName); + + if (!isReimport && Platform::isFile(qualifiedFromFile)) + { newAsset->setDataField(StringTable->insert("originalFilePath"), nullptr, qualifiedFromFile); + } + newAsset->setDataField(StringTable->insert("materialDefinitionName"), nullptr, assetName); //iterate through and write out the material maps dependencies @@ -2930,7 +3027,7 @@ Torque::Path AssetImporter::importShapeAsset(AssetImportObject* assetItem) //If it's not a re-import, check that the file isn't being in-place imported. If it isn't, store off the original //file path for reimporting support later - if (!isReimport && String::compare(qualifiedFromFile, qualifiedToFile)) + if (!isReimport && String::compare(qualifiedFromFile, qualifiedToFile) && Platform::isFile(qualifiedFromFile)) { newAsset->setDataField(StringTable->insert("originalFilePath"), nullptr, qualifiedFromFile); } @@ -3205,7 +3302,7 @@ Torque::Path AssetImporter::importSoundAsset(AssetImportObject* assetItem) //If it's not a re-import, check that the file isn't being in-place imported. If it isn't, store off the original //file path for reimporting support later - if (!isReimport && String::compare(qualifiedFromFile, qualifiedToFile)) + if (!isReimport && String::compare(qualifiedFromFile, qualifiedToFile) && Platform::isFile(qualifiedFromFile)) { newAsset->setDataField(StringTable->insert("originalFilePath"), nullptr, qualifiedFromFile); } @@ -3261,7 +3358,7 @@ Torque::Path AssetImporter::importShapeAnimationAsset(AssetImportObject* assetIt //If it's not a re-import, check that the file isn't being in-place imported. If it isn't, store off the original //file path for reimporting support later - if (!isReimport && String::compare(qualifiedFromFile, qualifiedToFile)) + if (!isReimport && String::compare(qualifiedFromFile, qualifiedToFile) && Platform::isFile(qualifiedFromFile)) { newAsset->setDataField(StringTable->insert("originalFilePath"), nullptr, qualifiedFromFile); } diff --git a/Engine/source/T3D/assets/assetImporter.h b/Engine/source/T3D/assets/assetImporter.h index 6605ebe8f..4e2fc53aa 100644 --- a/Engine/source/T3D/assets/assetImporter.h +++ b/Engine/source/T3D/assets/assetImporter.h @@ -261,6 +261,16 @@ public: /// F32 animFPS; + /// + /// When importing a shape animation, this indicates if it should automatically add a standard suffix onto the name + /// + bool AlwaysAddShapeAnimationSuffix; + + /// + /// If AlwaysAddShapeAnimationSuffix is on, this is the suffix to be added + /// + String AddedShapeAnimationSuffix; + // //Collision /// @@ -800,11 +810,17 @@ public: void processMaterialAsset(AssetImportObject* assetItem); /// - /// Process a specific AssetImportObject that is an ShapeAsset type to prepare it for importing + /// Process a specific AssetImportObject that is an ShapeAnimationAsset type to prepare it for importing /// @param assetItem, The AssetImportObject to process /// void processShapeAsset(AssetImportObject* assetItem); + /// + /// Process a specific AssetImportObject that is an ShapeAsset type to prepare it for importing + /// @param assetItem, The AssetImportObject to process + /// + void processShapeAnimationAsset(AssetImportObject* assetItem); + /// /// Process a specific ShapeAsset AssetImportObject with a material id in order to parse and handle the materials listed in the shape file /// @param assetItem, The AssetImportObject to process diff --git a/Templates/BaseGame/game/tools/assetBrowser/assetImportConfigs.xml b/Templates/BaseGame/game/tools/assetBrowser/assetImportConfigs.xml index 5c91b3d2a..285c9d235 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/assetImportConfigs.xml +++ b/Templates/BaseGame/game/tools/assetBrowser/assetImportConfigs.xml @@ -195,7 +195,7 @@ 0 FolderPrefix + name="DuplicateAutoResolution">AutoPrune 1