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
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.
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.
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,
Next, in the render function, we draw the line between the two positions just stored.
That's it we have a simple distance joint between two boxes. Here is the snapshot from this application.
Source code of this tutorial
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