How to convert a PxD6Joint into a PxArticulation to get ragdolls working.

Hi,

I am trying to add ragdolls to my game, so far, I managed to get everything working except for the joints. Characters fall, but their joints twist freely.

I figured out that problem was that I was just deserializing the rigid actors and not the joints. So I went ahead and wrote something like:

-----------------------------------

if( serializable->is() )
// do something

-------------------------------------

Which didn’t work. I read it’s a problem with the headers of PxJoint. So I changed it to:

-----------------------------------

if( serializable->is() )
// do something

-------------------------------------

Which worked. The problem is that I don’t know how to translate that to a PxArticulation. I read in the guide, that for ragdolls you need to use aggregates (which are composed of actors and articulations). How do you build the articulation from the joint?? furthermore, how do you put the joint into the scene? I mean, is there a way that I can just add the joint to the scene and forget about creating articulations?

Articulations need links and articulationJoints and I don’t know how to create any of them (and I did check the guide and the API).

I’m guessing that I have to do something like this:

-----------------------------------

repx::deserializeFromRepX(data, *physxSDK, *cooking, stringTable, externalRefs,
*bufferCollection, *sceneCollection, userRefs);

// some code

PxActor* actor = NULL;
PxD6Joint* joint = NULL;
for (unsigned int i = 0; i < nbActors; ++i) {
serializable = sceneCollection->getObject(i);

if( joint = serializable->is() )
//_aggregate->addArticulation( createArticulationFromJoint(joint) );

else if( actor = serializable->is() ) {
_aggregate->addActor(*actor);

  // the rest of the code to treat the actor

}
}

-------------------------------------

If I need to create and articulation then, how would you guys implement:

-----------------------------------

PxArticulation* createArticulationFromJoint( PxD6Joint* joint );

-------------------------------------

Many thanks in advance for the help.
Frank.

Not sure I do understand the question correctly but PxArticulation and PxJoint are two different kind of concepts and it is not clear to me why you would want to create one from the other. Either you build a ragdoll based on PxRigidDynamics and PxJoints or based on PxArticulation. In a lot of cases ragdolls based on PxJoints work fine and there is no need to use the more expensive PxArticulation. If the joints twist freely or the jointed bodies move apart, then you need to set/tweak the angular and linear joint limits accordingly (see PxD6Joint::setTwistLimit(), ::setSwingLimit(), ::setLinearLimit()). Unless you really need the simulation stability of an articulation I would just start with joints.

“…how do you put the joint into the scene?”
A joint gets added to the scene automatically when the jointed bodies/actors are added to the scene.

You do not need to use aggregates for ragdolls but it is recommended from a performance point of view. A PxAggregate is just a container of PxActors and/or PxArticulations to potentially speed up collision detection. It basically tells the system that some objects are close to each other and thus their bounding volumes can be summed up and treated as a single entity instead of using a whole bunch of small volumes separately. For a ragdoll based on joints, you can put all the connected bodies of the ragdoll into the aggregate (you can not add the joints and don’t need to because a joint has no geometric volume).

I’m doing the following: I set up the ragdoll in 3dmax using massfx (dynamic ragdoll). When I load the game I deserialize the ragdoll reading the repx file. I noticed that when I deserialize the repx file I get an error message saying that the twist limits of the joints are not valid.

According to what you said, just deserializing the actors and adding them to the aggregate should be enough (which is what I’m doing right now). Maybe the reason why they twist freely is because the setup is not well done.

If the twist limits of the joints are not valid they twist in any direction?

Many thanks,
Frank.

If you get an error message that the twist limits are not valid then the chance is high that the joints can twist in any direction. Can you preview the simulation of the ragdoll in 3dsmax and if yes, do the limits look ok there? It could be a version mismatch bug when the ragdoll gets deserialized into PhysX. Can you try to set the limits manually after deserializing into PhysX to see whether the behavior is fine in that case? If that is the case then please let us know which versions of PhysX and which version of the 3dsmax plugin you are using.
Also, I assume you did add the aggregate to the scene too?

The error message looks like the following:

  • INVALID_PARAMETER PxD6Joint::setTwistLimit: limitInvalid

I tried changing the size of the capsules in 3ds using the bones (instead of the meshes). That way I get a lot less errors. When I use meshes as capsules I also get this error -> INVALID_PARAMETER NpShape::setRestOffset:: restOffset should be less than contactOffset!

I tried checking the validity of the joints by code after deserializing them, and apparently they were all fine ( they returned true when I checked the method isValid() ). I even checked the twist limits debugging on visual studio and they were the same as the ones I found on the RepX file.

On 3ds the ragdoll runs perfectly. I checked visual debugger and the problem is that the doll rotates too much. For instance, the pelvis can rotate 180 degrees (that does not happen by any means in 3ds).

And yes, I’m adding the aggregate to the scene.

If it’s of any help I’m using Physx 3.2, the newest plugin to date for 3ds and 3ds 2013. I’ll check what happens if I put the values by hand.

Any other ideas?