Fix (needs more testing) in btRigidBody::setCenterOfMassTransform, assign m_interpolationWorldTransform = xform; instead of m_worldTransform;
Thanks Jay for reporting Added braking capability to btRaycastVehicle, see Bullet/Demos/VehicleDemo/VehicleDemo.cpp Added glutKeyboardUpFunc, for vehicle demo (keep accelerating/breaking, until key released/UP). Hope this is compatible with most GLUT implementations.
This commit is contained in:
@@ -368,6 +368,13 @@ void DemoApplication::keyboardCallback(unsigned char key, int x, int y)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DemoApplication::specialKeyboardUp(int key, int x, int y)
|
||||||
|
{
|
||||||
|
|
||||||
|
glutPostRedisplay();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void DemoApplication::specialKeyboard(int key, int x, int y)
|
void DemoApplication::specialKeyboard(int key, int x, int y)
|
||||||
{
|
{
|
||||||
(void)x;
|
(void)x;
|
||||||
|
|||||||
@@ -155,6 +155,8 @@ public:
|
|||||||
|
|
||||||
virtual void specialKeyboard(int key, int x, int y);
|
virtual void specialKeyboard(int key, int x, int y);
|
||||||
|
|
||||||
|
virtual void specialKeyboardUp(int key, int x, int y);
|
||||||
|
|
||||||
virtual void reshape(int w, int h);
|
virtual void reshape(int w, int h);
|
||||||
|
|
||||||
virtual void mouseFunc(int button, int state, int x, int y);
|
virtual void mouseFunc(int button, int state, int x, int y);
|
||||||
|
|||||||
@@ -32,6 +32,12 @@ static void glutSpecialKeyboardCallback(int key, int x, int y)
|
|||||||
gDemoApplication->specialKeyboard(key,x,y);
|
gDemoApplication->specialKeyboard(key,x,y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void glutSpecialKeyboardUpCallback(int key, int x, int y)
|
||||||
|
{
|
||||||
|
gDemoApplication->specialKeyboardUp(key,x,y);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void glutReshapeCallback(int w, int h)
|
static void glutReshapeCallback(int w, int h)
|
||||||
{
|
{
|
||||||
gDemoApplication->reshape(w,h);
|
gDemoApplication->reshape(w,h);
|
||||||
@@ -75,6 +81,8 @@ int glutmain(int argc, char **argv,int width,int height,const char* title,DemoAp
|
|||||||
|
|
||||||
glutKeyboardFunc(glutKeyboardCallback);
|
glutKeyboardFunc(glutKeyboardCallback);
|
||||||
glutSpecialFunc(glutSpecialKeyboardCallback);
|
glutSpecialFunc(glutSpecialKeyboardCallback);
|
||||||
|
glutSpecialUpFunc(glutSpecialKeyboardUpCallback);
|
||||||
|
|
||||||
glutReshapeFunc(glutReshapeCallback);
|
glutReshapeFunc(glutReshapeCallback);
|
||||||
//createMenu();
|
//createMenu();
|
||||||
glutIdleFunc(glutMoveAndDisplayCallback);
|
glutIdleFunc(glutMoveAndDisplayCallback);
|
||||||
|
|||||||
@@ -55,13 +55,17 @@ const int maxOverlap = 65535;
|
|||||||
///notice that for higher-quality slow-moving vehicles, another approach might be better
|
///notice that for higher-quality slow-moving vehicles, another approach might be better
|
||||||
///implementing explicit hinged-wheel constraints with cylinder collision, rather then raycasts
|
///implementing explicit hinged-wheel constraints with cylinder collision, rather then raycasts
|
||||||
float gEngineForce = 0.f;
|
float gEngineForce = 0.f;
|
||||||
float maxEngineForce = 3000.f;
|
float gBreakingForce = 0.f;
|
||||||
|
|
||||||
|
float maxEngineForce = 1000.f;//this should be engine/velocity dependent
|
||||||
|
float maxBreakingForce = 100.f;
|
||||||
|
|
||||||
float gVehicleSteering = 0.f;
|
float gVehicleSteering = 0.f;
|
||||||
float steeringIncrement = 0.04f;
|
float steeringIncrement = 0.04f;
|
||||||
float steeringClamp = 0.3f;
|
float steeringClamp = 0.3f;
|
||||||
float wheelRadius = 0.5f;
|
float wheelRadius = 0.5f;
|
||||||
float wheelWidth = 0.4f;
|
float wheelWidth = 0.4f;
|
||||||
float wheelFriction = 1e30f;//1000;//1e30f;
|
float wheelFriction = 1000;//1e30f;
|
||||||
float suspensionStiffness = 20.f;
|
float suspensionStiffness = 20.f;
|
||||||
float suspensionDamping = 2.3f;
|
float suspensionDamping = 2.3f;
|
||||||
float suspensionCompression = 4.4f;
|
float suspensionCompression = 4.4f;
|
||||||
@@ -103,6 +107,10 @@ m_maxCameraDistance(10.f)
|
|||||||
|
|
||||||
void VehicleDemo::setupPhysics()
|
void VehicleDemo::setupPhysics()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
extern btScalar gJitterVelocityDampingFactor;
|
||||||
|
gJitterVelocityDampingFactor = 1.f;
|
||||||
|
|
||||||
#ifdef FORCE_ZAXIS_UP
|
#ifdef FORCE_ZAXIS_UP
|
||||||
m_cameraUp = btVector3(0,0,1);
|
m_cameraUp = btVector3(0,0,1);
|
||||||
m_forwardAxis = 1;
|
m_forwardAxis = 1;
|
||||||
@@ -147,7 +155,8 @@ const float TRIANGLE_SIZE=20.f;
|
|||||||
for (int j=0;j<NUM_VERTS_Y;j++)
|
for (int j=0;j<NUM_VERTS_Y;j++)
|
||||||
{
|
{
|
||||||
float wl = .2f;
|
float wl = .2f;
|
||||||
float height = 20.f*sinf(float(i)*wl)*cosf(float(j)*wl);
|
//height set to zero, but can also use curved landscape, just uncomment out the code
|
||||||
|
float height = 0.f;//20.f*sinf(float(i)*wl)*cosf(float(j)*wl);
|
||||||
#ifdef FORCE_ZAXIS_UP
|
#ifdef FORCE_ZAXIS_UP
|
||||||
gVertices[i+j*NUM_VERTS_X].setValue(
|
gVertices[i+j*NUM_VERTS_X].setValue(
|
||||||
(i-NUM_VERTS_X*0.5f)*TRIANGLE_SIZE,
|
(i-NUM_VERTS_X*0.5f)*TRIANGLE_SIZE,
|
||||||
@@ -222,7 +231,7 @@ const float TRIANGLE_SIZE=20.f;
|
|||||||
tr.setOrigin(btVector3(0,0.f,0));
|
tr.setOrigin(btVector3(0,0.f,0));
|
||||||
|
|
||||||
m_carChassis = localCreateRigidBody(800,tr,compound);//chassisShape);
|
m_carChassis = localCreateRigidBody(800,tr,compound);//chassisShape);
|
||||||
m_carChassis->setDamping(0.2,0.2);
|
//m_carChassis->setDamping(0.2,0.2);
|
||||||
|
|
||||||
|
|
||||||
clientResetScene();
|
clientResetScene();
|
||||||
@@ -323,6 +332,24 @@ void VehicleDemo::clientMoveAndDisplay()
|
|||||||
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
int wheelIndex = 2;
|
||||||
|
m_vehicle->applyEngineForce(gEngineForce,wheelIndex);
|
||||||
|
m_vehicle->setBrake(gBreakingForce,wheelIndex);
|
||||||
|
wheelIndex = 3;
|
||||||
|
m_vehicle->applyEngineForce(gEngineForce,wheelIndex);
|
||||||
|
m_vehicle->setBrake(gBreakingForce,wheelIndex);
|
||||||
|
|
||||||
|
|
||||||
|
wheelIndex = 0;
|
||||||
|
m_vehicle->setSteeringValue(gVehicleSteering,wheelIndex);
|
||||||
|
wheelIndex = 1;
|
||||||
|
m_vehicle->setSteeringValue(gVehicleSteering,wheelIndex);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
float dt = m_clock.getTimeMicroseconds() * 0.000001f;
|
float dt = m_clock.getTimeMicroseconds() * 0.000001f;
|
||||||
m_clock.reset();
|
m_clock.reset();
|
||||||
if (m_dynamicsWorld)
|
if (m_dynamicsWorld)
|
||||||
@@ -334,7 +361,7 @@ void VehicleDemo::clientMoveAndDisplay()
|
|||||||
|
|
||||||
int numSimSteps = m_dynamicsWorld->stepSimulation(dt,maxSimSubSteps);
|
int numSimSteps = m_dynamicsWorld->stepSimulation(dt,maxSimSubSteps);
|
||||||
|
|
||||||
#define VERBOSE_FEEDBACK
|
//#define VERBOSE_FEEDBACK
|
||||||
#ifdef VERBOSE_FEEDBACK
|
#ifdef VERBOSE_FEEDBACK
|
||||||
if (!numSimSteps)
|
if (!numSimSteps)
|
||||||
printf("Interpolated transforms\n");
|
printf("Interpolated transforms\n");
|
||||||
@@ -356,18 +383,6 @@ void VehicleDemo::clientMoveAndDisplay()
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
{
|
|
||||||
int wheelIndex = 2;
|
|
||||||
m_vehicle->applyEngineForce(gEngineForce,wheelIndex);
|
|
||||||
wheelIndex = 3;
|
|
||||||
m_vehicle->applyEngineForce(gEngineForce,wheelIndex);
|
|
||||||
wheelIndex = 0;
|
|
||||||
m_vehicle->setSteeringValue(gVehicleSteering,wheelIndex);
|
|
||||||
wheelIndex = 1;
|
|
||||||
m_vehicle->setSteeringValue(gVehicleSteering,wheelIndex);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -417,7 +432,6 @@ void VehicleDemo::displayCallback(void)
|
|||||||
|
|
||||||
void VehicleDemo::clientResetScene()
|
void VehicleDemo::clientResetScene()
|
||||||
{
|
{
|
||||||
gEngineForce = 0.f;
|
|
||||||
gVehicleSteering = 0.f;
|
gVehicleSteering = 0.f;
|
||||||
m_carChassis->setCenterOfMassTransform(btTransform::getIdentity());
|
m_carChassis->setCenterOfMassTransform(btTransform::getIdentity());
|
||||||
m_carChassis->setLinearVelocity(btVector3(0,0,0));
|
m_carChassis->setLinearVelocity(btVector3(0,0,0));
|
||||||
@@ -437,10 +451,32 @@ void VehicleDemo::clientResetScene()
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void VehicleDemo::specialKeyboardUp(int key, int x, int y)
|
||||||
|
{
|
||||||
|
switch (key)
|
||||||
|
{
|
||||||
|
case GLUT_KEY_UP :
|
||||||
|
{
|
||||||
|
gEngineForce = 0.f;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GLUT_KEY_DOWN :
|
||||||
|
{
|
||||||
|
gBreakingForce = 0.f;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
DemoApplication::specialKeyboardUp(key,x,y);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void VehicleDemo::specialKeyboard(int key, int x, int y)
|
void VehicleDemo::specialKeyboard(int key, int x, int y)
|
||||||
{
|
{
|
||||||
|
|
||||||
printf("key = %i x=%i y=%i\n",key,x,y);
|
// printf("key = %i x=%i y=%i\n",key,x,y);
|
||||||
|
|
||||||
switch (key)
|
switch (key)
|
||||||
{
|
{
|
||||||
@@ -467,7 +503,7 @@ void VehicleDemo::specialKeyboard(int key, int x, int y)
|
|||||||
}
|
}
|
||||||
case GLUT_KEY_DOWN :
|
case GLUT_KEY_DOWN :
|
||||||
{
|
{
|
||||||
gEngineForce = -maxEngineForce;
|
gBreakingForce = maxBreakingForce;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -51,6 +51,8 @@ class VehicleDemo : public DemoApplication
|
|||||||
|
|
||||||
virtual void specialKeyboard(int key, int x, int y);
|
virtual void specialKeyboard(int key, int x, int y);
|
||||||
|
|
||||||
|
virtual void specialKeyboardUp(int key, int x, int y);
|
||||||
|
|
||||||
void renderme();
|
void renderme();
|
||||||
|
|
||||||
void setupPhysics();
|
void setupPhysics();
|
||||||
|
|||||||
@@ -91,7 +91,8 @@ extern "C" {
|
|||||||
glutJoystickFunc, glutForceJoystickFunc (NOT FINALIZED!).
|
glutJoystickFunc, glutForceJoystickFunc (NOT FINALIZED!).
|
||||||
**/
|
**/
|
||||||
#ifndef GLUT_API_VERSION /* allow this to be overriden */
|
#ifndef GLUT_API_VERSION /* allow this to be overriden */
|
||||||
#define GLUT_API_VERSION 3
|
//#define GLUT_API_VERSION 3
|
||||||
|
#define GLUT_API_VERSION 4
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -297,7 +297,7 @@ btQuaternion btRigidBody::getOrientation() const
|
|||||||
|
|
||||||
void btRigidBody::setCenterOfMassTransform(const btTransform& xform)
|
void btRigidBody::setCenterOfMassTransform(const btTransform& xform)
|
||||||
{
|
{
|
||||||
m_interpolationWorldTransform = m_worldTransform;
|
m_interpolationWorldTransform = xform;//m_worldTransform;
|
||||||
m_interpolationLinearVelocity = getLinearVelocity();
|
m_interpolationLinearVelocity = getLinearVelocity();
|
||||||
m_interpolationAngularVelocity = getAngularVelocity();
|
m_interpolationAngularVelocity = getAngularVelocity();
|
||||||
m_worldTransform = xform;
|
m_worldTransform = xform;
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
#include "BulletDynamics/Dynamics/btDynamicsWorld.h"
|
#include "BulletDynamics/Dynamics/btDynamicsWorld.h"
|
||||||
#include "btVehicleRaycaster.h"
|
#include "btVehicleRaycaster.h"
|
||||||
#include "btWheelInfo.h"
|
#include "btWheelInfo.h"
|
||||||
|
#include "LinearMath/btMinMax.h"
|
||||||
|
|
||||||
|
|
||||||
#include "BulletDynamics/ConstraintSolver/btContactConstraint.h"
|
#include "BulletDynamics/ConstraintSolver/btContactConstraint.h"
|
||||||
@@ -458,6 +459,63 @@ void btRaycastVehicle::updateSuspension(btScalar deltaTime)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct btWheelContactPoint
|
||||||
|
{
|
||||||
|
btRigidBody* m_body0;
|
||||||
|
btRigidBody* m_body1;
|
||||||
|
btVector3 m_frictionPositionWorld;
|
||||||
|
btVector3 m_frictionDirectionWorld;
|
||||||
|
btScalar m_jacDiagABInv;
|
||||||
|
btScalar m_maxImpulse;
|
||||||
|
|
||||||
|
|
||||||
|
btWheelContactPoint(btRigidBody* body0,btRigidBody* body1,const btVector3& frictionPosWorld,const btVector3& frictionDirectionWorld, btScalar maxImpulse)
|
||||||
|
:m_body0(body0),
|
||||||
|
m_body1(body1),
|
||||||
|
m_frictionPositionWorld(frictionPosWorld),
|
||||||
|
m_frictionDirectionWorld(frictionDirectionWorld),
|
||||||
|
m_maxImpulse(maxImpulse)
|
||||||
|
{
|
||||||
|
btScalar denom0 = body0->computeImpulseDenominator(frictionPosWorld,frictionDirectionWorld);
|
||||||
|
btScalar denom1 = body1->computeImpulseDenominator(frictionPosWorld,frictionDirectionWorld);
|
||||||
|
btScalar relaxation = 1.f;
|
||||||
|
m_jacDiagABInv = relaxation/(denom0+denom1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
btScalar calcRollingFriction(btWheelContactPoint& contactPoint)
|
||||||
|
{
|
||||||
|
|
||||||
|
btScalar j1=0.f;
|
||||||
|
|
||||||
|
const btVector3& contactPosWorld = contactPoint.m_frictionPositionWorld;
|
||||||
|
|
||||||
|
btVector3 rel_pos1 = contactPosWorld - contactPoint.m_body0->getCenterOfMassPosition();
|
||||||
|
btVector3 rel_pos2 = contactPosWorld - contactPoint.m_body1->getCenterOfMassPosition();
|
||||||
|
|
||||||
|
btScalar maxImpulse = contactPoint.m_maxImpulse;
|
||||||
|
|
||||||
|
btVector3 vel1 = contactPoint.m_body0->getVelocityInLocalPoint(rel_pos1);
|
||||||
|
btVector3 vel2 = contactPoint.m_body1->getVelocityInLocalPoint(rel_pos2);
|
||||||
|
btVector3 vel = vel1 - vel2;
|
||||||
|
|
||||||
|
btScalar vrel = contactPoint.m_frictionDirectionWorld.dot(vel);
|
||||||
|
|
||||||
|
// calculate j that moves us to zero relative velocity
|
||||||
|
j1 = -vrel * contactPoint.m_jacDiagABInv;
|
||||||
|
GEN_set_min(j1, maxImpulse);
|
||||||
|
GEN_set_max(j1, -maxImpulse);
|
||||||
|
|
||||||
|
return j1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
btScalar sideFrictionStiffness2 = btScalar(1.0);
|
btScalar sideFrictionStiffness2 = btScalar(1.0);
|
||||||
void btRaycastVehicle::updateFriction(btScalar timeStep)
|
void btRaycastVehicle::updateFriction(btScalar timeStep)
|
||||||
{
|
{
|
||||||
@@ -539,6 +597,26 @@ void btRaycastVehicle::updateFriction(btScalar timeStep)
|
|||||||
btWheelInfo& wheelInfo = m_wheelInfo[wheel];
|
btWheelInfo& wheelInfo = m_wheelInfo[wheel];
|
||||||
class btRigidBody* groundObject = (class btRigidBody*) wheelInfo.m_raycastInfo.m_groundObject;
|
class btRigidBody* groundObject = (class btRigidBody*) wheelInfo.m_raycastInfo.m_groundObject;
|
||||||
|
|
||||||
|
btScalar rollingFriction = 0.f;
|
||||||
|
|
||||||
|
if (groundObject)
|
||||||
|
{
|
||||||
|
if (wheelInfo.m_engineForce != 0.f)
|
||||||
|
{
|
||||||
|
rollingFriction = wheelInfo.m_engineForce* timeStep;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
btScalar defaultRollingFrictionImpulse = 0.f;
|
||||||
|
btScalar maxImpulse = wheelInfo.m_brake ? wheelInfo.m_brake : defaultRollingFrictionImpulse;
|
||||||
|
btWheelContactPoint contactPt(m_chassisBody,groundObject,wheelInfo.m_raycastInfo.m_contactPointWS,forwardWS[wheel],maxImpulse);
|
||||||
|
rollingFriction = calcRollingFriction(contactPt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//switch between active rolling (throttle), braking and non-active rolling friction (no throttle/break)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
forwardImpulse[wheel] = btScalar(0.);
|
forwardImpulse[wheel] = btScalar(0.);
|
||||||
m_wheelInfo[wheel].m_skidInfo= btScalar(1.);
|
m_wheelInfo[wheel].m_skidInfo= btScalar(1.);
|
||||||
@@ -552,7 +630,8 @@ void btRaycastVehicle::updateFriction(btScalar timeStep)
|
|||||||
|
|
||||||
btScalar maximpSquared = maximp * maximpSide;
|
btScalar maximpSquared = maximp * maximpSide;
|
||||||
|
|
||||||
forwardImpulse[wheel] = wheelInfo.m_engineForce* timeStep;
|
|
||||||
|
forwardImpulse[wheel] = rollingFriction;//wheelInfo.m_engineForce* timeStep;
|
||||||
|
|
||||||
btScalar x = (forwardImpulse[wheel] ) * fwdFactor;
|
btScalar x = (forwardImpulse[wheel] ) * fwdFactor;
|
||||||
btScalar y = (sideImpulse[wheel] ) * sideFactor;
|
btScalar y = (sideImpulse[wheel] ) * sideFactor;
|
||||||
|
|||||||
Reference in New Issue
Block a user