From 2db8bfa3d66d2d22337dde56fe42a2bb60c47de7 Mon Sep 17 00:00:00 2001 From: ejcoumans Date: Sun, 22 Apr 2007 15:23:20 +0000 Subject: [PATCH] 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. --- Demos/OpenGL/DemoApplication.cpp | 7 ++ Demos/OpenGL/DemoApplication.h | 2 + Demos/OpenGL/GlutStuff.cpp | 8 ++ Demos/VehicleDemo/VehicleDemo.cpp | 76 ++++++++++++----- Demos/VehicleDemo/VehicleDemo.h | 2 + Glut/GL/glut.h | 3 +- src/BulletDynamics/Dynamics/btRigidBody.cpp | 2 +- .../Vehicle/btRaycastVehicle.cpp | 81 ++++++++++++++++++- 8 files changed, 158 insertions(+), 23 deletions(-) diff --git a/Demos/OpenGL/DemoApplication.cpp b/Demos/OpenGL/DemoApplication.cpp index ed0af3910..a80ee0bb8 100644 --- a/Demos/OpenGL/DemoApplication.cpp +++ b/Demos/OpenGL/DemoApplication.cpp @@ -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)x; diff --git a/Demos/OpenGL/DemoApplication.h b/Demos/OpenGL/DemoApplication.h index f1388462a..2f58ef679 100644 --- a/Demos/OpenGL/DemoApplication.h +++ b/Demos/OpenGL/DemoApplication.h @@ -155,6 +155,8 @@ public: 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 mouseFunc(int button, int state, int x, int y); diff --git a/Demos/OpenGL/GlutStuff.cpp b/Demos/OpenGL/GlutStuff.cpp index f19d54f3b..65a603aea 100644 --- a/Demos/OpenGL/GlutStuff.cpp +++ b/Demos/OpenGL/GlutStuff.cpp @@ -32,6 +32,12 @@ static void glutSpecialKeyboardCallback(int key, int x, int 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) { gDemoApplication->reshape(w,h); @@ -75,6 +81,8 @@ int glutmain(int argc, char **argv,int width,int height,const char* title,DemoAp glutKeyboardFunc(glutKeyboardCallback); glutSpecialFunc(glutSpecialKeyboardCallback); + glutSpecialUpFunc(glutSpecialKeyboardUpCallback); + glutReshapeFunc(glutReshapeCallback); //createMenu(); glutIdleFunc(glutMoveAndDisplayCallback); diff --git a/Demos/VehicleDemo/VehicleDemo.cpp b/Demos/VehicleDemo/VehicleDemo.cpp index 933cd95fd..cc21fce58 100644 --- a/Demos/VehicleDemo/VehicleDemo.cpp +++ b/Demos/VehicleDemo/VehicleDemo.cpp @@ -55,13 +55,17 @@ const int maxOverlap = 65535; ///notice that for higher-quality slow-moving vehicles, another approach might be better ///implementing explicit hinged-wheel constraints with cylinder collision, rather then raycasts 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 steeringIncrement = 0.04f; float steeringClamp = 0.3f; float wheelRadius = 0.5f; float wheelWidth = 0.4f; -float wheelFriction = 1e30f;//1000;//1e30f; +float wheelFriction = 1000;//1e30f; float suspensionStiffness = 20.f; float suspensionDamping = 2.3f; float suspensionCompression = 4.4f; @@ -103,6 +107,10 @@ m_maxCameraDistance(10.f) void VehicleDemo::setupPhysics() { + + extern btScalar gJitterVelocityDampingFactor; + gJitterVelocityDampingFactor = 1.f; + #ifdef FORCE_ZAXIS_UP m_cameraUp = btVector3(0,0,1); m_forwardAxis = 1; @@ -147,7 +155,8 @@ const float TRIANGLE_SIZE=20.f; for (int j=0;jsetDamping(0.2,0.2); + //m_carChassis->setDamping(0.2,0.2); clientResetScene(); @@ -323,6 +332,24 @@ void VehicleDemo::clientMoveAndDisplay() 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; m_clock.reset(); if (m_dynamicsWorld) @@ -334,7 +361,7 @@ void VehicleDemo::clientMoveAndDisplay() int numSimSteps = m_dynamicsWorld->stepSimulation(dt,maxSimSubSteps); -#define VERBOSE_FEEDBACK +//#define VERBOSE_FEEDBACK #ifdef VERBOSE_FEEDBACK if (!numSimSteps) 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() { - gEngineForce = 0.f; gVehicleSteering = 0.f; m_carChassis->setCenterOfMassTransform(btTransform::getIdentity()); 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) { - printf("key = %i x=%i y=%i\n",key,x,y); +// printf("key = %i x=%i y=%i\n",key,x,y); switch (key) { @@ -467,7 +503,7 @@ void VehicleDemo::specialKeyboard(int key, int x, int y) } case GLUT_KEY_DOWN : { - gEngineForce = -maxEngineForce; + gBreakingForce = maxBreakingForce; break; } default: diff --git a/Demos/VehicleDemo/VehicleDemo.h b/Demos/VehicleDemo/VehicleDemo.h index ad9b2391d..e930de727 100644 --- a/Demos/VehicleDemo/VehicleDemo.h +++ b/Demos/VehicleDemo/VehicleDemo.h @@ -51,6 +51,8 @@ class VehicleDemo : public DemoApplication virtual void specialKeyboard(int key, int x, int y); + virtual void specialKeyboardUp(int key, int x, int y); + void renderme(); void setupPhysics(); diff --git a/Glut/GL/glut.h b/Glut/GL/glut.h index e0692adb4..1c821d74d 100644 --- a/Glut/GL/glut.h +++ b/Glut/GL/glut.h @@ -91,7 +91,8 @@ extern "C" { glutJoystickFunc, glutForceJoystickFunc (NOT FINALIZED!). **/ #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 /** diff --git a/src/BulletDynamics/Dynamics/btRigidBody.cpp b/src/BulletDynamics/Dynamics/btRigidBody.cpp index e7470f703..dbf73b85b 100644 --- a/src/BulletDynamics/Dynamics/btRigidBody.cpp +++ b/src/BulletDynamics/Dynamics/btRigidBody.cpp @@ -297,7 +297,7 @@ btQuaternion btRigidBody::getOrientation() const void btRigidBody::setCenterOfMassTransform(const btTransform& xform) { - m_interpolationWorldTransform = m_worldTransform; + m_interpolationWorldTransform = xform;//m_worldTransform; m_interpolationLinearVelocity = getLinearVelocity(); m_interpolationAngularVelocity = getAngularVelocity(); m_worldTransform = xform; diff --git a/src/BulletDynamics/Vehicle/btRaycastVehicle.cpp b/src/BulletDynamics/Vehicle/btRaycastVehicle.cpp index 29bc2e9b0..347305335 100644 --- a/src/BulletDynamics/Vehicle/btRaycastVehicle.cpp +++ b/src/BulletDynamics/Vehicle/btRaycastVehicle.cpp @@ -18,6 +18,7 @@ #include "BulletDynamics/Dynamics/btDynamicsWorld.h" #include "btVehicleRaycaster.h" #include "btWheelInfo.h" +#include "LinearMath/btMinMax.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); void btRaycastVehicle::updateFriction(btScalar timeStep) { @@ -539,6 +597,26 @@ void btRaycastVehicle::updateFriction(btScalar timeStep) btWheelInfo& wheelInfo = m_wheelInfo[wheel]; 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.); m_wheelInfo[wheel].m_skidInfo= btScalar(1.); @@ -551,8 +629,9 @@ void btRaycastVehicle::updateFriction(btScalar timeStep) btScalar maximpSide = maximp; btScalar maximpSquared = maximp * maximpSide; + - forwardImpulse[wheel] = wheelInfo.m_engineForce* timeStep; + forwardImpulse[wheel] = rollingFriction;//wheelInfo.m_engineForce* timeStep; btScalar x = (forwardImpulse[wheel] ) * fwdFactor; btScalar y = (sideImpulse[wheel] ) * sideFactor;