Custom Shape Mod
by Duncan Gray · 04/03/2005 (9:43 am) · 84 comments
Download Code File
This resource still works in TGE 1.51 if you copy/past from the included pdf file.
This mod involves applying scaling factors to vertices according to the bone nodes to which they are attached. Basically you select a bone, select a scaling factor for x,y,z and those scaling factors get stored in a vector list which is instanced for each character/vehicle/shape. Additionally, the scaling is fully ghosted on the clients making it possible for each player to enter the game with his own unique character proportions, visible to all other players.
It's thus also possible to dynamically scale body proportions while mid game. So if a player bumps his head, you can make his head swell up etc.
The idea is to let the user scale his character proportions which then get saved in prefs. When he joins a game, his details get sent to the server which then ghosts the character settings to all the clients.
It's not only of use for characters. The mod is done mostly in shapebase.cc which is the base class for all shapes. Therefore, in theory, you can make trees, vehicles etc and scale sections of the shape as long as you place a "bone" in that area and assign a vertex group to the bone. You will then be able to select that bone and scale the participating verticies dynamically, at run time, from script which can add a whole new element to your game.
[Edit]
Updated the readme.txt with notes about TGE 1.4
[edit]
For a solution to the "floating above ground" problem, go here
SCREENSHOTS
[edit]
I also made an update, in the shapebase.cc section, use the following rather than the version in the pdf
That will let you do server script based (or console) scaling by issuing the setScalePerBone(bla) command.
You don't need all the guiplayerview changes if you only want to scale from server script. Example, when a player spawns, give a random 30% scale change to relevant body parts so that all players look a little different from each other.
This resource still works in TGE 1.51 if you copy/past from the included pdf file.
This mod involves applying scaling factors to vertices according to the bone nodes to which they are attached. Basically you select a bone, select a scaling factor for x,y,z and those scaling factors get stored in a vector list which is instanced for each character/vehicle/shape. Additionally, the scaling is fully ghosted on the clients making it possible for each player to enter the game with his own unique character proportions, visible to all other players.
It's thus also possible to dynamically scale body proportions while mid game. So if a player bumps his head, you can make his head swell up etc.
The idea is to let the user scale his character proportions which then get saved in prefs. When he joins a game, his details get sent to the server which then ghosts the character settings to all the clients.
It's not only of use for characters. The mod is done mostly in shapebase.cc which is the base class for all shapes. Therefore, in theory, you can make trees, vehicles etc and scale sections of the shape as long as you place a "bone" in that area and assign a vertex group to the bone. You will then be able to select that bone and scale the participating verticies dynamically, at run time, from script which can add a whole new element to your game.
[Edit]
Updated the readme.txt with notes about TGE 1.4
[edit]
For a solution to the "floating above ground" problem, go here
SCREENSHOTS
[edit]
I also made an update, in the shapebase.cc section, use the following rather than the version in the pdf
ConsoleMethod( ShapeBase, setScalePerBone, void, 6, 6, "ShapeBase.setScalePerBone( x, y, z , bone-index )" )
{
argc;
Point3F scale;
S32 boneNdx = dAtoi(argv[5]);
TSShapeInstance* si = object->getShapeInstance();
scale.set(strtod(argv[2],(char **)NULL),strtod(argv[3],(char **)NULL),strtod(argv[4],(char **)NULL));
si->setScalePerBone( scale, boneNdx );
char DNA[20];
dSprintf(DNA,sizeof(DNA) ,"%03u %1.2f %1.2f %1.2f" ,boneNdx,scale.x,scale.y,scale.z);
object->setDNA(DNA);
}That will let you do server script based (or console) scaling by issuing the setScalePerBone(bla) command.
You don't need all the guiplayerview changes if you only want to scale from server script. Example, when a player spawns, give a random 30% scale change to relevant body parts so that all players look a little different from each other.
About the author
#62
I have just about implemented this resource effectively, but have come across the same issue as Robert above. The model resizes properly in the GUI, but then when is passed to the game, only one change (i.e.an arm) is made as only one bit of DNA is sent to the server.
Can anyone point me in the right direction to get ALL the DNA passed to the server?
Thanks for a wonderful resource Duncan!
TheGords
07/06/2006 (12:56 pm)
All,I have just about implemented this resource effectively, but have come across the same issue as Robert above. The model resizes properly in the GUI, but then when is passed to the game, only one change (i.e.an arm) is made as only one bit of DNA is sent to the server.
Can anyone point me in the right direction to get ALL the DNA passed to the server?
Thanks for a wonderful resource Duncan!
TheGords
#63
I have connected all the face and hair meshes to the 'head' bone then exported as a DTS. But when it comes to re-sizing the head bone, only the face re-sizes and the hair is left in its original state!
Thanks, TheGords
11/03/2006 (2:04 pm)
Has anyone noticed a strange problem that some meshes don't resize?I have connected all the face and hair meshes to the 'head' bone then exported as a DTS. But when it comes to re-sizing the head bone, only the face re-sizes and the hair is left in its original state!
Thanks, TheGords
#64
The "resize" stuff here works relatively only oif one bone connected with another one.
e.g.
If your "hair" is a child of "head" then after "head" transform your hair will also be changes. If "hair" is not child of head, then you need to perform additional actions to make it work.
It means that you can chage the "root" of "root's" and it will affect to all childs.
11/03/2006 (2:10 pm)
Gordon Marsh,The "resize" stuff here works relatively only oif one bone connected with another one.
e.g.
If your "hair" is a child of "head" then after "head" transform your hair will also be changes. If "hair" is not child of head, then you need to perform additional actions to make it work.
It means that you can chage the "root" of "root's" and it will affect to all childs.
#65
Unless I misunderstand your reply, I think something more strange is happening, if I scale the root node (in my case "hip"), everything scales as it should, legs, arms, head etc APART FROM the hair, eyeballs etc which stay in the same position in the same scale.
I can't work it out, as they must be connected to the 'head' bone as they move with the animation!
11/03/2006 (2:16 pm)
Wow, a lightning fast reply!Unless I misunderstand your reply, I think something more strange is happening, if I scale the root node (in my case "hip"), everything scales as it should, legs, arms, head etc APART FROM the hair, eyeballs etc which stay in the same position in the same scale.
I can't work it out, as they must be connected to the 'head' bone as they move with the animation!
#66
Just check that you have a sendDNA type call there. If it's there then you will have to do some further debugging.
And as bank says, when you adjust a node, it's children are also affected. If you objects eyeball etc are staying the same then you must have some weird linking heirarchy going on.
I'm too busy with other items so if someone has a stand-alone, working port of this resource with the latest TGE source, then I will be happy to mirror it on my server and post a link to it here.
11/03/2006 (5:16 pm)
Gorden, the code definitely used to pass the entire DNA string to the server in the optClose() call in optinDlg.csJust check that you have a sendDNA type call there. If it's there then you will have to do some further debugging.
And as bank says, when you adjust a node, it's children are also affected. If you objects eyeball etc are staying the same then you must have some weird linking heirarchy going on.
I'm too busy with other items so if someone has a stand-alone, working port of this resource with the latest TGE source, then I will be happy to mirror it on my server and post a link to it here.
#67
if someone has a stand-alone, working port of this resource with the latest TGE source, then I will be happy to mirror it on my server and post a link to it here.
11/03/2006 (5:24 pm)
A quote from a post higher up in this thread which may helpQuote:
(1) Try printing/logging $Pref::Player::DNA in function OptClose() at the bottom of OptionsDlg.cs straight after PlayerView.getDNA();
If it shows the DNA string then you know it got saved ok. If not...
getDNA eventually calls getScalePerBoneList in tsShapeInstance.cc
getScalePerBoneList calls Con::setVariable to set the $Pref::Player::DNA value
(2) In your serverCmdSetDNA function (last page of pdf) , also try printing the %DNA string received by the server from the client.
(3) Also to help with debugging things, try searching through the pdf and it should tell you what files to locate stuff in.
if someone has a stand-alone, working port of this resource with the latest TGE source, then I will be happy to mirror it on my server and post a link to it here.
#68
One thing I'm trying to follow up at the moment, although having huge problems with the Milkshape DTS exporter, is that I've just loaded my player model into ShowToolPro and can see that extra nodes have been mistakenly created with exactly the same name as the meshes that are not resizing. This doesn't affect the general use of the model (i.e. it loads and animates fine) but could be the cause of this resizing problem.
If I can get the model to export without these nodes, and it fixes the problem, I'll post back. Actually I'll also try re-sizing these superflous nodes that have been created and see what happens...
11/04/2006 (4:59 am)
Thanks Duncan, I'll take a look at your suggestion.One thing I'm trying to follow up at the moment, although having huge problems with the Milkshape DTS exporter, is that I've just loaded my player model into ShowToolPro and can see that extra nodes have been mistakenly created with exactly the same name as the meshes that are not resizing. This doesn't affect the general use of the model (i.e. it loads and animates fine) but could be the cause of this resizing problem.
If I can get the model to export without these nodes, and it fixes the problem, I'll post back. Actually I'll also try re-sizing these superflous nodes that have been created and see what happens...
#69
I still can't export my model properly, but this is now a question for the DTS exports forum and not here :(((
11/04/2006 (8:40 am)
Aaarghh, I have finally managed to export a version of my model by going through Unwrap3d which doesn't have these extra "duplicate mesh name" nodes in it... Without the superflous nodes the hair scales properly!I still can't export my model properly, but this is now a question for the DTS exports forum and not here :(((
#70
Anyone got any clues for this? I can see that in PlayerData.cs there is a setting:
boundingBox = "1.2 1.2 2.3";
...which assumedly needs to change. But there are a few problems - I assume these numbers are x,y,z sizes, but what do the values actually mean - 1.2 of what???
Also, would a good place to make this change be in GameConnection::createPlayer on the server?
Any comments most welcome!
Gords
11/10/2006 (11:22 am)
There are a few questions above from a while ago about changing the collision box size when you make your character smaller so they don't float above the ground.Anyone got any clues for this? I can see that in PlayerData.cs there is a setting:
boundingBox = "1.2 1.2 2.3";
...which assumedly needs to change. But there are a few problems - I assume these numbers are x,y,z sizes, but what do the values actually mean - 1.2 of what???
Also, would a good place to make this change be in GameConnection::createPlayer on the server?
Any comments most welcome!
Gords
#71
You would have to adjust the size and height placement of the collision box to suit your scale and prevent him floating above ground.
Ideally you could monitor the scale of the hip bone and or the leg bones and adjust the bounds box - collision box as those bones scale etc
11/10/2006 (12:25 pm)
The boundingBox size you mention is in meters. i assume that the collision box size is calculated from the bounding box so Look in player.cc for bounding box or worldbox or getWorlBox etc and see if you can trace where the collision box gets created.You would have to adjust the size and height placement of the collision box to suit your scale and prevent him floating above ground.
Ideally you could monitor the scale of the hip bone and or the leg bones and adjust the bounds box - collision box as those bones scale etc
#72
Gords
11/11/2006 (9:06 am)
Thanks Duncan, I have tried a few things in the engine now, but all to no avail. I have started a new thread here www.garagegames.com/mg/forums/result.thread.php?qt=53678 to see if anyone can help me get it sorted.Gords
#73
This is working in TGE 1.5 w/ CG in a TSctrl in the Main Menu.
In the bottom left hand corner is the PlayerView control (usually I make it not visible).
Here, the head is shrunk:
01/30/2007 (10:24 pm)
Still an epic resource.This is working in TGE 1.5 w/ CG in a TSctrl in the Main Menu.
In the bottom left hand corner is the PlayerView control (usually I make it not visible).
Here, the head is shrunk:
#74
01/30/2007 (11:42 pm)
Really nice looking GUI and game artwork as well. I wood love to see the game when it's done.
#76
12/26/2007 (12:24 pm)
This is COOL!
#77
Just got it to work in TGEA 1.7.1.
There is a typo in the pdf that is causing just a single DNA node to be saved in $pref::Player::DNA.
in void TSShapeInstance::getScalePerBoneList()
should be
Yes the extra space makes all the difference.
Took me 2 days to track this problem down.
06/20/2008 (4:16 pm)
Great resource.Just got it to work in TGEA 1.7.1.
There is a typo in the pdf that is causing just a single DNA node to be saved in $pref::Player::DNA.
in void TSShapeInstance::getScalePerBoneList()
dSprintf(&slist[j],sz*sz2 ,"%03u %1.2f %1.2f %1.2[b]f",[/b]i,mScalePerBone[i].x,mScalePerBone[i].y,mScalePerBone[i].z);
should be
dSprintf(&slist[j],sz*sz2 ,"%03u %1.2f %1.2f %1.2[b]f ",[/b]i,mScalePerBone[i].x,mScalePerBone[i].y,mScalePerBone[i].z);
Yes the extra space makes all the difference.
Took me 2 days to track this problem down.
#78
for example, if i scale the thigh wider, the foot will lose its registration with the ground. i don't really understand why this is the case. any got a clue ?
tia,
orion
02/10/2009 (4:11 pm)
i'm having some problems with foot placement when using a technique very similar to this.for example, if i scale the thigh wider, the foot will lose its registration with the ground. i don't really understand why this is the case. any got a clue ?
tia,
orion
#79
i'd like to compare the behaviour of ours to someone else's.
the issue i'm seeing is that a bone inherits its parent's scale values in the frame of the parent, not in the frame of the child.
so say i have a thigh and a calf bone, and apply a scale so the thigh is thicker. ie scaled up in the 'forward' direction. then as the calf is rotated towards 90 degrees, where it's parallel with the 'forward' direction of the parent, the calf's length increases. because the parent's scale has been applied to the child in the parent's frame of reference.
the solution i'm thinking of is a bit involved:
don't incorporate the scales into the mNodeTransforms array of MatrixFs, but instead compose them into a seperate mNodeScales array of Point3Fs, and only apply them later in TSSkinMesh::updateSkin(). but i anticipate problems with that approach.
another approach might be:
when building up mNodeTransforms, first apply the inverse of the parent's scale in the parent's frame of reference, then apply the parent's scale in the local frame of reference, then apply the local scale in the local frame of reference. unfortunately i'm not entirely sure how to achieve that.
02/11/2009 (9:27 am)
could someone post an executable with this resource integrated in ?i'd like to compare the behaviour of ours to someone else's.
the issue i'm seeing is that a bone inherits its parent's scale values in the frame of the parent, not in the frame of the child.
so say i have a thigh and a calf bone, and apply a scale so the thigh is thicker. ie scaled up in the 'forward' direction. then as the calf is rotated towards 90 degrees, where it's parallel with the 'forward' direction of the parent, the calf's length increases. because the parent's scale has been applied to the child in the parent's frame of reference.
the solution i'm thinking of is a bit involved:
don't incorporate the scales into the mNodeTransforms array of MatrixFs, but instead compose them into a seperate mNodeScales array of Point3Fs, and only apply them later in TSSkinMesh::updateSkin(). but i anticipate problems with that approach.
another approach might be:
when building up mNodeTransforms, first apply the inverse of the parent's scale in the parent's frame of reference, then apply the parent's scale in the local frame of reference, then apply the local scale in the local frame of reference. unfortunately i'm not entirely sure how to achieve that.
#80
02/11/2009 (9:29 am)
i guess another test would be to include some bone scale in an animation and see if stock TGE handles it correctly. 
Torque Owner Dave Shay
It required additional modifications to guiPlayerView.cc, as the definition of setModel() was in variance to how it is being called in the PDF's code snippets. I was able to find and paste in the relavant code from the TGE 1.3 zip included in Duncan's archive.
Anyway, here's some screenshots of the results:
http://coremud.org/blogimg/20060702-01.jpg
http://coremud.org/blogimg/20060702-02.jpg
http://coremud.org/blogimg/20060702-03.jpg
I'm having the same issue Bryce Wong reported re: the Options GUI not altering the model displayed in the GUI. This is shown in the 2nd screenshot. I have other work to do there, as clicking the buttons to go to the other Options tabs don't work... and if I use the Options screen in-game, it'll kick me back to the main menu when I'm done. I probably didn't paste in the changes correctly from the PDF, but I've had enough code monkeying for one day. :)
I also started down the path at looking at Bryce's suggestion of using GuiObjectView. I downloaded the resource and compiled it with the new methods Bryce pasted above. Thanks for sharing that, also. I ran out of caffeine before figuring out how to integrate it. I think I have a general idea, but any pointers would be helpful!