T3D 1.2 ShapeBase::ChangeMaterial BugFix
by Vincent BILLET · in Torque 3D Professional · 12/05/2012 (2:22 am) · 3 replies
Changing Materials into shape instances via scripts is an essential feature for many T3D users.
Unfortunately, depending on Torque versions it worked or NOT.
So, For T3D 1.2 (MIT), here is the fix :
in script you can use like this :
Edit : These changes can also be reported in
T3D/shapeBase.cpp
interior/interiorInstance.cpp And
T3D/tsStatic.cpp
Enjoy!
Unfortunately, depending on Torque versions it worked or NOT.
So, For T3D 1.2 (MIT), here is the fix :
DefineEngineMethod( ShapeBase, changeMaterial, void, ( const char* mapTo, Material* oldMat, Material* newMat ),,
"@brief Change one of the materials on the shape.nn"
"This method changes materials per mapTo with others. The material that "
"is being replaced is mapped to unmapped_mat as a part of this transition.n"
"@note Warning, right now this only sort of works. It doesn't do a live "
"update like it should.n"
"@param mapTo the name of the material target to remap (from getTargetName)n"
"@param oldMat the old Material that was mapped n"
"@param newMat the new Material to mapnn"
"@tsexamplen"
"// remap the first material in the shapen"
"%mapTo = %obj.getTargetName( 0 );n"
"%obj.changeMaterial( %mapTo, 0, MyMaterial );n"
"@endtsexamplen" )
{
// if no valid new material, theres no reason for doing this
if( !newMat )
{
Con::errorf("ShapeBase::changeMaterial failed: New material does not exist!");
return;
}
// initilize server/client versions
ShapeBase *serverObj = object;
ShapeBase *clientObj = dynamic_cast< ShapeBase* > ( object->getClientObject() );
// Check the mapTo name exists for this shape
S32 matIndex = serverObj->getShape()->materialList->getMaterialNameList().find_next(String(mapTo));
if (matIndex < 0)
{
Con::errorf("ShapeBase::changeMaterial failed: Invalid mapTo name '%s'", mapTo);
return;
}
// Lets remap the old material off, so as to let room for our current material room to claim its spot
if( oldMat )
oldMat->mMapTo = String("unmapped_mat");
newMat->mMapTo = mapTo;
// Map the material in the in the matmgr
MATMGR->mapMaterial( mapTo, newMat->getName() );
// Replace instances with the new material being traded in. For ShapeBase
// class we have to update the server/client objects separately so both
// represent our changes
delete serverObj->getShape()->materialList->mMatInstList[matIndex];
serverObj->getShape()->materialList->mMatInstList[matIndex] = newMat->createMatInstance();
if (clientObj)
{
delete clientObj->getShapeInstance()->mMaterialList->mMatInstList[matIndex];
clientObj->getShapeInstance()->mMaterialList->mMatInstList[matIndex] = newMat->createMatInstance();
}
// Finish up preparing the material instances for rendering
const GFXVertexFormat *flags = getGFXVertexFormat<GFXVertexPNTTB>();
FeatureSet features = MATMGR->getDefaultFeatures();
serverObj->getShape()->materialList->getMaterialInst(matIndex)->init( features, flags );
if (clientObj)
clientObj->getShapeInstance()->mMaterialList->getMaterialInst(matIndex)->init( features, flags );
}in script you can use like this :
%player.changeMaterial("TexutreORPartName",0,"NewMaterialName");or function AIPlayer::Wear(%this,%tset)
{
%this.changeMaterial("base.body",0,"tset_"@%tset@"_body");
%this.changeMaterial("base.legs",0,"tset_"@%tset@"_legs");
%this.changeMaterial("base.arms",0,"tset_"@%tset@"_arms");
%this.changeMaterial("base.hands",0,"tset_"@%tset@"_hands");
%this.changeMaterial("base.feet",0,"tset_"@%tset@"_feet");
%this.changeMaterial("base.head",0,"GeorgesHead");
}Edit : These changes can also be reported in
T3D/shapeBase.cpp
interior/interiorInstance.cpp And
T3D/tsStatic.cpp
Enjoy!
#2
12/05/2012 (7:37 am)
Speaking of setSkinName, I have heard reports of this not working on a player shape unless you use this function at shape creation (or something along those lines - complaints that it doesn't work all the time, conditions vary). Anyone else seen this?
#3
ChangeMaterial is really usefull... It can change each Material of a particular instance of AIPlayer. If you need, like me, to change Legs, body, arms, head, feet and hands of players and AIPlayers, it is really more powerful than setSkinName.
This sample code should be report to TsStatic, and Interiors also.
@Richard,
This function worked pretty well in T3D 1.01 (even on network). It seems that a bad copy past in later versions made it unworking. The main change is
12/05/2012 (8:01 am)
@Steve, ChangeMaterial is really usefull... It can change each Material of a particular instance of AIPlayer. If you need, like me, to change Legs, body, arms, head, feet and hands of players and AIPlayers, it is really more powerful than setSkinName.
This sample code should be report to TsStatic, and Interiors also.
@Richard,
This function worked pretty well in T3D 1.01 (even on network). It seems that a bad copy past in later versions made it unworking. The main change is
clientObj->getShapeInstance()instead of
clientObj->getShape()
Associate Steve Acaster
[YorkshireRifles.com]
Cool.