mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-13 07:34:45 +00:00
Merge pull request #520 from Areloch/EngineAssetify
Engine Asset Update
This commit is contained in:
commit
06aef7cff3
1916 changed files with 24328 additions and 8119 deletions
|
|
@ -282,7 +282,7 @@ bool Scene::saveScene(StringTableEntry fileName)
|
||||||
dSprintf(depSlotName, sizeof(depSlotName), "%s%d", "staticObjectAssetDependency", i);
|
dSprintf(depSlotName, sizeof(depSlotName), "%s%d", "staticObjectAssetDependency", i);
|
||||||
|
|
||||||
char depValue[255];
|
char depValue[255];
|
||||||
dSprintf(depValue, sizeof(depValue), "@Asset=%s", utilizedAssetsList[i]);
|
dSprintf(depValue, sizeof(depValue), "%s=%s", ASSET_ID_SIGNATURE, utilizedAssetsList[i]);
|
||||||
|
|
||||||
levelAssetDef->setDataField(StringTable->insert(depSlotName), NULL, StringTable->insert(depValue));
|
levelAssetDef->setDataField(StringTable->insert(depSlotName), NULL, StringTable->insert(depValue));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -85,19 +85,20 @@ AccumulationVolume::AccumulationVolume()
|
||||||
mWorldToObj.identity();
|
mWorldToObj.identity();
|
||||||
|
|
||||||
// Accumulation Texture.
|
// Accumulation Texture.
|
||||||
mTextureName = "";
|
INIT_IMAGEASSET(Texture);
|
||||||
mAccuTexture = NULL;
|
|
||||||
|
|
||||||
resetWorldBox();
|
resetWorldBox();
|
||||||
}
|
}
|
||||||
|
|
||||||
AccumulationVolume::~AccumulationVolume()
|
AccumulationVolume::~AccumulationVolume()
|
||||||
{
|
{
|
||||||
mAccuTexture = NULL;
|
mTexture = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AccumulationVolume::initPersistFields()
|
void AccumulationVolume::initPersistFields()
|
||||||
{
|
{
|
||||||
|
addProtectedField("textureAsset", TypeImageAssetId, Offset(mTextureAssetId, AccumulationVolume),
|
||||||
|
&_setTexture, &defaultProtectedGetFn, "Accumulation texture.");
|
||||||
addProtectedField( "texture", TypeStringFilename, Offset( mTextureName, AccumulationVolume ),
|
addProtectedField( "texture", TypeStringFilename, Offset( mTextureName, AccumulationVolume ),
|
||||||
&_setTexture, &defaultProtectedGetFn, "Accumulation texture." );
|
&_setTexture, &defaultProtectedGetFn, "Accumulation texture." );
|
||||||
|
|
||||||
|
|
@ -235,7 +236,7 @@ U32 AccumulationVolume::packUpdate( NetConnection *connection, U32 mask, BitStre
|
||||||
|
|
||||||
if (stream->writeFlag(mask & InitialUpdateMask))
|
if (stream->writeFlag(mask & InitialUpdateMask))
|
||||||
{
|
{
|
||||||
stream->write( mTextureName );
|
PACK_IMAGEASSET(connection, Texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
return retMask;
|
return retMask;
|
||||||
|
|
@ -247,8 +248,8 @@ void AccumulationVolume::unpackUpdate( NetConnection *connection, BitStream *str
|
||||||
|
|
||||||
if (stream->readFlag())
|
if (stream->readFlag())
|
||||||
{
|
{
|
||||||
stream->read( &mTextureName );
|
UNPACK_IMAGEASSET(connection, Texture);
|
||||||
setTexture(mTextureName);
|
//setTexture(mTextureName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -262,13 +263,7 @@ void AccumulationVolume::inspectPostApply()
|
||||||
|
|
||||||
void AccumulationVolume::setTexture( const String& name )
|
void AccumulationVolume::setTexture( const String& name )
|
||||||
{
|
{
|
||||||
mTextureName = name;
|
_setTexture(StringTable->insert(name.c_str()));
|
||||||
if ( isClientObject() && mTextureName.isNotEmpty() )
|
|
||||||
{
|
|
||||||
mAccuTexture.set(mTextureName, &GFXStaticTextureSRGBProfile, "AccumulationVolume::mAccuTexture");
|
|
||||||
if ( mAccuTexture.isNull() )
|
|
||||||
Con::warnf( "AccumulationVolume::setTexture - Unable to load texture: %s", mTextureName.c_str() );
|
|
||||||
}
|
|
||||||
refreshVolumes();
|
refreshVolumes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -312,7 +307,7 @@ void AccumulationVolume::refreshVolumes()
|
||||||
if ( object.isNull() ) continue;
|
if ( object.isNull() ) continue;
|
||||||
|
|
||||||
if ( volume->containsPoint(object->getPosition()) )
|
if ( volume->containsPoint(object->getPosition()) )
|
||||||
object->mAccuTex = volume->mAccuTexture;
|
object->mAccuTex = volume->getTextureResource();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -346,6 +341,6 @@ void AccumulationVolume::updateObject(SceneObject* object)
|
||||||
if ( volume.isNull() ) continue;
|
if ( volume.isNull() ) continue;
|
||||||
|
|
||||||
if ( volume->containsPoint(object->getPosition()) )
|
if ( volume->containsPoint(object->getPosition()) )
|
||||||
object->mAccuTex = volume->mAccuTexture;
|
object->mAccuTex = volume->getTextureResource();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -58,15 +58,15 @@ class AccumulationVolume : public ScenePolyhedralSpace
|
||||||
|
|
||||||
mutable Vector< SceneObject* > mVolumeQueryList;
|
mutable Vector< SceneObject* > mVolumeQueryList;
|
||||||
|
|
||||||
// Name (path) of the accumulation texture.
|
|
||||||
String mTextureName;
|
|
||||||
|
|
||||||
// SceneSpace.
|
// SceneSpace.
|
||||||
virtual void _renderObject( ObjectRenderInst* ri, SceneRenderState* state, BaseMatInstance* overrideMat );
|
virtual void _renderObject( ObjectRenderInst* ri, SceneRenderState* state, BaseMatInstance* overrideMat );
|
||||||
|
|
||||||
public:
|
DECLARE_IMAGEASSET(AccumulationVolume, Texture, onTextureChanged, GFXStaticTextureSRGBProfile);
|
||||||
|
DECLARE_IMAGEASSET_NET_SETGET(AccumulationVolume, Texture, -1);
|
||||||
|
|
||||||
GFXTexHandle mAccuTexture;
|
void onTextureChanged() {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
AccumulationVolume();
|
AccumulationVolume();
|
||||||
~AccumulationVolume();
|
~AccumulationVolume();
|
||||||
|
|
|
||||||
|
|
@ -136,7 +136,7 @@ void CubemapAsset::initializeAsset()
|
||||||
{
|
{
|
||||||
mScriptFile = expandAssetFilePath(mScriptFile);
|
mScriptFile = expandAssetFilePath(mScriptFile);
|
||||||
|
|
||||||
if(Platform::isFile(mScriptFile))
|
if(Torque::FS::IsScriptFile(mScriptFile))
|
||||||
Con::executeFile(mScriptFile, false, false);
|
Con::executeFile(mScriptFile, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -144,7 +144,7 @@ void CubemapAsset::onAssetRefresh()
|
||||||
{
|
{
|
||||||
mScriptFile = expandAssetFilePath(mScriptFile);
|
mScriptFile = expandAssetFilePath(mScriptFile);
|
||||||
|
|
||||||
if (Platform::isFile(mScriptFile))
|
if (Torque::FS::IsScriptFile(mScriptFile))
|
||||||
Con::executeFile(mScriptFile, false, false);
|
Con::executeFile(mScriptFile, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -207,8 +207,8 @@ GuiControl* GuiInspectorTypeCubemapAssetPtr::constructEditControl()
|
||||||
dSprintf(szBuffer, sizeof(szBuffer), "CubemapEditor.openCubemapAsset(%d.getText());", retCtrl->getId());
|
dSprintf(szBuffer, sizeof(szBuffer), "CubemapEditor.openCubemapAsset(%d.getText());", retCtrl->getId());
|
||||||
mShapeEdButton->setField("Command", szBuffer);
|
mShapeEdButton->setField("Command", szBuffer);
|
||||||
|
|
||||||
char bitmapName[512] = "tools/worldEditor/images/toolbar/shape-editor";
|
char bitmapName[512] = "ToolsModule:shape_editor_n_image";
|
||||||
mShapeEdButton->setBitmap(bitmapName);
|
mShapeEdButton->setBitmap(StringTable->insert(bitmapName));
|
||||||
|
|
||||||
mShapeEdButton->setDataField(StringTable->insert("Profile"), NULL, "GuiButtonProfile");
|
mShapeEdButton->setDataField(StringTable->insert("Profile"), NULL, "GuiButtonProfile");
|
||||||
mShapeEdButton->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile");
|
mShapeEdButton->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile");
|
||||||
|
|
|
||||||
|
|
@ -47,14 +47,14 @@
|
||||||
|
|
||||||
IMPLEMENT_CONOBJECT(GUIAsset);
|
IMPLEMENT_CONOBJECT(GUIAsset);
|
||||||
|
|
||||||
ConsoleType(GUIAssetPtr, TypeGUIAssetPtr, String, ASSET_ID_FIELD_PREFIX)
|
ConsoleType(GUIAssetPtr, TypeGUIAssetPtr, const char*, ASSET_ID_FIELD_PREFIX)
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
ConsoleGetType(TypeGUIAssetPtr)
|
ConsoleGetType(TypeGUIAssetPtr)
|
||||||
{
|
{
|
||||||
// Fetch asset Id.
|
// Fetch asset Id.
|
||||||
return *((StringTableEntry*)dptr);
|
return *((const char**)(dptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
@ -67,11 +67,7 @@ ConsoleSetType(TypeGUIAssetPtr)
|
||||||
// Yes, so fetch field value.
|
// Yes, so fetch field value.
|
||||||
const char* pFieldValue = argv[0];
|
const char* pFieldValue = argv[0];
|
||||||
|
|
||||||
// Fetch asset Id.
|
*((const char**)dptr) = StringTable->insert(argv[0]);
|
||||||
StringTableEntry* assetId = (StringTableEntry*)(dptr);
|
|
||||||
|
|
||||||
// Update asset value.
|
|
||||||
*assetId = StringTable->insert(pFieldValue);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -123,12 +119,12 @@ void GUIAsset::initializeAsset()
|
||||||
{
|
{
|
||||||
mGUIPath = expandAssetFilePath(mGUIFile);
|
mGUIPath = expandAssetFilePath(mGUIFile);
|
||||||
|
|
||||||
if (Platform::isFile(mGUIPath))
|
if (Torque::FS::IsScriptFile(mGUIPath))
|
||||||
Con::executeFile(mGUIPath, false, false);
|
Con::executeFile(mGUIPath, false, false);
|
||||||
|
|
||||||
mScriptPath = expandAssetFilePath(mScriptFile);
|
mScriptPath = expandAssetFilePath(mScriptFile);
|
||||||
|
|
||||||
if (Platform::isFile(mScriptPath))
|
if (Torque::FS::IsScriptFile(mScriptPath))
|
||||||
Con::executeFile(mScriptPath, false, false);
|
Con::executeFile(mScriptPath, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -136,12 +132,12 @@ void GUIAsset::onAssetRefresh()
|
||||||
{
|
{
|
||||||
mGUIPath = expandAssetFilePath(mGUIFile);
|
mGUIPath = expandAssetFilePath(mGUIFile);
|
||||||
|
|
||||||
if (Platform::isFile(mGUIPath))
|
if (Torque::FS::IsScriptFile(mGUIPath))
|
||||||
Con::executeFile(mGUIPath, false, false);
|
Con::executeFile(mGUIPath, false, false);
|
||||||
|
|
||||||
mScriptPath = expandAssetFilePath(mScriptFile);
|
mScriptPath = expandAssetFilePath(mScriptFile);
|
||||||
|
|
||||||
if (Platform::isFile(mScriptPath))
|
if (Torque::FS::IsScriptFile(mScriptPath))
|
||||||
Con::executeFile(mScriptPath, false, false);
|
Con::executeFile(mScriptPath, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -183,6 +179,50 @@ void GUIAsset::setScriptFile(const char* pScriptFile)
|
||||||
refreshAsset();
|
refreshAsset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StringTableEntry GUIAsset::getAssetIdByGUIName(StringTableEntry guiName)
|
||||||
|
{
|
||||||
|
StringTableEntry assetId = StringTable->EmptyString();
|
||||||
|
|
||||||
|
AssetQuery* query = new AssetQuery();
|
||||||
|
U32 foundCount = AssetDatabase.findAssetType(query, "GUIAsset");
|
||||||
|
if (foundCount == 0)
|
||||||
|
{
|
||||||
|
//Didn't work, so have us fall back to a placeholder asset
|
||||||
|
assetId = StringTable->insert("Core_Rendering:noMaterial");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GuiControl* guiObject;
|
||||||
|
if (!Sim::findObject(guiName, guiObject))
|
||||||
|
return "";
|
||||||
|
|
||||||
|
StringTableEntry guiFile = guiObject->getFilename();
|
||||||
|
|
||||||
|
for (U32 i = 0; i < foundCount; i++)
|
||||||
|
{
|
||||||
|
GUIAsset* guiAsset = AssetDatabase.acquireAsset<GUIAsset>(query->mAssetList[i]);
|
||||||
|
if (guiAsset && guiAsset->getGUIPath() == guiFile)
|
||||||
|
{
|
||||||
|
assetId = guiAsset->getAssetId();
|
||||||
|
AssetDatabase.releaseAsset(query->mAssetList[i]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
AssetDatabase.releaseAsset(query->mAssetList[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return assetId;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef TORQUE_TOOLS
|
||||||
|
DefineEngineStaticMethod(GUIAsset, getAssetIdByGUIName, const char*, (const char* guiName), (""),
|
||||||
|
"Queries the Asset Database to see if any asset exists that is associated with the provided GUI Name.\n"
|
||||||
|
"@return The AssetId of the associated asset, if any.")
|
||||||
|
{
|
||||||
|
return GUIAsset::getAssetIdByGUIName(StringTable->insert(guiName));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// GuiInspectorTypeAssetId
|
// GuiInspectorTypeAssetId
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
@ -221,13 +261,13 @@ GuiControl* GuiInspectorTypeGUIAssetPtr::constructEditControl()
|
||||||
dSprintf(szBuffer, sizeof(szBuffer), "echo(\"Game Object Editor not implemented yet!\");", retCtrl->getId());
|
dSprintf(szBuffer, sizeof(szBuffer), "echo(\"Game Object Editor not implemented yet!\");", retCtrl->getId());
|
||||||
mSMEdButton->setField("Command", szBuffer);
|
mSMEdButton->setField("Command", szBuffer);
|
||||||
|
|
||||||
char bitmapName[512] = "tools/worldEditor/images/toolbar/shape-editor";
|
char bitmapName[512] = "ToolsModule:GameTSCtrl_image";
|
||||||
mSMEdButton->setBitmap(bitmapName);
|
mSMEdButton->setBitmap(StringTable->insert(bitmapName));
|
||||||
|
|
||||||
mSMEdButton->setDataField(StringTable->insert("Profile"), NULL, "GuiButtonProfile");
|
mSMEdButton->setDataField(StringTable->insert("Profile"), NULL, "GuiButtonProfile");
|
||||||
mSMEdButton->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile");
|
mSMEdButton->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile");
|
||||||
mSMEdButton->setDataField(StringTable->insert("hovertime"), NULL, "1000");
|
mSMEdButton->setDataField(StringTable->insert("hovertime"), NULL, "1000");
|
||||||
mSMEdButton->setDataField(StringTable->insert("tooltip"), NULL, "Open this file in the State Machine Editor");
|
mSMEdButton->setDataField(StringTable->insert("tooltip"), NULL, "Open this file in the GUI Editor");
|
||||||
|
|
||||||
mSMEdButton->registerObject();
|
mSMEdButton->registerObject();
|
||||||
addObject(mSMEdButton);
|
addObject(mSMEdButton);
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,8 @@ public:
|
||||||
static void initPersistFields();
|
static void initPersistFields();
|
||||||
virtual void copyTo(SimObject* object);
|
virtual void copyTo(SimObject* object);
|
||||||
|
|
||||||
|
static StringTableEntry getAssetIdByGUIName(StringTableEntry guiName);
|
||||||
|
|
||||||
/// Declare Console Object.
|
/// Declare Console Object.
|
||||||
DECLARE_CONOBJECT(GUIAsset);
|
DECLARE_CONOBJECT(GUIAsset);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -133,7 +133,7 @@ void GameObjectAsset::initializeAsset()
|
||||||
//Ensure we have an expanded filepath
|
//Ensure we have an expanded filepath
|
||||||
mScriptPath = getOwned() ? expandAssetFilePath(mScriptFile) : mScriptPath;
|
mScriptPath = getOwned() ? expandAssetFilePath(mScriptFile) : mScriptPath;
|
||||||
|
|
||||||
if (Platform::isFile(mScriptPath))
|
if (Torque::FS::IsScriptFile(mScriptPath))
|
||||||
Con::executeFile(mScriptPath, false, false);
|
Con::executeFile(mScriptPath, false, false);
|
||||||
|
|
||||||
mTAMLPath = getOwned() ? expandAssetFilePath(mTAMLFile) : mTAMLPath;
|
mTAMLPath = getOwned() ? expandAssetFilePath(mTAMLFile) : mTAMLPath;
|
||||||
|
|
@ -144,7 +144,7 @@ void GameObjectAsset::onAssetRefresh()
|
||||||
//Ensure we have an expanded filepath
|
//Ensure we have an expanded filepath
|
||||||
mScriptPath = getOwned() ? expandAssetFilePath(mScriptFile) : mScriptPath;
|
mScriptPath = getOwned() ? expandAssetFilePath(mScriptFile) : mScriptPath;
|
||||||
|
|
||||||
if (Platform::isFile(mScriptPath))
|
if (Torque::FS::IsScriptFile(mScriptPath))
|
||||||
Con::executeFile(mScriptPath, false, false);
|
Con::executeFile(mScriptPath, false, false);
|
||||||
|
|
||||||
mTAMLPath = getOwned() ? expandAssetFilePath(mTAMLFile) : mTAMLPath;
|
mTAMLPath = getOwned() ? expandAssetFilePath(mTAMLFile) : mTAMLPath;
|
||||||
|
|
@ -192,7 +192,7 @@ void GameObjectAsset::setTAMLFile(const char* pTAMLFile)
|
||||||
|
|
||||||
const char* GameObjectAsset::create()
|
const char* GameObjectAsset::create()
|
||||||
{
|
{
|
||||||
if (!Platform::isFile(mTAMLFile))
|
if (!Torque::FS::IsFile(mTAMLFile))
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
// Set the format mode.
|
// Set the format mode.
|
||||||
|
|
|
||||||
|
|
@ -42,23 +42,30 @@
|
||||||
|
|
||||||
#include "gfx/gfxStringEnumTranslate.h"
|
#include "gfx/gfxStringEnumTranslate.h"
|
||||||
|
|
||||||
|
#include "ImageAssetInspectors.h"
|
||||||
|
|
||||||
// Debug Profiling.
|
// Debug Profiling.
|
||||||
#include "platform/profiler.h"
|
#include "platform/profiler.h"
|
||||||
|
|
||||||
#include "T3D/assets/assetImporter.h"
|
#include "T3D/assets/assetImporter.h"
|
||||||
|
#include "gfx/gfxDrawUtil.h"
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
StringTableEntry ImageAsset::smNoImageAssetFallback(StringTable->insert(Con::getVariable("$Core::NoImageAssetFallback")));
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
IMPLEMENT_CONOBJECT(ImageAsset);
|
IMPLEMENT_CONOBJECT(ImageAsset);
|
||||||
|
|
||||||
ConsoleType(ImageAssetPtr, TypeImageAssetPtr, String, ASSET_ID_FIELD_PREFIX)
|
ConsoleType(ImageAssetPtr, TypeImageAssetPtr, const char*, ASSET_ID_FIELD_PREFIX)
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
ConsoleGetType(TypeImageAssetPtr)
|
ConsoleGetType(TypeImageAssetPtr)
|
||||||
{
|
{
|
||||||
// Fetch asset Id.
|
// Fetch asset Id.
|
||||||
return *((StringTableEntry*)dptr);
|
return *((const char**)(dptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
@ -69,13 +76,7 @@ ConsoleSetType(TypeImageAssetPtr)
|
||||||
if (argc == 1)
|
if (argc == 1)
|
||||||
{
|
{
|
||||||
// Yes, so fetch field value.
|
// Yes, so fetch field value.
|
||||||
const char* pFieldValue = argv[0];
|
*((const char**)dptr) = StringTable->insert(argv[0]);
|
||||||
|
|
||||||
// Fetch asset Id.
|
|
||||||
StringTableEntry* assetId = (StringTableEntry*)(dptr);
|
|
||||||
|
|
||||||
// Update asset value.
|
|
||||||
*assetId = StringTable->insert(pFieldValue);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -84,7 +85,7 @@ ConsoleSetType(TypeImageAssetPtr)
|
||||||
Con::warnf("(TypeImageAssetPtr) - Cannot set multiple args to a single asset.");
|
Con::warnf("(TypeImageAssetPtr) - Cannot set multiple args to a single asset.");
|
||||||
}
|
}
|
||||||
|
|
||||||
ConsoleType(assetIdString, TypeImageAssetId, String, ASSET_ID_FIELD_PREFIX)
|
ConsoleType(assetIdString, TypeImageAssetId, const char*, ASSET_ID_FIELD_PREFIX)
|
||||||
|
|
||||||
ConsoleGetType(TypeImageAssetId)
|
ConsoleGetType(TypeImageAssetId)
|
||||||
{
|
{
|
||||||
|
|
@ -97,14 +98,7 @@ ConsoleSetType(TypeImageAssetId)
|
||||||
// Was a single argument specified?
|
// Was a single argument specified?
|
||||||
if (argc == 1)
|
if (argc == 1)
|
||||||
{
|
{
|
||||||
// Yes, so fetch field value.
|
*((const char**)dptr) = StringTable->insert(argv[0]);
|
||||||
const char* pFieldValue = argv[0];
|
|
||||||
|
|
||||||
// Fetch asset Id.
|
|
||||||
StringTableEntry* assetId = (StringTableEntry*)(dptr);
|
|
||||||
|
|
||||||
// Update asset value.
|
|
||||||
*assetId = StringTable->insert(pFieldValue);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -117,26 +111,27 @@ ConsoleSetType(TypeImageAssetId)
|
||||||
ImplementEnumType(ImageAssetType,
|
ImplementEnumType(ImageAssetType,
|
||||||
"Type of mesh data available in a shape.\n"
|
"Type of mesh data available in a shape.\n"
|
||||||
"@ingroup gameObjects")
|
"@ingroup gameObjects")
|
||||||
{ ImageAsset::Albedo, "Albedo", "" },
|
{ ImageAsset::Albedo, "Albedo", "" },
|
||||||
{ ImageAsset::Normal, "Normal", "" },
|
{ ImageAsset::Normal, "Normal", "" },
|
||||||
{ ImageAsset::ORMConfig, "ORMConfig", "" },
|
{ ImageAsset::ORMConfig, "ORMConfig", "" },
|
||||||
{ ImageAsset::GUI, "GUI", "" },
|
{ ImageAsset::GUI, "GUI", "" },
|
||||||
{ ImageAsset::Roughness, "Roughness", "" },
|
{ ImageAsset::Roughness, "Roughness", "" },
|
||||||
{ ImageAsset::AO, "AO", "" },
|
{ ImageAsset::AO, "AO", "" },
|
||||||
{ ImageAsset::Metalness, "Metalness", "" },
|
{ ImageAsset::Metalness, "Metalness", "" },
|
||||||
{ ImageAsset::Glow, "Glow", "" },
|
{ ImageAsset::Glow, "Glow", "" },
|
||||||
{ ImageAsset::Particle, "Particle", "" },
|
{ ImageAsset::Particle, "Particle", "" },
|
||||||
{ ImageAsset::Decal, "Decal", "" },
|
{ ImageAsset::Decal, "Decal", "" },
|
||||||
{ ImageAsset::Cubemap, "Cubemap", "" },
|
{ ImageAsset::Cubemap, "Cubemap", "" },
|
||||||
|
|
||||||
EndImplementEnumType;
|
EndImplementEnumType;
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
ImageAsset::ImageAsset() : AssetBase(), mImage(nullptr), mUseMips(true), mIsHDRImage(false), mIsValidImage(false), mImageType(Albedo)
|
ImageAsset::ImageAsset() : AssetBase(), mUseMips(true), mIsHDRImage(false), mIsValidImage(false), mImageType(Albedo)
|
||||||
{
|
{
|
||||||
mImageFileName = StringTable->EmptyString();
|
mImageFileName = StringTable->EmptyString();
|
||||||
mImagePath = StringTable->EmptyString();
|
mImagePath = StringTable->EmptyString();
|
||||||
|
mLoadedState = AssetErrCode::NotLoaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
@ -145,6 +140,15 @@ ImageAsset::~ImageAsset()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ImageAsset::consoleInit()
|
||||||
|
{
|
||||||
|
Parent::consoleInit();
|
||||||
|
Con::addVariable("$Core::NoImageAssetFallback", TypeString, &smNoImageAssetFallback,
|
||||||
|
"The assetId of the texture to display when the requested image asset is missing.\n"
|
||||||
|
"@ingroup GFX\n");
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
void ImageAsset::initPersistFields()
|
void ImageAsset::initPersistFields()
|
||||||
|
|
@ -163,85 +167,52 @@ void ImageAsset::initPersistFields()
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
//Utility function to 'fill out' bindings and resources with a matching asset if one exists
|
//Utility function to 'fill out' bindings and resources with a matching asset if one exists
|
||||||
bool ImageAsset::getAssetByFilename(StringTableEntry fileName, AssetPtr<ImageAsset>* imageAsset)
|
U32 ImageAsset::getAssetByFilename(StringTableEntry fileName, AssetPtr<ImageAsset>* imageAsset)
|
||||||
{
|
{
|
||||||
AssetQuery query;
|
AssetQuery query;
|
||||||
S32 foundAssetcount = AssetDatabase.findAssetLooseFile(&query, fileName);
|
S32 foundAssetcount = AssetDatabase.findAssetLooseFile(&query, fileName);
|
||||||
if (foundAssetcount == 0)
|
if (foundAssetcount == 0)
|
||||||
{
|
{
|
||||||
//Didn't find any assets
|
|
||||||
//If possible, see if we can run an in-place import and the get the asset from that
|
|
||||||
#if TORQUE_DEBUG
|
|
||||||
Con::warnf("ImageAsset::getAssetByFilename - Attempted to in-place import a image file(%s) that had no associated asset", fileName);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
AssetImporter* autoAssetImporter;
|
|
||||||
if (!Sim::findObject("autoAssetImporter", autoAssetImporter))
|
|
||||||
{
|
|
||||||
autoAssetImporter = new AssetImporter();
|
|
||||||
autoAssetImporter->registerObject("autoAssetImporter");
|
|
||||||
}
|
|
||||||
|
|
||||||
StringTableEntry resultingAssetId = autoAssetImporter->autoImportFile(fileName);
|
|
||||||
|
|
||||||
if (resultingAssetId != StringTable->EmptyString())
|
|
||||||
{
|
|
||||||
imageAsset->setAssetId(resultingAssetId);
|
|
||||||
|
|
||||||
if (!imageAsset->isNull())
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Didn't work, so have us fall back to a placeholder asset
|
//Didn't work, so have us fall back to a placeholder asset
|
||||||
imageAsset->setAssetId(StringTable->insert("Core_Rendering:noImage"));
|
imageAsset->setAssetId(ImageAsset::smNoImageAssetFallback);
|
||||||
|
|
||||||
if (!imageAsset->isNull())
|
if (imageAsset->isNull())
|
||||||
return true;
|
{
|
||||||
|
//Well that's bad, loading the fallback failed.
|
||||||
|
Con::warnf("ImageAsset::getAssetByFilename - Finding of asset associated with file %s failed with no fallback asset", fileName);
|
||||||
|
return AssetErrCode::Failed;
|
||||||
|
}
|
||||||
|
|
||||||
//That didn't work, so fail out
|
//handle noshape not being loaded itself
|
||||||
return false;
|
if ((*imageAsset)->mLoadedState == BadFileReference)
|
||||||
|
{
|
||||||
|
Con::warnf("ImageAsset::getAssetByFilename - Finding of associated with file %s failed, and fallback asset reported error of Bad File Reference.", fileName);
|
||||||
|
return AssetErrCode::BadFileReference;
|
||||||
|
}
|
||||||
|
|
||||||
|
Con::warnf("ImageAsset::getAssetByFilename - Finding of associated with file %s failed, utilizing fallback asset", fileName);
|
||||||
|
|
||||||
|
(*imageAsset)->mLoadedState = AssetErrCode::UsingFallback;
|
||||||
|
return AssetErrCode::UsingFallback;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//acquire and bind the asset, and return it out
|
//acquire and bind the asset, and return it out
|
||||||
imageAsset->setAssetId(query.mAssetList[0]);
|
imageAsset->setAssetId(query.mAssetList[0]);
|
||||||
return true;
|
return (*imageAsset)->mLoadedState;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StringTableEntry ImageAsset::getAssetIdByFilename(StringTableEntry fileName)
|
StringTableEntry ImageAsset::getAssetIdByFilename(StringTableEntry fileName)
|
||||||
{
|
{
|
||||||
StringTableEntry imageAssetId = StringTable->EmptyString();
|
if (fileName == StringTable->EmptyString())
|
||||||
|
return StringTable->EmptyString();
|
||||||
|
|
||||||
|
StringTableEntry imageAssetId = ImageAsset::smNoImageAssetFallback;
|
||||||
|
|
||||||
AssetQuery query;
|
AssetQuery query;
|
||||||
S32 foundAssetcount = AssetDatabase.findAssetLooseFile(&query, fileName);
|
S32 foundAssetcount = AssetDatabase.findAssetLooseFile(&query, fileName);
|
||||||
if (foundAssetcount == 0)
|
if (foundAssetcount != 0)
|
||||||
{
|
|
||||||
//Didn't find any assets
|
|
||||||
//If possible, see if we can run an in-place import and the get the asset from that
|
|
||||||
#if TORQUE_DEBUG
|
|
||||||
Con::warnf("ImageAsset::getAssetByFilename - Attempted to in-place import a image file(%s) that had no associated asset", fileName);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
AssetImporter* autoAssetImporter;
|
|
||||||
if (!Sim::findObject("autoAssetImporter", autoAssetImporter))
|
|
||||||
{
|
|
||||||
autoAssetImporter = new AssetImporter();
|
|
||||||
autoAssetImporter->registerObject("autoAssetImporter");
|
|
||||||
}
|
|
||||||
|
|
||||||
StringTableEntry resultingAssetId = autoAssetImporter->autoImportFile(fileName);
|
|
||||||
|
|
||||||
if (resultingAssetId != StringTable->EmptyString())
|
|
||||||
{
|
|
||||||
imageAssetId = resultingAssetId;
|
|
||||||
return imageAssetId;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Didn't work, so have us fall back to a placeholder asset
|
|
||||||
imageAssetId = StringTable->insert("Core_Rendering:noImage");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
//acquire and bind the asset, and return it out
|
//acquire and bind the asset, and return it out
|
||||||
imageAssetId = query.mAssetList[0];
|
imageAssetId = query.mAssetList[0];
|
||||||
|
|
@ -250,22 +221,37 @@ StringTableEntry ImageAsset::getAssetIdByFilename(StringTableEntry fileName)
|
||||||
return imageAssetId;
|
return imageAssetId;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImageAsset::getAssetById(StringTableEntry assetId, AssetPtr<ImageAsset>* imageAsset)
|
U32 ImageAsset::getAssetById(StringTableEntry assetId, AssetPtr<ImageAsset>* imageAsset)
|
||||||
{
|
{
|
||||||
(*imageAsset) = assetId;
|
(*imageAsset) = assetId;
|
||||||
|
|
||||||
if (!imageAsset->isNull())
|
if (imageAsset->notNull())
|
||||||
return true;
|
{
|
||||||
|
return (*imageAsset)->mLoadedState;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (imageAsset->isNull())
|
||||||
|
{
|
||||||
|
//Well that's bad, loading the fallback failed.
|
||||||
|
Con::warnf("ImageAsset::getAssetById - Finding of asset with id %s failed with no fallback asset", assetId);
|
||||||
|
return AssetErrCode::Failed;
|
||||||
|
}
|
||||||
|
|
||||||
//Didn't work, so have us fall back to a placeholder asset
|
//handle noshape not being loaded itself
|
||||||
StringTableEntry noImageId = StringTable->insert("Core_Rendering:noMaterial");
|
if ((*imageAsset)->mLoadedState == BadFileReference)
|
||||||
imageAsset->setAssetId(noImageId);
|
{
|
||||||
|
Con::warnf("ImageAsset::getAssetById - Finding of asset with id %s failed, and fallback asset reported error of Bad File Reference.", assetId);
|
||||||
|
return AssetErrCode::BadFileReference;
|
||||||
|
}
|
||||||
|
|
||||||
if (!imageAsset->isNull())
|
Con::warnf("ImageAsset::getAssetById - Finding of asset with id %s failed, utilizing fallback asset", assetId);
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
(*imageAsset)->mLoadedState = AssetErrCode::UsingFallback;
|
||||||
|
return AssetErrCode::UsingFallback;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
void ImageAsset::copyTo(SimObject* object)
|
void ImageAsset::copyTo(SimObject* object)
|
||||||
{
|
{
|
||||||
|
|
@ -275,32 +261,49 @@ void ImageAsset::copyTo(SimObject* object)
|
||||||
|
|
||||||
void ImageAsset::loadImage()
|
void ImageAsset::loadImage()
|
||||||
{
|
{
|
||||||
SAFE_DELETE(mImage);
|
|
||||||
|
|
||||||
if (mImagePath)
|
if (mImagePath)
|
||||||
{
|
{
|
||||||
if (!Platform::isFile(mImagePath))
|
if (!Torque::FS::IsFile(mImagePath))
|
||||||
{
|
{
|
||||||
Con::errorf("ImageAsset::initializeAsset: Attempted to load file %s but it was not valid!", mImageFileName);
|
Con::errorf("ImageAsset::initializeAsset: Attempted to load file %s but it was not valid!", mImageFileName);
|
||||||
|
mLoadedState = BadFileReference;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mImage.set(mImagePath, &GFXStaticTextureSRGBProfile, avar("%s() - mImage (line %d)", __FUNCTION__, __LINE__));
|
mLoadedState = Ok;
|
||||||
|
mIsValidImage = true;
|
||||||
|
return;
|
||||||
|
|
||||||
if (mImage)
|
//GFXTexHandle texture = getTexture(&GFXStaticTextureSRGBProfile);
|
||||||
|
|
||||||
|
//mTexture.set(mImagePath, &GFXStaticTextureSRGBProfile, avar("%s() - mImage (line %d)", __FUNCTION__, __LINE__));
|
||||||
|
|
||||||
|
/*if (texture.isValid())
|
||||||
{
|
{
|
||||||
mIsValidImage = true;
|
mIsValidImage = true;
|
||||||
|
|
||||||
|
//mBitmap = texture.getBitmap();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
|
mChangeSignal.trigger();
|
||||||
}
|
}
|
||||||
|
mLoadedState = BadFileReference;
|
||||||
|
|
||||||
mIsValidImage = false;
|
mIsValidImage = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageAsset::initializeAsset()
|
void ImageAsset::initializeAsset()
|
||||||
{
|
{
|
||||||
mImagePath = expandAssetFilePath(mImageFileName);
|
if (mImageFileName == StringTable->insert("z.png"))
|
||||||
|
{
|
||||||
|
Con::printf("Loaded z");
|
||||||
|
}
|
||||||
|
|
||||||
|
ResourceManager::get().getChangedSignal().notify(this, &ImageAsset::_onResourceChanged);
|
||||||
|
|
||||||
|
mImagePath = expandAssetFilePath(mImageFileName);
|
||||||
loadImage();
|
loadImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -311,6 +314,16 @@ void ImageAsset::onAssetRefresh()
|
||||||
loadImage();
|
loadImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ImageAsset::_onResourceChanged(const Torque::Path& path)
|
||||||
|
{
|
||||||
|
if (path != Torque::Path(mImagePath))
|
||||||
|
return;
|
||||||
|
|
||||||
|
refreshAsset();
|
||||||
|
|
||||||
|
loadImage();
|
||||||
|
}
|
||||||
|
|
||||||
void ImageAsset::setImageFileName(const char* pScriptFile)
|
void ImageAsset::setImageFileName(const char* pScriptFile)
|
||||||
{
|
{
|
||||||
// Sanity!
|
// Sanity!
|
||||||
|
|
@ -320,24 +333,34 @@ void ImageAsset::setImageFileName(const char* pScriptFile)
|
||||||
mImageFileName = StringTable->insert(pScriptFile);
|
mImageFileName = StringTable->insert(pScriptFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
GFXTexHandle ImageAsset::getImage(GFXTextureProfile requestedProfile)
|
const GBitmap& ImageAsset::getImage()
|
||||||
{
|
{
|
||||||
/*if (mResourceMap.contains(requestedProfile))
|
return GBitmap(); //TODO fix this
|
||||||
|
}
|
||||||
|
|
||||||
|
GFXTexHandle ImageAsset::getTexture(GFXTextureProfile* requestedProfile)
|
||||||
|
{
|
||||||
|
if (mResourceMap.contains(requestedProfile))
|
||||||
{
|
{
|
||||||
|
mLoadedState = Ok;
|
||||||
return mResourceMap.find(requestedProfile)->value;
|
return mResourceMap.find(requestedProfile)->value;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//If we don't have an existing map case to the requested format, we'll just create it and insert it in
|
//If we don't have an existing map case to the requested format, we'll just create it and insert it in
|
||||||
GFXTexHandle newImage;
|
GFXTexHandle newTex = TEXMGR->createTexture(mImagePath, requestedProfile);
|
||||||
newImage.set(mImageFileName, &requestedProfile, avar("%s() - mImage (line %d)", __FUNCTION__, __LINE__));
|
if (newTex)
|
||||||
mResourceMap.insert(requestedProfile, newImage);
|
{
|
||||||
|
mResourceMap.insert(requestedProfile, newTex);
|
||||||
|
mLoadedState = Ok;
|
||||||
|
return newTex;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mLoadedState = BadFileReference;
|
||||||
|
}
|
||||||
|
|
||||||
return newImage;
|
//if (mTexture.isValid())
|
||||||
}*/
|
// return mTexture;
|
||||||
|
|
||||||
if (mImage.isValid())
|
|
||||||
return mImage;
|
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
@ -348,7 +371,17 @@ const char* ImageAsset::getImageInfo()
|
||||||
{
|
{
|
||||||
static const U32 bufSize = 2048;
|
static const U32 bufSize = 2048;
|
||||||
char* returnBuffer = Con::getReturnBuffer(bufSize);
|
char* returnBuffer = Con::getReturnBuffer(bufSize);
|
||||||
dSprintf(returnBuffer, bufSize, "%s %d %d %d", GFXStringTextureFormat[mImage.getFormat()], mImage.getHeight(), mImage.getWidth(), mImage.getDepth());
|
|
||||||
|
GFXTexHandle newTex = TEXMGR->createTexture(mImagePath, &GFXStaticTextureSRGBProfile);
|
||||||
|
if (newTex)
|
||||||
|
{
|
||||||
|
dSprintf(returnBuffer, bufSize, "%s %d %d %d", GFXStringTextureFormat[newTex->getFormat()], newTex->getHeight(), newTex->getWidth(), newTex->getDepth());
|
||||||
|
newTex = nullptr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dSprintf(returnBuffer, bufSize, "ImageAsset::getImageInfo() - Failed to get image info for %s", getAssetId());
|
||||||
|
}
|
||||||
|
|
||||||
return returnBuffer;
|
return returnBuffer;
|
||||||
}
|
}
|
||||||
|
|
@ -384,6 +417,11 @@ const char* ImageAsset::getImageTypeNameFromType(ImageAsset::ImageTypes type)
|
||||||
|
|
||||||
ImageAsset::ImageTypes ImageAsset::getImageTypeFromName(const char* name)
|
ImageAsset::ImageTypes ImageAsset::getImageTypeFromName(const char* name)
|
||||||
{
|
{
|
||||||
|
if (dStrIsEmpty(name))
|
||||||
|
{
|
||||||
|
return (ImageTypes)Albedo;
|
||||||
|
}
|
||||||
|
|
||||||
S32 ret = -1;
|
S32 ret = -1;
|
||||||
for (S32 i = 0; i < ImageTypeCount; i++)
|
for (S32 i = 0; i < ImageTypeCount; i++)
|
||||||
{
|
{
|
||||||
|
|
@ -414,6 +452,15 @@ DefineEngineMethod(ImageAsset, getImageInfo, const char*, (), ,
|
||||||
return object->getImageInfo();
|
return object->getImageInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef TORQUE_TOOLS
|
||||||
|
DefineEngineStaticMethod(ImageAsset, 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 ImageAsset::getAssetIdByFilename(StringTable->insert(filePath));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// GuiInspectorTypeAssetId
|
// GuiInspectorTypeAssetId
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
@ -435,11 +482,16 @@ void GuiInspectorTypeImageAssetPtr::consoleInit()
|
||||||
|
|
||||||
GuiControl* GuiInspectorTypeImageAssetPtr::constructEditControl()
|
GuiControl* GuiInspectorTypeImageAssetPtr::constructEditControl()
|
||||||
{
|
{
|
||||||
|
if (mInspector->getInspectObject() == nullptr)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
// Create base filename edit controls
|
// Create base filename edit controls
|
||||||
GuiControl* retCtrl = Parent::constructEditControl();
|
GuiControl* retCtrl = Parent::constructEditControl();
|
||||||
if (retCtrl == NULL)
|
if (retCtrl == NULL)
|
||||||
return retCtrl;
|
return retCtrl;
|
||||||
|
|
||||||
|
retCtrl->getRenderTooltipDelegate().bind(this, &GuiInspectorTypeImageAssetPtr::renderTooltip);
|
||||||
|
|
||||||
// Change filespec
|
// Change filespec
|
||||||
char szBuffer[512];
|
char szBuffer[512];
|
||||||
dSprintf(szBuffer, sizeof(szBuffer), "AssetBrowser.showDialog(\"ImageAsset\", \"AssetBrowser.changeAsset\", %s, %s);",
|
dSprintf(szBuffer, sizeof(szBuffer), "AssetBrowser.showDialog(\"ImageAsset\", \"AssetBrowser.changeAsset\", %s, %s);",
|
||||||
|
|
@ -456,8 +508,8 @@ GuiControl* GuiInspectorTypeImageAssetPtr::constructEditControl()
|
||||||
dSprintf(szBuffer, sizeof(szBuffer), "ShapeEditorPlugin.openShapeAssetId(%d.getText());", retCtrl->getId());
|
dSprintf(szBuffer, sizeof(szBuffer), "ShapeEditorPlugin.openShapeAssetId(%d.getText());", retCtrl->getId());
|
||||||
mImageEdButton->setField("Command", szBuffer);
|
mImageEdButton->setField("Command", szBuffer);
|
||||||
|
|
||||||
char bitmapName[512] = "tools/worldEditor/images/toolbar/shape-editor";
|
char bitmapName[512] = "ToolsModule:GameTSCtrl_image";
|
||||||
mImageEdButton->setBitmap(bitmapName);
|
mImageEdButton->setBitmap(StringTable->insert(bitmapName));
|
||||||
|
|
||||||
mImageEdButton->setDataField(StringTable->insert("Profile"), NULL, "GuiButtonProfile");
|
mImageEdButton->setDataField(StringTable->insert("Profile"), NULL, "GuiButtonProfile");
|
||||||
mImageEdButton->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile");
|
mImageEdButton->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile");
|
||||||
|
|
@ -496,6 +548,66 @@ bool GuiInspectorTypeImageAssetPtr::updateRects()
|
||||||
return resized;
|
return resized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GuiInspectorTypeImageAssetPtr::renderTooltip(const Point2I& hoverPos, const Point2I& cursorPos, const char* tipText)
|
||||||
|
{
|
||||||
|
if (!mAwake)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
GuiCanvas* root = getRoot();
|
||||||
|
if (!root)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
AssetPtr<ImageAsset> imgAsset;
|
||||||
|
U32 assetState = ImageAsset::getAssetById(getData(), &imgAsset);
|
||||||
|
if (imgAsset == NULL || assetState == ImageAsset::Failed)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
StringTableEntry filename = imgAsset->getImagePath();
|
||||||
|
if (!filename || !filename[0])
|
||||||
|
return false;
|
||||||
|
|
||||||
|
GFXTexHandle texture(filename, &GFXStaticTextureSRGBProfile, avar("%s() - tooltip texture (line %d)", __FUNCTION__, __LINE__));
|
||||||
|
if (texture.isNull())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Render image at a reasonable screen size while
|
||||||
|
// keeping its aspect ratio...
|
||||||
|
Point2I screensize = getRoot()->getWindowSize();
|
||||||
|
Point2I offset = hoverPos;
|
||||||
|
Point2I tipBounds;
|
||||||
|
|
||||||
|
U32 texWidth = texture.getWidth();
|
||||||
|
U32 texHeight = texture.getHeight();
|
||||||
|
F32 aspect = (F32)texHeight / (F32)texWidth;
|
||||||
|
|
||||||
|
const F32 newWidth = 150.0f;
|
||||||
|
F32 newHeight = aspect * newWidth;
|
||||||
|
|
||||||
|
// Offset below cursor image
|
||||||
|
offset.y += 20; // TODO: Attempt to fix?: root->getCursorExtent().y;
|
||||||
|
tipBounds.x = newWidth;
|
||||||
|
tipBounds.y = newHeight;
|
||||||
|
|
||||||
|
// Make sure all of the tooltip will be rendered width the app window,
|
||||||
|
// 5 is given as a buffer against the edge
|
||||||
|
if (screensize.x < offset.x + tipBounds.x + 5)
|
||||||
|
offset.x = screensize.x - tipBounds.x - 5;
|
||||||
|
if (screensize.y < offset.y + tipBounds.y + 5)
|
||||||
|
offset.y = hoverPos.y - tipBounds.y - 5;
|
||||||
|
|
||||||
|
RectI oldClip = GFX->getClipRect();
|
||||||
|
RectI rect(offset, tipBounds);
|
||||||
|
GFX->setClipRect(rect);
|
||||||
|
|
||||||
|
GFXDrawUtil* drawer = GFX->getDrawUtil();
|
||||||
|
drawer->clearBitmapModulation();
|
||||||
|
GFX->getDrawUtil()->drawBitmapStretch(texture, rect);
|
||||||
|
|
||||||
|
GFX->setClipRect(oldClip);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
IMPLEMENT_CONOBJECT(GuiInspectorTypeImageAssetId);
|
IMPLEMENT_CONOBJECT(GuiInspectorTypeImageAssetId);
|
||||||
|
|
||||||
ConsoleDocClass(GuiInspectorTypeImageAssetId,
|
ConsoleDocClass(GuiInspectorTypeImageAssetId,
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,7 @@
|
||||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
// IN THE SOFTWARE.
|
// IN THE SOFTWARE.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
#ifndef IMAGE_ASSET_H
|
#pragma once
|
||||||
#define IMAGE_ASSET_H
|
|
||||||
|
|
||||||
#ifndef _ASSET_BASE_H_
|
#ifndef _ASSET_BASE_H_
|
||||||
#include "assets/assetBase.h"
|
#include "assets/assetBase.h"
|
||||||
|
|
@ -45,7 +44,9 @@
|
||||||
#include "gfx/bitmap/gBitmap.h"
|
#include "gfx/bitmap/gBitmap.h"
|
||||||
#include "gfx/gfxTextureHandle.h"
|
#include "gfx/gfxTextureHandle.h"
|
||||||
|
|
||||||
#include "gui/editor/guiInspectorTypes.h"
|
#include "sim/netConnection.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
class ImageAsset : public AssetBase
|
class ImageAsset : public AssetBase
|
||||||
|
|
@ -70,24 +71,33 @@ public:
|
||||||
ImageTypeCount = 11
|
ImageTypeCount = 11
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static StringTableEntry smNoImageAssetFallback;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
StringTableEntry mImageFileName;
|
StringTableEntry mImageFileName;
|
||||||
StringTableEntry mImagePath;
|
StringTableEntry mImagePath;
|
||||||
|
|
||||||
GFXTexHandle mImage;
|
|
||||||
|
|
||||||
bool mIsValidImage;
|
bool mIsValidImage;
|
||||||
bool mUseMips;
|
bool mUseMips;
|
||||||
bool mIsHDRImage;
|
bool mIsHDRImage;
|
||||||
|
|
||||||
ImageTypes mImageType;
|
ImageTypes mImageType;
|
||||||
|
|
||||||
Map<GFXTextureProfile, GFXTexHandle> mResourceMap;
|
HashMap<GFXTextureProfile*, GFXTexHandle> mResourceMap;
|
||||||
|
|
||||||
|
typedef Signal<void()> ImageAssetChanged;
|
||||||
|
ImageAssetChanged mChangeSignal;
|
||||||
|
|
||||||
|
typedef Signal<void(S32 index)> ImageAssetArrayChanged;
|
||||||
|
ImageAssetArrayChanged mChangeArraySignal;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ImageAsset();
|
ImageAsset();
|
||||||
virtual ~ImageAsset();
|
virtual ~ImageAsset();
|
||||||
|
|
||||||
|
/// Set up some global script interface stuff.
|
||||||
|
static void consoleInit();
|
||||||
|
|
||||||
/// Engine.
|
/// Engine.
|
||||||
static void initPersistFields();
|
static void initPersistFields();
|
||||||
virtual void copyTo(SimObject* object);
|
virtual void copyTo(SimObject* object);
|
||||||
|
|
@ -95,32 +105,40 @@ public:
|
||||||
/// Declare Console Object.
|
/// Declare Console Object.
|
||||||
DECLARE_CONOBJECT(ImageAsset);
|
DECLARE_CONOBJECT(ImageAsset);
|
||||||
|
|
||||||
void setImageFileName(const char* pScriptFile);
|
void _onResourceChanged(const Torque::Path& path);
|
||||||
|
|
||||||
|
ImageAssetChanged& getChangedSignal() { return mChangeSignal; }
|
||||||
|
ImageAssetArrayChanged& getChangedArraySignal() { return mChangeArraySignal; }
|
||||||
|
|
||||||
|
void setImageFileName(StringTableEntry pScriptFile);
|
||||||
inline StringTableEntry getImageFileName(void) const { return mImageFileName; };
|
inline StringTableEntry getImageFileName(void) const { return mImageFileName; };
|
||||||
|
|
||||||
inline StringTableEntry getImagePath(void) const { return mImagePath; };
|
inline StringTableEntry getImagePath(void) const { return mImagePath; };
|
||||||
|
|
||||||
bool isValid() { return mIsValidImage; }
|
bool isValid() { return mIsValidImage; }
|
||||||
|
|
||||||
GFXTexHandle getImage(GFXTextureProfile requestedProfile);
|
const GBitmap& getImage();
|
||||||
|
GFXTexHandle getTexture(GFXTextureProfile* requestedProfile);
|
||||||
|
|
||||||
const char* getImageInfo();
|
StringTableEntry getImageInfo();
|
||||||
|
|
||||||
static const char* getImageTypeNameFromType(ImageTypes type);
|
static StringTableEntry getImageTypeNameFromType(ImageTypes type);
|
||||||
static ImageTypes getImageTypeFromName(const char* name);
|
static ImageTypes getImageTypeFromName(StringTableEntry name);
|
||||||
|
|
||||||
void setImageType(ImageTypes type) { mImageType = type; }
|
void setImageType(ImageTypes type) { mImageType = type; }
|
||||||
|
ImageTypes getImageType() { return mImageType; }
|
||||||
|
|
||||||
static bool getAssetByFilename(StringTableEntry fileName, AssetPtr<ImageAsset>* imageAsset);
|
static U32 getAssetByFilename(StringTableEntry fileName, AssetPtr<ImageAsset>* imageAsset);
|
||||||
static StringTableEntry getAssetIdByFilename(StringTableEntry fileName);
|
static StringTableEntry getAssetIdByFilename(StringTableEntry fileName);
|
||||||
static bool getAssetById(StringTableEntry assetId, AssetPtr<ImageAsset>* imageAsset);
|
static U32 getAssetById(StringTableEntry assetId, AssetPtr<ImageAsset>* imageAsset);
|
||||||
|
static U32 getAssetById(String assetId, AssetPtr<ImageAsset>* imageAsset) { return getAssetById(assetId.c_str(), imageAsset); };
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void initializeAsset(void);
|
virtual void initializeAsset(void);
|
||||||
virtual void onAssetRefresh(void);
|
virtual void onAssetRefresh(void);
|
||||||
|
|
||||||
static bool setImageFileName(void* obj, const char* index, const char* data) { static_cast<ImageAsset*>(obj)->setImageFileName(data); return false; }
|
static bool setImageFileName(void* obj, StringTableEntry index, StringTableEntry data) { static_cast<ImageAsset*>(obj)->setImageFileName(data); return false; }
|
||||||
static const char* getImageFileName(void* obj, const char* data) { return static_cast<ImageAsset*>(obj)->getImageFileName(); }
|
static StringTableEntry getImageFileName(void* obj, StringTableEntry data) { return static_cast<ImageAsset*>(obj)->getImageFileName(); }
|
||||||
|
|
||||||
void loadImage();
|
void loadImage();
|
||||||
};
|
};
|
||||||
|
|
@ -131,89 +149,468 @@ DefineConsoleType(TypeImageAssetId, String)
|
||||||
typedef ImageAsset::ImageTypes ImageAssetType;
|
typedef ImageAsset::ImageTypes ImageAssetType;
|
||||||
DefineEnumType(ImageAssetType);
|
DefineEnumType(ImageAssetType);
|
||||||
|
|
||||||
class GuiInspectorTypeImageAssetPtr : public GuiInspectorTypeFileName
|
#pragma region Singular Asset Macros
|
||||||
{
|
|
||||||
typedef GuiInspectorTypeFileName Parent;
|
|
||||||
public:
|
|
||||||
|
|
||||||
GuiBitmapButtonCtrl* mImageEdButton;
|
//Singular assets
|
||||||
|
/// <Summary>
|
||||||
DECLARE_CONOBJECT(GuiInspectorTypeImageAssetPtr);
|
/// Declares an image asset
|
||||||
static void consoleInit();
|
/// This establishes the assetId, asset and legacy filepath fields, along with supplemental getter and setter functions
|
||||||
|
/// </Summary>
|
||||||
virtual GuiControl* constructEditControl();
|
#define DECLARE_IMAGEASSET(className, name, changeFunc, profile) public: \
|
||||||
virtual bool updateRects();
|
GFXTexHandle m##name = NULL;\
|
||||||
};
|
StringTableEntry m##name##Name; \
|
||||||
|
StringTableEntry m##name##AssetId;\
|
||||||
class GuiInspectorTypeImageAssetId : public GuiInspectorTypeImageAssetPtr
|
AssetPtr<ImageAsset> m##name##Asset;\
|
||||||
{
|
GFXTextureProfile* m##name##Profile = &profile;\
|
||||||
typedef GuiInspectorTypeImageAssetPtr Parent;
|
public: \
|
||||||
public:
|
const StringTableEntry get##name##File() const { return m##name##Name; }\
|
||||||
|
void set##name##File(const FileName &_in) { m##name##Name = StringTable->insert(_in.c_str());}\
|
||||||
DECLARE_CONOBJECT(GuiInspectorTypeImageAssetId);
|
const AssetPtr<ImageAsset> & get##name##Asset() const { return m##name##Asset; }\
|
||||||
static void consoleInit();
|
void set##name##Asset(const AssetPtr<ImageAsset> &_in) { m##name##Asset = _in;}\
|
||||||
};
|
\
|
||||||
|
bool _set##name(StringTableEntry _in)\
|
||||||
#define assetText(x,suff) std::string(std::string(#x) + std::string(#suff)).c_str()
|
|
||||||
|
|
||||||
#define initMapSlot(name) m##name##Filename = String::EmptyString; m##name##AssetId = StringTable->EmptyString(); m##name##Asset = NULL;
|
|
||||||
#define bindMapSlot(name) if (m##name##AssetId != String::EmptyString) m##name##Asset = m##name##AssetId;
|
|
||||||
|
|
||||||
#define scriptBindMapSlot(name, consoleClass, docs) addField(#name, TypeImageFilename, Offset(m##name##Filename, consoleClass), assetText(name, docs)); \
|
|
||||||
addProtectedField(assetText(name, Asset), TypeImageAssetId, Offset(m##name##AssetId, consoleClass), consoleClass::_set##name##Asset, & defaultProtectedGetFn, assetText(name, asset reference.));
|
|
||||||
|
|
||||||
#define initMapArraySlot(name,id) m##name##Filename[id] = String::EmptyString; m##name##AssetId[id] = StringTable->EmptyString(); m##name##Asset[id] = NULL;
|
|
||||||
#define bindMapArraySlot(name,id) if (m##name##AssetId[id] != String::EmptyString) m##name##Asset[id] = m##name##AssetId[id];
|
|
||||||
#define scriptBindMapArraySlot(name, arraySize, consoleClass, docs) addField(#name, TypeImageFilename, Offset(m##name##Filename, consoleClass), arraySize, assetText(name, docs)); \
|
|
||||||
addProtectedField(assetText(name,Asset), TypeImageAssetId, Offset(m##name##AssetId, consoleClass), consoleClass::_set##name##AssetSlot, &defaultProtectedGetFn, arraySize, assetText(name,asset reference.));
|
|
||||||
|
|
||||||
#define DECLARE_TEXTUREMAP(className,name) protected: \
|
|
||||||
FileName m##name##Filename;\
|
|
||||||
StringTableEntry m##name##AssetId;\
|
|
||||||
AssetPtr<ImageAsset> m##name##Asset;\
|
|
||||||
public: \
|
|
||||||
const String& get##name() const { return m##name##Filename; }\
|
|
||||||
void set##name(FileName _in) { m##name##Filename = _in; }\
|
|
||||||
const AssetPtr<ImageAsset> & get##name##Asset() const { return m##name##Asset; }\
|
|
||||||
void set##name##Asset(AssetPtr<ImageAsset>_in) { m##name##Asset = _in; }\
|
|
||||||
static bool _set##name##Asset(void* obj, const char* index, const char* data)\
|
|
||||||
{\
|
|
||||||
className* mat = static_cast<className*>(obj);\
|
|
||||||
mat->m##name##AssetId = StringTable->insert(data);\
|
|
||||||
if (ImageAsset::getAssetById(mat->m##name##AssetId, &mat->m##name##Asset))\
|
|
||||||
{\
|
{\
|
||||||
if (mat->m##name##Asset.getAssetId() != StringTable->insert("Core_Rendering:noMaterial"))\
|
if(m##name##AssetId != _in || m##name##Name != _in)\
|
||||||
mat->m##name##Filename = StringTable->EmptyString();\
|
|
||||||
return true;\
|
|
||||||
}\
|
|
||||||
return true;\
|
|
||||||
}
|
|
||||||
|
|
||||||
#define GET_TEXTUREMAP(name) get##name()
|
|
||||||
#define SET_TEXTUREMAP(name,_in) set##name(_in)
|
|
||||||
#define GET_TEXTUREASSET(name) get##name##Asset()
|
|
||||||
#define SET_TEXTUREASSET(name,_in) set##name##Asset(_in)
|
|
||||||
|
|
||||||
#define DECLARE_TEXTUREARRAY(className,name,max) FileName m##name##Filename[max];\
|
|
||||||
StringTableEntry m##name##AssetId[max];\
|
|
||||||
AssetPtr<ImageAsset> m##name##Asset[max];\
|
|
||||||
static bool _set##name##AssetSlot(void* obj, const char* index, const char* data)\
|
|
||||||
{\
|
|
||||||
className* mat = static_cast<className*>(obj);\
|
|
||||||
if (!index) return false;\
|
|
||||||
U32 idx = dAtoi(index);\
|
|
||||||
if (idx >= max)\
|
|
||||||
return false;\
|
|
||||||
mat->m##name##AssetId[idx] = StringTable->insert(data);\
|
|
||||||
if (ImageAsset::getAssetById(mat->m##name##AssetId[idx], &mat->m##name##Asset[idx]))\
|
|
||||||
{\
|
|
||||||
if (mat->m##name##Asset[idx].getAssetId() != StringTable->insert("Core_Rendering:noMaterial"))\
|
|
||||||
{\
|
{\
|
||||||
mat->m##name##Filename[idx] = StringTable->EmptyString();\
|
if (m##name##Asset.notNull())\
|
||||||
|
{\
|
||||||
|
m##name##Asset->getChangedSignal().remove(this, &className::changeFunc);\
|
||||||
|
}\
|
||||||
|
if (_in == StringTable->EmptyString())\
|
||||||
|
{\
|
||||||
|
m##name##Name = StringTable->EmptyString();\
|
||||||
|
m##name##AssetId = StringTable->EmptyString();\
|
||||||
|
m##name##Asset = NULL;\
|
||||||
|
m##name.free();\
|
||||||
|
m##name = NULL;\
|
||||||
|
return true;\
|
||||||
|
}\
|
||||||
|
else if(_in[0] == '$' || _in[0] == '#')\
|
||||||
|
{\
|
||||||
|
m##name##Name = _in;\
|
||||||
|
m##name##AssetId = StringTable->EmptyString();\
|
||||||
|
m##name##Asset = NULL;\
|
||||||
|
m##name.free();\
|
||||||
|
m##name = NULL;\
|
||||||
|
return true;\
|
||||||
|
}\
|
||||||
|
\
|
||||||
|
if (AssetDatabase.isDeclaredAsset(_in))\
|
||||||
|
{\
|
||||||
|
m##name##AssetId = _in;\
|
||||||
|
\
|
||||||
|
U32 assetState = ImageAsset::getAssetById(m##name##AssetId, &m##name##Asset);\
|
||||||
|
\
|
||||||
|
if (ImageAsset::Ok == assetState)\
|
||||||
|
{\
|
||||||
|
m##name##Name = StringTable->EmptyString();\
|
||||||
|
}\
|
||||||
|
}\
|
||||||
|
else\
|
||||||
|
{\
|
||||||
|
StringTableEntry assetId = ImageAsset::getAssetIdByFilename(_in);\
|
||||||
|
if (assetId != StringTable->EmptyString())\
|
||||||
|
{\
|
||||||
|
m##name##AssetId = assetId;\
|
||||||
|
if (ImageAsset::getAssetById(m##name##AssetId, &m##name##Asset) == ImageAsset::Ok)\
|
||||||
|
{\
|
||||||
|
m##name##Name = StringTable->EmptyString();\
|
||||||
|
}\
|
||||||
|
}\
|
||||||
|
else\
|
||||||
|
{\
|
||||||
|
m##name##Name = _in;\
|
||||||
|
m##name##AssetId = StringTable->EmptyString();\
|
||||||
|
m##name##Asset = NULL;\
|
||||||
|
}\
|
||||||
|
}\
|
||||||
|
}\
|
||||||
|
if (get##name() != StringTable->EmptyString() && m##name##Name != StringTable->insert("texhandle"))\
|
||||||
|
{\
|
||||||
|
if (m##name##Asset.notNull())\
|
||||||
|
{\
|
||||||
|
m##name##Asset->getChangedSignal().notify(this, &className::changeFunc);\
|
||||||
|
}\
|
||||||
|
\
|
||||||
|
m##name.set(get##name(), m##name##Profile, avar("%s() - mTextureObject (line %d)", __FUNCTION__, __LINE__));\
|
||||||
|
}\
|
||||||
|
else\
|
||||||
|
{\
|
||||||
|
m##name.free();\
|
||||||
|
m##name = NULL;\
|
||||||
|
}\
|
||||||
|
\
|
||||||
|
if(get##name() == StringTable->EmptyString())\
|
||||||
|
return true;\
|
||||||
|
\
|
||||||
|
if (m##name##Asset.notNull() && m##name##Asset->getStatus() != ImageAsset::Ok)\
|
||||||
|
{\
|
||||||
|
Con::errorf("%s(%s)::_set%s() - image asset failure\"%s\" due to [%s]", macroText(className), getName(), macroText(name), _in, ImageAsset::getAssetErrstrn(m##name##Asset->getStatus()).c_str());\
|
||||||
|
return false; \
|
||||||
|
}\
|
||||||
|
else if (bool(m##name) == NULL)\
|
||||||
|
{\
|
||||||
|
Con::errorf("%s(%s)::_set%s() - Couldn't load image \"%s\"", macroText(className), getName(), macroText(name), _in);\
|
||||||
|
return false;\
|
||||||
}\
|
}\
|
||||||
return true;\
|
return true;\
|
||||||
}\
|
}\
|
||||||
return true;\
|
\
|
||||||
|
const StringTableEntry get##name() const\
|
||||||
|
{\
|
||||||
|
if (m##name##Asset && (m##name##Asset->getImageFileName() != StringTable->EmptyString()))\
|
||||||
|
return Platform::makeRelativePathName(m##name##Asset->getImagePath(), Platform::getMainDotCsDir());\
|
||||||
|
else if (m##name##AssetId != StringTable->EmptyString())\
|
||||||
|
return m##name##AssetId;\
|
||||||
|
else if (m##name##Name != StringTable->EmptyString())\
|
||||||
|
return StringTable->insert(Platform::makeRelativePathName(m##name##Name, Platform::getMainDotCsDir()));\
|
||||||
|
else\
|
||||||
|
return StringTable->EmptyString();\
|
||||||
|
}\
|
||||||
|
GFXTexHandle get##name##Resource() \
|
||||||
|
{\
|
||||||
|
return m##name;\
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DECLARE_IMAGEASSET_SETGET(className, name)\
|
||||||
|
static bool _set##name##Data(void* obj, const char* index, const char* data)\
|
||||||
|
{\
|
||||||
|
bool ret = false;\
|
||||||
|
className* object = static_cast<className*>(obj);\
|
||||||
|
ret = object->_set##name(StringTable->insert(data));\
|
||||||
|
return ret;\
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DECLARE_IMAGEASSET_NET_SETGET(className, name, bitmask)\
|
||||||
|
static bool _set##name##Data(void* obj, const char* index, const char* data)\
|
||||||
|
{\
|
||||||
|
bool ret = false;\
|
||||||
|
className* object = static_cast<className*>(obj);\
|
||||||
|
ret = object->_set##name(StringTable->insert(data));\
|
||||||
|
if(ret)\
|
||||||
|
object->setMaskBits(bitmask);\
|
||||||
|
return ret;\
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DEF_IMAGEASSET_BINDS(className,name)\
|
||||||
|
DefineEngineMethod(className, get##name, const char*, (), , "get name")\
|
||||||
|
{\
|
||||||
|
return object->get##name(); \
|
||||||
|
}\
|
||||||
|
DefineEngineMethod(className, get##name##Asset, const char*, (), , assetText(name, asset reference))\
|
||||||
|
{\
|
||||||
|
return object->m##name##AssetId; \
|
||||||
|
}\
|
||||||
|
DefineEngineMethod(className, set##name, bool, (const char* map), , assetText(name,assignment. first tries asset then flat file.))\
|
||||||
|
{\
|
||||||
|
return object->_set##name(StringTable->insert(map));\
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define INIT_IMAGEASSET(name) \
|
||||||
|
m##name##Name = StringTable->EmptyString(); \
|
||||||
|
m##name##AssetId = StringTable->EmptyString(); \
|
||||||
|
m##name##Asset = NULL;
|
||||||
|
|
||||||
|
#ifdef TORQUE_SHOW_LEGACY_FILE_FIELDS
|
||||||
|
|
||||||
|
#define INITPERSISTFIELD_IMAGEASSET(name, consoleClass, docs) \
|
||||||
|
addProtectedField(#name, TypeImageFilename, Offset(m##name##Name, consoleClass), _set##name##Data, &defaultProtectedGetFn, assetDoc(name, docs)); \
|
||||||
|
addProtectedField(assetText(name, Asset), TypeImageAssetId, Offset(m##name##AssetId, consoleClass), _set##name##Data, &defaultProtectedGetFn, assetDoc(name, asset docs.));
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define INITPERSISTFIELD_IMAGEASSET(name, consoleClass, docs) \
|
||||||
|
addProtectedField(#name, TypeImageFilename, Offset(m##name##Name, consoleClass), _set##name##Data, &defaultProtectedGetFn, assetDoc(name, docs), AbstractClassRep::FIELD_HideInInspectors); \
|
||||||
|
addProtectedField(assetText(name, Asset), TypeImageAssetId, Offset(m##name##AssetId, consoleClass), _set##name##Data, &defaultProtectedGetFn, assetDoc(name, asset docs.));
|
||||||
|
|
||||||
|
#endif // SHOW_LEGACY_FILE_FIELDS
|
||||||
|
|
||||||
|
#define CLONE_IMAGEASSET(name) \
|
||||||
|
m##name##Name = other.m##name##Name;\
|
||||||
|
m##name##AssetId = other.m##name##AssetId;\
|
||||||
|
m##name##Asset = other.m##name##Asset;
|
||||||
|
|
||||||
|
#define LOAD_IMAGEASSET(name)\
|
||||||
|
if (m##name##AssetId != StringTable->EmptyString())\
|
||||||
|
{\
|
||||||
|
S32 assetState = ImageAsset::getAssetById(m##name##AssetId, &m##name##Asset);\
|
||||||
|
if (assetState == ImageAsset::Ok )\
|
||||||
|
{\
|
||||||
|
m##name##Name = StringTable->EmptyString();\
|
||||||
|
}\
|
||||||
|
else Con::warnf("Warning: %s::LOAD_IMAGEASSET(%s)-%s", mClassName, m##name##AssetId, ImageAsset::getAssetErrstrn(assetState).c_str());\
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PACKDATA_IMAGEASSET(name)\
|
||||||
|
if (stream->writeFlag(m##name##Asset.notNull()))\
|
||||||
|
{\
|
||||||
|
stream->writeString(m##name##Asset.getAssetId());\
|
||||||
|
_set##name(m##name##AssetId);\
|
||||||
|
}\
|
||||||
|
else\
|
||||||
|
stream->writeString(m##name##Name);
|
||||||
|
|
||||||
|
#define UNPACKDATA_IMAGEASSET(name)\
|
||||||
|
if (stream->readFlag())\
|
||||||
|
{\
|
||||||
|
m##name##AssetId = stream->readSTString();\
|
||||||
|
}\
|
||||||
|
else\
|
||||||
|
m##name##Name = stream->readSTString();
|
||||||
|
|
||||||
|
#define PACK_IMAGEASSET(netconn, name)\
|
||||||
|
if (stream->writeFlag(m##name##Asset.notNull()))\
|
||||||
|
{\
|
||||||
|
NetStringHandle assetIdStr = m##name##Asset.getAssetId();\
|
||||||
|
netconn->packNetStringHandleU(stream, assetIdStr);\
|
||||||
|
}\
|
||||||
|
else\
|
||||||
|
stream->writeString(m##name##Name);
|
||||||
|
|
||||||
|
#define UNPACK_IMAGEASSET(netconn, name)\
|
||||||
|
if (stream->readFlag())\
|
||||||
|
{\
|
||||||
|
m##name##AssetId = StringTable->insert(netconn->unpackNetStringHandleU(stream).getString());\
|
||||||
|
_set##name(m##name##AssetId);\
|
||||||
|
}\
|
||||||
|
else\
|
||||||
|
m##name##Name = stream->readSTString();
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region Arrayed Asset Macros
|
||||||
|
|
||||||
|
//Arrayed Assets
|
||||||
|
#define DECLARE_IMAGEASSET_ARRAY(className, name, profile, max) public: \
|
||||||
|
static const U32 sm##name##Count = max;\
|
||||||
|
GFXTexHandle m##name[max];\
|
||||||
|
StringTableEntry m##name##Name[max]; \
|
||||||
|
StringTableEntry m##name##AssetId[max];\
|
||||||
|
AssetPtr<ImageAsset> m##name##Asset[max];\
|
||||||
|
GFXTextureProfile * m##name##Profile = &profile;\
|
||||||
|
public: \
|
||||||
|
const StringTableEntry get##name##File(const U32& index) const { return m##name##Name[index]; }\
|
||||||
|
void set##name##File(const FileName &_in, const U32& index) { m##name##Name[index] = StringTable->insert(_in.c_str());}\
|
||||||
|
const AssetPtr<ImageAsset> & get##name##Asset(const U32& index) const { return m##name##Asset[index]; }\
|
||||||
|
void set##name##Asset(const AssetPtr<ImageAsset> &_in, const U32& index) { m##name##Asset[index] = _in;}\
|
||||||
|
\
|
||||||
|
bool _set##name(StringTableEntry _in, const U32& index)\
|
||||||
|
{\
|
||||||
|
if(m##name##AssetId[index] != _in || m##name##Name[index] != _in)\
|
||||||
|
{\
|
||||||
|
if(index >= sm##name##Count || index < 0)\
|
||||||
|
return false;\
|
||||||
|
if (_in == StringTable->EmptyString())\
|
||||||
|
{\
|
||||||
|
m##name##Name[index] = StringTable->EmptyString();\
|
||||||
|
m##name##AssetId[index] = StringTable->EmptyString();\
|
||||||
|
m##name##Asset[index] = NULL;\
|
||||||
|
m##name[index].free();\
|
||||||
|
m##name[index] = NULL;\
|
||||||
|
return true;\
|
||||||
|
}\
|
||||||
|
else if(_in[0] == '$' || _in[0] == '#')\
|
||||||
|
{\
|
||||||
|
m##name##Name[index] = _in;\
|
||||||
|
m##name##AssetId[index] = StringTable->EmptyString();\
|
||||||
|
m##name##Asset[index] = NULL;\
|
||||||
|
m##name[index].free();\
|
||||||
|
m##name[index] = NULL;\
|
||||||
|
return true;\
|
||||||
|
}\
|
||||||
|
\
|
||||||
|
if (AssetDatabase.isDeclaredAsset(_in))\
|
||||||
|
{\
|
||||||
|
m##name##AssetId[index] = _in;\
|
||||||
|
\
|
||||||
|
U32 assetState = ImageAsset::getAssetById(m##name##AssetId[index], &m##name##Asset[index]);\
|
||||||
|
\
|
||||||
|
if (ImageAsset::Ok == assetState)\
|
||||||
|
{\
|
||||||
|
m##name##Name[index] = StringTable->EmptyString();\
|
||||||
|
}\
|
||||||
|
}\
|
||||||
|
else\
|
||||||
|
{\
|
||||||
|
StringTableEntry assetId = ImageAsset::getAssetIdByFilename(_in);\
|
||||||
|
if (assetId != StringTable->EmptyString())\
|
||||||
|
{\
|
||||||
|
m##name##AssetId[index] = assetId;\
|
||||||
|
if (ImageAsset::getAssetById(m##name##AssetId[index], &m##name##Asset[index]) == ImageAsset::Ok)\
|
||||||
|
{\
|
||||||
|
m##name##Name[index] = StringTable->EmptyString();\
|
||||||
|
}\
|
||||||
|
}\
|
||||||
|
else\
|
||||||
|
{\
|
||||||
|
m##name##Name[index] = _in;\
|
||||||
|
m##name##AssetId[index] = StringTable->EmptyString();\
|
||||||
|
m##name##Asset[index] = NULL;\
|
||||||
|
}\
|
||||||
|
}\
|
||||||
|
}\
|
||||||
|
if (get##name(index) != StringTable->EmptyString() && m##name##Name[index] != StringTable->insert("texhandle"))\
|
||||||
|
{\
|
||||||
|
m##name[index].set(get##name(index), m##name##Profile, avar("%s() - mTextureObject (line %d)", __FUNCTION__, __LINE__));\
|
||||||
|
}\
|
||||||
|
else\
|
||||||
|
{\
|
||||||
|
m##name[index].free();\
|
||||||
|
m##name[index] = NULL;\
|
||||||
|
}\
|
||||||
|
\
|
||||||
|
if(get##name(index) == StringTable->EmptyString())\
|
||||||
|
return true;\
|
||||||
|
\
|
||||||
|
if (m##name##Asset[index].notNull() && m##name##Asset[index]->getStatus() != ImageAsset::Ok)\
|
||||||
|
{\
|
||||||
|
Con::errorf("%s(%s)::_set%s(%i) - image asset failure\"%s\" due to [%s]", macroText(className), getName(), macroText(name), index, _in, ImageAsset::getAssetErrstrn(m##name##Asset[index]->getStatus()).c_str());\
|
||||||
|
return false; \
|
||||||
|
}\
|
||||||
|
else if (bool(m##name[index]) == NULL)\
|
||||||
|
{\
|
||||||
|
Con::errorf("%s(%s)::_set%s(%i) - Couldn't load image \"%s\"", macroText(className), getName(), macroText(name), index, _in);\
|
||||||
|
return false; \
|
||||||
|
}\
|
||||||
|
return true;\
|
||||||
|
}\
|
||||||
|
\
|
||||||
|
const StringTableEntry get##name(const U32& index) const\
|
||||||
|
{\
|
||||||
|
if (m##name##Asset[index] && (m##name##Asset[index]->getImageFileName() != StringTable->EmptyString()))\
|
||||||
|
return Platform::makeRelativePathName(m##name##Asset[index]->getImagePath(), Platform::getMainDotCsDir());\
|
||||||
|
else if (m##name##AssetId[index] != StringTable->EmptyString())\
|
||||||
|
return m##name##AssetId[index];\
|
||||||
|
else if (m##name##Name[index] != StringTable->EmptyString())\
|
||||||
|
return StringTable->insert(Platform::makeRelativePathName(m##name##Name[index], Platform::getMainDotCsDir()));\
|
||||||
|
else\
|
||||||
|
return StringTable->EmptyString();\
|
||||||
|
}\
|
||||||
|
GFXTexHandle get##name##Resource(const U32& index) \
|
||||||
|
{\
|
||||||
|
if(index >= sm##name##Count || index < 0)\
|
||||||
|
return nullptr;\
|
||||||
|
return m##name[index];\
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DECLARE_IMAGEASSET_ARRAY_SETGET(className, name)\
|
||||||
|
static bool _set##name##Data(void* obj, const char* index, const char* data)\
|
||||||
|
{\
|
||||||
|
if (!index) return false;\
|
||||||
|
U32 idx = dAtoi(index);\
|
||||||
|
if (idx >= sm##name##Count)\
|
||||||
|
return false;\
|
||||||
|
bool ret = false;\
|
||||||
|
className* object = static_cast<className*>(obj);\
|
||||||
|
ret = object->_set##name(StringTable->insert(data),idx);\
|
||||||
|
return ret;\
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DECLARE_IMAGEASSET_ARRAY_NET_SETGET(className, name, bitmask)\
|
||||||
|
static bool _set##name##Data(void* obj, const char* index, const char* data)\
|
||||||
|
{\
|
||||||
|
if (!index) return false;\
|
||||||
|
U32 idx = dAtoi(index);\
|
||||||
|
if (idx >= sm##name##Count)\
|
||||||
|
return false;\
|
||||||
|
bool ret = false;\
|
||||||
|
className* object = static_cast<className*>(obj);\
|
||||||
|
ret = object->_set##name(StringTable->insert(data),idx);\
|
||||||
|
if(ret)\
|
||||||
|
object->setMaskBits(bitmask);\
|
||||||
|
return ret;\
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DEF_IMAGEASSET_ARRAY_BINDS(className,name)\
|
||||||
|
DefineEngineMethod(className, get##name, const char*, (S32 index), , "get name")\
|
||||||
|
{\
|
||||||
|
return object->get##name(index); \
|
||||||
|
}\
|
||||||
|
DefineEngineMethod(className, get##name##Asset, const char*, (S32 index), , assetText(name, asset reference))\
|
||||||
|
{\
|
||||||
|
if(index >= className::sm##name##Count || index < 0)\
|
||||||
|
return "";\
|
||||||
|
return object->m##name##AssetId[index]; \
|
||||||
|
}\
|
||||||
|
DefineEngineMethod(className, set##name, bool, (const char* map, S32 index), , assetText(name,assignment. first tries asset then flat file.))\
|
||||||
|
{\
|
||||||
|
return object->_set##name(StringTable->insert(map), index);\
|
||||||
|
}
|
||||||
|
|
||||||
|
#define INIT_IMAGEASSET_ARRAY(name, index) \
|
||||||
|
{\
|
||||||
|
m##name##Name[index] = StringTable->EmptyString(); \
|
||||||
|
m##name##AssetId[index] = StringTable->EmptyString(); \
|
||||||
|
m##name##Asset[index] = NULL;\
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef TORQUE_SHOW_LEGACY_FILE_FIELDS
|
||||||
|
|
||||||
|
#define INITPERSISTFIELD_IMAGEASSET_ARRAY(name, arraySize, consoleClass, docs) \
|
||||||
|
addProtectedField(#name, TypeImageFilename, Offset(m##name##Name, consoleClass), _set##name##Data, &defaultProtectedGetFn, arraySize, assetDoc(name, docs)); \
|
||||||
|
addProtectedField(assetText(name, Asset), TypeImageAssetId, Offset(m##name##AssetId, consoleClass), _set##name##Data, &defaultProtectedGetFn, arraySize, assetDoc(name, asset docs.));
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define INITPERSISTFIELD_IMAGEASSET_ARRAY(name, arraySize, consoleClass, docs) \
|
||||||
|
addProtectedField(#name, TypeImageFilename, Offset(m##name##Name, consoleClass), _set##name##Data, &defaultProtectedGetFn, arraySize, assetDoc(name, docs), AbstractClassRep::FIELD_HideInInspectors); \
|
||||||
|
addProtectedField(assetText(name, Asset), TypeImageAssetId, Offset(m##name##AssetId, consoleClass), _set##name##Data, &defaultProtectedGetFn, arraySize, assetDoc(name, asset docs.));
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define CLONE_IMAGEASSET_ARRAY(name, index) \
|
||||||
|
{\
|
||||||
|
m##name##Name[index] = other.m##name##Name[index];\
|
||||||
|
m##name##AssetId[index] = other.m##name##AssetId[index];\
|
||||||
|
m##name##Asset[index] = other.m##name##Asset[index];\
|
||||||
|
}
|
||||||
|
|
||||||
|
#define LOAD_IMAGEASSET_ARRAY(name, index)\
|
||||||
|
if (m##name##AssetId[index] != StringTable->EmptyString())\
|
||||||
|
{\
|
||||||
|
S32 assetState = ImageAsset::getAssetById(m##name##AssetId[index], &m##name##Asset[index]);\
|
||||||
|
if (assetState == ImageAsset::Ok )\
|
||||||
|
{\
|
||||||
|
m##name##Name[index] = StringTable->EmptyString();\
|
||||||
|
}\
|
||||||
|
else Con::warnf("Warning: %s::LOAD_IMAGEASSET(%s)-%s", mClassName, m##name##AssetId[index], ImageAsset::getAssetErrstrn(assetState).c_str());\
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PACKDATA_IMAGEASSET_ARRAY(name, index)\
|
||||||
|
if (stream->writeFlag(m##name##Asset[index].notNull()))\
|
||||||
|
{\
|
||||||
|
stream->writeString(m##name##Asset[index].getAssetId());\
|
||||||
|
}\
|
||||||
|
else\
|
||||||
|
stream->writeString(m##name##Name[index]);
|
||||||
|
|
||||||
|
#define UNPACKDATA_IMAGEASSET_ARRAY(name, index)\
|
||||||
|
if (stream->readFlag())\
|
||||||
|
{\
|
||||||
|
m##name##AssetId[index] = stream->readSTString();\
|
||||||
|
_set##name(m##name##AssetId[index], index);\
|
||||||
|
}\
|
||||||
|
else\
|
||||||
|
m##name##Name[index] = stream->readSTString();
|
||||||
|
|
||||||
|
#define PACK_IMAGEASSET_ARRAY(netconn, name, index)\
|
||||||
|
if (stream->writeFlag(m##name##Asset[index].notNull()))\
|
||||||
|
{\
|
||||||
|
NetStringHandle assetIdStr = m##name##Asset[index].getAssetId();\
|
||||||
|
netconn->packNetStringHandleU(stream, assetIdStr);\
|
||||||
|
}\
|
||||||
|
else\
|
||||||
|
stream->writeString(m##name##Name[index]);
|
||||||
|
|
||||||
|
#define UNPACK_IMAGEASSET_ARRAY(netconn, name, index)\
|
||||||
|
if (stream->readFlag())\
|
||||||
|
{\
|
||||||
|
m##name##AssetId[index] = StringTable->insert(netconn->unpackNetStringHandleU(stream).getString());\
|
||||||
|
_set##name(m##name##AssetId[index], index);\
|
||||||
|
}\
|
||||||
|
else\
|
||||||
|
m##name##Name[index] = stream->readSTString();
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
31
Engine/source/T3D/assets/ImageAssetInspectors.h
Normal file
31
Engine/source/T3D/assets/ImageAssetInspectors.h
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ImageAsset.h"
|
||||||
|
|
||||||
|
#ifndef _GUI_INSPECTOR_TYPES_H_
|
||||||
|
#include "gui/editor/guiInspectorTypes.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class GuiInspectorTypeImageAssetPtr : public GuiInspectorTypeFileName
|
||||||
|
{
|
||||||
|
typedef GuiInspectorTypeFileName Parent;
|
||||||
|
public:
|
||||||
|
|
||||||
|
GuiBitmapButtonCtrl* mImageEdButton;
|
||||||
|
|
||||||
|
DECLARE_CONOBJECT(GuiInspectorTypeImageAssetPtr);
|
||||||
|
static void consoleInit();
|
||||||
|
|
||||||
|
virtual GuiControl* constructEditControl();
|
||||||
|
virtual bool updateRects();
|
||||||
|
bool renderTooltip(const Point2I& hoverPos, const Point2I& cursorPos, const char* tipText = NULL);
|
||||||
|
};
|
||||||
|
|
||||||
|
class GuiInspectorTypeImageAssetId : public GuiInspectorTypeImageAssetPtr
|
||||||
|
{
|
||||||
|
typedef GuiInspectorTypeImageAssetPtr Parent;
|
||||||
|
public:
|
||||||
|
|
||||||
|
DECLARE_CONOBJECT(GuiInspectorTypeImageAssetId);
|
||||||
|
static void consoleInit();
|
||||||
|
};
|
||||||
|
|
@ -47,14 +47,14 @@
|
||||||
|
|
||||||
IMPLEMENT_CONOBJECT(LevelAsset);
|
IMPLEMENT_CONOBJECT(LevelAsset);
|
||||||
|
|
||||||
ConsoleType(LevelAssetPtr, TypeLevelAssetPtr, String, ASSET_ID_FIELD_PREFIX)
|
ConsoleType(LevelAssetPtr, TypeLevelAssetPtr, const char*, ASSET_ID_FIELD_PREFIX)
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
ConsoleGetType(TypeLevelAssetPtr)
|
ConsoleGetType(TypeLevelAssetPtr)
|
||||||
{
|
{
|
||||||
// Fetch asset Id.
|
// Fetch asset Id.
|
||||||
return *((StringTableEntry*)dptr);
|
return *((const char**)(dptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
@ -65,13 +65,7 @@ ConsoleSetType(TypeLevelAssetPtr)
|
||||||
if (argc == 1)
|
if (argc == 1)
|
||||||
{
|
{
|
||||||
// Yes, so fetch field value.
|
// Yes, so fetch field value.
|
||||||
const char* pFieldValue = argv[0];
|
*((const char**)dptr) = StringTable->insert(argv[0]);
|
||||||
|
|
||||||
// Fetch asset Id.
|
|
||||||
StringTableEntry* assetId = (StringTableEntry*)(dptr);
|
|
||||||
|
|
||||||
// Update asset value.
|
|
||||||
*assetId = StringTable->insert(pFieldValue);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -86,14 +80,12 @@ LevelAsset::LevelAsset() : AssetBase(), mIsSubLevel(false)
|
||||||
{
|
{
|
||||||
mLevelName = StringTable->EmptyString();
|
mLevelName = StringTable->EmptyString();
|
||||||
mLevelFile = StringTable->EmptyString();
|
mLevelFile = StringTable->EmptyString();
|
||||||
mPreviewImage = StringTable->EmptyString();
|
|
||||||
mPostFXPresetFile = StringTable->EmptyString();
|
mPostFXPresetFile = StringTable->EmptyString();
|
||||||
mDecalsFile = StringTable->EmptyString();
|
mDecalsFile = StringTable->EmptyString();
|
||||||
mForestFile = StringTable->EmptyString();
|
mForestFile = StringTable->EmptyString();
|
||||||
mNavmeshFile = StringTable->EmptyString();
|
mNavmeshFile = StringTable->EmptyString();
|
||||||
|
|
||||||
mLevelPath = StringTable->EmptyString();
|
mLevelPath = StringTable->EmptyString();
|
||||||
mPreviewImagePath = StringTable->EmptyString();
|
|
||||||
mPostFXPresetPath = StringTable->EmptyString();
|
mPostFXPresetPath = StringTable->EmptyString();
|
||||||
mDecalsPath = StringTable->EmptyString();
|
mDecalsPath = StringTable->EmptyString();
|
||||||
mForestPath = StringTable->EmptyString();
|
mForestPath = StringTable->EmptyString();
|
||||||
|
|
@ -104,6 +96,9 @@ LevelAsset::LevelAsset() : AssetBase(), mIsSubLevel(false)
|
||||||
|
|
||||||
mEditorFile = StringTable->EmptyString();
|
mEditorFile = StringTable->EmptyString();
|
||||||
mBakedSceneFile = StringTable->EmptyString();
|
mBakedSceneFile = StringTable->EmptyString();
|
||||||
|
|
||||||
|
mPreviewImageAssetId = StringTable->EmptyString();
|
||||||
|
mPreviewImageAsset = StringTable->EmptyString();
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
@ -122,8 +117,6 @@ void LevelAsset::initPersistFields()
|
||||||
addProtectedField("LevelFile", TypeAssetLooseFilePath, Offset(mLevelFile, LevelAsset),
|
addProtectedField("LevelFile", TypeAssetLooseFilePath, Offset(mLevelFile, LevelAsset),
|
||||||
&setLevelFile, &getLevelFile, "Path to the actual level file.");
|
&setLevelFile, &getLevelFile, "Path to the actual level file.");
|
||||||
addField("LevelName", TypeString, Offset(mLevelName, LevelAsset), "Human-friendly name for the level.");
|
addField("LevelName", TypeString, Offset(mLevelName, LevelAsset), "Human-friendly name for the level.");
|
||||||
addProtectedField("PreviewImage", TypeAssetLooseFilePath, Offset(mPreviewImage, LevelAsset),
|
|
||||||
&setPreviewImageFile, &getPreviewImageFile, "Path to the image used for selection preview.");
|
|
||||||
|
|
||||||
addProtectedField("PostFXPresetFile", TypeAssetLooseFilePath, Offset(mPostFXPresetFile, LevelAsset),
|
addProtectedField("PostFXPresetFile", TypeAssetLooseFilePath, Offset(mPostFXPresetFile, LevelAsset),
|
||||||
&setPostFXPresetFile, &getPostFXPresetFile, "Path to the level's postFXPreset.");
|
&setPostFXPresetFile, &getPostFXPresetFile, "Path to the level's postFXPreset.");
|
||||||
|
|
@ -157,24 +150,32 @@ void LevelAsset::initializeAsset()
|
||||||
// Call parent.
|
// Call parent.
|
||||||
Parent::initializeAsset();
|
Parent::initializeAsset();
|
||||||
|
|
||||||
// Ensure the image-file is expanded.
|
loadAsset();
|
||||||
mPreviewImagePath = expandAssetFilePath(mPreviewImage);
|
|
||||||
mLevelPath = expandAssetFilePath(mLevelFile);
|
|
||||||
mPostFXPresetPath = expandAssetFilePath(mPostFXPresetFile);
|
|
||||||
mDecalsPath = expandAssetFilePath(mDecalsFile);
|
|
||||||
mForestPath = expandAssetFilePath(mForestFile);
|
|
||||||
mNavmeshPath = expandAssetFilePath(mNavmeshFile);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LevelAsset::onAssetRefresh(void)
|
void LevelAsset::onAssetRefresh(void)
|
||||||
|
{
|
||||||
|
loadAsset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LevelAsset::loadAsset()
|
||||||
{
|
{
|
||||||
// Ensure the image-file is expanded.
|
// Ensure the image-file is expanded.
|
||||||
mPreviewImagePath = expandAssetFilePath(mPreviewImage);
|
|
||||||
mLevelPath = expandAssetFilePath(mLevelFile);
|
mLevelPath = expandAssetFilePath(mLevelFile);
|
||||||
mPostFXPresetPath = expandAssetFilePath(mPostFXPresetFile);
|
mPostFXPresetPath = expandAssetFilePath(mPostFXPresetFile);
|
||||||
mDecalsPath = expandAssetFilePath(mDecalsFile);
|
mDecalsPath = expandAssetFilePath(mDecalsFile);
|
||||||
mForestPath = expandAssetFilePath(mForestFile);
|
mForestPath = expandAssetFilePath(mForestFile);
|
||||||
mNavmeshPath = expandAssetFilePath(mNavmeshFile);
|
mNavmeshPath = expandAssetFilePath(mNavmeshFile);
|
||||||
|
|
||||||
|
StringTableEntry previewImageAssetId = getAssetDependencyField("previewImageAsset");
|
||||||
|
|
||||||
|
if (previewImageAssetId != StringTable->EmptyString())
|
||||||
|
{
|
||||||
|
mPreviewImageAssetId = previewImageAssetId;
|
||||||
|
|
||||||
|
AssetPtr<ImageAsset> previewImgAsset = mPreviewImageAssetId;
|
||||||
|
mPreviewImageAsset = previewImgAsset;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
@ -197,23 +198,19 @@ void LevelAsset::setLevelFile(const char* pLevelFile)
|
||||||
refreshAsset();
|
refreshAsset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LevelAsset::setImageFile(const char* pImageFile)
|
StringTableEntry LevelAsset::getPreviewImageAsset() const
|
||||||
{
|
{
|
||||||
// Sanity!
|
return mPreviewImageAssetId;
|
||||||
AssertFatal(pImageFile != NULL, "Cannot use a NULL image file.");
|
}
|
||||||
|
|
||||||
// Fetch image file.
|
StringTableEntry LevelAsset::getPreviewImagePath(void) const
|
||||||
pImageFile = StringTable->insert(pImageFile);
|
{
|
||||||
|
if (mPreviewImageAsset.notNull() && mPreviewImageAsset->isAssetValid())
|
||||||
|
{
|
||||||
|
return mPreviewImageAsset->getImagePath();
|
||||||
|
}
|
||||||
|
|
||||||
// Ignore no change,
|
return StringTable->EmptyString();
|
||||||
if (pImageFile == mPreviewImage)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Update.
|
|
||||||
mPreviewImage = pImageFile;
|
|
||||||
|
|
||||||
// Refresh the asset.
|
|
||||||
refreshAsset();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LevelAsset::setEditorFile(const char* pEditorFile)
|
void LevelAsset::setEditorFile(const char* pEditorFile)
|
||||||
|
|
@ -368,11 +365,18 @@ DefineEngineMethod(LevelAsset, getLevelPath, const char*, (),,
|
||||||
return object->getLevelPath();
|
return object->getLevelPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DefineEngineMethod(LevelAsset, getPreviewImageAsset, const char*, (), ,
|
||||||
|
"Gets the full path of the asset's defined preview image file.\n"
|
||||||
|
"@return The string result of the level preview image path")
|
||||||
|
{
|
||||||
|
return object->getPreviewImageAsset();
|
||||||
|
}
|
||||||
|
|
||||||
DefineEngineMethod(LevelAsset, getPreviewImagePath, const char*, (), ,
|
DefineEngineMethod(LevelAsset, getPreviewImagePath, const char*, (), ,
|
||||||
"Gets the full path of the asset's defined preview image file.\n"
|
"Gets the full path of the asset's defined preview image file.\n"
|
||||||
"@return The string result of the level preview image path")
|
"@return The string result of the level preview image path")
|
||||||
{
|
{
|
||||||
return object->getImagePath();
|
return object->getPreviewImagePath();
|
||||||
}
|
}
|
||||||
|
|
||||||
DefineEngineMethod(LevelAsset, getPostFXPresetPath, const char*, (), ,
|
DefineEngineMethod(LevelAsset, getPostFXPresetPath, const char*, (), ,
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@
|
||||||
#ifndef _ASSET_FIELD_TYPES_H_
|
#ifndef _ASSET_FIELD_TYPES_H_
|
||||||
#include "assets/assetFieldTypes.h"
|
#include "assets/assetFieldTypes.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include "T3D/assets/ImageAsset.h"
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
class LevelAsset : public AssetBase
|
class LevelAsset : public AssetBase
|
||||||
|
|
@ -50,14 +51,12 @@ class LevelAsset : public AssetBase
|
||||||
StringTableEntry mDecalsFile;
|
StringTableEntry mDecalsFile;
|
||||||
StringTableEntry mForestFile;
|
StringTableEntry mForestFile;
|
||||||
StringTableEntry mNavmeshFile;
|
StringTableEntry mNavmeshFile;
|
||||||
StringTableEntry mPreviewImage;
|
|
||||||
|
|
||||||
StringTableEntry mLevelPath;
|
StringTableEntry mLevelPath;
|
||||||
StringTableEntry mPostFXPresetPath;
|
StringTableEntry mPostFXPresetPath;
|
||||||
StringTableEntry mDecalsPath;
|
StringTableEntry mDecalsPath;
|
||||||
StringTableEntry mForestPath;
|
StringTableEntry mForestPath;
|
||||||
StringTableEntry mNavmeshPath;
|
StringTableEntry mNavmeshPath;
|
||||||
StringTableEntry mPreviewImagePath;
|
|
||||||
|
|
||||||
StringTableEntry mEditorFile;
|
StringTableEntry mEditorFile;
|
||||||
StringTableEntry mBakedSceneFile;
|
StringTableEntry mBakedSceneFile;
|
||||||
|
|
@ -69,6 +68,9 @@ class LevelAsset : public AssetBase
|
||||||
|
|
||||||
Vector<AssetBase*> mAssetDependencies;
|
Vector<AssetBase*> mAssetDependencies;
|
||||||
|
|
||||||
|
StringTableEntry mPreviewImageAssetId;
|
||||||
|
AssetPtr<ImageAsset> mPreviewImageAsset;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LevelAsset();
|
LevelAsset();
|
||||||
virtual ~LevelAsset();
|
virtual ~LevelAsset();
|
||||||
|
|
@ -93,15 +95,16 @@ public:
|
||||||
inline StringTableEntry getForestFile(void) const { return mForestFile; };
|
inline StringTableEntry getForestFile(void) const { return mForestFile; };
|
||||||
void setNavmeshFile(const char* pNavmeshFile);
|
void setNavmeshFile(const char* pNavmeshFile);
|
||||||
inline StringTableEntry getNavmeshFile(void) const { return mNavmeshFile; };
|
inline StringTableEntry getNavmeshFile(void) const { return mNavmeshFile; };
|
||||||
void setImageFile(const char* pImageFile);
|
|
||||||
inline StringTableEntry getImageFile(void) const { return mPreviewImage; };
|
StringTableEntry getPreviewImageAsset(void) const;
|
||||||
|
|
||||||
inline StringTableEntry getLevelPath(void) const { return mLevelPath; };
|
inline StringTableEntry getLevelPath(void) const { return mLevelPath; };
|
||||||
inline StringTableEntry getPostFXPresetPath(void) const { return mPostFXPresetPath; };
|
inline StringTableEntry getPostFXPresetPath(void) const { return mPostFXPresetPath; };
|
||||||
inline StringTableEntry getDecalsPath(void) const { return mDecalsPath; };
|
inline StringTableEntry getDecalsPath(void) const { return mDecalsPath; };
|
||||||
inline StringTableEntry getForestPath(void) const { return mForestPath; };
|
inline StringTableEntry getForestPath(void) const { return mForestPath; };
|
||||||
inline StringTableEntry getNavmeshPath(void) const { return mNavmeshPath; };
|
inline StringTableEntry getNavmeshPath(void) const { return mNavmeshPath; };
|
||||||
inline StringTableEntry getImagePath(void) const { return mPreviewImagePath; };
|
|
||||||
|
StringTableEntry getPreviewImagePath(void) const;
|
||||||
|
|
||||||
void setEditorFile(const char* pEditorFile);
|
void setEditorFile(const char* pEditorFile);
|
||||||
inline StringTableEntry getEditorFile(void) const { return mEditorFile; };
|
inline StringTableEntry getEditorFile(void) const { return mEditorFile; };
|
||||||
|
|
@ -113,8 +116,6 @@ public:
|
||||||
protected:
|
protected:
|
||||||
static bool setLevelFile(void *obj, const char *index, const char *data) { static_cast<LevelAsset*>(obj)->setLevelFile(data); return false; }
|
static bool setLevelFile(void *obj, const char *index, const char *data) { static_cast<LevelAsset*>(obj)->setLevelFile(data); return false; }
|
||||||
static const char* getLevelFile(void* obj, const char* data) { return static_cast<LevelAsset*>(obj)->getLevelFile(); }
|
static const char* getLevelFile(void* obj, const char* data) { return static_cast<LevelAsset*>(obj)->getLevelFile(); }
|
||||||
static bool setPreviewImageFile(void *obj, const char *index, const char *data) { static_cast<LevelAsset*>(obj)->setImageFile(data); return false; }
|
|
||||||
static const char* getPreviewImageFile(void* obj, const char* data) { return static_cast<LevelAsset*>(obj)->getImageFile(); }
|
|
||||||
|
|
||||||
static bool setEditorFile(void* obj, const char* index, const char* data) { static_cast<LevelAsset*>(obj)->setEditorFile(data); return false; }
|
static bool setEditorFile(void* obj, const char* index, const char* data) { static_cast<LevelAsset*>(obj)->setEditorFile(data); return false; }
|
||||||
static const char* getEditorFile(void* obj, const char* data) { return static_cast<LevelAsset*>(obj)->getEditorFile(); }
|
static const char* getEditorFile(void* obj, const char* data) { return static_cast<LevelAsset*>(obj)->getEditorFile(); }
|
||||||
|
|
@ -134,6 +135,7 @@ protected:
|
||||||
|
|
||||||
virtual void initializeAsset(void);
|
virtual void initializeAsset(void);
|
||||||
virtual void onAssetRefresh(void);
|
virtual void onAssetRefresh(void);
|
||||||
|
void loadAsset();
|
||||||
};
|
};
|
||||||
|
|
||||||
DefineConsoleType(TypeLevelAssetPtr, LevelAsset)
|
DefineConsoleType(TypeLevelAssetPtr, LevelAsset)
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,8 @@
|
||||||
|
|
||||||
#include "T3D/assets/assetImporter.h"
|
#include "T3D/assets/assetImporter.h"
|
||||||
|
|
||||||
|
StringTableEntry MaterialAsset::smNoMaterialAssetFallback(StringTable->insert(Con::getVariable("$Core::NoMaterialAssetFallback")));
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
IMPLEMENT_CONOBJECT(MaterialAsset);
|
IMPLEMENT_CONOBJECT(MaterialAsset);
|
||||||
|
|
@ -89,7 +91,7 @@ ConsoleSetType(TypeMaterialAssetPtr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ConsoleType(assetIdString, TypeMaterialAssetId, String, ASSET_ID_FIELD_PREFIX)
|
ConsoleType(assetIdString, TypeMaterialAssetId, const char*, ASSET_ID_FIELD_PREFIX)
|
||||||
|
|
||||||
ConsoleGetType(TypeMaterialAssetId)
|
ConsoleGetType(TypeMaterialAssetId)
|
||||||
{
|
{
|
||||||
|
|
@ -125,16 +127,26 @@ MaterialAsset::MaterialAsset()
|
||||||
mScriptFile = StringTable->EmptyString();
|
mScriptFile = StringTable->EmptyString();
|
||||||
mScriptPath = StringTable->EmptyString();
|
mScriptPath = StringTable->EmptyString();
|
||||||
mMatDefinitionName = StringTable->EmptyString();
|
mMatDefinitionName = StringTable->EmptyString();
|
||||||
|
mMaterialDefinition = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
MaterialAsset::~MaterialAsset()
|
MaterialAsset::~MaterialAsset()
|
||||||
{
|
{
|
||||||
|
//SAFE_DELETE(mMaterialDefinition);
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void MaterialAsset::consoleInit()
|
||||||
|
{
|
||||||
|
Parent::consoleInit();
|
||||||
|
Con::addVariable("$Core::NoMaterialAssetFallback", TypeString, &smNoMaterialAssetFallback,
|
||||||
|
"The assetId of the material to display when the requested material asset is missing.\n"
|
||||||
|
"@ingroup GFX\n");
|
||||||
|
}
|
||||||
|
|
||||||
void MaterialAsset::initPersistFields()
|
void MaterialAsset::initPersistFields()
|
||||||
{
|
{
|
||||||
// Call parent.
|
// Call parent.
|
||||||
|
|
@ -152,32 +164,22 @@ void MaterialAsset::initializeAsset()
|
||||||
// Call parent.
|
// Call parent.
|
||||||
Parent::initializeAsset();
|
Parent::initializeAsset();
|
||||||
|
|
||||||
compileShader();
|
|
||||||
|
|
||||||
mScriptPath = getOwned() ? expandAssetFilePath(mScriptFile) : mScriptPath;
|
mScriptPath = getOwned() ? expandAssetFilePath(mScriptFile) : mScriptPath;
|
||||||
|
|
||||||
if (Platform::isFile(mScriptPath))
|
if (Torque::FS::IsScriptFile(mScriptPath))
|
||||||
Con::executeFile(mScriptPath, false, false);
|
Con::executeFile(mScriptPath, false, false);
|
||||||
|
|
||||||
|
loadMaterial();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaterialAsset::onAssetRefresh()
|
void MaterialAsset::onAssetRefresh()
|
||||||
{
|
{
|
||||||
mScriptPath = getOwned() ? expandAssetFilePath(mScriptFile) : mScriptPath;
|
mScriptPath = getOwned() ? expandAssetFilePath(mScriptFile) : mScriptPath;
|
||||||
|
|
||||||
if (Platform::isFile(mScriptPath))
|
if (Torque::FS::IsScriptFile(mScriptPath))
|
||||||
Con::executeFile(mScriptPath, false, false);
|
Con::executeFile(mScriptPath, false, false);
|
||||||
|
|
||||||
if (mMatDefinitionName != StringTable->EmptyString())
|
loadMaterial();
|
||||||
{
|
|
||||||
Material* matDef;
|
|
||||||
if (!Sim::findObject(mMatDefinitionName, matDef))
|
|
||||||
{
|
|
||||||
Con::errorf("MaterialAsset: Unable to find the Material %s", mMatDefinitionName);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
matDef->reload();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaterialAsset::setScriptFile(const char* pScriptFile)
|
void MaterialAsset::setScriptFile(const char* pScriptFile)
|
||||||
|
|
@ -197,142 +199,162 @@ void MaterialAsset::setScriptFile(const char* pScriptFile)
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
void MaterialAsset::compileShader()
|
void MaterialAsset::loadMaterial()
|
||||||
{
|
{
|
||||||
|
if (mMaterialDefinition)
|
||||||
|
SAFE_DELETE(mMaterialDefinition);
|
||||||
|
|
||||||
|
if (mMatDefinitionName != StringTable->EmptyString())
|
||||||
|
{
|
||||||
|
Material* matDef;
|
||||||
|
if (!Sim::findObject(mMatDefinitionName, matDef))
|
||||||
|
{
|
||||||
|
Con::errorf("MaterialAsset: Unable to find the Material %s", mMatDefinitionName);
|
||||||
|
mLoadedState = BadFileReference;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mMaterialDefinition = matDef;
|
||||||
|
|
||||||
|
mLoadedState = Ok;
|
||||||
|
|
||||||
|
mMaterialDefinition->reload();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mLoadedState = Failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
void MaterialAsset::copyTo(SimObject* object)
|
void MaterialAsset::copyTo(SimObject* object)
|
||||||
{
|
{
|
||||||
// Call to parent.
|
// Call to parent.
|
||||||
Parent::copyTo(object);
|
Parent::copyTo(object);
|
||||||
}
|
}
|
||||||
|
|
||||||
DefineEngineMethod(MaterialAsset, compileShader, void, (), , "Compiles the material's generated shader, if any. Not yet implemented\n")
|
|
||||||
{
|
|
||||||
object->compileShader();
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
StringTableEntry MaterialAsset::getAssetIdByMaterialName(StringTableEntry matName)
|
U32 MaterialAsset::getAssetByMaterialName(StringTableEntry matName, AssetPtr<MaterialAsset>* matAsset)
|
||||||
{
|
{
|
||||||
StringTableEntry materialAssetId = StringTable->EmptyString();
|
AssetQuery query;
|
||||||
|
U32 foundAssetcount = AssetDatabase.findAssetType(&query, "MaterialAsset");
|
||||||
AssetQuery* query = new AssetQuery();
|
if (foundAssetcount == 0)
|
||||||
U32 foundCount = AssetDatabase.findAssetType(query, "MaterialAsset");
|
|
||||||
if (foundCount == 0)
|
|
||||||
{
|
{
|
||||||
//Didn't work, so have us fall back to a placeholder asset
|
//Didn't work, so have us fall back to a placeholder asset
|
||||||
materialAssetId = StringTable->insert("Core_Rendering:noMaterial");
|
matAsset->setAssetId(MaterialAsset::smNoMaterialAssetFallback);
|
||||||
|
|
||||||
|
if (matAsset->isNull())
|
||||||
|
{
|
||||||
|
//Well that's bad, loading the fallback failed.
|
||||||
|
Con::warnf("MaterialAsset::getAssetByMaterialName - Finding of asset associated with material name %s failed with no fallback asset", matName);
|
||||||
|
return AssetErrCode::Failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
//handle noshape not being loaded itself
|
||||||
|
if ((*matAsset)->mLoadedState == BadFileReference)
|
||||||
|
{
|
||||||
|
Con::warnf("ShapeAsset::getAssetByMaterialName - Finding of associated with aterial name %s failed, and fallback asset reported error of Bad File Reference.", matName);
|
||||||
|
return AssetErrCode::BadFileReference;
|
||||||
|
}
|
||||||
|
|
||||||
|
Con::warnf("ShapeAsset::getAssetByMaterialName - Finding of associated with aterial name %s failed, utilizing fallback asset", matName);
|
||||||
|
|
||||||
|
(*matAsset)->mLoadedState = AssetErrCode::UsingFallback;
|
||||||
|
return AssetErrCode::UsingFallback;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
for (U32 i = 0; i < foundAssetcount; i++)
|
||||||
|
{
|
||||||
|
MaterialAsset* tMatAsset = AssetDatabase.acquireAsset<MaterialAsset>(query.mAssetList[i]);
|
||||||
|
if (tMatAsset && tMatAsset->getMaterialDefinitionName() == matName)
|
||||||
|
{
|
||||||
|
matAsset->setAssetId(query.mAssetList[i]);
|
||||||
|
AssetDatabase.releaseAsset(query.mAssetList[i]);
|
||||||
|
return (*matAsset)->mLoadedState;
|
||||||
|
}
|
||||||
|
AssetDatabase.releaseAsset(query.mAssetList[i]); //cleanup if that's not the one we needed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StringTableEntry MaterialAsset::getAssetIdByMaterialName(StringTableEntry matName)
|
||||||
|
{
|
||||||
|
if (matName == StringTable->EmptyString())
|
||||||
|
return StringTable->EmptyString();
|
||||||
|
|
||||||
|
StringTableEntry materialAssetId = MaterialAsset::smNoMaterialAssetFallback;
|
||||||
|
|
||||||
|
AssetQuery query;
|
||||||
|
U32 foundCount = AssetDatabase.findAssetType(&query, "MaterialAsset");
|
||||||
|
if (foundCount != 0)
|
||||||
{
|
{
|
||||||
for (U32 i = 0; i < foundCount; i++)
|
for (U32 i = 0; i < foundCount; i++)
|
||||||
{
|
{
|
||||||
MaterialAsset* matAsset = AssetDatabase.acquireAsset<MaterialAsset>(query->mAssetList[i]);
|
MaterialAsset* matAsset = AssetDatabase.acquireAsset<MaterialAsset>(query.mAssetList[i]);
|
||||||
if (matAsset && matAsset->getMaterialDefinitionName() == matName)
|
if (matAsset && matAsset->getMaterialDefinitionName() == matName)
|
||||||
{
|
{
|
||||||
materialAssetId = matAsset->getAssetId();
|
materialAssetId = matAsset->getAssetId();
|
||||||
|
AssetDatabase.releaseAsset(query.mAssetList[i]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
AssetDatabase.releaseAsset(query->mAssetList[i]); //cleanup if that's not the one we needed
|
AssetDatabase.releaseAsset(query.mAssetList[i]);
|
||||||
}
|
|
||||||
|
|
||||||
if (materialAssetId == StringTable->EmptyString())
|
|
||||||
{
|
|
||||||
//Try auto-importing it if it exists already
|
|
||||||
BaseMaterialDefinition* baseMatDef;
|
|
||||||
if (!Sim::findObject(matName, baseMatDef))
|
|
||||||
{
|
|
||||||
//Not even a real material, apparently?
|
|
||||||
//return back a blank
|
|
||||||
return StringTable->EmptyString();
|
|
||||||
}
|
|
||||||
|
|
||||||
//Ok, a real mat def, we can work with this
|
|
||||||
#if TORQUE_DEBUG
|
|
||||||
Con::warnf("MaterialAsset::getAssetIdByMaterialName - Attempted to in-place import a material(%s) that had no associated asset", matName);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
AssetImporter* autoAssetImporter;
|
|
||||||
if (!Sim::findObject("autoAssetImporter", autoAssetImporter))
|
|
||||||
{
|
|
||||||
autoAssetImporter = new AssetImporter();
|
|
||||||
autoAssetImporter->registerObject("autoAssetImporter");
|
|
||||||
}
|
|
||||||
|
|
||||||
autoAssetImporter->resetImportSession(true);
|
|
||||||
|
|
||||||
String originalMaterialDefFile = Torque::Path(baseMatDef->getFilename()).getPath();
|
|
||||||
|
|
||||||
autoAssetImporter->setTargetPath(originalMaterialDefFile);
|
|
||||||
|
|
||||||
autoAssetImporter->resetImportConfig();
|
|
||||||
|
|
||||||
AssetImportObject* assetObj = autoAssetImporter->addImportingAsset("MaterialAsset", originalMaterialDefFile, nullptr, matName);
|
|
||||||
|
|
||||||
//Find out if the filepath has an associated module to it. If we're importing in-place, it needs to be within a module's directory
|
|
||||||
ModuleDefinition* targetModuleDef = AssetImporter::getModuleFromPath(originalMaterialDefFile);
|
|
||||||
|
|
||||||
if (targetModuleDef == nullptr)
|
|
||||||
{
|
|
||||||
return StringTable->EmptyString();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
autoAssetImporter->setTargetModuleId(targetModuleDef->getModuleId());
|
|
||||||
}
|
|
||||||
|
|
||||||
autoAssetImporter->processImportAssets();
|
|
||||||
|
|
||||||
bool hasIssues = autoAssetImporter->validateAssets();
|
|
||||||
|
|
||||||
if (hasIssues)
|
|
||||||
{
|
|
||||||
//log it
|
|
||||||
Con::errorf("Error! Import process of Material(%s) has failed due to issues discovered during validation!", matName);
|
|
||||||
return StringTable->EmptyString();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
autoAssetImporter->importAssets();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if TORQUE_DEBUG
|
|
||||||
autoAssetImporter->dumpActivityLog();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (hasIssues)
|
|
||||||
{
|
|
||||||
return StringTable->EmptyString();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
String assetId = autoAssetImporter->getTargetModuleId() + ":" + assetObj->assetName;
|
|
||||||
return StringTable->insert(assetId.c_str());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return materialAssetId;
|
return materialAssetId;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MaterialAsset::getAssetById(StringTableEntry assetId, AssetPtr<MaterialAsset>* materialAsset)
|
U32 MaterialAsset::getAssetById(StringTableEntry assetId, AssetPtr<MaterialAsset>* materialAsset)
|
||||||
{
|
{
|
||||||
(*materialAsset) = assetId;
|
(*materialAsset) = assetId;
|
||||||
|
|
||||||
if (!materialAsset->isNull())
|
if (materialAsset->notNull())
|
||||||
return true;
|
{
|
||||||
|
return (*materialAsset)->mLoadedState;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Didn't work, so have us fall back to a placeholder asset
|
||||||
|
materialAsset->setAssetId(MaterialAsset::smNoMaterialAssetFallback);
|
||||||
|
|
||||||
//Didn't work, so have us fall back to a placeholder asset
|
if (materialAsset->isNull())
|
||||||
StringTableEntry noImageId = StringTable->insert("Core_Rendering:noMaterial");
|
{
|
||||||
materialAsset->setAssetId(noImageId);
|
//Well that's bad, loading the fallback failed.
|
||||||
|
Con::warnf("MaterialAsset::getAssetById - Finding of asset with id %s failed with no fallback asset", assetId);
|
||||||
|
return AssetErrCode::Failed;
|
||||||
|
}
|
||||||
|
|
||||||
if (!materialAsset->isNull())
|
//handle noshape not being loaded itself
|
||||||
return true;
|
if ((*materialAsset)->mLoadedState == BadFileReference)
|
||||||
|
{
|
||||||
|
Con::warnf("MaterialAsset::getAssetById - Finding of asset with id %s failed, and fallback asset reported error of Bad File Reference.", assetId);
|
||||||
|
return AssetErrCode::BadFileReference;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
Con::warnf("MaterialAsset::getAssetById - Finding of asset with id %s failed, utilizing fallback asset", assetId);
|
||||||
|
|
||||||
|
(*materialAsset)->mLoadedState = AssetErrCode::UsingFallback;
|
||||||
|
return AssetErrCode::UsingFallback;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef TORQUE_TOOLS
|
||||||
|
DefineEngineStaticMethod(MaterialAsset, getAssetIdByMaterialName, const char*, (const char* materialName), (""),
|
||||||
|
"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.")
|
||||||
|
{
|
||||||
|
return MaterialAsset::getAssetIdByMaterialName(StringTable->insert(materialName));
|
||||||
|
}
|
||||||
|
|
||||||
|
DefineEngineMethod(MaterialAsset, getScriptPath, const char*, (), ,
|
||||||
|
"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.")
|
||||||
|
{
|
||||||
|
return object->getScriptPath();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// GuiInspectorTypeAssetId
|
// GuiInspectorTypeAssetId
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
@ -373,13 +395,13 @@ GuiControl* GuiInspectorTypeMaterialAssetPtr::constructEditControl()
|
||||||
dSprintf(szBuffer, sizeof(szBuffer), "AssetBrowser.editAsset(%d.getText());", retCtrl->getId());
|
dSprintf(szBuffer, sizeof(szBuffer), "AssetBrowser.editAsset(%d.getText());", retCtrl->getId());
|
||||||
mEditButton->setField("Command", szBuffer);
|
mEditButton->setField("Command", szBuffer);
|
||||||
|
|
||||||
char bitmapName[512] = "tools/worldEditor/images/toolbar/material-editor";
|
char bitmapName[512] = "ToolsModule:material_editor_n_image";
|
||||||
mEditButton->setBitmap(bitmapName);
|
mEditButton->setBitmap(StringTable->insert(bitmapName));
|
||||||
|
|
||||||
mEditButton->setDataField(StringTable->insert("Profile"), NULL, "GuiButtonProfile");
|
mEditButton->setDataField(StringTable->insert("Profile"), NULL, "GuiButtonProfile");
|
||||||
mEditButton->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile");
|
mEditButton->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile");
|
||||||
mEditButton->setDataField(StringTable->insert("hovertime"), NULL, "1000");
|
mEditButton->setDataField(StringTable->insert("hovertime"), NULL, "1000");
|
||||||
mEditButton->setDataField(StringTable->insert("tooltip"), NULL, "Open this file in the Material Editor");
|
mEditButton->setDataField(StringTable->insert("tooltip"), NULL, "Open this asset in the Material Editor");
|
||||||
|
|
||||||
mEditButton->registerObject();
|
mEditButton->registerObject();
|
||||||
addObject(mEditButton);
|
addObject(mEditButton);
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@
|
||||||
#include "materials/matTextureTarget.h"
|
#include "materials/matTextureTarget.h"
|
||||||
#include "materials/materialDefinition.h"
|
#include "materials/materialDefinition.h"
|
||||||
#include "materials/customMaterialDefinition.h"
|
#include "materials/customMaterialDefinition.h"
|
||||||
|
#include "materials/materialManager.h"
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
class MaterialAsset : public AssetBase
|
class MaterialAsset : public AssetBase
|
||||||
|
|
@ -64,25 +65,42 @@ class MaterialAsset : public AssetBase
|
||||||
StringTableEntry mScriptPath;
|
StringTableEntry mScriptPath;
|
||||||
StringTableEntry mMatDefinitionName;
|
StringTableEntry mMatDefinitionName;
|
||||||
|
|
||||||
|
SimObjectPtr<Material> mMaterialDefinition;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static StringTableEntry smNoMaterialAssetFallback;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MaterialAsset();
|
MaterialAsset();
|
||||||
virtual ~MaterialAsset();
|
virtual ~MaterialAsset();
|
||||||
|
|
||||||
|
/// Set up some global script interface stuff.
|
||||||
|
static void consoleInit();
|
||||||
|
|
||||||
/// Engine.
|
/// Engine.
|
||||||
static void initPersistFields();
|
static void initPersistFields();
|
||||||
virtual void copyTo(SimObject* object);
|
virtual void copyTo(SimObject* object);
|
||||||
|
|
||||||
void compileShader();
|
void loadMaterial();
|
||||||
|
|
||||||
StringTableEntry getMaterialDefinitionName() { return mMatDefinitionName; }
|
StringTableEntry getMaterialDefinitionName() { return mMatDefinitionName; }
|
||||||
|
SimObjectPtr<Material> getMaterialDefinition() { return mMaterialDefinition; }
|
||||||
|
|
||||||
void setScriptFile(const char* pScriptFile);
|
void setScriptFile(const char* pScriptFile);
|
||||||
inline StringTableEntry getScriptFile(void) const { return mScriptFile; };
|
inline StringTableEntry getScriptFile(void) const { return mScriptFile; };
|
||||||
|
|
||||||
inline StringTableEntry getScriptPath(void) const { return mScriptPath; };
|
inline StringTableEntry getScriptPath(void) const { return mScriptPath; };
|
||||||
|
|
||||||
static StringTableEntry getAssetIdByMaterialName(StringTableEntry fileName);
|
/// <summary>
|
||||||
static bool getAssetById(StringTableEntry assetId, AssetPtr<MaterialAsset>* materialAsset);
|
/// Looks for any assets that uses the provided Material Definition name.
|
||||||
|
/// If none are found, attempts to auto-import the material definition if the
|
||||||
|
/// material definition exists.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="matName">Material Definition name to look for</param>
|
||||||
|
/// <returns>AssetId of matching asset.</returns>
|
||||||
|
static StringTableEntry getAssetIdByMaterialName(StringTableEntry matName);
|
||||||
|
static U32 getAssetById(StringTableEntry assetId, AssetPtr<MaterialAsset>* materialAsset);
|
||||||
|
static U32 getAssetByMaterialName(StringTableEntry matName, AssetPtr<MaterialAsset>* matAsset);
|
||||||
|
|
||||||
/// Declare Console Object.
|
/// Declare Console Object.
|
||||||
DECLARE_CONOBJECT(MaterialAsset);
|
DECLARE_CONOBJECT(MaterialAsset);
|
||||||
|
|
@ -124,159 +142,203 @@ public:
|
||||||
static void consoleInit();
|
static void consoleInit();
|
||||||
};
|
};
|
||||||
|
|
||||||
#define assetText(x,suff) std::string(std::string(#x) + std::string(#suff)).c_str()
|
#pragma region Singular Asset Macros
|
||||||
|
|
||||||
#define initMaterialAsset(name) m##name##Name = ""; m##name##AssetId = StringTable->EmptyString(); m##name##Asset = NULL;
|
//Singular assets
|
||||||
#define bindMaterialAsset(name) if (m##name##AssetId != StringTable->EmptyString()) m##name##Asset = m##name##AssetId;
|
/// <Summary>
|
||||||
|
/// Declares an material asset
|
||||||
#define scriptBindMaterialAsset(name, consoleClass, docs)\
|
/// This establishes the assetId, asset and legacy filepath fields, along with supplemental getter and setter functions
|
||||||
addProtectedField(assetText(name, File), TypeMaterialName, Offset(m##name##Name, consoleClass), consoleClass::_set##name##Name, & defaultProtectedGetFn, assetText(name, docs), AbstractClassRep::FIELD_HideInInspectors); \
|
/// </Summary>
|
||||||
addProtectedField(assetText(name, Asset), TypeMaterialAssetId, Offset(m##name##AssetId, consoleClass), consoleClass::_set##name##Asset, & defaultProtectedGetFn, assetText(name, asset reference.));
|
#define DECLARE_MATERIALASSET(className, name) public: \
|
||||||
|
StringTableEntry m##name##Name;\
|
||||||
#define DECLARE_MATERIALASSET(className,name) protected: \
|
StringTableEntry m##name##AssetId;\
|
||||||
String m##name##Name;\
|
AssetPtr<MaterialAsset> m##name##Asset;\
|
||||||
StringTableEntry m##name##AssetId;\
|
SimObjectPtr<Material> m##name;\
|
||||||
AssetPtr<MaterialAsset> m##name##Asset;\
|
public: \
|
||||||
public: \
|
const StringTableEntry get##name##File() const { return m##name##Name; }\
|
||||||
const String& get##name() const { return m##name##Name; }\
|
void set##name##Name(const FileName &_in) { m##name##Name = StringTable->insert(_in.c_str());}\
|
||||||
void set##name(FileName _in) { m##name##Name = _in; }\
|
const AssetPtr<MaterialAsset> & get##name##Asset() const { return m##name##Asset; }\
|
||||||
const AssetPtr<MaterialAsset> & get##name##Asset() const { return m##name##Asset; }\
|
void set##name##Asset(const AssetPtr<MaterialAsset> &_in) { m##name##Asset = _in;}\
|
||||||
void set##name##Asset(AssetPtr<MaterialAsset>_in) { m##name##Asset = _in; }\
|
|
||||||
static bool _set##name##Name(void* obj, const char* index, const char* data)\
|
|
||||||
{\
|
|
||||||
className* shape = static_cast<className*>(obj);\
|
|
||||||
\
|
\
|
||||||
StringTableEntry assetId = MaterialAsset::getAssetIdByMaterialName(StringTable->insert(data));\
|
bool _set##name(StringTableEntry _in)\
|
||||||
if (assetId != StringTable->EmptyString())\
|
|
||||||
{\
|
{\
|
||||||
if (shape->_set##name##Asset(obj, index, assetId))\
|
if(m##name##AssetId != _in || m##name##Name != _in)\
|
||||||
{\
|
{\
|
||||||
if (assetId == StringTable->insert("Core_Rendering:noMaterial"))\
|
if (_in == StringTable->EmptyString())\
|
||||||
{\
|
{\
|
||||||
shape->m##name##Name = data;\
|
m##name##Name = StringTable->EmptyString();\
|
||||||
shape->m##name##AssetId = StringTable->EmptyString();\
|
m##name##AssetId = StringTable->EmptyString();\
|
||||||
\
|
m##name##Asset = NULL;\
|
||||||
|
m##name = NULL;\
|
||||||
return true;\
|
return true;\
|
||||||
}\
|
}\
|
||||||
|
\
|
||||||
|
if (AssetDatabase.isDeclaredAsset(_in))\
|
||||||
|
{\
|
||||||
|
m##name##AssetId = _in;\
|
||||||
|
\
|
||||||
|
U32 assetState = MaterialAsset::getAssetById(m##name##AssetId, &m##name##Asset);\
|
||||||
|
\
|
||||||
|
if (MaterialAsset::Ok == assetState)\
|
||||||
|
{\
|
||||||
|
m##name##Name = StringTable->EmptyString();\
|
||||||
|
}\
|
||||||
|
}\
|
||||||
else\
|
else\
|
||||||
{\
|
{\
|
||||||
shape->m##name##AssetId = assetId;\
|
StringTableEntry assetId = MaterialAsset::getAssetIdByMaterialName(_in);\
|
||||||
shape->m##name##Name = StringTable->EmptyString();\
|
if (assetId != StringTable->EmptyString())\
|
||||||
\
|
{\
|
||||||
return false;\
|
m##name##AssetId = assetId;\
|
||||||
|
if (MaterialAsset::getAssetById(m##name##AssetId, &m##name##Asset) == MaterialAsset::Ok)\
|
||||||
|
{\
|
||||||
|
m##name##Name = StringTable->EmptyString();\
|
||||||
|
}\
|
||||||
|
}\
|
||||||
|
else\
|
||||||
|
{\
|
||||||
|
m##name##Name = _in;\
|
||||||
|
m##name##AssetId = StringTable->EmptyString();\
|
||||||
|
m##name##Asset = NULL;\
|
||||||
|
}\
|
||||||
}\
|
}\
|
||||||
}\
|
}\
|
||||||
}\
|
if (get##name() != StringTable->EmptyString() && m##name##Asset.notNull())\
|
||||||
else\
|
|
||||||
{\
|
|
||||||
shape->m##name##Asset = StringTable->EmptyString();\
|
|
||||||
}\
|
|
||||||
\
|
|
||||||
return true;\
|
|
||||||
}\
|
|
||||||
\
|
|
||||||
static bool _set##name##Asset(void* obj, const char* index, const char* data)\
|
|
||||||
{\
|
|
||||||
className* shape = static_cast<className*>(obj);\
|
|
||||||
shape->m##name##AssetId = StringTable->insert(data);\
|
|
||||||
if (MaterialAsset::getAssetById(shape->m##name##AssetId, &shape->m##name##Asset))\
|
|
||||||
{\
|
|
||||||
if (shape->m##name##Asset.getAssetId() != StringTable->insert("Core_Rendering:noMaterial"))\
|
|
||||||
shape->m##name##Name = StringTable->EmptyString();\
|
|
||||||
\
|
|
||||||
return true;\
|
|
||||||
}\
|
|
||||||
return false;\
|
|
||||||
}\
|
|
||||||
\
|
|
||||||
static bool set##name##Asset(const char* assetId)\
|
|
||||||
{\
|
|
||||||
m##name##AssetId = StringTable->insert(assetId);\
|
|
||||||
if (m##name##AssetId != StringTable->EmptyString())\
|
|
||||||
m##name##Asset = m##name##AssetId;\
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// DECLARE_MATERIALASSET is a utility macro for MaterialAssets. It takes in the name of the class using it, the name of the field for the material, and a networking bitmask
|
|
||||||
/// The first 2 are for setting up/filling out the fields and class member defines
|
|
||||||
/// The bitmask is for when the material is changed, it can automatically kick a network update on the owner object to pass the changed asset to clients
|
|
||||||
/// </summary>
|
|
||||||
#define DECLARE_NET_MATERIALASSET(className,name,bitmask) protected: \
|
|
||||||
String m##name##Name;\
|
|
||||||
StringTableEntry m##name##AssetId;\
|
|
||||||
AssetPtr<MaterialAsset> m##name##Asset;\
|
|
||||||
public: \
|
|
||||||
const String& get##name() const { return m##name##Name; }\
|
|
||||||
void set##name(FileName _in) { m##name##Name = _in; }\
|
|
||||||
const AssetPtr<MaterialAsset> & get##name##Asset() const { return m##name##Asset; }\
|
|
||||||
void set##name##Asset(AssetPtr<MaterialAsset>_in) { m##name##Asset = _in; }\
|
|
||||||
static bool _set##name##Name(void* obj, const char* index, const char* data)\
|
|
||||||
{\
|
|
||||||
className* shape = static_cast<className*>(obj);\
|
|
||||||
\
|
|
||||||
StringTableEntry assetId = MaterialAsset::getAssetIdByMaterialName(StringTable->insert(data));\
|
|
||||||
if (assetId != StringTable->EmptyString())\
|
|
||||||
{\
|
|
||||||
if (shape->_set##name##Asset(obj, index, assetId))\
|
|
||||||
{\
|
{\
|
||||||
if (assetId == StringTable->insert("Core_Rendering:noMaterial"))\
|
if (m##name && String(m##name##Asset->getMaterialDefinitionName()).equal(m##name->getName(), String::NoCase))\
|
||||||
{\
|
|
||||||
shape->m##name##Name = data;\
|
|
||||||
shape->m##name##AssetId = StringTable->EmptyString();\
|
|
||||||
\
|
|
||||||
return true;\
|
|
||||||
}\
|
|
||||||
else\
|
|
||||||
{\
|
|
||||||
shape->m##name##AssetId = assetId;\
|
|
||||||
shape->m##name##Name = StringTable->EmptyString();\
|
|
||||||
\
|
|
||||||
return false;\
|
return false;\
|
||||||
}\
|
\
|
||||||
|
Material* tempMat = nullptr;\
|
||||||
|
\
|
||||||
|
if (!Sim::findObject(m##name##Asset->getMaterialDefinitionName(), tempMat))\
|
||||||
|
Con::errorf("%s::_set%s() - Material %s was not found.", macroText(className), macroText(name), m##name##Asset->getMaterialDefinitionName());\
|
||||||
|
m##name = tempMat;\
|
||||||
|
}\
|
||||||
|
else\
|
||||||
|
{\
|
||||||
|
m##name = NULL;\
|
||||||
}\
|
}\
|
||||||
}\
|
|
||||||
else\
|
|
||||||
{\
|
|
||||||
shape->m##name##Asset = StringTable->EmptyString();\
|
|
||||||
}\
|
|
||||||
\
|
|
||||||
return true;\
|
|
||||||
}\
|
|
||||||
\
|
|
||||||
static bool _set##name##Asset(void* obj, const char* index, const char* data)\
|
|
||||||
{\
|
|
||||||
className* shape = static_cast<className*>(obj);\
|
|
||||||
shape->m##name##AssetId = StringTable->insert(data);\
|
|
||||||
if (MaterialAsset::getAssetById(shape->m##name##AssetId, &shape->m##name##Asset))\
|
|
||||||
{\
|
|
||||||
if (shape->m##name##Asset.getAssetId() != StringTable->insert("Core_Rendering:noMaterial"))\
|
|
||||||
shape->m##name##Name = StringTable->EmptyString();\
|
|
||||||
\
|
\
|
||||||
shape->setMaskBits(bitmask);\
|
if(get##name() == StringTable->EmptyString())\
|
||||||
shape->inspectPostApply();\
|
return true;\
|
||||||
return true;\
|
|
||||||
}\
|
|
||||||
shape->inspectPostApply();\
|
|
||||||
return false;\
|
|
||||||
}\
|
|
||||||
\
|
|
||||||
bool set##name##AssetId(const char* _assetId)\
|
|
||||||
{\
|
|
||||||
m##name##AssetId = StringTable->insert(_assetId);\
|
|
||||||
if (m##name##AssetId != StringTable->EmptyString())\
|
|
||||||
{\
|
|
||||||
m##name##Asset = m##name##AssetId;\
|
|
||||||
\
|
\
|
||||||
setMaskBits(bitmask);\
|
if (m##name##Asset.notNull() && m##name##Asset->getStatus() != MaterialAsset::Ok)\
|
||||||
inspectPostApply();\
|
{\
|
||||||
|
Con::errorf("%s::_set%s() - material asset failure\"%s\" due to [%s]", macroText(className), macroText(name), _in, MaterialAsset::getAssetErrstrn(m##name##Asset->getStatus()).c_str());\
|
||||||
|
return false; \
|
||||||
|
}\
|
||||||
|
else if (bool(m##name) == NULL)\
|
||||||
|
{\
|
||||||
|
Con::errorf("%s::_set%s() - Couldn't load material \"%s\"", macroText(className), macroText(name), _in);\
|
||||||
|
return false;\
|
||||||
|
}\
|
||||||
return true;\
|
return true;\
|
||||||
}\
|
}\
|
||||||
\
|
\
|
||||||
return false;\
|
const StringTableEntry get##name() const\
|
||||||
|
{\
|
||||||
|
if (m##name##Asset && (m##name##Asset->getMaterialDefinitionName() != StringTable->EmptyString()))\
|
||||||
|
return m##name##Asset->getMaterialDefinitionName();\
|
||||||
|
else if (m##name##AssetId != StringTable->EmptyString())\
|
||||||
|
return m##name##AssetId;\
|
||||||
|
else if (m##name##Name != StringTable->EmptyString())\
|
||||||
|
return m##name##Name;\
|
||||||
|
else\
|
||||||
|
return StringTable->EmptyString();\
|
||||||
|
}\
|
||||||
|
SimObjectPtr<Material> get##name##Resource() \
|
||||||
|
{\
|
||||||
|
return m##name##;\
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DECLARE_MATERIALASSET_SETGET(className, name)\
|
||||||
|
static bool _set##name##Data(void* obj, const char* index, const char* data)\
|
||||||
|
{\
|
||||||
|
bool ret = false;\
|
||||||
|
className* object = static_cast<className*>(obj);\
|
||||||
|
ret = object->_set##name(StringTable->insert(data));\
|
||||||
|
return ret;\
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DECLARE_MATERIALASSET_NET_SETGET(className, name, bitmask)\
|
||||||
|
static bool _set##name##Data(void* obj, const char* index, const char* data)\
|
||||||
|
{\
|
||||||
|
bool ret = false;\
|
||||||
|
className* object = static_cast<className*>(obj);\
|
||||||
|
ret = object->_set##name(StringTable->insert(data));\
|
||||||
|
if(ret)\
|
||||||
|
object->setMaskBits(bitmask);\
|
||||||
|
return ret;\
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DEF_MATERIALASSET_BINDS(className,name)\
|
||||||
|
DefineEngineMethod(className, get##name, const char*, (), , "get name")\
|
||||||
|
{\
|
||||||
|
return object->get##name(); \
|
||||||
|
}\
|
||||||
|
DefineEngineMethod(className, get##name##Asset, const char*, (), , assetText(name, asset reference))\
|
||||||
|
{\
|
||||||
|
return object->m##name##AssetId; \
|
||||||
|
}\
|
||||||
|
DefineEngineMethod(className, set##name, bool, (const char* mat), , assetText(name,assignment. first tries asset then material name.))\
|
||||||
|
{\
|
||||||
|
return object->_set##name(StringTable->insert(mat));\
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define INIT_MATERIALASSET(name) \
|
||||||
|
m##name##Name = StringTable->EmptyString(); \
|
||||||
|
m##name##AssetId = StringTable->EmptyString(); \
|
||||||
|
m##name##Asset = NULL;\
|
||||||
|
m##name = NULL;
|
||||||
|
|
||||||
#define packMaterialAsset(netconn, name)\
|
#ifdef TORQUE_SHOW_LEGACY_FILE_FIELDS
|
||||||
|
|
||||||
|
#define INITPERSISTFIELD_MATERIALASSET(name, consoleClass, docs) \
|
||||||
|
addProtectedField(#name, TypeMaterialName, Offset(m##name##Name, consoleClass), _set##name##Data, &defaultProtectedGetFn,assetDoc(name, docs)); \
|
||||||
|
addProtectedField(assetText(name, Asset), TypeMaterialAssetId, Offset(m##name##AssetId, consoleClass), _set##name##Data, &defaultProtectedGetFn, assetDoc(name, asset docs.));
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define INITPERSISTFIELD_MATERIALASSET(name, consoleClass, docs) \
|
||||||
|
addProtectedField(#name, TypeMaterialName, Offset(m##name##Name, consoleClass), _set##name##Data, &defaultProtectedGetFn,assetDoc(name, docs), AbstractClassRep::FIELD_HideInInspectors); \
|
||||||
|
addProtectedField(assetText(name, Asset), TypeMaterialAssetId, Offset(m##name##AssetId, consoleClass), _set##name##Data, &defaultProtectedGetFn, assetDoc(name, asset docs.));
|
||||||
|
|
||||||
|
#endif // SHOW_LEGACY_FILE_FIELDS
|
||||||
|
|
||||||
|
#define CLONE_MATERIALASSET(name) \
|
||||||
|
m##name##Name = other.m##name##Name;\
|
||||||
|
m##name##AssetId = other.m##name##AssetId;\
|
||||||
|
m##name##Asset = other.m##name##Asset;
|
||||||
|
|
||||||
|
#define LOAD_MATERIALASSET(name)\
|
||||||
|
if (m##name##AssetId != StringTable->EmptyString())\
|
||||||
|
{\
|
||||||
|
S32 assetState = MaterialAsset::getAssetById(m##name##AssetId, &m##name##Asset);\
|
||||||
|
if (assetState == MaterialAsset::Ok )\
|
||||||
|
{\
|
||||||
|
m##name##Name = StringTable->EmptyString();\
|
||||||
|
}\
|
||||||
|
else Con::warnf("Warning: %s::LOAD_MATERIALASSET(%s)-%s", mClassName, m##name##AssetId, MaterialAsset::getAssetErrstrn(assetState).c_str());\
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PACKDATA_MATERIALASSET(name)\
|
||||||
|
if (stream->writeFlag(m##name##Asset.notNull()))\
|
||||||
|
{\
|
||||||
|
stream->writeString(m##name##Asset.getAssetId());\
|
||||||
|
}\
|
||||||
|
else\
|
||||||
|
stream->writeString(m##name##Name);
|
||||||
|
|
||||||
|
#define UNPACKDATA_MATERIALASSET(name)\
|
||||||
|
if (stream->readFlag())\
|
||||||
|
{\
|
||||||
|
m##name##AssetId = stream->readSTString();\
|
||||||
|
_set##name(m##name##AssetId);\
|
||||||
|
}\
|
||||||
|
else\
|
||||||
|
m##name##Name = stream->readSTString();
|
||||||
|
|
||||||
|
#define PACK_MATERIALASSET(netconn, name)\
|
||||||
if (stream->writeFlag(m##name##Asset.notNull()))\
|
if (stream->writeFlag(m##name##Asset.notNull()))\
|
||||||
{\
|
{\
|
||||||
NetStringHandle assetIdStr = m##name##Asset.getAssetId();\
|
NetStringHandle assetIdStr = m##name##Asset.getAssetId();\
|
||||||
|
|
@ -285,14 +347,16 @@ bool set##name##AssetId(const char* _assetId)\
|
||||||
else\
|
else\
|
||||||
stream->writeString(m##name##Name);
|
stream->writeString(m##name##Name);
|
||||||
|
|
||||||
#define unpackMaterialAsset(netconn, name)\
|
#define UNPACK_MATERIALASSET(netconn, name)\
|
||||||
if (stream->readFlag())\
|
if (stream->readFlag())\
|
||||||
{\
|
{\
|
||||||
m##name##AssetId = StringTable->insert(netconn->unpackNetStringHandleU(stream).getString());\
|
m##name##AssetId = StringTable->insert(netconn->unpackNetStringHandleU(stream).getString());\
|
||||||
MaterialAsset::getAssetById(m##name##AssetId, &m##name##Asset);\
|
_set##name(m##name##AssetId);\
|
||||||
}\
|
}\
|
||||||
else\
|
else\
|
||||||
m##name##Name = stream->readSTString();\
|
m##name##Name = stream->readSTString();
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
#endif // _ASSET_BASE_H_
|
#endif // _ASSET_BASE_H_
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -160,8 +160,8 @@ GuiControl* GuiInspectorTypeParticleAssetPtr::constructEditControl()
|
||||||
dSprintf(szBuffer, sizeof(szBuffer), "echo(\"Game Object Editor not implemented yet!\");", retCtrl->getId());
|
dSprintf(szBuffer, sizeof(szBuffer), "echo(\"Game Object Editor not implemented yet!\");", retCtrl->getId());
|
||||||
mSMEdButton->setField("Command", szBuffer);
|
mSMEdButton->setField("Command", szBuffer);
|
||||||
|
|
||||||
char bitmapName[512] = "tools/worldEditor/images/toolbar/shape-editor";
|
char bitmapName[512] = "ToolsModule:shape_editor_n_image";
|
||||||
mSMEdButton->setBitmap(bitmapName);
|
mSMEdButton->setBitmap(StringTable->insert(bitmapName));
|
||||||
|
|
||||||
mSMEdButton->setDataField(StringTable->insert("Profile"), NULL, "GuiButtonProfile");
|
mSMEdButton->setDataField(StringTable->insert("Profile"), NULL, "GuiButtonProfile");
|
||||||
mSMEdButton->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile");
|
mSMEdButton->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile");
|
||||||
|
|
|
||||||
|
|
@ -136,7 +136,7 @@ void PostEffectAsset::initializeAsset()
|
||||||
mHLSLShaderPath = expandAssetFilePath(mHLSLShaderFile);
|
mHLSLShaderPath = expandAssetFilePath(mHLSLShaderFile);
|
||||||
mGLSLShaderPath = expandAssetFilePath(mGLSLShaderFile);
|
mGLSLShaderPath = expandAssetFilePath(mGLSLShaderFile);
|
||||||
|
|
||||||
if (Platform::isFile(mScriptPath))
|
if (Torque::FS::IsScriptFile(mScriptPath))
|
||||||
Con::executeFile(mScriptPath, false, false);
|
Con::executeFile(mScriptPath, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -146,7 +146,7 @@ void PostEffectAsset::onAssetRefresh()
|
||||||
mHLSLShaderPath = expandAssetFilePath(mHLSLShaderFile);
|
mHLSLShaderPath = expandAssetFilePath(mHLSLShaderFile);
|
||||||
mGLSLShaderPath = expandAssetFilePath(mGLSLShaderFile);
|
mGLSLShaderPath = expandAssetFilePath(mGLSLShaderFile);
|
||||||
|
|
||||||
if (Platform::isFile(mScriptPath))
|
if (Torque::FS::IsScriptFile(mScriptPath))
|
||||||
Con::executeFile(mScriptPath, false, false);
|
Con::executeFile(mScriptPath, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -124,7 +124,7 @@ void ScriptAsset::initializeAsset()
|
||||||
{
|
{
|
||||||
mScriptPath = expandAssetFilePath(mScriptFile);
|
mScriptPath = expandAssetFilePath(mScriptFile);
|
||||||
|
|
||||||
if (Platform::isFile(mScriptPath))
|
if (Torque::FS::IsScriptFile(mScriptPath))
|
||||||
{
|
{
|
||||||
//We're initialized properly, so we'll go ahead and kick along any dependencies we may have as well
|
//We're initialized properly, so we'll go ahead and kick along any dependencies we may have as well
|
||||||
AssetManager::typeAssetDependsOnHash::Iterator assetDependenciesItr = mpOwningAssetManager->getDependedOnAssets()->find(mpAssetDefinition->mAssetId);
|
AssetManager::typeAssetDependsOnHash::Iterator assetDependenciesItr = mpOwningAssetManager->getDependedOnAssets()->find(mpAssetDefinition->mAssetId);
|
||||||
|
|
@ -152,7 +152,7 @@ void ScriptAsset::onAssetRefresh()
|
||||||
{
|
{
|
||||||
mScriptPath = expandAssetFilePath(mScriptFile);
|
mScriptPath = expandAssetFilePath(mScriptFile);
|
||||||
|
|
||||||
if (Platform::isFile(mScriptPath))
|
if (Torque::FS::IsScriptFile(mScriptPath))
|
||||||
{
|
{
|
||||||
//Refresh any dependencies we may have
|
//Refresh any dependencies we may have
|
||||||
for (U32 i = 0; i < mScriptAssets.size(); i++)
|
for (U32 i = 0; i < mScriptAssets.size(); i++)
|
||||||
|
|
@ -192,7 +192,7 @@ bool ScriptAsset::execScript()
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (Platform::isFile(mScriptPath))
|
if (Torque::FS::IsScriptFile(mScriptPath))
|
||||||
{
|
{
|
||||||
return Con::executeFile(mScriptPath, false, false);
|
return Con::executeFile(mScriptPath, false, false);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,8 @@
|
||||||
#include "ts/tsLastDetail.h"
|
#include "ts/tsLastDetail.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
StringTableEntry ShapeAsset::smNoShapeAssetFallback(StringTable->insert(Con::getVariable("$Core::NoShapeAssetFallback")));
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
IMPLEMENT_CONOBJECT(ShapeAsset);
|
IMPLEMENT_CONOBJECT(ShapeAsset);
|
||||||
|
|
@ -86,7 +88,7 @@ ConsoleSetType(TypeShapeAssetPtr)
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
ConsoleType(assetIdString, TypeShapeAssetId, String, ASSET_ID_FIELD_PREFIX)
|
ConsoleType(assetIdString, TypeShapeAssetId, const char*, ASSET_ID_FIELD_PREFIX)
|
||||||
|
|
||||||
ConsoleGetType(TypeShapeAssetId)
|
ConsoleGetType(TypeShapeAssetId)
|
||||||
{
|
{
|
||||||
|
|
@ -100,13 +102,7 @@ ConsoleSetType(TypeShapeAssetId)
|
||||||
if (argc == 1)
|
if (argc == 1)
|
||||||
{
|
{
|
||||||
// Yes, so fetch field value.
|
// Yes, so fetch field value.
|
||||||
const char* pFieldValue = argv[0];
|
*((const char**)dptr) = StringTable->insert(argv[0]);
|
||||||
|
|
||||||
// Fetch asset Id.
|
|
||||||
StringTableEntry* assetId = (StringTableEntry*)(dptr);
|
|
||||||
|
|
||||||
// Update asset value.
|
|
||||||
*assetId = StringTable->insert(pFieldValue);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -143,6 +139,17 @@ ShapeAsset::~ShapeAsset()
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void ShapeAsset::consoleInit()
|
||||||
|
{
|
||||||
|
Parent::consoleInit();
|
||||||
|
|
||||||
|
Con::addVariable("$Core::NoShapeAssetFallback", TypeString, &smNoShapeAssetFallback,
|
||||||
|
"The assetId of the shape to display when the requested shape asset is missing.\n"
|
||||||
|
"@ingroup GFX\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
void ShapeAsset::initPersistFields()
|
void ShapeAsset::initPersistFields()
|
||||||
{
|
{
|
||||||
// Call parent.
|
// Call parent.
|
||||||
|
|
@ -154,7 +161,7 @@ void ShapeAsset::initPersistFields()
|
||||||
&setShapeConstructorFile, &getShapeConstructorFile, "Path to the shape file we want to render");
|
&setShapeConstructorFile, &getShapeConstructorFile, "Path to the shape file we want to render");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShapeAsset::setDataField(StringTableEntry slotName, const char *array, const char *value)
|
void ShapeAsset::setDataField(StringTableEntry slotName, StringTableEntry array, StringTableEntry value)
|
||||||
{
|
{
|
||||||
Parent::setDataField(slotName, array, value);
|
Parent::setDataField(slotName, array, value);
|
||||||
|
|
||||||
|
|
@ -344,49 +351,39 @@ bool ShapeAsset::loadShape()
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
//Utility function to 'fill out' bindings and resources with a matching asset if one exists
|
//Utility function to 'fill out' bindings and resources with a matching asset if one exists
|
||||||
bool ShapeAsset::getAssetByFilename(StringTableEntry fileName, AssetPtr<ShapeAsset>* shapeAsset)
|
U32 ShapeAsset::getAssetByFilename(StringTableEntry fileName, AssetPtr<ShapeAsset>* shapeAsset)
|
||||||
{
|
{
|
||||||
AssetQuery query;
|
AssetQuery query;
|
||||||
S32 foundAssetcount = AssetDatabase.findAssetLooseFile(&query, fileName);
|
S32 foundAssetcount = AssetDatabase.findAssetLooseFile(&query, fileName);
|
||||||
if (foundAssetcount == 0)
|
if (foundAssetcount == 0)
|
||||||
{
|
{
|
||||||
//Didn't find any assets
|
|
||||||
//If possible, see if we can run an in-place import and the get the asset from that
|
|
||||||
#if TORQUE_DEBUG
|
|
||||||
Con::warnf("ShapeAsset::getAssetByFilename - Attempted to in-place import a shapefile(%s) that had no associated asset", fileName);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
AssetImporter* autoAssetImporter;
|
|
||||||
if (!Sim::findObject("autoAssetImporter", autoAssetImporter))
|
|
||||||
{
|
|
||||||
autoAssetImporter = new AssetImporter();
|
|
||||||
autoAssetImporter->registerObject("autoAssetImporter");
|
|
||||||
}
|
|
||||||
|
|
||||||
StringTableEntry resultingAssetId = autoAssetImporter->autoImportFile(fileName);
|
|
||||||
|
|
||||||
if (resultingAssetId != StringTable->EmptyString())
|
|
||||||
{
|
|
||||||
shapeAsset->setAssetId(resultingAssetId);
|
|
||||||
|
|
||||||
if (!shapeAsset->isNull())
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Didn't work, so have us fall back to a placeholder asset
|
//Didn't work, so have us fall back to a placeholder asset
|
||||||
shapeAsset->setAssetId(StringTable->insert("Core_Rendering:noshape"));
|
shapeAsset->setAssetId(ShapeAsset::smNoShapeAssetFallback);
|
||||||
|
|
||||||
if (!shapeAsset->isNull())
|
if (shapeAsset->isNull())
|
||||||
return true;
|
{
|
||||||
|
//Well that's bad, loading the fallback failed.
|
||||||
|
Con::warnf("ShapeAsset::getAssetByFilename - Finding of asset associated with file %s failed with no fallback asset", fileName);
|
||||||
|
return AssetErrCode::Failed;
|
||||||
|
}
|
||||||
|
|
||||||
//That didn't work, so fail out
|
//handle noshape not being loaded itself
|
||||||
return false;
|
if ((*shapeAsset)->mLoadedState == BadFileReference)
|
||||||
|
{
|
||||||
|
Con::warnf("ShapeAsset::getAssetByFilename - Finding of associated with file %s failed, and fallback asset reported error of Bad File Reference.", fileName);
|
||||||
|
return AssetErrCode::BadFileReference;
|
||||||
|
}
|
||||||
|
|
||||||
|
Con::warnf("ShapeAsset::getAssetByFilename - Finding of associated with file %s failed, utilizing fallback asset", fileName);
|
||||||
|
|
||||||
|
(*shapeAsset)->mLoadedState = AssetErrCode::UsingFallback;
|
||||||
|
return AssetErrCode::UsingFallback;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//acquire and bind the asset, and return it out
|
//acquire and bind the asset, and return it out
|
||||||
shapeAsset->setAssetId(query.mAssetList[0]);
|
shapeAsset->setAssetId(query.mAssetList[0]);
|
||||||
return true;
|
return (*shapeAsset)->mLoadedState;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -395,37 +392,11 @@ StringTableEntry ShapeAsset::getAssetIdByFilename(StringTableEntry fileName)
|
||||||
if (fileName == StringTable->EmptyString())
|
if (fileName == StringTable->EmptyString())
|
||||||
return StringTable->EmptyString();
|
return StringTable->EmptyString();
|
||||||
|
|
||||||
StringTableEntry shapeAssetId = StringTable->EmptyString();
|
StringTableEntry shapeAssetId = ShapeAsset::smNoShapeAssetFallback;
|
||||||
|
|
||||||
AssetQuery query;
|
AssetQuery query;
|
||||||
S32 foundAssetcount = AssetDatabase.findAssetLooseFile(&query, fileName);
|
S32 foundAssetcount = AssetDatabase.findAssetLooseFile(&query, fileName);
|
||||||
if (foundAssetcount == 0)
|
if (foundAssetcount != 0)
|
||||||
{
|
|
||||||
//Didn't find any assets
|
|
||||||
//If possible, see if we can run an in-place import and the get the asset from that
|
|
||||||
#if TORQUE_DEBUG
|
|
||||||
Con::warnf("ShapeAsset::getAssetByFilename - Attempted to in-place import a shapefile(%s) that had no associated asset", fileName);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
AssetImporter* autoAssetImporter;
|
|
||||||
if (!Sim::findObject("autoAssetImporter", autoAssetImporter))
|
|
||||||
{
|
|
||||||
autoAssetImporter = new AssetImporter();
|
|
||||||
autoAssetImporter->registerObject("autoAssetImporter");
|
|
||||||
}
|
|
||||||
|
|
||||||
StringTableEntry resultingAssetId = autoAssetImporter->autoImportFile(fileName);
|
|
||||||
|
|
||||||
if (resultingAssetId != StringTable->EmptyString())
|
|
||||||
{
|
|
||||||
shapeAssetId = resultingAssetId;
|
|
||||||
return shapeAssetId;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Didn't work, so have us fall back to a placeholder asset
|
|
||||||
shapeAssetId = StringTable->insert("Core_Rendering:noshape");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
//acquire and bind the asset, and return it out
|
//acquire and bind the asset, and return it out
|
||||||
shapeAssetId = query.mAssetList[0];
|
shapeAssetId = query.mAssetList[0];
|
||||||
|
|
@ -438,24 +409,34 @@ U32 ShapeAsset::getAssetById(StringTableEntry assetId, AssetPtr<ShapeAsset>* sha
|
||||||
{
|
{
|
||||||
(*shapeAsset) = assetId;
|
(*shapeAsset) = assetId;
|
||||||
|
|
||||||
if ((*shapeAsset))
|
|
||||||
return (*shapeAsset)->mLoadedState;
|
|
||||||
|
|
||||||
if (shapeAsset->notNull())
|
if (shapeAsset->notNull())
|
||||||
|
{
|
||||||
|
return (*shapeAsset)->mLoadedState;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
//Didn't work, so have us fall back to a placeholder asset
|
//Didn't work, so have us fall back to a placeholder asset
|
||||||
StringTableEntry noShapeId = StringTable->insert("Core_Rendering:noshape");
|
shapeAsset->setAssetId(ShapeAsset::smNoShapeAssetFallback);
|
||||||
shapeAsset->setAssetId(noShapeId);
|
|
||||||
|
if (shapeAsset->isNull())
|
||||||
|
{
|
||||||
|
//Well that's bad, loading the fallback failed.
|
||||||
|
Con::warnf("ShapeAsset::getAssetById - Finding of asset with id %s failed with no fallback asset", assetId);
|
||||||
|
return AssetErrCode::Failed;
|
||||||
|
}
|
||||||
|
|
||||||
//handle noshape not being loaded itself
|
//handle noshape not being loaded itself
|
||||||
if ((*shapeAsset)->mLoadedState == BadFileReference)
|
if ((*shapeAsset)->mLoadedState == BadFileReference)
|
||||||
return AssetErrCode::Failed;
|
{
|
||||||
|
Con::warnf("ShapeAsset::getAssetById - Finding of asset with id %s failed, and fallback asset reported error of Bad File Reference.", assetId);
|
||||||
|
return AssetErrCode::BadFileReference;
|
||||||
|
}
|
||||||
|
|
||||||
|
Con::warnf("ShapeAsset::getAssetById - Finding of asset with id %s failed, utilizing fallback asset", assetId);
|
||||||
|
|
||||||
(*shapeAsset)->mLoadedState = AssetErrCode::UsingFallback;
|
(*shapeAsset)->mLoadedState = AssetErrCode::UsingFallback;
|
||||||
return AssetErrCode::UsingFallback;
|
return AssetErrCode::UsingFallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
return AssetErrCode::Failed;
|
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
@ -555,17 +536,37 @@ DefineEngineMethod(ShapeAsset, getAnimation, ShapeAnimationAsset*, (S32 index),
|
||||||
}
|
}
|
||||||
|
|
||||||
DefineEngineMethod(ShapeAsset, getShapeFile, const char*, (), ,
|
DefineEngineMethod(ShapeAsset, getShapeFile, const char*, (), ,
|
||||||
"Creates a new script asset using the targetFilePath.\n"
|
"Gets the shape's file path\n"
|
||||||
"@return The bool result of calling exec")
|
"@return The filename of the shape file")
|
||||||
{
|
{
|
||||||
return object->getShapeFilePath();
|
return object->getShapeFilePath();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DefineEngineMethod(ShapeAsset, getShapeConstructorFilePath, const char*, (), ,
|
||||||
|
"Gets the shape's constructor file.\n"
|
||||||
|
"@return The filename of the shape constructor file")
|
||||||
|
{
|
||||||
|
return object->getShapeConstructorFilePath();
|
||||||
|
}
|
||||||
|
|
||||||
|
DefineEngineMethod(ShapeAsset, getStatusString, String, (), , "get status string")\
|
||||||
|
{
|
||||||
|
return ShapeAsset::getAssetErrstrn(object->getStatus());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef TORQUE_TOOLS
|
#ifdef TORQUE_TOOLS
|
||||||
DefineEngineMethod(ShapeAsset, generateCachedPreviewImage, const char*, (S32 resolution), (256), "")
|
DefineEngineMethod(ShapeAsset, generateCachedPreviewImage, const char*, (S32 resolution), (256), "")
|
||||||
{
|
{
|
||||||
return object->generateCachedPreviewImage(resolution);
|
return object->generateCachedPreviewImage(resolution);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DefineEngineStaticMethod(ShapeAsset, 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 ShapeAsset::getAssetIdByFilename(StringTable->insert(filePath));
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
@ -611,8 +612,8 @@ GuiControl* GuiInspectorTypeShapeAssetPtr::constructEditControl()
|
||||||
dSprintf(szBuffer, sizeof(szBuffer), "ShapeEditorPlugin.openShapeAssetId(%d.getText());", retCtrl->getId());
|
dSprintf(szBuffer, sizeof(szBuffer), "ShapeEditorPlugin.openShapeAssetId(%d.getText());", retCtrl->getId());
|
||||||
mShapeEdButton->setField("Command", szBuffer);
|
mShapeEdButton->setField("Command", szBuffer);
|
||||||
|
|
||||||
char bitmapName[512] = "tools/worldEditor/images/toolbar/shape-editor";
|
char bitmapName[512] = "ToolsModule:shape_editor_n_image";
|
||||||
mShapeEdButton->setBitmap(bitmapName);
|
mShapeEdButton->setBitmap(StringTable->insert(bitmapName));
|
||||||
|
|
||||||
mShapeEdButton->setDataField(StringTable->insert("Profile"), NULL, "GuiButtonProfile");
|
mShapeEdButton->setDataField(StringTable->insert("Profile"), NULL, "GuiButtonProfile");
|
||||||
mShapeEdButton->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile");
|
mShapeEdButton->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile");
|
||||||
|
|
|
||||||
|
|
@ -81,9 +81,11 @@ protected:
|
||||||
Vector<AssetPtr<ShapeAnimationAsset>> mAnimationAssets;
|
Vector<AssetPtr<ShapeAnimationAsset>> mAnimationAssets;
|
||||||
|
|
||||||
typedef Signal<void()> ShapeAssetChanged;
|
typedef Signal<void()> ShapeAssetChanged;
|
||||||
|
|
||||||
ShapeAssetChanged mChangeSignal;
|
ShapeAssetChanged mChangeSignal;
|
||||||
|
|
||||||
|
typedef Signal<void(S32 index)> ShapeAssetArrayChanged;
|
||||||
|
ShapeAssetArrayChanged mChangeArraySignal;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum ShapeAssetErrCode
|
enum ShapeAssetErrCode
|
||||||
{
|
{
|
||||||
|
|
@ -93,7 +95,12 @@ public:
|
||||||
Extended
|
Extended
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static StringTableEntry smNoShapeAssetFallback;
|
||||||
|
|
||||||
static const String mErrCodeStrings[ShapeAssetErrCode::Extended - Parent::Extended + 1];
|
static const String mErrCodeStrings[ShapeAssetErrCode::Extended - Parent::Extended + 1];
|
||||||
|
|
||||||
|
static U32 getAssetErrCode(AssetPtr<ShapeAsset> shapeAsset) { if (shapeAsset) return shapeAsset->mLoadedState; else return 0; }
|
||||||
|
|
||||||
static String getAssetErrstrn(U32 errCode)
|
static String getAssetErrstrn(U32 errCode)
|
||||||
{
|
{
|
||||||
if (errCode < Parent::Extended) return Parent::getAssetErrstrn(errCode);
|
if (errCode < Parent::Extended) return Parent::getAssetErrstrn(errCode);
|
||||||
|
|
@ -104,11 +111,14 @@ public:
|
||||||
ShapeAsset();
|
ShapeAsset();
|
||||||
virtual ~ShapeAsset();
|
virtual ~ShapeAsset();
|
||||||
|
|
||||||
|
/// Set up some global script interface stuff.
|
||||||
|
static void consoleInit();
|
||||||
|
|
||||||
/// Engine.
|
/// Engine.
|
||||||
static void initPersistFields();
|
static void initPersistFields();
|
||||||
virtual void copyTo(SimObject* object);
|
virtual void copyTo(SimObject* object);
|
||||||
|
|
||||||
virtual void setDataField(StringTableEntry slotName, const char *array, const char *value);
|
virtual void setDataField(StringTableEntry slotName, StringTableEntry array, StringTableEntry value);
|
||||||
|
|
||||||
virtual void initializeAsset();
|
virtual void initializeAsset();
|
||||||
|
|
||||||
|
|
@ -116,25 +126,25 @@ public:
|
||||||
DECLARE_CONOBJECT(ShapeAsset);
|
DECLARE_CONOBJECT(ShapeAsset);
|
||||||
|
|
||||||
bool loadShape();
|
bool loadShape();
|
||||||
U32 mLoadedState;
|
|
||||||
|
|
||||||
TSShape* getShape() { return mShape; }
|
TSShape* getShape() { return mShape; }
|
||||||
|
|
||||||
Resource<TSShape> getShapeResource() { return mShape; }
|
Resource<TSShape> getShapeResource() { return mShape; }
|
||||||
|
|
||||||
void SplitSequencePathAndName(String& srcPath, String& srcName);
|
void SplitSequencePathAndName(String& srcPath, String& srcName);
|
||||||
StringTableEntry getShapeFilename() { return mFilePath; }
|
StringTableEntry getShapeFileName() { return mFileName; }
|
||||||
|
StringTableEntry getShapePath() { return mFilePath; }
|
||||||
|
|
||||||
U32 getShapeFilenameHash() { return _StringTable::hashString(mFilePath); }
|
U32 getShapeFilenameHash() { return _StringTable::hashString(mFilePath); }
|
||||||
|
|
||||||
Vector<AssetPtr<MaterialAsset>> getMaterialAssets() { return mMaterialAssets; }
|
Vector<AssetPtr<MaterialAsset>> getMaterialAssets() { return mMaterialAssets; }
|
||||||
|
|
||||||
inline AssetPtr<MaterialAsset> getMaterialAsset(U32 matId)
|
inline AssetPtr<MaterialAsset> getMaterialAsset(U32 matId)
|
||||||
{
|
{
|
||||||
if(matId >= mMaterialAssets.size())
|
if (matId >= mMaterialAssets.size())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
else
|
else
|
||||||
return mMaterialAssets[matId];
|
return mMaterialAssets[matId];
|
||||||
}
|
}
|
||||||
|
|
||||||
void clearMaterialAssets() { mMaterialAssets.clear(); }
|
void clearMaterialAssets() { mMaterialAssets.clear(); }
|
||||||
|
|
@ -145,9 +155,10 @@ public:
|
||||||
S32 getAnimationCount() { return mAnimationAssets.size(); }
|
S32 getAnimationCount() { return mAnimationAssets.size(); }
|
||||||
ShapeAnimationAsset* getAnimation(S32 index);
|
ShapeAnimationAsset* getAnimation(S32 index);
|
||||||
|
|
||||||
void _onResourceChanged(const Torque::Path &path);
|
void _onResourceChanged(const Torque::Path& path);
|
||||||
|
|
||||||
ShapeAssetChanged& getChangedSignal() { return mChangeSignal; }
|
ShapeAssetChanged& getChangedSignal() { return mChangeSignal; }
|
||||||
|
ShapeAssetArrayChanged& getChangedArraySignal() { return mChangeArraySignal; }
|
||||||
|
|
||||||
void setShapeFile(const char* pScriptFile);
|
void setShapeFile(const char* pScriptFile);
|
||||||
inline StringTableEntry getShapeFile(void) const { return mFileName; };
|
inline StringTableEntry getShapeFile(void) const { return mFileName; };
|
||||||
|
|
@ -158,13 +169,11 @@ public:
|
||||||
inline StringTableEntry getShapeFilePath(void) const { return mFilePath; };
|
inline StringTableEntry getShapeFilePath(void) const { return mFilePath; };
|
||||||
inline StringTableEntry getShapeConstructorFilePath(void) const { return mConstructorFilePath; };
|
inline StringTableEntry getShapeConstructorFilePath(void) const { return mConstructorFilePath; };
|
||||||
|
|
||||||
static bool getAssetByFilename(StringTableEntry fileName, AssetPtr<ShapeAsset>* shapeAsset);
|
static U32 getAssetByFilename(StringTableEntry fileName, AssetPtr<ShapeAsset>* shapeAsset);
|
||||||
|
|
||||||
static StringTableEntry getAssetIdByFilename(StringTableEntry fileName);
|
static StringTableEntry getAssetIdByFilename(StringTableEntry fileName);
|
||||||
static U32 getAssetById(StringTableEntry assetId, AssetPtr<ShapeAsset>* shapeAsset);
|
static U32 getAssetById(StringTableEntry assetId, AssetPtr<ShapeAsset>* shapeAsset);
|
||||||
|
|
||||||
static StringTableEntry getNoShapeAssetId() { return StringTable->insert("Core_Rendering:noshape"); }
|
|
||||||
|
|
||||||
#ifdef TORQUE_TOOLS
|
#ifdef TORQUE_TOOLS
|
||||||
const char* generateCachedPreviewImage(S32 resolution);
|
const char* generateCachedPreviewImage(S32 resolution);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -172,7 +181,7 @@ public:
|
||||||
protected:
|
protected:
|
||||||
virtual void onAssetRefresh(void);
|
virtual void onAssetRefresh(void);
|
||||||
|
|
||||||
static bool setShapeFile(void *obj, const char *index, const char *data) { static_cast<ShapeAsset*>(obj)->setShapeFile(data); return false; }
|
static bool setShapeFile(void* obj, StringTableEntry index, StringTableEntry data) { static_cast<ShapeAsset*>(obj)->setShapeFile(data); return false; }
|
||||||
static const char* getShapeFile(void* obj, const char* data) { return static_cast<ShapeAsset*>(obj)->getShapeFile(); }
|
static const char* getShapeFile(void* obj, const char* data) { return static_cast<ShapeAsset*>(obj)->getShapeFile(); }
|
||||||
|
|
||||||
static bool setShapeConstructorFile(void* obj, const char* index, const char* data) { static_cast<ShapeAsset*>(obj)->setShapeConstructorFile(data); return false; }
|
static bool setShapeConstructorFile(void* obj, const char* index, const char* data) { static_cast<ShapeAsset*>(obj)->setShapeConstructorFile(data); return false; }
|
||||||
|
|
@ -192,7 +201,7 @@ class GuiInspectorTypeShapeAssetPtr : public GuiInspectorTypeFileName
|
||||||
typedef GuiInspectorTypeFileName Parent;
|
typedef GuiInspectorTypeFileName Parent;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
GuiBitmapButtonCtrl *mShapeEdButton;
|
GuiBitmapButtonCtrl* mShapeEdButton;
|
||||||
|
|
||||||
DECLARE_CONOBJECT(GuiInspectorTypeShapeAssetPtr);
|
DECLARE_CONOBJECT(GuiInspectorTypeShapeAssetPtr);
|
||||||
static void consoleInit();
|
static void consoleInit();
|
||||||
|
|
@ -211,86 +220,415 @@ public:
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define assetText(x,suff) std::string(std::string(#x) + std::string(#suff)).c_str()
|
#pragma region Singular Asset Macros
|
||||||
|
|
||||||
#define initShapeAsset(name) m##name##Name = StringTable->EmptyString(); m##name##AssetId = StringTable->EmptyString(); m##name##Asset = NULL;
|
#define DECLARE_SHAPEASSET(className,name,changeFunc) public: \
|
||||||
#define cloneShapeAsset(name) m##name##Name = other.m##name##Name; m##name##AssetId = other.m##name##AssetId; m##name##Asset = other.m##name##Asset;
|
Resource<TSShape>m##name;\
|
||||||
#define bindShapeAsset(name) if (m##name##AssetId != StringTable->EmptyString()) m##name##Asset = m##name##AssetId;
|
StringTableEntry m##name##Name; \
|
||||||
|
StringTableEntry m##name##AssetId;\
|
||||||
#define scriptBindShapeAsset(name, consoleClass, docs) addProtectedField(assetText(name, File), TypeShapeFilename, Offset(m##name##Name, consoleClass), consoleClass::_set##name##Filename, & defaultProtectedGetFn, assetText(name, docs)); \
|
AssetPtr<ShapeAsset> m##name##Asset;\
|
||||||
addProtectedField(assetText(name, Asset), TypeShapeAssetId, Offset(m##name##AssetId, consoleClass), consoleClass::_set##name##Asset, & defaultProtectedGetFn, assetText(name, asset reference.));
|
public: \
|
||||||
|
const StringTableEntry get##name##File() const { return StringTable->insert(m##name##Name); }\
|
||||||
#define DECLARE_SHAPEASSET(className,name)\
|
void set##name##Name(const FileName &_in) { m##name##Name = _in;}\
|
||||||
StringTableEntry m##name##Name;\
|
const AssetPtr<ShapeAsset> & get##name##Asset() const { return m##name##Asset; }\
|
||||||
StringTableEntry m##name##AssetId;\
|
void set##name##Asset(const AssetPtr<ShapeAsset> &_in) { m##name##Asset = _in;}\
|
||||||
AssetPtr<ShapeAsset> m##name##Asset;\
|
|
||||||
const StringTableEntry& get##name() const { return m##name##Name; }\
|
|
||||||
void set##name(FileName _in) { m##name##Name = _in; }\
|
|
||||||
const AssetPtr<ShapeAsset> & get##name##Asset() const { return m##name##Asset; }\
|
|
||||||
void set##name##Asset(AssetPtr<ShapeAsset>_in) { m##name##Asset = _in; }\
|
|
||||||
static bool _set##name##Filename(void* obj, const char* index, const char* data)\
|
|
||||||
{\
|
|
||||||
className* shape = static_cast<className*>(obj);\
|
|
||||||
\
|
\
|
||||||
StringTableEntry assetId = ShapeAsset::getAssetIdByFilename(StringTable->insert(data));\
|
bool _set##name(StringTableEntry _in)\
|
||||||
if (assetId != StringTable->EmptyString())\
|
|
||||||
{\
|
{\
|
||||||
if (shape->_set##name##Asset(obj, index, assetId))\
|
if(m##name##AssetId != _in || m##name##Name != _in)\
|
||||||
{\
|
{\
|
||||||
if (assetId == StringTable->insert("Core_Rendering:noShape"))\
|
if (m##name##Asset.notNull())\
|
||||||
{\
|
{\
|
||||||
shape->m##name##Name = data;\
|
m##name##Asset->getChangedSignal().remove(this, &className::changeFunc);\
|
||||||
shape->m##name##AssetId = StringTable->EmptyString();\
|
}\
|
||||||
\
|
if (_in == StringTable->EmptyString())\
|
||||||
|
{\
|
||||||
|
m##name##Name = StringTable->EmptyString();\
|
||||||
|
m##name##AssetId = StringTable->EmptyString();\
|
||||||
|
m##name##Asset = NULL;\
|
||||||
|
m##name = NULL;\
|
||||||
return true;\
|
return true;\
|
||||||
}\
|
}\
|
||||||
|
\
|
||||||
|
if (AssetDatabase.isDeclaredAsset(_in))\
|
||||||
|
{\
|
||||||
|
m##name##AssetId = _in;\
|
||||||
|
\
|
||||||
|
U32 assetState = ShapeAsset::getAssetById(m##name##AssetId, &m##name##Asset);\
|
||||||
|
\
|
||||||
|
if (ShapeAsset::Ok == assetState)\
|
||||||
|
{\
|
||||||
|
m##name##Name = StringTable->EmptyString();\
|
||||||
|
}\
|
||||||
|
}\
|
||||||
else\
|
else\
|
||||||
{\
|
{\
|
||||||
shape->m##name##AssetId = assetId;\
|
StringTableEntry assetId = ShapeAsset::getAssetIdByFilename(_in);\
|
||||||
shape->m##name##Name = StringTable->EmptyString();\
|
if (assetId != StringTable->EmptyString())\
|
||||||
\
|
{\
|
||||||
return false;\
|
m##name##AssetId = assetId;\
|
||||||
|
if (ShapeAsset::getAssetById(m##name##AssetId, &m##name##Asset) == ShapeAsset::Ok)\
|
||||||
|
{\
|
||||||
|
m##name##Name = StringTable->EmptyString();\
|
||||||
|
}\
|
||||||
|
}\
|
||||||
|
else\
|
||||||
|
{\
|
||||||
|
m##name##Name = _in;\
|
||||||
|
m##name##AssetId = StringTable->EmptyString();\
|
||||||
|
m##name##Asset = NULL;\
|
||||||
|
}\
|
||||||
}\
|
}\
|
||||||
}\
|
}\
|
||||||
}\
|
if (get##name() != StringTable->EmptyString() && m##name##Asset.notNull())\
|
||||||
else\
|
{\
|
||||||
{\
|
m##name = m##name##Asset->getShapeResource();\
|
||||||
shape->m##name##Asset = StringTable->EmptyString();\
|
\
|
||||||
}\
|
m##name##Asset->getChangedSignal().notify(this, &className::changeFunc);\
|
||||||
\
|
}\
|
||||||
return true;\
|
else\
|
||||||
}\
|
{\
|
||||||
\
|
m##name = NULL;\
|
||||||
static bool _set##name##Asset(void* obj, const char* index, const char* data)\
|
}\
|
||||||
{\
|
\
|
||||||
className* shape = static_cast<className*>(obj);\
|
if(get##name() == StringTable->EmptyString())\
|
||||||
shape->m##name##AssetId = StringTable->insert(data);\
|
return true;\
|
||||||
if (ShapeAsset::getAssetById(shape->m##name##AssetId, &shape->m##name##Asset))\
|
\
|
||||||
{\
|
if (m##name##Asset.notNull() && m##name##Asset->getStatus() != ShapeAsset::Ok)\
|
||||||
if (shape->m##name##Asset.getAssetId() != StringTable->insert("Core_Rendering:noShape"))\
|
{\
|
||||||
shape->m##name##Name = StringTable->EmptyString();\
|
Con::errorf("%s(%s)::_set%s() - shape asset failure \"%s\" due to [%s]", macroText(className), getName(), macroText(name), _in, ShapeAsset::getAssetErrstrn(m##name##Asset->getStatus()).c_str());\
|
||||||
|
return false; \
|
||||||
|
}\
|
||||||
|
else if (bool(m##name) == NULL)\
|
||||||
|
{\
|
||||||
|
Con::errorf("%s(%s)::_set%s() - Couldn't load shape \"%s\"", macroText(className), getName(), macroText(name), _in);\
|
||||||
|
return false;\
|
||||||
|
}\
|
||||||
return true;\
|
return true;\
|
||||||
}\
|
}\
|
||||||
return false;\
|
\
|
||||||
}\
|
const StringTableEntry get##name() const\
|
||||||
void pack##name##Asset(BitStream *stream)\
|
{\
|
||||||
|
if (m##name##Asset && (m##name##Asset->getShapePath() != StringTable->EmptyString()))\
|
||||||
|
return m##name##Asset->getShapePath();\
|
||||||
|
else if (m##name##AssetId != StringTable->EmptyString())\
|
||||||
|
return m##name##AssetId;\
|
||||||
|
else if (m##name##Name != StringTable->EmptyString())\
|
||||||
|
return m##name##Name;\
|
||||||
|
else\
|
||||||
|
return StringTable->EmptyString();\
|
||||||
|
}\
|
||||||
|
Resource<TSShape> get##name##Resource() \
|
||||||
|
{\
|
||||||
|
return m##name;\
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DECLARE_SHAPEASSET_SETGET(className, name)\
|
||||||
|
static bool _set##name##Data(void* obj, const char* index, const char* data)\
|
||||||
|
{\
|
||||||
|
bool ret = false;\
|
||||||
|
className* object = static_cast<className*>(obj);\
|
||||||
|
ret = object->_set##name(StringTable->insert(data));\
|
||||||
|
return ret;\
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DECLARE_SHAPEASSET_NET_SETGET(className, name, bitmask)\
|
||||||
|
static bool _set##name##Data(void* obj, const char* index, const char* data)\
|
||||||
|
{\
|
||||||
|
bool ret = false;\
|
||||||
|
className* object = static_cast<className*>(obj);\
|
||||||
|
ret = object->_set##name(StringTable->insert(data));\
|
||||||
|
if(ret)\
|
||||||
|
object->setMaskBits(bitmask);\
|
||||||
|
return ret;\
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DEF_SHAPEASSET_BINDS(className,name)\
|
||||||
|
DefineEngineMethod(className, get##name, String, (), , "get name")\
|
||||||
{\
|
{\
|
||||||
|
return object->get##name(); \
|
||||||
|
}\
|
||||||
|
DefineEngineMethod(className, get##name##Asset, String, (), , assetText(name, asset reference))\
|
||||||
|
{\
|
||||||
|
return object->m##name##AssetId; \
|
||||||
|
}\
|
||||||
|
DefineEngineMethod(className, set##name, bool, (const char* shape), , assetText(name,assignment. first tries asset then flat file.))\
|
||||||
|
{\
|
||||||
|
return object->_set##name(StringTable->insert(shape));\
|
||||||
|
}
|
||||||
|
|
||||||
|
#define INIT_SHAPEASSET(name) \
|
||||||
|
m##name##Name = StringTable->EmptyString(); \
|
||||||
|
m##name##AssetId = StringTable->EmptyString(); \
|
||||||
|
m##name##Asset = NULL; \
|
||||||
|
m##name = NULL;
|
||||||
|
|
||||||
|
#ifdef TORQUE_SHOW_LEGACY_FILE_FIELDS
|
||||||
|
|
||||||
|
#define INITPERSISTFIELD_SHAPEASSET(name, consoleClass, docs) \
|
||||||
|
addProtectedField(assetText(name, File), TypeShapeFilename, Offset(m##name##Name, consoleClass), _set##name##Data, & defaultProtectedGetFn, assetText(name, docs)); \
|
||||||
|
addProtectedField(assetText(name, Asset), TypeShapeAssetId, Offset(m##name##AssetId, consoleClass), _set##name##Data, & defaultProtectedGetFn, assetText(name, asset reference.));
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define INITPERSISTFIELD_SHAPEASSET(name, consoleClass, docs) \
|
||||||
|
addProtectedField(assetText(name, File), TypeShapeFilename, Offset(m##name##Name, consoleClass), _set##name##Data, & defaultProtectedGetFn, assetText(name, docs), AbstractClassRep::FIELD_HideInInspectors); \
|
||||||
|
addProtectedField(assetText(name, Asset), TypeShapeAssetId, Offset(m##name##AssetId, consoleClass), _set##name##Data, & defaultProtectedGetFn, assetText(name, asset reference.));
|
||||||
|
|
||||||
|
#endif // SHOW_LEGACY_FILE_FIELDS
|
||||||
|
|
||||||
|
#define CLONE_SHAPEASSET(name) \
|
||||||
|
m##name##Name = other.m##name##Name;\
|
||||||
|
m##name##AssetId = other.m##name##AssetId;\
|
||||||
|
m##name##Asset = other.m##name##Asset;\
|
||||||
|
|
||||||
|
#define PACKDATA_SHAPEASSET(name)\
|
||||||
if (stream->writeFlag(m##name##Asset.notNull()))\
|
if (stream->writeFlag(m##name##Asset.notNull()))\
|
||||||
|
{\
|
||||||
stream->writeString(m##name##Asset.getAssetId());\
|
stream->writeString(m##name##Asset.getAssetId());\
|
||||||
|
}\
|
||||||
else\
|
else\
|
||||||
stream->writeString(m##name##Name);\
|
stream->writeString(m##name##Name);
|
||||||
}\
|
|
||||||
void unpack##name##Asset(BitStream *stream)\
|
#define UNPACKDATA_SHAPEASSET(name)\
|
||||||
{\
|
|
||||||
if (stream->readFlag())\
|
if (stream->readFlag())\
|
||||||
{\
|
{\
|
||||||
m##name##AssetId = stream->readSTString();\
|
m##name##AssetId = stream->readSTString();\
|
||||||
ShapeAsset::getAssetById(m##name##AssetId, &m##name##Asset);\
|
_set##name(m##name##AssetId);\
|
||||||
m##name##Name = m##name##Asset->getShapeFilename(); \
|
|
||||||
}\
|
}\
|
||||||
else\
|
else\
|
||||||
m##name##Name = stream->readSTString();\
|
m##name##Name = stream->readSTString();
|
||||||
|
|
||||||
|
#define PACK_SHAPEASSET(netconn, name)\
|
||||||
|
if (stream->writeFlag(m##name##Asset.notNull()))\
|
||||||
|
{\
|
||||||
|
NetStringHandle assetIdStr = m##name##Asset.getAssetId();\
|
||||||
|
netconn->packNetStringHandleU(stream, assetIdStr);\
|
||||||
|
}\
|
||||||
|
else\
|
||||||
|
stream->writeString(m##name##Name);
|
||||||
|
|
||||||
|
#define UNPACK_SHAPEASSET(netconn, name)\
|
||||||
|
if (stream->readFlag())\
|
||||||
|
{\
|
||||||
|
m##name##AssetId = StringTable->insert(netconn->unpackNetStringHandleU(stream).getString());\
|
||||||
|
_set##name(m##name##AssetId);\
|
||||||
|
}\
|
||||||
|
else\
|
||||||
|
m##name##Name = stream->readSTString();
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region Arrayed Asset Macros
|
||||||
|
|
||||||
|
#define DECLARE_SHAPEASSET_ARRAY(className,name,max) public: \
|
||||||
|
static const U32 sm##name##Count = max;\
|
||||||
|
Resource<TSShape>m##name[max];\
|
||||||
|
StringTableEntry m##name##Name[max]; \
|
||||||
|
StringTableEntry m##name##AssetId[max];\
|
||||||
|
AssetPtr<ShapeAsset> m##name##Asset[max];\
|
||||||
|
public: \
|
||||||
|
const StringTableEntry get##name##File(const U32& index) const { return m##name##Name[index]; }\
|
||||||
|
void set##name##Name(const FileName &_in, const U32& index) { m##name##Name[index] = _in;}\
|
||||||
|
const AssetPtr<ShapeAsset> & get##name##Asset(const U32& index) const { return m##name##Asset[index]; }\
|
||||||
|
void set##name##Asset(const AssetPtr<ShapeAsset> &_in, const U32& index) { m##name##Asset[index] = _in;}\
|
||||||
|
\
|
||||||
|
bool _set##name(StringTableEntry _in, const U32& index)\
|
||||||
|
{\
|
||||||
|
if(m##name##AssetId[index] != _in || m##name##Name[index] != _in)\
|
||||||
|
{\
|
||||||
|
if(index >= sm##name##Count || index < 0)\
|
||||||
|
return false;\
|
||||||
|
if (_in == StringTable->EmptyString())\
|
||||||
|
{\
|
||||||
|
m##name##Name[index] = StringTable->EmptyString();\
|
||||||
|
m##name##AssetId[index] = StringTable->EmptyString();\
|
||||||
|
m##name##Asset[index] = NULL;\
|
||||||
|
m##name[index] = NULL;\
|
||||||
|
return true;\
|
||||||
|
}\
|
||||||
|
\
|
||||||
|
if (AssetDatabase.isDeclaredAsset(_in))\
|
||||||
|
{\
|
||||||
|
m##name##AssetId[index] = _in;\
|
||||||
|
\
|
||||||
|
U32 assetState = ShapeAsset::getAssetById(m##name##AssetId[index], &m##name##Asset[index]);\
|
||||||
|
\
|
||||||
|
if (ShapeAsset::Ok == assetState)\
|
||||||
|
{\
|
||||||
|
m##name##Name[index] = StringTable->EmptyString();\
|
||||||
|
}\
|
||||||
|
}\
|
||||||
|
else\
|
||||||
|
{\
|
||||||
|
StringTableEntry assetId = ShapeAsset::getAssetIdByFilename(_in);\
|
||||||
|
if (assetId != StringTable->EmptyString())\
|
||||||
|
{\
|
||||||
|
m##name##AssetId[index] = assetId;\
|
||||||
|
if (ShapeAsset::getAssetById(m##name##AssetId[index], &m##name##Asset[index]) == ShapeAsset::Ok)\
|
||||||
|
{\
|
||||||
|
m##name##Name[index] = StringTable->EmptyString();\
|
||||||
|
}\
|
||||||
|
}\
|
||||||
|
else\
|
||||||
|
{\
|
||||||
|
m##name##Name[index] = _in;\
|
||||||
|
m##name##AssetId[index] = StringTable->EmptyString();\
|
||||||
|
m##name##Asset[index] = NULL;\
|
||||||
|
}\
|
||||||
|
}\
|
||||||
|
}\
|
||||||
|
if (get##name(index) != StringTable->EmptyString() && m##name##Asset[index].notNull())\
|
||||||
|
{\
|
||||||
|
m##name[index] = m##name##Asset[index]->getShapeResource();\
|
||||||
|
}\
|
||||||
|
else\
|
||||||
|
{\
|
||||||
|
m##name[index] = NULL;\
|
||||||
|
}\
|
||||||
|
\
|
||||||
|
if(get##name(index) == StringTable->EmptyString())\
|
||||||
|
return true;\
|
||||||
|
\
|
||||||
|
if (m##name##Asset[index].notNull() && m##name##Asset[index]->getStatus() != ShapeAsset::Ok)\
|
||||||
|
{\
|
||||||
|
Con::errorf("%s(%s)::_set%s(%i) - shape asset failure \"%s\" due to [%s]", macroText(className), getName(), macroText(name), index, _in, ShapeAsset::getAssetErrstrn(m##name##Asset[index]->getStatus()).c_str());\
|
||||||
|
return false; \
|
||||||
|
}\
|
||||||
|
else if (bool(m##name[index]) == NULL)\
|
||||||
|
{\
|
||||||
|
Con::errorf("%s(%s)::_set%s(%i) - Couldn't load shape \"%s\"", macroText(className), getName(), macroText(name), index, _in);\
|
||||||
|
return false; \
|
||||||
|
}\
|
||||||
|
return true;\
|
||||||
|
}\
|
||||||
|
\
|
||||||
|
const StringTableEntry get##name(const U32& index) const\
|
||||||
|
{\
|
||||||
|
if (m##name##Asset[index] && (m##name##Asset[index]->getShapePath() != StringTable->EmptyString()))\
|
||||||
|
return m##name##Asset[index]->getShapePath();\
|
||||||
|
else if (m##name##AssetId[index] != StringTable->EmptyString())\
|
||||||
|
return m##name##AssetId[index];\
|
||||||
|
else if (m##name##Name[index] != StringTable->EmptyString())\
|
||||||
|
return StringTable->insert(m##name##Name[index]);\
|
||||||
|
else\
|
||||||
|
return StringTable->EmptyString();\
|
||||||
|
}\
|
||||||
|
Resource<TSShape> get##name##Resource(const U32& index) \
|
||||||
|
{\
|
||||||
|
if(index >= sm##name##Count || index < 0)\
|
||||||
|
return nullptr;\
|
||||||
|
return m##name[index];\
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DECLARE_SHAPEASSET_ARRAY_SETGET(className, name)\
|
||||||
|
static bool _set##name##Data(void* obj, const char* index, const char* data)\
|
||||||
|
{\
|
||||||
|
if (!index) return false;\
|
||||||
|
U32 idx = dAtoi(index);\
|
||||||
|
if (idx >= sm##name##Count)\
|
||||||
|
return false;\
|
||||||
|
bool ret = false;\
|
||||||
|
className* object = static_cast<className*>(obj);\
|
||||||
|
ret = object->_set##name(StringTable->insert(data), idx);\
|
||||||
|
return ret;\
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DECLARE_SHAPEASSET_ARRAY_NET_SETGET(className, name, bitmask)\
|
||||||
|
static bool _set##name##Data(void* obj, const char* index, const char* data)\
|
||||||
|
{\
|
||||||
|
if (!index) return false;\
|
||||||
|
U32 idx = dAtoi(index);\
|
||||||
|
if (idx >= sm##name##Count)\
|
||||||
|
return false;\
|
||||||
|
bool ret = false;\
|
||||||
|
className* object = static_cast<className*>(obj);\
|
||||||
|
ret = object->_set##name(StringTable->insert(data), idx);\
|
||||||
|
if(ret)\
|
||||||
|
object->setMaskBits(bitmask);\
|
||||||
|
return ret;\
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DEF_SHAPEASSET_ARRAY_BINDS(className,name)\
|
||||||
|
DefineEngineMethod(className, get##name, String, (S32 index), , "get name")\
|
||||||
|
{\
|
||||||
|
return object->get##name(index); \
|
||||||
|
}\
|
||||||
|
DefineEngineMethod(className, get##name##Asset, String, (S32 index), , assetText(name, asset reference))\
|
||||||
|
{\
|
||||||
|
if(index >= className::sm##name##Count || index < 0)\
|
||||||
|
return "";\
|
||||||
|
return object->m##name##AssetId[index]; \
|
||||||
|
}\
|
||||||
|
DefineEngineMethod(className, set##name, bool, (const char* shape, S32 index), , assetText(name,assignment. first tries asset then flat file.))\
|
||||||
|
{\
|
||||||
|
return object->_set##name(StringTable->insert(shape), index);\
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#define INIT_SHAPEASSET_ARRAY(name, index) \
|
||||||
|
{\
|
||||||
|
m##name##Name[index] = StringTable->EmptyString(); \
|
||||||
|
m##name##AssetId[index] = StringTable->EmptyString(); \
|
||||||
|
m##name##Asset[index] = NULL; \
|
||||||
|
m##name[index] = NULL;\
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef TORQUE_SHOW_LEGACY_FILE_FIELDS
|
||||||
|
|
||||||
|
#define INITPERSISTFIELD_SHAPEASSET_ARRAY(name, arraySize, consoleClass, docs) \
|
||||||
|
addProtectedField(assetText(name, File), TypeShapeFilename, Offset(m##name##Name, consoleClass), _set##name##Data, & defaultProtectedGetFn, arraySize, assetText(name, docs)); \
|
||||||
|
addProtectedField(assetText(name, Asset), TypeShapeAssetId, Offset(m##name##AssetId, consoleClass), _set##name##Data, & defaultProtectedGetFn, arraySize, assetText(name, asset reference.));
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define INITPERSISTFIELD_SHAPEASSET_ARRAY(name, arraySize, consoleClass, docs) \
|
||||||
|
addProtectedField(assetText(name, File), TypeShapeFilename, Offset(m##name##Name, consoleClass), _set##name##Data, & defaultProtectedGetFn, arraySize, assetText(name, docs), AbstractClassRep::FIELD_HideInInspectors); \
|
||||||
|
addProtectedField(assetText(name, Asset), TypeShapeAssetId, Offset(m##name##AssetId, consoleClass), _set##name##Data, & defaultProtectedGetFn, arraySize,assetText(name, asset reference.));
|
||||||
|
|
||||||
|
#endif // SHOW_LEGACY_FILE_FIELDS
|
||||||
|
|
||||||
|
#define CLONE_SHAPEASSET_ARRAY(name, index) \
|
||||||
|
{\
|
||||||
|
m##name##Name[index] = other.m##name##Name[index];\
|
||||||
|
m##name##AssetId[index] = other.m##name##AssetId[index];\
|
||||||
|
m##name##Asset[index] = other.m##name##Asset[index];\
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PACKDATA_SHAPEASSET_ARRAY(name, index)\
|
||||||
|
if (stream->writeFlag(m##name##Asset[index].notNull()))\
|
||||||
|
{\
|
||||||
|
stream->writeString(m##name##Asset[index].getAssetId());\
|
||||||
|
}\
|
||||||
|
else\
|
||||||
|
stream->writeString(m##name##Name[index]);
|
||||||
|
|
||||||
|
#define UNPACKDATA_SHAPEASSET_ARRAY(name, index)\
|
||||||
|
if (stream->readFlag())\
|
||||||
|
{\
|
||||||
|
m##name##AssetId[index] = stream->readSTString();\
|
||||||
|
_set##name(m##name##AssetId[index], index);\
|
||||||
|
}\
|
||||||
|
else\
|
||||||
|
m##name##Name[index] = stream->readSTString();
|
||||||
|
|
||||||
|
#define PACK_SHAPEASSET_ARRAY(netconn, name, index)\
|
||||||
|
if (stream->writeFlag(m##name##Asset[index].notNull()))\
|
||||||
|
{\
|
||||||
|
NetStringHandle assetIdStr = m##name##Asset[index].getAssetId();\
|
||||||
|
netconn->packNetStringHandleU(stream, assetIdStr);\
|
||||||
|
}\
|
||||||
|
else\
|
||||||
|
stream->writeString(m##name##Name[index]);
|
||||||
|
|
||||||
|
#define UNPACK_SHAPEASSET_ARRAY(netconn, name, index)\
|
||||||
|
if (stream->readFlag())\
|
||||||
|
{\
|
||||||
|
m##name##AssetId[index] = StringTable->insert(netconn->unpackNetStringHandleU(stream).getString());\
|
||||||
|
_set##name(m##name##AssetId[index], index);\
|
||||||
|
}\
|
||||||
|
else\
|
||||||
|
m##name##Name[index] = stream->readSTString();
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -42,19 +42,20 @@
|
||||||
|
|
||||||
// Debug Profiling.
|
// Debug Profiling.
|
||||||
#include "platform/profiler.h"
|
#include "platform/profiler.h"
|
||||||
|
#include "sfx/sfxTypes.h"
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
IMPLEMENT_CONOBJECT(SoundAsset);
|
IMPLEMENT_CONOBJECT(SoundAsset);
|
||||||
|
|
||||||
ConsoleType(SoundAssetPtr, TypeSoundAssetPtr, SoundAsset, ASSET_ID_FIELD_PREFIX)
|
ConsoleType(SoundAssetPtr, TypeSoundAssetPtr, const char*, ASSET_ID_FIELD_PREFIX)
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
ConsoleGetType(TypeSoundAssetPtr)
|
ConsoleGetType(TypeSoundAssetPtr)
|
||||||
{
|
{
|
||||||
// Fetch asset Id.
|
// Fetch asset Id.
|
||||||
return (*((AssetPtr<SoundAsset>*)dptr)).getAssetId();
|
return *((const char**)(dptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
@ -65,21 +66,7 @@ ConsoleSetType(TypeSoundAssetPtr)
|
||||||
if (argc == 1)
|
if (argc == 1)
|
||||||
{
|
{
|
||||||
// Yes, so fetch field value.
|
// Yes, so fetch field value.
|
||||||
const char* pFieldValue = argv[0];
|
*((const char**)dptr) = StringTable->insert(argv[0]);
|
||||||
|
|
||||||
// Fetch asset pointer.
|
|
||||||
AssetPtr<SoundAsset>* pAssetPtr = dynamic_cast<AssetPtr<SoundAsset>*>((AssetPtrBase*)(dptr));
|
|
||||||
|
|
||||||
// Is the asset pointer the correct type?
|
|
||||||
if (pAssetPtr == NULL)
|
|
||||||
{
|
|
||||||
// No, so fail.
|
|
||||||
//Con::warnf("(TypeSoundAssetPtr) - Failed to set asset Id '%d'.", pFieldValue);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set asset.
|
|
||||||
pAssetPtr->setAssetId(pFieldValue);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -90,15 +77,57 @@ ConsoleSetType(TypeSoundAssetPtr)
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ConsoleType(assetIdString, TypeSoundAssetId, const char*, ASSET_ID_FIELD_PREFIX)
|
||||||
|
|
||||||
|
ConsoleGetType(TypeSoundAssetId)
|
||||||
|
{
|
||||||
|
// Fetch asset Id.
|
||||||
|
return *((const char**)(dptr));
|
||||||
|
}
|
||||||
|
|
||||||
|
ConsoleSetType(TypeSoundAssetId)
|
||||||
|
{
|
||||||
|
// Was a single argument specified?
|
||||||
|
if (argc == 1)
|
||||||
|
{
|
||||||
|
// Yes, so fetch field value.
|
||||||
|
*((const char**)dptr) = StringTable->insert(argv[0]);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Warn.
|
||||||
|
Con::warnf("(TypeAssetId) - Cannot set multiple args to a single asset.");
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
SoundAsset::SoundAsset()
|
SoundAsset::SoundAsset()
|
||||||
{
|
{
|
||||||
mSoundFile = StringTable->EmptyString();
|
mSoundFile = StringTable->EmptyString();
|
||||||
mSoundPath = StringTable->EmptyString();
|
mSoundPath = StringTable->EmptyString();
|
||||||
|
mSubtitleString = StringTable->EmptyString();
|
||||||
|
|
||||||
mPitchAdjust = 1;
|
mLoadedState = AssetErrCode::NotLoaded;
|
||||||
mVolumeAdjust = 1;
|
mPreload = false;
|
||||||
|
// SFX description inits
|
||||||
|
// reverb is useless here, reverb is inacted on listener.
|
||||||
|
mProfileDesc.mPitch = 1;
|
||||||
|
mProfileDesc.mVolume = 1;
|
||||||
|
mProfileDesc.mIs3D = false;
|
||||||
|
mProfileDesc.mIsLooping = false;
|
||||||
|
mProfileDesc.mIsStreaming = false;
|
||||||
|
mProfileDesc.mUseHardware = false;
|
||||||
|
mProfileDesc.mMinDistance = 1;
|
||||||
|
mProfileDesc.mMaxDistance = 100;
|
||||||
|
mProfileDesc.mConeInsideAngle = 360;
|
||||||
|
mProfileDesc.mConeOutsideAngle = 360;
|
||||||
|
mProfileDesc.mConeOutsideVolume = 1;
|
||||||
|
mProfileDesc.mRolloffFactor = -1.0f;
|
||||||
|
mProfileDesc.mScatterDistance = Point3F(0.f, 0.f, 0.f);
|
||||||
|
mProfileDesc.mPriority = 1.0f;
|
||||||
|
mProfileDesc.mSourceGroup = NULL;
|
||||||
|
|
||||||
//mSound = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
@ -117,8 +146,24 @@ void SoundAsset::initPersistFields()
|
||||||
addProtectedField("soundFile", TypeAssetLooseFilePath, Offset(mSoundFile, SoundAsset),
|
addProtectedField("soundFile", TypeAssetLooseFilePath, Offset(mSoundFile, SoundAsset),
|
||||||
&setSoundFile, &getSoundFile, "Path to the sound file.");
|
&setSoundFile, &getSoundFile, "Path to the sound file.");
|
||||||
|
|
||||||
addField("pitchAdjust", TypeF32, Offset(mPitchAdjust, SoundAsset), "Adjustment of the pitch value");
|
addField("pitchAdjust", TypeF32, Offset(mProfileDesc.mPitch, SoundAsset), "Adjustment of the pitch value 1 is default.");
|
||||||
addField("volumeAdjust", TypeF32, Offset(mVolumeAdjust, SoundAsset), "Adjustment to the volume.");
|
addField("volumeAdjust", TypeF32, Offset(mProfileDesc.mVolume, SoundAsset), "Adjustment to the volume.");
|
||||||
|
addField("is3D", TypeBool, Offset(mProfileDesc.mIs3D, SoundAsset), "Set this sound to 3D.");
|
||||||
|
addField("isLooping", TypeBool, Offset(mProfileDesc.mIsLooping, SoundAsset), "Does this sound loop.");
|
||||||
|
// if streaming, a default packet size should be chosen for all sounds.
|
||||||
|
addField("isStreaming", TypeBool, Offset(mProfileDesc.mIsStreaming, SoundAsset), "Use streaming.");
|
||||||
|
//....why?
|
||||||
|
addField("useHardware", TypeBool, Offset(mProfileDesc.mUseHardware, SoundAsset), "Use hardware mixing for this sound.");
|
||||||
|
addField("minDistance", TypeF32, Offset(mProfileDesc.mMinDistance, SoundAsset), "Minimum distance for sound.");
|
||||||
|
// more like it.
|
||||||
|
addField("maxDistance", TypeF32, Offset(mProfileDesc.mMaxDistance, SoundAsset), "Max distance for sound.");
|
||||||
|
addField("coneInsideAngle", TypeS32, Offset(mProfileDesc.mConeInsideAngle, SoundAsset), "Cone inside angle.");
|
||||||
|
addField("coneOutsideAngle", TypeS32, Offset(mProfileDesc.mConeOutsideAngle, SoundAsset), "Cone outside angle.");
|
||||||
|
addField("coneOutsideVolume", TypeS32, Offset(mProfileDesc.mConeOutsideVolume, SoundAsset), "Cone outside volume.");
|
||||||
|
addField("rolloffFactor", TypeF32, Offset(mProfileDesc.mRolloffFactor, SoundAsset), "Rolloff factor.");
|
||||||
|
addField("scatterDistance", TypePoint3F, Offset(mProfileDesc.mScatterDistance, SoundAsset), "Randomization to the spacial position of the sound.");
|
||||||
|
addField("sourceGroup", TypeSFXSourceName, Offset(mProfileDesc.mSourceGroup, SoundAsset), "Group that sources playing with this description should be put into.");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
@ -131,20 +176,73 @@ void SoundAsset::copyTo(SimObject* object)
|
||||||
|
|
||||||
void SoundAsset::initializeAsset(void)
|
void SoundAsset::initializeAsset(void)
|
||||||
{
|
{
|
||||||
mSoundPath = expandAssetFilePath(mSoundFile);
|
Parent::initializeAsset();
|
||||||
|
|
||||||
|
if (mSoundFile == StringTable->EmptyString())
|
||||||
|
return;
|
||||||
|
|
||||||
|
//ResourceManager::get().getChangedSignal.notify(this, &SoundAsset::_onResourceChanged);
|
||||||
|
|
||||||
|
//Ensure our path is expando'd if it isn't already
|
||||||
|
if (!Platform::isFullPath(mSoundPath))
|
||||||
|
mSoundPath = getOwned() ? expandAssetFilePath(mSoundFile) : mSoundPath;
|
||||||
|
|
||||||
|
mSoundPath = expandAssetFilePath(mSoundPath);
|
||||||
|
|
||||||
|
loadSound();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoundAsset::_onResourceChanged(const Torque::Path &path)
|
||||||
|
{
|
||||||
|
if (path != Torque::Path(mSoundPath))
|
||||||
|
return;
|
||||||
|
|
||||||
|
refreshAsset();
|
||||||
|
|
||||||
|
loadSound();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundAsset::onAssetRefresh(void)
|
void SoundAsset::onAssetRefresh(void)
|
||||||
{
|
{
|
||||||
mSoundPath = expandAssetFilePath(mSoundFile);
|
if (mSoundFile == StringTable->EmptyString())
|
||||||
|
return;
|
||||||
|
|
||||||
|
//Update
|
||||||
|
if (!Platform::isFullPath(mSoundFile))
|
||||||
|
mSoundPath = getOwned() ? expandAssetFilePath(mSoundFile) : mSoundPath;
|
||||||
|
|
||||||
|
loadSound();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SoundAsset::loadSound()
|
||||||
|
{
|
||||||
|
if (mSoundPath)
|
||||||
|
{
|
||||||
|
if (!Torque::FS::IsFile(mSoundPath))
|
||||||
|
{
|
||||||
|
Con::errorf("SoundAsset::initializeAsset: Attempted to load file %s but it was not valid!", mSoundFile);
|
||||||
|
mLoadedState = BadFileReference;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{// = new SFXProfile(mProfileDesc, mSoundFile, mPreload);
|
||||||
|
mSFXProfile.setDescription(&mProfileDesc);
|
||||||
|
mSFXProfile.setSoundFileName(mSoundFile);
|
||||||
|
mSFXProfile.setPreload(mPreload);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
mChangeSignal.trigger();
|
||||||
|
mLoadedState = Ok;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundAsset::setSoundFile(const char* pSoundFile)
|
void SoundAsset::setSoundFile(const char* pSoundFile)
|
||||||
{
|
{
|
||||||
// Sanity!
|
// Sanity!
|
||||||
AssertFatal(pSoundFile != NULL, "Cannot use a NULL shape file.");
|
AssertFatal(pSoundFile != NULL, "Cannot use a NULL sound file.");
|
||||||
|
|
||||||
// Fetch image file.
|
// Fetch sound file.
|
||||||
pSoundFile = StringTable->insert(pSoundFile);
|
pSoundFile = StringTable->insert(pSoundFile);
|
||||||
|
|
||||||
// Ignore no change,
|
// Ignore no change,
|
||||||
|
|
@ -152,7 +250,7 @@ void SoundAsset::setSoundFile(const char* pSoundFile)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Update.
|
// Update.
|
||||||
mSoundFile = StringTable->insert(pSoundFile);
|
mSoundFile = pSoundFile;
|
||||||
|
|
||||||
// Refresh the asset.
|
// Refresh the asset.
|
||||||
refreshAsset();
|
refreshAsset();
|
||||||
|
|
@ -162,3 +260,43 @@ DefineEngineMethod(SoundAsset, getSoundPath, const char*, (), , "")
|
||||||
{
|
{
|
||||||
return object->getSoundPath();
|
return object->getSoundPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IMPLEMENT_CONOBJECT(GuiInspectorTypeSoundAssetPtr);
|
||||||
|
|
||||||
|
ConsoleDocClass(GuiInspectorTypeSoundAssetPtr,
|
||||||
|
"@brief Inspector field type for Sounds\n\n"
|
||||||
|
"Editor use only.\n\n"
|
||||||
|
"@internal"
|
||||||
|
);
|
||||||
|
|
||||||
|
void GuiInspectorTypeSoundAssetPtr::consoleInit()
|
||||||
|
{
|
||||||
|
Parent::consoleInit();
|
||||||
|
|
||||||
|
ConsoleBaseType::getType(TypeSoundAssetPtr)->setInspectorFieldType("GuiInspectorTypeSoundAssetPtr");
|
||||||
|
}
|
||||||
|
|
||||||
|
GuiControl * GuiInspectorTypeSoundAssetPtr::constructEditControl()
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GuiInspectorTypeSoundAssetPtr::updateRects()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
IMPLEMENT_CONOBJECT(GuiInspectorTypeSoundAssetId);
|
||||||
|
|
||||||
|
ConsoleDocClass(GuiInspectorTypeSoundAssetId,
|
||||||
|
"@brief Inspector field type for Sounds\n\n"
|
||||||
|
"Editor use only.\n\n"
|
||||||
|
"@internal"
|
||||||
|
);
|
||||||
|
|
||||||
|
void GuiInspectorTypeSoundAssetId::consoleInit()
|
||||||
|
{
|
||||||
|
Parent::consoleInit();
|
||||||
|
|
||||||
|
ConsoleBaseType::getType(TypeSoundAssetId)->setInspectorFieldType("GuiInspectorTypeSoundAssetId");
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,25 @@
|
||||||
#include "assets/assetFieldTypes.h"
|
#include "assets/assetFieldTypes.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class SFXTrack;
|
#include "gui/editor/guiInspectorTypes.h"
|
||||||
|
|
||||||
|
#ifndef _BITSTREAM_H_
|
||||||
|
#include "core/stream/bitStream.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _SFXRESOURCE_H_
|
||||||
|
#include "sfx/sfxResource.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _SFXDESCRIPTION_H_
|
||||||
|
#include "sfx/sfxDescription.h"
|
||||||
|
#endif // !_SFXDESCRIPTION_H_
|
||||||
|
|
||||||
|
#ifndef _SFXPROFILE_H_
|
||||||
|
#include "sfx/sfxProfile.h"
|
||||||
|
#endif // !_SFXPROFILE_H_
|
||||||
|
|
||||||
|
class SFXResource;
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
class SoundAsset : public AssetBase
|
class SoundAsset : public AssetBase
|
||||||
|
|
@ -49,8 +67,36 @@ class SoundAsset : public AssetBase
|
||||||
protected:
|
protected:
|
||||||
StringTableEntry mSoundFile;
|
StringTableEntry mSoundFile;
|
||||||
StringTableEntry mSoundPath;
|
StringTableEntry mSoundPath;
|
||||||
|
SFXProfile mSFXProfile;
|
||||||
|
SFXDescription mProfileDesc;
|
||||||
|
// subtitles
|
||||||
|
StringTableEntry mSubtitleString;
|
||||||
|
bool mPreload;
|
||||||
|
|
||||||
|
/*These will be needed in the refactor!
|
||||||
|
Resource<SFXResource> mSoundResource;
|
||||||
|
|
||||||
|
|
||||||
|
// SFXDesctriptions, some off these will be removed
|
||||||
F32 mPitchAdjust;
|
F32 mPitchAdjust;
|
||||||
F32 mVolumeAdjust;
|
F32 mVolumeAdjust;
|
||||||
|
bool mIs3D;
|
||||||
|
bool mLoop;
|
||||||
|
bool mIsStreaming;
|
||||||
|
bool mUseHardware;
|
||||||
|
|
||||||
|
F32 mMinDistance;
|
||||||
|
F32 mMaxDistance;
|
||||||
|
U32 mConeInsideAngle;
|
||||||
|
U32 mConeOutsideAngle;
|
||||||
|
F32 mConeOutsideVolume;
|
||||||
|
F32 mRolloffFactor;
|
||||||
|
Point3F mScatterDistance;
|
||||||
|
F32 mPriority;
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef Signal<void()> SoundAssetChanged;
|
||||||
|
SoundAssetChanged mChangeSignal;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SoundAsset();
|
SoundAsset();
|
||||||
|
|
@ -60,16 +106,26 @@ public:
|
||||||
static void initPersistFields();
|
static void initPersistFields();
|
||||||
virtual void copyTo(SimObject* object);
|
virtual void copyTo(SimObject* object);
|
||||||
|
|
||||||
|
//SFXResource* getSound() { return mSoundResource; }
|
||||||
|
Resource<SFXResource> getSoundResource() { return mSFXProfile.getResource(); }
|
||||||
|
|
||||||
/// Declare Console Object.
|
/// Declare Console Object.
|
||||||
DECLARE_CONOBJECT(SoundAsset);
|
DECLARE_CONOBJECT(SoundAsset);
|
||||||
|
|
||||||
void setSoundFile(const char* pSoundFile);
|
void setSoundFile(const char* pSoundFile);
|
||||||
|
bool loadSound();
|
||||||
inline StringTableEntry getSoundFile(void) const { return mSoundFile; };
|
inline StringTableEntry getSoundFile(void) const { return mSoundFile; };
|
||||||
|
|
||||||
inline StringTableEntry getSoundPath(void) const { return mSoundPath; };
|
inline StringTableEntry getSoundPath(void) const { return mSoundPath; };
|
||||||
|
SFXProfile* getSfxProfile() { return &mSFXProfile; }
|
||||||
|
SFXDescription* getSfxDescription() { return &mProfileDesc; }
|
||||||
|
|
||||||
|
bool isLoop() { return mProfileDesc.mIsLooping; }
|
||||||
|
bool is3D() { return mProfileDesc.mIs3D; }
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void initializeAsset(void);
|
virtual void initializeAsset(void);
|
||||||
|
void _onResourceChanged(const Torque::Path & path);
|
||||||
virtual void onAssetRefresh(void);
|
virtual void onAssetRefresh(void);
|
||||||
|
|
||||||
static bool setSoundFile(void *obj, const char *index, const char *data) { static_cast<SoundAsset*>(obj)->setSoundFile(data); return false; }
|
static bool setSoundFile(void *obj, const char *index, const char *data) { static_cast<SoundAsset*>(obj)->setSoundFile(data); return false; }
|
||||||
|
|
@ -77,6 +133,229 @@ protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
DefineConsoleType(TypeSoundAssetPtr, SoundAsset)
|
DefineConsoleType(TypeSoundAssetPtr, SoundAsset)
|
||||||
|
DefineConsoleType(TypeSoundAssetId, String)
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// TypeAssetId GuiInspectorField Class
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
class GuiInspectorTypeSoundAssetPtr : public GuiInspectorTypeFileName
|
||||||
|
{
|
||||||
|
typedef GuiInspectorTypeFileName Parent;
|
||||||
|
public:
|
||||||
|
|
||||||
|
GuiBitmapButtonCtrl* mSoundButton;
|
||||||
|
|
||||||
|
DECLARE_CONOBJECT(GuiInspectorTypeSoundAssetPtr);
|
||||||
|
static void consoleInit();
|
||||||
|
|
||||||
|
virtual GuiControl* constructEditControl();
|
||||||
|
virtual bool updateRects();
|
||||||
|
};
|
||||||
|
|
||||||
|
class GuiInspectorTypeSoundAssetId : public GuiInspectorTypeSoundAssetPtr
|
||||||
|
{
|
||||||
|
typedef GuiInspectorTypeSoundAssetPtr Parent;
|
||||||
|
public:
|
||||||
|
|
||||||
|
DECLARE_CONOBJECT(GuiInspectorTypeSoundAssetId);
|
||||||
|
static void consoleInit();
|
||||||
|
};
|
||||||
|
|
||||||
|
#pragma region Singular Asset Macros
|
||||||
|
|
||||||
|
//Singular assets
|
||||||
|
/// <Summary>
|
||||||
|
/// Declares a sound asset
|
||||||
|
/// This establishes the assetId, asset and legacy filepath fields, along with supplemental getter and setter functions
|
||||||
|
/// </Summary>
|
||||||
|
#define DECLARE_SOUNDASSET(className, name, profile) public: \
|
||||||
|
Resource<SFXResource> m##name;\
|
||||||
|
StringTableEntry m##name##Name; \
|
||||||
|
StringTableEntry m##name##AssetId;\
|
||||||
|
AssetPtr<SoundAsset> m##name##Asset = NULL;\
|
||||||
|
SFXProfile* m##name##Profile = &profile;\
|
||||||
|
public: \
|
||||||
|
const StringTableEntry get##name##File() const { return m##name##Name); }\
|
||||||
|
void set##name##File(const FileName &_in) { m##name##Name = StringTable->insert(_in.c_str());}\
|
||||||
|
const AssetPtr<SoundAsset> & get##name##Asset() const { return m##name##Asset; }\
|
||||||
|
void set##name##Asset(const AssetPtr<SoundAsset> &_in) { m##name##Asset = _in;}\
|
||||||
|
\
|
||||||
|
bool _set##name(StringTableEntry _in)\
|
||||||
|
{\
|
||||||
|
if(m##name##AssetId != _in || m##name##Name != _in)\
|
||||||
|
{\
|
||||||
|
if (_in == StringTable->EmptyString())\
|
||||||
|
{\
|
||||||
|
m##name##Name = StringTable->EmptyString();\
|
||||||
|
m##name##AssetId = StringTable->EmptyString();\
|
||||||
|
m##name##Asset = NULL;\
|
||||||
|
m##name = NULL;\
|
||||||
|
return true;\
|
||||||
|
}\
|
||||||
|
\
|
||||||
|
if (AssetDatabase.isDeclaredAsset(_in))\
|
||||||
|
{\
|
||||||
|
m##name##AssetId = _in;\
|
||||||
|
\
|
||||||
|
U32 assetState = SoundAsset::getAssetById(m##name##AssetId, &m##name##Asset);\
|
||||||
|
\
|
||||||
|
if (SoundAsset::Ok == assetState)\
|
||||||
|
{\
|
||||||
|
m##name##Name = StringTable->EmptyString();\
|
||||||
|
}\
|
||||||
|
}\
|
||||||
|
else\
|
||||||
|
{\
|
||||||
|
StringTableEntry assetId = SoundAsset::getAssetIdByFilename(_in);\
|
||||||
|
if (assetId != StringTable->EmptyString())\
|
||||||
|
{\
|
||||||
|
m##name##AssetId = assetId;\
|
||||||
|
if(SoundAsset::getAssetById(m##name##AssetId, &m##name##Asset) == SoundAsset::Ok)\
|
||||||
|
{\
|
||||||
|
m##name##Name = StringTable->EmptyString();\
|
||||||
|
}\
|
||||||
|
}\
|
||||||
|
else\
|
||||||
|
{\
|
||||||
|
m##name##Name = _in;\
|
||||||
|
m##name##AssetId = StringTable->EmptyString();\
|
||||||
|
m##name##Asset = NULL;\
|
||||||
|
}\
|
||||||
|
}\
|
||||||
|
}\
|
||||||
|
if (get##name() != StringTable->EmptyString() && m##name##Asset.notNull())\
|
||||||
|
{\
|
||||||
|
m##name = m##name##Asset->getSoundResource();\
|
||||||
|
}\
|
||||||
|
else\
|
||||||
|
{\
|
||||||
|
m##name = NULL;\
|
||||||
|
}\
|
||||||
|
\
|
||||||
|
if (m##name##Asset.notNull() && m##name##Asset->getStatus() != ShapeAsset::Ok)\
|
||||||
|
{\
|
||||||
|
Con::errorf("%s(%s)::_set%s() - sound asset failure\"%s\" due to [%s]", macroText(className), getName(), macroText(name), _in, ShapeAsset::getAssetErrstrn(m##name##Asset->getStatus()).c_str());\
|
||||||
|
return false; \
|
||||||
|
}\
|
||||||
|
else if (bool(m##name) == NULL)\
|
||||||
|
{\
|
||||||
|
Con::errorf("%s(%s)::_set%s() - Couldn't load sound \"%s\"", macroText(className), getName(), macroText(name), _in);\
|
||||||
|
return false;\
|
||||||
|
}\
|
||||||
|
return true;\
|
||||||
|
}\
|
||||||
|
\
|
||||||
|
const StringTableEntry get##name() const\
|
||||||
|
{\
|
||||||
|
if (m##name##Asset && (m##name##Asset->getSoundPath() != StringTable->EmptyString()))\
|
||||||
|
return m##name##Asset->getSoundPath();\
|
||||||
|
else if (m##name##AssetId != StringTable->EmptyString())\
|
||||||
|
return m##name##AssetId;\
|
||||||
|
else if (m##name##Name != StringTable->EmptyString())\
|
||||||
|
return StringTable->insert(m##name##Name);\
|
||||||
|
else\
|
||||||
|
return StringTable->EmptyString();\
|
||||||
|
}\
|
||||||
|
Resource<SFXResource> get##name##Resource() \
|
||||||
|
{\
|
||||||
|
return m##name;\
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DECLARE_SOUNDASSET_SETGET(className, name)\
|
||||||
|
static bool _set##name##Data(void* obj, const char* index, const char* data)\
|
||||||
|
{\
|
||||||
|
bool ret = false;\
|
||||||
|
className* object = static_cast<className*>(obj);\
|
||||||
|
ret = object->_set##name(StringTable->insert(data));\
|
||||||
|
return ret;\
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DECLARE_SOUNDASSET_NET_SETGET(className, name, bitmask)\
|
||||||
|
static bool _set##name##Data(void* obj, const char* index, const char* data)\
|
||||||
|
{\
|
||||||
|
bool ret = false;\
|
||||||
|
className* object = static_cast<className*>(obj);\
|
||||||
|
ret = object->_set##name(StringTable->insert(data));\
|
||||||
|
if(ret)\
|
||||||
|
object->setMaskBits(bitmask);\
|
||||||
|
return ret;\
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DEF_SOUNDASSET_BINDS(className,name)\
|
||||||
|
DefineEngineMethod(className, get##name, String, (), , "get name")\
|
||||||
|
{\
|
||||||
|
return object->get##name(); \
|
||||||
|
}\
|
||||||
|
DefineEngineMethod(className, get##name##Asset, String, (), , assetText(name, asset reference))\
|
||||||
|
{\
|
||||||
|
return object->m##name##AssetId; \
|
||||||
|
}\
|
||||||
|
DefineEngineMethod(className, set##name, bool, (const char* shape), , assetText(name,assignment. first tries asset then flat file.))\
|
||||||
|
{\
|
||||||
|
return object->_set##name(StringTable->insert(shape));\
|
||||||
|
}
|
||||||
|
|
||||||
|
#define INIT_SOUNDASSET(name) \
|
||||||
|
m##name##Name = StringTable->EmptyString(); \
|
||||||
|
m##name##AssetId = StringTable->EmptyString(); \
|
||||||
|
m##name##Asset = NULL; \
|
||||||
|
m##name = NULL;\
|
||||||
|
|
||||||
|
#ifdef TORQUE_SHOW_LEGACY_FILE_FIELDS
|
||||||
|
|
||||||
|
#define INITPERSISTFIELD_SOUNDASSET(name, consoleClass, docs) \
|
||||||
|
addProtectedField(assetText(name, File), TypeSoundFilename, Offset(m##name##Name, consoleClass), _set##name##Data, & defaultProtectedGetFn, assetText(name, docs)); \
|
||||||
|
addProtectedField(assetText(name, Asset), TypeSoundAssetId, Offset(m##name##AssetId, consoleClass), _set##name##Data, & defaultProtectedGetFn, assetText(name, asset reference.));
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define INITPERSISTFIELD_SOUNDASSET(name, consoleClass, docs) \
|
||||||
|
addProtectedField(assetText(name, File), TypeSoundFilename, Offset(m##name##Name, consoleClass), _set##name##Data, & defaultProtectedGetFn, assetText(name, docs), AbstractClassRep::FIELD_HideInInspectors); \
|
||||||
|
addProtectedField(assetText(name, Asset), TypeSoundAssetId, Offset(m##name##AssetId, consoleClass), _set##name##Data, & defaultProtectedGetFn, assetText(name, asset reference.));
|
||||||
|
|
||||||
|
#endif // TORQUE_SHOW_LEGACY_FILE_FIELDS
|
||||||
|
|
||||||
|
#define CLONE_SOUNDASSET(name) \
|
||||||
|
m##name##Name = other.m##name##Name;\
|
||||||
|
m##name##AssetId = other.m##name##AssetId;\
|
||||||
|
m##name##Asset = other.m##name##Asset;\
|
||||||
|
|
||||||
|
#define PACKDATA_SOUNDASSET(name)\
|
||||||
|
if (stream->writeFlag(m##name##Asset.notNull()))\
|
||||||
|
{\
|
||||||
|
stream->writeString(m##name##Asset.getAssetId());\
|
||||||
|
}\
|
||||||
|
else\
|
||||||
|
stream->writeString(m##name##Name);
|
||||||
|
|
||||||
|
#define UNPACKDATA_SOUNDASSET(name)\
|
||||||
|
if (stream->readFlag())\
|
||||||
|
{\
|
||||||
|
m##name##AssetId = stream->readSTString();\
|
||||||
|
_set##name(m##name##AssetId);\
|
||||||
|
}\
|
||||||
|
else\
|
||||||
|
m##name##Name = stream->readSTString();
|
||||||
|
|
||||||
|
#define PACK_SOUNDASSET(netconn, name)\
|
||||||
|
if (stream->writeFlag(m##name##Asset.notNull()))\
|
||||||
|
{\
|
||||||
|
NetStringHandle assetIdStr = m##name##Asset.getAssetId();\
|
||||||
|
netconn->packNetStringHandleU(stream, assetIdStr);\
|
||||||
|
}\
|
||||||
|
else\
|
||||||
|
stream->writeString(m##name##Name);
|
||||||
|
|
||||||
|
#define UNPACK_SOUNDASSET(netconn, name)\
|
||||||
|
if (stream->readFlag())\
|
||||||
|
{\
|
||||||
|
m##name##AssetId = StringTable->insert(netconn->unpackNetStringHandleU(stream).getString());\
|
||||||
|
_set##name(m##name##AssetId);\
|
||||||
|
}\
|
||||||
|
else\
|
||||||
|
m##name##Name = stream->readSTString();
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
#endif // _ASSET_BASE_H_
|
#endif // _ASSET_BASE_H_
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,7 @@ ConsoleSetType(TypeTerrainAssetPtr)
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
ConsoleType(assetIdString, TypeTerrainAssetId, String, ASSET_ID_FIELD_PREFIX)
|
ConsoleType(assetIdString, TypeTerrainAssetId, const char*, ASSET_ID_FIELD_PREFIX)
|
||||||
|
|
||||||
ConsoleGetType(TypeTerrainAssetId)
|
ConsoleGetType(TypeTerrainAssetId)
|
||||||
{
|
{
|
||||||
|
|
@ -107,11 +107,7 @@ ConsoleSetType(TypeTerrainAssetId)
|
||||||
// Yes, so fetch field value.
|
// Yes, so fetch field value.
|
||||||
const char* pFieldValue = argv[0];
|
const char* pFieldValue = argv[0];
|
||||||
|
|
||||||
// Fetch asset Id.
|
*((const char**)dptr) = StringTable->insert(argv[0]);
|
||||||
StringTableEntry* assetId = (StringTableEntry*)(dptr);
|
|
||||||
|
|
||||||
// Update asset value.
|
|
||||||
*assetId = StringTable->insert(pFieldValue);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -194,7 +190,7 @@ void TerrainAsset::setTerrainFileName(const char* pScriptFile)
|
||||||
|
|
||||||
bool TerrainAsset::loadTerrain()
|
bool TerrainAsset::loadTerrain()
|
||||||
{
|
{
|
||||||
if (!Platform::isFile(mTerrainFilePath))
|
if (!Torque::FS::IsFile(mTerrainFilePath))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
mTerrMaterialAssets.clear();
|
mTerrMaterialAssets.clear();
|
||||||
|
|
@ -471,8 +467,8 @@ GuiControl* GuiInspectorTypeTerrainAssetPtr::constructEditControl()
|
||||||
|
|
||||||
mShapeEdButton->setField("Command", "EditorGui.setEditor(TerrainEditorPlugin);");
|
mShapeEdButton->setField("Command", "EditorGui.setEditor(TerrainEditorPlugin);");
|
||||||
|
|
||||||
char bitmapName[512] = "tools/worldEditor/images/toolbar/shape-editor";
|
char bitmapName[512] = "ToolsModule:TerrainBlock_image";
|
||||||
mShapeEdButton->setBitmap(bitmapName);
|
mShapeEdButton->setBitmap(StringTable->insert(bitmapName));
|
||||||
|
|
||||||
mShapeEdButton->setDataField(StringTable->insert("Profile"), NULL, "GuiButtonProfile");
|
mShapeEdButton->setDataField(StringTable->insert("Profile"), NULL, "GuiButtonProfile");
|
||||||
mShapeEdButton->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile");
|
mShapeEdButton->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile");
|
||||||
|
|
|
||||||
|
|
@ -119,11 +119,9 @@ void TerrainMaterialAsset::initializeAsset()
|
||||||
// Call parent.
|
// Call parent.
|
||||||
Parent::initializeAsset();
|
Parent::initializeAsset();
|
||||||
|
|
||||||
compileShader();
|
|
||||||
|
|
||||||
mScriptPath = expandAssetFilePath(mScriptFile);
|
mScriptPath = expandAssetFilePath(mScriptFile);
|
||||||
|
|
||||||
if (Platform::isFile(mScriptPath))
|
if (Torque::FS::IsScriptFile(mScriptPath))
|
||||||
Con::executeFile(mScriptPath, false, false);
|
Con::executeFile(mScriptPath, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -131,7 +129,7 @@ void TerrainMaterialAsset::onAssetRefresh()
|
||||||
{
|
{
|
||||||
mScriptPath = expandAssetFilePath(mScriptFile);
|
mScriptPath = expandAssetFilePath(mScriptFile);
|
||||||
|
|
||||||
if (Platform::isFile(mScriptPath))
|
if (Torque::FS::IsScriptFile(mScriptPath))
|
||||||
Con::executeFile(mScriptPath, false, false);
|
Con::executeFile(mScriptPath, false, false);
|
||||||
|
|
||||||
if (mMatDefinitionName != StringTable->EmptyString())
|
if (mMatDefinitionName != StringTable->EmptyString())
|
||||||
|
|
@ -164,21 +162,49 @@ void TerrainMaterialAsset::setScriptFile(const char* pScriptFile)
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
void TerrainMaterialAsset::compileShader()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void TerrainMaterialAsset::copyTo(SimObject* object)
|
void TerrainMaterialAsset::copyTo(SimObject* object)
|
||||||
{
|
{
|
||||||
// Call to parent.
|
// Call to parent.
|
||||||
Parent::copyTo(object);
|
Parent::copyTo(object);
|
||||||
}
|
}
|
||||||
|
|
||||||
DefineEngineMethod(TerrainMaterialAsset, compileShader, void, (), , "Compiles the material's generated shader, if any. Not yet implemented\n")
|
StringTableEntry TerrainMaterialAsset::getAssetIdByMaterialName(StringTableEntry matName)
|
||||||
{
|
{
|
||||||
object->compileShader();
|
StringTableEntry materialAssetId = StringTable->EmptyString();
|
||||||
|
|
||||||
|
AssetQuery* query = new AssetQuery();
|
||||||
|
U32 foundCount = AssetDatabase.findAssetType(query, "TerrainMaterialAsset");
|
||||||
|
if (foundCount == 0)
|
||||||
|
{
|
||||||
|
//Didn't work, so have us fall back to a placeholder asset
|
||||||
|
materialAssetId = StringTable->insert("Core_Rendering:noMaterial");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (U32 i = 0; i < foundCount; i++)
|
||||||
|
{
|
||||||
|
TerrainMaterialAsset* matAsset = AssetDatabase.acquireAsset<TerrainMaterialAsset>(query->mAssetList[i]);
|
||||||
|
if (matAsset && matAsset->getMaterialDefinitionName() == matName)
|
||||||
|
{
|
||||||
|
materialAssetId = matAsset->getAssetId();
|
||||||
|
AssetDatabase.releaseAsset(query->mAssetList[i]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
AssetDatabase.releaseAsset(query->mAssetList[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return materialAssetId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef TORQUE_TOOLS
|
||||||
|
DefineEngineStaticMethod(TerrainMaterialAsset, getAssetIdByMaterialName, const char*, (const char* materialName), (""),
|
||||||
|
"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.")
|
||||||
|
{
|
||||||
|
return TerrainMaterialAsset::getAssetIdByMaterialName(StringTable->insert(materialName));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// GuiInspectorTypeAssetId
|
// GuiInspectorTypeAssetId
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
@ -218,7 +244,7 @@ GuiControl* GuiInspectorTypeTerrainMaterialAssetPtr::constructEditControl()
|
||||||
|
|
||||||
TerrainMaterial* materialDef = nullptr;
|
TerrainMaterial* materialDef = nullptr;
|
||||||
|
|
||||||
char bitmapName[512] = "tools/worldEditor/images/toolbar/shape-editor";
|
char bitmapName[512] = "ToolsModule:material_editor_n_image";
|
||||||
|
|
||||||
/*if (!Sim::findObject(matAsset->getMaterialDefinitionName(), materialDef))
|
/*if (!Sim::findObject(matAsset->getMaterialDefinitionName(), materialDef))
|
||||||
{
|
{
|
||||||
|
|
@ -245,7 +271,7 @@ GuiControl* GuiInspectorTypeTerrainMaterialAssetPtr::constructEditControl()
|
||||||
StringBuilder strbld;
|
StringBuilder strbld;
|
||||||
strbld.append(matAsset->getMaterialDefinitionName());
|
strbld.append(matAsset->getMaterialDefinitionName());
|
||||||
strbld.append("\n");
|
strbld.append("\n");
|
||||||
strbld.append("Open this file in the Material Editor");
|
strbld.append("Open this asset in the Material Editor");
|
||||||
|
|
||||||
mMatPreviewButton->setDataField(StringTable->insert("tooltip"), NULL, strbld.data());
|
mMatPreviewButton->setDataField(StringTable->insert("tooltip"), NULL, strbld.data());
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ public:
|
||||||
static void initPersistFields();
|
static void initPersistFields();
|
||||||
virtual void copyTo(SimObject* object);
|
virtual void copyTo(SimObject* object);
|
||||||
|
|
||||||
void compileShader();
|
static StringTableEntry getAssetIdByMaterialName(StringTableEntry matName);
|
||||||
|
|
||||||
StringTableEntry getMaterialDefinitionName() { return mMatDefinitionName; }
|
StringTableEntry getMaterialDefinitionName() { return mMatDefinitionName; }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,10 +32,11 @@ ConsoleDocClass(AssetImportConfig,
|
||||||
IMPLEMENT_CONOBJECT(AssetImportConfig);
|
IMPLEMENT_CONOBJECT(AssetImportConfig);
|
||||||
|
|
||||||
AssetImportConfig::AssetImportConfig() :
|
AssetImportConfig::AssetImportConfig() :
|
||||||
DuplicatAutoResolution("AutoRename"),
|
DuplicateAutoResolution("AutoRename"),
|
||||||
WarningsAsErrors(false),
|
WarningsAsErrors(false),
|
||||||
PreventImportWithErrors(true),
|
PreventImportWithErrors(true),
|
||||||
AutomaticallyPromptMissingFiles(false),
|
AutomaticallyPromptMissingFiles(false),
|
||||||
|
AddDirectoryPrefixToAssetName(false),
|
||||||
ImportMesh(true),
|
ImportMesh(true),
|
||||||
AlwaysAddShapeSuffix(false),
|
AlwaysAddShapeSuffix(false),
|
||||||
AddedShapeSuffix("_shape"),
|
AddedShapeSuffix("_shape"),
|
||||||
|
|
@ -89,7 +90,7 @@ AssetImportConfig::AssetImportConfig() :
|
||||||
ImageType("GUI"),
|
ImageType("GUI"),
|
||||||
DiffuseTypeSuffixes("_ALBEDO,_DIFFUSE,_ALB,_DIF,_COLOR,_COL,_A,_C,-ALBEDO,-DIFFUSE,-ALB,-DIF,-COLOR,-COL,-A,-C"),
|
DiffuseTypeSuffixes("_ALBEDO,_DIFFUSE,_ALB,_DIF,_COLOR,_COL,_A,_C,-ALBEDO,-DIFFUSE,-ALB,-DIF,-COLOR,-COL,-A,-C"),
|
||||||
NormalTypeSuffixes("_NORMAL,_NORM,_N,-NORMAL,-NORM,-N"),
|
NormalTypeSuffixes("_NORMAL,_NORM,_N,-NORMAL,-NORM,-N"),
|
||||||
MetalnessTypeSuffixes("_METAL,_MET,_METALNESS,_METALLIC,_M,-METAL, -MET, -METALNESS, -METALLIC, -M"),
|
MetalnessTypeSuffixes("_METAL,_MET,_METALNESS,_METALLIC,_M,-METAL,-MET,-METALNESS,-METALLIC,-M"),
|
||||||
RoughnessTypeSuffixes("_ROUGH,_ROUGHNESS,_R,-ROUGH,-ROUGHNESS,-R"),
|
RoughnessTypeSuffixes("_ROUGH,_ROUGHNESS,_R,-ROUGH,-ROUGHNESS,-R"),
|
||||||
SmoothnessTypeSuffixes("_SMOOTH,_SMOOTHNESS,_S,-SMOOTH,-SMOOTHNESS,-S"),
|
SmoothnessTypeSuffixes("_SMOOTH,_SMOOTHNESS,_S,-SMOOTH,-SMOOTHNESS,-S"),
|
||||||
AOTypeSuffixes("_AO,_AMBIENT,_AMBIENTOCCLUSION,-AO,-AMBIENT,-AMBIENTOCCLUSION"),
|
AOTypeSuffixes("_AO,_AMBIENT,_AMBIENTOCCLUSION,-AO,-AMBIENT,-AMBIENTOCCLUSION"),
|
||||||
|
|
@ -131,10 +132,11 @@ void AssetImportConfig::initPersistFields()
|
||||||
Parent::initPersistFields();
|
Parent::initPersistFields();
|
||||||
|
|
||||||
addGroup("General");
|
addGroup("General");
|
||||||
addField("DuplicatAutoResolution", TypeRealString, Offset(DuplicatAutoResolution, AssetImportConfig), "Duplicate Asset Auto-Resolution Action. Options are None, AutoPrune, AutoRename");
|
addField("DuplicateAutoResolution", TypeRealString, Offset(DuplicateAutoResolution, AssetImportConfig), "Duplicate Asset Auto-Resolution Action. Options are None, AutoPrune, AutoRename, FolderPrefix");
|
||||||
addField("WarningsAsErrors", TypeBool, Offset(WarningsAsErrors, AssetImportConfig), "Indicates if warnings should be treated as errors");
|
addField("WarningsAsErrors", TypeBool, Offset(WarningsAsErrors, AssetImportConfig), "Indicates if warnings should be treated as errors");
|
||||||
addField("PreventImportWithErrors", TypeBool, Offset(PreventImportWithErrors, AssetImportConfig), "Indicates if importing should be prevented from completing if any errors are detected at all");
|
addField("PreventImportWithErrors", TypeBool, Offset(PreventImportWithErrors, AssetImportConfig), "Indicates if importing should be prevented from completing if any errors are detected at all");
|
||||||
addField("AutomaticallyPromptMissingFiles", TypeBool, Offset(AutomaticallyPromptMissingFiles, AssetImportConfig), "Should the importer automatically prompt to find missing files if they are not detected automatically by the importer");
|
addField("AutomaticallyPromptMissingFiles", TypeBool, Offset(AutomaticallyPromptMissingFiles, AssetImportConfig), "Should the importer automatically prompt to find missing files if they are not detected automatically by the importer");
|
||||||
|
addField("AddDirectoryPrefixToAssetName", TypeBool, Offset(AddDirectoryPrefixToAssetName, AssetImportConfig), "Should the importer add the folder name as a prefix to the assetName. Helps prevent name collisions.");
|
||||||
endGroup("General");
|
endGroup("General");
|
||||||
|
|
||||||
addGroup("Meshes");
|
addGroup("Meshes");
|
||||||
|
|
@ -228,10 +230,11 @@ void AssetImportConfig::initPersistFields()
|
||||||
void AssetImportConfig::loadImportConfig(Settings* configSettings, String configName)
|
void AssetImportConfig::loadImportConfig(Settings* configSettings, String configName)
|
||||||
{
|
{
|
||||||
//General
|
//General
|
||||||
DuplicatAutoResolution = configSettings->value(String(configName + "/General/DuplicatAutoResolution").c_str());
|
DuplicateAutoResolution = configSettings->value(String(configName + "/General/DuplicateAutoResolution").c_str());
|
||||||
WarningsAsErrors = dAtob(configSettings->value(String(configName + "/General/WarningsAsErrors").c_str()));
|
WarningsAsErrors = dAtob(configSettings->value(String(configName + "/General/WarningsAsErrors").c_str()));
|
||||||
PreventImportWithErrors = dAtob(configSettings->value(String(configName + "/General/PreventImportWithErrors").c_str()));
|
PreventImportWithErrors = dAtob(configSettings->value(String(configName + "/General/PreventImportWithErrors").c_str()));
|
||||||
AutomaticallyPromptMissingFiles = dAtob(configSettings->value(String(configName + "/General/AutomaticallyPromptMissingFiles").c_str()));
|
AutomaticallyPromptMissingFiles = dAtob(configSettings->value(String(configName + "/General/AutomaticallyPromptMissingFiles").c_str()));
|
||||||
|
AddDirectoryPrefixToAssetName = dAtob(configSettings->value(String(configName + "/General/AddDirectoryPrefixToAssetName").c_str()));
|
||||||
|
|
||||||
//Meshes
|
//Meshes
|
||||||
ImportMesh = dAtob(configSettings->value(String(configName + "/Meshes/ImportMesh").c_str()));
|
ImportMesh = dAtob(configSettings->value(String(configName + "/Meshes/ImportMesh").c_str()));
|
||||||
|
|
@ -317,10 +320,11 @@ void AssetImportConfig::loadImportConfig(Settings* configSettings, String config
|
||||||
|
|
||||||
void AssetImportConfig::CopyTo(AssetImportConfig* target) const
|
void AssetImportConfig::CopyTo(AssetImportConfig* target) const
|
||||||
{
|
{
|
||||||
target->DuplicatAutoResolution = DuplicatAutoResolution;
|
target->DuplicateAutoResolution = DuplicateAutoResolution;
|
||||||
target->WarningsAsErrors = WarningsAsErrors;
|
target->WarningsAsErrors = WarningsAsErrors;
|
||||||
target->PreventImportWithErrors = PreventImportWithErrors;
|
target->PreventImportWithErrors = PreventImportWithErrors;
|
||||||
target->AutomaticallyPromptMissingFiles = AutomaticallyPromptMissingFiles;
|
target->AutomaticallyPromptMissingFiles = AutomaticallyPromptMissingFiles;
|
||||||
|
target->AddDirectoryPrefixToAssetName = AddDirectoryPrefixToAssetName;
|
||||||
|
|
||||||
//Meshes
|
//Meshes
|
||||||
target->ImportMesh = ImportMesh;
|
target->ImportMesh = ImportMesh;
|
||||||
|
|
@ -1444,8 +1448,8 @@ void AssetImporter::processImportAssets(AssetImportObject* assetItem)
|
||||||
if (!childItem->processed)
|
if (!childItem->processed)
|
||||||
{
|
{
|
||||||
//Sanitize before modifying our asset name(suffix additions, etc)
|
//Sanitize before modifying our asset name(suffix additions, etc)
|
||||||
if (childItem->assetName != childItem->cleanAssetName)
|
//if (childItem->assetName != childItem->cleanAssetName)
|
||||||
childItem->assetName = childItem->cleanAssetName;
|
// childItem->assetName = childItem->cleanAssetName;
|
||||||
|
|
||||||
//handle special pre-processing here for any types that need it
|
//handle special pre-processing here for any types that need it
|
||||||
|
|
||||||
|
|
@ -1579,6 +1583,28 @@ void AssetImporter::processImageAsset(AssetImportObject* assetItem)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//If we're processing an unaffiliated image without generating materials for it, we can check some other bits
|
||||||
|
if (assetItem->parentAssetItem == nullptr)
|
||||||
|
{
|
||||||
|
if (assetItem->typeHint != String::EmptyString)
|
||||||
|
{
|
||||||
|
ImageAssetType type = ImageAsset::getImageTypeFromName(StringTable->insert(assetItem->typeHint.c_str()));
|
||||||
|
|
||||||
|
if (type == ImageAssetType::GUI)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(assetItem->assetName == assetItem->cleanAssetName && activeImportConfig->AlwaysAddImageSuffix)
|
||||||
|
{
|
||||||
|
assetItem->assetName = assetItem->assetName + activeImportConfig->AddedImageSuffix;
|
||||||
|
assetItem->cleanAssetName = assetItem->assetName;
|
||||||
|
}
|
||||||
|
|
||||||
assetItem->processed = true;
|
assetItem->processed = true;
|
||||||
}
|
}
|
||||||
|
|
@ -1612,174 +1638,214 @@ void AssetImporter::processMaterialAsset(AssetImportObject* assetItem)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (activeImportConfig->AlwaysAddMaterialSuffix)
|
if (activeImportConfig->UseExistingMaterials)
|
||||||
{
|
{
|
||||||
assetItem->assetName += activeImportConfig->AddedMaterialSuffix;
|
//So if the material already exists, we should just use that. So first, let's find out if it already exists
|
||||||
}
|
|
||||||
|
|
||||||
if (activeImportConfig->PopulateMaterialMaps)
|
//check to see if the definition for this already exists
|
||||||
{
|
StringTableEntry existingMatAsset = MaterialAsset::getAssetIdByMaterialName(StringTable->insert(assetName));
|
||||||
//If we're trying to populate the rest of our material maps, we need to go looking
|
|
||||||
dSprintf(importLogBuffer, sizeof(importLogBuffer), "Attempting to Auto-Populate Material Maps");
|
|
||||||
activityLog.push_back(importLogBuffer);
|
|
||||||
|
|
||||||
AssetImportObject* matchedImageTypes[ImageAsset::ImageTypeCount] = { nullptr };
|
if (existingMatAsset != StringTable->EmptyString())
|
||||||
|
|
||||||
String materialImageNoSuffix;
|
|
||||||
|
|
||||||
for (U32 i = 0; i < assetItem->childAssetItems.size(); i++)
|
|
||||||
{
|
{
|
||||||
AssetImportObject* childAssetItem = assetItem->childAssetItems[i];
|
assetItem->skip = true;
|
||||||
|
dSprintf(importLogBuffer, sizeof(importLogBuffer), "Material %s has been skipped because we already found an asset Id that uses that material definition. The found assetId is: %s", assetItem->assetName.c_str(), existingMatAsset);
|
||||||
|
activityLog.push_back(importLogBuffer);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (childAssetItem->skip || childAssetItem->assetType != String("ImageAsset"))
|
//If there was no existing assetId, then lets see if it already exists in a legacy file, like a materials.cs or materials.tscript
|
||||||
continue;
|
//If it does, we'll just make our asset point to that instead of a new file
|
||||||
|
Material* mat = MATMGR->getMaterialDefinitionByName(assetName);
|
||||||
|
|
||||||
for (S32 t = 0; t < ImageAsset::ImageTypeCount; t++)
|
if (!mat)
|
||||||
|
mat = MATMGR->getMaterialDefinitionByMapTo(assetName);
|
||||||
|
|
||||||
|
if (!mat && assetItem->assetName != assetItem->cleanAssetName)
|
||||||
|
{
|
||||||
|
mat = MATMGR->getMaterialDefinitionByName(assetItem->cleanAssetName);
|
||||||
|
|
||||||
|
if (!mat)
|
||||||
|
mat = MATMGR->getMaterialDefinitionByMapTo(assetItem->cleanAssetName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mat)
|
||||||
|
{
|
||||||
|
//We found a match, so just modify our asset item's info to point against it. This will create the asset definition, but otherwise leave the material definition as-is.
|
||||||
|
assetItem->filePath = mat->getFilename();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (activeImportConfig->AlwaysAddMaterialSuffix) //we only opt to force on the suffix if we're not obligating using the original material defs
|
||||||
|
{
|
||||||
|
assetItem->assetName += activeImportConfig->AddedMaterialSuffix;
|
||||||
|
assetItem->cleanAssetName = assetItem->assetName;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (activeImportConfig->PopulateMaterialMaps)
|
||||||
|
{
|
||||||
|
//If we're trying to populate the rest of our material maps, we need to go looking
|
||||||
|
dSprintf(importLogBuffer, sizeof(importLogBuffer), "Attempting to Auto-Populate Material Maps");
|
||||||
|
activityLog.push_back(importLogBuffer);
|
||||||
|
|
||||||
|
AssetImportObject* matchedImageTypes[ImageAsset::ImageTypeCount] = { nullptr };
|
||||||
|
|
||||||
|
String materialImageNoSuffix;
|
||||||
|
|
||||||
|
for (U32 i = 0; i < assetItem->childAssetItems.size(); i++)
|
||||||
{
|
{
|
||||||
//If the imageType name and child asset image type match, check it off our list
|
AssetImportObject* childAssetItem = assetItem->childAssetItems[i];
|
||||||
if (!dStricmp(ImageAsset::getImageTypeNameFromType((ImageAsset::ImageTypes)t), childAssetItem->imageSuffixType.c_str()))
|
|
||||||
|
if (childAssetItem->skip || childAssetItem->assetType != String("ImageAsset"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (S32 t = 0; t < ImageAsset::ImageTypeCount; t++)
|
||||||
{
|
{
|
||||||
matchedImageTypes[t] = childAssetItem;
|
//If the imageType name and child asset image type match, check it off our list
|
||||||
|
if (!dStricmp(ImageAsset::getImageTypeNameFromType((ImageAsset::ImageTypes)t), childAssetItem->imageSuffixType.c_str()))
|
||||||
if (t == ImageAsset::ImageTypes::Albedo)
|
|
||||||
{
|
{
|
||||||
String sufType;
|
matchedImageTypes[t] = childAssetItem;
|
||||||
String suffix = parseImageSuffixes(childAssetItem->assetName, &sufType);
|
|
||||||
|
|
||||||
String imageAssetName = childAssetItem->assetName;
|
if (t == ImageAsset::ImageTypes::Albedo)
|
||||||
|
{
|
||||||
|
String sufType;
|
||||||
|
String suffix = parseImageSuffixes(childAssetItem->assetName, &sufType);
|
||||||
|
|
||||||
if (suffix.isEmpty())
|
String imageAssetName = childAssetItem->assetName;
|
||||||
materialImageNoSuffix = imageAssetName;
|
|
||||||
else
|
if (suffix.isEmpty())
|
||||||
materialImageNoSuffix = imageAssetName.erase(imageAssetName.length() - suffix.length(), suffix.length());//cache this for later as we may need it for file association lookups
|
materialImageNoSuffix = imageAssetName;
|
||||||
|
else
|
||||||
|
materialImageNoSuffix = imageAssetName.erase(imageAssetName.length() - suffix.length(), suffix.length());//cache this for later as we may need it for file association lookups
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
//Now that we've checked off any existingly matched image types, process through the unmatched to look for files that associate
|
//Now that we've checked off any existingly matched image types, process through the unmatched to look for files that associate
|
||||||
for (S32 t = 0; t < ImageAsset::ImageTypeCount; t++)
|
for (S32 t = 0; t < ImageAsset::ImageTypeCount; t++)
|
||||||
{
|
|
||||||
//This type wasn't found, so try and find a match based on suffix
|
|
||||||
String suffixList;
|
|
||||||
|
|
||||||
switch (t)
|
|
||||||
{
|
{
|
||||||
case ImageAsset::Albedo:
|
//This type wasn't found, so try and find a match based on suffix
|
||||||
suffixList = activeImportConfig->DiffuseTypeSuffixes;
|
String suffixList;
|
||||||
break;
|
|
||||||
case ImageAsset::Normal:
|
|
||||||
suffixList = activeImportConfig->NormalTypeSuffixes;
|
|
||||||
break;
|
|
||||||
case ImageAsset::ORMConfig:
|
|
||||||
suffixList = activeImportConfig->PBRTypeSuffixes;
|
|
||||||
break;
|
|
||||||
case ImageAsset::Metalness:
|
|
||||||
suffixList = activeImportConfig->MetalnessTypeSuffixes;
|
|
||||||
break;
|
|
||||||
case ImageAsset::AO:
|
|
||||||
suffixList = activeImportConfig->AOTypeSuffixes;
|
|
||||||
break;
|
|
||||||
case ImageAsset::Roughness:
|
|
||||||
suffixList = activeImportConfig->RoughnessTypeSuffixes;
|
|
||||||
break;
|
|
||||||
//TODO: Glow map lookup too
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!matchedImageTypes[t])
|
switch (t)
|
||||||
{
|
|
||||||
U32 suffixCount = StringUnit::getUnitCount(suffixList.c_str(), ",;\t");
|
|
||||||
for (U32 i = 0; i < suffixCount; i++)
|
|
||||||
{
|
{
|
||||||
//First, try checking based on the material's assetName for our patternbase
|
case ImageAsset::Albedo:
|
||||||
String testPath = assetItem->filePath.getRootAndPath();
|
suffixList = activeImportConfig->DiffuseTypeSuffixes;
|
||||||
testPath += "/" + assetItem->cleanAssetName + StringUnit::getUnit(suffixList.c_str(), i, ",;\t");
|
break;
|
||||||
|
case ImageAsset::Normal:
|
||||||
|
suffixList = activeImportConfig->NormalTypeSuffixes;
|
||||||
|
break;
|
||||||
|
case ImageAsset::ORMConfig:
|
||||||
|
suffixList = activeImportConfig->PBRTypeSuffixes;
|
||||||
|
break;
|
||||||
|
case ImageAsset::Metalness:
|
||||||
|
suffixList = activeImportConfig->MetalnessTypeSuffixes;
|
||||||
|
break;
|
||||||
|
case ImageAsset::AO:
|
||||||
|
suffixList = activeImportConfig->AOTypeSuffixes;
|
||||||
|
break;
|
||||||
|
case ImageAsset::Roughness:
|
||||||
|
suffixList = activeImportConfig->RoughnessTypeSuffixes;
|
||||||
|
break;
|
||||||
|
//TODO: Glow map lookup too
|
||||||
|
}
|
||||||
|
|
||||||
String imagePath = AssetImporter::findImagePath(testPath);
|
if (!matchedImageTypes[t])
|
||||||
|
{
|
||||||
if (imagePath.isNotEmpty())
|
U32 suffixCount = StringUnit::getUnitCount(suffixList.c_str(), ",;\t");
|
||||||
|
for (U32 i = 0; i < suffixCount; i++)
|
||||||
{
|
{
|
||||||
//got a match!
|
//First, try checking based on the material's assetName for our patternbase
|
||||||
AssetImportObject* newImageAssetObj = addImportingAsset("ImageAsset", imagePath, assetItem, "");
|
String testPath = assetItem->filePath.getRootAndPath();
|
||||||
|
testPath += "/" + assetItem->cleanAssetName + StringUnit::getUnit(suffixList.c_str(), i, ",;\t");
|
||||||
|
|
||||||
newImageAssetObj->imageSuffixType = ImageAsset::getImageTypeNameFromType((ImageAsset::ImageTypes)t);
|
String imagePath = AssetImporter::findImagePath(testPath);
|
||||||
|
|
||||||
matchedImageTypes[t] = newImageAssetObj;
|
if (imagePath.isNotEmpty())
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(materialImageNoSuffix.isNotEmpty())
|
|
||||||
{
|
{
|
||||||
testPath = assetItem->filePath.getRootAndPath();
|
//got a match!
|
||||||
testPath += "/" + materialImageNoSuffix + StringUnit::getUnit(suffixList.c_str(), i, ",;\t");
|
AssetImportObject* newImageAssetObj = addImportingAsset("ImageAsset", imagePath, assetItem, "");
|
||||||
|
|
||||||
imagePath = AssetImporter::findImagePath(testPath);
|
newImageAssetObj->imageSuffixType = ImageAsset::getImageTypeNameFromType((ImageAsset::ImageTypes)t);
|
||||||
|
|
||||||
if (imagePath.isNotEmpty())
|
matchedImageTypes[t] = newImageAssetObj;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (materialImageNoSuffix.isNotEmpty())
|
||||||
{
|
{
|
||||||
//got a match!
|
testPath = assetItem->filePath.getRootAndPath();
|
||||||
AssetImportObject* newImageAssetObj = addImportingAsset("ImageAsset", imagePath, assetItem, "");
|
testPath += "/" + materialImageNoSuffix + StringUnit::getUnit(suffixList.c_str(), i, ",;\t");
|
||||||
|
|
||||||
newImageAssetObj->imageSuffixType = ImageAsset::getImageTypeNameFromType((ImageAsset::ImageTypes)t);
|
imagePath = AssetImporter::findImagePath(testPath);
|
||||||
|
|
||||||
matchedImageTypes[t] = newImageAssetObj;
|
if (imagePath.isNotEmpty())
|
||||||
break;
|
{
|
||||||
|
//got a match!
|
||||||
|
AssetImportObject* newImageAssetObj = addImportingAsset("ImageAsset", imagePath, assetItem, "");
|
||||||
|
|
||||||
|
newImageAssetObj->imageSuffixType = ImageAsset::getImageTypeNameFromType((ImageAsset::ImageTypes)t);
|
||||||
|
|
||||||
|
matchedImageTypes[t] = newImageAssetObj;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
//If we're the abledo slot and after all that we didn't find anything, it probably is a suffixless image
|
//If we're the abledo slot and after all that we didn't find anything, it probably is a suffixless image
|
||||||
if (t == ImageAsset::Albedo && matchedImageTypes[t] == nullptr)
|
if (t == ImageAsset::Albedo && matchedImageTypes[t] == nullptr)
|
||||||
{
|
|
||||||
String testPath = assetItem->filePath.getRootAndPath() + "/" + assetItem->cleanAssetName;
|
|
||||||
String imagePath = AssetImporter::findImagePath(testPath);
|
|
||||||
|
|
||||||
if (imagePath.isNotEmpty())
|
|
||||||
{
|
{
|
||||||
//got a match!
|
String testPath = assetItem->filePath.getRootAndPath() + "/" + assetItem->cleanAssetName;
|
||||||
AssetImportObject* newImageAssetObj = addImportingAsset("ImageAsset", imagePath, assetItem, "");
|
String imagePath = AssetImporter::findImagePath(testPath);
|
||||||
|
|
||||||
//In the event that the names match, we want to avoid duplications, so we'll go ahead and append a suffix onto our new image asset
|
if (imagePath.isNotEmpty())
|
||||||
if (newImageAssetObj->assetName == assetItem->assetName)
|
|
||||||
{
|
{
|
||||||
newImageAssetObj->assetName += StringUnit::getUnit(suffixList.c_str(), 0, ",;\t");
|
//got a match!
|
||||||
newImageAssetObj->cleanAssetName = newImageAssetObj->assetName;
|
AssetImportObject* newImageAssetObj = addImportingAsset("ImageAsset", imagePath, assetItem, "");
|
||||||
|
|
||||||
|
//In the event that the names match, we want to avoid duplications, so we'll go ahead and append a suffix onto our new image asset
|
||||||
|
if (newImageAssetObj->assetName == assetItem->assetName)
|
||||||
|
{
|
||||||
|
newImageAssetObj->assetName += StringUnit::getUnit(suffixList.c_str(), 0, ",;\t");
|
||||||
|
newImageAssetObj->cleanAssetName = newImageAssetObj->assetName;
|
||||||
|
}
|
||||||
|
|
||||||
|
newImageAssetObj->imageSuffixType = ImageAsset::getImageTypeNameFromType(ImageAsset::ImageTypes::Albedo);
|
||||||
|
|
||||||
|
matchedImageTypes[t] = newImageAssetObj;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
newImageAssetObj->imageSuffixType = ImageAsset::getImageTypeNameFromType(ImageAsset::ImageTypes::Albedo);
|
}
|
||||||
|
else
|
||||||
matchedImageTypes[t] = newImageAssetObj;
|
{
|
||||||
|
//just a bit of cleanup and logical testing for matches
|
||||||
|
//in the event we KNOW what the type is, but we don't have a suffix, such as a found image on a material lookup
|
||||||
|
//that doesn't have a suffix, we assume it to be the albedo, so we'll just append the suffix to avoid collisions if
|
||||||
|
//the name already matches our material name, similar to above logic
|
||||||
|
if (matchedImageTypes[t]->assetName == assetItem->assetName)
|
||||||
|
{
|
||||||
|
matchedImageTypes[t]->assetName += StringUnit::getUnit(suffixList.c_str(), 0, ",;\t");
|
||||||
|
matchedImageTypes[t]->cleanAssetName = matchedImageTypes[t]->assetName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
/*for (U32 i = 0; i < assetItem->childAssetItems.size(); i++)
|
||||||
{
|
{
|
||||||
//just a bit of cleanup and logical testing for matches
|
AssetImportObject* childAssetItem = assetItem->childAssetItems[i];
|
||||||
//in the event we KNOW what the type is, but we don't have a suffix, such as a found image on a material lookup
|
|
||||||
//that doesn't have a suffix, we assume it to be the albedo, so we'll just append the suffix to avoid collisions if
|
if (childAssetItem->skip || childAssetItem->processed || childAssetItem->assetType != String("ImageAsset"))
|
||||||
//the name already matches our material name, similar to above logic
|
continue;
|
||||||
if (matchedImageTypes[t]->assetName == assetItem->assetName)
|
|
||||||
|
if (childAssetItem->imageSuffixType == String("Albedo"))
|
||||||
{
|
{
|
||||||
matchedImageTypes[t]->assetName += StringUnit::getUnit(suffixList.c_str(), 0, ",;\t");
|
assetItem->diffuseImageAsset = % childAssetItem;
|
||||||
matchedImageTypes[t]->cleanAssetName = matchedImageTypes[t]->assetName;
|
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/*for (U32 i = 0; i < assetItem->childAssetItems.size(); i++)
|
|
||||||
{
|
|
||||||
AssetImportObject* childAssetItem = assetItem->childAssetItems[i];
|
|
||||||
|
|
||||||
if (childAssetItem->skip || childAssetItem->processed || childAssetItem->assetType != String("ImageAsset"))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (childAssetItem->imageSuffixType == String("Albedo"))
|
|
||||||
{
|
|
||||||
assetItem->diffuseImageAsset = % childAssetItem;
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
assetItem->processed = true;
|
assetItem->processed = true;
|
||||||
|
|
@ -1822,6 +1888,7 @@ void AssetImporter::processShapeAsset(AssetImportObject* assetItem)
|
||||||
if (activeImportConfig->AlwaysAddShapeSuffix)
|
if (activeImportConfig->AlwaysAddShapeSuffix)
|
||||||
{
|
{
|
||||||
assetItem->assetName += activeImportConfig->AddedShapeSuffix;
|
assetItem->assetName += activeImportConfig->AddedShapeSuffix;
|
||||||
|
assetItem->cleanAssetName = assetItem->assetName;
|
||||||
}
|
}
|
||||||
|
|
||||||
S32 meshCount = dAtoi(assetItem->shapeInfo->getDataField(StringTable->insert("_meshCount"), nullptr));
|
S32 meshCount = dAtoi(assetItem->shapeInfo->getDataField(StringTable->insert("_meshCount"), nullptr));
|
||||||
|
|
@ -1888,7 +1955,7 @@ void AssetImporter::processShapeMaterialInfo(AssetImportObject* assetItem, S32 m
|
||||||
if (matName == assetItem->assetName)
|
if (matName == assetItem->assetName)
|
||||||
{
|
{
|
||||||
//So apparently we managed to name the material the same as the shape. So we'll tweak the name
|
//So apparently we managed to name the material the same as the shape. So we'll tweak the name
|
||||||
matAssetName += activeImportConfig->AlwaysAddMaterialSuffix;
|
matAssetName += activeImportConfig->AddedMaterialSuffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Do a check so we don't import materials that are on our ignore list
|
//Do a check so we don't import materials that are on our ignore list
|
||||||
|
|
@ -2278,18 +2345,18 @@ void AssetImporter::resolveAssetItemIssues(AssetImportObject* assetItem)
|
||||||
String humanReadableReason = assetItem->statusType == String("DuplicateImportAsset") ? "Importing asset was duplicate of another importing asset" : "Importing asset was duplicate of an existing asset";
|
String humanReadableReason = assetItem->statusType == String("DuplicateImportAsset") ? "Importing asset was duplicate of another importing asset" : "Importing asset was duplicate of an existing asset";
|
||||||
|
|
||||||
//get the config value for duplicateAutoResolution
|
//get the config value for duplicateAutoResolution
|
||||||
if (activeImportConfig->DuplicatAutoResolution == String("AutoPrune"))
|
if (activeImportConfig->DuplicateAutoResolution == String("AutoPrune"))
|
||||||
{
|
{
|
||||||
//delete the item
|
//delete the item
|
||||||
deleteImportingAsset(assetItem);
|
deleteImportingAsset(assetItem);
|
||||||
|
|
||||||
//log it's deletion
|
//log it's deletion
|
||||||
dSprintf(importLogBuffer, sizeof(importLogBuffer), "Asset %s was autoprined due to %s as part of the Import Configuration", assetItem->assetName.c_str(), humanReadableReason.c_str());
|
dSprintf(importLogBuffer, sizeof(importLogBuffer), "Asset %s was autopruned due to %s as part of the Import Configuration", assetItem->assetName.c_str(), humanReadableReason.c_str());
|
||||||
activityLog.push_back(importLogBuffer);
|
activityLog.push_back(importLogBuffer);
|
||||||
|
|
||||||
importIssues = false;
|
importIssues = false;
|
||||||
}
|
}
|
||||||
else if (activeImportConfig->DuplicatAutoResolution == String("AutoRename"))
|
else if (activeImportConfig->DuplicateAutoResolution == String("AutoRename"))
|
||||||
{
|
{
|
||||||
//Set trailing number
|
//Set trailing number
|
||||||
String renamedAssetName = assetItem->assetName;
|
String renamedAssetName = assetItem->assetName;
|
||||||
|
|
@ -2308,10 +2375,31 @@ void AssetImporter::resolveAssetItemIssues(AssetImportObject* assetItem)
|
||||||
resetAssetValidationStatus(assetItem);
|
resetAssetValidationStatus(assetItem);
|
||||||
importIssues = false;
|
importIssues = false;
|
||||||
}
|
}
|
||||||
else if (activeImportConfig->DuplicatAutoResolution == String("UseExisting"))
|
else if (activeImportConfig->DuplicateAutoResolution == String("UseExisting"))
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
else if (activeImportConfig->DuplicateAutoResolution == String("FolderPrefix"))
|
||||||
|
{
|
||||||
|
//Set trailing number
|
||||||
|
String renamedAssetName = assetItem->assetName;
|
||||||
|
String owningFolder = assetItem->filePath.getDirectory(assetItem->filePath.getDirectoryCount() - 1);
|
||||||
|
|
||||||
|
renamedAssetName = owningFolder + "_" + renamedAssetName;
|
||||||
|
|
||||||
|
//Log it's renaming
|
||||||
|
dSprintf(importLogBuffer, sizeof(importLogBuffer), "Asset %s was renamed due to %s as part of the Import Configuration", assetItem->assetName.c_str(), humanReadableReason.c_str());
|
||||||
|
activityLog.push_back(importLogBuffer);
|
||||||
|
|
||||||
|
dSprintf(importLogBuffer, sizeof(importLogBuffer), "Asset %s was renamed to %s", assetItem->assetName.c_str(), renamedAssetName.c_str());
|
||||||
|
activityLog.push_back(importLogBuffer);
|
||||||
|
|
||||||
|
assetItem->assetName = renamedAssetName;
|
||||||
|
|
||||||
|
//Whatever status we had prior is no longer relevent, so reset the status
|
||||||
|
resetAssetValidationStatus(assetItem);
|
||||||
|
importIssues = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (assetItem->statusType == String("MissingFile"))
|
else if (assetItem->statusType == String("MissingFile"))
|
||||||
{
|
{
|
||||||
|
|
@ -2348,7 +2436,7 @@ void AssetImporter::resetImportConfig()
|
||||||
//
|
//
|
||||||
// Importing
|
// Importing
|
||||||
//
|
//
|
||||||
StringTableEntry AssetImporter::autoImportFile(Torque::Path filePath)
|
StringTableEntry AssetImporter::autoImportFile(Torque::Path filePath, String typeHint)
|
||||||
{
|
{
|
||||||
//Just in case we're reusing the same importer object from another import session, nuke any existing files
|
//Just in case we're reusing the same importer object from another import session, nuke any existing files
|
||||||
resetImportSession(true);
|
resetImportSession(true);
|
||||||
|
|
@ -2359,6 +2447,8 @@ StringTableEntry AssetImporter::autoImportFile(Torque::Path filePath)
|
||||||
{
|
{
|
||||||
dSprintf(importLogBuffer, sizeof(importLogBuffer), "Unable to import file %s because it is a folder or zip.", filePath.getFullPath().c_str());
|
dSprintf(importLogBuffer, sizeof(importLogBuffer), "Unable to import file %s because it is a folder or zip.", filePath.getFullPath().c_str());
|
||||||
activityLog.push_back(importLogBuffer);
|
activityLog.push_back(importLogBuffer);
|
||||||
|
|
||||||
|
dumpActivityLog();
|
||||||
return StringTable->EmptyString();
|
return StringTable->EmptyString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2366,6 +2456,8 @@ StringTableEntry AssetImporter::autoImportFile(Torque::Path filePath)
|
||||||
{
|
{
|
||||||
dSprintf(importLogBuffer, sizeof(importLogBuffer), "Unable to import file %s because it is of an unrecognized/unsupported type.", filePath.getFullPath().c_str());
|
dSprintf(importLogBuffer, sizeof(importLogBuffer), "Unable to import file %s because it is of an unrecognized/unsupported type.", filePath.getFullPath().c_str());
|
||||||
activityLog.push_back(importLogBuffer);
|
activityLog.push_back(importLogBuffer);
|
||||||
|
|
||||||
|
dumpActivityLog();
|
||||||
return StringTable->EmptyString();
|
return StringTable->EmptyString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2374,7 +2466,10 @@ StringTableEntry AssetImporter::autoImportFile(Torque::Path filePath)
|
||||||
|
|
||||||
if (targetModuleDef == nullptr)
|
if (targetModuleDef == nullptr)
|
||||||
{
|
{
|
||||||
//log it
|
dSprintf(importLogBuffer, sizeof(importLogBuffer), "Unable to import file %s because it is not in a valid module folder.", filePath.getFullPath().c_str());
|
||||||
|
activityLog.push_back(importLogBuffer);
|
||||||
|
|
||||||
|
dumpActivityLog();
|
||||||
return StringTable->EmptyString();
|
return StringTable->EmptyString();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -2404,14 +2499,7 @@ StringTableEntry AssetImporter::autoImportFile(Torque::Path filePath)
|
||||||
importAssets();
|
importAssets();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if TORQUE_DEBUG
|
dumpActivityLog();
|
||||||
Con::printf("/***************/");
|
|
||||||
for (U32 i = 0; i < activityLog.size(); i++)
|
|
||||||
{
|
|
||||||
Con::printf(activityLog[i].c_str());
|
|
||||||
}
|
|
||||||
Con::printf("/***************/");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (hasIssues)
|
if (hasIssues)
|
||||||
{
|
{
|
||||||
|
|
@ -2628,8 +2716,15 @@ Torque::Path AssetImporter::importImageAsset(AssetImportObject* assetItem)
|
||||||
newAsset->setDataField(StringTable->insert("originalFilePath"), nullptr, qualifiedFromFile);
|
newAsset->setDataField(StringTable->insert("originalFilePath"), nullptr, qualifiedFromFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageAsset::ImageTypes imageType = ImageAsset::getImageTypeFromName(assetItem->imageSuffixType.c_str());
|
if (assetItem->typeHint != String::EmptyString)
|
||||||
newAsset->setImageType(imageType);
|
{
|
||||||
|
newAsset->setImageType(ImageAsset::getImageTypeFromName(StringTable->insert(assetItem->typeHint.c_str())));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ImageAsset::ImageTypes imageType = ImageAsset::getImageTypeFromName(assetItem->imageSuffixType.c_str());
|
||||||
|
newAsset->setImageType(imageType);
|
||||||
|
}
|
||||||
|
|
||||||
Taml tamlWriter;
|
Taml tamlWriter;
|
||||||
bool importSuccessful = tamlWriter.write(newAsset, tamlPath.c_str());
|
bool importSuccessful = tamlWriter.write(newAsset, tamlPath.c_str());
|
||||||
|
|
@ -2694,7 +2789,7 @@ Torque::Path AssetImporter::importMaterialAsset(AssetImportObject* assetItem)
|
||||||
dSprintf(dependencyFieldName, 64, "imageMap%i", dependencySlotId);
|
dSprintf(dependencyFieldName, 64, "imageMap%i", dependencySlotId);
|
||||||
|
|
||||||
char dependencyFieldDef[512];
|
char dependencyFieldDef[512];
|
||||||
dSprintf(dependencyFieldDef, 512, "@Asset=%s:%s", targetModuleId.c_str(), childItem->assetName.c_str());
|
dSprintf(dependencyFieldDef, 512, "%s=%s:%s", ASSET_ID_SIGNATURE, targetModuleId.c_str(), childItem->assetName.c_str());
|
||||||
|
|
||||||
newAsset->setDataField(StringTable->insert(dependencyFieldName), nullptr, dependencyFieldDef);
|
newAsset->setDataField(StringTable->insert(dependencyFieldName), nullptr, dependencyFieldDef);
|
||||||
|
|
||||||
|
|
@ -2752,74 +2847,96 @@ Torque::Path AssetImporter::importMaterialAsset(AssetImportObject* assetItem)
|
||||||
FileObject* file = new FileObject();
|
FileObject* file = new FileObject();
|
||||||
file->registerObject();
|
file->registerObject();
|
||||||
|
|
||||||
//Now write the script file containing our material out
|
if (activeImportConfig->UseExistingMaterials && Platform::isFile(qualifiedFromFile))
|
||||||
//There's 2 ways to do this. If we're in-place importing an existing asset, we can see if the definition existed already, like in an old
|
|
||||||
//materials.tscript file. if it does, we can just find the object by name, and save it out to our new file
|
|
||||||
//If not, we'll just generate one
|
|
||||||
Material* existingMat = MATMGR->getMaterialDefinitionByName(assetName);
|
|
||||||
|
|
||||||
//It's also possible that, for legacy models, the material hooks in via the material's mapTo field, and the material name is something completely different
|
|
||||||
//So we'll check for that as well if we didn't find it by name up above
|
|
||||||
if (existingMat == nullptr)
|
|
||||||
{
|
{
|
||||||
existingMat = MATMGR->getMaterialDefinitionByMapTo(assetName);
|
//Now write the script file containing our material out
|
||||||
}
|
//There's 2 ways to do this. If we're in-place importing an existing asset, we can see if the definition existed already, like in an old
|
||||||
|
//materials.tscript file. if it does, we can just find the object by name, and save it out to our new file
|
||||||
|
//If not, we'll just generate one
|
||||||
|
Material* existingMat = MATMGR->getMaterialDefinitionByName(assetName);
|
||||||
|
|
||||||
if (existingMat)
|
//It's also possible that, for legacy models, the material hooks in via the material's mapTo field, and the material name is something completely different
|
||||||
{
|
//So we'll check for that as well if we didn't find it by name up above
|
||||||
for (U32 i = 0; i < assetItem->childAssetItems.size(); i++)
|
if (existingMat == nullptr)
|
||||||
|
existingMat = MATMGR->getMaterialDefinitionByMapTo(assetName);
|
||||||
|
|
||||||
|
if (existingMat == nullptr && assetItem->assetName != assetItem->cleanAssetName)
|
||||||
{
|
{
|
||||||
AssetImportObject* childItem = assetItem->childAssetItems[i];
|
existingMat = MATMGR->getMaterialDefinitionByName(assetItem->cleanAssetName);
|
||||||
|
if (existingMat == nullptr)
|
||||||
if (childItem->skip || !childItem->processed || childItem->assetType.compare("ImageAsset") != 0)
|
existingMat = MATMGR->getMaterialDefinitionByMapTo(assetItem->cleanAssetName);
|
||||||
continue;
|
}
|
||||||
|
|
||||||
String path = childItem->filePath.getFullFileName();
|
if (existingMat)
|
||||||
|
{
|
||||||
String mapFieldName = "";
|
PersistenceManager* persistMgr;
|
||||||
String assetFieldName = "";
|
if (Sim::findObject("ImageAssetValidator", persistMgr))
|
||||||
|
{
|
||||||
ImageAsset::ImageTypes imageType = ImageAsset::getImageTypeFromName(childItem->imageSuffixType);
|
for (U32 i = 0; i < assetItem->childAssetItems.size(); i++)
|
||||||
|
{
|
||||||
if (imageType == ImageAsset::ImageTypes::Albedo || childItem->imageSuffixType.isEmpty())
|
AssetImportObject* childItem = assetItem->childAssetItems[i];
|
||||||
{
|
|
||||||
mapFieldName = "DiffuseMap";
|
if (childItem->skip || !childItem->processed || childItem->assetType.compare("ImageAsset") != 0)
|
||||||
}
|
continue;
|
||||||
else if (imageType == ImageAsset::ImageTypes::Normal)
|
|
||||||
{
|
String path = childItem->filePath.getFullFileName();
|
||||||
mapFieldName = "NormalMap";
|
|
||||||
}
|
String mapFieldName = "";
|
||||||
else if (imageType == ImageAsset::ImageTypes::ORMConfig)
|
String assetFieldName = "";
|
||||||
{
|
|
||||||
mapFieldName = "ORMConfig";
|
ImageAsset::ImageTypes imageType = ImageAsset::getImageTypeFromName(childItem->imageSuffixType);
|
||||||
}
|
|
||||||
else if (imageType == ImageAsset::ImageTypes::Metalness)
|
if (imageType == ImageAsset::ImageTypes::Albedo || childItem->imageSuffixType.isEmpty())
|
||||||
{
|
{
|
||||||
mapFieldName = "MetalnessMap";
|
mapFieldName = "DiffuseMap";
|
||||||
}
|
}
|
||||||
else if (imageType == ImageAsset::ImageTypes::AO)
|
else if (imageType == ImageAsset::ImageTypes::Normal)
|
||||||
{
|
{
|
||||||
mapFieldName = "AOMap";
|
mapFieldName = "NormalMap";
|
||||||
}
|
}
|
||||||
else if (imageType == ImageAsset::ImageTypes::Roughness)
|
else if (imageType == ImageAsset::ImageTypes::ORMConfig)
|
||||||
{
|
{
|
||||||
mapFieldName = "RoughnessMap";
|
mapFieldName = "ORMConfig";
|
||||||
}
|
}
|
||||||
|
else if (imageType == ImageAsset::ImageTypes::Metalness)
|
||||||
assetFieldName = mapFieldName + "Asset[0]";
|
{
|
||||||
mapFieldName += "[0]";
|
mapFieldName = "MetalnessMap";
|
||||||
|
}
|
||||||
//If there's already an existing image map file on the material definition in this slot, don't override it
|
else if (imageType == ImageAsset::ImageTypes::AO)
|
||||||
if(!path.isEmpty())
|
{
|
||||||
existingMat->writeField(mapFieldName.c_str(), path.c_str());
|
mapFieldName = "AOMap";
|
||||||
|
}
|
||||||
String targetAsset = targetModuleId + ":" + childItem->assetName;
|
else if (imageType == ImageAsset::ImageTypes::Roughness)
|
||||||
|
{
|
||||||
existingMat->writeField(assetFieldName.c_str(), targetAsset.c_str());
|
mapFieldName = "RoughnessMap";
|
||||||
|
}
|
||||||
|
|
||||||
|
assetFieldName = mapFieldName + "Asset[0]";
|
||||||
|
mapFieldName += "[0]";
|
||||||
|
|
||||||
|
//If there's already an existing image map file on the material definition in this slot, don't override it
|
||||||
|
if (!path.isEmpty())
|
||||||
|
existingMat->writeField(mapFieldName.c_str(), path.c_str());
|
||||||
|
|
||||||
|
String targetAsset = targetModuleId + ":" + childItem->assetName;
|
||||||
|
|
||||||
|
existingMat->writeField(assetFieldName.c_str(), targetAsset.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
persistMgr->setDirty(existingMat);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Con::errorf("ImageAssetValidator not found!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Failed to find original material definition %s!", assetName);
|
||||||
|
activityLog.push_back(importLogBuffer);
|
||||||
|
return tamlPath;
|
||||||
}
|
}
|
||||||
existingMat->save(scriptPath.c_str());
|
|
||||||
}
|
}
|
||||||
//However, if we didn't find any existing material, then we'll want to go ahead and just write out a new one
|
|
||||||
else if (file->openForWrite(scriptPath.c_str()))
|
else if (file->openForWrite(scriptPath.c_str()))
|
||||||
{
|
{
|
||||||
file->writeLine((U8*)"//--- OBJECT WRITE BEGIN ---");
|
file->writeLine((U8*)"//--- OBJECT WRITE BEGIN ---");
|
||||||
|
|
@ -2936,7 +3053,7 @@ Torque::Path AssetImporter::importShapeAsset(AssetImportObject* assetItem)
|
||||||
newAsset->setShapeFile(shapeFileName.c_str());
|
newAsset->setShapeFile(shapeFileName.c_str());
|
||||||
newAsset->setShapeConstructorFile(constructorFileName.c_str());
|
newAsset->setShapeConstructorFile(constructorFileName.c_str());
|
||||||
|
|
||||||
AssetImportConfig* cachedConfig = new AssetImportConfig();;
|
AssetImportConfig* cachedConfig = new AssetImportConfig();
|
||||||
cachedConfig->registerObject();
|
cachedConfig->registerObject();
|
||||||
activeImportConfig->CopyTo(cachedConfig);
|
activeImportConfig->CopyTo(cachedConfig);
|
||||||
|
|
||||||
|
|
@ -2968,7 +3085,7 @@ Torque::Path AssetImporter::importShapeAsset(AssetImportObject* assetItem)
|
||||||
dSprintf(dependencyFieldName, 64, "materialSlot%i", dependencySlotId);
|
dSprintf(dependencyFieldName, 64, "materialSlot%i", dependencySlotId);
|
||||||
|
|
||||||
char dependencyFieldDef[512];
|
char dependencyFieldDef[512];
|
||||||
dSprintf(dependencyFieldDef, 512, "@Asset=%s:%s", targetModuleId.c_str(), childItem->assetName.c_str());
|
dSprintf(dependencyFieldDef, 512, "%s=%s:%s", ASSET_ID_SIGNATURE, targetModuleId.c_str(), childItem->assetName.c_str());
|
||||||
|
|
||||||
newAsset->setDataField(StringTable->insert(dependencyFieldName), nullptr, dependencyFieldDef);
|
newAsset->setDataField(StringTable->insert(dependencyFieldName), nullptr, dependencyFieldDef);
|
||||||
|
|
||||||
|
|
@ -2980,7 +3097,7 @@ Torque::Path AssetImporter::importShapeAsset(AssetImportObject* assetItem)
|
||||||
dSprintf(dependencyFieldName, 64, "animationSequence%i", dependencySlotId);
|
dSprintf(dependencyFieldName, 64, "animationSequence%i", dependencySlotId);
|
||||||
|
|
||||||
char dependencyFieldDef[512];
|
char dependencyFieldDef[512];
|
||||||
dSprintf(dependencyFieldDef, 512, "@Asset=%s:%s", targetModuleId.c_str(), childItem->assetName.c_str());
|
dSprintf(dependencyFieldDef, 512, "%s=%s:%s", ASSET_ID_SIGNATURE, targetModuleId.c_str(), childItem->assetName.c_str());
|
||||||
|
|
||||||
newAsset->setDataField(StringTable->insert(dependencyFieldName), nullptr, dependencyFieldDef);
|
newAsset->setDataField(StringTable->insert(dependencyFieldName), nullptr, dependencyFieldDef);
|
||||||
|
|
||||||
|
|
@ -3010,19 +3127,47 @@ Torque::Path AssetImporter::importShapeAsset(AssetImportObject* assetItem)
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isInPlace && Platform::isFile(qualifiedFromCSFile))
|
if (!isInPlace)
|
||||||
{
|
{
|
||||||
if(!dPathCopy(qualifiedFromCSFile, qualifiedToCSFile, !isReimport))
|
if (Platform::isFile(qualifiedFromCSFile))
|
||||||
{
|
{
|
||||||
dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Unable to copy file %s", qualifiedFromCSFile);
|
if (!dPathCopy(qualifiedFromCSFile, qualifiedToCSFile, !isReimport))
|
||||||
|
{
|
||||||
|
dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Unable to copy file %s", qualifiedFromCSFile);
|
||||||
|
activityLog.push_back(importLogBuffer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//We successfully copied the original constructor file, so no extra work required
|
||||||
|
makeNewConstructor = false;
|
||||||
|
dSprintf(importLogBuffer, sizeof(importLogBuffer), "Successfully copied original TSShape Constructor file %s", qualifiedFromCSFile);
|
||||||
|
activityLog.push_back(importLogBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//We're doing an in-place import, so double check we've already got a constructor file in the expected spot
|
||||||
|
if (Platform::isFile(qualifiedFromCSFile))
|
||||||
|
{
|
||||||
|
//Yup, found it, we're good to go
|
||||||
|
makeNewConstructor = false;
|
||||||
|
dSprintf(importLogBuffer, sizeof(importLogBuffer), "Existing TSShape Constructor file %s found", qualifiedFromCSFile);
|
||||||
activityLog.push_back(importLogBuffer);
|
activityLog.push_back(importLogBuffer);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//We successfully copied the original constructor file, so no extra work required
|
//Didn't work, but it's possible it's using the old .cs extension when our extension variable is set to something else, so check that one as well just to be sure
|
||||||
makeNewConstructor = false;
|
Torque::Path constrFilePath = qualifiedFromCSFile;
|
||||||
dSprintf(importLogBuffer, sizeof(importLogBuffer), "Successfully copied original TSShape Constructor file %s", qualifiedFromCSFile);
|
constrFilePath.setExtension("cs");
|
||||||
activityLog.push_back(importLogBuffer);
|
|
||||||
|
if (Platform::isFile(constrFilePath.getFullPath().c_str()))
|
||||||
|
{
|
||||||
|
//Yup, found it, we're good to go
|
||||||
|
makeNewConstructor = false;
|
||||||
|
dSprintf(importLogBuffer, sizeof(importLogBuffer), "Existing TSShape Constructor file %s found", constrFilePath.getFullPath().c_str());
|
||||||
|
activityLog.push_back(importLogBuffer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3033,10 +3178,10 @@ Torque::Path AssetImporter::importShapeAsset(AssetImportObject* assetItem)
|
||||||
activityLog.push_back(importLogBuffer);
|
activityLog.push_back(importLogBuffer);
|
||||||
|
|
||||||
//find/create shape constructor
|
//find/create shape constructor
|
||||||
TSShapeConstructor* constructor = TSShapeConstructor::findShapeConstructor(Torque::Path(qualifiedToFile).getFullPath());
|
TSShapeConstructor* constructor = TSShapeConstructor::findShapeConstructorByFilename(Torque::Path(qualifiedToFile).getFullPath());
|
||||||
if (constructor == nullptr)
|
if (constructor == nullptr)
|
||||||
{
|
{
|
||||||
constructor = new TSShapeConstructor(qualifiedToFile);
|
constructor = new TSShapeConstructor(StringTable->insert(qualifiedToFile));
|
||||||
|
|
||||||
String constructorName = assetItem->filePath.getFileName() + assetItem->filePath.getExtension().substr(0, 3);
|
String constructorName = assetItem->filePath.getFileName() + assetItem->filePath.getExtension().substr(0, 3);
|
||||||
constructorName.replace(" ", "_");
|
constructorName.replace(" ", "_");
|
||||||
|
|
@ -3046,7 +3191,6 @@ Torque::Path AssetImporter::importShapeAsset(AssetImportObject* assetItem)
|
||||||
constructor->registerObject(constructorName.c_str());
|
constructor->registerObject(constructorName.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//now we write the import config logic into the constructor itself to ensure we load like we wanted it to
|
//now we write the import config logic into the constructor itself to ensure we load like we wanted it to
|
||||||
String neverImportMats;
|
String neverImportMats;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ public:
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Duplicate Asset Auto-Resolution Action. Options are None, AutoPrune, AutoRename
|
/// Duplicate Asset Auto-Resolution Action. Options are None, AutoPrune, AutoRename
|
||||||
/// </summary>
|
/// </summary>
|
||||||
String DuplicatAutoResolution;
|
String DuplicateAutoResolution;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Indicates if warnings should be treated as errors.
|
/// Indicates if warnings should be treated as errors.
|
||||||
|
|
@ -40,6 +40,11 @@ public:
|
||||||
bool AutomaticallyPromptMissingFiles;
|
bool AutomaticallyPromptMissingFiles;
|
||||||
//
|
//
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Should the importer add the folder name as a prefix to the assetName. Helps prevent name collisions.
|
||||||
|
/// </summary>
|
||||||
|
bool AddDirectoryPrefixToAssetName;
|
||||||
|
//
|
||||||
//
|
//
|
||||||
//Mesh Settings
|
//Mesh Settings
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -531,6 +536,13 @@ public:
|
||||||
/// </summary>
|
/// </summary>
|
||||||
GuiTreeViewCtrl* shapeInfo;
|
GuiTreeViewCtrl* shapeInfo;
|
||||||
|
|
||||||
|
//
|
||||||
|
/// <summary>
|
||||||
|
/// A string that can hold a hint string to help the auto-import ensure the correct asset subtype is assigned.
|
||||||
|
/// e.g. "GUI" would inform an image asset being imported that it should be flagged as a GUI image type
|
||||||
|
/// </summary>
|
||||||
|
String typeHint;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AssetImportObject();
|
AssetImportObject();
|
||||||
virtual ~AssetImportObject();
|
virtual ~AssetImportObject();
|
||||||
|
|
@ -820,9 +832,10 @@ public:
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Runs the import process on a single file in-place. Intended primarily for autoimporting a loose file that's in the game directory.
|
/// Runs the import process on a single file in-place. Intended primarily for autoimporting a loose file that's in the game directory.
|
||||||
/// <para>@param filePath, The filePath of the file to be imported in as an asset</para>
|
/// <para>@param filePath, The filePath of the file to be imported in as an asset</para>
|
||||||
|
/// <para>@param typeHint, Optional. A string that provides a hint of the intended asset type. Such as an image being intended for GUI use.</para>
|
||||||
/// <para>@return AssetId of the asset that was imported. If import failed, it will be empty.</para>
|
/// <para>@return AssetId of the asset that was imported. If import failed, it will be empty.</para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
StringTableEntry autoImportFile(Torque::Path filePath);
|
StringTableEntry autoImportFile(Torque::Path filePath, String typeHint);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Runs the import process in the current session
|
/// Runs the import process in the current session
|
||||||
|
|
|
||||||
|
|
@ -47,11 +47,11 @@ DefineEngineMethod(AssetImporter, getActivityLogLine, String, (S32 i), (0),
|
||||||
return object->getActivityLogLine(0);
|
return object->getActivityLogLine(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
DefineEngineMethod(AssetImporter, autoImportFile, String, (String path), (""),
|
DefineEngineMethod(AssetImporter, autoImportFile, String, (String path, String typeHint), ("", ""),
|
||||||
"Creates a new script asset using the targetFilePath.\n"
|
"Creates a new script asset using the targetFilePath.\n"
|
||||||
"@return The bool result of calling exec")
|
"@return The bool result of calling exec")
|
||||||
{
|
{
|
||||||
return object->autoImportFile(path);
|
return object->autoImportFile(path, typeHint);
|
||||||
}
|
}
|
||||||
|
|
||||||
DefineEngineMethod(AssetImporter, addImportingFile, AssetImportObject*, (String path), (""),
|
DefineEngineMethod(AssetImporter, addImportingFile, AssetImportObject*, (String path), (""),
|
||||||
|
|
|
||||||
|
|
@ -195,8 +195,8 @@ GuiControl* GuiInspectorTypeStateMachineAssetPtr::constructEditControl()
|
||||||
dSprintf(szBuffer, sizeof(szBuffer), "StateMachineEditor.loadStateMachineAsset(%d.getText()); Canvas.pushDialog(StateMachineEditor);", retCtrl->getId());
|
dSprintf(szBuffer, sizeof(szBuffer), "StateMachineEditor.loadStateMachineAsset(%d.getText()); Canvas.pushDialog(StateMachineEditor);", retCtrl->getId());
|
||||||
mSMEdButton->setField("Command", szBuffer);
|
mSMEdButton->setField("Command", szBuffer);
|
||||||
|
|
||||||
char bitmapName[512] = "tools/worldEditor/images/toolbar/shape-editor";
|
char bitmapName[512] = "ToolsModule:shape_editor_n_image";
|
||||||
mSMEdButton->setBitmap(bitmapName);
|
mSMEdButton->setBitmap(StringTable->insert(bitmapName));
|
||||||
|
|
||||||
mSMEdButton->setDataField(StringTable->insert("Profile"), NULL, "GuiButtonProfile");
|
mSMEdButton->setDataField(StringTable->insert("Profile"), NULL, "GuiButtonProfile");
|
||||||
mSMEdButton->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile");
|
mSMEdButton->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile");
|
||||||
|
|
|
||||||
|
|
@ -264,7 +264,7 @@ bool ConvexShape::protectedSetSurfaceTexture(void *object, const char *index, co
|
||||||
|
|
||||||
surfaceMaterial surface;
|
surfaceMaterial surface;
|
||||||
|
|
||||||
surface.materialName = data;
|
surface._setMaterial(data);
|
||||||
|
|
||||||
shape->mSurfaceTextures.push_back(surface);
|
shape->mSurfaceTextures.push_back(surface);
|
||||||
|
|
||||||
|
|
@ -272,7 +272,7 @@ bool ConvexShape::protectedSetSurfaceTexture(void *object, const char *index, co
|
||||||
}
|
}
|
||||||
|
|
||||||
ConvexShape::ConvexShape()
|
ConvexShape::ConvexShape()
|
||||||
: mMaterialName( "Grid512_OrangeLines_Mat" ),
|
:
|
||||||
mMaterialInst( NULL ),
|
mMaterialInst( NULL ),
|
||||||
//mVertCount( 0 ),
|
//mVertCount( 0 ),
|
||||||
//mPrimCount( 0 ),
|
//mPrimCount( 0 ),
|
||||||
|
|
@ -289,6 +289,8 @@ ConvexShape::ConvexShape()
|
||||||
mSurfaceBuffers.clear();
|
mSurfaceBuffers.clear();
|
||||||
mSurfaceUVs.clear();
|
mSurfaceUVs.clear();
|
||||||
mSurfaceTextures.clear();
|
mSurfaceTextures.clear();
|
||||||
|
|
||||||
|
INIT_MATERIALASSET(Material);
|
||||||
}
|
}
|
||||||
|
|
||||||
ConvexShape::~ConvexShape()
|
ConvexShape::~ConvexShape()
|
||||||
|
|
@ -310,7 +312,7 @@ void ConvexShape::initPersistFields()
|
||||||
{
|
{
|
||||||
addGroup( "Rendering" );
|
addGroup( "Rendering" );
|
||||||
|
|
||||||
addField( "material", TypeMaterialName, Offset( mMaterialName, ConvexShape ), "Material used to render the ConvexShape surface." );
|
INITPERSISTFIELD_MATERIALASSET(Material, ConvexShape, "Default material used to render the ConvexShape surface.");
|
||||||
|
|
||||||
endGroup( "Rendering" );
|
endGroup( "Rendering" );
|
||||||
|
|
||||||
|
|
@ -461,9 +463,7 @@ void ConvexShape::writeFields( Stream &stream, U32 tabStop )
|
||||||
char buffer[1024];
|
char buffer[1024];
|
||||||
dMemset(buffer, 0, 1024);
|
dMemset(buffer, 0, 1024);
|
||||||
|
|
||||||
const char* tex = mSurfaceTextures[i].materialName.c_str();
|
dSprintf(buffer, 1024, "surfaceTexture = \"%s\";", mSurfaceTextures[i].getMaterial());
|
||||||
|
|
||||||
dSprintf(buffer, 1024, "surfaceTexture = \"%s\";", mSurfaceTextures[i].materialName.c_str());
|
|
||||||
|
|
||||||
stream.writeLine((const U8*)buffer);
|
stream.writeLine((const U8*)buffer);
|
||||||
}
|
}
|
||||||
|
|
@ -528,7 +528,7 @@ U32 ConvexShape::packUpdate( NetConnection *conn, U32 mask, BitStream *stream )
|
||||||
|
|
||||||
if ( stream->writeFlag( mask & UpdateMask ) )
|
if ( stream->writeFlag( mask & UpdateMask ) )
|
||||||
{
|
{
|
||||||
stream->write( mMaterialName );
|
PACK_MATERIALASSET(conn, Material);
|
||||||
|
|
||||||
U32 surfCount = mSurfaces.size();
|
U32 surfCount = mSurfaces.size();
|
||||||
stream->writeInt( surfCount, 32 );
|
stream->writeInt( surfCount, 32 );
|
||||||
|
|
@ -556,8 +556,13 @@ U32 ConvexShape::packUpdate( NetConnection *conn, U32 mask, BitStream *stream )
|
||||||
//next check for any texture coord or scale mods
|
//next check for any texture coord or scale mods
|
||||||
for(U32 i=0; i < surfaceTex; i++)
|
for(U32 i=0; i < surfaceTex; i++)
|
||||||
{
|
{
|
||||||
String a = mSurfaceTextures[i].materialName;
|
if (stream->writeFlag(mSurfaceTextures[i].mMaterialAsset.notNull()))
|
||||||
stream->write( mSurfaceTextures[i].materialName );
|
{
|
||||||
|
NetStringHandle assetIdStr = mSurfaceTextures[i].mMaterialAsset.getAssetId();
|
||||||
|
conn->packNetStringHandleU(stream, assetIdStr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
stream->writeString(mSurfaceTextures[i].mMaterialName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -579,7 +584,7 @@ void ConvexShape::unpackUpdate( NetConnection *conn, BitStream *stream )
|
||||||
|
|
||||||
if ( stream->readFlag() ) // UpdateMask
|
if ( stream->readFlag() ) // UpdateMask
|
||||||
{
|
{
|
||||||
stream->read( &mMaterialName );
|
UNPACK_MATERIALASSET(conn, Material);
|
||||||
|
|
||||||
mSurfaces.clear();
|
mSurfaces.clear();
|
||||||
mSurfaceUVs.clear();
|
mSurfaceUVs.clear();
|
||||||
|
|
@ -619,7 +624,13 @@ void ConvexShape::unpackUpdate( NetConnection *conn, BitStream *stream )
|
||||||
{
|
{
|
||||||
mSurfaceTextures.increment();
|
mSurfaceTextures.increment();
|
||||||
|
|
||||||
stream->read( &mSurfaceTextures[i].materialName );
|
if (stream->readFlag())
|
||||||
|
{
|
||||||
|
mSurfaceTextures[i].mMaterialAssetId = StringTable->insert(conn->unpackNetStringHandleU(stream).getString());
|
||||||
|
mSurfaceTextures[i]._setMaterial(mSurfaceTextures[i].mMaterialAssetId);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mSurfaceTextures[i].mMaterialName = stream->readSTString();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isProperlyAdded())
|
if (isProperlyAdded())
|
||||||
|
|
@ -1207,13 +1218,13 @@ void ConvexShape::_updateMaterial()
|
||||||
for (U32 i = 0; i<mSurfaceTextures.size(); i++)
|
for (U32 i = 0; i<mSurfaceTextures.size(); i++)
|
||||||
{
|
{
|
||||||
//If we already have the material inst and it hasn't changed, skip
|
//If we already have the material inst and it hasn't changed, skip
|
||||||
if (mSurfaceTextures[i].materialInst && mSurfaceTextures[i].materialName.equal(mSurfaceTextures[i].materialInst->getMaterial()->getName(), String::NoCase))
|
if (mSurfaceTextures[i].materialInst &&
|
||||||
|
mSurfaceTextures[i].getMaterialAsset()->getMaterialDefinitionName() == mSurfaceTextures[i].materialInst->getMaterial()->getName())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Material *material;
|
Material* material = mSurfaceTextures[i].getMaterialResource();
|
||||||
|
|
||||||
if (!Sim::findObject(mSurfaceTextures[i].materialName, material))
|
if (material == nullptr)
|
||||||
//bail
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
mSurfaceTextures[i].materialInst = material->createMatInstance();
|
mSurfaceTextures[i].materialInst = material->createMatInstance();
|
||||||
|
|
@ -1229,15 +1240,15 @@ void ConvexShape::_updateMaterial()
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the material name matches then don't bother updating it.
|
// If the material name matches then don't bother updating it.
|
||||||
if (mMaterialInst && mMaterialName.equal(mMaterialInst->getMaterial()->getName(), String::NoCase))
|
if (mMaterialInst && getMaterialAsset()->getMaterialDefinitionName() == mMaterialInst->getMaterial()->getName())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SAFE_DELETE( mMaterialInst );
|
SAFE_DELETE( mMaterialInst );
|
||||||
|
|
||||||
Material *material;
|
Material* material = getMaterialResource();
|
||||||
|
|
||||||
if ( !Sim::findObject( mMaterialName, material ) )
|
if (material == nullptr)
|
||||||
Sim::findObject( "WarningMaterial", material );
|
return;
|
||||||
|
|
||||||
mMaterialInst = material->createMatInstance();
|
mMaterialInst = material->createMatInstance();
|
||||||
|
|
||||||
|
|
@ -2159,3 +2170,5 @@ void ConvexShape::Geometry::generate(const Vector< PlaneF > &planes, const Vecto
|
||||||
faces.push_back( newFace );
|
faces.push_back( newFace );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEF_MATERIALASSET_BINDS(ConvexShape, Material);
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,8 @@
|
||||||
#include "collision/convex.h"
|
#include "collision/convex.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "T3D/assets/MaterialAsset.h"
|
||||||
|
|
||||||
class ConvexShape;
|
class ConvexShape;
|
||||||
|
|
||||||
// Crap name, but whatcha gonna do.
|
// Crap name, but whatcha gonna do.
|
||||||
|
|
@ -134,14 +136,17 @@ public:
|
||||||
struct surfaceMaterial
|
struct surfaceMaterial
|
||||||
{
|
{
|
||||||
// The name of the Material we will use for rendering
|
// The name of the Material we will use for rendering
|
||||||
String materialName;
|
DECLARE_MATERIALASSET(surfaceMaterial, Material);
|
||||||
|
|
||||||
|
DECLARE_MATERIALASSET_SETGET(surfaceMaterial, Material);
|
||||||
|
|
||||||
// The actual Material instance
|
// The actual Material instance
|
||||||
BaseMatInstance* materialInst;
|
BaseMatInstance* materialInst;
|
||||||
|
|
||||||
surfaceMaterial()
|
surfaceMaterial()
|
||||||
{
|
{
|
||||||
materialName = "";
|
INIT_MATERIALASSET(Material);
|
||||||
|
|
||||||
materialInst = NULL;
|
materialInst = NULL;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -258,8 +263,8 @@ protected:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// The name of the Material we will use for rendering
|
DECLARE_MATERIALASSET(ConvexShape, Material);
|
||||||
String mMaterialName;
|
DECLARE_MATERIALASSET_SETGET(ConvexShape, Material);
|
||||||
|
|
||||||
// The actual Material instance
|
// The actual Material instance
|
||||||
BaseMatInstance* mMaterialInst;
|
BaseMatInstance* mMaterialInst;
|
||||||
|
|
|
||||||
|
|
@ -109,13 +109,14 @@ DebrisData::DebrisData()
|
||||||
minSpinSpeed = 0.0f;
|
minSpinSpeed = 0.0f;
|
||||||
maxSpinSpeed = 0.0f;
|
maxSpinSpeed = 0.0f;
|
||||||
textureName = NULL;
|
textureName = NULL;
|
||||||
shapeName = NULL;
|
|
||||||
fade = true;
|
fade = true;
|
||||||
useRadiusMass = false;
|
useRadiusMass = false;
|
||||||
baseRadius = 1.0f;
|
baseRadius = 1.0f;
|
||||||
gravModifier = 1.0f;
|
gravModifier = 1.0f;
|
||||||
terminalVelocity = 0.0f;
|
terminalVelocity = 0.0f;
|
||||||
ignoreWater = true;
|
ignoreWater = true;
|
||||||
|
|
||||||
|
INIT_SHAPEASSET(Shape);
|
||||||
}
|
}
|
||||||
|
|
||||||
//#define TRACK_DEBRIS_DATA_CLONES
|
//#define TRACK_DEBRIS_DATA_CLONES
|
||||||
|
|
@ -150,8 +151,9 @@ DebrisData::DebrisData(const DebrisData& other, bool temp_clone) : GameBaseData(
|
||||||
gravModifier = other.gravModifier;
|
gravModifier = other.gravModifier;
|
||||||
terminalVelocity = other.terminalVelocity;
|
terminalVelocity = other.terminalVelocity;
|
||||||
ignoreWater = other.ignoreWater;
|
ignoreWater = other.ignoreWater;
|
||||||
shapeName = other.shapeName;
|
|
||||||
shape = other.shape; // -- TSShape loaded using shapeName
|
CLONE_SHAPEASSET(Shape);
|
||||||
|
|
||||||
textureName = other.textureName;
|
textureName = other.textureName;
|
||||||
explosionId = other.explosionId; // -- for pack/unpack of explosion ptr
|
explosionId = other.explosionId; // -- for pack/unpack of explosion ptr
|
||||||
explosion = other.explosion;
|
explosion = other.explosion;
|
||||||
|
|
@ -189,12 +191,7 @@ DebrisData* DebrisData::cloneAndPerformSubstitutions(const SimObject* owner, S32
|
||||||
|
|
||||||
void DebrisData::onPerformSubstitutions()
|
void DebrisData::onPerformSubstitutions()
|
||||||
{
|
{
|
||||||
if( shapeName && shapeName[0] != '\0')
|
_setShape(getShape());
|
||||||
{
|
|
||||||
shape = ResourceManager::get().load(shapeName);
|
|
||||||
if( bool(shape) == false )
|
|
||||||
Con::errorf("DebrisData::onPerformSubstitutions(): failed to load shape \"%s\"", shapeName);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DebrisData::onAdd()
|
bool DebrisData::onAdd()
|
||||||
|
|
@ -277,20 +274,20 @@ bool DebrisData::preload(bool server, String &errorStr)
|
||||||
|
|
||||||
if( server ) return true;
|
if( server ) return true;
|
||||||
|
|
||||||
if( shapeName && shapeName[0] != '\0' && !bool(shape) )
|
if (mShapeAsset.notNull())
|
||||||
{
|
{
|
||||||
shape = ResourceManager::get().load(shapeName);
|
if (!mShape)
|
||||||
if( bool(shape) == false )
|
|
||||||
{
|
{
|
||||||
errorStr = String::ToString("DebrisData::load: Couldn't load shape \"%s\"", shapeName);
|
errorStr = String::ToString("DebrisData::load: Couldn't load shape \"%s\"", mShapeAssetId);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TSShapeInstance* pDummy = new TSShapeInstance(shape, !server);
|
TSShapeInstance* pDummy = new TSShapeInstance(mShape, !server);
|
||||||
delete pDummy;
|
delete pDummy;
|
||||||
|
if (!server && !mShape->preloadMaterialList(mShape.getPath()) && NetConnection::filesWereDownloaded())
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -300,9 +297,9 @@ void DebrisData::initPersistFields()
|
||||||
{
|
{
|
||||||
addGroup("Display");
|
addGroup("Display");
|
||||||
addField("texture", TypeString, Offset(textureName, DebrisData),
|
addField("texture", TypeString, Offset(textureName, DebrisData),
|
||||||
"@brief Texture imagemap to use for this debris object.\n\nNot used any more.\n");
|
"@brief Texture imagemap to use for this debris object.\n\nNot used any more.\n", AbstractClassRep::FIELD_HideInInspectors);
|
||||||
addField("shapeFile", TypeShapeFilename, Offset(shapeName, DebrisData),
|
|
||||||
"@brief Object model to use for this debris object.\n\nThis shape is optional. You could have Debris made up of only particles.\n");
|
INITPERSISTFIELD_SHAPEASSET(Shape, DebrisData, "Shape to use for this debris object.");
|
||||||
endGroup("Display");
|
endGroup("Display");
|
||||||
|
|
||||||
addGroup("Datablocks");
|
addGroup("Datablocks");
|
||||||
|
|
@ -384,7 +381,8 @@ void DebrisData::packData(BitStream* stream)
|
||||||
stream->write(ignoreWater);
|
stream->write(ignoreWater);
|
||||||
|
|
||||||
stream->writeString( textureName );
|
stream->writeString( textureName );
|
||||||
stream->writeString( shapeName );
|
|
||||||
|
PACKDATA_SHAPEASSET(Shape);
|
||||||
|
|
||||||
for( S32 i=0; i<DDC_NUM_EMITTERS; i++ )
|
for( S32 i=0; i<DDC_NUM_EMITTERS; i++ )
|
||||||
{
|
{
|
||||||
|
|
@ -427,7 +425,8 @@ void DebrisData::unpackData(BitStream* stream)
|
||||||
stream->read(&ignoreWater);
|
stream->read(&ignoreWater);
|
||||||
|
|
||||||
textureName = stream->readSTString();
|
textureName = stream->readSTString();
|
||||||
shapeName = stream->readSTString();
|
|
||||||
|
UNPACKDATA_SHAPEASSET(Shape);
|
||||||
|
|
||||||
for( S32 i=0; i<DDC_NUM_EMITTERS; i++ )
|
for( S32 i=0; i<DDC_NUM_EMITTERS; i++ )
|
||||||
{
|
{
|
||||||
|
|
@ -669,18 +668,18 @@ bool Debris::onAdd()
|
||||||
mFriction = mDataBlock->friction;
|
mFriction = mDataBlock->friction;
|
||||||
|
|
||||||
// Setup our bounding box
|
// Setup our bounding box
|
||||||
if( mDataBlock->shape )
|
if( mDataBlock->mShape )
|
||||||
{
|
{
|
||||||
mObjBox = mDataBlock->shape->mBounds;
|
mObjBox = mDataBlock->mShape->mBounds;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mObjBox = Box3F(Point3F(-1, -1, -1), Point3F(1, 1, 1));
|
mObjBox = Box3F(Point3F(-1, -1, -1), Point3F(1, 1, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
if( mDataBlock->shape )
|
if( mDataBlock->mShape)
|
||||||
{
|
{
|
||||||
mShape = new TSShapeInstance( mDataBlock->shape, true);
|
mShape = new TSShapeInstance( mDataBlock->mShape, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( mPart )
|
if( mPart )
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,8 @@
|
||||||
#include "T3D/gameBase/gameBase.h"
|
#include "T3D/gameBase/gameBase.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "T3D/assets/ShapeAsset.h"
|
||||||
|
|
||||||
class ParticleEmitterData;
|
class ParticleEmitterData;
|
||||||
class ParticleEmitter;
|
class ParticleEmitter;
|
||||||
class ExplosionData;
|
class ExplosionData;
|
||||||
|
|
@ -81,8 +83,8 @@ struct DebrisData : public GameBaseData
|
||||||
F32 terminalVelocity; // max velocity magnitude
|
F32 terminalVelocity; // max velocity magnitude
|
||||||
bool ignoreWater;
|
bool ignoreWater;
|
||||||
|
|
||||||
const char* shapeName;
|
DECLARE_SHAPEASSET(DebrisData, Shape, onShapeChanged);
|
||||||
Resource<TSShape> shape;
|
DECLARE_SHAPEASSET_SETGET(DebrisData, Shape);
|
||||||
|
|
||||||
StringTableEntry textureName;
|
StringTableEntry textureName;
|
||||||
|
|
||||||
|
|
@ -108,6 +110,8 @@ public:
|
||||||
DebrisData* cloneAndPerformSubstitutions(const SimObject*, S32 index=0);
|
DebrisData* cloneAndPerformSubstitutions(const SimObject*, S32 index=0);
|
||||||
virtual void onPerformSubstitutions();
|
virtual void onPerformSubstitutions();
|
||||||
virtual bool allowSubstitutions() const { return true; }
|
virtual bool allowSubstitutions() const { return true; }
|
||||||
|
|
||||||
|
void onShapeChanged() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ ConsoleDocClass( DecalData,
|
||||||
DecalData::DecalData()
|
DecalData::DecalData()
|
||||||
{
|
{
|
||||||
size = 5;
|
size = 5;
|
||||||
materialName = "";
|
INIT_MATERIALASSET(Material);
|
||||||
|
|
||||||
lifeSpan = 5000;
|
lifeSpan = 5000;
|
||||||
fadeTime = 1000;
|
fadeTime = 1000;
|
||||||
|
|
@ -89,7 +89,6 @@ DecalData::DecalData()
|
||||||
fadeStartPixelSize = -1.0f;
|
fadeStartPixelSize = -1.0f;
|
||||||
fadeEndPixelSize = 200.0f;
|
fadeEndPixelSize = 200.0f;
|
||||||
|
|
||||||
material = NULL;
|
|
||||||
matInst = NULL;
|
matInst = NULL;
|
||||||
|
|
||||||
renderPriority = 10;
|
renderPriority = 10;
|
||||||
|
|
@ -144,8 +143,7 @@ void DecalData::initPersistFields()
|
||||||
addField( "size", TypeF32, Offset( size, DecalData ),
|
addField( "size", TypeF32, Offset( size, DecalData ),
|
||||||
"Width and height of the decal in meters before scale is applied." );
|
"Width and height of the decal in meters before scale is applied." );
|
||||||
|
|
||||||
addField( "material", TypeMaterialName, Offset( materialName, DecalData ),
|
INITPERSISTFIELD_MATERIALASSET(Material, DecalData, "Material to use for this decal.");
|
||||||
"Material to use for this decal." );
|
|
||||||
|
|
||||||
addField( "lifeSpan", TypeS32, Offset( lifeSpan, DecalData ),
|
addField( "lifeSpan", TypeS32, Offset( lifeSpan, DecalData ),
|
||||||
"Time (in milliseconds) before this decal will be automatically deleted." );
|
"Time (in milliseconds) before this decal will be automatically deleted." );
|
||||||
|
|
@ -226,7 +224,7 @@ void DecalData::onStaticModified( const char *slotName, const char *newValue )
|
||||||
// To allow changing materials live.
|
// To allow changing materials live.
|
||||||
if ( dStricmp( slotName, "material" ) == 0 )
|
if ( dStricmp( slotName, "material" ) == 0 )
|
||||||
{
|
{
|
||||||
materialName = newValue;
|
_setMaterial(newValue);
|
||||||
_updateMaterial();
|
_updateMaterial();
|
||||||
}
|
}
|
||||||
// To allow changing name live.
|
// To allow changing name live.
|
||||||
|
|
@ -259,7 +257,9 @@ void DecalData::packData( BitStream *stream )
|
||||||
|
|
||||||
stream->write( lookupName );
|
stream->write( lookupName );
|
||||||
stream->write( size );
|
stream->write( size );
|
||||||
stream->write( materialName );
|
|
||||||
|
PACKDATA_MATERIALASSET(Material);
|
||||||
|
|
||||||
stream->write( lifeSpan );
|
stream->write( lifeSpan );
|
||||||
stream->write( fadeTime );
|
stream->write( fadeTime );
|
||||||
stream->write( texCoordCount );
|
stream->write( texCoordCount );
|
||||||
|
|
@ -285,8 +285,10 @@ void DecalData::unpackData( BitStream *stream )
|
||||||
|
|
||||||
stream->read( &lookupName );
|
stream->read( &lookupName );
|
||||||
assignName(lookupName);
|
assignName(lookupName);
|
||||||
stream->read( &size );
|
stream->read( &size );
|
||||||
stream->read( &materialName );
|
|
||||||
|
UNPACKDATA_MATERIALASSET(Material);
|
||||||
|
|
||||||
_updateMaterial();
|
_updateMaterial();
|
||||||
stream->read( &lifeSpan );
|
stream->read( &lifeSpan );
|
||||||
stream->read( &fadeTime );
|
stream->read( &fadeTime );
|
||||||
|
|
@ -311,8 +313,10 @@ void DecalData::_initMaterial()
|
||||||
{
|
{
|
||||||
SAFE_DELETE( matInst );
|
SAFE_DELETE( matInst );
|
||||||
|
|
||||||
if ( material )
|
if (mMaterialAsset.notNull())
|
||||||
matInst = material->createMatInstance();
|
{
|
||||||
|
matInst = getMaterialResource()->createMatInstance();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
matInst = MATMGR->createMatInstance( "WarningMaterial" );
|
matInst = MATMGR->createMatInstance( "WarningMaterial" );
|
||||||
|
|
||||||
|
|
@ -324,7 +328,7 @@ void DecalData::_initMaterial()
|
||||||
matInst->init( MATMGR->getDefaultFeatures(), getGFXVertexFormat<DecalVertex>() );
|
matInst->init( MATMGR->getDefaultFeatures(), getGFXVertexFormat<DecalVertex>() );
|
||||||
if( !matInst->isValid() )
|
if( !matInst->isValid() )
|
||||||
{
|
{
|
||||||
Con::errorf( "DecalData::_initMaterial - failed to create material instance for '%s'", materialName.c_str() );
|
Con::errorf( "DecalData::_initMaterial - failed to create material instance for '%s'", mMaterialAssetId );
|
||||||
SAFE_DELETE( matInst );
|
SAFE_DELETE( matInst );
|
||||||
matInst = MATMGR->createMatInstance( "WarningMaterial" );
|
matInst = MATMGR->createMatInstance( "WarningMaterial" );
|
||||||
matInst->init( MATMGR->getDefaultFeatures(), getGFXVertexFormat< DecalVertex >() );
|
matInst->init( MATMGR->getDefaultFeatures(), getGFXVertexFormat< DecalVertex >() );
|
||||||
|
|
@ -333,38 +337,29 @@ void DecalData::_initMaterial()
|
||||||
|
|
||||||
void DecalData::_updateMaterial()
|
void DecalData::_updateMaterial()
|
||||||
{
|
{
|
||||||
if ( materialName.isEmpty() )
|
if(mMaterialAsset.isNull())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Material *pMat = NULL;
|
|
||||||
if ( !Sim::findObject( materialName, pMat ) )
|
|
||||||
{
|
|
||||||
Con::printf( "DecalData::unpackUpdate, failed to find Material of name %s!", materialName.c_str() );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
material = pMat;
|
|
||||||
|
|
||||||
// Only update material instance if we have one allocated.
|
// Only update material instance if we have one allocated.
|
||||||
if ( matInst )
|
if ( matInst )
|
||||||
_initMaterial();
|
_initMaterial();
|
||||||
}
|
}
|
||||||
|
|
||||||
Material* DecalData::getMaterial()
|
Material* DecalData::getMaterialDefinition()
|
||||||
{
|
{
|
||||||
if ( !material )
|
if ( !getMaterialResource() )
|
||||||
{
|
{
|
||||||
_updateMaterial();
|
_updateMaterial();
|
||||||
if ( !material )
|
if ( !mMaterial )
|
||||||
material = static_cast<Material*>( Sim::findObject("WarningMaterial") );
|
mMaterial = static_cast<Material*>( Sim::findObject("WarningMaterial") );
|
||||||
}
|
}
|
||||||
|
|
||||||
return material;
|
return mMaterial;
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseMatInstance* DecalData::getMaterialInstance()
|
BaseMatInstance* DecalData::getMaterialInstance()
|
||||||
{
|
{
|
||||||
if ( !material || !matInst || matInst->getMaterial() != material )
|
if ( !mMaterial || !matInst || matInst->getMaterial() != mMaterial)
|
||||||
_initMaterial();
|
_initMaterial();
|
||||||
|
|
||||||
return matInst;
|
return matInst;
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,8 @@
|
||||||
#include "console/dynamicTypes.h"
|
#include "console/dynamicTypes.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "T3D/assets/MaterialAsset.h"
|
||||||
|
|
||||||
GFXDeclareVertexFormat( DecalVertex )
|
GFXDeclareVertexFormat( DecalVertex )
|
||||||
{
|
{
|
||||||
// .xyz = coords
|
// .xyz = coords
|
||||||
|
|
@ -75,11 +77,8 @@ class DecalData : public SimDataBlock
|
||||||
F32 fadeStartPixelSize;
|
F32 fadeStartPixelSize;
|
||||||
F32 fadeEndPixelSize;
|
F32 fadeEndPixelSize;
|
||||||
|
|
||||||
/// Name of material to use.
|
DECLARE_MATERIALASSET(DecalData, Material);
|
||||||
String materialName;
|
DECLARE_MATERIALASSET_SETGET(DecalData, Material);
|
||||||
|
|
||||||
/// Render material for decal.
|
|
||||||
SimObjectPtr<Material> material;
|
|
||||||
|
|
||||||
/// Material instance for decal.
|
/// Material instance for decal.
|
||||||
BaseMatInstance *matInst;
|
BaseMatInstance *matInst;
|
||||||
|
|
@ -113,7 +112,7 @@ class DecalData : public SimDataBlock
|
||||||
virtual void packData( BitStream* );
|
virtual void packData( BitStream* );
|
||||||
virtual void unpackData( BitStream* );
|
virtual void unpackData( BitStream* );
|
||||||
|
|
||||||
Material* getMaterial();
|
Material* getMaterialDefinition();
|
||||||
BaseMatInstance* getMaterialInstance();
|
BaseMatInstance* getMaterialInstance();
|
||||||
|
|
||||||
static SimSet* getSet();
|
static SimSet* getSet();
|
||||||
|
|
|
||||||
|
|
@ -206,8 +206,8 @@ bool DecalDataFile::read( Stream &stream )
|
||||||
data->lookupName = name;
|
data->lookupName = name;
|
||||||
data->registerObject(name);
|
data->registerObject(name);
|
||||||
Sim::getRootGroup()->addObject( data );
|
Sim::getRootGroup()->addObject( data );
|
||||||
data->materialName = "WarningMaterial";
|
data->mMaterialName = "WarningMaterial";
|
||||||
data->material = dynamic_cast<Material*>(Sim::findObject("WarningMaterial"));
|
data->mMaterial = dynamic_cast<Material*>(Sim::findObject("WarningMaterial"));
|
||||||
|
|
||||||
Con::errorf( "DecalDataFile::read() - DecalData %s does not exist! Temporarily created %s_missing.", lookupName.c_str(), lookupName.c_str());
|
Con::errorf( "DecalDataFile::read() - DecalData %s does not exist! Temporarily created %s_missing.", lookupName.c_str(), lookupName.c_str());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -186,7 +186,7 @@ S32 QSORT_CALLBACK cmpDecalRenderOrder( const void *p1, const void *p2 )
|
||||||
|
|
||||||
if ( (*pd2)->mFlags & SaveDecal )
|
if ( (*pd2)->mFlags & SaveDecal )
|
||||||
{
|
{
|
||||||
S32 id = ( (*pd1)->mDataBlock->getMaterial()->getId() - (*pd2)->mDataBlock->getMaterial()->getId() );
|
S32 id = ( (*pd1)->mDataBlock->getMaterialDefinition()->getId() - (*pd2)->mDataBlock->getMaterialDefinition()->getId() );
|
||||||
if ( id != 0 )
|
if ( id != 0 )
|
||||||
return id;
|
return id;
|
||||||
|
|
||||||
|
|
@ -1225,7 +1225,7 @@ void DecalManager::prepRenderImage( SceneRenderState* state )
|
||||||
{
|
{
|
||||||
DecalInstance *decal = mDecalQueue[i];
|
DecalInstance *decal = mDecalQueue[i];
|
||||||
DecalData *data = decal->mDataBlock;
|
DecalData *data = decal->mDataBlock;
|
||||||
Material *mat = data->getMaterial();
|
Material *mat = data->getMaterialDefinition();
|
||||||
|
|
||||||
if ( currentBatch == NULL )
|
if ( currentBatch == NULL )
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -59,11 +59,7 @@ RenderMeshExample::RenderMeshExample()
|
||||||
// Set it as a "static" object that casts shadows
|
// Set it as a "static" object that casts shadows
|
||||||
mTypeMask |= StaticObjectType | StaticShapeObjectType;
|
mTypeMask |= StaticObjectType | StaticShapeObjectType;
|
||||||
|
|
||||||
// Make sure we the Material instance to NULL
|
INIT_MATERIALASSET(Material);
|
||||||
// so we don't try to access it incorrectly
|
|
||||||
mMaterialInst = NULL;
|
|
||||||
|
|
||||||
initMaterialAsset(Material);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderMeshExample::~RenderMeshExample()
|
RenderMeshExample::~RenderMeshExample()
|
||||||
|
|
@ -78,7 +74,7 @@ RenderMeshExample::~RenderMeshExample()
|
||||||
void RenderMeshExample::initPersistFields()
|
void RenderMeshExample::initPersistFields()
|
||||||
{
|
{
|
||||||
addGroup( "Rendering" );
|
addGroup( "Rendering" );
|
||||||
scriptBindMaterialAsset(Material, RenderMeshExample, "The material used to render the mesh.");
|
INITPERSISTFIELD_MATERIALASSET(Material, RenderMeshExample, "The material used to render the mesh.");
|
||||||
endGroup( "Rendering" );
|
endGroup( "Rendering" );
|
||||||
|
|
||||||
// SceneObject already handles exposing the transform
|
// SceneObject already handles exposing the transform
|
||||||
|
|
@ -147,7 +143,7 @@ U32 RenderMeshExample::packUpdate( NetConnection *conn, U32 mask, BitStream *str
|
||||||
// Write out any of the updated editable properties
|
// Write out any of the updated editable properties
|
||||||
if (stream->writeFlag(mask & UpdateMask))
|
if (stream->writeFlag(mask & UpdateMask))
|
||||||
{
|
{
|
||||||
packMaterialAsset(conn, Material);
|
PACK_MATERIALASSET(conn, Material);
|
||||||
}
|
}
|
||||||
|
|
||||||
return retMask;
|
return retMask;
|
||||||
|
|
@ -168,7 +164,7 @@ void RenderMeshExample::unpackUpdate(NetConnection *conn, BitStream *stream)
|
||||||
|
|
||||||
if ( stream->readFlag() ) // UpdateMask
|
if ( stream->readFlag() ) // UpdateMask
|
||||||
{
|
{
|
||||||
unpackMaterialAsset(conn, Material);
|
UNPACK_MATERIALASSET(conn, Material);
|
||||||
|
|
||||||
if ( isProperlyAdded() )
|
if ( isProperlyAdded() )
|
||||||
updateMaterial();
|
updateMaterial();
|
||||||
|
|
|
||||||
|
|
@ -64,18 +64,18 @@ class RenderMeshExample : public SceneObject
|
||||||
NextFreeMask = Parent::NextFreeMask << 2
|
NextFreeMask = Parent::NextFreeMask << 2
|
||||||
};
|
};
|
||||||
|
|
||||||
//--------------------------------------------------------------------------
|
|
||||||
// Rendering variables
|
|
||||||
//--------------------------------------------------------------------------
|
|
||||||
DECLARE_NET_MATERIALASSET(RenderMeshExample, Material, UpdateMask);
|
|
||||||
|
|
||||||
// The actual Material instance
|
|
||||||
BaseMatInstance* mMaterialInst;
|
|
||||||
|
|
||||||
// Define our vertex format here so we don't have to
|
// Define our vertex format here so we don't have to
|
||||||
// change it in multiple spots later
|
// change it in multiple spots later
|
||||||
typedef GFXVertexPNT VertexType;
|
typedef GFXVertexPNT VertexType;
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
// Rendering variables
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
BaseMatInstance* mMaterialInst;
|
||||||
|
|
||||||
|
DECLARE_MATERIALASSET(RenderMeshExample, Material);
|
||||||
|
DECLARE_MATERIALASSET_NET_SETGET(RenderMeshExample, Material, UpdateMask);
|
||||||
|
|
||||||
// The GFX vertex and primitive buffers
|
// The GFX vertex and primitive buffers
|
||||||
GFXVertexBufferHandle< VertexType > mVertexBuffer;
|
GFXVertexBufferHandle< VertexType > mVertexBuffer;
|
||||||
GFXPrimitiveBufferHandle mPrimitiveBuffer;
|
GFXPrimitiveBufferHandle mPrimitiveBuffer;
|
||||||
|
|
|
||||||
|
|
@ -72,8 +72,7 @@ RenderShapeExample::~RenderShapeExample()
|
||||||
void RenderShapeExample::initPersistFields()
|
void RenderShapeExample::initPersistFields()
|
||||||
{
|
{
|
||||||
addGroup( "Rendering" );
|
addGroup( "Rendering" );
|
||||||
addField( "shapeFile", TypeStringFilename, Offset( mShapeFile, RenderShapeExample ),
|
INITPERSISTFIELD_SHAPEASSET(Shape, RenderShapeExample, "The path to the shape file.")
|
||||||
"The path to the DTS shape file." );
|
|
||||||
endGroup( "Rendering" );
|
endGroup( "Rendering" );
|
||||||
|
|
||||||
// SceneObject already handles exposing the transform
|
// SceneObject already handles exposing the transform
|
||||||
|
|
@ -146,7 +145,7 @@ U32 RenderShapeExample::packUpdate( NetConnection *conn, U32 mask, BitStream *st
|
||||||
// Write out any of the updated editable properties
|
// Write out any of the updated editable properties
|
||||||
if ( stream->writeFlag( mask & UpdateMask ) )
|
if ( stream->writeFlag( mask & UpdateMask ) )
|
||||||
{
|
{
|
||||||
stream->write( mShapeFile );
|
PACK_SHAPEASSET(conn, Shape);
|
||||||
|
|
||||||
// Allow the server object a chance to handle a new shape
|
// Allow the server object a chance to handle a new shape
|
||||||
createShape();
|
createShape();
|
||||||
|
|
@ -170,7 +169,7 @@ void RenderShapeExample::unpackUpdate(NetConnection *conn, BitStream *stream)
|
||||||
|
|
||||||
if ( stream->readFlag() ) // UpdateMask
|
if ( stream->readFlag() ) // UpdateMask
|
||||||
{
|
{
|
||||||
stream->read( &mShapeFile );
|
UNPACK_SHAPEASSET(conn, Shape);
|
||||||
|
|
||||||
if ( isProperlyAdded() )
|
if ( isProperlyAdded() )
|
||||||
createShape();
|
createShape();
|
||||||
|
|
@ -182,33 +181,22 @@ void RenderShapeExample::unpackUpdate(NetConnection *conn, BitStream *stream)
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void RenderShapeExample::createShape()
|
void RenderShapeExample::createShape()
|
||||||
{
|
{
|
||||||
if ( mShapeFile.isEmpty() )
|
if ( getShape() == StringTable->EmptyString() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// If this is the same shape then no reason to update it
|
// If this is the same shape then no reason to update it
|
||||||
if ( mShapeInstance && mShapeFile.equal( mShape.getPath().getFullPath(), String::NoCase ) )
|
if ( mShapeInstance && getShape() == StringTable->insert(mShape.getPath().getFullPath().c_str()) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Clean up our previous shape
|
// Clean up our previous shape
|
||||||
if ( mShapeInstance )
|
if ( mShapeInstance )
|
||||||
SAFE_DELETE( mShapeInstance );
|
SAFE_DELETE( mShapeInstance );
|
||||||
mShape = NULL;
|
|
||||||
|
|
||||||
// Attempt to get the resource from the ResourceManager
|
|
||||||
mShape = ResourceManager::get().load( mShapeFile );
|
|
||||||
|
|
||||||
if ( !mShape )
|
|
||||||
{
|
|
||||||
Con::errorf( "RenderShapeExample::createShape() - Unable to load shape: %s", mShapeFile.c_str() );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Attempt to preload the Materials for this shape
|
// Attempt to preload the Materials for this shape
|
||||||
if ( isClientObject() &&
|
if ( isClientObject() &&
|
||||||
!mShape->preloadMaterialList( mShape.getPath() ) &&
|
!mShape->preloadMaterialList( mShape.getPath() ) &&
|
||||||
NetConnection::filesWereDownloaded() )
|
NetConnection::filesWereDownloaded() )
|
||||||
{
|
{
|
||||||
mShape = NULL;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,8 @@
|
||||||
#include "ts/tsShapeInstance.h"
|
#include "ts/tsShapeInstance.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "T3D/assets/ShapeAsset.h"
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// This class implements a basic SceneObject that can exist in the world at a
|
// This class implements a basic SceneObject that can exist in the world at a
|
||||||
// 3D position and render itself. There are several valid ways to render an
|
// 3D position and render itself. There are several valid ways to render an
|
||||||
|
|
@ -59,12 +61,13 @@ class RenderShapeExample : public SceneObject
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
// Rendering variables
|
// Rendering variables
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
// The name of the shape file we will use for rendering
|
DECLARE_SHAPEASSET(RenderShapeExample, Shape, onShapeChanged);
|
||||||
String mShapeFile;
|
DECLARE_SHAPEASSET_SETGET(RenderShapeExample, Shape);
|
||||||
|
|
||||||
// The actual shape instance
|
// The actual shape instance
|
||||||
TSShapeInstance* mShapeInstance;
|
TSShapeInstance* mShapeInstance;
|
||||||
// Store the resource so we can access the filename later
|
|
||||||
Resource<TSShape> mShape;
|
void onShapeChanged() {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RenderShapeExample();
|
RenderShapeExample();
|
||||||
|
|
|
||||||
|
|
@ -225,7 +225,6 @@ ConsoleDocClass( ExplosionData,
|
||||||
|
|
||||||
ExplosionData::ExplosionData()
|
ExplosionData::ExplosionData()
|
||||||
{
|
{
|
||||||
dtsFileName = NULL;
|
|
||||||
particleDensity = 10;
|
particleDensity = 10;
|
||||||
particleRadius = 1.0f;
|
particleRadius = 1.0f;
|
||||||
|
|
||||||
|
|
@ -238,7 +237,8 @@ ExplosionData::ExplosionData()
|
||||||
explosionScale.set(1.0f, 1.0f, 1.0f);
|
explosionScale.set(1.0f, 1.0f, 1.0f);
|
||||||
playSpeed = 1.0f;
|
playSpeed = 1.0f;
|
||||||
|
|
||||||
explosionShape = NULL;
|
INIT_SHAPEASSET(ExplosionShape);
|
||||||
|
|
||||||
explosionAnimation = -1;
|
explosionAnimation = -1;
|
||||||
|
|
||||||
dMemset( emitterList, 0, sizeof( emitterList ) );
|
dMemset( emitterList, 0, sizeof( emitterList ) );
|
||||||
|
|
@ -305,7 +305,6 @@ ExplosionData::ExplosionData(const ExplosionData& other, bool temp_clone) : Game
|
||||||
Con::errorf("ExplosionData -- Clones are on the loose!");
|
Con::errorf("ExplosionData -- Clones are on the loose!");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
dtsFileName = other.dtsFileName;
|
|
||||||
faceViewer = other.faceViewer;
|
faceViewer = other.faceViewer;
|
||||||
particleDensity = other.particleDensity;
|
particleDensity = other.particleDensity;
|
||||||
particleRadius = other.particleRadius;
|
particleRadius = other.particleRadius;
|
||||||
|
|
@ -314,7 +313,7 @@ ExplosionData::ExplosionData(const ExplosionData& other, bool temp_clone) : Game
|
||||||
particleEmitterId = other.particleEmitterId; // -- for pack/unpack of particleEmitter ptr
|
particleEmitterId = other.particleEmitterId; // -- for pack/unpack of particleEmitter ptr
|
||||||
explosionScale = other.explosionScale;
|
explosionScale = other.explosionScale;
|
||||||
playSpeed = other.playSpeed;
|
playSpeed = other.playSpeed;
|
||||||
explosionShape = other.explosionShape; // -- TSShape loaded using dtsFileName
|
CLONE_SHAPEASSET(ExplosionShape);
|
||||||
explosionAnimation = other.explosionAnimation; // -- from explosionShape sequence "ambient"
|
explosionAnimation = other.explosionAnimation; // -- from explosionShape sequence "ambient"
|
||||||
dMemcpy( emitterList, other.emitterList, sizeof( emitterList ) );
|
dMemcpy( emitterList, other.emitterList, sizeof( emitterList ) );
|
||||||
dMemcpy( emitterIDList, other.emitterIDList, sizeof( emitterIDList ) ); // -- for pack/unpack of emitterList ptrs
|
dMemcpy( emitterIDList, other.emitterIDList, sizeof( emitterIDList ) ); // -- for pack/unpack of emitterList ptrs
|
||||||
|
|
@ -392,10 +391,9 @@ ExplosionData* ExplosionData::cloneAndPerformSubstitutions(const SimObject* owne
|
||||||
|
|
||||||
void ExplosionData::initPersistFields()
|
void ExplosionData::initPersistFields()
|
||||||
{
|
{
|
||||||
addField( "explosionShape", TypeShapeFilename, Offset(dtsFileName, ExplosionData),
|
INITPERSISTFIELD_SHAPEASSET(ExplosionShape, ExplosionData, "@brief Optional shape asset to place at the center of the explosion.\n\n"
|
||||||
"@brief Optional DTS or DAE shape to place at the center of the explosion.\n\n"
|
"The <i>ambient</i> animation of this model will be played automatically at the start of the explosion.");
|
||||||
"The <i>ambient</i> animation of this model will be played automatically at "
|
|
||||||
"the start of the explosion." );
|
|
||||||
addField( "explosionScale", TypePoint3F, Offset(explosionScale, ExplosionData),
|
addField( "explosionScale", TypePoint3F, Offset(explosionScale, ExplosionData),
|
||||||
"\"X Y Z\" scale factor applied to the explosionShape model at the start "
|
"\"X Y Z\" scale factor applied to the explosionShape model at the start "
|
||||||
"of the explosion." );
|
"of the explosion." );
|
||||||
|
|
@ -656,7 +654,7 @@ void ExplosionData::packData(BitStream* stream)
|
||||||
{
|
{
|
||||||
Parent::packData(stream);
|
Parent::packData(stream);
|
||||||
|
|
||||||
stream->writeString(dtsFileName);
|
PACKDATA_SHAPEASSET(ExplosionShape);
|
||||||
|
|
||||||
sfxWrite( stream, soundProfile );
|
sfxWrite( stream, soundProfile );
|
||||||
if (stream->writeFlag(particleEmitter))
|
if (stream->writeFlag(particleEmitter))
|
||||||
|
|
@ -759,7 +757,7 @@ void ExplosionData::unpackData(BitStream* stream)
|
||||||
{
|
{
|
||||||
Parent::unpackData(stream);
|
Parent::unpackData(stream);
|
||||||
|
|
||||||
dtsFileName = stream->readSTString();
|
UNPACKDATA_SHAPEASSET(ExplosionShape);
|
||||||
|
|
||||||
sfxRead( stream, &soundProfile );
|
sfxRead( stream, &soundProfile );
|
||||||
|
|
||||||
|
|
@ -874,22 +872,16 @@ bool ExplosionData::preload(bool server, String &errorStr)
|
||||||
Con::errorf(ConsoleLogEntry::General, "Error, unable to load particle emitter for explosion datablock");
|
Con::errorf(ConsoleLogEntry::General, "Error, unable to load particle emitter for explosion datablock");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dtsFileName && dtsFileName[0]) {
|
if (mExplosionShapeAsset.notNull()) {
|
||||||
explosionShape = ResourceManager::get().load(dtsFileName);
|
|
||||||
if (!bool(explosionShape)) {
|
|
||||||
errorStr = String::ToString("ExplosionData: Couldn't load shape \"%s\"", dtsFileName);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Resolve animations
|
// Resolve animations
|
||||||
explosionAnimation = explosionShape->findSequence("ambient");
|
explosionAnimation = mExplosionShape->findSequence("ambient");
|
||||||
|
|
||||||
// Preload textures with a dummy instance...
|
// Preload textures with a dummy instance...
|
||||||
TSShapeInstance* pDummy = new TSShapeInstance(explosionShape, !server);
|
TSShapeInstance* pDummy = new TSShapeInstance(mExplosionShape, !server);
|
||||||
delete pDummy;
|
delete pDummy;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
explosionShape = NULL;
|
|
||||||
explosionAnimation = -1;
|
explosionAnimation = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1377,8 +1369,8 @@ bool Explosion::explode()
|
||||||
launchDebris( mInitialNormal );
|
launchDebris( mInitialNormal );
|
||||||
spawnSubExplosions();
|
spawnSubExplosions();
|
||||||
|
|
||||||
if (bool(mDataBlock->explosionShape) && mDataBlock->explosionAnimation != -1) {
|
if (bool(mDataBlock->mExplosionShape) && mDataBlock->explosionAnimation != -1) {
|
||||||
mExplosionInstance = new TSShapeInstance(mDataBlock->explosionShape, true);
|
mExplosionInstance = new TSShapeInstance(mDataBlock->mExplosionShape, true);
|
||||||
|
|
||||||
mExplosionThread = mExplosionInstance->addThread();
|
mExplosionThread = mExplosionInstance->addThread();
|
||||||
mExplosionInstance->setSequence(mExplosionThread, mDataBlock->explosionAnimation, 0);
|
mExplosionInstance->setSequence(mExplosionThread, mDataBlock->explosionAnimation, 0);
|
||||||
|
|
@ -1388,7 +1380,7 @@ bool Explosion::explode()
|
||||||
mEndingMS = U32(mExplosionInstance->getScaledDuration(mExplosionThread) * 1000.0f);
|
mEndingMS = U32(mExplosionInstance->getScaledDuration(mExplosionThread) * 1000.0f);
|
||||||
|
|
||||||
mObjScale.convolve(mDataBlock->explosionScale);
|
mObjScale.convolve(mDataBlock->explosionScale);
|
||||||
mObjBox = mDataBlock->explosionShape->mBounds;
|
mObjBox = mDataBlock->mExplosionShape->mBounds;
|
||||||
resetWorldBox();
|
resetWorldBox();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,8 @@
|
||||||
#include "lighting/lightInfo.h"
|
#include "lighting/lightInfo.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "T3D/assets/ShapeAsset.h"
|
||||||
|
|
||||||
class ParticleEmitter;
|
class ParticleEmitter;
|
||||||
class ParticleEmitterData;
|
class ParticleEmitterData;
|
||||||
class TSThread;
|
class TSThread;
|
||||||
|
|
@ -62,8 +64,6 @@ class ExplosionData : public GameBaseData {
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
StringTableEntry dtsFileName;
|
|
||||||
|
|
||||||
bool faceViewer;
|
bool faceViewer;
|
||||||
|
|
||||||
S32 particleDensity;
|
S32 particleDensity;
|
||||||
|
|
@ -76,7 +76,9 @@ class ExplosionData : public GameBaseData {
|
||||||
Point3F explosionScale;
|
Point3F explosionScale;
|
||||||
F32 playSpeed;
|
F32 playSpeed;
|
||||||
|
|
||||||
Resource<TSShape> explosionShape;
|
DECLARE_SHAPEASSET(ExplosionData, ExplosionShape, onShapeChanged);
|
||||||
|
DECLARE_SHAPEASSET_SETGET(ExplosionData, ExplosionShape);
|
||||||
|
|
||||||
S32 explosionAnimation;
|
S32 explosionAnimation;
|
||||||
|
|
||||||
ParticleEmitterData* emitterList[EC_NUM_EMITTERS];
|
ParticleEmitterData* emitterList[EC_NUM_EMITTERS];
|
||||||
|
|
@ -137,6 +139,8 @@ public:
|
||||||
/*D*/ ~ExplosionData();
|
/*D*/ ~ExplosionData();
|
||||||
ExplosionData* cloneAndPerformSubstitutions(const SimObject*, S32 index=0);
|
ExplosionData* cloneAndPerformSubstitutions(const SimObject*, S32 index=0);
|
||||||
virtual bool allowSubstitutions() const { return true; }
|
virtual bool allowSubstitutions() const { return true; }
|
||||||
|
|
||||||
|
void onShapeChanged() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,7 @@
|
||||||
#include "materials/matInstance.h"
|
#include "materials/matInstance.h"
|
||||||
#include "renderInstance/renderDeferredMgr.h"
|
#include "renderInstance/renderDeferredMgr.h"
|
||||||
#include "console/engineAPI.h"
|
#include "console/engineAPI.h"
|
||||||
|
#include "T3D/assets/MaterialAsset.h"
|
||||||
|
|
||||||
/// This is used for rendering ground cover billboards.
|
/// This is used for rendering ground cover billboards.
|
||||||
GFXImplementVertexFormat( GCVertex )
|
GFXImplementVertexFormat( GCVertex )
|
||||||
|
|
@ -458,9 +459,9 @@ GroundCover::GroundCover()
|
||||||
|
|
||||||
mRandomSeed = 1;
|
mRandomSeed = 1;
|
||||||
|
|
||||||
initMaterialAsset(Material);
|
INIT_MATERIALASSET(Material);
|
||||||
|
mMaterialInst = NULL;
|
||||||
|
|
||||||
mMatInst = NULL;
|
|
||||||
mMatParams = NULL;
|
mMatParams = NULL;
|
||||||
mTypeRectsParam = NULL;
|
mTypeRectsParam = NULL;
|
||||||
mFadeParams = NULL;
|
mFadeParams = NULL;
|
||||||
|
|
@ -519,7 +520,8 @@ GroundCover::GroundCover()
|
||||||
mBillboardRects[i].point.set( 0.0f, 0.0f );
|
mBillboardRects[i].point.set( 0.0f, 0.0f );
|
||||||
mBillboardRects[i].extent.set( 1.0f, 1.0f );
|
mBillboardRects[i].extent.set( 1.0f, 1.0f );
|
||||||
|
|
||||||
mShapeFilenames[i] = NULL;
|
INIT_SHAPEASSET_ARRAY(Shape, i);
|
||||||
|
|
||||||
mShapeInstances[i] = NULL;
|
mShapeInstances[i] = NULL;
|
||||||
|
|
||||||
mBillboardAspectScales[i] = 1.0f;
|
mBillboardAspectScales[i] = 1.0f;
|
||||||
|
|
@ -530,7 +532,7 @@ GroundCover::GroundCover()
|
||||||
|
|
||||||
GroundCover::~GroundCover()
|
GroundCover::~GroundCover()
|
||||||
{
|
{
|
||||||
SAFE_DELETE( mMatInst );
|
SAFE_DELETE( mMaterialInst );
|
||||||
}
|
}
|
||||||
|
|
||||||
IMPLEMENT_CO_NETOBJECT_V1(GroundCover);
|
IMPLEMENT_CO_NETOBJECT_V1(GroundCover);
|
||||||
|
|
@ -539,7 +541,7 @@ void GroundCover::initPersistFields()
|
||||||
{
|
{
|
||||||
addGroup( "GroundCover General" );
|
addGroup( "GroundCover General" );
|
||||||
|
|
||||||
scriptBindMaterialAsset(Material, GroundCover, "Material used by all GroundCover segments.");
|
INITPERSISTFIELD_MATERIALASSET(Material, GroundCover, "Material used by all GroundCover segments.");
|
||||||
|
|
||||||
addField( "radius", TypeF32, Offset( mRadius, GroundCover ), "Outer generation radius from the current camera position." );
|
addField( "radius", TypeF32, Offset( mRadius, GroundCover ), "Outer generation radius from the current camera position." );
|
||||||
addField( "dissolveRadius",TypeF32, Offset( mFadeRadius, GroundCover ), "This is less than or equal to radius and defines when fading of cover elements begins." );
|
addField( "dissolveRadius",TypeF32, Offset( mFadeRadius, GroundCover ), "This is less than or equal to radius and defines when fading of cover elements begins." );
|
||||||
|
|
@ -559,7 +561,8 @@ void GroundCover::initPersistFields()
|
||||||
|
|
||||||
addField( "billboardUVs", TypeRectUV, Offset( mBillboardRects, GroundCover ), MAX_COVERTYPES, "Subset material UV coordinates for this cover billboard." );
|
addField( "billboardUVs", TypeRectUV, Offset( mBillboardRects, GroundCover ), MAX_COVERTYPES, "Subset material UV coordinates for this cover billboard." );
|
||||||
|
|
||||||
addField( "shapeFilename", TypeFilename, Offset( mShapeFilenames, GroundCover ), MAX_COVERTYPES, "The cover shape filename. [Optional]" );
|
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]");
|
||||||
|
|
||||||
addField( "layer", TypeTerrainMaterialName, Offset( mLayer, GroundCover ), MAX_COVERTYPES, "Terrain material name to limit coverage to, or blank to not limit." );
|
addField( "layer", TypeTerrainMaterialName, Offset( mLayer, GroundCover ), MAX_COVERTYPES, "Terrain material name to limit coverage to, or blank to not limit." );
|
||||||
|
|
||||||
|
|
@ -710,7 +713,7 @@ U32 GroundCover::packUpdate( NetConnection *connection, U32 mask, BitStream *str
|
||||||
// TODO: We could probably optimize a few of these
|
// TODO: We could probably optimize a few of these
|
||||||
// based on reasonable units at some point.
|
// based on reasonable units at some point.
|
||||||
|
|
||||||
packMaterialAsset(connection, Material);
|
PACK_MATERIALASSET(connection, Material);
|
||||||
|
|
||||||
stream->write( mRadius );
|
stream->write( mRadius );
|
||||||
stream->write( mZOffset );
|
stream->write( mZOffset );
|
||||||
|
|
@ -741,11 +744,11 @@ U32 GroundCover::packUpdate( NetConnection *connection, U32 mask, BitStream *str
|
||||||
|
|
||||||
stream->write( mMinSlope[i] );
|
stream->write( mMinSlope[i] );
|
||||||
stream->write( mMaxSlope[i] );
|
stream->write( mMaxSlope[i] );
|
||||||
stream->writeFlag(mConformToNormal[i]);
|
stream->writeFlag(mConformToNormal[i]);
|
||||||
stream->write(mMinRotX[i]);
|
stream->write(mMinRotX[i]);
|
||||||
stream->write(mMaxRotX[i]);
|
stream->write(mMaxRotX[i]);
|
||||||
stream->write(mMinRotY[i]);
|
stream->write(mMinRotY[i]);
|
||||||
stream->write(mMaxRotY[i]);
|
stream->write(mMaxRotY[i]);
|
||||||
|
|
||||||
stream->write( mMinElevation[i] );
|
stream->write( mMinElevation[i] );
|
||||||
stream->write( mMaxElevation[i] );
|
stream->write( mMaxElevation[i] );
|
||||||
|
|
@ -763,7 +766,7 @@ U32 GroundCover::packUpdate( NetConnection *connection, U32 mask, BitStream *str
|
||||||
stream->write( mBillboardRects[i].extent.x );
|
stream->write( mBillboardRects[i].extent.x );
|
||||||
stream->write( mBillboardRects[i].extent.y );
|
stream->write( mBillboardRects[i].extent.y );
|
||||||
|
|
||||||
stream->writeString( mShapeFilenames[i] );
|
PACK_SHAPEASSET_ARRAY(connection, Shape, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
stream->writeFlag( mDebugRenderCells );
|
stream->writeFlag( mDebugRenderCells );
|
||||||
|
|
@ -781,7 +784,7 @@ void GroundCover::unpackUpdate( NetConnection *connection, BitStream *stream )
|
||||||
|
|
||||||
if (stream->readFlag())
|
if (stream->readFlag())
|
||||||
{
|
{
|
||||||
unpackMaterialAsset(connection, Material);
|
UNPACK_MATERIALASSET(connection, Material);
|
||||||
|
|
||||||
stream->read( &mRadius );
|
stream->read( &mRadius );
|
||||||
stream->read( &mZOffset );
|
stream->read( &mZOffset );
|
||||||
|
|
@ -812,11 +815,11 @@ void GroundCover::unpackUpdate( NetConnection *connection, BitStream *stream )
|
||||||
|
|
||||||
stream->read( &mMinSlope[i] );
|
stream->read( &mMinSlope[i] );
|
||||||
stream->read( &mMaxSlope[i] );
|
stream->read( &mMaxSlope[i] );
|
||||||
mConformToNormal[i] = stream->readFlag();
|
mConformToNormal[i] = stream->readFlag();
|
||||||
stream->read(&mMinRotX[i]);
|
stream->read(&mMinRotX[i]);
|
||||||
stream->read(&mMaxRotX[i]);
|
stream->read(&mMaxRotX[i]);
|
||||||
stream->read(&mMinRotY[i]);
|
stream->read(&mMinRotY[i]);
|
||||||
stream->read(&mMaxRotY[i]);
|
stream->read(&mMaxRotY[i]);
|
||||||
|
|
||||||
stream->read( &mMinElevation[i] );
|
stream->read( &mMinElevation[i] );
|
||||||
stream->read( &mMaxElevation[i] );
|
stream->read( &mMaxElevation[i] );
|
||||||
|
|
@ -834,7 +837,7 @@ void GroundCover::unpackUpdate( NetConnection *connection, BitStream *stream )
|
||||||
stream->read( &mBillboardRects[i].extent.x );
|
stream->read( &mBillboardRects[i].extent.x );
|
||||||
stream->read( &mBillboardRects[i].extent.y );
|
stream->read( &mBillboardRects[i].extent.y );
|
||||||
|
|
||||||
mShapeFilenames[i] = stream->readSTString();
|
UNPACK_SHAPEASSET_ARRAY(connection, Shape, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
mDebugRenderCells = stream->readFlag();
|
mDebugRenderCells = stream->readFlag();
|
||||||
|
|
@ -854,28 +857,12 @@ void GroundCover::unpackUpdate( NetConnection *connection, BitStream *stream )
|
||||||
|
|
||||||
void GroundCover::_initMaterial()
|
void GroundCover::_initMaterial()
|
||||||
{
|
{
|
||||||
if (mMaterialAsset.notNull())
|
SAFE_DELETE(mMaterialInst);
|
||||||
{
|
|
||||||
if (mMatInst && String(mMaterialAsset->getMaterialDefinitionName()).equal(mMatInst->getMaterial()->getName(), String::NoCase))
|
|
||||||
return;
|
|
||||||
|
|
||||||
SAFE_DELETE(mMatInst);
|
if (mMaterialAsset.notNull() && mMaterialAsset->getStatus() == MaterialAsset::Ok)
|
||||||
|
mMaterialInst = mMaterial->createMatInstance();
|
||||||
if (!Sim::findObject(mMaterialAsset->getMaterialDefinitionName(), mMaterial))
|
|
||||||
Con::errorf("GroundCover::_initMaterial - Material %s was not found.", mMaterialAsset->getMaterialDefinitionName());
|
|
||||||
|
|
||||||
if (mMaterial)
|
|
||||||
mMatInst = mMaterial->createMatInstance();
|
|
||||||
else
|
|
||||||
mMatInst = MATMGR->createMatInstance("WarningMaterial");
|
|
||||||
|
|
||||||
if (!mMatInst)
|
|
||||||
Con::errorf("GroundCover::_initMaterial - no Material called '%s'", mMaterialAsset->getMaterialDefinitionName());
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
mMaterialInst = MATMGR->createMatInstance("WarningMaterial");
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add our special feature that makes it all work...
|
// Add our special feature that makes it all work...
|
||||||
FeatureSet features = MATMGR->getDefaultFeatures();
|
FeatureSet features = MATMGR->getDefaultFeatures();
|
||||||
|
|
@ -883,10 +870,10 @@ void GroundCover::_initMaterial()
|
||||||
|
|
||||||
// Our feature requires a pointer back to this object
|
// Our feature requires a pointer back to this object
|
||||||
// to properly setup its shader consts.
|
// to properly setup its shader consts.
|
||||||
mMatInst->setUserObject( this );
|
mMaterialInst->setUserObject( this );
|
||||||
|
|
||||||
// DO IT!
|
// DO IT!
|
||||||
mMatInst->init( features, getGFXVertexFormat<GCVertex>() );
|
mMaterialInst->init( features, getGFXVertexFormat<GCVertex>() );
|
||||||
}
|
}
|
||||||
|
|
||||||
void GroundCover::_initShapes()
|
void GroundCover::_initShapes()
|
||||||
|
|
@ -895,25 +882,17 @@ void GroundCover::_initShapes()
|
||||||
|
|
||||||
for ( S32 i=0; i < MAX_COVERTYPES; i++ )
|
for ( S32 i=0; i < MAX_COVERTYPES; i++ )
|
||||||
{
|
{
|
||||||
if ( !mShapeFilenames[i] || !mShapeFilenames[i][0] )
|
if ( mShapeAsset[i].isNull() || mShape[i] == nullptr)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Load the shape.
|
if ( isClientObject() && !mShape[i]->preloadMaterialList(mShape[i].getPath()) && NetConnection::filesWereDownloaded() )
|
||||||
Resource<TSShape> shape = ResourceManager::get().load(mShapeFilenames[i]);
|
|
||||||
if ( !(bool)shape )
|
|
||||||
{
|
{
|
||||||
Con::warnf( "GroundCover::_initShapes() unable to load shape: %s", mShapeFilenames[i] );
|
Con::warnf( "GroundCover::_initShapes() material preload failed for shape: %s", mShapeAssetId[i] );
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( isClientObject() && !shape->preloadMaterialList(shape.getPath()) && NetConnection::filesWereDownloaded() )
|
|
||||||
{
|
|
||||||
Con::warnf( "GroundCover::_initShapes() material preload failed for shape: %s", mShapeFilenames[i] );
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the shape instance.
|
// Create the shape instance.
|
||||||
mShapeInstances[i] = new TSShapeInstance( shape, isClientObject() );
|
mShapeInstances[i] = new TSShapeInstance(mShape[i], isClientObject() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -982,16 +961,16 @@ void GroundCover::_initialize( U32 cellCount, U32 cellPlacementCount )
|
||||||
|
|
||||||
// Rebuild the texture aspect scales for each type.
|
// Rebuild the texture aspect scales for each type.
|
||||||
F32 textureAspect = 1.0f;
|
F32 textureAspect = 1.0f;
|
||||||
if( mMatInst && mMatInst->isValid())
|
if( mMaterialInst && mMaterialInst->isValid())
|
||||||
{
|
{
|
||||||
Material* mat = dynamic_cast<Material*>(mMatInst->getMaterial());
|
Material* mat = dynamic_cast<Material*>(mMaterialInst->getMaterial());
|
||||||
if(mat)
|
if(mat)
|
||||||
{
|
{
|
||||||
GFXTexHandle tex;
|
GFXTexHandle tex;
|
||||||
if (!mat->mDiffuseMapFilename[0].isEmpty())
|
if (mat->getDiffuseMapResource(0))
|
||||||
tex = GFXTexHandle(mat->mDiffuseMapFilename[0], &GFXStaticTextureSRGBProfile, "GroundCover texture aspect ratio check");
|
tex = mat->getDiffuseMapResource(0);
|
||||||
else if (!mat->mDiffuseMapAsset[0].isNull())
|
else if (mat->getDiffuseMap(0) != StringTable->EmptyString())
|
||||||
tex = mat->mDiffuseMapAsset[0]->getImage(GFXStaticTextureSRGBProfile);
|
tex = GFXTexHandle(mat->getDiffuseMap(0), &GFXStaticTextureSRGBProfile, "GroundCover texture aspect ratio check");
|
||||||
|
|
||||||
if(tex.isValid())
|
if(tex.isValid())
|
||||||
{
|
{
|
||||||
|
|
@ -1580,7 +1559,7 @@ void GroundCover::_updateCoverGrid( const Frustum &culler )
|
||||||
void GroundCover::prepRenderImage( SceneRenderState *state )
|
void GroundCover::prepRenderImage( SceneRenderState *state )
|
||||||
{
|
{
|
||||||
// Reset stats each time we hit the diffuse pass.
|
// Reset stats each time we hit the diffuse pass.
|
||||||
if (mMatInst == nullptr)
|
if (mMaterialInst == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if( state->isDiffusePass() )
|
if( state->isDiffusePass() )
|
||||||
|
|
@ -1617,7 +1596,7 @@ void GroundCover::prepRenderImage( SceneRenderState *state )
|
||||||
|
|
||||||
// Render billboards but not into shadow passes.
|
// Render billboards but not into shadow passes.
|
||||||
|
|
||||||
if ( !state->isShadowPass() && mMatInst->isValid() && !mDebugNoBillboards )
|
if ( !state->isShadowPass() && mMaterialInst->isValid() && !mDebugNoBillboards )
|
||||||
{
|
{
|
||||||
PROFILE_SCOPE( GroundCover_RenderBillboards );
|
PROFILE_SCOPE( GroundCover_RenderBillboards );
|
||||||
|
|
||||||
|
|
@ -1692,7 +1671,7 @@ void GroundCover::prepRenderImage( SceneRenderState *state )
|
||||||
if ( mCuller.isCulled( cell->getRenderBounds() ) )
|
if ( mCuller.isCulled( cell->getRenderBounds() ) )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
cell->renderBillboards( state, mMatInst, &mPrimBuffer );
|
cell->renderBillboards( state, mMaterialInst, &mPrimBuffer );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@
|
||||||
#include "shaderGen/shaderFeature.h"
|
#include "shaderGen/shaderFeature.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "T3D/assets/MaterialAsset.h"
|
#include "T3D/assets/ShapeAsset.h"
|
||||||
|
|
||||||
class TerrainBlock;
|
class TerrainBlock;
|
||||||
class GroundCoverCell;
|
class GroundCoverCell;
|
||||||
|
|
@ -266,9 +266,10 @@ protected:
|
||||||
static F32 smDensityScale;
|
static F32 smDensityScale;
|
||||||
static F32 smFadeScale;
|
static F32 smFadeScale;
|
||||||
|
|
||||||
DECLARE_NET_MATERIALASSET(GroundCover, Material, InitialUpdateMask);
|
BaseMatInstance* mMaterialInst;
|
||||||
Material* mMaterial;
|
|
||||||
BaseMatInstance *mMatInst;
|
DECLARE_MATERIALASSET(GroundCover, Material);
|
||||||
|
DECLARE_MATERIALASSET_NET_SETGET(GroundCover, Material, InitialUpdateMask);
|
||||||
|
|
||||||
GroundCoverShaderConstData mShaderConstData;
|
GroundCoverShaderConstData mShaderConstData;
|
||||||
|
|
||||||
|
|
@ -339,7 +340,8 @@ protected:
|
||||||
RectF mBillboardRects[MAX_COVERTYPES];
|
RectF mBillboardRects[MAX_COVERTYPES];
|
||||||
|
|
||||||
/// The cover shape filenames.
|
/// The cover shape filenames.
|
||||||
StringTableEntry mShapeFilenames[MAX_COVERTYPES];
|
DECLARE_SHAPEASSET_ARRAY(GroundCover, Shape, MAX_COVERTYPES);
|
||||||
|
DECLARE_SHAPEASSET_ARRAY_NET_SETGET(GroundCover, Shape, -1);
|
||||||
|
|
||||||
/// The cover shape instances.
|
/// The cover shape instances.
|
||||||
TSShapeInstance* mShapeInstances[MAX_COVERTYPES];
|
TSShapeInstance* mShapeInstances[MAX_COVERTYPES];
|
||||||
|
|
|
||||||
|
|
@ -121,10 +121,10 @@ ParticleData::ParticleData()
|
||||||
animTexTiling.set(0,0); // tiling dimensions
|
animTexTiling.set(0,0); // tiling dimensions
|
||||||
animTexFramesString = NULL; // string of animation frame indices
|
animTexFramesString = NULL; // string of animation frame indices
|
||||||
animTexUVs = NULL; // array of tile vertex UVs
|
animTexUVs = NULL; // array of tile vertex UVs
|
||||||
textureName = NULL; // texture filename
|
|
||||||
textureHandle = NULL; // loaded texture handle
|
INIT_IMAGEASSET(Texture);
|
||||||
textureExtName = NULL;
|
INIT_IMAGEASSET(TextureExt);
|
||||||
textureExtHandle = NULL;
|
|
||||||
constrain_pos = false;
|
constrain_pos = false;
|
||||||
start_angle = 0.0f;
|
start_angle = 0.0f;
|
||||||
angle_variance = 0.0f;
|
angle_variance = 0.0f;
|
||||||
|
|
@ -203,11 +203,13 @@ void ParticleData::initPersistFields()
|
||||||
"animTexFrames = \"0-16 20 19 18 17 31-21\";\n"
|
"animTexFrames = \"0-16 20 19 18 17 31-21\";\n"
|
||||||
"@endtsexample\n" );
|
"@endtsexample\n" );
|
||||||
|
|
||||||
addField( "textureName", TYPEID< StringTableEntry >(), Offset(textureName, ParticleData),
|
addProtectedField( "textureName", TYPEID< StringTableEntry >(), Offset(mTextureName, ParticleData), _setTextureData, defaultProtectedGetFn,
|
||||||
"Texture file to use for this particle." );
|
"Texture file to use for this particle.", AbstractClassRep::FIELD_HideInInspectors );
|
||||||
addField( "animTexName", TYPEID< StringTableEntry >(), Offset(textureName, ParticleData),
|
addField( "animTexName", TYPEID< StringTableEntry >(), Offset(mTextureName, ParticleData),
|
||||||
"@brief Texture file to use for this particle if animateTexture is true.\n\n"
|
"@brief Texture file to use for this particle if animateTexture is true.\n\n"
|
||||||
"Deprecated. Use textureName instead." );
|
"Deprecated. Use textureName instead.", AbstractClassRep::FIELD_HideInInspectors);
|
||||||
|
INITPERSISTFIELD_IMAGEASSET(Texture, ParticleData, "Texture to use for this particle.");
|
||||||
|
|
||||||
|
|
||||||
// Interpolation variables
|
// Interpolation variables
|
||||||
addField( "colors", TYPEID< LinearColorF >(), Offset(colors, ParticleData), PDC_NUM_KEYS,
|
addField( "colors", TYPEID< LinearColorF >(), Offset(colors, ParticleData), PDC_NUM_KEYS,
|
||||||
|
|
@ -224,8 +226,9 @@ void ParticleData::initPersistFields()
|
||||||
"@brief Time keys used with the colors and sizes keyframes.\n\n"
|
"@brief Time keys used with the colors and sizes keyframes.\n\n"
|
||||||
"Values are from 0.0 (particle creation) to 1.0 (end of lifespace)." );
|
"Values are from 0.0 (particle creation) to 1.0 (end of lifespace)." );
|
||||||
|
|
||||||
addGroup("AFX");
|
addGroup("AFX");
|
||||||
addField("textureExtName", TypeFilename, Offset(textureExtName, ParticleData));
|
addProtectedField("textureExtName", TypeFilename, Offset(mTextureExtName, ParticleData), _setTextureExtData, &defaultProtectedGetFn, "", AbstractClassRep::FIELD_HideInInspectors);
|
||||||
|
INITPERSISTFIELD_IMAGEASSET(TextureExt, ParticleData, "");
|
||||||
addField("constrainPos", TypeBool, Offset(constrain_pos, ParticleData));
|
addField("constrainPos", TypeBool, Offset(constrain_pos, ParticleData));
|
||||||
addField("angle", TypeF32, Offset(start_angle, ParticleData));
|
addField("angle", TypeF32, Offset(start_angle, ParticleData));
|
||||||
addField("angleVariance", TypeF32, Offset(angle_variance, ParticleData));
|
addField("angleVariance", TypeF32, Offset(angle_variance, ParticleData));
|
||||||
|
|
@ -290,8 +293,8 @@ void ParticleData::packData(BitStream* stream)
|
||||||
stream->writeFloat( times[i], 8);
|
stream->writeFloat( times[i], 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stream->writeFlag(textureName && textureName[0]))
|
//PACKDATA_IMAGEASSET(Texture);
|
||||||
stream->writeString(textureName);
|
|
||||||
for (i = 0; i < 4; i++)
|
for (i = 0; i < 4; i++)
|
||||||
mathWrite(*stream, texCoords[i]);
|
mathWrite(*stream, texCoords[i]);
|
||||||
if (stream->writeFlag(animateTexture))
|
if (stream->writeFlag(animateTexture))
|
||||||
|
|
@ -303,8 +306,9 @@ void ParticleData::packData(BitStream* stream)
|
||||||
mathWrite(*stream, animTexTiling);
|
mathWrite(*stream, animTexTiling);
|
||||||
stream->writeInt(framesPerSec, 8);
|
stream->writeInt(framesPerSec, 8);
|
||||||
}
|
}
|
||||||
if (stream->writeFlag(textureExtName && textureExtName[0]))
|
|
||||||
stream->writeString(textureExtName);
|
//PACKDATA_IMAGEASSET(TextureExt);
|
||||||
|
|
||||||
stream->writeFlag(constrain_pos);
|
stream->writeFlag(constrain_pos);
|
||||||
stream->writeFloat(start_angle/360.0f, 11);
|
stream->writeFloat(start_angle/360.0f, 11);
|
||||||
stream->writeFloat(angle_variance/180.0f, 10);
|
stream->writeFloat(angle_variance/180.0f, 10);
|
||||||
|
|
@ -373,7 +377,9 @@ void ParticleData::unpackData(BitStream* stream)
|
||||||
sizes[i] = stream->readFloat(16) * MaxParticleSize;
|
sizes[i] = stream->readFloat(16) * MaxParticleSize;
|
||||||
times[i] = stream->readFloat(8);
|
times[i] = stream->readFloat(8);
|
||||||
}
|
}
|
||||||
textureName = (stream->readFlag()) ? stream->readSTString() : 0;
|
|
||||||
|
//UNPACKDATA_IMAGEASSET(Texture);
|
||||||
|
|
||||||
for (i = 0; i < 4; i++)
|
for (i = 0; i < 4; i++)
|
||||||
mathRead(*stream, &texCoords[i]);
|
mathRead(*stream, &texCoords[i]);
|
||||||
|
|
||||||
|
|
@ -384,7 +390,9 @@ void ParticleData::unpackData(BitStream* stream)
|
||||||
mathRead(*stream, &animTexTiling);
|
mathRead(*stream, &animTexTiling);
|
||||||
framesPerSec = stream->readInt(8);
|
framesPerSec = stream->readInt(8);
|
||||||
}
|
}
|
||||||
textureExtName = (stream->readFlag()) ? stream->readSTString() : 0;
|
|
||||||
|
//UNPACKDATA_IMAGEASSET(Texture);
|
||||||
|
|
||||||
constrain_pos = stream->readFlag();
|
constrain_pos = stream->readFlag();
|
||||||
start_angle = 360.0f*stream->readFloat(11);
|
start_angle = 360.0f*stream->readFloat(11);
|
||||||
angle_variance = 180.0f*stream->readFloat(10);
|
angle_variance = 180.0f*stream->readFloat(10);
|
||||||
|
|
@ -556,27 +564,6 @@ bool ParticleData::preload(bool server, String &errorStr)
|
||||||
bool error = false;
|
bool error = false;
|
||||||
if(!server)
|
if(!server)
|
||||||
{
|
{
|
||||||
// Here we attempt to load the particle's texture if specified. An undefined
|
|
||||||
// texture is *not* an error since the emitter may provide one.
|
|
||||||
if (textureName && textureName[0])
|
|
||||||
{
|
|
||||||
textureHandle = GFXTexHandle(textureName, &GFXStaticTextureSRGBProfile, avar("%s() - textureHandle (line %d)", __FUNCTION__, __LINE__));
|
|
||||||
if (!textureHandle)
|
|
||||||
{
|
|
||||||
errorStr = String::ToString("Missing particle texture: %s", textureName);
|
|
||||||
error = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (textureExtName && textureExtName[0])
|
|
||||||
{
|
|
||||||
textureExtHandle = GFXTexHandle(textureExtName, &GFXStaticTextureSRGBProfile, avar("%s() - textureExtHandle (line %d)", __FUNCTION__, __LINE__));
|
|
||||||
if (!textureExtHandle)
|
|
||||||
{
|
|
||||||
errorStr = String::ToString("Missing particle texture: %s", textureName);
|
|
||||||
error = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (animateTexture)
|
if (animateTexture)
|
||||||
{
|
{
|
||||||
// Here we parse animTexFramesString into byte-size frame numbers in animTexFrames.
|
// Here we parse animTexFramesString into byte-size frame numbers in animTexFrames.
|
||||||
|
|
@ -698,15 +685,14 @@ void ParticleData::initializeParticle(Particle* init, const Point3F& inheritVelo
|
||||||
bool ParticleData::reload(char errorBuffer[256])
|
bool ParticleData::reload(char errorBuffer[256])
|
||||||
{
|
{
|
||||||
bool error = false;
|
bool error = false;
|
||||||
if (textureName && textureName[0])
|
|
||||||
|
StringTableEntry particleTex = getTexture();
|
||||||
|
|
||||||
|
if (!_setTexture(particleTex))
|
||||||
{
|
{
|
||||||
textureHandle = GFXTexHandle(textureName, &GFXStaticTextureSRGBProfile, avar("%s() - textureHandle (line %d)", __FUNCTION__, __LINE__));
|
dSprintf(errorBuffer, 256, "Missing particle texture: %s", particleTex);
|
||||||
if (!textureHandle)
|
}
|
||||||
{
|
|
||||||
dSprintf(errorBuffer, 256, "Missing particle texture: %s", textureName);
|
|
||||||
error = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*
|
/*
|
||||||
numFrames = 0;
|
numFrames = 0;
|
||||||
for( S32 i=0; i<PDC_MAX_TEX; i++ )
|
for( S32 i=0; i<PDC_MAX_TEX; i++ )
|
||||||
|
|
@ -776,12 +762,14 @@ ParticleData::ParticleData(const ParticleData& other, bool temp_clone) : SimData
|
||||||
animTexTiling = other.animTexTiling;
|
animTexTiling = other.animTexTiling;
|
||||||
animTexFramesString = other.animTexFramesString;
|
animTexFramesString = other.animTexFramesString;
|
||||||
animTexFrames = other.animTexFrames; // -- parsed from animTexFramesString
|
animTexFrames = other.animTexFrames; // -- parsed from animTexFramesString
|
||||||
textureName = other.textureName;
|
|
||||||
textureHandle = other.textureHandle;
|
CLONE_IMAGEASSET(Texture);
|
||||||
|
|
||||||
spinBias = other.spinBias;
|
spinBias = other.spinBias;
|
||||||
randomizeSpinDir = other.randomizeSpinDir;
|
randomizeSpinDir = other.randomizeSpinDir;
|
||||||
textureExtName = other.textureExtName;
|
|
||||||
textureExtHandle = other.textureExtHandle;
|
CLONE_IMAGEASSET(TextureExt);
|
||||||
|
|
||||||
constrain_pos = other.constrain_pos;
|
constrain_pos = other.constrain_pos;
|
||||||
start_angle = other.start_angle;
|
start_angle = other.start_angle;
|
||||||
angle_variance = other.angle_variance;
|
angle_variance = other.angle_variance;
|
||||||
|
|
@ -815,3 +803,5 @@ void ParticleData::onPerformSubstitutions()
|
||||||
char errorBuffer[256];
|
char errorBuffer[256];
|
||||||
reload(errorBuffer);
|
reload(errorBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEF_IMAGEASSET_BINDS(ParticleData, Texture);
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,8 @@
|
||||||
#include "gfx/gfxTextureHandle.h"
|
#include "gfx/gfxTextureHandle.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "T3D/assets/ImageAsset.h"
|
||||||
|
|
||||||
#define MaxParticleSize 50.0
|
#define MaxParticleSize 50.0
|
||||||
|
|
||||||
struct Particle;
|
struct Particle;
|
||||||
|
|
@ -83,13 +85,16 @@ class ParticleData : public SimDataBlock
|
||||||
Point2I animTexTiling;
|
Point2I animTexTiling;
|
||||||
StringTableEntry animTexFramesString;
|
StringTableEntry animTexFramesString;
|
||||||
Vector<U8> animTexFrames;
|
Vector<U8> animTexFrames;
|
||||||
StringTableEntry textureName;
|
|
||||||
GFXTexHandle textureHandle;
|
|
||||||
|
|
||||||
static bool protectedSetSizes( void *object, const char *index, const char *data );
|
DECLARE_IMAGEASSET(ParticleData, Texture, onImageChanged, GFXStaticTextureSRGBProfile);
|
||||||
static bool protectedSetTimes( void *object, const char *index, const char *data );
|
DECLARE_IMAGEASSET_SETGET(ParticleData, Texture);
|
||||||
|
|
||||||
public:
|
static bool protectedSetSizes(void* object, const char* index, const char* data);
|
||||||
|
static bool protectedSetTimes(void* object, const char* index, const char* data);
|
||||||
|
|
||||||
|
void onImageChanged() {}
|
||||||
|
|
||||||
|
public:
|
||||||
ParticleData();
|
ParticleData();
|
||||||
~ParticleData();
|
~ParticleData();
|
||||||
|
|
||||||
|
|
@ -111,9 +116,10 @@ class ParticleData : public SimDataBlock
|
||||||
protected:
|
protected:
|
||||||
F32 spinBias;
|
F32 spinBias;
|
||||||
bool randomizeSpinDir;
|
bool randomizeSpinDir;
|
||||||
StringTableEntry textureExtName;
|
|
||||||
public:
|
public:
|
||||||
GFXTexHandle textureExtHandle;
|
DECLARE_IMAGEASSET(ParticleData, TextureExt, onImageChanged, GFXStaticTextureSRGBProfile);
|
||||||
|
DECLARE_IMAGEASSET_SETGET(ParticleData, TextureExt);
|
||||||
|
|
||||||
bool constrain_pos;
|
bool constrain_pos;
|
||||||
F32 start_angle;
|
F32 start_angle;
|
||||||
F32 angle_variance;
|
F32 angle_variance;
|
||||||
|
|
|
||||||
|
|
@ -741,11 +741,11 @@ bool ParticleEmitterData::preload(bool server, String &errorStr)
|
||||||
// otherwise, check that all particles refer to the same texture
|
// otherwise, check that all particles refer to the same texture
|
||||||
else if (particleDataBlocks.size() > 1)
|
else if (particleDataBlocks.size() > 1)
|
||||||
{
|
{
|
||||||
StringTableEntry txr_name = particleDataBlocks[0]->textureName;
|
StringTableEntry txr_name = particleDataBlocks[0]->getTexture();
|
||||||
for (S32 i = 1; i < particleDataBlocks.size(); i++)
|
for (S32 i = 1; i < particleDataBlocks.size(); i++)
|
||||||
{
|
{
|
||||||
// warn if particle textures are inconsistent
|
// warn if particle textures are inconsistent
|
||||||
if (particleDataBlocks[i]->textureName != txr_name)
|
if (particleDataBlocks[i]->getTexture() != txr_name)
|
||||||
{
|
{
|
||||||
Con::warnf(ConsoleLogEntry::General, "ParticleEmitterData(%s) particles reference different textures.", getName());
|
Con::warnf(ConsoleLogEntry::General, "ParticleEmitterData(%s) particles reference different textures.", getName());
|
||||||
break;
|
break;
|
||||||
|
|
@ -1225,7 +1225,7 @@ void ParticleEmitter::prepRenderImage(SceneRenderState* state)
|
||||||
if (mDataBlock->textureHandle)
|
if (mDataBlock->textureHandle)
|
||||||
ri->diffuseTex = &*(mDataBlock->textureHandle);
|
ri->diffuseTex = &*(mDataBlock->textureHandle);
|
||||||
else
|
else
|
||||||
ri->diffuseTex = &*(part_list_head.next->dataBlock->textureHandle);
|
ri->diffuseTex = &*(part_list_head.next->dataBlock->getTextureResource());
|
||||||
|
|
||||||
ri->softnessDistance = mDataBlock->softnessDistance;
|
ri->softnessDistance = mDataBlock->softnessDistance;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -129,9 +129,12 @@ PrecipitationData::PrecipitationData()
|
||||||
{
|
{
|
||||||
soundProfile = NULL;
|
soundProfile = NULL;
|
||||||
|
|
||||||
mDropName = StringTable->EmptyString();
|
INIT_IMAGEASSET(Drop);
|
||||||
|
|
||||||
mDropShaderName = StringTable->EmptyString();
|
mDropShaderName = StringTable->EmptyString();
|
||||||
mSplashName = StringTable->EmptyString();
|
|
||||||
|
INIT_IMAGEASSET(Splash);
|
||||||
|
|
||||||
mSplashShaderName = StringTable->EmptyString();
|
mSplashShaderName = StringTable->EmptyString();
|
||||||
|
|
||||||
mDropsPerSide = 4;
|
mDropsPerSide = 4;
|
||||||
|
|
@ -142,18 +145,32 @@ void PrecipitationData::initPersistFields()
|
||||||
{
|
{
|
||||||
addField( "soundProfile", TYPEID< SFXTrack >(), Offset(soundProfile, PrecipitationData),
|
addField( "soundProfile", TYPEID< SFXTrack >(), Offset(soundProfile, PrecipitationData),
|
||||||
"Looping SFXProfile effect to play while Precipitation is active." );
|
"Looping SFXProfile effect to play while Precipitation is active." );
|
||||||
addField( "dropTexture", TypeFilename, Offset(mDropName, PrecipitationData),
|
|
||||||
|
addProtectedField( "dropTexture", TypeFilename, Offset(mDropName, PrecipitationData), &_setDropData, &defaultProtectedGetFn,
|
||||||
"@brief Texture filename for drop particles.\n\n"
|
"@brief Texture filename for drop particles.\n\n"
|
||||||
"The drop texture can contain several different drop sub-textures "
|
"The drop texture can contain several different drop sub-textures "
|
||||||
"arranged in a grid. There must be the same number of rows as columns. A "
|
"arranged in a grid. There must be the same number of rows as columns. A "
|
||||||
"random frame will be chosen for each drop." );
|
"random frame will be chosen for each drop.", AbstractClassRep::FIELD_HideInInspectors );
|
||||||
|
|
||||||
|
INITPERSISTFIELD_IMAGEASSET(Drop, PrecipitationData, "@brief Texture for drop particles.\n\n"
|
||||||
|
"The drop texture can contain several different drop sub-textures "
|
||||||
|
"arranged in a grid. There must be the same number of rows as columns. A "
|
||||||
|
"random frame will be chosen for each drop.");
|
||||||
|
|
||||||
addField( "dropShader", TypeString, Offset(mDropShaderName, PrecipitationData),
|
addField( "dropShader", TypeString, Offset(mDropShaderName, PrecipitationData),
|
||||||
"The name of the shader used for raindrops." );
|
"The name of the shader used for raindrops." );
|
||||||
addField( "splashTexture", TypeFilename, Offset(mSplashName, PrecipitationData),
|
|
||||||
|
addProtectedField("splashTexture", TypeFilename, Offset(mSplashName, PrecipitationData), &_setSplashData, &defaultProtectedGetFn,
|
||||||
"@brief Texture filename for splash particles.\n\n"
|
"@brief Texture filename for splash particles.\n\n"
|
||||||
"The splash texture can contain several different splash sub-textures "
|
"The splash texture can contain several different splash sub-textures "
|
||||||
"arranged in a grid. There must be the same number of rows as columns. A "
|
"arranged in a grid. There must be the same number of rows as columns. A "
|
||||||
"random frame will be chosen for each splash." );
|
"random frame will be chosen for each splash.", AbstractClassRep::FIELD_HideInInspectors);
|
||||||
|
|
||||||
|
INITPERSISTFIELD_IMAGEASSET(Splash, PrecipitationData, "@brief Texture for splash particles.\n\n"
|
||||||
|
"The splash texture can contain several different splash sub-textures "
|
||||||
|
"arranged in a grid. There must be the same number of rows as columns. A "
|
||||||
|
"random frame will be chosen for each splash.");
|
||||||
|
|
||||||
addField( "splashShader", TypeString, Offset(mSplashShaderName, PrecipitationData),
|
addField( "splashShader", TypeString, Offset(mSplashShaderName, PrecipitationData),
|
||||||
"The name of the shader used for splashes." );
|
"The name of the shader used for splashes." );
|
||||||
addField( "dropsPerSide", TypeS32, Offset(mDropsPerSide, PrecipitationData),
|
addField( "dropsPerSide", TypeS32, Offset(mDropsPerSide, PrecipitationData),
|
||||||
|
|
@ -185,9 +202,12 @@ void PrecipitationData::packData(BitStream* stream)
|
||||||
|
|
||||||
sfxWrite( stream, soundProfile );
|
sfxWrite( stream, soundProfile );
|
||||||
|
|
||||||
stream->writeString(mDropName);
|
PACKDATA_IMAGEASSET(Drop);
|
||||||
|
|
||||||
stream->writeString(mDropShaderName);
|
stream->writeString(mDropShaderName);
|
||||||
stream->writeString(mSplashName);
|
|
||||||
|
PACKDATA_IMAGEASSET(Splash);
|
||||||
|
|
||||||
stream->writeString(mSplashShaderName);
|
stream->writeString(mSplashShaderName);
|
||||||
stream->write(mDropsPerSide);
|
stream->write(mDropsPerSide);
|
||||||
stream->write(mSplashesPerSide);
|
stream->write(mSplashesPerSide);
|
||||||
|
|
@ -199,9 +219,12 @@ void PrecipitationData::unpackData(BitStream* stream)
|
||||||
|
|
||||||
sfxRead( stream, &soundProfile );
|
sfxRead( stream, &soundProfile );
|
||||||
|
|
||||||
mDropName = stream->readSTString();
|
UNPACKDATA_IMAGEASSET(Drop);
|
||||||
|
|
||||||
mDropShaderName = stream->readSTString();
|
mDropShaderName = stream->readSTString();
|
||||||
mSplashName = stream->readSTString();
|
|
||||||
|
UNPACKDATA_IMAGEASSET(Splash);
|
||||||
|
|
||||||
mSplashShaderName = stream->readSTString();
|
mSplashShaderName = stream->readSTString();
|
||||||
stream->read(&mDropsPerSide);
|
stream->read(&mDropsPerSide);
|
||||||
stream->read(&mSplashesPerSide);
|
stream->read(&mSplashesPerSide);
|
||||||
|
|
@ -604,8 +627,10 @@ void Precipitation::initMaterials()
|
||||||
mDropShader = NULL;
|
mDropShader = NULL;
|
||||||
mSplashShader = NULL;
|
mSplashShader = NULL;
|
||||||
|
|
||||||
if( dStrlen(pd->mDropName) > 0 && !mDropHandle.set(pd->mDropName, &GFXStaticTextureSRGBProfile, avar("%s() - mDropHandle (line %d)", __FUNCTION__, __LINE__)) )
|
if(pd->mDrop.isNull())
|
||||||
Con::warnf("Precipitation::initMaterials - failed to locate texture '%s'!", pd->mDropName);
|
Con::warnf("Precipitation::initMaterials - failed to locate texture '%s'!", pd->getDrop());
|
||||||
|
else
|
||||||
|
mDropHandle = pd->mDrop;
|
||||||
|
|
||||||
if ( dStrlen(pd->mDropShaderName) > 0 )
|
if ( dStrlen(pd->mDropShaderName) > 0 )
|
||||||
{
|
{
|
||||||
|
|
@ -625,8 +650,10 @@ void Precipitation::initMaterials()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( dStrlen(pd->mSplashName) > 0 && !mSplashHandle.set(pd->mSplashName, &GFXStaticTextureSRGBProfile, avar("%s() - mSplashHandle (line %d)", __FUNCTION__, __LINE__)) )
|
if (pd->mSplash.isNull())
|
||||||
Con::warnf("Precipitation::initMaterials - failed to locate texture '%s'!", pd->mSplashName);
|
Con::warnf("Precipitation::initMaterials - failed to locate texture '%s'!", pd->getSplash());
|
||||||
|
else
|
||||||
|
mSplashHandle = pd->mSplash;
|
||||||
|
|
||||||
if ( dStrlen(pd->mSplashShaderName) > 0 )
|
if ( dStrlen(pd->mSplashShaderName) > 0 )
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,8 @@
|
||||||
#include "renderInstance/renderPassManager.h"
|
#include "renderInstance/renderPassManager.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "T3D/assets/ImageAsset.h"
|
||||||
|
|
||||||
class SFXTrack;
|
class SFXTrack;
|
||||||
class SFXSource;
|
class SFXSource;
|
||||||
|
|
||||||
|
|
@ -45,9 +47,14 @@ class PrecipitationData : public GameBaseData
|
||||||
public:
|
public:
|
||||||
SFXTrack* soundProfile;
|
SFXTrack* soundProfile;
|
||||||
|
|
||||||
StringTableEntry mDropName; ///< Texture filename for drop particles
|
DECLARE_IMAGEASSET(PrecipitationData, Drop, onDropChanged, GFXStaticTextureSRGBProfile); ///< Texture for drop particles
|
||||||
|
DECLARE_IMAGEASSET_SETGET(PrecipitationData, Drop);
|
||||||
|
|
||||||
StringTableEntry mDropShaderName; ///< The name of the shader used for raindrops
|
StringTableEntry mDropShaderName; ///< The name of the shader used for raindrops
|
||||||
StringTableEntry mSplashName; ///< Texture filename for splash particles
|
|
||||||
|
DECLARE_IMAGEASSET(PrecipitationData, Splash, onSplashChanged, GFXStaticTextureSRGBProfile); ///< Texture for splash particles
|
||||||
|
DECLARE_IMAGEASSET_SETGET(PrecipitationData, Splash);
|
||||||
|
|
||||||
StringTableEntry mSplashShaderName; ///< The name of the shader used for raindrops
|
StringTableEntry mSplashShaderName; ///< The name of the shader used for raindrops
|
||||||
|
|
||||||
S32 mDropsPerSide; ///< How many drops are on a side of the raindrop texture.
|
S32 mDropsPerSide; ///< How many drops are on a side of the raindrop texture.
|
||||||
|
|
@ -59,6 +66,9 @@ class PrecipitationData : public GameBaseData
|
||||||
static void initPersistFields();
|
static void initPersistFields();
|
||||||
virtual void packData(BitStream* stream);
|
virtual void packData(BitStream* stream);
|
||||||
virtual void unpackData(BitStream* stream);
|
virtual void unpackData(BitStream* stream);
|
||||||
|
|
||||||
|
void onDropChanged() {}
|
||||||
|
void onSplashChanged() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Raindrop
|
struct Raindrop
|
||||||
|
|
|
||||||
|
|
@ -93,9 +93,10 @@ SplashData::SplashData()
|
||||||
explosion = NULL;
|
explosion = NULL;
|
||||||
explosionId = 0;
|
explosionId = 0;
|
||||||
|
|
||||||
dMemset( textureName, 0, sizeof( textureName ) );
|
|
||||||
|
|
||||||
U32 i;
|
U32 i;
|
||||||
|
for (i = 0; i < NUM_TEX; i++)
|
||||||
|
INIT_IMAGEASSET_ARRAY(Texture, i);
|
||||||
|
|
||||||
for( i=0; i<NUM_TIME_KEYS; i++ )
|
for( i=0; i<NUM_TIME_KEYS; i++ )
|
||||||
times[i] = 1.0;
|
times[i] = 1.0;
|
||||||
|
|
||||||
|
|
@ -125,7 +126,9 @@ SplashData::SplashData()
|
||||||
addField("acceleration", TypeF32, Offset(acceleration, SplashData), "Constant acceleration value to place upon the splash effect.\n");
|
addField("acceleration", TypeF32, Offset(acceleration, SplashData), "Constant acceleration value to place upon the splash effect.\n");
|
||||||
addField("times", TypeF32, Offset(times, SplashData), NUM_TIME_KEYS, "Times to transition through the splash effect. Up to 4 allowed. Values are 0.0 - 1.0, and corrispond to the life of the particle where 0 is first created and 1 is end of lifespace.\n" );
|
addField("times", TypeF32, Offset(times, SplashData), NUM_TIME_KEYS, "Times to transition through the splash effect. Up to 4 allowed. Values are 0.0 - 1.0, and corrispond to the life of the particle where 0 is first created and 1 is end of lifespace.\n" );
|
||||||
addField("colors", TypeColorF, Offset(colors, SplashData), NUM_TIME_KEYS, "Color values to set the splash effect, rgba. Up to 4 allowed. Will transition through colors based on values set in the times value. Example: colors[0] = \"0.6 1.0 1.0 0.5\".\n" );
|
addField("colors", TypeColorF, Offset(colors, SplashData), NUM_TIME_KEYS, "Color values to set the splash effect, rgba. Up to 4 allowed. Will transition through colors based on values set in the times value. Example: colors[0] = \"0.6 1.0 1.0 0.5\".\n" );
|
||||||
addField("texture", TypeFilename, Offset(textureName, SplashData), NUM_TEX, "Imagemap file to use as the texture for the splash effect.\n");
|
|
||||||
|
INITPERSISTFIELD_IMAGEASSET_ARRAY(Texture, NUM_TEX, SplashData, "Image to use as the texture for the splash effect.\n");
|
||||||
|
|
||||||
addField("texWrap", TypeF32, Offset(texWrap, SplashData), "Amount to wrap the texture around the splash ring, 0.0f - 1.0f.\n");
|
addField("texWrap", TypeF32, Offset(texWrap, SplashData), "Amount to wrap the texture around the splash ring, 0.0f - 1.0f.\n");
|
||||||
addField("texFactor", TypeF32, Offset(texFactor, SplashData), "Factor in which to apply the texture to the splash ring, 0.0f - 1.0f.\n");
|
addField("texFactor", TypeF32, Offset(texFactor, SplashData), "Factor in which to apply the texture to the splash ring, 0.0f - 1.0f.\n");
|
||||||
addField("ejectionFreq", TypeF32, Offset(ejectionFreq, SplashData), "Frequency in which to emit splash rings.\n");
|
addField("ejectionFreq", TypeF32, Offset(ejectionFreq, SplashData), "Frequency in which to emit splash rings.\n");
|
||||||
|
|
@ -198,7 +201,7 @@ void SplashData::packData(BitStream* stream)
|
||||||
|
|
||||||
for( i=0; i<NUM_TEX; i++ )
|
for( i=0; i<NUM_TEX; i++ )
|
||||||
{
|
{
|
||||||
stream->writeString(textureName[i]);
|
PACKDATA_IMAGEASSET_ARRAY(Texture, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -252,7 +255,7 @@ void SplashData::unpackData(BitStream* stream)
|
||||||
|
|
||||||
for( i=0; i<NUM_TEX; i++ )
|
for( i=0; i<NUM_TEX; i++ )
|
||||||
{
|
{
|
||||||
textureName[i] = stream->readSTString();
|
UNPACKDATA_IMAGEASSET_ARRAY(Texture, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -280,9 +283,9 @@ bool SplashData::preload(bool server, String &errorStr)
|
||||||
|
|
||||||
for( i=0; i<NUM_TEX; i++ )
|
for( i=0; i<NUM_TEX; i++ )
|
||||||
{
|
{
|
||||||
if (textureName[i] && textureName[i][0])
|
if (mTexture[i].isNull())
|
||||||
{
|
{
|
||||||
textureHandle[i] = GFXTexHandle(textureName[i], &GFXStaticTextureSRGBProfile, avar("%s() - textureHandle[%d] (line %d)", __FUNCTION__, i, __LINE__) );
|
_setTexture(getTexture(i), i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,8 @@
|
||||||
|
|
||||||
#include "gfx/gfxTextureHandle.h"
|
#include "gfx/gfxTextureHandle.h"
|
||||||
|
|
||||||
|
#include "T3D/assets/ImageAsset.h"
|
||||||
|
|
||||||
class ParticleEmitter;
|
class ParticleEmitter;
|
||||||
class ParticleEmitterData;
|
class ParticleEmitterData;
|
||||||
class AudioProfile;
|
class AudioProfile;
|
||||||
|
|
@ -116,8 +118,8 @@ public:
|
||||||
F32 times[ NUM_TIME_KEYS ];
|
F32 times[ NUM_TIME_KEYS ];
|
||||||
LinearColorF colors[ NUM_TIME_KEYS ];
|
LinearColorF colors[ NUM_TIME_KEYS ];
|
||||||
|
|
||||||
StringTableEntry textureName[NUM_TEX];
|
DECLARE_IMAGEASSET_ARRAY(SplashData, Texture, GFXStaticTextureSRGBProfile, NUM_TEX);
|
||||||
GFXTexHandle textureHandle[NUM_TEX];
|
DECLARE_IMAGEASSET_ARRAY_SETGET(SplashData, Texture)
|
||||||
|
|
||||||
ExplosionData* explosion;
|
ExplosionData* explosion;
|
||||||
S32 explosionId;
|
S32 explosionId;
|
||||||
|
|
|
||||||
|
|
@ -371,7 +371,6 @@ void GameConnection::onConnectionEstablished(bool isInitiator)
|
||||||
setTranslatesStrings(true);
|
setTranslatesStrings(true);
|
||||||
Sim::getClientGroup()->addObject(this);
|
Sim::getClientGroup()->addObject(this);
|
||||||
mMoveList->init();
|
mMoveList->init();
|
||||||
|
|
||||||
const char *argv[MaxConnectArgs + 2];
|
const char *argv[MaxConnectArgs + 2];
|
||||||
argv[0] = "onConnect";
|
argv[0] = "onConnect";
|
||||||
argv[1] = NULL; // Filled in later
|
argv[1] = NULL; // Filled in later
|
||||||
|
|
@ -646,6 +645,7 @@ void GameConnection::setCameraObject(GameBase *obj)
|
||||||
smFovUpdate.trigger(fov);
|
smFovUpdate.trigger(fov);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GameBase* GameConnection::getCameraObject()
|
GameBase* GameConnection::getCameraObject()
|
||||||
|
|
|
||||||
|
|
@ -403,7 +403,7 @@ protected:
|
||||||
public:
|
public:
|
||||||
void setRolloverObj(SceneObject*);
|
void setRolloverObj(SceneObject*);
|
||||||
SceneObject* getRolloverObj() { return mRolloverObj; }
|
SceneObject* getRolloverObj() { return mRolloverObj; }
|
||||||
void setSelectedObj(SceneObject*, bool propagate_to_client=false);
|
void setSelectedObj(SceneObject*, bool propagate_to_client=false);
|
||||||
SceneObject* getSelectedObj() { return mSelectedObj; }
|
SceneObject* getSelectedObj() { return mSelectedObj; }
|
||||||
void setPreSelectedObjFromRollover();
|
void setPreSelectedObjFromRollover();
|
||||||
void clearPreSelectedObj();
|
void clearPreSelectedObj();
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,7 @@ GroundPlane::GroundPlane()
|
||||||
mScaleU( 1.0f ),
|
mScaleU( 1.0f ),
|
||||||
mScaleV( 1.0f ),
|
mScaleV( 1.0f ),
|
||||||
mMaterial( NULL ),
|
mMaterial( NULL ),
|
||||||
|
mMaterialInst(NULL),
|
||||||
mPhysicsRep( NULL ),
|
mPhysicsRep( NULL ),
|
||||||
mMin( 0.0f, 0.0f ),
|
mMin( 0.0f, 0.0f ),
|
||||||
mMax( 0.0f, 0.0f )
|
mMax( 0.0f, 0.0f )
|
||||||
|
|
@ -86,13 +87,15 @@ GroundPlane::GroundPlane()
|
||||||
mConvexList = new Convex;
|
mConvexList = new Convex;
|
||||||
mTypeMask |= TerrainLikeObjectType;
|
mTypeMask |= TerrainLikeObjectType;
|
||||||
|
|
||||||
initMaterialAsset(Material);
|
INIT_MATERIALASSET(Material);
|
||||||
}
|
}
|
||||||
|
|
||||||
GroundPlane::~GroundPlane()
|
GroundPlane::~GroundPlane()
|
||||||
{
|
{
|
||||||
if( mMaterial )
|
mMaterial = nullptr;
|
||||||
SAFE_DELETE( mMaterial );
|
|
||||||
|
if(mMaterialInst)
|
||||||
|
SAFE_DELETE(mMaterialInst);
|
||||||
|
|
||||||
mConvexList->nukeList();
|
mConvexList->nukeList();
|
||||||
SAFE_DELETE( mConvexList );
|
SAFE_DELETE( mConvexList );
|
||||||
|
|
@ -106,7 +109,7 @@ void GroundPlane::initPersistFields()
|
||||||
addField( "scaleU", TypeF32, Offset( mScaleU, GroundPlane ), "Scale of texture repeat in the U direction." );
|
addField( "scaleU", TypeF32, Offset( mScaleU, GroundPlane ), "Scale of texture repeat in the U direction." );
|
||||||
addField( "scaleV", TypeF32, Offset( mScaleV, GroundPlane ), "Scale of texture repeat in the V direction." );
|
addField( "scaleV", TypeF32, Offset( mScaleV, GroundPlane ), "Scale of texture repeat in the V direction." );
|
||||||
|
|
||||||
scriptBindMaterialAsset(Material, GroundPlane, "The material used to render the ground plane.");
|
INITPERSISTFIELD_MATERIALASSET(Material, GroundPlane, "The material used to render the ground plane.");
|
||||||
|
|
||||||
endGroup( "Plane" );
|
endGroup( "Plane" );
|
||||||
|
|
||||||
|
|
@ -153,6 +156,11 @@ bool GroundPlane::onAdd()
|
||||||
|
|
||||||
void GroundPlane::onRemove()
|
void GroundPlane::onRemove()
|
||||||
{
|
{
|
||||||
|
if (!mMaterialAsset.isNull())
|
||||||
|
AssetDatabase.releaseAsset(mMaterialAsset.getAssetId());
|
||||||
|
|
||||||
|
//SAFE_DELETE(mMaterialInst);
|
||||||
|
|
||||||
SAFE_DELETE( mPhysicsRep );
|
SAFE_DELETE( mPhysicsRep );
|
||||||
|
|
||||||
removeFromScene();
|
removeFromScene();
|
||||||
|
|
@ -191,7 +199,7 @@ U32 GroundPlane::packUpdate( NetConnection* connection, U32 mask, BitStream* str
|
||||||
stream->write( mScaleU );
|
stream->write( mScaleU );
|
||||||
stream->write( mScaleV );
|
stream->write( mScaleV );
|
||||||
|
|
||||||
packMaterialAsset(connection, Material);
|
PACK_MATERIALASSET(connection, Material);
|
||||||
|
|
||||||
return retMask;
|
return retMask;
|
||||||
}
|
}
|
||||||
|
|
@ -204,7 +212,7 @@ void GroundPlane::unpackUpdate( NetConnection* connection, BitStream* stream )
|
||||||
stream->read( &mScaleU );
|
stream->read( &mScaleU );
|
||||||
stream->read( &mScaleV );
|
stream->read( &mScaleV );
|
||||||
|
|
||||||
unpackMaterialAsset(connection, Material);
|
UNPACK_MATERIALASSET(connection, Material);
|
||||||
|
|
||||||
// If we're added then something possibly changed in
|
// If we're added then something possibly changed in
|
||||||
// the editor... do an update of the material and the
|
// the editor... do an update of the material and the
|
||||||
|
|
@ -220,14 +228,14 @@ void GroundPlane::_updateMaterial()
|
||||||
{
|
{
|
||||||
if (mMaterialAsset.notNull())
|
if (mMaterialAsset.notNull())
|
||||||
{
|
{
|
||||||
if (mMaterial && String(mMaterialAsset->getMaterialDefinitionName()).equal(mMaterial->getMaterial()->getName(), String::NoCase))
|
if (mMaterialInst && String(mMaterialAsset->getMaterialDefinitionName()).equal(mMaterialInst->getMaterial()->getName(), String::NoCase))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SAFE_DELETE(mMaterial);
|
SAFE_DELETE(mMaterialInst);
|
||||||
|
|
||||||
mMaterial = MATMGR->createMatInstance(mMaterialAsset->getMaterialDefinitionName(), getGFXVertexFormat< VertexType >());
|
mMaterialInst = MATMGR->createMatInstance(mMaterialAsset->getMaterialDefinitionName(), getGFXVertexFormat< VertexType >());
|
||||||
|
|
||||||
if (!mMaterial)
|
if (!mMaterialInst)
|
||||||
Con::errorf("GroundPlane::_updateMaterial - no Material called '%s'", mMaterialAsset->getMaterialDefinitionName());
|
Con::errorf("GroundPlane::_updateMaterial - no Material called '%s'", mMaterialAsset->getMaterialDefinitionName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -242,7 +250,7 @@ bool GroundPlane::castRay( const Point3F& start, const Point3F& end, RayInfo* in
|
||||||
info->t = t;
|
info->t = t;
|
||||||
info->setContactPoint( start, end );
|
info->setContactPoint( start, end );
|
||||||
info->normal.set( 0, 0, 1 );
|
info->normal.set( 0, 0, 1 );
|
||||||
info->material = mMaterial;
|
info->material = mMaterialInst;
|
||||||
info->object = this;
|
info->object = this;
|
||||||
info->distance = 0;
|
info->distance = 0;
|
||||||
info->faceDot = 0;
|
info->faceDot = 0;
|
||||||
|
|
@ -336,7 +344,7 @@ bool GroundPlane::buildPolyList( PolyListContext context, AbstractPolyList* poly
|
||||||
}
|
}
|
||||||
|
|
||||||
Box3F planeBox = getPlaneBox();
|
Box3F planeBox = getPlaneBox();
|
||||||
polyList->addBox( planeBox, mMaterial );
|
polyList->addBox( planeBox, mMaterialInst );
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -353,7 +361,7 @@ void GroundPlane::prepRenderImage( SceneRenderState* state )
|
||||||
|
|
||||||
// If we don't have a material instance after the override then
|
// If we don't have a material instance after the override then
|
||||||
// we can skip rendering all together.
|
// we can skip rendering all together.
|
||||||
BaseMatInstance *matInst = state->getOverrideMaterial( mMaterial );
|
BaseMatInstance *matInst = state->getOverrideMaterial(mMaterialInst);
|
||||||
if ( !matInst )
|
if ( !matInst )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -584,7 +592,7 @@ void GroundPlane::generateGrid( U32 width, U32 height, F32 squareSize,
|
||||||
|
|
||||||
void GroundPlane::getUtilizedAssets(Vector<StringTableEntry>* usedAssetsList)
|
void GroundPlane::getUtilizedAssets(Vector<StringTableEntry>* usedAssetsList)
|
||||||
{
|
{
|
||||||
if (!mMaterialAsset.isNull() && mMaterialAsset->getAssetId() != StringTable->insert("Core_Rendering:noMaterial"))
|
if (!mMaterialAsset.isNull() && mMaterialAsset->getAssetId() != MaterialAsset::smNoMaterialAssetFallback)
|
||||||
usedAssetsList->push_back_unique(mMaterialAsset->getAssetId());
|
usedAssetsList->push_back_unique(mMaterialAsset->getAssetId());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -104,9 +104,11 @@ private:
|
||||||
F32 mSquareSize; ///< World units per grid cell edge.
|
F32 mSquareSize; ///< World units per grid cell edge.
|
||||||
F32 mScaleU; ///< Scale factor for U texture coordinates.
|
F32 mScaleU; ///< Scale factor for U texture coordinates.
|
||||||
F32 mScaleV; ///< Scale factor for V texture coordinates.
|
F32 mScaleV; ///< Scale factor for V texture coordinates.
|
||||||
BaseMatInstance* mMaterial; ///< Instantiated material based on given material name.
|
|
||||||
|
|
||||||
DECLARE_NET_MATERIALASSET(GroundPlane, Material, -1);
|
BaseMatInstance* mMaterialInst;
|
||||||
|
|
||||||
|
DECLARE_MATERIALASSET(GroundPlane, Material);
|
||||||
|
DECLARE_MATERIALASSET_NET_SETGET(GroundPlane, Material, -1);
|
||||||
|
|
||||||
PhysicsBody *mPhysicsRep;
|
PhysicsBody *mPhysicsRep;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -634,7 +634,7 @@ void GuiObjectView::_initAnimation()
|
||||||
{
|
{
|
||||||
Con::errorf( "GuiObjectView::_initAnimation - Cannot find animation sequence '%s' on '%s'",
|
Con::errorf( "GuiObjectView::_initAnimation - Cannot find animation sequence '%s' on '%s'",
|
||||||
mAnimationSeqName.c_str(),
|
mAnimationSeqName.c_str(),
|
||||||
mModelName.c_str()
|
mModelName
|
||||||
);
|
);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
@ -649,7 +649,7 @@ void GuiObjectView::_initAnimation()
|
||||||
{
|
{
|
||||||
Con::errorf( "GuiObjectView::_initAnimation - Sequence '%i' out of range for model '%s'",
|
Con::errorf( "GuiObjectView::_initAnimation - Sequence '%i' out of range for model '%s'",
|
||||||
mAnimationSeq,
|
mAnimationSeq,
|
||||||
mModelName.c_str()
|
mModelName
|
||||||
);
|
);
|
||||||
|
|
||||||
mAnimationSeq = -1;
|
mAnimationSeq = -1;
|
||||||
|
|
@ -685,7 +685,7 @@ void GuiObjectView::_initMount()
|
||||||
{
|
{
|
||||||
Con::errorf( "GuiObjectView::_initMount - No node '%s' on '%s'",
|
Con::errorf( "GuiObjectView::_initMount - No node '%s' on '%s'",
|
||||||
mMountNodeName.c_str(),
|
mMountNodeName.c_str(),
|
||||||
mModelName.c_str()
|
mModelName
|
||||||
);
|
);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
@ -698,7 +698,7 @@ void GuiObjectView::_initMount()
|
||||||
{
|
{
|
||||||
Con::errorf( "GuiObjectView::_initMount - Mount node index '%i' out of range for '%s'",
|
Con::errorf( "GuiObjectView::_initMount - Mount node index '%i' out of range for '%s'",
|
||||||
mMountNode,
|
mMountNode,
|
||||||
mModelName.c_str()
|
mModelName
|
||||||
);
|
);
|
||||||
|
|
||||||
mMountNode = -1;
|
mMountNode = -1;
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,8 @@
|
||||||
#include "ts/tsShapeInstance.h"
|
#include "ts/tsShapeInstance.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "T3D/assets/ShapeAsset.h"
|
||||||
|
|
||||||
|
|
||||||
class LightInfo;
|
class LightInfo;
|
||||||
|
|
||||||
|
|
@ -68,7 +70,7 @@ class GuiObjectView : public GuiTSCtrl
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/// Name of the model loaded for display.
|
/// Name of the model loaded for display.
|
||||||
String mModelName;
|
StringTableEntry mModelName;
|
||||||
|
|
||||||
/// Model being displayed in the view.
|
/// Model being displayed in the view.
|
||||||
TSShapeInstance* mModel;
|
TSShapeInstance* mModel;
|
||||||
|
|
|
||||||
|
|
@ -98,8 +98,8 @@ LevelInfo::LevelInfo()
|
||||||
mNetFlags.set( ScopeAlways | Ghostable );
|
mNetFlags.set( ScopeAlways | Ghostable );
|
||||||
|
|
||||||
mAdvancedLightmapSupport = true;
|
mAdvancedLightmapSupport = true;
|
||||||
mAccuTextureName = "";
|
|
||||||
mAccuTexture = NULL;
|
INIT_IMAGEASSET(AccuTexture);
|
||||||
|
|
||||||
// Register with the light manager activation signal, and we need to do it first
|
// Register with the light manager activation signal, and we need to do it first
|
||||||
// so the advanced light bin manager can be instructed about MRT lightmaps
|
// so the advanced light bin manager can be instructed about MRT lightmaps
|
||||||
|
|
@ -166,8 +166,7 @@ void LevelInfo::initPersistFields()
|
||||||
//addField( "advancedLightmapSupport", TypeBool, Offset( mAdvancedLightmapSupport, LevelInfo ),
|
//addField( "advancedLightmapSupport", TypeBool, Offset( mAdvancedLightmapSupport, LevelInfo ),
|
||||||
// "Enable expanded support for mixing static and dynamic lighting (more costly)" );
|
// "Enable expanded support for mixing static and dynamic lighting (more costly)" );
|
||||||
|
|
||||||
addProtectedField("AccuTexture", TypeStringFilename, Offset(mAccuTextureName, LevelInfo),
|
INITPERSISTFIELD_IMAGEASSET(AccuTexture, LevelInfo, "Accumulation texture.");
|
||||||
&_setLevelAccuTexture, &defaultProtectedGetFn, "Accumulation texture.");
|
|
||||||
|
|
||||||
endGroup( "Lighting" );
|
endGroup( "Lighting" );
|
||||||
|
|
||||||
|
|
@ -216,7 +215,8 @@ U32 LevelInfo::packUpdate(NetConnection *conn, U32 mask, BitStream *stream)
|
||||||
sfxWrite( stream, mSoundAmbience );
|
sfxWrite( stream, mSoundAmbience );
|
||||||
stream->writeInt( mSoundDistanceModel, 1 );
|
stream->writeInt( mSoundDistanceModel, 1 );
|
||||||
|
|
||||||
stream->write(mAccuTextureName);
|
PACK_IMAGEASSET(conn, AccuTexture);
|
||||||
|
|
||||||
return retMask;
|
return retMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -261,8 +261,9 @@ void LevelInfo::unpackUpdate(NetConnection *conn, BitStream *stream)
|
||||||
|
|
||||||
SFX->setDistanceModel( mSoundDistanceModel );
|
SFX->setDistanceModel( mSoundDistanceModel );
|
||||||
}
|
}
|
||||||
stream->read(&mAccuTextureName);
|
|
||||||
setLevelAccuTexture(mAccuTextureName);
|
UNPACK_IMAGEASSET(conn, AccuTexture);
|
||||||
|
setLevelAccuTexture(getAccuTexture());
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
@ -361,21 +362,21 @@ void LevelInfo::_onLMActivate(const char *lm, bool enable)
|
||||||
bool LevelInfo::_setLevelAccuTexture(void *object, const char *index, const char *data)
|
bool LevelInfo::_setLevelAccuTexture(void *object, const char *index, const char *data)
|
||||||
{
|
{
|
||||||
LevelInfo* volume = reinterpret_cast< LevelInfo* >(object);
|
LevelInfo* volume = reinterpret_cast< LevelInfo* >(object);
|
||||||
volume->setLevelAccuTexture(data);
|
volume->setLevelAccuTexture(StringTable->insert(data));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LevelInfo::setLevelAccuTexture(const String& name)
|
void LevelInfo::setLevelAccuTexture(StringTableEntry name)
|
||||||
{
|
{
|
||||||
mAccuTextureName = name;
|
_setAccuTexture(name);
|
||||||
if (isClientObject() && mAccuTextureName.isNotEmpty())
|
|
||||||
|
if (isClientObject() && getAccuTexture() != StringTable->EmptyString())
|
||||||
{
|
{
|
||||||
mAccuTexture.set(mAccuTextureName, &GFXStaticTextureSRGBProfile, "AccumulationVolume::mAccuTexture");
|
|
||||||
if (mAccuTexture.isNull())
|
if (mAccuTexture.isNull())
|
||||||
Con::warnf("AccumulationVolume::setTexture - Unable to load texture: %s", mAccuTextureName.c_str());
|
Con::warnf("AccumulationVolume::setTexture - Unable to load texture: %s", getAccuTexture());
|
||||||
else
|
else
|
||||||
gLevelAccuMap = mAccuTexture;
|
gLevelAccuMap = mAccuTexture;
|
||||||
}
|
}
|
||||||
AccumulationVolume::refreshVolumes();
|
AccumulationVolume::refreshVolumes();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,8 @@
|
||||||
#include "gfx/gfxTextureHandle.h"
|
#include "gfx/gfxTextureHandle.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "T3D/assets/ImageAsset.h"
|
||||||
|
|
||||||
class SFXAmbience;
|
class SFXAmbience;
|
||||||
class SFXSoundscape;
|
class SFXSoundscape;
|
||||||
|
|
||||||
|
|
@ -101,8 +103,11 @@ class LevelInfo : public NetObject
|
||||||
|
|
||||||
void _onLMActivate(const char *lm, bool enable);
|
void _onLMActivate(const char *lm, bool enable);
|
||||||
protected:
|
protected:
|
||||||
// Name (path) of the accumulation texture.
|
|
||||||
String mAccuTextureName;
|
DECLARE_IMAGEASSET(LevelInfo, AccuTexture, onAccuTextureChanged, GFXStaticTextureSRGBProfile);
|
||||||
|
DECLARE_IMAGEASSET_SETGET(LevelInfo, AccuTexture);
|
||||||
|
|
||||||
|
void onAccuTextureChanged() {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
@ -137,13 +142,11 @@ class LevelInfo : public NetObject
|
||||||
UpdateMask = BIT(0)
|
UpdateMask = BIT(0)
|
||||||
};
|
};
|
||||||
|
|
||||||
GFXTexHandle mAccuTexture;
|
|
||||||
|
|
||||||
virtual U32 packUpdate( NetConnection *conn, U32 mask, BitStream *stream );
|
virtual U32 packUpdate( NetConnection *conn, U32 mask, BitStream *stream );
|
||||||
virtual void unpackUpdate( NetConnection *conn, BitStream *stream );
|
virtual void unpackUpdate( NetConnection *conn, BitStream *stream );
|
||||||
static bool _setLevelAccuTexture(void *object, const char *index, const char *data);
|
static bool _setLevelAccuTexture(void *object, const char *index, const char *data);
|
||||||
void setLevelAccuTexture(const String& name);
|
void setLevelAccuTexture(StringTableEntry name);
|
||||||
/// @}
|
/// @}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _LEVELINFO_H_
|
#endif // _LEVELINFO_H_
|
||||||
|
|
|
||||||
|
|
@ -131,7 +131,9 @@ LightFlareData::LightFlareData()
|
||||||
dMemset( mElementUseLightColor, 0, sizeof( bool ) * MAX_ELEMENTS );
|
dMemset( mElementUseLightColor, 0, sizeof( bool ) * MAX_ELEMENTS );
|
||||||
|
|
||||||
for ( U32 i = 0; i < MAX_ELEMENTS; i++ )
|
for ( U32 i = 0; i < MAX_ELEMENTS; i++ )
|
||||||
mElementDist[i] = -1.0f;
|
mElementDist[i] = -1.0f;
|
||||||
|
|
||||||
|
INIT_IMAGEASSET(FlareTexture);
|
||||||
}
|
}
|
||||||
|
|
||||||
LightFlareData::~LightFlareData()
|
LightFlareData::~LightFlareData()
|
||||||
|
|
@ -158,8 +160,7 @@ void LightFlareData::initPersistFields()
|
||||||
addField( "flareEnabled", TypeBool, Offset( mFlareEnabled, LightFlareData ),
|
addField( "flareEnabled", TypeBool, Offset( mFlareEnabled, LightFlareData ),
|
||||||
"Allows the user to disable this flare globally for any lights referencing it." );
|
"Allows the user to disable this flare globally for any lights referencing it." );
|
||||||
|
|
||||||
addField( "flareTexture", TypeImageFilename, Offset( mFlareTextureName, LightFlareData ),
|
INITPERSISTFIELD_IMAGEASSET(FlareTexture, LightFlareData, "The texture / sprite sheet for this flare.");
|
||||||
"The texture / sprite sheet for this flare." );
|
|
||||||
|
|
||||||
addArray( "Elements", MAX_ELEMENTS );
|
addArray( "Elements", MAX_ELEMENTS );
|
||||||
|
|
||||||
|
|
@ -217,7 +218,9 @@ void LightFlareData::packData( BitStream *stream )
|
||||||
Parent::packData( stream );
|
Parent::packData( stream );
|
||||||
|
|
||||||
stream->writeFlag( mFlareEnabled );
|
stream->writeFlag( mFlareEnabled );
|
||||||
stream->write( mFlareTextureName );
|
|
||||||
|
PACKDATA_IMAGEASSET(FlareTexture);
|
||||||
|
|
||||||
stream->write( mScale );
|
stream->write( mScale );
|
||||||
stream->write( mOcclusionRadius );
|
stream->write( mOcclusionRadius );
|
||||||
stream->writeFlag( mRenderReflectPass );
|
stream->writeFlag( mRenderReflectPass );
|
||||||
|
|
@ -240,7 +243,9 @@ void LightFlareData::unpackData( BitStream *stream )
|
||||||
Parent::unpackData( stream );
|
Parent::unpackData( stream );
|
||||||
|
|
||||||
mFlareEnabled = stream->readFlag();
|
mFlareEnabled = stream->readFlag();
|
||||||
stream->read( &mFlareTextureName );
|
|
||||||
|
UNPACKDATA_IMAGEASSET(FlareTexture);
|
||||||
|
|
||||||
stream->read( &mScale );
|
stream->read( &mScale );
|
||||||
stream->read( &mOcclusionRadius );
|
stream->read( &mOcclusionRadius );
|
||||||
mRenderReflectPass = stream->readFlag();
|
mRenderReflectPass = stream->readFlag();
|
||||||
|
|
@ -631,12 +636,6 @@ bool LightFlareData::_preload( bool server, String &errorStr )
|
||||||
if ( mElementCount > 0 )
|
if ( mElementCount > 0 )
|
||||||
_makePrimBuffer( &mFlarePrimBuffer, mElementCount );
|
_makePrimBuffer( &mFlarePrimBuffer, mElementCount );
|
||||||
|
|
||||||
if ( !server )
|
|
||||||
{
|
|
||||||
if ( mFlareTextureName.isNotEmpty() )
|
|
||||||
mFlareTexture.set( mFlareTextureName, &GFXStaticTextureSRGBProfile, "FlareTexture" );
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,8 @@
|
||||||
#include "gfx/gfxOcclusionQuery.h"
|
#include "gfx/gfxOcclusionQuery.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "T3D/assets/ImageAsset.h"
|
||||||
|
|
||||||
class LightInfo;
|
class LightInfo;
|
||||||
struct ObjectRenderInst;
|
struct ObjectRenderInst;
|
||||||
class SceneRenderState;
|
class SceneRenderState;
|
||||||
|
|
@ -104,6 +106,8 @@ protected:
|
||||||
void _makePrimBuffer( GFXPrimitiveBufferHandle *pb, U32 count );
|
void _makePrimBuffer( GFXPrimitiveBufferHandle *pb, U32 count );
|
||||||
void _renderCorona( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat );
|
void _renderCorona( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat );
|
||||||
|
|
||||||
|
void onImageChanged() {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
static const U32 LosMask;
|
static const U32 LosMask;
|
||||||
|
|
@ -115,8 +119,10 @@ protected:
|
||||||
|
|
||||||
F32 mScale;
|
F32 mScale;
|
||||||
bool mFlareEnabled;
|
bool mFlareEnabled;
|
||||||
String mFlareTextureName;
|
|
||||||
GFXTexHandle mFlareTexture;
|
DECLARE_IMAGEASSET(LightFlareData, FlareTexture, onImageChanged, GFXStaticTextureSRGBProfile);
|
||||||
|
DECLARE_IMAGEASSET_SETGET(LightFlareData, FlareTexture);
|
||||||
|
|
||||||
F32 mOcclusionRadius;
|
F32 mOcclusionRadius;
|
||||||
bool mRenderReflectPass;
|
bool mRenderReflectPass;
|
||||||
|
|
||||||
|
|
@ -133,4 +139,4 @@ protected:
|
||||||
GFXPrimitiveBufferHandle mFlarePrimBuffer;
|
GFXPrimitiveBufferHandle mFlarePrimBuffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _LIGHTFLAREDATA_H_
|
#endif // _LIGHTFLAREDATA_H_
|
||||||
|
|
|
||||||
|
|
@ -111,6 +111,7 @@ ReflectionProbe::ReflectionProbe()
|
||||||
|
|
||||||
mUseHDRCaptures = true;
|
mUseHDRCaptures = true;
|
||||||
|
|
||||||
|
mCubemapName = StringTable->EmptyString();
|
||||||
mStaticCubemap = NULL;
|
mStaticCubemap = NULL;
|
||||||
mProbeUniqueID = "";
|
mProbeUniqueID = "";
|
||||||
|
|
||||||
|
|
@ -259,7 +260,7 @@ bool ReflectionProbe::_setReflectionMode(void *object, const char *index, const
|
||||||
{
|
{
|
||||||
//Clear our cubemap if we changed it to be baked, just for cleanliness
|
//Clear our cubemap if we changed it to be baked, just for cleanliness
|
||||||
probe->mReflectionModeType = BakedCubemap;
|
probe->mReflectionModeType = BakedCubemap;
|
||||||
probe->mCubemapName = "";
|
probe->mCubemapName = StringTable->EmptyString();
|
||||||
}
|
}
|
||||||
|
|
||||||
probe->setMaskBits(StaticDataMask);
|
probe->setMaskBits(StaticDataMask);
|
||||||
|
|
@ -426,7 +427,7 @@ U32 ReflectionProbe::packUpdate(NetConnection *conn, U32 mask, BitStream *stream
|
||||||
stream->write(mRadius);
|
stream->write(mRadius);
|
||||||
stream->write(mProbeUniqueID);
|
stream->write(mProbeUniqueID);
|
||||||
stream->write((U32)mReflectionModeType);
|
stream->write((U32)mReflectionModeType);
|
||||||
stream->write(mCubemapName);
|
stream->writeString(mCubemapName);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stream->writeFlag(mask & EnabledMask))
|
if (stream->writeFlag(mask & EnabledMask))
|
||||||
|
|
@ -474,8 +475,8 @@ void ReflectionProbe::unpackUpdate(NetConnection *conn, BitStream *stream)
|
||||||
stream->read(&reflectModeType);
|
stream->read(&reflectModeType);
|
||||||
mReflectionModeType = (ReflectionModeType)reflectModeType;
|
mReflectionModeType = (ReflectionModeType)reflectModeType;
|
||||||
|
|
||||||
String oldCubemapName = mCubemapName;
|
StringTableEntry oldCubemapName = mCubemapName;
|
||||||
stream->read(&mCubemapName);
|
mCubemapName = stream->readSTString();
|
||||||
|
|
||||||
if(oldReflectModeType != mReflectionModeType || oldCubemapName != mCubemapName)
|
if(oldReflectModeType != mReflectionModeType || oldCubemapName != mCubemapName)
|
||||||
mCubemapDirty = true;
|
mCubemapDirty = true;
|
||||||
|
|
@ -630,7 +631,7 @@ void ReflectionProbe::processStaticCubemap()
|
||||||
String path = Con::getVariable("$pref::ReflectionProbes::CurrentLevelPath", "levels/");
|
String path = Con::getVariable("$pref::ReflectionProbes::CurrentLevelPath", "levels/");
|
||||||
|
|
||||||
char irradFileName[256];
|
char irradFileName[256];
|
||||||
dSprintf(irradFileName, 256, "%s%s_Irradiance.dds", path.c_str(), mCubemapName.c_str());
|
dSprintf(irradFileName, 256, "%s%s_Irradiance.dds", path.c_str(), mCubemapName);
|
||||||
|
|
||||||
if (Platform::isFile(irradFileName))
|
if (Platform::isFile(irradFileName))
|
||||||
{
|
{
|
||||||
|
|
@ -645,7 +646,7 @@ void ReflectionProbe::processStaticCubemap()
|
||||||
}
|
}
|
||||||
|
|
||||||
char prefilterFileName[256];
|
char prefilterFileName[256];
|
||||||
dSprintf(prefilterFileName, 256, "%s%s_Prefilter.dds", path.c_str(), mCubemapName.c_str());
|
dSprintf(prefilterFileName, 256, "%s%s_Prefilter.dds", path.c_str(), mCubemapName);
|
||||||
|
|
||||||
if (Platform::isFile(prefilterFileName))
|
if (Platform::isFile(prefilterFileName))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -162,7 +162,7 @@ protected:
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This is used when a static cubemap is used. The name of the cubemap is looked up and loaded for the IBL calculations
|
/// This is used when a static cubemap is used. The name of the cubemap is looked up and loaded for the IBL calculations
|
||||||
/// </summary>
|
/// </summary>
|
||||||
String mCubemapName;
|
StringTableEntry mCubemapName;
|
||||||
CubemapData *mStaticCubemap;
|
CubemapData *mStaticCubemap;
|
||||||
GFXCubemapHandle mDynamicCubemap;
|
GFXCubemapHandle mDynamicCubemap;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,8 @@ PhysicsDebrisData::PhysicsDebrisData()
|
||||||
{
|
{
|
||||||
lifetime = 5.0f;
|
lifetime = 5.0f;
|
||||||
lifetimeVariance = 0.0f;
|
lifetimeVariance = 0.0f;
|
||||||
shapeName = NULL;
|
|
||||||
|
INIT_SHAPEASSET(Shape);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PhysicsDebrisData::onAdd()
|
bool PhysicsDebrisData::onAdd()
|
||||||
|
|
@ -91,21 +92,17 @@ bool PhysicsDebrisData::preload( bool server, String &errorStr )
|
||||||
|
|
||||||
if ( server ) return true;
|
if ( server ) return true;
|
||||||
|
|
||||||
if ( shapeName && shapeName[0] != '\0' && !bool(shape) )
|
if ( mShapeAsset.notNull() )
|
||||||
{
|
{
|
||||||
shape = ResourceManager::get().load( shapeName );
|
// Create a dummy shape to force the generation of shaders and materials
|
||||||
if ( bool(shape) == false )
|
// during the level load and not during gameplay.
|
||||||
{
|
TSShapeInstance *pDummy = new TSShapeInstance( mShape, !server );
|
||||||
errorStr = String::ToString( "PhysicsDebrisData::load: Couldn't load shape \"%s\"", shapeName );
|
delete pDummy;
|
||||||
return false;
|
}
|
||||||
}
|
else
|
||||||
else
|
{
|
||||||
{
|
errorStr = String::ToString("PhysicsDebrisData::load: Couldn't load shape asset \"%s\"", mShapeAssetId);
|
||||||
// Create a dummy shape to force the generation of shaders and materials
|
return false;
|
||||||
// during the level load and not during gameplay.
|
|
||||||
TSShapeInstance *pDummy = new TSShapeInstance( shape, !server );
|
|
||||||
delete pDummy;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -115,8 +112,11 @@ void PhysicsDebrisData::initPersistFields()
|
||||||
{
|
{
|
||||||
addGroup( "Display" );
|
addGroup( "Display" );
|
||||||
|
|
||||||
addField( "shapeFile", TypeShapeFilename, Offset( shapeName, PhysicsDebrisData ),
|
addProtectedField( "shapeFile", TypeShapeFilename, Offset( mShapeName, PhysicsDebrisData ), &_setShapeData, &defaultProtectedGetFn,
|
||||||
"@brief Path to the .DAE or .DTS file to use for this shape.\n\n"
|
"@brief Path to the .DAE or .DTS file to use for this shape.\n\n"
|
||||||
|
"Compatable with Live-Asset Reloading.", AbstractClassRep::FIELD_HideInInspectors);
|
||||||
|
|
||||||
|
INITPERSISTFIELD_SHAPEASSET(Shape, PhysicsDebrisData, "@brief Shape to use with this debris.\n\n"
|
||||||
"Compatable with Live-Asset Reloading.");
|
"Compatable with Live-Asset Reloading.");
|
||||||
|
|
||||||
addField( "castShadows", TypeBool, Offset( castShadows, PhysicsDebrisData ),
|
addField( "castShadows", TypeBool, Offset( castShadows, PhysicsDebrisData ),
|
||||||
|
|
@ -214,7 +214,8 @@ void PhysicsDebrisData::packData(BitStream* stream)
|
||||||
stream->write( angularSleepThreshold );
|
stream->write( angularSleepThreshold );
|
||||||
stream->write( waterDampingScale );
|
stream->write( waterDampingScale );
|
||||||
stream->write( buoyancyDensity );
|
stream->write( buoyancyDensity );
|
||||||
stream->writeString( shapeName );
|
|
||||||
|
PACKDATA_SHAPEASSET(Shape);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicsDebrisData::unpackData(BitStream* stream)
|
void PhysicsDebrisData::unpackData(BitStream* stream)
|
||||||
|
|
@ -235,7 +236,7 @@ void PhysicsDebrisData::unpackData(BitStream* stream)
|
||||||
stream->read( &waterDampingScale );
|
stream->read( &waterDampingScale );
|
||||||
stream->read( &buoyancyDensity );
|
stream->read( &buoyancyDensity );
|
||||||
|
|
||||||
shapeName = stream->readSTString();
|
UNPACKDATA_SHAPEASSET(Shape);
|
||||||
}
|
}
|
||||||
|
|
||||||
DefineEngineMethod( PhysicsDebrisData, preload, void, (), ,
|
DefineEngineMethod( PhysicsDebrisData, preload, void, (), ,
|
||||||
|
|
@ -246,7 +247,8 @@ DefineEngineMethod( PhysicsDebrisData, preload, void, (), ,
|
||||||
{
|
{
|
||||||
String errorStr;
|
String errorStr;
|
||||||
|
|
||||||
object->shape = NULL;
|
object->_setShape(object->getShape());
|
||||||
|
|
||||||
if( !object->preload( false, errorStr ) )
|
if( !object->preload( false, errorStr ) )
|
||||||
Con::errorf( "PhsysicsDebrisData::preload - error: %s", errorStr.c_str() );
|
Con::errorf( "PhsysicsDebrisData::preload - error: %s", errorStr.c_str() );
|
||||||
}
|
}
|
||||||
|
|
@ -358,7 +360,7 @@ bool PhysicsDebris::onAdd()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup our bounding box
|
// Setup our bounding box
|
||||||
mObjBox = mDataBlock->shape->mBounds;
|
mObjBox = mDataBlock->mShape->mBounds;
|
||||||
resetWorldBox();
|
resetWorldBox();
|
||||||
|
|
||||||
// Add it to the client scene.
|
// Add it to the client scene.
|
||||||
|
|
@ -621,7 +623,7 @@ void PhysicsDebris::_createFragments()
|
||||||
if ( !mWorld )
|
if ( !mWorld )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
TSShape *shape = mDataBlock->shape;
|
TSShape *shape = mDataBlock->mShape;
|
||||||
|
|
||||||
mShapeInstance = new TSShapeInstance( shape, true );
|
mShapeInstance = new TSShapeInstance( shape, true );
|
||||||
mShapeInstance->animate();
|
mShapeInstance->animate();
|
||||||
|
|
@ -695,7 +697,7 @@ void PhysicsDebris::_findNodes( U32 colNode, Vector<U32> &nodeIds )
|
||||||
// 1. Visible mesh nodes are siblings of the collision node under a common parent dummy node
|
// 1. Visible mesh nodes are siblings of the collision node under a common parent dummy node
|
||||||
// 2. Collision node is a child of its visible mesh node
|
// 2. Collision node is a child of its visible mesh node
|
||||||
|
|
||||||
TSShape *shape = mDataBlock->shape;
|
TSShape *shape = mDataBlock->mShape;
|
||||||
S32 itr = shape->nodes[colNode].parentIndex;
|
S32 itr = shape->nodes[colNode].parentIndex;
|
||||||
itr = shape->nodes[itr].firstChild;
|
itr = shape->nodes[itr].firstChild;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,8 @@
|
||||||
#include "T3D/physics/physicsCommon.h"
|
#include "T3D/physics/physicsCommon.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "T3D/assets/ShapeAsset.h"
|
||||||
|
|
||||||
|
|
||||||
class TSShapeInstance;
|
class TSShapeInstance;
|
||||||
class TSShape;
|
class TSShape;
|
||||||
|
|
@ -84,8 +86,8 @@ public:
|
||||||
/// Is rendererd during shadow passes.
|
/// Is rendererd during shadow passes.
|
||||||
bool castShadows;
|
bool castShadows;
|
||||||
|
|
||||||
const char* shapeName;
|
DECLARE_SHAPEASSET(PhysicsDebrisData, Shape, onShapeChanged);
|
||||||
Resource<TSShape> shape;
|
DECLARE_SHAPEASSET_SETGET(PhysicsDebrisData, Shape);
|
||||||
|
|
||||||
PhysicsDebrisData();
|
PhysicsDebrisData();
|
||||||
|
|
||||||
|
|
@ -95,6 +97,8 @@ public:
|
||||||
void packData( BitStream *stream );
|
void packData( BitStream *stream );
|
||||||
void unpackData( BitStream *stream );
|
void unpackData( BitStream *stream );
|
||||||
|
|
||||||
|
void onShapeChanged() {}
|
||||||
|
|
||||||
DECLARE_CONOBJECT( PhysicsDebrisData );
|
DECLARE_CONOBJECT( PhysicsDebrisData );
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -66,8 +66,7 @@ ConsoleDocClass( PhysicsShapeData,
|
||||||
);
|
);
|
||||||
|
|
||||||
PhysicsShapeData::PhysicsShapeData()
|
PhysicsShapeData::PhysicsShapeData()
|
||||||
: shapeName( NULL ),
|
: mass( 1.0f ),
|
||||||
mass( 1.0f ),
|
|
||||||
dynamicFriction( 0.0f ),
|
dynamicFriction( 0.0f ),
|
||||||
staticFriction( 0.0f ),
|
staticFriction( 0.0f ),
|
||||||
restitution( 0.0f ),
|
restitution( 0.0f ),
|
||||||
|
|
@ -79,6 +78,7 @@ PhysicsShapeData::PhysicsShapeData()
|
||||||
buoyancyDensity( 0.0f ),
|
buoyancyDensity( 0.0f ),
|
||||||
simType( SimType_ClientServer )
|
simType( SimType_ClientServer )
|
||||||
{
|
{
|
||||||
|
INIT_SHAPEASSET(Shape);
|
||||||
}
|
}
|
||||||
|
|
||||||
PhysicsShapeData::~PhysicsShapeData()
|
PhysicsShapeData::~PhysicsShapeData()
|
||||||
|
|
@ -91,9 +91,8 @@ void PhysicsShapeData::initPersistFields()
|
||||||
|
|
||||||
addGroup("Media");
|
addGroup("Media");
|
||||||
|
|
||||||
addField( "shapeName", TypeShapeFilename, Offset( shapeName, PhysicsShapeData ),
|
INITPERSISTFIELD_SHAPEASSET(Shape, PhysicsShapeData, "@brief Shape asset to be used with this physics object.\n\n"
|
||||||
"@brief Path to the .DAE or .DTS file to use for this shape.\n\n"
|
"Compatable with Live-Asset Reloading. ")
|
||||||
"Compatable with Live-Asset Reloading. ");
|
|
||||||
|
|
||||||
addField( "debris", TYPEID< SimObjectRef<PhysicsDebrisData> >(), Offset( debris, PhysicsShapeData ),
|
addField( "debris", TYPEID< SimObjectRef<PhysicsDebrisData> >(), Offset( debris, PhysicsShapeData ),
|
||||||
"@brief Name of a PhysicsDebrisData to spawn when this shape is destroyed (optional)." );
|
"@brief Name of a PhysicsDebrisData to spawn when this shape is destroyed (optional)." );
|
||||||
|
|
@ -181,7 +180,7 @@ void PhysicsShapeData::packData( BitStream *stream )
|
||||||
{
|
{
|
||||||
Parent::packData( stream );
|
Parent::packData( stream );
|
||||||
|
|
||||||
stream->writeString( shapeName );
|
PACKDATA_SHAPEASSET(Shape);
|
||||||
|
|
||||||
stream->write( mass );
|
stream->write( mass );
|
||||||
stream->write( dynamicFriction );
|
stream->write( dynamicFriction );
|
||||||
|
|
@ -205,7 +204,7 @@ void PhysicsShapeData::unpackData( BitStream *stream )
|
||||||
{
|
{
|
||||||
Parent::unpackData(stream);
|
Parent::unpackData(stream);
|
||||||
|
|
||||||
shapeName = stream->readSTString();
|
UNPACKDATA_SHAPEASSET(Shape);
|
||||||
|
|
||||||
stream->read( &mass );
|
stream->read( &mass );
|
||||||
stream->read( &dynamicFriction );
|
stream->read( &dynamicFriction );
|
||||||
|
|
@ -242,28 +241,28 @@ void PhysicsShapeData::onRemove()
|
||||||
|
|
||||||
void PhysicsShapeData::_onResourceChanged( const Torque::Path &path )
|
void PhysicsShapeData::_onResourceChanged( const Torque::Path &path )
|
||||||
{
|
{
|
||||||
if ( path != Path( shapeName ) )
|
if (mShapeAsset.isNull())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if ( path != Path(mShapeAsset->getShapeFilePath()) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
_setShape(getShape());
|
||||||
|
|
||||||
// Reload the changed shape.
|
// Reload the changed shape.
|
||||||
Resource<TSShape> reloadShape;
|
|
||||||
PhysicsCollisionRef reloadcolShape;
|
PhysicsCollisionRef reloadcolShape;
|
||||||
|
|
||||||
reloadShape = ResourceManager::get().load( shapeName );
|
if ( !mShape )
|
||||||
if ( !bool(reloadShape) )
|
|
||||||
{
|
{
|
||||||
Con::warnf( ConsoleLogEntry::General, "PhysicsShapeData::_onResourceChanged: Could not reload %s.", path.getFileName().c_str() );
|
Con::warnf( ConsoleLogEntry::General, "PhysicsShapeData::_onResourceChanged: Could not reload %s.", path.getFileName().c_str() );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reload the collision shape.
|
// Reload the collision shape.
|
||||||
reloadcolShape = reloadShape->buildColShape( false, Point3F::One );
|
reloadcolShape = mShape->buildColShape( false, Point3F::One );
|
||||||
|
|
||||||
if ( bool(reloadShape) && bool(reloadcolShape))
|
if ( bool(reloadcolShape))
|
||||||
{
|
|
||||||
shape = reloadShape;
|
|
||||||
colShape = reloadcolShape;
|
colShape = reloadcolShape;
|
||||||
}
|
|
||||||
|
|
||||||
mReloadSignal.trigger();
|
mReloadSignal.trigger();
|
||||||
}
|
}
|
||||||
|
|
@ -283,35 +282,33 @@ bool PhysicsShapeData::preload( bool server, String &errorBuffer )
|
||||||
|
|
||||||
bool shapeError = false;
|
bool shapeError = false;
|
||||||
|
|
||||||
if (shapeName && shapeName[0])
|
if (mShapeAsset.notNull())
|
||||||
{
|
{
|
||||||
// Resolve shapename
|
if (bool(mShape) == false)
|
||||||
shape = ResourceManager::get().load(shapeName);
|
|
||||||
if (bool(shape) == false)
|
|
||||||
{
|
{
|
||||||
errorBuffer = String::ToString("PhysicsShapeData: Couldn't load shape \"%s\"", shapeName);
|
errorBuffer = String::ToString("PhysicsShapeData: Couldn't load shape \"%s\"", mShapeAssetId);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!server && !shape->preloadMaterialList(shape.getPath()) && NetConnection::filesWereDownloaded())
|
if (!server && !mShape->preloadMaterialList(mShape.getPath()) && NetConnection::filesWereDownloaded())
|
||||||
shapeError = true;
|
shapeError = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prepare the shared physics collision shape.
|
// Prepare the shared physics collision shape.
|
||||||
if ( !colShape && shape )
|
if ( !colShape && mShape)
|
||||||
{
|
{
|
||||||
colShape = shape->buildColShape( false, Point3F::One );
|
colShape = mShape->buildColShape( false, Point3F::One );
|
||||||
|
|
||||||
// If we got here and didn't get a collision shape then
|
// If we got here and didn't get a collision shape then
|
||||||
// we need to fail... can't have a shape without collision.
|
// we need to fail... can't have a shape without collision.
|
||||||
if ( !colShape )
|
if ( !colShape )
|
||||||
{
|
{
|
||||||
//no collision so we create a simple box collision shape from the shapes bounds and alert the user
|
//no collision so we create a simple box collision shape from the shapes bounds and alert the user
|
||||||
Con::warnf( "PhysicsShapeData::preload - No collision found for shape '%s', auto-creating one", shapeName );
|
Con::warnf( "PhysicsShapeData::preload - No collision found for shape '%s', auto-creating one", mShapeAssetId);
|
||||||
Point3F halfWidth = shape->mBounds.getExtents() * 0.5f;
|
Point3F halfWidth = mShape->mBounds.getExtents() * 0.5f;
|
||||||
colShape = PHYSICSMGR->createCollision();
|
colShape = PHYSICSMGR->createCollision();
|
||||||
MatrixF centerXfm(true);
|
MatrixF centerXfm(true);
|
||||||
centerXfm.setPosition(shape->mBounds.getCenter());
|
centerXfm.setPosition(mShape->mBounds.getCenter());
|
||||||
colShape->addBox(halfWidth, centerXfm);
|
colShape->addBox(halfWidth, centerXfm);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -703,11 +700,11 @@ bool PhysicsShape::_createShape()
|
||||||
mAmbientSeq = -1;
|
mAmbientSeq = -1;
|
||||||
|
|
||||||
PhysicsShapeData *db = getDataBlock();
|
PhysicsShapeData *db = getDataBlock();
|
||||||
if ( !db || !db->shape)
|
if ( !db || !db->mShape)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Set the world box.
|
// Set the world box.
|
||||||
mObjBox = db->shape->mBounds;
|
mObjBox = db->mShape->mBounds;
|
||||||
resetWorldBox();
|
resetWorldBox();
|
||||||
|
|
||||||
// If this is the server and its a client only simulation
|
// If this is the server and its a client only simulation
|
||||||
|
|
@ -721,11 +718,11 @@ bool PhysicsShape::_createShape()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the shape instance.
|
// Create the shape instance.
|
||||||
mShapeInst = new TSShapeInstance( db->shape, isClientObject() );
|
mShapeInst = new TSShapeInstance( db->mShape, isClientObject() );
|
||||||
|
|
||||||
if ( isClientObject() )
|
if ( isClientObject() )
|
||||||
{
|
{
|
||||||
mAmbientSeq = db->shape->findSequence( "ambient" );
|
mAmbientSeq = db->mShape->findSequence( "ambient" );
|
||||||
_initAmbient();
|
_initAmbient();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1207,4 +1204,4 @@ DefineEngineMethod(PhysicsShape, applyForce, void, (Point3F force), ,
|
||||||
"@note This value is ignored on physics shapes that are not dynamic. Wakes up the dynamic physics shape if it is sleeping.\n")
|
"@note This value is ignored on physics shapes that are not dynamic. Wakes up the dynamic physics shape if it is sleeping.\n")
|
||||||
{
|
{
|
||||||
object->applyForce( force );
|
object->applyForce( force );
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,8 @@
|
||||||
#include "console/simObjectRef.h"
|
#include "console/simObjectRef.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "T3D/assets/ShapeAsset.h"
|
||||||
|
|
||||||
class TSShapeInstance;
|
class TSShapeInstance;
|
||||||
class PhysicsBody;
|
class PhysicsBody;
|
||||||
class PhysicsWorld;
|
class PhysicsWorld;
|
||||||
|
|
@ -72,11 +74,8 @@ public:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// The shape to load.
|
DECLARE_SHAPEASSET(PhysicsShapeData, Shape, onShapeChanged);
|
||||||
StringTableEntry shapeName;
|
DECLARE_SHAPEASSET_SETGET(PhysicsShapeData, Shape);
|
||||||
|
|
||||||
/// The shape resource.
|
|
||||||
Resource<TSShape> shape;
|
|
||||||
|
|
||||||
/// The shared unscaled collision shape.
|
/// The shared unscaled collision shape.
|
||||||
PhysicsCollisionRef colShape;
|
PhysicsCollisionRef colShape;
|
||||||
|
|
@ -135,6 +134,8 @@ public:
|
||||||
SimObjectRef< PhysicsDebrisData > debris;
|
SimObjectRef< PhysicsDebrisData > debris;
|
||||||
SimObjectRef< ExplosionData > explosion;
|
SimObjectRef< ExplosionData > explosion;
|
||||||
SimObjectRef< PhysicsShapeData > destroyedShape;
|
SimObjectRef< PhysicsShapeData > destroyedShape;
|
||||||
|
|
||||||
|
void onShapeChanged() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef PhysicsShapeData::SimType PhysicsSimType;
|
typedef PhysicsShapeData::SimType PhysicsSimType;
|
||||||
|
|
|
||||||
|
|
@ -272,7 +272,7 @@ PlayerData::PlayerData()
|
||||||
imageAnimPrefixFP = StringTable->EmptyString();
|
imageAnimPrefixFP = StringTable->EmptyString();
|
||||||
for (U32 i=0; i<ShapeBase::MaxMountedImages; ++i)
|
for (U32 i=0; i<ShapeBase::MaxMountedImages; ++i)
|
||||||
{
|
{
|
||||||
shapeNameFP[i] = StringTable->EmptyString();
|
INIT_SHAPEASSET_ARRAY(ShapeFP, i);
|
||||||
mCRCFP[i] = 0;
|
mCRCFP[i] = 0;
|
||||||
mValidShapeFP[i] = false;
|
mValidShapeFP[i] = false;
|
||||||
}
|
}
|
||||||
|
|
@ -585,35 +585,34 @@ bool PlayerData::preload(bool server, String &errorStr)
|
||||||
{
|
{
|
||||||
bool shapeError = false;
|
bool shapeError = false;
|
||||||
|
|
||||||
if (shapeNameFP[i] && shapeNameFP[i][0])
|
if (mShapeFPAssetId[i] != StringTable->EmptyString())
|
||||||
{
|
{
|
||||||
mShapeFP[i] = ResourceManager::get().load(shapeNameFP[i]);
|
if (!mShapeFP[i])
|
||||||
if (bool(mShapeFP[i]) == false)
|
|
||||||
{
|
{
|
||||||
errorStr = String::ToString("PlayerData: Couldn't load mounted image %d shape \"%s\"",i,shapeNameFP[i]);
|
errorStr = String::ToString("PlayerData: Couldn't load mounted image %d shape \"%s\"", i, mShapeFPAssetId[i]);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!server && !mShapeFP[i]->preloadMaterialList(mShapeFP[i].getPath()) && NetConnection::filesWereDownloaded())
|
if (!server && !mShapeFP[i]->preloadMaterialList(mShapeFP[i].getPath()) && NetConnection::filesWereDownloaded())
|
||||||
shapeError = true;
|
shapeError = true;
|
||||||
|
|
||||||
if(computeCRC)
|
if (computeCRC)
|
||||||
{
|
{
|
||||||
Con::printf("Validation required for mounted image %d shape: %s", i, shapeNameFP[i]);
|
Con::printf("Validation required for mounted image %d shape: %s", i, mShapeFPAssetId[i]);
|
||||||
|
|
||||||
Torque::FS::FileNodeRef fileRef = Torque::FS::GetFileNode(mShapeFP[i].getPath());
|
Torque::FS::FileNodeRef fileRef = Torque::FS::GetFileNode(mShapeFP[i].getPath());
|
||||||
|
|
||||||
if (!fileRef)
|
if (!fileRef)
|
||||||
{
|
{
|
||||||
errorStr = String::ToString("PlayerData: Mounted image %d loading failed, shape \"%s\" is not found.",i,mShapeFP[i].getPath().getFullPath().c_str());
|
errorStr = String::ToString("PlayerData: Mounted image %d loading failed, shape \"%s\" is not found.", i, mShapeFP[i].getPath().getFullPath().c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(server)
|
if (server)
|
||||||
mCRCFP[i] = fileRef->getChecksum();
|
mCRCFP[i] = fileRef->getChecksum();
|
||||||
else if(mCRCFP[i] != fileRef->getChecksum())
|
else if (mCRCFP[i] != fileRef->getChecksum())
|
||||||
{
|
{
|
||||||
errorStr = String::ToString("PlayerData: Mounted image %d shape \"%s\" does not match version on server.",i,shapeNameFP[i]);
|
errorStr = String::ToString("PlayerData: Mounted image %d shape \"%s\" does not match version on server.", i, mShapeFPAssetId[i]);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1165,9 +1164,13 @@ void PlayerData::initPersistFields()
|
||||||
|
|
||||||
// Mounted images arrays
|
// Mounted images arrays
|
||||||
addArray( "Mounted Images", ShapeBase::MaxMountedImages );
|
addArray( "Mounted Images", ShapeBase::MaxMountedImages );
|
||||||
|
addProtectedField("shapeNameFP", TypeShapeFilename, Offset(mShapeFPName, PlayerData), &_setShapeFPData, &defaultProtectedGetFn, ShapeBase::MaxMountedImages,
|
||||||
addField( "shapeNameFP", TypeShapeFilename, Offset(shapeNameFP, PlayerData), ShapeBase::MaxMountedImages,
|
|
||||||
"@brief File name of this player's shape that will be used in conjunction with the corresponding mounted image.\n\n"
|
"@brief File name of this player's shape that will be used in conjunction with the corresponding mounted image.\n\n"
|
||||||
|
"These optional parameters correspond to each mounted image slot to indicate a shape that is rendered "
|
||||||
|
"in addition to the mounted image shape. Typically these are a player's arms (or arm) that is "
|
||||||
|
"animated along with the mounted image's state animation sequences.\n", AbstractClassRep::FIELD_HideInInspectors);
|
||||||
|
|
||||||
|
INITPERSISTFIELD_SHAPEASSET_ARRAY(ShapeFP, ShapeBase::MaxMountedImages, PlayerData, "@brief File name of this player's shape that will be used in conjunction with the corresponding mounted image.\n\n"
|
||||||
"These optional parameters correspond to each mounted image slot to indicate a shape that is rendered "
|
"These optional parameters correspond to each mounted image slot to indicate a shape that is rendered "
|
||||||
"in addition to the mounted image shape. Typically these are a player's arms (or arm) that is "
|
"in addition to the mounted image shape. Typically these are a player's arms (or arm) that is "
|
||||||
"animated along with the mounted image's state animation sequences.\n");
|
"animated along with the mounted image's state animation sequences.\n");
|
||||||
|
|
@ -1369,7 +1372,7 @@ void PlayerData::packData(BitStream* stream)
|
||||||
stream->writeString(imageAnimPrefixFP);
|
stream->writeString(imageAnimPrefixFP);
|
||||||
for (U32 i=0; i<ShapeBase::MaxMountedImages; ++i)
|
for (U32 i=0; i<ShapeBase::MaxMountedImages; ++i)
|
||||||
{
|
{
|
||||||
stream->writeString(shapeNameFP[i]);
|
PACKDATA_SHAPEASSET_ARRAY(ShapeFP, i);
|
||||||
|
|
||||||
// computeCRC is handled in ShapeBaseData
|
// computeCRC is handled in ShapeBaseData
|
||||||
if (computeCRC)
|
if (computeCRC)
|
||||||
|
|
@ -1549,7 +1552,7 @@ void PlayerData::unpackData(BitStream* stream)
|
||||||
imageAnimPrefixFP = stream->readSTString();
|
imageAnimPrefixFP = stream->readSTString();
|
||||||
for (U32 i=0; i<ShapeBase::MaxMountedImages; ++i)
|
for (U32 i=0; i<ShapeBase::MaxMountedImages; ++i)
|
||||||
{
|
{
|
||||||
shapeNameFP[i] = stream->readSTString();
|
UNPACKDATA_SHAPEASSET_ARRAY(ShapeFP, i);
|
||||||
|
|
||||||
// computeCRC is handled in ShapeBaseData
|
// computeCRC is handled in ShapeBaseData
|
||||||
if (computeCRC)
|
if (computeCRC)
|
||||||
|
|
|
||||||
|
|
@ -75,10 +75,11 @@ struct PlayerData: public ShapeBaseData {
|
||||||
/// that we don't create a TSThread on the player if we don't
|
/// that we don't create a TSThread on the player if we don't
|
||||||
/// need to.
|
/// need to.
|
||||||
|
|
||||||
StringTableEntry shapeNameFP[ShapeBase::MaxMountedImages]; ///< Used to render with mounted images in first person [optional]
|
DECLARE_SHAPEASSET_ARRAY(PlayerData, ShapeFP, ShapeBase::MaxMountedImages); ///< Used to render with mounted images in first person [optional]
|
||||||
|
DECLARE_SHAPEASSET_ARRAY_SETGET(PlayerData, ShapeFP);
|
||||||
|
|
||||||
StringTableEntry imageAnimPrefixFP; ///< Passed along to mounted images to modify
|
StringTableEntry imageAnimPrefixFP; ///< Passed along to mounted images to modify
|
||||||
/// animation sequences played in first person. [optional]
|
/// animation sequences played in first person. [optional]
|
||||||
Resource<TSShape> mShapeFP[ShapeBase::MaxMountedImages]; ///< First person mounted image shape resources [optional]
|
|
||||||
U32 mCRCFP[ShapeBase::MaxMountedImages]; ///< Computed CRC values for the first person mounted image shapes
|
U32 mCRCFP[ShapeBase::MaxMountedImages]; ///< Computed CRC values for the first person mounted image shapes
|
||||||
/// Depends on the ShapeBaseData computeCRC field.
|
/// Depends on the ShapeBaseData computeCRC field.
|
||||||
bool mValidShapeFP[ShapeBase::MaxMountedImages]; ///< Indicates that there is a valid first person mounted image shape
|
bool mValidShapeFP[ShapeBase::MaxMountedImages]; ///< Indicates that there is a valid first person mounted image shape
|
||||||
|
|
|
||||||
|
|
@ -196,7 +196,7 @@ U32 Prefab::packUpdate( NetConnection *conn, U32 mask, BitStream *stream )
|
||||||
|
|
||||||
if ( stream->writeFlag( mask & FileMask ) )
|
if ( stream->writeFlag( mask & FileMask ) )
|
||||||
{
|
{
|
||||||
stream->write( mFilename );
|
stream->writeString( mFilename );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( stream->writeFlag( mask & TransformMask ) )
|
if ( stream->writeFlag( mask & TransformMask ) )
|
||||||
|
|
@ -218,7 +218,7 @@ void Prefab::unpackUpdate(NetConnection *conn, BitStream *stream)
|
||||||
// FileMask
|
// FileMask
|
||||||
if ( stream->readFlag() )
|
if ( stream->readFlag() )
|
||||||
{
|
{
|
||||||
stream->read( &mFilename );
|
mFilename = stream->readSTString();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TransformMask
|
// TransformMask
|
||||||
|
|
@ -235,9 +235,7 @@ bool Prefab::protectedSetFile( void *object, const char *index, const char *data
|
||||||
{
|
{
|
||||||
Prefab *prefab = static_cast<Prefab*>(object);
|
Prefab *prefab = static_cast<Prefab*>(object);
|
||||||
|
|
||||||
String file = String( Platform::makeRelativePathName(data, Platform::getMainDotCsDir()) );
|
prefab->setFile( StringTable->insert(Platform::makeRelativePathName(data, Platform::getMainDotCsDir())));
|
||||||
|
|
||||||
prefab->setFile( file );
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -336,12 +334,12 @@ void Prefab::_loadFile( bool addFileNotify )
|
||||||
{
|
{
|
||||||
AssertFatal( isServerObject(), "Prefab-bad" );
|
AssertFatal( isServerObject(), "Prefab-bad" );
|
||||||
|
|
||||||
if ( mFilename.isEmpty() )
|
if ( mFilename == StringTable->EmptyString())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ( !Platform::isFile( mFilename ) )
|
if ( !Torque::FS::IsScriptFile( mFilename ) )
|
||||||
{
|
{
|
||||||
Con::errorf( "Prefab::_loadFile() - file %s was not found.", mFilename.c_str() );
|
Con::errorf( "Prefab::_loadFile() - file %s was not found.", mFilename );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -349,19 +347,19 @@ void Prefab::_loadFile( bool addFileNotify )
|
||||||
{
|
{
|
||||||
Con::errorf(
|
Con::errorf(
|
||||||
"Prefab::_loadFile - failed loading prefab file (%s). \n"
|
"Prefab::_loadFile - failed loading prefab file (%s). \n"
|
||||||
"File was referenced recursively by both a Parent and Child prefab.", mFilename.c_str() );
|
"File was referenced recursively by both a Parent and Child prefab.", mFilename );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sPrefabFileStack.push_back(mFilename);
|
sPrefabFileStack.push_back(mFilename);
|
||||||
|
|
||||||
String command = String::ToString( "exec( \"%s\" );", mFilename.c_str() );
|
String command = String::ToString( "exec( \"%s\" );", mFilename );
|
||||||
Con::evaluate( command );
|
Con::evaluate( command );
|
||||||
|
|
||||||
SimGroup *group;
|
SimGroup *group;
|
||||||
if ( !Sim::findObject( Con::getVariable( "$ThisPrefab" ), group ) )
|
if ( !Sim::findObject( Con::getVariable( "$ThisPrefab" ), group ) )
|
||||||
{
|
{
|
||||||
Con::errorf( "Prefab::_loadFile() - file %s did not create $ThisPrefab.", mFilename.c_str() );
|
Con::errorf( "Prefab::_loadFile() - file %s did not create $ThisPrefab.", mFilename );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -614,4 +612,4 @@ void ExplodePrefabUndoAction::redo()
|
||||||
name += "_exploded";
|
name += "_exploded";
|
||||||
name = Sim::getUniqueName( name );
|
name = Sim::getUniqueName( name );
|
||||||
mGroup->assignName( name );
|
mGroup->assignName( name );
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,7 @@ protected:
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/// Prefab file which defines our children objects.
|
/// Prefab file which defines our children objects.
|
||||||
String mFilename;
|
StringTableEntry mFilename;
|
||||||
|
|
||||||
/// Group which holds all children objects.
|
/// Group which holds all children objects.
|
||||||
SimObjectPtr<SimGroup> mChildGroup;
|
SimObjectPtr<SimGroup> mChildGroup;
|
||||||
|
|
@ -168,4 +168,4 @@ protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // _PREFAB_H_
|
#endif // _PREFAB_H_
|
||||||
|
|
|
||||||
|
|
@ -144,7 +144,7 @@ U32 Projectile::smProjectileWarpTicks = 5;
|
||||||
//
|
//
|
||||||
ProjectileData::ProjectileData()
|
ProjectileData::ProjectileData()
|
||||||
{
|
{
|
||||||
projectileShapeName = NULL;
|
INIT_SHAPEASSET(ProjectileShape);
|
||||||
|
|
||||||
sound = NULL;
|
sound = NULL;
|
||||||
|
|
||||||
|
|
@ -197,7 +197,6 @@ ProjectileData::ProjectileData()
|
||||||
|
|
||||||
ProjectileData::ProjectileData(const ProjectileData& other, bool temp_clone) : GameBaseData(other, temp_clone)
|
ProjectileData::ProjectileData(const ProjectileData& other, bool temp_clone) : GameBaseData(other, temp_clone)
|
||||||
{
|
{
|
||||||
projectileShapeName = other.projectileShapeName;
|
|
||||||
faceViewer = other.faceViewer; // -- always set to false
|
faceViewer = other.faceViewer; // -- always set to false
|
||||||
scale = other.scale;
|
scale = other.scale;
|
||||||
velInheritFactor = other.velInheritFactor;
|
velInheritFactor = other.velInheritFactor;
|
||||||
|
|
@ -221,7 +220,7 @@ ProjectileData::ProjectileData(const ProjectileData& other, bool temp_clone) : G
|
||||||
sound = other.sound;
|
sound = other.sound;
|
||||||
lightDesc = other.lightDesc;
|
lightDesc = other.lightDesc;
|
||||||
lightDescId = other.lightDescId; // -- for pack/unpack of lightDesc ptr
|
lightDescId = other.lightDescId; // -- for pack/unpack of lightDesc ptr
|
||||||
projectileShape = other.projectileShape; // -- TSShape loads using projectileShapeName
|
CLONE_SHAPEASSET(ProjectileShape);// -- TSShape loads using mProjectileShapeName
|
||||||
activateSeq = other.activateSeq; // -- from projectileShape sequence "activate"
|
activateSeq = other.activateSeq; // -- from projectileShape sequence "activate"
|
||||||
maintainSeq = other.maintainSeq; // -- from projectileShape sequence "maintain"
|
maintainSeq = other.maintainSeq; // -- from projectileShape sequence "maintain"
|
||||||
particleEmitter = other.particleEmitter;
|
particleEmitter = other.particleEmitter;
|
||||||
|
|
@ -244,8 +243,11 @@ void ProjectileData::initPersistFields()
|
||||||
"as the projectile enters or leaves water.\n\n"
|
"as the projectile enters or leaves water.\n\n"
|
||||||
"@see particleEmitter\n");
|
"@see particleEmitter\n");
|
||||||
|
|
||||||
addField("projectileShapeName", TypeShapeFilename, Offset(projectileShapeName, ProjectileData),
|
addProtectedField("projectileShapeName", TypeShapeFilename, Offset(mProjectileShapeName, ProjectileData), &_setProjectileShapeData, &defaultProtectedGetFn,
|
||||||
"@brief File path to the model of the projectile.\n\n");
|
"@brief File path to the model of the projectile.\n\n", AbstractClassRep::FIELD_HideInInspectors);
|
||||||
|
|
||||||
|
INITPERSISTFIELD_SHAPEASSET(ProjectileShape, ProjectileData, "@brief The model of the projectile.\n\n");
|
||||||
|
|
||||||
addField("scale", TypePoint3F, Offset(scale, ProjectileData),
|
addField("scale", TypePoint3F, Offset(scale, ProjectileData),
|
||||||
"@brief Scale to apply to the projectile's size.\n\n"
|
"@brief Scale to apply to the projectile's size.\n\n"
|
||||||
"@note This is applied after SceneObject::scale\n");
|
"@note This is applied after SceneObject::scale\n");
|
||||||
|
|
@ -375,22 +377,22 @@ bool ProjectileData::preload(bool server, String &errorStr)
|
||||||
Con::errorf(ConsoleLogEntry::General, "ProjectileData::preload: Invalid packet, bad datablockid(lightDesc): %d", lightDescId);
|
Con::errorf(ConsoleLogEntry::General, "ProjectileData::preload: Invalid packet, bad datablockid(lightDesc): %d", lightDescId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (projectileShapeName && projectileShapeName[0] != '\0')
|
if (mProjectileShapeAssetId != StringTable->EmptyString())
|
||||||
{
|
{
|
||||||
projectileShape = ResourceManager::get().load(projectileShapeName);
|
//If we've got a shapeAsset assigned for our projectile, but we failed to load the shape data itself, report the error
|
||||||
if (bool(projectileShape) == false)
|
if (!mProjectileShape)
|
||||||
{
|
{
|
||||||
errorStr = String::ToString("ProjectileData::load: Couldn't load shape \"%s\"", projectileShapeName);
|
errorStr = String::ToString("ProjectileData::load: Couldn't load shape \"%s\"", mProjectileShapeAssetId);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
activateSeq = projectileShape->findSequence("activate");
|
else
|
||||||
maintainSeq = projectileShape->findSequence("maintain");
|
{
|
||||||
}
|
activateSeq = mProjectileShape->findSequence("activate");
|
||||||
|
maintainSeq = mProjectileShape->findSequence("maintain");
|
||||||
|
|
||||||
if (bool(projectileShape)) // create an instance to preload shape data
|
TSShapeInstance* pDummy = new TSShapeInstance(mProjectileShape, !server);
|
||||||
{
|
delete pDummy;
|
||||||
TSShapeInstance* pDummy = new TSShapeInstance(projectileShape, !server);
|
}
|
||||||
delete pDummy;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -401,7 +403,8 @@ void ProjectileData::packData(BitStream* stream)
|
||||||
{
|
{
|
||||||
Parent::packData(stream);
|
Parent::packData(stream);
|
||||||
|
|
||||||
stream->writeString(projectileShapeName);
|
PACKDATA_SHAPEASSET(ProjectileShape);
|
||||||
|
|
||||||
stream->writeFlag(faceViewer);
|
stream->writeFlag(faceViewer);
|
||||||
if(stream->writeFlag(scale.x != 1 || scale.y != 1 || scale.z != 1))
|
if(stream->writeFlag(scale.x != 1 || scale.y != 1 || scale.z != 1))
|
||||||
{
|
{
|
||||||
|
|
@ -465,7 +468,7 @@ void ProjectileData::unpackData(BitStream* stream)
|
||||||
{
|
{
|
||||||
Parent::unpackData(stream);
|
Parent::unpackData(stream);
|
||||||
|
|
||||||
projectileShapeName = stream->readSTString();
|
UNPACKDATA_SHAPEASSET(ProjectileShape);
|
||||||
|
|
||||||
faceViewer = stream->readFlag();
|
faceViewer = stream->readFlag();
|
||||||
if(stream->readFlag())
|
if(stream->readFlag())
|
||||||
|
|
@ -786,9 +789,9 @@ bool Projectile::onAdd()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (bool(mDataBlock->projectileShape))
|
if (bool(mDataBlock->mProjectileShape))
|
||||||
{
|
{
|
||||||
mProjectileShape = new TSShapeInstance(mDataBlock->projectileShape, isClientObject());
|
mProjectileShape = new TSShapeInstance(mDataBlock->mProjectileShape, isClientObject());
|
||||||
|
|
||||||
if (mDataBlock->activateSeq != -1)
|
if (mDataBlock->activateSeq != -1)
|
||||||
{
|
{
|
||||||
|
|
@ -827,8 +830,8 @@ bool Projectile::onAdd()
|
||||||
processAfter(mSourceObject);
|
processAfter(mSourceObject);
|
||||||
|
|
||||||
// Setup our bounding box
|
// Setup our bounding box
|
||||||
if (bool(mDataBlock->projectileShape) == true)
|
if (bool(mDataBlock->mProjectileShape) == true)
|
||||||
mObjBox = mDataBlock->projectileShape->mBounds;
|
mObjBox = mDataBlock->mProjectileShape->mBounds;
|
||||||
else
|
else
|
||||||
mObjBox = Box3F(Point3F(0, 0, 0), Point3F(0, 0, 0));
|
mObjBox = Box3F(Point3F(0, 0, 0), Point3F(0, 0, 0));
|
||||||
|
|
||||||
|
|
@ -1509,4 +1512,4 @@ DefineEngineMethod(Projectile, presimulate, void, (F32 seconds), (1.0f),
|
||||||
"@note This function is not called if the SimObject::hidden is true.")
|
"@note This function is not called if the SimObject::hidden is true.")
|
||||||
{
|
{
|
||||||
object->simulate( seconds );
|
object->simulate( seconds );
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@
|
||||||
#include "lighting/lightInfo.h"
|
#include "lighting/lightInfo.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "T3D/assets/ShapeAsset.h"
|
||||||
|
|
||||||
class ExplosionData;
|
class ExplosionData;
|
||||||
class SplashData;
|
class SplashData;
|
||||||
|
|
@ -69,9 +70,8 @@ protected:
|
||||||
bool onAdd();
|
bool onAdd();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// variables set in datablock definition:
|
DECLARE_SHAPEASSET(ProjectileData, ProjectileShape, onShapeChanged);
|
||||||
// Shape related
|
DECLARE_SHAPEASSET_SETGET(ProjectileData, ProjectileShape);
|
||||||
const char* projectileShapeName;
|
|
||||||
|
|
||||||
/// Set to true if it is a billboard and want it to always face the viewer, false otherwise
|
/// Set to true if it is a billboard and want it to always face the viewer, false otherwise
|
||||||
bool faceViewer;
|
bool faceViewer;
|
||||||
|
|
@ -121,7 +121,6 @@ public:
|
||||||
S32 lightDescId;
|
S32 lightDescId;
|
||||||
|
|
||||||
// variables set on preload:
|
// variables set on preload:
|
||||||
Resource<TSShape> projectileShape;
|
|
||||||
S32 activateSeq;
|
S32 activateSeq;
|
||||||
S32 maintainSeq;
|
S32 maintainSeq;
|
||||||
|
|
||||||
|
|
@ -152,6 +151,8 @@ public:
|
||||||
public:
|
public:
|
||||||
ProjectileData(const ProjectileData&, bool = false);
|
ProjectileData(const ProjectileData&, bool = false);
|
||||||
virtual bool allowSubstitutions() const { return true; }
|
virtual bool allowSubstitutions() const { return true; }
|
||||||
|
|
||||||
|
void onShapeChanged() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -291,7 +291,7 @@ bool RigidShapeData::preload(bool server, String &errorStr)
|
||||||
if (!collisionDetails.size() || collisionDetails[0] == -1)
|
if (!collisionDetails.size() || collisionDetails[0] == -1)
|
||||||
{
|
{
|
||||||
Con::errorf("RigidShapeData::preload failed: Rigid shapes must define a collision-1 detail");
|
Con::errorf("RigidShapeData::preload failed: Rigid shapes must define a collision-1 detail");
|
||||||
errorStr = String::ToString("RigidShapeData: Couldn't load shape \"%s\"", mShapeName);
|
errorStr = String::ToString("RigidShapeData: Couldn't load shape asset \"%s\"", mShapeAsset.getAssetId());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -721,12 +721,12 @@ void SFXEmitter::_update()
|
||||||
mLocalProfile.mResource = NULL;
|
mLocalProfile.mResource = NULL;
|
||||||
mLocalProfile.mBuffer = NULL;
|
mLocalProfile.mBuffer = NULL;
|
||||||
|
|
||||||
if( !mLocalProfile.mFilename.isEmpty() )
|
if( mLocalProfile.mFilename != StringTable->EmptyString() )
|
||||||
{
|
{
|
||||||
mSource = SFX->createSource( &mLocalProfile, &transform, &velocity );
|
mSource = SFX->createSource( &mLocalProfile, &transform, &velocity );
|
||||||
if( !mSource )
|
if( !mSource )
|
||||||
Con::errorf( "SFXEmitter::_update() - failed to create sound for: %s",
|
Con::errorf( "SFXEmitter::_update() - failed to create sound for: %s",
|
||||||
mLocalProfile.mFilename.c_str() );
|
mLocalProfile.mFilename );
|
||||||
|
|
||||||
prevState = mPlayOnAdd ? SFXStatusPlaying : prevState;
|
prevState = mPlayOnAdd ? SFXStatusPlaying : prevState;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -163,7 +163,6 @@ ShapeBaseData::ShapeBaseData()
|
||||||
reflectorDesc( NULL ),
|
reflectorDesc( NULL ),
|
||||||
debris( NULL ),
|
debris( NULL ),
|
||||||
debrisID( 0 ),
|
debrisID( 0 ),
|
||||||
debrisShapeName( StringTable->EmptyString() ),
|
|
||||||
explosion( NULL ),
|
explosion( NULL ),
|
||||||
explosionID( 0 ),
|
explosionID( 0 ),
|
||||||
underwaterExplosion( NULL ),
|
underwaterExplosion( NULL ),
|
||||||
|
|
@ -198,7 +197,9 @@ ShapeBaseData::ShapeBaseData()
|
||||||
renderWhenDestroyed( true ),
|
renderWhenDestroyed( true ),
|
||||||
inheritEnergyFromMount( false )
|
inheritEnergyFromMount( false )
|
||||||
{
|
{
|
||||||
initShapeAsset(Shape);
|
INIT_SHAPEASSET(Shape);
|
||||||
|
INIT_SHAPEASSET(DebrisShape);
|
||||||
|
|
||||||
dMemset( mountPointNode, -1, sizeof( S32 ) * SceneObject::NumMountPoints );
|
dMemset( mountPointNode, -1, sizeof( S32 ) * SceneObject::NumMountPoints );
|
||||||
remap_txr_tags = NULL;
|
remap_txr_tags = NULL;
|
||||||
remap_buffer = NULL;
|
remap_buffer = NULL;
|
||||||
|
|
@ -213,14 +214,13 @@ ShapeBaseData::ShapeBaseData(const ShapeBaseData& other, bool temp_clone) : Game
|
||||||
shadowProjectionDistance = other.shadowProjectionDistance;
|
shadowProjectionDistance = other.shadowProjectionDistance;
|
||||||
shadowSphereAdjust = other.shadowSphereAdjust;
|
shadowSphereAdjust = other.shadowSphereAdjust;
|
||||||
cloakTexName = other.cloakTexName;
|
cloakTexName = other.cloakTexName;
|
||||||
cloneShapeAsset(Shape);
|
CLONE_SHAPEASSET(Shape);
|
||||||
cubeDescName = other.cubeDescName;
|
cubeDescName = other.cubeDescName;
|
||||||
cubeDescId = other.cubeDescId;
|
cubeDescId = other.cubeDescId;
|
||||||
reflectorDesc = other.reflectorDesc;
|
reflectorDesc = other.reflectorDesc;
|
||||||
debris = other.debris;
|
debris = other.debris;
|
||||||
debrisID = other.debrisID; // -- for pack/unpack of debris ptr
|
debrisID = other.debrisID; // -- for pack/unpack of debris ptr
|
||||||
debrisShapeName = other.debrisShapeName;
|
CLONE_SHAPEASSET(DebrisShape);
|
||||||
debrisShape = other.debrisShape; // -- TSShape loaded using debrisShapeName
|
|
||||||
explosion = other.explosion;
|
explosion = other.explosion;
|
||||||
explosionID = other.explosionID; // -- for pack/unpack of explosion ptr
|
explosionID = other.explosionID; // -- for pack/unpack of explosion ptr
|
||||||
underwaterExplosion = other.underwaterExplosion;
|
underwaterExplosion = other.underwaterExplosion;
|
||||||
|
|
@ -337,67 +337,28 @@ bool ShapeBaseData::preload(bool server, String &errorStr)
|
||||||
"ShapeBaseData::preload: invalid debris data");
|
"ShapeBaseData::preload: invalid debris data");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( bool(mDebrisShape))
|
||||||
if( debrisShapeName && debrisShapeName[0] != '\0' && !bool(debrisShape) )
|
|
||||||
{
|
{
|
||||||
debrisShape = ResourceManager::get().load(debrisShapeName);
|
TSShapeInstance* pDummy = new TSShapeInstance(mDebrisShape, !server);
|
||||||
if( bool(debrisShape) == false )
|
delete pDummy;
|
||||||
{
|
|
||||||
errorStr = String::ToString("ShapeBaseData::load: Couldn't load shape \"%s\"", debrisShapeName);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(!server && !debrisShape->preloadMaterialList(debrisShape.getPath()) && NetConnection::filesWereDownloaded())
|
|
||||||
shapeError = true;
|
|
||||||
|
|
||||||
TSShapeInstance* pDummy = new TSShapeInstance(debrisShape, !server);
|
|
||||||
delete pDummy;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PersistenceManager *persistMgr;
|
|
||||||
if (!Sim::findObject("ServerAssetValidator", persistMgr)) Con::errorf("ServerAssetValidator not found!");
|
|
||||||
if (server && persistMgr && mShapeAssetId == StringTable->EmptyString())
|
|
||||||
{
|
|
||||||
persistMgr->setDirty(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Legacy catch
|
S32 i;
|
||||||
if (mShapeName != StringTable->EmptyString())
|
if (ShapeAsset::getAssetErrCode(mShapeAsset) != ShapeAsset::Failed && ShapeAsset::getAssetErrCode(mShapeAsset) != ShapeAsset::BadFileReference)
|
||||||
{
|
{
|
||||||
mShapeAssetId = ShapeAsset::getAssetIdByFilename(mShapeName);
|
if (!server && !mShape->preloadMaterialList(mShape.getPath()) && NetConnection::filesWereDownloaded())
|
||||||
}
|
|
||||||
U32 assetState = ShapeAsset::getAssetById(mShapeAssetId, &mShapeAsset);
|
|
||||||
if (ShapeAsset::Failed != assetState)
|
|
||||||
{
|
|
||||||
//only clear the legacy direct file reference if everything checks out fully
|
|
||||||
if (assetState == ShapeAsset::Ok)
|
|
||||||
{
|
|
||||||
mShapeName = StringTable->EmptyString();
|
|
||||||
}
|
|
||||||
else Con::warnf("Warning: ShapeBaseData::preload-%s", ShapeAsset::getAssetErrstrn(assetState).c_str());
|
|
||||||
S32 i;
|
|
||||||
|
|
||||||
// Resolve shapename
|
|
||||||
mShape = mShapeAsset->getShapeResource();
|
|
||||||
if (bool(mShape) == false)
|
|
||||||
{
|
|
||||||
errorStr = String::ToString("ShapeBaseData: Couldn't load shape \"%s\"",mShapeName);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if(!server && !mShape->preloadMaterialList(mShape.getPath()) && NetConnection::filesWereDownloaded())
|
|
||||||
shapeError = true;
|
shapeError = true;
|
||||||
|
|
||||||
if(computeCRC)
|
if(computeCRC)
|
||||||
{
|
{
|
||||||
Con::printf("Validation required for shape: %s", mShapeName);
|
Con::printf("Validation required for shape asset: %s", mShapeAsset.getAssetId());
|
||||||
|
|
||||||
Torque::FS::FileNodeRef fileRef = Torque::FS::GetFileNode(mShape.getPath());
|
Torque::FS::FileNodeRef fileRef = Torque::FS::GetFileNode(mShapeAsset->getShapePath());
|
||||||
|
|
||||||
if (!fileRef)
|
if (!fileRef)
|
||||||
{
|
{
|
||||||
errorStr = String::ToString("ShapeBaseData: Couldn't load shape \"%s\"", mShapeName);
|
errorStr = String::ToString("ShapeBaseData: Couldn't load shape asset \"%s\"", mShapeAsset.getAssetId());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -405,7 +366,7 @@ bool ShapeBaseData::preload(bool server, String &errorStr)
|
||||||
mCRC = fileRef->getChecksum();
|
mCRC = fileRef->getChecksum();
|
||||||
else if(mCRC != fileRef->getChecksum())
|
else if(mCRC != fileRef->getChecksum())
|
||||||
{
|
{
|
||||||
errorStr = String::ToString("Shape \"%s\" does not match version on server.", mShapeName);
|
errorStr = String::ToString("Shape asset \"%s\" does not match version on server.", mShapeAsset.getAssetId());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -427,13 +388,13 @@ bool ShapeBaseData::preload(bool server, String &errorStr)
|
||||||
if (!mShape->mBounds.isContained(collisionBounds.last()))
|
if (!mShape->mBounds.isContained(collisionBounds.last()))
|
||||||
{
|
{
|
||||||
if (!silent_bbox_check)
|
if (!silent_bbox_check)
|
||||||
Con::warnf("Warning: shape %s collision detail %d (Collision-%d) bounds exceed that of shape.", mShapeName, collisionDetails.size() - 1, collisionDetails.last());
|
Con::warnf("Warning: shape asset %s collision detail %d (Collision-%d) bounds exceed that of shape.", mShapeAsset.getAssetId(), collisionDetails.size() - 1, collisionDetails.last());
|
||||||
collisionBounds.last() = mShape->mBounds;
|
collisionBounds.last() = mShape->mBounds;
|
||||||
}
|
}
|
||||||
else if (collisionBounds.last().isValidBox() == false)
|
else if (collisionBounds.last().isValidBox() == false)
|
||||||
{
|
{
|
||||||
if (!silent_bbox_check)
|
if (!silent_bbox_check)
|
||||||
Con::errorf("Error: shape %s-collision detail %d (Collision-%d) bounds box invalid!", mShapeName, collisionDetails.size() - 1, collisionDetails.last());
|
Con::errorf("Error: shape asset %s-collision detail %d (Collision-%d) bounds box invalid!", mShapeAsset.getAssetId(), collisionDetails.size() - 1, collisionDetails.last());
|
||||||
collisionBounds.last() = mShape->mBounds;
|
collisionBounds.last() = mShape->mBounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -593,11 +554,7 @@ void ShapeBaseData::initPersistFields()
|
||||||
|
|
||||||
addGroup( "Render" );
|
addGroup( "Render" );
|
||||||
|
|
||||||
addField("shapeAsset", TypeShapeAssetId, Offset(mShapeAssetId, ShapeBaseData),
|
INITPERSISTFIELD_SHAPEASSET(Shape, ShapeBaseData, "The source shape asset.");
|
||||||
"The source shape asset.");
|
|
||||||
|
|
||||||
addField( "shapeFile", TypeShapeFilename, Offset(mShapeName, ShapeBaseData),
|
|
||||||
"The DTS or DAE model to use for this object." );
|
|
||||||
|
|
||||||
endGroup( "Render" );
|
endGroup( "Render" );
|
||||||
|
|
||||||
|
|
@ -611,8 +568,8 @@ void ShapeBaseData::initPersistFields()
|
||||||
"%Debris to generate when this shape is blown up." );
|
"%Debris to generate when this shape is blown up." );
|
||||||
addField( "renderWhenDestroyed", TypeBool, Offset(renderWhenDestroyed, ShapeBaseData),
|
addField( "renderWhenDestroyed", TypeBool, Offset(renderWhenDestroyed, ShapeBaseData),
|
||||||
"Whether to render the shape when it is in the \"Destroyed\" damage state." );
|
"Whether to render the shape when it is in the \"Destroyed\" damage state." );
|
||||||
addField( "debrisShapeName", TypeShapeFilename, Offset(debrisShapeName, ShapeBaseData),
|
|
||||||
"The DTS or DAE model to use for auto-generated breakups. @note may not be functional." );
|
INITPERSISTFIELD_SHAPEASSET(DebrisShape, ShapeBaseData, "The shape asset to use for auto-generated breakups. @note may not be functional.");
|
||||||
|
|
||||||
endGroup( "Destruction" );
|
endGroup( "Destruction" );
|
||||||
|
|
||||||
|
|
@ -800,8 +757,8 @@ void ShapeBaseData::packData(BitStream* stream)
|
||||||
stream->write(shadowProjectionDistance);
|
stream->write(shadowProjectionDistance);
|
||||||
stream->write(shadowSphereAdjust);
|
stream->write(shadowSphereAdjust);
|
||||||
|
|
||||||
|
PACKDATA_SHAPEASSET(Shape);
|
||||||
packShapeAsset(stream);
|
PACKDATA_SHAPEASSET(DebrisShape);
|
||||||
|
|
||||||
stream->writeString(cloakTexName);
|
stream->writeString(cloakTexName);
|
||||||
if(stream->writeFlag(mass != gShapeBaseDataProto.mass))
|
if(stream->writeFlag(mass != gShapeBaseDataProto.mass))
|
||||||
|
|
@ -825,7 +782,6 @@ void ShapeBaseData::packData(BitStream* stream)
|
||||||
stream->write(cameraMaxFov);
|
stream->write(cameraMaxFov);
|
||||||
stream->writeFlag(cameraCanBank);
|
stream->writeFlag(cameraCanBank);
|
||||||
stream->writeFlag(mountedImagesBank);
|
stream->writeFlag(mountedImagesBank);
|
||||||
stream->writeString( debrisShapeName );
|
|
||||||
|
|
||||||
stream->writeFlag(observeThroughObject);
|
stream->writeFlag(observeThroughObject);
|
||||||
|
|
||||||
|
|
@ -879,8 +835,8 @@ void ShapeBaseData::unpackData(BitStream* stream)
|
||||||
stream->read(&shadowProjectionDistance);
|
stream->read(&shadowProjectionDistance);
|
||||||
stream->read(&shadowSphereAdjust);
|
stream->read(&shadowSphereAdjust);
|
||||||
|
|
||||||
|
UNPACKDATA_SHAPEASSET(Shape);
|
||||||
unpackShapeAsset(stream);
|
UNPACKDATA_SHAPEASSET(DebrisShape);
|
||||||
|
|
||||||
cloakTexName = stream->readSTString();
|
cloakTexName = stream->readSTString();
|
||||||
if(stream->readFlag())
|
if(stream->readFlag())
|
||||||
|
|
@ -930,9 +886,6 @@ void ShapeBaseData::unpackData(BitStream* stream)
|
||||||
|
|
||||||
cameraCanBank = stream->readFlag();
|
cameraCanBank = stream->readFlag();
|
||||||
mountedImagesBank = stream->readFlag();
|
mountedImagesBank = stream->readFlag();
|
||||||
|
|
||||||
debrisShapeName = stream->readSTString();
|
|
||||||
|
|
||||||
observeThroughObject = stream->readFlag();
|
observeThroughObject = stream->readFlag();
|
||||||
|
|
||||||
if( stream->readFlag() )
|
if( stream->readFlag() )
|
||||||
|
|
@ -2011,13 +1964,13 @@ void ShapeBase::blowUp()
|
||||||
|
|
||||||
TSShapeInstance *debShape = NULL;
|
TSShapeInstance *debShape = NULL;
|
||||||
|
|
||||||
if( mDataBlock->debrisShape == NULL )
|
if( mDataBlock->mDebrisShape == NULL )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
debShape = new TSShapeInstance( mDataBlock->debrisShape, true);
|
debShape = new TSShapeInstance( mDataBlock->mDebrisShape, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -373,8 +373,11 @@ struct ShapeBaseImageData: public GameBaseData {
|
||||||
F32 scriptAnimTransitionTime; ///< The amount of time to transition between the previous sequence and new sequence
|
F32 scriptAnimTransitionTime; ///< The amount of time to transition between the previous sequence and new sequence
|
||||||
///< when the script prefix has changed.
|
///< when the script prefix has changed.
|
||||||
|
|
||||||
StringTableEntry shapeName; ///< Name of shape to render.
|
DECLARE_SHAPEASSET_ARRAY(ShapeBaseImageData, Shape, MaxShapes); ///< Name of shape to render.
|
||||||
StringTableEntry shapeNameFP; ///< Name of shape to render in first person (optional).
|
DECLARE_SHAPEASSET_ARRAY_SETGET(ShapeBaseImageData, Shape);
|
||||||
|
|
||||||
|
//DECLARE_SHAPEASSET(ShapeBaseImageData, ShapeFP); ///< Name of shape to render in first person (optional).
|
||||||
|
//DECLARE_SHAPEASSET_SETGET(ShapeBaseImageData, ShapeFP);
|
||||||
|
|
||||||
StringTableEntry imageAnimPrefix; ///< Passed along to the mounting shape to modify
|
StringTableEntry imageAnimPrefix; ///< Passed along to the mounting shape to modify
|
||||||
/// animation sequences played in 3rd person. [optional]
|
/// animation sequences played in 3rd person. [optional]
|
||||||
|
|
@ -407,7 +410,6 @@ struct ShapeBaseImageData: public GameBaseData {
|
||||||
|
|
||||||
/// @name Shape Data
|
/// @name Shape Data
|
||||||
/// @{
|
/// @{
|
||||||
Resource<TSShape> shape[MaxShapes]; ///< Shape handle
|
|
||||||
bool shapeIsValid[MaxShapes]; ///< Indicates that the shape has been loaded and is valid
|
bool shapeIsValid[MaxShapes]; ///< Indicates that the shape has been loaded and is valid
|
||||||
|
|
||||||
U32 mCRC[MaxShapes]; ///< Checksum of shape.
|
U32 mCRC[MaxShapes]; ///< Checksum of shape.
|
||||||
|
|
@ -538,7 +540,8 @@ public:
|
||||||
F32 shadowProjectionDistance;
|
F32 shadowProjectionDistance;
|
||||||
F32 shadowSphereAdjust;
|
F32 shadowSphereAdjust;
|
||||||
|
|
||||||
DECLARE_SHAPEASSET(ShapeBaseData, Shape);
|
DECLARE_SHAPEASSET(ShapeBaseData, Shape, onShapeChanged);
|
||||||
|
DECLARE_SHAPEASSET_SETGET(ShapeBaseData, Shape);
|
||||||
|
|
||||||
StringTableEntry cloakTexName;
|
StringTableEntry cloakTexName;
|
||||||
|
|
||||||
|
|
@ -552,8 +555,9 @@ public:
|
||||||
/// @{
|
/// @{
|
||||||
DebrisData * debris;
|
DebrisData * debris;
|
||||||
S32 debrisID;
|
S32 debrisID;
|
||||||
StringTableEntry debrisShapeName;
|
|
||||||
Resource<TSShape> debrisShape;
|
DECLARE_SHAPEASSET(ShapeBaseData, DebrisShape, onDebrisChanged);
|
||||||
|
DECLARE_SHAPEASSET_SETGET(ShapeBaseData, DebrisShape);
|
||||||
|
|
||||||
ExplosionData* explosion;
|
ExplosionData* explosion;
|
||||||
S32 explosionID;
|
S32 explosionID;
|
||||||
|
|
@ -598,8 +602,6 @@ public:
|
||||||
|
|
||||||
/// @name Data initialized on preload
|
/// @name Data initialized on preload
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
Resource<TSShape> mShape; ///< Shape handle
|
|
||||||
U32 mCRC;
|
U32 mCRC;
|
||||||
bool computeCRC;
|
bool computeCRC;
|
||||||
|
|
||||||
|
|
@ -672,6 +674,9 @@ public:
|
||||||
char* remap_buffer;
|
char* remap_buffer;
|
||||||
Vector<TextureTagRemapping> txr_tag_remappings;
|
Vector<TextureTagRemapping> txr_tag_remappings;
|
||||||
bool silent_bbox_check;
|
bool silent_bbox_check;
|
||||||
|
|
||||||
|
void onShapeChanged() {}
|
||||||
|
void onDebrisChanged() {}
|
||||||
public:
|
public:
|
||||||
ShapeBaseData(const ShapeBaseData&, bool = false);
|
ShapeBaseData(const ShapeBaseData&, bool = false);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -191,8 +191,6 @@ ShapeBaseImageData::ShapeBaseImageData()
|
||||||
lightRadius = 10.f;
|
lightRadius = 10.f;
|
||||||
lightBrightness = 1.0f;
|
lightBrightness = 1.0f;
|
||||||
|
|
||||||
shapeName = "core/rendering/shapes/noshape.dts";
|
|
||||||
shapeNameFP = "";
|
|
||||||
imageAnimPrefix = "";
|
imageAnimPrefix = "";
|
||||||
imageAnimPrefixFP = "";
|
imageAnimPrefixFP = "";
|
||||||
fireState = -1;
|
fireState = -1;
|
||||||
|
|
@ -295,6 +293,8 @@ ShapeBaseImageData::ShapeBaseImageData()
|
||||||
isAnimated[i] = false;
|
isAnimated[i] = false;
|
||||||
hasFlash[i] = false;
|
hasFlash[i] = false;
|
||||||
shapeIsValid[i] = false;
|
shapeIsValid[i] = false;
|
||||||
|
|
||||||
|
INIT_SHAPEASSET_ARRAY(Shape, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
shakeCamera = false;
|
shakeCamera = false;
|
||||||
|
|
@ -407,6 +407,7 @@ bool ShapeBaseImageData::preload(bool server, String &errorStr)
|
||||||
{
|
{
|
||||||
if (!Parent::preload(server, errorStr))
|
if (!Parent::preload(server, errorStr))
|
||||||
return false;
|
return false;
|
||||||
|
bool shapeError = false;
|
||||||
|
|
||||||
// Resolve objects transmitted from server
|
// Resolve objects transmitted from server
|
||||||
if (!server) {
|
if (!server) {
|
||||||
|
|
@ -434,14 +435,12 @@ bool ShapeBaseImageData::preload(bool server, String &errorStr)
|
||||||
// Shape 0: Standard image shape
|
// Shape 0: Standard image shape
|
||||||
// Shape 1: Optional first person image shape
|
// Shape 1: Optional first person image shape
|
||||||
|
|
||||||
StringTableEntry name;
|
|
||||||
if (i == FirstPersonImageShape)
|
if (i == FirstPersonImageShape)
|
||||||
{
|
{
|
||||||
if ((useEyeOffset || useEyeNode) && shapeNameFP && shapeNameFP[0])
|
if ((useEyeOffset || useEyeNode) && !mShapeAsset[i].isNull())
|
||||||
{
|
{
|
||||||
// Make use of the first person shape
|
// Make use of the first person shape
|
||||||
useFirstPersonShape = true;
|
useFirstPersonShape = true;
|
||||||
name = shapeNameFP;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -449,27 +448,25 @@ bool ShapeBaseImageData::preload(bool server, String &errorStr)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
name = shapeName;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (name && name[0]) {
|
if (!mShapeAsset[i].isNull())
|
||||||
|
{
|
||||||
// Resolve shapename
|
// Resolve shapename
|
||||||
shape[i] = ResourceManager::get().load(name);
|
mShape[i] = mShapeAsset[i]->getShapeResource();
|
||||||
if (!bool(shape[i])) {
|
|
||||||
errorStr = String::ToString("Unable to load shape: %s", name);
|
if (!bool(mShape[i])) {
|
||||||
|
errorStr = String::ToString("Unable to load shape asset: %s", mShapeAsset[i]->getAssetId());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if(computeCRC)
|
if(computeCRC)
|
||||||
{
|
{
|
||||||
Con::printf("Validation required for shape: %s", name);
|
Con::printf("Validation required for shape asset: %s", mShapeAsset[i]->getAssetId());
|
||||||
|
|
||||||
Torque::FS::FileNodeRef fileRef = Torque::FS::GetFileNode(shape[i].getPath());
|
Torque::FS::FileNodeRef fileRef = Torque::FS::GetFileNode(mShape[i].getPath());
|
||||||
|
|
||||||
if (!fileRef)
|
if (!fileRef)
|
||||||
{
|
{
|
||||||
errorStr = String::ToString("ShapeBaseImageData: Couldn't load shape \"%s\"",name);
|
errorStr = String::ToString("ShapeBaseImageData: Couldn't load shape asset\"%s\"", mShapeAsset[i]->getAssetId());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -479,29 +476,29 @@ bool ShapeBaseImageData::preload(bool server, String &errorStr)
|
||||||
}
|
}
|
||||||
else if(mCRC[i] != fileRef->getChecksum())
|
else if(mCRC[i] != fileRef->getChecksum())
|
||||||
{
|
{
|
||||||
errorStr = String::ToString("Shape \"%s\" does not match version on server.",name);
|
errorStr = String::ToString("Shape asset\"%s\" does not match version on server.", mShapeAsset[i]->getAssetId());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resolve nodes & build mount transform
|
// Resolve nodes & build mount transform
|
||||||
eyeMountNode[i] = shape[i]->findNode("eyeMount");
|
eyeMountNode[i] = mShape[i]->findNode("eyeMount");
|
||||||
eyeNode[i] = shape[i]->findNode("eye");
|
eyeNode[i] = mShape[i]->findNode("eye");
|
||||||
if (eyeNode[i] == -1)
|
if (eyeNode[i] == -1)
|
||||||
eyeNode[i] = eyeMountNode[i];
|
eyeNode[i] = eyeMountNode[i];
|
||||||
ejectNode[i] = shape[i]->findNode("ejectPoint");
|
ejectNode[i] = mShape[i]->findNode("ejectPoint");
|
||||||
muzzleNode[i] = shape[i]->findNode("muzzlePoint");
|
muzzleNode[i] = mShape[i]->findNode("muzzlePoint");
|
||||||
retractNode[i] = shape[i]->findNode("retractionPoint");
|
retractNode[i] = mShape[i]->findNode("retractionPoint");
|
||||||
mountTransform[i] = mountOffset;
|
mountTransform[i] = mountOffset;
|
||||||
S32 node = shape[i]->findNode("mountPoint");
|
S32 node = mShape[i]->findNode("mountPoint");
|
||||||
if (node != -1) {
|
if (node != -1) {
|
||||||
MatrixF total(1);
|
MatrixF total(1);
|
||||||
do {
|
do {
|
||||||
MatrixF nmat;
|
MatrixF nmat;
|
||||||
QuatF q;
|
QuatF q;
|
||||||
TSTransform::setMatrix(shape[i]->defaultRotations[node].getQuatF(&q),shape[i]->defaultTranslations[node],&nmat);
|
TSTransform::setMatrix(mShape[i]->defaultRotations[node].getQuatF(&q), mShape[i]->defaultTranslations[node],&nmat);
|
||||||
total.mul(nmat);
|
total.mul(nmat);
|
||||||
node = shape[i]->nodes[node].parentIndex;
|
node = mShape[i]->nodes[node].parentIndex;
|
||||||
}
|
}
|
||||||
while(node != -1);
|
while(node != -1);
|
||||||
total.inverse();
|
total.inverse();
|
||||||
|
|
@ -514,7 +511,7 @@ bool ShapeBaseImageData::preload(bool server, String &errorStr)
|
||||||
for (U32 j = 0; j < MaxStates; j++) {
|
for (U32 j = 0; j < MaxStates; j++) {
|
||||||
StateData& s = state[j];
|
StateData& s = state[j];
|
||||||
if (stateSequence[j] && stateSequence[j][0])
|
if (stateSequence[j] && stateSequence[j][0])
|
||||||
s.sequence[i] = shape[i]->findSequence(stateSequence[j]);
|
s.sequence[i] = mShape[i]->findSequence(stateSequence[j]);
|
||||||
if (s.sequence[i] != -1)
|
if (s.sequence[i] != -1)
|
||||||
{
|
{
|
||||||
// This state has an animation sequence
|
// This state has an animation sequence
|
||||||
|
|
@ -525,7 +522,7 @@ bool ShapeBaseImageData::preload(bool server, String &errorStr)
|
||||||
char bufferVis[128];
|
char bufferVis[128];
|
||||||
dStrncpy(bufferVis, stateSequence[j], 100);
|
dStrncpy(bufferVis, stateSequence[j], 100);
|
||||||
dStrcat(bufferVis, "_vis", 128);
|
dStrcat(bufferVis, "_vis", 128);
|
||||||
s.sequenceVis[i] = shape[i]->findSequence(bufferVis);
|
s.sequenceVis[i] = mShape[i]->findSequence(bufferVis);
|
||||||
}
|
}
|
||||||
if (s.sequenceVis[i] != -1)
|
if (s.sequenceVis[i] != -1)
|
||||||
{
|
{
|
||||||
|
|
@ -537,13 +534,13 @@ bool ShapeBaseImageData::preload(bool server, String &errorStr)
|
||||||
s.ignoreLoadedForReady = stateIgnoreLoadedForReady[j];
|
s.ignoreLoadedForReady = stateIgnoreLoadedForReady[j];
|
||||||
|
|
||||||
if (stateEmitterNode[j] && stateEmitterNode[j][0])
|
if (stateEmitterNode[j] && stateEmitterNode[j][0])
|
||||||
s.emitterNode[i] = shape[i]->findNode(stateEmitterNode[j]);
|
s.emitterNode[i] = mShape[i]->findNode(stateEmitterNode[j]);
|
||||||
if (s.emitterNode[i] == -1)
|
if (s.emitterNode[i] == -1)
|
||||||
s.emitterNode[i] = muzzleNode[i];
|
s.emitterNode[i] = muzzleNode[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
ambientSequence[i] = shape[i]->findSequence("ambient");
|
ambientSequence[i] = mShape[i]->findSequence("ambient");
|
||||||
spinSequence[i] = shape[i]->findSequence("spin");
|
spinSequence[i] = mShape[i]->findSequence("spin");
|
||||||
|
|
||||||
shapeIsValid[i] = true;
|
shapeIsValid[i] = true;
|
||||||
}
|
}
|
||||||
|
|
@ -567,7 +564,7 @@ bool ShapeBaseImageData::preload(bool server, String &errorStr)
|
||||||
{
|
{
|
||||||
if( shapeIsValid[i] )
|
if( shapeIsValid[i] )
|
||||||
{
|
{
|
||||||
TSShapeInstance* pDummy = new TSShapeInstance(shape[i], !server);
|
TSShapeInstance* pDummy = new TSShapeInstance(mShape[i], !server);
|
||||||
delete pDummy;
|
delete pDummy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -590,19 +587,9 @@ void ShapeBaseImageData::initPersistFields()
|
||||||
addField( "emap", TypeBool, Offset(emap, ShapeBaseImageData),
|
addField( "emap", TypeBool, Offset(emap, ShapeBaseImageData),
|
||||||
"@brief Whether to enable environment mapping on this Image.\n\n" );
|
"@brief Whether to enable environment mapping on this Image.\n\n" );
|
||||||
|
|
||||||
addField( "shapeFile", TypeShapeFilename, Offset(shapeName, ShapeBaseImageData),
|
INITPERSISTFIELD_SHAPEASSET_ARRAY(Shape, MaxShapes, ShapeBaseImageData, "The shape asset to use for this image in the third person")
|
||||||
"@brief The DTS or DAE model to use for this Image.\n\n" );
|
|
||||||
|
|
||||||
addField( "shapeFileFP", TypeShapeFilename, Offset(shapeNameFP, ShapeBaseImageData),
|
//addProtectedField("shapeFileFP", TypeShapeFilename, Offset(mShapeName[1], ShapeBaseImageData), _setShapeData, defaultProtectedGetFn, "deprecated alias for ShapeFPFile/Asset", AbstractClassRep::FIELD_HideInInspectors);
|
||||||
"@brief The DTS or DAE model to use for this Image when in first person.\n\n"
|
|
||||||
"This is an optional parameter that also requires either eyeOffset or useEyeNode "
|
|
||||||
"to be set. If none of these conditions is met then shapeFile will be used "
|
|
||||||
"for all cases.\n\n"
|
|
||||||
"Typically you set a first person image for a weapon that "
|
|
||||||
"includes the player's arms attached to it for animating while firing, "
|
|
||||||
"reloading, etc. This is typical of many FPS games."
|
|
||||||
"@see eyeOffset\n"
|
|
||||||
"@see useEyeNode\n");
|
|
||||||
|
|
||||||
addField( "imageAnimPrefix", TypeCaseString, Offset(imageAnimPrefix, ShapeBaseImageData),
|
addField( "imageAnimPrefix", TypeCaseString, Offset(imageAnimPrefix, ShapeBaseImageData),
|
||||||
"@brief Passed along to the mounting shape to modify animation sequences played in third person. [optional]\n\n" );
|
"@brief Passed along to the mounting shape to modify animation sequences played in third person. [optional]\n\n" );
|
||||||
|
|
@ -987,8 +974,10 @@ void ShapeBaseImageData::packData(BitStream* stream)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stream->writeString(shapeName); // shape 0 for normal use
|
for (U32 j = 0; j < MaxShapes; ++j)
|
||||||
stream->writeString(shapeNameFP); // shape 1 for first person use (optional)
|
{
|
||||||
|
PACKDATA_SHAPEASSET_ARRAY(Shape, j); // shape 0 for normal use, shape 1 for first person use (optional)
|
||||||
|
}
|
||||||
|
|
||||||
stream->writeString(imageAnimPrefix);
|
stream->writeString(imageAnimPrefix);
|
||||||
stream->writeString(imageAnimPrefixFP);
|
stream->writeString(imageAnimPrefixFP);
|
||||||
|
|
@ -1169,8 +1158,10 @@ void ShapeBaseImageData::unpackData(BitStream* stream)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
shapeName = stream->readSTString(); // shape 0 for normal use
|
for (U32 j = 0; j < MaxShapes; ++j)
|
||||||
shapeNameFP = stream->readSTString(); // shape 1 for first person use (optional)
|
{
|
||||||
|
UNPACKDATA_SHAPEASSET_ARRAY(Shape, j); // shape 0 for normal use, shape 1 for first person use (optional)
|
||||||
|
}
|
||||||
|
|
||||||
imageAnimPrefix = stream->readSTString();
|
imageAnimPrefix = stream->readSTString();
|
||||||
imageAnimPrefixFP = stream->readSTString();
|
imageAnimPrefixFP = stream->readSTString();
|
||||||
|
|
@ -2128,7 +2119,7 @@ S32 ShapeBase::getNodeIndex(U32 imageSlot,StringTableEntry nodeName)
|
||||||
{
|
{
|
||||||
MountedImage& image = mMountedImageList[imageSlot];
|
MountedImage& image = mMountedImageList[imageSlot];
|
||||||
if (image.dataBlock)
|
if (image.dataBlock)
|
||||||
return image.dataBlock->shape[getImageShapeIndex(image)]->findNode(nodeName);
|
return image.dataBlock->mShape[getImageShapeIndex(image)]->findNode(nodeName);
|
||||||
else
|
else
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -2318,7 +2309,7 @@ void ShapeBase::setImage( U32 imageSlot,
|
||||||
for (U32 i=0; i<ShapeBaseImageData::MaxShapes; ++i)
|
for (U32 i=0; i<ShapeBaseImageData::MaxShapes; ++i)
|
||||||
{
|
{
|
||||||
if (image.dataBlock->shapeIsValid[i])
|
if (image.dataBlock->shapeIsValid[i])
|
||||||
image.shapeInstance[i] = new TSShapeInstance(image.dataBlock->shape[i], isClientObject());
|
image.shapeInstance[i] = new TSShapeInstance(image.dataBlock->mShape[i], isClientObject());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isClientObject())
|
if (isClientObject())
|
||||||
|
|
|
||||||
|
|
@ -114,7 +114,6 @@ TSStatic::TSStatic()
|
||||||
|
|
||||||
mTypeMask |= StaticObjectType | StaticShapeObjectType;
|
mTypeMask |= StaticObjectType | StaticShapeObjectType;
|
||||||
|
|
||||||
mShapeName = "";
|
|
||||||
mShapeInstance = NULL;
|
mShapeInstance = NULL;
|
||||||
|
|
||||||
mPlayAmbient = true;
|
mPlayAmbient = true;
|
||||||
|
|
@ -150,8 +149,7 @@ TSStatic::TSStatic()
|
||||||
mAnimOffset = 0.0f;
|
mAnimOffset = 0.0f;
|
||||||
mAnimSpeed = 1.0f;
|
mAnimSpeed = 1.0f;
|
||||||
|
|
||||||
mShapeAsset = StringTable->EmptyString();
|
INIT_SHAPEASSET(Shape);
|
||||||
mShapeAssetId = StringTable->EmptyString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TSStatic::~TSStatic()
|
TSStatic::~TSStatic()
|
||||||
|
|
@ -184,13 +182,11 @@ void TSStatic::initPersistFields()
|
||||||
"Percent Animation Speed.");
|
"Percent Animation Speed.");
|
||||||
addGroup("Shape");
|
addGroup("Shape");
|
||||||
|
|
||||||
addProtectedField("shapeAsset", TypeShapeAssetId, Offset(mShapeAssetId, TSStatic),
|
INITPERSISTFIELD_SHAPEASSET(Shape, TSStatic, "Model to use for this TSStatic");
|
||||||
&TSStatic::_setShapeAsset, &defaultProtectedGetFn,
|
|
||||||
"The source shape asset.");
|
|
||||||
|
|
||||||
addProtectedField("shapeName", TypeShapeFilename, Offset(mShapeName, TSStatic),
|
addProtectedField("shapeName", TypeShapeFilename, Offset(mShapeName, TSStatic),
|
||||||
&TSStatic::_setShapeName, &defaultProtectedGetFn,
|
&TSStatic::_setShapeData, &defaultProtectedGetFn,
|
||||||
"%Path and filename of the model file (.DTS, .DAE) to use for this TSStatic. Legacy field. Any loose files assigned here will attempt to be auto-imported in as an asset.");
|
"%Path and filename of the model file (.DTS, .DAE) to use for this TSStatic. Legacy field. Any loose files assigned here will attempt to be auto-imported in as an asset.", AbstractClassRep::FIELD_HideInInspectors);
|
||||||
|
|
||||||
endGroup("Shape");
|
endGroup("Shape");
|
||||||
|
|
||||||
|
|
@ -287,50 +283,6 @@ void TSStatic::consoleInit()
|
||||||
Con::addVariable("$pref::staticObjectUnfadeableSize", TypeF32, &TSStatic::smStaticObjectUnfadeableSize, "Size of object where if the bounds is at or bigger than this, it will be ignored in the $pref::useStaticObjectFade logic. Useful for very large, distance-important objects.\n");
|
Con::addVariable("$pref::staticObjectUnfadeableSize", TypeF32, &TSStatic::smStaticObjectUnfadeableSize, "Size of object where if the bounds is at or bigger than this, it will be ignored in the $pref::useStaticObjectFade logic. Useful for very large, distance-important objects.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TSStatic::_setShapeAsset(void* obj, const char* index, const char* data)
|
|
||||||
{
|
|
||||||
TSStatic* ts = static_cast<TSStatic*>(obj);// ->setFile(FileName(data));
|
|
||||||
|
|
||||||
ts->mShapeAssetId = StringTable->insert(data);
|
|
||||||
|
|
||||||
return ts->setShapeAsset(ts->mShapeAssetId);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TSStatic::_setShapeName(void* obj, const char* index, const char* data)
|
|
||||||
{
|
|
||||||
TSStatic* ts = static_cast<TSStatic*>(obj);// ->setFile(FileName(data));
|
|
||||||
|
|
||||||
StringTableEntry assetId = ShapeAsset::getAssetIdByFilename(StringTable->insert(data));
|
|
||||||
if (assetId != StringTable->EmptyString())
|
|
||||||
{
|
|
||||||
//Special exception case. If we've defaulted to the 'no shape' mesh, don't save it out, we'll retain the original ids/paths so it doesn't break
|
|
||||||
//the TSStatic
|
|
||||||
if (ts->setShapeAsset(assetId))
|
|
||||||
{
|
|
||||||
if (assetId == StringTable->insert("Core_Rendering:noShape"))
|
|
||||||
{
|
|
||||||
ts->mShapeName = data;
|
|
||||||
ts->mShapeAssetId = StringTable->EmptyString();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ts->mShapeAssetId = assetId;
|
|
||||||
ts->mShapeName = StringTable->EmptyString();
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ts->mShapeAsset = StringTable->EmptyString();
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TSStatic::_setFieldSkin(void* object, const char* index, const char* data)
|
bool TSStatic::_setFieldSkin(void* object, const char* index, const char* data)
|
||||||
{
|
{
|
||||||
TSStatic* ts = static_cast<TSStatic*>(object);
|
TSStatic* ts = static_cast<TSStatic*>(object);
|
||||||
|
|
@ -425,34 +377,6 @@ bool TSStatic::onAdd()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TSStatic::setShapeAsset(const StringTableEntry shapeAssetId)
|
|
||||||
{
|
|
||||||
if (!mShapeAsset.isNull())
|
|
||||||
{
|
|
||||||
mShapeAsset->getChangedSignal().remove(this, &TSStatic::_onAssetChanged);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ShapeAsset::getAssetById(shapeAssetId, &mShapeAsset))
|
|
||||||
{
|
|
||||||
//Special exception case. If we've defaulted to the 'no shape' mesh, don't save it out, we'll retain the original ids/paths so it doesn't break
|
|
||||||
//the TSStatic
|
|
||||||
if (mShapeAsset.getAssetId() != StringTable->insert("Core_Rendering:noshape"))
|
|
||||||
{
|
|
||||||
mShapeName = StringTable->EmptyString();
|
|
||||||
|
|
||||||
mShapeAsset->getChangedSignal().notify(this, &TSStatic::_onAssetChanged);
|
|
||||||
}
|
|
||||||
|
|
||||||
_createShape();
|
|
||||||
|
|
||||||
setMaskBits(-1);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TSStatic::_createShape()
|
bool TSStatic::_createShape()
|
||||||
{
|
{
|
||||||
// Cleanup before we create.
|
// Cleanup before we create.
|
||||||
|
|
@ -674,9 +598,6 @@ void TSStatic::onRemove()
|
||||||
if (isClientObject())
|
if (isClientObject())
|
||||||
mCubeReflector.unregisterReflector();
|
mCubeReflector.unregisterReflector();
|
||||||
|
|
||||||
if(!mShapeAsset.isNull())
|
|
||||||
mShapeAsset->getChangedSignal().remove(this, &TSStatic::_onAssetChanged);
|
|
||||||
|
|
||||||
Parent::onRemove();
|
Parent::onRemove();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -689,7 +610,7 @@ void TSStatic::_onResourceChanged(const Torque::Path& path)
|
||||||
_updateShouldTick();
|
_updateShouldTick();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TSStatic::_onAssetChanged()
|
void TSStatic::onShapeChanged()
|
||||||
{
|
{
|
||||||
_createShape();
|
_createShape();
|
||||||
_updateShouldTick();
|
_updateShouldTick();
|
||||||
|
|
@ -1037,8 +958,7 @@ U32 TSStatic::packUpdate(NetConnection* con, U32 mask, BitStream* stream)
|
||||||
|
|
||||||
if (stream->writeFlag(mask & AdvancedStaticOptionsMask))
|
if (stream->writeFlag(mask & AdvancedStaticOptionsMask))
|
||||||
{
|
{
|
||||||
stream->writeString(mShapeAsset.getAssetId());
|
PACK_SHAPEASSET(con, Shape);
|
||||||
stream->writeString(mShapeName);
|
|
||||||
|
|
||||||
stream->write((U32)mDecalType);
|
stream->write((U32)mDecalType);
|
||||||
|
|
||||||
|
|
@ -1153,11 +1073,7 @@ void TSStatic::unpackUpdate(NetConnection* con, BitStream* stream)
|
||||||
|
|
||||||
if (stream->readFlag()) // AdvancedStaticOptionsMask
|
if (stream->readFlag()) // AdvancedStaticOptionsMask
|
||||||
{
|
{
|
||||||
char buffer[256];
|
UNPACK_SHAPEASSET(con, Shape);
|
||||||
stream->readString(buffer);
|
|
||||||
setShapeAsset(StringTable->insert(buffer));
|
|
||||||
|
|
||||||
mShapeName = stream->readSTString();
|
|
||||||
|
|
||||||
stream->read((U32*)&mDecalType);
|
stream->read((U32*)&mDecalType);
|
||||||
|
|
||||||
|
|
@ -1676,7 +1592,7 @@ void TSStatic::updateMaterials()
|
||||||
|
|
||||||
String path;
|
String path;
|
||||||
if (mShapeAsset->isAssetValid())
|
if (mShapeAsset->isAssetValid())
|
||||||
path = mShapeAsset->getShapeFilename();
|
path = mShapeAsset->getShapeFileName();
|
||||||
else
|
else
|
||||||
path = mShapeName;
|
path = mShapeName;
|
||||||
|
|
||||||
|
|
@ -1709,9 +1625,8 @@ void TSStatic::updateMaterials()
|
||||||
|
|
||||||
void TSStatic::getUtilizedAssets(Vector<StringTableEntry>* usedAssetsList)
|
void TSStatic::getUtilizedAssets(Vector<StringTableEntry>* usedAssetsList)
|
||||||
{
|
{
|
||||||
if(!mShapeAsset.isNull() && mShapeAsset->getAssetId() != StringTable->insert("Core_Rendering:noShape"))
|
if(!mShapeAsset.isNull() && mShapeAsset->getAssetId() != ShapeAsset::smNoShapeAssetFallback)
|
||||||
usedAssetsList->push_back_unique(mShapeAsset->getAssetId());
|
usedAssetsList->push_back_unique(mShapeAsset->getAssetId());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------
|
//------------------------------------------------------------------------
|
||||||
|
|
@ -1874,7 +1789,7 @@ DefineEngineMethod(TSStatic, changeMaterial, void, (const char* mapTo, Material*
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
TSMaterialList* shapeMaterialList = object->getShape()->materialList;
|
TSMaterialList* shapeMaterialList = object->getShapeResource()->materialList;
|
||||||
|
|
||||||
// Check the mapTo name exists for this shape
|
// Check the mapTo name exists for this shape
|
||||||
S32 matIndex = shapeMaterialList->getMaterialNameList().find_next(String(mapTo));
|
S32 matIndex = shapeMaterialList->getMaterialNameList().find_next(String(mapTo));
|
||||||
|
|
@ -1914,7 +1829,7 @@ DefineEngineMethod(TSStatic, getModelFile, const char*, (), ,
|
||||||
"@endtsexample\n"
|
"@endtsexample\n"
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return object->getShapeFileName();
|
return object->getShape();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TSStatic::set_special_typing()
|
void TSStatic::set_special_typing()
|
||||||
|
|
|
||||||
|
|
@ -163,8 +163,6 @@ protected:
|
||||||
bool buildExportPolyList(ColladaUtils::ExportData* exportData, const Box3F& box, const SphereF&);
|
bool buildExportPolyList(ColladaUtils::ExportData* exportData, const Box3F& box, const SphereF&);
|
||||||
void buildConvex(const Box3F& box, Convex* convex);
|
void buildConvex(const Box3F& box, Convex* convex);
|
||||||
|
|
||||||
bool setShapeAsset(const StringTableEntry shapeAssetId);
|
|
||||||
|
|
||||||
bool _createShape();
|
bool _createShape();
|
||||||
|
|
||||||
void _updatePhysics();
|
void _updatePhysics();
|
||||||
|
|
@ -172,7 +170,7 @@ protected:
|
||||||
void _renderNormals(ObjectRenderInst* ri, SceneRenderState* state, BaseMatInstance* overrideMat);
|
void _renderNormals(ObjectRenderInst* ri, SceneRenderState* state, BaseMatInstance* overrideMat);
|
||||||
|
|
||||||
void _onResourceChanged(const Torque::Path& path);
|
void _onResourceChanged(const Torque::Path& path);
|
||||||
void _onAssetChanged();
|
void onShapeChanged();
|
||||||
|
|
||||||
// ProcessObject
|
// ProcessObject
|
||||||
virtual void processTick(const Move* move);
|
virtual void processTick(const Move* move);
|
||||||
|
|
@ -193,16 +191,14 @@ protected:
|
||||||
|
|
||||||
Convex* mConvexList;
|
Convex* mConvexList;
|
||||||
|
|
||||||
StringTableEntry mShapeName;
|
DECLARE_SHAPEASSET(TSStatic, Shape, onShapeChanged);
|
||||||
|
DECLARE_SHAPEASSET_NET_SETGET(TSStatic, Shape, AdvancedStaticOptionsMask);
|
||||||
|
|
||||||
U32 mShapeHash;
|
U32 mShapeHash;
|
||||||
Resource<TSShape> mShape;
|
|
||||||
Vector<S32> mCollisionDetails;
|
Vector<S32> mCollisionDetails;
|
||||||
Vector<S32> mLOSDetails;
|
Vector<S32> mLOSDetails;
|
||||||
TSShapeInstance* mShapeInstance;
|
TSShapeInstance* mShapeInstance;
|
||||||
|
|
||||||
AssetPtr<ShapeAsset> mShapeAsset;
|
|
||||||
StringTableEntry mShapeAssetId;
|
|
||||||
|
|
||||||
NetStringHandle mSkinNameHandle;
|
NetStringHandle mSkinNameHandle;
|
||||||
String mAppliedSkinName;
|
String mAppliedSkinName;
|
||||||
|
|
||||||
|
|
@ -242,8 +238,6 @@ public:
|
||||||
DECLARE_CONOBJECT(TSStatic);
|
DECLARE_CONOBJECT(TSStatic);
|
||||||
static void initPersistFields();
|
static void initPersistFields();
|
||||||
static void consoleInit();
|
static void consoleInit();
|
||||||
static bool _setShapeAsset(void* obj, const char* index, const char* data);
|
|
||||||
static bool _setShapeName(void* obj, const char* index, const char* data);
|
|
||||||
static bool _setFieldSkin(void* object, const char* index, const char* data);
|
static bool _setFieldSkin(void* object, const char* index, const char* data);
|
||||||
static const char* _getFieldSkin(void* object, const char* data);
|
static const char* _getFieldSkin(void* object, const char* data);
|
||||||
|
|
||||||
|
|
@ -268,10 +262,6 @@ public:
|
||||||
|
|
||||||
bool allowPlayerStep() const { return mAllowPlayerStep; }
|
bool allowPlayerStep() const { return mAllowPlayerStep; }
|
||||||
|
|
||||||
Resource<TSShape> getShape() const { return mShape; }
|
|
||||||
StringTableEntry getShapeFileName() { return mShapeName; }
|
|
||||||
void setShapeFileName(StringTableEntry shapeName) { mShapeName = shapeName; }
|
|
||||||
|
|
||||||
TSShapeInstance* getShapeInstance() const { return mShapeInstance; }
|
TSShapeInstance* getShapeInstance() const { return mShapeInstance; }
|
||||||
|
|
||||||
U32 getNumDetails();
|
U32 getNumDetails();
|
||||||
|
|
|
||||||
|
|
@ -208,7 +208,7 @@ bool VehicleData::preload(bool server, String &errorStr)
|
||||||
if (!collisionDetails.size() || collisionDetails[0] == -1)
|
if (!collisionDetails.size() || collisionDetails[0] == -1)
|
||||||
{
|
{
|
||||||
Con::errorf("VehicleData::preload failed: Vehicle models must define a collision-1 detail");
|
Con::errorf("VehicleData::preload failed: Vehicle models must define a collision-1 detail");
|
||||||
errorStr = String::ToString("VehicleData: Couldn't load shape \"%s\"", mShapeName);
|
errorStr = String::ToString("VehicleData: Couldn't load shape asset \"%s\"", mShapeAsset.getAssetId());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -75,8 +75,8 @@ ConsoleDocClass( WheeledVehicleTire,
|
||||||
|
|
||||||
WheeledVehicleTire::WheeledVehicleTire()
|
WheeledVehicleTire::WheeledVehicleTire()
|
||||||
{
|
{
|
||||||
shape = 0;
|
INIT_SHAPEASSET(Shape);
|
||||||
shapeName = "";
|
|
||||||
staticFriction = 1;
|
staticFriction = 1;
|
||||||
kineticFriction = 0.5f;
|
kineticFriction = 0.5f;
|
||||||
restitution = 1;
|
restitution = 1;
|
||||||
|
|
@ -94,21 +94,17 @@ bool WheeledVehicleTire::preload(bool server, String &errorStr)
|
||||||
{
|
{
|
||||||
// Load up the tire shape. ShapeBase has an option to force a
|
// Load up the tire shape. ShapeBase has an option to force a
|
||||||
// CRC check, this is left out here, but could be easily added.
|
// CRC check, this is left out here, but could be easily added.
|
||||||
if (shapeName && shapeName[0])
|
if (!mShape)
|
||||||
|
{
|
||||||
|
errorStr = String::ToString("WheeledVehicleTire: Couldn't load shape \"%s\"", mShapeAssetId);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
// Load up the shape resource
|
|
||||||
shape = ResourceManager::get().load(shapeName);
|
|
||||||
if (!bool(shape))
|
|
||||||
{
|
|
||||||
errorStr = String::ToString("WheeledVehicleTire: Couldn't load shape \"%s\"",shapeName);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Determinw wheel radius from the shape's bounding box.
|
// Determinw wheel radius from the shape's bounding box.
|
||||||
// The tire should be built with it's hub axis along the
|
// The tire should be built with it's hub axis along the
|
||||||
// object's Y axis.
|
// object's Y axis.
|
||||||
radius = shape->mBounds.len_z() / 2;
|
radius = mShape->mBounds.len_z() / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -116,8 +112,8 @@ bool WheeledVehicleTire::preload(bool server, String &errorStr)
|
||||||
|
|
||||||
void WheeledVehicleTire::initPersistFields()
|
void WheeledVehicleTire::initPersistFields()
|
||||||
{
|
{
|
||||||
addField( "shapeFile",TypeShapeFilename,Offset(shapeName,WheeledVehicleTire),
|
INITPERSISTFIELD_SHAPEASSET(Shape, WheeledVehicleTire, "The shape to use for the wheel.");
|
||||||
"The path to the shape to use for the wheel." );
|
|
||||||
addField( "mass", TypeF32, Offset(mass, WheeledVehicleTire),
|
addField( "mass", TypeF32, Offset(mass, WheeledVehicleTire),
|
||||||
"The mass of the wheel.\nCurrently unused." );
|
"The mass of the wheel.\nCurrently unused." );
|
||||||
addField( "radius", TypeF32, Offset(radius, WheeledVehicleTire),
|
addField( "radius", TypeF32, Offset(radius, WheeledVehicleTire),
|
||||||
|
|
@ -181,7 +177,8 @@ void WheeledVehicleTire::packData(BitStream* stream)
|
||||||
{
|
{
|
||||||
Parent::packData(stream);
|
Parent::packData(stream);
|
||||||
|
|
||||||
stream->writeString(shapeName);
|
PACKDATA_SHAPEASSET(Shape);
|
||||||
|
|
||||||
stream->write(mass);
|
stream->write(mass);
|
||||||
stream->write(staticFriction);
|
stream->write(staticFriction);
|
||||||
stream->write(kineticFriction);
|
stream->write(kineticFriction);
|
||||||
|
|
@ -199,7 +196,8 @@ void WheeledVehicleTire::unpackData(BitStream* stream)
|
||||||
{
|
{
|
||||||
Parent::unpackData(stream);
|
Parent::unpackData(stream);
|
||||||
|
|
||||||
shapeName = stream->readSTString();
|
UNPACKDATA_SHAPEASSET(Shape);
|
||||||
|
|
||||||
stream->read(&mass);
|
stream->read(&mass);
|
||||||
stream->read(&staticFriction);
|
stream->read(&staticFriction);
|
||||||
stream->read(&kineticFriction);
|
stream->read(&kineticFriction);
|
||||||
|
|
@ -1542,8 +1540,8 @@ void WheeledVehicle::unpackUpdate(NetConnection *con, BitStream *stream)
|
||||||
|
|
||||||
// Create an instance of the tire for rendering
|
// Create an instance of the tire for rendering
|
||||||
delete wheel->shapeInstance;
|
delete wheel->shapeInstance;
|
||||||
wheel->shapeInstance = (wheel->tire->shape == NULL) ? 0:
|
wheel->shapeInstance = (wheel->tire->mShape == NULL) ? 0:
|
||||||
new TSShapeInstance(wheel->tire->shape);
|
new TSShapeInstance(wheel->tire->mShape);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,8 @@
|
||||||
#include "collision/clippedPolyList.h"
|
#include "collision/clippedPolyList.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "T3D/assets/ShapeAsset.h"
|
||||||
|
|
||||||
class ParticleEmitter;
|
class ParticleEmitter;
|
||||||
class ParticleEmitterData;
|
class ParticleEmitterData;
|
||||||
|
|
||||||
|
|
@ -41,8 +43,8 @@ struct WheeledVehicleTire: public SimDataBlock
|
||||||
{
|
{
|
||||||
typedef SimDataBlock Parent;
|
typedef SimDataBlock Parent;
|
||||||
|
|
||||||
//
|
DECLARE_SHAPEASSET(WheeledVehicleTire, Shape, onShapeChanged);
|
||||||
StringTableEntry shapeName;// Max shape to render
|
DECLARE_SHAPEASSET_SETGET(WheeledVehicleTire, Shape);
|
||||||
|
|
||||||
// Physical properties
|
// Physical properties
|
||||||
F32 mass; // Mass of the whole wheel
|
F32 mass; // Mass of the whole wheel
|
||||||
|
|
@ -62,7 +64,6 @@ struct WheeledVehicleTire: public SimDataBlock
|
||||||
F32 longitudinalRelaxation;
|
F32 longitudinalRelaxation;
|
||||||
|
|
||||||
// Shape information initialized in the preload
|
// Shape information initialized in the preload
|
||||||
Resource<TSShape> shape; // The loaded shape
|
|
||||||
F32 radius; // Tire radius
|
F32 radius; // Tire radius
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
@ -72,6 +73,8 @@ struct WheeledVehicleTire: public SimDataBlock
|
||||||
bool preload(bool, String &errorStr);
|
bool preload(bool, String &errorStr);
|
||||||
virtual void packData(BitStream* stream);
|
virtual void packData(BitStream* stream);
|
||||||
virtual void unpackData(BitStream* stream);
|
virtual void unpackData(BitStream* stream);
|
||||||
|
|
||||||
|
void onShapeChanged() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,7 @@ public:
|
||||||
virtual U32 packUpdate(NetConnection*, U32, BitStream*);
|
virtual U32 packUpdate(NetConnection*, U32, BitStream*);
|
||||||
virtual void unpackUpdate(NetConnection*, BitStream*);
|
virtual void unpackUpdate(NetConnection*, BitStream*);
|
||||||
|
|
||||||
const char* getShapeFileName() const { return mDataBlock->mShapeName; }
|
const char* getShapeFileName() const { return mDataBlock->mShapeAsset->getShapeFileName(); }
|
||||||
void setVisibility(bool flag) { mIs_visible = flag; }
|
void setVisibility(bool flag) { mIs_visible = flag; }
|
||||||
|
|
||||||
DECLARE_CONOBJECT(afxStaticShape);
|
DECLARE_CONOBJECT(afxStaticShape);
|
||||||
|
|
|
||||||
|
|
@ -146,7 +146,7 @@ void afxParticlePool::pool_renderObject_Normal(RenderPassManager *renderManager,
|
||||||
if (main_emitter_data->textureHandle)
|
if (main_emitter_data->textureHandle)
|
||||||
ri->diffuseTex = &*(main_emitter_data->textureHandle);
|
ri->diffuseTex = &*(main_emitter_data->textureHandle);
|
||||||
else
|
else
|
||||||
ri->diffuseTex = &*(main_emitter_data->particleDataBlocks[0]->textureHandle);
|
ri->diffuseTex = &*(main_emitter_data->particleDataBlocks[0]->getTextureResource());
|
||||||
|
|
||||||
ri->softnessDistance = main_emitter_data->softnessDistance;
|
ri->softnessDistance = main_emitter_data->softnessDistance;
|
||||||
|
|
||||||
|
|
@ -277,7 +277,7 @@ void afxParticlePool::pool_renderObject_TwoPass(RenderPassManager *renderManager
|
||||||
//if (main_emitter_data->textureHandle)
|
//if (main_emitter_data->textureHandle)
|
||||||
// ri->diffuseTex = &*(main_emitter_data->textureHandle);
|
// ri->diffuseTex = &*(main_emitter_data->textureHandle);
|
||||||
//else
|
//else
|
||||||
ri->diffuseTex = &*(main_emitter_data->particleDataBlocks[0]->textureExtHandle);
|
ri->diffuseTex = &*(main_emitter_data->particleDataBlocks[0]->getTextureExtResource());
|
||||||
|
|
||||||
F32 save_sort_dist = ri->sortDistSq;
|
F32 save_sort_dist = ri->sortDistSq;
|
||||||
|
|
||||||
|
|
@ -481,7 +481,7 @@ void afxParticlePool::pool_renderObject_TwoPass(RenderPassManager *renderManager
|
||||||
if (main_emitter_data->textureHandle)
|
if (main_emitter_data->textureHandle)
|
||||||
ri->diffuseTex = &*(main_emitter_data->textureHandle);
|
ri->diffuseTex = &*(main_emitter_data->textureHandle);
|
||||||
else
|
else
|
||||||
ri->diffuseTex = &*(main_emitter_data->particleDataBlocks[0]->textureHandle);
|
ri->diffuseTex = &*(main_emitter_data->particleDataBlocks[0]->getTextureResource());
|
||||||
|
|
||||||
ri->softnessDistance = main_emitter_data->softnessDistance;
|
ri->softnessDistance = main_emitter_data->softnessDistance;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,7 @@ mAssetInitialized(false)
|
||||||
mInternalName = StringTable->EmptyString();
|
mInternalName = StringTable->EmptyString();
|
||||||
mClassName = StringTable->EmptyString();
|
mClassName = StringTable->EmptyString();
|
||||||
mSuperClassName = StringTable->EmptyString();
|
mSuperClassName = StringTable->EmptyString();
|
||||||
|
mLoadedState = AssetErrCode::NotLoaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
@ -315,6 +316,32 @@ S32 AssetBase::getAssetDependencyFieldCount(const char* pFieldName)
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
StringTableEntry AssetBase::getAssetDependencyField(const char* pFieldName, S32 index)
|
||||||
|
{
|
||||||
|
SimFieldDictionary* fieldDictionary = getFieldDictionary();
|
||||||
|
for (SimFieldDictionaryIterator itr(fieldDictionary); *itr; ++itr)
|
||||||
|
{
|
||||||
|
SimFieldDictionary::Entry* entry = *itr;
|
||||||
|
|
||||||
|
String slotName = String(entry->slotName);
|
||||||
|
|
||||||
|
if (slotName.startsWith(pFieldName))
|
||||||
|
{
|
||||||
|
S32 trailingNum;
|
||||||
|
String::GetTrailingNumber(slotName.c_str(), trailingNum);
|
||||||
|
|
||||||
|
if (trailingNum == index)
|
||||||
|
{
|
||||||
|
return StringTable->insert(String(entry->value).replace(ASSET_ID_FIELD_PREFIX, "").c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return StringTable->EmptyString();
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
void AssetBase::clearAssetDependencyFields(const char* pFieldName)
|
void AssetBase::clearAssetDependencyFields(const char* pFieldName)
|
||||||
{
|
{
|
||||||
SimFieldDictionary* fieldDictionary = getFieldDictionary();
|
SimFieldDictionary* fieldDictionary = getFieldDictionary();
|
||||||
|
|
@ -340,7 +367,7 @@ void AssetBase::addAssetDependencyField(const char* pFieldName, const char* pAss
|
||||||
dSprintf(depSlotName, sizeof(depSlotName), "%s%d", pFieldName, existingFieldCount);
|
dSprintf(depSlotName, sizeof(depSlotName), "%s%d", pFieldName, existingFieldCount);
|
||||||
|
|
||||||
char depValue[255];
|
char depValue[255];
|
||||||
dSprintf(depValue, sizeof(depValue), "@Asset=%s", pAssetId);
|
dSprintf(depValue, sizeof(depValue), "%s=%s", ASSET_ID_SIGNATURE, pAssetId);
|
||||||
|
|
||||||
setDataField(StringTable->insert(depSlotName), NULL, StringTable->insert(depValue));
|
setDataField(StringTable->insert(depSlotName), NULL, StringTable->insert(depValue));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,7 @@ protected:
|
||||||
bool mAssetInitialized;
|
bool mAssetInitialized;
|
||||||
AssetDefinition* mpAssetDefinition;
|
AssetDefinition* mpAssetDefinition;
|
||||||
U32 mAcquireReferenceCount;
|
U32 mAcquireReferenceCount;
|
||||||
|
U32 mLoadedState;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum AssetErrCode
|
enum AssetErrCode
|
||||||
|
|
@ -87,7 +88,7 @@ public:
|
||||||
if (errCode > AssetErrCode::Extended) return "undefined error";
|
if (errCode > AssetErrCode::Extended) return "undefined error";
|
||||||
return mErrCodeStrings[errCode];
|
return mErrCodeStrings[errCode];
|
||||||
};
|
};
|
||||||
|
U32 getStatus() { return mLoadedState; };
|
||||||
AssetBase();
|
AssetBase();
|
||||||
virtual ~AssetBase();
|
virtual ~AssetBase();
|
||||||
|
|
||||||
|
|
@ -124,6 +125,7 @@ public:
|
||||||
void refreshAsset(void);
|
void refreshAsset(void);
|
||||||
|
|
||||||
S32 getAssetDependencyFieldCount(const char* pFieldName);
|
S32 getAssetDependencyFieldCount(const char* pFieldName);
|
||||||
|
StringTableEntry getAssetDependencyField(const char* pFieldName, S32 index = 0);
|
||||||
void clearAssetDependencyFields(const char* pFieldName);
|
void clearAssetDependencyFields(const char* pFieldName);
|
||||||
void addAssetDependencyField(const char* pFieldName, const char* pAssetId);
|
void addAssetDependencyField(const char* pFieldName, const char* pAssetId);
|
||||||
|
|
||||||
|
|
@ -167,5 +169,10 @@ private:
|
||||||
void setOwned(AssetManager* pAssetManager, AssetDefinition* pAssetDefinition);
|
void setOwned(AssetManager* pAssetManager, AssetDefinition* pAssetDefinition);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//helper macro for stitching string and non string values togeather sans quotes
|
||||||
|
#define assetText(x,suff) #x#suff
|
||||||
|
#define macroText(x) #x
|
||||||
|
#define assetDoc(x,suff) "@brief "#x" "#suff
|
||||||
|
|
||||||
#endif // _ASSET_BASE_H_
|
#endif // _ASSET_BASE_H_
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,15 @@ DefineEngineMethod(AssetBase, getAssetDependencyFieldCount, S32, (const char* pF
|
||||||
return object->getAssetDependencyFieldCount(pFieldName);
|
return object->getAssetDependencyFieldCount(pFieldName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DefineEngineMethod(AssetBase, getAssetDependencyField, const char*, (const char* pFieldName, S32 index), ("", 0),
|
||||||
|
"Gets an asset dependency field to the asset definition at a given index.\n"
|
||||||
|
"@param fieldName The name of the field.\n"
|
||||||
|
"@param index The index of the field to look up in the event there are multiple dependency fields. Defaults to 0"
|
||||||
|
"@return The assetID assigned to the given dependency field.\n")
|
||||||
|
{
|
||||||
|
return object->getAssetDependencyField(pFieldName, index);
|
||||||
|
}
|
||||||
|
|
||||||
DefineEngineMethod(AssetBase, clearAssetDependencyFields, void, (const char* pFieldName), (""),
|
DefineEngineMethod(AssetBase, clearAssetDependencyFields, void, (const char* pFieldName), (""),
|
||||||
"Clears any asset dependency fields matching the name provided.\n"
|
"Clears any asset dependency fields matching the name provided.\n"
|
||||||
"@param fieldName The name of the fields to be cleared")
|
"@param fieldName The name of the fields to be cleared")
|
||||||
|
|
@ -71,3 +80,15 @@ DefineEngineMethod(AssetBase, saveAsset, bool, (), ,
|
||||||
{
|
{
|
||||||
return object->saveAsset();
|
return object->saveAsset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DefineEngineMethod(AssetBase, getStatus, S32, (), , "get status")\
|
||||||
|
{
|
||||||
|
return object->getStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
DefineEngineMethod(AssetBase, getStatusString, const char*, (), ,
|
||||||
|
"Returns the load status of the asset.\n"
|
||||||
|
"@return What status code the asset had after being loaded.\n")
|
||||||
|
{
|
||||||
|
return object->getAssetErrstrn(object->getStatus());
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ DefineNewEngineMethod(SimObject, InspectPreApply, void, (), , "")
|
||||||
object->inspectPreApply();
|
object->inspectPreApply();
|
||||||
}
|
}
|
||||||
|
|
||||||
DefineNewEngineMethod(SimObject, InspectPostApply, void, (), , "")
|
DefineEngineMethod(SimObject, InspectPostApply, void, (), , "")
|
||||||
{
|
{
|
||||||
object->inspectPostApply();
|
object->inspectPostApply();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2801,3 +2801,11 @@ DefineEngineFunction( getMaxDynamicVerts, S32, (),,
|
||||||
{
|
{
|
||||||
return GFX_MAX_DYNAMIC_VERTS / 2;
|
return GFX_MAX_DYNAMIC_VERTS / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DefineEngineFunction( getStringHash, S32, (const char* _inString, bool _sensitive), ("", true), "generate a hash from a string. foramt is (string, casesensitive). defaults to true")
|
||||||
|
{
|
||||||
|
if (_sensitive)
|
||||||
|
return S32(String::String(_inString).getHashCaseSensitive());
|
||||||
|
else
|
||||||
|
return S32(String::String(_inString).getHashCaseInsensitive());
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -159,7 +159,7 @@ ConsoleProcessData( TypeFilename )
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// TypeStringFilename
|
// TypeStringFilename
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
ConsolePrepType( filename, TypeStringFilename, String )
|
ConsolePrepType( filename, TypeStringFilename, const char* )
|
||||||
|
|
||||||
ConsoleSetType( TypeStringFilename )
|
ConsoleSetType( TypeStringFilename )
|
||||||
{
|
{
|
||||||
|
|
@ -177,7 +177,7 @@ ConsoleSetType( TypeStringFilename )
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
*((String*)dptr) = String(buffer);
|
*((const char**)dptr) = StringTable->insert(buffer);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Con::printf("(TypeStringFilename) Cannot set multiple args to a single filename.");
|
Con::printf("(TypeStringFilename) Cannot set multiple args to a single filename.");
|
||||||
|
|
@ -185,7 +185,7 @@ ConsoleSetType( TypeStringFilename )
|
||||||
|
|
||||||
ConsoleGetType( TypeStringFilename )
|
ConsoleGetType( TypeStringFilename )
|
||||||
{
|
{
|
||||||
return *((String*)dptr);
|
return *((const char**)(dptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
ConsoleProcessData( TypeStringFilename )
|
ConsoleProcessData( TypeStringFilename )
|
||||||
|
|
@ -204,7 +204,7 @@ ConsoleProcessData( TypeStringFilename )
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// TypePrefabFilename
|
// TypePrefabFilename
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
ConsolePrepType( filename, TypePrefabFilename, String )
|
ConsolePrepType( filename, TypePrefabFilename, const char* )
|
||||||
|
|
||||||
ConsoleSetType( TypePrefabFilename )
|
ConsoleSetType( TypePrefabFilename )
|
||||||
{
|
{
|
||||||
|
|
@ -213,7 +213,7 @@ ConsoleSetType( TypePrefabFilename )
|
||||||
|
|
||||||
ConsoleGetType( TypePrefabFilename )
|
ConsoleGetType( TypePrefabFilename )
|
||||||
{
|
{
|
||||||
return *((String*)dptr);
|
return *((const char**)(dptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
ConsoleProcessData( TypePrefabFilename )
|
ConsoleProcessData( TypePrefabFilename )
|
||||||
|
|
@ -232,16 +232,16 @@ ConsoleProcessData( TypePrefabFilename )
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// TypeImageFilename
|
// TypeImageFilename
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
ConsolePrepType( filename, TypeImageFilename, String )
|
ConsolePrepType( filename, TypeImageFilename, const char* )
|
||||||
|
|
||||||
ConsoleSetType( TypeImageFilename )
|
ConsoleSetType( TypeImageFilename )
|
||||||
{
|
{
|
||||||
Con::setData(TypeStringFilename, dptr, 0, argc, argv, tbl, flag);
|
Con::setData(TypeFilename, dptr, 0, argc, argv, tbl, flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
ConsoleGetType( TypeImageFilename )
|
ConsoleGetType( TypeImageFilename )
|
||||||
{
|
{
|
||||||
return *((String*)dptr);
|
return *((const char**)(dptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
ConsoleProcessData( TypeImageFilename )
|
ConsoleProcessData( TypeImageFilename )
|
||||||
|
|
@ -281,6 +281,33 @@ ConsoleProcessData( TypeShapeFilename )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// TypeSoundFilename
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
ConsolePrepType(filename, TypeSoundFilename, const char*)
|
||||||
|
|
||||||
|
ConsoleSetType(TypeSoundFilename)
|
||||||
|
{
|
||||||
|
Con::setData(TypeFilename, dptr, 0, argc, argv, tbl, flag);
|
||||||
|
}
|
||||||
|
|
||||||
|
ConsoleGetType(TypeSoundFilename)
|
||||||
|
{
|
||||||
|
return *((const char **)(dptr));
|
||||||
|
}
|
||||||
|
|
||||||
|
ConsoleProcessData(TypeSoundFilename)
|
||||||
|
{
|
||||||
|
if (Con::expandScriptFilename(buffer, bufferSz, data))
|
||||||
|
return buffer;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Con::warnf("(TypeSoundFilename) illegal filename detected: %s", data);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// TypeS8
|
// TypeS8
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
@ -797,20 +824,17 @@ ConsoleSetType( TypeParticleParameterString )
|
||||||
// TypeMaterialName
|
// TypeMaterialName
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
ConsoleType(string, TypeMaterialName, String, "")
|
ConsoleType(string, TypeMaterialName, const char*, "")
|
||||||
|
|
||||||
ConsoleGetType( TypeMaterialName )
|
ConsoleGetType( TypeMaterialName )
|
||||||
{
|
{
|
||||||
const String *theString = static_cast<const String*>(dptr);
|
return* ((const char**)(dptr));
|
||||||
return theString->c_str();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ConsoleSetType( TypeMaterialName )
|
ConsoleSetType( TypeMaterialName )
|
||||||
{
|
{
|
||||||
String *theString = static_cast<String*>(dptr);
|
|
||||||
|
|
||||||
if(argc == 1)
|
if(argc == 1)
|
||||||
*theString = argv[0];
|
*((const char**)dptr) = StringTable->insert(argv[0]);
|
||||||
else
|
else
|
||||||
Con::printf("(TypeMaterialName) Cannot set multiple args to a single string.");
|
Con::printf("(TypeMaterialName) Cannot set multiple args to a single string.");
|
||||||
}
|
}
|
||||||
|
|
@ -860,20 +884,17 @@ ConsoleSetType( TypeTerrainMaterialName )
|
||||||
// TypeCubemapName
|
// TypeCubemapName
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
ConsoleType(string, TypeCubemapName, String, "")
|
ConsoleType(string, TypeCubemapName, const char*, "")
|
||||||
|
|
||||||
ConsoleGetType( TypeCubemapName )
|
ConsoleGetType( TypeCubemapName )
|
||||||
{
|
{
|
||||||
const String *theString = static_cast<const String*>(dptr);
|
return*((const char**)(dptr));
|
||||||
return theString->c_str();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ConsoleSetType( TypeCubemapName )
|
ConsoleSetType( TypeCubemapName )
|
||||||
{
|
{
|
||||||
String *theString = static_cast<String*>(dptr);
|
|
||||||
|
|
||||||
if(argc == 1)
|
if(argc == 1)
|
||||||
*theString = argv[0];
|
*((const char**)dptr) = StringTable->insert(argv[0]);
|
||||||
else
|
else
|
||||||
Con::printf("(TypeCubemapName) Cannot set multiple args to a single string.");
|
Con::printf("(TypeCubemapName) Cannot set multiple args to a single string.");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@ DefineConsoleType( TypeCaseString, const char * )
|
||||||
DefineConsoleType( TypeRealString, String )
|
DefineConsoleType( TypeRealString, String )
|
||||||
DefineConsoleType( TypeCommand, String )
|
DefineConsoleType( TypeCommand, String )
|
||||||
DefineConsoleType( TypeFilename, const char * )
|
DefineConsoleType( TypeFilename, const char * )
|
||||||
DefineConsoleType( TypeStringFilename, String )
|
DefineConsoleType( TypeStringFilename, const char*)
|
||||||
|
|
||||||
DefineConsoleType(TypeRotationF, RotationF)
|
DefineConsoleType(TypeRotationF, RotationF)
|
||||||
|
|
||||||
|
|
@ -87,22 +87,27 @@ DefineUnmappedConsoleType( TypePID, SimPersistID* );
|
||||||
/// TypeImageFilename is equivalent to TypeStringFilename in its usage,
|
/// TypeImageFilename is equivalent to TypeStringFilename in its usage,
|
||||||
/// it exists for the benefit of GuiInspector, which will provide a custom
|
/// it exists for the benefit of GuiInspector, which will provide a custom
|
||||||
/// InspectorField for this type that can display a texture preview.
|
/// InspectorField for this type that can display a texture preview.
|
||||||
DefineConsoleType( TypeImageFilename, String )
|
DefineConsoleType( TypeImageFilename, const char* )
|
||||||
|
|
||||||
/// TypePrefabFilename is equivalent to TypeStringFilename in its usage,
|
/// TypePrefabFilename is equivalent to TypeStringFilename in its usage,
|
||||||
/// it exists for the benefit of GuiInspector, which will provide a
|
/// it exists for the benefit of GuiInspector, which will provide a
|
||||||
/// custom InspectorField for this type.
|
/// custom InspectorField for this type.
|
||||||
DefineConsoleType( TypePrefabFilename, String )
|
DefineConsoleType( TypePrefabFilename, const char*)
|
||||||
|
|
||||||
/// TypeShapeFilename is equivalent to TypeStringFilename in its usage,
|
/// TypeShapeFilename is equivalent to TypeStringFilename in its usage,
|
||||||
/// it exists for the benefit of GuiInspector, which will provide a
|
/// it exists for the benefit of GuiInspector, which will provide a
|
||||||
/// custom InspectorField for this type.
|
/// custom InspectorField for this type.
|
||||||
DefineConsoleType( TypeShapeFilename, String )
|
DefineConsoleType( TypeShapeFilename, const char* )
|
||||||
|
|
||||||
|
/// TypeSoundFilename is exactly the same as TypeShapeFilename
|
||||||
|
/// it exists for the benefit of GuiInspector, which will provide a
|
||||||
|
/// custom InspectorField for this type.
|
||||||
|
DefineConsoleType(TypeSoundFilename, const char*)
|
||||||
|
|
||||||
/// TypeMaterialName is equivalent to TypeRealString in its usage,
|
/// TypeMaterialName is equivalent to TypeRealString in its usage,
|
||||||
/// it exists for the benefit of GuiInspector, which will provide a
|
/// it exists for the benefit of GuiInspector, which will provide a
|
||||||
/// custom InspectorField for this type.
|
/// custom InspectorField for this type.
|
||||||
DefineConsoleType( TypeMaterialName, String )
|
DefineConsoleType( TypeMaterialName, const char*)
|
||||||
|
|
||||||
/// TypeTerrainMaterialIndex is equivalent to TypeS32 in its usage,
|
/// TypeTerrainMaterialIndex is equivalent to TypeS32 in its usage,
|
||||||
/// it exists for the benefit of GuiInspector, which will provide a
|
/// it exists for the benefit of GuiInspector, which will provide a
|
||||||
|
|
@ -116,7 +121,7 @@ DefineConsoleType( TypeTerrainMaterialName, const char * )
|
||||||
|
|
||||||
/// TypeCubemapName is equivalent to TypeRealString in its usage,
|
/// TypeCubemapName is equivalent to TypeRealString in its usage,
|
||||||
/// but the Inspector will provide a drop-down list of CubemapData objects.
|
/// but the Inspector will provide a drop-down list of CubemapData objects.
|
||||||
DefineConsoleType( TypeCubemapName, String )
|
DefineConsoleType( TypeCubemapName, const char*)
|
||||||
|
|
||||||
DefineConsoleType( TypeParticleParameterString, const char * )
|
DefineConsoleType( TypeParticleParameterString, const char * )
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -398,6 +398,21 @@ DefineEngineFunction(isFile, bool, ( const char* fileName ),,
|
||||||
return Torque::FS::IsFile(givenPath);
|
return Torque::FS::IsFile(givenPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DefineEngineFunction(isScriptFile, bool, (const char* fileName), ,
|
||||||
|
"@brief Determines if the specified file exists or not\n\n"
|
||||||
|
|
||||||
|
"@param fileName The path to the file.\n"
|
||||||
|
"@return Returns true if the file was found.\n"
|
||||||
|
|
||||||
|
"@ingroup FileSystem")
|
||||||
|
{
|
||||||
|
String cleanfilename(Torque::Path::CleanSeparators(fileName));
|
||||||
|
Con::expandScriptFilename(sgScriptFilenameBuffer, sizeof(sgScriptFilenameBuffer), cleanfilename.c_str());
|
||||||
|
|
||||||
|
Torque::Path givenPath(Torque::Path::CompressPath(sgScriptFilenameBuffer));
|
||||||
|
return Torque::FS::IsScriptFile(givenPath.getFullPath());
|
||||||
|
}
|
||||||
|
|
||||||
DefineEngineFunction( IsDirectory, bool, ( const char* directory ),,
|
DefineEngineFunction( IsDirectory, bool, ( const char* directory ),,
|
||||||
"@brief Determines if a specified directory exists or not\n\n"
|
"@brief Determines if a specified directory exists or not\n\n"
|
||||||
|
|
||||||
|
|
@ -565,6 +580,27 @@ DefineEngineFunction( fileCreatedTime, String, ( const char* fileName ),,
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DefineEngineFunction(compareFileTimes, S32, (const char* fileA, const char* fileB), ("", ""),
|
||||||
|
"@brief Compares 2 files' modified file times."
|
||||||
|
|
||||||
|
"@param fileName Name and path of first file to compare\n"
|
||||||
|
"@param fileName Name and path of second file to compare\n"
|
||||||
|
"@return S32. If value is 1, then fileA is newer. If value is -1, then fileB is newer. If value is 0, they are equal.\n"
|
||||||
|
"@ingroup FileSystem")
|
||||||
|
{
|
||||||
|
Con::expandScriptFilename(sgScriptFilenameBuffer, sizeof(sgScriptFilenameBuffer), fileA);
|
||||||
|
|
||||||
|
FileTime fileATime = { 0 };
|
||||||
|
Platform::getFileTimes(sgScriptFilenameBuffer, NULL, &fileATime);
|
||||||
|
|
||||||
|
Con::expandScriptFilename(sgScriptFilenameBuffer, sizeof(sgScriptFilenameBuffer), fileB);
|
||||||
|
|
||||||
|
FileTime fileBTime = { 0 };
|
||||||
|
Platform::getFileTimes(sgScriptFilenameBuffer, NULL, &fileBTime);
|
||||||
|
|
||||||
|
return Platform::compareFileTimes(fileATime, fileBTime);
|
||||||
|
}
|
||||||
|
|
||||||
DefineEngineFunction(fileDelete, bool, ( const char* path ),,
|
DefineEngineFunction(fileDelete, bool, ( const char* path ),,
|
||||||
"@brief Delete a file from the hard drive\n\n"
|
"@brief Delete a file from the hard drive\n\n"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1254,17 +1254,7 @@ PersistenceManager::ParsedObject* PersistenceManager::writeNewObject(SimObject*
|
||||||
dynamic_cast<TSShapeConstructor*>(object))
|
dynamic_cast<TSShapeConstructor*>(object))
|
||||||
dclToken = "singleton";
|
dclToken = "singleton";
|
||||||
else if( dynamic_cast< SimDataBlock* >( object ) )
|
else if( dynamic_cast< SimDataBlock* >( object ) )
|
||||||
{
|
dclToken = "datablock";
|
||||||
SimDataBlock* db = static_cast<SimDataBlock*>(object);
|
|
||||||
|
|
||||||
if( db->isClientOnly() )
|
|
||||||
{
|
|
||||||
if( db->getName() && db->getName()[ 0 ] )
|
|
||||||
dclToken = "singleton";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
dclToken = "datablock";
|
|
||||||
}
|
|
||||||
|
|
||||||
char newLine[ 4096 ];
|
char newLine[ 4096 ];
|
||||||
dMemset(newLine, 0, sizeof( newLine));
|
dMemset(newLine, 0, sizeof( newLine));
|
||||||
|
|
@ -1416,17 +1406,25 @@ void PersistenceManager::updateObject(SimObject* object, ParsedObject* parentObj
|
||||||
{
|
{
|
||||||
// TODO: This should be wrapped in a helper method... probably.
|
// TODO: This should be wrapped in a helper method... probably.
|
||||||
// Detect and collapse relative path information
|
// Detect and collapse relative path information
|
||||||
if (f->type == TypeFilename ||
|
if (f->type == TypeFilename ||
|
||||||
f->type == TypeStringFilename ||
|
f->type == TypeStringFilename ||
|
||||||
f->type == TypeImageFilename ||
|
f->type == TypeImageFilename ||
|
||||||
f->type == TypePrefabFilename ||
|
f->type == TypePrefabFilename ||
|
||||||
f->type == TypeShapeFilename)
|
f->type == TypeShapeFilename ||
|
||||||
|
f->type == TypeSoundFilename )
|
||||||
{
|
{
|
||||||
char fnBuf[1024];
|
char fnBuf[1024];
|
||||||
Con::collapseScriptFilename(fnBuf, 1024, value);
|
Con::collapseScriptFilename(fnBuf, 1024, value);
|
||||||
|
|
||||||
updateToken(prop.valueLine, prop.valuePosition, prop.endPosition - prop.valuePosition, fnBuf, true);
|
updateToken(prop.valueLine, prop.valuePosition, prop.endPosition - prop.valuePosition, fnBuf, true);
|
||||||
}
|
}
|
||||||
|
else if (f->type == TypeCommand || f->type == TypeString || f->type == TypeRealString)
|
||||||
|
{
|
||||||
|
char cmdBuf[1024];
|
||||||
|
expandEscape(cmdBuf, value);
|
||||||
|
|
||||||
|
updateToken(prop.valueLine, prop.valuePosition, prop.endPosition - prop.valuePosition, cmdBuf, true);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
updateToken(prop.valueLine, prop.valuePosition, prop.endPosition - prop.valuePosition, value, true);
|
updateToken(prop.valueLine, prop.valuePosition, prop.endPosition - prop.valuePosition, value, true);
|
||||||
}
|
}
|
||||||
|
|
@ -1495,17 +1493,25 @@ void PersistenceManager::updateObject(SimObject* object, ParsedObject* parentObj
|
||||||
{
|
{
|
||||||
// TODO: This should be wrapped in a helper method... probably.
|
// TODO: This should be wrapped in a helper method... probably.
|
||||||
// Detect and collapse relative path information
|
// Detect and collapse relative path information
|
||||||
if (f->type == TypeFilename ||
|
if (f->type == TypeFilename ||
|
||||||
f->type == TypeStringFilename ||
|
f->type == TypeStringFilename ||
|
||||||
f->type == TypeImageFilename ||
|
f->type == TypeImageFilename ||
|
||||||
f->type == TypePrefabFilename ||
|
f->type == TypePrefabFilename ||
|
||||||
f->type == TypeShapeFilename)
|
f->type == TypeShapeFilename ||
|
||||||
|
f->type == TypeSoundFilename )
|
||||||
{
|
{
|
||||||
char fnBuf[1024];
|
char fnBuf[1024];
|
||||||
Con::collapseScriptFilename(fnBuf, 1024, value);
|
Con::collapseScriptFilename(fnBuf, 1024, value);
|
||||||
|
|
||||||
newLines.push_back(createNewProperty(f->pFieldname, fnBuf, f->elementCount > 1, j));
|
newLines.push_back(createNewProperty(f->pFieldname, fnBuf, f->elementCount > 1, j));
|
||||||
}
|
}
|
||||||
|
else if (f->type == TypeCommand)
|
||||||
|
{
|
||||||
|
char cmdBuf[1024];
|
||||||
|
expandEscape(cmdBuf, value);
|
||||||
|
|
||||||
|
newLines.push_back(createNewProperty(f->pFieldname, cmdBuf, f->elementCount > 1, j));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
newLines.push_back(createNewProperty(f->pFieldname, value, f->elementCount > 1, j));
|
newLines.push_back(createNewProperty(f->pFieldname, value, f->elementCount > 1, j));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -339,11 +339,12 @@ void SimObject::writeFields(Stream &stream, U32 tabStop)
|
||||||
|
|
||||||
// detect and collapse relative path information
|
// detect and collapse relative path information
|
||||||
char fnBuf[1024];
|
char fnBuf[1024];
|
||||||
if (f->type == TypeFilename ||
|
if (f->type == TypeFilename ||
|
||||||
f->type == TypeStringFilename ||
|
f->type == TypeStringFilename ||
|
||||||
f->type == TypeImageFilename ||
|
f->type == TypeImageFilename ||
|
||||||
f->type == TypePrefabFilename ||
|
f->type == TypePrefabFilename ||
|
||||||
f->type == TypeShapeFilename)
|
f->type == TypeShapeFilename ||
|
||||||
|
f->type == TypeSoundFilename )
|
||||||
{
|
{
|
||||||
Con::collapseScriptFilename(fnBuf, 1024, val);
|
Con::collapseScriptFilename(fnBuf, 1024, val);
|
||||||
val = fnBuf;
|
val = fnBuf;
|
||||||
|
|
@ -919,7 +920,15 @@ void SimObject::assignFieldsFrom(SimObject *parent)
|
||||||
dMemset( bufferSecure, 0, 2048 );
|
dMemset( bufferSecure, 0, 2048 );
|
||||||
dMemcpy( bufferSecure, szBuffer, dStrlen( szBuffer ) );
|
dMemcpy( bufferSecure, szBuffer, dStrlen( szBuffer ) );
|
||||||
|
|
||||||
if((*f->setDataFn)( this, NULL, bufferSecure ) )
|
//If we have an index worth mentioning, process it for pass-along as well to ensure we set stuff correctly
|
||||||
|
char* elementIdxBuffer = nullptr;
|
||||||
|
if (f->elementCount > 1)
|
||||||
|
{
|
||||||
|
elementIdxBuffer = Con::getArgBuffer(256);
|
||||||
|
dSprintf(elementIdxBuffer, 256, "%i", j);
|
||||||
|
}
|
||||||
|
|
||||||
|
if((*f->setDataFn)( this, elementIdxBuffer, bufferSecure ) )
|
||||||
Con::setData(f->type, (void *) (((const char *)this) + f->offset), j, 1, &fieldVal, f->table);
|
Con::setData(f->type, (void *) (((const char *)this) + f->offset), j, 1, &fieldVal, f->table);
|
||||||
|
|
||||||
if (f->networkMask != 0)
|
if (f->networkMask != 0)
|
||||||
|
|
@ -3176,6 +3185,31 @@ DefineEngineMethod( SimObject, getField, const char*, ( S32 index ),,
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DefineEngineFunction(getClassHierarchy, const char*, (const char* name), ,
|
||||||
|
"Returns the inheritance hierarchy for a given class.")
|
||||||
|
{
|
||||||
|
AbstractClassRep* pRep = AbstractClassRep::findClassRep(name);
|
||||||
|
if (!pRep)
|
||||||
|
{
|
||||||
|
//Con::errorf("%s does not exist", name);
|
||||||
|
return StringTable->EmptyString();
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder buffer;
|
||||||
|
|
||||||
|
while (pRep != NULL)
|
||||||
|
{
|
||||||
|
StringTableEntry className = pRep->getClassName();
|
||||||
|
buffer.append(className);
|
||||||
|
buffer.append(" ");
|
||||||
|
pRep = pRep->getParentClass();
|
||||||
|
}
|
||||||
|
|
||||||
|
String result = buffer.end().trim();
|
||||||
|
//Con::printf("getClassHierarchy for %s=%s", name, result.c_str());
|
||||||
|
return Con::getReturnBuffer(result.c_str());
|
||||||
|
|
||||||
|
}
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
#ifdef TORQUE_DEBUG
|
#ifdef TORQUE_DEBUG
|
||||||
|
|
|
||||||
|
|
@ -177,7 +177,7 @@ const U8 *FileObject::readLine()
|
||||||
return mFileBuffer + tokPos;
|
return mFileBuffer + tokPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileObject::peekLine( U8* line, S32 length )
|
void FileObject::peekLine( S32 peekLineOffset, U8* line, S32 length )
|
||||||
{
|
{
|
||||||
if(!mFileBuffer)
|
if(!mFileBuffer)
|
||||||
{
|
{
|
||||||
|
|
@ -189,6 +189,31 @@ void FileObject::peekLine( U8* line, S32 length )
|
||||||
// we can't modify the file buffer.
|
// we can't modify the file buffer.
|
||||||
S32 i = 0;
|
S32 i = 0;
|
||||||
U32 tokPos = mCurPos;
|
U32 tokPos = mCurPos;
|
||||||
|
S32 lineOffset = 0;
|
||||||
|
|
||||||
|
//Lets push our tokPos up until we've offset the requested number of lines
|
||||||
|
while (lineOffset < peekLineOffset && tokPos <= mBufferSize)
|
||||||
|
{
|
||||||
|
if (mFileBuffer[tokPos] == '\r')
|
||||||
|
{
|
||||||
|
tokPos++;
|
||||||
|
if (mFileBuffer[tokPos] == '\n')
|
||||||
|
tokPos++;
|
||||||
|
lineOffset++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mFileBuffer[tokPos] == '\n')
|
||||||
|
{
|
||||||
|
tokPos++;
|
||||||
|
lineOffset++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
tokPos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//now peek that line, then return the results
|
||||||
while( ( tokPos != mBufferSize ) && ( mFileBuffer[tokPos] != '\r' ) && ( mFileBuffer[tokPos] != '\n' ) && ( i < ( length - 1 ) ) )
|
while( ( tokPos != mBufferSize ) && ( mFileBuffer[tokPos] != '\r' ) && ( mFileBuffer[tokPos] != '\n' ) && ( i < ( length - 1 ) ) )
|
||||||
line[i++] = mFileBuffer[tokPos++];
|
line[i++] = mFileBuffer[tokPos++];
|
||||||
|
|
||||||
|
|
@ -317,7 +342,7 @@ DefineEngineMethod( FileObject, readLine, const char*, (),,
|
||||||
return (const char *) object->readLine();
|
return (const char *) object->readLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
DefineEngineMethod( FileObject, peekLine, const char*, (),,
|
DefineEngineMethod( FileObject, peekLine, const char*, (S32 peekOffset), (0),
|
||||||
"@brief Read a line from the file without moving the stream position.\n\n"
|
"@brief Read a line from the file without moving the stream position.\n\n"
|
||||||
|
|
||||||
"Emphasis on *line*, as in you cannot parse individual characters or chunks of data. "
|
"Emphasis on *line*, as in you cannot parse individual characters or chunks of data. "
|
||||||
|
|
@ -345,7 +370,7 @@ DefineEngineMethod( FileObject, peekLine, const char*, (),,
|
||||||
{
|
{
|
||||||
static const U32 bufSize = 512;
|
static const U32 bufSize = 512;
|
||||||
char *line = Con::getReturnBuffer( bufSize );
|
char *line = Con::getReturnBuffer( bufSize );
|
||||||
object->peekLine( (U8*)line, bufSize );
|
object->peekLine(peekOffset, (U8*)line, bufSize );
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ public:
|
||||||
bool readMemory(const char *fileName);
|
bool readMemory(const char *fileName);
|
||||||
const U8 *buffer() { return mFileBuffer; }
|
const U8 *buffer() { return mFileBuffer; }
|
||||||
const U8 *readLine();
|
const U8 *readLine();
|
||||||
void peekLine(U8 *line, S32 length);
|
void peekLine(S32 peekLineOffset, U8 *line, S32 length);
|
||||||
bool isEOF();
|
bool isEOF();
|
||||||
void writeLine(const U8 *line);
|
void writeLine(const U8 *line);
|
||||||
void close();
|
void close();
|
||||||
|
|
|
||||||
|
|
@ -344,22 +344,52 @@ void BitStream::writeInt(S32 val, S32 bitCount)
|
||||||
|
|
||||||
void BitStream::writeFloat(F32 f, S32 bitCount)
|
void BitStream::writeFloat(F32 f, S32 bitCount)
|
||||||
{
|
{
|
||||||
writeInt((S32)(f * ((1 << bitCount) - 1)), bitCount);
|
auto maxInt = (1U << bitCount) - 1;
|
||||||
|
U32 i;
|
||||||
|
if (f < POINT_EPSILON)
|
||||||
|
{
|
||||||
|
// Special case: <= 0 serializes to 0
|
||||||
|
i = 0.0f;
|
||||||
|
}
|
||||||
|
else if (f == 0.5)
|
||||||
|
{
|
||||||
|
// Special case: 0.5 serializes to maxInt / 2 + 1
|
||||||
|
i = maxInt / 2 + 1;
|
||||||
|
}
|
||||||
|
else if (f > (1.0f- POINT_EPSILON))
|
||||||
|
{
|
||||||
|
// Special case: >= 1 serializes to maxInt
|
||||||
|
i = maxInt;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Serialize normally but round the number
|
||||||
|
i = static_cast<U32>(roundf(f * maxInt));
|
||||||
|
}
|
||||||
|
writeInt(i, bitCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
F32 BitStream::readFloat(S32 bitCount)
|
F32 BitStream::readFloat(S32 bitCount)
|
||||||
{
|
{
|
||||||
return readInt(bitCount) / F32((1 << bitCount) - 1);
|
auto maxInt = (1U << bitCount) - 1;
|
||||||
|
auto i = static_cast<U32>(readInt(bitCount));
|
||||||
|
if (i == 0)
|
||||||
|
return 0;
|
||||||
|
if (i == maxInt / 2 + 1)
|
||||||
|
return 0.5;
|
||||||
|
if (i == maxInt)
|
||||||
|
return 1;
|
||||||
|
return i / static_cast<F32>(maxInt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BitStream::writeSignedFloat(F32 f, S32 bitCount)
|
void BitStream::writeSignedFloat(F32 f, S32 bitCount)
|
||||||
{
|
{
|
||||||
writeInt((S32)(((f + 1) * .5) * ((1 << bitCount) - 1)), bitCount);
|
writeFloat((f + 1) / 2, bitCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
F32 BitStream::readSignedFloat(S32 bitCount)
|
F32 BitStream::readSignedFloat(S32 bitCount)
|
||||||
{
|
{
|
||||||
return readInt(bitCount) * 2 / F32((1 << bitCount) - 1) - 1.0f;
|
return readFloat(bitCount) * 2 - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BitStream::writeSignedInt(S32 value, S32 bitCount)
|
void BitStream::writeSignedInt(S32 value, S32 bitCount)
|
||||||
|
|
|
||||||
|
|
@ -1074,6 +1074,18 @@ bool IsFile(const Path &path)
|
||||||
return sgMountSystem.isFile(path);
|
return sgMountSystem.isFile(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsScriptFile(const char* pFilePath)
|
||||||
|
{
|
||||||
|
return (sgMountSystem.isFile(pFilePath)
|
||||||
|
|| sgMountSystem.isFile(pFilePath + String(".dso"))
|
||||||
|
|| sgMountSystem.isFile(pFilePath + String(".mis"))
|
||||||
|
|| sgMountSystem.isFile(pFilePath + String(".mis.dso"))
|
||||||
|
|| sgMountSystem.isFile(pFilePath + String(".gui"))
|
||||||
|
|| sgMountSystem.isFile(pFilePath + String(".gui.dso"))
|
||||||
|
|| sgMountSystem.isFile(pFilePath + String("." TORQUE_SCRIPT_EXTENSION))
|
||||||
|
|| sgMountSystem.isFile(pFilePath + String("." TORQUE_SCRIPT_EXTENSION) + String(".dso")));
|
||||||
|
}
|
||||||
|
|
||||||
bool IsDirectory(const Path &path)
|
bool IsDirectory(const Path &path)
|
||||||
{
|
{
|
||||||
return sgMountSystem.isDirectory(path);
|
return sgMountSystem.isDirectory(path);
|
||||||
|
|
|
||||||
|
|
@ -550,6 +550,7 @@ bool CreatePath(const Path &path);
|
||||||
bool IsReadOnly(const Path &path);
|
bool IsReadOnly(const Path &path);
|
||||||
bool IsDirectory(const Path &path);
|
bool IsDirectory(const Path &path);
|
||||||
bool IsFile(const Path &path);
|
bool IsFile(const Path &path);
|
||||||
|
bool IsScriptFile(const char* pFilePath);
|
||||||
bool VerifyWriteAccess(const Path &path);
|
bool VerifyWriteAccess(const Path &path);
|
||||||
|
|
||||||
/// This returns a unique file path from the components
|
/// This returns a unique file path from the components
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue