Server Side Material List in TGE
by Dave Young · 03/06/2008 (11:38 am) · 2 comments
This resource is built into the RPG Series: Character Creation for AFX course being built for TorqueSchool.
Why? In TGEA, the server has an excellent notion of materials, but in TGE it doesn't. This is most likely because most servers don't really need to load up textures with the rest of the shape. So while the server at one point does indeed have its hands on the file and can look at the material list, it basically says PAH! materials! who needs em, and throws the list out.
We are not storing an actual materiallist object by the way, but rather the names of the materials.
If you happen to need that list, there is a way to do it. In this implementation we are just keeping track of material names, but it can be expanded to keep track of other things as well, perhaps even using a normal TSMaterialList structure without the actual handles.
First we add the magic to TSShape, so when a shape is read the material names are tucked away in a new
In TSShape.h, line 347, add the item in bold:
Note that it's in the Public section, so it will be available to anything that has a tsShape object.
In TSShape.cc, line 1312 in function bool TSShape::read(Stream * s):
after
Add:
There you have a server side list. Done!! Note that the list also exists client side, but we don't really need it there as we have a full materialList and materialNames is populated as well.
Now for an example of how to access the list! Let's say in shapeBase you need to be able to look at the materialList on a shape and from the server side. We made a shapeBase localized copy of the texture names also, and a vector to store new skin names in as well. This is for reskinning purposes, but the reskinning portion of this resource is posted separately.
In Shapebase.h, right above:
Add:
In my project, these two vectors store the lists of original textures and changed textures, respectively.
To populate them, I add a section before the end of ShapeBase::onAdd in Shapebase.cc. Before the final return; in OnAdd, add:
This code checks to make sure it's a server object and has a valid shape. If so, that shape has material names on it from our previous work. For each name, we pop it as a StringTableEntry into a local vector list. Then we are free to do comparisons, send the names to the client, etc.
A further implementation including reskinning is posted separately. Enjoy!
Why? In TGEA, the server has an excellent notion of materials, but in TGE it doesn't. This is most likely because most servers don't really need to load up textures with the rest of the shape. So while the server at one point does indeed have its hands on the file and can look at the material list, it basically says PAH! materials! who needs em, and throws the list out.
We are not storing an actual materiallist object by the way, but rather the names of the materials.
If you happen to need that list, there is a way to do it. In this implementation we are just keeping track of material names, but it can be expanded to keep track of other things as well, perhaps even using a normal TSMaterialList structure without the actual handles.
First we add the magic to TSShape, so when a shape is read the material names are tucked away in a new
In TSShape.h, line 347, add the item in bold:
TSMaterialList * materialList; [b] Vector<const char *> mBaseTextureNames; [/b]
Note that it's in the Public section, so it will be available to anything that has a tsShape object.
In TSShape.cc, line 1312 in function bool TSShape::read(Stream * s):
after
// read material list delete materialList; // just in case... materialList = new TSMaterialList; materialList->read(*s);
Add:
mBaseTextureNames.setSize(materialList->mMaterialNames.size());
for (S32 j = 0; j < materialList->mMaterialNames.size(); j++)
{
const char* pName = materialList->mMaterialNames[j];
if (pName == NULL){continue;}
mBaseTextureNames[j] = pName;
}There you have a server side list. Done!! Note that the list also exists client side, but we don't really need it there as we have a full materialList and materialNames is populated as well.
Now for an example of how to access the list! Let's say in shapeBase you need to be able to look at the materialList on a shape and from the server side. We made a shapeBase localized copy of the texture names also, and a vector to store new skin names in as well. This is for reskinning purposes, but the reskinning portion of this resource is posted separately.
In Shapebase.h, right above:
enum PublicConstants {
ThreadSequenceBits = 6,
MaxSequenceIndex = (1 << ThreadSequenceBits) - 1,
EnergyLevelBits = 5,
DamageLevelBits = 6,Add:
Vector<StringTableEntry> mSkinNameHandles; Vector<StringTableEntry> mNewSkinNameHandles;
In my project, these two vectors store the lists of original textures and changed textures, respectively.
To populate them, I add a section before the end of ShapeBase::onAdd in Shapebase.cc. Before the final return; in OnAdd, add:
if(mDataBlock->shape && !isClientObject())
{
S32 matSize = mDataBlock->shape->mBaseTextureNames.size();
for(int y=0; y < matSize; y++)
{
mSkinNameHandles.push_back(StringTable->insert(mDataBlock->shape->mBaseTextureNames[y]));
mNewSkinNameHandles.push_back(StringTable->insert(mDataBlock->shape->mBaseTextureNames[y]));
}
}This code checks to make sure it's a server object and has a valid shape. If so, that shape has material names on it from our previous work. For each name, we pop it as a StringTableEntry into a local vector list. Then we are free to do comparisons, send the names to the client, etc.
A further implementation including reskinning is posted separately. Enjoy!
About the author
#2
03/06/2008 (6:51 pm)
i can think of several good reasons to have this, and with a few slight mods will work well for what i am trying to do. book marking this page for later use.
Torque 3D Owner Sparkling
I can propose a not-so-nefarious reason for wanting an easily accessible list of all the textures being used in the game. We use TGEA of course, so it may or may not be as closely relevant for TGE, but we ran into a recent situation where if the same material is located in 2 different places, and is being used on 2 different models, the engine will use the first instance of that material but not the second instance of it. In the second instance it will simply display the surface of the model as invisible in the areas where that material is being used. So we had to go through our entire build, find EVERY location where the same material was being used, and in many cases move the material file up a level so that all models referencing said material could access the same material without having it duplicated in 2 or more locations. NOT a fun task I assure you. And I wasn't even the one who had to sift throught he code with a microscope to find the duplicates, my invaluable developer, George, did the troubleshooting on the problem and instated the solution for us.
So yeah, having an easily accessible listing would be very very nice! Would avoid the many many hours of work sifting through to find anomolies!
Good job!
-Sparkling