From ca1604170ddb4e6f81bcd51131a13da59b01f39e Mon Sep 17 00:00:00 2001 From: marauder2k7 Date: Thu, 19 Jun 2025 13:34:07 +0100 Subject: [PATCH] initial commit change the macro to use the refactor (exact same structure as the imageasset macro) --- Engine/source/T3D/assets/ShapeAsset.cpp | 81 ++++- Engine/source/T3D/assets/ShapeAsset.h | 195 +++++++++++ Engine/source/T3D/debris.cpp | 28 +- Engine/source/T3D/debris.h | 8 +- .../T3D/examples/renderShapeExample.cpp | 19 +- .../source/T3D/examples/renderShapeExample.h | 7 +- Engine/source/T3D/missionMarker.cpp | 8 +- Engine/source/T3D/player.cpp | 38 +- Engine/source/T3D/proximityMine.cpp | 6 +- Engine/source/T3D/rigidShape.cpp | 2 +- Engine/source/T3D/shapeBase.cpp | 325 +++++++++--------- Engine/source/T3D/shapeBase.h | 31 +- Engine/source/T3D/shapeImage.cpp | 56 ++- Engine/source/T3D/tsStatic.cpp | 113 +++--- Engine/source/T3D/tsStatic.h | 13 +- Engine/source/T3D/turret/aiTurretShape.cpp | 6 +- Engine/source/T3D/turret/turretShape.cpp | 20 +- Engine/source/T3D/vehicles/flyingVehicle.cpp | 4 +- Engine/source/T3D/vehicles/hoverVehicle.cpp | 2 +- Engine/source/T3D/vehicles/vehicle.cpp | 2 +- Engine/source/T3D/vehicles/wheeledVehicle.cpp | 33 +- Engine/source/T3D/vehicles/wheeledVehicle.h | 8 +- Engine/source/afx/afxMagicMissile.cpp | 17 +- Engine/source/afx/afxMagicMissile.h | 16 +- Engine/source/afx/ce/afxModel.cpp | 60 ++-- Engine/source/afx/ce/afxModel.h | 19 +- Engine/source/afx/ce/afxStaticShape.h | 2 +- Engine/source/environment/VolumetricFog.cpp | 32 +- Engine/source/environment/VolumetricFog.h | 6 +- 29 files changed, 700 insertions(+), 457 deletions(-) diff --git a/Engine/source/T3D/assets/ShapeAsset.cpp b/Engine/source/T3D/assets/ShapeAsset.cpp index ff27573cc..decc7258a 100644 --- a/Engine/source/T3D/assets/ShapeAsset.cpp +++ b/Engine/source/T3D/assets/ShapeAsset.cpp @@ -117,6 +117,54 @@ ConsoleSetType(TypeShapeAssetId) //----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +// REFACTOR +//----------------------------------------------------------------------------- + +IMPLEMENT_STRUCT(AssetPtr, AssetPtrShapeAsset, , "") +END_IMPLEMENT_STRUCT + +ConsoleType(ShapeAssetPtrRefactor, TypeShapeAssetPtrRefactor, AssetPtr, ASSET_ID_FIELD_PREFIX) + + +ConsoleGetType(TypeShapeAssetPtrRefactor) +{ + // Fetch asset Id. + return (*((AssetPtr*)dptr)).getAssetId(); +} + +ConsoleSetType(TypeShapeAssetPtrRefactor) +{ + // Was a single argument specified? + if (argc == 1) + { + // Yes, so fetch field value. + const char* pFieldValue = argv[0]; + + // Fetch asset pointer. + AssetPtr* pAssetPtr = dynamic_cast*>((AssetPtrBase*)(dptr)); + + // Is the asset pointer the correct type? + if (pAssetPtr == NULL) + { + Con::warnf("(TypeShapeAssetPtrRefactor) - Failed to set asset Id '%d'.", pFieldValue); + return; + } + + // Set asset. + pAssetPtr->setAssetId(pFieldValue); + + return; + } + + // Warn. + Con::warnf("(TypeShapeAssetPtrRefactor) - Cannot set multiple args to a single asset."); +} + +//----------------------------------------------------------------------------- +// REFACTOR END +//----------------------------------------------------------------------------- + const String ShapeAsset::mErrCodeStrings[] = { "TooManyVerts", @@ -478,7 +526,38 @@ StringTableEntry ShapeAsset::getAssetIdByFilename(StringTableEntry fileName) } else { - AssetPtr shapeAsset = shapeAssetId; //ensures the fallback is loaded + foundAssetcount = AssetDatabase.findAssetType(&query, "ShapeAsset"); + if (foundAssetcount != 0) + { + // loop all image assets and see if we can find one + // using the same image file/named target. + for (auto shapeAsset : query.mAssetList) + { + AssetPtr temp = shapeAsset; + if (temp.notNull()) + { + if (temp->getShapePath() == fileName) + { + return shapeAsset; + } + else + { + Torque::Path temp1 = temp->getShapePath(); + Torque::Path temp2 = fileName; + + if (temp1.getPath() == temp2.getPath() && temp1.getFileName() == temp2.getFileName()) + { + return shapeAsset; + } + } + + } + } + } + else + { + AssetPtr shapeAsset = shapeAssetId; //ensures the fallback is loaded + } } return shapeAssetId; diff --git a/Engine/source/T3D/assets/ShapeAsset.h b/Engine/source/T3D/assets/ShapeAsset.h index 2d186346d..1d7b960cd 100644 --- a/Engine/source/T3D/assets/ShapeAsset.h +++ b/Engine/source/T3D/assets/ShapeAsset.h @@ -212,6 +212,9 @@ protected: DefineConsoleType(TypeShapeAssetPtr, S32) DefineConsoleType(TypeShapeAssetId, String) +DECLARE_STRUCT(AssetPtr) +DefineConsoleType(TypeShapeAssetPtrRefactor, AssetPtr) + #ifdef TORQUE_TOOLS //----------------------------------------------------------------------------- // TypeAssetId GuiInspectorField Class @@ -493,4 +496,196 @@ public: \ #pragma endregion + +//----------------------------------------------------------------------------- +// REFACTOR +//----------------------------------------------------------------------------- + +#pragma region Refactor Asset Macros + +#define DECLARE_SHAPEASSET_REFACTOR(className, name) \ +private: \ + AssetPtr m##name##Asset; \ + StringTableEntry m##name##File = StringTable->EmptyString(); \ +public: \ + void _set##name(StringTableEntry _in) { \ + if (m##name##Asset.getAssetId() == _in) \ + return; \ + if(get##name##File() == _in) \ + return; \ + if (_in == NULL || _in == StringTable->EmptyString()) \ + { \ + m##name##Asset = NULL; \ + m##name##File = ""; \ + return; \ + } \ + if (!AssetDatabase.isDeclaredAsset(_in)) \ + { \ + StringTableEntry shapeAssetId = StringTable->EmptyString(); \ + AssetQuery query; \ + S32 foundAssetcount = AssetDatabase.findAssetLooseFile(&query, _in); \ + if (foundAssetcount != 0) \ + { \ + shapeAssetId = query.mAssetList[0]; \ + } \ + else if (Torque::FS::IsFile(_in) || (_in[0] == '$' || _in[0] == '#')) \ + { \ + shapeAssetId = ShapeAsset::getAssetIdByFilename(_in); \ + if (shapeAssetId == ShapeAsset::smNoShapeAssetFallback) \ + { \ + ShapeAsset* privateShape = new ShapeAsset(); \ + privateShape->setShapeFile(_in); \ + shapeAssetId = AssetDatabase.addPrivateAsset(privateShape); \ + } \ + } \ + else \ + { \ + Con::warnf("%s::%s: Could not find asset for: %s using fallback", #className, #name, _in); \ + shapeAssetId = ShapeAsset::smNoShapeAssetFallback; \ + } \ + m##name##Asset = shapeAssetId; \ + m##name##File = _in; \ + } \ + else \ + { \ + m##name##Asset = _in; \ + m##name##File = get##name##File(); \ + } \ + }; \ + \ + inline StringTableEntry _get##name##AssetId(void) const { return m##name##Asset.getAssetId(); } \ + Resource get##name() { if (m##name##Asset.notNull()) return m##name##Asset->getShapeResource(); else return NULL; } \ + AssetPtr get##name##Asset(void) { return m##name##Asset; } \ + static bool _set##name##Data(void* obj, const char* index, const char* data) { static_cast(obj)->_set##name(_getStringTable()->insert(data)); return false; } \ + StringTableEntry get##name##File() { return m##name##Asset.notNull() ? m##name##Asset->getShapePath() : ""; } + +#define DECLARE_SHAPEASSET_NET_REFACTOR(className, name, mask) \ +private: \ + AssetPtr m##name##Asset; \ + StringTableEntry m##name##File = StringTable->EmptyString(); \ +public: \ + void _set##name(StringTableEntry _in) { \ + if (m##name##Asset.getAssetId() == _in) \ + return; \ + if(get##name##File() == _in) \ + return; \ + if (_in == NULL || _in == StringTable->EmptyString()) \ + { \ + m##name##Asset = NULL; \ + m##name##File = ""; \ + setMaskBits(mask); \ + return; \ + } \ + if (!AssetDatabase.isDeclaredAsset(_in)) \ + { \ + StringTableEntry shapeAssetId = StringTable->EmptyString(); \ + AssetQuery query; \ + S32 foundAssetcount = AssetDatabase.findAssetLooseFile(&query, _in); \ + if (foundAssetcount != 0) \ + { \ + shapeAssetId = query.mAssetList[0]; \ + } \ + else if (Torque::FS::IsFile(_in) || (_in[0] == '$' || _in[0] == '#')) \ + { \ + shapeAssetId = ShapeAsset::getAssetIdByFilename(_in); \ + if (shapeAssetId == ShapeAsset::smNoShapeAssetFallback) \ + { \ + ShapeAsset* privateShape = new ShapeAsset(); \ + privateShape->setShapeFile(_in); \ + shapeAssetId = AssetDatabase.addPrivateAsset(privateShape); \ + } \ + } \ + else \ + { \ + Con::warnf("%s::%s: Could not find asset for: %s using fallback", #className, #name, _in); \ + shapeAssetId = ShapeAsset::smNoShapeAssetFallback; \ + } \ + m##name##Asset = shapeAssetId; \ + m##name##File = _in; \ + } \ + else \ + { \ + m##name##Asset = _in; \ + m##name##File = get##name##File(); \ + } \ + setMaskBits(mask); \ + }; \ + \ + inline StringTableEntry _get##name##AssetId(void) const { return m##name##Asset.getAssetId(); } \ + Resource get##name() { if (m##name##Asset.notNull()) return m##name##Asset->getShapeResource(); else return NULL; } \ + AssetPtr get##name##Asset(void) { return m##name##Asset; } \ + static bool _set##name##Data(void* obj, const char* index, const char* data) { static_cast(obj)->_set##name(_getStringTable()->insert(data)); return false; } \ + StringTableEntry get##name##File() { return m##name##Asset.notNull() ? m##name##Asset->getShapePath() : ""; } + +#define INITPERSISTFIELD_SHAPEASSET_REFACTOR(name, consoleClass, docs) \ + addProtectedField(assetText(name, Asset), TypeShapeAssetPtrRefactor, Offset(m##name##Asset, consoleClass), _set##name##Data, &defaultProtectedGetFn, assetDoc(name, asset docs.)); \ + addProtectedField(assetText(name, File), TypeFilename, Offset(m##name##File, consoleClass), _set##name##Data, &defaultProtectedGetFn, assetDoc(name, file docs.)); + + +#define DECLARE_SHAPEASSET_ARRAY_REFACTOR(className, name, max) \ +private: \ + AssetPtr m##name##Asset[max]; \ + StringTableEntry m##name##File[max] = {StringTable->EmptyString() }; \ +public: \ + void _set##name(StringTableEntry _in, const U32& index){ \ + if (m##name##Asset[index].getAssetId() == _in) \ + return; \ + if(get##name##File(index) == _in) \ + return; \ + if (_in == NULL || _in == StringTable->EmptyString()) \ + { \ + m##name##Asset[index] = NULL; \ + m##name##File[index] = ""; \ + return; \ + } \ + if (!AssetDatabase.isDeclaredAsset(_in)) \ + { \ + StringTableEntry shapeAssetId = StringTable->EmptyString(); \ + AssetQuery query; \ + S32 foundAssetcount = AssetDatabase.findAssetLooseFile(&query, _in); \ + if (foundAssetcount != 0) \ + { \ + shapeAssetId = query.mAssetList[0]; \ + } \ + else if (Torque::FS::IsFile(_in) || (_in[0] == '$' || _in[0] == '#')) \ + { \ + shapeAssetId = ShapeAsset::getAssetIdByFilename(_in); \ + if (shapeAssetId == ShapeAsset::smNoShapeAssetFallback) \ + { \ + ShapeAsset* privateShape = new ShapeAsset(); \ + privateShape->setShapeFile(_in); \ + shapeAssetId = AssetDatabase.addPrivateAsset(privateShape); \ + } \ + } \ + else \ + { \ + Con::warnf("%s::%s: Could not find asset for: %s using fallback", #className, #name, _in); \ + shapeAssetId = ShapeAsset::smNoShapeAssetFallback; \ + } \ + m##name##Asset[index] = shapeAssetId; \ + m##name##File[index] = _in; \ + } \ + else \ + { \ + m##name##Asset[index] = _in; \ + m##name##File[index] = get##name##File(index); \ + } \ + }; \ + \ + inline StringTableEntry _get##name##AssetId(const U32& index) const { return m##name##Asset[index].getAssetId(); } \ + Resource get##name(const U32& index) { if (m##name##Asset[index].notNull()) return m##name##Asset[index]->getShapeResource(); else return NULL; } \ + AssetPtr get##name##Asset(const U32& index) { return m##name##Asset[index]; } \ + static bool _set##name##Data(void* obj, const char* index, const char* data) { static_cast(obj)->_set##name(_getStringTable()->insert(data), dAtoi(index)); return false;}\ + StringTableEntry get##name##File(const U32& idx) { return m##name##Asset[idx].notNull() ? m##name##Asset[idx]->getShapePath() : ""; } + +#define INITPERSISTFIELD_SHAPEASSET_ARRAY_REFACTOR(name, arraySize, consoleClass, docs) \ + addProtectedField(assetText(name, Asset), TypeShapeAssetPtrRefactor, Offset(m##name##Asset, consoleClass), _set##name##Data, &defaultProtectedGetFn, arraySize, assetDoc(name, asset docs.));\ + addProtectedField(assetText(name, File), TypeFilename, Offset(m##name##File, consoleClass), _set##name##Data, &defaultProtectedGetFn, arraySize, assetDoc(name, asset docs.)); + +#pragma endregion + +//----------------------------------------------------------------------------- +// REFACTOR END +//----------------------------------------------------------------------------- + #endif diff --git a/Engine/source/T3D/debris.cpp b/Engine/source/T3D/debris.cpp index 78a1e53cc..b7566ab72 100644 --- a/Engine/source/T3D/debris.cpp +++ b/Engine/source/T3D/debris.cpp @@ -116,7 +116,7 @@ DebrisData::DebrisData() terminalVelocity = 0.0f; ignoreWater = true; - INIT_ASSET(Shape); + mShapeAsset.registerRefreshNotify(this); } //#define TRACK_DEBRIS_DATA_CLONES @@ -152,7 +152,7 @@ DebrisData::DebrisData(const DebrisData& other, bool temp_clone) : GameBaseData( terminalVelocity = other.terminalVelocity; ignoreWater = other.ignoreWater; - CLONE_ASSET(Shape); + mShapeAsset = other.mShapeAsset; textureName = other.textureName; explosionId = other.explosionId; // -- for pack/unpack of explosion ptr @@ -191,7 +191,7 @@ DebrisData* DebrisData::cloneAndPerformSubstitutions(const SimObject* owner, S32 void DebrisData::onPerformSubstitutions() { - _setShape(getShape()); + _setShape(_getShapeAssetId()); } bool DebrisData::onAdd() @@ -276,16 +276,16 @@ bool DebrisData::preload(bool server, String &errorStr) if (mShapeAsset.notNull()) { - if (!mShape) + if (!getShape()) { - errorStr = String::ToString("DebrisData::load: Couldn't load shape \"%s\"", mShapeAssetId); + errorStr = String::ToString("DebrisData::load: Couldn't load shape \"%s\"", _getShapeAssetId()); return false; } else { - TSShapeInstance* pDummy = new TSShapeInstance(mShape, !server); + TSShapeInstance* pDummy = new TSShapeInstance(getShape(), !server); delete pDummy; - if (!server && !mShape->preloadMaterialList(mShape.getPath()) && NetConnection::filesWereDownloaded()) + if (!server && !getShape()->preloadMaterialList(getShape().getPath()) && NetConnection::filesWereDownloaded()) return false; } } @@ -304,7 +304,7 @@ void DebrisData::initPersistFields() addGroup("Shapes"); addField("texture", TypeString, Offset(textureName, DebrisData), "@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."); + INITPERSISTFIELD_SHAPEASSET_REFACTOR(Shape, DebrisData, "Shape to use for this debris object."); endGroup("Shapes"); addGroup("Particle Effects"); @@ -389,7 +389,7 @@ void DebrisData::packData(BitStream* stream) stream->writeString( textureName ); - PACKDATA_ASSET(Shape); + PACKDATA_ASSET_REFACTOR(Shape); for( S32 i=0; ireadSTString(); - UNPACKDATA_ASSET(Shape); + UNPACKDATA_ASSET_REFACTOR(Shape); for( S32 i=0; ifriction; // Setup our bounding box - if( mDataBlock->mShape ) + if( mDataBlock->getShape()) { - mObjBox = mDataBlock->mShape->mBounds; + mObjBox = mDataBlock->getShape()->mBounds; } else { mObjBox = Box3F(Point3F(-1, -1, -1), Point3F(1, 1, 1)); } - if( mDataBlock->mShape) + if( mDataBlock->getShape()) { - mShape = new TSShapeInstance( mDataBlock->mShape, true); + mShape = new TSShapeInstance( mDataBlock->getShape(), true); } if( mPart ) diff --git a/Engine/source/T3D/debris.h b/Engine/source/T3D/debris.h index 1d1116031..9d9065d0b 100644 --- a/Engine/source/T3D/debris.h +++ b/Engine/source/T3D/debris.h @@ -47,7 +47,7 @@ class TSShape; //************************************************************************** // Debris Data //************************************************************************** -struct DebrisData : public GameBaseData +struct DebrisData : public GameBaseData, protected AssetPtrCallback { typedef GameBaseData Parent; @@ -83,8 +83,7 @@ struct DebrisData : public GameBaseData F32 terminalVelocity; // max velocity magnitude bool ignoreWater; - DECLARE_SHAPEASSET(DebrisData, Shape, onShapeChanged); - DECLARE_ASSET_SETGET(DebrisData, Shape); + DECLARE_SHAPEASSET_REFACTOR(DebrisData, Shape) StringTableEntry textureName; @@ -111,7 +110,8 @@ public: void onPerformSubstitutions() override; bool allowSubstitutions() const override { return true; } - void onShapeChanged() +protected: + void onAssetRefreshed(AssetPtrBase* pAssetPtrBase) override { reloadOnLocalClient(); } diff --git a/Engine/source/T3D/examples/renderShapeExample.cpp b/Engine/source/T3D/examples/renderShapeExample.cpp index 731db472e..2762cfe9b 100644 --- a/Engine/source/T3D/examples/renderShapeExample.cpp +++ b/Engine/source/T3D/examples/renderShapeExample.cpp @@ -59,7 +59,6 @@ RenderShapeExample::RenderShapeExample() mTypeMask |= StaticObjectType | StaticShapeObjectType; // Make sure to initialize our TSShapeInstance to NULL - INIT_ASSET(Shape); mShapeInstance = NULL; } @@ -75,7 +74,7 @@ void RenderShapeExample::initPersistFields() docsURL; Parent::initPersistFields(); addGroup( "Shapes" ); - INITPERSISTFIELD_SHAPEASSET(Shape, RenderShapeExample, "The path to the shape file.") + INITPERSISTFIELD_SHAPEASSET_REFACTOR(Shape, RenderShapeExample, "The path to the shape file.") endGroup( "Shapes" ); // SceneObject already handles exposing the transform @@ -147,7 +146,7 @@ U32 RenderShapeExample::packUpdate( NetConnection *conn, U32 mask, BitStream *st // Write out any of the updated editable properties if ( stream->writeFlag( mask & UpdateMask ) ) { - PACK_ASSET(conn, Shape); + PACK_ASSET_REFACTOR(conn, Shape); // Allow the server object a chance to handle a new shape createShape(); @@ -171,7 +170,7 @@ void RenderShapeExample::unpackUpdate(NetConnection *conn, BitStream *stream) if ( stream->readFlag() ) // UpdateMask { - UNPACK_ASSET(conn, Shape); + UNPACK_ASSET_REFACTOR(conn, Shape); if ( isProperlyAdded() ) createShape(); @@ -183,11 +182,7 @@ void RenderShapeExample::unpackUpdate(NetConnection *conn, BitStream *stream) //----------------------------------------------------------------------------- void RenderShapeExample::createShape() { - if ( getShape() == StringTable->EmptyString() ) - return; - - // If this is the same shape then no reason to update it - if ( mShapeInstance && getShape() == StringTable->insert(mShape.getPath().getFullPath().c_str()) ) + if ( mShapeAsset.isNull() ) return; // Clean up our previous shape @@ -196,19 +191,19 @@ void RenderShapeExample::createShape() // Attempt to preload the Materials for this shape if ( isClientObject() && - !mShape->preloadMaterialList( mShape.getPath() ) && + !getShape()->preloadMaterialList(getShape().getPath() ) && NetConnection::filesWereDownloaded() ) { return; } // Update the bounding box - mObjBox = mShape->mBounds; + mObjBox = getShape()->mBounds; resetWorldBox(); setRenderTransform(mObjToWorld); // Create the TSShapeInstance - mShapeInstance = new TSShapeInstance( mShape, isClientObject() ); + mShapeInstance = new TSShapeInstance(getShape(), isClientObject() ); } void RenderShapeExample::prepRenderImage( SceneRenderState *state ) diff --git a/Engine/source/T3D/examples/renderShapeExample.h b/Engine/source/T3D/examples/renderShapeExample.h index 3f452c72a..8160044a6 100644 --- a/Engine/source/T3D/examples/renderShapeExample.h +++ b/Engine/source/T3D/examples/renderShapeExample.h @@ -61,14 +61,11 @@ class RenderShapeExample : public SceneObject //-------------------------------------------------------------------------- // Rendering variables //-------------------------------------------------------------------------- - DECLARE_SHAPEASSET(RenderShapeExample, Shape, onShapeChanged); - DECLARE_ASSET_SETGET(RenderShapeExample, Shape); + DECLARE_SHAPEASSET_REFACTOR(RenderShapeExample, Shape) // The actual shape instance TSShapeInstance* mShapeInstance; - void onShapeChanged() {} - public: RenderShapeExample(); virtual ~RenderShapeExample(); @@ -119,4 +116,4 @@ public: void prepRenderImage( SceneRenderState *state ) override; }; -#endif // _RENDERSHAPEEXAMPLE_H_ \ No newline at end of file +#endif // _RENDERSHAPEEXAMPLE_H_ diff --git a/Engine/source/T3D/missionMarker.cpp b/Engine/source/T3D/missionMarker.cpp index a18523ef7..7290ccc97 100644 --- a/Engine/source/T3D/missionMarker.cpp +++ b/Engine/source/T3D/missionMarker.cpp @@ -444,14 +444,14 @@ void SpawnSphere::unpackUpdate(NetConnection * con, BitStream * stream) { delete mShapeInstance; ShapeBaseData *spawnedDatablock = dynamic_cast(Sim::findObject(mSpawnDataBlock.c_str())); - if (spawnedDatablock && spawnedDatablock->mShape) + if (spawnedDatablock && spawnedDatablock->getShape()) { - mShapeInstance = new TSShapeInstance(spawnedDatablock->mShape); + mShapeInstance = new TSShapeInstance(spawnedDatablock->getShape()); } else if (mDataBlock) { - if (mDataBlock->mShape) - mShapeInstance = new TSShapeInstance(mDataBlock->mShape); + if (mDataBlock->getShape()) + mShapeInstance = new TSShapeInstance(mDataBlock->getShape()); } } stream->read(&mSpawnName); diff --git a/Engine/source/T3D/player.cpp b/Engine/source/T3D/player.cpp index c736ff022..8239bd2f3 100644 --- a/Engine/source/T3D/player.cpp +++ b/Engine/source/T3D/player.cpp @@ -502,10 +502,10 @@ bool PlayerData::preload(bool server, String &errorStr) // If we don't have a shape don't crash out trying to // setup animations and sequences. - if ( mShape ) + if (getShape()) { // Go ahead a pre-load the player shape - TSShapeInstance* si = new TSShapeInstance(mShape, false); + TSShapeInstance* si = new TSShapeInstance(getShape(), false); TSThread* thread = si->addThread(); // Extract ground transform velocity from animations @@ -516,7 +516,7 @@ bool PlayerData::preload(bool server, String &errorStr) ActionAnimationDef *sp = &ActionAnimationList[i]; dp->name = sp->name; dp->dir.set(sp->dir.x,sp->dir.y,sp->dir.z); - dp->sequence = mShape->findSequence(sp->name); + dp->sequence = getShape()->findSequence(sp->name); // If this is a sprint action and is missing a sequence, attempt to use // the standard run ones. @@ -524,7 +524,7 @@ bool PlayerData::preload(bool server, String &errorStr) { S32 offset = i-SprintRootAnim; ActionAnimationDef *standDef = &ActionAnimationList[RootAnim+offset]; - dp->sequence = mShape->findSequence(standDef->name); + dp->sequence = getShape()->findSequence(standDef->name); } dp->velocityScale = true; @@ -532,12 +532,12 @@ bool PlayerData::preload(bool server, String &errorStr) if (dp->sequence != -1) getGroundInfo(si,thread,dp); } - for (S32 b = 0; b < mShape->sequences.size(); b++) + for (S32 b = 0; b < getShape()->sequences.size(); b++) { if (!isTableSequence(b)) { dp->sequence = b; - dp->name = mShape->getName(mShape->sequences[b].nameIndex); + dp->name = getShape()->getName(getShape()->sequences[b].nameIndex); dp->velocityScale = false; getGroundInfo(si,thread,dp++); } @@ -554,17 +554,17 @@ bool PlayerData::preload(bool server, String &errorStr) lookAction = c; // Resolve spine - spineNode[0] = mShape->findNode("Bip01 Pelvis"); - spineNode[1] = mShape->findNode("Bip01 Spine"); - spineNode[2] = mShape->findNode("Bip01 Spine1"); - spineNode[3] = mShape->findNode("Bip01 Spine2"); - spineNode[4] = mShape->findNode("Bip01 Neck"); - spineNode[5] = mShape->findNode("Bip01 Head"); + spineNode[0] = getShape()->findNode("Bip01 Pelvis"); + spineNode[1] = getShape()->findNode("Bip01 Spine"); + spineNode[2] = getShape()->findNode("Bip01 Spine1"); + spineNode[3] = getShape()->findNode("Bip01 Spine2"); + spineNode[4] = getShape()->findNode("Bip01 Neck"); + spineNode[5] = getShape()->findNode("Bip01 Head"); // Recoil animations - recoilSequence[0] = mShape->findSequence("light_recoil"); - recoilSequence[1] = mShape->findSequence("medium_recoil"); - recoilSequence[2] = mShape->findSequence("heavy_recoil"); + recoilSequence[0] = getShape()->findSequence("light_recoil"); + recoilSequence[1] = getShape()->findSequence("medium_recoil"); + recoilSequence[2] = getShape()->findSequence("heavy_recoil"); } // Convert pickupRadius to a delta of boundingBox @@ -7511,8 +7511,8 @@ F32 Player::getAnimationDurationByID(U32 anim_id) if (anim_id == BAD_ANIM_ID) return 0.0f; S32 seq_id = mDataBlock->actionList[anim_id].sequence; - if (seq_id >= 0 && seq_id < mDataBlock->mShape->sequences.size()) - return mDataBlock->mShape->sequences[seq_id].duration; + if (seq_id >= 0 && seq_id < mDataBlock->getShape()->sequences.size()) + return mDataBlock->getShape()->sequences[seq_id].duration; return 0.0f; } @@ -7524,8 +7524,8 @@ bool Player::isBlendAnimation(const char* name) return false; S32 seq_id = mDataBlock->actionList[anim_id].sequence; - if (seq_id >= 0 && seq_id < mDataBlock->mShape->sequences.size()) - return mDataBlock->mShape->sequences[seq_id].isBlend(); + if (seq_id >= 0 && seq_id < mDataBlock->getShape()->sequences.size()) + return mDataBlock->getShape()->sequences[seq_id].isBlend(); return false; } diff --git a/Engine/source/T3D/proximityMine.cpp b/Engine/source/T3D/proximityMine.cpp index fd02fc091..86c9807b6 100644 --- a/Engine/source/T3D/proximityMine.cpp +++ b/Engine/source/T3D/proximityMine.cpp @@ -144,11 +144,11 @@ bool ProximityMineData::preload( bool server, String& errorStr ) } } - if ( mShape ) + if ( getShape() ) { // Lookup animation sequences - armingSequence = mShape->findSequence( "armed" ); - triggerSequence = mShape->findSequence( "triggered" ); + armingSequence = getShape()->findSequence( "armed" ); + triggerSequence = getShape()->findSequence( "triggered" ); } return true; diff --git a/Engine/source/T3D/rigidShape.cpp b/Engine/source/T3D/rigidShape.cpp index 8a453b065..b87bcc056 100644 --- a/Engine/source/T3D/rigidShape.cpp +++ b/Engine/source/T3D/rigidShape.cpp @@ -310,7 +310,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 asset \"%s\"", mShapeAsset.getAssetId()); + errorStr = String::ToString("RigidShapeData: Couldn't load shape asset \"%s\"", getShapeAsset().getAssetId()); return false; } diff --git a/Engine/source/T3D/shapeBase.cpp b/Engine/source/T3D/shapeBase.cpp index 92f5f4da6..8e1f19013 100644 --- a/Engine/source/T3D/shapeBase.cpp +++ b/Engine/source/T3D/shapeBase.cpp @@ -201,13 +201,12 @@ ShapeBaseData::ShapeBaseData() inheritEnergyFromMount( false ), mAIControllData(NULL) { - INIT_ASSET(Shape); - INIT_ASSET(DebrisShape); - dMemset( mountPointNode, -1, sizeof( S32 ) * SceneObject::NumMountPoints ); remap_txr_tags = NULL; remap_buffer = NULL; silent_bbox_check = false; + mShapeAsset.registerRefreshNotify(this); + mDebrisShapeAsset.registerRefreshNotify(this); } ShapeBaseData::ShapeBaseData(const ShapeBaseData& other, bool temp_clone) : GameBaseData(other, temp_clone) @@ -217,13 +216,13 @@ ShapeBaseData::ShapeBaseData(const ShapeBaseData& other, bool temp_clone) : Game shadowProjectionDistance = other.shadowProjectionDistance; shadowSphereAdjust = other.shadowSphereAdjust; cloakTexName = other.cloakTexName; - CLONE_ASSET(Shape); + mShapeAsset = other.mShapeAsset; cubeDescName = other.cubeDescName; cubeDescId = other.cubeDescId; reflectorDesc = other.reflectorDesc; debris = other.debris; debrisID = other.debrisID; // -- for pack/unpack of debris ptr - CLONE_ASSET(DebrisShape); + mDebrisShapeAsset = other.mDebrisShapeAsset; explosion = other.explosion; explosionID = other.explosionID; // -- for pack/unpack of explosion ptr underwaterExplosion = other.underwaterExplosion; @@ -245,7 +244,6 @@ ShapeBaseData::ShapeBaseData(const ShapeBaseData& other, bool temp_clone) : Game cameraMaxFov = other.cameraMaxFov; cameraCanBank = other.cameraCanBank; mountedImagesBank = other.mountedImagesBank; - mShape = other.mShape; // -- TSShape loaded using shapeName mCRC = other.mCRC; // -- from shape, used to verify client shape computeCRC = other.computeCRC; eyeNode = other.eyeNode; // -- from shape node "eye" @@ -304,6 +302,9 @@ ShapeBaseData::~ShapeBaseData() if (remap_buffer && !isTempClone()) dFree(remap_buffer); + + mShapeAsset.unregisterRefreshNotify(); + mDebrisShapeAsset.unregisterRefreshNotify(); } bool ShapeBaseData::preload(bool server, String &errorStr) @@ -342,156 +343,159 @@ bool ShapeBaseData::preload(bool server, String &errorStr) "ShapeBaseData::preload: invalid debris data"); } - if( bool(mDebrisShape)) + if(mDebrisShapeAsset.notNull()) { - TSShapeInstance* pDummy = new TSShapeInstance(mDebrisShape, !server); + TSShapeInstance* pDummy = new TSShapeInstance(getDebrisShape(), !server); delete pDummy; } } S32 i; - U32 assetStatus = ShapeAsset::getAssetErrCode(mShapeAsset); - if (assetStatus == AssetBase::Ok || assetStatus == AssetBase::UsingFallback) + if (mShapeAsset.notNull()) { - if (!server && !mShape->preloadMaterialList(mShape.getPath()) && NetConnection::filesWereDownloaded()) - shapeError = true; - - if(computeCRC) + U32 assetStatus = ShapeAsset::getAssetErrCode(mShapeAsset); + if (assetStatus == AssetBase::Ok || assetStatus == AssetBase::UsingFallback) { - Con::printf("Validation required for shape asset: %s", mShapeAsset.getAssetId()); + if (!server && !getShape()->preloadMaterialList(getShape().getPath()) && NetConnection::filesWereDownloaded()) + shapeError = true; - Torque::FS::FileNodeRef fileRef = Torque::FS::GetFileNode(mShapeAsset->getShapePath()); - - if (!fileRef) + if (computeCRC) { - errorStr = String::ToString("ShapeBaseData: Couldn't load shape asset \"%s\"", mShapeAsset.getAssetId()); - return false; - } + Con::printf("Validation required for shape asset: %s", mShapeAsset.getAssetId()); - if(server) - mCRC = fileRef->getChecksum(); - else if(mCRC != fileRef->getChecksum()) - { - errorStr = String::ToString("Shape asset \"%s\" does not match version on server.", mShapeAsset.getAssetId()); - return false; - } - } - // Resolve details and camera node indexes. - static const String sCollisionStr( "collision-" ); + Torque::FS::FileNodeRef fileRef = Torque::FS::GetFileNode(mShapeAsset->getShapePath()); - for (i = 0; i < mShape->details.size(); i++) - { - const String &name = mShape->names[mShape->details[i].nameIndex]; - - if (name.compare( sCollisionStr, sCollisionStr.length(), String::NoCase ) == 0) - { - collisionDetails.push_back(i); - collisionBounds.increment(); - - mShape->computeBounds(collisionDetails.last(), collisionBounds.last()); - mShape->getAccelerator(collisionDetails.last()); - - if (!mShape->mBounds.isContained(collisionBounds.last())) + if (!fileRef) { - if (!silent_bbox_check) - 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 asset %s-collision detail %d (Collision-%d) bounds box invalid!", mShapeAsset.getAssetId(), collisionDetails.size() - 1, collisionDetails.last()); - collisionBounds.last() = mShape->mBounds; + errorStr = String::ToString("ShapeBaseData: Couldn't load shape asset \"%s\"", mShapeAsset.getAssetId()); + return false; } - // The way LOS works is that it will check to see if there is a LOS detail that matches - // the the collision detail + 1 + MaxCollisionShapes (this variable name should change in - // the future). If it can't find a matching LOS it will simply use the collision instead. - // We check for any "unmatched" LOS's further down - LOSDetails.increment(); - - String buff = String::ToString("LOS-%d", i + 1 + MaxCollisionShapes); - U32 los = mShape->findDetail(buff); - if (los == -1) - LOSDetails.last() = i; - else - LOSDetails.last() = los; - } - } - - // Snag any "unmatched" LOS details - static const String sLOSStr( "LOS-" ); - - for (i = 0; i < mShape->details.size(); i++) - { - const String &name = mShape->names[mShape->details[i].nameIndex]; - - if (name.compare( sLOSStr, sLOSStr.length(), String::NoCase ) == 0) - { - // See if we already have this LOS - bool found = false; - for (U32 j = 0; j < LOSDetails.size(); j++) + if (server) + mCRC = fileRef->getChecksum(); + else if (mCRC != fileRef->getChecksum()) { - if (LOSDetails[j] == i) + errorStr = String::ToString("Shape asset \"%s\" does not match version on server.", mShapeAsset.getAssetId()); + return false; + } + } + // Resolve details and camera node indexes. + static const String sCollisionStr("collision-"); + + for (i = 0; i < getShape()->details.size(); i++) + { + const String& name = getShape()->names[getShape()->details[i].nameIndex]; + + if (name.compare(sCollisionStr, sCollisionStr.length(), String::NoCase) == 0) + { + collisionDetails.push_back(i); + collisionBounds.increment(); + + getShape()->computeBounds(collisionDetails.last(), collisionBounds.last()); + getShape()->getAccelerator(collisionDetails.last()); + + if (!getShape()->mBounds.isContained(collisionBounds.last())) { + if (!silent_bbox_check) + 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() = getShape()->mBounds; + } + else if (collisionBounds.last().isValidBox() == false) + { + if (!silent_bbox_check) + Con::errorf("Error: shape asset %s-collision detail %d (Collision-%d) bounds box invalid!", mShapeAsset.getAssetId(), collisionDetails.size() - 1, collisionDetails.last()); + collisionBounds.last() = getShape()->mBounds; + } + + // The way LOS works is that it will check to see if there is a LOS detail that matches + // the the collision detail + 1 + MaxCollisionShapes (this variable name should change in + // the future). If it can't find a matching LOS it will simply use the collision instead. + // We check for any "unmatched" LOS's further down + LOSDetails.increment(); + + String buff = String::ToString("LOS-%d", i + 1 + MaxCollisionShapes); + U32 los = getShape()->findDetail(buff); + if (los == -1) + LOSDetails.last() = i; + else + LOSDetails.last() = los; + } + } + + // Snag any "unmatched" LOS details + static const String sLOSStr("LOS-"); + + for (i = 0; i < getShape()->details.size(); i++) + { + const String& name = getShape()->names[getShape()->details[i].nameIndex]; + + if (name.compare(sLOSStr, sLOSStr.length(), String::NoCase) == 0) + { + // See if we already have this LOS + bool found = false; + for (U32 j = 0; j < LOSDetails.size(); j++) + { + if (LOSDetails[j] == i) + { found = true; break; + } } - } - if (!found) - LOSDetails.push_back(i); + if (!found) + LOSDetails.push_back(i); + } } - } - debrisDetail = mShape->findDetail("Debris-17"); - eyeNode = mShape->findNode("eye"); - earNode = mShape->findNode( "ear" ); - if( earNode == -1 ) - earNode = eyeNode; - cameraNode = mShape->findNode("cam"); - if (cameraNode == -1) - cameraNode = eyeNode; + debrisDetail = getShape()->findDetail("Debris-17"); + eyeNode = getShape()->findNode("eye"); + earNode = getShape()->findNode("ear"); + if (earNode == -1) + earNode = eyeNode; + cameraNode = getShape()->findNode("cam"); + if (cameraNode == -1) + cameraNode = eyeNode; - // Resolve mount point node indexes - for (i = 0; i < SceneObject::NumMountPoints; i++) { - char fullName[256]; - dSprintf(fullName,sizeof(fullName),"mount%d",i); - mountPointNode[i] = mShape->findNode(fullName); - } + // Resolve mount point node indexes + for (i = 0; i < SceneObject::NumMountPoints; i++) { + char fullName[256]; + dSprintf(fullName, sizeof(fullName), "mount%d", i); + mountPointNode[i] = getShape()->findNode(fullName); + } - // find the AIRepairNode - hardcoded to be the last node in the array... - mountPointNode[AIRepairNode] = mShape->findNode("AIRepairNode"); + // find the AIRepairNode - hardcoded to be the last node in the array... + mountPointNode[AIRepairNode] = getShape()->findNode("AIRepairNode"); - // - hulkSequence = mShape->findSequence("Visibility"); - damageSequence = mShape->findSequence("Damage"); + // + hulkSequence = getShape()->findSequence("Visibility"); + damageSequence = getShape()->findSequence("Damage"); - // - F32 w = mShape->mBounds.len_y() / 2; - if (cameraMaxDist < w) - cameraMaxDist = w; - // just parse up the string and collect the remappings in txr_tag_remappings. - if (!server && remap_txr_tags != NULL && remap_txr_tags != StringTable->insert("")) - { - txr_tag_remappings.clear(); - if (remap_buffer) - dFree(remap_buffer); - - remap_buffer = dStrdup(remap_txr_tags); - - char* remap_token = dStrtok(remap_buffer, " \t"); - while (remap_token != NULL) + // + F32 w = getShape()->mBounds.len_y() / 2; + if (cameraMaxDist < w) + cameraMaxDist = w; + // just parse up the string and collect the remappings in txr_tag_remappings. + if (!server && remap_txr_tags != NULL && remap_txr_tags != StringTable->insert("")) { - char* colon = dStrchr(remap_token, ':'); - if (colon) + txr_tag_remappings.clear(); + if (remap_buffer) + dFree(remap_buffer); + + remap_buffer = dStrdup(remap_txr_tags); + + char* remap_token = dStrtok(remap_buffer, " \t"); + while (remap_token != NULL) { - *colon = '\0'; - txr_tag_remappings.increment(); - txr_tag_remappings.last().old_tag = remap_token; - txr_tag_remappings.last().new_tag = colon+1; + char* colon = dStrchr(remap_token, ':'); + if (colon) + { + *colon = '\0'; + txr_tag_remappings.increment(); + txr_tag_remappings.last().old_tag = remap_token; + txr_tag_remappings.last().new_tag = colon + 1; + } + remap_token = dStrtok(NULL, " \t"); } - remap_token = dStrtok(NULL, " \t"); } } } @@ -543,12 +547,12 @@ void ShapeBaseData::initPersistFields() { docsURL; addGroup( "Shapes" ); - INITPERSISTFIELD_SHAPEASSET(Shape, ShapeBaseData, "The source shape asset."); + INITPERSISTFIELD_SHAPEASSET_REFACTOR(Shape, ShapeBaseData, "The source shape asset."); addField("computeCRC", TypeBool, Offset(computeCRC, ShapeBaseData), "If true, verify that the CRC of the client's shape model matches the " "server's CRC for the shape model when loaded by the client."); addField("silentBBoxValidation", TypeBool, Offset(silent_bbox_check, ShapeBaseData)); - INITPERSISTFIELD_SHAPEASSET(DebrisShape, ShapeBaseData, "The shape asset to use for auto-generated breakups via blowup(). @note may not be functional."); + INITPERSISTFIELD_SHAPEASSET_REFACTOR(DebrisShape, ShapeBaseData, "The shape asset to use for auto-generated breakups via blowup(). @note may not be functional."); endGroup( "Shapes" ); addGroup("Movement"); addField("aiControllerData", TYPEID< AIControllerData >(), Offset(mAIControllData, ShapeBaseData), @@ -677,12 +681,12 @@ DefineEngineMethod( ShapeBaseData, checkDeployPos, bool, ( TransformF txfm ),, "@note This is a server side only check, and is not actually limited to spawning.\n") { - if (bool(object->mShape) == false) + if (bool(object->getShape()) == false) return false; MatrixF mat = txfm.getMatrix(); - Box3F objBox = object->mShape->mBounds; + Box3F objBox = object->getShape()->mBounds; Point3F boxCenter = (objBox.minExtents + objBox.maxExtents) * 0.5f; objBox.minExtents = boxCenter + (objBox.minExtents - boxCenter) * 0.9f; objBox.maxExtents = boxCenter + (objBox.maxExtents - boxCenter) * 0.9f; @@ -752,8 +756,8 @@ void ShapeBaseData::packData(BitStream* stream) stream->write(shadowProjectionDistance); stream->write(shadowSphereAdjust); - PACKDATA_ASSET(Shape); - PACKDATA_ASSET(DebrisShape); + PACKDATA_ASSET_REFACTOR(Shape); + PACKDATA_ASSET_REFACTOR(DebrisShape); stream->writeString(cloakTexName); if(stream->writeFlag(mass != gShapeBaseDataProto.mass)) @@ -829,8 +833,8 @@ void ShapeBaseData::unpackData(BitStream* stream) stream->read(&shadowProjectionDistance); stream->read(&shadowSphereAdjust); - UNPACKDATA_ASSET(Shape); - UNPACKDATA_ASSET(DebrisShape); + UNPACKDATA_ASSET_REFACTOR(Shape); + UNPACKDATA_ASSET_REFACTOR(DebrisShape); cloakTexName = stream->readSTString(); if(stream->readFlag()) @@ -918,17 +922,6 @@ void ShapeBaseData::unpackData(BitStream* stream) silent_bbox_check = stream->readFlag(); } -// -// -void ShapeBaseData::onShapeChanged() -{ - reloadOnLocalClient(); -} - -void ShapeBaseData::onDebrisChanged() -{ - reloadOnLocalClient(); -} //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- @@ -1210,12 +1203,12 @@ bool ShapeBase::onNewDataBlock( GameBaseData *dptr, bool reload ) // Even if loadShape succeeds, there may not actually be // a shape assigned to this object. - if (bool(mDataBlock->mShape)) { + if (bool(mDataBlock->getShape())) { delete mShapeInstance; if (isClientObject() && mDataBlock->txr_tag_remappings.size() > 0) { // temporarily substitute material tags with alternates - TSMaterialList* mat_list = mDataBlock->mShape->materialList; + TSMaterialList* mat_list = mDataBlock->getShape()->materialList; if (mat_list) { for (S32 i = 0; i < mDataBlock->txr_tag_remappings.size(); i++) @@ -1235,7 +1228,7 @@ bool ShapeBase::onNewDataBlock( GameBaseData *dptr, bool reload ) } } } - mShapeInstance = new TSShapeInstance(mDataBlock->mShape, isClientObject()); + mShapeInstance = new TSShapeInstance(mDataBlock->getShape(), isClientObject()); if (isClientObject()) { mShapeInstance->cloneMaterialList(); @@ -1243,7 +1236,7 @@ bool ShapeBase::onNewDataBlock( GameBaseData *dptr, bool reload ) // restore the material tags to original form if (mDataBlock->txr_tag_remappings.size() > 0) { - TSMaterialList* mat_list = mDataBlock->mShape->materialList; + TSMaterialList* mat_list = mDataBlock->getShape()->materialList; if (mat_list) { for (S32 i = 0; i < mDataBlock->txr_tag_remappings.size(); i++) @@ -1269,11 +1262,11 @@ bool ShapeBase::onNewDataBlock( GameBaseData *dptr, bool reload ) } } - mObjBox = mDataBlock->mShape->mBounds; + mObjBox = mDataBlock->getShape()->mBounds; resetWorldBox(); // Set the initial mesh hidden state. - mMeshHidden.setSize(mDataBlock->mShape->objects.size()); + mMeshHidden.setSize(mDataBlock->getShape()->objects.size()); mMeshHidden.clear(); // Initialize the threads @@ -1297,11 +1290,11 @@ bool ShapeBase::onNewDataBlock( GameBaseData *dptr, bool reload ) AssertFatal(prevDB != NULL, "ShapeBase::onNewDataBlock - how did you have a sequence playing without a prior datablock?"); - const TSShape* prevShape = prevDB->mShape; + const TSShape* prevShape = prevDB->getShape(); const TSShape::Sequence& prevSeq = prevShape->sequences[st.sequence]; const String& prevSeqName = prevShape->names[prevSeq.nameIndex]; - st.sequence = mDataBlock->mShape->findSequence(prevSeqName); + st.sequence = mDataBlock->getShape()->findSequence(prevSeqName); if (st.sequence != -1) { @@ -1971,13 +1964,13 @@ void ShapeBase::blowUp() TSShapeInstance *debShape = NULL; - if( mDataBlock->mDebrisShape == NULL ) + if( mDataBlock->getDebrisShape() == NULL) { return; } else { - debShape = new TSShapeInstance( mDataBlock->mDebrisShape, true); + debShape = new TSShapeInstance( mDataBlock->getDebrisShape(), true); } @@ -2049,7 +2042,7 @@ Point3F ShapeBase::getAIRepairPoint() //---------------------------------------------------------------------------- void ShapeBase::getNodeTransform(const char* nodeName, MatrixF* outMat) { - S32 nodeIDx = mDataBlock->getShapeResource()->findNode(nodeName); + S32 nodeIDx = mDataBlock->getShape()->findNode(nodeName); const MatrixF& xfm = isMounted() ? mMount.xfm : MatrixF::Identity; MatrixF nodeTransform(xfm); @@ -2216,7 +2209,7 @@ void ShapeBase::getNodeTransform(const char* nodeName, const MatrixF& xfm, Matri if (!mShapeInstance) return; - S32 nodeIDx = mDataBlock->getShapeResource()->findNode(nodeName); + S32 nodeIDx = mDataBlock->getShape()->findNode(nodeName); MatrixF nodeTransform(xfm); const Point3F& scale = getScale(); @@ -5027,7 +5020,7 @@ void ShapeBase::_updateHiddenMeshes() void ShapeBase::setMeshHidden( const char *meshName, bool forceHidden ) { - setMeshHidden( mDataBlock->mShape->findObject( meshName ), forceHidden ); + setMeshHidden( mDataBlock->getShape()->findObject(meshName), forceHidden); } void ShapeBase::setMeshHidden( S32 meshIndex, bool forceHidden ) @@ -5096,7 +5089,7 @@ void ShapeBase::dumpMeshVisibility() { const TSShapeInstance::MeshObjectInstance &mesh = meshes[i]; - const String &meshName = mDataBlock->mShape->getMeshName( i ); + const String &meshName = mDataBlock->getShape()->getMeshName( i ); Con::printf( "%d - %s - forceHidden = %s, visibility = %f", i, @@ -5378,8 +5371,8 @@ F32 ShapeBase::getAnimationDurationByID(U32 anim_id) return 0.0f; S32 seq_id = (S32) anim_id; - if (seq_id >= 0 && seq_id < mDataBlock->mShape->sequences.size()) - return mDataBlock->mShape->sequences[seq_id].duration; + if (seq_id >= 0 && seq_id < mDataBlock->getShape()->sequences.size()) + return mDataBlock->getShape()->sequences[seq_id].duration; return 0.0f; } @@ -5391,8 +5384,8 @@ bool ShapeBase::isBlendAnimation(const char* name) return false; S32 seq_id = (S32) anim_id; - if (seq_id >= 0 && seq_id < mDataBlock->mShape->sequences.size()) - return mDataBlock->mShape->sequences[seq_id].isBlend(); + if (seq_id >= 0 && seq_id < mDataBlock->getShape()->sequences.size()) + return mDataBlock->getShape()->sequences[seq_id].isBlend(); return false; } @@ -5404,11 +5397,11 @@ const char* ShapeBase::getLastClipName(U32 clip_tag) S32 seq_id = (S32) last_anim_id; - S32 idx = mDataBlock->mShape->sequences[seq_id].nameIndex; - if (idx < 0 || idx >= mDataBlock->mShape->names.size()) + S32 idx = mDataBlock->getShape()->sequences[seq_id].nameIndex; + if (idx < 0 || idx >= mDataBlock->getShape()->names.size()) return 0; - return mDataBlock->mShape->names[idx]; + return mDataBlock->getShape()->names[idx]; } // diff --git a/Engine/source/T3D/shapeBase.h b/Engine/source/T3D/shapeBase.h index 46f9a3270..a8807a026 100644 --- a/Engine/source/T3D/shapeBase.h +++ b/Engine/source/T3D/shapeBase.h @@ -140,7 +140,8 @@ class ShapeBaseConvex : public Convex //-------------------------------------------------------------------------- -struct ShapeBaseImageData: public GameBaseData { +struct ShapeBaseImageData: public GameBaseData, protected AssetPtrCallback +{ private: typedef GameBaseData Parent; @@ -380,11 +381,7 @@ 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. - DECLARE_SHAPEASSET_ARRAY(ShapeBaseImageData, Shape, MaxShapes, onShapeChanged); ///< Name of shape to render. - DECLARE_ASSET_ARRAY_SETGET(ShapeBaseImageData, Shape); - - //DECLARE_SHAPEASSET(ShapeBaseImageData, ShapeFP); ///< Name of shape to render in first person (optional). - //DECLARE_ASSET_SETGET(ShapeBaseImageData, ShapeFP); + DECLARE_SHAPEASSET_ARRAY_REFACTOR(ShapeBaseImageData, Shape, MaxShapes) ///< Name of shape to render. StringTableEntry imageAnimPrefix; ///< Passed along to the mounting shape to modify /// animation sequences played in 3rd person. [optional] @@ -519,6 +516,12 @@ struct ShapeBaseImageData: public GameBaseData { DECLARE_CALLBACK( void, onMount, ( SceneObject* obj, S32 slot, F32 dt ) ); DECLARE_CALLBACK( void, onUnmount, ( SceneObject* obj, S32 slot, F32 dt ) ); /// @} + +protected: + void onAssetRefreshed(AssetPtrBase* pAssetPtrBase) override + { + reloadOnLocalClient(); + } }; typedef ShapeBaseImageData::LightType ShapeBaseImageLightType; @@ -533,7 +536,7 @@ DefineEnumType( ShapeBaseImageRecoilState ); //-------------------------------------------------------------------------- /// @nosubgrouping -struct ShapeBaseData : public GameBaseData { +struct ShapeBaseData : public GameBaseData, protected AssetPtrCallback { private: typedef GameBaseData Parent; @@ -553,8 +556,7 @@ public: F32 shadowProjectionDistance; F32 shadowSphereAdjust; - DECLARE_SHAPEASSET(ShapeBaseData, Shape, onShapeChanged); - DECLARE_ASSET_SETGET(ShapeBaseData, Shape); + DECLARE_SHAPEASSET_REFACTOR(ShapeBaseData, Shape) StringTableEntry cloakTexName; @@ -570,8 +572,7 @@ public: DebrisData * debris; S32 debrisID; - DECLARE_SHAPEASSET(ShapeBaseData, DebrisShape, onDebrisChanged); - DECLARE_ASSET_SETGET(ShapeBaseData, DebrisShape); + DECLARE_SHAPEASSET_REFACTOR(ShapeBaseData, DebrisShape) ExplosionData* explosion; S32 explosionID; @@ -691,10 +692,14 @@ public: Vector txr_tag_remappings; bool silent_bbox_check; - void onShapeChanged(); - void onDebrisChanged(); public: ShapeBaseData(const ShapeBaseData&, bool = false); + +protected: + void onAssetRefreshed(AssetPtrBase* pAssetPtrBase) override + { + reloadOnLocalClient(); + } }; diff --git a/Engine/source/T3D/shapeImage.cpp b/Engine/source/T3D/shapeImage.cpp index bf1687649..95281cbd6 100644 --- a/Engine/source/T3D/shapeImage.cpp +++ b/Engine/source/T3D/shapeImage.cpp @@ -293,8 +293,7 @@ ShapeBaseImageData::ShapeBaseImageData() isAnimated[i] = false; hasFlash[i] = false; shapeIsValid[i] = false; - - INIT_ASSET_ARRAY(Shape, i); + mShapeAsset[i].registerRefreshNotify(this); } shakeCamera = false; @@ -454,10 +453,7 @@ bool ShapeBaseImageData::preload(bool server, String &errorStr) if (!mShapeAsset[i].isNull()) { - // Resolve shapename - mShape[i] = mShapeAsset[i]->getShapeResource(); - - if (!bool(mShape[i])) { + if (!bool(getShape(i))) { errorStr = String::ToString("Unable to load shape asset: %s", mShapeAsset[i]->getAssetId()); return false; } @@ -465,7 +461,7 @@ bool ShapeBaseImageData::preload(bool server, String &errorStr) { Con::printf("Validation required for shape asset: %s", mShapeAsset[i]->getAssetId()); - Torque::FS::FileNodeRef fileRef = Torque::FS::GetFileNode(mShape[i].getPath()); + Torque::FS::FileNodeRef fileRef = Torque::FS::GetFileNode(getShape(i).getPath()); if (!fileRef) { @@ -485,23 +481,23 @@ bool ShapeBaseImageData::preload(bool server, String &errorStr) } // Resolve nodes & build mount transform - eyeMountNode[i] = mShape[i]->findNode("eyeMount"); - eyeNode[i] = mShape[i]->findNode("eye"); + eyeMountNode[i] = getShape(i)->findNode("eyeMount"); + eyeNode[i] = getShape(i)->findNode("eye"); if (eyeNode[i] == -1) eyeNode[i] = eyeMountNode[i]; - ejectNode[i] = mShape[i]->findNode("ejectPoint"); - muzzleNode[i] = mShape[i]->findNode("muzzlePoint"); - retractNode[i] = mShape[i]->findNode("retractionPoint"); + ejectNode[i] = getShape(i)->findNode("ejectPoint"); + muzzleNode[i] = getShape(i)->findNode("muzzlePoint"); + retractNode[i] = getShape(i)->findNode("retractionPoint"); mountTransform[i] = mountOffset; - S32 node = mShape[i]->findNode("mountPoint"); + S32 node = getShape(i)->findNode("mountPoint"); if (node != -1) { MatrixF total(1); do { MatrixF nmat; QuatF q; - TSTransform::setMatrix(mShape[i]->defaultRotations[node].getQuatF(&q), mShape[i]->defaultTranslations[node],&nmat); + TSTransform::setMatrix(getShape(i)->defaultRotations[node].getQuatF(&q), getShape(i)->defaultTranslations[node],&nmat); total.mul(nmat); - node = mShape[i]->nodes[node].parentIndex; + node = getShape(i)->nodes[node].parentIndex; } while(node != -1); total.inverse(); @@ -514,7 +510,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] = mShape[i]->findSequence(stateSequence[j]); + s.sequence[i] = getShape(i)->findSequence(stateSequence[j]); if (s.sequence[i] != -1) { // This state has an animation sequence @@ -525,7 +521,7 @@ bool ShapeBaseImageData::preload(bool server, String &errorStr) char bufferVis[128]; dStrncpy(bufferVis, stateSequence[j], 100); dStrcat(bufferVis, "_vis", 128); - s.sequenceVis[i] = mShape[i]->findSequence(bufferVis); + s.sequenceVis[i] = getShape(i)->findSequence(bufferVis); } if (s.sequenceVis[i] != -1) { @@ -537,13 +533,13 @@ bool ShapeBaseImageData::preload(bool server, String &errorStr) s.ignoreLoadedForReady = stateIgnoreLoadedForReady[j]; if (stateEmitterNode[j] && stateEmitterNode[j][0]) - s.emitterNode[i] = mShape[i]->findNode(stateEmitterNode[j]); + s.emitterNode[i] = getShape(i)->findNode(stateEmitterNode[j]); if (s.emitterNode[i] == -1) s.emitterNode[i] = muzzleNode[i]; } - ambientSequence[i] = mShape[i]->findSequence("ambient"); - spinSequence[i] = mShape[i]->findSequence("spin"); + ambientSequence[i] = getShape(i)->findSequence("ambient"); + spinSequence[i] = getShape(i)->findSequence("spin"); shapeIsValid[i] = true; } @@ -567,7 +563,7 @@ bool ShapeBaseImageData::preload(bool server, String &errorStr) { if( shapeIsValid[i] ) { - TSShapeInstance* pDummy = new TSShapeInstance(mShape[i], !server); + TSShapeInstance* pDummy = new TSShapeInstance(getShape(i), !server); delete pDummy; } } @@ -628,8 +624,8 @@ void ShapeBaseImageData::initPersistFields() { docsURL; addGroup("Shapes"); - INITPERSISTFIELD_SHAPEASSET_ARRAY(Shape, MaxShapes, ShapeBaseImageData, "The shape asset to use for this image in the third person") - //addProtectedField("shapeFileFP", TypeShapeFilename, Offset(mShapeName[1], ShapeBaseImageData), _setShapeData, defaultProtectedGetFn, "deprecated alias for ShapeFPFile/Asset", AbstractClassRep::FIELD_HideInInspectors); + INITPERSISTFIELD_SHAPEASSET_ARRAY_REFACTOR(Shape, MaxShapes, ShapeBaseImageData, "The shape assets for this shape image") + addField("casing", TYPEID< DebrisData >(), Offset(casing, ShapeBaseImageData), "@brief DebrisData datablock to use for ejected casings.\n\n" "@see stateEjectShell"); @@ -1002,10 +998,7 @@ void ShapeBaseImageData::packData(BitStream* stream) } } - for (U32 j = 0; j < MaxShapes; ++j) - { - PACKDATA_ASSET_ARRAY(Shape, j); // shape 0 for normal use, shape 1 for first person use (optional) - } + PACKDATA_ASSET_ARRAY_REFACTOR(Shape, MaxShapes); // shape 0 for normal use, shape 1 for first person use (optional) stream->writeString(imageAnimPrefix); stream->writeString(imageAnimPrefixFP); @@ -1186,10 +1179,7 @@ void ShapeBaseImageData::unpackData(BitStream* stream) } } - for (U32 j = 0; j < MaxShapes; ++j) - { - UNPACKDATA_ASSET_ARRAY(Shape, j); // shape 0 for normal use, shape 1 for first person use (optional) - } + UNPACKDATA_ASSET_ARRAY_REFACTOR(Shape, MaxShapes); // shape 0 for normal use, shape 1 for first person use (optional) imageAnimPrefix = stream->readSTString(); imageAnimPrefixFP = stream->readSTString(); @@ -2148,7 +2138,7 @@ S32 ShapeBase::getNodeIndex(U32 imageSlot,StringTableEntry nodeName) { MountedImage& image = mMountedImageList[imageSlot]; if (image.dataBlock) - return image.dataBlock->mShape[getImageShapeIndex(image)]->findNode(nodeName); + return image.dataBlock->getShape(getImageShapeIndex(image))->findNode(nodeName); else return -1; } @@ -2338,7 +2328,7 @@ void ShapeBase::setImage( U32 imageSlot, for (U32 i=0; ishapeIsValid[i]) - image.shapeInstance[i] = new TSShapeInstance(image.dataBlock->mShape[i], isClientObject()); + image.shapeInstance[i] = new TSShapeInstance(image.dataBlock->getShape(i), isClientObject()); } if (isClientObject()) diff --git a/Engine/source/T3D/tsStatic.cpp b/Engine/source/T3D/tsStatic.cpp index 52a28d14b..ad41f08c6 100644 --- a/Engine/source/T3D/tsStatic.cpp +++ b/Engine/source/T3D/tsStatic.cpp @@ -151,13 +151,14 @@ TSStatic::TSStatic() mAnimOffset = 0.0f; mAnimSpeed = 1.0f; - INIT_ASSET(Shape); + mShapeAsset.registerRefreshNotify(this); } TSStatic::~TSStatic() { delete mConvexList; mConvexList = NULL; + mShapeAsset.unregisterRefreshNotify(); } ImplementEnumType(TSMeshType, @@ -180,11 +181,7 @@ void TSStatic::initPersistFields() docsURL; addGroup("Shape"); - INITPERSISTFIELD_SHAPEASSET(Shape, TSStatic, "Model to use for this TSStatic"); - - addProtectedField("shapeName", TypeShapeFilename, Offset(mShapeName, TSStatic), - &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); + INITPERSISTFIELD_SHAPEASSET_REFACTOR(Shape, TSStatic, "Model to use for this TSStatic"); endGroup("Shape"); @@ -393,59 +390,55 @@ bool TSStatic::_createShape() mAmbientThread = NULL; //mShape = NULL; - U32 assetStatus = ShapeAsset::getAssetErrCode(mShapeAsset); - if (assetStatus == AssetBase::Ok || assetStatus == AssetBase::UsingFallback) + if (mShapeAsset.notNull()) { - //Special-case handling, usually because we set noShape - mShape = mShapeAsset->getShapeResource(); - } + if (!getShape()) + { + Con::errorf("TSStatic::_createShape() - Shape Asset %s had no valid shape!", mShapeAsset.getAssetId()); + return false; + } - if (!mShape) - { - Con::errorf("TSStatic::_createShape() - Shape Asset %s had no valid shape!", mShapeAsset.getAssetId()); - return false; - } + if (isClientObject() && + !getShape()->preloadMaterialList(getShape().getPath()) && + NetConnection::filesWereDownloaded()) + return false; - if (isClientObject() && - !mShape->preloadMaterialList(mShape.getPath()) && - NetConnection::filesWereDownloaded()) - return false; + mObjBox = getShape()->mBounds; + resetWorldBox(); - mObjBox = mShape->mBounds; - resetWorldBox(); + mShapeInstance = new TSShapeInstance(getShape(), isClientObject()); + mShapeInstance->resetMaterialList(); + mShapeInstance->cloneMaterialList(); - mShapeInstance = new TSShapeInstance(mShape, isClientObject()); - mShapeInstance->resetMaterialList(); - mShapeInstance->cloneMaterialList(); + if (isGhost()) + { + // Reapply the current skin + mAppliedSkinName = ""; + reSkin(); - if (isGhost()) - { - // Reapply the current skin - mAppliedSkinName = ""; - reSkin(); + updateMaterials(); + } - updateMaterials(); - } + prepCollision(); - prepCollision(); + // Find the "ambient" animation if it exists + S32 ambientSeq = getShape()->findSequence("ambient"); - // Find the "ambient" animation if it exists - S32 ambientSeq = mShape->findSequence("ambient"); + if (ambientSeq > -1 && !mAmbientThread) + mAmbientThread = mShapeInstance->addThread(); - if (ambientSeq > -1 && !mAmbientThread) - mAmbientThread = mShapeInstance->addThread(); + if ( mAmbientThread ) + mShapeInstance->setSequence(mAmbientThread, ambientSeq, mAnimOffset); - if ( mAmbientThread ) - mShapeInstance->setSequence(mAmbientThread, ambientSeq, mAnimOffset); - - // Resolve CubeReflectorDesc. - if (cubeDescName.isNotEmpty()) - { - Sim::findObject(cubeDescName, reflectorDesc); - } - else if (cubeDescId > 0) - { - Sim::findObject(cubeDescId, reflectorDesc); + // Resolve CubeReflectorDesc. + if (cubeDescName.isNotEmpty()) + { + Sim::findObject(cubeDescName, reflectorDesc); + } + else if (cubeDescId > 0) + { + Sim::findObject(cubeDescId, reflectorDesc); + } } //Set up the material slot vars for easy manipulation @@ -533,20 +526,20 @@ void TSStatic::prepCollision() if (mCollisionType == CollisionMesh || mCollisionType == VisibleMesh) { - mShape->findColDetails(mCollisionType == VisibleMesh, &mCollisionDetails, &mLOSDetails, mCollisionLOD); + getShape()->findColDetails(mCollisionType == VisibleMesh, &mCollisionDetails, &mLOSDetails, mCollisionLOD); if (mDecalType == mCollisionType) { mDecalDetailsPtr = &mCollisionDetails; } else if (mDecalType == CollisionMesh || mDecalType == VisibleMesh) { - mShape->findColDetails(mDecalType == VisibleMesh, &mDecalDetails, 0, mCollisionLOD); + getShape()->findColDetails(mDecalType == VisibleMesh, &mDecalDetails, 0, mCollisionLOD); mDecalDetailsPtr = &mDecalDetails; } } else if (mDecalType == CollisionMesh || mDecalType == VisibleMesh) { - mShape->findColDetails(mDecalType == VisibleMesh, &mDecalDetails, 0, mCollisionLOD); + getShape()->findColDetails(mDecalType == VisibleMesh, &mDecalDetails, 0, mCollisionLOD); mDecalDetailsPtr = &mDecalDetails; } @@ -564,12 +557,12 @@ void TSStatic::_updatePhysics() if (mCollisionType == Bounds) { MatrixF offset(true); - offset.setPosition(mShape->center); + offset.setPosition(getShape()->center); colShape = PHYSICSMGR->createCollision(); colShape->addBox(getObjBox().getExtents() * 0.5f * mObjScale, offset); } else - colShape = mShape->buildColShape(mCollisionType == VisibleMesh, getScale()); + colShape = getShape()->buildColShape(mCollisionType == VisibleMesh, getScale()); if (colShape) { @@ -958,7 +951,7 @@ U32 TSStatic::packUpdate(NetConnection* con, U32 mask, BitStream* stream) if (stream->writeFlag(mask & AdvancedStaticOptionsMask)) { - PACK_ASSET(con, Shape); + PACK_ASSET_REFACTOR(con, Shape); stream->write((U32)mDecalType); @@ -1074,7 +1067,7 @@ void TSStatic::unpackUpdate(NetConnection* con, BitStream* stream) if (stream->readFlag()) // AdvancedStaticOptionsMask { - UNPACK_ASSET(con, Shape); + UNPACK_ASSET_REFACTOR(con, Shape); stream->read((U32*)&mDecalType); @@ -1596,7 +1589,7 @@ void TSStatic::updateMaterials() if (mShapeAsset->isAssetValid()) path = mShapeAsset->getShapeFileName(); else - path = mShapeName; + path = mShapeFile; pMatList->setTextureLookupPath(path); @@ -1778,7 +1771,7 @@ DefineEngineMethod(TSStatic, changeMaterial, void, (const char* mapTo, Material* return; } - TSMaterialList* shapeMaterialList = object->getShapeResource()->materialList; + TSMaterialList* shapeMaterialList = object->getShape()->materialList; // Check the mapTo name exists for this shape S32 matIndex = shapeMaterialList->getMaterialNameList().find_next(String(mapTo)); @@ -1818,7 +1811,7 @@ DefineEngineMethod(TSStatic, getModelFile, const char*, (), , "@endtsexample\n" ) { - return object->getShape(); + return object->getShapeFile(); } void TSStatic::set_special_typing() @@ -1863,14 +1856,14 @@ void TSStatic::setSelectionFlags(U8 flags) bool TSStatic::hasNode(const char* nodeName) { - S32 nodeIDx = getShapeResource()->findNode(nodeName); + S32 nodeIDx = getShape()->findNode(nodeName); return nodeIDx >= 0; } void TSStatic::getNodeTransform(const char *nodeName, const MatrixF &xfm, MatrixF *outMat) { - S32 nodeIDx = getShapeResource()->findNode(nodeName); + S32 nodeIDx = getShape()->findNode(nodeName); MatrixF nodeTransform(xfm); const Point3F& scale = getScale(); diff --git a/Engine/source/T3D/tsStatic.h b/Engine/source/T3D/tsStatic.h index fef5ed0bb..150aa59cf 100644 --- a/Engine/source/T3D/tsStatic.h +++ b/Engine/source/T3D/tsStatic.h @@ -101,7 +101,7 @@ public: /// A simple mesh shape with optional ambient animation. -class TSStatic : public SceneObject +class TSStatic : public SceneObject, protected AssetPtrCallback { typedef SceneObject Parent; @@ -186,12 +186,17 @@ protected: ReflectorDesc* reflectorDesc; CubeReflector mCubeReflector; + void onAssetRefreshed(AssetPtrBase* pAssetPtrBase) override + { + _createShape(); + _updateShouldTick(); + } + protected: Convex* mConvexList; - DECLARE_SHAPEASSET(TSStatic, Shape, onShapeChanged); - DECLARE_ASSET_NET_SETGET(TSStatic, Shape, AdvancedStaticOptionsMask); + DECLARE_SHAPEASSET_NET_REFACTOR(TSStatic, Shape, AdvancedStaticOptionsMask) U32 mShapeHash; Vector mCollisionDetails; @@ -239,7 +244,7 @@ public: DECLARE_CATEGORY("Object \t Simple"); static void initPersistFields(); /// returns the shape asset used for this object - StringTableEntry getTypeHint() const override { return (getShapeAsset()) ? getShapeAsset()->getAssetName(): StringTable->EmptyString(); } + StringTableEntry getTypeHint() const override { return (mShapeAsset.notNull()) ? mShapeAsset->getAssetName(): StringTable->EmptyString(); } static void consoleInit(); static bool _setFieldSkin(void* object, const char* index, const char* data); static const char* _getFieldSkin(void* object, const char* data); diff --git a/Engine/source/T3D/turret/aiTurretShape.cpp b/Engine/source/T3D/turret/aiTurretShape.cpp index 5ad3df020..cedb51af2 100644 --- a/Engine/source/T3D/turret/aiTurretShape.cpp +++ b/Engine/source/T3D/turret/aiTurretShape.cpp @@ -246,8 +246,8 @@ bool AITurretShapeData::preload(bool server, String &errorStr) return false; // We have mShape at this point. Resolve nodes. - scanNode = mShape->findNode("scanPoint"); - aimNode = mShape->findNode("aimPoint"); + scanNode = getShape()->findNode("scanPoint"); + aimNode = getShape()->findNode("aimPoint"); if (scanNode == -1) scanNode = pitchNode; if (scanNode == -1) scanNode = headingNode; @@ -259,7 +259,7 @@ bool AITurretShapeData::preload(bool server, String &errorStr) for (U32 j = 0; j < MaxStates; j++) { StateData& s = state[j]; if (stateSequence[j] && stateSequence[j][0]) - s.sequence = mShape->findSequence(stateSequence[j]); + s.sequence = getShape()->findSequence(stateSequence[j]); if (s.sequence != -1) { // This state has an animation sequence diff --git a/Engine/source/T3D/turret/turretShape.cpp b/Engine/source/T3D/turret/turretShape.cpp index e155663aa..08380da6a 100644 --- a/Engine/source/T3D/turret/turretShape.cpp +++ b/Engine/source/T3D/turret/turretShape.cpp @@ -217,35 +217,35 @@ bool TurretShapeData::preload(bool server, String &errorStr) return false; // We have mShape at this point. Resolve nodes. - headingNode = mShape->findNode("heading"); - pitchNode = mShape->findNode("pitch"); + headingNode = getShape()->findNode("heading"); + pitchNode = getShape()->findNode("pitch"); // Find any mirror pitch nodes for (U32 i = 0; i < NumMirrorDirectionNodes; ++i) { char name[32]; dSprintf(name, 31, "pitch%d", i+1); - pitchNodes[i] = mShape->findNode(name); + pitchNodes[i] = getShape()->findNode(name); dSprintf(name, 31, "heading%d", i+1); - headingNodes[i] = mShape->findNode(name); + headingNodes[i] = getShape()->findNode(name); } // Resolve weapon mount point node indexes for (U32 i = 0; i < ShapeBase::MaxMountedImages; i++) { char fullName[256]; dSprintf(fullName,sizeof(fullName),"weaponMount%d",i); - weaponMountNode[i] = mShape->findNode(fullName); + weaponMountNode[i] = getShape()->findNode(fullName); } // Recoil animations - recoilSequence[0] = mShape->findSequence("light_recoil"); - recoilSequence[1] = mShape->findSequence("medium_recoil"); - recoilSequence[2] = mShape->findSequence("heavy_recoil"); + recoilSequence[0] = getShape()->findSequence("light_recoil"); + recoilSequence[1] = getShape()->findSequence("medium_recoil"); + recoilSequence[2] = getShape()->findSequence("heavy_recoil"); // Optional sequences used when the turret rotates - pitchSequence = mShape->findSequence("pitch"); - headingSequence = mShape->findSequence("heading"); + pitchSequence = getShape()->findSequence("pitch"); + headingSequence = getShape()->findSequence("heading"); return true; } diff --git a/Engine/source/T3D/vehicles/flyingVehicle.cpp b/Engine/source/T3D/vehicles/flyingVehicle.cpp index 24cf33490..4e10c4b2a 100644 --- a/Engine/source/T3D/vehicles/flyingVehicle.cpp +++ b/Engine/source/T3D/vehicles/flyingVehicle.cpp @@ -135,7 +135,7 @@ bool FlyingVehicleData::preload(bool server, String &errorStr) if (!Parent::preload(server, errorStr)) return false; - TSShapeInstance* si = new TSShapeInstance(mShape, false); + TSShapeInstance* si = new TSShapeInstance(getShape(), false); // Resolve objects transmitted from server if (!server) { @@ -164,7 +164,7 @@ bool FlyingVehicleData::preload(bool server, String &errorStr) // Resolve jet nodes for (S32 j = 0; j < MaxJetNodes; j++) - jetNode[j] = mShape->findNode(sJetNode[j]); + jetNode[j] = getShape()->findNode(sJetNode[j]); // maxSpeed = maneuveringForce / minDrag; diff --git a/Engine/source/T3D/vehicles/hoverVehicle.cpp b/Engine/source/T3D/vehicles/hoverVehicle.cpp index 482364bd3..9f536454c 100644 --- a/Engine/source/T3D/vehicles/hoverVehicle.cpp +++ b/Engine/source/T3D/vehicles/hoverVehicle.cpp @@ -332,7 +332,7 @@ bool HoverVehicleData::preload(bool server, String &errorStr) } // Resolve jet nodes for (S32 j = 0; j < MaxJetNodes; j++) - jetNode[j] = mShape->findNode(sJetNode[j]); + jetNode[j] = getShape()->findNode(sJetNode[j]); return true; } diff --git a/Engine/source/T3D/vehicles/vehicle.cpp b/Engine/source/T3D/vehicles/vehicle.cpp index 9ad0abdbf..167ea203a 100644 --- a/Engine/source/T3D/vehicles/vehicle.cpp +++ b/Engine/source/T3D/vehicles/vehicle.cpp @@ -163,7 +163,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 asset \"%s\"", mShapeAsset.getAssetId()); + errorStr = String::ToString("VehicleData: Couldn't load shape asset \"%s\"", getShapeAsset().getAssetId()); return false; } diff --git a/Engine/source/T3D/vehicles/wheeledVehicle.cpp b/Engine/source/T3D/vehicles/wheeledVehicle.cpp index 9f3febd13..ec107eedc 100644 --- a/Engine/source/T3D/vehicles/wheeledVehicle.cpp +++ b/Engine/source/T3D/vehicles/wheeledVehicle.cpp @@ -75,8 +75,6 @@ ConsoleDocClass( WheeledVehicleTire, WheeledVehicleTire::WheeledVehicleTire() { - INIT_ASSET(Shape); - staticFriction = 1; kineticFriction = 0.5f; restitution = 1; @@ -88,15 +86,16 @@ WheeledVehicleTire::WheeledVehicleTire() longitudinalDamping = 1; longitudinalRelaxation = 1; mass = 1.f; + mShapeAsset.registerRefreshNotify(this); } 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 (!mShape) + if (!getShape()) { - errorStr = String::ToString("WheeledVehicleTire: Couldn't load shape \"%s\"", mShapeAssetId); + errorStr = String::ToString("WheeledVehicleTire: Couldn't load shape \"%s\"", _getShapeAssetId()); return false; } else @@ -104,7 +103,7 @@ bool WheeledVehicleTire::preload(bool server, String &errorStr) // 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 = mShape->mBounds.len_z() / 2; + radius = getShape()->mBounds.len_z() / 2; } return true; @@ -113,7 +112,7 @@ bool WheeledVehicleTire::preload(bool server, String &errorStr) void WheeledVehicleTire::initPersistFields() { docsURL; - INITPERSISTFIELD_SHAPEASSET(Shape, WheeledVehicleTire, "The shape to use for the wheel."); + INITPERSISTFIELD_SHAPEASSET_REFACTOR(Shape, WheeledVehicleTire, "The shape to use for the wheel."); addFieldV( "mass", TypeRangedF32, Offset(mass, WheeledVehicleTire), &CommonValidators::PositiveFloat, "The mass of the wheel.\nCurrently unused." ); @@ -178,7 +177,7 @@ void WheeledVehicleTire::packData(BitStream* stream) { Parent::packData(stream); - PACKDATA_ASSET(Shape); + PACKDATA_ASSET_REFACTOR(Shape); stream->write(mass); stream->write(staticFriction); @@ -197,7 +196,7 @@ void WheeledVehicleTire::unpackData(BitStream* stream) { Parent::unpackData(stream); - UNPACKDATA_ASSET(Shape); + UNPACKDATA_ASSET_REFACTOR(Shape); stream->read(&mass); stream->read(&staticFriction); @@ -343,7 +342,7 @@ bool WheeledVehicleData::preload(bool server, String &errorStr) // A temporary shape instance is created so that we can // animate the shape and extract wheel information. - TSShapeInstance* si = new TSShapeInstance(mShape, false); + TSShapeInstance* si = new TSShapeInstance(getShape(), false); // Resolve objects transmitted from server if (!server) { @@ -367,14 +366,14 @@ bool WheeledVehicleData::preload(bool server, String &errorStr) // The wheel must have a hub node to operate at all. dSprintf(buff,sizeof(buff),"hub%d",i); - wp->springNode = mShape->findNode(buff); + wp->springNode = getShape()->findNode(buff); if (wp->springNode != -1) { // Check for spring animation.. If there is none we just grab // the current position of the hub. Otherwise we'll animate // and get the position at time 0. dSprintf(buff,sizeof(buff),"spring%d",i); - wp->springSequence = mShape->findSequence(buff); + wp->springSequence = getShape()->findSequence(buff); if (wp->springSequence == -1) si->mNodeTransforms[wp->springNode].getColumn(3, &wp->pos); else { @@ -403,17 +402,17 @@ bool WheeledVehicleData::preload(bool server, String &errorStr) // Check for steering. Should think about normalizing the // steering animation the way the suspension is, but I don't // think it's as critical. - steeringSequence = mShape->findSequence("steering"); + steeringSequence = getShape()->findSequence("steering"); // Brakes - brakeLightSequence = mShape->findSequence("brakelight"); + brakeLightSequence = getShape()->findSequence("brakelight"); // Extract collision planes from shape collision detail level if (collisionDetails[0] != -1) { MatrixF imat(1); SphereF sphere; - sphere.center = mShape->center; - sphere.radius = mShape->mRadius; + sphere.center = getShape()->center; + sphere.radius = getShape()->mRadius; PlaneExtractorPolyList polyList; polyList.mPlaneList = &rigidBody.mPlaneList; polyList.setTransform(&imat, Point3F(1,1,1)); @@ -1579,8 +1578,8 @@ void WheeledVehicle::unpackUpdate(NetConnection *con, BitStream *stream) // Create an instance of the tire for rendering delete wheel->shapeInstance; - wheel->shapeInstance = (wheel->tire->mShape == NULL) ? 0: - new TSShapeInstance(wheel->tire->mShape); + wheel->shapeInstance = (wheel->tire->getShape() == NULL) ? 0: + new TSShapeInstance(wheel->tire->getShape()); } } } diff --git a/Engine/source/T3D/vehicles/wheeledVehicle.h b/Engine/source/T3D/vehicles/wheeledVehicle.h index f208fbf5b..17164a286 100644 --- a/Engine/source/T3D/vehicles/wheeledVehicle.h +++ b/Engine/source/T3D/vehicles/wheeledVehicle.h @@ -39,12 +39,11 @@ class ParticleEmitterData; //---------------------------------------------------------------------------- -struct WheeledVehicleTire: public SimDataBlock +struct WheeledVehicleTire: public SimDataBlock, protected AssetPtrCallback { typedef SimDataBlock Parent; - DECLARE_SHAPEASSET(WheeledVehicleTire, Shape, onShapeChanged); - DECLARE_ASSET_SETGET(WheeledVehicleTire, Shape); + DECLARE_SHAPEASSET_REFACTOR(WheeledVehicleTire, Shape) // Physical properties F32 mass; // Mass of the whole wheel @@ -74,7 +73,8 @@ struct WheeledVehicleTire: public SimDataBlock void packData(BitStream* stream) override; void unpackData(BitStream* stream) override; - void onShapeChanged() +protected: + void onAssetRefreshed(AssetPtrBase* pAssetPtrBase) override { reloadOnLocalClient(); } diff --git a/Engine/source/afx/afxMagicMissile.cpp b/Engine/source/afx/afxMagicMissile.cpp index d77ead423..46a8d6371 100644 --- a/Engine/source/afx/afxMagicMissile.cpp +++ b/Engine/source/afx/afxMagicMissile.cpp @@ -141,7 +141,6 @@ U32 Projectile::smProjectileWarpTicks = 5; // afxMagicMissileData::afxMagicMissileData() { - INIT_ASSET(ProjectileShape); INIT_ASSET(ProjectileSound); /* From stock Projectile code... @@ -241,11 +240,13 @@ afxMagicMissileData::afxMagicMissileData() reverse_targeting = false; caster_safety_time = U32_MAX; + + mProjectileShapeAsset.registerRefreshNotify(this); } afxMagicMissileData::afxMagicMissileData(const afxMagicMissileData& other, bool temp_clone) : GameBaseData(other, temp_clone) { - CLONE_ASSET(ProjectileShape); + mProjectileShapeAsset = other.mProjectileShapeAsset; projectileShape = other.projectileShape; // -- TSShape loads using projectileShapeName CLONE_ASSET(ProjectileSound); splash = other.splash; @@ -305,6 +306,8 @@ afxMagicMissileData::~afxMagicMissileData() { if (wiggle_axis) delete [] wiggle_axis; + + mProjectileShapeAsset.unregisterRefreshNotify(); } afxMagicMissileData* afxMagicMissileData::cloneAndPerformSubstitutions(const SimObject* owner, S32 index) @@ -334,7 +337,7 @@ void afxMagicMissileData::initPersistFields() static IRangeValidatorScaled ticksFromMS(TickMs, 0, MaxLifetimeTicks); addGroup("Shapes"); - INITPERSISTFIELD_SHAPEASSET(ProjectileShape, afxMagicMissileData, "Shape for the projectile"); + INITPERSISTFIELD_SHAPEASSET_REFACTOR(ProjectileShape, afxMagicMissileData, "Shape for the projectile"); addField("scale", TypePoint3F, Offset(scale, afxMagicMissileData)); addField("missileShapeScale", TypePoint3F, myOffset(scale)); endGroup("Shapes"); @@ -531,10 +534,10 @@ bool afxMagicMissileData::preload(bool server, String &errorStr) U32 assetStatus = ShapeAsset::getAssetErrCode(mProjectileShapeAsset); if (assetStatus == AssetBase::Ok || assetStatus == AssetBase::UsingFallback) { - projectileShape = mProjectileShapeAsset->getShapeResource(); + projectileShape = getProjectileShape(); if (bool(projectileShape) == false) { - errorStr = String::ToString("afxMagicMissileData::preload: Couldn't load shape \"%s\"", mProjectileShapeAssetId); + errorStr = String::ToString("afxMagicMissileData::preload: Couldn't load shape \"%s\"", _getProjectileShapeAssetId()); return false; } /* From stock Projectile code... @@ -586,7 +589,7 @@ void afxMagicMissileData::packData(BitStream* stream) { Parent::packData(stream); - PACKDATA_ASSET(ProjectileShape); + PACKDATA_ASSET_REFACTOR(ProjectileShape); /* From stock Projectile code... stream->writeFlag(faceViewer); @@ -697,7 +700,7 @@ void afxMagicMissileData::unpackData(BitStream* stream) { Parent::unpackData(stream); - UNPACKDATA_ASSET(ProjectileShape); + UNPACKDATA_ASSET_REFACTOR(ProjectileShape); /* From stock Projectile code... faceViewer = stream->readFlag(); */ diff --git a/Engine/source/afx/afxMagicMissile.h b/Engine/source/afx/afxMagicMissile.h index 8aa8f8084..26f731ae3 100644 --- a/Engine/source/afx/afxMagicMissile.h +++ b/Engine/source/afx/afxMagicMissile.h @@ -56,7 +56,7 @@ class SFXSource; //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// // afxMagicMissileData -class afxMagicMissileData : public GameBaseData +class afxMagicMissileData : public GameBaseData, protected AssetPtrCallback { typedef GameBaseData Parent; @@ -66,16 +66,10 @@ protected: public: enum { MaxLifetimeTicks = 4095 }; - void onShapeChanged() - { - reloadOnLocalClient(); - } - public: // variables set in datablock definition: // Shape related - DECLARE_SHAPEASSET(afxMagicMissileData, ProjectileShape, onShapeChanged); - DECLARE_ASSET_SETGET(afxMagicMissileData, ProjectileShape); + DECLARE_SHAPEASSET_REFACTOR(afxMagicMissileData, ProjectileShape) //StringTableEntry projectileShapeName; //bool hasLight; @@ -228,6 +222,12 @@ public: afxMagicMissileData* cloneAndPerformSubstitutions(const SimObject*, S32 index=0); bool allowSubstitutions() const override { return true; } void gather_cons_defs(Vector& defs); + +protected: + void onAssetRefreshed(AssetPtrBase* pAssetPtrBase) override + { + reloadOnLocalClient(); + } }; //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// diff --git a/Engine/source/afx/ce/afxModel.cpp b/Engine/source/afx/ce/afxModel.cpp index 97746493d..00a2e0f71 100644 --- a/Engine/source/afx/ce/afxModel.cpp +++ b/Engine/source/afx/ce/afxModel.cpp @@ -54,7 +54,6 @@ ConsoleDocClass( afxModelData, afxModelData::afxModelData() { - INIT_ASSET(Shape); sequence = ST_NULLSTRING; seq_rate = 1.0f; seq_offset = 0.0f; @@ -79,11 +78,13 @@ afxModelData::afxModelData() shadowMaxVisibleDistance = 80.0f; shadowProjectionDistance = 10.0f; shadowSphereAdjust = 1.0; + + mShapeAsset.registerRefreshNotify(this); } afxModelData::afxModelData(const afxModelData& other, bool temp_clone) : GameBaseData(other, temp_clone) { - CLONE_ASSET(Shape); + mShapeAsset = other.mShapeAsset; sequence = other.sequence; seq_rate = other.seq_rate; seq_offset = other.seq_offset; @@ -113,6 +114,8 @@ afxModelData::~afxModelData() { if (remap_buffer) dFree(remap_buffer); + + mShapeAsset.unregisterRefreshNotify(); } bool afxModelData::preload(bool server, String &errorStr) @@ -126,9 +129,9 @@ bool afxModelData::preload(bool server, String &errorStr) if (mShapeAsset.notNull()) { - if (!mShape) + if (!getShape()) { - errorStr = String::ToString("afxModelData::load: Failed to load shape \"%s\"", mShapeAssetId); + errorStr = String::ToString("afxModelData::load: Failed to load shape \"%s\"", _getShapeAssetId()); return false; } @@ -160,7 +163,7 @@ bool afxModelData::preload(bool server, String &errorStr) if (txr_tag_remappings.size() == 0) { // this little hack forces the textures to preload - TSShapeInstance* pDummy = new TSShapeInstance(mShape); + TSShapeInstance* pDummy = new TSShapeInstance(getShape()); delete pDummy; } } @@ -174,7 +177,7 @@ void afxModelData::initPersistFields() { docsURL; addGroup("Shapes"); - INITPERSISTFIELD_SHAPEASSET(Shape, afxModelData, "The name of a .dts format file to use for the model."); + INITPERSISTFIELD_SHAPEASSET_REFACTOR(Shape, afxModelData, "The name of a .dts format file to use for the model."); endGroup("Shapes"); addGroup("Animation"); @@ -258,7 +261,7 @@ void afxModelData::packData(BitStream* stream) { Parent::packData(stream); - PACKDATA_ASSET(Shape); + PACKDATA_ASSET_REFACTOR(Shape); stream->writeString(sequence); stream->write(seq_rate); stream->write(seq_offset); @@ -289,7 +292,7 @@ void afxModelData::unpackData(BitStream* stream) { Parent::unpackData(stream); - UNPACKDATA_ASSET(Shape); + UNPACKDATA_ASSET_REFACTOR(Shape); sequence = stream->readSTString(); stream->read(&seq_rate); stream->read(&seq_offset); @@ -318,21 +321,10 @@ void afxModelData::unpackData(BitStream* stream) void afxModelData::onPerformSubstitutions() { - if (mShapeAssetId != StringTable->EmptyString()) + if (!getShape()) { - mShapeAsset = mShapeAssetId; - if (mShapeAsset.notNull()) - { - mShape = mShapeAsset->getShapeResource(); - } - - if (!mShape) - { - Con::errorf("afxModelData::onPerformSubstitutions: Failed to load shape \"%s\"", mShapeAssetId); - return; - } - - // REMAP-TEXTURE-TAGS ISSUES? + Con::errorf("afxModelData::onPerformSubstitutions: Failed to load shape \"%s\"", _getShapeAssetId()); + return; } } @@ -406,18 +398,18 @@ bool afxModel::onAdd() return false; // setup our bounding box - if (mDataBlock->mShape) - mObjBox = mDataBlock->mShape->mBounds; + if (mDataBlock->getShape()) + mObjBox = mDataBlock->getShape()->mBounds; else mObjBox = Box3F(Point3F(-1, -1, -1), Point3F(1, 1, 1)); // setup the shape instance and sequence - if (mDataBlock->mShape) + if (mDataBlock->getShape()) { if (/*isClientObject() && */mDataBlock->txr_tag_remappings.size() > 0) { // temporarily substitute material tags with alternates - TSMaterialList* mat_list = mDataBlock->mShape->materialList; + TSMaterialList* mat_list = mDataBlock->getShape()->materialList; if (mat_list) { for (S32 i = 0; i < mDataBlock->txr_tag_remappings.size(); i++) @@ -438,7 +430,7 @@ bool afxModel::onAdd() } } - shape_inst = new TSShapeInstance(mDataBlock->mShape); + shape_inst = new TSShapeInstance(mDataBlock->getShape()); if (true) // isClientObject()) { @@ -447,7 +439,7 @@ bool afxModel::onAdd() // restore the material tags to original form if (mDataBlock->txr_tag_remappings.size() > 0) { - TSMaterialList* mat_list = mDataBlock->mShape->materialList; + TSMaterialList* mat_list = mDataBlock->getShape()->materialList; if (mat_list) { for (S32 i = 0; i < mDataBlock->txr_tag_remappings.size(); i++) @@ -513,14 +505,14 @@ bool afxModel::onAdd() resetWorldBox(); - if (mDataBlock->mShape) + if (mDataBlock->getShape()) { // Scan out the collision hulls... static const String sCollisionStr( "collision-" ); - for (U32 i = 0; i < mDataBlock->mShape->details.size(); i++) + for (U32 i = 0; i < mDataBlock->getShape()->details.size(); i++) { - const String &name = mDataBlock->mShape->names[mDataBlock->mShape->details[i].nameIndex]; + const String &name = mDataBlock->getShape()->names[mDataBlock->getShape()->details[i].nameIndex]; if (name.compare( sCollisionStr, sCollisionStr.length(), String::NoCase ) == 0) { @@ -534,7 +526,7 @@ bool afxModel::onAdd() char buff[128]; dSprintf(buff, sizeof(buff), "LOS-%d", i + 1 + 8/*MaxCollisionShapes*/); - U32 los = mDataBlock->mShape->findDetail(buff); + U32 los = mDataBlock->getShape()->findDetail(buff); if (los == -1) mLOSDetails.last() = i; else @@ -545,9 +537,9 @@ bool afxModel::onAdd() // Snag any "unmatched" LOS details static const String sLOSStr( "LOS-" ); - for (U32 i = 0; i < mDataBlock->mShape->details.size(); i++) + for (U32 i = 0; i < mDataBlock->getShape()->details.size(); i++) { - const String &name = mDataBlock->mShape->names[mDataBlock->mShape->details[i].nameIndex]; + const String &name = mDataBlock->getShape()->names[mDataBlock->getShape()->details[i].nameIndex]; if (name.compare( sLOSStr, sLOSStr.length(), String::NoCase ) == 0) { diff --git a/Engine/source/afx/ce/afxModel.h b/Engine/source/afx/ce/afxModel.h index de2656b8f..ce7fb19ac 100644 --- a/Engine/source/afx/ce/afxModel.h +++ b/Engine/source/afx/ce/afxModel.h @@ -39,12 +39,11 @@ class TSShape; //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// // afxModel Data -struct afxModelData : public GameBaseData +struct afxModelData : public GameBaseData, protected AssetPtrCallback { typedef GameBaseData Parent; - DECLARE_SHAPEASSET(afxModelData, Shape, onShapeChanged); - DECLARE_ASSET_SETGET(afxModelData, Shape); + DECLARE_SHAPEASSET_REFACTOR(afxModelData, Shape) StringTableEntry sequence; @@ -94,13 +93,15 @@ public: static void initPersistFields(); - void onShapeChanged() - { - reloadOnLocalClient(); - } void onSequenceChanged() {} DECLARE_CONOBJECT(afxModelData); + +protected: + void onAssetRefreshed(AssetPtrBase* pAssetPtrBase) override + { + reloadOnLocalClient(); + } }; //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// @@ -154,9 +155,9 @@ public: void setSequenceRateFactor(F32 factor); void setSortPriority(S8 priority) { sort_priority = priority; } - const char* getShapeFileName() const { return mDataBlock->getShape(); } + const char* getShapeFileName() const { return mDataBlock->getShapeFile(); } void setVisibility(bool flag) { is_visible = flag; } - TSShape* getTSShape() { return mDataBlock->getShapeResource(); } + TSShape* getTSShape() { return mDataBlock->getShape(); } TSShapeInstance* getTSShapeInstance() { return shape_inst; } U32 setAnimClip(const char* clip, F32 pos, F32 rate, F32 trans); diff --git a/Engine/source/afx/ce/afxStaticShape.h b/Engine/source/afx/ce/afxStaticShape.h index 3d0e3f2d9..fce335f90 100644 --- a/Engine/source/afx/ce/afxStaticShape.h +++ b/Engine/source/afx/ce/afxStaticShape.h @@ -85,7 +85,7 @@ public: U32 packUpdate(NetConnection*, U32, BitStream*) override; void unpackUpdate(NetConnection*, BitStream*) override; - const char* getShapeFileName() const { return mDataBlock->mShapeAsset->getShapeFileName(); } + const char* getShapeFileName() const { return mDataBlock->getShapeFile(); } void setVisibility(bool flag) { mIs_visible = flag; } DECLARE_CONOBJECT(afxStaticShape); diff --git a/Engine/source/environment/VolumetricFog.cpp b/Engine/source/environment/VolumetricFog.cpp index 875982015..be8b8a2cc 100644 --- a/Engine/source/environment/VolumetricFog.cpp +++ b/Engine/source/environment/VolumetricFog.cpp @@ -135,8 +135,6 @@ VolumetricFog::VolumetricFog() mTexTiles = 1.0f; mSpeed1.set(0.5f, 0.0f); mSpeed2.set(0.1f, 0.1f); - - INIT_ASSET(Shape); } VolumetricFog::~VolumetricFog() @@ -164,7 +162,7 @@ void VolumetricFog::initPersistFields() docsURL; Parent::initPersistFields(); addGroup("Shapes"); - INITPERSISTFIELD_SHAPEASSET(Shape, VolumetricFog, "The source shape asset."); + INITPERSISTFIELD_SHAPEASSET_REFACTOR(Shape, VolumetricFog, "The source shape asset."); endGroup("Shapes"); addGroup("VolumetricFogData"); @@ -342,7 +340,7 @@ void VolumetricFog::handleResize(VolumetricFogRTManager *RTM, bool resize) bool VolumetricFog::setShapeAsset(const StringTableEntry shapeAssetId) { - mShapeAssetId = shapeAssetId; + _setShape(shapeAssetId); LoadShape(); return true; @@ -358,20 +356,20 @@ bool VolumetricFog::LoadShape() return false; } - if (!mShape) + if (!getShape()) { Con::errorf("VolumetricFog::_createShape() - Shape Asset had no valid shape!"); return false; } - mObjBox = mShape->mBounds; - mRadius = mShape->mRadius; + mObjBox = getShape()->mBounds; + mRadius = getShape()->mRadius; resetWorldBox(); if (!isClientObject()) return false; - TSShapeInstance *mShapeInstance = new TSShapeInstance(mShape, false); + TSShapeInstance *mShapeInstance = new TSShapeInstance(getShape(), false); meshes mesh_detail; for (S32 i = 0; i < det_size.size(); i++) @@ -387,9 +385,9 @@ bool VolumetricFog::LoadShape() // browsing model for detail levels - for (U32 i = 0; i < mShape->details.size(); i++) + for (U32 i = 0; i < getShape()->details.size(); i++) { - const TSDetail *detail = &mShape->details[i]; + const TSDetail *detail = &getShape()->details[i]; mesh_detail.det_size = detail->size; mesh_detail.sub_shape = detail->subShapeNum; mesh_detail.obj_det = detail->objectDetailNum; @@ -405,8 +403,8 @@ bool VolumetricFog::LoadShape() const S32 ss = det_size[i].sub_shape; if (ss >= 0) { - const S32 start = mShape->subShapeFirstObject[ss]; - const S32 end = start + mShape->subShapeNumObjects[ss]; + const S32 start = getShape()->subShapeFirstObject[ss]; + const S32 end = start + getShape()->subShapeNumObjects[ss]; for (S32 j = start; j < end; j++) { // Loading shape, only the first mesh for each detail will be used! @@ -568,7 +566,7 @@ U32 VolumetricFog::packUpdate(NetConnection *con, U32 mask, BitStream *stream) } if (stream->writeFlag(mask & FogShapeMask)) { - PACK_ASSET(con, Shape); + PACK_ASSET_REFACTOR(con, Shape); mathWrite(*stream, getTransform()); mathWrite(*stream, getScale()); @@ -597,8 +595,8 @@ void VolumetricFog::unpackUpdate(NetConnection *con, BitStream *stream) VectorF scale; VectorF mOldScale = getScale(); StringTableEntry oldTextureName = mTextureAsset.getAssetId(); - StringTableEntry oldShapeAsset = mShapeAssetId; - StringTableEntry oldShape = mShapeName; + StringTableEntry oldShapeAsset = _getShapeAssetId(); + StringTableEntry oldShape = getShapeFile(); if (stream->readFlag())// Fog color stream->read(&mFogColor); @@ -667,11 +665,11 @@ void VolumetricFog::unpackUpdate(NetConnection *con, BitStream *stream) } if (stream->readFlag())//Fog shape { - UNPACK_ASSET(con, Shape); + UNPACK_ASSET_REFACTOR(con, Shape); mathRead(*stream, &mat); mathRead(*stream, &scale); - if (strcmp(oldShapeAsset, mShapeAssetId) != 0 || strcmp(oldShape, mShapeName) != 0) + if (strcmp(oldShapeAsset, _getShapeAssetId()) != 0 || strcmp(oldShape, getShapeFile()) != 0) { mIsVBDirty = true; mShapeLoaded = LoadShape(); diff --git a/Engine/source/environment/VolumetricFog.h b/Engine/source/environment/VolumetricFog.h index 42f085eab..76519f654 100644 --- a/Engine/source/environment/VolumetricFog.h +++ b/Engine/source/environment/VolumetricFog.h @@ -84,8 +84,7 @@ class VolumetricFog : public SceneObject Vector *indices; }; - DECLARE_SHAPEASSET(VolumetricFog, Shape, onShapeChanged); - DECLARE_ASSET_NET_SETGET(VolumetricFog, Shape, FogShapeMask); + DECLARE_SHAPEASSET_REFACTOR(VolumetricFog, Shape) protected: // Rendertargets; @@ -203,6 +202,7 @@ class VolumetricFog : public SceneObject void ResizeRT(PlatformWindow *win, bool resize); protected: + // Protected methods bool onAdd() override; void onRemove() override; @@ -246,8 +246,6 @@ class VolumetricFog : public SceneObject bool isInsideFog(); bool setShapeAsset(const StringTableEntry shapeAssetId); - - void onShapeChanged() {} DECLARE_CONOBJECT(VolumetricFog); DECLARE_CATEGORY("Environment \t Weather");