Posted By: jcl
A8 Ragdoll conversion from A7 - case study - 08/06/10 14:10
We were asked to help fixing the A8 version of the A7 Ragdoll demo by Helghast. As this is a good example of the problems you can encounter when converting an A7 ODE project to A8 PhysX, I'm posting here our experiences as case study.
1. Continous collision detection
For speed reasons, PhysX does not use CCD by default. This causes very small objects, such as the tiny bones of the demo, to fall through the floor. So you need to activate CCD when tiny things move fast and collide with something.
2. Initialize physics objects
Begin with the default settings. They will suffice in most cases. Adjust them later if necessary. The mass is calculated automatically in A8.
3. Initialize joints
In A8, joints are addressed through the entity pointer, not through a hinge handle, and have more parameters (for instance restitution, and break limits). When you don't need a break limit, pass NULL for the vector parameter. Passing nullvector would set the break limits to 0. And don't join an object with itself! This will cause a crash, just as in real life.
4. Reading object positions
Don't disable or enable objects for reading their positions in A8. First, it is not necessary. Second, you can't displace objects that are attached to joints, so disabling an object requires removing its joints first. You don't want to do that for a ragdoll.
1. Continous collision detection
For speed reasons, PhysX does not use CCD by default. This causes very small objects, such as the tiny bones of the demo, to fall through the floor. So you need to activate CCD when tiny things move fast and collide with something.
Code:
// A7 physics initialization fps_max = 60; fps_min = 30; ph_iterations = 20; // set itterating physics to smooth out. ph_setgravity(vector(0, 0, -668)); // set gravity ph_setcorrections(9000, 0); // set physics corrections ph_setcollisions(1000, 20);
Code:
// A8 physics initialization for CCD physX_open(); pX_setgravity(vector(0, 0, -9.81)); // set gravity pX_setccd(1);
2. Initialize physics objects
Begin with the default settings. They will suffice in most cases. Adjust them later if necessary. The mass is calculated automatically in A8.
Code:
// A7 physics object initialization set(entityMe, PASSABLE); phent_settype(entityMe, PH_RIGID, PH_BOX); phent_setmass(entityMe, mass, PH_BOX); phent_setfriction(entityMe, 15); phent_setdamping(entityMe, 35, 35); phent_setelasticity(entityMe, 35, 30); // bounciness reset(entityMe, PASSABLE);
Code:
// A8 physics object initialization with CCD pXent_settype(entityMe, PH_RIGID, PH_BOX); pXent_setccdskeleton(entityMe, nullvector, 1);
3. Initialize joints
In A8, joints are addressed through the entity pointer, not through a hinge handle, and have more parameters (for instance restitution, and break limits). When you don't need a break limit, pass NULL for the vector parameter. Passing nullvector would set the break limits to 0. And don't join an object with itself! This will cause a crash, just as in real life.
Code:
// A7 hinge initialization var tempHinge; // make constraint tempHinge = phcon_add(PH_HINGE, constr_1, constr_2); // attach to bodypart phcon_setparams1(tempHinge, constr_1.x, RD_Hinge1, nullvector); // set hinge limits phcon_setparams2(tempHinge, RD_Hinge2, nullvector, nullvector);
Code:
// A8 hinge initialization // make constraint pXcon_add(PH_HINGE, constr_1, constr_2, 0); // attach to bodypart pXcon_setparams1(constr_1, constr_1.x, RD_Hinge1, NULL); // set hinge limits pXcon_setparams2(constr_1, RD_Hinge2, NULL, NULL); // same
4. Reading object positions
Don't disable or enable objects for reading their positions in A8. First, it is not necessary. Second, you can't displace objects that are attached to joints, so disabling an object requires removing its joints first. You don't want to do that for a ragdoll.
Code:
// A7 pXent_enable(limb, 0); vec_for_bone(limb.x, actor, boneBlend); // place at right position ang_for_bone(limb.pan, actor, boneBlend); // rotate by right angle pXent_enable(limb, 1);
Code:
// A8 vec_for_bone(limb.x, actor, boneBlend); // place at right position ang_for_bone(limb.pan, actor, boneBlend); // rotate by right angle