Constraint demo has been changed - debug visualization turned on by default

This commit is contained in:
rponom
2009-01-16 03:06:28 +00:00
parent 21afccdb29
commit 4bcd016c98
4 changed files with 603 additions and 390 deletions

View File

@@ -34,6 +34,7 @@ const int numObjects = 3;
#define M_PI 3.1415926f #define M_PI 3.1415926f
#define M_PI_2 ((M_PI)*0.5f) #define M_PI_2 ((M_PI)*0.5f)
#define M_PI_4 ((M_PI)*0.25f)
btTransform sliderTransform; btTransform sliderTransform;
btVector3 lowerSliderLimit = btVector3(-10,0,0); btVector3 lowerSliderLimit = btVector3(-10,0,0);
@@ -79,6 +80,16 @@ void ConstraintDemo::initPhysics()
m_constraintSolver = new btSequentialImpulseConstraintSolver(); m_constraintSolver = new btSequentialImpulseConstraintSolver();
m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_overlappingPairCache,m_constraintSolver,m_collisionConfiguration); m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_overlappingPairCache,m_constraintSolver,m_collisionConfiguration);
btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(50.),btScalar(40.),btScalar(50.)));
m_collisionShapes.push_back(groundShape);
btTransform groundTransform;
groundTransform.setIdentity();
groundTransform.setOrigin(btVector3(0,-56,0));
btRigidBody* groundBody = localCreateRigidBody(0, groundTransform, groundShape);
btCollisionShape* shape = new btBoxShape(btVector3(CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS)); btCollisionShape* shape = new btBoxShape(btVector3(CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS));
m_collisionShapes.push_back(shape); m_collisionShapes.push_back(shape);
btTransform trans; btTransform trans;
@@ -86,6 +97,7 @@ void ConstraintDemo::initPhysics()
trans.setOrigin(btVector3(0,20,0)); trans.setOrigin(btVector3(0,20,0));
float mass = 1.f; float mass = 1.f;
#if 1
//point to point constraint (ball socket) //point to point constraint (ball socket)
{ {
btRigidBody* body0 = localCreateRigidBody( mass,trans,shape); btRigidBody* body0 = localCreateRigidBody( mass,trans,shape);
@@ -93,6 +105,7 @@ void ConstraintDemo::initPhysics()
mass = 1.f; mass = 1.f;
btRigidBody* body1 = 0;//localCreateRigidBody( mass,trans,shape); btRigidBody* body1 = 0;//localCreateRigidBody( mass,trans,shape);
// btRigidBody* body1 = localCreateRigidBody( 0.0,trans,0);
//body1->setActivationState(DISABLE_DEACTIVATION); //body1->setActivationState(DISABLE_DEACTIVATION);
//body1->setDamping(0.3,0.3); //body1->setDamping(0.3,0.3);
@@ -116,10 +129,12 @@ void ConstraintDemo::initPhysics()
hinge->enableAngularMotor(true,targetVelocity,maxMotorImpulse); hinge->enableAngularMotor(true,targetVelocity,maxMotorImpulse);
m_dynamicsWorld->addConstraint(hinge);//p2p); m_dynamicsWorld->addConstraint(hinge);//p2p);
// m_dynamicsWorld->addConstraint(p2p);
} }
#endif
#if 1
//create a slider, using the generic D6 constraint //create a slider, using the generic D6 constraint
{ {
mass = 1.f; mass = 1.f;
@@ -141,36 +156,143 @@ void ConstraintDemo::initPhysics()
frameInA = btTransform::getIdentity(); frameInA = btTransform::getIdentity();
frameInB = btTransform::getIdentity(); frameInB = btTransform::getIdentity();
bool useLinearReferenceFrameA = false;//use fixed frame B for linear limits // bool useLinearReferenceFrameA = false;//use fixed frame B for linear llimits
btGeneric6DofConstraint* slider = new btGeneric6DofConstraint(*d6body0,*fixedBody1,frameInA,frameInB,useLinearReferenceFrameA); bool useLinearReferenceFrameA = true;//use fixed frame A for linear llimits
btGeneric6DofConstraint* slider = new btGeneric6DofConstraint(*fixedBody1, *d6body0,frameInA,frameInB,useLinearReferenceFrameA);
slider->setLinearLowerLimit(lowerSliderLimit); slider->setLinearLowerLimit(lowerSliderLimit);
slider->setLinearUpperLimit(hiSliderLimit); slider->setLinearUpperLimit(hiSliderLimit);
//range should be small, otherwise singularities will 'explode' the constraint //range should be small, otherwise singularities will 'explode' the constraint
slider->setAngularLowerLimit(btVector3(20,0,0)); slider->setAngularLowerLimit(btVector3(-1.5,0,0));
slider->setAngularUpperLimit(btVector3(0,0,0)); slider->setAngularUpperLimit(btVector3(1.5,0,0));
// slider->setAngularLowerLimit(btVector3(0,0,0));
// slider->setAngularUpperLimit(btVector3(0,0,0));
slider->getTranslationalLimitMotor()->m_enableMotor[0] = true;
slider->getTranslationalLimitMotor()->m_targetVelocity[0] = -5.0f;
slider->getTranslationalLimitMotor()->m_maxMotorForce[0] = 0.1f;
m_dynamicsWorld->addConstraint(slider); m_dynamicsWorld->addConstraint(slider);
} }
#endif
#if 1
{ // create a door using hinge constraint attached to the world { // create a door using hinge constraint attached to the world
btCollisionShape* pDoorShape = new btBoxShape(btVector3(2.0f, 5.0f, 0.2f)); btCollisionShape* pDoorShape = new btBoxShape(btVector3(2.0f, 5.0f, 0.2f));
m_collisionShapes.push_back(pDoorShape); m_collisionShapes.push_back(pDoorShape);
btTransform doorTrans; btTransform doorTrans;
doorTrans.setIdentity(); doorTrans.setIdentity();
doorTrans.setOrigin(btVector3(-5.0f, 0.0f, 0.0f)); doorTrans.setOrigin(btVector3(-5.0f, -2.0f, 0.0f));
btRigidBody* pDoorBody = localCreateRigidBody( 1.0, doorTrans, pDoorShape); btRigidBody* pDoorBody = localCreateRigidBody( 1.0, doorTrans, pDoorShape);
pDoorBody->setActivationState(DISABLE_DEACTIVATION); pDoorBody->setActivationState(DISABLE_DEACTIVATION);
const btVector3 btPivotA( 2.1f, 0.0f, 0.0f ); // right next to the door slightly outside const btVector3 btPivotA( 2.1f, -2.0f, 0.0f ); // right next to the door slightly outside
btVector3 btAxisA( 0.0f, 1.0f, 0.0f ); // pointing upwards, aka Y-axis btVector3 btAxisA( 0.0f, 1.0f, 0.0f ); // pointing upwards, aka Y-axis
spDoorHinge = new btHingeConstraint( *pDoorBody, btPivotA, btAxisA ); spDoorHinge = new btHingeConstraint( *pDoorBody, btPivotA, btAxisA );
spDoorHinge->setLimit( 0.0f, M_PI_2 ); spDoorHinge->setLimit( 0.0f, M_PI_2 );
m_dynamicsWorld->addConstraint(spDoorHinge); m_dynamicsWorld->addConstraint(spDoorHinge);
}
//doorTrans.setOrigin(btVector3(-5.0f, 2.0f, 0.0f));
//btRigidBody* pDropBody = localCreateRigidBody( 10.0, doorTrans, shape);
}
#endif
#if 1
{ // create a generic 6DOF constraint
btTransform tr;
tr.setIdentity();
tr.setOrigin(btVector3(btScalar(10.), btScalar(6.), btScalar(0.)));
tr.getBasis().setEulerZYX(0,0,0);
// btRigidBody* pBodyA = localCreateRigidBody( mass, tr, shape);
btRigidBody* pBodyA = localCreateRigidBody( 0.0, tr, shape);
// btRigidBody* pBodyA = localCreateRigidBody( 0.0, tr, 0);
pBodyA->setActivationState(DISABLE_DEACTIVATION);
tr.setIdentity();
tr.setOrigin(btVector3(btScalar(0.), btScalar(6.), btScalar(0.)));
tr.getBasis().setEulerZYX(0,0,0);
btRigidBody* pBodyB = localCreateRigidBody(1.0, tr, shape);
pBodyB->setActivationState(DISABLE_DEACTIVATION);
btTransform frameInA, frameInB;
frameInA = btTransform::getIdentity();
frameInA.setOrigin(btVector3(btScalar(-5.), btScalar(0.), btScalar(0.)));
frameInB = btTransform::getIdentity();
frameInB.setOrigin(btVector3(btScalar(5.), btScalar(0.), btScalar(0.)));
btGeneric6DofConstraint* pGen6DOF = new btGeneric6DofConstraint(*pBodyA, *pBodyB, frameInA, frameInB, true);
// btGeneric6DofConstraint* pGen6DOF = new btGeneric6DofConstraint(*pBodyA, *pBodyB, frameInA, frameInB, false);
pGen6DOF->setLinearLowerLimit(btVector3(-10., -2., -1.));
pGen6DOF->setLinearUpperLimit(btVector3(10., 2., 1.));
// pGen6DOF->setLinearLowerLimit(btVector3(-10., 0., 0.));
// pGen6DOF->setLinearUpperLimit(btVector3(10., 0., 0.));
// pGen6DOF->setLinearLowerLimit(btVector3(0., 0., 0.));
// pGen6DOF->setLinearUpperLimit(btVector3(0., 0., 0.));
// pGen6DOF->getTranslationalLimitMotor()->m_enableMotor[0] = true;
// pGen6DOF->getTranslationalLimitMotor()->m_targetVelocity[0] = 5.0f;
// pGen6DOF->getTranslationalLimitMotor()->m_maxMotorForce[0] = 0.1f;
// pGen6DOF->setAngularLowerLimit(btVector3(0., SIMD_HALF_PI*0.9, 0.));
// pGen6DOF->setAngularUpperLimit(btVector3(0., -SIMD_HALF_PI*0.9, 0.));
// pGen6DOF->setAngularLowerLimit(btVector3(0., 0., -SIMD_HALF_PI));
// pGen6DOF->setAngularUpperLimit(btVector3(0., 0., SIMD_HALF_PI));
pGen6DOF->setAngularLowerLimit(btVector3(-SIMD_HALF_PI * 0.5f, -0.75, -SIMD_HALF_PI * 0.8f));
pGen6DOF->setAngularUpperLimit(btVector3(SIMD_HALF_PI * 0.5f, 0.75, SIMD_HALF_PI * 0.8f));
// pGen6DOF->setAngularLowerLimit(btVector3(-0.75,-0.5, -0.5));
// pGen6DOF->setAngularUpperLimit(btVector3(0.75,0.5, 0.5));
// pGen6DOF->setAngularLowerLimit(btVector3(-0.75,0., 0.));
// pGen6DOF->setAngularUpperLimit(btVector3(0.75,0., 0.));
m_dynamicsWorld->addConstraint(pGen6DOF, true);
}
#endif
#if 1
{ // create a ConeTwist constraint
btTransform tr;
tr.setIdentity();
tr.setOrigin(btVector3(btScalar(-10.), btScalar(5.), btScalar(0.)));
tr.getBasis().setEulerZYX(0,0,0);
btRigidBody* pBodyA = localCreateRigidBody( 0.0, tr, shape);
pBodyA->setActivationState(DISABLE_DEACTIVATION);
tr.setIdentity();
tr.setOrigin(btVector3(btScalar(-10.), btScalar(0.), btScalar(0.)));
tr.getBasis().setEulerZYX(0,0,0);
btRigidBody* pBodyB = localCreateRigidBody(1.0, tr, shape);
btTransform frameInA, frameInB;
frameInA = btTransform::getIdentity();
frameInA.getBasis().setEulerZYX(0, 0, M_PI_2);
frameInA.setOrigin(btVector3(btScalar(0.), btScalar(-1.), btScalar(0.)));
frameInB = btTransform::getIdentity();
frameInB.getBasis().setEulerZYX(0,0, M_PI_2);
frameInB.setOrigin(btVector3(btScalar(0.), btScalar(4.), btScalar(0.)));
btConeTwistConstraint* pCT = new btConeTwistConstraint(*pBodyA, *pBodyB, frameInA, frameInB);
pCT->setLimit(btScalar(M_PI_4)*0.5f, btScalar(M_PI_4), btScalar(M_PI * 0.9));
m_dynamicsWorld->addConstraint(pCT, true);
}
#endif
#if 1
{ // Hinge connected to the world, with motor (to hinge motor with new and old constraint solver)
btTransform tr;
tr.setIdentity();
tr.setOrigin(btVector3(btScalar(0.), btScalar(0.), btScalar(0.)));
btRigidBody* pBody = localCreateRigidBody( 1.0, tr, shape);
pBody->setActivationState(DISABLE_DEACTIVATION);
const btVector3 btPivotA( 10.0f, 0.0f, 0.0f );
btVector3 btAxisA( 0.0f, 0.0f, 1.0f );
btHingeConstraint* pHinge = new btHingeConstraint( *pBody, btPivotA, btAxisA );
pHinge->enableAngularMotor(true, -1.0, 0.165);
m_dynamicsWorld->addConstraint(pHinge);
}
#endif
} }
ConstraintDemo::~ConstraintDemo() ConstraintDemo::~ConstraintDemo()
@@ -266,7 +388,7 @@ void ConstraintDemo::clientMoveAndDisplay()
} }
renderme(); renderme();
drawLimit(); // drawLimit();
glFlush(); glFlush();
glutSwapBuffers(); glutSwapBuffers();
@@ -282,7 +404,7 @@ void ConstraintDemo::displayCallback(void) {
if (m_dynamicsWorld) if (m_dynamicsWorld)
m_dynamicsWorld->debugDrawWorld(); m_dynamicsWorld->debugDrawWorld();
drawLimit(); // drawLimit();
renderme(); renderme();

View File

@@ -1,15 +1,20 @@
#include "ConstraintDemo.h" #include "ConstraintDemo.h"
#include "GlutStuff.h" #include "GlutStuff.h"
#include "GLDebugDrawer.h"
int main(int argc,char** argv) #include "btBulletDynamicsCommon.h"
{
int main(int argc,char** argv)
ConstraintDemo* constraintDemo = new ConstraintDemo(); {
constraintDemo->initPhysics(); GLDebugDrawer gDebugDrawer;
ConstraintDemo* constraintDemo = new ConstraintDemo();
return glutmain(argc, argv,640,480,"Constraint Demo. http://www.continuousphysics.com/Bullet/phpBB2/",constraintDemo);
} constraintDemo->initPhysics();
constraintDemo->getDynamicsWorld()->setDebugDrawer(&gDebugDrawer);
constraintDemo->setDebugMode(btIDebugDraw::DBG_DrawConstraints+btIDebugDraw::DBG_DrawConstraintLimits);
return glutmain(argc, argv,640,480,"Constraint Demo. http://www.continuousphysics.com/Bullet/phpBB2/",constraintDemo);
}

View File

@@ -368,6 +368,18 @@ void DemoApplication::keyboardCallback(unsigned char key, int x, int y)
else else
m_debugMode |= btIDebugDraw::DBG_DrawContactPoints; m_debugMode |= btIDebugDraw::DBG_DrawContactPoints;
break; break;
case 'C' :
if (m_debugMode & btIDebugDraw::DBG_DrawConstraints)
m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DrawConstraints);
else
m_debugMode |= btIDebugDraw::DBG_DrawConstraints;
break;
case 'L' :
if (m_debugMode & btIDebugDraw::DBG_DrawConstraintLimits)
m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DrawConstraintLimits);
else
m_debugMode |= btIDebugDraw::DBG_DrawConstraintLimits;
break;
case 'd' : case 'd' :
if (m_debugMode & btIDebugDraw::DBG_NoDeactivation) if (m_debugMode & btIDebugDraw::DBG_NoDeactivation)

View File

@@ -1,365 +1,439 @@
/* /*
Bullet Continuous Collision Detection and Physics Library Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty. This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software. In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely, including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions: subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution. 3. This notice may not be removed or altered from any source distribution.
*/ */
/* /*
Added by Roman Ponomarev (rponom@gmail.com) Added by Roman Ponomarev (rponom@gmail.com)
April 04, 2008 April 04, 2008
Added support for ODE sover Added support for ODE sover
April 24, 2008 April 24, 2008
*/ */
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "btBulletDynamicsCommon.h" #include "btBulletDynamicsCommon.h"
#include "LinearMath/btIDebugDraw.h" #include "LinearMath/btIDebugDraw.h"
#include "GLDebugDrawer.h" #include "GLDebugDrawer.h"
#include "BMF_Api.h" #include "BMF_Api.h"
#include <stdio.h> //printf debugging #include <stdio.h> //printf debugging
#include "SliderConstraintDemo.h" #include "SliderConstraintDemo.h"
#include "GL_ShapeDrawer.h" #include "GL_ShapeDrawer.h"
#include "GlutStuff.h" #include "GlutStuff.h"
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#define SLIDER_DEMO_USE_ODE_SOLVER 0 #define SLIDER_DEMO_USE_ODE_SOLVER 0
#define SLIDER_DEMO_USE_6DOF 0 #define SLIDER_DEMO_USE_6DOF 0
#define CUBE_HALF_EXTENTS 1.f #define CUBE_HALF_EXTENTS 1.f
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// A couple of sliders // A couple of sliders
#if SLIDER_DEMO_USE_6DOF #if SLIDER_DEMO_USE_6DOF
static btGeneric6DofConstraint *spSlider1, *spSlider2; static btGeneric6DofConstraint *spSlider1, *spSlider2;
#else #else
static btSliderConstraint *spSlider1, *spSlider2; static btSliderConstraint *spSlider1, *spSlider2;
#endif #endif
//----------------------------------------------------------------------------- static btPoint2PointConstraint* spP2PConst;
static btHingeConstraint* spHingeConst;
static void draw_axes(const btRigidBody& rb, const btTransform& frame)
{ //-----------------------------------------------------------------------------
glBegin(GL_LINES);
// draw world transform static void draw_axes(const btRigidBody& rb, const btTransform& frame)
btVector3 from = rb.getWorldTransform().getOrigin(); {
btVector3 to = from + rb.getWorldTransform().getBasis() * btVector3(5,0,0); glBegin(GL_LINES);
// X in red // draw world transform
glColor3f(255.0F, 0.0F, 0.0F); btVector3 from = rb.getWorldTransform().getOrigin();
glVertex3d(from.getX(), from.getY(), from.getZ()); btVector3 to = from + rb.getWorldTransform().getBasis() * btVector3(5,0,0);
glVertex3d(to.getX(), to.getY(), to.getZ()); // X in red
to = from + rb.getWorldTransform().getBasis() * btVector3(0,5,0); glColor3f(255.0F, 0.0F, 0.0F);
// Y in green glVertex3d(from.getX(), from.getY(), from.getZ());
glColor3f(0.0F, 255.0F, 0.0F); glVertex3d(to.getX(), to.getY(), to.getZ());
glVertex3d(from.getX(), from.getY(), from.getZ()); to = from + rb.getWorldTransform().getBasis() * btVector3(0,5,0);
glVertex3d(to.getX(), to.getY(), to.getZ()); // Y in green
to = from + rb.getWorldTransform().getBasis() * btVector3(0,0,5); glColor3f(0.0F, 255.0F, 0.0F);
// Z in blue glVertex3d(from.getX(), from.getY(), from.getZ());
glColor3f(0.0F, 0.0F, 255.0F); glVertex3d(to.getX(), to.getY(), to.getZ());
glVertex3d(from.getX(), from.getY(), from.getZ()); to = from + rb.getWorldTransform().getBasis() * btVector3(0,0,5);
glVertex3d(to.getX(), to.getY(), to.getZ()); // Z in blue
// draw slider frame glColor3f(0.0F, 0.0F, 255.0F);
btTransform calc_frame = rb.getWorldTransform() * frame; glVertex3d(from.getX(), from.getY(), from.getZ());
from = calc_frame.getOrigin(); glVertex3d(to.getX(), to.getY(), to.getZ());
to = from + calc_frame.getBasis() * btVector3(10,0,0); // draw slider frame
// X in red btTransform calc_frame = rb.getWorldTransform() * frame;
glColor3f(255.0F, 0.0F, 0.0F); from = calc_frame.getOrigin();
glVertex3d(from.getX(), from.getY(), from.getZ()); to = from + calc_frame.getBasis() * btVector3(10,0,0);
glVertex3d(to.getX(), to.getY(), to.getZ()); // X in red
to = from + calc_frame.getBasis() * btVector3(0,10,0); glColor3f(255.0F, 0.0F, 0.0F);
// Y in green glVertex3d(from.getX(), from.getY(), from.getZ());
glColor3f(0.0F, 255.0F, 0.0F); glVertex3d(to.getX(), to.getY(), to.getZ());
glVertex3d(from.getX(), from.getY(), from.getZ()); to = from + calc_frame.getBasis() * btVector3(0,10,0);
glVertex3d(to.getX(), to.getY(), to.getZ()); // Y in green
to = from + calc_frame.getBasis() * btVector3(0,0,10); glColor3f(0.0F, 255.0F, 0.0F);
// Z in blue glVertex3d(from.getX(), from.getY(), from.getZ());
glColor3f(0.0F, 0.0F, 255.0F); glVertex3d(to.getX(), to.getY(), to.getZ());
glVertex3d(from.getX(), from.getY(), from.getZ()); to = from + calc_frame.getBasis() * btVector3(0,0,10);
glVertex3d(to.getX(), to.getY(), to.getZ()); // Z in blue
glEnd(); glColor3f(0.0F, 0.0F, 255.0F);
} // draw_axes() glVertex3d(from.getX(), from.getY(), from.getZ());
glVertex3d(to.getX(), to.getY(), to.getZ());
//----------------------------------------------------------------------------- glEnd();
} // draw_axes()
#if SLIDER_DEMO_USE_6DOF
static void drawSlider(btGeneric6DofConstraint* pSlider) //-----------------------------------------------------------------------------
{
draw_axes(pSlider->getRigidBodyA(), pSlider->getFrameOffsetA()); #if SLIDER_DEMO_USE_6DOF
draw_axes(pSlider->getRigidBodyB(), pSlider->getFrameOffsetB()); static void drawSlider(btGeneric6DofConstraint* pSlider)
} // drawSlider() {
#else draw_axes(pSlider->getRigidBodyA(), pSlider->getFrameOffsetA());
static void drawSlider(btSliderConstraint* pSlider) draw_axes(pSlider->getRigidBodyB(), pSlider->getFrameOffsetB());
{ } // drawSlider()
draw_axes(pSlider->getRigidBodyA(), pSlider->getFrameOffsetA()); #else
draw_axes(pSlider->getRigidBodyB(), pSlider->getFrameOffsetB()); static void drawSlider(btSliderConstraint* pSlider)
// draw limits in white {
btVector3 from(pSlider->getLowerLinLimit(), 0, 0); draw_axes(pSlider->getRigidBodyA(), pSlider->getFrameOffsetA());
btVector3 to(pSlider->getUpperLinLimit(), 0, 0); draw_axes(pSlider->getRigidBodyB(), pSlider->getFrameOffsetB());
btTransform trans; // draw limits in white
if(pSlider->getUseLinearReferenceFrameA()) btVector3 from(pSlider->getLowerLinLimit(), 0, 0);
{ btVector3 to(pSlider->getUpperLinLimit(), 0, 0);
trans = pSlider->getRigidBodyA().getWorldTransform() * pSlider->getFrameOffsetA(); btTransform trans;
} if(pSlider->getUseLinearReferenceFrameA())
else {
{ trans = pSlider->getRigidBodyA().getWorldTransform() * pSlider->getFrameOffsetA();
trans = pSlider->getRigidBodyB().getWorldTransform() * pSlider->getFrameOffsetB(); }
} else
from = trans * from; {
to = trans * to; trans = pSlider->getRigidBodyB().getWorldTransform() * pSlider->getFrameOffsetB();
glBegin(GL_LINES); }
glColor3f(255.0F, 255.0F, 255.0F); from = trans * from;
glVertex3d(from.getX(), from.getY(), from.getZ()); to = trans * to;
glVertex3d(to.getX(), to.getY(), to.getZ()); glBegin(GL_LINES);
glEnd(); glColor3f(255.0F, 255.0F, 255.0F);
} // drawSlider() glVertex3d(from.getX(), from.getY(), from.getZ());
#endif glVertex3d(to.getX(), to.getY(), to.getZ());
glEnd();
//----------------------------------------------------------------------------- } // drawSlider()
#endif
void SliderConstraintDemo::initPhysics()
{ //-----------------------------------------------------------------------------
void SliderConstraintDemo::initPhysics()
{
setTexturing(true); setTexturing(true);
setShadows(true); setShadows(true);
setCameraDistance(26.f); setCameraDistance(26.f);
// init world // init world
m_collisionConfiguration = new btDefaultCollisionConfiguration(); m_collisionConfiguration = new btDefaultCollisionConfiguration();
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
btVector3 worldMin(-1000,-1000,-1000); btVector3 worldMin(-1000,-1000,-1000);
btVector3 worldMax(1000,1000,1000); btVector3 worldMax(1000,1000,1000);
m_overlappingPairCache = new btAxisSweep3(worldMin,worldMax); m_overlappingPairCache = new btAxisSweep3(worldMin,worldMax);
#if SLIDER_DEMO_USE_ODE_SOLVER #if SLIDER_DEMO_USE_ODE_SOLVER
m_constraintSolver = new btOdeQuickstepConstraintSolver(); m_constraintSolver = new btOdeQuickstepConstraintSolver();
#else #else
m_constraintSolver = new btSequentialImpulseConstraintSolver(); m_constraintSolver = new btSequentialImpulseConstraintSolver();
#endif #endif
btDiscreteDynamicsWorld* wp = new btDiscreteDynamicsWorld(m_dispatcher,m_overlappingPairCache,m_constraintSolver,m_collisionConfiguration); btDiscreteDynamicsWorld* wp = new btDiscreteDynamicsWorld(m_dispatcher,m_overlappingPairCache,m_constraintSolver,m_collisionConfiguration);
// wp->getSolverInfo().m_numIterations = 20; // default is 10 // wp->getSolverInfo().m_numIterations = 20; // default is 10
m_dynamicsWorld = wp; m_dynamicsWorld = wp;
// wp->getSolverInfo().m_erp = 0.8;
// add floor
//btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),50); // add floor
btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.))); //btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),50);
m_collisionShapes.push_back(groundShape); btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.)));
btTransform groundTransform; m_collisionShapes.push_back(groundShape);
groundTransform.setIdentity(); btTransform groundTransform;
groundTransform.setOrigin(btVector3(0,-56,0)); groundTransform.setIdentity();
btRigidBody* groundBody = localCreateRigidBody(0, groundTransform, groundShape); groundTransform.setOrigin(btVector3(0,-56,0));
btRigidBody* groundBody = localCreateRigidBody(0, groundTransform, groundShape);
// add box shape (will be reused for all bodies)
btCollisionShape* shape = new btBoxShape(btVector3(CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS)); // add box shape (will be reused for all bodies)
m_collisionShapes.push_back(shape); btCollisionShape* shape = new btBoxShape(btVector3(CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS));
// mass of dymamic bodies m_collisionShapes.push_back(shape);
btScalar mass = btScalar(1.); // mass of dymamic bodies
btScalar mass = btScalar(1.);
// add dynamic rigid body A1
btTransform trans; // add dynamic rigid body A1
trans.setIdentity(); btTransform trans;
btVector3 worldPos(0,0,0); trans.setIdentity();
trans.setOrigin(worldPos); btVector3 worldPos(0,0,0);
btRigidBody* pRbA1 = localCreateRigidBody(mass, trans, shape); trans.setOrigin(worldPos);
pRbA1->setActivationState(DISABLE_DEACTIVATION); btRigidBody* pRbA1 = localCreateRigidBody(mass, trans, shape);
pRbA1->setActivationState(DISABLE_DEACTIVATION);
// add dynamic rigid body B1
worldPos.setValue(-10,0,0); // add dynamic rigid body B1
trans.setOrigin(worldPos); worldPos.setValue(-10,0,0);
btRigidBody* pRbB1 = localCreateRigidBody(mass, trans, shape); trans.setOrigin(worldPos);
pRbB1->setActivationState(DISABLE_DEACTIVATION); btRigidBody* pRbB1 = localCreateRigidBody(mass, trans, shape);
pRbB1->setActivationState(DISABLE_DEACTIVATION);
// create slider constraint between A1 and B1 and add it to world
btTransform frameInA, frameInB; // create slider constraint between A1 and B1 and add it to world
frameInA = btTransform::getIdentity(); btTransform frameInA, frameInB;
frameInB = btTransform::getIdentity(); frameInA = btTransform::getIdentity();
frameInB = btTransform::getIdentity();
#if SLIDER_DEMO_USE_6DOF
spSlider1 = new btGeneric6DofConstraint(*pRbA1, *pRbB1, frameInA, frameInB, true); #if SLIDER_DEMO_USE_6DOF
btVector3 lowerSliderLimit = btVector3(-20,0,0); spSlider1 = new btGeneric6DofConstraint(*pRbA1, *pRbB1, frameInA, frameInB, true);
btVector3 hiSliderLimit = btVector3(-10,0,0); btVector3 lowerSliderLimit = btVector3(-20,0,0);
// btVector3 lowerSliderLimit = btVector3(-20,-5,-5); btVector3 hiSliderLimit = btVector3(-10,0,0);
// btVector3 hiSliderLimit = btVector3(-10,5,5); // btVector3 lowerSliderLimit = btVector3(-20,-5,-5);
spSlider1->setLinearLowerLimit(lowerSliderLimit); // btVector3 hiSliderLimit = btVector3(-10,5,5);
spSlider1->setLinearUpperLimit(hiSliderLimit); spSlider1->setLinearLowerLimit(lowerSliderLimit);
spSlider1->setAngularLowerLimit(btVector3(0,0,0)); spSlider1->setLinearUpperLimit(hiSliderLimit);
spSlider1->setAngularUpperLimit(btVector3(0,0,0)); spSlider1->setAngularLowerLimit(btVector3(0,0,0));
#else spSlider1->setAngularUpperLimit(btVector3(0,0,0));
spSlider1 = new btSliderConstraint(*pRbA1, *pRbB1, frameInA, frameInB, true); #else
spSlider1->setLowerLinLimit(-15.0F); spSlider1 = new btSliderConstraint(*pRbA1, *pRbB1, frameInA, frameInB, true);
spSlider1->setUpperLinLimit(-5.0F); // spSlider1 = new btSliderConstraint(*pRbA1, *pRbB1, frameInA, frameInB, false);
// spSlider1->setLowerLinLimit(-10.0F); spSlider1->setLowerLinLimit(-15.0F);
// spSlider1->setUpperLinLimit(-10.0F); spSlider1->setUpperLinLimit(-5.0F);
spSlider1->setLowerAngLimit(-SIMD_PI / 3.0F); // spSlider1->setLowerLinLimit(5.0F);
spSlider1->setUpperAngLimit( SIMD_PI / 3.0F); // spSlider1->setUpperLinLimit(15.0F);
#endif // spSlider1->setLowerLinLimit(-10.0F);
// spSlider1->setUpperLinLimit(-10.0F);
m_dynamicsWorld->addConstraint(spSlider1, true); spSlider1->setLowerAngLimit(-SIMD_PI / 3.0F);
spSlider1->setUpperAngLimit( SIMD_PI / 3.0F);
// add kinematic rigid body A2 #endif
worldPos.setValue(0,2,0);
trans.setOrigin(worldPos); m_dynamicsWorld->addConstraint(spSlider1, true);
btRigidBody* pRbA2 = localCreateRigidBody(0, trans, shape);
pRbA2->setActivationState(DISABLE_DEACTIVATION); // add kinematic rigid body A2
worldPos.setValue(0,2,0);
// add dynamic rigid body B2 trans.setOrigin(worldPos);
worldPos.setValue(-10,2,0); btRigidBody* pRbA2 = localCreateRigidBody(0., trans, shape);
trans.setOrigin(worldPos); pRbA2->setActivationState(DISABLE_DEACTIVATION);
btRigidBody* pRbB2 = localCreateRigidBody(mass, trans, shape);
pRbB2->setActivationState(DISABLE_DEACTIVATION); // add dynamic rigid body B2
worldPos.setValue(-10,2,0);
// create slider constraint between A2 and B2 and add it to world trans.setOrigin(worldPos);
#if SLIDER_DEMO_USE_6DOF btRigidBody* pRbB2 = localCreateRigidBody(mass, trans, shape);
spSlider2 = new btGeneric6DofConstraint(*pRbA2, *pRbB2, frameInA, frameInB, true); pRbB2->setActivationState(DISABLE_DEACTIVATION);
spSlider2->setLinearLowerLimit(lowerSliderLimit);
spSlider2->setLinearUpperLimit(hiSliderLimit); // create slider constraint between A2 and B2 and add it to world
spSlider2->setAngularLowerLimit(btVector3(0,0,0)); #if SLIDER_DEMO_USE_6DOF
spSlider2->setAngularUpperLimit(btVector3(0,0,0)); spSlider2 = new btGeneric6DofConstraint(*pRbA2, *pRbB2, frameInA, frameInB, true);
#else spSlider2->setLinearLowerLimit(lowerSliderLimit);
spSlider2 = new btSliderConstraint(*pRbA2, *pRbB2, frameInA, frameInB, true); spSlider2->setLinearUpperLimit(hiSliderLimit);
spSlider2->setLowerLinLimit(-25.0F); spSlider2->setAngularLowerLimit(btVector3(0,0,0));
spSlider2->setUpperLinLimit(-5.0F); spSlider2->setAngularUpperLimit(btVector3(0,0,0));
spSlider2->setLowerAngLimit(SIMD_PI / 2.0F); #else
spSlider2->setUpperAngLimit(-SIMD_PI / 2.0F); spSlider2 = new btSliderConstraint(*pRbA2, *pRbB2, frameInA, frameInB, true);
// add motors // spSlider2 = new btSliderConstraint(*pRbA2, *pRbB2, frameInA, frameInB, false);
spSlider2->setPoweredLinMotor(true); spSlider2->setLowerLinLimit(-25.0F);
spSlider2->setMaxLinMotorForce(0.1); spSlider2->setUpperLinLimit(-5.0F);
spSlider2->setTargetLinMotorVelocity(5.0); // spSlider2->setLowerLinLimit(5.0F);
// spSlider2->setUpperLinLimit(25.0F);
spSlider2->setPoweredAngMotor(true); // spSlider2->setUpperLinLimit(-5.0F);
// spSlider2->setMaxAngMotorForce(0.01); // spSlider2->setUpperLinLimit(-9.99F);
spSlider2->setMaxAngMotorForce(10.0);
spSlider2->setTargetAngMotorVelocity(1.0);
// spSlider2->setLowerAngLimit(SIMD_PI / 2.0F);
// change default damping and restitution // spSlider2->setUpperAngLimit(-SIMD_PI / 2.0F);
spSlider2->setLowerAngLimit(-SIMD_PI / 2.0F);
spSlider2->setDampingDirLin(0.005F); spSlider2->setUpperAngLimit(SIMD_PI / 2.0F);
spSlider2->setRestitutionLimLin(1.1F); // spSlider2->setLowerAngLimit(-0.01F);
// spSlider2->setUpperAngLimit(0.01F);
// various ODE tests
// spSlider2->setDampingLimLin(0.1F); // linear bounce factor for ODE == 1.0 - DampingLimLin;
// spSlider2->setDampingLimAng(0.1F); // angular bounce factor for ODE == 1.0 - DampingLimAng; // spSlider2->setDampingLimLin(0.5f);
// spSlider2->setSoftnessOrthoAng(0.1);
// spSlider2->setSoftnessOrthoLin(0.1); #if 0
// spSlider2->setSoftnessLimLin(0.1); // add motors
// spSlider2->setSoftnessLimAng(0.1); spSlider2->setPoweredLinMotor(true);
#endif spSlider2->setMaxLinMotorForce(0.1);
m_dynamicsWorld->addConstraint(spSlider2, true); spSlider2->setTargetLinMotorVelocity(-5.0);
spSlider2->setPoweredAngMotor(true);
} // SliderConstraintDemo::initPhysics() // spSlider2->setMaxAngMotorForce(0.01);
spSlider2->setMaxAngMotorForce(10.0);
//----------------------------------------------------------------------------- spSlider2->setTargetAngMotorVelocity(1.0);
SliderConstraintDemo::~SliderConstraintDemo() // change default damping and restitution
{
//cleanup in the reverse order of creation/initialization spSlider2->setDampingDirLin(0.005F);
int i; spSlider2->setRestitutionLimLin(1.1F);
//removed/delete constraints #endif
for (i=m_dynamicsWorld->getNumConstraints()-1; i>=0 ;i--)
{ // various ODE tests
btTypedConstraint* constraint = m_dynamicsWorld->getConstraint(i); // spSlider2->setDampingLimLin(0.1F); // linear bounce factor for ODE == 1.0 - DampingLimLin;
m_dynamicsWorld->removeConstraint(constraint); // spSlider2->setDampingLimAng(0.1F); // angular bounce factor for ODE == 1.0 - DampingLimAng;
delete constraint; // spSlider2->setSoftnessOrthoAng(0.1);
} // spSlider2->setSoftnessOrthoLin(0.1);
//remove the rigidbodies from the dynamics world and delete them // spSlider2->setSoftnessLimLin(0.1);
for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) // spSlider2->setSoftnessLimAng(0.1);
{ #endif
btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; m_dynamicsWorld->addConstraint(spSlider2, true);
btRigidBody* body = btRigidBody::upcast(obj);
if (body && body->getMotionState())
{ #if 1
delete body->getMotionState(); {
} // add dynamic rigid body A1
m_dynamicsWorld->removeCollisionObject( obj ); trans.setIdentity();
delete obj; worldPos.setValue(20,0,0);
} trans.setOrigin(worldPos);
//delete collision shapes btRigidBody* pRbA3 = localCreateRigidBody(0.0F, trans, shape);
for (int j=0;j<m_collisionShapes.size();j++) pRbA1->setActivationState(DISABLE_DEACTIVATION);
{
btCollisionShape* shape = m_collisionShapes[j]; // add dynamic rigid body B1
delete shape; worldPos.setValue(25,0,0);
} trans.setOrigin(worldPos);
//delete dynamics world btRigidBody* pRbB3 = localCreateRigidBody(mass, trans, shape);
delete m_dynamicsWorld; pRbB1->setActivationState(DISABLE_DEACTIVATION);
//delete solver
delete m_constraintSolver; btVector3 pivA( 2.5, 0., 0.);
//delete broadphase btVector3 pivB(-2.5, 0., 0.);
delete m_overlappingPairCache; spP2PConst = new btPoint2PointConstraint(*pRbA3, *pRbB3, pivA, pivB);
//delete dispatcher m_dynamicsWorld->addConstraint(spP2PConst, true);
delete m_dispatcher; }
delete m_collisionConfiguration; #endif
} // SliderConstraintDemo::~SliderConstraintDemo()
#if 1
//----------------------------------------------------------------------------- // add dynamic rigid body A4
trans.setIdentity();
void SliderConstraintDemo::clientMoveAndDisplay() worldPos.setValue(20,10,0);
{ trans.setOrigin(worldPos);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); btRigidBody* pRbA4 = localCreateRigidBody(0.0F, trans, shape);
float dt = float(getDeltaTimeMicroseconds()) * 0.000001f; pRbA4->setActivationState(DISABLE_DEACTIVATION);
//during idle mode, just run 1 simulation step maximum
int maxSimSubSteps = m_idle ? 1 : 1; // add dynamic rigid body B1
if(m_idle) worldPos.setValue(27,10,0);
{ trans.setOrigin(worldPos);
dt = 1.0/420.f; btRigidBody* pRbB4 = localCreateRigidBody(mass, trans, shape);
} pRbB1->setActivationState(DISABLE_DEACTIVATION);
int numSimSteps = m_dynamicsWorld->stepSimulation(dt,maxSimSubSteps);
//optional but useful: debug drawing
m_dynamicsWorld->debugDrawWorld(); btVector3 pivA( 2., 0., 0.);
bool verbose = false; btVector3 pivB(-5., 0., 0.);
if (verbose) btVector3 axisA(0., 0., 1.);
{ btVector3 axisB(0., 0., 1.);
if (!numSimSteps)
printf("Interpolated transforms\n"); spHingeConst = new btHingeConstraint(*pRbA4, *pRbB4, pivA, pivB, axisA, axisB);
else // spHingeConst->setLimit(-1.57, 1.57);
{ spHingeConst->setLimit(1.57, -1.57);
if (numSimSteps > maxSimSubSteps) spHingeConst->enableAngularMotor(true, 10.0, 0.19);
{
//detect dropping frames m_dynamicsWorld->addConstraint(spHingeConst, true);
printf("Dropped (%i) simulation steps out of %i\n",numSimSteps - maxSimSubSteps,numSimSteps); #endif
} else
{ } // SliderConstraintDemo::initPhysics()
printf("Simulated (%i) steps\n",numSimSteps);
} //-----------------------------------------------------------------------------
}
} SliderConstraintDemo::~SliderConstraintDemo()
renderme(); {
drawSlider(spSlider1); //cleanup in the reverse order of creation/initialization
drawSlider(spSlider2); int i;
glFlush(); //removed/delete constraints
glutSwapBuffers(); for (i=m_dynamicsWorld->getNumConstraints()-1; i>=0 ;i--)
} // SliderConstraintDemo::clientMoveAndDisplay() {
btTypedConstraint* constraint = m_dynamicsWorld->getConstraint(i);
//----------------------------------------------------------------------------- m_dynamicsWorld->removeConstraint(constraint);
delete constraint;
void SliderConstraintDemo::displayCallback(void) }
{ //remove the rigidbodies from the dynamics world and delete them
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--)
if(m_dynamicsWorld) {
{ btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
m_dynamicsWorld->debugDrawWorld(); btRigidBody* body = btRigidBody::upcast(obj);
} if (body && body->getMotionState())
drawSlider(spSlider1); {
drawSlider(spSlider2); delete body->getMotionState();
renderme(); }
glFlush(); m_dynamicsWorld->removeCollisionObject( obj );
glutSwapBuffers(); delete obj;
} // SliderConstraintDemo::displayCallback() }
//delete collision shapes
//----------------------------------------------------------------------------- for (int j=0;j<m_collisionShapes.size();j++)
{
btCollisionShape* shape = m_collisionShapes[j];
delete shape;
}
//delete dynamics world
delete m_dynamicsWorld;
//delete solver
delete m_constraintSolver;
//delete broadphase
delete m_overlappingPairCache;
//delete dispatcher
delete m_dispatcher;
delete m_collisionConfiguration;
} // SliderConstraintDemo::~SliderConstraintDemo()
//-----------------------------------------------------------------------------
void SliderConstraintDemo::clientMoveAndDisplay()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
float dt = float(getDeltaTimeMicroseconds()) * 0.000001f;
//during idle mode, just run 1 simulation step maximum
int maxSimSubSteps = m_idle ? 1 : 1;
if(m_idle)
{
dt = 1.0/420.f;
}
int numSimSteps = m_dynamicsWorld->stepSimulation(dt,maxSimSubSteps);
//optional but useful: debug drawing
m_dynamicsWorld->debugDrawWorld();
bool verbose = false;
if (verbose)
{
if (!numSimSteps)
printf("Interpolated transforms\n");
else
{
if (numSimSteps > maxSimSubSteps)
{
//detect dropping frames
printf("Dropped (%i) simulation steps out of %i\n",numSimSteps - maxSimSubSteps,numSimSteps);
} else
{
printf("Simulated (%i) steps\n",numSimSteps);
}
}
}
renderme();
// drawSlider(spSlider1);
// drawSlider(spSlider2);
glFlush();
glutSwapBuffers();
} // SliderConstraintDemo::clientMoveAndDisplay()
//-----------------------------------------------------------------------------
void SliderConstraintDemo::displayCallback(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if(m_dynamicsWorld)
{
m_dynamicsWorld->debugDrawWorld();
}
// drawSlider(spSlider1);
// drawSlider(spSlider2);
renderme();
glFlush();
glutSwapBuffers();
} // SliderConstraintDemo::displayCallback()
//-----------------------------------------------------------------------------