Joints are an important feature of every physics engine and of course PhysX with which nGENE Tech is integrated offers them. There are many kinds of joints so it is hard to generalize their purpose but it is possible to say that what they do is binding two actors (or an actor and the scene) together. This link can behave like a spring, joint between human bones, hinge or can be fixed (i.e. no relational movement between two bodies is possible). Therefore joints can be used in a number of different situations eg. for ragdoll system or doors in the level.
Creating joints in nGENE is a fairly easy task:
PhysicsActor* pActor1, pActor2; PhysicsWorld* pWorld; ... JOINT_DESC desc; desc.actor1 = pActor1; desc.actor2 = pActor2; Joint* pJoint = pWorld->createJoint(L"Fixed", desc);
This code creates "Fixed" joint between two actors what means that none of them can move or rotate relatively to the other. If one of the pointers was NULL (i.e. desc.actor1 or desc.actor2) the link would be created between not-null actor and the scene. Besides at least one of the actors has to be dynamic (i.e. of BT_DYNAMIC type) and none of them could be static (BT_STATIC).
The list of joints you can create is as follows:
- "Cylinder" - cylindrical joint, a sliding joint (movement/rotation is possible along single axis).
- "Distance" - distance joint keeps distance between actors. It can also stretch and shorten like a spring or band
- "Fixed" - no relational movement/rotation is possible
- "Hinge" - behaves like a hinge, i.e. only rotation along single axis is possible
- "PointInPlane" - enables movement of one body inside a plane attached to the other
- "PointOnLine" - enables movement of one body on a line attached to the other
- "Prism" - movement along one axis is possible but no rotation
- "Pulley" - simulates a rope thrown over two pulleys
- "Sphere" - similar joint as in a human's shoulder
Some of them should be created in a slightly different manner. Instead of passing reference to JOINT_DESC object they should be described with their own specific structures. This concerns following joints (names of structures which should be used for them is provided in parentheses):
- "Distance" (DISTANCE_JOINT_DESC)
- "Pulley" (PULLEY_JOINT_DESC)
- "Sphere" (SPHERE_JOINT_DESC)
Even though many of the joints parameters can be specified at joint creation only, there are some which could be altered later on but this all depends on the joint type.
Another concept regarding joints is that they can be "breakable" i.e. under specified force they break and stop to exist (what means that actors are independent henceforth). That is useful for simulating breaking springs or ropes for instance. To set constraints at which a joint breaks, call:
float maximumForce; float maximumTorque; ... pJoint->setBreakable(maximumForce, maximumTorque);
Where maximumForce and maximumTorque are maximum linear and angular force respectively under which a joint breaks.
Other useful methods of Joint class are specified below:
- void setPosition(const Vector3& _vec) - sets global position of the joint
- void setDirection(const Vector3& _direction) - sets global axis of the joint.
Both position and direction have different meaning for different types of joints so check source code/documentation for more details. If you want to set local position and direction for each of the actors you can do this when creating a joint. JOINT_DESC specifies following useful fields:
- localAnchor1 - position (anchor point) in space of actor1
- localAnchor2 - position (anchor point) in space of actor2
- localDirection1 - direction in space of actor1
- localDirection2 - direction in space of actor2
- globalAnchor - setting this will override localAnchor1 and localAnchor2. It is anchor in world space coordinates.
- globalDirection - setting this will override localDirection1 and localDirection2. It is axis in world space coordinates.
Following code excerpted from this tutorial full source creates door-like hinge joint between a box (pActor) and the scene:
desc.actor1 = pActor; desc.actor2 = NULL; pJoint = pWorld->createJoint(L"Hinge", desc); vecPos.set(-1.0f, 5.0f, -5.0f); pJoint->setPosition(vecPos); pJoint->setDirection(Vector3::UNIT_Y);
Code is omitted from this tutorial, see sources for more details on implementation.