TGEA Multiple Skins / Material datablocks
by Mark Farra · in Torque Game Engine Advanced · 11/10/2008 (1:08 pm) · 5 replies
I've got setting materials in TGEA down pat. That is, if they're a single texture on a model. But I have the Character System from FRO Games, and I cannot - for the life of me - figure out how I'm supposed to set up a Material datablock for multiple skins on a single character model. I know that in TGEA *ALL* materials must be defined, and the code source that comes with the package is based on TGE, not TGEA.
I have skins for the model parts as such:
001.body.human.jpg
001.legs.human.jpg
001.hands.human.jpg
001.feet.human.jpg
002.body.human.jpg
002.legs.human.jpg
002.hands.human.jpg
002.feet.human.jpg
and so on...
If I use the example given in the documentation, I can call:
I've attempted to set up a Material for the example, like so:
It attempts to cover all meshes (body, feet, hands, legs, head) and still with the "no texture" default texture. Now I've taken a look at the engine source code and added a few Con::warnf() debugs to see what exactly was going on, and strangely enough, it reports the file paths perfectly (though the console still reports that it can't find the texture!!!).
Please... I'm begging you... anyone! I'm pulling my hair out with this. Is there anyone that has had experience with this in TGEA? Perhaps point me in the right direction for what I need to do? I don't mind the work at all, I just need a direction to go in.
Thanks much in advance!
I have skins for the model parts as such:
001.body.human.jpg
001.legs.human.jpg
001.hands.human.jpg
001.feet.human.jpg
002.body.human.jpg
002.legs.human.jpg
002.hands.human.jpg
002.feet.human.jpg
and so on...
If I use the example given in the documentation, I can call:
%obj.setSkinName("001.body");to change the Body texture ONLY. And it works, to an effect. While it's only the body mesh that changes textures, it displays the default "no texture" texture... bad. If I call:%obj.setSkinName("001");it attempts to change all textures; still with the default "no texture" texture... still bad.I've attempted to set up a Material for the example, like so:
new Material(001)
{
mapTo = "001.body";
baseTex[0] = "001.body";
preload = true;
};It attempts to cover all meshes (body, feet, hands, legs, head) and still with the "no texture" default texture. Now I've taken a look at the engine source code and added a few Con::warnf() debugs to see what exactly was going on, and strangely enough, it reports the file paths perfectly (though the console still reports that it can't find the texture!!!).
Please... I'm begging you... anyone! I'm pulling my hair out with this. Is there anyone that has had experience with this in TGEA? Perhaps point me in the right direction for what I need to do? I don't mind the work at all, I just need a direction to go in.
Thanks much in advance!
About the author
#2
11/10/2008 (1:57 pm)
Yes, I've tried that as well. It isn't doing anything different than what I've mentioned above.
#3
to the part of the models body its for and export..
11/10/2008 (1:57 pm)
I think each texture needs its own Material in whichever 3d app your using... Uvmap each Material/texture to the part of the models body its for and export..
#4
"base.body.human" - for the torso
"base.pants.human" - for the legs
"base.hands.human" - for the hands
"base.head.human" - for the head
"base.feet.human" - for the feet
Those are obvious, I know. And they work correctly; meaning:
Changing skins on other models (not setup with multiple texture tags) work fine. I have a troll model with a variety of skins and %npc.setSkinName(greentrollskin) works fine with:
In fact, I have several other models where multiple skins work fine with setSkinName(). But the player-controlled model (the character) is setup with multiple texture tags - those listed above - and I cannot make it work at all. I've applied the changes listed in the resource here, and even though it's for TGE, the code compiles in TGEA fine. I can even notice the difference. For example, in stock TGEA 1.7.1 + AFX 1.2, using the following:
As I said, I know that I must create the Material in a materials.cs file, but even with one created, the use of setSkinName() either does nothing or it covers the model (whole unmodified, or a portion with code changes) with the orange "No Material" texture. As of today I've officially search and tested (basically wasted) a week on this problem, to no avail. Though I'm fairly poor at C++, I've been through TSMaterialList::setMaterial(), TSShapeInstance::reSkin() and makeSkinPath() a hundred times in source code. I know those functions are getting called with setSkinName(), and I know on models with a single texture tag and Materials setup correctly in TScript, they fire fine.
Inside TSMaterialList::setMaterial() at the end where:
One other curious thing to note: I've mentioned in another thread a few months ago that in order to get a Material to swap correctly with setSkinName() the Material name MUST be the same as the actual texture name. So if you had a material like this:
I believe this may be one reason why the multiple texture tags isn't working for me. You can't place a dot (.) in the Material name like "new Material(platearmor.body)" and trying an underscore there "new Material(platearmor_body)" directly searches for "platearmor_body.body.human" and so on.
Meh... I'm rambling, I apologize. I'm not looking for next-gen graphics capabilities, here. I don't need texture overlays and fancy shader work (hehe). I just need the torso of my model to change it's texture to something else. I don't know enough C++ to follow exactly how everything works in the engine code, or I'd surely have this figured out already.
Again, any help is appreciated!
TIA
11/12/2008 (9:10 am)
Hmm. Each texture tag is already set, they are as follows:"base.body.human" - for the torso
"base.pants.human" - for the legs
"base.hands.human" - for the hands
"base.head.human" - for the head
"base.feet.human" - for the feet
Those are obvious, I know. And they work correctly; meaning:
new Material(platearmor)
{
mapTo = "base.body.human";
baseTex[0] = "platearmor.body.human";
};... will actually load the "platearmor.body.human.jpg" on the torso of the model correctly on load. I cannot, of course, map multiple materials to one texture tag, unfortunately.Changing skins on other models (not setup with multiple texture tags) work fine. I have a troll model with a variety of skins and %npc.setSkinName(greentrollskin) works fine with:
new Material(greentrollskin)
{
baseTex[0] = "greentrollskin.troll";
translucent = false;
};In fact, I have several other models where multiple skins work fine with setSkinName(). But the player-controlled model (the character) is setup with multiple texture tags - those listed above - and I cannot make it work at all. I've applied the changes listed in the resource here, and even though it's for TGE, the code compiles in TGEA fine. I can even notice the difference. For example, in stock TGEA 1.7.1 + AFX 1.2, using the following:
%player.setSkinName(platearmor);cycle through and reports this:
GFXTextureManager::createTexture - Unable to load Texture: platearmor.body.human GFXTextureManager::createTexture - Unable to load Texture: platearmor.pants.human GFXTextureManager::createTexture - Unable to load Texture: platearmor.head.human GFXTextureManager::createTexture - Unable to load Texture: platearmor.hands.human GFXTextureManager::createTexture - Unable to load Texture: platearmor.feet.humanHowever, with the code modifications from the above resource, and using:
%player.setSkinName("platearmor.body");as the instructions say, report this:GFXTextureManager::createTexture - Unable to load Texture: platearmor.body.human GFXTextureManager::createTexture - Unable to load Texture: base.pants.human GFXTextureManager::createTexture - Unable to load Texture: base.head.human GFXTextureManager::createTexture - Unable to load Texture: base.hands.human GFXTextureManager::createTexture - Unable to load Texture: base.feet.human... and you can only see the torso portion of the model changed to "No Material" orange instead of the whole thing, which is a difference!
As I said, I know that I must create the Material in a materials.cs file, but even with one created, the use of setSkinName() either does nothing or it covers the model (whole unmodified, or a portion with code changes) with the orange "No Material" texture. As of today I've officially search and tested (basically wasted) a week on this problem, to no avail. Though I'm fairly poor at C++, I've been through TSMaterialList::setMaterial(), TSShapeInstance::reSkin() and makeSkinPath() a hundred times in source code. I know those functions are getting called with setSkinName(), and I know on models with a single texture tag and Materials setup correctly in TScript, they fire fine.
Inside TSMaterialList::setMaterial() at the end where:
const MaterialPropertyMap::MapEntry * entry = matMap->getMapEntry(matName);attempts to get the "entry" variable, it fails. All other variables in the function above that line contain data correctly. But "entry" returns null, and thus doesn't meet the condition requirements for the block that follows it:
if(entry && entry->materialName) {...So... I'm at a loss there.One other curious thing to note: I've mentioned in another thread a few months ago that in order to get a Material to swap correctly with setSkinName() the Material name MUST be the same as the actual texture name. So if you had a material like this:
new Material(myMaterial)
{
baseTex[0] = "skinone.model";
};... would NOT work. The Material name must be the same, so:new Material(skinone)
{
baseTex[0] = "skinone.model";
};... would be the correct way to do it. The engine code with literally look for the Material name. If your texture was named "skinone.model.jpg", and the material you defined was named "myMaterial" on the model, the code returns a "could not find mymaterial.model". I believe this may be one reason why the multiple texture tags isn't working for me. You can't place a dot (.) in the Material name like "new Material(platearmor.body)" and trying an underscore there "new Material(platearmor_body)" directly searches for "platearmor_body.body.human" and so on.
Meh... I'm rambling, I apologize. I'm not looking for next-gen graphics capabilities, here. I don't need texture overlays and fancy shader work (hehe). I just need the torso of my model to change it's texture to something else. I don't know enough C++ to follow exactly how everything works in the engine code, or I'd surely have this figured out already.
Again, any help is appreciated!
TIA
#5
I'm getting desperate. Does anyone have *ANY* idea where I might look for a solution to this issue?
I know exactly where the source C++ code is failing; should I post more detail on that?
11/16/2008 (1:33 am)
*bump*I'm getting desperate. Does anyone have *ANY* idea where I might look for a solution to this issue?
I know exactly where the source C++ code is failing; should I post more detail on that?
Torque Owner Timothy Castagna
TK Games LLC