Monday, May 30, 2011

PhysX3: Simple distance joint

In this tutorial, we will see how to create a simple distance joint. We will reuse the picking code in this tutorial to make things a bit more interesting. So without any further ado, lets get started. We will create two boxes one of which will be a static object. The other box will be manipulated by the mouse hence it will be dynamic.
Creating the boxes
The dynamic box

//2) Create dynamic cube  
PxReal density = 1.0f;
PxTransform transform(PxVec3(0.0f, 3.0, 0.0f), PxQuat::createIdentity());
PxVec3 dimensions(0.5,0.5,0.5);
PxBoxGeometry geometry(dimensions);    
PxRigidDynamic *dyn_box = PxCreateDynamic(*gPhysicsSDK, transform, geometry, *mMaterial, density);
if (!dyn_box)
   cerr<<"create actor failed!"<<endl;
dyn_box->setAngularDamping(0.75);
dyn_box->setLinearVelocity(PxVec3(0,0,0)); 
gScene->addActor(*dyn_box);
boxes.push_back(dyn_box);

The above lines are what we have seen in all the tutorials.
The static box
For static box, we simply create a PxRigidStatic object reusing the same geometry.
//create static cube
transform.p=PxVec3(0,5,0);
PxRigidStatic *static_box = PxCreateStatic(*gPhysicsSDK, transform, geometry, *mMaterial);
if (!static_box)
   cerr<<"create actor failed!"<<endl;
gScene->addActor(*static_box);
boxes.push_back(static_box);


Creating joint
For creating a very basic distance joint, we need to use the PxDistanceJointCreate function. This function takes the PhysX sdk object, the first rigidbody, the local transform of it, the second rigid body and its local transform. Next, the parameters are set for the distance joint as we did for the previous PhysX version.
//create a joint  
PxDistanceJoint* j = PxDistanceJointCreate(*gPhysicsSDK, dyn_box, PxTransform::createIdentity(), static_box, PxTransform::createIdentity());
j->setDamping(1);
j->setSpring(200);
j->setMinDistance(1);
j->setMaxDistance(2);
j->setConstraintFlag(PxConstraintFlag::eCOLLISION_ENABLED, true);
j->setDistanceJointFlag(PxDistanceJointFlag::eMIN_DISTANCE_ENABLED, true);
j->setDistanceJointFlag(PxDistanceJointFlag::eMAX_DISTANCE_ENABLED, true);
j->setDistanceJointFlag(PxDistanceJointFlag::eSPRING_ENABLED, true);


Rendering of the distance joint
For rendering of the distance joint, we do a fairly simple thing by creating a global array for 2 PxVec3 types. When we are about to draw the box actors, we store their current positions in the global array so the new DrawCube function is this,
//Stored globally
PxVec3 pos[2]; //for storing the two end points of spring
void DrawBox(PxShape* pShape) {
static int count=0;
 
PxTransform pT = PxShapeExt::getGlobalPose(*pShape);
pos[(count++)%2] = pT.p;
PxBoxGeometry bg;
pShape->getBoxGeometry(bg);
PxMat33 m = PxMat33Legacy(pT.q );
float mat[16];
getColumnMajor(m,pT.p, mat);
glPushMatrix(); 
glMultMatrixf(mat);
glutSolidCube(bg.halfExtents.x*2);
glPopMatrix(); 
}
 

Next, in the render function, we draw the line between the two positions just stored.
glColor3f(gMouseJoint!=NULL,gMouseJoint==NULL,gMouseJoint==NULL);
//Draw the spring 
glBegin(GL_LINES);
   glVertex3f(pos[0].x, pos[0].y, pos[0].z);
   glVertex3f(pos[1].x, pos[1].y, pos[1].z);
glEnd();


That's it we have a simple distance joint between two boxes. Here is the snapshot from this application.



Source code of this tutorial

6 comments:

  1. Hi, I'm trying to render a softbody and a fluid with the lastest physx version. The documentation is poor for this kind of sutff.

    If you can help me I will be grateful

    ReplyDelete
  2. Hi Edgar,
    I have successfully implemented the softbody in PhysX. Adding in Fluid should not be a problem. Could u tell me what problem are u facing? Can u make both fluids and softbody work separately?

    ReplyDelete
  3. Hi, thanks for answering me. I've done some code test with the previous version and with the new one and I don't know how to handle the deformable (softbody).

    I need to collide a softbody with a fluid. Adding the fluid rendering into should not be a problem because I've already implemented. My problems are on creating/setting/loading the deformable within the new version, because there isn't a sample of it.

    ReplyDelete
  4. Hi Edgar,
    You are right, the API docs are terrible and the PhysXGuide is plain useless. There is hardly anything for implementing cloth or soft bodies. I have been trying to port my cloth tutorial from PhysX 2.8.X to PhysX3/3.1 but I am having problems and nobody at the forums is answering me.

    For soft body I have already implemented them in the earlier version and I will soon post a PhysX 3.1 version soon.

    ReplyDelete
  5. Hi Mobeen, you're right about the forum. Nobody answers for that.

    Thanks man, I'll wait for that sample, really help me a lot in my studies.

    So, do you think that to have a soft body will not work in Physx 3.0?

    Thanks again.

    ReplyDelete
  6. Hi Edgar,
    I have finished the tutorial on doing cloth using the new cloth API in PhysX 3.1. Check it out here
    http://mmmovania.blogspot.com/2011/10/cloth-in-physx-31.html

    ReplyDelete