SetMaterial doesn't "apply" new material to mesh
by J Helleman · in Torque 3D Professional · 03/18/2011 (5:25 am) · 7 replies
Hi,
shapeInstance->cloneMaterialList fails on me, I checked and it happens inside cloneMaterialInstance when it creates a new instance of MaterialList. I use the following code:
What I don't get in the examples I read is that cloneMaterialList should generate some sort of new list of materials from it's parent, at least I suspect, but the cloneMaterialList func is copying itself as far as I could trace back?
It fails at the constructor of TSMaterialList(...);
Can anyone share his knowledge? Beta 3 btw
Jan
shapeInstance->cloneMaterialList fails on me, I checked and it happens inside cloneMaterialInstance when it creates a new instance of MaterialList. I use the following code:
U32 SimCurl::loadBitmap(TSStatic* tsStatic)
{
bitmap = new GBitmap;
if(isRunning()) { Con::errorf("Still running!:");
return 0;
}
Con::printf("Name of shape instance: %s", tsStatic->getClassName());
TSShapeInstance* tsShapeInst = tsStatic->getShapeInstance();
TSMaterialList* materials = tsShapeInst->getMaterialList();
TSShape* tsShape = tsShapeInst->getShape();
const char* matname;
if (materials == NULL)
{
materials = tsShape->materialList;
}
Con::printf("Name of shape instance: %s", tsStatic->getName());
Con::printf("Number of materials: %d", materials->getMaterialCount());
Con::printf("obsolete line to test 1 ");
TSMesh * imesh = tsShapeInst->mMeshObjects[0].getMesh(0);
Con::printf("obsolete line to test 2 ");
U32 material = imesh->primitives[0].matIndex & TSDrawPrimitive::MaterialMask;
Con::printf("obsolete line to test 3 ");
if (imesh->primitives[0].matIndex & TSDrawPrimitive::NoMaterial)
{
Con::errorf("No material on this mesh");
return 10;
}
else
{
Con::printf("Found material id: %d", material);
if (!tsShapeInst->ownMaterialList())
{
Con::printf("No material list so cloned it!");
tsShapeInst->cloneMaterialList();
}
Con::printf("obsolete line to test 4a ");
materials = tsShapeInst->getMaterialList();
Con::printf("obsolete line to test 4b ");
matname = materials->getMaterialName(material);
}
Con::printf("obsolete line to test 5 ");
if (matname)
{
Con::printf("Matname found: %s", matname);
}
return (S32)materials->getMaterialCount();
}What I don't get in the examples I read is that cloneMaterialList should generate some sort of new list of materials from it's parent, at least I suspect, but the cloneMaterialList func is copying itself as far as I could trace back?
void TSShapeInstance::cloneMaterialList( const FeatureSet *features )
{
if ( mOwnMaterialList )
return;
mMaterialList = new TSMaterialList(mMaterialList);
initMaterialList( features );
mOwnMaterialList = true;
}It fails at the constructor of TSMaterialList(...);
Can anyone share his knowledge? Beta 3 btw
Jan
#2
03/18/2011 (1:15 pm)
TSStatics have no networked features, and as such ANY changes do them once they're created isn't reflected. The whole nature of the networked system in Torque takes getting used to...even in single player there's a server and a client, and the server only sends networked features down to the client which accepts your input and displays your visuals.
#3
SimCurl* client = dynamic_cast< SimCurl* > ( (this->getClientObject() );
And process the same stuff with the client pointer...
03/18/2011 (1:22 pm)
I believe you have to do the same for the client object.SimCurl* client = dynamic_cast< SimCurl* > ( (this->getClientObject() );
And process the same stuff with the client pointer...
#4
03/19/2011 (4:00 am)
I am gonna try that tonight and keep you guys posted on how it goes, thank you for the help so far!
#5
03/19/2011 (8:38 am)
Thanks you guys you made my whole week look like sunshine because of this! Just for the records, where should I have learned this information without you guys?
#6
03/19/2011 (3:45 pm)
Quote:SimCurl* client = dynamic_cast< SimCurl* > ( (this->getClientObject() );Be warned though, this will only work when you're running a server and client on the same machine. Any remote clients who connect to your game will not see the new textures, because getClientObject only applies to local connections. For a more robust implementation, you'll need to use the mask/update system (see pack/unpackUpdate and setMaskBits).
Quote:Just for the records, where should I have learned this information without you guys?Experience and reading code. There's no great reference for Torque's internals; most of the recent documentation work has focused on scripting and beginner tutorials.
#7
Cheers for your wisdom!
03/19/2011 (5:21 pm)
Quote:I will keep that in mind. As for the prototype I am building, it is not an issue, but definitely one to keep in mind for the future! Thanks for the info!
Be warned though, this will only work when you're running a server and client on the same machine. Any remote clients who connect to your game will not see the new textures, because getClientObject only applies to local connections. For a more robust implementation, you'll need to use the mask/update system (see pack/unpackUpdate and setMaskBits)
Quote:thank god you gives are on the forums then, else it would have taken me days, maybe weeks to figure this out. None of the resources I found in the forum told about this method.
Experience and reading code. There's no great reference for Torque's internals; most of the recent documentation work has focused on scripting and beginner tutorials.
Cheers for your wisdom!
Torque 3D Owner J Helleman
U32 SimCurl::loadBitmap(TSStatic* tsStatic) { bitmap = new GBitmap; if(isRunning()) { Con::errorf("Still running!:"); return 0; } FileStream* fileStream = FileStream::createAndOpen("starter.fps/test.png", Torque::FS::File::AccessMode::Write); //fileStream->writeLine(b); //fileStream->writeLine((U8 *)storagedesc.mem.ptr); fileStream->write(storagedesc.mem.rsize, storagedesc.mem.ptr); MemStream* mStream = new MemStream(storagedesc.mem.rsize, storagedesc.mem.ptr, true, false); //fileStream->write((U8 *)storagedesc.mem.ptr); //bitmap->readBitmap("png", *mStream); fileStream->close(); Con::printf("Name of shape instance: %s", tsStatic->getClassName()); TSShapeInstance* tsShapeInst = tsStatic->getShapeInstance(); TSMaterialList* materials = tsShapeInst->getMaterialList(); TSShape* tsShape = tsShapeInst->getShape(); const char* matname; if (materials == NULL) { materials = tsShape->materialList; } Con::printf("Name of shape instance: %s", tsStatic->getName()); TSMesh * imesh = tsShapeInst->mMeshObjects[0].getMesh(0); for(U32 j = 0; j < imesh->primitives.size(); j++) { if(imesh->getMeshType() != TSMesh::NullMeshType) { U32 material = imesh->primitives[j].matIndex & TSDrawPrimitive::MaterialMask; if (imesh->primitives[j].matIndex & TSDrawPrimitive::NoMaterial) { Con::errorf("No material on this mesh"); return 10; } else { Con::printf("test mat index: %d", material); if (!tsShapeInst->ownMaterialList()) { tsShapeInst->setMaterialList(tsShape->materialList); tsShapeInst->cloneMaterialList(); Con::printf("Materials in list: %d", materials->getMaterialCount()); } materials = tsShapeInst->getMaterialList(); matname = materials->getMaterialName(material); if(materials->setMaterial(material, Torque::Path("starter.fps/test2.png"))) { materials->mapMaterials(); tsShapeInst->initMaterialList(); } } if (matname) { Con::printf("Matname found: %s", matname); } } else { Con::printf("0 primitives?"); } }But it still doesn't show the new texture on the TSStatics. This code is called for all statics for testing purpose from torquescript. But it simply doesn't change the texture of the objects. Am I missing something here?