Adds cleanup of material and terrain material objects when creating a new asset of the respective type to avoid collisions when we immediately properly init the asset on creation

Reorganizes the terrainMaterialDlg to use a split container for better usability, fixed some minor layout issues, and added in FX material fields to be able to edit those directly via the terrain mat editor
Updated the terrainMaterialDlg save logic to better sequence the steps for saving to allow stable in-place creation of asset for stub materials due to missing references
Updated the terrainMaterialDlg save logic to properly save out all the material effects stuff like footstep flags, effect colors, or sounds.
This commit is contained in:
JeffR 2022-03-30 01:38:15 -05:00
parent 81aa43a4bd
commit 85bb4cbff3
4 changed files with 442 additions and 1286 deletions

View file

@ -21,6 +21,9 @@ function AssetBrowser::createMaterialAsset(%this)
TamlWrite(%asset, %tamlpath);
//cleanup before proper init'ing
%assetName.delete();
%moduleDef = ModuleDatabase.findModule(%moduleName, 1);
AssetDatabase.addDeclaredAsset(%moduleDef, %tamlpath);

View file

@ -48,6 +48,10 @@ function AssetBrowser::createTerrainMaterialAsset(%this)
TamlWrite(%asset, %tamlpath);
//cleanup before proper init'ing
%matDef.delete();
%fxMatDef.delete();
%moduleDef = ModuleDatabase.findModule(%moduleName, 1);
AssetDatabase.addDeclaredAsset(%moduleDef, %tamlpath);

View file

@ -109,6 +109,31 @@ function TerrainMaterialDlg::onWake( %this )
%item = %matLibTree.getFirstRootItem();
%matLibTree.expandItem( %item );
//Sounds
%this-->footstepSoundPopup.clear();
%this-->impactSoundPopup.clear();
%sounds = "<None>" TAB "<Soft>" TAB "<Hard>" TAB "<Metal>" TAB "<Snow>"; // Default sounds
%assetQuery = new AssetQuery();
AssetDatabase.findAssetType(%assetQuery, "SoundAsset");
%count = %assetQuery.getCount();
// Get custom sound assets
for(%i=0; %i < %count; %i++)
{
%assetId = %assetQuery.getAsset(%i);
%sounds = %sounds TAB %assetId;
}
%count = getFieldCount(%sounds);
for (%i = 0; %i < %count; %i++)
{
%name = getField(%sounds, %i);
%this-->footstepSoundPopup.add(%name);
%this-->impactSoundPopup.add(%name);
}
%this.activateMaterialCtrls( true );
}
@ -150,18 +175,8 @@ function TerrainMaterialDlg::dialogApply( %this )
%mat.delete();
}
// Make sure we save any changes to the current selection.
%this.saveDirtyMaterial( %this.activeMat );
// Delete the snapshot.
TerrainMaterialDlgSnapshot.delete();
// Remove ourselves from the canvas.
Canvas.popDialog( TerrainMaterialDlg );
call( %this.onApplyCallback, %this.activeMat, %this.matIndex );
TerrainMaterialDlg.matDirty = false;
%this.prepSaveDirtyMaterial();
}
//-----------------------------------------------------------------------------
@ -171,7 +186,7 @@ function TerrainMaterialDlg::dialogCancel( %this )
if(TerrainMaterialDlg.matDirty)
{
toolsMessageBoxYesNo("Save Dirty Material?", "The current material has been modified. Do you wish save your changes?",
"TerrainMaterialDlg.saveDirtyMaterial(" @ %this-->matLibTree.getSelectedItem() @ ");TerrainMaterialDlg.closeDialog();", "TerrainMaterialDlg.closeDialog();");
"TerrainMaterialDlg.prepSaveDirtyMaterial("@%this-->matLibTree.getSelectedItem()@");TerrainMaterialDlg.closeDialog();", "TerrainMaterialDlg.closeDialog();");
}
else
{
@ -380,13 +395,13 @@ function TerrainMaterialTreeCtrl::onSelect( %this, %item )
if(TerrainMaterialDlg.matDirty)
{
toolsMessageBoxYesNo("Save Dirty Material?", "The current material has been modified. Do you wish save your changes?",
"TerrainMaterialDlg.saveDirtyMaterial(" @ TerrainMaterialDlg.previousMat @ ");TerrainMaterialDlg.setActiveMaterial(" @ %item @ ");",
"TerrainMaterialDlg.prepSaveDirtyMaterial(" @ TerrainMaterialDlg.previousMat @ ");TerrainMaterialDlg.setActiveMaterial(" @ %item @ ");",
"TerrainMaterialDlg.setActiveMaterial(" @ %item @ ");");
}
else
{
TerrainMaterialDlg.setActiveMaterial( %item );
}
TerrainMaterialDlg.setActiveMaterial( %item );
}
}
//-----------------------------------------------------------------------------
@ -461,6 +476,32 @@ function TerrainMaterialDlg::setActiveMaterial( %this, %mat )
%this-->isSRGB.setValue( %mat.isSRGB );
%this-->invertRoughness.setValue( %mat.invertRoughness );
//FX material stuffs
if(AssetDatabase.isDeclaredAsset(%mat.internalName))
{
%asset = AssetDatabase.acquireAsset(%mat.internalName);
%fxMat = %asset.getFXMaterialDefinition();
if(isObject(%fxMat))
{
%this-->effectColor0Swatch.color = %fxMat.effectColor[0];
%this-->effectColor1Swatch.color = %fxMat.effectColor[1];
%this-->showFootprintsCheckbox.setValue(%fxMat.showFootprints);
%this-->showDustCheckbox.setValue(%fxMat.showDust);
%this.updateSoundPopup("Footstep", %fxMat.footstepSoundId, %fxMat.customFootstepSound);
%this.updateSoundPopup("Impact", %fxMat.impactSoundId, %fxMat.customImpactSound);
}
else
{
%this-->effectColor0Swatch.color = "1 1 1 1";
%this-->effectColor1Swatch.color = "1 1 1 1";
%this-->showFootprintsCheckbox.setValue(0);
%this-->showFootprintsCheckbox.setValue(0);
%this.updateSoundPopup("Footstep", 0, "");
%this.updateSoundPopup("Impact", 0, "");
}
}
%this.activateMaterialCtrls( true );
}
else
@ -470,40 +511,133 @@ function TerrainMaterialDlg::setActiveMaterial( %this, %mat )
}
}
//-----------------------------------------------------------------------------
function TerrainMaterialDlg::saveDirtyMaterial( %this, %mat )
function TerrainMaterialDlg::updateSoundPopup(%this, %type, %defaultId, %customName)
{
//If we happen to have been handed an assetId, process it
if(AssetDatabase.isDeclaredAsset(%mat))
%ctrl = TerrainMaterialDlg.findObjectByInternalName( %type @ "SoundPopup", true );
switch (%defaultId)
{
%assetDef = AssetDatabase.acquireAsset(%mat);
%mat = %assetDef.getMaterialDefinition();
case 0: %name = "<Soft>";
case 1: %name = "<Hard>";
case 2: %name = "<Metal>";
case 3: %name = "<Snow>";
default:
if (%customName $= "")
%name = "<None>";
else
%name = %customName;
}
%r = %ctrl.findText(%name);
if (%r != -1)
%ctrl.setSelected(%r, false);
else
%ctrl.setText(%name);
}
function TerrainMaterialDlg::getBehaviorSound(%this, %type, %sound)
{
%defaultId = -1;
%customName = "";
switch$ (%sound)
{
case "<Soft>": %defaultId = 0;
case "<Hard>": %defaultId = 1;
case "<Metal>": %defaultId = 2;
case "<Snow>": %defaultId = 3;
default: %customName = %sound;
}
// Skip over obviously bad cases.
if ( !isObject( %mat ) ||
!%mat.isMemberOfClass( TerrainMaterial ) )
return;
//Lets validate it wasn't a generated stub. if so, we need to add an intermediate
//step to create the asset
%assetDef = AssetDatabase.acquireAsset(%mat.internalName);
if(%assetDef $= "")
return %defaultId TAB %customName;
}
function TerrainMaterialDlg::updateEffectColor0(%this, %color)
{
%this-->effectColor0Swatch.color = %color;
}
function TerrainMaterialDlg::updateEffectColor1(%this, %color)
{
%this-->effectColor1Swatch.color = %color;
}
//-----------------------------------------------------------------------------
function TerrainMaterialDlg::prepSaveDirtyMaterial(%this, %material)
{
if(%material $= "")
%material = %this.activeMat;
if(!isObject(%material))
{
%moduleSplit = strpos(%mat.internalName, ":");
%moduleName = getSubStr(%mat.internalName, 0, %moduleSplit);
%assetName = getSubStr(%mat.internalName, %moduleSplit+1, -1);
error("TerrainMaterialDlg::prepSaveDirtyMaterial() - active material is not a valid object");
return;
}
if(!AssetDatabase.isDeclaredAsset(%material.internalName))
{
//No valid asset, so we probably generated it as a stub due to a leftover
//reference. Let's generate a new asset
%assetId = %material.internalName;
%moduleSplit = strpos(%material.internalName, ":");
%moduleName = getSubStr(%material.internalName, 0, %moduleSplit);
%assetName = getSubStr(%material.internalName, %moduleSplit+1, -1);
if(ModuleDatabase.findModule(%moduleName) !$= "")
{
AssetBrowser.selectedModule = %moduleName;
}
//we need to create an actual asset here
//Clear the stub
TerrainMaterialSet.remove(%material);
%material.delete();
%oldMat = TerrainMaterialSet.findObjectByInternalName( %assetId );
AssetBrowser.setupCreateNewAsset("TerrainMaterialAsset", AssetBrowser.selectedModule, "TerrainMaterialDlg.saveDirtyMaterial", %assetName);
}
else
{
%assetDef = AssetDatabase.acquireAsset(%material.internalName);
//If we somehow don't have an FX material, make one
%fxMat = %assetDef.getFXMaterialDefinition();
if(!isObject(%fxMat))
{
%fxMat = new Material("TerrainFX_" @ %assetDef.assetName){
mapTo = %assetDef.assetName;
};
%assetDef.add(%fxMat);
}
// Make sure we save any changes to the current selection.
%this.saveDirtyMaterial( %material.internalName );
}
}
function TerrainMaterialDlg::saveDirtyMaterial( %this, %materialAssetId )
{
%assetDef = "";
%mat = "";
//If we happen to have been handed an assetId, process it
if(AssetDatabase.isDeclaredAsset(%materialAssetId))
{
%assetDef = AssetDatabase.acquireAsset(%materialAssetId);
%mat = %assetDef.getMaterialDefinition();
}
else
{
error("TerrainMaterialDlg::saveDirtyMaterial() - attempting to save invalid assetId: " @ %materialAssetId);
return;
}
// Skip over obviously bad cases.
if ( !isObject( %mat ) ||
!%mat.isMemberOfClass( TerrainMaterial ) )
return;
%this.activeMat = %mat;
// Read out properties from the dialog.
%newName = %this-->matNameCtrl.getText();
@ -552,6 +686,17 @@ function TerrainMaterialDlg::saveDirtyMaterial( %this, %mat )
%isSRGB = %this-->isSRGB.getValue();
%invertRoughness = %this-->invertRoughness.getValue();
//Effects
%effectColor0 = %this-->effectColor0Swatch.color;
%effectColor1 = %this-->effectColor1Swatch.color;
%showFootsteps = %this-->showFootprintsCheckbox.getValue();
%showDust = %this-->showDustCheckbox.getValue();
%footstepSound = %this.getBehaviorSound("Footstep", %this-->footstepSoundPopup.getText());
%impactSound = %this.getBehaviorSound("Impact", %this-->impactSoundPopup.getText());
%fxMat = %assetDef.getFXMaterialDefinition();
// If no properties of this materials have changed,
// return.
@ -573,7 +718,15 @@ function TerrainMaterialDlg::saveDirtyMaterial( %this, %mat )
%mat.blendHeightBase == %blendHeightBase &&
%mat.blendHeightContrast == %blendHeightContrast &&
%mat.isSRGB == %isSRGB &&
%mat.invertRoughness == %invertRoughness && false)
%mat.invertRoughness == %invertRoughness &&
%fxMat.effectColor[0] == %effectColor0 &&
%fxMat.effectColor[1] == %effectColor1 &&
%fxMat.showFootprints == %showFootsteps &&
%fxMat.showDust == %showDust &&
%fxMat.footstepSoundId == getField(%footstepSound, 0) &&
%fxMat.customFootstepSound == getField(%footstepSound, 1) &&
%fxMat.impactSoundId == getField(%impactSound, 0) &&
%fxMat.customImpactSound == getField(%impactSound, 1) && false)
return;
// Make sure the material name is unique.
@ -614,11 +767,35 @@ function TerrainMaterialDlg::saveDirtyMaterial( %this, %mat )
%mat.isSRGB = %isSRGB;
%mat.invertRoughness = %invertRoughness;
//effects
%fxMat.effectColor[0] = %effectColor0;
%fxMat.effectColor[1] = %effectColor1;
%fxMat.showFootprints = %showFootsteps;
%fxMat.showDust = %showDust;
%fxMat.footstepSoundId = getField(%footstepSound, 0);
%fxMat.customFootstepSound = getField(%footstepSound, 1);
%fxMat.impactSoundId = getField(%impactSound, 0);
%fxMat.customImpactSound = getField(%impactSound, 1);
//Save the material asset
%assetDef = AssetDatabase.acquireAsset(%mat.internalName);
%assetDef.saveAsset();
%this.schedule(32, "cleanupDirtyMaterial");
}
function TerrainMaterialDlg::cleanupDirtyMaterial(%this)
{
// Delete the snapshot.
TerrainMaterialDlgSnapshot.delete();
// Remove ourselves from the canvas.
Canvas.popDialog( TerrainMaterialDlg );
call( %this.onApplyCallback, %this.activeMat, %this.matIndex );
TerrainMaterialDlg.matDirty = false;
//%this.setActiveMaterial(%this.activeMat);
}
//-----------------------------------------------------------------------------
function TerrainMaterialDlg::snapshotMaterials( %this )