MountImage skinTag issues in TGEA 1.7.1
by John Doppler Schiff · in Torque Game Engine Advanced · 07/31/2008 (1:14 am) · 7 replies
Hi folks,
I'm trying to skin an image, something I haven't tackled until today. (I've used setSkinName on players without a problem, but now I'm stuck on mountImages skins).
For testing, I put a hat on the player:
The hat appears on the player, but only with the base skin. No errors, no feedback in the console.
The hat is modeled in 3DS Max with the base.bowler.png material applied.
Material definitions are:
The appropriate textures are in .png format in the shapes/gear directory. The script is in server/scripts, the app is running locally.
Any ideas what I might be doing wrong?
I'm trying to skin an image, something I haven't tackled until today. (I've used setSkinName on players without a problem, but now I'm stuck on mountImages skins).
For testing, I put a hat on the player:
%victimID.mountImage( BowlerHatImage1, 1, false, redBowler );
The hat appears on the player, but only with the base skin. No errors, no feedback in the console.
The hat is modeled in 3DS Max with the base.bowler.png material applied.
Material definitions are:
new Material( blackBowler )
{
baseTex[0] = "~data/shapes/gear/blackBowler.bowler";
};
new Material( tanBowler )
{
baseTex[0] = "~data/shapes/gear/tanBowler.bowler";
};
new Material( redBowler )
{
baseTex[0] = "~data/shapes/gear/redBowler.bowler";
};The appropriate textures are in .png format in the shapes/gear directory. The script is in server/scripts, the app is running locally.
Any ideas what I might be doing wrong?
#2
Odd that my player skins don't need a mapTo, though... This code works fine on my players.
07/31/2008 (5:09 pm)
Woot! You rock, Dave, thanks!Odd that my player skins don't need a mapTo, though... This code works fine on my players.
new Material( crash )
{
baseTex[0] = "~/data/shapes/players/FemaleA/crash.Player";
pixelSpecular[0] = false;
};
#3
You still rock, Dave, but that wasn't the solution. =)
07/31/2008 (5:32 pm)
Gah, I spoke too soon. I had inadvertently mapped a texture to my "base.bowler". The mapTo field did not solve the problem.You still rock, Dave, but that wasn't the solution. =)
#4
08/05/2008 (1:10 pm)
Hey John -- I might have stumbled across this problem (and fixed it even) when I was porting the player skinning resource over to TGEA for my project. Can you include the code where you actually change the bowler material? I'll see if your problem was the same one I was seeing. I haven't used setSkinName specifically myself, as I'm going through a different resource, but I suspect the code path is probably the same.
#5
I was using a stock TGEA 1.7.1 code base, then a TGEA/AFX pre-merged base (which I believe is identical for this particular section of code).
I'm just curious if this works at all in TGEA 1.7.1, or if I have a hiccup in my code somewhere.
God, what I wouldn't give for an up-to-date bug list for TGEA! I can't begin to count how many development hours I've wasted trying to figure out what's wrong with my code, only to discover that "that's not working in TGEA x.x" or "that's never worked"... sigh!
08/05/2008 (4:32 pm)
Hi Devon,I was using a stock TGEA 1.7.1 code base, then a TGEA/AFX pre-merged base (which I believe is identical for this particular section of code).
void ShapeBase::setSkinName(const char* name)
{
if (!isGhost()) {
if (name[0] != '[[6281f1a16dfde]]') {
// Use tags for better network performance
// Should be a tag, but we'll convert to one if it isn't.
if (name[0] == StringTagPrefixByte) {
mSkinNameHandle = NetStringHandle(U32(dAtoi(name + 1)));
}
else {
mSkinNameHandle = NetStringHandle(name);
}
}
else {
mSkinNameHandle = NetStringHandle();
}
setMaskBits(SkinMask);
}
}I'm just curious if this works at all in TGEA 1.7.1, or if I have a hiccup in my code somewhere.
God, what I wouldn't give for an up-to-date bug list for TGEA! I can't begin to count how many development hours I've wasted trying to figure out what's wrong with my code, only to discover that "that's not working in TGEA x.x" or "that's never worked"... sigh!
#6
The way setMaterial appears to work is it takes your texture pathname, turns it into a material name by stripping out the path part, and then looks up that material in the materialProperties table. If it doesn't find that material, it just fails. If it does find the material, it creates a new instance of that material, stuffs it into the material instance list for the shape, initializes it with a default light set, and returns.
So first assumption -- you *must* have a material set up whose name is the same as the filename of the texture your specified in your setSkinName call. As your material name is 'blackbowler', and the texturename is 'blackbowler.bowler', you might try changing the material name to match the texture name exactly, and see if that fixes it. (And no, I don't know why this would work for your player but not the mounted shape.. :/) The other thing is to make sure your material definitions are actually getting compiled. The default client initialization rips through your client directory structure looking for 'materials.cs' files and execs them. If for whatever reasion it can't find your materials.cs file, or you've named it something that isn't 'materials.cs', it might not be getting compiled.
Another things that setMaterial does is, if it finds your material name (derived from the path you gave setSkinName) in the material list already, then it just early outs without doing anything. You might also check the code that strips out the path parts of your texture path -- the extra exensions in your pathname 'blackbowler.bowler.png' might be giving it fits.
My biggest beef with this function is that it lies -- the lie grew out of it's port from TGE to TGEA. You think you're giving it a path to a texture. And it even uses that path to create a texture handle, and it stuffs that texture handle in the mMaterials array for the shape. But that texture isn't used! Because it then looks for a material based on the path you gave it, and that material -- and whatever texture it specifies, it's what's actually used. It's misleading, it's confusing, and rife with potential for failure.
Anyway... excuse the rant. :) I totally feel your pain on wishing for an up to date bug list. If it's any consolation, working with other large scale engines *cough Unreal* is much, much worse. Hope that gives you enough info to figure out your problem.
08/06/2008 (6:25 am)
Hey John. So I'm pretty sure the root of your problem is going to be in the TSMaterialList::setMaterial function, found in materialList.cpp. Set a breakpoint at the top of this bad boy and step through it. I just spent quite a bit of time there myself, for a similar problem. This function makes a lot of hidden assumptions, and if any one of them fails, the routine silently comes back without having done anything.The way setMaterial appears to work is it takes your texture pathname, turns it into a material name by stripping out the path part, and then looks up that material in the materialProperties table. If it doesn't find that material, it just fails. If it does find the material, it creates a new instance of that material, stuffs it into the material instance list for the shape, initializes it with a default light set, and returns.
So first assumption -- you *must* have a material set up whose name is the same as the filename of the texture your specified in your setSkinName call. As your material name is 'blackbowler', and the texturename is 'blackbowler.bowler', you might try changing the material name to match the texture name exactly, and see if that fixes it. (And no, I don't know why this would work for your player but not the mounted shape.. :/) The other thing is to make sure your material definitions are actually getting compiled. The default client initialization rips through your client directory structure looking for 'materials.cs' files and execs them. If for whatever reasion it can't find your materials.cs file, or you've named it something that isn't 'materials.cs', it might not be getting compiled.
Another things that setMaterial does is, if it finds your material name (derived from the path you gave setSkinName) in the material list already, then it just early outs without doing anything. You might also check the code that strips out the path parts of your texture path -- the extra exensions in your pathname 'blackbowler.bowler.png' might be giving it fits.
My biggest beef with this function is that it lies -- the lie grew out of it's port from TGE to TGEA. You think you're giving it a path to a texture. And it even uses that path to create a texture handle, and it stuffs that texture handle in the mMaterials array for the shape. But that texture isn't used! Because it then looks for a material based on the path you gave it, and that material -- and whatever texture it specifies, it's what's actually used. It's misleading, it's confusing, and rife with potential for failure.
Anyway... excuse the rant. :) I totally feel your pain on wishing for an up to date bug list. If it's any consolation, working with other large scale engines *cough Unreal* is much, much worse. Hope that gives you enough info to figure out your problem.
#7
For the benefit of the frustrated skinners out there:
My object is testGadget.dts. It's skinned with a texture named base.testGadget.jpg, defined in 3DS Max. It's placed in \scriptsAndAssets\data\shapes\ .
The base texture and its alternate textures are placed in that same directory. I named them base.testGadget.jpg, red.testGadget.jpg, and blue.testGadget.jpg.
I created a materials.cs file in that same directory. It defines:
Now, when I issue ####.setSkinName(red); on the server, I get the red skin. ####.setSkinName(blue); gives me a blue skin. Note that the material name defined in materials.cs appears to be completely irrelevant, it's the filename that's crucial.
Hope your development goes more smoothly than mine! =D
-- JohnDopp
08/13/2008 (3:13 pm)
I've got it working, and many thanks to those who lent a hand! I did not need to make engine modifications (other than the TSShapeInstance setSkinName() fix, which I'd implemented earlier). For the benefit of the frustrated skinners out there:
My object is testGadget.dts. It's skinned with a texture named base.testGadget.jpg, defined in 3DS Max. It's placed in \scriptsAndAssets\data\shapes\ .
The base texture and its alternate textures are placed in that same directory. I named them base.testGadget.jpg, red.testGadget.jpg, and blue.testGadget.jpg.
I created a materials.cs file in that same directory. It defines:
new Material( default_gadget )
{
baseTex[0] = "base.testGadget";
};
new Material( scarletBogusNameThatDoesntMatter )
{
baseTex[0] = "red.testGadget";
};
new Material( ImBlueDaBaDeeDaBaDah)
{
baseTex[0] = "blue.testGadget";
};Now, when I issue ####.setSkinName(red); on the server, I get the red skin. ####.setSkinName(blue); gives me a blue skin. Note that the material name defined in materials.cs appears to be completely irrelevant, it's the filename that's crucial.
Hope your development goes more smoothly than mine! =D
-- JohnDopp
Associate Dave Calabrese
Cerulean Games
new Material( blackBowler ) { mapTo = "blackBowler.bowler"; baseTex[0] = "~data/shapes/gear/blackBowler.bowler"; };See if that helps ya.
-Dave Calabrese
Gaslight Studios