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
#42
Thanks for the tip on the bounding box, will see if i can get it working.
Jonathan Stevens:
I used the pdf instructions to modify 1.4, worked 1st time.
01/24/2006 (12:53 am)
Duncan:Thanks for the tip on the bounding box, will see if i can get it working.
Jonathan Stevens:
I used the pdf instructions to modify 1.4, worked 1st time.
#43
01/24/2006 (1:45 am)
@Duncan and all others who got it working, well done. Perhaps post some screenshots of your success.
#44
thanks
01/25/2006 (3:18 pm)
has anyone got this working on mac osx in 1.4 i get an error /usr/bin/ld: warning prebinding disabled because of undefined symbols /usr/bin/ld: Undefined symbols: typeinfo for GuiSliderCtrl vtable for GuiSliderCtrl collect2: ld returned 1 exit statusim not sure what it is that is going wrong in guisliderctrl pleeez help
thanks
#45
Did you copy the GuiSliderCtrl changes from the pdf? or did you use the 1.3 version?
01/25/2006 (4:17 pm)
@Jonathan Lawitts Did you copy the GuiSliderCtrl changes from the pdf? or did you use the 1.3 version?
#47
Maybe update of instructions for those who is not well in c++ programming?
P.S. i'll post public some pics when I done client/server scripting for this mod in my project (persistant world - avatar customized only during registration, when logging in for a first time).
edit: spl
01/26/2006 (8:57 pm)
Duncan, it won't compile with stock TGE1.4 guiPlayerView (in my case I use HEAD 17/1/2006) until you set#include <stdlib.h>in head of guiPlayerView.cc file.
Maybe update of instructions for those who is not well in c++ programming?
P.S. i'll post public some pics when I done client/server scripting for this mod in my project (persistant world - avatar customized only during registration, when logging in for a first time).
edit: spl
#48
01/30/2006 (10:49 pm)
I'm having issues with the sliders not actually changing the model at all. I can move then left and right but the model stays exactly the same both in the playerview of options and in-game. Any thoughts?
#49
02/02/2006 (7:50 am)
I almost have this resource working but not quite. I can scale everything in the options just fine, and it saves everything correctly. If I quit out and start again I see the model the way I left it in the options. Its in-game that's being a problem. The DNA is being sent to the player, but nothing is being done with it. I thought that setDNA was supposed to take care of that, but as I look at it more it doesn't really seem to do anything more than set the DNA string. I assume that setting the SkinMask is supposed to force the rescale correct. Any help would be appreciated.
#50
02/02/2006 (9:49 am)
Nevermind, I got it to work. It turns out I had a bracket in the wrong place in setDNA and I missed an else statement. Great resource!
#51
05/03/2006 (1:20 pm)
What will this resource do to models made up of multiple meshes? Will they scale smoothly or will it introduce cracks between the pieces?
#52
05/03/2006 (5:05 pm)
Take a look at the screenshots link at the top. Those multi-colored models are made up of multiple meshes.
#53
Cool resource though, I can still think of a million other ways to use it.
05/04/2006 (4:20 am)
Yes, but the default orc guy isn't seamlessly joined along edges. I just tested this on my player models and it produced funky results on faces that have multiple joint influences. It also produced cracks at the seams.Cool resource though, I can still think of a million other ways to use it.
#54
I've started working on this today.. but no luck so far ;-/
05/23/2006 (2:14 am)
anyone tried to add "Hiding Meshes" resource into guiPlayerView?I've started working on this today.. but no luck so far ;-/
#55
05/23/2006 (10:19 am)
huh.. forget/ignore my previous post!... I've found that it's much easier to do with guiObjectView.
#56
Just let me know.
Regards,
Dreamer
p.s. If you do MeshHiding forget about the parts where you add that new mask, instead just reuse either the skinmask or the name mask for it.
05/23/2006 (10:59 am)
Hey Bank, you might want to look at the MMORPG Enhancement Kit where we have mesh hiding implemented into GuiObjectView. I think you are already an owner, but if not, I could post that little bit as a resource here.Just let me know.
Regards,
Dreamer
p.s. If you do MeshHiding forget about the parts where you add that new mask, instead just reuse either the skinmask or the name mask for it.
#57
For my project I've done customShapeMod + mesh hiding in engine and guiObjectView already.
Currently working on custom skinning of every single mesh, and yeah, I'm using skinMask for both - the skins and hidden meshes network updates (as soon as we launch our next phrase of tests, I'll post a snapshot of our avatars, etc.. for current moment you can have a look at the screenshots on our web-site).
I really want to have a look at MMORPG-EK, but just don't have time. Too much things to do.. We are preparing to start pre-beta in a few months, so it's not only programming.. I'm taking care of all the equipment, servers setup, etc...
as soon as I find some time, I'll get it ;)
thanks
05/23/2006 (11:14 am)
Dreamer, the separate resource can be good idea.. just for other ppl around here..For my project I've done customShapeMod + mesh hiding in engine and guiObjectView already.
Currently working on custom skinning of every single mesh, and yeah, I'm using skinMask for both - the skins and hidden meshes network updates (as soon as we launch our next phrase of tests, I'll post a snapshot of our avatars, etc.. for current moment you can have a look at the screenshots on our web-site).
I really want to have a look at MMORPG-EK, but just don't have time. Too much things to do.. We are preparing to start pre-beta in a few months, so it's not only programming.. I'm taking care of all the equipment, servers setup, etc...
as soon as I find some time, I'll get it ;)
thanks
#58
Thank you everyone for the snippets of code.
Recently added the mod from the pdf to a clean tge 1.4 starter.fps and it compiles/runs fine. On the player options gui all the settings for different body parts are loading from previous changes correctly. While playing the game, the changes are loaded and it looks great!
Ran into a problem and wondering if anyone has a fix for this.
When in the player options gui, unable to see the changes being done to the playerview. It doesn't show any of the changes when it loads on that gui. We have to actually run a game to see the changes.
Please help. =)
05/30/2006 (3:15 am)
This is an awesome post! Thank you everyone for the snippets of code.
Recently added the mod from the pdf to a clean tge 1.4 starter.fps and it compiles/runs fine. On the player options gui all the settings for different body parts are loading from previous changes correctly. While playing the game, the changes are loaded and it looks great!
Ran into a problem and wondering if anyone has a fix for this.
When in the player options gui, unable to see the changes being done to the playerview. It doesn't show any of the changes when it loads on that gui. We have to actually run a game to see the changes.
Please help. =)
#59
Used the GuiObjectView and this worked fine.
Also added two methods (probably not the best way to do this) to get the Main Mesh's Node's name and Size. This was added so we can do a loop in a "gui.cs" to list all the nodes for an object.
P.S. Sending around as sent to be.
----------Here is the two methods for GuiObjectView
ConsoleMethod( GuiObjectView, getThisNodeName, const char*, 3, 3, "ObjectView.getThisNodeName( nodeIndex )" )
{
argc;
GuiObjectView* view = static_cast( object );
return view->getNodeName(atoi(argv[2]));
}
//Returns Name of the MainObject's node at nodeIndex.
const char * GuiObjectView::getNodeName( S32 nodeIndex )
{
TSShape* shape;
if (mMeshObjects.mMainObject)
{
shape = mMeshObjects.mMainObject->getShape();
return shape->getName(nodeIndex);
}
else
return "";
}
ConsoleMethod( GuiObjectView, getThisNodesSize, S32, 2, 2, "ObjectView.getThisNodesSize( )" )
{
argc;
GuiObjectView* view = static_cast( object );
return view->getNodesSize();
}
//Returns Size of MainObject's Nodes.
U32 GuiObjectView::getNodesSize()
{
TSShape* shape;
if (mMeshObjects.mMainObject)
{
shape = mMeshObjects.mMainObject->getShape();
return shape->nodes.size();
}
else
return 0;
}
------------------Here is what we used them for.
Instead of using the hardcoded list to be added to the OptBoneAreaList.. use:
%maxNodeSize = PlayerView.getThisNodesSize();
for (%i = 0; %i < %maxNodeSize; %i++) {
%nodeName = PlayerView.getThisNodeName(%i);
OptBoneAreaList.add(%nodeName, PlayerView.findThisNode(%nodeName));
}
//%selId = OptBoneAreaList.findText("Whole Body");
//OptBoneAreaList.setSelected( %selId );
//OptBoneAreaList.onSelect( %selId, "" );
06/08/2006 (2:39 am)
Was not able to solve the playerview problem. BUT!!!Used the GuiObjectView and this worked fine.
Also added two methods (probably not the best way to do this) to get the Main Mesh's Node's name and Size. This was added so we can do a loop in a "gui.cs" to list all the nodes for an object.
P.S. Sending around as sent to be.
----------Here is the two methods for GuiObjectView
ConsoleMethod( GuiObjectView, getThisNodeName, const char*, 3, 3, "ObjectView.getThisNodeName( nodeIndex )" )
{
argc;
GuiObjectView* view = static_cast
return view->getNodeName(atoi(argv[2]));
}
//Returns Name of the MainObject's node at nodeIndex.
const char * GuiObjectView::getNodeName( S32 nodeIndex )
{
TSShape* shape;
if (mMeshObjects.mMainObject)
{
shape = mMeshObjects.mMainObject->getShape();
return shape->getName(nodeIndex);
}
else
return "";
}
ConsoleMethod( GuiObjectView, getThisNodesSize, S32, 2, 2, "ObjectView.getThisNodesSize( )" )
{
argc;
GuiObjectView* view = static_cast
return view->getNodesSize();
}
//Returns Size of MainObject's Nodes.
U32 GuiObjectView::getNodesSize()
{
TSShape* shape;
if (mMeshObjects.mMainObject)
{
shape = mMeshObjects.mMainObject->getShape();
return shape->nodes.size();
}
else
return 0;
}
------------------Here is what we used them for.
Instead of using the hardcoded list to be added to the OptBoneAreaList.. use:
%maxNodeSize = PlayerView.getThisNodesSize();
for (%i = 0; %i < %maxNodeSize; %i++) {
%nodeName = PlayerView.getThisNodeName(%i);
OptBoneAreaList.add(%nodeName, PlayerView.findThisNode(%nodeName));
}
//%selId = OptBoneAreaList.findText("Whole Body");
//OptBoneAreaList.setSelected( %selId );
//OptBoneAreaList.onSelect( %selId, "" );
#60
The only potential problem I see is that some of the standard player models also use nodes/bones for other purposes besides controling vertex groups. You could therefore end up having OptBoneAreaList containing bones you don't really want your users to mess with.
A solution would be to have some type of exclusion list containing names of bones to not display in the list.
06/08/2006 (4:54 am)
@Bryce, I'm not too active on TGE anymore, having moved on to other things.The only potential problem I see is that some of the standard player models also use nodes/bones for other purposes besides controling vertex groups. You could therefore end up having OptBoneAreaList containing bones you don't really want your users to mess with.
A solution would be to have some type of exclusion list containing names of bones to not display in the list.

Torque Owner Duncan Gray