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