Browse Source

Added fix so if a looping sound is preview-playing in the AB and you edit the properties, it doesn't try to reload the asset while it's playing, causing a crash
Added console method for looking up a soundAsset by filename
Added initial pass of project importer for sound assets content

Areloch 4 năm trước cách đây
mục cha
commit
0ca66b99db

+ 8 - 0
Engine/source/T3D/assets/SoundAsset.cpp

@@ -343,6 +343,14 @@ DefineEngineMethod(SoundAsset, playSound, S32, (Point3F position), (Point3F::Zer
       return 0;
 }
 
+#ifdef TORQUE_TOOLS
+DefineEngineStaticMethod(SoundAsset, getAssetIdByFilename, const char*, (const char* filePath), (""),
+   "Queries the Asset Database to see if any asset exists that is associated with the provided file path.\n"
+   "@return The AssetId of the associated asset, if any.")
+{
+   return SoundAsset::getAssetIdByFileName(StringTable->insert(filePath));
+}
+#endif
 IMPLEMENT_CONOBJECT(GuiInspectorTypeSoundAssetPtr);
 
 ConsoleDocClass(GuiInspectorTypeSoundAssetPtr,

+ 10 - 1
Engine/source/sfx/sfxSource.cpp

@@ -791,6 +791,9 @@ void SFXSource::_setStatus( SFXStatus status )
 
 void SFXSource::_updateVolume( const MatrixF& listener )
 {
+   if (!mDescription)
+      return;
+
    // Handle fades (compute mFadedVolume).
       
    mFadedVolume = mPreFadeVolume;
@@ -919,13 +922,19 @@ void SFXSource::_updateVolume( const MatrixF& listener )
 
 void SFXSource::_updatePitch()
 {
+   if (!mDescription)
+      return;
+
    mEffectivePitch = mModulativePitch * mPitch;
 }
 
 //-----------------------------------------------------------------------------
 
 void SFXSource::_updatePriority()
-{      
+{
+   if (!mDescription)
+      return;
+
    mEffectivePriority = mPriority * mModulativePriority;
 
    SFXSource* group = getSourceGroup();

+ 4 - 0
Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/shape.tscript

@@ -42,6 +42,10 @@ function AssetBrowser::editShapeAsset(%this, %assetDef)
    ShapeEditorPlugin.openShapeAsset(%assetDef);    
 }
 
+function AssetBrowser::onShapeAssetChanged(%this, %assetDef)
+{
+}
+
 function AssetBrowser::deleteShapeAsset(%this, %assetDef)
 {
    

+ 6 - 0
Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/sound.tscript

@@ -5,6 +5,12 @@ function AssetBrowser::editSoundAsset(%this, %assetDef)
    $PreviewSoundSource = %assetDef.playSound();
 }
 
+function AssetBrowser::onSoundAssetChanged(%this, %assetDef)
+{
+   if (isObject($PreviewSoundSource))
+        sfxStop($PreviewSoundSource);
+}
+
 function AssetBrowser::buildSoundAssetPreview(%this, %assetDef, %previewData)
 {
    %previewData.assetName = %assetDef.assetName;

+ 5 - 0
Templates/BaseGame/game/tools/assetBrowser/scripts/editAsset.tscript

@@ -6,6 +6,11 @@ function AssetBrowser_editAsset::saveAsset(%this)
    AssetBrowser.reloadAsset(%this.editedAssetId);
 
    AssetBrowser.refresh();
+   
+   %assetType = AssetDatabase.getAssetType(%this.editedAssetId);
+   %assetDef = AssetDatabase.acquireAsset(%this.editedAssetId);
+   AssetBrowser.call("on" @ %assetType @ "Changed", %assetDef);
+   AssetDatabase.releaseAsset(%this.editedAssetId);
 
    Canvas.popDialog(AssetBrowser_editAsset);
 }

+ 168 - 0
Templates/BaseGame/game/tools/projectImporter/scripts/pre40/T3Dpre4ProjectImporter.tscript

@@ -838,6 +838,7 @@ T3Dpre4ProjectImporter::genProcessor("afxBillboardData", "texture textureAsset")
 T3Dpre4ProjectImporter::genProcessor("afxModelData", "shapeName shapeAsset shapeFile shapeAsset");
 T3Dpre4ProjectImporter::genProcessor("afxZodiacData", "texture textureAsset");
 T3Dpre4ProjectImporter::genProcessor("afxZodiacPlaneData", "texture textureAsset");
+T3Dpre4ProjectImporter::genProcessor("sfxEmitter", "track soundAsset filename soundAsset");
 //==============================================================================
 // Levels
 //==============================================================================
@@ -1064,6 +1065,173 @@ function T3Dpre4ProjectImporter::processTerrainMaterialObject(%this, %file, %obj
 //==============================================================================
 T3Dpre4ProjectImporter::genProcessor("PostEffect", "texture textureAsset");
 
+//==============================================================================
+// Sounds
+// Sounds are a little weird because there's so much data tied up in a given sound
+// source. So our approach is find old SFXProfiles and process those into sound assets
+// by cross-referencing the filename for existing asset definitions.
+// Using existing SFXProfiles allows us to also injest the descriptions, giving us
+// our meta-properties on the sound asset itself.
+//==============================================================================
+function T3Dpre4ProjectImporter::processSFXProfileLine(%this, %line)
+{
+   return %line;
+}
+
+function T3Dpre4ProjectImporter::processSFXProfileObject(%this, %file, %objectName)
+{
+   %soundFilename = findObjectField("filename");
+   
+   %soundFilename = sanitizeFilename(%soundFilename);
+
+   %soundAsset = SoundAsset::getAssetIdByFilename(%soundFilename);
+   
+   //Throw a warn that this file's already been claimed and move on
+   if(%soundAsset !$= "")
+   {
+      error("T3Dpre4ProjectImporter::processSFXProfileObject() - attempting to process SFXProfile " @ %objectName 
+               @ " but its filename is already associated to another sound asset.");
+      return false;
+   }  
+   //Otherwise, process it into an asset
+   else
+   {
+      %assetName = %objectName;
+   
+      %moduleName = AssetBrowser.dirHandler.getModuleFromAddress(%soundFilename).ModuleId;
+      
+      %assetPath = filePath(%soundFilename) @ "/";   
+      
+      %tamlpath = %assetPath @ %assetName @ ".asset.taml";
+      
+      if(isFile(%tamlpath))
+      {
+         error("T3Dpre4ProjectImporter::processSFXProfileObject() - Failed to create as taml file already exists: " @ %soundFilename);
+         return false;
+      }
+      
+      %asset = new SoundAsset()
+      {
+         AssetName = %assetName;
+         versionId = 1;
+         shaderData = "";
+         soundFile = fileBase(%soundFilename) @ fileExt(%soundFilename);
+      };
+      
+      %descriptionName = findObjectField("description");
+      
+      if(%descriptionName !$= "")
+      {
+         //Optimization, see if we already have this description by happenstance
+         if(isObject(%descriptionName))
+         {
+            %asset.sourceGroup = %descriptionName.sourceGroup;
+            %asset.volume = %descriptionName.volume;
+            %asset.pitch = %descriptionName.pitch;
+            %asset.isLooping = %descriptionName.isLooping;
+            %asset.priority = %descriptionName.priority;
+            %asset.useHardware = %descriptionName.useHardware;
+            %asset.is3D = %descriptionName.is3D;
+            %asset.minDistance = %descriptionName.minDistance;
+            %asset.maxDistance = %descriptionName.maxDistance;
+            %asset.scatterDistance = %descriptionName.scatterDistance;
+            %asset.coneInsideAngle = %descriptionName.coneInsideAngle;            
+            %asset.coneOutsideAngle = %descriptionName.coneOutsideAngle;         
+            %asset.coneOutsideVolume = %descriptionName.coneOutsideVolume;
+            %asset.rolloffFactor = %descriptionName.rolloffFactor;
+            %asset.isStreaming = %descriptionName.isStreaming;
+         }
+         else
+         {
+            %objFileFinder = findObjectInFiles(%descriptionName);
+            if(%objFileFinder !$= "")
+            {
+               %valueArray = new ArrayObject();
+               
+               %valueArray.add("sourceGroup" SPC findObjectField("sourceGroup", %objFileFinder));
+               %valueArray.add("volume" SPC findObjectField("volume", %objFileFinder));
+               %valueArray.add("pitch" SPC findObjectField("pitch", %objFileFinder));
+               %valueArray.add("isLooping" SPC findObjectField("isLooping", %objFileFinder));
+               %valueArray.add("priority" SPC findObjectField("priority", %objFileFinder));
+               %valueArray.add("useHardware" SPC findObjectField("useHardware", %objFileFinder));
+               %valueArray.add("is3D" SPC findObjectField("is3D", %objFileFinder));
+               %valueArray.add("minDistance" SPC findObjectField("minDistance", %objFileFinder));
+               %valueArray.add("maxDistance" SPC findObjectField("maxDistance", %objFileFinder));
+               %valueArray.add("scatterDistance" SPC findObjectField("scatterDistance", %objFileFinder));
+               %valueArray.add("coneInsideAngle" SPC findObjectField("coneInsideAngle", %objFileFinder));
+               %valueArray.add("coneOutsideAngle" SPC findObjectField("coneOutsideAngle", %objFileFinder));
+               %valueArray.add("coneOutsideVolume" SPC findObjectField("coneOutsideVolume", %objFileFinder));
+               %valueArray.add("rolloffFactor" SPC findObjectField("rolloffFactor", %objFileFinder));
+               %valueArray.add("isStreaming" SPC findObjectField("isStreaming", %objFileFinder));
+               
+               %objFileFinder.delete();
+               
+               for(%v=0; %v < %valueArray.Count(); %v++)
+               {
+                  %varSet = %valueArray.getKey(%v);
+                  %var = getWord(%varSet, 0);
+                  %varVal = getWord(%varSet, 1);
+
+                  if(%varVal !$= "")
+                     %asset.setFieldValue(%var, %varVal);
+               }
+            }
+         }
+      }
+      
+      TamlWrite(%asset, %tamlpath);
+      
+      %moduleDef = ModuleDatabase.findModule(%moduleName, 1);
+      %success = AssetDatabase.addDeclaredAsset(%moduleDef, %tamlpath);
+      
+      if(!%success)
+         return false;
+   }
+   
+   //Now mark the original SFXProfile for removal from the file as it's redundant
+   //now that we have the asset def
+   
+   /*if(%matAsset $= "" || %matAsset $= "Core_Rendering:NoMaterial")
+   {
+      %assetName = %objectName;
+   
+      %moduleName = AssetBrowser.dirHandler.getModuleFromAddress(%file).ModuleId;
+      
+      %assetPath = filePath(%file) @ "/";   
+      
+      %tamlpath = %assetPath @ %assetName @ ".asset.taml";
+      
+      if(isFile(%tamlpath))
+      {
+         error("T3Dpre4ProjectImporter::processMaterialObject() - Failed to create as taml file already exists: " @ %file);
+         return false;
+      }
+      
+      %asset = new MaterialAsset()
+      {
+         AssetName = %assetName;
+         versionId = 1;
+         shaderData = "";
+         materialDefinitionName = %assetName;
+         scriptFile = fileBase(%file);
+      };
+      
+      TamlWrite(%asset, %tamlpath);
+      
+      %moduleDef = ModuleDatabase.findModule(%moduleName, 1);
+      %success = AssetDatabase.addDeclaredAsset(%moduleDef, %tamlpath);
+      
+      if(!%success)
+         return false;
+   }*/
+   
+   return true;
+}
+
+function T3Dpre4ProjectImporter::processAudioProfileObject(%this, %file, %objectName)
+{
+   return %this.processSFXProfileObject(%file, %objectName);
+}
 
 //==============================================================================
 // Misc Utility functions

+ 108 - 7
Templates/BaseGame/game/tools/projectImporter/scripts/projectImporter.tscript

@@ -416,7 +416,7 @@ function sanitizeFilename(%file)
    %sanitizedName = sanitizeString(%targetName);
    if(startsWith(%sanitizedName, "_"))
    {
-      %sanitizedName = substr(%sanitizedName, 1, -1);
+      %sanitizedName = getSubStr(%sanitizedName, 1, -1);
    }
    if(%sanitizedName !$= %targetName)
    {
@@ -472,6 +472,12 @@ function testFilenameExtensions(%filename)
       return %filename @ ".dae";
    else if(isFile(%filename @ ".dds"))
       return %filename @ ".dds";
+   else if(isFile(%filename @ ".ogg"))
+      return %filename @ ".ogg";
+   else if(isFile(%filename @ ".wav"))
+      return %filename @ ".wav";
+   else if(isFile(%filename @ ".mp3"))
+      return %filename @ ".dds";
       
    return %filename;
 }
@@ -659,11 +665,14 @@ function findObjectName(%line, %createWord)
    return %objectName; 
 }
 
-function findObjectField(%fieldName)
+function findObjectField(%fieldName, %fileObj)
 {
+   if(%fileObj $= "")
+      %fileObj = $ProjectImporter::fileObject;
+      
    %value = "";
    %peekLineOffset = 0;
-   %peekLine = $ProjectImporter::fileObject.peekLine(%peekLineOffset);
+   %peekLine = %fileObj.peekLine(%peekLineOffset);
    while(!strIsMatchExpr("*};*", %peekLine) && 
          !strIsMatchExpr("*singleton*(*)*", %peekLine) && 
          !strIsMatchExpr("*new*(*)*", %peekLine) && 
@@ -671,7 +680,7 @@ function findObjectField(%fieldName)
          !strIsMatchExpr("\n", %peekLine) && 
          !strIsMatchExpr("\r", %peekLine))
    {
-      if(strpos(%peekLine, %fieldName) != -1)
+      if(strpos(strlwr(%peekLine), strlwr(%fieldName)) != -1)
       {
          %value = "";
          %pos = strpos(%peekLine, "= \"");
@@ -682,8 +691,7 @@ function findObjectField(%fieldName)
            %value = getSubStr(%peekLine, %pos+3, %endPos-%pos-3);
            break;
          }
-         else
-         {
+         
             %pos = strpos(%peekLine, "=\"");
             if(%pos != -1)
             {
@@ -692,16 +700,109 @@ function findObjectField(%fieldName)
               %value = getSubStr(%peekLine, %pos+2, %endPos-%pos-2);
               break;
             }
+         
+         %pos = strpos(%peekLine, "= ");
+         if(%pos != -1)
+         {
+           %endPos = strpos(%peekLine, ";", %pos); 
+           
+           %value = getSubStr(%peekLine, %pos+2, %endPos-%pos-2);
+           break;
+         }
+
+         %pos = strpos(%peekLine, "=");
+         if(%pos != -1)
+         {
+           %endPos = strpos(%peekLine, ";", %pos); 
+           
+           %value = getSubStr(%peekLine, %pos+2, %endPos-%pos-2);
+           break;
          }  
       }
       
       %peekLineOffset++;
-      %peekLine = $ProjectImporter::fileObject.peekLine(%peekLineOffset);
+      %peekLine = %fileObj.peekLine(%peekLineOffset);
    }  
    
    return %value;
 }
 
+function findObjectInFiles(%objectName)
+{
+   //First, wipe out any files inside the folder first
+   %file = findFirstFileMultiExpr( "*.*", true);
+   
+   %fileObj = new FileObject();
+   
+   while( %file !$= "" )
+   {      
+      %filename = fileName(%file);
+      %fileBase = fileBase(%file);
+      %fileExt = fileExt(%file);
+      %filePath = filePath(%file);
+      
+      if ( %fileObj.openForRead( %file ) ) 
+      {
+         %lineNum = 0;
+         while ( !%fileObj.isEOF() ) 
+         {
+            %line = %fileObj.readLine();
+            %trimmedLine = trim(%line);
+            
+            if(strIsMatchExpr("*new*(*)*", %line) && strpos(%line, "::") == -1)
+            {
+               %className = findObjectClass(%line, "new");
+               if (%className $= "") continue;
+
+               %objName = findObjectName(%line, "new");
+               
+               if(%objectName $= %objName)
+               {
+                  return %fileObj;
+               }
+            }
+            else if(strIsMatchExpr("*datablock*(*)*", %line) && strpos(%line, "::") == -1)
+            {
+               %className = findObjectClass(%line, "datablock");
+               if (%className $= "") continue;
+
+               %objName = findObjectName(%line, "datablock");
+               
+               if(%objectName $= %objName)
+               {
+                  return %fileObj;
+               }
+            }
+            else if(strIsMatchExpr("*singleton*(*)*", %line) && strpos(%line, "::") == -1)
+            {
+               %className = findObjectClass(%line, "singleton");
+               if (%className $= "") continue;
+
+               %objName = findObjectName(%line, "singleton");
+               
+               if(%objectName $= %objName)
+               {
+                  return %fileObj;
+               }
+            }
+            
+            %lineNum++;
+         }
+         
+         %fileObj.close();
+      }
+      else
+      {
+         error("findObjectInFiles() - File not able to be opened: " @ %file);  
+      }
+      
+      %file = findNextFileMultiExpr( "*.*" );
+   }
+
+   %fileObj.delete();
+   
+   return "";
+}
 //==============================================================================
 //Shape Importing
 //==============================================================================