Merge pull request #755 from Areloch/MiscTerrainFixes

Misc Fixes for terrain material editing, creation and usage
This commit is contained in:
Brian Roberts 2022-03-31 19:42:56 -05:00 committed by GitHub
commit 798dd6ca6b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 611 additions and 1408 deletions

View file

@ -177,11 +177,6 @@ void TerrainMaterialAsset::initializeAsset()
return; return;
} }
if (mMatDefinitionName == StringTable->insert("DetailBlue"))
{
bool asdfsd = true;
}
if (size() != 0 && mScriptPath == StringTable->EmptyString()) if (size() != 0 && mScriptPath == StringTable->EmptyString())
{ {
mLoadedState = EmbeddedDefinition; mLoadedState = EmbeddedDefinition;
@ -267,18 +262,20 @@ void TerrainMaterialAsset::loadMaterial()
{ {
for (U32 i = 0; i < size(); i++) for (U32 i = 0; i < size(); i++)
{ {
mMaterialDefinition = dynamic_cast<TerrainMaterial*>(getObject(i)); TerrainMaterial* terrMat = dynamic_cast<TerrainMaterial*>(getObject(i));
if (mMaterialDefinition) if (terrMat)
{ {
mMaterialDefinition = terrMat;
mLoadedState = Ok; mLoadedState = Ok;
mMaterialDefinition->setInternalName(getAssetId()); mMaterialDefinition->setInternalName(getAssetId());
continue; continue;
} }
//Otherwise, check if it's our FX material //Otherwise, check if it's our FX material
mFXMaterialDefinition = dynamic_cast<Material*>(getObject(i)); Material* fxMat = dynamic_cast<Material*>(getObject(i));
if (mFXMaterialDefinition) if (fxMat)
{ {
mFXMaterialDefinition = fxMat;
//mMaterialDefinition->setInternalName(getAssetId()); //mMaterialDefinition->setInternalName(getAssetId());
mFXMaterialDefinition->reload(); mFXMaterialDefinition->reload();
continue; continue;
@ -286,6 +283,9 @@ void TerrainMaterialAsset::loadMaterial()
} }
} }
if(mLoadedState == Ok)
return;
} }
else if ((mLoadedState == ScriptLoaded || mLoadedState == DefinitionAlreadyExists) && mMatDefinitionName != StringTable->EmptyString()) else if ((mLoadedState == ScriptLoaded || mLoadedState == DefinitionAlreadyExists) && mMatDefinitionName != StringTable->EmptyString())
{ {
@ -460,6 +460,28 @@ DefineEngineMethod(TerrainMaterialAsset, getScriptPath, const char*, (), ,
{ {
return object->getScriptPath(); return object->getScriptPath();
} }
DefineEngineMethod(TerrainMaterialAsset, getMaterialDefinition, S32, (), ,
"Queries the Asset Database to see if any asset exists that is associated with the provided material name.\n"
"@return The AssetId of the associated asset, if any.")
{
SimObjectPtr<TerrainMaterial> mat = object->getMaterialDefinition();
if (mat.isValid())
return mat->getId();
else
return 0;
}
DefineEngineMethod(TerrainMaterialAsset, getFXMaterialDefinition, S32, (), ,
"Queries the Asset Database to see if any asset exists that is associated with the provided material name.\n"
"@return The AssetId of the associated asset, if any.")
{
SimObjectPtr<Material> mat = object->getFXMaterialDefinition();
if (mat.isValid())
return mat->getId();
else
return 0;
}
#endif #endif
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// GuiInspectorTypeAssetId // GuiInspectorTypeAssetId
@ -483,68 +505,36 @@ void GuiInspectorTypeTerrainMaterialAssetPtr::consoleInit()
GuiControl* GuiInspectorTypeTerrainMaterialAssetPtr::constructEditControl() GuiControl* GuiInspectorTypeTerrainMaterialAssetPtr::constructEditControl()
{ {
// Create base filename edit controls // Create base filename edit controls
mUseHeightOverride = true; GuiControl* retCtrl = Parent::constructEditControl();
mHeightOverride = 100; if (retCtrl == NULL)
return retCtrl;
mMatEdContainer = new GuiControl();
mMatEdContainer->registerObject();
addObject(mMatEdContainer);
// Create "Open in ShapeEditor" button
mMatPreviewButton = new GuiBitmapButtonCtrl();
const char* matAssetId = getData();
TerrainMaterialAsset* matAsset = AssetDatabase.acquireAsset< TerrainMaterialAsset>(matAssetId);
TerrainMaterial* materialDef = nullptr;
char bitmapName[512] = "ToolsModule:material_editor_n_image";
/*if (!Sim::findObject(matAsset->getMaterialDefinitionName(), materialDef))
{
Con::errorf("GuiInspectorTypeTerrainMaterialAssetPtr::constructEditControl() - unable to find material in asset");
}
else
{
mMatPreviewButton->setBitmap(materialDef->mDiffuseMapFilename[0]);
}*/
mMatPreviewButton->setPosition(0, 0);
mMatPreviewButton->setExtent(100,100);
// Change filespec // Change filespec
char szBuffer[512]; char szBuffer[512];
dSprintf(szBuffer, sizeof(szBuffer), "AssetBrowser.showDialog(\"TerrainMaterialAsset\", \"AssetBrowser.changeAsset\", %d, %s);", dSprintf(szBuffer, sizeof(szBuffer), "AssetBrowser.showDialog(\"TerrainMaterialAsset\", \"AssetBrowser.changeAsset\", %s, %s);",
mInspector->getIdString(), mCaption); mInspector->getIdString(), mCaption);
mMatPreviewButton->setField("Command", szBuffer); mBrowseButton->setField("Command", szBuffer);
mMatPreviewButton->setDataField(StringTable->insert("Profile"), NULL, "GuiButtonProfile"); setDataField(StringTable->insert("targetObject"), NULL, mInspector->getInspectObject()->getIdString());
mMatPreviewButton->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile");
mMatPreviewButton->setDataField(StringTable->insert("hovertime"), NULL, "1000");
StringBuilder strbld; // Create "Open in Editor" button
strbld.append(matAsset->getMaterialDefinitionName()); mEditButton = new GuiBitmapButtonCtrl();
strbld.append("\n");
strbld.append("Open this asset in the Material Editor");
mMatPreviewButton->setDataField(StringTable->insert("tooltip"), NULL, strbld.data()); dSprintf(szBuffer, sizeof(szBuffer), "AssetBrowser.editAsset(%d.getText());", retCtrl->getId());
mEditButton->setField("Command", szBuffer);
_registerEditControl(mMatPreviewButton); char bitmapName[512] = "ToolsModule:material_editor_n_image";
//mMatPreviewButton->registerObject(); mEditButton->setBitmap(StringTable->insert(bitmapName));
mMatEdContainer->addObject(mMatPreviewButton);
mMatAssetIdTxt = new GuiTextEditCtrl(); mEditButton->setDataField(StringTable->insert("Profile"), NULL, "GuiButtonProfile");
mMatAssetIdTxt->registerObject(); mEditButton->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile");
mMatAssetIdTxt->setActive(false); mEditButton->setDataField(StringTable->insert("hovertime"), NULL, "1000");
mEditButton->setDataField(StringTable->insert("tooltip"), NULL, "Open this asset in the Terrain Material Editor");
mMatAssetIdTxt->setText(matAssetId); mEditButton->registerObject();
addObject(mEditButton);
mMatAssetIdTxt->setBounds(100, 0, 150, 18); return retCtrl;
mMatEdContainer->addObject(mMatAssetIdTxt);
return mMatEdContainer;
} }
bool GuiInspectorTypeTerrainMaterialAssetPtr::updateRects() bool GuiInspectorTypeTerrainMaterialAssetPtr::updateRects()
@ -558,45 +548,21 @@ bool GuiInspectorTypeTerrainMaterialAssetPtr::updateRects()
mEditCtrlRect.set(fieldExtent.x - dividerPos + dividerMargin, 1, dividerPos - dividerMargin - 34, fieldExtent.y); mEditCtrlRect.set(fieldExtent.x - dividerPos + dividerMargin, 1, dividerPos - dividerMargin - 34, fieldExtent.y);
bool resized = mEdit->resize(mEditCtrlRect.point, mEditCtrlRect.extent); bool resized = mEdit->resize(mEditCtrlRect.point, mEditCtrlRect.extent);
if (mBrowseButton != NULL)
if (mMatEdContainer != nullptr)
{ {
mMatPreviewButton->resize(mEditCtrlRect.point, mEditCtrlRect.extent); mBrowseRect.set(fieldExtent.x - 32, 2, 14, fieldExtent.y - 4);
resized |= mBrowseButton->resize(mBrowseRect.point, mBrowseRect.extent);
} }
if (mMatPreviewButton != nullptr) if (mEditButton != NULL)
{ {
mMatPreviewButton->resize(Point2I::Zero, Point2I(100, 100)); RectI shapeEdRect(fieldExtent.x - 16, 2, 14, fieldExtent.y - 4);
} resized |= mEditButton->resize(shapeEdRect.point, shapeEdRect.extent);
if (mMatAssetIdTxt != nullptr)
{
mMatAssetIdTxt->resize(Point2I(100, 0), Point2I(mEditCtrlRect.extent.x - 100, 18));
} }
return resized; return resized;
} }
void GuiInspectorTypeTerrainMaterialAssetPtr::setMaterialAsset(String assetId)
{
mTargetObject->setDataField(mCaption, "", assetId);
//force a refresh
SimObject* obj = mInspector->getInspectObject();
mInspector->inspectObject(obj);
}
DefineEngineMethod(GuiInspectorTypeTerrainMaterialAssetPtr, setMaterialAsset, void, (String assetId), (""),
"Gets a particular shape animation asset for this shape.\n"
"@param animation asset index.\n"
"@return Shape Animation Asset.\n")
{
if (assetId == String::EmptyString)
return;
return object->setMaterialAsset(assetId);
}
IMPLEMENT_CONOBJECT(GuiInspectorTypeTerrainMaterialAssetId); IMPLEMENT_CONOBJECT(GuiInspectorTypeTerrainMaterialAssetId);
ConsoleDocClass(GuiInspectorTypeTerrainMaterialAssetId, ConsoleDocClass(GuiInspectorTypeTerrainMaterialAssetId,

View file

@ -94,6 +94,8 @@ public:
StringTableEntry getMaterialDefinitionName() { return mMatDefinitionName; } StringTableEntry getMaterialDefinitionName() { return mMatDefinitionName; }
SimObjectPtr<TerrainMaterial> getMaterialDefinition() { return mMaterialDefinition; } SimObjectPtr<TerrainMaterial> getMaterialDefinition() { return mMaterialDefinition; }
SimObjectPtr<Material> getFXMaterialDefinition() { return mFXMaterialDefinition; }
void setScriptFile(const char* pScriptFile); void setScriptFile(const char* pScriptFile);
inline StringTableEntry getScriptFile(void) const { return mScriptFile; }; inline StringTableEntry getScriptFile(void) const { return mScriptFile; };
@ -127,26 +129,23 @@ protected:
}; };
DefineConsoleType(TypeTerrainMaterialAssetPtr, TerrainMaterialAsset) DefineConsoleType(TypeTerrainMaterialAssetPtr, TerrainMaterialAsset)
DefineConsoleType(TypeMaterialAssetId, String) DefineConsoleType(TypeTerrainMaterialAssetId, String)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// TypeAssetId GuiInspectorField Class // TypeAssetId GuiInspectorField Class
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
class GuiInspectorTypeTerrainMaterialAssetPtr : public GuiInspectorField class GuiInspectorTypeTerrainMaterialAssetPtr : public GuiInspectorTypeFileName
{ {
typedef GuiInspectorField Parent; typedef GuiInspectorTypeFileName Parent;
public: public:
GuiControl* mMatEdContainer; GuiBitmapButtonCtrl* mEditButton;
GuiBitmapButtonCtrl *mMatPreviewButton;
GuiTextEditCtrl *mMatAssetIdTxt;
DECLARE_CONOBJECT(GuiInspectorTypeTerrainMaterialAssetPtr); DECLARE_CONOBJECT(GuiInspectorTypeTerrainMaterialAssetPtr);
static void consoleInit(); static void consoleInit();
virtual GuiControl* constructEditControl(); virtual GuiControl* constructEditControl();
virtual bool updateRects(); virtual bool updateRects();
void setMaterialAsset(String assetId);
}; };
class GuiInspectorTypeTerrainMaterialAssetId : public GuiInspectorTypeTerrainMaterialAssetPtr class GuiInspectorTypeTerrainMaterialAssetId : public GuiInspectorTypeTerrainMaterialAssetPtr
{ {

View file

@ -50,6 +50,7 @@
#include "renderInstance/renderDeferredMgr.h" #include "renderInstance/renderDeferredMgr.h"
#include "console/engineAPI.h" #include "console/engineAPI.h"
#include "T3D/assets/MaterialAsset.h" #include "T3D/assets/MaterialAsset.h"
#include "T3D/assets/TerrainMaterialAsset.h"
/// This is used for rendering ground cover billboards. /// This is used for rendering ground cover billboards.
GFXImplementVertexFormat( GCVertex ) GFXImplementVertexFormat( GCVertex )
@ -564,7 +565,7 @@ void GroundCover::initPersistFields()
addField("shapeFilename", TypeFilename, Offset(mShapeName, GroundCover), MAX_COVERTYPES, "The cover shape filename. [Optional]", AbstractClassRep::FIELD_HideInInspectors); addField("shapeFilename", TypeFilename, Offset(mShapeName, GroundCover), MAX_COVERTYPES, "The cover shape filename. [Optional]", AbstractClassRep::FIELD_HideInInspectors);
INITPERSISTFIELD_SHAPEASSET_ARRAY(Shape, MAX_COVERTYPES, GroundCover, "The cover shape. [Optional]"); INITPERSISTFIELD_SHAPEASSET_ARRAY(Shape, MAX_COVERTYPES, GroundCover, "The cover shape. [Optional]");
addField( "layer", TypeTerrainMaterialName, Offset( mLayer, GroundCover ), MAX_COVERTYPES, "Terrain material name to limit coverage to, or blank to not limit." ); addField( "layer", TypeTerrainMaterialAssetId, Offset( mLayer, GroundCover ), MAX_COVERTYPES, "Terrain material assetId to limit coverage to, or blank to not limit." );
addField( "invertLayer", TypeBool, Offset( mInvertLayer, GroundCover ), MAX_COVERTYPES, "Indicates that the terrain material index given in 'layer' is an exclusion mask." ); addField( "invertLayer", TypeBool, Offset( mInvertLayer, GroundCover ), MAX_COVERTYPES, "Indicates that the terrain material index given in 'layer' is an exclusion mask." );
@ -1178,6 +1179,7 @@ GroundCoverCell* GroundCover::_generateCell( const Point2I& index,
const bool typeIsShape = mShapeInstances[ type ] != NULL; const bool typeIsShape = mShapeInstances[ type ] != NULL;
const Box3F typeShapeBounds = typeIsShape ? mShapeInstances[ type ]->getShape()->mBounds : Box3F(); const Box3F typeShapeBounds = typeIsShape ? mShapeInstances[ type ]->getShape()->mBounds : Box3F();
const F32 typeWindScale = mWindScale[type]; const F32 typeWindScale = mWindScale[type];
StringTableEntry typeLayer = mLayer[type]; StringTableEntry typeLayer = mLayer[type];
const bool typeInvertLayer = mInvertLayer[type]; const bool typeInvertLayer = mInvertLayer[type];

View file

@ -312,7 +312,7 @@ protected:
/// The maximum world space elevation for placement. /// The maximum world space elevation for placement.
F32 mMaxElevation[MAX_COVERTYPES]; F32 mMaxElevation[MAX_COVERTYPES];
/// Terrain material name to limit coverage to, or /// Terrain material assetId to limit coverage to, or
/// left empty to cover entire terrain. /// left empty to cover entire terrain.
StringTableEntry mLayer[MAX_COVERTYPES]; StringTableEntry mLayer[MAX_COVERTYPES];

View file

@ -229,6 +229,9 @@ Material::Material()
dMemset(mEffectColor, 0, sizeof(mEffectColor)); dMemset(mEffectColor, 0, sizeof(mEffectColor));
mEffectColor[0] = LinearColorF::WHITE;
mEffectColor[1] = LinearColorF::WHITE;
mFootstepSoundId = -1; mImpactSoundId = -1; mFootstepSoundId = -1; mImpactSoundId = -1;
mImpactFXIndex = -1; mImpactFXIndex = -1;
INIT_ASSET(CustomFootstepSound); INIT_ASSET(CustomFootstepSound);

View file

@ -138,12 +138,18 @@ bool TerrainMaterial::onAdd()
// Make sure we have an internal name set. // Make sure we have an internal name set.
if (!mInternalName || !mInternalName[0]) if (!mInternalName || !mInternalName[0])
{
Con::warnf("TerrainMaterial::onAdd() - No internal name set!"); Con::warnf("TerrainMaterial::onAdd() - No internal name set!");
return false;
}
else else
{ {
SimObject *object = set->findObjectByInternalName( mInternalName ); SimObject *object = set->findObjectByInternalName( mInternalName );
if (object) if (object)
{
Con::warnf("TerrainMaterial::onAdd() - Internal name collision; '%s' already exists!", mInternalName); Con::warnf("TerrainMaterial::onAdd() - Internal name collision; '%s' already exists!", mInternalName);
return false;
}
} }
set->addObject( this ); set->addObject( this );

View file

@ -639,9 +639,18 @@ function AssetBrowser::loadDirectories( %this )
%dataItem = AssetBrowser-->filterTree.insertItem(AssetBrowser-->filterTree.modulesIdx, "data"); %dataItem = AssetBrowser-->filterTree.insertItem(AssetBrowser-->filterTree.modulesIdx, "data");
AssetBrowser-->filterTree.tagsIdx = AssetBrowser-->filterTree.insertItem(1, "Tags"); AssetBrowser-->filterTree.tagsIdx = AssetBrowser-->filterTree.insertItem(1, "Tags");
if(!%this.selectMode)
AssetBrowser-->filterTree.creatorIdx = AssetBrowser-->filterTree.insertItem(1, "Creator"); AssetBrowser-->filterTree.creatorIdx = AssetBrowser-->filterTree.insertItem(1, "Creator");
AssetBrowser-->filterTree.clearSelection();
if(%this.selectMode)
{
AssetBrowser-->filterTree.addSelection(AssetBrowser-->filterTree.collectionsIdx);
AssetBrowser-->filterTree.addSelection(AssetBrowser-->filterTree.creatorIdx);
AssetBrowser-->filterTree.hideSelection();
}
%this.dirHandler.loadFolders("data", %dataItem); %this.dirHandler.loadFolders("data", %dataItem);
%this.loadCollectionSets(); %this.loadCollectionSets();
@ -750,20 +759,6 @@ function AssetBrowser::loadDirectories( %this )
function AssetBrowser::updateSelection( %this, %asset, %moduleName ) function AssetBrowser::updateSelection( %this, %asset, %moduleName )
{ {
/*%isAssetBorder = 0;
eval("%isAssetBorder = isObject(AssetBrowser-->"@%asset@"Border);");
if( %isAssetBorder )
{
eval( "AssetBrowser-->"@%asset@"Border.setStateOn(1);");
}
%isAssetBorderPrevious = 0;
eval("%isAssetBorderPrevious = isObject(AssetBrowser-->"@%this.prevSelectedMaterialHL@"Border);");
if( %isAssetBorderPrevious )
{
eval( "AssetBrowser-->"@%this.prevSelectedMaterialHL@"Border.setStateOn(0);");
}*/
//If we had an existing selected assetDef, clear the reference //If we had an existing selected assetDef, clear the reference
if(isObject(AssetBrowser.selectedAssetDef)) if(isObject(AssetBrowser.selectedAssetDef))
AssetDatabase.releaseAsset(AssetBrowser.selectedAssetDef.getAssetId()); AssetDatabase.releaseAsset(AssetBrowser.selectedAssetDef.getAssetId());
@ -775,11 +770,13 @@ function AssetBrowser::updateSelection( %this, %asset, %moduleName )
if(strstr(%moduleName, "/") != -1) if(strstr(%moduleName, "/") != -1)
return; return;
//Otherwise, it's an asset so we'll select the definition while we're at it //Check if this is an actual assetId, or if it's just a programmatic reference
//like what we use for the creator entries
if(AssetDatabase.isDeclaredAsset(AssetBrowser.selectedAsset))
{
//Looks good, it's an asset so we'll select the definition while we're at it
AssetBrowser.selectedAssetDef = AssetDatabase.acquireAsset(AssetBrowser.selectedAsset); AssetBrowser.selectedAssetDef = AssetDatabase.acquireAsset(AssetBrowser.selectedAsset);
//AssetBrowser.selectedPreviewImagePath = %previewImagePath; }
//%this.prevSelectedMaterialHL = %asset;
} }
function AssetBrowser::loadCollectionSets(%this) function AssetBrowser::loadCollectionSets(%this)

View file

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

View file

@ -32,7 +32,7 @@ function AssetBrowser::createTerrainMaterialAsset(%this)
%fxMatDef = new Material("TerrainFX_" @ %assetName) %fxMatDef = new Material("TerrainFX_" @ %assetName)
{ {
mapTo = %assetName; mapTo = %moduleName @ ":" @ %assetName;
footstepSoundId = 0; footstepSoundId = 0;
terrainMaterials = "1"; terrainMaterials = "1";
ShowDust = "1"; ShowDust = "1";
@ -48,6 +48,10 @@ function AssetBrowser::createTerrainMaterialAsset(%this)
TamlWrite(%asset, %tamlpath); TamlWrite(%asset, %tamlpath);
//cleanup before proper init'ing
%matDef.delete();
%fxMatDef.delete();
%moduleDef = ModuleDatabase.findModule(%moduleName, 1); %moduleDef = ModuleDatabase.findModule(%moduleName, 1);
AssetDatabase.addDeclaredAsset(%moduleDef, %tamlpath); AssetDatabase.addDeclaredAsset(%moduleDef, %tamlpath);

View file

@ -85,7 +85,7 @@ function NewAssetModuleBtn::onClick(%this)
AssetBrowser_addModuleWindow.selectWindow(); AssetBrowser_addModuleWindow.selectWindow();
} }
function AssetBrowser::setupCreateNewAsset(%this, %assetType, %moduleName, %callback) function AssetBrowser::setupCreateNewAsset(%this, %assetType, %moduleName, %callback, %nameOverride)
{ {
Canvas.pushDialog(AssetBrowser_newAsset); Canvas.pushDialog(AssetBrowser_newAsset);
@ -106,8 +106,12 @@ function AssetBrowser::setupCreateNewAsset(%this, %assetType, %moduleName, %call
%this.newAssetSettings.assetType = %assetType; %this.newAssetSettings.assetType = %assetType;
%this.newAssetSettings.moduleName = %moduleName; %this.newAssetSettings.moduleName = %moduleName;
%newAssetName = "New" @ %shortAssetTypeName;
if(%nameOverride !$= "")
%newAssetName = %nameOverride;
NewAssetPropertiesInspector.startGroup("General"); NewAssetPropertiesInspector.startGroup("General");
NewAssetPropertiesInspector.addField("assetName", "New Asset Name", "String", "Name of the new asset", "New" @ %shortAssetTypeName, "", %this.newAssetSettings); NewAssetPropertiesInspector.addField("assetName", "New Asset Name", "String", "Name of the new asset", %newAssetName, "", %this.newAssetSettings);
//NewAssetPropertiesInspector.addField("AssetType", "New Asset Type", "List", "Type of the new asset", %assetType, "Component,Image,Material,Shape,Sound,State Machine", %newAssetSettings); //NewAssetPropertiesInspector.addField("AssetType", "New Asset Type", "List", "Type of the new asset", %assetType, "Component,Image,Material,Shape,Sound,State Machine", %newAssetSettings);
//NewAssetPropertiesInspector.addField("friendlyName", "Friendly Name", "String", "Human-readable name of new asset", "", "", %this.newAssetSettings); //NewAssetPropertiesInspector.addField("friendlyName", "Friendly Name", "String", "Human-readable name of new asset", "", "", %this.newAssetSettings);

View file

@ -1963,7 +1963,24 @@ function MaterialEditorGui::save( %this )
MaterialEditorGui.copyMaterials( materialEd_previewMaterial, notDirtyMaterial ); MaterialEditorGui.copyMaterials( materialEd_previewMaterial, notDirtyMaterial );
%assetDef = AssetDatabase.acquireAsset(MaterialEditorGui.currentMaterialAsset); %assetDef = AssetDatabase.acquireAsset(MaterialEditorGui.currentMaterialAsset);
%assetDef.saveAsset(); //write it out %didEmbed = false;
%matScriptFile = %assetDef.getScriptPath();
if(%matScriptFile !$= "")
{
//lets up-convert to embedded
%assetDef.add(%assetDef.materialDefinitionName);
%assetDef.scriptFile = "";
%didEmbed = true;
}
//write it out
if(%assetDef.saveAsset())
{
if(%didEmbed)
{
fileDelete(%matScriptFile); //cleanup the old definition file
}
}
} }
else else
{ {

View file

@ -1203,7 +1203,7 @@ function T3Dpre4ProjectImporter::processTerrainMaterialObject(%this, %fileObject
{ {
%fxMatObj = getField(%fxMatList, %i); %fxMatObj = getField(%fxMatList, %i);
%fxMatObjMapTo = findObjectField(%fxMatObj, "mapTo"); %fxMatObjMapTo = findObjectField(%fxMatObj, "mapTo");
if(%fxMatObjMapTo $= %objectName) if(%fxMatObjMapTo $= %objectName || %fxMatObjMapTo $= %assetName)
{ {
%fileObject.FXMaterial = %fxMatObj; %fileObject.FXMaterial = %fxMatObj;
break; break;
@ -1215,7 +1215,7 @@ function T3Dpre4ProjectImporter::processTerrainMaterialObject(%this, %fileObject
if(%fileObject.FXMaterial !$= "") if(%fileObject.FXMaterial !$= "")
{ {
//Ensure our mapto is up to date for any name sanitize/tweaks //Ensure our mapto is up to date for any name sanitize/tweaks
setObjectField(%fileObject.FXMaterial, "mapTo", %objectName); setObjectField(%fileObject.FXMaterial, "mapTo", %moduleName @ ":" @ %assetName);
//we associated to an FX material, so process that now //we associated to an FX material, so process that now
%objectDefinition = ""; %objectDefinition = "";
@ -1244,6 +1244,15 @@ function T3Dpre4ProjectImporter::processTerrainMaterialObject(%this, %fileObject
%fileObject.FXMaterial.processed = true; %fileObject.FXMaterial.processed = true;
%fileObject.FXMaterial.skip = true; %fileObject.FXMaterial.skip = true;
} }
else
{
//if after all that we still have no FXMaterial, just create a new one
%fxMat = new Material("TerrainFX_" @ %objectName)
{
mapTo = %moduleName @ ":" @ %assetName;
};
%asset.add(%fxMat);
}
%success = false; %success = false;
if(TamlWrite(%asset, %tamlpath)) if(TamlWrite(%asset, %tamlpath))

View file

@ -109,6 +109,31 @@ function TerrainMaterialDlg::onWake( %this )
%item = %matLibTree.getFirstRootItem(); %item = %matLibTree.getFirstRootItem();
%matLibTree.expandItem( %item ); %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 ); %this.activateMaterialCtrls( true );
} }
@ -150,18 +175,8 @@ function TerrainMaterialDlg::dialogApply( %this )
%mat.delete(); %mat.delete();
} }
// Make sure we save any changes to the current selection.
%this.saveDirtyMaterial( %this.activeMat );
// Delete the snapshot. %this.prepSaveDirtyMaterial();
TerrainMaterialDlgSnapshot.delete();
// Remove ourselves from the canvas.
Canvas.popDialog( TerrainMaterialDlg );
call( %this.onApplyCallback, %this.activeMat, %this.matIndex );
TerrainMaterialDlg.matDirty = false;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -171,7 +186,7 @@ function TerrainMaterialDlg::dialogCancel( %this )
if(TerrainMaterialDlg.matDirty) if(TerrainMaterialDlg.matDirty)
{ {
toolsMessageBoxYesNo("Save Dirty Material?", "The current material has been modified. Do you wish save your changes?", 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 else
{ {
@ -380,7 +395,7 @@ function TerrainMaterialTreeCtrl::onSelect( %this, %item )
if(TerrainMaterialDlg.matDirty) if(TerrainMaterialDlg.matDirty)
{ {
toolsMessageBoxYesNo("Save Dirty Material?", "The current material has been modified. Do you wish save your changes?", 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 @ ");"); "TerrainMaterialDlg.setActiveMaterial(" @ %item @ ");");
} }
else else
@ -461,6 +476,32 @@ function TerrainMaterialDlg::setActiveMaterial( %this, %mat )
%this-->isSRGB.setValue( %mat.isSRGB ); %this-->isSRGB.setValue( %mat.isSRGB );
%this-->invertRoughness.setValue( %mat.invertRoughness ); %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 ); %this.activateMaterialCtrls( true );
} }
else else
@ -470,15 +511,133 @@ function TerrainMaterialDlg::setActiveMaterial( %this, %mat )
} }
} }
//----------------------------------------------------------------------------- function TerrainMaterialDlg::updateSoundPopup(%this, %type, %defaultId, %customName)
function TerrainMaterialDlg::saveDirtyMaterial( %this, %mat )
{ {
%ctrl = TerrainMaterialDlg.findObjectByInternalName( %type @ "SoundPopup", true );
switch (%defaultId)
{
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;
}
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))
{
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;
}
//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 = %material.internalName;
};
%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. // Skip over obviously bad cases.
if ( !isObject( %mat ) || if ( !isObject( %mat ) ||
!%mat.isMemberOfClass( TerrainMaterial ) ) !%mat.isMemberOfClass( TerrainMaterial ) )
return; return;
%this.activeMat = %mat;
// Read out properties from the dialog. // Read out properties from the dialog.
%newName = %this-->matNameCtrl.getText(); %newName = %this-->matNameCtrl.getText();
@ -487,28 +646,28 @@ function TerrainMaterialDlg::saveDirtyMaterial( %this, %mat )
//--- //---
%newDiffuse = %this-->texDiffuseMap.getBitmap(); %newDiffuse = %this-->diffuseMapAssetId.text;
if(%newDiffuse $= $TerrainMaterialEditor::emptyMaterialImage || %newDiffuse $= %blankBitmap) if(%newDiffuse $= "None")
%newDiffuse = ""; %newDiffuse = "";
//--- //---
%newNormal = %this-->texNormalMap.getBitmap(); %newNormal = %this-->normalMapAssetId.text;
if(%newNormal $= $TerrainMaterialEditor::emptyMaterialImage || %newNormal $= %blankBitmap) if(%newNormal $= "None")
%newNormal = ""; %newNormal = "";
//--- //---
%newormConfig = %this-->texORMConfigMap.getBitmap(); %newormConfig = %this-->ORMMapAssetId.text;
if(%newormConfig $= $TerrainMaterialEditor::emptyMaterialImage || %newormConfig $= %blankBitmap) if(%newormConfig $= "None")
%newormConfig = ""; %newormConfig = "";
//--- //---
%newDetail = %this-->texDetailMap.getBitmap(); %newDetail = %this-->detailMapAssetId.text;
if(%newDetail $= $TerrainMaterialEditor::emptyMaterialImage || %newDetail $= %blankBitmap) if(%newDetail $= "None")
%newDetail = ""; %newDetail = "";
//--- //---
%newMacro = %this-->texMacroMap.getBitmap(); %newMacro = %this-->macroMapAssetId.text;
if(%newMacro $= $TerrainMaterialEditor::emptyMaterialImage || %newMacro $= %blankBitmap) if(%newMacro $= "None")
%newMacro = ""; %newMacro = "";
%detailSize = %this-->detSizeCtrl.getText(); %detailSize = %this-->detSizeCtrl.getText();
@ -527,6 +686,17 @@ function TerrainMaterialDlg::saveDirtyMaterial( %this, %mat )
%isSRGB = %this-->isSRGB.getValue(); %isSRGB = %this-->isSRGB.getValue();
%invertRoughness = %this-->invertRoughness.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, // If no properties of this materials have changed,
// return. // return.
@ -548,7 +718,15 @@ function TerrainMaterialDlg::saveDirtyMaterial( %this, %mat )
%mat.blendHeightBase == %blendHeightBase && %mat.blendHeightBase == %blendHeightBase &&
%mat.blendHeightContrast == %blendHeightContrast && %mat.blendHeightContrast == %blendHeightContrast &&
%mat.isSRGB == %isSRGB && %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; return;
// Make sure the material name is unique. // Make sure the material name is unique.
@ -589,11 +767,54 @@ function TerrainMaterialDlg::saveDirtyMaterial( %this, %mat )
%mat.isSRGB = %isSRGB; %mat.isSRGB = %isSRGB;
%mat.invertRoughness = %invertRoughness; %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 //Save the material asset
%assetDef = AssetDatabase.acquireAsset(%mat.internalName); %didEmbed = false;
%assetDef.saveAsset(); %matScriptFile = %assetDef.getScriptPath();
if(%matScriptFile !$= "")
{
//lets up-convert to embedded
%assetDef.add(%mat);
%assetDef.add(%fxMat);
%assetDef.scriptFile = "";
%didEmbed = true;
} }
//write it out
if(%assetDef.saveAsset())
{
if(%didEmbed)
{
fileDelete(%matScriptFile); //cleanup the old definition file
}
}
%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 ) function TerrainMaterialDlg::snapshotMaterials( %this )