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
This commit is contained in:
Areloch 2021-09-05 03:43:41 -05:00
parent df0f8dafa6
commit 0ca66b99db
7 changed files with 309 additions and 8 deletions

View file

@ -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,

View file

@ -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();

View file

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

View file

@ -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;

View file

@ -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);
}

View file

@ -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

View file

@ -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
//==============================================================================