Преглед изворни кода

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.

JeffR пре 3 година
родитељ
комит
b3342ff7e6

+ 1 - 1
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;

+ 107 - 10
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);
    }

+ 17 - 1
Engine/source/T3D/assets/assetImporter.h

@@ -261,6 +261,16 @@ public:
    /// </summary>
    F32 animFPS;
 
+   /// <summary>
+   /// When importing a shape animation, this indicates if it should automatically add a standard suffix onto the name
+   /// </summary>
+   bool AlwaysAddShapeAnimationSuffix;
+
+   /// <summary>
+   /// If AlwaysAddShapeAnimationSuffix is on, this is the suffix to be added
+   /// </summary>
+   String AddedShapeAnimationSuffix;
+
    //
    //Collision
    /// <summary>
@@ -800,11 +810,17 @@ public:
    void processMaterialAsset(AssetImportObject* assetItem);
 
    /// <summary>
-   /// 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
    /// <para>@param assetItem, The AssetImportObject to process</para>
    /// </summary>
    void processShapeAsset(AssetImportObject* assetItem);
 
+   /// <summary>
+   /// Process a specific AssetImportObject that is an ShapeAsset type to prepare it for importing
+   /// <para>@param assetItem, The AssetImportObject to process</para>
+   /// </summary>
+   void processShapeAnimationAsset(AssetImportObject* assetItem);
+
    /// <summary>
    /// Process a specific ShapeAsset AssetImportObject with a material id in order to parse and handle the materials listed in the shape file
    /// <para>@param assetItem, The AssetImportObject to process</para>

+ 1 - 1
Templates/BaseGame/game/tools/assetBrowser/assetImportConfigs.xml

@@ -195,7 +195,7 @@
             <Setting
                 name="AutomaticallyPromptMissingFiles">0</Setting>
             <Setting
-                name="DuplicateAutoResolution">FolderPrefix</Setting>
+                name="DuplicateAutoResolution">AutoPrune</Setting>
             <Setting
                 name="PreventImportWithErrors">1</Setting>
             <Setting

+ 2 - 1
Templates/BaseGame/game/tools/assetBrowser/scripts/assetImport.tscript

@@ -108,7 +108,8 @@ function isShapeFormat(%fileExt)
    (%fileExt $= ".gltf") || 
    (%fileExt $= ".glb") || 
    (%fileExt $= ".obj") || 
-   (%fileExt $= ".blend"))
+   (%fileExt $= ".blend") || 
+   (%fileExt $= ".dsq"))
       return true;
       
    return false;

+ 6 - 1
Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/image.tscript

@@ -148,10 +148,15 @@ function AssetBrowser::importImageAsset(%this, %assetItem)
       assetName = %assetName;
       versionId = 1;
       imageFile = fileName(%filePath);
-      originalFilePath = %filePath;
       imageType = %assetItem.imageType;
    };
    
+   //No point in indicating the original path data if it was imported in-place
+   if(!startsWith(makeFullPath(%filePath), getMainDotCsDir()))
+   {
+      %newAsset.originalFilePath = %filePath;
+   }
+   
    %assetImportSuccessful = TAMLWrite(%newAsset, %assetPath @ "/" @ %assetName @ ".asset.taml"); 
    
    //and copy the file into the relevent directory

+ 7 - 1
Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/material.tscript

@@ -321,10 +321,16 @@ function AssetBrowser::importMaterialAsset(%this, %assetItem)
       versionId = 1;
       shaderGraph = %sgfPath;
       scriptFile = %assetName @ "." @ $TorqueScriptFileExtension;
-      originalFilePath = %filePath;
       materialDefinitionName = %assetName;
    };
    
+   //No point in indicating the original path data if it was imported in-place
+   %mainPath = getMainDotCsDir();
+   if(!startsWith(makeFullPath(%filePath), getMainDotCsDir()))
+   {
+      %newAsset.originalFilePath = %filePath;
+   }
+   
    //check dependencies
    %dependencySlotId = 0;
    for(%i=0; %i < %assetItem.childAssetItems.count(); %i++)

+ 6 - 1
Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/shape.tscript

@@ -131,10 +131,15 @@ function AssetBrowser::importShapeAsset(%this, %assetItem)
       assetName = %assetName;
       versionId = 1;
       fileName = fileName(%filePath);
-      originalFilePath = %filePath;
       isNewShape = true;
    };
    
+   //No point in indicating the original path data if it was imported in-place
+   if(!startsWith(makeFullPath(%filePath), getMainDotCsDir()))
+   {
+      %newAsset.originalFilePath = %filePath;
+   }
+   
    //check dependencies
    %dependencySlotId = 0;
    for(%i=0; %i < %assetItem.childAssetItems.count(); %i++)

+ 10 - 0
Templates/BaseGame/game/tools/materialEditor/scripts/materialEditor.ed.tscript

@@ -290,6 +290,15 @@ function SubMaterialSelector::onSelect( %this )
       if( MaterialEditorGui.currentObject.isMethod("postApply") )
          MaterialEditorGui.currentObject.postApply();*/
    }
+   else
+   {
+      %materialAssetId = MaterialAsset::getAssetIdByMaterialName(%material);
+      if(%materialAssetId !$= "" && %materialAssetId !$= $Core::NoMaterialAssetFallback)
+      {
+         MaterialEditorGui.currentMaterialAsset = %materialAssetId;
+         %assetDef = AssetDatabase.acquireAsset(%material);
+      }
+   }
 
    MaterialEditorGui.prepareActiveMaterial( %material.getId() );
 }
@@ -1950,6 +1959,7 @@ function MaterialEditorGui::save( %this )
      
    if(MaterialEditorGui.currentMaterialAsset !$= "")
    {
+      echo("Attempting to save material: " @ MaterialEditorGui.currentMaterialAsset);
       MaterialEditorGui.copyMaterials( materialEd_previewMaterial, notDirtyMaterial );
       
       %assetDef = AssetDatabase.acquireAsset(MaterialEditorGui.currentMaterialAsset);

+ 3 - 0
Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript

@@ -1029,6 +1029,8 @@ function testFilenameExtensions(%filename)
       return %filename @ ".dae";
    else if(isFile(%filename @ ".dds"))
       return %filename @ ".dds";
+   else if(isFile(%filename @ ".dsq"))
+      return %filename @ ".dsq";
    else if(isFile(%filename @ ".ogg"))
       return %filename @ ".ogg";
    else if(isFile(%filename @ ".wav"))
@@ -2101,6 +2103,7 @@ function scanForDuplicateFiles(%toTestFile)
       //We only really care about content files for this
       if(!endsWith(%file, "dts") &&
          !endsWith(%file, "dae") && 
+         !endsWith(%file, "dsq") && 
          !endsWith(%file, "fbx") &&
          !endsWith(%file, "ter") &&
          !endsWith(%file, "png") &&