Initial pass at implementing MaterialAsset macromagic utility functions and applies it to the renderMeshExample object as well as groundPlane

This commit is contained in:
Areloch 2020-12-27 23:24:29 -06:00
parent e9dba74891
commit c1cd217557
5 changed files with 131 additions and 113 deletions

View file

@ -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_

View file

@ -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();
}
}

View file

@ -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_

View file

@ -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());
}
}

View file

@ -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;