Browse Source

Adjusts handling so if a file being processed for importing is not actually imported as a new, successful asset it does not return an id, allowing tooling to only worry about actual new assets.
Adds utility functions to TerrainBlock to be able to replace names of materials in the terrain file, mostly used for importing legacy files
Adjusts terrainblock save asset logic to be able to save on a non-networked terrainblock such as when loaded temporarily on the server, for tooling purposes.
Changes handling of not-found terrain materials when loading a terrain block so it will create a dummy terrain material with the same name as the not-found, but set the texture as the Warning image, instead of thrashing the original material names data
Adds logic for testing newly imported terrain files' materials and if needbe, replacing them with the new terrain material asset ids.
Adds logic in the project importer for if a would-be level asset's name already exists, we attempt to slap a "Level" suffix onto it to sidestep collisions.
Changed LegacyImport config to try always adding shape suffix to help minimize probable naming collisions.
Fixed handling of mission file's MissionGroup defines by specially checking for MissionGroup objects and processing the line into a Scene() declaration instead.

JeffR 3 years ago
parent
commit
cf8659735b

+ 4 - 1
Engine/source/T3D/assets/assetImporter.cpp

@@ -2534,7 +2534,10 @@ StringTableEntry AssetImporter::autoImportFile(Torque::Path filePath, String typ
 
    dumpActivityLog();
 
-   if (hasIssues)
+   if (hasIssues ||
+      assetItem->importStatus == AssetImportObject::Skipped ||
+      assetItem->importStatus == AssetImportObject::UseForDependencies ||
+      assetItem->importStatus == AssetImportObject::Error)
    {
       return StringTable->EmptyString();
    }

+ 45 - 3
Engine/source/terrain/terrData.cpp

@@ -480,16 +480,21 @@ bool TerrainBlock::saveAsset()
 
       AssetDatabase.findAssetType(pAssetQuery, "TerrainMaterialAsset");
 
-      TerrainBlock* clientTerr = static_cast<TerrainBlock*>(getClientObject());
+      TerrainBlock* terr = static_cast<TerrainBlock*>(getClientObject());
+      if (!terr)
+      {
+         Con::warnf("No active client terrain while trying to save asset. Could be a server action, but should check to be sure!");
+         terr = this;
+      }
 
       for (U32 i = 0; i < pAssetQuery->mAssetList.size(); i++)
       {
          //Acquire it so we can check it for matches
          AssetPtr<TerrainMaterialAsset> terrMatAsset = pAssetQuery->mAssetList[i];
 
-         for (U32 m = 0; m < clientTerr->mFile->mMaterials.size(); m++)
+         for (U32 m = 0; m < terr->mFile->mMaterials.size(); m++)
          {
-            StringTableEntry intMatName = clientTerr->mFile->mMaterials[m]->getInternalName();
+            StringTableEntry intMatName = terr->mFile->mMaterials[m]->getInternalName();
 
             StringTableEntry assetMatDefName = terrMatAsset->getMaterialDefinitionName();
             if (assetMatDefName == intMatName)
@@ -1456,6 +1461,25 @@ void TerrainBlock::getUtilizedAssets(Vector<StringTableEntry>* usedAssetsList)
 // Console Methods
 //-----------------------------------------------------------------------------
 
+bool TerrainBlock::renameTerrainMaterial(StringTableEntry oldMatName, StringTableEntry newMatName)
+{
+   TerrainMaterial* newMat = TerrainMaterial::findOrCreate(newMatName);
+   if (!newMat)
+      return false;
+
+   U32 terrainMaterialCount = mFile->mMaterials.size();
+   for (U32 i = 0; i < terrainMaterialCount; i++)
+   {
+      if (mFile->mMaterials[i]->getInternalName() == oldMatName)
+      {
+         TerrainMaterial* oldMat = mFile->mMaterials[i];
+         mFile->mMaterials[i] = newMat;
+      }
+   }
+
+   return true;
+}
+
 DefineEngineMethod( TerrainBlock, save, bool, ( const char* fileName),,
 				   "@brief Saves the terrain block's terrain file to the specified file name.\n\n"
 
@@ -1623,3 +1647,21 @@ DefineEngineMethod(TerrainBlock, setTerrain, bool, (const char* terrain), , "Ter
 {
    return object->_setTerrain(StringTable->insert(terrain));
 }
+
+DefineEngineMethod(TerrainBlock, getTerrainMaterialCount, S32, (), , "Gets the number of terrain materials for this block")
+{
+   return object->getTerrainMaterialCount();
+}
+
+DefineEngineMethod(TerrainBlock, getTerrainMaterialName, const char*, (S32 index), , "Gets the number of terrain materials for this block")
+{
+   if (index < 0 || index >= object->getTerrainMaterialCount())
+      return StringTable->EmptyString();
+
+   return object->getTerrainMaterialName(index);
+}
+
+DefineEngineMethod(TerrainBlock, renameTerrainMaterial, bool, (const char* oldMaterialName, const char* newMaterialName), , "Updates the terrain material from the original to the new name in the file. Mostly used for import/conversions.")
+{
+   return object->renameTerrainMaterial(StringTable->insert(oldMaterialName), StringTable->insert(newMaterialName));
+}

+ 13 - 0
Engine/source/terrain/terrData.h

@@ -522,6 +522,19 @@ public:
       return true;
    }
  
+   bool renameTerrainMaterial(StringTableEntry oldMatName, StringTableEntry newMatName);
+   S32 getTerrainMaterialCount() {
+      if (mFile)
+         return mFile->mMaterials.size();
+      return 0;
+   }
+
+   StringTableEntry getTerrainMaterialName(S32 index) {
+      if (mFile)
+         return mFile->mMaterials[index]->getInternalName();
+
+      return StringTable->EmptyString();
+   }
 protected:
    bool mUpdateBasetex;
    bool mIgnoreZodiacs;

+ 17 - 10
Engine/source/terrain/terrMaterial.cpp

@@ -30,6 +30,8 @@
 #include "console/persistenceManager.h"
 #endif
 
+#include "T3D/assets/TerrainMaterialAsset.h"
+
 #include <string>
 
 
@@ -166,6 +168,18 @@ TerrainMaterial* TerrainMaterial::findOrCreate( const char *nameOrPath )
    if ( mat )
       return mat;
 
+   StringTableEntry assetId = TerrainMaterialAsset::getAssetIdByMaterialName(nameOrPath);
+   if (assetId != StringTable->EmptyString())
+   {
+      TerrainMaterialAsset* terrMatAsset = AssetDatabase.acquireAsset<TerrainMaterialAsset>(assetId);
+      if (terrMatAsset)
+      {
+         mat = terrMatAsset->getMaterialDefinition();
+         if (mat)
+            return mat;
+      }
+   }
+
    // We didn't find it... so see if its a path to a
    // file.  If it is lets assume its the texture.
    if ( GBitmap::sFindFiles( nameOrPath, NULL ) )
@@ -178,15 +192,9 @@ TerrainMaterial* TerrainMaterial::findOrCreate( const char *nameOrPath )
       return mat;
    }
 
-   // Ok... return a debug material then.
-   mat = dynamic_cast<TerrainMaterial*>( set->findObjectByInternalName( StringTable->insert( "warning_material" ) ) );
-   if ( !mat )
-   {
-      // This shouldn't happen.... the warning_texture should
-      // have already been defined in script, but we put this
-      // fallback here just in case it gets "lost".
+   // Ok... return a placeholder material then.
       mat = new TerrainMaterial();
-      mat->setInternalName( "warning_material" );
+   mat->setInternalName(nameOrPath);
       mat->_setDiffuseMap(GFXTextureManager::getWarningTexturePath());
       mat->mDiffuseSize = 500;
       mat->_setDetailMap(StringTable->EmptyString());
@@ -195,8 +203,7 @@ TerrainMaterial* TerrainMaterial::findOrCreate( const char *nameOrPath )
 	   mat->mMacroSize = 200;
       mat->registerObject();
       
-      Sim::getRootGroup()->addObject( mat );
-   }
+   Sim::getRootGroup()->addObject(mat);
 
    return mat;
 }

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

@@ -110,7 +110,7 @@
             <Setting
                 name="AdjustFloor">0</Setting>
             <Setting
-                name="AlwaysAddShapeSuffix">0</Setting>
+                name="AlwaysAddShapeSuffix">1</Setting>
             <Setting
                 name="calcTangentSpace">0</Setting>
             <Setting

+ 41 - 8
Templates/BaseGame/game/tools/projectImporter/importers/pre40/T3Dpre4ProjectImporter.tscript

@@ -353,6 +353,7 @@ function T3Dpre4ProjectImporter::beginMaterialFilesImport(%this)
       %file = $ProjectImporter::FileList.getKey(%i);
       %rootFileSectionObject = $ProjectImporter::FileList.getValue(%i);
       
+      $ProjectImporter::currentFile = %rootFileSectionObject.fileDestination;
       $ProjectImporter::currentFilePath = filePath(%rootFileSectionObject.fileDestination) @ "/"; //give context to the file we're processing
       
       if(%rootFileSectionObject.binaryFile == true || %rootFileSectionObject.imported == true)
@@ -458,6 +459,7 @@ function T3Dpre4ProjectImporter::beginSoundProfilesImport(%this)
       %file = $ProjectImporter::FileList.getKey(%i);
       %rootFileSectionObject = $ProjectImporter::FileList.getValue(%i);
       
+      $ProjectImporter::currentFile = %rootFileSectionObject.fileDestination;
       $ProjectImporter::currentFilePath = filePath(%rootFileSectionObject.fileDestination) @ "/"; //give context to the file we're processing
       
       if(%rootFileSectionObject.binaryFile == true || %rootFileSectionObject.imported == true)
@@ -523,17 +525,24 @@ function T3Dpre4ProjectImporter::processScripts(%this, %arrayObj)
                   T3Dpre4ProjectImporter.call(%processFunction, %lineObj, %sanitizedName);
                }
                
-               //Now, we process the fields to be asset-ified on our object
-               for(%l=0; %l < %lineObj.count(); %l++)
+               //we're gunna handle the mission group definition lines specially because we need to process against an object's NAME
+               //rather than just the className
+               if(%lineObj.objectName $= "MissionGroup")
                {
-                  %objectCodeLine = %lineObj.getKey(%l);
-                  if(!isObject(%objectCodeLine))
+                  $ProjectImporter::assetQuery.clear();
+                  %assetsFound = AssetDatabase.findAssetLooseFile($ProjectImporter::assetQuery, $ProjectImporter::currentFile);
+                  if(%assetsFound != 0)
                   {
-                     %processLineFunction = "process" @ %subclass @ "Line";
-                     if(T3Dpre4ProjectImporter.isMethod(%processLineFunction))
+                     //ok, valid level asset  
+                     %levelAssetId = $ProjectImporter::assetQuery.getAsset(0);
+                     %levelName = AssetDatabase.getAssetName(%levelAssetId);
+                     
+                     //Now, we process the fields to be asset-ified on our object
+                     for(%l=0; %l < %lineObj.count(); %l++)
                      {
-                        %resultLine = T3Dpre4ProjectImporter.call(%processLineFunction, %objectCodeLine);
-
+                        %objectCodeLine = %lineObj.getKey(%l);
+                        %resultLine = T3Dpre4ProjectImporter.processMissionGroupLine(%objectCodeLine, %levelName);
+                        
                         if(%resultLine !$= %objectCodeLine)
                         {
                            projectImporterLog("   processed line: " @ %resultLine @ " from: " @ %objectCodeLine);
@@ -542,6 +551,28 @@ function T3Dpre4ProjectImporter::processScripts(%this, %arrayObj)
                      }
                   }
                }
+               else //regular convertwork
+               {
+                  //Now, we process the fields to be asset-ified on our object
+                  for(%l=0; %l < %lineObj.count(); %l++)
+                  {
+                     %objectCodeLine = %lineObj.getKey(%l);
+                     if(!isObject(%objectCodeLine))
+                     {
+                        %processLineFunction = "process" @ %subclass @ "Line";
+                        if(T3Dpre4ProjectImporter.isMethod(%processLineFunction))
+                        {
+                           %resultLine = T3Dpre4ProjectImporter.call(%processLineFunction, %objectCodeLine);
+
+                           if(%resultLine !$= %objectCodeLine)
+                           {
+                              projectImporterLog("   processed line: " @ %resultLine @ " from: " @ %objectCodeLine);
+                              %lineObj.setKey(%resultLine, %l);
+                           }
+                        }
+                     }
+                  }
+               }
             }
             
             %lineObj.processed = true;
@@ -624,6 +655,7 @@ function T3Dpre4ProjectImporter::beginScriptFilesImport(%this)
          continue;
       }
       
+      $ProjectImporter::currentFile = %rootFileSectionObject.fileDestination;
       $ProjectImporter::currentFilePath = filePath(%rootFileSectionObject.fileDestination) @ "/";
       
       projectImporterLog("T3Dpre4ProjectImporter::beginScriptFilesImport() - Processing script file: " @ %file);
@@ -693,6 +725,7 @@ function T3Dpre4ProjectImporter::beginAssetAndModuleImport(%this)
             continue;
             
          projectImporterLog("T3Dpre4ProjectImporter::beginAssetAndModuleImport() - processing file: " @ %file);
+         $ProjectImporter::currentFile = %rootFileSectionObject.fileDestination;
          $ProjectImporter::currentFilePath = filePath(%rootFileSectionObject.fileDestination) @ "/";
          %this.processModuleFile(%rootFileSectionObject);
          %rootFileSectionObject.processed = true;

+ 55 - 1
Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript

@@ -1613,6 +1613,21 @@ function beginTerrainImport()
             //test import config here for forcing type suffixes
             %assetName = fileBase(%destinationPath);
             
+            if(AssetDatabase.isDeclaredAsset(%moduleName @ ":" @ %assetName))
+            {
+               //Attempt to rename it to avoid collisions
+               if(!endsWith(%assetName, "Terrain") && !AssetDatabase.isDeclaredAsset(%moduleName @ ":" @ %assetName @ "Terrain"))
+               {
+                  %assetName = %assetName @ "Terrain";
+               }
+               else
+               {
+                  //Nope, there's already a matching one for that too, so just bail
+                  projectImporterLog("Legacy Project Importer - Error - trying to process a Terrain into an asset that already exists");
+                  return false;  
+               }
+            }
+            
             %assetPath = filePath(%destinationPath) @ "/";
             
             %tamlpath = %assetPath @ %assetName @ ".asset.taml";
@@ -1628,6 +1643,36 @@ function beginTerrainImport()
             {
                AssetDatabase.addDeclaredAsset(%moduleDef, %tamlpath);
                
+               //we probably need to update the terrainMaterial references if any of them got renamed, so lets do that now
+               %terrBlock = new TerrainBlock(tmp) {
+                  terrainAsset = %moduleName @ ":" @ %assetName;
+               };
+               
+               %matNamesChanged = false;
+               %terrMatCount = %terrBlock.getTerrainMaterialCount();
+               for(%tm = 0; %tm < %terrMatCount; %tm++)
+               {
+                  %terrMatName = %terrBlock.getTerrainMaterialName(%tm);
+                  %terrMatAssetId = TerrainMaterialAsset::getAssetIdByMaterialName(%terrMatName);
+                  if(%terrMatAssetId $= "")
+                  {
+                     //k, one didn't map right, lets try and fix it
+                     %terrMatAssetId = TerrainMaterialAsset::getAssetIdByMaterialName(%terrMatName @ "_terrainMat");
+                     if(%terrMatAssetId !$= "")
+                     {
+                        //Ok, success, lets run the rename
+                        if(%terrBlock.renameTerrainMaterial(%terrMatName, %terrMatName @ "_terrainMat"))
+                           %matNamesChanged = true;
+                     }
+                  }
+               }
+               
+               if(%matNamesChanged)
+               {
+                  %terrBlock.saveAsset();
+                  %terrBlock.delete();
+               }
+               
                projectImporterLog("Finished importing Terrain file, resulting in asset with an id of: " @ %moduleName @ ":" @ %assetName);
                projectImporterLog("");
                
@@ -1918,9 +1963,18 @@ function beginLevelImport()
             
             if(AssetDatabase.isDeclaredAsset(%moduleName @ ":" @ %assetName))
             {
-               projectImporterLog("Legacy Project Importer - trying to process a level into an asset that already exists");
+               //Attempt to rename it to avoid collisions
+               if(!endsWith(%assetName, "Level") && !AssetDatabase.isDeclaredAsset(%moduleName @ ":" @ %assetName @ "Level"))
+               {
+                  %assetName = %assetName @ "Level";
+               }
+               else
+               {
+                  //Nope, there's already a matching one for that too, so just bail
+                  projectImporterLog("Legacy Project Importer - Error - trying to process a level into an asset that already exists");
                return false;  
             }
+            }
             
             %assetPath = %filePath @ "/";
             %tamlpath = %assetPath @ %assetName @ ".asset.taml";