void RaycastVehicle::AddWheel(Node* wheelNode, Vector3 wheelDirection, Vector3 wheelAxle, float restLength, float wheelRadius, bool frontWheel) { btRaycastVehicle* vehicle = vehicleData_->Get(); int id = GetNumWheels(); Vector3 connectionPoint = wheelNode->GetWorldPosition() - node_->GetWorldPosition(); btVector3 connectionPointCS0(connectionPoint.x_, connectionPoint.y_, connectionPoint.z_); btVector3 wheelDirectionCS0(wheelDirection.x_, wheelDirection.y_, wheelDirection.z_); btVector3 wheelAxleCS(wheelAxle.x_, wheelAxle.y_, wheelAxle.z_); btWheelInfo& wheel = vehicle->addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, restLength, wheelRadius, vehicleData_->tuning_, frontWheel); wheelNodes_.Push(wheelNode); origRotation_.Push(wheelNode->GetWorldRotation()); skidInfoCumulative_.Push(1.0f); wheelSideSlipSpeed_.Push(0.0f); wheel.m_raycastInfo.m_isInContact = false; }
void VehicleObject::init_wheels() { m_vWheelDirCS0 = btVector3(0, -1, 0); m_vWheelAxelCS = btVector3(0, 0, -1); //Wheel connection float fWheelHeight = m_vehicle_properties.m_fWheelHeight; float fWheelRadius = m_vehicle_properties.m_fWheelRadius; float fSuspRestLength = m_vehicle_properties.m_fSuspRestLength; float fWheelWidth = m_vehicle_properties.m_fWheelWidth; float halfExtx = m_vehicle_properties.m_fWheelPosOffset_x; float halfExty = m_vehicle_properties.m_fWheelPosOffset_y; float halfExtz = m_vehicle_properties.m_fWheelPosOffset_z; bool m_bIsFrontWheel = true; btVector3 connectionPointCS0(m_box_size.x()*halfExtx-fWheelRadius, fWheelHeight, halfExtz-(0.3f*fWheelWidth)); //Add front wheels m_pvehicle->addWheel(connectionPointCS0, m_vWheelDirCS0, m_vWheelAxelCS, fSuspRestLength, fWheelRadius, m_vehicle_tuning, m_bIsFrontWheel); connectionPointCS0 = btVector3(m_box_size.x()*halfExtx-fWheelRadius, fWheelHeight,-halfExtz+(0.3f*fWheelWidth) ); m_pvehicle->addWheel(connectionPointCS0, m_vWheelDirCS0, m_vWheelAxelCS, fSuspRestLength, fWheelRadius, m_vehicle_tuning, m_bIsFrontWheel); //Add rear wheels m_bIsFrontWheel = false; connectionPointCS0 = btVector3(-m_box_size.x()*halfExtx+fWheelRadius, fWheelHeight,-halfExtz+(0.3f*fWheelWidth) ); m_pvehicle->addWheel(connectionPointCS0, m_vWheelDirCS0, m_vWheelAxelCS, fSuspRestLength, fWheelRadius, m_vehicle_tuning, m_bIsFrontWheel); connectionPointCS0 = btVector3(-m_box_size.x()*halfExtx+fWheelRadius, fWheelHeight,halfExtz-(0.3f*fWheelWidth) ); m_pvehicle->addWheel(connectionPointCS0, m_vWheelDirCS0, m_vWheelAxelCS, fSuspRestLength, fWheelRadius, m_vehicle_tuning, m_bIsFrontWheel); // for(int i =0; i < m_pvehicle->getNumWheels(); i++) { btWheelInfo& wheel = m_pvehicle->getWheelInfo(i); wheel.m_suspensionStiffness = m_vehicle_properties.m_fSuspStiffness; wheel.m_wheelsDampingRelaxation = m_vehicle_properties.m_fSuspDamping; wheel.m_wheelsDampingCompression = m_vehicle_properties.m_fSuspCompression; wheel.m_frictionSlip = m_vehicle_properties.m_fWheelFriction; wheel.m_rollInfluence = m_vehicle_properties.m_fRollInfluence; } }
virtual void AddWheel( PHY_IMotionState* motionState, PHY__Vector3 connectionPoint, PHY__Vector3 downDirection, PHY__Vector3 axleDirection, float suspensionRestLength, float wheelRadius, bool hasSteering ) { SimdVector3 connectionPointCS0(connectionPoint[0],connectionPoint[1],connectionPoint[2]); SimdVector3 wheelDirectionCS0(downDirection[0],downDirection[1],downDirection[2]); SimdVector3 wheelAxle(axleDirection[0],axleDirection[1],axleDirection[2]); WheelInfo& info = m_vehicle->AddWheel(connectionPointCS0,wheelDirectionCS0,wheelAxle, suspensionRestLength,wheelRadius,gTuning,hasSteering); info.m_clientInfo = motionState; }
void ForkLiftDemo::initPhysics() { #ifdef FORCE_ZAXIS_UP m_cameraUp = btVector3(0,0,1); m_forwardAxis = 1; #endif 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_overlappingPairCache = new btAxisSweep3(worldMin,worldMax); m_constraintSolver = new btSequentialImpulseConstraintSolver(); m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_overlappingPairCache,m_constraintSolver,m_collisionConfiguration); #ifdef FORCE_ZAXIS_UP m_dynamicsWorld->setGravity(btVector3(0,0,-10)); #endif //m_dynamicsWorld->setGravity(btVector3(0,0,0)); btTransform tr; tr.setIdentity(); tr.setOrigin(btVector3(0,-10,0)); //either use heightfield or triangle mesh //create ground object localCreateRigidBody(0,tr,groundShape); #ifdef FORCE_ZAXIS_UP // indexRightAxis = 0; // indexUpAxis = 2; // indexForwardAxis = 1; btCollisionShape* chassisShape = new btBoxShape(btVector3(1.f,2.f, 0.5f)); btCompoundShape* compound = new btCompoundShape(); btTransform localTrans; localTrans.setIdentity(); //localTrans effectively shifts the center of mass with respect to the chassis localTrans.setOrigin(btVector3(0,0,1)); #else 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)); #endif 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)); { 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(4, loadTrans, loadCompound); } clientResetScene(); /// 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); #ifdef FORCE_ZAXIS_UP btVector3 connectionPointCS0(CUBE_HALF_EXTENTS-(0.3*wheelWidth),2*CUBE_HALF_EXTENTS-wheelRadius, connectionHeight); #else btVector3 connectionPointCS0(CUBE_HALF_EXTENTS-(0.3*wheelWidth),connectionHeight,2*CUBE_HALF_EXTENTS-wheelRadius); #endif m_vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,wheelAxleCS,suspensionRestLength,wheelRadius,m_tuning,isFrontWheel); #ifdef FORCE_ZAXIS_UP connectionPointCS0 = btVector3(-CUBE_HALF_EXTENTS+(0.3*wheelWidth),2*CUBE_HALF_EXTENTS-wheelRadius, connectionHeight); #else connectionPointCS0 = btVector3(-CUBE_HALF_EXTENTS+(0.3*wheelWidth),connectionHeight,2*CUBE_HALF_EXTENTS-wheelRadius); #endif m_vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,wheelAxleCS,suspensionRestLength,wheelRadius,m_tuning,isFrontWheel); #ifdef FORCE_ZAXIS_UP connectionPointCS0 = btVector3(-CUBE_HALF_EXTENTS+(0.3*wheelWidth),-2*CUBE_HALF_EXTENTS+wheelRadius, connectionHeight); #else connectionPointCS0 = btVector3(-CUBE_HALF_EXTENTS+(0.3*wheelWidth),connectionHeight,-2*CUBE_HALF_EXTENTS+wheelRadius); #endif //FORCE_ZAXIS_UP isFrontWheel = false; m_vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,wheelAxleCS,suspensionRestLength,wheelRadius,m_tuning,isFrontWheel); #ifdef FORCE_ZAXIS_UP connectionPointCS0 = btVector3(CUBE_HALF_EXTENTS-(0.3*wheelWidth),-2*CUBE_HALF_EXTENTS+wheelRadius, connectionHeight); #else connectionPointCS0 = btVector3(CUBE_HALF_EXTENTS-(0.3*wheelWidth),connectionHeight,-2*CUBE_HALF_EXTENTS+wheelRadius); #endif 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; } } setCameraDistance(26.f); }
void RaycastVehicle::ApplyAttributes() { int index = 0; hullBody_ = node_->GetOrCreateComponent<RigidBody>(); Scene* scene = GetScene(); vehicleData_->Init(scene, hullBody_); VariantVector& value = loadedWheelData_; int numObjects = value[index++].GetInt(); int wheelIndex = 0; origRotation_.Clear(); skidInfoCumulative_.Clear(); wheelSideSlipSpeed_.Clear(); for (int i = 0; i < numObjects; i++) { int node_id = value[index++].GetInt(); Vector3 direction = value[index++].GetVector3(); Vector3 axle = value[index++].GetVector3(); float restLength = value[index++].GetFloat(); float radius = value[index++].GetFloat(); bool isFrontWheel = value[index++].GetBool(); float steering = value[index++].GetFloat(); Vector3 connectionPoint = value[index++].GetVector3(); Quaternion origRotation = value[index++].GetQuaternion(); float skidInfoC = value[index++].GetFloat(); float sideSlipSpeed = value[index++].GetFloat(); bool isContact = value[index++].GetBool(); Vector3 contactPosition = value[index++].GetVector3(); Vector3 contactNormal = value[index++].GetVector3(); float suspensionStiffness = value[index++].GetFloat(); float dampingRelaxation = value[index++].GetFloat(); float dampingCompression = value[index++].GetFloat(); float frictionSlip = value[index++].GetFloat(); float rollInfluence = value[index++].GetFloat(); float engineForce = value[index++].GetFloat(); float brake = value[index++].GetFloat(); float skidInfo = value[index++].GetFloat(); Node* wheelNode = GetScene()->GetNode(node_id); if (!wheelNode) { URHO3D_LOGERROR("RaycastVehicle: Incorrect node id = " + String(node_id) + " index: " + String(index)); continue; } btRaycastVehicle* vehicle = vehicleData_->Get(); int id = GetNumWheels(); btVector3 connectionPointCS0(connectionPoint.x_, connectionPoint.y_, connectionPoint.z_); btVector3 wheelDirectionCS0(direction.x_, direction.y_, direction.z_); btVector3 wheelAxleCS(axle.x_, axle.y_, axle.z_); btWheelInfo& wheel = vehicle->addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, restLength, radius, vehicleData_->tuning_, isFrontWheel); wheelNodes_.Push(wheelNode); origRotation_.Push(origRotation); skidInfoCumulative_.Push(skidInfoC); wheelSideSlipSpeed_.Push(sideSlipSpeed); SetSteeringValue(wheelIndex, steering); wheel.m_raycastInfo.m_isInContact = isContact; wheel.m_raycastInfo.m_contactNormalWS = btVector3(contactNormal.x_, contactNormal.y_, contactNormal.z_); wheel.m_raycastInfo.m_contactPointWS = btVector3(contactPosition.x_, contactPosition.y_, contactPosition.z_); wheel.m_suspensionStiffness = suspensionStiffness; wheel.m_wheelsDampingRelaxation = dampingRelaxation; wheel.m_wheelsDampingCompression = dampingCompression; wheel.m_frictionSlip = frictionSlip; wheel.m_rollInfluence = rollInfluence; wheel.m_engineForce = engineForce; wheel.m_brake = brake; wheel.m_skidInfo = skidInfo; wheelIndex++; } URHO3D_LOGDEBUG("maxSideSlipSpeed_ value: " + String(maxSideSlipSpeed_)); URHO3D_LOGDEBUG("loaded items: " + String(index)); URHO3D_LOGDEBUG("loaded wheels: " + String(GetNumWheels())); }
void VehicleDemo::initPhysics() { #ifdef FORCE_ZAXIS_UP m_cameraUp = btVector3(0,0,1); m_forwardAxis = 1; #endif 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_overlappingPairCache = new btAxisSweep3(worldMin,worldMax); m_constraintSolver = new btSequentialImpulseConstraintSolver(); m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_overlappingPairCache,m_constraintSolver,m_collisionConfiguration); #ifdef FORCE_ZAXIS_UP m_dynamicsWorld->setGravity(btVector3(0,0,-10)); #endif //m_dynamicsWorld->setGravity(btVector3(0,0,0)); btTransform tr; tr.setIdentity(); //either use heightfield or triangle mesh //#define USE_TRIMESH_GROUND 1 #ifdef USE_TRIMESH_GROUND int i; const float TRIANGLE_SIZE=20.f; //create a triangle-mesh ground int vertStride = sizeof(btVector3); int indexStride = 3*sizeof(int); const int NUM_VERTS_X = 20; const int NUM_VERTS_Y = 20; const int totalVerts = NUM_VERTS_X*NUM_VERTS_Y; const int totalTriangles = 2*(NUM_VERTS_X-1)*(NUM_VERTS_Y-1); m_vertices = new btVector3[totalVerts]; int* gIndices = new int[totalTriangles*3]; for ( i=0;i<NUM_VERTS_X;i++) { for (int j=0;j<NUM_VERTS_Y;j++) { float wl = .2f; //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 m_vertices[i+j*NUM_VERTS_X].setValue( (i-NUM_VERTS_X*0.5f)*TRIANGLE_SIZE, (j-NUM_VERTS_Y*0.5f)*TRIANGLE_SIZE, height ); #else m_vertices[i+j*NUM_VERTS_X].setValue( (i-NUM_VERTS_X*0.5f)*TRIANGLE_SIZE, height, (j-NUM_VERTS_Y*0.5f)*TRIANGLE_SIZE); #endif } } int index=0; for ( i=0;i<NUM_VERTS_X-1;i++) { for (int j=0;j<NUM_VERTS_Y-1;j++) { gIndices[index++] = j*NUM_VERTS_X+i; gIndices[index++] = j*NUM_VERTS_X+i+1; gIndices[index++] = (j+1)*NUM_VERTS_X+i+1; gIndices[index++] = j*NUM_VERTS_X+i; gIndices[index++] = (j+1)*NUM_VERTS_X+i+1; gIndices[index++] = (j+1)*NUM_VERTS_X+i; } } m_indexVertexArrays = new btTriangleIndexVertexArray(totalTriangles, gIndices, indexStride, totalVerts,(btScalar*) &m_vertices[0].x(),vertStride); bool useQuantizedAabbCompression = true; groundShape = new btBvhTriangleMeshShape(m_indexVertexArrays,useQuantizedAabbCompression); tr.setOrigin(btVector3(0,-4.5f,0)); #else //testing btHeightfieldTerrainShape int width=128; int length=128; #ifdef LOAD_FROM_FILE unsigned char* heightfieldData = new unsigned char[width*length]; { for (int i=0;i<width*length;i++) { heightfieldData[i]=0; } } char* filename="heightfield128x128.raw"; FILE* heightfieldFile = fopen(filename,"r"); if (!heightfieldFile) { filename="../../heightfield128x128.raw"; heightfieldFile = fopen(filename,"r"); } if (heightfieldFile) { int numBytes =fread(heightfieldData,1,width*length,heightfieldFile); //btAssert(numBytes); if (!numBytes) { printf("couldn't read heightfield at %s\n",filename); } fclose (heightfieldFile); } #else char* heightfieldData = MyHeightfield; #endif //btScalar maxHeight = 20000.f;//exposes a bug btScalar maxHeight = 100; bool useFloatDatam=false; bool flipQuadEdges=false; btHeightfieldTerrainShape* heightFieldShape = new btHeightfieldTerrainShape(width,length,heightfieldData,maxHeight,upIndex,useFloatDatam,flipQuadEdges);; btVector3 mmin,mmax; heightFieldShape->getAabb(btTransform::getIdentity(),mmin,mmax); groundShape = heightFieldShape; heightFieldShape->setUseDiamondSubdivision(true); btVector3 localScaling(100,1,100); localScaling[upIndex]=1.f; groundShape->setLocalScaling(localScaling); //tr.setOrigin(btVector3(0,9940,0)); tr.setOrigin(btVector3(0,49.4,0)); #endif // m_collisionShapes.push_back(groundShape); //create ground object localCreateRigidBody(0,tr,groundShape); tr.setOrigin(btVector3(0,0,0));//-64.5f,0)); #ifdef FORCE_ZAXIS_UP // indexRightAxis = 0; // indexUpAxis = 2; // indexForwardAxis = 1; btCollisionShape* chassisShape = new btBoxShape(btVector3(1.f,2.f, 0.5f)); btCompoundShape* compound = new btCompoundShape(); btTransform localTrans; localTrans.setIdentity(); //localTrans effectively shifts the center of mass with respect to the chassis localTrans.setOrigin(btVector3(0,0,1)); #else 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)); #endif compound->addChildShape(localTrans,chassisShape); 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)); clientResetScene(); /// 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); #ifdef FORCE_ZAXIS_UP btVector3 connectionPointCS0(CUBE_HALF_EXTENTS-(0.3*wheelWidth),2*CUBE_HALF_EXTENTS-wheelRadius, connectionHeight); #else btVector3 connectionPointCS0(CUBE_HALF_EXTENTS-(0.3*wheelWidth),connectionHeight,2*CUBE_HALF_EXTENTS-wheelRadius); #endif m_vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,wheelAxleCS,suspensionRestLength,wheelRadius,m_tuning,isFrontWheel); #ifdef FORCE_ZAXIS_UP connectionPointCS0 = btVector3(-CUBE_HALF_EXTENTS+(0.3*wheelWidth),2*CUBE_HALF_EXTENTS-wheelRadius, connectionHeight); #else connectionPointCS0 = btVector3(-CUBE_HALF_EXTENTS+(0.3*wheelWidth),connectionHeight,2*CUBE_HALF_EXTENTS-wheelRadius); #endif m_vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,wheelAxleCS,suspensionRestLength,wheelRadius,m_tuning,isFrontWheel); #ifdef FORCE_ZAXIS_UP connectionPointCS0 = btVector3(-CUBE_HALF_EXTENTS+(0.3*wheelWidth),-2*CUBE_HALF_EXTENTS+wheelRadius, connectionHeight); #else connectionPointCS0 = btVector3(-CUBE_HALF_EXTENTS+(0.3*wheelWidth),connectionHeight,-2*CUBE_HALF_EXTENTS+wheelRadius); #endif //FORCE_ZAXIS_UP isFrontWheel = false; m_vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,wheelAxleCS,suspensionRestLength,wheelRadius,m_tuning,isFrontWheel); #ifdef FORCE_ZAXIS_UP connectionPointCS0 = btVector3(CUBE_HALF_EXTENTS-(0.3*wheelWidth),-2*CUBE_HALF_EXTENTS+wheelRadius, connectionHeight); #else connectionPointCS0 = btVector3(CUBE_HALF_EXTENTS-(0.3*wheelWidth),connectionHeight,-2*CUBE_HALF_EXTENTS+wheelRadius); #endif 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; } } setCameraDistance(26.f); }
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); }
Vehicle::Vehicle(btDynamicsWorld* world): carChassis(0), collisionShapes(), tuning(), vehicleRayCaster(0), vehicle(0), wheelShape(0), dynamicsWorld(world), rightIndex(0), upIndex(1), forwardIndex(2), wheelDirectionCS0(0,-1,0), wheelAxleCS(-1,0,0), engineForce(0.f), brakingForce(0.f), maxEngineForce(3000.f), maxBrakingForce(300.f), steering(0.f), targetSteering(0.f), steeringIncrement(0.9f), steeringClamp(0.4f), wheelRadius(0.5f), wheelWidth(0.4f), wheelFriction(10.f), suspensionStiffness(20.f), suspensionDamping(2.3f), suspensionCompression(4.4f), rollInfluence(0.1f), wheelColor(1,0,0), suspensionRestLength(0.6f) { btTransform tr; tr.setIdentity(); btCollisionShape* chassisShape = new btBoxShape(btVector3(1.f,0.5f,2.f)); collisionShapes.push_back(chassisShape); btCompoundShape* compound = new btCompoundShape(); collisionShapes.push_back(compound); btTransform localTrans; localTrans.setIdentity(); localTrans.setOrigin(btVector3(0,0.7,0));//localTrans effectively shifts the center of mass with respect to the chassis compound->addChildShape(localTrans,chassisShape); tr.setOrigin(btVector3(0,0.f,0)); carChassis = World::CreateRigidBody(1000,tr,compound);//chassisShape); dynamicsWorld->addRigidBody(carChassis); //m_carChassis->setDamping(0.2,0.2); wheelShape = new btCylinderShapeX(btVector3(wheelWidth,wheelRadius,wheelRadius)); Reset(); /// create vehicle vehicleRayCaster = new btDefaultVehicleRaycaster(dynamicsWorld); vehicle = new btRaycastVehicle(tuning, carChassis, vehicleRayCaster); ///never deactivate the vehicle carChassis->setActivationState(DISABLE_DEACTIVATION); dynamicsWorld->addVehicle(vehicle); float connectionHeight = 0.5f; bool isFrontWheel=true; //choose coordinate system vehicle->setCoordinateSystem(rightIndex,upIndex,forwardIndex); btVector3 connectionPointCS0(CUBE_HALF_EXTENTS-(0.3f*wheelWidth),connectionHeight,2*CUBE_HALF_EXTENTS-wheelRadius); vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,wheelAxleCS,suspensionRestLength,wheelRadius,tuning,isFrontWheel); connectionPointCS0 = btVector3(-CUBE_HALF_EXTENTS+(0.3f*wheelWidth),connectionHeight,2*CUBE_HALF_EXTENTS-wheelRadius); vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,wheelAxleCS,suspensionRestLength,wheelRadius,tuning,isFrontWheel); isFrontWheel = false; connectionPointCS0 = btVector3(-CUBE_HALF_EXTENTS+(0.3f*wheelWidth),connectionHeight,-2*CUBE_HALF_EXTENTS+wheelRadius); vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,wheelAxleCS,suspensionRestLength,wheelRadius,tuning,isFrontWheel); connectionPointCS0 = btVector3(CUBE_HALF_EXTENTS-(0.3f*wheelWidth),connectionHeight,-2*CUBE_HALF_EXTENTS+wheelRadius); vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,wheelAxleCS,suspensionRestLength,wheelRadius,tuning,isFrontWheel); for (int i=0;i<vehicle->getNumWheels();i++) { btWheelInfo& wheel = vehicle->getWheelInfo(i); wheel.m_suspensionStiffness = suspensionStiffness; wheel.m_wheelsDampingRelaxation = suspensionDamping; wheel.m_wheelsDampingCompression = suspensionCompression; wheel.m_frictionSlip = wheelFriction; wheel.m_rollInfluence = rollInfluence; } }
//============================================================================= //============================================================================= void Vehicle::Init() { // This function is called only from the main program when initially creating the vehicle, not on scene load ResourceCache* cache = GetSubsystem<ResourceCache>(); StaticModel* hullObject = node_->CreateComponent<StaticModel>(); hullBody_ = node_->CreateComponent<RigidBody>(); CollisionShape* hullColShape = node_->CreateComponent<CollisionShape>(); hullBody_->SetMass(1200.0f); hullBody_->SetLinearDamping(0.2f); // Some air resistance hullBody_->SetAngularDamping(0.5f); hullBody_->SetCollisionLayer(1); int rightIndex = 0; int upIndex = 1; int forwardIndex = 2; PhysicsWorld *pPhysWorld = GetScene()->GetComponent<PhysicsWorld>(); btDynamicsWorld *pbtDynWorld = (btDynamicsWorld*)pPhysWorld->GetWorld(); m_vehicleRayCaster = new btDefaultVehicleRaycaster( pbtDynWorld ); m_vehicle = new btRaycastVehicle( m_tuning, hullBody_->GetBody(), m_vehicleRayCaster ); pbtDynWorld->addVehicle( m_vehicle ); m_vehicle->setCoordinateSystem( rightIndex, upIndex, forwardIndex ); //Vector3 v3BoxExtents = Vector3::ONE;//Vector3(1.5f, 1.0f, 3.0f); hullObject->SetModel(cache->GetResource<Model>("MyProjects/MiniCooper/test/Chassis_001.mdl")); node_->SetScale( Vector3(1.0f, 1.0f, 1.0f) ); hullColShape->SetConvexHull(cache->GetResource<Model>("MyProjects/MiniCooper/test/collision.mdl")); //hullColShape->SetConvexHull(cache->GetResource<Model>("Models/Box.mdl")); //hullColShape->SetBox((hullObject->GetBoundingBox()).Size()); //hullColShape->SetTriangleMesh(cache->GetResource<Model>("Models/Box.mdl")); //hullColShape->SetSize(Vector3(1.0f, 1.0f, 3.0f)); //hullColShape->SetPosition((hullObject->GetBoundingBox()).Center() - Vector3(0.0f, 0.0f, 0.0f) ); //hullColShape->SetPosition( Vector3(0.0f, +0.2f, 0.0f) ); hullObject->SetCastShadows(true); Node* patricleTest = node_->CreateChild("patricleTest"); patricleTest->LoadXML(cache->GetResource<XMLFile>("MyProjects/MiniCooper/particleTest.xml")->GetRoot()); patricleTest->SetPosition(Vector3(0.0f, 0.2f, -2.0f)); Node* lightTest = node_->CreateChild("lightTest"); lightTest->LoadXML(cache->GetResource<XMLFile>("MyProjects/MiniCooper/lightTest.xml")->GetRoot()); lightTest->SetPosition(Vector3(0.0f, 0.2f, 2.0f)); //float connectionHeight = -0.4f;//1.2f; //float connectionHeight = 0.0f; bool isFrontWheel=true; btVector3 wheelDirectionCS0(0,-1,0); btVector3 wheelAxleCS(1,0,0); double wheelOffset = 0.5; // front right ////////////// Node* node_wheel_temp0 = GetScene()->CreateChild("node_wheel_temp0"); StaticModel* model_wheel_temp0 = node_wheel_temp0->CreateComponent<StaticModel>(); model_wheel_temp0->SetModel(cache->GetResource<Model>("MyProjects/MiniCooper/test/wheel_000.mdl")); model_wheel_temp0->ApplyMaterialList("MyProjects/MiniCooper/test/wheel_000.txt"); model_wheel_temp0->SetCastShadows(true); //btVector3 connectionPointCS0(((model_wheel_temp0->GetBoundingBox()).Center()).x_, ((model_wheel_temp0->GetBoundingBox()).Center()).y_, ((model_wheel_temp0->GetBoundingBox()).Center()).z_); //wheelRadius = model_wheel_temp0->GetBoundingBox().HalfSize().y_; //m_vehicle->addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, m_tuning, isFrontWheel); btVector3 connectionPointCS0((model_wheel_temp0->GetBoundingBox()).Center().x_,((model_wheel_temp0->GetBoundingBox()).Center()).y_ + wheelOffset,((model_wheel_temp0->GetBoundingBox()).Center()).z_); m_vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,btVector3(-1,0,0),suspensionRestLength,wheelRadius,m_tuning,isFrontWheel); Node* node_wheel_0 = GetScene()->CreateChild("node_wheel_0"); node_wheel_0->SetPosition((model_wheel_temp0->GetBoundingBox()).Center()); node_wheel_0->SetRotation(Quaternion(0.0f, 0.0f, 90.0f)); node_wheel_temp0->SetParent(node_wheel_0); m_vpNodeWheel.Push( node_wheel_0 ); //SDL_Log( "node_wheel_temp0: %f, %f, %f \n", ((model_wheel_temp0->GetBoundingBox()).Center()).x_, ((model_wheel_temp0->GetBoundingBox()).Center()).y_, ((model_wheel_temp0->GetBoundingBox()).Center()).z_); //SDL_Log( "node_wheel_temp0.HalfSize: %s \n", model_wheel_temp0->GetBoundingBox().HalfSize().ToString().CString() ); //SDL_Log("##################### \n"); //SDL_Log("node_wheel_temp0WorldP: %f, %f, %f \n", node_wheel_temp0->GetWorldPosition().x_, node_wheel_temp0->GetWorldPosition().y_, node_wheel_temp0->GetWorldPosition().z_); //SDL_Log("node_wheel_temp0P: %f, %f, %f \n", node_wheel_temp0->GetPosition().x_, node_wheel_temp0->GetPosition().y_, node_wheel_temp0->GetPosition().z_); //SDL_Log( "model_wheel_temp0BoundP: %f, %f, %f \n", ((model_wheel_temp0->GetBoundingBox()).Center()).x_, ((model_wheel_temp0->GetBoundingBox()).Center()).y_, ((model_wheel_temp0->GetBoundingBox()).Center()).z_); //node_wheel_temp0->SetPosition(node_wheel_temp0->GetPosition() - (model_wheel_temp0->GetBoundingBox()).Center()); //SDL_Log("transform: %f, %f, %f \n", v3Origin.x_, v3Origin.y_, v3Origin.z_); //v3Origin = v3Origin - Vector3(0.704, 0.379, 1.19); //SDL_Log("transform: %f, %f, %f \n", v3Origin.x_, v3Origin.y_, v3Origin.z_); // front left ///////////// Node* node_wheel_temp1 = GetScene()->CreateChild("node_wheel_temp1"); StaticModel* model_wheel_temp1 = node_wheel_temp1->CreateComponent<StaticModel>(); model_wheel_temp1->SetModel(cache->GetResource<Model>("MyProjects/MiniCooper/test/wheel_001.mdl")); model_wheel_temp1->SetCastShadows(true); //btVector3 connectionPointCS0(((model_wheel_temp0->GetBoundingBox()).Center()).x_, ((model_wheel_temp0->GetBoundingBox()).Center()).y_, ((model_wheel_temp0->GetBoundingBox()).Center()).z_); //wheelRadius = model_wheel_temp0->GetBoundingBox().HalfSize().y_; //m_vehicle->addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, m_tuning, isFrontWheel); connectionPointCS0 = btVector3((model_wheel_temp1->GetBoundingBox()).Center().x_,((model_wheel_temp1->GetBoundingBox()).Center()).y_ + wheelOffset,((model_wheel_temp1->GetBoundingBox()).Center()).z_); m_vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,btVector3(-1,0,0),suspensionRestLength,wheelRadius,m_tuning,isFrontWheel); Node* node_wheel_1 = GetScene()->CreateChild("node_wheel_1"); node_wheel_1->SetPosition((model_wheel_temp1->GetBoundingBox()).Center()); node_wheel_1->SetRotation(Quaternion(0.0f, 0.0f, -90.0f)); node_wheel_temp1->SetParent(node_wheel_1); m_vpNodeWheel.Push( node_wheel_1 ); isFrontWheel = false; // back right ///////////// Node* node_wheel_temp2 = GetScene()->CreateChild("node_wheel_temp2"); StaticModel* model_wheel_temp2 = node_wheel_temp2->CreateComponent<StaticModel>(); model_wheel_temp2->SetModel(cache->GetResource<Model>("MyProjects/MiniCooper/test/wheel_002.mdl")); model_wheel_temp2->SetCastShadows(true); //btVector3 connectionPointCS0(((model_wheel_temp0->GetBoundingBox()).Center()).x_, ((model_wheel_temp0->GetBoundingBox()).Center()).y_, ((model_wheel_temp0->GetBoundingBox()).Center()).z_); //wheelRadius = model_wheel_temp0->GetBoundingBox().HalfSize().y_; //m_vehicle->addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, m_tuning, isFrontWheel); connectionPointCS0 = btVector3((model_wheel_temp2->GetBoundingBox()).Center().x_,((model_wheel_temp2->GetBoundingBox()).Center()).y_ + wheelOffset,((model_wheel_temp2->GetBoundingBox()).Center()).z_); m_vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,btVector3(-1,0,0),suspensionRestLength,wheelRadius,m_tuning,isFrontWheel); Node* node_wheel_2 = GetScene()->CreateChild("node_wheel_2"); node_wheel_2->SetPosition((model_wheel_temp2->GetBoundingBox()).Center()); node_wheel_2->SetRotation(Quaternion(0.0f, 0.0f, 90.0f)); node_wheel_temp2->SetParent(node_wheel_2); m_vpNodeWheel.Push( node_wheel_2 ); // back left ///////////// /// \brief objectNode3 Node* node_wheel_temp3 = GetScene()->CreateChild("node_wheel_temp3"); StaticModel* model_wheel_temp3 = node_wheel_temp3->CreateComponent<StaticModel>(); model_wheel_temp3->SetModel(cache->GetResource<Model>("MyProjects/MiniCooper/test/wheel_003.mdl")); model_wheel_temp3->SetCastShadows(true); //btVector3 connectionPointCS0(((model_wheel_temp0->GetBoundingBox()).Center()).x_, ((model_wheel_temp0->GetBoundingBox()).Center()).y_, ((model_wheel_temp0->GetBoundingBox()).Center()).z_); //wheelRadius = model_wheel_temp0->GetBoundingBox().HalfSize().y_; //m_vehicle->addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, m_tuning, isFrontWheel); connectionPointCS0 = btVector3((model_wheel_temp3->GetBoundingBox()).Center().x_,((model_wheel_temp3->GetBoundingBox()).Center()).y_ + wheelOffset,((model_wheel_temp3->GetBoundingBox()).Center()).z_); m_vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,btVector3(-1,0,0),suspensionRestLength,wheelRadius,m_tuning,isFrontWheel); Node* node_wheel_3 = GetScene()->CreateChild("node_wheel_2"); node_wheel_3->SetPosition((model_wheel_temp3->GetBoundingBox()).Center()); node_wheel_3->SetRotation(Quaternion(0.0f, 0.0f, -90.0f)); node_wheel_temp3->SetParent(node_wheel_3); m_vpNodeWheel.Push( node_wheel_3 ); /* 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; } */ 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); btTransform transform = m_vehicle->getWheelTransformWS( i ); /* //Vector3 v3Origin = ToVector3( transform.getOrigin() ); //Quaternion qRot = ToQuaternion( transform.getRotation() ); // create wheel node Node *wheelNode = GetScene()->CreateChild(); //wheelNode->SetPosition( v3Origin ); //btWheelInfo whInfo = m_vehicle->getWheelInfo( i ); //Vector3 v3PosLS = ToVector3( whInfo.m_chassisConnectionPointCS ); //wheelNode->SetRotation( v3PosLS.x_ >= 0.0 ? Quaternion(0.0f, 0.0f, -90.0f) : Quaternion(0.0f, 0.0f, 90.0f) ); //wheelNode->SetScale(Vector3(1.0f, 0.65f, 1.0f)); StaticModel *pWheel = wheelNode->CreateComponent<StaticModel>(); if(i == 0) pWheel->SetModel(cache->GetResource<Model>("MyProjects/SimpeCar/wheel.mdl")); else pWheel->SetModel(cache->GetResource<Model>("MyProjects/SimpeCar/wheel.mdl")); if(i == 0) { //wheelNode->SetPosition( Vector3(50,50,50) ); //wheelNode->SetRotation(Quaternion(0.0f, 0.0f, 0.0f)); }else { //wheelNode->SetPosition( v3Origin ); //wheelNode->SetRotation(Quaternion(0.0f, 0.0f, 0.0f)); } m_vpNodeWheel.Push( wheelNode ); //pWheel->SetModel(cache->GetResource<Model>("MyProjects/MiniCooper/test/wheel_004.mdl")); pWheel->SetMaterial(cache->GetResource<Material>("MyProjects/SimpeCar/TireTextureMaterial.xml")); pWheel->SetCastShadows(true); */ } } }
void Vehicle::initPhysics(){ m_chassisShape = new btBoxShape(btVector3(1.f,0.5f,2.f)); // stash this shape away cPhysics::Get().getCollisionShapes().push_back(m_chassisShape); m_compound = new btCompoundShape(); cPhysics::Get().getCollisionShapes().push_back(m_compound); btTransform localTrans; localTrans.setIdentity(); //localTrans effectively shifts the center of mass with respect to the chassis localTrans.setOrigin(btVector3(0,1.4,0)); //** localTrans.setOrigin(btVector3(0,1,0)); m_compound->addChildShape(localTrans,m_chassisShape); float mass = 800.f; m_carChassis = cPhysics::Get().GetNewBody(m_compound, mass, cVec3(0.f, 0.f, 0.f), 329.9f); //chassisShape //m_carChassis->setDamping(0.2,0.2); m_wheelShape = new btCylinderShapeX(btVector3(wheelWidth,wheelRadius,wheelRadius)); ResetVehicleParams(); /// create vehicle { m_vehicleRayCaster = new btDefaultVehicleRaycaster(cPhysics::Get().GetBulletWorld()); m_vehicle = new btRaycastVehicle(m_tuning, m_carChassis, m_vehicleRayCaster); ///never deactivate the vehicle m_carChassis->setActivationState(DISABLE_DEACTIVATION); cPhysics::Get().GetBulletWorld()->addAction(m_vehicle); //** ->addVehicle(m_vehicle); float connectionHeight = 1.2f; bool isFrontWheel=true; //choose coordinate system m_vehicle->setCoordinateSystem(rightIndex, upIndex, forwardIndex); // front left 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); // front right 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); // rear left 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); // rear right connectionPointCS0 = btVector3(CUBE_HALF_EXTENTS-(0.3*wheelWidth),connectionHeight,-2*CUBE_HALF_EXTENTS+wheelRadius); btWheelInfo& wheel_RR = 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; } } }