mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-01-20 04:34:48 +00:00
Initial pass at implementing MaterialAsset macromagic utility functions and applies it to the renderMeshExample object as well as groundPlane
This commit is contained in:
parent
e9dba74891
commit
c1cd217557
|
|
@ -19,6 +19,8 @@
|
|||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
#pragma once
|
||||
|
||||
#ifndef MATERIALASSET_H
|
||||
#define MATERIALASSET_H
|
||||
|
||||
|
|
@ -42,6 +44,10 @@
|
|||
#include "gfx/gfxDevice.h"
|
||||
#endif
|
||||
|
||||
#ifndef _NETCONNECTION_H_
|
||||
#include "sim/netConnection.h"
|
||||
#endif
|
||||
|
||||
#include "gui/editor/guiInspectorTypes.h"
|
||||
|
||||
#include "materials/matTextureTarget.h"
|
||||
|
|
@ -118,5 +124,93 @@ public:
|
|||
static void consoleInit();
|
||||
};
|
||||
|
||||
#define assetText(x,suff) std::string(std::string(#x) + std::string(#suff)).c_str()
|
||||
|
||||
#define initMaterialAsset(name) m##name##Name = StringTable->EmptyString(); m##name##AssetId = StringTable->EmptyString(); m##name##Asset = NULL;
|
||||
#define bindMaterialAsset(name) if (m##name##AssetId != StringTable->EmptyString()) m##name##Asset = m##name##AssetId;
|
||||
|
||||
#define scriptBindMaterialAsset(name, consoleClass, docs) addProtectedField(assetText(name, File), TypeMaterialName, Offset(m##name##Name, consoleClass), consoleClass::_set##name##Name, & defaultProtectedGetFn, assetText(name, docs)); \
|
||||
addProtectedField(assetText(name, Asset), TypeMaterialAssetId, Offset(m##name##AssetId, consoleClass), consoleClass::_set##name##Asset, & defaultProtectedGetFn, assetText(name, asset reference.));
|
||||
|
||||
/// <summary>
|
||||
/// DECLARE_MATERIALASSET is a utility macro for MaterialAssets. It takes in the name of the class using it, the name of the field for the material, and a networking bitmask
|
||||
/// The first 2 are for setting up/filling out the fields and class member defines
|
||||
/// The bitmask is for when the material is changed, it can automatically kick a network update on the owner object to pass the changed asset to clients
|
||||
/// </summary>
|
||||
#define DECLARE_MATERIALASSET(className,name,bitmask) protected: \
|
||||
StringTableEntry m##name##Name;\
|
||||
StringTableEntry m##name##AssetId;\
|
||||
AssetPtr<MaterialAsset> m##name##Asset;\
|
||||
public: \
|
||||
const StringTableEntry& get##name() const { return m##name##Name; }\
|
||||
void set##name(FileName _in) { m##name##Name = _in; }\
|
||||
const AssetPtr<MaterialAsset> & get##name##Asset() const { return m##name##Asset; }\
|
||||
void set##name##Asset(AssetPtr<MaterialAsset>_in) { m##name##Asset = _in; }\
|
||||
static bool _set##name##Name(void* obj, const char* index, const char* data)\
|
||||
{\
|
||||
className* shape = static_cast<className*>(obj);\
|
||||
\
|
||||
StringTableEntry assetId = MaterialAsset::getAssetIdByMaterialName(StringTable->insert(data));\
|
||||
if (assetId != StringTable->EmptyString())\
|
||||
{\
|
||||
if (shape->_set##name##Asset(obj, index, assetId))\
|
||||
{\
|
||||
if (assetId == StringTable->insert("Core_Rendering:noMaterial"))\
|
||||
{\
|
||||
shape->m##name##Name = data;\
|
||||
shape->m##name##AssetId = StringTable->EmptyString();\
|
||||
\
|
||||
return true;\
|
||||
}\
|
||||
else\
|
||||
{\
|
||||
shape->m##name##AssetId = assetId;\
|
||||
shape->m##name##Name = StringTable->EmptyString();\
|
||||
\
|
||||
return false;\
|
||||
}\
|
||||
}\
|
||||
}\
|
||||
else\
|
||||
{\
|
||||
shape->m##name##Asset = StringTable->EmptyString();\
|
||||
}\
|
||||
\
|
||||
return true;\
|
||||
}\
|
||||
\
|
||||
static bool _set##name##Asset(void* obj, const char* index, const char* data)\
|
||||
{\
|
||||
className* shape = static_cast<className*>(obj);\
|
||||
shape->m##name##AssetId = StringTable->insert(data);\
|
||||
if (MaterialAsset::getAssetById(shape->m##name##AssetId, &shape->m##name##Asset))\
|
||||
{\
|
||||
if (shape->m##name##Asset.getAssetId() != StringTable->insert("Core_Rendering:noMaterial"))\
|
||||
shape->m##name##Name = StringTable->EmptyString();\
|
||||
\
|
||||
shape->setMaskBits(bitmask);\
|
||||
return true;\
|
||||
}\
|
||||
return false;\
|
||||
}
|
||||
|
||||
#define packMaterialAsset(netconn, name)\
|
||||
if (stream->writeFlag(m##name##Asset.notNull()))\
|
||||
{\
|
||||
NetStringHandle assetIdStr = m##name##Asset.getAssetId();\
|
||||
##netconn##->packNetStringHandleU(stream, assetIdStr);\
|
||||
}\
|
||||
else\
|
||||
stream->writeString(m##name##Name);
|
||||
|
||||
#define unpackMaterialAsset(netconn, name)\
|
||||
if (stream->readFlag())\
|
||||
{\
|
||||
m##name##AssetId = StringTable->insert(##netconn##->unpackNetStringHandleU(stream).getString());\
|
||||
MaterialAsset::getAssetById(m##name##AssetId, &m##name##Asset);\
|
||||
}\
|
||||
else\
|
||||
m##name##Name = stream->readSTString();\
|
||||
|
||||
#endif // _ASSET_BASE_H_
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@
|
|||
#include "lighting/lightQuery.h"
|
||||
#include "console/engineAPI.h"
|
||||
|
||||
|
||||
IMPLEMENT_CO_NETOBJECT_V1(RenderMeshExample);
|
||||
|
||||
ConsoleDocClass( RenderMeshExample,
|
||||
|
|
@ -63,6 +62,8 @@ RenderMeshExample::RenderMeshExample()
|
|||
// Make sure we the Material instance to NULL
|
||||
// so we don't try to access it incorrectly
|
||||
mMaterialInst = NULL;
|
||||
|
||||
initMaterialAsset(Material);
|
||||
}
|
||||
|
||||
RenderMeshExample::~RenderMeshExample()
|
||||
|
|
@ -77,8 +78,7 @@ RenderMeshExample::~RenderMeshExample()
|
|||
void RenderMeshExample::initPersistFields()
|
||||
{
|
||||
addGroup( "Rendering" );
|
||||
addField( "material", TypeMaterialName, Offset( mMaterialName, RenderMeshExample ),
|
||||
"The name of the material used to render the mesh." );
|
||||
scriptBindMaterialAsset(Material, RenderMeshExample, "The material used to render the mesh.");
|
||||
endGroup( "Rendering" );
|
||||
|
||||
// SceneObject already handles exposing the transform
|
||||
|
|
@ -145,8 +145,10 @@ U32 RenderMeshExample::packUpdate( NetConnection *conn, U32 mask, BitStream *str
|
|||
}
|
||||
|
||||
// Write out any of the updated editable properties
|
||||
if ( stream->writeFlag( mask & UpdateMask ) )
|
||||
stream->write( mMaterialName );
|
||||
if (stream->writeFlag(mask & UpdateMask))
|
||||
{
|
||||
packMaterialAsset(conn, Material);
|
||||
}
|
||||
|
||||
return retMask;
|
||||
}
|
||||
|
|
@ -166,7 +168,7 @@ void RenderMeshExample::unpackUpdate(NetConnection *conn, BitStream *stream)
|
|||
|
||||
if ( stream->readFlag() ) // UpdateMask
|
||||
{
|
||||
stream->read( &mMaterialName );
|
||||
unpackMaterialAsset(conn, Material);
|
||||
|
||||
if ( isProperlyAdded() )
|
||||
updateMaterial();
|
||||
|
|
@ -248,18 +250,18 @@ void RenderMeshExample::createGeometry()
|
|||
|
||||
void RenderMeshExample::updateMaterial()
|
||||
{
|
||||
if ( mMaterialName.isEmpty() )
|
||||
return;
|
||||
if (mMaterialAsset.notNull())
|
||||
{
|
||||
if (mMaterialInst && String(mMaterialAsset->getMaterialDefinitionName()).equal(mMaterialInst->getMaterial()->getName(), String::NoCase))
|
||||
return;
|
||||
|
||||
// If the material name matches then don't bother updating it.
|
||||
if ( mMaterialInst && mMaterialName.equal( mMaterialInst->getMaterial()->getName(), String::NoCase ) )
|
||||
return;
|
||||
SAFE_DELETE(mMaterialInst);
|
||||
|
||||
SAFE_DELETE( mMaterialInst );
|
||||
mMaterialInst = MATMGR->createMatInstance(mMaterialAsset->getMaterialDefinitionName(), getGFXVertexFormat< VertexType >());
|
||||
|
||||
mMaterialInst = MATMGR->createMatInstance( mMaterialName, getGFXVertexFormat< VertexType >() );
|
||||
if ( !mMaterialInst )
|
||||
Con::errorf( "RenderMeshExample::updateMaterial - no Material called '%s'", mMaterialName.c_str() );
|
||||
if (!mMaterialInst)
|
||||
Con::errorf("RenderMeshExample::updateMaterial - no Material called '%s'", mMaterialAsset->getMaterialDefinitionName());
|
||||
}
|
||||
}
|
||||
|
||||
void RenderMeshExample::prepRenderImage( SceneRenderState *state )
|
||||
|
|
@ -353,4 +355,4 @@ DefineEngineMethod( RenderMeshExample, postApply, void, (),,
|
|||
"A utility method for forcing a network update.\n")
|
||||
{
|
||||
object->inspectPostApply();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@
|
|||
#include "gfx/gfxPrimitiveBuffer.h"
|
||||
#endif
|
||||
|
||||
#include "T3D/assets/MaterialAsset.h"
|
||||
|
||||
class BaseMatInstance;
|
||||
|
||||
|
||||
|
|
@ -65,8 +67,8 @@ class RenderMeshExample : public SceneObject
|
|||
//--------------------------------------------------------------------------
|
||||
// Rendering variables
|
||||
//--------------------------------------------------------------------------
|
||||
// The name of the Material we will use for rendering
|
||||
String mMaterialName;
|
||||
DECLARE_MATERIALASSET(RenderMeshExample, Material, UpdateMask);
|
||||
|
||||
// The actual Material instance
|
||||
BaseMatInstance* mMaterialInst;
|
||||
|
||||
|
|
@ -131,4 +133,4 @@ public:
|
|||
void prepRenderImage( SceneRenderState *state );
|
||||
};
|
||||
|
||||
#endif // _RENDERMESHEXAMPLE_H_
|
||||
#endif // _RENDERMESHEXAMPLE_H_
|
||||
|
|
|
|||
|
|
@ -86,8 +86,7 @@ GroundPlane::GroundPlane()
|
|||
mConvexList = new Convex;
|
||||
mTypeMask |= TerrainLikeObjectType;
|
||||
|
||||
mMaterialAsset = StringTable->EmptyString();
|
||||
mMaterialAssetId = StringTable->EmptyString();
|
||||
initMaterialAsset(Material);
|
||||
}
|
||||
|
||||
GroundPlane::~GroundPlane()
|
||||
|
|
@ -107,13 +106,7 @@ void GroundPlane::initPersistFields()
|
|||
addField( "scaleU", TypeF32, Offset( mScaleU, GroundPlane ), "Scale of texture repeat in the U direction." );
|
||||
addField( "scaleV", TypeF32, Offset( mScaleV, GroundPlane ), "Scale of texture repeat in the V direction." );
|
||||
|
||||
addProtectedField("materialAsset", TypeMaterialAssetId, Offset(mMaterialAssetId, GroundPlane),
|
||||
&GroundPlane::_setMaterialAsset, &defaultProtectedGetFn,
|
||||
"The material asset.");
|
||||
|
||||
addProtectedField("material", TypeMaterialName, Offset(mMaterialName, GroundPlane),
|
||||
&GroundPlane::_setMaterialName, &defaultProtectedGetFn,
|
||||
"The material name.");
|
||||
scriptBindMaterialAsset(Material, GroundPlane, "The material used to render the ground plane.");
|
||||
|
||||
endGroup( "Plane" );
|
||||
|
||||
|
|
@ -124,72 +117,6 @@ void GroundPlane::initPersistFields()
|
|||
removeField( "rotation" );
|
||||
}
|
||||
|
||||
bool GroundPlane::_setMaterialAsset(void* obj, const char* index, const char* data)
|
||||
{
|
||||
GroundPlane* gp = static_cast<GroundPlane*>(obj);// ->setFile(FileName(data));
|
||||
|
||||
gp->mMaterialAssetId = StringTable->insert(data);
|
||||
|
||||
return gp->setMaterialAsset(gp->mMaterialAssetId);
|
||||
}
|
||||
|
||||
bool GroundPlane::_setMaterialName(void* obj, const char* index, const char* data)
|
||||
{
|
||||
GroundPlane* gp = static_cast<GroundPlane*>(obj);// ->setFile(FileName(data));
|
||||
|
||||
StringTableEntry assetId = MaterialAsset::getAssetIdByMaterialName(StringTable->insert(data));
|
||||
if (assetId != StringTable->EmptyString())
|
||||
{
|
||||
//Special exception case. If we've defaulted to the 'no shape' mesh, don't save it out, we'll retain the original ids/paths so it doesn't break
|
||||
//the TSStatic
|
||||
if (gp->setMaterialAsset(assetId))
|
||||
{
|
||||
if (assetId == StringTable->insert("Core_Rendering:NoMaterial"))
|
||||
{
|
||||
gp->mMaterialName = data;
|
||||
gp->mMaterialAssetId = StringTable->EmptyString();
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
gp->mMaterialAssetId = assetId;
|
||||
gp->mMaterialName = StringTable->EmptyString();
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gp->mMaterialAsset = StringTable->EmptyString();
|
||||
gp->mMaterialName = data;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GroundPlane::setMaterialAsset(const StringTableEntry materialAssetId)
|
||||
{
|
||||
if (MaterialAsset::getAssetById(materialAssetId, &mMaterialAsset))
|
||||
{
|
||||
//Special exception case. If we've defaulted to the 'no shape' mesh, don't save it out, we'll retain the original ids/paths so it doesn't break
|
||||
//the TSStatic
|
||||
if (mMaterialAsset.getAssetId() != StringTable->insert("Core_Rendering:noMaterial"))
|
||||
{
|
||||
mMaterialName = StringTable->EmptyString();
|
||||
}
|
||||
|
||||
_updateMaterial();
|
||||
|
||||
setMaskBits(-1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GroundPlane::onAdd()
|
||||
{
|
||||
if( !Parent::onAdd() )
|
||||
|
|
@ -263,8 +190,8 @@ U32 GroundPlane::packUpdate( NetConnection* connection, U32 mask, BitStream* str
|
|||
stream->write( mSquareSize );
|
||||
stream->write( mScaleU );
|
||||
stream->write( mScaleV );
|
||||
stream->writeString( mMaterialAsset.getAssetId() );
|
||||
stream->write( mMaterialName );
|
||||
|
||||
packMaterialAsset(connection, Material);
|
||||
|
||||
return retMask;
|
||||
}
|
||||
|
|
@ -277,11 +204,7 @@ void GroundPlane::unpackUpdate( NetConnection* connection, BitStream* stream )
|
|||
stream->read( &mScaleU );
|
||||
stream->read( &mScaleV );
|
||||
|
||||
char buffer[256];
|
||||
stream->readString(buffer);
|
||||
setMaterialAsset(StringTable->insert(buffer));
|
||||
|
||||
stream->read( &mMaterialName );
|
||||
unpackMaterialAsset(connection, Material);
|
||||
|
||||
// If we're added then something possibly changed in
|
||||
// the editor... do an update of the material and the
|
||||
|
|
@ -295,13 +218,17 @@ void GroundPlane::unpackUpdate( NetConnection* connection, BitStream* stream )
|
|||
|
||||
void GroundPlane::_updateMaterial()
|
||||
{
|
||||
if (!mMaterialAsset.isNull())
|
||||
if (mMaterialAsset.notNull())
|
||||
{
|
||||
String matName = mMaterialAsset->getMaterialDefinitionName();
|
||||
if (mMaterial && String(mMaterialAsset->getMaterialDefinitionName()).equal(mMaterial->getMaterial()->getName(), String::NoCase))
|
||||
return;
|
||||
|
||||
SAFE_DELETE(mMaterial);
|
||||
|
||||
mMaterial = MATMGR->createMatInstance(mMaterialAsset->getMaterialDefinitionName(), getGFXVertexFormat< VertexType >());
|
||||
|
||||
mMaterial = MATMGR->createMatInstance(matName, getGFXVertexFormat< VertexType >());
|
||||
if (!mMaterial)
|
||||
Con::errorf("GroundPlane::_updateMaterial - no material called '%s'", matName.c_str());
|
||||
Con::errorf("GroundPlane::_updateMaterial - no Material called '%s'", mMaterialAsset->getMaterialDefinitionName());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -64,9 +64,6 @@ public:
|
|||
GroundPlane();
|
||||
virtual ~GroundPlane();
|
||||
|
||||
static bool _setMaterialAsset(void* obj, const char* index, const char* data);
|
||||
static bool _setMaterialName(void* obj, const char* index, const char* data);
|
||||
|
||||
virtual bool onAdd();
|
||||
virtual void onRemove();
|
||||
virtual U32 packUpdate( NetConnection* connection, U32 mask, BitStream* stream );
|
||||
|
|
@ -81,8 +78,6 @@ public:
|
|||
|
||||
static void initPersistFields();
|
||||
|
||||
bool setMaterialAsset(const StringTableEntry materialAssetId);
|
||||
|
||||
virtual void getUtilizedAssets(Vector<StringTableEntry>* usedAssetsList);
|
||||
|
||||
protected:
|
||||
|
|
@ -109,11 +104,9 @@ private:
|
|||
F32 mSquareSize; ///< World units per grid cell edge.
|
||||
F32 mScaleU; ///< Scale factor for U texture coordinates.
|
||||
F32 mScaleV; ///< Scale factor for V texture coordinates.
|
||||
String mMaterialName; ///< Object name of material to use.
|
||||
BaseMatInstance* mMaterial; ///< Instantiated material based on given material name.
|
||||
|
||||
AssetPtr<MaterialAsset> mMaterialAsset;
|
||||
StringTableEntry mMaterialAssetId;
|
||||
DECLARE_MATERIALASSET(GroundPlane, Material, -1);
|
||||
|
||||
PhysicsBody *mPhysicsRep;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue