Merge branch 'Preview4_0' into feature-vfs-security

This commit is contained in:
Robert MacGregor 2022-06-13 08:05:26 -04:00
commit 161ffc62fe
3013 changed files with 348715 additions and 182470 deletions

View file

@ -102,7 +102,7 @@ void GUIAsset::initPersistFields()
&setScriptFile, &getScriptFile, "Path to the script file for the gui");
addProtectedField("GUIFile", TypeAssetLooseFilePath, Offset(mGUIFile, GUIAsset),
&setScriptFile, &getScriptFile, "Path to the gui file");
&setGUIFile, &getGUIFile, "Path to the gui file");
}
//------------------------------------------------------------------------------
@ -115,28 +115,28 @@ void GUIAsset::copyTo(SimObject* object)
void GUIAsset::initializeAsset()
{
mGUIPath = getOwned() ? expandAssetFilePath(mGUIFile) : mGUIPath;
if (Torque::FS::IsScriptFile(mGUIPath))
Con::executeFile(mGUIPath, false, false);
mScriptPath = getOwned() ? expandAssetFilePath(mScriptFile) : mScriptPath;
if (Torque::FS::IsScriptFile(mScriptPath))
Con::executeFile(mScriptPath, false, false);
mGUIPath = getOwned() ? expandAssetFilePath(mGUIFile) : mGUIPath;
if (Torque::FS::IsScriptFile(mGUIPath))
Con::executeFile(mGUIPath, false, false);
}
void GUIAsset::onAssetRefresh()
{
mGUIPath = getOwned() ? expandAssetFilePath(mGUIFile) : mGUIPath;
if (Torque::FS::IsScriptFile(mGUIPath))
Con::executeFile(mGUIPath, false, false);
mScriptPath = getOwned() ? expandAssetFilePath(mScriptFile) : mScriptPath;
if (Torque::FS::IsScriptFile(mScriptPath))
Con::executeFile(mScriptPath, false, false);
mGUIPath = getOwned() ? expandAssetFilePath(mGUIFile) : mGUIPath;
if (Torque::FS::IsScriptFile(mGUIPath))
Con::executeFile(mGUIPath, false, false);
}
void GUIAsset::setGUIFile(const char* pScriptFile)
@ -226,6 +226,13 @@ DefineEngineMethod(GUIAsset, getScriptPath, const char*, (), ,
{
return object->getScriptPath();
}
DefineEngineMethod(GUIAsset, getGUIPath, const char*, (), ,
"Gets the GUI file path associated to this asset.\n"
"@return The full script file path.")
{
return object->getGUIPath();
}
#endif
//-----------------------------------------------------------------------------

View file

@ -58,7 +58,7 @@ StringTableEntry ImageAsset::smNoImageAssetFallback = NULL;
IMPLEMENT_CONOBJECT(ImageAsset);
ConsoleType(ImageAssetPtr, TypeImageAssetPtr, const char*, ASSET_ID_FIELD_PREFIX)
ConsoleType(ImageAssetPtr, TypeImageAssetPtr, const char*, "")
//-----------------------------------------------------------------------------
@ -85,7 +85,7 @@ ConsoleSetType(TypeImageAssetPtr)
Con::warnf("(TypeImageAssetPtr) - Cannot set multiple args to a single asset.");
}
ConsoleType(assetIdString, TypeImageAssetId, const char*, ASSET_ID_FIELD_PREFIX)
ConsoleType(assetIdString, TypeImageAssetId, const char*, "")
ConsoleGetType(TypeImageAssetId)
{
@ -219,6 +219,10 @@ StringTableEntry ImageAsset::getAssetIdByFilename(StringTableEntry fileName)
//acquire and bind the asset, and return it out
imageAssetId = query.mAssetList[0];
}
else
{
AssetPtr<ImageAsset> imageAsset = imageAssetId; //ensures the fallback is loaded
}
return imageAssetId;
}

View file

@ -391,6 +391,20 @@ DefineEngineMethod(LevelAsset, getDecalsPath, const char*, (), ,
return object->getDecalsPath();
}
DefineEngineMethod(LevelAsset, getForestPath, const char*, (), ,
"Gets the full path of the asset's defined forest file.\n"
"@return The string result of the forest path")
{
return object->getForestPath();
}
DefineEngineMethod(LevelAsset, getNavmeshPath, const char*, (), ,
"Gets the full path of the asset's defined navmesh file.\n"
"@return The string result of the navmesh path")
{
return object->getNavmeshPath();
}
DefineEngineMethod(LevelAsset, loadDependencies, void, (), ,
"Initiates the loading of asset dependencies for this level.")
{

View file

@ -154,8 +154,9 @@ void MaterialAsset::initPersistFields()
Parent::initPersistFields();
//addField("shaderGraph", TypeRealString, Offset(mShaderGraphFile, MaterialAsset), "");
addProtectedField("scriptFile", TypeAssetLooseFilePath, Offset(mScriptFile, MaterialAsset),
&setScriptFile, &getScriptFile, "Path to the file containing the material definition.");
//addProtectedField("scriptFile", TypeAssetLooseFilePath, Offset(mScriptFile, MaterialAsset),
// &setScriptFile, &getScriptFile, "Path to the file containing the material definition.");
addField("scriptFile", TypeAssetLooseFilePath, Offset(mScriptFile, MaterialAsset), "");
addField("materialDefinitionName", TypeString, Offset(mMatDefinitionName, MaterialAsset), "Name of the material definition this asset is for.");
}
@ -173,7 +174,11 @@ void MaterialAsset::initializeAsset()
return;
}
if (Torque::FS::IsScriptFile(mScriptPath))
if (size() != 0 && mScriptPath == StringTable->EmptyString())
{
mLoadedState = EmbeddedDefinition;
}
else if (Torque::FS::IsScriptFile(mScriptPath))
{
if (!Sim::findObject(mMatDefinitionName))
{
@ -230,7 +235,6 @@ void MaterialAsset::setScriptFile(const char* pScriptFile)
// Sanity!
AssertFatal(pScriptFile != NULL, "Cannot use a NULL script file.");
// Fetch image file.
pScriptFile = StringTable->insert(pScriptFile, true);
// Update.
@ -245,9 +249,28 @@ void MaterialAsset::setScriptFile(const char* pScriptFile)
void MaterialAsset::loadMaterial()
{
if (mMaterialDefinition)
SAFE_DELETE(mMaterialDefinition);
{
mMaterialDefinition->safeDeleteObject();
}
if ((mLoadedState == ScriptLoaded || mLoadedState == DefinitionAlreadyExists) && mMatDefinitionName != StringTable->EmptyString())
if (mLoadedState == EmbeddedDefinition)
{
if (size() != 0)
{
for (U32 i = 0; i < size(); i++)
{
mMaterialDefinition = dynamic_cast<Material*>(getObject(i));
if (mMaterialDefinition)
{
mLoadedState = Ok;
mMaterialDefinition->setInternalName(getAssetId());
mMaterialDefinition->reload();
return;
}
}
}
}
else if ((mLoadedState == ScriptLoaded || mLoadedState == DefinitionAlreadyExists) && mMatDefinitionName != StringTable->EmptyString())
{
Material* matDef;
if (!Sim::findObject(mMatDefinitionName, matDef))
@ -260,7 +283,7 @@ void MaterialAsset::loadMaterial()
mMaterialDefinition = matDef;
mLoadedState = Ok;
mMaterialDefinition->setInternalName(getAssetId());
mMaterialDefinition->reload();
return;
}
@ -296,11 +319,11 @@ U32 MaterialAsset::getAssetByMaterialName(StringTableEntry matName, AssetPtr<Mat
//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);
Con::warnf("MaterialAsset::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);
Con::warnf("MaterialAsset::getAssetByMaterialName - Finding of associated with aterial name %s failed, utilizing fallback asset", matName);
(*matAsset)->mLoadedState = AssetErrCode::UsingFallback;
return AssetErrCode::UsingFallback;
@ -388,6 +411,17 @@ U32 MaterialAsset::getAssetById(StringTableEntry assetId, AssetPtr<MaterialAsset
}
}
SimObjectPtr<Material> MaterialAsset::findMaterialDefinitionByAssetId(StringTableEntry assetId)
{
SimSet* matSet = MATMGR->getMaterialSet();
if (matSet)
{
SimObjectPtr<Material> matDef = dynamic_cast<Material*>(matSet->findObjectByInternalName(assetId));
return matDef;
}
return nullptr;
}
#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"
@ -396,9 +430,21 @@ DefineEngineStaticMethod(MaterialAsset, getAssetIdByMaterialName, const char*, (
return MaterialAsset::getAssetIdByMaterialName(StringTable->insert(materialName));
}
//MaterialAsset::findMaterialDefinitionByAssetId("Prototyping:Detail")
DefineEngineStaticMethod(MaterialAsset, findMaterialDefinitionByAssetId, S32, (const char* assetId), (""),
"Queries the MaterialSet to see if any MaterialDefinition exists that is associated to the provided assetId.\n"
"@return The MaterialDefinition Id associated to the assetId, if any")
{
SimObjectPtr<Material> matDef = MaterialAsset::findMaterialDefinitionByAssetId(StringTable->insert(assetId));
if (matDef.isNull())
return SimObjectId(0);
else
return matDef->getId();
}
DefineEngineMethod(MaterialAsset, getScriptPath, const char*, (), ,
"Queries the Asset Database to see if any asset exists that is associated with the provided material name.\n"
"@return The AssetId of the associated asset, if any.")
"Gets the script file path for the asset.")
{
return object->getScriptPath();
}

View file

@ -48,7 +48,9 @@
#include "sim/netConnection.h"
#endif
#ifndef _GUI_INSPECTOR_TYPES_H_
#include "gui/editor/guiInspectorTypes.h"
#endif
#include "materials/matTextureTarget.h"
#include "materials/materialDefinition.h"
@ -75,6 +77,7 @@ public:
{
ScriptLoaded = AssetErrCode::Extended,
DefinitionAlreadyExists,
EmbeddedDefinition,
Extended
};
@ -108,6 +111,7 @@ public:
/// <returns>AssetId of matching asset.</returns>
static StringTableEntry getAssetIdByMaterialName(StringTableEntry matName);
static U32 getAssetById(StringTableEntry assetId, AssetPtr<MaterialAsset>* materialAsset);
static SimObjectPtr<Material> findMaterialDefinitionByAssetId(StringTableEntry assetId);
static U32 getAssetByMaterialName(StringTableEntry matName, AssetPtr<MaterialAsset>* matAsset);
/// Declare Console Object.

View file

@ -206,3 +206,21 @@ void PostEffectAsset::setGLSLShaderFile(const char* pShaderFile)
// Refresh the asset.
refreshAsset();
}
DefineEngineMethod(PostEffectAsset, getScriptPath, const char*, (), ,
"Gets the script file path for the asset.")
{
return object->getScriptPath();
}
DefineEngineMethod(PostEffectAsset, getHLSLShaderPath, const char*, (), ,
"Gets the HLSL Shader file path for the asset.")
{
return object->getHLSLShaderPath();
}
DefineEngineMethod(PostEffectAsset, getGLSLShaderPath, const char*, (), ,
"Gets the GLSL Shader file path for the asset.")
{
return object->getGLSLShaderPath();
}

View file

@ -151,7 +151,7 @@ void ShapeAnimationAsset::initializeAsset(void)
mSourceShape = ResourceManager::get().load(mFilePath);
if (!mSourceShape->addSequence("ambient", "", mAnimationName, mStartFrame, mEndFrame, mPadRotation, mPadTransforms))
if (!mSourceShape || !mSourceShape->addSequence("ambient", "", mAnimationName, mStartFrame, mEndFrame, mPadRotation, mPadTransforms))
{
Con::errorf("ShapeAnimationAsset::initializeAsset - Unable to do initial setup of the animation clip named %s for asset %s", mAnimationName, getAssetName());
return;
@ -204,3 +204,9 @@ DefineEngineMethod(ShapeAnimationAsset, getAnimationCount, S32, (), ,
{
return object->getAnimationCount();
}
DefineEngineMethod(ShapeAnimationAsset, getAnimationPath, const char*, (), ,
"Gets the Animation file path associated to this asset.")
{
return object->getAnimationPath();
}

View file

@ -51,6 +51,9 @@
#endif
#include "util/imposterCapture.h"
#include "ts/tsShapeInstance.h"
#include "gfx/bitmap/imageUtils.h"
StringTableEntry ShapeAsset::smNoShapeAssetFallback = NULL;
//-----------------------------------------------------------------------------
@ -470,6 +473,10 @@ StringTableEntry ShapeAsset::getAssetIdByFilename(StringTableEntry fileName)
//acquire and bind the asset, and return it out
shapeAssetId = query.mAssetList[0];
}
else
{
AssetPtr<ShapeAsset> shapeAsset = shapeAssetId; //ensures the fallback is loaded
}
return shapeAssetId;
}
@ -560,25 +567,97 @@ ShapeAnimationAsset* ShapeAsset::getAnimation(S32 index)
}
#ifdef TORQUE_TOOLS
const char* ShapeAsset::generateCachedPreviewImage(S32 resolution)
const char* ShapeAsset::generateCachedPreviewImage(S32 resolution, String overrideMaterial)
{
if (!mShape)
return "";
TSLastDetail* dt = new TSLastDetail(mShape,
mFilePath,
1,
0,
0,
false,
0,
resolution);
// We're gonna render... make sure we can.
bool sceneBegun = GFX->canCurrentlyRender();
if (!sceneBegun)
GFX->beginScene();
dt->update();
// We need to create our own instance to render with.
TSShapeInstance* shape = new TSShapeInstance(mShape, true);
delete dt;
if (overrideMaterial.isNotEmpty())
{
Material *tMat = dynamic_cast<Material*>(Sim::findObject(overrideMaterial));
if (tMat)
shape->reSkin(tMat->mMapTo, mShape->materialList->getMaterialName(0));
}
// Animate the shape once.
shape->animate(0);
return mFilePath;
// So we don't have to change it everywhere.
const GFXFormat format = GFXFormatR8G8B8A8;
GBitmap* imposter = NULL;
GBitmap* imposterNrml = NULL;
ImposterCapture* imposterCap = new ImposterCapture();
static const MatrixF topXfm(EulerF(-M_PI_F / 2.0f, 0, 0));
static const MatrixF bottomXfm(EulerF(M_PI_F / 2.0f, 0, 0));
MatrixF angMat;
S32 mip = 0;
PROFILE_START(ShapeAsset_generateCachedPreviewImage);
//dMemset(destBmp.getWritableBits(mip), 0, destBmp.getWidth(mip) * destBmp.getHeight(mip) * GFXFormat_getByteSize(format));
F32 rotX = -(mDegToRad(60.0) - 0.5f * M_PI_F);
F32 rotZ = -(mDegToRad(45.0) - 0.5f * M_PI_F);
// We capture the images in a particular order which must
// match the order expected by the imposter renderer.
imposterCap->begin(shape, 0, resolution, mShape->mRadius, mShape->center);
angMat.mul(MatrixF(EulerF(rotX, 0, 0)),
MatrixF(EulerF(0, 0, rotZ)));
imposterCap->capture(angMat, &imposter, &imposterNrml);
imposterCap->end();
PROFILE_END(); // ShapeAsset_generateCachedPreviewImage
delete imposterCap;
delete shape;
String dumpPath = String(mFilePath) + "_Preview.dds";
char* returnBuffer = Con::getReturnBuffer(128);
dSprintf(returnBuffer, 128, "%s", dumpPath.c_str());
/*FileStream stream;
if (stream.open(dumpPath, Torque::FS::File::Write))
destBmp.writeBitmap("png", stream);
stream.close();*/
DDSFile* ddsDest = DDSFile::createDDSFileFromGBitmap(imposter);
ImageUtil::ddsCompress(ddsDest, GFXFormatBC2);
// Finally save the imposters to disk.
FileStream fs;
if (fs.open(returnBuffer, Torque::FS::File::Write))
{
ddsDest->write(fs);
fs.close();
}
delete ddsDest;
delete imposter;
delete imposterNrml;
// If we did a begin then end it now.
if (!sceneBegun)
GFX->endScene();
return returnBuffer;
}
#endif
@ -604,7 +683,7 @@ DefineEngineMethod(ShapeAsset, getAnimation, ShapeAnimationAsset*, (S32 index),
return object->getAnimation(index);
}
DefineEngineMethod(ShapeAsset, getShapeFile, const char*, (), ,
DefineEngineMethod(ShapeAsset, getShapePath, const char*, (), ,
"Gets the shape's file path\n"
"@return The filename of the shape file")
{
@ -625,9 +704,12 @@ DefineEngineMethod(ShapeAsset, getStatusString, String, (), , "get status string
#ifdef TORQUE_TOOLS
DefineEngineMethod(ShapeAsset, generateCachedPreviewImage, const char*, (S32 resolution), (256), "")
DefineEngineMethod(ShapeAsset, generateCachedPreviewImage, const char*, (S32 resolution, const char* overrideMaterialName), (256, ""),
"Generates a baked preview image of the given shapeAsset. Only really used for generating Asset Browser icons.\n"
"@param resolution Optional field for what resolution to bake the preview image at. Must be pow2\n"
"@param overrideMaterialName Optional field for overriding the material used when rendering the shape for the bake.")
{
return object->generateCachedPreviewImage(resolution);
return object->generateCachedPreviewImage(resolution, overrideMaterialName);
}
DefineEngineStaticMethod(ShapeAsset, getAssetIdByFilename, const char*, (const char* filePath), (""),

View file

@ -191,7 +191,7 @@ public:
static U32 getAssetById(StringTableEntry assetId, AssetPtr<ShapeAsset>* shapeAsset);
#ifdef TORQUE_TOOLS
const char* generateCachedPreviewImage(S32 resolution);
const char* generateCachedPreviewImage(S32 resolution, String overrideMaterial = "");
#endif
protected:

View file

@ -218,6 +218,9 @@ bool SoundAsset::loadSound()
{
Con::errorf("SoundAsset::initializeAsset: Attempted to load file %s but it was not valid!", mSoundFile);
mLoadedState = BadFileReference;
mSFXProfile.setDescription(NULL);
mSFXProfile.setSoundFileName(StringTable->insert(StringTable->EmptyString()));
mSFXProfile.setPreload(false);
return false;
}
else
@ -225,6 +228,9 @@ bool SoundAsset::loadSound()
mSFXProfile.setDescription(&mProfileDesc);
mSFXProfile.setSoundFileName(mSoundPath);
mSFXProfile.setPreload(mPreload);
//give it a nudge to preload if required
mSFXProfile.getBuffer();
}
}
@ -257,7 +263,7 @@ StringTableEntry SoundAsset::getAssetIdByFileName(StringTableEntry fileName)
if (fileName == StringTable->EmptyString())
return StringTable->EmptyString();
StringTableEntry materialAssetId = "";
StringTableEntry soundAssetId = StringTable->EmptyString();
AssetQuery query;
U32 foundCount = AssetDatabase.findAssetType(&query, "SoundAsset");
@ -268,7 +274,7 @@ StringTableEntry SoundAsset::getAssetIdByFileName(StringTableEntry fileName)
SoundAsset* soundAsset = AssetDatabase.acquireAsset<SoundAsset>(query.mAssetList[i]);
if (soundAsset && soundAsset->getSoundPath() == fileName)
{
materialAssetId = soundAsset->getAssetId();
soundAssetId = soundAsset->getAssetId();
AssetDatabase.releaseAsset(query.mAssetList[i]);
break;
}
@ -276,7 +282,7 @@ StringTableEntry SoundAsset::getAssetIdByFileName(StringTableEntry fileName)
}
}
return materialAssetId;
return soundAssetId;
}
U32 SoundAsset::getAssetById(StringTableEntry assetId, AssetPtr<SoundAsset>* soundAsset)
@ -330,15 +336,18 @@ DefineEngineMethod(SoundAsset, getSoundPath, const char*, (), , "")
}
DefineEngineMethod(SoundAsset, playSound, S32, (Point3F position), (Point3F::Zero),
"Gets the number of materials for this shape asset.\n"
"@return Material count.\n")
"Plays the sound for this asset.\n"
"@return (sound plays).\n")
{
if (object->getSfxProfile())
{
MatrixF transform;
transform.setPosition(position);
SFXSource* source = SFX->playOnce(object->getSfxProfile(), &transform, NULL, -1);
return source->getId();
if(source)
return source->getId();
else
return 0;
}
else
return 0;

View file

@ -40,6 +40,9 @@
#endif
#include "gui/editor/guiInspectorTypes.h"
#ifndef _ASSET_PTR_H_
#include "assets/assetPtr.h"
#endif
#ifndef _BITSTREAM_H_
#include "core/stream/bitStream.h"
@ -57,6 +60,10 @@
#include "sfx/sfxProfile.h"
#endif // !_SFXPROFILE_H_
#ifndef _RESOURCEMANAGER_H_
#include "core/resourceManager.h"
#endif
#include "assetMacroHelpers.h"
class SFXResource;
@ -178,6 +185,8 @@ public:
StringTableEntry m##name##AssetId;\
AssetPtr<SoundAsset> m##name##Asset = NULL;\
SFXProfile* m##name##Profile = NULL;\
SFXDescription* m##name##Desc = NULL;\
SimObjectId m##name##SFXId = NULL;\
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());}\
@ -245,7 +254,7 @@ public: \
Con::errorf("%s(%s)::_set%s() - sound asset failure\"%s\" due to [%s]", macroText(className), getName(), macroText(name), _in, SoundAsset::getAssetErrstrn(m##name##Asset->getStatus()).c_str());\
return false; \
}\
else if (!m##name)\
else if (!m##name && (m##name##Name != StringTable->EmptyString() && !Sim::findObject(m##name##Name)))\
{\
Con::errorf("%s(%s)::_set%s() - Couldn't load sound \"%s\"", macroText(className), getName(), macroText(name), _in);\
return false;\
@ -271,7 +280,15 @@ public: \
SFXProfile* get##name##Profile()\
{\
if (get##name() != StringTable->EmptyString() && m##name##Asset.notNull())\
return m##name##Asset->getSfxProfile();\
m##name##Profile = m##name##Asset->getSfxProfile();\
return m##name##Profile;\
return NULL;\
}\
SFXDescription* get##name##Description()\
{\
if (get##name() != StringTable->EmptyString() && m##name##Asset.notNull())\
m##name##Desc = m##name##Asset->getSfxDescription();\
return m##name##Desc;\
return NULL;\
}\
bool is##name##Valid() { return (get##name() != StringTable->EmptyString() && m##name##Asset->getStatus() == AssetBase::Ok); }
@ -290,10 +307,61 @@ public: \
#endif // TORQUE_SHOW_LEGACY_FILE_FIELDS
//network send - datablock
#define PACKDATA_SOUNDASSET(name)\
if (stream->writeFlag(m##name##Asset.notNull()))\
{\
stream->writeString(m##name##Asset.getAssetId());\
}\
else\
{\
if(stream->writeFlag(Sim::findObject(m##name##Name)))\
{\
SFXTrack* sndTrack;\
Sim::findObject(m##name##Name, sndTrack);\
stream->writeRangedU32(SimObjectId(sndTrack->getId()), DataBlockObjectIdFirst, DataBlockObjectIdLast);\
}\
else\
{\
stream->writeString(m##name##Name);\
}\
}
//network recieve - datablock
#define UNPACKDATA_SOUNDASSET(name)\
if (stream->readFlag())\
{\
m##name##AssetId = stream->readSTString();\
_set##name(m##name##AssetId);\
}\
else\
{\
if(stream->readFlag())\
{\
m##name##SFXId = stream->readRangedU32( DataBlockObjectIdFirst, DataBlockObjectIdLast );\
}\
else\
{\
m##name##Name = stream->readSTString(); \
_set##name(m##name##Name); \
}\
}
#pragma endregion
#pragma region Arrayed Asset Macros
#define INIT_SOUNDASSET_ARRAY(name, index) \
{\
m##name##Name[index] = StringTable->EmptyString(); \
m##name##AssetId[index] = StringTable->EmptyString(); \
m##name##Asset[index] = NULL;\
m##name[index] = NULL;\
m##name##Profile[index] = NULL;\
m##name##SFXId[index] = 0;\
}
#define DECLARE_SOUNDASSET_ARRAY(className,name,max) public: \
static const U32 sm##name##Count = max;\
Resource<SFXResource> m##name[max];\
@ -301,6 +369,7 @@ public: \
StringTableEntry m##name##AssetId[max];\
AssetPtr<SoundAsset> m##name##Asset[max];\
SFXProfile* m##name##Profile[max];\
SimObjectId m##name##SFXId[max];\
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());}\
@ -376,7 +445,7 @@ public: \
Con::errorf("%s(%s)::_set%s(%i) - sound asset failure\"%s\" due to [%s]", macroText(className), getName(), macroText(name),index, _in, SoundAsset::getAssetErrstrn(m##name##Asset[index]->getStatus()).c_str());\
return false; \
}\
else if (!m##name[index])\
else if (!m##name[index] && (m##name##Name[index] != StringTable->EmptyString() && !Sim::findObject(m##name##Name[index])))\
{\
Con::errorf("%s(%s)::_set%s(%i) - Couldn't load sound \"%s\"", macroText(className), getName(), macroText(name),index, _in);\
return false;\
@ -448,6 +517,46 @@ if (m##name##AssetId[index] != StringTable->EmptyString())\
addField(assetEnumNameConcat(enumString, Asset), TypeSoundAssetId, Offset(m##name##AssetId[0], consoleClass) + sizeof(m##name##AssetId[0])*i, assetText(name, asset reference.));\
}\
}
#define PACKDATA_SOUNDASSET_ARRAY(name, index)\
if (stream->writeFlag(m##name##Asset[index].notNull()))\
{\
stream->writeString(m##name##Asset[index].getAssetId());\
}\
else\
{\
if(stream->writeFlag(Sim::findObject(m##name##Name[index])))\
{\
SFXTrack* sndTrack;\
Sim::findObject(m##name##Name[index], sndTrack);\
stream->writeRangedU32(SimObjectId(sndTrack->getId()), DataBlockObjectIdFirst, DataBlockObjectIdLast);\
}\
else\
{\
stream->writeString(m##name##Name[index]);\
}\
}
//network recieve - datablock
#define UNPACKDATA_SOUNDASSET_ARRAY(name, index)\
if (stream->readFlag())\
{\
m##name##AssetId[index] = stream->readSTString();\
_set##name(m##name##AssetId[index], index);\
}\
else\
{\
if(stream->readFlag())\
{\
m##name##SFXId[index] = stream->readRangedU32( DataBlockObjectIdFirst, DataBlockObjectIdLast );\
}\
else\
{\
m##name##Name[index] = stream->readSTString(); \
_set##name(m##name##Name[index], index); \
}\
}
#pragma endregion
#endif // _ASSET_BASE_H_

View file

@ -247,7 +247,7 @@ bool TerrainAsset::getAssetByFilename(StringTableEntry fileName, AssetPtr<Terrai
{
//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
#ifdef TORQUE_DEBUG
Con::warnf("TerrainAsset::getAssetByFilename - Attempted to in-place import a terrainFile(%s) that had no associated asset", fileName);
#endif

View file

@ -40,6 +40,10 @@
#include "assets/assetPtr.h"
#endif
#include "T3D/assets/assetImporter.h"
StringTableEntry TerrainMaterialAsset::smNoTerrainMaterialAssetFallback = NULL;
//-----------------------------------------------------------------------------
IMPLEMENT_CONOBJECT(TerrainMaterialAsset);
@ -85,6 +89,35 @@ ConsoleSetType(TypeTerrainMaterialAssetPtr)
Con::warnf("(TypeTerrainMaterialAssetPtr) - Cannot set multiple args to a single asset.");
}
ConsoleType(assetIdString, TypeTerrainMaterialAssetId, const char*, ASSET_ID_FIELD_PREFIX)
ConsoleGetType(TypeTerrainMaterialAssetId)
{
// Fetch asset Id.
return *((const char**)(dptr));
}
ConsoleSetType(TypeTerrainMaterialAssetId)
{
// 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);
return;
}
// Warn.
Con::warnf("(TypeTerrainMaterialAssetId) - Cannot set multiple args to a single asset.");
}
//-----------------------------------------------------------------------------
TerrainMaterialAsset::TerrainMaterialAsset()
@ -92,24 +125,41 @@ TerrainMaterialAsset::TerrainMaterialAsset()
mScriptFile = StringTable->EmptyString();
mScriptPath = StringTable->EmptyString();
mMatDefinitionName = StringTable->EmptyString();
mMaterialDefinition = nullptr;
mFXMaterialDefinition = nullptr;
}
//-----------------------------------------------------------------------------
TerrainMaterialAsset::~TerrainMaterialAsset()
{
if (mMaterialDefinition)
mMaterialDefinition->safeDeleteObject();
if (mFXMaterialDefinition)
mFXMaterialDefinition->safeDeleteObject();
}
//-----------------------------------------------------------------------------
void TerrainMaterialAsset::consoleInit()
{
Parent::consoleInit();
Con::addVariable("$Core::NoTerrainMaterialAssetFallback", TypeString, &smNoTerrainMaterialAssetFallback,
"The assetId of the material to display when the requested material asset is missing.\n"
"@ingroup GFX\n");
smNoTerrainMaterialAssetFallback = StringTable->insert(Con::getVariable("$Core::NoTerrainMaterialAssetFallback"));
}
void TerrainMaterialAsset::initPersistFields()
{
// Call parent.
Parent::initPersistFields();
//addField("shaderGraph", TypeRealString, Offset(mShaderGraphFile, TerrainMaterialAsset), "");
addProtectedField("scriptFile", TypeAssetLooseFilePath, Offset(mScriptFile, TerrainMaterialAsset),
&setScriptFile, &getScriptFile, "Path to the file containing the material definition.");
//addProtectedField("scriptFile", TypeAssetLooseFilePath, Offset(mScriptFile, TerrainMaterialAsset),
// &setScriptFile, &getScriptFile, "Path to the file containing the material definition.");
addField("scriptFile", TypeAssetLooseFilePath, Offset(mScriptFile, TerrainMaterialAsset), "");
addField("materialDefinitionName", TypeString, Offset(mMatDefinitionName, TerrainMaterialAsset), "Name of the material definition this asset is for.");
}
@ -121,28 +171,66 @@ void TerrainMaterialAsset::initializeAsset()
mScriptPath = getOwned() ? expandAssetFilePath(mScriptFile) : mScriptPath;
if (Torque::FS::IsScriptFile(mScriptPath))
Con::executeFile(mScriptPath, false, false);
if (mMatDefinitionName == StringTable->EmptyString())
{
mLoadedState = Failed;
return;
}
if (size() != 0 && mScriptPath == StringTable->EmptyString())
{
mLoadedState = EmbeddedDefinition;
}
else if (Torque::FS::IsScriptFile(mScriptPath))
{
if (!Sim::findObject(mMatDefinitionName))
{
if (Con::executeFile(mScriptPath, false, false))
{
mLoadedState = ScriptLoaded;
}
else
{
mLoadedState = Failed;
}
}
else
{
mLoadedState = DefinitionAlreadyExists;
}
}
loadMaterial();
}
void TerrainMaterialAsset::onAssetRefresh()
{
mScriptPath = getOwned() ? expandAssetFilePath(mScriptFile) : mScriptPath;
if (Torque::FS::IsScriptFile(mScriptPath))
Con::executeFile(mScriptPath, false, false);
if (mMatDefinitionName != StringTable->EmptyString())
if (mMatDefinitionName == StringTable->EmptyString())
{
TerrainMaterial* matDef;
if (!Sim::findObject(mMatDefinitionName, matDef))
{
Con::errorf("TerrainMaterialAsset: Unable to find the Material %s", mMatDefinitionName);
mLoadedState = Failed;
return;
}
//matDef->reload();
if (Torque::FS::IsScriptFile(mScriptPath))
{
//Since we're refreshing, we can assume that the file we're executing WILL have an existing definition.
//But that definition, whatever it is, is the 'correct' one, so we enable the Replace Existing behavior
//when the engine encounters a named object conflict.
String redefineBehaviorPrev = Con::getVariable("$Con::redefineBehavior");
Con::setVariable("$Con::redefineBehavior", "replaceExisting");
if (Con::executeFile(mScriptPath, false, false))
mLoadedState = ScriptLoaded;
else
mLoadedState = Failed;
//And now that we've executed, switch back to the prior behavior
Con::setVariable("$Con::redefineBehavior", redefineBehaviorPrev.c_str());
}
loadMaterial();
}
void TerrainMaterialAsset::setScriptFile(const char* pScriptFile)
@ -152,10 +240,6 @@ void TerrainMaterialAsset::setScriptFile(const char* pScriptFile)
pScriptFile = StringTable->insert(pScriptFile, true);
// Ignore no change,
if (pScriptFile == mScriptFile)
return;
// Update.
mScriptFile = getOwned() ? expandAssetFilePath(pScriptFile) : pScriptFile;
@ -165,41 +249,190 @@ void TerrainMaterialAsset::setScriptFile(const char* pScriptFile)
//------------------------------------------------------------------------------
void TerrainMaterialAsset::loadMaterial()
{
if (mMaterialDefinition)
mMaterialDefinition->safeDeleteObject();
if (mFXMaterialDefinition)
mFXMaterialDefinition->safeDeleteObject();
if (mLoadedState == EmbeddedDefinition)
{
if (size() != 0)
{
for (U32 i = 0; i < size(); i++)
{
TerrainMaterial* terrMat = dynamic_cast<TerrainMaterial*>(getObject(i));
if (terrMat)
{
mMaterialDefinition = terrMat;
mLoadedState = Ok;
mMaterialDefinition->setInternalName(getAssetId());
continue;
}
//Otherwise, check if it's our FX material
Material* fxMat = dynamic_cast<Material*>(getObject(i));
if (fxMat)
{
mFXMaterialDefinition = fxMat;
//mMaterialDefinition->setInternalName(getAssetId());
mFXMaterialDefinition->reload();
continue;
}
}
}
if(mLoadedState == Ok)
return;
}
else if ((mLoadedState == ScriptLoaded || mLoadedState == DefinitionAlreadyExists) && mMatDefinitionName != StringTable->EmptyString())
{
TerrainMaterial* matDef;
if (!Sim::findObject(mMatDefinitionName, matDef))
{
Con::errorf("TerrainMaterialAsset: Unable to find the Material %s", mMatDefinitionName);
mLoadedState = BadFileReference;
return;
}
mMaterialDefinition = matDef;
mLoadedState = Ok;
mMaterialDefinition->setInternalName(getAssetId());
return;
}
mLoadedState = Failed;
}
//------------------------------------------------------------------------------
void TerrainMaterialAsset::copyTo(SimObject* object)
{
// Call to parent.
Parent::copyTo(object);
}
StringTableEntry TerrainMaterialAsset::getAssetIdByMaterialName(StringTableEntry matName)
//------------------------------------------------------------------------------
U32 TerrainMaterialAsset::getAssetByMaterialName(StringTableEntry matName, AssetPtr<TerrainMaterialAsset>* matAsset)
{
StringTableEntry materialAssetId = StringTable->EmptyString();
AssetQuery* query = new AssetQuery();
U32 foundCount = AssetDatabase.findAssetType(query, "TerrainMaterialAsset");
if (foundCount == 0)
AssetQuery query;
U32 foundAssetcount = AssetDatabase.findAssetType(&query, "TerrainMaterialAsset");
if (foundAssetcount == 0)
{
//Didn't work, so have us fall back to a placeholder asset
materialAssetId = StringTable->insert("Core_Rendering:noMaterial");
matAsset->setAssetId(TerrainMaterialAsset::smNoTerrainMaterialAssetFallback);
if (matAsset->isNull())
{
//Well that's bad, loading the fallback failed.
Con::warnf("TerrainMaterialAsset::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("TerrainMaterialAsset::getAssetByMaterialName - Finding of associated with aterial name %s failed, and fallback asset reported error of Bad File Reference.", matName);
return AssetErrCode::BadFileReference;
}
Con::warnf("TerrainMaterialAsset::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++)
{
TerrainMaterialAsset* tMatAsset = AssetDatabase.acquireAsset<TerrainMaterialAsset>(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
}
}
//Somehow we failed to bind an asset, so just use the fallback and mark the failure
matAsset->setAssetId(TerrainMaterialAsset::smNoTerrainMaterialAssetFallback);
(*matAsset)->mLoadedState = AssetErrCode::UsingFallback;
return AssetErrCode::UsingFallback;
}
StringTableEntry TerrainMaterialAsset::getAssetIdByMaterialName(StringTableEntry matName)
{
if (matName == StringTable->EmptyString())
return StringTable->EmptyString();
StringTableEntry materialAssetId = TerrainMaterialAsset::smNoTerrainMaterialAssetFallback;
AssetQuery query;
U32 foundCount = AssetDatabase.findAssetType(&query, "TerrainMaterialAsset");
if (foundCount != 0)
{
for (U32 i = 0; i < foundCount; i++)
{
TerrainMaterialAsset* matAsset = AssetDatabase.acquireAsset<TerrainMaterialAsset>(query->mAssetList[i]);
TerrainMaterialAsset* matAsset = AssetDatabase.acquireAsset<TerrainMaterialAsset>(query.mAssetList[i]);
if (matAsset && matAsset->getMaterialDefinitionName() == matName)
{
materialAssetId = matAsset->getAssetId();
AssetDatabase.releaseAsset(query->mAssetList[i]);
AssetDatabase.releaseAsset(query.mAssetList[i]);
break;
}
AssetDatabase.releaseAsset(query->mAssetList[i]);
AssetDatabase.releaseAsset(query.mAssetList[i]);
}
}
return materialAssetId;
}
U32 TerrainMaterialAsset::getAssetById(StringTableEntry assetId, AssetPtr<TerrainMaterialAsset>* materialAsset)
{
(*materialAsset) = assetId;
if (materialAsset->notNull())
{
return (*materialAsset)->mLoadedState;
}
else
{
//Didn't work, so have us fall back to a placeholder asset
materialAsset->setAssetId(TerrainMaterialAsset::smNoTerrainMaterialAssetFallback);
if (materialAsset->isNull())
{
//Well that's bad, loading the fallback failed.
Con::warnf("TerrainMaterialAsset::getAssetById - Finding of asset with id %s failed with no fallback asset", assetId);
return AssetErrCode::Failed;
}
//handle noshape not being loaded itself
if ((*materialAsset)->mLoadedState == BadFileReference)
{
Con::warnf("TerrainMaterialAsset::getAssetById - Finding of asset with id %s failed, and fallback asset reported error of Bad File Reference.", assetId);
return AssetErrCode::BadFileReference;
}
Con::warnf("TerrainMaterialAsset::getAssetById - Finding of asset with id %s failed, utilizing fallback asset", assetId);
(*materialAsset)->mLoadedState = AssetErrCode::UsingFallback;
return AssetErrCode::UsingFallback;
}
}
SimObjectPtr<TerrainMaterial> TerrainMaterialAsset::findMaterialDefinitionByAssetId(StringTableEntry assetId)
{
SimSet* terrainMatSet;
if (!Sim::findObject("TerrainMaterialSet", terrainMatSet))
{
return nullptr;
}
SimObjectPtr<TerrainMaterial> matDef = dynamic_cast<TerrainMaterial*>(terrainMatSet->findObjectByInternalName(assetId));
return matDef;
}
#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"
@ -207,6 +440,48 @@ DefineEngineStaticMethod(TerrainMaterialAsset, getAssetIdByMaterialName, const c
{
return TerrainMaterialAsset::getAssetIdByMaterialName(StringTable->insert(materialName));
}
//MaterialAsset::findMaterialDefinitionByAssetId("Prototyping:Detail")
DefineEngineStaticMethod(TerrainMaterialAsset, findMaterialDefinitionByAssetId, S32, (const char* assetId), (""),
"Queries the MaterialSet to see if any MaterialDefinition exists that is associated to the provided assetId.\n"
"@return The MaterialDefinition Id associated to the assetId, if any")
{
SimObjectPtr<TerrainMaterial> matDef = TerrainMaterialAsset::findMaterialDefinitionByAssetId(StringTable->insert(assetId));
if (matDef.isNull())
return SimObjectId(0);
else
return matDef->getId();
}
DefineEngineMethod(TerrainMaterialAsset, getScriptPath, const char*, (), ,
"Queries the Asset Database to see if any asset exists that is associated with the provided material name.\n"
"@return The AssetId of the associated asset, if any.")
{
return object->getScriptPath();
}
DefineEngineMethod(TerrainMaterialAsset, getMaterialDefinition, S32, (), ,
"Queries the Asset Database to see if any asset exists that is associated with the provided material name.\n"
"@return The AssetId of the associated asset, if any.")
{
SimObjectPtr<TerrainMaterial> mat = object->getMaterialDefinition();
if (mat.isValid())
return mat->getId();
else
return 0;
}
DefineEngineMethod(TerrainMaterialAsset, getFXMaterialDefinition, S32, (), ,
"Queries the Asset Database to see if any asset exists that is associated with the provided material name.\n"
"@return The AssetId of the associated asset, if any.")
{
SimObjectPtr<Material> mat = object->getFXMaterialDefinition();
if (mat.isValid())
return mat->getId();
else
return 0;
}
#endif
//-----------------------------------------------------------------------------
// GuiInspectorTypeAssetId
@ -230,68 +505,36 @@ void GuiInspectorTypeTerrainMaterialAssetPtr::consoleInit()
GuiControl* GuiInspectorTypeTerrainMaterialAssetPtr::constructEditControl()
{
// Create base filename edit controls
mUseHeightOverride = true;
mHeightOverride = 100;
mMatEdContainer = new GuiControl();
mMatEdContainer->registerObject();
addObject(mMatEdContainer);
// Create "Open in ShapeEditor" button
mMatPreviewButton = new GuiBitmapButtonCtrl();
const char* matAssetId = getData();
TerrainMaterialAsset* matAsset = AssetDatabase.acquireAsset< TerrainMaterialAsset>(matAssetId);
TerrainMaterial* materialDef = nullptr;
char bitmapName[512] = "ToolsModule:material_editor_n_image";
/*if (!Sim::findObject(matAsset->getMaterialDefinitionName(), materialDef))
{
Con::errorf("GuiInspectorTypeTerrainMaterialAssetPtr::constructEditControl() - unable to find material in asset");
}
else
{
mMatPreviewButton->setBitmap(materialDef->mDiffuseMapFilename[0]);
}*/
mMatPreviewButton->setPosition(0, 0);
mMatPreviewButton->setExtent(100,100);
GuiControl* retCtrl = Parent::constructEditControl();
if (retCtrl == NULL)
return retCtrl;
// Change filespec
char szBuffer[512];
dSprintf(szBuffer, sizeof(szBuffer), "AssetBrowser.showDialog(\"TerrainMaterialAsset\", \"AssetBrowser.changeAsset\", %d, %s);",
dSprintf(szBuffer, sizeof(szBuffer), "AssetBrowser.showDialog(\"TerrainMaterialAsset\", \"AssetBrowser.changeAsset\", %s, %s);",
mInspector->getIdString(), mCaption);
mMatPreviewButton->setField("Command", szBuffer);
mBrowseButton->setField("Command", szBuffer);
mMatPreviewButton->setDataField(StringTable->insert("Profile"), NULL, "GuiButtonProfile");
mMatPreviewButton->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile");
mMatPreviewButton->setDataField(StringTable->insert("hovertime"), NULL, "1000");
setDataField(StringTable->insert("targetObject"), NULL, mInspector->getInspectObject()->getIdString());
StringBuilder strbld;
strbld.append(matAsset->getMaterialDefinitionName());
strbld.append("\n");
strbld.append("Open this asset in the Material Editor");
// Create "Open in Editor" button
mEditButton = new GuiBitmapButtonCtrl();
mMatPreviewButton->setDataField(StringTable->insert("tooltip"), NULL, strbld.data());
dSprintf(szBuffer, sizeof(szBuffer), "AssetBrowser.editAsset(%d.getText());", retCtrl->getId());
mEditButton->setField("Command", szBuffer);
_registerEditControl(mMatPreviewButton);
//mMatPreviewButton->registerObject();
mMatEdContainer->addObject(mMatPreviewButton);
char bitmapName[512] = "ToolsModule:material_editor_n_image";
mEditButton->setBitmap(StringTable->insert(bitmapName));
mMatAssetIdTxt = new GuiTextEditCtrl();
mMatAssetIdTxt->registerObject();
mMatAssetIdTxt->setActive(false);
mEditButton->setDataField(StringTable->insert("Profile"), NULL, "GuiButtonProfile");
mEditButton->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile");
mEditButton->setDataField(StringTable->insert("hovertime"), NULL, "1000");
mEditButton->setDataField(StringTable->insert("tooltip"), NULL, "Open this asset in the Terrain Material Editor");
mMatAssetIdTxt->setText(matAssetId);
mEditButton->registerObject();
addObject(mEditButton);
mMatAssetIdTxt->setBounds(100, 0, 150, 18);
mMatEdContainer->addObject(mMatAssetIdTxt);
return mMatEdContainer;
return retCtrl;
}
bool GuiInspectorTypeTerrainMaterialAssetPtr::updateRects()
@ -305,41 +548,32 @@ bool GuiInspectorTypeTerrainMaterialAssetPtr::updateRects()
mEditCtrlRect.set(fieldExtent.x - dividerPos + dividerMargin, 1, dividerPos - dividerMargin - 34, fieldExtent.y);
bool resized = mEdit->resize(mEditCtrlRect.point, mEditCtrlRect.extent);
if (mMatEdContainer != nullptr)
if (mBrowseButton != NULL)
{
mMatPreviewButton->resize(mEditCtrlRect.point, mEditCtrlRect.extent);
mBrowseRect.set(fieldExtent.x - 32, 2, 14, fieldExtent.y - 4);
resized |= mBrowseButton->resize(mBrowseRect.point, mBrowseRect.extent);
}
if (mMatPreviewButton != nullptr)
if (mEditButton != NULL)
{
mMatPreviewButton->resize(Point2I::Zero, Point2I(100, 100));
}
if (mMatAssetIdTxt != nullptr)
{
mMatAssetIdTxt->resize(Point2I(100, 0), Point2I(mEditCtrlRect.extent.x - 100, 18));
RectI shapeEdRect(fieldExtent.x - 16, 2, 14, fieldExtent.y - 4);
resized |= mEditButton->resize(shapeEdRect.point, shapeEdRect.extent);
}
return resized;
}
void GuiInspectorTypeTerrainMaterialAssetPtr::setMaterialAsset(String assetId)
IMPLEMENT_CONOBJECT(GuiInspectorTypeTerrainMaterialAssetId);
ConsoleDocClass(GuiInspectorTypeTerrainMaterialAssetId,
"@brief Inspector field type for Terrain Material Assets\n\n"
"Editor use only.\n\n"
"@internal"
);
void GuiInspectorTypeTerrainMaterialAssetId::consoleInit()
{
mTargetObject->setDataField(mCaption, "", assetId);
Parent::consoleInit();
//force a refresh
SimObject* obj = mInspector->getInspectObject();
mInspector->inspectObject(obj);
}
DefineEngineMethod(GuiInspectorTypeTerrainMaterialAssetPtr, setMaterialAsset, void, (String assetId), (""),
"Gets a particular shape animation asset for this shape.\n"
"@param animation asset index.\n"
"@return Shape Animation Asset.\n")
{
if (assetId == String::EmptyString)
return;
return object->setMaterialAsset(assetId);
ConsoleBaseType::getType(TypeTerrainMaterialAssetId)->setInspectorFieldType("GuiInspectorTypeTerrainMaterialAssetId");
}

View file

@ -47,7 +47,13 @@
#include "gui/editor/guiInspectorTypes.h"
#endif
#ifndef _TERRMATERIAL_H_
#include "terrain/terrMaterial.h"
#endif
#ifndef _MATERIALDEFINITION_H_
#include "materials/materialDefinition.h"
#endif
//-----------------------------------------------------------------------------
class TerrainMaterialAsset : public AssetBase
@ -58,23 +64,55 @@ class TerrainMaterialAsset : public AssetBase
StringTableEntry mScriptPath;
StringTableEntry mMatDefinitionName;
SimObjectPtr<TerrainMaterial> mMaterialDefinition;
SimObjectPtr<Material> mFXMaterialDefinition;
public:
static StringTableEntry smNoTerrainMaterialAssetFallback;
enum TerrainMaterialAssetErrCode
{
ScriptLoaded = AssetErrCode::Extended,
DefinitionAlreadyExists,
EmbeddedDefinition,
Extended
};
public:
TerrainMaterialAsset();
virtual ~TerrainMaterialAsset();
/// Set up some global script interface stuff.
static void consoleInit();
/// Engine.
static void initPersistFields();
virtual void copyTo(SimObject* object);
static StringTableEntry getAssetIdByMaterialName(StringTableEntry matName);
void loadMaterial();
StringTableEntry getMaterialDefinitionName() { return mMatDefinitionName; }
SimObjectPtr<TerrainMaterial> getMaterialDefinition() { return mMaterialDefinition; }
SimObjectPtr<Material> getFXMaterialDefinition() { return mFXMaterialDefinition; }
void setScriptFile(const char* pScriptFile);
inline StringTableEntry getScriptFile(void) const { return mScriptFile; };
inline StringTableEntry getScriptPath(void) const { return mScriptPath; };
/// <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<TerrainMaterialAsset>* materialAsset);
static SimObjectPtr<TerrainMaterial> findMaterialDefinitionByAssetId(StringTableEntry assetId);
static U32 getAssetByMaterialName(StringTableEntry matName, AssetPtr<TerrainMaterialAsset>* matAsset);
/// Declare Console Object.
DECLARE_CONOBJECT(TerrainMaterialAsset);
@ -82,30 +120,40 @@ protected:
virtual void initializeAsset();
virtual void onAssetRefresh(void);
static bool setScriptFile(void *obj, const char *index, const char *data) { static_cast<TerrainMaterialAsset*>(obj)->setScriptFile(data); return false; }
static bool setScriptFile(void *obj, const char *index, const char *data)
{
static_cast<TerrainMaterialAsset*>(obj)->setScriptFile(data);
return false;
}
static const char* getScriptFile(void* obj, const char* data) { return static_cast<TerrainMaterialAsset*>(obj)->getScriptFile(); }
};
DefineConsoleType(TypeTerrainMaterialAssetPtr, TerrainMaterialAsset)
DefineConsoleType(TypeTerrainMaterialAssetId, String)
//-----------------------------------------------------------------------------
// TypeAssetId GuiInspectorField Class
//-----------------------------------------------------------------------------
class GuiInspectorTypeTerrainMaterialAssetPtr : public GuiInspectorField
class GuiInspectorTypeTerrainMaterialAssetPtr : public GuiInspectorTypeFileName
{
typedef GuiInspectorField Parent;
typedef GuiInspectorTypeFileName Parent;
public:
GuiControl* mMatEdContainer;
GuiBitmapButtonCtrl *mMatPreviewButton;
GuiTextEditCtrl *mMatAssetIdTxt;
GuiBitmapButtonCtrl* mEditButton;
DECLARE_CONOBJECT(GuiInspectorTypeTerrainMaterialAssetPtr);
static void consoleInit();
virtual GuiControl* constructEditControl();
virtual bool updateRects();
void setMaterialAsset(String assetId);
};
class GuiInspectorTypeTerrainMaterialAssetId : public GuiInspectorTypeTerrainMaterialAssetPtr
{
typedef GuiInspectorTypeTerrainMaterialAssetPtr Parent;
public:
DECLARE_CONOBJECT(GuiInspectorTypeTerrainMaterialAssetId);
static void consoleInit();
};
#endif // _ASSET_BASE_H_

View file

@ -79,6 +79,8 @@ AssetImportConfig::AssetImportConfig() :
SeparateAnimationPrefix(""),
animTiming("FrameCount"),
animFPS(false),
AlwaysAddShapeAnimationSuffix(true),
AddedShapeAnimationSuffix("_anim"),
GenerateCollisions(false),
GenCollisionType(""),
CollisionMeshPrefix(""),
@ -190,6 +192,8 @@ void AssetImportConfig::initPersistFields()
addField("SeparateAnimationPrefix", TypeRealString, Offset(SeparateAnimationPrefix, AssetImportConfig), "If separating animations out from a source file, what prefix should be added to the names for grouping association");
addField("animTiming", TypeRealString, Offset(animTiming, AssetImportConfig), "Defines the animation timing for the given animation sequence. Options are FrameTime, Seconds, Milliseconds");
addField("animFPS", TypeBool, Offset(animFPS, AssetImportConfig), "The FPS of the animation sequence");
addField("AlwaysAddShapeAnimationSuffix", TypeBool, Offset(AlwaysAddShapeAnimationSuffix, AssetImportConfig), "When importing a shape animation, this indicates if it should automatically add a standard suffix onto the name");
addField("AddedShapeAnimationSuffix", TypeString, Offset(AddedShapeAnimationSuffix, AssetImportConfig), " If AlwaysAddShapeAnimationSuffix is on, this is the suffix to be added");
endGroup("Animation");
addGroup("Collision");
@ -287,6 +291,8 @@ void AssetImportConfig::loadImportConfig(Settings* configSettings, String config
SeparateAnimationPrefix = configSettings->value(String(configName + "/Animations/SeparateAnimationPrefix").c_str());
animTiming = configSettings->value(String(configName + "/Animations/animTiming").c_str());
animFPS = dAtof(configSettings->value(String(configName + "/Animations/animFPS").c_str()));
AlwaysAddShapeAnimationSuffix = dAtob(configSettings->value(String(configName + "/Animations/AlwaysAddShapeAnimationSuffix").c_str()));
AddedShapeAnimationSuffix = configSettings->value(String(configName + "/Animations/AddedShapeAnimationSuffix").c_str());
//Collisions
GenerateCollisions = dAtob(configSettings->value(String(configName + "/Collision/GenerateCollisions").c_str()));
@ -379,6 +385,8 @@ void AssetImportConfig::CopyTo(AssetImportConfig* target) const
target->SeparateAnimationPrefix = SeparateAnimationPrefix;
target->animTiming = animTiming;
target->animFPS = animFPS;
target->AlwaysAddShapeAnimationSuffix = AlwaysAddShapeAnimationSuffix;
target->AddedShapeAnimationSuffix = AddedShapeAnimationSuffix;
//Collisions
target->GenerateCollisions = GenerateCollisions;
@ -609,14 +617,32 @@ AssetImportObject* AssetImporter::addImportingAsset(String assetType, Torque::Pa
assetImportObj->registerObject();
//sanitize
assetName.replace(' ', '_');
assetName.replace('~', '_');
assetName.replace('`', '_');
assetName.replace('-', '_');
assetName.replace('*', '_');
assetName.replace('-', '_');
assetName.replace('+', '_');
assetName.replace('&', '_');
String processedString = assetName;
U32 start;
U32 end;
String firstNumber = String::GetFirstNumber(processedString, start, end);
if (!firstNumber.isEmpty() && processedString.startsWith(firstNumber.c_str()))
processedString = processedString.replace(firstNumber, "");
processedString = processedString.replace(" ", "_");
U32 len = processedString.length() + 1;
char* sanitizedStr = Con::getReturnBuffer(len);
dStrcpy(sanitizedStr, processedString.c_str(), len);
U32 pos = dStrcspn(sanitizedStr, "-+*/%$&<26>=()[].?\\\"#,;!~<>|<7C>^{}");
while (pos < dStrlen(sanitizedStr))
{
dStrcpy(sanitizedStr + pos, sanitizedStr + pos + 1, len - pos);
pos = dStrcspn(sanitizedStr, "-+*/%$&<26>=()[].?\\\"#,;!~<>|<7C>^{}");
}
//If we did, indeed, modify the name, update it now
if (String(sanitizedStr) != assetName)
{
assetName = sanitizedStr;
}
assetImportObj->assetType = assetType;
assetImportObj->filePath = filePath;
@ -1513,13 +1539,15 @@ void AssetImporter::processImportAssets(AssetImportObject* assetItem)
{
processMaterialAsset(item);
}
/*else if (item->assetType == String("ShapeAnimationAsset"))
ShapeAnimationAsset::prepareAssetForImport(this, item);*/
else if (item->assetType == String("ShapeAnimationAsset"))
{
processShapeAnimationAsset(item);
}
else
{
String processCommand = "process";
processCommand += item->assetType;
if(isMethod(processCommand.c_str()))
if (isMethod(processCommand.c_str()))
Con::executef(this, processCommand.c_str(), item);
}
@ -1605,7 +1633,7 @@ void AssetImporter::processImageAsset(AssetImportObject* assetItem)
{
String diffuseToken = StringUnit::getUnit(activeImportConfig->DiffuseTypeSuffixes, 0, ",;\t");
assetItem->assetName = assetItem->assetName + diffuseToken;
assetItem->cleanAssetName = assetItem->assetName;
//assetItem->cleanAssetName = assetItem->assetName;
}
else
{
@ -1614,7 +1642,7 @@ void AssetImporter::processImageAsset(AssetImportObject* assetItem)
if ((materialAsset && materialAsset->assetName.compare(assetItem->assetName) == 0) || activeImportConfig->AlwaysAddImageSuffix)
{
assetItem->assetName = assetItem->assetName + activeImportConfig->AddedImageSuffix;
assetItem->cleanAssetName = assetItem->assetName;
//assetItem->cleanAssetName = assetItem->assetName;
}
}
@ -1645,8 +1673,8 @@ void AssetImporter::processImageAsset(AssetImportObject* assetItem)
if(assetItem->assetName == assetItem->cleanAssetName && activeImportConfig->AlwaysAddImageSuffix)
{
assetItem->assetName = assetItem->assetName + activeImportConfig->AddedImageSuffix;
assetItem->cleanAssetName = assetItem->assetName;
if (!assetItem->assetName.endsWith(activeImportConfig->AddedImageSuffix.c_str()))
assetItem->assetName = assetItem->assetName + activeImportConfig->AddedImageSuffix;
}
assetItem->importStatus = AssetImportObject::Processed;
@ -1699,7 +1727,8 @@ void AssetImporter::processMaterialAsset(AssetImportObject* assetItem)
//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);
Material* mat;
Sim::findObject(assetName, mat);
if (!mat)
mat = MATMGR->getMaterialDefinitionByMapTo(assetName);
@ -1724,8 +1753,8 @@ void AssetImporter::processMaterialAsset(AssetImportObject* assetItem)
{
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(!assetItem->assetName.endsWith(activeImportConfig->AddedMaterialSuffix.c_str()))
assetItem->assetName += activeImportConfig->AddedMaterialSuffix;
}
if (activeImportConfig->PopulateMaterialMaps)
@ -1908,7 +1937,7 @@ void AssetImporter::processMaterialAsset(AssetImportObject* assetItem)
if (newImageAssetObj->assetName == assetItem->assetName)
{
newImageAssetObj->assetName += StringUnit::getUnit(suffixList.c_str(), 0, ",;\t");
newImageAssetObj->cleanAssetName = newImageAssetObj->assetName;
//newImageAssetObj->cleanAssetName = newImageAssetObj->assetName;
}
newImageAssetObj->imageSuffixType = ImageAsset::getImageTypeNameFromType(ImageAsset::ImageTypes::Albedo);
@ -1926,7 +1955,7 @@ void AssetImporter::processMaterialAsset(AssetImportObject* assetItem)
if (matchedImageTypes[t]->assetName == assetItem->assetName)
{
matchedImageTypes[t]->assetName += StringUnit::getUnit(suffixList.c_str(), 0, ",;\t");
matchedImageTypes[t]->cleanAssetName = matchedImageTypes[t]->assetName;
//matchedImageTypes[t]->cleanAssetName = matchedImageTypes[t]->assetName;
}
}
}
@ -1972,8 +2001,8 @@ void AssetImporter::processShapeAsset(AssetImportObject* assetItem)
if (activeImportConfig->AlwaysAddShapeSuffix)
{
assetItem->assetName += activeImportConfig->AddedShapeSuffix;
assetItem->cleanAssetName = assetItem->assetName;
if(!assetItem->assetName.endsWith(activeImportConfig->AddedShapeSuffix.c_str()))
assetItem->assetName += activeImportConfig->AddedShapeSuffix;
}
S32 meshCount = dAtoi(assetItem->shapeInfo->getDataField(StringTable->insert("_meshCount"), nullptr));
@ -2030,6 +2059,73 @@ void AssetImporter::processShapeAsset(AssetImportObject* assetItem)
assetItem->importStatus = AssetImportObject::Processed;
}
void AssetImporter::processShapeAnimationAsset(AssetImportObject* assetItem)
{
dSprintf(importLogBuffer, sizeof(importLogBuffer), "Preparing Shape Animation for Import: %s", assetItem->assetName.c_str());
activityLog.push_back(importLogBuffer);
String filePath = assetItem->filePath.getFullPath();
String fileName = assetItem->filePath.getFileName();
String fileExt = assetItem->filePath.getExtension();
if (assetItem->shapeInfo == nullptr)
{
GuiTreeViewCtrl* shapeInfo = new GuiTreeViewCtrl();
shapeInfo->registerObject();
if (fileExt.compare("dae") == 0)
{
enumColladaForImport(filePath, shapeInfo, false);
}
else if (fileExt.compare("dts") == 0 || fileExt.compare("dsq") == 0)
{
enumDTSForImport(filePath, shapeInfo);
}
else
{
// Check if a cached DTS is available => no need to import the source file
// if we can load the DTS instead
AssimpShapeLoader loader;
loader.fillGuiTreeView(filePath.c_str(), shapeInfo);
}
assetItem->shapeInfo = shapeInfo;
}
if (activeImportConfig->AlwaysAddShapeAnimationSuffix)
{
if (!assetItem->assetName.endsWith(activeImportConfig->AddedShapeAnimationSuffix.c_str()))
assetItem->assetName += activeImportConfig->AddedShapeAnimationSuffix;
}
S32 animCount = dAtoi(assetItem->shapeInfo->getDataField(StringTable->insert("_animCount"), nullptr));
dSprintf(importLogBuffer, sizeof(importLogBuffer), " Shape Animation Info: Anim Count: %i", animCount);
activityLog.push_back(importLogBuffer);
AssetImportConfig* cachedConfig = new AssetImportConfig();;
cachedConfig->registerObject();
activeImportConfig->CopyTo(cachedConfig);
if (!activeImportConfig->UseManualShapeConfigRules)
{
//Try and load a sis file if it exists for this format
activeImportConfig->loadSISFile(assetItem->filePath);
}
if (activeImportConfig->ImportAnimations && animCount > 0)
{
}
//restore the cached version just in case we loaded a sis file
cachedConfig->CopyTo(activeImportConfig);
cachedConfig->deleteObject();
assetItem->importStatus = AssetImportObject::Processed;
}
void AssetImporter::processShapeMaterialInfo(AssetImportObject* assetItem, S32 materialItemId)
{
String matName = assetItem->shapeInfo->getItemText(materialItemId);
@ -2099,22 +2195,28 @@ void AssetImporter::processShapeMaterialInfo(AssetImportObject* assetItem, S32 m
String imgFileName = AssetImporter::findImagePath(testFilePath.getPath() + "/" + testFilePath.getFileName());
if (imgFileName.isNotEmpty())
filePath = imgFileName;
else
filePath = Torque::Path(""); //no luck, so we just won't try importing in the image
}
}
matAssetItem = addImportingAsset("MaterialAsset", shapePathBase + "/" + matName, assetItem, matName);
AssetImportObject* imageAssetItem = addImportingAsset("ImageAsset", filePath, matAssetItem, "");
String suffixType;
String suffix = parseImageSuffixes(imageAssetItem->assetName, &suffixType);
if (suffix.isNotEmpty())
if (!filePath.isEmpty())
{
imageAssetItem->imageSuffixType = suffixType;
}
else
{
//we'll assume it's albedo
imageAssetItem->imageSuffixType = "Albedo";
AssetImportObject* imageAssetItem = addImportingAsset("ImageAsset", filePath, matAssetItem, "");
String suffixType;
String suffix = parseImageSuffixes(imageAssetItem->assetName, &suffixType);
if (suffix.isNotEmpty())
{
imageAssetItem->imageSuffixType = suffixType;
}
else
{
//we'll assume it's albedo
imageAssetItem->imageSuffixType = "Albedo";
}
}
}
else
@ -2136,8 +2238,8 @@ void AssetImporter::processSoundAsset(AssetImportObject* assetItem)
if (activeImportConfig->AlwaysAddSoundSuffix)
{
assetItem->assetName += activeImportConfig->AddedSoundSuffix;
assetItem->cleanAssetName = assetItem->assetName;
if (!assetItem->assetName.endsWith(activeImportConfig->AddedSoundSuffix.c_str()))
assetItem->assetName += activeImportConfig->AddedSoundSuffix;
}
assetItem->importStatus = AssetImportObject::Processed;
@ -2164,9 +2266,20 @@ bool AssetImporter::validateAssets()
void AssetImporter::validateAsset(AssetImportObject* assetItem)
{
if (assetItem->importStatus == AssetImportObject::Skipped || assetItem->importStatus == AssetImportObject::NotProcessed)
if (assetItem->importStatus == AssetImportObject::Skipped || assetItem->importStatus == AssetImportObject::NotProcessed
|| assetItem->importStatus == AssetImportObject::UseForDependencies)
return;
//If this item's already been marked as being in error, don't bother with it. It knows what it did.
//This avoids running collision checks on an item already known to have a collision, which could erroneously
//mark the original, not-colliding item as colliding with this item, invaliding both
if (assetItem->status == String("Error") || assetItem->statusType.isNotEmpty())
{
importIssues = true;
return;
}
//Runm this item against our other importing assets and check for any collisions
if (checkAssetForCollision(assetItem))
{
importIssues = true;
@ -2270,7 +2383,7 @@ bool AssetImporter::checkAssetForCollision(AssetImportObject* assetItemToCheck,
{
AssetImportObject* importingAsset = itemList[i];
if (importingAsset->importStatus == AssetImportObject::Skipped)
if (importingAsset->importStatus == AssetImportObject::Skipped || importingAsset->importStatus == AssetImportObject::UseForDependencies)
continue;
if ((assetItemToCheck->assetName.compare(importingAsset->assetName) == 0) && (assetItemToCheck->getId() != importingAsset->getId()))
@ -2506,11 +2619,16 @@ StringTableEntry AssetImporter::autoImportFile(Torque::Path filePath, String typ
else
{
importAssets();
acquireAssets();
}
dumpActivityLog();
if (hasIssues)
if (hasIssues ||
assetItem->importStatus == AssetImportObject::Skipped ||
assetItem->importStatus == AssetImportObject::UseForDependencies ||
assetItem->importStatus == AssetImportObject::Error)
{
return StringTable->EmptyString();
}
@ -2560,6 +2678,10 @@ void AssetImporter::importAssets(AssetImportObject* assetItem)
{
assetPath = importMaterialAsset(item);
}
else if (item->assetType == String("ShapeAnimationAsset"))
{
assetPath = importShapeAnimationAsset(item);
}
else
{
finalImportedAssetPath = String::EmptyString;
@ -2601,7 +2723,7 @@ void AssetImporter::importAssets(AssetImportObject* assetItem)
else
{
//Any special-case post-reg stuff here
if (item->assetType == String("ShapeAsset"))
if (item->assetType == String("ShapeAsset") || item->assetType == String("ShapeAnimationAsset"))
{
//forcefully update it's shape constructor
TSShapeConstructor* tss = TSShapeConstructor::findShapeConstructorByAssetId(assetId);
@ -2610,10 +2732,6 @@ void AssetImporter::importAssets(AssetImportObject* assetItem)
tss->setShapeAssetId(assetId);
}
}
//Go ahead and force the asset to load now just to kick it for immediate use
AssetBase* assetDef = AssetDatabase.acquireAsset<AssetBase>(assetId);
AssetDatabase.releaseAsset(assetId);
}
else
{
@ -2638,6 +2756,34 @@ void AssetImporter::importAssets(AssetImportObject* assetItem)
dumpActivityLog();
}
void AssetImporter::acquireAssets(AssetImportObject* assetItem)
{
Vector<AssetImportObject*> itemList = importingAssets;
if (assetItem != nullptr)
itemList = assetItem->childAssetItems;
for (U32 i = 0; i < itemList.size(); i++)
{
AssetImportObject* item = itemList[i];
if (item->importStatus == AssetImportObject::Skipped ||
item->importStatus == AssetImportObject::NotProcessed ||
item->importStatus == AssetImportObject::Error)
continue;
//recurse if needed, we want to process child items first for dependency reasons
acquireAssets(item);
//Go ahead and force the asset to load now just to kick it for immediate use
String assetId = item->moduleName + ":" + item->assetName;
if (AssetDatabase.isDeclaredAsset(assetId))
{
AssetBase* assetDef = AssetDatabase.acquireAsset<AssetBase>(assetId);
AssetDatabase.releaseAsset(assetId);
}
}
}
//
// Type-specific import logic
//
@ -2673,7 +2819,7 @@ Torque::Path AssetImporter::importImageAsset(AssetImportObject* assetItem)
//If it's not a re-import, check that the file isn't being in-place imported. If it isn't, store off the original
//file path for reimporting support later
if (!isReimport && String::compare(qualifiedFromFile, qualifiedToFile))
if (!isReimport && String::compare(qualifiedFromFile, qualifiedToFile) && Torque::FS::isFile(qualifiedFromFile))
{
newAsset->setDataField(StringTable->insert("originalFilePath"), nullptr, qualifiedFromFile);
}
@ -2724,8 +2870,6 @@ Torque::Path AssetImporter::importMaterialAsset(AssetImportObject* assetItem)
StringTableEntry assetName = StringTable->insert(assetItem->assetName.c_str());
String tamlPath = targetPath + "/" + assetName + ".asset.taml";
String scriptName = assetItem->assetName + "." TORQUE_SCRIPT_EXTENSION;
String scriptPath = targetPath + "/" + scriptName;
String originalPath = assetItem->filePath.getFullPath().c_str();
char qualifiedFromFile[2048];
@ -2737,10 +2881,13 @@ Torque::Path AssetImporter::importMaterialAsset(AssetImportObject* assetItem)
#endif
newAsset->setAssetName(assetName);
newAsset->setScriptFile(scriptName.c_str());
if (!isReimport && Torque::FS::isFile(qualifiedFromFile))
{
newAsset->setDataField(StringTable->insert("originalFilePath"), nullptr, qualifiedFromFile);
}
newAsset->setDataField(StringTable->insert("materialDefinitionName"), nullptr, assetName);
//iterate through and write out the material maps dependencies
S32 dependencySlotId = 0;
@ -2762,16 +2909,6 @@ Torque::Path AssetImporter::importMaterialAsset(AssetImportObject* assetItem)
dependencySlotId++;
}
Taml tamlWriter;
bool importSuccessful = tamlWriter.write(newAsset, tamlPath.c_str());
if (!importSuccessful)
{
dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Unable to write asset taml file %s", tamlPath.c_str());
activityLog.push_back(importLogBuffer);
return "";
}
//build the ORMConfig file if we're flagged to and have valid image maps
if (activeImportConfig->CreateORMConfig)
{
@ -2810,109 +2947,12 @@ Torque::Path AssetImporter::importMaterialAsset(AssetImportObject* assetItem)
}
}
FileObject* file = new FileObject();
file->registerObject();
if (activeImportConfig->UseExistingMaterials && Torque::FS::IsFile(qualifiedFromFile))
//If we're not using existing materials, or the material in question doesn't actually already exist, spool it up
if (!activeImportConfig->UseExistingMaterials || !Sim::findObject(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);
//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)
{
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->canImport() || 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 = "MetalMap";
}
else if (imageType == ImageAsset::ImageTypes::AO)
{
mapFieldName = "AOMap";
}
else if (imageType == ImageAsset::ImageTypes::Roughness)
{
mapFieldName = "RoughMap";
}
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;
}
}
else if (file->openForWrite(scriptPath.c_str()))
{
file->writeLine((U8*)"//--- OBJECT WRITE BEGIN ---");
char lineBuffer[1024];
dSprintf(lineBuffer, 1024, "singleton Material(%s) {", assetName);
file->writeLine((U8*)lineBuffer);
dSprintf(lineBuffer, 1024, " mapTo=\"%s\";", assetName);
file->writeLine((U8*)lineBuffer);
Material* newMat = new Material();
newMat->registerObject(assetName);
newMat->mMapTo = assetItem->cleanAssetName;
bool hasRoughness = false;
for (U32 i = 0; i < assetItem->childAssetItems.size(); i++)
@ -2922,63 +2962,58 @@ Torque::Path AssetImporter::importMaterialAsset(AssetImportObject* assetItem)
if ((!childItem->canImport() && childItem->importStatus != AssetImportObject::UseForDependencies) || childItem->assetType.compare("ImageAsset") != 0)
continue;
String mapFieldName = "";
String assetFieldName = "";
ImageAsset::ImageTypes imageType = ImageAsset::getImageTypeFromName(childItem->imageSuffixType);
String assetMapFillIn = targetModuleId + ":" + childItem->assetName;
StringTableEntry assetMapFillInStr = StringTable->insert(assetMapFillIn.c_str());
if (imageType == ImageAsset::ImageTypes::Albedo || childItem->imageSuffixType.isEmpty())
{
mapFieldName = "DiffuseMap";
newMat->mDiffuseMapAssetId[0] = assetMapFillInStr;
}
else if (imageType == ImageAsset::ImageTypes::Normal)
{
mapFieldName = "NormalMap";
newMat->mNormalMapAssetId[0] = assetMapFillInStr;
}
else if (imageType == ImageAsset::ImageTypes::ORMConfig)
{
mapFieldName = "ORMConfigMap";
newMat->mORMConfigMapAssetId[0] = assetMapFillInStr;
}
else if (imageType == ImageAsset::ImageTypes::Metalness)
{
mapFieldName = "MetalMap";
newMat->mMetalMapAssetId[0] = assetMapFillInStr;
}
else if (imageType == ImageAsset::ImageTypes::AO)
{
mapFieldName = "AOMap";
newMat->mAOMapAssetId[0] = assetMapFillInStr;
}
else if (imageType == ImageAsset::ImageTypes::Roughness)
{
mapFieldName = "RoughMap";
newMat->mRoughMapAssetId[0] = assetMapFillInStr;
hasRoughness = true;
}
assetFieldName = mapFieldName + "Asset";
assetFieldName += "[0]";
//String path = childItem->filePath.getFullFileName();
//dSprintf(lineBuffer, 1024, " %s = \"%s\";", mapFieldName.c_str(), path.c_str());
//file->writeLine((U8*)lineBuffer);
dSprintf(lineBuffer, 1024, " %s = \"%s:%s\";", assetFieldName.c_str(), targetModuleId.c_str(), childItem->assetName.c_str());
file->writeLine((U8*)lineBuffer);
}
if (hasRoughness)
{
file->writeLine((U8*)" invertSmoothness = true;");
newMat->mInvertRoughness[0] = true;
}
file->writeLine((U8*)"};");
file->writeLine((U8*)"//--- OBJECT WRITE END ---");
file->close();
newAsset->addObject(newMat);
}
else
else
{
dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Unable to write asset script file %s", scriptPath.c_str());
dSprintf(importLogBuffer, sizeof(importLogBuffer), "Set to use an existing material, so avoiding writing a material definition to new asset definition for material: %s", assetName);
activityLog.push_back(importLogBuffer);
return "";
}
Taml tamlWriter;
bool importSuccessful = tamlWriter.write(newAsset, tamlPath.c_str());
if (!importSuccessful)
{
dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Unable to write asset taml file %s", tamlPath.c_str());
activityLog.push_back(importLogBuffer);
return "";
}
@ -3037,7 +3072,7 @@ Torque::Path AssetImporter::importShapeAsset(AssetImportObject* assetItem)
//If it's not a re-import, check that the file isn't being in-place imported. If it isn't, store off the original
//file path for reimporting support later
if (!isReimport && String::compare(qualifiedFromFile, qualifiedToFile))
if (!isReimport && String::compare(qualifiedFromFile, qualifiedToFile) && Torque::FS::isFile(qualifiedFromFile))
{
newAsset->setDataField(StringTable->insert("originalFilePath"), nullptr, qualifiedFromFile);
}
@ -3317,7 +3352,7 @@ Torque::Path AssetImporter::importSoundAsset(AssetImportObject* assetItem)
//If it's not a re-import, check that the file isn't being in-place imported. If it isn't, store off the original
//file path for reimporting support later
if (!isReimport && String::compare(qualifiedFromFile, qualifiedToFile))
if (!isReimport && String::compare(qualifiedFromFile, qualifiedToFile) && Torque::FS::isFile(qualifiedFromFile))
{
newAsset->setDataField(StringTable->insert("originalFilePath"), nullptr, qualifiedFromFile);
}
@ -3378,7 +3413,7 @@ Torque::Path AssetImporter::importShapeAnimationAsset(AssetImportObject* assetIt
//If it's not a re-import, check that the file isn't being in-place imported. If it isn't, store off the original
//file path for reimporting support later
if (!isReimport && String::compare(qualifiedFromFile, qualifiedToFile))
if (!isReimport && String::compare(qualifiedFromFile, qualifiedToFile) && Torque::FS:::isFile(qualifiedFromFile))
{
newAsset->setDataField(StringTable->insert("originalFilePath"), nullptr, qualifiedFromFile);
}

View file

@ -261,6 +261,16 @@ public:
/// </summary>
F32 animFPS;
/// <summary>
/// When importing a shape animation, this indicates if it should automatically add a standard suffix onto the name
/// </summary>
bool AlwaysAddShapeAnimationSuffix;
/// <summary>
/// If AlwaysAddShapeAnimationSuffix is on, this is the suffix to be added
/// </summary>
String AddedShapeAnimationSuffix;
//
//Collision
/// <summary>
@ -800,11 +810,17 @@ public:
void processMaterialAsset(AssetImportObject* assetItem);
/// <summary>
/// Process a specific AssetImportObject that is an ShapeAsset type to prepare it for importing
/// Process a specific AssetImportObject that is an ShapeAnimationAsset type to prepare it for importing
/// <para>@param assetItem, The AssetImportObject to process</para>
/// </summary>
void processShapeAsset(AssetImportObject* assetItem);
/// <summary>
/// Process a specific AssetImportObject that is an ShapeAsset type to prepare it for importing
/// <para>@param assetItem, The AssetImportObject to process</para>
/// </summary>
void processShapeAnimationAsset(AssetImportObject* assetItem);
/// <summary>
/// Process a specific ShapeAsset AssetImportObject with a material id in order to parse and handle the materials listed in the shape file
/// <para>@param assetItem, The AssetImportObject to process</para>
@ -898,6 +914,12 @@ public:
/// </summary>
Torque::Path importShapeAnimationAsset(AssetImportObject* assetItem);
/// <summary>
/// Iterates over all the items in the current session and acquires them, which jumpstarts the loading/init'ng process on them, making the available for use immediately
/// <para>@param assetItem, if null, will loop over and recurse the main import asset items, if a specific AssetImportObject is passed in, it will recurse it's children</para>
/// </summary>
void acquireAssets(AssetImportObject* assetItem = nullptr);
//
/// <summary>
/// Gets the currently active import configuration

View file

@ -92,7 +92,9 @@ DefineEngineMethod(AssetImporter, resolveAssetItemIssues, void, (AssetImportObje
DefineEngineMethod(AssetImporter, importAssets, void, (),,
"Runs the actual import action on the items.")
{
return object->importAssets();
object->importAssets();
object->acquireAssets();
}
DefineEngineMethod(AssetImporter, getAssetItemCount, S32, (),,