Proper Ragdoll format

Recommended Posts

Hi Guys, i'm using Tokamak physics to play with ragdolls. Till today i always used quads and now it is time to switch to skinned model - merged with ragdoll operated from Tokamak engine. I am trying to find out any format that would help me doing that, Tokamak requires Bones / Joints to create a proper ragdoll, does any one ever used Tokamak to build Skinned Ragdoll from some model?

Share on other sites
The way it works is you have two seperate skeletons. One for the ragdoll physics, and one for the character graphics. The character graphic skeleton is usually updated with animation data, which is just a set of joint angles at a particular time.

To apply your ragdoll to the skinned model you need to generate a set of these joint angles to emulate the animation data at the current point in time. If your ragdoll and graphics are a 1 to 1 skeleton match then this is very easy, the angles are just 1 to 1 also.

Usually the ragdoll skeleton is much lower resolution for efficiency. It *at least* will not have fingers and eyes and such but it may even have fewer spine and limb joints. This is what can complicate things. You have to basically do a form of IK to generate the intermediate joint angles to make the joints that do exist coincide.

IIRC, your game is the flying robot ragdoll one with radial blur? If so, you can ignore my 3rd point. It should be easy for you to create a ragdoll skeleton which exactly fits your graphic skelton.

Share on other sites
bzroom - thanks for the reply.

The thing is that i am not sure if any type of model is suitable for Tokamak. As tokamak requires to have bones and joints defined.

I cannot exactly understand how is the ragdollskeleton being 'transformed' to my model having joints. I know it is easier to do that by having exactly the same amount of bones/joints in 3dmodel as in ragdoll skeleton.

If there is anything that would somehow enlighten me - i would really appreciate!

Share on other sites
It seems as though you have the mindset that you should start with the ragdoll and some how derive a graphics model. Infact it's the opposite way. Your ragdoll skeleton should be derived from the artist created graphic skeleton.

Any model format which includes bones is going to be a suitable format. You'll use the relative bone locations to create your ragdoll skeleton structure to be an exact fit for your graphic one, creating rigid bodies to represent each bone. So the root graphic bone will obtain the world transform of the root rigid body, and each bone after that will obtain the orientation from the ragdoll joints connecting that bone to the parent bone.

I'm not familiar with Tokamaks ragdoll structures so unfortunately my descriptions may be confusing or misleading. If you could point me to the ragdoll structure documentation, I'll look it over when I have a chance and try to give a more accurate description. But in short any boned graphic model format is a good place to start. I noticed in one of your other threads you were intersted in using MD5. That should be perfectly fine.

Share on other sites
bzroom,

that cleared up the chaos in my mind.
I'm running my own model format now exported from MS3d.
It is skineed and runs skel. animation within. What i'll do now, is try to merge ragdoll-skeleton to this model as you mentioned and see the results.
Of course i'll drop an update here with the results.

Thanks for letting me know,
it really makes more sense to me now.

Share on other sites
Just to let you have a look at tokamak's Ragdoll creation process. Here is a complete solution.

#define PI 3.141592653589793238462643fenum EBoneType {	BT_BODY,			 	BT_HEAD,			 	BT_RIGHT_ARM,	BT_LEFT_ARM	,	BT_RIGHT_FOREARM,	BT_LEFT_FOREARM	,	BT_RIGHT_THIGH,	BT_LEFT_THIGH,	BT_RIGHT_LEG,	BT_LEFT_LEG,	BT_BACKPACK,};	//	enum EBoneType;enum EBonesJointType {	BJT_BALL,		BJT_HINGE,	};	//	enum EBonesJointType;struct SBone {	float ZRotation;	neV3 Position, Size;	neRigidBody *Body;};	//	struct SBone; struct SBonesJoint { 	EBoneType BoneA, BoneB; 	neV3 Position; 	EBonesJointType Type; 	float LowerLimit, UpperLimit; 	bool EnableLimit, EnableTwistLimit; 	float TwistLimit; 	neJoint *Joint;};	//	struct SBonesJoint;static const int BonesCount = 10;SBone Bones[] = {	{	0.0f,	{	0.0f,	0.0f,	0.0f	},	{	0.55f,	0.7f,	0.3f	}	},	//	BT_BODY	{	0.0f,	{	0.0f,	0.55f,	0.0f	},	{	0.4f,	0.35f,	0.2f	}	},	//	BT_HEAD	{	PI/2,	{	-0.45f,	0.28f,	0.0f	},	{	0.25f,	0.4f,	0.2f	}	},	//	BT_RIGHT_ARM	{	PI/2,	{	0.45f,	0.28f,	0.0f	},	{	0.25f,	0.4f,	0.2f	}	},	//	BT_LEFT_ARM	{	-PI/2,	{	-0.9f,	0.28f,	0.0f	},	{	0.24f,	0.6f,	0.24f	}	},	//	BT_RIGHT_FOREARM	{	PI/2,	{	0.9f,	0.28f,	0.0f	},	{	0.24f,	0.6f,	0.24f	}	},	//	BT_LEFT_FOREARM	{	0.0f,	{	-0.2f,	-0.6f,	0.0f	},	{	0.27f,	0.7f,	0.2f	}	},	//	BT_RIGHT_THIGH	{	0.0f,	{	0.2f,	-0.6f,	0.0f	},	{	0.27f,	0.7f,	0.2f	}	},	//	BT_LEFT_THIGH	{	0.0f,	{	-0.2f,	-1.3f,	0.0f	},	{	0.3f,	0.8f,	0.3f	}	},	//	BT_RIGHT_LEG	{	0.0f,	{	0.2f,	-1.3f,	0.0f	},	{	0.3f,	0.8f,	0.3f	}	},	//	BT_LEFT_LEG};	//	SBone Bones[] static const int JointsCount = 9;// 	     BoneA,             BoneB ,             Position,                  Type ,        LowerLimit,  UpperLimit,  EnableLimit, EnableTwistLimit,TwistLimit,neJoint *Joint;  	 SBonesJoint Joints[] = {	{	BT_HEAD,			BT_BODY,		{	0.0f,	0.35f,	0.0f	},	BJT_HINGE,	-NE_PI/4,		NE_PI/4,		true,	false,	0.0f},	{	BT_RIGHT_ARM,		BT_BODY,		{	-0.22f, 0.28f,	0.0f	},	BJT_BALL,	0.0f,			NE_PI/2.5,		true,	true,	0.1f},	{	BT_LEFT_ARM,		BT_BODY,		{	0.22f,	0.28f,	0.0f	},	BJT_BALL,	0.0f,			NE_PI/2.5,		true,	true,	0.1f},	{	BT_RIGHT_FOREARM,	BT_RIGHT_ARM,	{	-0.65f,	0.28f,	0.0f	},	BJT_HINGE,	0.0f,			NE_PI/2,		true,	false,	0.0f},	{	BT_LEFT_FOREARM,	BT_LEFT_ARM,	{	0.65f,	0.28f,	0.0f	},	BJT_HINGE,	0.0f,			NE_PI/2,		true,	false,	0.0f},	{	BT_RIGHT_THIGH,		BT_BODY,		{	-0.2f,	-0.32f,	0.0f	},	BJT_BALL,	0.0f,			NE_PI/4,		true,	true,	0.8f},	{	BT_LEFT_THIGH,		BT_BODY,		{	0.2f,	-0.32f,	0.0f	},	BJT_BALL,	0.0f,			NE_PI/4,		true,	true,	0.8f},	{	BT_RIGHT_LEG,		BT_RIGHT_THIGH,	{	-0.2f,	-0.95f, 0.0f	},	BJT_HINGE,	0,0,0,0,0},	{	BT_LEFT_LEG,		BT_LEFT_THIGH,	{	0.2f,	-0.95f, 0.0f	},	BJT_HINGE,	0,0,0,0,0}, };	//	SBonesJoint Joints[]inline void neT3ToMatrix(const neT3 _Transform, float _Matrix[16]) {	_Matrix[0]	= _Transform.rot[0][0];	_Matrix[1]	= _Transform.rot[0][1];	_Matrix[2]	= _Transform.rot[0][2];	_Matrix[3]	= 0.0f;	_Matrix[4]	= _Transform.rot[1][0];	_Matrix[5]	= _Transform.rot[1][1];	_Matrix[6]	= _Transform.rot[1][2];	_Matrix[7]	= 0.0f;	_Matrix[8]	= _Transform.rot[2][0];	_Matrix[9]	= _Transform.rot[2][1];	_Matrix[10]	= _Transform.rot[2][2];	_Matrix[11]	= 0.0f;	_Matrix[12]	= _Transform.pos[0];	_Matrix[13]	= _Transform.pos[1];	_Matrix[14]	= _Transform.pos[2];	_Matrix[15]	= 1.0f;}	//	inline void neT3ToMatrix(const neT3 _Transform, float _Matrix[16])  void CreateRagDoll(neV3 &_Position ) {	float Mass = 10;	neV3 XAxis; XAxis.Set(1.0f, 0.0f, 0.0f);	neV3 ZAxis; ZAxis.Set(0.0f, 0.0f, 1.0f);	for (int i=0; i<BonesCount; i++) {		if(i==BT_RIGHT_ARM || i == BT_LEFT_ARM)Mass=2;		if(i==BT_RIGHT_FOREARM || i == BT_LEFT_FOREARM)Mass=2;		if(i==BT_RIGHT_THIGH || i == BT_LEFT_THIGH)Mass=2;		if(i==BT_RIGHT_LEG || i == BT_LEFT_LEG)Mass=2;		if(i==BT_BODY)Mass=10;		if(i==BT_HEAD)Mass=1;		 		Bones[i].Body = Simulator->CreateRigidBody();		Bones[i].Body->CollideConnected(true);				neGeometry *Geometry = Bones[i].Body->AddGeometry();		Geometry->SetBoxSize(Bones[i].Size[0]*Scale, Bones[i].Size[1]*Scale, Bones[i].Size[2]*Scale);		Bones[i].Body->UpdateBoundingInfo();		neV3 InertiaTensor = neBoxInertiaTensor(Bones[i].Size[0]*Scale, 												Bones[i].Size[1]*Scale, 												Bones[i].Size[2]*Scale, Mass);		Bones[i].Body->SetInertiaTensor(InertiaTensor);		Bones[i].Body->SetMass(Mass);		Bones[i].Body->SetUserData(100+i);				neV3 Position = Bones[i].Position * Scale + _Position;		Bones[i].Body->SetPos(Position);		neQ Quaternion; Quaternion.Set(Bones[i].ZRotation, ZAxis);		Bones[i].Body->SetRotation(Quaternion);	}	//	for (int i=0; i<BonesCount; i++)	neJoint *Joint; neT3 JointFrame;	for (int i=0; i<JointsCount; i++) {		Joint = Simulator->CreateJoint(Bones[Joints[i].BoneA].Body, Bones[Joints[i].BoneB].Body);		if (Joints[i].Type == BJT_BALL) Joint->SetType(neJoint::NE_JOINT_BALLSOCKET);		else Joint->SetType(neJoint::NE_JOINT_HINGE);		JointFrame.SetIdentity();		JointFrame.pos = Joints[i].Position * Scale + _Position;		Joint->SetJointFrameWorld(JointFrame);		if (Joints[i].EnableLimit) {			Joint->SetLowerLimit(Joints[i].LowerLimit);			Joint->SetUpperLimit(Joints[i].UpperLimit);			Joint->EnableLimit(true);		}	//	if (Joints[i].EnableLimit)		if (Joints[i].EnableTwistLimit) {			Joint->SetLowerLimit2(Joints[i].TwistLimit);			Joint->EnableLimit2(true);		}	//	if (Joints[i].EnableTwistLimit)				Joint->Enable(true);		Joints[i].Joint = Joint;	}	//	for (i=0; i<JointsCount; i++)}	//	void CreateRagDoll(neV3 &_Position)

Have a look.

Share on other sites
No way..
i can't get this to work..

having md5 loaded into the gl app i see total difference between tokamak ragdoll requirements and data i can get from md5mesh..

it seems tokamak uses a lot more data to create ragdoll ...

numJoints 47numMeshes 2joints {	"origin"	-1 ( 0.4811630249 -0.0000028610 0.0000000000 ) ( -0.7071067810 0.0000000000 0.0000000000 )		//	"bip01"	0 ( -9.5188369750 -0.0000028610 60.3541145324 ) ( 0.0000000000 0.0000000000 -0.0000000000 )		// origin	"pelvis"	1 ( -5.0578060150 -0.0000012252 60.3541145324 ) ( 0.4999996662 0.4999999046 0.4999996662 )		// bip01	"SPINNER"	2 ( -5.0674753189 0.0000003234 67.1245803833 ) ( 0.5610293388 0.4304026126 0.4304039001 )		// pelvis	"lthigh"	3 ( -5.0578050613 10.0008354187 60.3541221618 ) ( -0.5834061622 -0.4835883617 0.4166314601 )		// SPINNER	"lcalf"	4 ( -0.5389073371 13.5598382949 36.6310081481 ) ( -0.4712568759 -0.5934116840 0.5111591339 )		// lthigh	"lfoot"	5 ( -6.4881482124 17.3538913726 11.3716907501 ) ( -0.4687849998 -0.5041595458 0.4945433616 )		// lcalf	"ltoe0"	6 ( 1.8877953529 17.3558692932 -0.0474251937 ) ( -0.6883964061 -0.0014082899 -0.0004831372 )		// lfoot	"rthigh"	3 ( -5.0578069686 -10.0008430480 60.3541183471 ) ( -0.5023481845 -0.4163796901 0.4836173534 )		// SPINNER	"rcalf"	8 ( -0.5300383090 -13.5642156600 36.6333541870 ) ( -0.4057850360 -0.5109444141 0.5934447765 )		// rthigh	"rfoot"	9 ( -6.4698333740 -17.3586616516 11.3718748092 ) ( -0.5303904533 -0.4950637340 0.5043305397 )		// rcalf	"rtoe0"	10 ( 1.8903812408 -17.3516902923 -0.0587604522 ) ( -0.7255538940 0.0007310948 -0.0000904309 )		// rfoot	"chest"	3 ( -1.8212223052 -0.0000083983 79.2687149047 ) ( 0.5559721946 0.4369155883 0.4369168758 )		// SPINNER	"spine2"	12 ( 1.1410928964 -0.0000086274 91.4858703613 ) ( 0.5647228240 0.4255448341 0.4255461215 )		// chest	"neck"	13 ( 4.6032929420 -0.0000180431 103.5735626220 ) ( 0.6724569797 0.2186382532 0.2186391592 )		// spine2	"head"	14 ( 9.5343465805 -0.0000126771 107.1591186523 ) ( 0.5154178619 0.4840913295 0.4840930461 )		// neck	"lclavicle"	14 ( 4.6061553955 8.3088197708 103.5696334838 ) ( -0.0350226211 -0.1519666671 -0.7471330165 )		// neck	"lupperArm"	16 ( 1.4367122650 27.3352127075 100.7619400024 ) ( 0.3077651500 -0.3132365703 -0.6398134231 )		// lclavicle	"lforearm"	17 ( 1.1434220075 39.3802108764 85.2917709350 ) ( 0.3071821928 -0.3138090610 -0.6409855842 )		// lupperArm	"lhand"	18 ( 0.7824479103 51.2514343261 70.0449447631 ) ( 0.6679525375 0.2118231296 -0.6815388202 )		// lforearm	"lfinger0"	19 ( 7.9092764854 53.5329475402 64.1895828247 ) ( 0.9459392547 -0.1261154174 -0.1287528152 )		// lhand	"lfinger01"	20 ( 12.8584899902 52.6375923156 62.5402641296 ) ( 0.8883567810 -0.3486094474 -0.1894884109 )		// lfinger0	"lfinger1"	19 ( 3.8787021636 58.0599861145 59.6129150390 ) ( 0.7265145301 0.1490605449 -0.6495935916 )		// lhand	"lfinger11"	22 ( 4.3646926879 59.9493408203 55.7203826904 ) ( 0.7345753669 0.1021831035 -0.6589811325 )		// lfinger1	"lfinger12"	23 ( 4.8231744766 61.2562026977 51.8133735656 ) ( -0.7399286746 0.0504764080 0.6706750392 )		// lfinger11	"lfinger2"	19 ( -3.3590462207 57.9970283508 59.9384346008 ) ( 0.6382870674 0.1741897344 -0.7372230529 )		// lhand	"lfinger21"	25 ( -3.9294841766 59.6358146667 56.4874610900 ) ( 0.6507125377 0.1196893692 -0.7461503028 )		// lfinger2	"lfinger22"	26 ( -4.4799113273 60.6679306030 52.7956809997 ) ( -0.6616077899 -0.0052459449 0.7477327346 )		// lfinger21	"rclavicle"	14 ( 4.6061539649 -8.3088407516 103.5696334838 ) ( -0.6459535598 0.7471277236 0.1528254890 )		// neck	"rupperArm"	28 ( 1.4268237113 -27.3281612396 100.7254104614 ) ( 0.6308963298 -0.6398245811 -0.3129609823 )		// rclavicle	"rforearm"	29 ( 1.1397520303 -39.3826904296 85.2625427246 ) ( 0.6297044754 -0.6409974098 -0.3135330438 )		// rupperArm	"rhand"	30 ( 0.7848826408 -51.2633056640 70.0229034423 ) ( 0.2098594665 -0.6810718059 0.2129654645 )		// rforearm	"rfinger0"	31 ( 7.9183864593 -53.5641326904 64.1832427978 ) ( 0.2697207689 -0.1280962705 -0.1246078968 )		// rhand	"rfinger01"	32 ( 12.8733806610 -52.6817169189 62.5443420410 ) ( 0.2312743425 -0.1888655185 -0.3472106218 )		// rfinger0	"jaw"	15 ( 10.6289491653 -0.0000390880 107.5216674804 ) ( -0.6648724079 -0.2407165050 0.2407176733 )		// head	"rfinger1"	31 ( 3.8860769271 -58.0817604064 59.5988044738 ) ( 0.1663712120 -0.6490144252 0.1502279996 )		// rhand	"rfinger11"	35 ( 4.3755779266 -59.9730987548 55.7076797485 ) ( 0.1244264125 -0.6583441734 0.1033168673 )		// rfinger1	"rfinger12"	36 ( 4.8390846252 -61.2818832397 51.8019104003 ) ( -0.0130878186 -0.6698714256 -0.0494819450 )		// rfinger11	"rfinger2"	31 ( -3.3521680831 -58.0002899169 59.9088287353 ) ( 0.1358649253 -0.7366971015 0.1752205467 )		// rhand	"rfinger21"	38 ( -3.9194021224 -59.6382751464 56.4569511413 ) ( 0.0731943607 -0.7455363750 0.1206698894 )		// rfinger2	"rfinger22"	39 ( -4.4645586013 -60.6696815490 52.7641944885 ) ( -0.0569608879 -0.7469521045 0.0061010932 )		// rfinger21	"bottom_lip"	34 ( 8.4189233779 -0.0000362893 105.6040191650 ) ( -0.7061348438 -0.0370621633 0.0370631790 )		// jaw	"top_lip"	15 ( 7.2049083709 -0.0000357129 107.7356643676 ) ( -0.7058193206 0.0426523971 -0.0426515007 )		// head	"lmissile"	19 ( 0.9081200599 47.0400505065 59.2516555786 ) ( 0.0002388954 -0.0080377407 -0.0029151344 )		// lhand	"rmissile"	31 ( 0.9442643165 -47.0545234680 59.2291297912 ) ( -0.0001485671 -0.0069670495 0.0041923837 )		// rhand	"lknee"	5 ( 21.1109294891 13.5514030456 36.6243934631 ) ( 0.0000537166 -0.0001528452 0.0001918395 )		// lcalf	"rknee"	9 ( 21.1197681427 -13.5645313262 36.6361160278 ) ( 0.0000005902 0.0000638169 0.0000073403 )		// rcalf}

Md5 has joints listed,
tokamak needs Bones/Joints to create a ragdoll..

damn i'm scratching my head with this for two days now..

Share on other sites
Quote:
 Original post by dirtysanchezdamn i'm scratching my head with this for two days now..

Thats nothin.. Just keep at it man you'll get it.

One thing that is surely missing from your model file is the size to make the collision envelope for the ragdoll rigidbodies. For my game I just came up with some algorithm and lookup table for certain bones. Such as spin bones width and length were 1/4 the height, etc. It worked out pretty well.

The way the pros do it is they use a model format which allows the artist to explicitly define the shape of each ragdoll bone. So if you can find a model format which allows you to tag your geometry you could create geometry for all the bones and tag it as follows:

tags:
ragdoll_bone_spine1_collison

Or something. That way in code you'll know how big to make the bone. You'll also need to come up with some way to specify joint axis limits. I used a lookup table for that. So my model was accompanied with an xml file which defined all these parameters for each bone define in the graphic model file.

Share on other sites
Sure thing mate,
i'm on it...

But it is really a headache...

I would love to hear it is possible to be done with Tokamak - based on what i wrote up there(before) - this would kick my ass to progress with this..

Gotta make it!

Share on other sites
Ok, i made another step forward.

My mesh is rendered perfectly also
i'm able to get the joints rendered /set up 'almost' properly.
A small pic:

going forward...

Share on other sites

Ok,

another progress :

i'm really close to have it finished.

Share on other sites

Ok as i have my joints/bones ready - applied to the ones in the mesh i run the physics and i see that on every bone move my MD5 mesh is getting 'squizzed' and 'twisted' - this is probably due to quaternions...

The thing is.

Animation works from anim file perfectly, so the quaternions are calculated perfectly for each animation frame.

When i move the joints i apply next_animation_frame joints position to those from physic ragdoll so in pseudocode:

next_position=animation[nextframe].position;  //x y z of joint positionnext_position[0]=physics_ragdoll.position.x;next_position[1]=physics_ragdoll.position.y;next_position[2]=physics_ragdoll.position.z;interpJoint.pos[0] = actualposition[0] + animTime*(position[0] - actualposition[0]);interpJoint.pos[1] = actualposition[1] + animTime*(position[1] - actualposition[1]);interpJoint.pos[2] = actualposition[2] + animTime*(position[2] - actualposition[2]);interpJoint.quat = slerp(frame.joints[i].quat, nextFrame.joints[i].quat, animTime);

Results.

When there is physic applied and i do not put any force on the model, it seems that everything is calculated properly:

But after few impulses applied to the ragdoll, some falling, rotations ... my model gets bad.. really bad... Even though ragdoll joint positions are in place, and should point model joint positions correctly, the model itself is corrupted.

Any tips and tricks ?

I can obtain current ragdoll(physic) bone quaternion (x,y,z,w), rotation, position.. can't understand why it behavies this way...

Effect can be also seen here: http://www.youtube.com/watch?v=wl9J8r5Gyvg

Noone...?

Share on other sites
Looks to me like you've let your bones "stretch"; performing rotations on the bone actual vectors, instead of on the normalized bone orientation vector which you will then scale out to meet the bone length.

Alternatively, the same kind of error is creeping into your bone matrices; are you rebuilding them periodically, or only progressively altering them?

Share on other sites
Ok well.

Here is what i do.

Default code:

  // interpolate between the joints of the current frame and those of the next  // frame and store them in interpFrame  for ( int i=0; i < numJoints; i++ ) {    Joint &interpJoint = interpFrame.joints[i];    // linearly interpolate between joint positions    float *pos1 = frame.joints[i].pos,          *pos2 = nextFrame.joints[i].pos;    interpJoint.pos[0] = pos1[0] + animTime*(pos2[0] - pos1[0]);    interpJoint.pos[1] = pos1[1] + animTime*(pos2[1] - pos1[1]);    interpJoint.pos[2] = pos1[2] + animTime*(pos2[2] - pos1[2]);    interpJoint.quat = slerp(frame.joints[i].quat, nextFrame.joints[i].quat, animTime);  }  buildVerts(interpFrame);

My code:

  for ( int i=0; i < numJoints; i++ ) {		neV3 bp;		bp=Bones[i].Body->GetPos(); //physics ragdoll		joints[i].pos[0]=bp.X();		joints[i].pos[1]=bp.Y();		joints[i].pos[2]=bp.Z();}buildVerts();

I assign md5 joints position to match actual ragdoll joints position and everything gets 'squizzed'. It is ok untill i start to move the ragdoll joints.

This is Tokamak and md5 loader by A.J. Tavakoli. I try to understand how to join those two to have a skinned ragdoll running.

I am almost sure it is a quaternion issue here.. but i can't understand how to fix this.

Share on other sites
Ok,

i am almost in the middle of giving up with this for a longer time. Seems i'm really missing something that makes this damn MD5 mesh look properly.

Last time details - if anyone here worked with Tokamak and MD5 - i will really be very greatfull for any help..

  for ( int i=0; i < numJoints; i++ ) {		neV3 bp;		bp=Bones[i].Body->GetPos();		joints[i].pos[0]=bp.X();		joints[i].pos[1]=bp.Y();		joints[i].pos[2]=bp.Z();		Joints[i].Position.Set(joints[i].pos);			neT3 transform;		transform=Bones[i].Body->GetTransform();		joints[i].pos[0]=transform.pos.X();		joints[i].pos[1]=transform.pos.Y();		joints[i].pos[2]=transform.pos.Z();		neQ qqq;		qqq=Bones[i].Body->GetRotationQ();		joints[i].quat=buildQuat(qqq.X,qqq.Y,qqq.Z);				joints[i].quat.normalize();  }

As per above, this is how i apply md5 joints to tokamak's ragdoll.
then after applying positions i need to apply quaternion, i get actual bone quaternion by using tokamak's GetRotationQ() - call and passing to
'buildQuat' which calculates the 4th (W) value of quat and applies that to md5 joint..

No results .. still.., i am releasing md5 from 'static' to physics here to show how does above modification work... well it works, but the mesh is squizzed...

Video

I also publish the sourcecode for this project, you might wanna see it by yourself how does that work and what makes this whole md5 mesh so bad..

MD5RAGDOLL-TOKAMAK Source Code

Any chance that someone would help me out with this please?

Share on other sites
uf

i see noone here...

Share on other sites
As I mentioned before, it's very helpful to draw the ragdoll rigid bodies along with the character in order to see what the underlying ragdoll is actuallying doing.

Here's an example, scroll to 0:36. http://video.google.com/videoplay?docid=-4271219493080505499

Also, are you normalizing your quaternions after you manipulate them? you should.

Also, as a test, you should ensure that your skeletal code is working correctly by manually changing the angles, rather than setting them via the ragdoll. For example you should rig the elbows up to the up and down arrow buttons so you can test that the model does not get messed up when the rotate under normal situations. Once that works, then get the angle from the ragdoll.

After reading some of your previous posts i see that you've already done most of this. So my guess is that it's the normalization.

And again i see that you've done that also :)

I'm really out of suggestions :/

Share on other sites
Yes i have my "PHYSIC RAGDOLL" working great, i can see it's perfectly running the physics/collisions and so on.

The only thing is with the Model quaternion...

This video shows the physic ragdoll working perfectly, it's a dev video so it shows also some additional stuff, but yes - my ragdoll works great.

Md5 is just messed up due to those quaternions...

Share on other sites
Ok what i have came up to is that my Bones are in the same position as Joints are. This is what probably causes the problem ? - Please confirm..

So having position of two joints, how do i calculate properly the Bone position and its size?

Share on other sites
Can you draw some illustrations of what you mean by both of your questions? I have some ideas but i just want to make sure i'm on the right track before i go rambling off..

Share on other sites

So here is the deal.

Having positions of all joints, how do i calculate the bones positions/sizes between ?

I think the main problem with my ragdoll was that the ragdoll was having BONES position in JOINTS position. Tokamak uses Bones to manipulate the ragdoll, i see MD5 gives Joints positions only so i ahve to figure out the Bones positions by myself.

Hope that helps

Share on other sites
what kind of joints do you use? ball/socket? It looks to me as if your model gets twisted.
I think the right joint type here would be some kind of a hinge.

Share on other sites
Joints[i].Type=BJT_HINGE;

Is the type i'm using, head is a BALL type.

Share on other sites
If i understand you correctly, tokamak reports the positions of the joints you have shown here and you want a way to compute the positions and orientations of the "bones" you have here. Well for one, the bones are specified in the space of the joints, so it should be fairly trivial, but that's not going to be my official answer.

The bone positions of your graphical skelton should not be located between the joints of your ragdoll as you have illustrated here. The should coincide. The hand bone of your skeleton should be at the wrist position, exactly inline with the wrist joint. Your forearm bone is actually your elbow joint, and so on. The bones rotate through their origin, so they are infact joints. To call them two different things is only going to mislead you. Bones == joints. With that in mind, it should be easy to convert between the two.

Revised answer: Your description and illustration are confusing (there are two sets of data structures, tokamak and md5, you've only drawn one and didnt mention which it refered to). But rereading your post it seems like that MD5 uses the joints? and that bones are actually refering to the rigid bodies?

Tokamak uses rigidbodies and joints, where as md5 uses only joints. So given the joint positions from tokamak, you should easily compute the joint positions of the md5. Now if you want to go back the other way from MD5 to tokamak, then you'll need to compute the orientation and positions of the rigidbodies based on the joint positions from the animation. Is this what you're trying to do?

Create an account

Register a new account

• Partner Spotlight

• Forum Statistics

• Total Topics
627680
• Total Posts
2978610

• 13
• 12
• 10
• 12
• 22