mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-01-20 04:34:48 +00:00
Converts all game, gui editor, and system classes to utilize assets
Processed core, tools and default modules to utilize assets Converted all console types that were string based, such as TypeImageFilename to utilize const char*/the string table, which avoids a lot of type swapping shenanigans and avoids string corruption Removed unneeded MainEditor mockup module Removed some unused/duplicate image assets from the tools
This commit is contained in:
parent
83b0432283
commit
5525f8ecdd
|
|
@ -282,7 +282,7 @@ bool Scene::saveScene(StringTableEntry fileName)
|
|||
dSprintf(depSlotName, sizeof(depSlotName), "%s%d", "staticObjectAssetDependency", i);
|
||||
|
||||
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));
|
||||
|
||||
|
|
|
|||
|
|
@ -85,19 +85,20 @@ AccumulationVolume::AccumulationVolume()
|
|||
mWorldToObj.identity();
|
||||
|
||||
// Accumulation Texture.
|
||||
mTextureName = "";
|
||||
mAccuTexture = NULL;
|
||||
INIT_IMAGEASSET(Texture);
|
||||
|
||||
resetWorldBox();
|
||||
}
|
||||
|
||||
AccumulationVolume::~AccumulationVolume()
|
||||
{
|
||||
mAccuTexture = NULL;
|
||||
mTexture = nullptr;
|
||||
}
|
||||
|
||||
void AccumulationVolume::initPersistFields()
|
||||
{
|
||||
addProtectedField("textureAsset", TypeImageAssetId, Offset(mTextureAssetId, AccumulationVolume),
|
||||
&_setTexture, &defaultProtectedGetFn, "Accumulation texture.");
|
||||
addProtectedField( "texture", TypeStringFilename, Offset( mTextureName, AccumulationVolume ),
|
||||
&_setTexture, &defaultProtectedGetFn, "Accumulation texture." );
|
||||
|
||||
|
|
@ -235,7 +236,7 @@ U32 AccumulationVolume::packUpdate( NetConnection *connection, U32 mask, BitStre
|
|||
|
||||
if (stream->writeFlag(mask & InitialUpdateMask))
|
||||
{
|
||||
stream->write( mTextureName );
|
||||
PACK_IMAGEASSET(connection, Texture);
|
||||
}
|
||||
|
||||
return retMask;
|
||||
|
|
@ -247,8 +248,8 @@ void AccumulationVolume::unpackUpdate( NetConnection *connection, BitStream *str
|
|||
|
||||
if (stream->readFlag())
|
||||
{
|
||||
stream->read( &mTextureName );
|
||||
setTexture(mTextureName);
|
||||
UNPACK_IMAGEASSET(connection, Texture);
|
||||
//setTexture(mTextureName);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -262,13 +263,7 @@ void AccumulationVolume::inspectPostApply()
|
|||
|
||||
void AccumulationVolume::setTexture( const String& name )
|
||||
{
|
||||
mTextureName = name;
|
||||
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() );
|
||||
}
|
||||
_setTexture(StringTable->insert(name.c_str()));
|
||||
refreshVolumes();
|
||||
}
|
||||
|
||||
|
|
@ -312,7 +307,7 @@ void AccumulationVolume::refreshVolumes()
|
|||
if ( object.isNull() ) continue;
|
||||
|
||||
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->containsPoint(object->getPosition()) )
|
||||
object->mAccuTex = volume->mAccuTexture;
|
||||
object->mAccuTex = volume->getTextureResource();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,15 +58,15 @@ class AccumulationVolume : public ScenePolyhedralSpace
|
|||
|
||||
mutable Vector< SceneObject* > mVolumeQueryList;
|
||||
|
||||
// Name (path) of the accumulation texture.
|
||||
String mTextureName;
|
||||
|
||||
// SceneSpace.
|
||||
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();
|
||||
|
|
|
|||
|
|
@ -208,7 +208,7 @@ GuiControl* GuiInspectorTypeCubemapAssetPtr::constructEditControl()
|
|||
mShapeEdButton->setField("Command", szBuffer);
|
||||
|
||||
char bitmapName[512] = "tools/worldEditor/images/toolbar/shape-editor";
|
||||
mShapeEdButton->setBitmap(bitmapName);
|
||||
mShapeEdButton->setBitmap(StringTable->insert(bitmapName));
|
||||
|
||||
mShapeEdButton->setDataField(StringTable->insert("Profile"), NULL, "GuiButtonProfile");
|
||||
mShapeEdButton->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile");
|
||||
|
|
|
|||
|
|
@ -47,14 +47,14 @@
|
|||
|
||||
IMPLEMENT_CONOBJECT(GUIAsset);
|
||||
|
||||
ConsoleType(GUIAssetPtr, TypeGUIAssetPtr, String, ASSET_ID_FIELD_PREFIX)
|
||||
ConsoleType(GUIAssetPtr, TypeGUIAssetPtr, const char*, ASSET_ID_FIELD_PREFIX)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
ConsoleGetType(TypeGUIAssetPtr)
|
||||
{
|
||||
// Fetch asset Id.
|
||||
return *((StringTableEntry*)dptr);
|
||||
return *((const char**)(dptr));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -67,11 +67,7 @@ ConsoleSetType(TypeGUIAssetPtr)
|
|||
// Yes, so fetch field value.
|
||||
const char* pFieldValue = argv[0];
|
||||
|
||||
// Fetch asset Id.
|
||||
StringTableEntry* assetId = (StringTableEntry*)(dptr);
|
||||
|
||||
// Update asset value.
|
||||
*assetId = StringTable->insert(pFieldValue);
|
||||
*((const char**)dptr) = StringTable->insert(argv[0]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
@ -183,6 +179,50 @@ void GUIAsset::setScriptFile(const char* pScriptFile)
|
|||
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
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -222,7 +262,7 @@ GuiControl* GuiInspectorTypeGUIAssetPtr::constructEditControl()
|
|||
mSMEdButton->setField("Command", szBuffer);
|
||||
|
||||
char bitmapName[512] = "tools/worldEditor/images/toolbar/shape-editor";
|
||||
mSMEdButton->setBitmap(bitmapName);
|
||||
mSMEdButton->setBitmap(StringTable->insert(bitmapName));
|
||||
|
||||
mSMEdButton->setDataField(StringTable->insert("Profile"), NULL, "GuiButtonProfile");
|
||||
mSMEdButton->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile");
|
||||
|
|
|
|||
|
|
@ -60,6 +60,8 @@ public:
|
|||
static void initPersistFields();
|
||||
virtual void copyTo(SimObject* object);
|
||||
|
||||
static StringTableEntry getAssetIdByGUIName(StringTableEntry guiName);
|
||||
|
||||
/// Declare Console Object.
|
||||
DECLARE_CONOBJECT(GUIAsset);
|
||||
|
||||
|
|
|
|||
|
|
@ -42,23 +42,30 @@
|
|||
|
||||
#include "gfx/gfxStringEnumTranslate.h"
|
||||
|
||||
#include "ImageAssetInspectors.h"
|
||||
|
||||
// Debug Profiling.
|
||||
#include "platform/profiler.h"
|
||||
|
||||
#include "T3D/assets/assetImporter.h"
|
||||
#include "gfx/gfxDrawUtil.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
StringTableEntry ImageAsset::smNoImageAssetFallback(StringTable->insert(Con::getVariable("$Core::NoImageAssetFallback")));
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
IMPLEMENT_CONOBJECT(ImageAsset);
|
||||
|
||||
ConsoleType(ImageAssetPtr, TypeImageAssetPtr, String, ASSET_ID_FIELD_PREFIX)
|
||||
ConsoleType(ImageAssetPtr, TypeImageAssetPtr, const char*, ASSET_ID_FIELD_PREFIX)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
ConsoleGetType(TypeImageAssetPtr)
|
||||
{
|
||||
// Fetch asset Id.
|
||||
return *((StringTableEntry*)dptr);
|
||||
return *((const char**)(dptr));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -69,13 +76,7 @@ ConsoleSetType(TypeImageAssetPtr)
|
|||
if (argc == 1)
|
||||
{
|
||||
// Yes, so fetch field value.
|
||||
const char* pFieldValue = argv[0];
|
||||
|
||||
// Fetch asset Id.
|
||||
StringTableEntry* assetId = (StringTableEntry*)(dptr);
|
||||
|
||||
// Update asset value.
|
||||
*assetId = StringTable->insert(pFieldValue);
|
||||
*((const char**)dptr) = StringTable->insert(argv[0]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
@ -84,7 +85,7 @@ ConsoleSetType(TypeImageAssetPtr)
|
|||
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)
|
||||
{
|
||||
|
|
@ -97,14 +98,7 @@ ConsoleSetType(TypeImageAssetId)
|
|||
// Was a single argument specified?
|
||||
if (argc == 1)
|
||||
{
|
||||
// Yes, so fetch field value.
|
||||
const char* pFieldValue = argv[0];
|
||||
|
||||
// Fetch asset Id.
|
||||
StringTableEntry* assetId = (StringTableEntry*)(dptr);
|
||||
|
||||
// Update asset value.
|
||||
*assetId = StringTable->insert(pFieldValue);
|
||||
*((const char**)dptr) = StringTable->insert(argv[0]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
@ -117,26 +111,27 @@ ConsoleSetType(TypeImageAssetId)
|
|||
ImplementEnumType(ImageAssetType,
|
||||
"Type of mesh data available in a shape.\n"
|
||||
"@ingroup gameObjects")
|
||||
{ ImageAsset::Albedo, "Albedo", "" },
|
||||
{ ImageAsset::Normal, "Normal", "" },
|
||||
{ ImageAsset::ORMConfig, "ORMConfig", "" },
|
||||
{ ImageAsset::GUI, "GUI", "" },
|
||||
{ ImageAsset::Roughness, "Roughness", "" },
|
||||
{ ImageAsset::AO, "AO", "" },
|
||||
{ ImageAsset::Metalness, "Metalness", "" },
|
||||
{ ImageAsset::Glow, "Glow", "" },
|
||||
{ ImageAsset::Particle, "Particle", "" },
|
||||
{ ImageAsset::Decal, "Decal", "" },
|
||||
{ ImageAsset::Cubemap, "Cubemap", "" },
|
||||
{ ImageAsset::Albedo, "Albedo", "" },
|
||||
{ ImageAsset::Normal, "Normal", "" },
|
||||
{ ImageAsset::ORMConfig, "ORMConfig", "" },
|
||||
{ ImageAsset::GUI, "GUI", "" },
|
||||
{ ImageAsset::Roughness, "Roughness", "" },
|
||||
{ ImageAsset::AO, "AO", "" },
|
||||
{ ImageAsset::Metalness, "Metalness", "" },
|
||||
{ ImageAsset::Glow, "Glow", "" },
|
||||
{ ImageAsset::Particle, "Particle", "" },
|
||||
{ ImageAsset::Decal, "Decal", "" },
|
||||
{ ImageAsset::Cubemap, "Cubemap", "" },
|
||||
|
||||
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();
|
||||
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()
|
||||
|
|
@ -163,85 +167,52 @@ void ImageAsset::initPersistFields()
|
|||
|
||||
//------------------------------------------------------------------------------
|
||||
//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;
|
||||
S32 foundAssetcount = AssetDatabase.findAssetLooseFile(&query, fileName);
|
||||
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
|
||||
imageAsset->setAssetId(StringTable->insert("Core_Rendering:noImage"));
|
||||
imageAsset->setAssetId(ImageAsset::smNoImageAssetFallback);
|
||||
|
||||
if (!imageAsset->isNull())
|
||||
return true;
|
||||
if (imageAsset->isNull())
|
||||
{
|
||||
//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
|
||||
return false;
|
||||
//handle noshape not being loaded itself
|
||||
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
|
||||
{
|
||||
//acquire and bind the asset, and return it out
|
||||
imageAsset->setAssetId(query.mAssetList[0]);
|
||||
return true;
|
||||
return (*imageAsset)->mLoadedState;
|
||||
}
|
||||
}
|
||||
|
||||
StringTableEntry ImageAsset::getAssetIdByFilename(StringTableEntry fileName)
|
||||
{
|
||||
StringTableEntry imageAssetId = StringTable->EmptyString();
|
||||
if (fileName == StringTable->EmptyString())
|
||||
return StringTable->EmptyString();
|
||||
|
||||
StringTableEntry imageAssetId = ImageAsset::smNoImageAssetFallback;
|
||||
|
||||
AssetQuery query;
|
||||
S32 foundAssetcount = AssetDatabase.findAssetLooseFile(&query, fileName);
|
||||
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
|
||||
if (foundAssetcount != 0)
|
||||
{
|
||||
//acquire and bind the asset, and return it out
|
||||
imageAssetId = query.mAssetList[0];
|
||||
|
|
@ -250,22 +221,37 @@ StringTableEntry ImageAsset::getAssetIdByFilename(StringTableEntry fileName)
|
|||
return imageAssetId;
|
||||
}
|
||||
|
||||
bool ImageAsset::getAssetById(StringTableEntry assetId, AssetPtr<ImageAsset>* imageAsset)
|
||||
U32 ImageAsset::getAssetById(StringTableEntry assetId, AssetPtr<ImageAsset>* imageAsset)
|
||||
{
|
||||
(*imageAsset) = assetId;
|
||||
|
||||
if (!imageAsset->isNull())
|
||||
return true;
|
||||
if (imageAsset->notNull())
|
||||
{
|
||||
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
|
||||
StringTableEntry noImageId = StringTable->insert("Core_Rendering:noMaterial");
|
||||
imageAsset->setAssetId(noImageId);
|
||||
//handle noshape not being loaded itself
|
||||
if ((*imageAsset)->mLoadedState == BadFileReference)
|
||||
{
|
||||
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())
|
||||
return true;
|
||||
Con::warnf("ImageAsset::getAssetById - Finding of asset with id %s failed, utilizing fallback asset", assetId);
|
||||
|
||||
return false;
|
||||
(*imageAsset)->mLoadedState = AssetErrCode::UsingFallback;
|
||||
return AssetErrCode::UsingFallback;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void ImageAsset::copyTo(SimObject* object)
|
||||
{
|
||||
|
|
@ -275,32 +261,49 @@ void ImageAsset::copyTo(SimObject* object)
|
|||
|
||||
void ImageAsset::loadImage()
|
||||
{
|
||||
SAFE_DELETE(mImage);
|
||||
|
||||
if (mImagePath)
|
||||
{
|
||||
if (!Platform::isFile(mImagePath))
|
||||
{
|
||||
Con::errorf("ImageAsset::initializeAsset: Attempted to load file %s but it was not valid!", mImageFileName);
|
||||
mLoadedState = BadFileReference;
|
||||
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;
|
||||
|
||||
//mBitmap = texture.getBitmap();
|
||||
|
||||
return;
|
||||
}
|
||||
}*/
|
||||
|
||||
mChangeSignal.trigger();
|
||||
}
|
||||
mLoadedState = BadFileReference;
|
||||
|
||||
mIsValidImage = false;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
|
|
@ -311,6 +314,16 @@ void ImageAsset::onAssetRefresh()
|
|||
loadImage();
|
||||
}
|
||||
|
||||
void ImageAsset::_onResourceChanged(const Torque::Path& path)
|
||||
{
|
||||
if (path != Torque::Path(mImagePath))
|
||||
return;
|
||||
|
||||
refreshAsset();
|
||||
|
||||
loadImage();
|
||||
}
|
||||
|
||||
void ImageAsset::setImageFileName(const char* pScriptFile)
|
||||
{
|
||||
// Sanity!
|
||||
|
|
@ -320,24 +333,34 @@ void ImageAsset::setImageFileName(const char* 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;
|
||||
}
|
||||
else
|
||||
{
|
||||
//If we don't have an existing map case to the requested format, we'll just create it and insert it in
|
||||
GFXTexHandle newImage;
|
||||
newImage.set(mImageFileName, &requestedProfile, avar("%s() - mImage (line %d)", __FUNCTION__, __LINE__));
|
||||
mResourceMap.insert(requestedProfile, newImage);
|
||||
GFXTexHandle newTex = TEXMGR->createTexture(mImagePath, requestedProfile);
|
||||
if (newTex)
|
||||
{
|
||||
mResourceMap.insert(requestedProfile, newTex);
|
||||
mLoadedState = Ok;
|
||||
return newTex;
|
||||
}
|
||||
else
|
||||
mLoadedState = BadFileReference;
|
||||
}
|
||||
|
||||
return newImage;
|
||||
}*/
|
||||
|
||||
if (mImage.isValid())
|
||||
return mImage;
|
||||
//if (mTexture.isValid())
|
||||
// return mTexture;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
|
@ -348,7 +371,17 @@ const char* ImageAsset::getImageInfo()
|
|||
{
|
||||
static const U32 bufSize = 2048;
|
||||
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;
|
||||
}
|
||||
|
|
@ -384,6 +417,11 @@ const char* ImageAsset::getImageTypeNameFromType(ImageAsset::ImageTypes type)
|
|||
|
||||
ImageAsset::ImageTypes ImageAsset::getImageTypeFromName(const char* name)
|
||||
{
|
||||
if (dStrIsEmpty(name))
|
||||
{
|
||||
return (ImageTypes)Albedo;
|
||||
}
|
||||
|
||||
S32 ret = -1;
|
||||
for (S32 i = 0; i < ImageTypeCount; i++)
|
||||
{
|
||||
|
|
@ -414,6 +452,15 @@ DefineEngineMethod(ImageAsset, getImageInfo, const char*, (), ,
|
|||
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
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -435,11 +482,16 @@ void GuiInspectorTypeImageAssetPtr::consoleInit()
|
|||
|
||||
GuiControl* GuiInspectorTypeImageAssetPtr::constructEditControl()
|
||||
{
|
||||
if (mInspector->getInspectObject() == nullptr)
|
||||
return nullptr;
|
||||
|
||||
// Create base filename edit controls
|
||||
GuiControl* retCtrl = Parent::constructEditControl();
|
||||
if (retCtrl == NULL)
|
||||
return retCtrl;
|
||||
|
||||
retCtrl->getRenderTooltipDelegate().bind(this, &GuiInspectorTypeImageAssetPtr::renderTooltip);
|
||||
|
||||
// Change filespec
|
||||
char szBuffer[512];
|
||||
dSprintf(szBuffer, sizeof(szBuffer), "AssetBrowser.showDialog(\"ImageAsset\", \"AssetBrowser.changeAsset\", %s, %s);",
|
||||
|
|
@ -457,7 +509,7 @@ GuiControl* GuiInspectorTypeImageAssetPtr::constructEditControl()
|
|||
mImageEdButton->setField("Command", szBuffer);
|
||||
|
||||
char bitmapName[512] = "tools/worldEditor/images/toolbar/shape-editor";
|
||||
mImageEdButton->setBitmap(bitmapName);
|
||||
mImageEdButton->setBitmap(StringTable->insert(bitmapName));
|
||||
|
||||
mImageEdButton->setDataField(StringTable->insert("Profile"), NULL, "GuiButtonProfile");
|
||||
mImageEdButton->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile");
|
||||
|
|
@ -496,6 +548,66 @@ bool GuiInspectorTypeImageAssetPtr::updateRects()
|
|||
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);
|
||||
|
||||
ConsoleDocClass(GuiInspectorTypeImageAssetId,
|
||||
|
|
|
|||
|
|
@ -20,8 +20,7 @@
|
|||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef IMAGE_ASSET_H
|
||||
#define IMAGE_ASSET_H
|
||||
#pragma once
|
||||
|
||||
#ifndef _ASSET_BASE_H_
|
||||
#include "assets/assetBase.h"
|
||||
|
|
@ -45,7 +44,9 @@
|
|||
#include "gfx/bitmap/gBitmap.h"
|
||||
#include "gfx/gfxTextureHandle.h"
|
||||
|
||||
#include "gui/editor/guiInspectorTypes.h"
|
||||
#include "sim/netConnection.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class ImageAsset : public AssetBase
|
||||
|
|
@ -70,24 +71,33 @@ public:
|
|||
ImageTypeCount = 11
|
||||
};
|
||||
|
||||
static StringTableEntry smNoImageAssetFallback;
|
||||
|
||||
protected:
|
||||
StringTableEntry mImageFileName;
|
||||
StringTableEntry mImagePath;
|
||||
|
||||
GFXTexHandle mImage;
|
||||
|
||||
bool mIsValidImage;
|
||||
bool mUseMips;
|
||||
bool mIsHDRImage;
|
||||
|
||||
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:
|
||||
ImageAsset();
|
||||
virtual ~ImageAsset();
|
||||
|
||||
/// Set up some global script interface stuff.
|
||||
static void consoleInit();
|
||||
|
||||
/// Engine.
|
||||
static void initPersistFields();
|
||||
virtual void copyTo(SimObject* object);
|
||||
|
|
@ -95,32 +105,40 @@ public:
|
|||
/// Declare Console Object.
|
||||
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 getImagePath(void) const { return mImagePath; };
|
||||
|
||||
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 ImageTypes getImageTypeFromName(const char* name);
|
||||
static StringTableEntry getImageTypeNameFromType(ImageTypes type);
|
||||
static ImageTypes getImageTypeFromName(StringTableEntry name);
|
||||
|
||||
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 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:
|
||||
virtual void initializeAsset(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 const char* getImageFileName(void* obj, const char* data) { return static_cast<ImageAsset*>(obj)->getImageFileName(); }
|
||||
static bool setImageFileName(void* obj, StringTableEntry index, StringTableEntry data) { static_cast<ImageAsset*>(obj)->setImageFileName(data); return false; }
|
||||
static StringTableEntry getImageFileName(void* obj, StringTableEntry data) { return static_cast<ImageAsset*>(obj)->getImageFileName(); }
|
||||
|
||||
void loadImage();
|
||||
};
|
||||
|
|
@ -131,89 +149,464 @@ DefineConsoleType(TypeImageAssetId, String)
|
|||
typedef ImageAsset::ImageTypes ImageAssetType;
|
||||
DefineEnumType(ImageAssetType);
|
||||
|
||||
class GuiInspectorTypeImageAssetPtr : public GuiInspectorTypeFileName
|
||||
{
|
||||
typedef GuiInspectorTypeFileName Parent;
|
||||
public:
|
||||
#pragma region Singular Asset Macros
|
||||
|
||||
GuiBitmapButtonCtrl* mImageEdButton;
|
||||
|
||||
DECLARE_CONOBJECT(GuiInspectorTypeImageAssetPtr);
|
||||
static void consoleInit();
|
||||
|
||||
virtual GuiControl* constructEditControl();
|
||||
virtual bool updateRects();
|
||||
};
|
||||
|
||||
class GuiInspectorTypeImageAssetId : public GuiInspectorTypeImageAssetPtr
|
||||
{
|
||||
typedef GuiInspectorTypeImageAssetPtr Parent;
|
||||
public:
|
||||
|
||||
DECLARE_CONOBJECT(GuiInspectorTypeImageAssetId);
|
||||
static void consoleInit();
|
||||
};
|
||||
|
||||
#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))\
|
||||
//Singular assets
|
||||
/// <Summary>
|
||||
/// Declares an image asset
|
||||
/// This establishes the assetId, asset and legacy filepath fields, along with supplemental getter and setter functions
|
||||
/// </Summary>
|
||||
#define DECLARE_IMAGEASSET(className, name, changeFunc, profile) public: \
|
||||
GFXTexHandle m##name = NULL;\
|
||||
StringTableEntry m##name##Name; \
|
||||
StringTableEntry m##name##AssetId;\
|
||||
AssetPtr<ImageAsset> m##name##Asset;\
|
||||
GFXTextureProfile* 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<ImageAsset> & get##name##Asset() const { return m##name##Asset; }\
|
||||
void set##name##Asset(const AssetPtr<ImageAsset> &_in) { m##name##Asset = _in;}\
|
||||
\
|
||||
bool _set##name(StringTableEntry _in)\
|
||||
{\
|
||||
if (mat->m##name##Asset.getAssetId() != StringTable->insert("Core_Rendering:noMaterial"))\
|
||||
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"))\
|
||||
if(m##name##AssetId != _in || m##name##Name != _in)\
|
||||
{\
|
||||
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;\
|
||||
\
|
||||
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
|
||||
|
||||
#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);
|
||||
|
||||
ConsoleType(LevelAssetPtr, TypeLevelAssetPtr, String, ASSET_ID_FIELD_PREFIX)
|
||||
ConsoleType(LevelAssetPtr, TypeLevelAssetPtr, const char*, ASSET_ID_FIELD_PREFIX)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
ConsoleGetType(TypeLevelAssetPtr)
|
||||
{
|
||||
// Fetch asset Id.
|
||||
return *((StringTableEntry*)dptr);
|
||||
return *((const char**)(dptr));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -65,13 +65,7 @@ ConsoleSetType(TypeLevelAssetPtr)
|
|||
if (argc == 1)
|
||||
{
|
||||
// Yes, so fetch field value.
|
||||
const char* pFieldValue = argv[0];
|
||||
|
||||
// Fetch asset Id.
|
||||
StringTableEntry* assetId = (StringTableEntry*)(dptr);
|
||||
|
||||
// Update asset value.
|
||||
*assetId = StringTable->insert(pFieldValue);
|
||||
*((const char**)dptr) = StringTable->insert(argv[0]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
@ -86,14 +80,12 @@ LevelAsset::LevelAsset() : AssetBase(), mIsSubLevel(false)
|
|||
{
|
||||
mLevelName = StringTable->EmptyString();
|
||||
mLevelFile = StringTable->EmptyString();
|
||||
mPreviewImage = StringTable->EmptyString();
|
||||
mPostFXPresetFile = StringTable->EmptyString();
|
||||
mDecalsFile = StringTable->EmptyString();
|
||||
mForestFile = StringTable->EmptyString();
|
||||
mNavmeshFile = StringTable->EmptyString();
|
||||
|
||||
mLevelPath = StringTable->EmptyString();
|
||||
mPreviewImagePath = StringTable->EmptyString();
|
||||
mPostFXPresetPath = StringTable->EmptyString();
|
||||
mDecalsPath = StringTable->EmptyString();
|
||||
mForestPath = StringTable->EmptyString();
|
||||
|
|
@ -104,6 +96,9 @@ LevelAsset::LevelAsset() : AssetBase(), mIsSubLevel(false)
|
|||
|
||||
mEditorFile = StringTable->EmptyString();
|
||||
mBakedSceneFile = StringTable->EmptyString();
|
||||
|
||||
mPreviewImageAssetId = StringTable->EmptyString();
|
||||
mPreviewImageAsset = StringTable->EmptyString();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -122,8 +117,6 @@ void LevelAsset::initPersistFields()
|
|||
addProtectedField("LevelFile", TypeAssetLooseFilePath, Offset(mLevelFile, LevelAsset),
|
||||
&setLevelFile, &getLevelFile, "Path to the actual level file.");
|
||||
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),
|
||||
&setPostFXPresetFile, &getPostFXPresetFile, "Path to the level's postFXPreset.");
|
||||
|
|
@ -157,24 +150,32 @@ void LevelAsset::initializeAsset()
|
|||
// Call parent.
|
||||
Parent::initializeAsset();
|
||||
|
||||
// Ensure the image-file is expanded.
|
||||
mPreviewImagePath = expandAssetFilePath(mPreviewImage);
|
||||
mLevelPath = expandAssetFilePath(mLevelFile);
|
||||
mPostFXPresetPath = expandAssetFilePath(mPostFXPresetFile);
|
||||
mDecalsPath = expandAssetFilePath(mDecalsFile);
|
||||
mForestPath = expandAssetFilePath(mForestFile);
|
||||
mNavmeshPath = expandAssetFilePath(mNavmeshFile);
|
||||
loadAsset();
|
||||
}
|
||||
|
||||
void LevelAsset::onAssetRefresh(void)
|
||||
{
|
||||
loadAsset();
|
||||
}
|
||||
|
||||
void LevelAsset::loadAsset()
|
||||
{
|
||||
// Ensure the image-file is expanded.
|
||||
mPreviewImagePath = expandAssetFilePath(mPreviewImage);
|
||||
mLevelPath = expandAssetFilePath(mLevelFile);
|
||||
mPostFXPresetPath = expandAssetFilePath(mPostFXPresetFile);
|
||||
mDecalsPath = expandAssetFilePath(mDecalsFile);
|
||||
mForestPath = expandAssetFilePath(mForestFile);
|
||||
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();
|
||||
}
|
||||
|
||||
void LevelAsset::setImageFile(const char* pImageFile)
|
||||
StringTableEntry LevelAsset::getPreviewImageAsset() const
|
||||
{
|
||||
// Sanity!
|
||||
AssertFatal(pImageFile != NULL, "Cannot use a NULL image file.");
|
||||
return mPreviewImageAssetId;
|
||||
}
|
||||
|
||||
// Fetch image file.
|
||||
pImageFile = StringTable->insert(pImageFile);
|
||||
StringTableEntry LevelAsset::getPreviewImagePath(void) const
|
||||
{
|
||||
if (mPreviewImageAsset.notNull() && mPreviewImageAsset->isAssetValid())
|
||||
{
|
||||
return mPreviewImageAsset->getImagePath();
|
||||
}
|
||||
|
||||
// Ignore no change,
|
||||
if (pImageFile == mPreviewImage)
|
||||
return;
|
||||
|
||||
// Update.
|
||||
mPreviewImage = pImageFile;
|
||||
|
||||
// Refresh the asset.
|
||||
refreshAsset();
|
||||
return StringTable->EmptyString();
|
||||
}
|
||||
|
||||
void LevelAsset::setEditorFile(const char* pEditorFile)
|
||||
|
|
@ -368,11 +365,18 @@ DefineEngineMethod(LevelAsset, getLevelPath, const char*, (),,
|
|||
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*, (), ,
|
||||
"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->getImagePath();
|
||||
return object->getPreviewImagePath();
|
||||
}
|
||||
|
||||
DefineEngineMethod(LevelAsset, getPostFXPresetPath, const char*, (), ,
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
#ifndef _ASSET_FIELD_TYPES_H_
|
||||
#include "assets/assetFieldTypes.h"
|
||||
#endif
|
||||
#include "T3D/assets/ImageAsset.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class LevelAsset : public AssetBase
|
||||
|
|
@ -50,14 +51,12 @@ class LevelAsset : public AssetBase
|
|||
StringTableEntry mDecalsFile;
|
||||
StringTableEntry mForestFile;
|
||||
StringTableEntry mNavmeshFile;
|
||||
StringTableEntry mPreviewImage;
|
||||
|
||||
StringTableEntry mLevelPath;
|
||||
StringTableEntry mPostFXPresetPath;
|
||||
StringTableEntry mDecalsPath;
|
||||
StringTableEntry mForestPath;
|
||||
StringTableEntry mNavmeshPath;
|
||||
StringTableEntry mPreviewImagePath;
|
||||
|
||||
StringTableEntry mEditorFile;
|
||||
StringTableEntry mBakedSceneFile;
|
||||
|
|
@ -69,6 +68,9 @@ class LevelAsset : public AssetBase
|
|||
|
||||
Vector<AssetBase*> mAssetDependencies;
|
||||
|
||||
StringTableEntry mPreviewImageAssetId;
|
||||
AssetPtr<ImageAsset> mPreviewImageAsset;
|
||||
|
||||
public:
|
||||
LevelAsset();
|
||||
virtual ~LevelAsset();
|
||||
|
|
@ -93,15 +95,16 @@ public:
|
|||
inline StringTableEntry getForestFile(void) const { return mForestFile; };
|
||||
void setNavmeshFile(const char* pNavmeshFile);
|
||||
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 getPostFXPresetPath(void) const { return mPostFXPresetPath; };
|
||||
inline StringTableEntry getDecalsPath(void) const { return mDecalsPath; };
|
||||
inline StringTableEntry getForestPath(void) const { return mForestPath; };
|
||||
inline StringTableEntry getNavmeshPath(void) const { return mNavmeshPath; };
|
||||
inline StringTableEntry getImagePath(void) const { return mPreviewImagePath; };
|
||||
|
||||
StringTableEntry getPreviewImagePath(void) const;
|
||||
|
||||
void setEditorFile(const char* pEditorFile);
|
||||
inline StringTableEntry getEditorFile(void) const { return mEditorFile; };
|
||||
|
|
@ -113,8 +116,6 @@ public:
|
|||
protected:
|
||||
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 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 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 onAssetRefresh(void);
|
||||
void loadAsset();
|
||||
};
|
||||
|
||||
DefineConsoleType(TypeLevelAssetPtr, LevelAsset)
|
||||
|
|
|
|||
|
|
@ -43,6 +43,8 @@
|
|||
|
||||
#include "T3D/assets/assetImporter.h"
|
||||
|
||||
StringTableEntry MaterialAsset::smNoMaterialAssetFallback(StringTable->insert(Con::getVariable("$Core::NoMaterialAssetFallback")));
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
@ -125,16 +127,26 @@ MaterialAsset::MaterialAsset()
|
|||
mScriptFile = StringTable->EmptyString();
|
||||
mScriptPath = StringTable->EmptyString();
|
||||
mMatDefinitionName = StringTable->EmptyString();
|
||||
mMaterialDefinition = nullptr;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
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()
|
||||
{
|
||||
// Call parent.
|
||||
|
|
@ -152,12 +164,12 @@ void MaterialAsset::initializeAsset()
|
|||
// Call parent.
|
||||
Parent::initializeAsset();
|
||||
|
||||
compileShader();
|
||||
|
||||
mScriptPath = getOwned() ? expandAssetFilePath(mScriptFile) : mScriptPath;
|
||||
|
||||
if (Platform::isFile(mScriptPath))
|
||||
Con::executeFile(mScriptPath, false, false);
|
||||
|
||||
loadMaterial();
|
||||
}
|
||||
|
||||
void MaterialAsset::onAssetRefresh()
|
||||
|
|
@ -167,17 +179,7 @@ void MaterialAsset::onAssetRefresh()
|
|||
if (Platform::isFile(mScriptPath))
|
||||
Con::executeFile(mScriptPath, false, false);
|
||||
|
||||
if (mMatDefinitionName != StringTable->EmptyString())
|
||||
{
|
||||
Material* matDef;
|
||||
if (!Sim::findObject(mMatDefinitionName, matDef))
|
||||
{
|
||||
Con::errorf("MaterialAsset: Unable to find the Material %s", mMatDefinitionName);
|
||||
return;
|
||||
}
|
||||
|
||||
matDef->reload();
|
||||
}
|
||||
loadMaterial();
|
||||
}
|
||||
|
||||
void MaterialAsset::setScriptFile(const char* pScriptFile)
|
||||
|
|
@ -197,142 +199,155 @@ 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)
|
||||
{
|
||||
// Call to parent.
|
||||
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 = new AssetQuery();
|
||||
U32 foundCount = AssetDatabase.findAssetType(query, "MaterialAsset");
|
||||
if (foundCount == 0)
|
||||
AssetQuery query;
|
||||
U32 foundAssetcount = AssetDatabase.findAssetType(&query, "MaterialAsset");
|
||||
if (foundAssetcount == 0)
|
||||
{
|
||||
//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
|
||||
{
|
||||
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++)
|
||||
{
|
||||
MaterialAsset* matAsset = AssetDatabase.acquireAsset<MaterialAsset>(query->mAssetList[i]);
|
||||
MaterialAsset* matAsset = AssetDatabase.acquireAsset<MaterialAsset>(query.mAssetList[i]);
|
||||
if (matAsset && matAsset->getMaterialDefinitionName() == matName)
|
||||
{
|
||||
materialAssetId = matAsset->getAssetId();
|
||||
AssetDatabase.releaseAsset(query.mAssetList[i]);
|
||||
break;
|
||||
}
|
||||
AssetDatabase.releaseAsset(query->mAssetList[i]); //cleanup if that's not the one we needed
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
AssetDatabase.releaseAsset(query.mAssetList[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return materialAssetId;
|
||||
}
|
||||
|
||||
bool MaterialAsset::getAssetById(StringTableEntry assetId, AssetPtr<MaterialAsset>* materialAsset)
|
||||
U32 MaterialAsset::getAssetById(StringTableEntry assetId, AssetPtr<MaterialAsset>* materialAsset)
|
||||
{
|
||||
(*materialAsset) = assetId;
|
||||
|
||||
if (!materialAsset->isNull())
|
||||
return true;
|
||||
if (materialAsset->notNull())
|
||||
{
|
||||
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
|
||||
StringTableEntry noImageId = StringTable->insert("Core_Rendering:noMaterial");
|
||||
materialAsset->setAssetId(noImageId);
|
||||
if (materialAsset->isNull())
|
||||
{
|
||||
//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())
|
||||
return true;
|
||||
//handle noshape not being loaded itself
|
||||
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));
|
||||
}
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// GuiInspectorTypeAssetId
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -374,7 +389,7 @@ GuiControl* GuiInspectorTypeMaterialAssetPtr::constructEditControl()
|
|||
mEditButton->setField("Command", szBuffer);
|
||||
|
||||
char bitmapName[512] = "tools/worldEditor/images/toolbar/material-editor";
|
||||
mEditButton->setBitmap(bitmapName);
|
||||
mEditButton->setBitmap(StringTable->insert(bitmapName));
|
||||
|
||||
mEditButton->setDataField(StringTable->insert("Profile"), NULL, "GuiButtonProfile");
|
||||
mEditButton->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile");
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@
|
|||
#include "materials/matTextureTarget.h"
|
||||
#include "materials/materialDefinition.h"
|
||||
#include "materials/customMaterialDefinition.h"
|
||||
#include "materials/materialManager.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class MaterialAsset : public AssetBase
|
||||
|
|
@ -64,25 +65,42 @@ class MaterialAsset : public AssetBase
|
|||
StringTableEntry mScriptPath;
|
||||
StringTableEntry mMatDefinitionName;
|
||||
|
||||
SimObjectPtr<Material> mMaterialDefinition;
|
||||
|
||||
public:
|
||||
static StringTableEntry smNoMaterialAssetFallback;
|
||||
|
||||
public:
|
||||
MaterialAsset();
|
||||
virtual ~MaterialAsset();
|
||||
|
||||
/// Set up some global script interface stuff.
|
||||
static void consoleInit();
|
||||
|
||||
/// Engine.
|
||||
static void initPersistFields();
|
||||
virtual void copyTo(SimObject* object);
|
||||
|
||||
void compileShader();
|
||||
void loadMaterial();
|
||||
|
||||
StringTableEntry getMaterialDefinitionName() { return mMatDefinitionName; }
|
||||
SimObjectPtr<Material> getMaterialDefinition() { return mMaterialDefinition; }
|
||||
|
||||
void setScriptFile(const char* pScriptFile);
|
||||
inline StringTableEntry getScriptFile(void) const { return mScriptFile; };
|
||||
|
||||
inline StringTableEntry getScriptPath(void) const { return mScriptPath; };
|
||||
|
||||
static StringTableEntry getAssetIdByMaterialName(StringTableEntry fileName);
|
||||
static bool getAssetById(StringTableEntry assetId, AssetPtr<MaterialAsset>* materialAsset);
|
||||
/// <summary>
|
||||
/// 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_CONOBJECT(MaterialAsset);
|
||||
|
|
@ -124,159 +142,203 @@ public:
|
|||
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;
|
||||
#define bindMaterialAsset(name) if (m##name##AssetId != StringTable->EmptyString()) m##name##Asset = m##name##AssetId;
|
||||
|
||||
#define scriptBindMaterialAsset(name, consoleClass, docs)\
|
||||
addProtectedField(assetText(name, File), TypeMaterialName, Offset(m##name##Name, consoleClass), consoleClass::_set##name##Name, & defaultProtectedGetFn, assetText(name, docs), AbstractClassRep::FIELD_HideInInspectors); \
|
||||
addProtectedField(assetText(name, Asset), TypeMaterialAssetId, Offset(m##name##AssetId, consoleClass), consoleClass::_set##name##Asset, & defaultProtectedGetFn, assetText(name, asset reference.));
|
||||
|
||||
#define DECLARE_MATERIALASSET(className,name) 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);\
|
||||
//Singular assets
|
||||
/// <Summary>
|
||||
/// Declares an material asset
|
||||
/// This establishes the assetId, asset and legacy filepath fields, along with supplemental getter and setter functions
|
||||
/// </Summary>
|
||||
#define DECLARE_MATERIALASSET(className, name) public: \
|
||||
StringTableEntry m##name##Name;\
|
||||
StringTableEntry m##name##AssetId;\
|
||||
AssetPtr<MaterialAsset> m##name##Asset;\
|
||||
SimObjectPtr<Material> m##name;\
|
||||
public: \
|
||||
const StringTableEntry get##name##File() const { return m##name##Name; }\
|
||||
void set##name##Name(const FileName &_in) { m##name##Name = StringTable->insert(_in.c_str());}\
|
||||
const AssetPtr<MaterialAsset> & get##name##Asset() const { return m##name##Asset; }\
|
||||
void set##name##Asset(const AssetPtr<MaterialAsset> &_in) { m##name##Asset = _in;}\
|
||||
\
|
||||
StringTableEntry assetId = MaterialAsset::getAssetIdByMaterialName(StringTable->insert(data));\
|
||||
if (assetId != StringTable->EmptyString())\
|
||||
bool _set##name(StringTableEntry _in)\
|
||||
{\
|
||||
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;\
|
||||
shape->m##name##AssetId = 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 = MaterialAsset::getAssetById(m##name##AssetId, &m##name##Asset);\
|
||||
\
|
||||
if (MaterialAsset::Ok == assetState)\
|
||||
{\
|
||||
m##name##Name = StringTable->EmptyString();\
|
||||
}\
|
||||
}\
|
||||
else\
|
||||
{\
|
||||
shape->m##name##AssetId = assetId;\
|
||||
shape->m##name##Name = StringTable->EmptyString();\
|
||||
\
|
||||
return false;\
|
||||
StringTableEntry assetId = MaterialAsset::getAssetIdByMaterialName(_in);\
|
||||
if (assetId != StringTable->EmptyString())\
|
||||
{\
|
||||
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;\
|
||||
}\
|
||||
}\
|
||||
}\
|
||||
}\
|
||||
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 (get##name() != StringTable->EmptyString() && m##name##Asset.notNull())\
|
||||
{\
|
||||
if (assetId == StringTable->insert("Core_Rendering:noMaterial"))\
|
||||
{\
|
||||
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();\
|
||||
\
|
||||
if (m##name && String(m##name##Asset->getMaterialDefinitionName()).equal(m##name->getName(), String::NoCase))\
|
||||
return false;\
|
||||
}\
|
||||
\
|
||||
Material* tempMat = nullptr;\
|
||||
\
|
||||
if (!Sim::findObject(m##name##Asset->getMaterialDefinitionName(), tempMat))\
|
||||
Con::errorf("classname::_set##name() - Material %s was not found.", 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);\
|
||||
shape->inspectPostApply();\
|
||||
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;\
|
||||
if(get##name() == StringTable->EmptyString())\
|
||||
return true;\
|
||||
\
|
||||
setMaskBits(bitmask);\
|
||||
inspectPostApply();\
|
||||
if (m##name##Asset.notNull() && m##name##Asset->getStatus() != MaterialAsset::Ok)\
|
||||
{\
|
||||
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 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(map));\
|
||||
}
|
||||
|
||||
#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()))\
|
||||
{\
|
||||
NetStringHandle assetIdStr = m##name##Asset.getAssetId();\
|
||||
|
|
@ -285,14 +347,16 @@ bool set##name##AssetId(const char* _assetId)\
|
|||
else\
|
||||
stream->writeString(m##name##Name);
|
||||
|
||||
#define unpackMaterialAsset(netconn, name)\
|
||||
#define UNPACK_MATERIALASSET(netconn, name)\
|
||||
if (stream->readFlag())\
|
||||
{\
|
||||
m##name##AssetId = StringTable->insert(netconn->unpackNetStringHandleU(stream).getString());\
|
||||
MaterialAsset::getAssetById(m##name##AssetId, &m##name##Asset);\
|
||||
_set##name(m##name##AssetId);\
|
||||
}\
|
||||
else\
|
||||
m##name##Name = stream->readSTString();\
|
||||
m##name##Name = stream->readSTString();
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#endif // _ASSET_BASE_H_
|
||||
|
||||
|
|
|
|||
|
|
@ -161,7 +161,7 @@ GuiControl* GuiInspectorTypeParticleAssetPtr::constructEditControl()
|
|||
mSMEdButton->setField("Command", szBuffer);
|
||||
|
||||
char bitmapName[512] = "tools/worldEditor/images/toolbar/shape-editor";
|
||||
mSMEdButton->setBitmap(bitmapName);
|
||||
mSMEdButton->setBitmap(StringTable->insert(bitmapName));
|
||||
|
||||
mSMEdButton->setDataField(StringTable->insert("Profile"), NULL, "GuiButtonProfile");
|
||||
mSMEdButton->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile");
|
||||
|
|
|
|||
|
|
@ -50,6 +50,8 @@
|
|||
#include "ts/tsLastDetail.h"
|
||||
#endif
|
||||
|
||||
StringTableEntry ShapeAsset::smNoShapeAssetFallback(StringTable->insert(Con::getVariable("$Core::NoShapeAssetFallback")));
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
@ -100,13 +102,7 @@ ConsoleSetType(TypeShapeAssetId)
|
|||
if (argc == 1)
|
||||
{
|
||||
// Yes, so fetch field value.
|
||||
const char* pFieldValue = argv[0];
|
||||
|
||||
// Fetch asset Id.
|
||||
StringTableEntry* assetId = (StringTableEntry*)(dptr);
|
||||
|
||||
// Update asset value.
|
||||
*assetId = StringTable->insert(pFieldValue);
|
||||
*((const char**)dptr) = StringTable->insert(argv[0]);
|
||||
|
||||
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()
|
||||
{
|
||||
// Call parent.
|
||||
|
|
@ -154,7 +161,7 @@ void ShapeAsset::initPersistFields()
|
|||
&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);
|
||||
|
||||
|
|
@ -344,49 +351,39 @@ bool ShapeAsset::loadShape()
|
|||
|
||||
//------------------------------------------------------------------------------
|
||||
//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;
|
||||
S32 foundAssetcount = AssetDatabase.findAssetLooseFile(&query, fileName);
|
||||
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
|
||||
shapeAsset->setAssetId(StringTable->insert("Core_Rendering:noshape"));
|
||||
shapeAsset->setAssetId(ShapeAsset::smNoShapeAssetFallback);
|
||||
|
||||
if (!shapeAsset->isNull())
|
||||
return true;
|
||||
if (shapeAsset->isNull())
|
||||
{
|
||||
//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
|
||||
return false;
|
||||
//handle noshape not being loaded itself
|
||||
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
|
||||
{
|
||||
//acquire and bind the asset, and return it out
|
||||
shapeAsset->setAssetId(query.mAssetList[0]);
|
||||
return true;
|
||||
return (*shapeAsset)->mLoadedState;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -395,37 +392,11 @@ StringTableEntry ShapeAsset::getAssetIdByFilename(StringTableEntry fileName)
|
|||
if (fileName == StringTable->EmptyString())
|
||||
return StringTable->EmptyString();
|
||||
|
||||
StringTableEntry shapeAssetId = StringTable->EmptyString();
|
||||
StringTableEntry shapeAssetId = ShapeAsset::smNoShapeAssetFallback;
|
||||
|
||||
AssetQuery query;
|
||||
S32 foundAssetcount = AssetDatabase.findAssetLooseFile(&query, fileName);
|
||||
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
|
||||
if (foundAssetcount != 0)
|
||||
{
|
||||
//acquire and bind the asset, and return it out
|
||||
shapeAssetId = query.mAssetList[0];
|
||||
|
|
@ -438,24 +409,34 @@ U32 ShapeAsset::getAssetById(StringTableEntry assetId, AssetPtr<ShapeAsset>* sha
|
|||
{
|
||||
(*shapeAsset) = assetId;
|
||||
|
||||
if ((*shapeAsset))
|
||||
return (*shapeAsset)->mLoadedState;
|
||||
|
||||
if (shapeAsset->notNull())
|
||||
{
|
||||
return (*shapeAsset)->mLoadedState;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Didn't work, so have us fall back to a placeholder asset
|
||||
StringTableEntry noShapeId = StringTable->insert("Core_Rendering:noshape");
|
||||
shapeAsset->setAssetId(noShapeId);
|
||||
shapeAsset->setAssetId(ShapeAsset::smNoShapeAssetFallback);
|
||||
|
||||
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
|
||||
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;
|
||||
return AssetErrCode::UsingFallback;
|
||||
}
|
||||
|
||||
return AssetErrCode::Failed;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
|
@ -561,11 +542,24 @@ DefineEngineMethod(ShapeAsset, getShapeFile, const char*, (), ,
|
|||
return object->getShapeFilePath();
|
||||
}
|
||||
|
||||
DefineEngineMethod(ShapeAsset, getStatusString, String, (), , "get status string")\
|
||||
{
|
||||
return ShapeAsset::getAssetErrstrn(object->getStatus());
|
||||
}
|
||||
|
||||
|
||||
#ifdef TORQUE_TOOLS
|
||||
DefineEngineMethod(ShapeAsset, generateCachedPreviewImage, const char*, (S32 resolution), (256), "")
|
||||
{
|
||||
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
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -612,7 +606,7 @@ GuiControl* GuiInspectorTypeShapeAssetPtr::constructEditControl()
|
|||
mShapeEdButton->setField("Command", szBuffer);
|
||||
|
||||
char bitmapName[512] = "tools/worldEditor/images/toolbar/shape-editor";
|
||||
mShapeEdButton->setBitmap(bitmapName);
|
||||
mShapeEdButton->setBitmap(StringTable->insert(bitmapName));
|
||||
|
||||
mShapeEdButton->setDataField(StringTable->insert("Profile"), NULL, "GuiButtonProfile");
|
||||
mShapeEdButton->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile");
|
||||
|
|
|
|||
|
|
@ -81,9 +81,11 @@ protected:
|
|||
Vector<AssetPtr<ShapeAnimationAsset>> mAnimationAssets;
|
||||
|
||||
typedef Signal<void()> ShapeAssetChanged;
|
||||
|
||||
ShapeAssetChanged mChangeSignal;
|
||||
|
||||
typedef Signal<void(S32 index)> ShapeAssetArrayChanged;
|
||||
ShapeAssetArrayChanged mChangeArraySignal;
|
||||
|
||||
public:
|
||||
enum ShapeAssetErrCode
|
||||
{
|
||||
|
|
@ -93,7 +95,12 @@ public:
|
|||
Extended
|
||||
};
|
||||
|
||||
static StringTableEntry smNoShapeAssetFallback;
|
||||
|
||||
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)
|
||||
{
|
||||
if (errCode < Parent::Extended) return Parent::getAssetErrstrn(errCode);
|
||||
|
|
@ -104,11 +111,14 @@ public:
|
|||
ShapeAsset();
|
||||
virtual ~ShapeAsset();
|
||||
|
||||
/// Set up some global script interface stuff.
|
||||
static void consoleInit();
|
||||
|
||||
/// Engine.
|
||||
static void initPersistFields();
|
||||
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();
|
||||
|
||||
|
|
@ -116,25 +126,25 @@ public:
|
|||
DECLARE_CONOBJECT(ShapeAsset);
|
||||
|
||||
bool loadShape();
|
||||
U32 mLoadedState;
|
||||
|
||||
TSShape* getShape() { return mShape; }
|
||||
|
||||
Resource<TSShape> getShapeResource() { return mShape; }
|
||||
|
||||
void SplitSequencePathAndName(String& srcPath, String& srcName);
|
||||
StringTableEntry getShapeFilename() { return mFilePath; }
|
||||
|
||||
StringTableEntry getShapeFileName() { return mFileName; }
|
||||
StringTableEntry getShapePath() { return mFilePath; }
|
||||
|
||||
U32 getShapeFilenameHash() { return _StringTable::hashString(mFilePath); }
|
||||
|
||||
Vector<AssetPtr<MaterialAsset>> getMaterialAssets() { return mMaterialAssets; }
|
||||
|
||||
inline AssetPtr<MaterialAsset> getMaterialAsset(U32 matId)
|
||||
{
|
||||
if(matId >= mMaterialAssets.size())
|
||||
return nullptr;
|
||||
else
|
||||
return mMaterialAssets[matId];
|
||||
inline AssetPtr<MaterialAsset> getMaterialAsset(U32 matId)
|
||||
{
|
||||
if (matId >= mMaterialAssets.size())
|
||||
return nullptr;
|
||||
else
|
||||
return mMaterialAssets[matId];
|
||||
}
|
||||
|
||||
void clearMaterialAssets() { mMaterialAssets.clear(); }
|
||||
|
|
@ -145,9 +155,10 @@ public:
|
|||
S32 getAnimationCount() { return mAnimationAssets.size(); }
|
||||
ShapeAnimationAsset* getAnimation(S32 index);
|
||||
|
||||
void _onResourceChanged(const Torque::Path &path);
|
||||
void _onResourceChanged(const Torque::Path& path);
|
||||
|
||||
ShapeAssetChanged& getChangedSignal() { return mChangeSignal; }
|
||||
ShapeAssetArrayChanged& getChangedArraySignal() { return mChangeArraySignal; }
|
||||
|
||||
void setShapeFile(const char* pScriptFile);
|
||||
inline StringTableEntry getShapeFile(void) const { return mFileName; };
|
||||
|
|
@ -158,13 +169,11 @@ public:
|
|||
inline StringTableEntry getShapeFilePath(void) const { return mFilePath; };
|
||||
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 U32 getAssetById(StringTableEntry assetId, AssetPtr<ShapeAsset>* shapeAsset);
|
||||
|
||||
static StringTableEntry getNoShapeAssetId() { return StringTable->insert("Core_Rendering:noshape"); }
|
||||
|
||||
#ifdef TORQUE_TOOLS
|
||||
const char* generateCachedPreviewImage(S32 resolution);
|
||||
#endif
|
||||
|
|
@ -172,7 +181,7 @@ public:
|
|||
protected:
|
||||
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 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;
|
||||
public:
|
||||
|
||||
GuiBitmapButtonCtrl *mShapeEdButton;
|
||||
GuiBitmapButtonCtrl* mShapeEdButton;
|
||||
|
||||
DECLARE_CONOBJECT(GuiInspectorTypeShapeAssetPtr);
|
||||
static void consoleInit();
|
||||
|
|
@ -211,86 +220,413 @@ public:
|
|||
};
|
||||
#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 cloneShapeAsset(name) m##name##Name = other.m##name##Name; m##name##AssetId = other.m##name##AssetId; m##name##Asset = other.m##name##Asset;
|
||||
#define bindShapeAsset(name) if (m##name##AssetId != StringTable->EmptyString()) m##name##Asset = 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)); \
|
||||
addProtectedField(assetText(name, Asset), TypeShapeAssetId, Offset(m##name##AssetId, consoleClass), consoleClass::_set##name##Asset, & defaultProtectedGetFn, assetText(name, asset reference.));
|
||||
|
||||
#define DECLARE_SHAPEASSET(className,name)\
|
||||
StringTableEntry m##name##Name;\
|
||||
StringTableEntry m##name##AssetId;\
|
||||
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);\
|
||||
#define DECLARE_SHAPEASSET(className,name,changeFunc) public: \
|
||||
Resource<TSShape>m##name;\
|
||||
StringTableEntry m##name##Name; \
|
||||
StringTableEntry m##name##AssetId;\
|
||||
AssetPtr<ShapeAsset> m##name##Asset;\
|
||||
public: \
|
||||
const StringTableEntry get##name##File() const { return StringTable->insert(m##name##Name); }\
|
||||
void set##name##Name(const FileName &_in) { m##name##Name = _in;}\
|
||||
const AssetPtr<ShapeAsset> & get##name##Asset() const { return m##name##Asset; }\
|
||||
void set##name##Asset(const AssetPtr<ShapeAsset> &_in) { m##name##Asset = _in;}\
|
||||
\
|
||||
StringTableEntry assetId = ShapeAsset::getAssetIdByFilename(StringTable->insert(data));\
|
||||
if (assetId != StringTable->EmptyString())\
|
||||
bool _set##name(StringTableEntry _in)\
|
||||
{\
|
||||
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;\
|
||||
shape->m##name##AssetId = StringTable->EmptyString();\
|
||||
\
|
||||
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 = NULL;\
|
||||
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\
|
||||
{\
|
||||
shape->m##name##AssetId = assetId;\
|
||||
shape->m##name##Name = StringTable->EmptyString();\
|
||||
\
|
||||
return false;\
|
||||
StringTableEntry assetId = ShapeAsset::getAssetIdByFilename(_in);\
|
||||
if (assetId != StringTable->EmptyString())\
|
||||
{\
|
||||
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;\
|
||||
}\
|
||||
}\
|
||||
}\
|
||||
}\
|
||||
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 (ShapeAsset::getAssetById(shape->m##name##AssetId, &shape->m##name##Asset))\
|
||||
{\
|
||||
if (shape->m##name##Asset.getAssetId() != StringTable->insert("Core_Rendering:noShape"))\
|
||||
shape->m##name##Name = StringTable->EmptyString();\
|
||||
if (get##name() != StringTable->EmptyString() && m##name##Asset.notNull())\
|
||||
{\
|
||||
m##name = m##name##Asset->getShapeResource();\
|
||||
\
|
||||
m##name##Asset->getChangedSignal().notify(this, &className::changeFunc);\
|
||||
}\
|
||||
else\
|
||||
{\
|
||||
m##name = NULL;\
|
||||
}\
|
||||
\
|
||||
if(get##name() == StringTable->EmptyString())\
|
||||
return true;\
|
||||
\
|
||||
if (m##name##Asset.notNull() && m##name##Asset->getStatus() != ShapeAsset::Ok)\
|
||||
{\
|
||||
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 false;\
|
||||
}\
|
||||
void pack##name##Asset(BitStream *stream)\
|
||||
\
|
||||
const StringTableEntry get##name() const\
|
||||
{\
|
||||
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;\
|
||||
_set##name(StringTable->insert(ShapeAsset::smNoShapeAssetFallback));
|
||||
|
||||
#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()))\
|
||||
{\
|
||||
stream->writeString(m##name##Asset.getAssetId());\
|
||||
}\
|
||||
else\
|
||||
stream->writeString(m##name##Name);\
|
||||
}\
|
||||
void unpack##name##Asset(BitStream *stream)\
|
||||
{\
|
||||
stream->writeString(m##name##Name);
|
||||
|
||||
#define UNPACKDATA_SHAPEASSET(name)\
|
||||
if (stream->readFlag())\
|
||||
{\
|
||||
m##name##AssetId = stream->readSTString();\
|
||||
ShapeAsset::getAssetById(m##name##AssetId, &m##name##Asset);\
|
||||
m##name##Name = m##name##Asset->getShapeFilename(); \
|
||||
_set##name(m##name##AssetId);\
|
||||
}\
|
||||
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;\
|
||||
_set##name(StringTable->insert(ShapeAsset::smNoShapeAssetFallback), index);
|
||||
|
||||
#ifdef TORQUE_SHOW_LEGACY_FILE_FIELDS
|
||||
|
||||
#define INITPERSISTFIELD_SHAPEASSET_ARRAY(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_ARRAY(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_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.
|
||||
#include "platform/profiler.h"
|
||||
#include "sfx/sfxTypes.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
IMPLEMENT_CONOBJECT(SoundAsset);
|
||||
|
||||
ConsoleType(SoundAssetPtr, TypeSoundAssetPtr, SoundAsset, ASSET_ID_FIELD_PREFIX)
|
||||
ConsoleType(SoundAssetPtr, TypeSoundAssetPtr, const char*, ASSET_ID_FIELD_PREFIX)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
ConsoleGetType(TypeSoundAssetPtr)
|
||||
{
|
||||
// Fetch asset Id.
|
||||
return (*((AssetPtr<SoundAsset>*)dptr)).getAssetId();
|
||||
return *((const char**)(dptr));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -65,21 +66,7 @@ ConsoleSetType(TypeSoundAssetPtr)
|
|||
if (argc == 1)
|
||||
{
|
||||
// Yes, so fetch field value.
|
||||
const char* pFieldValue = 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);
|
||||
*((const char**)dptr) = StringTable->insert(argv[0]);
|
||||
|
||||
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()
|
||||
{
|
||||
mSoundFile = StringTable->EmptyString();
|
||||
mSoundPath = StringTable->EmptyString();
|
||||
mSubtitleString = StringTable->EmptyString();
|
||||
|
||||
mPitchAdjust = 1;
|
||||
mVolumeAdjust = 1;
|
||||
mLoadedState = AssetErrCode::NotLoaded;
|
||||
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),
|
||||
&setSoundFile, &getSoundFile, "Path to the sound file.");
|
||||
|
||||
addField("pitchAdjust", TypeF32, Offset(mPitchAdjust, SoundAsset), "Adjustment of the pitch value");
|
||||
addField("volumeAdjust", TypeF32, Offset(mVolumeAdjust, SoundAsset), "Adjustment to the volume.");
|
||||
addField("pitchAdjust", TypeF32, Offset(mProfileDesc.mPitch, SoundAsset), "Adjustment of the pitch value 1 is default.");
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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 (!Platform::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)
|
||||
{
|
||||
// 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);
|
||||
|
||||
// Ignore no change,
|
||||
|
|
@ -152,7 +250,7 @@ void SoundAsset::setSoundFile(const char* pSoundFile)
|
|||
return;
|
||||
|
||||
// Update.
|
||||
mSoundFile = StringTable->insert(pSoundFile);
|
||||
mSoundFile = pSoundFile;
|
||||
|
||||
// Refresh the asset.
|
||||
refreshAsset();
|
||||
|
|
@ -162,3 +260,43 @@ DefineEngineMethod(SoundAsset, getSoundPath, const char*, (), , "")
|
|||
{
|
||||
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"
|
||||
#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
|
||||
|
|
@ -49,8 +67,36 @@ class SoundAsset : public AssetBase
|
|||
protected:
|
||||
StringTableEntry mSoundFile;
|
||||
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 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:
|
||||
SoundAsset();
|
||||
|
|
@ -60,16 +106,26 @@ public:
|
|||
static void initPersistFields();
|
||||
virtual void copyTo(SimObject* object);
|
||||
|
||||
//SFXResource* getSound() { return mSoundResource; }
|
||||
Resource<SFXResource> getSoundResource() { return mSFXProfile.getResource(); }
|
||||
|
||||
/// Declare Console Object.
|
||||
DECLARE_CONOBJECT(SoundAsset);
|
||||
|
||||
void setSoundFile(const char* pSoundFile);
|
||||
bool loadSound();
|
||||
inline StringTableEntry getSoundFile(void) const { return mSoundFile; };
|
||||
|
||||
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:
|
||||
virtual void initializeAsset(void);
|
||||
void _onResourceChanged(const Torque::Path & path);
|
||||
virtual void onAssetRefresh(void);
|
||||
|
||||
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(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_
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
@ -107,11 +107,7 @@ ConsoleSetType(TypeTerrainAssetId)
|
|||
// Yes, so fetch field value.
|
||||
const char* pFieldValue = argv[0];
|
||||
|
||||
// Fetch asset Id.
|
||||
StringTableEntry* assetId = (StringTableEntry*)(dptr);
|
||||
|
||||
// Update asset value.
|
||||
*assetId = StringTable->insert(pFieldValue);
|
||||
*((const char**)dptr) = StringTable->insert(argv[0]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
@ -472,7 +468,7 @@ GuiControl* GuiInspectorTypeTerrainAssetPtr::constructEditControl()
|
|||
mShapeEdButton->setField("Command", "EditorGui.setEditor(TerrainEditorPlugin);");
|
||||
|
||||
char bitmapName[512] = "tools/worldEditor/images/toolbar/shape-editor";
|
||||
mShapeEdButton->setBitmap(bitmapName);
|
||||
mShapeEdButton->setBitmap(StringTable->insert(bitmapName));
|
||||
|
||||
mShapeEdButton->setDataField(StringTable->insert("Profile"), NULL, "GuiButtonProfile");
|
||||
mShapeEdButton->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile");
|
||||
|
|
|
|||
|
|
@ -119,8 +119,6 @@ void TerrainMaterialAsset::initializeAsset()
|
|||
// Call parent.
|
||||
Parent::initializeAsset();
|
||||
|
||||
compileShader();
|
||||
|
||||
mScriptPath = expandAssetFilePath(mScriptFile);
|
||||
|
||||
if (Platform::isFile(mScriptPath))
|
||||
|
|
@ -164,21 +162,49 @@ void TerrainMaterialAsset::setScriptFile(const char* pScriptFile)
|
|||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void TerrainMaterialAsset::compileShader()
|
||||
{
|
||||
}
|
||||
|
||||
void TerrainMaterialAsset::copyTo(SimObject* object)
|
||||
{
|
||||
// Call to parent.
|
||||
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
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ public:
|
|||
static void initPersistFields();
|
||||
virtual void copyTo(SimObject* object);
|
||||
|
||||
void compileShader();
|
||||
static StringTableEntry getAssetIdByMaterialName(StringTableEntry matName);
|
||||
|
||||
StringTableEntry getMaterialDefinitionName() { return mMatDefinitionName; }
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ AssetImportConfig::AssetImportConfig() :
|
|||
WarningsAsErrors(false),
|
||||
PreventImportWithErrors(true),
|
||||
AutomaticallyPromptMissingFiles(false),
|
||||
AddDirectoryPrefixToAssetName(false),
|
||||
ImportMesh(true),
|
||||
AlwaysAddShapeSuffix(false),
|
||||
AddedShapeSuffix("_shape"),
|
||||
|
|
@ -89,7 +90,7 @@ AssetImportConfig::AssetImportConfig() :
|
|||
ImageType("GUI"),
|
||||
DiffuseTypeSuffixes("_ALBEDO,_DIFFUSE,_ALB,_DIF,_COLOR,_COL,_A,_C,-ALBEDO,-DIFFUSE,-ALB,-DIF,-COLOR,-COL,-A,-C"),
|
||||
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"),
|
||||
SmoothnessTypeSuffixes("_SMOOTH,_SMOOTHNESS,_S,-SMOOTH,-SMOOTHNESS,-S"),
|
||||
AOTypeSuffixes("_AO,_AMBIENT,_AMBIENTOCCLUSION,-AO,-AMBIENT,-AMBIENTOCCLUSION"),
|
||||
|
|
@ -135,6 +136,7 @@ void AssetImportConfig::initPersistFields()
|
|||
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("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");
|
||||
|
||||
addGroup("Meshes");
|
||||
|
|
@ -232,6 +234,7 @@ void AssetImportConfig::loadImportConfig(Settings* configSettings, String config
|
|||
WarningsAsErrors = dAtob(configSettings->value(String(configName + "/General/WarningsAsErrors").c_str()));
|
||||
PreventImportWithErrors = dAtob(configSettings->value(String(configName + "/General/PreventImportWithErrors").c_str()));
|
||||
AutomaticallyPromptMissingFiles = dAtob(configSettings->value(String(configName + "/General/AutomaticallyPromptMissingFiles").c_str()));
|
||||
AddDirectoryPrefixToAssetName = dAtob(configSettings->value(String(configName + "/General/AddDirectoryPrefixToAssetName").c_str()));
|
||||
|
||||
//Meshes
|
||||
ImportMesh = dAtob(configSettings->value(String(configName + "/Meshes/ImportMesh").c_str()));
|
||||
|
|
@ -321,6 +324,7 @@ void AssetImportConfig::CopyTo(AssetImportConfig* target) const
|
|||
target->WarningsAsErrors = WarningsAsErrors;
|
||||
target->PreventImportWithErrors = PreventImportWithErrors;
|
||||
target->AutomaticallyPromptMissingFiles = AutomaticallyPromptMissingFiles;
|
||||
target->AddDirectoryPrefixToAssetName = AddDirectoryPrefixToAssetName;
|
||||
|
||||
//Meshes
|
||||
target->ImportMesh = ImportMesh;
|
||||
|
|
@ -1444,8 +1448,8 @@ void AssetImporter::processImportAssets(AssetImportObject* assetItem)
|
|||
if (!childItem->processed)
|
||||
{
|
||||
//Sanitize before modifying our asset name(suffix additions, etc)
|
||||
if (childItem->assetName != childItem->cleanAssetName)
|
||||
childItem->assetName = childItem->cleanAssetName;
|
||||
//if (childItem->assetName != childItem->cleanAssetName)
|
||||
// childItem->assetName = childItem->cleanAssetName;
|
||||
|
||||
//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;
|
||||
}
|
||||
|
|
@ -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)
|
||||
{
|
||||
//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);
|
||||
//check to see if the definition for this already exists
|
||||
StringTableEntry existingMatAsset = MaterialAsset::getAssetIdByMaterialName(StringTable->insert(assetName));
|
||||
|
||||
AssetImportObject* matchedImageTypes[ImageAsset::ImageTypeCount] = { nullptr };
|
||||
|
||||
String materialImageNoSuffix;
|
||||
|
||||
for (U32 i = 0; i < assetItem->childAssetItems.size(); i++)
|
||||
if (existingMatAsset != StringTable->EmptyString())
|
||||
{
|
||||
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"))
|
||||
continue;
|
||||
//If there was no existing assetId, then lets see if it already exists in a legacy file, like a materials.cs or materials.tscript
|
||||
//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
|
||||
if (!dStricmp(ImageAsset::getImageTypeNameFromType((ImageAsset::ImageTypes)t), childAssetItem->imageSuffixType.c_str()))
|
||||
AssetImportObject* childAssetItem = assetItem->childAssetItems[i];
|
||||
|
||||
if (childAssetItem->skip || childAssetItem->assetType != String("ImageAsset"))
|
||||
continue;
|
||||
|
||||
for (S32 t = 0; t < ImageAsset::ImageTypeCount; t++)
|
||||
{
|
||||
matchedImageTypes[t] = childAssetItem;
|
||||
|
||||
if (t == ImageAsset::ImageTypes::Albedo)
|
||||
//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()))
|
||||
{
|
||||
String sufType;
|
||||
String suffix = parseImageSuffixes(childAssetItem->assetName, &sufType);
|
||||
matchedImageTypes[t] = childAssetItem;
|
||||
|
||||
String imageAssetName = childAssetItem->assetName;
|
||||
if (t == ImageAsset::ImageTypes::Albedo)
|
||||
{
|
||||
String sufType;
|
||||
String suffix = parseImageSuffixes(childAssetItem->assetName, &sufType);
|
||||
|
||||
if (suffix.isEmpty())
|
||||
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
|
||||
String imageAssetName = childAssetItem->assetName;
|
||||
|
||||
if (suffix.isEmpty())
|
||||
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
|
||||
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)
|
||||
//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++)
|
||||
{
|
||||
case ImageAsset::Albedo:
|
||||
suffixList = activeImportConfig->DiffuseTypeSuffixes;
|
||||
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
|
||||
}
|
||||
//This type wasn't found, so try and find a match based on suffix
|
||||
String suffixList;
|
||||
|
||||
if (!matchedImageTypes[t])
|
||||
{
|
||||
U32 suffixCount = StringUnit::getUnitCount(suffixList.c_str(), ",;\t");
|
||||
for (U32 i = 0; i < suffixCount; i++)
|
||||
switch (t)
|
||||
{
|
||||
//First, try checking based on the material's assetName for our patternbase
|
||||
String testPath = assetItem->filePath.getRootAndPath();
|
||||
testPath += "/" + assetItem->cleanAssetName + StringUnit::getUnit(suffixList.c_str(), i, ",;\t");
|
||||
case ImageAsset::Albedo:
|
||||
suffixList = activeImportConfig->DiffuseTypeSuffixes;
|
||||
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 (imagePath.isNotEmpty())
|
||||
if (!matchedImageTypes[t])
|
||||
{
|
||||
U32 suffixCount = StringUnit::getUnitCount(suffixList.c_str(), ",;\t");
|
||||
for (U32 i = 0; i < suffixCount; i++)
|
||||
{
|
||||
//got a match!
|
||||
AssetImportObject* newImageAssetObj = addImportingAsset("ImageAsset", imagePath, assetItem, "");
|
||||
//First, try checking based on the material's assetName for our patternbase
|
||||
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;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(materialImageNoSuffix.isNotEmpty())
|
||||
if (imagePath.isNotEmpty())
|
||||
{
|
||||
testPath = assetItem->filePath.getRootAndPath();
|
||||
testPath += "/" + materialImageNoSuffix + StringUnit::getUnit(suffixList.c_str(), i, ",;\t");
|
||||
//got a match!
|
||||
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!
|
||||
AssetImportObject* newImageAssetObj = addImportingAsset("ImageAsset", imagePath, assetItem, "");
|
||||
testPath = assetItem->filePath.getRootAndPath();
|
||||
testPath += "/" + materialImageNoSuffix + StringUnit::getUnit(suffixList.c_str(), i, ",;\t");
|
||||
|
||||
newImageAssetObj->imageSuffixType = ImageAsset::getImageTypeNameFromType((ImageAsset::ImageTypes)t);
|
||||
imagePath = AssetImporter::findImagePath(testPath);
|
||||
|
||||
matchedImageTypes[t] = newImageAssetObj;
|
||||
break;
|
||||
if (imagePath.isNotEmpty())
|
||||
{
|
||||
//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 (t == ImageAsset::Albedo && matchedImageTypes[t] == nullptr)
|
||||
{
|
||||
String testPath = assetItem->filePath.getRootAndPath() + "/" + assetItem->cleanAssetName;
|
||||
String imagePath = AssetImporter::findImagePath(testPath);
|
||||
|
||||
if (imagePath.isNotEmpty())
|
||||
//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)
|
||||
{
|
||||
//got a match!
|
||||
AssetImportObject* newImageAssetObj = addImportingAsset("ImageAsset", imagePath, assetItem, "");
|
||||
String testPath = assetItem->filePath.getRootAndPath() + "/" + assetItem->cleanAssetName;
|
||||
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 (newImageAssetObj->assetName == assetItem->assetName)
|
||||
if (imagePath.isNotEmpty())
|
||||
{
|
||||
newImageAssetObj->assetName += StringUnit::getUnit(suffixList.c_str(), 0, ",;\t");
|
||||
newImageAssetObj->cleanAssetName = newImageAssetObj->assetName;
|
||||
//got a match!
|
||||
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);
|
||||
|
||||
matchedImageTypes[t] = newImageAssetObj;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//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
|
||||
//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)
|
||||
AssetImportObject* childAssetItem = assetItem->childAssetItems[i];
|
||||
|
||||
if (childAssetItem->skip || childAssetItem->processed || childAssetItem->assetType != String("ImageAsset"))
|
||||
continue;
|
||||
|
||||
if (childAssetItem->imageSuffixType == String("Albedo"))
|
||||
{
|
||||
matchedImageTypes[t]->assetName += StringUnit::getUnit(suffixList.c_str(), 0, ",;\t");
|
||||
matchedImageTypes[t]->cleanAssetName = matchedImageTypes[t]->assetName;
|
||||
assetItem->diffuseImageAsset = % childAssetItem;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
/*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;
|
||||
|
|
@ -1822,6 +1888,7 @@ void AssetImporter::processShapeAsset(AssetImportObject* assetItem)
|
|||
if (activeImportConfig->AlwaysAddShapeSuffix)
|
||||
{
|
||||
assetItem->assetName += activeImportConfig->AddedShapeSuffix;
|
||||
assetItem->cleanAssetName = assetItem->assetName;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
//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
|
||||
|
|
@ -2284,7 +2351,7 @@ void AssetImporter::resolveAssetItemIssues(AssetImportObject* assetItem)
|
|||
deleteImportingAsset(assetItem);
|
||||
|
||||
//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);
|
||||
|
||||
importIssues = false;
|
||||
|
|
@ -2348,7 +2415,7 @@ void AssetImporter::resetImportConfig()
|
|||
//
|
||||
// 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
|
||||
resetImportSession(true);
|
||||
|
|
@ -2359,6 +2426,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());
|
||||
activityLog.push_back(importLogBuffer);
|
||||
|
||||
dumpActivityLog();
|
||||
return StringTable->EmptyString();
|
||||
}
|
||||
|
||||
|
|
@ -2366,6 +2435,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());
|
||||
activityLog.push_back(importLogBuffer);
|
||||
|
||||
dumpActivityLog();
|
||||
return StringTable->EmptyString();
|
||||
}
|
||||
|
||||
|
|
@ -2374,7 +2445,10 @@ StringTableEntry AssetImporter::autoImportFile(Torque::Path filePath)
|
|||
|
||||
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();
|
||||
}
|
||||
else
|
||||
|
|
@ -2404,14 +2478,7 @@ StringTableEntry AssetImporter::autoImportFile(Torque::Path filePath)
|
|||
importAssets();
|
||||
}
|
||||
|
||||
#if TORQUE_DEBUG
|
||||
Con::printf("/***************/");
|
||||
for (U32 i = 0; i < activityLog.size(); i++)
|
||||
{
|
||||
Con::printf(activityLog[i].c_str());
|
||||
}
|
||||
Con::printf("/***************/");
|
||||
#endif
|
||||
dumpActivityLog();
|
||||
|
||||
if (hasIssues)
|
||||
{
|
||||
|
|
@ -2628,8 +2695,15 @@ Torque::Path AssetImporter::importImageAsset(AssetImportObject* assetItem)
|
|||
newAsset->setDataField(StringTable->insert("originalFilePath"), nullptr, qualifiedFromFile);
|
||||
}
|
||||
|
||||
ImageAsset::ImageTypes imageType = ImageAsset::getImageTypeFromName(assetItem->imageSuffixType.c_str());
|
||||
newAsset->setImageType(imageType);
|
||||
if (assetItem->typeHint != String::EmptyString)
|
||||
{
|
||||
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;
|
||||
bool importSuccessful = tamlWriter.write(newAsset, tamlPath.c_str());
|
||||
|
|
@ -2694,7 +2768,7 @@ Torque::Path AssetImporter::importMaterialAsset(AssetImportObject* assetItem)
|
|||
dSprintf(dependencyFieldName, 64, "imageMap%i", dependencySlotId);
|
||||
|
||||
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);
|
||||
|
||||
|
|
@ -2752,74 +2826,96 @@ Torque::Path AssetImporter::importMaterialAsset(AssetImportObject* assetItem)
|
|||
FileObject* file = new FileObject();
|
||||
file->registerObject();
|
||||
|
||||
//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);
|
||||
|
||||
//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)
|
||||
if (activeImportConfig->UseExistingMaterials && Platform::isFile(qualifiedFromFile))
|
||||
{
|
||||
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)
|
||||
{
|
||||
for (U32 i = 0; i < assetItem->childAssetItems.size(); i++)
|
||||
//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);
|
||||
|
||||
if (existingMat == nullptr && assetItem->assetName != assetItem->cleanAssetName)
|
||||
{
|
||||
AssetImportObject* childItem = assetItem->childAssetItems[i];
|
||||
|
||||
if (childItem->skip || !childItem->processed || childItem->assetType.compare("ImageAsset") != 0)
|
||||
continue;
|
||||
|
||||
String path = childItem->filePath.getFullFileName();
|
||||
|
||||
String mapFieldName = "";
|
||||
String assetFieldName = "";
|
||||
|
||||
ImageAsset::ImageTypes imageType = ImageAsset::getImageTypeFromName(childItem->imageSuffixType);
|
||||
|
||||
if (imageType == ImageAsset::ImageTypes::Albedo || childItem->imageSuffixType.isEmpty())
|
||||
{
|
||||
mapFieldName = "DiffuseMap";
|
||||
}
|
||||
else if (imageType == ImageAsset::ImageTypes::Normal)
|
||||
{
|
||||
mapFieldName = "NormalMap";
|
||||
}
|
||||
else if (imageType == ImageAsset::ImageTypes::ORMConfig)
|
||||
{
|
||||
mapFieldName = "ORMConfig";
|
||||
}
|
||||
else if (imageType == ImageAsset::ImageTypes::Metalness)
|
||||
{
|
||||
mapFieldName = "MetalnessMap";
|
||||
}
|
||||
else if (imageType == ImageAsset::ImageTypes::AO)
|
||||
{
|
||||
mapFieldName = "AOMap";
|
||||
}
|
||||
else if (imageType == ImageAsset::ImageTypes::Roughness)
|
||||
{
|
||||
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());
|
||||
existingMat = MATMGR->getMaterialDefinitionByName(assetItem->cleanAssetName);
|
||||
if (existingMat == nullptr)
|
||||
existingMat = MATMGR->getMaterialDefinitionByMapTo(assetItem->cleanAssetName);
|
||||
}
|
||||
|
||||
if (existingMat)
|
||||
{
|
||||
PersistenceManager* persistMgr;
|
||||
if (Sim::findObject("ImageAssetValidator", persistMgr))
|
||||
{
|
||||
for (U32 i = 0; i < assetItem->childAssetItems.size(); i++)
|
||||
{
|
||||
AssetImportObject* childItem = assetItem->childAssetItems[i];
|
||||
|
||||
if (childItem->skip || !childItem->processed || childItem->assetType.compare("ImageAsset") != 0)
|
||||
continue;
|
||||
|
||||
String path = childItem->filePath.getFullFileName();
|
||||
|
||||
String mapFieldName = "";
|
||||
String assetFieldName = "";
|
||||
|
||||
ImageAsset::ImageTypes imageType = ImageAsset::getImageTypeFromName(childItem->imageSuffixType);
|
||||
|
||||
if (imageType == ImageAsset::ImageTypes::Albedo || childItem->imageSuffixType.isEmpty())
|
||||
{
|
||||
mapFieldName = "DiffuseMap";
|
||||
}
|
||||
else if (imageType == ImageAsset::ImageTypes::Normal)
|
||||
{
|
||||
mapFieldName = "NormalMap";
|
||||
}
|
||||
else if (imageType == ImageAsset::ImageTypes::ORMConfig)
|
||||
{
|
||||
mapFieldName = "ORMConfig";
|
||||
}
|
||||
else if (imageType == ImageAsset::ImageTypes::Metalness)
|
||||
{
|
||||
mapFieldName = "MetalnessMap";
|
||||
}
|
||||
else if (imageType == ImageAsset::ImageTypes::AO)
|
||||
{
|
||||
mapFieldName = "AOMap";
|
||||
}
|
||||
else if (imageType == ImageAsset::ImageTypes::Roughness)
|
||||
{
|
||||
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()))
|
||||
{
|
||||
file->writeLine((U8*)"//--- OBJECT WRITE BEGIN ---");
|
||||
|
|
@ -2936,7 +3032,7 @@ Torque::Path AssetImporter::importShapeAsset(AssetImportObject* assetItem)
|
|||
newAsset->setShapeFile(shapeFileName.c_str());
|
||||
newAsset->setShapeConstructorFile(constructorFileName.c_str());
|
||||
|
||||
AssetImportConfig* cachedConfig = new AssetImportConfig();;
|
||||
AssetImportConfig* cachedConfig = new AssetImportConfig();
|
||||
cachedConfig->registerObject();
|
||||
activeImportConfig->CopyTo(cachedConfig);
|
||||
|
||||
|
|
@ -2968,7 +3064,7 @@ Torque::Path AssetImporter::importShapeAsset(AssetImportObject* assetItem)
|
|||
dSprintf(dependencyFieldName, 64, "materialSlot%i", dependencySlotId);
|
||||
|
||||
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);
|
||||
|
||||
|
|
@ -2980,7 +3076,7 @@ Torque::Path AssetImporter::importShapeAsset(AssetImportObject* assetItem)
|
|||
dSprintf(dependencyFieldName, 64, "animationSequence%i", dependencySlotId);
|
||||
|
||||
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);
|
||||
|
||||
|
|
@ -3036,7 +3132,7 @@ Torque::Path AssetImporter::importShapeAsset(AssetImportObject* assetItem)
|
|||
TSShapeConstructor* constructor = TSShapeConstructor::findShapeConstructor(Torque::Path(qualifiedToFile).getFullPath());
|
||||
if (constructor == nullptr)
|
||||
{
|
||||
constructor = new TSShapeConstructor(qualifiedToFile);
|
||||
constructor = new TSShapeConstructor(StringTable->insert(qualifiedToFile));
|
||||
|
||||
String constructorName = assetItem->filePath.getFileName() + assetItem->filePath.getExtension().substr(0, 3);
|
||||
constructorName.replace(" ", "_");
|
||||
|
|
@ -3046,7 +3142,6 @@ Torque::Path AssetImporter::importShapeAsset(AssetImportObject* assetItem)
|
|||
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
|
||||
String neverImportMats;
|
||||
|
||||
|
|
|
|||
|
|
@ -40,6 +40,11 @@ public:
|
|||
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
|
||||
/// <summary>
|
||||
|
|
@ -531,6 +536,13 @@ public:
|
|||
/// </summary>
|
||||
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:
|
||||
AssetImportObject();
|
||||
virtual ~AssetImportObject();
|
||||
|
|
@ -820,9 +832,10 @@ public:
|
|||
/// <summary>
|
||||
/// 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 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>
|
||||
/// </summary>
|
||||
StringTableEntry autoImportFile(Torque::Path filePath);
|
||||
StringTableEntry autoImportFile(Torque::Path filePath, String typeHint);
|
||||
|
||||
/// <summary>
|
||||
/// Runs the import process in the current session
|
||||
|
|
|
|||
|
|
@ -47,11 +47,11 @@ DefineEngineMethod(AssetImporter, getActivityLogLine, String, (S32 i), (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"
|
||||
"@return The bool result of calling exec")
|
||||
{
|
||||
return object->autoImportFile(path);
|
||||
return object->autoImportFile(path, typeHint);
|
||||
}
|
||||
|
||||
DefineEngineMethod(AssetImporter, addImportingFile, AssetImportObject*, (String path), (""),
|
||||
|
|
|
|||
|
|
@ -196,7 +196,7 @@ GuiControl* GuiInspectorTypeStateMachineAssetPtr::constructEditControl()
|
|||
mSMEdButton->setField("Command", szBuffer);
|
||||
|
||||
char bitmapName[512] = "tools/worldEditor/images/toolbar/shape-editor";
|
||||
mSMEdButton->setBitmap(bitmapName);
|
||||
mSMEdButton->setBitmap(StringTable->insert(bitmapName));
|
||||
|
||||
mSMEdButton->setDataField(StringTable->insert("Profile"), NULL, "GuiButtonProfile");
|
||||
mSMEdButton->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile");
|
||||
|
|
|
|||
|
|
@ -264,7 +264,7 @@ bool ConvexShape::protectedSetSurfaceTexture(void *object, const char *index, co
|
|||
|
||||
surfaceMaterial surface;
|
||||
|
||||
surface.materialName = data;
|
||||
surface._setMaterial(data);
|
||||
|
||||
shape->mSurfaceTextures.push_back(surface);
|
||||
|
||||
|
|
@ -272,7 +272,7 @@ bool ConvexShape::protectedSetSurfaceTexture(void *object, const char *index, co
|
|||
}
|
||||
|
||||
ConvexShape::ConvexShape()
|
||||
: mMaterialName( "Grid512_OrangeLines_Mat" ),
|
||||
:
|
||||
mMaterialInst( NULL ),
|
||||
//mVertCount( 0 ),
|
||||
//mPrimCount( 0 ),
|
||||
|
|
@ -289,6 +289,8 @@ ConvexShape::ConvexShape()
|
|||
mSurfaceBuffers.clear();
|
||||
mSurfaceUVs.clear();
|
||||
mSurfaceTextures.clear();
|
||||
|
||||
INIT_MATERIALASSET(Material);
|
||||
}
|
||||
|
||||
ConvexShape::~ConvexShape()
|
||||
|
|
@ -310,7 +312,7 @@ void ConvexShape::initPersistFields()
|
|||
{
|
||||
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" );
|
||||
|
||||
|
|
@ -461,9 +463,7 @@ void ConvexShape::writeFields( Stream &stream, U32 tabStop )
|
|||
char buffer[1024];
|
||||
dMemset(buffer, 0, 1024);
|
||||
|
||||
const char* tex = mSurfaceTextures[i].materialName.c_str();
|
||||
|
||||
dSprintf(buffer, 1024, "surfaceTexture = \"%s\";", mSurfaceTextures[i].materialName.c_str());
|
||||
dSprintf(buffer, 1024, "surfaceTexture = \"%s\";", mSurfaceTextures[i].getMaterial());
|
||||
|
||||
stream.writeLine((const U8*)buffer);
|
||||
}
|
||||
|
|
@ -528,7 +528,7 @@ U32 ConvexShape::packUpdate( NetConnection *conn, U32 mask, BitStream *stream )
|
|||
|
||||
if ( stream->writeFlag( mask & UpdateMask ) )
|
||||
{
|
||||
stream->write( mMaterialName );
|
||||
PACK_MATERIALASSET(conn, Material);
|
||||
|
||||
U32 surfCount = mSurfaces.size();
|
||||
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
|
||||
for(U32 i=0; i < surfaceTex; i++)
|
||||
{
|
||||
String a = mSurfaceTextures[i].materialName;
|
||||
stream->write( mSurfaceTextures[i].materialName );
|
||||
if (stream->writeFlag(mSurfaceTextures[i].mMaterialAsset.notNull()))
|
||||
{
|
||||
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
|
||||
{
|
||||
stream->read( &mMaterialName );
|
||||
UNPACK_MATERIALASSET(conn, Material);
|
||||
|
||||
mSurfaces.clear();
|
||||
mSurfaceUVs.clear();
|
||||
|
|
@ -619,7 +624,13 @@ void ConvexShape::unpackUpdate( NetConnection *conn, BitStream *stream )
|
|||
{
|
||||
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())
|
||||
|
|
@ -1207,13 +1218,13 @@ void ConvexShape::_updateMaterial()
|
|||
for (U32 i = 0; i<mSurfaceTextures.size(); i++)
|
||||
{
|
||||
//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;
|
||||
|
||||
Material *material;
|
||||
Material* material = mSurfaceTextures[i].getMaterialResource();
|
||||
|
||||
if (!Sim::findObject(mSurfaceTextures[i].materialName, material))
|
||||
//bail
|
||||
if (material == nullptr)
|
||||
continue;
|
||||
|
||||
mSurfaceTextures[i].materialInst = material->createMatInstance();
|
||||
|
|
@ -1229,15 +1240,15 @@ void ConvexShape::_updateMaterial()
|
|||
}
|
||||
|
||||
// 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;
|
||||
|
||||
SAFE_DELETE( mMaterialInst );
|
||||
|
||||
Material *material;
|
||||
|
||||
if ( !Sim::findObject( mMaterialName, material ) )
|
||||
Sim::findObject( "WarningMaterial", material );
|
||||
Material* material = getMaterialResource();
|
||||
|
||||
if (material == nullptr)
|
||||
return;
|
||||
|
||||
mMaterialInst = material->createMatInstance();
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@
|
|||
#include "collision/convex.h"
|
||||
#endif
|
||||
|
||||
#include "T3D/assets/MaterialAsset.h"
|
||||
|
||||
class ConvexShape;
|
||||
|
||||
// Crap name, but whatcha gonna do.
|
||||
|
|
@ -134,14 +136,17 @@ public:
|
|||
struct surfaceMaterial
|
||||
{
|
||||
// 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
|
||||
BaseMatInstance* materialInst;
|
||||
|
||||
surfaceMaterial()
|
||||
{
|
||||
materialName = "";
|
||||
INIT_MATERIALASSET(Material);
|
||||
|
||||
materialInst = NULL;
|
||||
}
|
||||
};
|
||||
|
|
@ -258,8 +263,8 @@ protected:
|
|||
|
||||
protected:
|
||||
|
||||
// The name of the Material we will use for rendering
|
||||
String mMaterialName;
|
||||
DECLARE_MATERIALASSET(ConvexShape, Material);
|
||||
DECLARE_MATERIALASSET_SETGET(ConvexShape, Material);
|
||||
|
||||
// The actual Material instance
|
||||
BaseMatInstance* mMaterialInst;
|
||||
|
|
|
|||
|
|
@ -109,13 +109,14 @@ DebrisData::DebrisData()
|
|||
minSpinSpeed = 0.0f;
|
||||
maxSpinSpeed = 0.0f;
|
||||
textureName = NULL;
|
||||
shapeName = NULL;
|
||||
fade = true;
|
||||
useRadiusMass = false;
|
||||
baseRadius = 1.0f;
|
||||
gravModifier = 1.0f;
|
||||
terminalVelocity = 0.0f;
|
||||
ignoreWater = true;
|
||||
|
||||
INIT_SHAPEASSET(Shape);
|
||||
}
|
||||
|
||||
//#define TRACK_DEBRIS_DATA_CLONES
|
||||
|
|
@ -150,8 +151,9 @@ DebrisData::DebrisData(const DebrisData& other, bool temp_clone) : GameBaseData(
|
|||
gravModifier = other.gravModifier;
|
||||
terminalVelocity = other.terminalVelocity;
|
||||
ignoreWater = other.ignoreWater;
|
||||
shapeName = other.shapeName;
|
||||
shape = other.shape; // -- TSShape loaded using shapeName
|
||||
|
||||
CLONE_SHAPEASSET(Shape);
|
||||
|
||||
textureName = other.textureName;
|
||||
explosionId = other.explosionId; // -- for pack/unpack of explosion ptr
|
||||
explosion = other.explosion;
|
||||
|
|
@ -189,12 +191,7 @@ DebrisData* DebrisData::cloneAndPerformSubstitutions(const SimObject* owner, S32
|
|||
|
||||
void DebrisData::onPerformSubstitutions()
|
||||
{
|
||||
if( shapeName && shapeName[0] != '\0')
|
||||
{
|
||||
shape = ResourceManager::get().load(shapeName);
|
||||
if( bool(shape) == false )
|
||||
Con::errorf("DebrisData::onPerformSubstitutions(): failed to load shape \"%s\"", shapeName);
|
||||
}
|
||||
_setShape(getShape());
|
||||
}
|
||||
|
||||
bool DebrisData::onAdd()
|
||||
|
|
@ -277,20 +274,18 @@ bool DebrisData::preload(bool server, String &errorStr)
|
|||
|
||||
if( server ) return true;
|
||||
|
||||
if( shapeName && shapeName[0] != '\0' && !bool(shape) )
|
||||
if (mShapeAsset.notNull())
|
||||
{
|
||||
shape = ResourceManager::get().load(shapeName);
|
||||
if( bool(shape) == false )
|
||||
if (!mShape)
|
||||
{
|
||||
errorStr = String::ToString("DebrisData::load: Couldn't load shape \"%s\"", shapeName);
|
||||
errorStr = String::ToString("DebrisData::load: Couldn't load shape \"%s\"", mShapeAssetId);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
TSShapeInstance* pDummy = new TSShapeInstance(shape, !server);
|
||||
TSShapeInstance* pDummy = new TSShapeInstance(mShape, !server);
|
||||
delete pDummy;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -300,9 +295,9 @@ void DebrisData::initPersistFields()
|
|||
{
|
||||
addGroup("Display");
|
||||
addField("texture", TypeString, Offset(textureName, DebrisData),
|
||||
"@brief Texture imagemap to use for this debris object.\n\nNot used any more.\n");
|
||||
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");
|
||||
"@brief Texture imagemap to use for this debris object.\n\nNot used any more.\n", AbstractClassRep::FIELD_HideInInspectors);
|
||||
|
||||
INITPERSISTFIELD_SHAPEASSET(Shape, DebrisData, "Shape to use for this debris object.");
|
||||
endGroup("Display");
|
||||
|
||||
addGroup("Datablocks");
|
||||
|
|
@ -384,7 +379,8 @@ void DebrisData::packData(BitStream* stream)
|
|||
stream->write(ignoreWater);
|
||||
|
||||
stream->writeString( textureName );
|
||||
stream->writeString( shapeName );
|
||||
|
||||
PACKDATA_SHAPEASSET(Shape);
|
||||
|
||||
for( S32 i=0; i<DDC_NUM_EMITTERS; i++ )
|
||||
{
|
||||
|
|
@ -427,7 +423,8 @@ void DebrisData::unpackData(BitStream* stream)
|
|||
stream->read(&ignoreWater);
|
||||
|
||||
textureName = stream->readSTString();
|
||||
shapeName = stream->readSTString();
|
||||
|
||||
UNPACKDATA_SHAPEASSET(Shape);
|
||||
|
||||
for( S32 i=0; i<DDC_NUM_EMITTERS; i++ )
|
||||
{
|
||||
|
|
@ -669,18 +666,18 @@ bool Debris::onAdd()
|
|||
mFriction = mDataBlock->friction;
|
||||
|
||||
// Setup our bounding box
|
||||
if( mDataBlock->shape )
|
||||
if( mDataBlock->mShape )
|
||||
{
|
||||
mObjBox = mDataBlock->shape->mBounds;
|
||||
mObjBox = mDataBlock->mShape->mBounds;
|
||||
}
|
||||
else
|
||||
{
|
||||
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 )
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@
|
|||
#include "T3D/gameBase/gameBase.h"
|
||||
#endif
|
||||
|
||||
#include "T3D/assets/ShapeAsset.h"
|
||||
|
||||
class ParticleEmitterData;
|
||||
class ParticleEmitter;
|
||||
class ExplosionData;
|
||||
|
|
@ -81,8 +83,8 @@ struct DebrisData : public GameBaseData
|
|||
F32 terminalVelocity; // max velocity magnitude
|
||||
bool ignoreWater;
|
||||
|
||||
const char* shapeName;
|
||||
Resource<TSShape> shape;
|
||||
DECLARE_SHAPEASSET(DebrisData, Shape, onShapeChanged);
|
||||
DECLARE_SHAPEASSET_SETGET(DebrisData, Shape);
|
||||
|
||||
StringTableEntry textureName;
|
||||
|
||||
|
|
@ -108,6 +110,8 @@ public:
|
|||
DebrisData* cloneAndPerformSubstitutions(const SimObject*, S32 index=0);
|
||||
virtual void onPerformSubstitutions();
|
||||
virtual bool allowSubstitutions() const { return true; }
|
||||
|
||||
void onShapeChanged() {}
|
||||
};
|
||||
|
||||
//**************************************************************************
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ ConsoleDocClass( DecalData,
|
|||
DecalData::DecalData()
|
||||
{
|
||||
size = 5;
|
||||
materialName = "";
|
||||
INIT_MATERIALASSET(Material);
|
||||
|
||||
lifeSpan = 5000;
|
||||
fadeTime = 1000;
|
||||
|
|
@ -89,7 +89,6 @@ DecalData::DecalData()
|
|||
fadeStartPixelSize = -1.0f;
|
||||
fadeEndPixelSize = 200.0f;
|
||||
|
||||
material = NULL;
|
||||
matInst = NULL;
|
||||
|
||||
renderPriority = 10;
|
||||
|
|
@ -144,8 +143,7 @@ void DecalData::initPersistFields()
|
|||
addField( "size", TypeF32, Offset( size, DecalData ),
|
||||
"Width and height of the decal in meters before scale is applied." );
|
||||
|
||||
addField( "material", TypeMaterialName, Offset( materialName, DecalData ),
|
||||
"Material to use for this decal." );
|
||||
INITPERSISTFIELD_MATERIALASSET(Material, DecalData, "Material to use for this decal.");
|
||||
|
||||
addField( "lifeSpan", TypeS32, Offset( lifeSpan, DecalData ),
|
||||
"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.
|
||||
if ( dStricmp( slotName, "material" ) == 0 )
|
||||
{
|
||||
materialName = newValue;
|
||||
_setMaterial(newValue);
|
||||
_updateMaterial();
|
||||
}
|
||||
// To allow changing name live.
|
||||
|
|
@ -259,7 +257,9 @@ void DecalData::packData( BitStream *stream )
|
|||
|
||||
stream->write( lookupName );
|
||||
stream->write( size );
|
||||
stream->write( materialName );
|
||||
|
||||
PACKDATA_MATERIALASSET(Material);
|
||||
|
||||
stream->write( lifeSpan );
|
||||
stream->write( fadeTime );
|
||||
stream->write( texCoordCount );
|
||||
|
|
@ -285,8 +285,10 @@ void DecalData::unpackData( BitStream *stream )
|
|||
|
||||
stream->read( &lookupName );
|
||||
assignName(lookupName);
|
||||
stream->read( &size );
|
||||
stream->read( &materialName );
|
||||
stream->read( &size );
|
||||
|
||||
UNPACKDATA_MATERIALASSET(Material);
|
||||
|
||||
_updateMaterial();
|
||||
stream->read( &lifeSpan );
|
||||
stream->read( &fadeTime );
|
||||
|
|
@ -311,8 +313,10 @@ void DecalData::_initMaterial()
|
|||
{
|
||||
SAFE_DELETE( matInst );
|
||||
|
||||
if ( material )
|
||||
matInst = material->createMatInstance();
|
||||
if (mMaterialAsset.notNull())
|
||||
{
|
||||
matInst = getMaterialResource()->createMatInstance();
|
||||
}
|
||||
else
|
||||
matInst = MATMGR->createMatInstance( "WarningMaterial" );
|
||||
|
||||
|
|
@ -324,7 +328,7 @@ void DecalData::_initMaterial()
|
|||
matInst->init( MATMGR->getDefaultFeatures(), getGFXVertexFormat<DecalVertex>() );
|
||||
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 );
|
||||
matInst = MATMGR->createMatInstance( "WarningMaterial" );
|
||||
matInst->init( MATMGR->getDefaultFeatures(), getGFXVertexFormat< DecalVertex >() );
|
||||
|
|
@ -333,38 +337,29 @@ void DecalData::_initMaterial()
|
|||
|
||||
void DecalData::_updateMaterial()
|
||||
{
|
||||
if ( materialName.isEmpty() )
|
||||
if(mMaterialAsset.isNull())
|
||||
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.
|
||||
if ( matInst )
|
||||
_initMaterial();
|
||||
}
|
||||
|
||||
Material* DecalData::getMaterial()
|
||||
Material* DecalData::getMaterialDefinition()
|
||||
{
|
||||
if ( !material )
|
||||
if ( !getMaterialResource() )
|
||||
{
|
||||
_updateMaterial();
|
||||
if ( !material )
|
||||
material = static_cast<Material*>( Sim::findObject("WarningMaterial") );
|
||||
if ( !mMaterial )
|
||||
mMaterial = static_cast<Material*>( Sim::findObject("WarningMaterial") );
|
||||
}
|
||||
|
||||
return material;
|
||||
return mMaterial;
|
||||
}
|
||||
|
||||
BaseMatInstance* DecalData::getMaterialInstance()
|
||||
{
|
||||
if ( !material || !matInst || matInst->getMaterial() != material )
|
||||
if ( !mMaterial || !matInst || matInst->getMaterial() != mMaterial)
|
||||
_initMaterial();
|
||||
|
||||
return matInst;
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@
|
|||
#include "console/dynamicTypes.h"
|
||||
#endif
|
||||
|
||||
#include "T3D/assets/MaterialAsset.h"
|
||||
|
||||
GFXDeclareVertexFormat( DecalVertex )
|
||||
{
|
||||
// .xyz = coords
|
||||
|
|
@ -75,11 +77,8 @@ class DecalData : public SimDataBlock
|
|||
F32 fadeStartPixelSize;
|
||||
F32 fadeEndPixelSize;
|
||||
|
||||
/// Name of material to use.
|
||||
String materialName;
|
||||
|
||||
/// Render material for decal.
|
||||
SimObjectPtr<Material> material;
|
||||
DECLARE_MATERIALASSET(DecalData, Material);
|
||||
DECLARE_MATERIALASSET_SETGET(DecalData, Material);
|
||||
|
||||
/// Material instance for decal.
|
||||
BaseMatInstance *matInst;
|
||||
|
|
@ -113,7 +112,7 @@ class DecalData : public SimDataBlock
|
|||
virtual void packData( BitStream* );
|
||||
virtual void unpackData( BitStream* );
|
||||
|
||||
Material* getMaterial();
|
||||
Material* getMaterialDefinition();
|
||||
BaseMatInstance* getMaterialInstance();
|
||||
|
||||
static SimSet* getSet();
|
||||
|
|
|
|||
|
|
@ -206,8 +206,8 @@ bool DecalDataFile::read( Stream &stream )
|
|||
data->lookupName = name;
|
||||
data->registerObject(name);
|
||||
Sim::getRootGroup()->addObject( data );
|
||||
data->materialName = "WarningMaterial";
|
||||
data->material = dynamic_cast<Material*>(Sim::findObject("WarningMaterial"));
|
||||
data->mMaterialName = "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());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -186,7 +186,7 @@ S32 QSORT_CALLBACK cmpDecalRenderOrder( const void *p1, const void *p2 )
|
|||
|
||||
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 )
|
||||
return id;
|
||||
|
||||
|
|
@ -1225,7 +1225,7 @@ void DecalManager::prepRenderImage( SceneRenderState* state )
|
|||
{
|
||||
DecalInstance *decal = mDecalQueue[i];
|
||||
DecalData *data = decal->mDataBlock;
|
||||
Material *mat = data->getMaterial();
|
||||
Material *mat = data->getMaterialDefinition();
|
||||
|
||||
if ( currentBatch == NULL )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -59,11 +59,7 @@ RenderMeshExample::RenderMeshExample()
|
|||
// Set it as a "static" object that casts shadows
|
||||
mTypeMask |= StaticObjectType | StaticShapeObjectType;
|
||||
|
||||
// Make sure we the Material instance to NULL
|
||||
// so we don't try to access it incorrectly
|
||||
mMaterialInst = NULL;
|
||||
|
||||
initMaterialAsset(Material);
|
||||
INIT_MATERIALASSET(Material);
|
||||
}
|
||||
|
||||
RenderMeshExample::~RenderMeshExample()
|
||||
|
|
@ -78,7 +74,7 @@ RenderMeshExample::~RenderMeshExample()
|
|||
void RenderMeshExample::initPersistFields()
|
||||
{
|
||||
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" );
|
||||
|
||||
// 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
|
||||
if (stream->writeFlag(mask & UpdateMask))
|
||||
{
|
||||
packMaterialAsset(conn, Material);
|
||||
PACK_MATERIALASSET(conn, Material);
|
||||
}
|
||||
|
||||
return retMask;
|
||||
|
|
@ -168,7 +164,7 @@ void RenderMeshExample::unpackUpdate(NetConnection *conn, BitStream *stream)
|
|||
|
||||
if ( stream->readFlag() ) // UpdateMask
|
||||
{
|
||||
unpackMaterialAsset(conn, Material);
|
||||
UNPACK_MATERIALASSET(conn, Material);
|
||||
|
||||
if ( isProperlyAdded() )
|
||||
updateMaterial();
|
||||
|
|
|
|||
|
|
@ -64,18 +64,18 @@ class RenderMeshExample : public SceneObject
|
|||
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
|
||||
// change it in multiple spots later
|
||||
typedef GFXVertexPNT VertexType;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Rendering variables
|
||||
//--------------------------------------------------------------------------
|
||||
BaseMatInstance* mMaterialInst;
|
||||
|
||||
DECLARE_MATERIALASSET(RenderMeshExample, Material);
|
||||
DECLARE_MATERIALASSET_NET_SETGET(RenderMeshExample, Material, UpdateMask);
|
||||
|
||||
// The GFX vertex and primitive buffers
|
||||
GFXVertexBufferHandle< VertexType > mVertexBuffer;
|
||||
GFXPrimitiveBufferHandle mPrimitiveBuffer;
|
||||
|
|
|
|||
|
|
@ -72,8 +72,7 @@ RenderShapeExample::~RenderShapeExample()
|
|||
void RenderShapeExample::initPersistFields()
|
||||
{
|
||||
addGroup( "Rendering" );
|
||||
addField( "shapeFile", TypeStringFilename, Offset( mShapeFile, RenderShapeExample ),
|
||||
"The path to the DTS shape file." );
|
||||
INITPERSISTFIELD_SHAPEASSET(Shape, RenderShapeExample, "The path to the shape file.")
|
||||
endGroup( "Rendering" );
|
||||
|
||||
// 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
|
||||
if ( stream->writeFlag( mask & UpdateMask ) )
|
||||
{
|
||||
stream->write( mShapeFile );
|
||||
PACK_SHAPEASSET(conn, Shape);
|
||||
|
||||
// Allow the server object a chance to handle a new shape
|
||||
createShape();
|
||||
|
|
@ -170,7 +169,7 @@ void RenderShapeExample::unpackUpdate(NetConnection *conn, BitStream *stream)
|
|||
|
||||
if ( stream->readFlag() ) // UpdateMask
|
||||
{
|
||||
stream->read( &mShapeFile );
|
||||
UNPACK_SHAPEASSET(conn, Shape);
|
||||
|
||||
if ( isProperlyAdded() )
|
||||
createShape();
|
||||
|
|
@ -182,33 +181,22 @@ void RenderShapeExample::unpackUpdate(NetConnection *conn, BitStream *stream)
|
|||
//-----------------------------------------------------------------------------
|
||||
void RenderShapeExample::createShape()
|
||||
{
|
||||
if ( mShapeFile.isEmpty() )
|
||||
if ( getShape() == StringTable->EmptyString() )
|
||||
return;
|
||||
|
||||
// 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;
|
||||
|
||||
// Clean up our previous shape
|
||||
if ( 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
|
||||
if ( isClientObject() &&
|
||||
!mShape->preloadMaterialList( mShape.getPath() ) &&
|
||||
NetConnection::filesWereDownloaded() )
|
||||
{
|
||||
mShape = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@
|
|||
#include "ts/tsShapeInstance.h"
|
||||
#endif
|
||||
|
||||
#include "T3D/assets/ShapeAsset.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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
|
||||
|
|
@ -59,12 +61,13 @@ class RenderShapeExample : public SceneObject
|
|||
//--------------------------------------------------------------------------
|
||||
// Rendering variables
|
||||
//--------------------------------------------------------------------------
|
||||
// The name of the shape file we will use for rendering
|
||||
String mShapeFile;
|
||||
DECLARE_SHAPEASSET(RenderShapeExample, Shape, onShapeChanged);
|
||||
DECLARE_SHAPEASSET_SETGET(RenderShapeExample, Shape);
|
||||
|
||||
// The actual shape instance
|
||||
TSShapeInstance* mShapeInstance;
|
||||
// Store the resource so we can access the filename later
|
||||
Resource<TSShape> mShape;
|
||||
|
||||
void onShapeChanged() {}
|
||||
|
||||
public:
|
||||
RenderShapeExample();
|
||||
|
|
|
|||
|
|
@ -225,7 +225,6 @@ ConsoleDocClass( ExplosionData,
|
|||
|
||||
ExplosionData::ExplosionData()
|
||||
{
|
||||
dtsFileName = NULL;
|
||||
particleDensity = 10;
|
||||
particleRadius = 1.0f;
|
||||
|
||||
|
|
@ -238,7 +237,8 @@ ExplosionData::ExplosionData()
|
|||
explosionScale.set(1.0f, 1.0f, 1.0f);
|
||||
playSpeed = 1.0f;
|
||||
|
||||
explosionShape = NULL;
|
||||
INIT_SHAPEASSET(ExplosionShape);
|
||||
|
||||
explosionAnimation = -1;
|
||||
|
||||
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!");
|
||||
#endif
|
||||
|
||||
dtsFileName = other.dtsFileName;
|
||||
faceViewer = other.faceViewer;
|
||||
particleDensity = other.particleDensity;
|
||||
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
|
||||
explosionScale = other.explosionScale;
|
||||
playSpeed = other.playSpeed;
|
||||
explosionShape = other.explosionShape; // -- TSShape loaded using dtsFileName
|
||||
CLONE_SHAPEASSET(ExplosionShape);
|
||||
explosionAnimation = other.explosionAnimation; // -- from explosionShape sequence "ambient"
|
||||
dMemcpy( emitterList, other.emitterList, sizeof( emitterList ) );
|
||||
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()
|
||||
{
|
||||
addField( "explosionShape", TypeShapeFilename, Offset(dtsFileName, ExplosionData),
|
||||
"@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." );
|
||||
INITPERSISTFIELD_SHAPEASSET(ExplosionShape, ExplosionData, "@brief Optional shape asset 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.");
|
||||
|
||||
addField( "explosionScale", TypePoint3F, Offset(explosionScale, ExplosionData),
|
||||
"\"X Y Z\" scale factor applied to the explosionShape model at the start "
|
||||
"of the explosion." );
|
||||
|
|
@ -656,7 +654,7 @@ void ExplosionData::packData(BitStream* stream)
|
|||
{
|
||||
Parent::packData(stream);
|
||||
|
||||
stream->writeString(dtsFileName);
|
||||
PACKDATA_SHAPEASSET(ExplosionShape);
|
||||
|
||||
sfxWrite( stream, soundProfile );
|
||||
if (stream->writeFlag(particleEmitter))
|
||||
|
|
@ -759,7 +757,7 @@ void ExplosionData::unpackData(BitStream* stream)
|
|||
{
|
||||
Parent::unpackData(stream);
|
||||
|
||||
dtsFileName = stream->readSTString();
|
||||
UNPACKDATA_SHAPEASSET(ExplosionShape);
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
if (dtsFileName && dtsFileName[0]) {
|
||||
explosionShape = ResourceManager::get().load(dtsFileName);
|
||||
if (!bool(explosionShape)) {
|
||||
errorStr = String::ToString("ExplosionData: Couldn't load shape \"%s\"", dtsFileName);
|
||||
return false;
|
||||
}
|
||||
if (mExplosionShapeAsset.notNull()) {
|
||||
|
||||
// Resolve animations
|
||||
explosionAnimation = explosionShape->findSequence("ambient");
|
||||
explosionAnimation = mExplosionShape->findSequence("ambient");
|
||||
|
||||
// Preload textures with a dummy instance...
|
||||
TSShapeInstance* pDummy = new TSShapeInstance(explosionShape, !server);
|
||||
TSShapeInstance* pDummy = new TSShapeInstance(mExplosionShape, !server);
|
||||
delete pDummy;
|
||||
|
||||
} else {
|
||||
explosionShape = NULL;
|
||||
explosionAnimation = -1;
|
||||
}
|
||||
|
||||
|
|
@ -1377,8 +1369,8 @@ bool Explosion::explode()
|
|||
launchDebris( mInitialNormal );
|
||||
spawnSubExplosions();
|
||||
|
||||
if (bool(mDataBlock->explosionShape) && mDataBlock->explosionAnimation != -1) {
|
||||
mExplosionInstance = new TSShapeInstance(mDataBlock->explosionShape, true);
|
||||
if (bool(mDataBlock->mExplosionShape) && mDataBlock->explosionAnimation != -1) {
|
||||
mExplosionInstance = new TSShapeInstance(mDataBlock->mExplosionShape, true);
|
||||
|
||||
mExplosionThread = mExplosionInstance->addThread();
|
||||
mExplosionInstance->setSequence(mExplosionThread, mDataBlock->explosionAnimation, 0);
|
||||
|
|
@ -1388,7 +1380,7 @@ bool Explosion::explode()
|
|||
mEndingMS = U32(mExplosionInstance->getScaledDuration(mExplosionThread) * 1000.0f);
|
||||
|
||||
mObjScale.convolve(mDataBlock->explosionScale);
|
||||
mObjBox = mDataBlock->explosionShape->mBounds;
|
||||
mObjBox = mDataBlock->mExplosionShape->mBounds;
|
||||
resetWorldBox();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,6 +41,8 @@
|
|||
#include "lighting/lightInfo.h"
|
||||
#endif
|
||||
|
||||
#include "T3D/assets/ShapeAsset.h"
|
||||
|
||||
class ParticleEmitter;
|
||||
class ParticleEmitterData;
|
||||
class TSThread;
|
||||
|
|
@ -62,8 +64,6 @@ class ExplosionData : public GameBaseData {
|
|||
};
|
||||
|
||||
public:
|
||||
StringTableEntry dtsFileName;
|
||||
|
||||
bool faceViewer;
|
||||
|
||||
S32 particleDensity;
|
||||
|
|
@ -76,7 +76,9 @@ class ExplosionData : public GameBaseData {
|
|||
Point3F explosionScale;
|
||||
F32 playSpeed;
|
||||
|
||||
Resource<TSShape> explosionShape;
|
||||
DECLARE_SHAPEASSET(ExplosionData, ExplosionShape, onShapeChanged);
|
||||
DECLARE_SHAPEASSET_SETGET(ExplosionData, ExplosionShape);
|
||||
|
||||
S32 explosionAnimation;
|
||||
|
||||
ParticleEmitterData* emitterList[EC_NUM_EMITTERS];
|
||||
|
|
@ -137,6 +139,8 @@ public:
|
|||
/*D*/ ~ExplosionData();
|
||||
ExplosionData* cloneAndPerformSubstitutions(const SimObject*, S32 index=0);
|
||||
virtual bool allowSubstitutions() const { return true; }
|
||||
|
||||
void onShapeChanged() {}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -458,9 +458,9 @@ GroundCover::GroundCover()
|
|||
|
||||
mRandomSeed = 1;
|
||||
|
||||
initMaterialAsset(Material);
|
||||
INIT_MATERIALASSET(Material);
|
||||
mMaterialInst = NULL;
|
||||
|
||||
mMatInst = NULL;
|
||||
mMatParams = NULL;
|
||||
mTypeRectsParam = NULL;
|
||||
mFadeParams = NULL;
|
||||
|
|
@ -519,7 +519,8 @@ GroundCover::GroundCover()
|
|||
mBillboardRects[i].point.set( 0.0f, 0.0f );
|
||||
mBillboardRects[i].extent.set( 1.0f, 1.0f );
|
||||
|
||||
mShapeFilenames[i] = NULL;
|
||||
INIT_SHAPEASSET_ARRAY(Shape, i);
|
||||
|
||||
mShapeInstances[i] = NULL;
|
||||
|
||||
mBillboardAspectScales[i] = 1.0f;
|
||||
|
|
@ -530,7 +531,7 @@ GroundCover::GroundCover()
|
|||
|
||||
GroundCover::~GroundCover()
|
||||
{
|
||||
SAFE_DELETE( mMatInst );
|
||||
SAFE_DELETE( mMaterialInst );
|
||||
}
|
||||
|
||||
IMPLEMENT_CO_NETOBJECT_V1(GroundCover);
|
||||
|
|
@ -539,7 +540,7 @@ void GroundCover::initPersistFields()
|
|||
{
|
||||
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( "dissolveRadius",TypeF32, Offset( mFadeRadius, GroundCover ), "This is less than or equal to radius and defines when fading of cover elements begins." );
|
||||
|
|
@ -559,7 +560,8 @@ void GroundCover::initPersistFields()
|
|||
|
||||
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]" );
|
||||
INITPERSISTFIELD_SHAPEASSET_ARRAY(Shape, GroundCover, "The cover shape. [Optional]");
|
||||
addField( "shapeFilename", TypeFilename, Offset( mShapeName, GroundCover ), MAX_COVERTYPES, "The cover shape filename. [Optional]", AbstractClassRep::FIELD_HideInInspectors );
|
||||
|
||||
addField( "layer", TypeTerrainMaterialName, Offset( mLayer, GroundCover ), MAX_COVERTYPES, "Terrain material name to limit coverage to, or blank to not limit." );
|
||||
|
||||
|
|
@ -710,7 +712,7 @@ U32 GroundCover::packUpdate( NetConnection *connection, U32 mask, BitStream *str
|
|||
// TODO: We could probably optimize a few of these
|
||||
// based on reasonable units at some point.
|
||||
|
||||
packMaterialAsset(connection, Material);
|
||||
PACK_MATERIALASSET(connection, Material);
|
||||
|
||||
stream->write( mRadius );
|
||||
stream->write( mZOffset );
|
||||
|
|
@ -741,11 +743,11 @@ U32 GroundCover::packUpdate( NetConnection *connection, U32 mask, BitStream *str
|
|||
|
||||
stream->write( mMinSlope[i] );
|
||||
stream->write( mMaxSlope[i] );
|
||||
stream->writeFlag(mConformToNormal[i]);
|
||||
stream->write(mMinRotX[i]);
|
||||
stream->write(mMaxRotX[i]);
|
||||
stream->write(mMinRotY[i]);
|
||||
stream->write(mMaxRotY[i]);
|
||||
stream->writeFlag(mConformToNormal[i]);
|
||||
stream->write(mMinRotX[i]);
|
||||
stream->write(mMaxRotX[i]);
|
||||
stream->write(mMinRotY[i]);
|
||||
stream->write(mMaxRotY[i]);
|
||||
|
||||
stream->write( mMinElevation[i] );
|
||||
stream->write( mMaxElevation[i] );
|
||||
|
|
@ -763,7 +765,7 @@ U32 GroundCover::packUpdate( NetConnection *connection, U32 mask, BitStream *str
|
|||
stream->write( mBillboardRects[i].extent.x );
|
||||
stream->write( mBillboardRects[i].extent.y );
|
||||
|
||||
stream->writeString( mShapeFilenames[i] );
|
||||
PACK_SHAPEASSET_ARRAY(connection, Shape, i);
|
||||
}
|
||||
|
||||
stream->writeFlag( mDebugRenderCells );
|
||||
|
|
@ -781,7 +783,7 @@ void GroundCover::unpackUpdate( NetConnection *connection, BitStream *stream )
|
|||
|
||||
if (stream->readFlag())
|
||||
{
|
||||
unpackMaterialAsset(connection, Material);
|
||||
UNPACK_MATERIALASSET(connection, Material);
|
||||
|
||||
stream->read( &mRadius );
|
||||
stream->read( &mZOffset );
|
||||
|
|
@ -812,11 +814,11 @@ void GroundCover::unpackUpdate( NetConnection *connection, BitStream *stream )
|
|||
|
||||
stream->read( &mMinSlope[i] );
|
||||
stream->read( &mMaxSlope[i] );
|
||||
mConformToNormal[i] = stream->readFlag();
|
||||
stream->read(&mMinRotX[i]);
|
||||
stream->read(&mMaxRotX[i]);
|
||||
stream->read(&mMinRotY[i]);
|
||||
stream->read(&mMaxRotY[i]);
|
||||
mConformToNormal[i] = stream->readFlag();
|
||||
stream->read(&mMinRotX[i]);
|
||||
stream->read(&mMaxRotX[i]);
|
||||
stream->read(&mMinRotY[i]);
|
||||
stream->read(&mMaxRotY[i]);
|
||||
|
||||
stream->read( &mMinElevation[i] );
|
||||
stream->read( &mMaxElevation[i] );
|
||||
|
|
@ -834,7 +836,7 @@ void GroundCover::unpackUpdate( NetConnection *connection, BitStream *stream )
|
|||
stream->read( &mBillboardRects[i].extent.x );
|
||||
stream->read( &mBillboardRects[i].extent.y );
|
||||
|
||||
mShapeFilenames[i] = stream->readSTString();
|
||||
UNPACK_SHAPEASSET_ARRAY(connection, Shape, i);
|
||||
}
|
||||
|
||||
mDebugRenderCells = stream->readFlag();
|
||||
|
|
@ -854,28 +856,8 @@ void GroundCover::unpackUpdate( NetConnection *connection, BitStream *stream )
|
|||
|
||||
void GroundCover::_initMaterial()
|
||||
{
|
||||
if (mMaterialAsset.notNull())
|
||||
{
|
||||
if (mMatInst && String(mMaterialAsset->getMaterialDefinitionName()).equal(mMatInst->getMaterial()->getName(), String::NoCase))
|
||||
return;
|
||||
|
||||
SAFE_DELETE(mMatInst);
|
||||
|
||||
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
|
||||
{
|
||||
if (!mMaterialInst)
|
||||
return;
|
||||
}
|
||||
|
||||
// Add our special feature that makes it all work...
|
||||
FeatureSet features = MATMGR->getDefaultFeatures();
|
||||
|
|
@ -883,10 +865,10 @@ void GroundCover::_initMaterial()
|
|||
|
||||
// Our feature requires a pointer back to this object
|
||||
// to properly setup its shader consts.
|
||||
mMatInst->setUserObject( this );
|
||||
mMaterialInst->setUserObject( this );
|
||||
|
||||
// DO IT!
|
||||
mMatInst->init( features, getGFXVertexFormat<GCVertex>() );
|
||||
mMaterialInst->init( features, getGFXVertexFormat<GCVertex>() );
|
||||
}
|
||||
|
||||
void GroundCover::_initShapes()
|
||||
|
|
@ -895,25 +877,17 @@ void GroundCover::_initShapes()
|
|||
|
||||
for ( S32 i=0; i < MAX_COVERTYPES; i++ )
|
||||
{
|
||||
if ( !mShapeFilenames[i] || !mShapeFilenames[i][0] )
|
||||
if ( mShapeAsset[i].isNull() || mShape[i] == nullptr)
|
||||
continue;
|
||||
|
||||
// Load the shape.
|
||||
Resource<TSShape> shape = ResourceManager::get().load(mShapeFilenames[i]);
|
||||
if ( !(bool)shape )
|
||||
if ( isClientObject() && !mShape[i]->preloadMaterialList(mShape[i].getPath()) && NetConnection::filesWereDownloaded() )
|
||||
{
|
||||
Con::warnf( "GroundCover::_initShapes() unable to load shape: %s", mShapeFilenames[i] );
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( isClientObject() && !shape->preloadMaterialList(shape.getPath()) && NetConnection::filesWereDownloaded() )
|
||||
{
|
||||
Con::warnf( "GroundCover::_initShapes() material preload failed for shape: %s", mShapeFilenames[i] );
|
||||
Con::warnf( "GroundCover::_initShapes() material preload failed for shape: %s", mShapeAssetId[i] );
|
||||
continue;
|
||||
}
|
||||
|
||||
// Create the shape instance.
|
||||
mShapeInstances[i] = new TSShapeInstance( shape, isClientObject() );
|
||||
mShapeInstances[i] = new TSShapeInstance(mShape[i], isClientObject() );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -982,16 +956,16 @@ void GroundCover::_initialize( U32 cellCount, U32 cellPlacementCount )
|
|||
|
||||
// Rebuild the texture aspect scales for each type.
|
||||
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)
|
||||
{
|
||||
GFXTexHandle tex;
|
||||
if (!mat->mDiffuseMapFilename[0].isEmpty())
|
||||
tex = GFXTexHandle(mat->mDiffuseMapFilename[0], &GFXStaticTextureSRGBProfile, "GroundCover texture aspect ratio check");
|
||||
if (mat->mDiffuseMapName[0] != StringTable->EmptyString())
|
||||
tex = GFXTexHandle(mat->mDiffuseMapName[0], &GFXStaticTextureSRGBProfile, "GroundCover texture aspect ratio check");
|
||||
else if (!mat->mDiffuseMapAsset[0].isNull())
|
||||
tex = mat->mDiffuseMapAsset[0]->getImage(GFXStaticTextureSRGBProfile);
|
||||
tex = mat->mDiffuseMapAsset[0]->getTexture(&GFXStaticTextureSRGBProfile);
|
||||
|
||||
if(tex.isValid())
|
||||
{
|
||||
|
|
@ -1580,7 +1554,7 @@ void GroundCover::_updateCoverGrid( const Frustum &culler )
|
|||
void GroundCover::prepRenderImage( SceneRenderState *state )
|
||||
{
|
||||
// Reset stats each time we hit the diffuse pass.
|
||||
if (mMatInst == nullptr)
|
||||
if (mMaterialInst == nullptr)
|
||||
return;
|
||||
|
||||
if( state->isDiffusePass() )
|
||||
|
|
@ -1617,7 +1591,7 @@ void GroundCover::prepRenderImage( SceneRenderState *state )
|
|||
|
||||
// Render billboards but not into shadow passes.
|
||||
|
||||
if ( !state->isShadowPass() && mMatInst->isValid() && !mDebugNoBillboards )
|
||||
if ( !state->isShadowPass() && mMaterialInst->isValid() && !mDebugNoBillboards )
|
||||
{
|
||||
PROFILE_SCOPE( GroundCover_RenderBillboards );
|
||||
|
||||
|
|
@ -1692,7 +1666,7 @@ void GroundCover::prepRenderImage( SceneRenderState *state )
|
|||
if ( mCuller.isCulled( cell->getRenderBounds() ) )
|
||||
continue;
|
||||
|
||||
cell->renderBillboards( state, mMatInst, &mPrimBuffer );
|
||||
cell->renderBillboards( state, mMaterialInst, &mPrimBuffer );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@
|
|||
#include "shaderGen/shaderFeature.h"
|
||||
#endif
|
||||
|
||||
#include "T3D/assets/MaterialAsset.h"
|
||||
#include "T3D/assets/ShapeAsset.h"
|
||||
|
||||
class TerrainBlock;
|
||||
class GroundCoverCell;
|
||||
|
|
@ -266,9 +266,10 @@ protected:
|
|||
static F32 smDensityScale;
|
||||
static F32 smFadeScale;
|
||||
|
||||
DECLARE_NET_MATERIALASSET(GroundCover, Material, InitialUpdateMask);
|
||||
Material* mMaterial;
|
||||
BaseMatInstance *mMatInst;
|
||||
BaseMatInstance* mMaterialInst;
|
||||
|
||||
DECLARE_MATERIALASSET(GroundCover, Material);
|
||||
DECLARE_MATERIALASSET_NET_SETGET(GroundCover, Material, InitialUpdateMask);
|
||||
|
||||
GroundCoverShaderConstData mShaderConstData;
|
||||
|
||||
|
|
@ -339,7 +340,8 @@ protected:
|
|||
RectF mBillboardRects[MAX_COVERTYPES];
|
||||
|
||||
/// 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.
|
||||
TSShapeInstance* mShapeInstances[MAX_COVERTYPES];
|
||||
|
|
|
|||
|
|
@ -121,10 +121,10 @@ ParticleData::ParticleData()
|
|||
animTexTiling.set(0,0); // tiling dimensions
|
||||
animTexFramesString = NULL; // string of animation frame indices
|
||||
animTexUVs = NULL; // array of tile vertex UVs
|
||||
textureName = NULL; // texture filename
|
||||
textureHandle = NULL; // loaded texture handle
|
||||
textureExtName = NULL;
|
||||
textureExtHandle = NULL;
|
||||
|
||||
INIT_IMAGEASSET(Texture);
|
||||
INIT_IMAGEASSET(TextureExt);
|
||||
|
||||
constrain_pos = false;
|
||||
start_angle = 0.0f;
|
||||
angle_variance = 0.0f;
|
||||
|
|
@ -203,11 +203,13 @@ void ParticleData::initPersistFields()
|
|||
"animTexFrames = \"0-16 20 19 18 17 31-21\";\n"
|
||||
"@endtsexample\n" );
|
||||
|
||||
addField( "textureName", TYPEID< StringTableEntry >(), Offset(textureName, ParticleData),
|
||||
"Texture file to use for this particle." );
|
||||
addField( "animTexName", TYPEID< StringTableEntry >(), Offset(textureName, ParticleData),
|
||||
addProtectedField( "textureName", TYPEID< StringTableEntry >(), Offset(mTextureName, ParticleData), _setTextureData, defaultProtectedGetFn,
|
||||
"Texture file to use for this particle.", AbstractClassRep::FIELD_HideInInspectors );
|
||||
addField( "animTexName", TYPEID< StringTableEntry >(), Offset(mTextureName, ParticleData),
|
||||
"@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
|
||||
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"
|
||||
"Values are from 0.0 (particle creation) to 1.0 (end of lifespace)." );
|
||||
|
||||
addGroup("AFX");
|
||||
addField("textureExtName", TypeFilename, Offset(textureExtName, ParticleData));
|
||||
addGroup("AFX");
|
||||
addProtectedField("textureExtName", TypeFilename, Offset(mTextureExtName, ParticleData), _setTextureExtData, &defaultProtectedGetFn, "", AbstractClassRep::FIELD_HideInInspectors);
|
||||
INITPERSISTFIELD_IMAGEASSET(TextureExt, ParticleData, "");
|
||||
addField("constrainPos", TypeBool, Offset(constrain_pos, ParticleData));
|
||||
addField("angle", TypeF32, Offset(start_angle, ParticleData));
|
||||
addField("angleVariance", TypeF32, Offset(angle_variance, ParticleData));
|
||||
|
|
@ -290,8 +293,8 @@ void ParticleData::packData(BitStream* stream)
|
|||
stream->writeFloat( times[i], 8);
|
||||
}
|
||||
|
||||
if (stream->writeFlag(textureName && textureName[0]))
|
||||
stream->writeString(textureName);
|
||||
//PACKDATA_IMAGEASSET(Texture);
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
mathWrite(*stream, texCoords[i]);
|
||||
if (stream->writeFlag(animateTexture))
|
||||
|
|
@ -303,8 +306,9 @@ void ParticleData::packData(BitStream* stream)
|
|||
mathWrite(*stream, animTexTiling);
|
||||
stream->writeInt(framesPerSec, 8);
|
||||
}
|
||||
if (stream->writeFlag(textureExtName && textureExtName[0]))
|
||||
stream->writeString(textureExtName);
|
||||
|
||||
//PACKDATA_IMAGEASSET(TextureExt);
|
||||
|
||||
stream->writeFlag(constrain_pos);
|
||||
stream->writeFloat(start_angle/360.0f, 11);
|
||||
stream->writeFloat(angle_variance/180.0f, 10);
|
||||
|
|
@ -373,7 +377,9 @@ void ParticleData::unpackData(BitStream* stream)
|
|||
sizes[i] = stream->readFloat(16) * MaxParticleSize;
|
||||
times[i] = stream->readFloat(8);
|
||||
}
|
||||
textureName = (stream->readFlag()) ? stream->readSTString() : 0;
|
||||
|
||||
//UNPACKDATA_IMAGEASSET(Texture);
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
mathRead(*stream, &texCoords[i]);
|
||||
|
||||
|
|
@ -384,7 +390,9 @@ void ParticleData::unpackData(BitStream* stream)
|
|||
mathRead(*stream, &animTexTiling);
|
||||
framesPerSec = stream->readInt(8);
|
||||
}
|
||||
textureExtName = (stream->readFlag()) ? stream->readSTString() : 0;
|
||||
|
||||
//UNPACKDATA_IMAGEASSET(Texture);
|
||||
|
||||
constrain_pos = stream->readFlag();
|
||||
start_angle = 360.0f*stream->readFloat(11);
|
||||
angle_variance = 180.0f*stream->readFloat(10);
|
||||
|
|
@ -556,27 +564,6 @@ bool ParticleData::preload(bool server, String &errorStr)
|
|||
bool error = false;
|
||||
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)
|
||||
{
|
||||
// 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 error = false;
|
||||
if (textureName && textureName[0])
|
||||
|
||||
StringTableEntry particleTex = getTexture();
|
||||
|
||||
if (!_setTexture(particleTex))
|
||||
{
|
||||
textureHandle = GFXTexHandle(textureName, &GFXStaticTextureSRGBProfile, avar("%s() - textureHandle (line %d)", __FUNCTION__, __LINE__));
|
||||
if (!textureHandle)
|
||||
{
|
||||
dSprintf(errorBuffer, 256, "Missing particle texture: %s", textureName);
|
||||
error = true;
|
||||
}
|
||||
}
|
||||
dSprintf(errorBuffer, 256, "Missing particle texture: %s", particleTex);
|
||||
}
|
||||
|
||||
/*
|
||||
numFrames = 0;
|
||||
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;
|
||||
animTexFramesString = other.animTexFramesString;
|
||||
animTexFrames = other.animTexFrames; // -- parsed from animTexFramesString
|
||||
textureName = other.textureName;
|
||||
textureHandle = other.textureHandle;
|
||||
|
||||
CLONE_IMAGEASSET(Texture);
|
||||
|
||||
spinBias = other.spinBias;
|
||||
randomizeSpinDir = other.randomizeSpinDir;
|
||||
textureExtName = other.textureExtName;
|
||||
textureExtHandle = other.textureExtHandle;
|
||||
|
||||
CLONE_IMAGEASSET(TextureExt);
|
||||
|
||||
constrain_pos = other.constrain_pos;
|
||||
start_angle = other.start_angle;
|
||||
angle_variance = other.angle_variance;
|
||||
|
|
@ -815,3 +803,5 @@ void ParticleData::onPerformSubstitutions()
|
|||
char errorBuffer[256];
|
||||
reload(errorBuffer);
|
||||
}
|
||||
|
||||
DEF_IMAGEASSET_BINDS(ParticleData, Texture);
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@
|
|||
#include "gfx/gfxTextureHandle.h"
|
||||
#endif
|
||||
|
||||
#include "T3D/assets/ImageAsset.h"
|
||||
|
||||
#define MaxParticleSize 50.0
|
||||
|
||||
struct Particle;
|
||||
|
|
@ -83,13 +85,16 @@ class ParticleData : public SimDataBlock
|
|||
Point2I animTexTiling;
|
||||
StringTableEntry animTexFramesString;
|
||||
Vector<U8> animTexFrames;
|
||||
StringTableEntry textureName;
|
||||
GFXTexHandle textureHandle;
|
||||
|
||||
static bool protectedSetSizes( void *object, const char *index, const char *data );
|
||||
static bool protectedSetTimes( void *object, const char *index, const char *data );
|
||||
DECLARE_IMAGEASSET(ParticleData, Texture, onImageChanged, GFXStaticTextureSRGBProfile);
|
||||
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();
|
||||
|
||||
|
|
@ -111,9 +116,10 @@ class ParticleData : public SimDataBlock
|
|||
protected:
|
||||
F32 spinBias;
|
||||
bool randomizeSpinDir;
|
||||
StringTableEntry textureExtName;
|
||||
public:
|
||||
GFXTexHandle textureExtHandle;
|
||||
DECLARE_IMAGEASSET(ParticleData, TextureExt, onImageChanged, GFXStaticTextureSRGBProfile);
|
||||
DECLARE_IMAGEASSET_SETGET(ParticleData, TextureExt);
|
||||
|
||||
bool constrain_pos;
|
||||
F32 start_angle;
|
||||
F32 angle_variance;
|
||||
|
|
|
|||
|
|
@ -741,11 +741,11 @@ bool ParticleEmitterData::preload(bool server, String &errorStr)
|
|||
// otherwise, check that all particles refer to the same texture
|
||||
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++)
|
||||
{
|
||||
// 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());
|
||||
break;
|
||||
|
|
@ -1225,7 +1225,7 @@ void ParticleEmitter::prepRenderImage(SceneRenderState* state)
|
|||
if (mDataBlock->textureHandle)
|
||||
ri->diffuseTex = &*(mDataBlock->textureHandle);
|
||||
else
|
||||
ri->diffuseTex = &*(part_list_head.next->dataBlock->textureHandle);
|
||||
ri->diffuseTex = &*(part_list_head.next->dataBlock->getTextureResource());
|
||||
|
||||
ri->softnessDistance = mDataBlock->softnessDistance;
|
||||
|
||||
|
|
|
|||
|
|
@ -129,9 +129,12 @@ PrecipitationData::PrecipitationData()
|
|||
{
|
||||
soundProfile = NULL;
|
||||
|
||||
mDropName = StringTable->EmptyString();
|
||||
INIT_IMAGEASSET(Drop);
|
||||
|
||||
mDropShaderName = StringTable->EmptyString();
|
||||
mSplashName = StringTable->EmptyString();
|
||||
|
||||
INIT_IMAGEASSET(Splash);
|
||||
|
||||
mSplashShaderName = StringTable->EmptyString();
|
||||
|
||||
mDropsPerSide = 4;
|
||||
|
|
@ -142,18 +145,32 @@ void PrecipitationData::initPersistFields()
|
|||
{
|
||||
addField( "soundProfile", TYPEID< SFXTrack >(), Offset(soundProfile, PrecipitationData),
|
||||
"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"
|
||||
"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." );
|
||||
"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),
|
||||
"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"
|
||||
"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." );
|
||||
"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),
|
||||
"The name of the shader used for splashes." );
|
||||
addField( "dropsPerSide", TypeS32, Offset(mDropsPerSide, PrecipitationData),
|
||||
|
|
@ -185,9 +202,12 @@ void PrecipitationData::packData(BitStream* stream)
|
|||
|
||||
sfxWrite( stream, soundProfile );
|
||||
|
||||
stream->writeString(mDropName);
|
||||
PACKDATA_IMAGEASSET(Drop);
|
||||
|
||||
stream->writeString(mDropShaderName);
|
||||
stream->writeString(mSplashName);
|
||||
|
||||
PACKDATA_IMAGEASSET(Splash);
|
||||
|
||||
stream->writeString(mSplashShaderName);
|
||||
stream->write(mDropsPerSide);
|
||||
stream->write(mSplashesPerSide);
|
||||
|
|
@ -199,9 +219,12 @@ void PrecipitationData::unpackData(BitStream* stream)
|
|||
|
||||
sfxRead( stream, &soundProfile );
|
||||
|
||||
mDropName = stream->readSTString();
|
||||
UNPACKDATA_IMAGEASSET(Drop);
|
||||
|
||||
mDropShaderName = stream->readSTString();
|
||||
mSplashName = stream->readSTString();
|
||||
|
||||
UNPACKDATA_IMAGEASSET(Splash);
|
||||
|
||||
mSplashShaderName = stream->readSTString();
|
||||
stream->read(&mDropsPerSide);
|
||||
stream->read(&mSplashesPerSide);
|
||||
|
|
@ -604,8 +627,8 @@ void Precipitation::initMaterials()
|
|||
mDropShader = NULL;
|
||||
mSplashShader = NULL;
|
||||
|
||||
if( dStrlen(pd->mDropName) > 0 && !mDropHandle.set(pd->mDropName, &GFXStaticTextureSRGBProfile, avar("%s() - mDropHandle (line %d)", __FUNCTION__, __LINE__)) )
|
||||
Con::warnf("Precipitation::initMaterials - failed to locate texture '%s'!", pd->mDropName);
|
||||
if(pd->mDrop.isNull())
|
||||
Con::warnf("Precipitation::initMaterials - failed to locate texture '%s'!", pd->getDrop());
|
||||
|
||||
if ( dStrlen(pd->mDropShaderName) > 0 )
|
||||
{
|
||||
|
|
@ -625,8 +648,8 @@ void Precipitation::initMaterials()
|
|||
}
|
||||
}
|
||||
|
||||
if( dStrlen(pd->mSplashName) > 0 && !mSplashHandle.set(pd->mSplashName, &GFXStaticTextureSRGBProfile, avar("%s() - mSplashHandle (line %d)", __FUNCTION__, __LINE__)) )
|
||||
Con::warnf("Precipitation::initMaterials - failed to locate texture '%s'!", pd->mSplashName);
|
||||
if (pd->mSplash.isNull())
|
||||
Con::warnf("Precipitation::initMaterials - failed to locate texture '%s'!", pd->getSplash());
|
||||
|
||||
if ( dStrlen(pd->mSplashShaderName) > 0 )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@
|
|||
#include "renderInstance/renderPassManager.h"
|
||||
#endif
|
||||
|
||||
#include "T3D/assets/ImageAsset.h"
|
||||
|
||||
class SFXTrack;
|
||||
class SFXSource;
|
||||
|
||||
|
|
@ -45,9 +47,14 @@ class PrecipitationData : public GameBaseData
|
|||
public:
|
||||
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 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
|
||||
|
||||
S32 mDropsPerSide; ///< How many drops are on a side of the raindrop texture.
|
||||
|
|
@ -59,6 +66,9 @@ class PrecipitationData : public GameBaseData
|
|||
static void initPersistFields();
|
||||
virtual void packData(BitStream* stream);
|
||||
virtual void unpackData(BitStream* stream);
|
||||
|
||||
void onDropChanged() {}
|
||||
void onSplashChanged() {}
|
||||
};
|
||||
|
||||
struct Raindrop
|
||||
|
|
|
|||
|
|
@ -93,9 +93,10 @@ SplashData::SplashData()
|
|||
explosion = NULL;
|
||||
explosionId = 0;
|
||||
|
||||
dMemset( textureName, 0, sizeof( textureName ) );
|
||||
|
||||
U32 i;
|
||||
for (i = 0; i < NUM_TEX; i++)
|
||||
INIT_IMAGEASSET_ARRAY(Texture, i);
|
||||
|
||||
for( i=0; i<NUM_TIME_KEYS; i++ )
|
||||
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("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("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("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");
|
||||
|
|
@ -198,7 +201,7 @@ void SplashData::packData(BitStream* stream)
|
|||
|
||||
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++ )
|
||||
{
|
||||
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++ )
|
||||
{
|
||||
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 "T3D/assets/ImageAsset.h"
|
||||
|
||||
class ParticleEmitter;
|
||||
class ParticleEmitterData;
|
||||
class AudioProfile;
|
||||
|
|
@ -116,8 +118,8 @@ public:
|
|||
F32 times[ NUM_TIME_KEYS ];
|
||||
LinearColorF colors[ NUM_TIME_KEYS ];
|
||||
|
||||
StringTableEntry textureName[NUM_TEX];
|
||||
GFXTexHandle textureHandle[NUM_TEX];
|
||||
DECLARE_IMAGEASSET_ARRAY(SplashData, Texture, GFXStaticTextureSRGBProfile, NUM_TEX);
|
||||
DECLARE_IMAGEASSET_ARRAY_SETGET(SplashData, Texture)
|
||||
|
||||
ExplosionData* explosion;
|
||||
S32 explosionId;
|
||||
|
|
|
|||
|
|
@ -371,7 +371,6 @@ void GameConnection::onConnectionEstablished(bool isInitiator)
|
|||
setTranslatesStrings(true);
|
||||
Sim::getClientGroup()->addObject(this);
|
||||
mMoveList->init();
|
||||
|
||||
const char *argv[MaxConnectArgs + 2];
|
||||
argv[0] = "onConnect";
|
||||
argv[1] = NULL; // Filled in later
|
||||
|
|
@ -646,6 +645,7 @@ void GameConnection::setCameraObject(GameBase *obj)
|
|||
smFovUpdate.trigger(fov);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
GameBase* GameConnection::getCameraObject()
|
||||
|
|
|
|||
|
|
@ -403,7 +403,7 @@ protected:
|
|||
public:
|
||||
void setRolloverObj(SceneObject*);
|
||||
SceneObject* getRolloverObj() { return mRolloverObj; }
|
||||
void setSelectedObj(SceneObject*, bool propagate_to_client=false);
|
||||
void setSelectedObj(SceneObject*, bool propagate_to_client=false);
|
||||
SceneObject* getSelectedObj() { return mSelectedObj; }
|
||||
void setPreSelectedObjFromRollover();
|
||||
void clearPreSelectedObj();
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ GroundPlane::GroundPlane()
|
|||
mScaleU( 1.0f ),
|
||||
mScaleV( 1.0f ),
|
||||
mMaterial( NULL ),
|
||||
mMaterialInst(NULL),
|
||||
mPhysicsRep( NULL ),
|
||||
mMin( 0.0f, 0.0f ),
|
||||
mMax( 0.0f, 0.0f )
|
||||
|
|
@ -86,13 +87,15 @@ GroundPlane::GroundPlane()
|
|||
mConvexList = new Convex;
|
||||
mTypeMask |= TerrainLikeObjectType;
|
||||
|
||||
initMaterialAsset(Material);
|
||||
INIT_MATERIALASSET(Material);
|
||||
}
|
||||
|
||||
GroundPlane::~GroundPlane()
|
||||
{
|
||||
if( mMaterial )
|
||||
SAFE_DELETE( mMaterial );
|
||||
mMaterial = nullptr;
|
||||
|
||||
if(mMaterialInst)
|
||||
SAFE_DELETE(mMaterialInst);
|
||||
|
||||
mConvexList->nukeList();
|
||||
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( "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" );
|
||||
|
||||
|
|
@ -153,6 +156,11 @@ bool GroundPlane::onAdd()
|
|||
|
||||
void GroundPlane::onRemove()
|
||||
{
|
||||
if (!mMaterialAsset.isNull())
|
||||
AssetDatabase.releaseAsset(mMaterialAsset.getAssetId());
|
||||
|
||||
//SAFE_DELETE(mMaterialInst);
|
||||
|
||||
SAFE_DELETE( mPhysicsRep );
|
||||
|
||||
removeFromScene();
|
||||
|
|
@ -191,7 +199,7 @@ U32 GroundPlane::packUpdate( NetConnection* connection, U32 mask, BitStream* str
|
|||
stream->write( mScaleU );
|
||||
stream->write( mScaleV );
|
||||
|
||||
packMaterialAsset(connection, Material);
|
||||
PACK_MATERIALASSET(connection, Material);
|
||||
|
||||
return retMask;
|
||||
}
|
||||
|
|
@ -204,7 +212,7 @@ void GroundPlane::unpackUpdate( NetConnection* connection, BitStream* stream )
|
|||
stream->read( &mScaleU );
|
||||
stream->read( &mScaleV );
|
||||
|
||||
unpackMaterialAsset(connection, Material);
|
||||
UNPACK_MATERIALASSET(connection, Material);
|
||||
|
||||
// If we're added then something possibly changed in
|
||||
// the editor... do an update of the material and the
|
||||
|
|
@ -220,14 +228,14 @@ void GroundPlane::_updateMaterial()
|
|||
{
|
||||
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;
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
|
@ -242,7 +250,7 @@ bool GroundPlane::castRay( const Point3F& start, const Point3F& end, RayInfo* in
|
|||
info->t = t;
|
||||
info->setContactPoint( start, end );
|
||||
info->normal.set( 0, 0, 1 );
|
||||
info->material = mMaterial;
|
||||
info->material = mMaterialInst;
|
||||
info->object = this;
|
||||
info->distance = 0;
|
||||
info->faceDot = 0;
|
||||
|
|
@ -336,7 +344,7 @@ bool GroundPlane::buildPolyList( PolyListContext context, AbstractPolyList* poly
|
|||
}
|
||||
|
||||
Box3F planeBox = getPlaneBox();
|
||||
polyList->addBox( planeBox, mMaterial );
|
||||
polyList->addBox( planeBox, mMaterialInst );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -353,7 +361,7 @@ void GroundPlane::prepRenderImage( SceneRenderState* state )
|
|||
|
||||
// If we don't have a material instance after the override then
|
||||
// we can skip rendering all together.
|
||||
BaseMatInstance *matInst = state->getOverrideMaterial( mMaterial );
|
||||
BaseMatInstance *matInst = state->getOverrideMaterial(mMaterialInst);
|
||||
if ( !matInst )
|
||||
return;
|
||||
|
||||
|
|
@ -584,7 +592,7 @@ void GroundPlane::generateGrid( U32 width, U32 height, F32 squareSize,
|
|||
|
||||
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());
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -104,9 +104,11 @@ private:
|
|||
F32 mSquareSize; ///< World units per grid cell edge.
|
||||
F32 mScaleU; ///< Scale factor for U 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;
|
||||
|
||||
|
|
|
|||
|
|
@ -634,7 +634,7 @@ void GuiObjectView::_initAnimation()
|
|||
{
|
||||
Con::errorf( "GuiObjectView::_initAnimation - Cannot find animation sequence '%s' on '%s'",
|
||||
mAnimationSeqName.c_str(),
|
||||
mModelName.c_str()
|
||||
mModelName
|
||||
);
|
||||
|
||||
return;
|
||||
|
|
@ -649,7 +649,7 @@ void GuiObjectView::_initAnimation()
|
|||
{
|
||||
Con::errorf( "GuiObjectView::_initAnimation - Sequence '%i' out of range for model '%s'",
|
||||
mAnimationSeq,
|
||||
mModelName.c_str()
|
||||
mModelName
|
||||
);
|
||||
|
||||
mAnimationSeq = -1;
|
||||
|
|
@ -685,7 +685,7 @@ void GuiObjectView::_initMount()
|
|||
{
|
||||
Con::errorf( "GuiObjectView::_initMount - No node '%s' on '%s'",
|
||||
mMountNodeName.c_str(),
|
||||
mModelName.c_str()
|
||||
mModelName
|
||||
);
|
||||
|
||||
return;
|
||||
|
|
@ -698,7 +698,7 @@ void GuiObjectView::_initMount()
|
|||
{
|
||||
Con::errorf( "GuiObjectView::_initMount - Mount node index '%i' out of range for '%s'",
|
||||
mMountNode,
|
||||
mModelName.c_str()
|
||||
mModelName
|
||||
);
|
||||
|
||||
mMountNode = -1;
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@
|
|||
#include "ts/tsShapeInstance.h"
|
||||
#endif
|
||||
|
||||
#include "T3D/assets/ShapeAsset.h"
|
||||
|
||||
|
||||
class LightInfo;
|
||||
|
||||
|
|
@ -68,7 +70,7 @@ class GuiObjectView : public GuiTSCtrl
|
|||
/// @{
|
||||
|
||||
/// Name of the model loaded for display.
|
||||
String mModelName;
|
||||
StringTableEntry mModelName;
|
||||
|
||||
/// Model being displayed in the view.
|
||||
TSShapeInstance* mModel;
|
||||
|
|
|
|||
|
|
@ -98,8 +98,8 @@ LevelInfo::LevelInfo()
|
|||
mNetFlags.set( ScopeAlways | Ghostable );
|
||||
|
||||
mAdvancedLightmapSupport = true;
|
||||
mAccuTextureName = "";
|
||||
mAccuTexture = NULL;
|
||||
|
||||
INIT_IMAGEASSET(AccuTexture);
|
||||
|
||||
// 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
|
||||
|
|
@ -166,8 +166,7 @@ void LevelInfo::initPersistFields()
|
|||
//addField( "advancedLightmapSupport", TypeBool, Offset( mAdvancedLightmapSupport, LevelInfo ),
|
||||
// "Enable expanded support for mixing static and dynamic lighting (more costly)" );
|
||||
|
||||
addProtectedField("AccuTexture", TypeStringFilename, Offset(mAccuTextureName, LevelInfo),
|
||||
&_setLevelAccuTexture, &defaultProtectedGetFn, "Accumulation texture.");
|
||||
INITPERSISTFIELD_IMAGEASSET(AccuTexture, LevelInfo, "Accumulation texture.");
|
||||
|
||||
endGroup( "Lighting" );
|
||||
|
||||
|
|
@ -216,7 +215,8 @@ U32 LevelInfo::packUpdate(NetConnection *conn, U32 mask, BitStream *stream)
|
|||
sfxWrite( stream, mSoundAmbience );
|
||||
stream->writeInt( mSoundDistanceModel, 1 );
|
||||
|
||||
stream->write(mAccuTextureName);
|
||||
PACK_IMAGEASSET(conn, AccuTexture);
|
||||
|
||||
return retMask;
|
||||
}
|
||||
|
||||
|
|
@ -261,8 +261,9 @@ void LevelInfo::unpackUpdate(NetConnection *conn, BitStream *stream)
|
|||
|
||||
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)
|
||||
{
|
||||
LevelInfo* volume = reinterpret_cast< LevelInfo* >(object);
|
||||
volume->setLevelAccuTexture(data);
|
||||
volume->setLevelAccuTexture(StringTable->insert(data));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void LevelInfo::setLevelAccuTexture(const String& name)
|
||||
void LevelInfo::setLevelAccuTexture(StringTableEntry name)
|
||||
{
|
||||
mAccuTextureName = name;
|
||||
if (isClientObject() && mAccuTextureName.isNotEmpty())
|
||||
_setAccuTexture(name);
|
||||
|
||||
if (isClientObject() && getAccuTexture() != StringTable->EmptyString())
|
||||
{
|
||||
mAccuTexture.set(mAccuTextureName, &GFXStaticTextureSRGBProfile, "AccumulationVolume::mAccuTexture");
|
||||
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
|
||||
gLevelAccuMap = mAccuTexture;
|
||||
}
|
||||
AccumulationVolume::refreshVolumes();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,8 @@
|
|||
#include "gfx/gfxTextureHandle.h"
|
||||
#endif
|
||||
|
||||
#include "T3D/assets/ImageAsset.h"
|
||||
|
||||
class SFXAmbience;
|
||||
class SFXSoundscape;
|
||||
|
||||
|
|
@ -101,8 +103,11 @@ class LevelInfo : public NetObject
|
|||
|
||||
void _onLMActivate(const char *lm, bool enable);
|
||||
protected:
|
||||
// Name (path) of the accumulation texture.
|
||||
String mAccuTextureName;
|
||||
|
||||
DECLARE_IMAGEASSET(LevelInfo, AccuTexture, onAccuTextureChanged, GFXStaticTextureSRGBProfile);
|
||||
DECLARE_IMAGEASSET_SETGET(LevelInfo, AccuTexture);
|
||||
|
||||
void onAccuTextureChanged() {}
|
||||
|
||||
public:
|
||||
|
||||
|
|
@ -137,13 +142,11 @@ class LevelInfo : public NetObject
|
|||
UpdateMask = BIT(0)
|
||||
};
|
||||
|
||||
GFXTexHandle mAccuTexture;
|
||||
|
||||
virtual U32 packUpdate( NetConnection *conn, U32 mask, BitStream *stream );
|
||||
virtual void unpackUpdate( NetConnection *conn, BitStream *stream );
|
||||
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 );
|
||||
|
||||
for ( U32 i = 0; i < MAX_ELEMENTS; i++ )
|
||||
mElementDist[i] = -1.0f;
|
||||
mElementDist[i] = -1.0f;
|
||||
|
||||
INIT_IMAGEASSET(FlareTexture);
|
||||
}
|
||||
|
||||
LightFlareData::~LightFlareData()
|
||||
|
|
@ -158,8 +160,7 @@ void LightFlareData::initPersistFields()
|
|||
addField( "flareEnabled", TypeBool, Offset( mFlareEnabled, LightFlareData ),
|
||||
"Allows the user to disable this flare globally for any lights referencing it." );
|
||||
|
||||
addField( "flareTexture", TypeImageFilename, Offset( mFlareTextureName, LightFlareData ),
|
||||
"The texture / sprite sheet for this flare." );
|
||||
INITPERSISTFIELD_IMAGEASSET(FlareTexture, LightFlareData, "The texture / sprite sheet for this flare.");
|
||||
|
||||
addArray( "Elements", MAX_ELEMENTS );
|
||||
|
||||
|
|
@ -217,7 +218,9 @@ void LightFlareData::packData( BitStream *stream )
|
|||
Parent::packData( stream );
|
||||
|
||||
stream->writeFlag( mFlareEnabled );
|
||||
stream->write( mFlareTextureName );
|
||||
|
||||
PACKDATA_IMAGEASSET(FlareTexture);
|
||||
|
||||
stream->write( mScale );
|
||||
stream->write( mOcclusionRadius );
|
||||
stream->writeFlag( mRenderReflectPass );
|
||||
|
|
@ -240,7 +243,9 @@ void LightFlareData::unpackData( BitStream *stream )
|
|||
Parent::unpackData( stream );
|
||||
|
||||
mFlareEnabled = stream->readFlag();
|
||||
stream->read( &mFlareTextureName );
|
||||
|
||||
UNPACKDATA_IMAGEASSET(FlareTexture);
|
||||
|
||||
stream->read( &mScale );
|
||||
stream->read( &mOcclusionRadius );
|
||||
mRenderReflectPass = stream->readFlag();
|
||||
|
|
@ -631,12 +636,6 @@ bool LightFlareData::_preload( bool server, String &errorStr )
|
|||
if ( mElementCount > 0 )
|
||||
_makePrimBuffer( &mFlarePrimBuffer, mElementCount );
|
||||
|
||||
if ( !server )
|
||||
{
|
||||
if ( mFlareTextureName.isNotEmpty() )
|
||||
mFlareTexture.set( mFlareTextureName, &GFXStaticTextureSRGBProfile, "FlareTexture" );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -45,6 +45,8 @@
|
|||
#include "gfx/gfxOcclusionQuery.h"
|
||||
#endif
|
||||
|
||||
#include "T3D/assets/ImageAsset.h"
|
||||
|
||||
class LightInfo;
|
||||
struct ObjectRenderInst;
|
||||
class SceneRenderState;
|
||||
|
|
@ -104,6 +106,8 @@ protected:
|
|||
void _makePrimBuffer( GFXPrimitiveBufferHandle *pb, U32 count );
|
||||
void _renderCorona( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat );
|
||||
|
||||
void onImageChanged() {}
|
||||
|
||||
protected:
|
||||
|
||||
static const U32 LosMask;
|
||||
|
|
@ -115,8 +119,10 @@ protected:
|
|||
|
||||
F32 mScale;
|
||||
bool mFlareEnabled;
|
||||
String mFlareTextureName;
|
||||
GFXTexHandle mFlareTexture;
|
||||
|
||||
DECLARE_IMAGEASSET(LightFlareData, FlareTexture, onImageChanged, GFXStaticTextureSRGBProfile);
|
||||
DECLARE_IMAGEASSET_SETGET(LightFlareData, FlareTexture);
|
||||
|
||||
F32 mOcclusionRadius;
|
||||
bool mRenderReflectPass;
|
||||
|
||||
|
|
@ -133,4 +139,4 @@ protected:
|
|||
GFXPrimitiveBufferHandle mFlarePrimBuffer;
|
||||
};
|
||||
|
||||
#endif // _LIGHTFLAREDATA_H_
|
||||
#endif // _LIGHTFLAREDATA_H_
|
||||
|
|
|
|||
|
|
@ -426,7 +426,7 @@ U32 ReflectionProbe::packUpdate(NetConnection *conn, U32 mask, BitStream *stream
|
|||
stream->write(mRadius);
|
||||
stream->write(mProbeUniqueID);
|
||||
stream->write((U32)mReflectionModeType);
|
||||
stream->write(mCubemapName);
|
||||
stream->writeString(mCubemapName);
|
||||
}
|
||||
|
||||
if (stream->writeFlag(mask & EnabledMask))
|
||||
|
|
@ -474,8 +474,8 @@ void ReflectionProbe::unpackUpdate(NetConnection *conn, BitStream *stream)
|
|||
stream->read(&reflectModeType);
|
||||
mReflectionModeType = (ReflectionModeType)reflectModeType;
|
||||
|
||||
String oldCubemapName = mCubemapName;
|
||||
stream->read(&mCubemapName);
|
||||
StringTableEntry oldCubemapName = mCubemapName;
|
||||
mCubemapName = stream->readSTString();
|
||||
|
||||
if(oldReflectModeType != mReflectionModeType || oldCubemapName != mCubemapName)
|
||||
mCubemapDirty = true;
|
||||
|
|
@ -630,7 +630,7 @@ void ReflectionProbe::processStaticCubemap()
|
|||
String path = Con::getVariable("$pref::ReflectionProbes::CurrentLevelPath", "levels/");
|
||||
|
||||
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))
|
||||
{
|
||||
|
|
@ -645,7 +645,7 @@ void ReflectionProbe::processStaticCubemap()
|
|||
}
|
||||
|
||||
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))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ protected:
|
|||
/// <summary>
|
||||
/// This is used when a static cubemap is used. The name of the cubemap is looked up and loaded for the IBL calculations
|
||||
/// </summary>
|
||||
String mCubemapName;
|
||||
StringTableEntry mCubemapName;
|
||||
CubemapData *mStaticCubemap;
|
||||
GFXCubemapHandle mDynamicCubemap;
|
||||
|
||||
|
|
|
|||
|
|
@ -73,7 +73,8 @@ PhysicsDebrisData::PhysicsDebrisData()
|
|||
{
|
||||
lifetime = 5.0f;
|
||||
lifetimeVariance = 0.0f;
|
||||
shapeName = NULL;
|
||||
|
||||
INIT_SHAPEASSET(Shape);
|
||||
}
|
||||
|
||||
bool PhysicsDebrisData::onAdd()
|
||||
|
|
@ -91,21 +92,17 @@ bool PhysicsDebrisData::preload( bool server, String &errorStr )
|
|||
|
||||
if ( server ) return true;
|
||||
|
||||
if ( shapeName && shapeName[0] != '\0' && !bool(shape) )
|
||||
if ( mShapeAsset.notNull() )
|
||||
{
|
||||
shape = ResourceManager::get().load( shapeName );
|
||||
if ( bool(shape) == false )
|
||||
{
|
||||
errorStr = String::ToString( "PhysicsDebrisData::load: Couldn't load shape \"%s\"", shapeName );
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create a dummy shape to force the generation of shaders and materials
|
||||
// during the level load and not during gameplay.
|
||||
TSShapeInstance *pDummy = new TSShapeInstance( shape, !server );
|
||||
delete pDummy;
|
||||
}
|
||||
// Create a dummy shape to force the generation of shaders and materials
|
||||
// during the level load and not during gameplay.
|
||||
TSShapeInstance *pDummy = new TSShapeInstance( mShape, !server );
|
||||
delete pDummy;
|
||||
}
|
||||
else
|
||||
{
|
||||
errorStr = String::ToString("PhysicsDebrisData::load: Couldn't load shape asset \"%s\"", mShapeAssetId);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -115,8 +112,11 @@ void PhysicsDebrisData::initPersistFields()
|
|||
{
|
||||
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"
|
||||
"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.");
|
||||
|
||||
addField( "castShadows", TypeBool, Offset( castShadows, PhysicsDebrisData ),
|
||||
|
|
@ -214,7 +214,8 @@ void PhysicsDebrisData::packData(BitStream* stream)
|
|||
stream->write( angularSleepThreshold );
|
||||
stream->write( waterDampingScale );
|
||||
stream->write( buoyancyDensity );
|
||||
stream->writeString( shapeName );
|
||||
|
||||
PACKDATA_SHAPEASSET(Shape);
|
||||
}
|
||||
|
||||
void PhysicsDebrisData::unpackData(BitStream* stream)
|
||||
|
|
@ -235,7 +236,7 @@ void PhysicsDebrisData::unpackData(BitStream* stream)
|
|||
stream->read( &waterDampingScale );
|
||||
stream->read( &buoyancyDensity );
|
||||
|
||||
shapeName = stream->readSTString();
|
||||
UNPACKDATA_SHAPEASSET(Shape);
|
||||
}
|
||||
|
||||
DefineEngineMethod( PhysicsDebrisData, preload, void, (), ,
|
||||
|
|
@ -246,7 +247,8 @@ DefineEngineMethod( PhysicsDebrisData, preload, void, (), ,
|
|||
{
|
||||
String errorStr;
|
||||
|
||||
object->shape = NULL;
|
||||
object->_setShape(object->getShape());
|
||||
|
||||
if( !object->preload( false, errorStr ) )
|
||||
Con::errorf( "PhsysicsDebrisData::preload - error: %s", errorStr.c_str() );
|
||||
}
|
||||
|
|
@ -358,7 +360,7 @@ bool PhysicsDebris::onAdd()
|
|||
}
|
||||
|
||||
// Setup our bounding box
|
||||
mObjBox = mDataBlock->shape->mBounds;
|
||||
mObjBox = mDataBlock->mShape->mBounds;
|
||||
resetWorldBox();
|
||||
|
||||
// Add it to the client scene.
|
||||
|
|
@ -621,7 +623,7 @@ void PhysicsDebris::_createFragments()
|
|||
if ( !mWorld )
|
||||
return;
|
||||
|
||||
TSShape *shape = mDataBlock->shape;
|
||||
TSShape *shape = mDataBlock->mShape;
|
||||
|
||||
mShapeInstance = new TSShapeInstance( shape, true );
|
||||
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
|
||||
// 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;
|
||||
itr = shape->nodes[itr].firstChild;
|
||||
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@
|
|||
#include "T3D/physics/physicsCommon.h"
|
||||
#endif
|
||||
|
||||
#include "T3D/assets/ShapeAsset.h"
|
||||
|
||||
|
||||
class TSShapeInstance;
|
||||
class TSShape;
|
||||
|
|
@ -84,8 +86,8 @@ public:
|
|||
/// Is rendererd during shadow passes.
|
||||
bool castShadows;
|
||||
|
||||
const char* shapeName;
|
||||
Resource<TSShape> shape;
|
||||
DECLARE_SHAPEASSET(PhysicsDebrisData, Shape, onShapeChanged);
|
||||
DECLARE_SHAPEASSET_SETGET(PhysicsDebrisData, Shape);
|
||||
|
||||
PhysicsDebrisData();
|
||||
|
||||
|
|
@ -95,6 +97,8 @@ public:
|
|||
void packData( BitStream *stream );
|
||||
void unpackData( BitStream *stream );
|
||||
|
||||
void onShapeChanged() {}
|
||||
|
||||
DECLARE_CONOBJECT( PhysicsDebrisData );
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -66,8 +66,7 @@ ConsoleDocClass( PhysicsShapeData,
|
|||
);
|
||||
|
||||
PhysicsShapeData::PhysicsShapeData()
|
||||
: shapeName( NULL ),
|
||||
mass( 1.0f ),
|
||||
: mass( 1.0f ),
|
||||
dynamicFriction( 0.0f ),
|
||||
staticFriction( 0.0f ),
|
||||
restitution( 0.0f ),
|
||||
|
|
@ -79,6 +78,7 @@ PhysicsShapeData::PhysicsShapeData()
|
|||
buoyancyDensity( 0.0f ),
|
||||
simType( SimType_ClientServer )
|
||||
{
|
||||
INIT_SHAPEASSET(Shape);
|
||||
}
|
||||
|
||||
PhysicsShapeData::~PhysicsShapeData()
|
||||
|
|
@ -91,9 +91,8 @@ void PhysicsShapeData::initPersistFields()
|
|||
|
||||
addGroup("Media");
|
||||
|
||||
addField( "shapeName", TypeShapeFilename, Offset( shapeName, PhysicsShapeData ),
|
||||
"@brief Path to the .DAE or .DTS file to use for this shape.\n\n"
|
||||
"Compatable with Live-Asset Reloading. ");
|
||||
INITPERSISTFIELD_SHAPEASSET(Shape, PhysicsShapeData, "@brief Shape asset to be used with this physics object.\n\n"
|
||||
"Compatable with Live-Asset Reloading. ")
|
||||
|
||||
addField( "debris", TYPEID< SimObjectRef<PhysicsDebrisData> >(), Offset( debris, PhysicsShapeData ),
|
||||
"@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 );
|
||||
|
||||
stream->writeString( shapeName );
|
||||
PACKDATA_SHAPEASSET(Shape);
|
||||
|
||||
stream->write( mass );
|
||||
stream->write( dynamicFriction );
|
||||
|
|
@ -205,7 +204,7 @@ void PhysicsShapeData::unpackData( BitStream *stream )
|
|||
{
|
||||
Parent::unpackData(stream);
|
||||
|
||||
shapeName = stream->readSTString();
|
||||
UNPACKDATA_SHAPEASSET(Shape);
|
||||
|
||||
stream->read( &mass );
|
||||
stream->read( &dynamicFriction );
|
||||
|
|
@ -242,28 +241,28 @@ void PhysicsShapeData::onRemove()
|
|||
|
||||
void PhysicsShapeData::_onResourceChanged( const Torque::Path &path )
|
||||
{
|
||||
if ( path != Path( shapeName ) )
|
||||
if (mShapeAsset.isNull())
|
||||
return;
|
||||
|
||||
if ( path != Path(mShapeAsset->getShapeFilePath()) )
|
||||
return;
|
||||
|
||||
_setShape(getShape());
|
||||
|
||||
// Reload the changed shape.
|
||||
Resource<TSShape> reloadShape;
|
||||
PhysicsCollisionRef reloadcolShape;
|
||||
|
||||
reloadShape = ResourceManager::get().load( shapeName );
|
||||
if ( !bool(reloadShape) )
|
||||
if ( !mShape )
|
||||
{
|
||||
Con::warnf( ConsoleLogEntry::General, "PhysicsShapeData::_onResourceChanged: Could not reload %s.", path.getFileName().c_str() );
|
||||
return;
|
||||
}
|
||||
|
||||
// Reload the collision shape.
|
||||
reloadcolShape = reloadShape->buildColShape( false, Point3F::One );
|
||||
reloadcolShape = mShape->buildColShape( false, Point3F::One );
|
||||
|
||||
if ( bool(reloadShape) && bool(reloadcolShape))
|
||||
{
|
||||
shape = reloadShape;
|
||||
if ( bool(reloadcolShape))
|
||||
colShape = reloadcolShape;
|
||||
}
|
||||
|
||||
mReloadSignal.trigger();
|
||||
}
|
||||
|
|
@ -283,35 +282,33 @@ bool PhysicsShapeData::preload( bool server, String &errorBuffer )
|
|||
|
||||
bool shapeError = false;
|
||||
|
||||
if (shapeName && shapeName[0])
|
||||
if (mShapeAsset.notNull())
|
||||
{
|
||||
// Resolve shapename
|
||||
shape = ResourceManager::get().load(shapeName);
|
||||
if (bool(shape) == false)
|
||||
if (bool(mShape) == false)
|
||||
{
|
||||
errorBuffer = String::ToString("PhysicsShapeData: Couldn't load shape \"%s\"", shapeName);
|
||||
errorBuffer = String::ToString("PhysicsShapeData: Couldn't load shape \"%s\"", mShapeAssetId);
|
||||
return false;
|
||||
}
|
||||
if (!server && !shape->preloadMaterialList(shape.getPath()) && NetConnection::filesWereDownloaded())
|
||||
if (!server && !mShape->preloadMaterialList(mShape.getPath()) && NetConnection::filesWereDownloaded())
|
||||
shapeError = true;
|
||||
|
||||
}
|
||||
|
||||
// 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
|
||||
// we need to fail... can't have a shape without collision.
|
||||
if ( !colShape )
|
||||
{
|
||||
//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 );
|
||||
Point3F halfWidth = shape->mBounds.getExtents() * 0.5f;
|
||||
Con::warnf( "PhysicsShapeData::preload - No collision found for shape '%s', auto-creating one", mShapeAssetId);
|
||||
Point3F halfWidth = mShape->mBounds.getExtents() * 0.5f;
|
||||
colShape = PHYSICSMGR->createCollision();
|
||||
MatrixF centerXfm(true);
|
||||
centerXfm.setPosition(shape->mBounds.getCenter());
|
||||
centerXfm.setPosition(mShape->mBounds.getCenter());
|
||||
colShape->addBox(halfWidth, centerXfm);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -703,11 +700,11 @@ bool PhysicsShape::_createShape()
|
|||
mAmbientSeq = -1;
|
||||
|
||||
PhysicsShapeData *db = getDataBlock();
|
||||
if ( !db || !db->shape)
|
||||
if ( !db || !db->mShape)
|
||||
return false;
|
||||
|
||||
// Set the world box.
|
||||
mObjBox = db->shape->mBounds;
|
||||
mObjBox = db->mShape->mBounds;
|
||||
resetWorldBox();
|
||||
|
||||
// If this is the server and its a client only simulation
|
||||
|
|
@ -721,11 +718,11 @@ bool PhysicsShape::_createShape()
|
|||
}
|
||||
|
||||
// Create the shape instance.
|
||||
mShapeInst = new TSShapeInstance( db->shape, isClientObject() );
|
||||
mShapeInst = new TSShapeInstance( db->mShape, isClientObject() );
|
||||
|
||||
if ( isClientObject() )
|
||||
{
|
||||
mAmbientSeq = db->shape->findSequence( "ambient" );
|
||||
mAmbientSeq = db->mShape->findSequence( "ambient" );
|
||||
_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")
|
||||
{
|
||||
object->applyForce( force );
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,6 +42,8 @@
|
|||
#include "console/simObjectRef.h"
|
||||
#endif
|
||||
|
||||
#include "T3D/assets/ShapeAsset.h"
|
||||
|
||||
class TSShapeInstance;
|
||||
class PhysicsBody;
|
||||
class PhysicsWorld;
|
||||
|
|
@ -72,11 +74,8 @@ public:
|
|||
|
||||
public:
|
||||
|
||||
/// The shape to load.
|
||||
StringTableEntry shapeName;
|
||||
|
||||
/// The shape resource.
|
||||
Resource<TSShape> shape;
|
||||
DECLARE_SHAPEASSET(PhysicsShapeData, Shape, onShapeChanged);
|
||||
DECLARE_SHAPEASSET_SETGET(PhysicsShapeData, Shape);
|
||||
|
||||
/// The shared unscaled collision shape.
|
||||
PhysicsCollisionRef colShape;
|
||||
|
|
@ -135,6 +134,8 @@ public:
|
|||
SimObjectRef< PhysicsDebrisData > debris;
|
||||
SimObjectRef< ExplosionData > explosion;
|
||||
SimObjectRef< PhysicsShapeData > destroyedShape;
|
||||
|
||||
void onShapeChanged() {}
|
||||
};
|
||||
|
||||
typedef PhysicsShapeData::SimType PhysicsSimType;
|
||||
|
|
|
|||
|
|
@ -272,7 +272,7 @@ PlayerData::PlayerData()
|
|||
imageAnimPrefixFP = StringTable->EmptyString();
|
||||
for (U32 i=0; i<ShapeBase::MaxMountedImages; ++i)
|
||||
{
|
||||
shapeNameFP[i] = StringTable->EmptyString();
|
||||
INIT_SHAPEASSET_ARRAY(ShapeFP, i);
|
||||
mCRCFP[i] = 0;
|
||||
mValidShapeFP[i] = false;
|
||||
}
|
||||
|
|
@ -585,35 +585,34 @@ bool PlayerData::preload(bool server, String &errorStr)
|
|||
{
|
||||
bool shapeError = false;
|
||||
|
||||
if (shapeNameFP[i] && shapeNameFP[i][0])
|
||||
if (mShapeFPAssetId[i] != StringTable->EmptyString())
|
||||
{
|
||||
mShapeFP[i] = ResourceManager::get().load(shapeNameFP[i]);
|
||||
if (bool(mShapeFP[i]) == false)
|
||||
if (!mShapeFP[i])
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
if(!server && !mShapeFP[i]->preloadMaterialList(mShapeFP[i].getPath()) && NetConnection::filesWereDownloaded())
|
||||
if (!server && !mShapeFP[i]->preloadMaterialList(mShapeFP[i].getPath()) && NetConnection::filesWereDownloaded())
|
||||
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());
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if(server)
|
||||
if (server)
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1166,8 +1165,13 @@ void PlayerData::initPersistFields()
|
|||
// Mounted images arrays
|
||||
addArray( "Mounted Images", ShapeBase::MaxMountedImages );
|
||||
|
||||
addField( "shapeNameFP", TypeShapeFilename, Offset(shapeNameFP, PlayerData), ShapeBase::MaxMountedImages,
|
||||
addProtectedField( "shapeNameFP", TypeShapeFilename, Offset(mShapeFPName, PlayerData), &_setShapeFPData, &defaultProtectedGetFn, ShapeBase::MaxMountedImages,
|
||||
"@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, 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 "
|
||||
"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");
|
||||
|
|
@ -1369,7 +1373,7 @@ void PlayerData::packData(BitStream* stream)
|
|||
stream->writeString(imageAnimPrefixFP);
|
||||
for (U32 i=0; i<ShapeBase::MaxMountedImages; ++i)
|
||||
{
|
||||
stream->writeString(shapeNameFP[i]);
|
||||
PACKDATA_SHAPEASSET_ARRAY(ShapeFP, i);
|
||||
|
||||
// computeCRC is handled in ShapeBaseData
|
||||
if (computeCRC)
|
||||
|
|
@ -1549,7 +1553,7 @@ void PlayerData::unpackData(BitStream* stream)
|
|||
imageAnimPrefixFP = stream->readSTString();
|
||||
for (U32 i=0; i<ShapeBase::MaxMountedImages; ++i)
|
||||
{
|
||||
shapeNameFP[i] = stream->readSTString();
|
||||
UNPACKDATA_SHAPEASSET_ARRAY(ShapeFP, i);
|
||||
|
||||
// computeCRC is handled in ShapeBaseData
|
||||
if (computeCRC)
|
||||
|
|
|
|||
|
|
@ -75,10 +75,11 @@ struct PlayerData: public ShapeBaseData {
|
|||
/// that we don't create a TSThread on the player if we don't
|
||||
/// 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
|
||||
/// 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
|
||||
/// Depends on the ShapeBaseData computeCRC field.
|
||||
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 ) )
|
||||
{
|
||||
stream->write( mFilename );
|
||||
stream->writeString( mFilename );
|
||||
}
|
||||
|
||||
if ( stream->writeFlag( mask & TransformMask ) )
|
||||
|
|
@ -218,7 +218,7 @@ void Prefab::unpackUpdate(NetConnection *conn, BitStream *stream)
|
|||
// FileMask
|
||||
if ( stream->readFlag() )
|
||||
{
|
||||
stream->read( &mFilename );
|
||||
mFilename = stream->readSTString();
|
||||
}
|
||||
|
||||
// TransformMask
|
||||
|
|
@ -235,9 +235,7 @@ bool Prefab::protectedSetFile( void *object, const char *index, const char *data
|
|||
{
|
||||
Prefab *prefab = static_cast<Prefab*>(object);
|
||||
|
||||
String file = String( Platform::makeRelativePathName(data, Platform::getMainDotCsDir()) );
|
||||
|
||||
prefab->setFile( file );
|
||||
prefab->setFile( StringTable->insert(Platform::makeRelativePathName(data, Platform::getMainDotCsDir())));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
@ -336,12 +334,12 @@ void Prefab::_loadFile( bool addFileNotify )
|
|||
{
|
||||
AssertFatal( isServerObject(), "Prefab-bad" );
|
||||
|
||||
if ( mFilename.isEmpty() )
|
||||
if ( mFilename == StringTable->EmptyString())
|
||||
return;
|
||||
|
||||
if ( !Platform::isFile( mFilename ) )
|
||||
{
|
||||
Con::errorf( "Prefab::_loadFile() - file %s was not found.", mFilename.c_str() );
|
||||
Con::errorf( "Prefab::_loadFile() - file %s was not found.", mFilename );
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -349,19 +347,19 @@ void Prefab::_loadFile( bool addFileNotify )
|
|||
{
|
||||
Con::errorf(
|
||||
"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;
|
||||
}
|
||||
|
||||
sPrefabFileStack.push_back(mFilename);
|
||||
|
||||
String command = String::ToString( "exec( \"%s\" );", mFilename.c_str() );
|
||||
String command = String::ToString( "exec( \"%s\" );", mFilename );
|
||||
Con::evaluate( command );
|
||||
|
||||
SimGroup *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;
|
||||
}
|
||||
|
||||
|
|
@ -614,4 +612,4 @@ void ExplodePrefabUndoAction::redo()
|
|||
name += "_exploded";
|
||||
name = Sim::getUniqueName( name );
|
||||
mGroup->assignName( name );
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ protected:
|
|||
protected:
|
||||
|
||||
/// Prefab file which defines our children objects.
|
||||
String mFilename;
|
||||
StringTableEntry mFilename;
|
||||
|
||||
/// Group which holds all children objects.
|
||||
SimObjectPtr<SimGroup> mChildGroup;
|
||||
|
|
@ -168,4 +168,4 @@ protected:
|
|||
};
|
||||
|
||||
|
||||
#endif // _PREFAB_H_
|
||||
#endif // _PREFAB_H_
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ U32 Projectile::smProjectileWarpTicks = 5;
|
|||
//
|
||||
ProjectileData::ProjectileData()
|
||||
{
|
||||
projectileShapeName = NULL;
|
||||
INIT_SHAPEASSET(ProjectileShape);
|
||||
|
||||
sound = NULL;
|
||||
|
||||
|
|
@ -197,7 +197,6 @@ ProjectileData::ProjectileData()
|
|||
|
||||
ProjectileData::ProjectileData(const ProjectileData& other, bool temp_clone) : GameBaseData(other, temp_clone)
|
||||
{
|
||||
projectileShapeName = other.projectileShapeName;
|
||||
faceViewer = other.faceViewer; // -- always set to false
|
||||
scale = other.scale;
|
||||
velInheritFactor = other.velInheritFactor;
|
||||
|
|
@ -221,7 +220,7 @@ ProjectileData::ProjectileData(const ProjectileData& other, bool temp_clone) : G
|
|||
sound = other.sound;
|
||||
lightDesc = other.lightDesc;
|
||||
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"
|
||||
maintainSeq = other.maintainSeq; // -- from projectileShape sequence "maintain"
|
||||
particleEmitter = other.particleEmitter;
|
||||
|
|
@ -244,8 +243,11 @@ void ProjectileData::initPersistFields()
|
|||
"as the projectile enters or leaves water.\n\n"
|
||||
"@see particleEmitter\n");
|
||||
|
||||
addField("projectileShapeName", TypeShapeFilename, Offset(projectileShapeName, ProjectileData),
|
||||
"@brief File path to the model of the projectile.\n\n");
|
||||
addProtectedField("projectileShapeName", TypeShapeFilename, Offset(mProjectileShapeName, ProjectileData), &_setProjectileShapeData, &defaultProtectedGetFn,
|
||||
"@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),
|
||||
"@brief Scale to apply to the projectile's size.\n\n"
|
||||
"@note This is applied after SceneObject::scale\n");
|
||||
|
|
@ -375,21 +377,17 @@ bool ProjectileData::preload(bool server, String &errorStr)
|
|||
Con::errorf(ConsoleLogEntry::General, "ProjectileData::preload: Invalid packet, bad datablockid(lightDesc): %d", lightDescId);
|
||||
}
|
||||
|
||||
if (projectileShapeName && projectileShapeName[0] != '\0')
|
||||
if (!mProjectileShape)
|
||||
{
|
||||
projectileShape = ResourceManager::get().load(projectileShapeName);
|
||||
if (bool(projectileShape) == false)
|
||||
{
|
||||
errorStr = String::ToString("ProjectileData::load: Couldn't load shape \"%s\"", projectileShapeName);
|
||||
return false;
|
||||
}
|
||||
activateSeq = projectileShape->findSequence("activate");
|
||||
maintainSeq = projectileShape->findSequence("maintain");
|
||||
errorStr = String::ToString("ProjectileData::load: Couldn't load shape \"%s\"", mProjectileShapeAssetId);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (bool(projectileShape)) // create an instance to preload shape data
|
||||
else
|
||||
{
|
||||
TSShapeInstance* pDummy = new TSShapeInstance(projectileShape, !server);
|
||||
activateSeq = mProjectileShape->findSequence("activate");
|
||||
maintainSeq = mProjectileShape->findSequence("maintain");
|
||||
|
||||
TSShapeInstance* pDummy = new TSShapeInstance(mProjectileShape, !server);
|
||||
delete pDummy;
|
||||
}
|
||||
|
||||
|
|
@ -401,7 +399,8 @@ void ProjectileData::packData(BitStream* stream)
|
|||
{
|
||||
Parent::packData(stream);
|
||||
|
||||
stream->writeString(projectileShapeName);
|
||||
PACKDATA_SHAPEASSET(ProjectileShape);
|
||||
|
||||
stream->writeFlag(faceViewer);
|
||||
if(stream->writeFlag(scale.x != 1 || scale.y != 1 || scale.z != 1))
|
||||
{
|
||||
|
|
@ -465,7 +464,7 @@ void ProjectileData::unpackData(BitStream* stream)
|
|||
{
|
||||
Parent::unpackData(stream);
|
||||
|
||||
projectileShapeName = stream->readSTString();
|
||||
UNPACKDATA_SHAPEASSET(ProjectileShape);
|
||||
|
||||
faceViewer = stream->readFlag();
|
||||
if(stream->readFlag())
|
||||
|
|
@ -786,9 +785,9 @@ bool Projectile::onAdd()
|
|||
}
|
||||
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)
|
||||
{
|
||||
|
|
@ -827,8 +826,8 @@ bool Projectile::onAdd()
|
|||
processAfter(mSourceObject);
|
||||
|
||||
// Setup our bounding box
|
||||
if (bool(mDataBlock->projectileShape) == true)
|
||||
mObjBox = mDataBlock->projectileShape->mBounds;
|
||||
if (bool(mDataBlock->mProjectileShape) == true)
|
||||
mObjBox = mDataBlock->mProjectileShape->mBounds;
|
||||
else
|
||||
mObjBox = Box3F(Point3F(0, 0, 0), Point3F(0, 0, 0));
|
||||
|
||||
|
|
@ -1509,4 +1508,4 @@ DefineEngineMethod(Projectile, presimulate, void, (F32 seconds), (1.0f),
|
|||
"@note This function is not called if the SimObject::hidden is true.")
|
||||
{
|
||||
object->simulate( seconds );
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@
|
|||
#include "lighting/lightInfo.h"
|
||||
#endif
|
||||
|
||||
#include "T3D/assets/ShapeAsset.h"
|
||||
|
||||
class ExplosionData;
|
||||
class SplashData;
|
||||
|
|
@ -69,9 +70,8 @@ protected:
|
|||
bool onAdd();
|
||||
|
||||
public:
|
||||
// variables set in datablock definition:
|
||||
// Shape related
|
||||
const char* projectileShapeName;
|
||||
DECLARE_SHAPEASSET(ProjectileData, ProjectileShape, onShapeChanged);
|
||||
DECLARE_SHAPEASSET_SETGET(ProjectileData, ProjectileShape);
|
||||
|
||||
/// Set to true if it is a billboard and want it to always face the viewer, false otherwise
|
||||
bool faceViewer;
|
||||
|
|
@ -121,7 +121,6 @@ public:
|
|||
S32 lightDescId;
|
||||
|
||||
// variables set on preload:
|
||||
Resource<TSShape> projectileShape;
|
||||
S32 activateSeq;
|
||||
S32 maintainSeq;
|
||||
|
||||
|
|
@ -152,6 +151,8 @@ public:
|
|||
public:
|
||||
ProjectileData(const ProjectileData&, bool = false);
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -721,12 +721,12 @@ void SFXEmitter::_update()
|
|||
mLocalProfile.mResource = NULL;
|
||||
mLocalProfile.mBuffer = NULL;
|
||||
|
||||
if( !mLocalProfile.mFilename.isEmpty() )
|
||||
if( mLocalProfile.mFilename != StringTable->EmptyString() )
|
||||
{
|
||||
mSource = SFX->createSource( &mLocalProfile, &transform, &velocity );
|
||||
if( !mSource )
|
||||
Con::errorf( "SFXEmitter::_update() - failed to create sound for: %s",
|
||||
mLocalProfile.mFilename.c_str() );
|
||||
mLocalProfile.mFilename );
|
||||
|
||||
prevState = mPlayOnAdd ? SFXStatusPlaying : prevState;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -163,7 +163,6 @@ ShapeBaseData::ShapeBaseData()
|
|||
reflectorDesc( NULL ),
|
||||
debris( NULL ),
|
||||
debrisID( 0 ),
|
||||
debrisShapeName( StringTable->EmptyString() ),
|
||||
explosion( NULL ),
|
||||
explosionID( 0 ),
|
||||
underwaterExplosion( NULL ),
|
||||
|
|
@ -198,7 +197,9 @@ ShapeBaseData::ShapeBaseData()
|
|||
renderWhenDestroyed( true ),
|
||||
inheritEnergyFromMount( false )
|
||||
{
|
||||
initShapeAsset(Shape);
|
||||
INIT_SHAPEASSET(Shape);
|
||||
INIT_SHAPEASSET(DebrisShape);
|
||||
|
||||
dMemset( mountPointNode, -1, sizeof( S32 ) * SceneObject::NumMountPoints );
|
||||
remap_txr_tags = NULL;
|
||||
remap_buffer = NULL;
|
||||
|
|
@ -213,14 +214,13 @@ ShapeBaseData::ShapeBaseData(const ShapeBaseData& other, bool temp_clone) : Game
|
|||
shadowProjectionDistance = other.shadowProjectionDistance;
|
||||
shadowSphereAdjust = other.shadowSphereAdjust;
|
||||
cloakTexName = other.cloakTexName;
|
||||
cloneShapeAsset(Shape);
|
||||
CLONE_SHAPEASSET(Shape);
|
||||
cubeDescName = other.cubeDescName;
|
||||
cubeDescId = other.cubeDescId;
|
||||
reflectorDesc = other.reflectorDesc;
|
||||
debris = other.debris;
|
||||
debrisID = other.debrisID; // -- for pack/unpack of debris ptr
|
||||
debrisShapeName = other.debrisShapeName;
|
||||
debrisShape = other.debrisShape; // -- TSShape loaded using debrisShapeName
|
||||
CLONE_SHAPEASSET(DebrisShape);
|
||||
explosion = other.explosion;
|
||||
explosionID = other.explosionID; // -- for pack/unpack of explosion ptr
|
||||
underwaterExplosion = other.underwaterExplosion;
|
||||
|
|
@ -337,67 +337,25 @@ bool ShapeBaseData::preload(bool server, String &errorStr)
|
|||
"ShapeBaseData::preload: invalid debris data");
|
||||
}
|
||||
|
||||
|
||||
if( debrisShapeName && debrisShapeName[0] != '\0' && !bool(debrisShape) )
|
||||
if( bool(mDebrisShape))
|
||||
{
|
||||
debrisShape = ResourceManager::get().load(debrisShapeName);
|
||||
if( bool(debrisShape) == false )
|
||||
{
|
||||
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;
|
||||
}
|
||||
TSShapeInstance* pDummy = new TSShapeInstance(mDebrisShape, !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
|
||||
if (mShapeName != StringTable->EmptyString())
|
||||
S32 i;
|
||||
if (ShapeAsset::getAssetErrCode(mShapeAsset) != ShapeAsset::Failed && ShapeAsset::getAssetErrCode(mShapeAsset) != ShapeAsset::BadFileReference)
|
||||
{
|
||||
mShapeAssetId = ShapeAsset::getAssetIdByFilename(mShapeName);
|
||||
}
|
||||
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;
|
||||
|
||||
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)
|
||||
{
|
||||
errorStr = String::ToString("ShapeBaseData: Couldn't load shape \"%s\"", mShapeName);
|
||||
errorStr = String::ToString("ShapeBaseData: Couldn't load shape asset \"%s\"", mShapeAsset.getAssetId());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -405,7 +363,7 @@ bool ShapeBaseData::preload(bool server, String &errorStr)
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -427,13 +385,13 @@ bool ShapeBaseData::preload(bool server, String &errorStr)
|
|||
if (!mShape->mBounds.isContained(collisionBounds.last()))
|
||||
{
|
||||
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;
|
||||
}
|
||||
else if (collisionBounds.last().isValidBox() == false)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -593,11 +551,7 @@ void ShapeBaseData::initPersistFields()
|
|||
|
||||
addGroup( "Render" );
|
||||
|
||||
addField("shapeAsset", TypeShapeAssetId, Offset(mShapeAssetId, ShapeBaseData),
|
||||
"The source shape asset.");
|
||||
|
||||
addField( "shapeFile", TypeShapeFilename, Offset(mShapeName, ShapeBaseData),
|
||||
"The DTS or DAE model to use for this object." );
|
||||
INITPERSISTFIELD_SHAPEASSET(Shape, ShapeBaseData, "The source shape asset.");
|
||||
|
||||
endGroup( "Render" );
|
||||
|
||||
|
|
@ -611,8 +565,8 @@ void ShapeBaseData::initPersistFields()
|
|||
"%Debris to generate when this shape is blown up." );
|
||||
addField( "renderWhenDestroyed", TypeBool, Offset(renderWhenDestroyed, ShapeBaseData),
|
||||
"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" );
|
||||
|
||||
|
|
@ -800,8 +754,8 @@ void ShapeBaseData::packData(BitStream* stream)
|
|||
stream->write(shadowProjectionDistance);
|
||||
stream->write(shadowSphereAdjust);
|
||||
|
||||
|
||||
packShapeAsset(stream);
|
||||
PACKDATA_SHAPEASSET(Shape);
|
||||
PACKDATA_SHAPEASSET(DebrisShape);
|
||||
|
||||
stream->writeString(cloakTexName);
|
||||
if(stream->writeFlag(mass != gShapeBaseDataProto.mass))
|
||||
|
|
@ -825,7 +779,6 @@ void ShapeBaseData::packData(BitStream* stream)
|
|||
stream->write(cameraMaxFov);
|
||||
stream->writeFlag(cameraCanBank);
|
||||
stream->writeFlag(mountedImagesBank);
|
||||
stream->writeString( debrisShapeName );
|
||||
|
||||
stream->writeFlag(observeThroughObject);
|
||||
|
||||
|
|
@ -879,8 +832,8 @@ void ShapeBaseData::unpackData(BitStream* stream)
|
|||
stream->read(&shadowProjectionDistance);
|
||||
stream->read(&shadowSphereAdjust);
|
||||
|
||||
|
||||
unpackShapeAsset(stream);
|
||||
UNPACKDATA_SHAPEASSET(Shape);
|
||||
UNPACKDATA_SHAPEASSET(DebrisShape);
|
||||
|
||||
cloakTexName = stream->readSTString();
|
||||
if(stream->readFlag())
|
||||
|
|
@ -930,9 +883,6 @@ void ShapeBaseData::unpackData(BitStream* stream)
|
|||
|
||||
cameraCanBank = stream->readFlag();
|
||||
mountedImagesBank = stream->readFlag();
|
||||
|
||||
debrisShapeName = stream->readSTString();
|
||||
|
||||
observeThroughObject = stream->readFlag();
|
||||
|
||||
if( stream->readFlag() )
|
||||
|
|
@ -2011,13 +1961,13 @@ void ShapeBase::blowUp()
|
|||
|
||||
TSShapeInstance *debShape = NULL;
|
||||
|
||||
if( mDataBlock->debrisShape == NULL )
|
||||
if( mDataBlock->mDebrisShape == NULL )
|
||||
{
|
||||
return;
|
||||
}
|
||||
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
|
||||
///< when the script prefix has changed.
|
||||
|
||||
StringTableEntry shapeName; ///< Name of shape to render.
|
||||
StringTableEntry shapeNameFP; ///< Name of shape to render in first person (optional).
|
||||
DECLARE_SHAPEASSET_ARRAY(ShapeBaseImageData, Shape, MaxShapes); ///< Name of shape to render.
|
||||
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
|
||||
/// animation sequences played in 3rd person. [optional]
|
||||
|
|
@ -407,7 +410,6 @@ struct ShapeBaseImageData: public GameBaseData {
|
|||
|
||||
/// @name Shape Data
|
||||
/// @{
|
||||
Resource<TSShape> shape[MaxShapes]; ///< Shape handle
|
||||
bool shapeIsValid[MaxShapes]; ///< Indicates that the shape has been loaded and is valid
|
||||
|
||||
U32 mCRC[MaxShapes]; ///< Checksum of shape.
|
||||
|
|
@ -538,7 +540,8 @@ public:
|
|||
F32 shadowProjectionDistance;
|
||||
F32 shadowSphereAdjust;
|
||||
|
||||
DECLARE_SHAPEASSET(ShapeBaseData, Shape);
|
||||
DECLARE_SHAPEASSET(ShapeBaseData, Shape, onShapeChanged);
|
||||
DECLARE_SHAPEASSET_SETGET(ShapeBaseData, Shape);
|
||||
|
||||
StringTableEntry cloakTexName;
|
||||
|
||||
|
|
@ -552,8 +555,9 @@ public:
|
|||
/// @{
|
||||
DebrisData * debris;
|
||||
S32 debrisID;
|
||||
StringTableEntry debrisShapeName;
|
||||
Resource<TSShape> debrisShape;
|
||||
|
||||
DECLARE_SHAPEASSET(ShapeBaseData, DebrisShape, onDebrisChanged);
|
||||
DECLARE_SHAPEASSET_SETGET(ShapeBaseData, DebrisShape);
|
||||
|
||||
ExplosionData* explosion;
|
||||
S32 explosionID;
|
||||
|
|
@ -598,8 +602,6 @@ public:
|
|||
|
||||
/// @name Data initialized on preload
|
||||
/// @{
|
||||
|
||||
Resource<TSShape> mShape; ///< Shape handle
|
||||
U32 mCRC;
|
||||
bool computeCRC;
|
||||
|
||||
|
|
@ -672,6 +674,9 @@ public:
|
|||
char* remap_buffer;
|
||||
Vector<TextureTagRemapping> txr_tag_remappings;
|
||||
bool silent_bbox_check;
|
||||
|
||||
void onShapeChanged() {}
|
||||
void onDebrisChanged() {}
|
||||
public:
|
||||
ShapeBaseData(const ShapeBaseData&, bool = false);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -191,8 +191,6 @@ ShapeBaseImageData::ShapeBaseImageData()
|
|||
lightRadius = 10.f;
|
||||
lightBrightness = 1.0f;
|
||||
|
||||
shapeName = "core/rendering/shapes/noshape.dts";
|
||||
shapeNameFP = "";
|
||||
imageAnimPrefix = "";
|
||||
imageAnimPrefixFP = "";
|
||||
fireState = -1;
|
||||
|
|
@ -295,6 +293,8 @@ ShapeBaseImageData::ShapeBaseImageData()
|
|||
isAnimated[i] = false;
|
||||
hasFlash[i] = false;
|
||||
shapeIsValid[i] = false;
|
||||
|
||||
INIT_SHAPEASSET_ARRAY(Shape, i);
|
||||
}
|
||||
|
||||
shakeCamera = false;
|
||||
|
|
@ -407,6 +407,7 @@ bool ShapeBaseImageData::preload(bool server, String &errorStr)
|
|||
{
|
||||
if (!Parent::preload(server, errorStr))
|
||||
return false;
|
||||
bool shapeError = false;
|
||||
|
||||
// Resolve objects transmitted from server
|
||||
if (!server) {
|
||||
|
|
@ -434,14 +435,12 @@ bool ShapeBaseImageData::preload(bool server, String &errorStr)
|
|||
// Shape 0: Standard image shape
|
||||
// Shape 1: Optional first person image shape
|
||||
|
||||
StringTableEntry name;
|
||||
if (i == FirstPersonImageShape)
|
||||
{
|
||||
if ((useEyeOffset || useEyeNode) && shapeNameFP && shapeNameFP[0])
|
||||
if ((useEyeOffset || useEyeNode) && !mShapeAsset[i].isNull())
|
||||
{
|
||||
// Make use of the first person shape
|
||||
useFirstPersonShape = true;
|
||||
name = shapeNameFP;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -449,27 +448,25 @@ bool ShapeBaseImageData::preload(bool server, String &errorStr)
|
|||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
name = shapeName;
|
||||
}
|
||||
|
||||
if (name && name[0]) {
|
||||
if (!mShapeAsset[i].isNull())
|
||||
{
|
||||
// Resolve shapename
|
||||
shape[i] = ResourceManager::get().load(name);
|
||||
if (!bool(shape[i])) {
|
||||
errorStr = String::ToString("Unable to load shape: %s", name);
|
||||
mShape[i] = mShapeAsset[i]->getShapeResource();
|
||||
|
||||
if (!bool(mShape[i])) {
|
||||
errorStr = String::ToString("Unable to load shape asset: %s", mShapeAsset[i]->getAssetId());
|
||||
return false;
|
||||
}
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -479,29 +476,29 @@ bool ShapeBaseImageData::preload(bool server, String &errorStr)
|
|||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve nodes & build mount transform
|
||||
eyeMountNode[i] = shape[i]->findNode("eyeMount");
|
||||
eyeNode[i] = shape[i]->findNode("eye");
|
||||
eyeMountNode[i] = mShape[i]->findNode("eyeMount");
|
||||
eyeNode[i] = mShape[i]->findNode("eye");
|
||||
if (eyeNode[i] == -1)
|
||||
eyeNode[i] = eyeMountNode[i];
|
||||
ejectNode[i] = shape[i]->findNode("ejectPoint");
|
||||
muzzleNode[i] = shape[i]->findNode("muzzlePoint");
|
||||
retractNode[i] = shape[i]->findNode("retractionPoint");
|
||||
ejectNode[i] = mShape[i]->findNode("ejectPoint");
|
||||
muzzleNode[i] = mShape[i]->findNode("muzzlePoint");
|
||||
retractNode[i] = mShape[i]->findNode("retractionPoint");
|
||||
mountTransform[i] = mountOffset;
|
||||
S32 node = shape[i]->findNode("mountPoint");
|
||||
S32 node = mShape[i]->findNode("mountPoint");
|
||||
if (node != -1) {
|
||||
MatrixF total(1);
|
||||
do {
|
||||
MatrixF nmat;
|
||||
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);
|
||||
node = shape[i]->nodes[node].parentIndex;
|
||||
node = mShape[i]->nodes[node].parentIndex;
|
||||
}
|
||||
while(node != -1);
|
||||
total.inverse();
|
||||
|
|
@ -514,7 +511,7 @@ bool ShapeBaseImageData::preload(bool server, String &errorStr)
|
|||
for (U32 j = 0; j < MaxStates; j++) {
|
||||
StateData& s = state[j];
|
||||
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)
|
||||
{
|
||||
// This state has an animation sequence
|
||||
|
|
@ -525,7 +522,7 @@ bool ShapeBaseImageData::preload(bool server, String &errorStr)
|
|||
char bufferVis[128];
|
||||
dStrncpy(bufferVis, stateSequence[j], 100);
|
||||
dStrcat(bufferVis, "_vis", 128);
|
||||
s.sequenceVis[i] = shape[i]->findSequence(bufferVis);
|
||||
s.sequenceVis[i] = mShape[i]->findSequence(bufferVis);
|
||||
}
|
||||
if (s.sequenceVis[i] != -1)
|
||||
{
|
||||
|
|
@ -537,13 +534,13 @@ bool ShapeBaseImageData::preload(bool server, String &errorStr)
|
|||
s.ignoreLoadedForReady = stateIgnoreLoadedForReady[j];
|
||||
|
||||
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)
|
||||
s.emitterNode[i] = muzzleNode[i];
|
||||
}
|
||||
|
||||
ambientSequence[i] = shape[i]->findSequence("ambient");
|
||||
spinSequence[i] = shape[i]->findSequence("spin");
|
||||
ambientSequence[i] = mShape[i]->findSequence("ambient");
|
||||
spinSequence[i] = mShape[i]->findSequence("spin");
|
||||
|
||||
shapeIsValid[i] = true;
|
||||
}
|
||||
|
|
@ -567,7 +564,7 @@ bool ShapeBaseImageData::preload(bool server, String &errorStr)
|
|||
{
|
||||
if( shapeIsValid[i] )
|
||||
{
|
||||
TSShapeInstance* pDummy = new TSShapeInstance(shape[i], !server);
|
||||
TSShapeInstance* pDummy = new TSShapeInstance(mShape[i], !server);
|
||||
delete pDummy;
|
||||
}
|
||||
}
|
||||
|
|
@ -590,19 +587,9 @@ void ShapeBaseImageData::initPersistFields()
|
|||
addField( "emap", TypeBool, Offset(emap, ShapeBaseImageData),
|
||||
"@brief Whether to enable environment mapping on this Image.\n\n" );
|
||||
|
||||
addField( "shapeFile", TypeShapeFilename, Offset(shapeName, ShapeBaseImageData),
|
||||
"@brief The DTS or DAE model to use for this Image.\n\n" );
|
||||
INITPERSISTFIELD_SHAPEASSET_ARRAY(Shape, ShapeBaseImageData, "The shape asset to use for this image in the third person")
|
||||
|
||||
addField( "shapeFileFP", TypeShapeFilename, Offset(shapeNameFP, ShapeBaseImageData),
|
||||
"@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");
|
||||
addProtectedField("shapeFileFP", TypeShapeFilename, Offset(mShapeName[1], ShapeBaseImageData), _setShapeData, defaultProtectedGetFn, "deprecated alias for ShapeFPFile/Asset", AbstractClassRep::FIELD_HideInInspectors);
|
||||
|
||||
addField( "imageAnimPrefix", TypeCaseString, Offset(imageAnimPrefix, ShapeBaseImageData),
|
||||
"@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
|
||||
stream->writeString(shapeNameFP); // shape 1 for first person use (optional)
|
||||
for (U32 j = 0; j < MaxShapes; ++j)
|
||||
{
|
||||
PACKDATA_SHAPEASSET_ARRAY(Shape, j); // shape 0 for normal use, shape 1 for first person use (optional)
|
||||
}
|
||||
|
||||
stream->writeString(imageAnimPrefix);
|
||||
stream->writeString(imageAnimPrefixFP);
|
||||
|
|
@ -1169,8 +1158,10 @@ void ShapeBaseImageData::unpackData(BitStream* stream)
|
|||
}
|
||||
}
|
||||
|
||||
shapeName = stream->readSTString(); // shape 0 for normal use
|
||||
shapeNameFP = stream->readSTString(); // shape 1 for first person use (optional)
|
||||
for (U32 j = 0; j < MaxShapes; ++j)
|
||||
{
|
||||
UNPACKDATA_SHAPEASSET_ARRAY(Shape, j); // shape 0 for normal use, shape 1 for first person use (optional)
|
||||
}
|
||||
|
||||
imageAnimPrefix = stream->readSTString();
|
||||
imageAnimPrefixFP = stream->readSTString();
|
||||
|
|
@ -2128,7 +2119,7 @@ S32 ShapeBase::getNodeIndex(U32 imageSlot,StringTableEntry nodeName)
|
|||
{
|
||||
MountedImage& image = mMountedImageList[imageSlot];
|
||||
if (image.dataBlock)
|
||||
return image.dataBlock->shape[getImageShapeIndex(image)]->findNode(nodeName);
|
||||
return image.dataBlock->mShape[getImageShapeIndex(image)]->findNode(nodeName);
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -2318,7 +2309,7 @@ void ShapeBase::setImage( U32 imageSlot,
|
|||
for (U32 i=0; i<ShapeBaseImageData::MaxShapes; ++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())
|
||||
|
|
|
|||
|
|
@ -114,7 +114,6 @@ TSStatic::TSStatic()
|
|||
|
||||
mTypeMask |= StaticObjectType | StaticShapeObjectType;
|
||||
|
||||
mShapeName = "";
|
||||
mShapeInstance = NULL;
|
||||
|
||||
mPlayAmbient = true;
|
||||
|
|
@ -150,8 +149,7 @@ TSStatic::TSStatic()
|
|||
mAnimOffset = 0.0f;
|
||||
mAnimSpeed = 1.0f;
|
||||
|
||||
mShapeAsset = StringTable->EmptyString();
|
||||
mShapeAssetId = StringTable->EmptyString();
|
||||
INIT_SHAPEASSET(Shape);
|
||||
}
|
||||
|
||||
TSStatic::~TSStatic()
|
||||
|
|
@ -184,13 +182,11 @@ void TSStatic::initPersistFields()
|
|||
"Percent Animation Speed.");
|
||||
addGroup("Shape");
|
||||
|
||||
addProtectedField("shapeAsset", TypeShapeAssetId, Offset(mShapeAssetId, TSStatic),
|
||||
&TSStatic::_setShapeAsset, &defaultProtectedGetFn,
|
||||
"The source shape asset.");
|
||||
INITPERSISTFIELD_SHAPEASSET(Shape, TSStatic, "Model to use for this TSStatic");
|
||||
|
||||
addProtectedField("shapeName", TypeShapeFilename, Offset(mShapeName, TSStatic),
|
||||
&TSStatic::_setShapeName, &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.");
|
||||
&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.", AbstractClassRep::FIELD_HideInInspectors);
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
TSStatic* ts = static_cast<TSStatic*>(object);
|
||||
|
|
@ -425,34 +377,6 @@ bool TSStatic::onAdd()
|
|||
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()
|
||||
{
|
||||
// Cleanup before we create.
|
||||
|
|
@ -674,9 +598,6 @@ void TSStatic::onRemove()
|
|||
if (isClientObject())
|
||||
mCubeReflector.unregisterReflector();
|
||||
|
||||
if(!mShapeAsset.isNull())
|
||||
mShapeAsset->getChangedSignal().remove(this, &TSStatic::_onAssetChanged);
|
||||
|
||||
Parent::onRemove();
|
||||
}
|
||||
|
||||
|
|
@ -689,7 +610,7 @@ void TSStatic::_onResourceChanged(const Torque::Path& path)
|
|||
_updateShouldTick();
|
||||
}
|
||||
|
||||
void TSStatic::_onAssetChanged()
|
||||
void TSStatic::onShapeChanged()
|
||||
{
|
||||
_createShape();
|
||||
_updateShouldTick();
|
||||
|
|
@ -1037,8 +958,7 @@ U32 TSStatic::packUpdate(NetConnection* con, U32 mask, BitStream* stream)
|
|||
|
||||
if (stream->writeFlag(mask & AdvancedStaticOptionsMask))
|
||||
{
|
||||
stream->writeString(mShapeAsset.getAssetId());
|
||||
stream->writeString(mShapeName);
|
||||
PACK_SHAPEASSET(con, Shape);
|
||||
|
||||
stream->write((U32)mDecalType);
|
||||
|
||||
|
|
@ -1153,11 +1073,7 @@ void TSStatic::unpackUpdate(NetConnection* con, BitStream* stream)
|
|||
|
||||
if (stream->readFlag()) // AdvancedStaticOptionsMask
|
||||
{
|
||||
char buffer[256];
|
||||
stream->readString(buffer);
|
||||
setShapeAsset(StringTable->insert(buffer));
|
||||
|
||||
mShapeName = stream->readSTString();
|
||||
UNPACK_SHAPEASSET(con, Shape);
|
||||
|
||||
stream->read((U32*)&mDecalType);
|
||||
|
||||
|
|
@ -1676,7 +1592,7 @@ void TSStatic::updateMaterials()
|
|||
|
||||
String path;
|
||||
if (mShapeAsset->isAssetValid())
|
||||
path = mShapeAsset->getShapeFilename();
|
||||
path = mShapeAsset->getShapeFileName();
|
||||
else
|
||||
path = mShapeName;
|
||||
|
||||
|
|
@ -1709,9 +1625,8 @@ void TSStatic::updateMaterials()
|
|||
|
||||
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());
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
|
@ -1874,7 +1789,7 @@ DefineEngineMethod(TSStatic, changeMaterial, void, (const char* mapTo, Material*
|
|||
return;
|
||||
}
|
||||
|
||||
TSMaterialList* shapeMaterialList = object->getShape()->materialList;
|
||||
TSMaterialList* shapeMaterialList = object->getShapeResource()->materialList;
|
||||
|
||||
// Check the mapTo name exists for this shape
|
||||
S32 matIndex = shapeMaterialList->getMaterialNameList().find_next(String(mapTo));
|
||||
|
|
@ -1914,7 +1829,7 @@ DefineEngineMethod(TSStatic, getModelFile, const char*, (), ,
|
|||
"@endtsexample\n"
|
||||
)
|
||||
{
|
||||
return object->getShapeFileName();
|
||||
return object->getShape();
|
||||
}
|
||||
|
||||
void TSStatic::set_special_typing()
|
||||
|
|
|
|||
|
|
@ -163,8 +163,6 @@ protected:
|
|||
bool buildExportPolyList(ColladaUtils::ExportData* exportData, const Box3F& box, const SphereF&);
|
||||
void buildConvex(const Box3F& box, Convex* convex);
|
||||
|
||||
bool setShapeAsset(const StringTableEntry shapeAssetId);
|
||||
|
||||
bool _createShape();
|
||||
|
||||
void _updatePhysics();
|
||||
|
|
@ -172,7 +170,7 @@ protected:
|
|||
void _renderNormals(ObjectRenderInst* ri, SceneRenderState* state, BaseMatInstance* overrideMat);
|
||||
|
||||
void _onResourceChanged(const Torque::Path& path);
|
||||
void _onAssetChanged();
|
||||
void onShapeChanged();
|
||||
|
||||
// ProcessObject
|
||||
virtual void processTick(const Move* move);
|
||||
|
|
@ -193,16 +191,14 @@ protected:
|
|||
|
||||
Convex* mConvexList;
|
||||
|
||||
StringTableEntry mShapeName;
|
||||
DECLARE_SHAPEASSET(TSStatic, Shape, onShapeChanged);
|
||||
DECLARE_SHAPEASSET_NET_SETGET(TSStatic, Shape, AdvancedStaticOptionsMask);
|
||||
|
||||
U32 mShapeHash;
|
||||
Resource<TSShape> mShape;
|
||||
Vector<S32> mCollisionDetails;
|
||||
Vector<S32> mLOSDetails;
|
||||
TSShapeInstance* mShapeInstance;
|
||||
|
||||
AssetPtr<ShapeAsset> mShapeAsset;
|
||||
StringTableEntry mShapeAssetId;
|
||||
|
||||
NetStringHandle mSkinNameHandle;
|
||||
String mAppliedSkinName;
|
||||
|
||||
|
|
@ -242,8 +238,6 @@ public:
|
|||
DECLARE_CONOBJECT(TSStatic);
|
||||
static void initPersistFields();
|
||||
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 const char* _getFieldSkin(void* object, const char* data);
|
||||
|
||||
|
|
@ -268,10 +262,6 @@ public:
|
|||
|
||||
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; }
|
||||
|
||||
U32 getNumDetails();
|
||||
|
|
|
|||
|
|
@ -208,7 +208,7 @@ bool VehicleData::preload(bool server, String &errorStr)
|
|||
if (!collisionDetails.size() || collisionDetails[0] == -1)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -75,8 +75,8 @@ ConsoleDocClass( WheeledVehicleTire,
|
|||
|
||||
WheeledVehicleTire::WheeledVehicleTire()
|
||||
{
|
||||
shape = 0;
|
||||
shapeName = "";
|
||||
INIT_SHAPEASSET(Shape);
|
||||
|
||||
staticFriction = 1;
|
||||
kineticFriction = 0.5f;
|
||||
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
|
||||
// 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.
|
||||
// The tire should be built with it's hub axis along the
|
||||
// object's Y axis.
|
||||
radius = shape->mBounds.len_z() / 2;
|
||||
radius = mShape->mBounds.len_z() / 2;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -116,8 +112,8 @@ bool WheeledVehicleTire::preload(bool server, String &errorStr)
|
|||
|
||||
void WheeledVehicleTire::initPersistFields()
|
||||
{
|
||||
addField( "shapeFile",TypeShapeFilename,Offset(shapeName,WheeledVehicleTire),
|
||||
"The path to the shape to use for the wheel." );
|
||||
INITPERSISTFIELD_SHAPEASSET(Shape, WheeledVehicleTire, "The shape to use for the wheel.");
|
||||
|
||||
addField( "mass", TypeF32, Offset(mass, WheeledVehicleTire),
|
||||
"The mass of the wheel.\nCurrently unused." );
|
||||
addField( "radius", TypeF32, Offset(radius, WheeledVehicleTire),
|
||||
|
|
@ -181,7 +177,8 @@ void WheeledVehicleTire::packData(BitStream* stream)
|
|||
{
|
||||
Parent::packData(stream);
|
||||
|
||||
stream->writeString(shapeName);
|
||||
PACKDATA_SHAPEASSET(Shape);
|
||||
|
||||
stream->write(mass);
|
||||
stream->write(staticFriction);
|
||||
stream->write(kineticFriction);
|
||||
|
|
@ -199,7 +196,8 @@ void WheeledVehicleTire::unpackData(BitStream* stream)
|
|||
{
|
||||
Parent::unpackData(stream);
|
||||
|
||||
shapeName = stream->readSTString();
|
||||
UNPACKDATA_SHAPEASSET(Shape);
|
||||
|
||||
stream->read(&mass);
|
||||
stream->read(&staticFriction);
|
||||
stream->read(&kineticFriction);
|
||||
|
|
@ -1542,8 +1540,8 @@ void WheeledVehicle::unpackUpdate(NetConnection *con, BitStream *stream)
|
|||
|
||||
// Create an instance of the tire for rendering
|
||||
delete wheel->shapeInstance;
|
||||
wheel->shapeInstance = (wheel->tire->shape == NULL) ? 0:
|
||||
new TSShapeInstance(wheel->tire->shape);
|
||||
wheel->shapeInstance = (wheel->tire->mShape == NULL) ? 0:
|
||||
new TSShapeInstance(wheel->tire->mShape);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,8 @@
|
|||
#include "collision/clippedPolyList.h"
|
||||
#endif
|
||||
|
||||
#include "T3D/assets/ShapeAsset.h"
|
||||
|
||||
class ParticleEmitter;
|
||||
class ParticleEmitterData;
|
||||
|
||||
|
|
@ -41,8 +43,8 @@ struct WheeledVehicleTire: public SimDataBlock
|
|||
{
|
||||
typedef SimDataBlock Parent;
|
||||
|
||||
//
|
||||
StringTableEntry shapeName;// Max shape to render
|
||||
DECLARE_SHAPEASSET(WheeledVehicleTire, Shape, onShapeChanged);
|
||||
DECLARE_SHAPEASSET_SETGET(WheeledVehicleTire, Shape);
|
||||
|
||||
// Physical properties
|
||||
F32 mass; // Mass of the whole wheel
|
||||
|
|
@ -62,7 +64,6 @@ struct WheeledVehicleTire: public SimDataBlock
|
|||
F32 longitudinalRelaxation;
|
||||
|
||||
// Shape information initialized in the preload
|
||||
Resource<TSShape> shape; // The loaded shape
|
||||
F32 radius; // Tire radius
|
||||
|
||||
//
|
||||
|
|
@ -72,6 +73,8 @@ struct WheeledVehicleTire: public SimDataBlock
|
|||
bool preload(bool, String &errorStr);
|
||||
virtual void packData(BitStream* stream);
|
||||
virtual void unpackData(BitStream* stream);
|
||||
|
||||
void onShapeChanged() {}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ public:
|
|||
virtual U32 packUpdate(NetConnection*, U32, 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; }
|
||||
|
||||
DECLARE_CONOBJECT(afxStaticShape);
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ void afxParticlePool::pool_renderObject_Normal(RenderPassManager *renderManager,
|
|||
if (main_emitter_data->textureHandle)
|
||||
ri->diffuseTex = &*(main_emitter_data->textureHandle);
|
||||
else
|
||||
ri->diffuseTex = &*(main_emitter_data->particleDataBlocks[0]->textureHandle);
|
||||
ri->diffuseTex = &*(main_emitter_data->particleDataBlocks[0]->getTextureResource());
|
||||
|
||||
ri->softnessDistance = main_emitter_data->softnessDistance;
|
||||
|
||||
|
|
@ -277,7 +277,7 @@ void afxParticlePool::pool_renderObject_TwoPass(RenderPassManager *renderManager
|
|||
//if (main_emitter_data->textureHandle)
|
||||
// ri->diffuseTex = &*(main_emitter_data->textureHandle);
|
||||
//else
|
||||
ri->diffuseTex = &*(main_emitter_data->particleDataBlocks[0]->textureExtHandle);
|
||||
ri->diffuseTex = &*(main_emitter_data->particleDataBlocks[0]->getTextureExtResource());
|
||||
|
||||
F32 save_sort_dist = ri->sortDistSq;
|
||||
|
||||
|
|
@ -481,7 +481,7 @@ void afxParticlePool::pool_renderObject_TwoPass(RenderPassManager *renderManager
|
|||
if (main_emitter_data->textureHandle)
|
||||
ri->diffuseTex = &*(main_emitter_data->textureHandle);
|
||||
else
|
||||
ri->diffuseTex = &*(main_emitter_data->particleDataBlocks[0]->textureHandle);
|
||||
ri->diffuseTex = &*(main_emitter_data->particleDataBlocks[0]->getTextureResource());
|
||||
|
||||
ri->softnessDistance = main_emitter_data->softnessDistance;
|
||||
|
||||
|
|
|
|||
|
|
@ -315,6 +315,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)
|
||||
{
|
||||
SimFieldDictionary* fieldDictionary = getFieldDictionary();
|
||||
|
|
@ -340,7 +366,7 @@ void AssetBase::addAssetDependencyField(const char* pFieldName, const char* pAss
|
|||
dSprintf(depSlotName, sizeof(depSlotName), "%s%d", pFieldName, existingFieldCount);
|
||||
|
||||
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));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ protected:
|
|||
bool mAssetInitialized;
|
||||
AssetDefinition* mpAssetDefinition;
|
||||
U32 mAcquireReferenceCount;
|
||||
U32 mLoadedState;
|
||||
|
||||
public:
|
||||
enum AssetErrCode
|
||||
|
|
@ -87,7 +88,7 @@ public:
|
|||
if (errCode > AssetErrCode::Extended) return "undefined error";
|
||||
return mErrCodeStrings[errCode];
|
||||
};
|
||||
|
||||
U32 getStatus() { return mLoadedState; };
|
||||
AssetBase();
|
||||
virtual ~AssetBase();
|
||||
|
||||
|
|
@ -124,6 +125,7 @@ public:
|
|||
void refreshAsset(void);
|
||||
|
||||
S32 getAssetDependencyFieldCount(const char* pFieldName);
|
||||
StringTableEntry getAssetDependencyField(const char* pFieldName, S32 index = 0);
|
||||
void clearAssetDependencyFields(const char* pFieldName);
|
||||
void addAssetDependencyField(const char* pFieldName, const char* pAssetId);
|
||||
|
||||
|
|
@ -167,5 +169,10 @@ private:
|
|||
void setOwned(AssetManager* pAssetManager, AssetDefinition* pAssetDefinition);
|
||||
};
|
||||
|
||||
//helper macro for stitching string and non string values togeather sans quotes
|
||||
#define assetText(x,suff) std::string(std::string(#x) + std::string(#suff)).c_str()
|
||||
#define macroText(x) std::string(std::string(#x)).c_str()
|
||||
#define assetDoc(x,suff) std::string(std::string("@brief") + std::string(#x) + std::string(#suff)).c_str()
|
||||
|
||||
#endif // _ASSET_BASE_H_
|
||||
|
||||
|
|
|
|||
|
|
@ -50,6 +50,15 @@ DefineEngineMethod(AssetBase, getAssetDependencyFieldCount, S32, (const char* pF
|
|||
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), (""),
|
||||
"Clears any asset dependency fields matching the name provided.\n"
|
||||
"@param fieldName The name of the fields to be cleared")
|
||||
|
|
@ -71,3 +80,15 @@ DefineEngineMethod(AssetBase, saveAsset, bool, (), ,
|
|||
{
|
||||
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());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2801,3 +2801,11 @@ DefineEngineFunction( getMaxDynamicVerts, S32, (),,
|
|||
{
|
||||
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
|
||||
//-----------------------------------------------------------------------------
|
||||
ConsolePrepType( filename, TypeStringFilename, String )
|
||||
ConsolePrepType( filename, TypeStringFilename, const char* )
|
||||
|
||||
ConsoleSetType( TypeStringFilename )
|
||||
{
|
||||
|
|
@ -177,7 +177,7 @@ ConsoleSetType( TypeStringFilename )
|
|||
return;
|
||||
}
|
||||
|
||||
*((String*)dptr) = String(buffer);
|
||||
*((const char**)dptr) = StringTable->insert(buffer);
|
||||
}
|
||||
else
|
||||
Con::printf("(TypeStringFilename) Cannot set multiple args to a single filename.");
|
||||
|
|
@ -185,7 +185,7 @@ ConsoleSetType( TypeStringFilename )
|
|||
|
||||
ConsoleGetType( TypeStringFilename )
|
||||
{
|
||||
return *((String*)dptr);
|
||||
return *((const char**)(dptr));
|
||||
}
|
||||
|
||||
ConsoleProcessData( TypeStringFilename )
|
||||
|
|
@ -204,7 +204,7 @@ ConsoleProcessData( TypeStringFilename )
|
|||
//-----------------------------------------------------------------------------
|
||||
// TypePrefabFilename
|
||||
//-----------------------------------------------------------------------------
|
||||
ConsolePrepType( filename, TypePrefabFilename, String )
|
||||
ConsolePrepType( filename, TypePrefabFilename, const char* )
|
||||
|
||||
ConsoleSetType( TypePrefabFilename )
|
||||
{
|
||||
|
|
@ -213,7 +213,7 @@ ConsoleSetType( TypePrefabFilename )
|
|||
|
||||
ConsoleGetType( TypePrefabFilename )
|
||||
{
|
||||
return *((String*)dptr);
|
||||
return *((const char**)(dptr));
|
||||
}
|
||||
|
||||
ConsoleProcessData( TypePrefabFilename )
|
||||
|
|
@ -232,16 +232,16 @@ ConsoleProcessData( TypePrefabFilename )
|
|||
//-----------------------------------------------------------------------------
|
||||
// TypeImageFilename
|
||||
//-----------------------------------------------------------------------------
|
||||
ConsolePrepType( filename, TypeImageFilename, String )
|
||||
ConsolePrepType( filename, TypeImageFilename, const char* )
|
||||
|
||||
ConsoleSetType( TypeImageFilename )
|
||||
{
|
||||
Con::setData(TypeStringFilename, dptr, 0, argc, argv, tbl, flag);
|
||||
Con::setData(TypeFilename, dptr, 0, argc, argv, tbl, flag);
|
||||
}
|
||||
|
||||
ConsoleGetType( TypeImageFilename )
|
||||
{
|
||||
return *((String*)dptr);
|
||||
return *((const char**)(dptr));
|
||||
}
|
||||
|
||||
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
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -797,20 +824,17 @@ ConsoleSetType( TypeParticleParameterString )
|
|||
// TypeMaterialName
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
ConsoleType(string, TypeMaterialName, String, "")
|
||||
ConsoleType(string, TypeMaterialName, const char*, "")
|
||||
|
||||
ConsoleGetType( TypeMaterialName )
|
||||
{
|
||||
const String *theString = static_cast<const String*>(dptr);
|
||||
return theString->c_str();
|
||||
return* ((const char**)(dptr));
|
||||
}
|
||||
|
||||
ConsoleSetType( TypeMaterialName )
|
||||
{
|
||||
String *theString = static_cast<String*>(dptr);
|
||||
|
||||
if(argc == 1)
|
||||
*theString = argv[0];
|
||||
*((const char**)dptr) = StringTable->insert(argv[0]);
|
||||
else
|
||||
Con::printf("(TypeMaterialName) Cannot set multiple args to a single string.");
|
||||
}
|
||||
|
|
@ -860,20 +884,17 @@ ConsoleSetType( TypeTerrainMaterialName )
|
|||
// TypeCubemapName
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
ConsoleType(string, TypeCubemapName, String, "")
|
||||
ConsoleType(string, TypeCubemapName, const char*, "")
|
||||
|
||||
ConsoleGetType( TypeCubemapName )
|
||||
{
|
||||
const String *theString = static_cast<const String*>(dptr);
|
||||
return theString->c_str();
|
||||
return*((const char**)(dptr));
|
||||
}
|
||||
|
||||
ConsoleSetType( TypeCubemapName )
|
||||
{
|
||||
String *theString = static_cast<String*>(dptr);
|
||||
|
||||
if(argc == 1)
|
||||
*theString = argv[0];
|
||||
*((const char**)dptr) = StringTable->insert(argv[0]);
|
||||
else
|
||||
Con::printf("(TypeCubemapName) Cannot set multiple args to a single string.");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ DefineConsoleType( TypeCaseString, const char * )
|
|||
DefineConsoleType( TypeRealString, String )
|
||||
DefineConsoleType( TypeCommand, String )
|
||||
DefineConsoleType( TypeFilename, const char * )
|
||||
DefineConsoleType( TypeStringFilename, String )
|
||||
DefineConsoleType( TypeStringFilename, const char*)
|
||||
|
||||
DefineConsoleType(TypeRotationF, RotationF)
|
||||
|
||||
|
|
@ -87,22 +87,27 @@ DefineUnmappedConsoleType( TypePID, SimPersistID* );
|
|||
/// TypeImageFilename is equivalent to TypeStringFilename in its usage,
|
||||
/// it exists for the benefit of GuiInspector, which will provide a custom
|
||||
/// 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,
|
||||
/// it exists for the benefit of GuiInspector, which will provide a
|
||||
/// custom InspectorField for this type.
|
||||
DefineConsoleType( TypePrefabFilename, String )
|
||||
DefineConsoleType( TypePrefabFilename, const char*)
|
||||
|
||||
/// TypeShapeFilename is equivalent to TypeStringFilename in its usage,
|
||||
/// it exists for the benefit of GuiInspector, which will provide a
|
||||
/// 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,
|
||||
/// it exists for the benefit of GuiInspector, which will provide a
|
||||
/// custom InspectorField for this type.
|
||||
DefineConsoleType( TypeMaterialName, String )
|
||||
DefineConsoleType( TypeMaterialName, const char*)
|
||||
|
||||
/// TypeTerrainMaterialIndex is equivalent to TypeS32 in its usage,
|
||||
/// 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,
|
||||
/// but the Inspector will provide a drop-down list of CubemapData objects.
|
||||
DefineConsoleType( TypeCubemapName, String )
|
||||
DefineConsoleType( TypeCubemapName, const char*)
|
||||
|
||||
DefineConsoleType( TypeParticleParameterString, const char * )
|
||||
|
||||
|
|
|
|||
|
|
@ -1254,17 +1254,7 @@ PersistenceManager::ParsedObject* PersistenceManager::writeNewObject(SimObject*
|
|||
dynamic_cast<TSShapeConstructor*>(object))
|
||||
dclToken = "singleton";
|
||||
else if( dynamic_cast< SimDataBlock* >( object ) )
|
||||
{
|
||||
SimDataBlock* db = static_cast<SimDataBlock*>(object);
|
||||
|
||||
if( db->isClientOnly() )
|
||||
{
|
||||
if( db->getName() && db->getName()[ 0 ] )
|
||||
dclToken = "singleton";
|
||||
}
|
||||
else
|
||||
dclToken = "datablock";
|
||||
}
|
||||
dclToken = "datablock";
|
||||
|
||||
char newLine[ 4096 ];
|
||||
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.
|
||||
// Detect and collapse relative path information
|
||||
if (f->type == TypeFilename ||
|
||||
f->type == TypeStringFilename ||
|
||||
f->type == TypeImageFilename ||
|
||||
f->type == TypePrefabFilename ||
|
||||
f->type == TypeShapeFilename)
|
||||
if (f->type == TypeFilename ||
|
||||
f->type == TypeStringFilename ||
|
||||
f->type == TypeImageFilename ||
|
||||
f->type == TypePrefabFilename ||
|
||||
f->type == TypeShapeFilename ||
|
||||
f->type == TypeSoundFilename )
|
||||
{
|
||||
char fnBuf[1024];
|
||||
Con::collapseScriptFilename(fnBuf, 1024, value);
|
||||
|
||||
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
|
||||
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.
|
||||
// Detect and collapse relative path information
|
||||
if (f->type == TypeFilename ||
|
||||
if (f->type == TypeFilename ||
|
||||
f->type == TypeStringFilename ||
|
||||
f->type == TypeImageFilename ||
|
||||
f->type == TypeImageFilename ||
|
||||
f->type == TypePrefabFilename ||
|
||||
f->type == TypeShapeFilename)
|
||||
f->type == TypeShapeFilename ||
|
||||
f->type == TypeSoundFilename )
|
||||
{
|
||||
char fnBuf[1024];
|
||||
Con::collapseScriptFilename(fnBuf, 1024, value);
|
||||
|
||||
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
|
||||
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
|
||||
char fnBuf[1024];
|
||||
if (f->type == TypeFilename ||
|
||||
if (f->type == TypeFilename ||
|
||||
f->type == TypeStringFilename ||
|
||||
f->type == TypeImageFilename ||
|
||||
f->type == TypeImageFilename ||
|
||||
f->type == TypePrefabFilename ||
|
||||
f->type == TypeShapeFilename)
|
||||
f->type == TypeShapeFilename ||
|
||||
f->type == TypeSoundFilename )
|
||||
{
|
||||
Con::collapseScriptFilename(fnBuf, 1024, val);
|
||||
val = fnBuf;
|
||||
|
|
@ -919,7 +920,15 @@ void SimObject::assignFieldsFrom(SimObject *parent)
|
|||
dMemset( bufferSecure, 0, 2048 );
|
||||
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);
|
||||
|
||||
if (f->networkMask != 0)
|
||||
|
|
|
|||
|
|
@ -124,7 +124,6 @@ VolumetricFog::VolumetricFog()
|
|||
mLightRayMod = 1.0f;
|
||||
mOldLightRayStrength = 0.1f;
|
||||
|
||||
mShapeName = "";
|
||||
mShapeLoaded = false;
|
||||
mMinDisplaySize = 10.0f;
|
||||
mFadeSize = 0.0f;
|
||||
|
|
@ -132,15 +131,14 @@ VolumetricFog::VolumetricFog()
|
|||
mNumDetailLevels = 0;
|
||||
det_size.clear();
|
||||
|
||||
mTextureName = "";
|
||||
mIsTextured = false;
|
||||
mStrength = 0.5f;
|
||||
mTexTiles = 1.0f;
|
||||
mSpeed1.set(0.5f, 0.0f);
|
||||
mSpeed2.set(0.1f, 0.1f);
|
||||
|
||||
mShapeAsset = StringTable->EmptyString();
|
||||
mShapeAssetId = StringTable->EmptyString();
|
||||
INIT_SHAPEASSET(Shape);
|
||||
INIT_IMAGEASSET(Texture);
|
||||
}
|
||||
|
||||
VolumetricFog::~VolumetricFog()
|
||||
|
|
@ -168,11 +166,8 @@ VolumetricFog::~VolumetricFog()
|
|||
void VolumetricFog::initPersistFields()
|
||||
{
|
||||
addGroup("VolumetricFogData");
|
||||
addProtectedField("shapeAsset", TypeShapeAssetPtr, Offset(mShapeAsset, VolumetricFog),
|
||||
&VolumetricFog::_setShapeAsset, &defaultProtectedGetFn, "The source shape asset.");
|
||||
|
||||
addField("shapeName", TypeShapeFilename, Offset(mShapeName, VolumetricFog),
|
||||
"Path and filename of the model file (.DTS, .DAE) to use for this Volume.", AbstractClassRep::FieldFlags::FIELD_HideInInspectors );
|
||||
INITPERSISTFIELD_SHAPEASSET(Shape, VolumetricFog, "The source shape asset.");
|
||||
|
||||
addField("FogColor", TypeColorI, Offset(mFogColor, VolumetricFog),
|
||||
"Fog color RGBA (Alpha is ignored)");
|
||||
|
|
@ -187,8 +182,8 @@ void VolumetricFog::initPersistFields()
|
|||
endGroup("VolumetricFogData");
|
||||
|
||||
addGroup("VolumetricFogModulation");
|
||||
addField("texture", TypeImageFilename, Offset(mTextureName, VolumetricFog),
|
||||
"A texture which contains Fogdensity modulator in the red channel and color with 1-green channel. No texture disables modulation.");
|
||||
INITPERSISTFIELD_IMAGEASSET(Texture, VolumetricFog, "A texture which contains Fogdensity modulator in the red channel and color with 1-green channel. No texture disables modulation.");
|
||||
|
||||
addField("tiles", TypeF32, Offset(mTexTiles, VolumetricFog),
|
||||
"How many times the texture is mapped to the object.");
|
||||
addField("modStrength", TypeF32, Offset(mStrength, VolumetricFog),
|
||||
|
|
@ -356,40 +351,15 @@ bool VolumetricFog::LoadShape()
|
|||
{
|
||||
GFXPrimitiveType GFXdrawTypes[] = { GFXTriangleList, GFXTriangleStrip };
|
||||
|
||||
Resource<TSShape> mShape;
|
||||
if (mShapeAssetId != StringTable->EmptyString())
|
||||
if (mShapeAsset.isNull())
|
||||
{
|
||||
mShapeAsset = mShapeAssetId;
|
||||
|
||||
if (mShapeAsset.isNull())
|
||||
{
|
||||
Con::errorf("[TSStatic] Failed to load shape asset.");
|
||||
return false;
|
||||
}
|
||||
|
||||
mShape = mShapeAsset->getShapeResource();
|
||||
|
||||
if (!mShape)
|
||||
{
|
||||
Con::errorf("TSStatic::_createShape() - Shape Asset had no valid shape!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!mShapeName || mShapeName[0] == '\0')
|
||||
{
|
||||
Con::errorf("VolumetricFog::LoadShape() - No shape name! Volumetric Fog will not be rendered!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Load shape, server side only reads bounds and radius
|
||||
mShape = ResourceManager::get().load(mShapeName);
|
||||
Con::errorf("[VolumetricFog] Failed to load shape asset.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (bool(mShape) == false)
|
||||
if (!mShape)
|
||||
{
|
||||
Con::errorf("VolumetricFog::LoadShape() - Unable to load shape: %s", mShapeName);
|
||||
Con::errorf("VolumetricFog::_createShape() - Shape Asset had no valid shape!");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -573,7 +543,7 @@ U32 VolumetricFog::packUpdate(NetConnection *con, U32 mask, BitStream *stream)
|
|||
stream->write(mFogDensity);
|
||||
if (stream->writeFlag(mask & FogModulationMask))
|
||||
{
|
||||
stream->write(mTextureName);
|
||||
PACK_IMAGEASSET(con, Texture);
|
||||
mTexTiles = mFabs(mTexTiles);
|
||||
stream->write(mTexTiles);
|
||||
stream->write(mStrength);
|
||||
|
|
@ -597,27 +567,20 @@ U32 VolumetricFog::packUpdate(NetConnection *con, U32 mask, BitStream *stream)
|
|||
}
|
||||
if (stream->writeFlag(mask & FogShapeMask))
|
||||
{
|
||||
stream->writeString(mShapeAssetId);
|
||||
stream->writeString(mShapeName);
|
||||
PACK_SHAPEASSET(con, Shape);
|
||||
mathWrite(*stream, getTransform());
|
||||
mathWrite(*stream, getScale());
|
||||
|
||||
Resource<TSShape> mShape;
|
||||
|
||||
if (mShapeAssetId != StringTable->EmptyString())
|
||||
if (mShapeAsset.notNull())
|
||||
{
|
||||
mShape = mShapeAsset->getShapeResource();
|
||||
mObjBox = mShapeAsset->getShapeResource()->mBounds;
|
||||
mRadius = mShapeAsset->getShapeResource()->mRadius;
|
||||
}
|
||||
else if (mShapeName && mShapeName[0] != '\0')
|
||||
else
|
||||
{
|
||||
mShape = ResourceManager::get().load(mShapeName);
|
||||
}
|
||||
|
||||
if (bool(mShape) == false)
|
||||
return retMask;
|
||||
}
|
||||
|
||||
mObjBox = mShape->mBounds;
|
||||
mRadius = mShape->mRadius;
|
||||
resetWorldBox();
|
||||
mObjSize = mWorldBox.getGreatestDiagonalLength();
|
||||
mObjScale = getScale();
|
||||
|
|
@ -632,7 +595,7 @@ void VolumetricFog::unpackUpdate(NetConnection *con, BitStream *stream)
|
|||
MatrixF mat;
|
||||
VectorF scale;
|
||||
VectorF mOldScale = getScale();
|
||||
String oldTextureName = mTextureName;
|
||||
StringTableEntry oldTextureName = mTextureAssetId;
|
||||
StringTableEntry oldShapeAsset = mShapeAssetId;
|
||||
StringTableEntry oldShape = mShapeName;
|
||||
|
||||
|
|
@ -650,7 +613,7 @@ void VolumetricFog::unpackUpdate(NetConnection *con, BitStream *stream)
|
|||
}
|
||||
if (stream->readFlag())// Fog Modulation
|
||||
{
|
||||
stream->read(&mTextureName);
|
||||
UNPACK_IMAGEASSET(con, Texture);
|
||||
stream->read(&mTexTiles);
|
||||
mTexTiles = mFabs(mTexTiles);
|
||||
stream->read(&mStrength);
|
||||
|
|
@ -660,9 +623,9 @@ void VolumetricFog::unpackUpdate(NetConnection *con, BitStream *stream)
|
|||
|
||||
if (isProperlyAdded())
|
||||
{
|
||||
if (oldTextureName != mTextureName)
|
||||
if (oldTextureName != mTextureAssetId)
|
||||
InitTexture();
|
||||
if (oldTextureName.isNotEmpty() && mTextureName.isEmpty())
|
||||
if (oldTextureName != StringTable->EmptyString() && mTextureAssetId == StringTable->EmptyString())
|
||||
{
|
||||
mIsTextured = false;
|
||||
mTexture.free();
|
||||
|
|
@ -704,11 +667,8 @@ void VolumetricFog::unpackUpdate(NetConnection *con, BitStream *stream)
|
|||
}
|
||||
if (stream->readFlag())//Fog shape
|
||||
{
|
||||
char buffer[256];
|
||||
stream->readString(buffer);
|
||||
mShapeAssetId = StringTable->insert(buffer);
|
||||
UNPACK_SHAPEASSET(con, Shape);
|
||||
|
||||
mShapeName = stream->readSTString();
|
||||
mathRead(*stream, &mat);
|
||||
mathRead(*stream, &scale);
|
||||
if (strcmp(oldShapeAsset, mShapeAssetId) != 0 || strcmp(oldShape, mShapeName) != 0)
|
||||
|
|
@ -1255,8 +1215,8 @@ void VolumetricFog::InitTexture()
|
|||
{
|
||||
mIsTextured = false;
|
||||
|
||||
if (mTextureName.isNotEmpty())
|
||||
mTexture.set(mTextureName, &GFXStaticTextureSRGBProfile, "VolumetricFogMod");
|
||||
if (mTextureAsset.isNull())
|
||||
return;
|
||||
|
||||
if (!mTexture.isNull())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -83,6 +83,9 @@ class VolumetricFog : public SceneObject
|
|||
Vector <GFXPrimitive> *piArray;
|
||||
Vector <U32> *indices;
|
||||
};
|
||||
|
||||
DECLARE_SHAPEASSET(VolumetricFog, Shape, onShapeChanged);
|
||||
DECLARE_SHAPEASSET_NET_SETGET(VolumetricFog, Shape, FogShapeMask);
|
||||
|
||||
protected:
|
||||
// Rendertargets;
|
||||
|
|
@ -91,9 +94,6 @@ class VolumetricFog : public SceneObject
|
|||
NamedTexTargetRef mDepthBufferTarget;
|
||||
NamedTexTargetRef mFrontBufferTarget;
|
||||
|
||||
// Fog Modulation texture
|
||||
GFXTexHandle mTexture;
|
||||
|
||||
// Shaders
|
||||
GFXShaderRef mShader;
|
||||
GFXShaderRef mDeferredShader;
|
||||
|
|
@ -143,10 +143,7 @@ class VolumetricFog : public SceneObject
|
|||
GFXPrimitiveBufferHandle mPB;
|
||||
|
||||
// Fog volume data;
|
||||
AssetPtr<ShapeAsset> mShapeAsset;
|
||||
StringTableEntry mShapeAssetId;
|
||||
|
||||
StringTableEntry mShapeName;
|
||||
|
||||
ColorI mFogColor;
|
||||
F32 mFogDensity;
|
||||
bool mIgnoreWater;
|
||||
|
|
@ -165,7 +162,9 @@ class VolumetricFog : public SceneObject
|
|||
F32 mInvScale;
|
||||
|
||||
// Fog Modulation data
|
||||
String mTextureName;
|
||||
DECLARE_IMAGEASSET(VolumetricFog, Texture, onImageChanged, GFXStaticTextureSRGBProfile);
|
||||
DECLARE_IMAGEASSET_NET_SETGET(VolumetricFog, Texture, FogModulationMask);
|
||||
|
||||
bool mIsTextured;
|
||||
F32 mTexTiles;
|
||||
F32 mStrength;
|
||||
|
|
@ -221,6 +220,8 @@ class VolumetricFog : public SceneObject
|
|||
void _leaveFog(ShapeBase *control);
|
||||
|
||||
static bool _setShapeAsset(void* obj, const char* index, const char* data);
|
||||
|
||||
void onImageChanged() {}
|
||||
|
||||
public:
|
||||
// Public methods
|
||||
|
|
@ -248,6 +249,8 @@ class VolumetricFog : public SceneObject
|
|||
bool isInsideFog();
|
||||
|
||||
bool setShapeAsset(const StringTableEntry shapeAssetId);
|
||||
|
||||
void onShapeChanged() {}
|
||||
|
||||
DECLARE_CONOBJECT(VolumetricFog);
|
||||
|
||||
|
|
|
|||
|
|
@ -173,8 +173,7 @@ void BasicClouds::initPersistFields()
|
|||
addField( "layerEnabled", TypeBool, Offset( mLayerEnabled, BasicClouds ), TEX_COUNT,
|
||||
"Enable or disable rendering of this layer." );
|
||||
|
||||
addField( "texture", TypeImageFilename, Offset( mTexName, BasicClouds ), TEX_COUNT,
|
||||
"Texture for this layer." );
|
||||
INITPERSISTFIELD_IMAGEASSET_ARRAY(Texture, TEX_COUNT, BasicClouds, "Texture for this layer.");
|
||||
|
||||
addField( "texScale", TypeF32, Offset( mTexScale, BasicClouds ), TEX_COUNT,
|
||||
"Texture repeat for this layer." );
|
||||
|
|
@ -216,7 +215,7 @@ U32 BasicClouds::packUpdate( NetConnection *conn, U32 mask, BitStream *stream )
|
|||
{
|
||||
stream->writeFlag( mLayerEnabled[i] );
|
||||
|
||||
stream->write( mTexName[i] );
|
||||
PACK_IMAGEASSET_ARRAY(conn, Texture, i);
|
||||
|
||||
stream->write( mTexScale[i] );
|
||||
mathWrite( *stream, mTexDirection[i] );
|
||||
|
|
@ -237,7 +236,7 @@ void BasicClouds::unpackUpdate( NetConnection *conn, BitStream *stream )
|
|||
{
|
||||
mLayerEnabled[i] = stream->readFlag();
|
||||
|
||||
stream->read( &mTexName[i] );
|
||||
UNPACK_IMAGEASSET_ARRAY(conn, Texture, i);
|
||||
|
||||
stream->read( &mTexScale[i] );
|
||||
mathRead( *stream, &mTexDirection[i] );
|
||||
|
|
@ -340,11 +339,7 @@ void BasicClouds::_initTexture()
|
|||
continue;
|
||||
}
|
||||
|
||||
if ( mTexName[i].isNotEmpty() )
|
||||
mTexture[i].set( mTexName[i], &GFXStaticTextureSRGBProfile, "BasicClouds" );
|
||||
|
||||
if ( mTexture[i].isNull() )
|
||||
mTexture[i].set( GFXTextureManager::getWarningTexturePath(), &GFXStaticTextureSRGBProfile, "BasicClouds" );
|
||||
_setTexture(getTexture(i), i);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,8 @@
|
|||
#include "gfx/gfxShader.h"
|
||||
#endif
|
||||
|
||||
#include "T3D/assets/ImageAsset.h"
|
||||
|
||||
class BaseMatInstance;
|
||||
|
||||
|
||||
|
|
@ -91,7 +93,8 @@ protected:
|
|||
static U32 smVertCount;
|
||||
static U32 smTriangleCount;
|
||||
|
||||
GFXTexHandle mTexture[TEX_COUNT];
|
||||
DECLARE_IMAGEASSET_ARRAY(BasicClouds, Texture, GFXStaticTextureSRGBProfile, TEX_COUNT);
|
||||
DECLARE_IMAGEASSET_ARRAY_NET_SETGET(BasicClouds, Texture, -1);
|
||||
|
||||
GFXStateBlockRef mStateblock;
|
||||
|
||||
|
|
@ -111,7 +114,6 @@ protected:
|
|||
// Fields...
|
||||
|
||||
bool mLayerEnabled[TEX_COUNT];
|
||||
String mTexName[TEX_COUNT];
|
||||
F32 mTexScale[TEX_COUNT];
|
||||
Point2F mTexDirection[TEX_COUNT];
|
||||
F32 mTexSpeed[TEX_COUNT];
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@
|
|||
#include "lighting/lightInfo.h"
|
||||
#include "math/mathIO.h"
|
||||
|
||||
#include "sim/netConnection.h"
|
||||
|
||||
ConsoleDocClass( CloudLayer,
|
||||
"@brief A layer of clouds which change shape over time and are affected by scene lighting.\n\n"
|
||||
|
||||
|
|
@ -110,6 +112,8 @@ CloudLayer::CloudLayer()
|
|||
mTexOffset[0] = mTexOffset[1] = mTexOffset[2] = Point2F::Zero;
|
||||
|
||||
mHeight = 4.0f;
|
||||
|
||||
INIT_IMAGEASSET(Texture);
|
||||
}
|
||||
|
||||
IMPLEMENT_CO_NETOBJECT_V1( CloudLayer );
|
||||
|
|
@ -127,9 +131,10 @@ bool CloudLayer::onAdd()
|
|||
|
||||
addToScene();
|
||||
|
||||
LOAD_IMAGEASSET(Texture);
|
||||
|
||||
if ( isClientObject() )
|
||||
{
|
||||
_initTexture();
|
||||
_initBuffers();
|
||||
|
||||
// Find ShaderData
|
||||
|
|
@ -186,11 +191,10 @@ void CloudLayer::onRemove()
|
|||
|
||||
void CloudLayer::initPersistFields()
|
||||
{
|
||||
addGroup( "CloudLayer" );
|
||||
|
||||
addField( "texture", TypeImageFilename, Offset( mTextureName, CloudLayer ),
|
||||
"An RGBA texture which should contain normals and opacity (density)." );
|
||||
addGroup( "CloudLayer" );
|
||||
|
||||
INITPERSISTFIELD_IMAGEASSET(Texture, CloudLayer, "An RGBA texture which should contain normals and opacity (density).");
|
||||
|
||||
addArray( "Textures", TEX_COUNT );
|
||||
|
||||
addField( "texScale", TypeF32, Offset( mTexScale, CloudLayer ), TEX_COUNT,
|
||||
|
|
@ -238,7 +242,7 @@ U32 CloudLayer::packUpdate( NetConnection *conn, U32 mask, BitStream *stream )
|
|||
{
|
||||
U32 retMask = Parent::packUpdate( conn, mask, stream );
|
||||
|
||||
stream->write( mTextureName );
|
||||
PACK_IMAGEASSET(conn, Texture);
|
||||
|
||||
for ( U32 i = 0; i < TEX_COUNT; i++ )
|
||||
{
|
||||
|
|
@ -260,8 +264,10 @@ void CloudLayer::unpackUpdate( NetConnection *conn, BitStream *stream )
|
|||
{
|
||||
Parent::unpackUpdate( conn, stream );
|
||||
|
||||
String oldTextureName = mTextureName;
|
||||
stream->read( &mTextureName );
|
||||
UNPACK_IMAGEASSET(conn, Texture);
|
||||
|
||||
if(mTextureAssetId != StringTable->EmptyString())
|
||||
mTextureAsset = mTextureAssetId;
|
||||
|
||||
for ( U32 i = 0; i < TEX_COUNT; i++ )
|
||||
{
|
||||
|
|
@ -283,8 +289,6 @@ void CloudLayer::unpackUpdate( NetConnection *conn, BitStream *stream )
|
|||
|
||||
if ( isProperlyAdded() )
|
||||
{
|
||||
if ( ( oldTextureName != mTextureName ) || ( ( oldCoverage == 0.0f ) != ( mCoverage == 0.0f ) ) )
|
||||
_initTexture();
|
||||
if ( oldHeight != mHeight )
|
||||
_initBuffers();
|
||||
}
|
||||
|
|
@ -330,6 +334,9 @@ void CloudLayer::renderObject( ObjectRenderInst *ri, SceneRenderState *state, Ba
|
|||
{
|
||||
GFXTransformSaver saver;
|
||||
|
||||
if (!mTextureAsset || !mTextureAsset->isAssetValid())
|
||||
return;
|
||||
|
||||
const Point3F &camPos = state->getCameraPosition();
|
||||
MatrixF xfm(true);
|
||||
xfm.setPosition(camPos);
|
||||
|
|
@ -378,7 +385,7 @@ void CloudLayer::renderObject( ObjectRenderInst *ri, SceneRenderState *state, Ba
|
|||
|
||||
mShaderConsts->setSafe( mExposureSC, mExposure );
|
||||
|
||||
GFX->setTexture( mNormalHeightMapSC->getSamplerRegister(), mTexture );
|
||||
GFX->setTexture( mNormalHeightMapSC->getSamplerRegister(), getTextureResource());
|
||||
GFX->setVertexBuffer( mVB );
|
||||
GFX->setPrimitiveBuffer( mPB );
|
||||
|
||||
|
|
@ -389,21 +396,6 @@ void CloudLayer::renderObject( ObjectRenderInst *ri, SceneRenderState *state, Ba
|
|||
// CloudLayer Internal Methods....
|
||||
|
||||
|
||||
void CloudLayer::_initTexture()
|
||||
{
|
||||
if ( mCoverage <= 0.0f )
|
||||
{
|
||||
mTexture = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
if ( mTextureName.isNotEmpty() )
|
||||
mTexture.set( mTextureName, &GFXNormalMapProfile, "CloudLayer" );
|
||||
|
||||
if ( mTexture.isNull() )
|
||||
mTexture.set( GFXTextureManager::getWarningTexturePath(), &GFXNormalMapProfile, "CloudLayer" );
|
||||
}
|
||||
|
||||
void CloudLayer::_initBuffers()
|
||||
{
|
||||
// Vertex Buffer...
|
||||
|
|
|
|||
|
|
@ -39,6 +39,8 @@
|
|||
#include "materials/matInstance.h"
|
||||
#endif
|
||||
|
||||
#include "T3D/assets/ImageAsset.h"
|
||||
|
||||
GFXDeclareVertexFormat( GFXCloudVertex )
|
||||
{
|
||||
Point3F point;
|
||||
|
|
@ -81,9 +83,10 @@ public:
|
|||
void prepRenderImage( SceneRenderState *state );
|
||||
void renderObject( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *mi );
|
||||
|
||||
void onImageChanged() {}
|
||||
|
||||
protected:
|
||||
|
||||
void _initTexture();
|
||||
void _initBuffers();
|
||||
|
||||
protected:
|
||||
|
|
@ -93,7 +96,8 @@ protected:
|
|||
static U32 smVertCount;
|
||||
static U32 smTriangleCount;
|
||||
|
||||
GFXTexHandle mTexture;
|
||||
DECLARE_IMAGEASSET(CloudLayer, Texture, onImageChanged, GFXStaticTextureSRGBProfile);
|
||||
DECLARE_IMAGEASSET_NET_SETGET(CloudLayer, Texture, CloudLayerMask);
|
||||
|
||||
GFXShaderRef mShader;
|
||||
|
||||
|
|
@ -120,7 +124,6 @@ protected:
|
|||
|
||||
// Fields...
|
||||
|
||||
String mTextureName;
|
||||
F32 mTexScale[TEX_COUNT];
|
||||
Point2F mTexDirection[TEX_COUNT];
|
||||
F32 mTexSpeed[TEX_COUNT];
|
||||
|
|
|
|||
|
|
@ -277,8 +277,6 @@ DecalRoad::DecalRoad()
|
|||
mTextureLength( 5.0f ),
|
||||
mRenderPriority( 10 ),
|
||||
mLoadRenderData( true ),
|
||||
mMaterial( NULL ),
|
||||
mMatInst( NULL ),
|
||||
mTriangleCount(0),
|
||||
mVertCount(0),
|
||||
mUpdateEventId( -1 ),
|
||||
|
|
@ -289,7 +287,9 @@ DecalRoad::DecalRoad()
|
|||
mTypeMask |= StaticObjectType | StaticShapeObjectType;
|
||||
mNetFlags.set(Ghostable);
|
||||
|
||||
initMaterialAsset(Material);
|
||||
INIT_MATERIALASSET(Material);
|
||||
|
||||
mMaterialInst = nullptr;
|
||||
}
|
||||
|
||||
DecalRoad::~DecalRoad()
|
||||
|
|
@ -305,8 +305,7 @@ void DecalRoad::initPersistFields()
|
|||
{
|
||||
addGroup( "DecalRoad" );
|
||||
|
||||
addProtectedField("materialAsset", TypeMaterialAssetId, Offset(mMaterialAssetId, DecalRoad), &DecalRoad::_setMaterialAsset, &defaultProtectedGetFn, "Material Asset used for rendering.");
|
||||
addProtectedField( "material", TypeMaterialName, Offset( mMaterialName, DecalRoad ), &DecalRoad::_setMaterialName, &defaultProtectedGetFn, "Material used for rendering." );
|
||||
INITPERSISTFIELD_MATERIALASSET(Material, DecalRoad, "Material used for rendering.");
|
||||
|
||||
addProtectedField( "textureLength", TypeF32, Offset( mTextureLength, DecalRoad ), &DecalRoad::ptSetTextureLength, &defaultProtectedGetFn,
|
||||
"The length in meters of textures mapped to the DecalRoad" );
|
||||
|
|
@ -398,7 +397,7 @@ bool DecalRoad::onAdd()
|
|||
|
||||
void DecalRoad::onRemove()
|
||||
{
|
||||
SAFE_DELETE( mMatInst );
|
||||
SAFE_DELETE( mMaterialInst );
|
||||
|
||||
TerrainBlock::smUpdateSignal.remove( this, &DecalRoad::_onTerrainChanged );
|
||||
|
||||
|
|
@ -492,7 +491,7 @@ U32 DecalRoad::packUpdate(NetConnection * con, U32 mask, BitStream * stream)
|
|||
if ( stream->writeFlag( mask & DecalRoadMask ) )
|
||||
{
|
||||
// Write Texture Name.
|
||||
packMaterialAsset(con, Material);
|
||||
PACK_MATERIALASSET(con, Material);
|
||||
|
||||
stream->write( mBreakAngle );
|
||||
|
||||
|
|
@ -581,7 +580,7 @@ void DecalRoad::unpackUpdate( NetConnection *con, BitStream *stream )
|
|||
// DecalRoadMask
|
||||
if ( stream->readFlag() )
|
||||
{
|
||||
unpackMaterialAsset(con, Material);
|
||||
UNPACK_MATERIALASSET(con, Material);
|
||||
|
||||
if (isProperlyAdded())
|
||||
_initMaterial();
|
||||
|
|
@ -685,13 +684,13 @@ void DecalRoad::prepRenderImage( SceneRenderState* state )
|
|||
|
||||
if ( mNodes.size() <= 1 ||
|
||||
mBatches.size() == 0 ||
|
||||
!mMatInst ||
|
||||
!mMaterialInst ||
|
||||
state->isShadowPass() )
|
||||
return;
|
||||
|
||||
// If we don't have a material instance after the override then
|
||||
// we can skip rendering all together.
|
||||
BaseMatInstance *matInst = state->getOverrideMaterial( mMatInst );
|
||||
BaseMatInstance *matInst = state->getOverrideMaterial(mMaterialInst);
|
||||
if ( !matInst )
|
||||
return;
|
||||
|
||||
|
|
@ -1045,12 +1044,14 @@ bool DecalRoad::addNodeFromField( void *object, const char *index, const char *d
|
|||
|
||||
void DecalRoad::_initMaterial()
|
||||
{
|
||||
_setMaterial(getMaterial());
|
||||
|
||||
if (mMaterialAsset.notNull())
|
||||
{
|
||||
if (mMatInst && String(mMaterialAsset->getMaterialDefinitionName()).equal(mMatInst->getMaterial()->getName(), String::NoCase))
|
||||
if (mMaterialInst && String(mMaterialAsset->getMaterialDefinitionName()).equal(mMaterialInst->getMaterial()->getName(), String::NoCase))
|
||||
return;
|
||||
|
||||
SAFE_DELETE(mMatInst);
|
||||
SAFE_DELETE(mMaterialInst);
|
||||
|
||||
Material* tMat = nullptr;
|
||||
|
||||
|
|
@ -1060,22 +1061,22 @@ void DecalRoad::_initMaterial()
|
|||
mMaterial = tMat;
|
||||
|
||||
if (mMaterial)
|
||||
mMatInst = mMaterial->createMatInstance();
|
||||
mMaterialInst = mMaterial->createMatInstance();
|
||||
else
|
||||
mMatInst = MATMGR->createMatInstance("WarningMaterial");
|
||||
mMaterialInst = MATMGR->createMatInstance("WarningMaterial");
|
||||
|
||||
if (!mMatInst)
|
||||
if (!mMaterialInst)
|
||||
Con::errorf("DecalRoad::_initMaterial - no Material called '%s'", mMaterialAsset->getMaterialDefinitionName());
|
||||
}
|
||||
|
||||
if (!mMatInst)
|
||||
if (!mMaterialInst)
|
||||
return;
|
||||
|
||||
GFXStateBlockDesc desc;
|
||||
desc.setZReadWrite( true, false );
|
||||
mMatInst->addStateBlockDesc( desc );
|
||||
mMaterialInst->addStateBlockDesc( desc );
|
||||
|
||||
mMatInst->init( MATMGR->getDefaultFeatures(), getGFXVertexFormat<GFXVertexPNTBT>() );
|
||||
mMaterialInst->init( MATMGR->getDefaultFeatures(), getGFXVertexFormat<GFXVertexPNTBT>() );
|
||||
}
|
||||
|
||||
void DecalRoad::_debugRender( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance* )
|
||||
|
|
|
|||
|
|
@ -240,7 +240,11 @@ protected:
|
|||
U32 mSegmentsPerBatch;
|
||||
F32 mTextureLength;
|
||||
|
||||
DECLARE_NET_MATERIALASSET(DecalRoad, Material, DecalRoadMask);
|
||||
BaseMatInstance* mMaterialInst;
|
||||
|
||||
DECLARE_MATERIALASSET(DecalRoad, Material);
|
||||
DECLARE_MATERIALASSET_NET_SETGET(DecalRoad, Material, DecalRoadMask);
|
||||
|
||||
U32 mRenderPriority;
|
||||
|
||||
// Static ConsoleVars for editor
|
||||
|
|
@ -261,9 +265,6 @@ protected:
|
|||
RoadBatchVector mBatches;
|
||||
|
||||
bool mLoadRenderData;
|
||||
|
||||
SimObjectPtr<Material> mMaterial;
|
||||
BaseMatInstance *mMatInst;
|
||||
|
||||
GFXVertexBufferHandle<GFXVertexPNTBT> mVB;
|
||||
GFXPrimitiveBufferHandle mPB;
|
||||
|
|
|
|||
|
|
@ -97,6 +97,10 @@ GuiMeshRoadEditorCtrl::GuiMeshRoadEditorCtrl()
|
|||
mHoverNodeColor( 255,255,255,255 ),
|
||||
mHasCopied( false )
|
||||
{
|
||||
INIT_MATERIALASSET(TopMaterial);
|
||||
INIT_MATERIALASSET(BottomMaterial);
|
||||
INIT_MATERIALASSET(SideMaterial);
|
||||
|
||||
mTopMaterialAssetId = Con::getVariable("$MeshRoadEditor::defaultTopMaterialAsset");
|
||||
mBottomMaterialAssetId = Con::getVariable("$MeshRoadEditor::defaultBottomMaterialAsset");
|
||||
mSideMaterialAssetId = Con::getVariable("$MeshRoadEditor::defaultSideMaterialAsset");
|
||||
|
|
@ -205,10 +209,6 @@ bool GuiMeshRoadEditorCtrl::onAdd()
|
|||
desc.zEnable = true;
|
||||
mZEnableSB = GFX->createStateBlock(desc);
|
||||
|
||||
bindMaterialAsset(TopMaterial);
|
||||
bindMaterialAsset(BottomMaterial);
|
||||
bindMaterialAsset(SideMaterial);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -222,9 +222,9 @@ void GuiMeshRoadEditorCtrl::initPersistFields()
|
|||
addField( "HoverNodeColor", TypeColorI, Offset( mHoverNodeColor, GuiMeshRoadEditorCtrl ) );
|
||||
addField( "isDirty", TypeBool, Offset( mIsDirty, GuiMeshRoadEditorCtrl ) );
|
||||
|
||||
addField("topMaterial", TypeMaterialAssetId, Offset(mTopMaterialAssetId, GuiMeshRoadEditorCtrl), "Default Material used by the Mesh Road Editor on upper surface road creation.");
|
||||
addField("bottomMaterial", TypeMaterialAssetId, Offset(mBottomMaterialAssetId, GuiMeshRoadEditorCtrl), "Default Material used by the Mesh Road Editor on bottom surface road creation.");
|
||||
addField("sideMaterial", TypeMaterialAssetId, Offset(mSideMaterialAssetId, GuiMeshRoadEditorCtrl), "Default Material used by the Mesh Road Editor on side surface road creation.");
|
||||
INITPERSISTFIELD_MATERIALASSET(TopMaterial, GuiMeshRoadEditorCtrl, "Default Material used by the Mesh Road Editor on upper surface road creation.");
|
||||
INITPERSISTFIELD_MATERIALASSET(BottomMaterial, GuiMeshRoadEditorCtrl, "Default Material used by the Mesh Road Editor on bottom surface road creation.");
|
||||
INITPERSISTFIELD_MATERIALASSET(SideMaterial, GuiMeshRoadEditorCtrl, "Default Material used by the Mesh Road Editor on side surface road creation.");
|
||||
|
||||
//addField( "MoveNodeCursor", TYPEID< SimObject >(), Offset( mMoveNodeCursor, GuiMeshRoadEditorCtrl) );
|
||||
//addField( "AddNodeCursor", TYPEID< SimObject >(), Offset( mAddNodeCursor, GuiMeshRoadEditorCtrl) );
|
||||
|
|
@ -627,11 +627,11 @@ void GuiMeshRoadEditorCtrl::on3DMouseDown(const Gui3DMouseEvent & event)
|
|||
MeshRoad *newRoad = new MeshRoad;
|
||||
|
||||
if(mTopMaterialAsset.notNull())
|
||||
newRoad->setTopMaterialAssetId(mTopMaterialAssetId);
|
||||
newRoad->_setTopMaterial(mTopMaterialAssetId);
|
||||
if (mBottomMaterialAsset.notNull())
|
||||
newRoad->setBottomMaterialAssetId(mBottomMaterialAssetId);
|
||||
newRoad->_setBottomMaterial(mBottomMaterialAssetId);
|
||||
if (mSideMaterialAsset.notNull())
|
||||
newRoad->setSideMaterialAssetId(mSideMaterialAssetId);
|
||||
newRoad->_setSideMaterial(mSideMaterialAssetId);
|
||||
|
||||
newRoad->registerObject();
|
||||
|
||||
|
|
|
|||
|
|
@ -159,13 +159,14 @@ class GuiMeshRoadEditorCtrl : public EditTSCtrl
|
|||
bool mHasCopied;
|
||||
public:
|
||||
|
||||
StringTableEntry mTopMaterialAssetId;
|
||||
StringTableEntry mBottomMaterialAssetId;
|
||||
StringTableEntry mSideMaterialAssetId;
|
||||
DECLARE_MATERIALASSET(GuiMeshRoadEditorCtrl, TopMaterial);
|
||||
DECLARE_MATERIALASSET_SETGET(GuiMeshRoadEditorCtrl, TopMaterial);
|
||||
|
||||
AssetPtr<MaterialAsset> mTopMaterialAsset;
|
||||
AssetPtr<MaterialAsset> mBottomMaterialAsset;
|
||||
AssetPtr<MaterialAsset> mSideMaterialAsset;
|
||||
DECLARE_MATERIALASSET(GuiMeshRoadEditorCtrl, BottomMaterial);
|
||||
DECLARE_MATERIALASSET_SETGET(GuiMeshRoadEditorCtrl, BottomMaterial);
|
||||
|
||||
DECLARE_MATERIALASSET(GuiMeshRoadEditorCtrl, SideMaterial);
|
||||
DECLARE_MATERIALASSET_SETGET(GuiMeshRoadEditorCtrl, SideMaterial);
|
||||
};
|
||||
|
||||
class GuiMeshRoadEditorUndoAction : public UndoAction
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue