void Hinge2Vehicle::resetForklift() { gVehicleSteering = 0.f; gBreakingForce = defaultBreakingForce; gEngineForce = 0.f; m_carChassis->setCenterOfMassTransform(btTransform::getIdentity()); m_carChassis->setLinearVelocity(btVector3(0,0,0)); m_carChassis->setAngularVelocity(btVector3(0,0,0)); m_dynamicsWorld->getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(m_carChassis->getBroadphaseHandle(),getDynamicsWorld()->getDispatcher()); #if 0 if (m_vehicle) { m_vehicle->resetSuspension(); for (int i=0;i<m_vehicle->getNumWheels();i++) { //synchronize the wheels with the (interpolated) chassis worldtransform m_vehicle->updateWheelTransform(i,true); } } #endif btTransform liftTrans; liftTrans.setIdentity(); liftTrans.setOrigin(m_liftStartPos); m_liftBody->activate(); m_liftBody->setCenterOfMassTransform(liftTrans); m_liftBody->setLinearVelocity(btVector3(0,0,0)); m_liftBody->setAngularVelocity(btVector3(0,0,0)); btTransform forkTrans; forkTrans.setIdentity(); forkTrans.setOrigin(m_forkStartPos); m_forkBody->activate(); m_forkBody->setCenterOfMassTransform(forkTrans); m_forkBody->setLinearVelocity(btVector3(0,0,0)); m_forkBody->setAngularVelocity(btVector3(0,0,0)); // m_liftHinge->setLimit(-LIFT_EPS, LIFT_EPS); m_liftHinge->setLimit(0.0f, 0.0f); m_liftHinge->enableAngularMotor(false, 0, 0); m_forkSlider->setLowerLinLimit(0.1f); m_forkSlider->setUpperLinLimit(0.1f); m_forkSlider->setPoweredLinMotor(false); btTransform loadTrans; loadTrans.setIdentity(); loadTrans.setOrigin(m_loadStartPos); m_loadBody->activate(); m_loadBody->setCenterOfMassTransform(loadTrans); m_loadBody->setLinearVelocity(btVector3(0,0,0)); m_loadBody->setAngularVelocity(btVector3(0,0,0)); }
void Hinge2Vehicle::lockForkSlider(void) { btScalar linDepth = m_forkSlider->getLinearPos(); btScalar lowLim = m_forkSlider->getLowerLinLimit(); btScalar hiLim = m_forkSlider->getUpperLinLimit(); m_forkSlider->setPoweredLinMotor(false); if(linDepth <= lowLim) { m_forkSlider->setLowerLinLimit(lowLim); m_forkSlider->setUpperLinLimit(lowLim); } else if(linDepth > hiLim) { m_forkSlider->setLowerLinLimit(hiLim); m_forkSlider->setUpperLinLimit(hiLim); } else { m_forkSlider->setLowerLinLimit(linDepth); m_forkSlider->setUpperLinLimit(linDepth); } return; } // Hinge2Vehicle::lockForkSlider()
void Hinge2Vehicle::specialKeyboard(int key, int x, int y) { #if 0 if (key==GLUT_KEY_END) return; // printf("key = %i x=%i y=%i\n",key,x,y); int state; state=glutGetModifiers(); if (state & GLUT_ACTIVE_SHIFT) { switch (key) { case GLUT_KEY_LEFT : { m_liftHinge->setLimit(-M_PI/16.0f, M_PI/8.0f); m_liftHinge->enableAngularMotor(true, -0.1, maxMotorImpulse); break; } case GLUT_KEY_RIGHT : { m_liftHinge->setLimit(-M_PI/16.0f, M_PI/8.0f); m_liftHinge->enableAngularMotor(true, 0.1, maxMotorImpulse); break; } case GLUT_KEY_UP : { m_forkSlider->setLowerLinLimit(0.1f); m_forkSlider->setUpperLinLimit(3.9f); m_forkSlider->setPoweredLinMotor(true); m_forkSlider->setMaxLinMotorForce(maxMotorImpulse); m_forkSlider->setTargetLinMotorVelocity(1.0); break; } case GLUT_KEY_DOWN : { m_forkSlider->setLowerLinLimit(0.1f); m_forkSlider->setUpperLinLimit(3.9f); m_forkSlider->setPoweredLinMotor(true); m_forkSlider->setMaxLinMotorForce(maxMotorImpulse); m_forkSlider->setTargetLinMotorVelocity(-1.0); break; } default: DemoApplication::specialKeyboard(key,x,y); break; } } else { switch (key) { case GLUT_KEY_LEFT : { gVehicleSteering += steeringIncrement; if ( gVehicleSteering > steeringClamp) gVehicleSteering = steeringClamp; break; } case GLUT_KEY_RIGHT : { gVehicleSteering -= steeringIncrement; if ( gVehicleSteering < -steeringClamp) gVehicleSteering = -steeringClamp; break; } case GLUT_KEY_UP : { gEngineForce = maxEngineForce; gBreakingForce = 0.f; break; } case GLUT_KEY_DOWN : { gEngineForce = -maxEngineForce; gBreakingForce = 0.f; break; } case GLUT_KEY_F7: { btDiscreteDynamicsWorld* world = (btDiscreteDynamicsWorld*)m_dynamicsWorld; world->setLatencyMotionStateInterpolation(!world->getLatencyMotionStateInterpolation()); printf("world latencyMotionStateInterpolation = %d\n", world->getLatencyMotionStateInterpolation()); break; } case GLUT_KEY_F6: { //switch solver (needs demo restart) useMCLPSolver = !useMCLPSolver; printf("switching to useMLCPSolver = %d\n", useMCLPSolver); delete m_solver; if (useMCLPSolver) { btDantzigSolver* mlcp = new btDantzigSolver(); //btSolveProjectedGaussSeidel* mlcp = new btSolveProjectedGaussSeidel; btMLCPSolver* sol = new btMLCPSolver(mlcp); m_solver = sol; } else { m_solver = new btSequentialImpulseConstraintSolver(); } m_dynamicsWorld->setConstraintSolver(m_solver); //exitPhysics(); //initPhysics(); break; } case GLUT_KEY_F5: m_useDefaultCamera = !m_useDefaultCamera; break; default: DemoApplication::specialKeyboard(key,x,y); break; } } // glutPostRedisplay(); #endif }
bool Hinge2Vehicle::keyboardCallback(int key, int state) { bool handled = false; bool isShiftPressed = m_guiHelper->getAppInterface()->m_window->isModifierKeyPressed(B3G_SHIFT); if (state) { if (isShiftPressed) { switch (key) { case B3G_LEFT_ARROW : { m_liftHinge->setLimit(-M_PI/16.0f, M_PI/8.0f); m_liftHinge->enableAngularMotor(true, -0.1, maxMotorImpulse); handled = true; break; } case B3G_RIGHT_ARROW : { m_liftHinge->setLimit(-M_PI/16.0f, M_PI/8.0f); m_liftHinge->enableAngularMotor(true, 0.1, maxMotorImpulse); handled = true; break; } case B3G_UP_ARROW : { m_forkSlider->setLowerLinLimit(0.1f); m_forkSlider->setUpperLinLimit(3.9f); m_forkSlider->setPoweredLinMotor(true); m_forkSlider->setMaxLinMotorForce(maxMotorImpulse); m_forkSlider->setTargetLinMotorVelocity(1.0); handled = true; break; } case B3G_DOWN_ARROW : { m_forkSlider->setLowerLinLimit(0.1f); m_forkSlider->setUpperLinLimit(3.9f); m_forkSlider->setPoweredLinMotor(true); m_forkSlider->setMaxLinMotorForce(maxMotorImpulse); m_forkSlider->setTargetLinMotorVelocity(-1.0); handled = true; break; } } } else { switch (key) { case B3G_LEFT_ARROW : { handled = true; gVehicleSteering += steeringIncrement; if ( gVehicleSteering > steeringClamp) gVehicleSteering = steeringClamp; break; } case B3G_RIGHT_ARROW : { handled = true; gVehicleSteering -= steeringIncrement; if ( gVehicleSteering < -steeringClamp) gVehicleSteering = -steeringClamp; break; } case B3G_UP_ARROW : { handled = true; gEngineForce = maxEngineForce; gBreakingForce = 0.f; break; } case B3G_DOWN_ARROW : { handled = true; gEngineForce = -maxEngineForce; gBreakingForce = 0.f; break; } case B3G_F7: { handled = true; btDiscreteDynamicsWorld* world = (btDiscreteDynamicsWorld*)m_dynamicsWorld; world->setLatencyMotionStateInterpolation(!world->getLatencyMotionStateInterpolation()); printf("world latencyMotionStateInterpolation = %d\n", world->getLatencyMotionStateInterpolation()); break; } case B3G_F6: { handled = true; //switch solver (needs demo restart) useMCLPSolver = !useMCLPSolver; printf("switching to useMLCPSolver = %d\n", useMCLPSolver); delete m_solver; if (useMCLPSolver) { btDantzigSolver* mlcp = new btDantzigSolver(); //btSolveProjectedGaussSeidel* mlcp = new btSolveProjectedGaussSeidel; btMLCPSolver* sol = new btMLCPSolver(mlcp); m_solver = sol; } else { m_solver = new btSequentialImpulseConstraintSolver(); } m_dynamicsWorld->setConstraintSolver(m_solver); //exitPhysics(); //initPhysics(); break; } case B3G_F5: handled = true; m_useDefaultCamera = !m_useDefaultCamera; break; default: break; } } } else { switch (key) { case B3G_UP_ARROW: { lockForkSlider(); gEngineForce = 0.f; gBreakingForce = defaultBreakingForce; handled=true; break; } case B3G_DOWN_ARROW: { lockForkSlider(); gEngineForce = 0.f; gBreakingForce = defaultBreakingForce; handled=true; break; } case B3G_LEFT_ARROW: case B3G_RIGHT_ARROW: { lockLiftHinge(); handled=true; break; } default: break; } } return handled; }
void Hinge2Vehicle::initPhysics() { m_guiHelper->setUpAxis(1); btCollisionShape* groundShape = new btBoxShape(btVector3(50,3,50)); m_collisionShapes.push_back(groundShape); m_collisionConfiguration = new btDefaultCollisionConfiguration(); m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); btVector3 worldMin(-1000,-1000,-1000); btVector3 worldMax(1000,1000,1000); m_broadphase = new btAxisSweep3(worldMin,worldMax); if (useMCLPSolver) { btDantzigSolver* mlcp = new btDantzigSolver(); //btSolveProjectedGaussSeidel* mlcp = new btSolveProjectedGaussSeidel; btMLCPSolver* sol = new btMLCPSolver(mlcp); m_solver = sol; } else { m_solver = new btSequentialImpulseConstraintSolver(); } m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); if (useMCLPSolver) { m_dynamicsWorld ->getSolverInfo().m_minimumSolverBatchSize = 1;//for direct solver it is better to have a small A matrix } else { m_dynamicsWorld ->getSolverInfo().m_minimumSolverBatchSize = 128;//for direct solver, it is better to solve multiple objects together, small batches have high overhead } m_dynamicsWorld->getSolverInfo().m_numIterations = 100; m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); //m_dynamicsWorld->setGravity(btVector3(0,0,0)); btTransform tr; tr.setIdentity(); tr.setOrigin(btVector3(0,-3,0)); //either use heightfield or triangle mesh //create ground object localCreateRigidBody(0,tr,groundShape); btCollisionShape* chassisShape = new btBoxShape(btVector3(1.f,0.5f,2.f)); m_collisionShapes.push_back(chassisShape); btCompoundShape* compound = new btCompoundShape(); m_collisionShapes.push_back(compound); btTransform localTrans; localTrans.setIdentity(); //localTrans effectively shifts the center of mass with respect to the chassis localTrans.setOrigin(btVector3(0,1,0)); compound->addChildShape(localTrans,chassisShape); { btCollisionShape* suppShape = new btBoxShape(btVector3(0.5f,0.1f,0.5f)); btTransform suppLocalTrans; suppLocalTrans.setIdentity(); //localTrans effectively shifts the center of mass with respect to the chassis suppLocalTrans.setOrigin(btVector3(0,1.0,2.5)); compound->addChildShape(suppLocalTrans, suppShape); } tr.setOrigin(btVector3(0,0.f,0)); btScalar chassisMass = 800; m_carChassis = localCreateRigidBody(chassisMass,tr,compound);//chassisShape); //m_carChassis->setDamping(0.2,0.2); //m_wheelShape = new btCylinderShapeX(btVector3(wheelWidth,wheelRadius,wheelRadius)); m_wheelShape = new btCylinderShapeX(btVector3(wheelWidth,wheelRadius,wheelRadius)); //const float position[4]={0,10,10,0}; //const float quaternion[4]={0,0,0,1}; //const float color[4]={0,1,0,1}; //const float scaling[4] = {1,1,1,1}; btVector3 wheelPos[4] = { btVector3(btScalar(-1.), btScalar(-0.25), btScalar(1.25)), btVector3(btScalar(1.), btScalar(-0.25), btScalar(1.25)), btVector3(btScalar(1.), btScalar(-0.25), btScalar(-1.25)), btVector3(btScalar(-1.), btScalar(-0.25), btScalar(-1.25)) }; for (int i=0;i<4;i++) { // create a Hinge2 joint // create two rigid bodies // static bodyA (parent) on top: btRigidBody* pBodyA = this->m_carChassis;//m_chassis;//createRigidBody( 0.0, tr, m_wheelShape); pBodyA->setActivationState(DISABLE_DEACTIVATION); // dynamic bodyB (child) below it : btTransform tr; tr.setIdentity(); tr.setOrigin(wheelPos[i]); btRigidBody* pBodyB = createRigidBody(10.0, tr, m_wheelShape); pBodyB->setFriction(1110); pBodyB->setActivationState(DISABLE_DEACTIVATION); // add some data to build constraint frames btVector3 parentAxis(0.f, 1.f, 0.f); btVector3 childAxis(1.f, 0.f, 0.f); btVector3 anchor = tr.getOrigin();//(0.f, 0.f, 0.f); btHinge2Constraint* pHinge2 = new btHinge2Constraint(*pBodyA, *pBodyB, anchor, parentAxis, childAxis); //m_guiHelper->get2dCanvasInterface(); pHinge2->setLowerLimit(-SIMD_HALF_PI * 0.5f); pHinge2->setUpperLimit( SIMD_HALF_PI * 0.5f); // add constraint to world m_dynamicsWorld->addConstraint(pHinge2, true); // draw constraint frames and limits for debugging { int motorAxis = 3; pHinge2->enableMotor(motorAxis,true); pHinge2->setMaxMotorForce(motorAxis,1000); pHinge2->setTargetVelocity(motorAxis,-1); } { int motorAxis = 5; pHinge2->enableMotor(motorAxis,true); pHinge2->setMaxMotorForce(motorAxis,1000); pHinge2->setTargetVelocity(motorAxis,0); } pHinge2->setDbgDrawSize(btScalar(5.f)); } { btCollisionShape* liftShape = new btBoxShape(btVector3(0.5f,2.0f,0.05f)); m_collisionShapes.push_back(liftShape); btTransform liftTrans; m_liftStartPos = btVector3(0.0f, 2.5f, 3.05f); liftTrans.setIdentity(); liftTrans.setOrigin(m_liftStartPos); m_liftBody = localCreateRigidBody(10,liftTrans, liftShape); btTransform localA, localB; localA.setIdentity(); localB.setIdentity(); localA.getBasis().setEulerZYX(0, M_PI_2, 0); localA.setOrigin(btVector3(0.0, 1.0, 3.05)); localB.getBasis().setEulerZYX(0, M_PI_2, 0); localB.setOrigin(btVector3(0.0, -1.5, -0.05)); m_liftHinge = new btHingeConstraint(*m_carChassis,*m_liftBody, localA, localB); // m_liftHinge->setLimit(-LIFT_EPS, LIFT_EPS); m_liftHinge->setLimit(0.0f, 0.0f); m_dynamicsWorld->addConstraint(m_liftHinge, true); btCollisionShape* forkShapeA = new btBoxShape(btVector3(1.0f,0.1f,0.1f)); m_collisionShapes.push_back(forkShapeA); btCompoundShape* forkCompound = new btCompoundShape(); m_collisionShapes.push_back(forkCompound); btTransform forkLocalTrans; forkLocalTrans.setIdentity(); forkCompound->addChildShape(forkLocalTrans, forkShapeA); btCollisionShape* forkShapeB = new btBoxShape(btVector3(0.1f,0.02f,0.6f)); m_collisionShapes.push_back(forkShapeB); forkLocalTrans.setIdentity(); forkLocalTrans.setOrigin(btVector3(-0.9f, -0.08f, 0.7f)); forkCompound->addChildShape(forkLocalTrans, forkShapeB); btCollisionShape* forkShapeC = new btBoxShape(btVector3(0.1f,0.02f,0.6f)); m_collisionShapes.push_back(forkShapeC); forkLocalTrans.setIdentity(); forkLocalTrans.setOrigin(btVector3(0.9f, -0.08f, 0.7f)); forkCompound->addChildShape(forkLocalTrans, forkShapeC); btTransform forkTrans; m_forkStartPos = btVector3(0.0f, 0.6f, 3.2f); forkTrans.setIdentity(); forkTrans.setOrigin(m_forkStartPos); m_forkBody = localCreateRigidBody(5, forkTrans, forkCompound); localA.setIdentity(); localB.setIdentity(); localA.getBasis().setEulerZYX(0, 0, M_PI_2); localA.setOrigin(btVector3(0.0f, -1.9f, 0.05f)); localB.getBasis().setEulerZYX(0, 0, M_PI_2); localB.setOrigin(btVector3(0.0, 0.0, -0.1)); m_forkSlider = new btSliderConstraint(*m_liftBody, *m_forkBody, localA, localB, true); m_forkSlider->setLowerLinLimit(0.1f); m_forkSlider->setUpperLinLimit(0.1f); // m_forkSlider->setLowerAngLimit(-LIFT_EPS); // m_forkSlider->setUpperAngLimit(LIFT_EPS); m_forkSlider->setLowerAngLimit(0.0f); m_forkSlider->setUpperAngLimit(0.0f); m_dynamicsWorld->addConstraint(m_forkSlider, true); btCompoundShape* loadCompound = new btCompoundShape(); m_collisionShapes.push_back(loadCompound); btCollisionShape* loadShapeA = new btBoxShape(btVector3(2.0f,0.5f,0.5f)); m_collisionShapes.push_back(loadShapeA); btTransform loadTrans; loadTrans.setIdentity(); loadCompound->addChildShape(loadTrans, loadShapeA); btCollisionShape* loadShapeB = new btBoxShape(btVector3(0.1f,1.0f,1.0f)); m_collisionShapes.push_back(loadShapeB); loadTrans.setIdentity(); loadTrans.setOrigin(btVector3(2.1f, 0.0f, 0.0f)); loadCompound->addChildShape(loadTrans, loadShapeB); btCollisionShape* loadShapeC = new btBoxShape(btVector3(0.1f,1.0f,1.0f)); m_collisionShapes.push_back(loadShapeC); loadTrans.setIdentity(); loadTrans.setOrigin(btVector3(-2.1f, 0.0f, 0.0f)); loadCompound->addChildShape(loadTrans, loadShapeC); loadTrans.setIdentity(); m_loadStartPos = btVector3(0.0f, 3.5f, 7.0f); loadTrans.setOrigin(m_loadStartPos); m_loadBody = localCreateRigidBody(loadMass, loadTrans, loadCompound); } resetForklift(); // setCameraDistance(26.f); m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld); }
void ForkLiftDemo::initPhysics() { int upAxis = 1; m_guiHelper->setUpAxis(upAxis); btVector3 groundExtents(50,50,50); groundExtents[upAxis]=3; btCollisionShape* groundShape = new btBoxShape(groundExtents); m_collisionShapes.push_back(groundShape); m_collisionConfiguration = new btDefaultCollisionConfiguration(); m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); btVector3 worldMin(-1000,-1000,-1000); btVector3 worldMax(1000,1000,1000); m_overlappingPairCache = new btAxisSweep3(worldMin,worldMax); if (useMCLPSolver) { btDantzigSolver* mlcp = new btDantzigSolver(); //btSolveProjectedGaussSeidel* mlcp = new btSolveProjectedGaussSeidel; btMLCPSolver* sol = new btMLCPSolver(mlcp); m_constraintSolver = sol; } else { m_constraintSolver = new btSequentialImpulseConstraintSolver(); } m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_overlappingPairCache,m_constraintSolver,m_collisionConfiguration); if (useMCLPSolver) { m_dynamicsWorld ->getSolverInfo().m_minimumSolverBatchSize = 1;//for direct solver it is better to have a small A matrix } else { m_dynamicsWorld ->getSolverInfo().m_minimumSolverBatchSize = 128;//for direct solver, it is better to solve multiple objects together, small batches have high overhead } m_dynamicsWorld->getSolverInfo().m_globalCfm = 0.00001; m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); //m_dynamicsWorld->setGravity(btVector3(0,0,0)); btTransform tr; tr.setIdentity(); tr.setOrigin(btVector3(0,-3,0)); //either use heightfield or triangle mesh //create ground object localCreateRigidBody(0,tr,groundShape); btCollisionShape* chassisShape = new btBoxShape(btVector3(1.f,0.5f,2.f)); m_collisionShapes.push_back(chassisShape); btCompoundShape* compound = new btCompoundShape(); m_collisionShapes.push_back(compound); btTransform localTrans; localTrans.setIdentity(); //localTrans effectively shifts the center of mass with respect to the chassis localTrans.setOrigin(btVector3(0,1,0)); compound->addChildShape(localTrans,chassisShape); { btCollisionShape* suppShape = new btBoxShape(btVector3(0.5f,0.1f,0.5f)); btTransform suppLocalTrans; suppLocalTrans.setIdentity(); //localTrans effectively shifts the center of mass with respect to the chassis suppLocalTrans.setOrigin(btVector3(0,1.0,2.5)); compound->addChildShape(suppLocalTrans, suppShape); } tr.setOrigin(btVector3(0,0.f,0)); m_carChassis = localCreateRigidBody(800,tr,compound);//chassisShape); //m_carChassis->setDamping(0.2,0.2); m_wheelShape = new btCylinderShapeX(btVector3(wheelWidth,wheelRadius,wheelRadius)); m_guiHelper->createCollisionShapeGraphicsObject(m_wheelShape); int wheelGraphicsIndex = m_wheelShape->getUserIndex(); const float position[4]={0,10,10,0}; const float quaternion[4]={0,0,0,1}; const float color[4]={0,1,0,1}; const float scaling[4] = {1,1,1,1}; for (int i=0;i<4;i++) { m_wheelInstances[i] = m_guiHelper->registerGraphicsInstance(wheelGraphicsIndex, position, quaternion, color, scaling); } { btCollisionShape* liftShape = new btBoxShape(btVector3(0.5f,2.0f,0.05f)); m_collisionShapes.push_back(liftShape); btTransform liftTrans; m_liftStartPos = btVector3(0.0f, 2.5f, 3.05f); liftTrans.setIdentity(); liftTrans.setOrigin(m_liftStartPos); m_liftBody = localCreateRigidBody(10,liftTrans, liftShape); btTransform localA, localB; localA.setIdentity(); localB.setIdentity(); localA.getBasis().setEulerZYX(0, M_PI_2, 0); localA.setOrigin(btVector3(0.0, 1.0, 3.05)); localB.getBasis().setEulerZYX(0, M_PI_2, 0); localB.setOrigin(btVector3(0.0, -1.5, -0.05)); m_liftHinge = new btHingeConstraint(*m_carChassis,*m_liftBody, localA, localB); // m_liftHinge->setLimit(-LIFT_EPS, LIFT_EPS); m_liftHinge->setLimit(0.0f, 0.0f); m_dynamicsWorld->addConstraint(m_liftHinge, true); btCollisionShape* forkShapeA = new btBoxShape(btVector3(1.0f,0.1f,0.1f)); m_collisionShapes.push_back(forkShapeA); btCompoundShape* forkCompound = new btCompoundShape(); m_collisionShapes.push_back(forkCompound); btTransform forkLocalTrans; forkLocalTrans.setIdentity(); forkCompound->addChildShape(forkLocalTrans, forkShapeA); btCollisionShape* forkShapeB = new btBoxShape(btVector3(0.1f,0.02f,0.6f)); m_collisionShapes.push_back(forkShapeB); forkLocalTrans.setIdentity(); forkLocalTrans.setOrigin(btVector3(-0.9f, -0.08f, 0.7f)); forkCompound->addChildShape(forkLocalTrans, forkShapeB); btCollisionShape* forkShapeC = new btBoxShape(btVector3(0.1f,0.02f,0.6f)); m_collisionShapes.push_back(forkShapeC); forkLocalTrans.setIdentity(); forkLocalTrans.setOrigin(btVector3(0.9f, -0.08f, 0.7f)); forkCompound->addChildShape(forkLocalTrans, forkShapeC); btTransform forkTrans; m_forkStartPos = btVector3(0.0f, 0.6f, 3.2f); forkTrans.setIdentity(); forkTrans.setOrigin(m_forkStartPos); m_forkBody = localCreateRigidBody(5, forkTrans, forkCompound); localA.setIdentity(); localB.setIdentity(); localA.getBasis().setEulerZYX(0, 0, M_PI_2); localA.setOrigin(btVector3(0.0f, -1.9f, 0.05f)); localB.getBasis().setEulerZYX(0, 0, M_PI_2); localB.setOrigin(btVector3(0.0, 0.0, -0.1)); m_forkSlider = new btSliderConstraint(*m_liftBody, *m_forkBody, localA, localB, true); m_forkSlider->setLowerLinLimit(0.1f); m_forkSlider->setUpperLinLimit(0.1f); // m_forkSlider->setLowerAngLimit(-LIFT_EPS); // m_forkSlider->setUpperAngLimit(LIFT_EPS); m_forkSlider->setLowerAngLimit(0.0f); m_forkSlider->setUpperAngLimit(0.0f); m_dynamicsWorld->addConstraint(m_forkSlider, true); btCompoundShape* loadCompound = new btCompoundShape(); m_collisionShapes.push_back(loadCompound); btCollisionShape* loadShapeA = new btBoxShape(btVector3(2.0f,0.5f,0.5f)); m_collisionShapes.push_back(loadShapeA); btTransform loadTrans; loadTrans.setIdentity(); loadCompound->addChildShape(loadTrans, loadShapeA); btCollisionShape* loadShapeB = new btBoxShape(btVector3(0.1f,1.0f,1.0f)); m_collisionShapes.push_back(loadShapeB); loadTrans.setIdentity(); loadTrans.setOrigin(btVector3(2.1f, 0.0f, 0.0f)); loadCompound->addChildShape(loadTrans, loadShapeB); btCollisionShape* loadShapeC = new btBoxShape(btVector3(0.1f,1.0f,1.0f)); m_collisionShapes.push_back(loadShapeC); loadTrans.setIdentity(); loadTrans.setOrigin(btVector3(-2.1f, 0.0f, 0.0f)); loadCompound->addChildShape(loadTrans, loadShapeC); loadTrans.setIdentity(); m_loadStartPos = btVector3(0.0f, 3.5f, 7.0f); loadTrans.setOrigin(m_loadStartPos); m_loadBody = localCreateRigidBody(loadMass, loadTrans, loadCompound); } /// create vehicle { m_vehicleRayCaster = new btDefaultVehicleRaycaster(m_dynamicsWorld); m_vehicle = new btRaycastVehicle(m_tuning,m_carChassis,m_vehicleRayCaster); ///never deactivate the vehicle m_carChassis->setActivationState(DISABLE_DEACTIVATION); m_dynamicsWorld->addVehicle(m_vehicle); float connectionHeight = 1.2f; bool isFrontWheel=true; //choose coordinate system m_vehicle->setCoordinateSystem(rightIndex,upIndex,forwardIndex); btVector3 connectionPointCS0(CUBE_HALF_EXTENTS-(0.3*wheelWidth),connectionHeight,2*CUBE_HALF_EXTENTS-wheelRadius); m_vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,wheelAxleCS,suspensionRestLength,wheelRadius,m_tuning,isFrontWheel); connectionPointCS0 = btVector3(-CUBE_HALF_EXTENTS+(0.3*wheelWidth),connectionHeight,2*CUBE_HALF_EXTENTS-wheelRadius); m_vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,wheelAxleCS,suspensionRestLength,wheelRadius,m_tuning,isFrontWheel); connectionPointCS0 = btVector3(-CUBE_HALF_EXTENTS+(0.3*wheelWidth),connectionHeight,-2*CUBE_HALF_EXTENTS+wheelRadius); isFrontWheel = false; m_vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,wheelAxleCS,suspensionRestLength,wheelRadius,m_tuning,isFrontWheel); connectionPointCS0 = btVector3(CUBE_HALF_EXTENTS-(0.3*wheelWidth),connectionHeight,-2*CUBE_HALF_EXTENTS+wheelRadius); m_vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,wheelAxleCS,suspensionRestLength,wheelRadius,m_tuning,isFrontWheel); for (int i=0;i<m_vehicle->getNumWheels();i++) { btWheelInfo& wheel = m_vehicle->getWheelInfo(i); wheel.m_suspensionStiffness = suspensionStiffness; wheel.m_wheelsDampingRelaxation = suspensionDamping; wheel.m_wheelsDampingCompression = suspensionCompression; wheel.m_frictionSlip = wheelFriction; wheel.m_rollInfluence = rollInfluence; } } resetForklift(); // setCameraDistance(26.f); m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld); }