In this tutorial, I will show you how to render a simple distance joint (a basic stiff spring). We will add to the picking code we covered in the last tutorial so that we can displace a given box using the mouse.
The scene in this tutorial contains two boxes: a static box and a dynamic box. The dynamic box and the static box are linked with a distance constraint. We can move the dynamic box using mouse and due to the spring constraint, it maintains a certain distance from the static box. So lets get started. For this demo, the AddRigidBodies function is as follow.
Adding a spring constraint
The only difference here is the addition of the stiff spring constraint. To create it, we first create the hkpStiffSpringConstraintData object. We then pass it the world space position of where the spring is located along with the two rigid bodies between which this constraint is created. Next,
the hkpStiffSpringConstraintData object and the two rigid bodies are passed to the hkpConstraintInstance object and then hkpWorld::addConstraint function is called passing it the hkpConstraintInstance object as shown in the following code snippet.
Rendering of the spring constraint
Another change we did is in the render function. It is now changed to render the spring constraint as well along with the two rigid bodies. The picked dynamic rigid body is rendered green when picked.
Output
That's all, after compiling and running, you will see two boxes linked with a spring constraint. You can pick the lower (dynamic) box by left clicking and dragging the mouse to reposition it as shown in the following figure.
After displacement, the spring constraint acts on the dynamic rigid body to ensure that it remains at the fixed distance that was given at the time of instantiation of the constraint.
You can get the full source code from my github repo https://github.com/mmmovania/HavokPhysicsTutorials
Controls:
Left click to rotate, left click on box to pick and reposition
Middle click to zoom
Right click to pan
What's next:
In the next tutorial, I will show you how to create a simple chain.
The scene in this tutorial contains two boxes: a static box and a dynamic box. The dynamic box and the static box are linked with a distance constraint. We can move the dynamic box using mouse and due to the spring constraint, it maintains a certain distance from the static box. So lets get started. For this demo, the AddRigidBodies function is as follow.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void AddRigidBodies() { | |
//add the falling movingBox | |
{ | |
hkVector4 halfExtents(0.5f, 0.5f, 0.5f); | |
hkpBoxShape* boxShape = new hkpBoxShape(halfExtents); | |
hkpRigidBodyCinfo ci; | |
ci.m_shape = boxShape; | |
ci.m_position = pos2; | |
ci.m_motionType = hkpMotion::MOTION_DYNAMIC; | |
boxShape->setRadius(0.001f); | |
const hkReal boxMass(10.0f); | |
hkMassProperties massProps; | |
hkpInertiaTensorComputer::computeShapeVolumeMassProperties(boxShape, boxMass, massProps); | |
ci.setMassProperties(massProps); | |
hkpRigidBody* rigidBody = new hkpRigidBody(ci); | |
movingBox = static_cast<hkpRigidBody*>(g_pWorld->addEntity(rigidBody)); | |
rigidBody->removeReference(); | |
//create the fixed box | |
ci.m_position = pos1; | |
ci.m_motionType = hkpMotion::MOTION_FIXED; | |
rigidBody = new hkpRigidBody(ci); | |
fixedBox = static_cast<hkpRigidBody*>(g_pWorld->addEntity(rigidBody)); | |
rigidBody->removeReference(); | |
boxShape->removeReference(); | |
} | |
//create the static box where the smaller movingBox will fall | |
{ | |
hkVector4 halfExtents(20.0f, 2.0f, 20.f); | |
hkpBoxShape* boxShape = new hkpBoxShape(halfExtents); | |
hkpRigidBodyCinfo ci; | |
ci.m_shape = boxShape; | |
ci.m_position = hkVector4(0, -2, 0); | |
ci.m_motionType = hkpMotion::MOTION_FIXED; | |
boxShape->setRadius(0.001f); | |
hkpRigidBody* rigidBody = new hkpRigidBody(ci); | |
boxShape->removeReference(); | |
g_pWorld->addEntity(rigidBody)->removeReference(); | |
} | |
// | |
// CREATE STIFF SPRING CONSTRAINT | |
// | |
{ | |
hkpStiffSpringConstraintData* spring = new hkpStiffSpringConstraintData(); | |
// Create constraint | |
spring->setInWorldSpace(movingBox->getTransform(), fixedBox->getTransform(), pos2, pos1); | |
// | |
// Create and add the constraint | |
// | |
{ | |
hkpConstraintInstance* constraint = new hkpConstraintInstance(movingBox, fixedBox, spring ); | |
g_pWorld->addConstraint(constraint); | |
constraint->removeReference(); | |
} | |
spring->removeReference(); | |
} | |
} |
Adding a spring constraint
The only difference here is the addition of the stiff spring constraint. To create it, we first create the hkpStiffSpringConstraintData object. We then pass it the world space position of where the spring is located along with the two rigid bodies between which this constraint is created. Next,
the hkpStiffSpringConstraintData object and the two rigid bodies are passed to the hkpConstraintInstance object and then hkpWorld::addConstraint function is called passing it the hkpConstraintInstance object as shown in the following code snippet.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
hkpStiffSpringConstraintData* spring = new hkpStiffSpringConstraintData(); | |
// Create constraint | |
spring->setInWorldSpace(movingBox->getTransform(), fixedBox->getTransform(), pos2, pos1); | |
// Create and add the constraint | |
{ | |
hkpConstraintInstance* constraint = new hkpConstraintInstance(movingBox, fixedBox, spring ); | |
g_pWorld->addConstraint(constraint); | |
constraint->removeReference(); | |
} | |
spring->removeReference(); |
Rendering of the spring constraint
Another change we did is in the render function. It is now changed to render the spring constraint as well along with the two rigid bodies. The picked dynamic rigid body is rendered green when picked.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//draw spring | |
glBegin(GL_LINES); | |
glColor3f(0,1,0); | |
glVertex3f(pos1.getComponent(0), pos1.getComponent(1), pos1.getComponent(2)); | |
glVertex3f(pos2.getComponent(0), pos2.getComponent(1), pos2.getComponent(2)); | |
glEnd(); | |
//draw boxes | |
glEnable(GL_LIGHTING); | |
glColor3f(1,1,1); | |
DrawBox(fixedBox); | |
if(wasHit) | |
glColor3f(0,1,0); | |
DrawBox(movingBox, true); | |
glDisable(GL_LIGHTING); |
Output
That's all, after compiling and running, you will see two boxes linked with a spring constraint. You can pick the lower (dynamic) box by left clicking and dragging the mouse to reposition it as shown in the following figure.
After displacement, the spring constraint acts on the dynamic rigid body to ensure that it remains at the fixed distance that was given at the time of instantiation of the constraint.
You can get the full source code from my github repo https://github.com/mmmovania/HavokPhysicsTutorials
Controls:
Left click to rotate, left click on box to pick and reposition
Middle click to zoom
Right click to pan
What's next:
In the next tutorial, I will show you how to create a simple chain.
2 comments:
How do you control the stiffness of spring
You can use the restlength parameter of stiff spring. Check the members of hkpStiffSpringConstraintData class
Post a Comment