aboutsummaryrefslogtreecommitdiff
path: root/KaplaDemo/samples/sampleViewer3/VehicleManager.cpp
diff options
context:
space:
mode:
authorgit perforce import user <a@b>2016-10-25 12:29:14 -0600
committerSheikh Dawood Abdul Ajees <Sheikh Dawood Abdul Ajees>2016-10-25 18:56:37 -0500
commit3dfe2108cfab31ba3ee5527e217d0d8e99a51162 (patch)
treefa6485c169e50d7415a651bf838f5bcd0fd3bfbd /KaplaDemo/samples/sampleViewer3/VehicleManager.cpp
downloadphysx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.tar.xz
physx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.zip
Initial commit:
PhysX 3.4.0 Update @ 21294896 APEX 1.4.0 Update @ 21275617 [CL 21300167]
Diffstat (limited to 'KaplaDemo/samples/sampleViewer3/VehicleManager.cpp')
-rw-r--r--KaplaDemo/samples/sampleViewer3/VehicleManager.cpp473
1 files changed, 473 insertions, 0 deletions
diff --git a/KaplaDemo/samples/sampleViewer3/VehicleManager.cpp b/KaplaDemo/samples/sampleViewer3/VehicleManager.cpp
new file mode 100644
index 00000000..ee0b2624
--- /dev/null
+++ b/KaplaDemo/samples/sampleViewer3/VehicleManager.cpp
@@ -0,0 +1,473 @@
+
+#include "SceneVehicleSceneQuery.h"
+#include "VehicleManager.h"
+#include "VehicleWheelQueryResults.h"
+#include "vehicle/PxVehicleUtilSetup.h"
+#include "PxRigidActorExt.h"
+#include "PxSceneLock.h"
+#include "PxD6Joint.h"
+
+
+VehicleManager::VehicleManager() : mSqWheelRaycastBatchQuery(NULL)
+{
+
+}
+
+VehicleManager::~VehicleManager()
+{
+ PxCloseVehicleSDK();
+}
+
+void VehicleManager::init(PxPhysics& physics, const PxMaterial** drivableSurfaceMaterials, const PxVehicleDrivableSurfaceType* drivableSurfaceTypes)
+{
+ //Initialise the sdk.
+ PxInitVehicleSDK(physics, NULL);
+
+ //Set the basis vectors.
+ PxVec3 up(0, 1, 0);
+ PxVec3 forward(0, 0, 1);
+ PxVehicleSetBasisVectors(up, forward);
+
+ //Set the vehicle update mode to be immediate velocity changes.
+ PxVehicleSetUpdateMode(PxVehicleUpdateMode::eVELOCITY_CHANGE);
+
+ //Initialise vehicle ptrs to null.
+ mVehicle = NULL;
+
+ //Allocate simulation data so we can switch from 3-wheeled to 4-wheeled cars by switching simulation data.
+ mWheelsSimData4W = PxVehicleWheelsSimData::allocate(4);
+
+ //Scene query data for to allow raycasts for all suspensions of all vehicles.
+ mSqData = VehicleSceneQueryData::allocate(4);
+
+ //Data to store reports for each wheel.
+ mWheelQueryResults = VehicleWheelQueryResults::allocate(4);
+
+ //Set up the friction values arising from combinations of tire type and surface type.
+ mSurfaceTirePairs = PxVehicleDrivableSurfaceToTireFrictionPairs::allocate(MAX_NUM_TIRE_TYPES, MAX_NUM_SURFACE_TYPES);
+ mSurfaceTirePairs->setup(MAX_NUM_TIRE_TYPES, MAX_NUM_SURFACE_TYPES, drivableSurfaceMaterials, drivableSurfaceTypes);
+ for (PxU32 i = 0; i<MAX_NUM_SURFACE_TYPES; i++)
+ {
+ for (PxU32 j = 0; j<MAX_NUM_TIRE_TYPES; j++)
+ {
+ mSurfaceTirePairs->setTypePairFriction(i, j, 1.3f*TireFrictionMultipliers::getValue(i, j));
+ }
+ }
+
+}
+
+void VehicleManager::computeWheelWidthsAndRadii(PxConvexMesh** wheelConvexMeshes, PxF32* wheelWidths, PxF32* wheelRadii)
+{
+ for (PxU32 i = 0; i<4; i++)
+ {
+ const PxU32 numWheelVerts = wheelConvexMeshes[i]->getNbVertices();
+ const PxVec3* wheelVerts = wheelConvexMeshes[i]->getVertices();
+ PxVec3 wheelMin(PX_MAX_F32, PX_MAX_F32, PX_MAX_F32);
+ PxVec3 wheelMax(-PX_MAX_F32, -PX_MAX_F32, -PX_MAX_F32);
+ for (PxU32 j = 0; j<numWheelVerts; j++)
+ {
+ wheelMin.x = PxMin(wheelMin.x, wheelVerts[j].x);
+ wheelMin.y = PxMin(wheelMin.y, wheelVerts[j].y);
+ wheelMin.z = PxMin(wheelMin.z, wheelVerts[j].z);
+ wheelMax.x = PxMax(wheelMax.x, wheelVerts[j].x);
+ wheelMax.y = PxMax(wheelMax.y, wheelVerts[j].y);
+ wheelMax.z = PxMax(wheelMax.z, wheelVerts[j].z);
+ }
+ wheelWidths[i] = wheelMax.x - wheelMin.x;
+ wheelRadii[i] = PxMax(wheelMax.y, wheelMax.z)*0.975f;
+ }
+}
+
+PxVec3 VehicleManager::computeChassisAABBDimensions(const PxConvexMesh* chassisConvexMesh)
+{
+ const PxU32 numChassisVerts = chassisConvexMesh->getNbVertices();
+ const PxVec3* chassisVerts = chassisConvexMesh->getVertices();
+ PxVec3 chassisMin(PX_MAX_F32, PX_MAX_F32, PX_MAX_F32);
+ PxVec3 chassisMax(-PX_MAX_F32, -PX_MAX_F32, -PX_MAX_F32);
+ for (PxU32 i = 0; i<numChassisVerts; i++)
+ {
+ chassisMin.x = PxMin(chassisMin.x, chassisVerts[i].x);
+ chassisMin.y = PxMin(chassisMin.y, chassisVerts[i].y);
+ chassisMin.z = PxMin(chassisMin.z, chassisVerts[i].z);
+ chassisMax.x = PxMax(chassisMax.x, chassisVerts[i].x);
+ chassisMax.y = PxMax(chassisMax.y, chassisVerts[i].y);
+ chassisMax.z = PxMax(chassisMax.z, chassisVerts[i].z);
+ }
+ const PxVec3 chassisDims = chassisMax - chassisMin;
+ return chassisDims;
+}
+
+void VehicleManager::createVehicle4WSimulationData(const PxF32 chassisMass, PxConvexMesh* chassisConvexMesh, const PxF32 wheelMass, PxConvexMesh** wheelConvexMeshes,
+ const PxVec3* wheelCentreOffsets, PxVehicleWheelsSimData& wheelsData, PxVehicleDriveSimData4W& driveData, PxVehicleChassisData& chassisData)
+{
+ //Extract the chassis AABB dimensions from the chassis convex mesh.
+ const PxVec3 chassisDims = computeChassisAABBDimensions(chassisConvexMesh);
+
+ //The origin is at the center of the chassis mesh.
+ //Set the center of mass to be below this point and a little towards the front.
+ const PxVec3 chassisCMOffset = PxVec3(0.0f, -chassisDims.y*0.5f + 0.65f, 0.25f);
+
+ //Now compute the chassis mass and moment of inertia.
+ //Use the moment of inertia of a cuboid as an approximate value for the chassis moi.
+ PxVec3 chassisMOI
+ ((chassisDims.y*chassisDims.y + chassisDims.z*chassisDims.z)*chassisMass / 12.0f,
+ (chassisDims.x*chassisDims.x + chassisDims.z*chassisDims.z)*chassisMass / 12.0f,
+ (chassisDims.x*chassisDims.x + chassisDims.y*chassisDims.y)*chassisMass / 12.0f);
+ //A bit of tweaking here. The car will have more responsive turning if we reduce the
+ //y-component of the chassis moment of inertia.
+ chassisMOI.y *= 0.8f;
+
+ //Let's set up the chassis data structure now.
+ chassisData.mMass = chassisMass;
+ chassisData.mMOI = chassisMOI;
+ chassisData.mCMOffset = chassisCMOffset;
+
+ //Compute the sprung masses of each suspension spring using a helper function.
+ PxF32 suspSprungMasses[4];
+ PxVehicleComputeSprungMasses(4, wheelCentreOffsets, chassisCMOffset, chassisMass, 1, suspSprungMasses);
+
+ //Extract the wheel radius and width from the wheel convex meshes.
+ PxF32 wheelWidths[4];
+ PxF32 wheelRadii[4];
+ computeWheelWidthsAndRadii(wheelConvexMeshes, wheelWidths, wheelRadii);
+
+ //Now compute the wheel masses and inertias components around the axle's axis.
+ //http://en.wikipedia.org/wiki/List_of_moments_of_inertia
+ PxF32 wheelMOIs[4];
+ for (PxU32 i = 0; i<4; i++)
+ {
+ wheelMOIs[i] = 0.5f*wheelMass*wheelRadii[i] * wheelRadii[i];
+ }
+ //Let's set up the wheel data structures now with radius, mass, and moi.
+ PxVehicleWheelData wheels[4];
+ for (PxU32 i = 0; i<4; i++)
+ {
+ wheels[i].mRadius = wheelRadii[i];
+ wheels[i].mMass = wheelMass;
+ wheels[i].mMOI = wheelMOIs[i];
+ wheels[i].mWidth = wheelWidths[i];
+ }
+ //Disable the handbrake from the front wheels and enable for the rear wheels
+ wheels[PxVehicleDrive4WWheelOrder::eFRONT_LEFT].mMaxHandBrakeTorque = 0.0f;
+ wheels[PxVehicleDrive4WWheelOrder::eFRONT_RIGHT].mMaxHandBrakeTorque = 0.0f;
+ wheels[PxVehicleDrive4WWheelOrder::eREAR_LEFT].mMaxHandBrakeTorque = 4000.0f;
+ wheels[PxVehicleDrive4WWheelOrder::eREAR_RIGHT].mMaxHandBrakeTorque = 4000.0f;
+ //Enable steering for the front wheels and disable for the front wheels.
+ wheels[PxVehicleDrive4WWheelOrder::eFRONT_LEFT].mMaxSteer = PxPi*0.3333f;
+ wheels[PxVehicleDrive4WWheelOrder::eFRONT_RIGHT].mMaxSteer = PxPi*0.3333f;
+ wheels[PxVehicleDrive4WWheelOrder::eREAR_LEFT].mMaxSteer = 0.0f;
+ wheels[PxVehicleDrive4WWheelOrder::eREAR_RIGHT].mMaxSteer = 0.0f;
+
+ //Let's set up the tire data structures now.
+ //Put slicks on the front tires and wets on the rear tires.
+ PxVehicleTireData tires[4];
+ tires[PxVehicleDrive4WWheelOrder::eFRONT_LEFT].mType = TIRE_TYPE_SLICKS;
+ tires[PxVehicleDrive4WWheelOrder::eFRONT_RIGHT].mType = TIRE_TYPE_SLICKS;
+ tires[PxVehicleDrive4WWheelOrder::eREAR_LEFT].mType = TIRE_TYPE_WETS;
+ tires[PxVehicleDrive4WWheelOrder::eREAR_RIGHT].mType = TIRE_TYPE_WETS;
+
+ //Let's set up the suspension data structures now.
+ PxVehicleSuspensionData susps[4];
+ for (PxU32 i = 0; i<4; i++)
+ {
+ susps[i].mMaxCompression = 0.3f;
+ susps[i].mMaxDroop = 0.1f;
+ susps[i].mSpringStrength = 35000.0f;
+ susps[i].mSpringDamperRate = 4500.0f;
+ }
+ susps[PxVehicleDrive4WWheelOrder::eFRONT_LEFT].mSprungMass = suspSprungMasses[PxVehicleDrive4WWheelOrder::eFRONT_LEFT];
+ susps[PxVehicleDrive4WWheelOrder::eFRONT_RIGHT].mSprungMass = suspSprungMasses[PxVehicleDrive4WWheelOrder::eFRONT_RIGHT];
+ susps[PxVehicleDrive4WWheelOrder::eREAR_LEFT].mSprungMass = suspSprungMasses[PxVehicleDrive4WWheelOrder::eREAR_LEFT];
+ susps[PxVehicleDrive4WWheelOrder::eREAR_RIGHT].mSprungMass = suspSprungMasses[PxVehicleDrive4WWheelOrder::eREAR_RIGHT];
+
+ //Set up the camber.
+ //Remember that the left and right wheels need opposite camber so that the car preserves symmetry about the forward direction.
+ //Set the camber to 0.0f when the spring is neither compressed or elongated.
+ const PxF32 camberAngleAtRest = 0.0;
+ susps[PxVehicleDrive4WWheelOrder::eFRONT_LEFT].mCamberAtRest = camberAngleAtRest;
+ susps[PxVehicleDrive4WWheelOrder::eFRONT_RIGHT].mCamberAtRest = -camberAngleAtRest;
+ susps[PxVehicleDrive4WWheelOrder::eREAR_LEFT].mCamberAtRest = camberAngleAtRest;
+ susps[PxVehicleDrive4WWheelOrder::eREAR_RIGHT].mCamberAtRest = -camberAngleAtRest;
+ //Set the wheels to camber inwards at maximum droop (the left and right wheels almost form a V shape)
+ const PxF32 camberAngleAtMaxDroop = 0.001f;
+ susps[PxVehicleDrive4WWheelOrder::eFRONT_LEFT].mCamberAtMaxDroop = camberAngleAtMaxDroop;
+ susps[PxVehicleDrive4WWheelOrder::eFRONT_RIGHT].mCamberAtMaxDroop = -camberAngleAtMaxDroop;
+ susps[PxVehicleDrive4WWheelOrder::eREAR_LEFT].mCamberAtMaxDroop = camberAngleAtMaxDroop;
+ susps[PxVehicleDrive4WWheelOrder::eREAR_RIGHT].mCamberAtMaxDroop = -camberAngleAtMaxDroop;
+ //Set the wheels to camber outwards at maximum compression (the left and right wheels almost form a A shape).
+ const PxF32 camberAngleAtMaxCompression = -0.001f;
+ susps[PxVehicleDrive4WWheelOrder::eFRONT_LEFT].mCamberAtMaxCompression = camberAngleAtMaxCompression;
+ susps[PxVehicleDrive4WWheelOrder::eFRONT_RIGHT].mCamberAtMaxCompression = -camberAngleAtMaxCompression;
+ susps[PxVehicleDrive4WWheelOrder::eREAR_LEFT].mCamberAtMaxCompression = camberAngleAtMaxCompression;
+ susps[PxVehicleDrive4WWheelOrder::eREAR_RIGHT].mCamberAtMaxCompression = -camberAngleAtMaxCompression;
+
+ //We need to set up geometry data for the suspension, wheels, and tires.
+ //We already know the wheel centers described as offsets from the actor center and the center of mass offset from actor center.
+ //From here we can approximate application points for the tire and suspension forces.
+ //Lets assume that the suspension travel directions are absolutely vertical.
+ //Also assume that we apply the tire and suspension forces 30cm below the center of mass.
+ PxVec3 suspTravelDirections[4] = { PxVec3(0, -1, 0), PxVec3(0, -1, 0), PxVec3(0, -1, 0), PxVec3(0, -1, 0) };
+ PxVec3 wheelCentreCMOffsets[4];
+ PxVec3 suspForceAppCMOffsets[4];
+ PxVec3 tireForceAppCMOffsets[4];
+ for (PxU32 i = 0; i<4; i++)
+ {
+ wheelCentreCMOffsets[i] = wheelCentreOffsets[i] - chassisCMOffset;
+ suspForceAppCMOffsets[i] = PxVec3(wheelCentreCMOffsets[i].x, -0.3f, wheelCentreCMOffsets[i].z);
+ tireForceAppCMOffsets[i] = PxVec3(wheelCentreCMOffsets[i].x, -0.3f, wheelCentreCMOffsets[i].z);
+ }
+
+ //Now add the wheel, tire and suspension data.
+ for (PxU32 i = 0; i<4; i++)
+ {
+ wheelsData.setWheelData(i, wheels[i]);
+ wheelsData.setTireData(i, tires[i]);
+ wheelsData.setSuspensionData(i, susps[i]);
+ wheelsData.setSuspTravelDirection(i, suspTravelDirections[i]);
+ wheelsData.setWheelCentreOffset(i, wheelCentreCMOffsets[i]);
+ wheelsData.setSuspForceAppPointOffset(i, suspForceAppCMOffsets[i]);
+ wheelsData.setTireForceAppPointOffset(i, tireForceAppCMOffsets[i]);
+ }
+
+ //Set the car to perform 3 sub-steps when it moves with a forwards speed of less than 5.0
+ //and with a single step when it moves at speed greater than or equal to 5.0.
+ wheelsData.setSubStepCount(5.0f, 5, 5);
+
+
+ //Now set up the differential, engine, gears, clutch, and ackermann steering.
+
+ //Diff
+ PxVehicleDifferential4WData diff;
+ diff.mType = PxVehicleDifferential4WData::eDIFF_TYPE_LS_4WD;
+ driveData.setDiffData(diff);
+
+ //Engine
+ PxVehicleEngineData engine;
+ engine.mPeakTorque = 1500.0f;
+ engine.mMaxOmega = 1000.0f;//approx 6000 rpm
+ engine.mMOI = 2.f;
+
+ driveData.setEngineData(engine);
+
+ //Gears
+ PxVehicleGearsData gears;
+ gears.mSwitchTime = 0.5f;
+ driveData.setGearsData(gears);
+
+ //Clutch
+ PxVehicleClutchData clutch;
+ clutch.mStrength = 10.0f;
+ driveData.setClutchData(clutch);
+
+ //Ackermann steer accuracy
+ PxVehicleAckermannGeometryData ackermann;
+ ackermann.mAccuracy = 1.0f;
+ ackermann.mAxleSeparation = wheelCentreOffsets[PxVehicleDrive4WWheelOrder::eFRONT_LEFT].z - wheelCentreOffsets[PxVehicleDrive4WWheelOrder::eREAR_LEFT].z;
+ ackermann.mFrontWidth = wheelCentreOffsets[PxVehicleDrive4WWheelOrder::eFRONT_RIGHT].x - wheelCentreOffsets[PxVehicleDrive4WWheelOrder::eFRONT_LEFT].x;
+ ackermann.mRearWidth = wheelCentreOffsets[PxVehicleDrive4WWheelOrder::eREAR_RIGHT].x - wheelCentreOffsets[PxVehicleDrive4WWheelOrder::eREAR_LEFT].x;
+ driveData.setAckermannGeometryData(ackermann);
+}
+
+void setupActor
+(PxRigidDynamic* vehActor,
+const PxFilterData& vehQryFilterData,
+const PxGeometry** wheelGeometries, const PxTransform* wheelLocalPoses, const PxU32 numWheelGeometries, const PxMaterial* wheelMaterial, const PxFilterData& wheelCollFilterData,
+const PxGeometry** chassisGeometries, const PxTransform* chassisLocalPoses, const PxU32 numChassisGeometries, const PxMaterial* chassisMaterial, const PxFilterData& chassisCollFilterData,
+const PxVehicleChassisData& chassisData,
+PxPhysics* physics)
+{
+ //Add all the wheel shapes to the actor.
+ for (PxU32 i = 0; i<numWheelGeometries; i++)
+ {
+ PxShape* wheelShape = PxRigidActorExt::createExclusiveShape(*vehActor, *wheelGeometries[i], *wheelMaterial);
+ wheelShape->setQueryFilterData(vehQryFilterData);
+ wheelShape->setFlag(PxShapeFlag::eSCENE_QUERY_SHAPE, false);
+ //wheelShape->setFlag(PxShapeFlag::eSIMULATION_SHAPE, false);
+ wheelShape->setSimulationFilterData(wheelCollFilterData);
+ wheelShape->setLocalPose(wheelLocalPoses[i]);
+ }
+
+ //Add the chassis shapes to the actor.
+ for (PxU32 i = 0; i<numChassisGeometries; i++)
+ {
+ PxShape* chassisShape = PxRigidActorExt::createExclusiveShape(*vehActor, *chassisGeometries[i], *chassisMaterial);
+ chassisShape->setFlag(PxShapeFlag::eSCENE_QUERY_SHAPE, false);
+ chassisShape->setQueryFilterData(vehQryFilterData);
+ chassisShape->setSimulationFilterData(chassisCollFilterData);
+ chassisShape->setLocalPose(chassisLocalPoses[i]);
+ }
+
+ vehActor->setMass(chassisData.mMass);
+ vehActor->setMassSpaceInertiaTensor(chassisData.mMOI);
+ vehActor->setCMassLocalPose(PxTransform(chassisData.mCMOffset, PxQuat(PxIdentity)));
+}
+
+PxRigidDynamic* createVehicleActor4W
+(const PxVehicleChassisData& chassisData,
+PxConvexMesh** wheelConvexMeshes, PxConvexMesh* chassisConvexMesh,
+PxScene& scene, PxPhysics& physics, const PxMaterial& material)
+{
+ //We need a rigid body actor for the vehicle.
+ //Don't forget to add the actor the scene after setting up the associated vehicle.
+ PxRigidDynamic* vehActor = physics.createRigidDynamic(PxTransform(PxIdentity));
+
+ //We need to add wheel collision shapes, their local poses, a material for the wheels, and a simulation filter for the wheels.
+ PxConvexMeshGeometry frontLeftWheelGeom(wheelConvexMeshes[0]);
+ PxConvexMeshGeometry frontRightWheelGeom(wheelConvexMeshes[1]);
+ PxConvexMeshGeometry rearLeftWheelGeom(wheelConvexMeshes[2]);
+ PxConvexMeshGeometry rearRightWheelGeom(wheelConvexMeshes[3]);
+ const PxGeometry* wheelGeometries[4] = { &frontLeftWheelGeom, &frontRightWheelGeom, &rearLeftWheelGeom, &rearRightWheelGeom };
+
+ const PxTransform wheelLocalPoses[4] = { PxTransform(PxIdentity), PxTransform(PxIdentity), PxTransform(PxIdentity), PxTransform(PxIdentity) };
+ const PxMaterial& wheelMaterial = material;
+ PxFilterData wheelCollFilterData;
+ wheelCollFilterData.word0 = COLLISION_FLAG_WHEEL;
+ wheelCollFilterData.word1 = COLLISION_FLAG_WHEEL_AGAINST;
+ wheelCollFilterData.word2 = PxPairFlag::eMODIFY_CONTACTS;
+
+ //We need to add chassis collision shapes, their local poses, a material for the chassis, and a simulation filter for the chassis.
+ PxConvexMeshGeometry chassisConvexGeom(chassisConvexMesh);
+ const PxGeometry* chassisGeoms[1] = { &chassisConvexGeom };
+ const PxTransform chassisLocalPoses[1] = { PxTransform(PxIdentity) };
+ const PxMaterial& chassisMaterial = material;
+ PxFilterData chassisCollFilterData;
+ chassisCollFilterData.word0 = COLLISION_FLAG_CHASSIS;
+ chassisCollFilterData.word1 = COLLISION_FLAG_CHASSIS_AGAINST;
+
+ //Create a query filter data for the car to ensure that cars
+ //do not attempt to drive on themselves.
+ PxFilterData vehQryFilterData;
+ VehicleSetupVehicleShapeQueryFilterData(&vehQryFilterData);
+
+ //Set up the physx rigid body actor with shapes, local poses, and filters.
+ setupActor
+ (vehActor,
+ vehQryFilterData,
+ wheelGeometries, wheelLocalPoses, 4, &wheelMaterial, wheelCollFilterData,
+ chassisGeoms, chassisLocalPoses, 1, &chassisMaterial, chassisCollFilterData,
+ chassisData,
+ &physics);
+
+ return vehActor;
+}
+
+
+void VehicleManager::resetNWCar(const PxTransform& startTransform, PxVehicleWheels* vehWheels)
+{
+
+ PxVehicleDrive4W* vehDrive4W = (PxVehicleDrive4W*)vehWheels;
+ //Set the car back to its rest state.
+ vehDrive4W->setToRestState();
+ //Set the car to first gear.
+ vehDrive4W->mDriveDynData.forceGearChange(PxVehicleGearsData::eFIRST);
+
+ //Set the car's transform to be the start transform.
+ PxRigidDynamic* actor = vehWheels->getRigidDynamicActor();
+ PxSceneWriteLock scopedLock(*actor->getScene());
+ actor->setGlobalPose(startTransform);
+}
+
+void VehicleManager::suspensionRaycasts(PxScene* scene)
+{
+ //Create a scene query if we haven't already done so.
+ if (NULL == mSqWheelRaycastBatchQuery)
+ {
+ mSqWheelRaycastBatchQuery = mSqData->setUpBatchedSceneQuery(scene);
+ }
+ //Raycasts.
+ PxSceneReadLock scopedLock(*scene);
+ PxVehicleWheels* vehicles[1] = { mVehicle };
+ PxVehicleSuspensionRaycasts(mSqWheelRaycastBatchQuery, 1, vehicles, mSqData->getRaycastQueryResultBufferSize(), mSqData->getRaycastQueryResultBuffer());
+}
+
+void VehicleManager::suspensionSweeps(PxScene* scene)
+{
+ //Create a scene query if we haven't already done so.
+ if (NULL == mSqWheelRaycastBatchQuery)
+ {
+ mSqWheelRaycastBatchQuery = mSqData->setUpBatchedSceneQuerySweep(scene);
+ }
+ //Raycasts.
+ PxSceneReadLock scopedLock(*scene);
+ PxVehicleWheels* vehicles[1] = { mVehicle };
+ PxVehicleSuspensionSweeps(mSqWheelRaycastBatchQuery, 1, vehicles, mSqData->getSweepQueryResultBufferSize(), mSqData->getSweepQueryResultBuffer(), 1);
+}
+
+void VehicleManager::update(const PxF32 timestep, const PxVec3& gravity)
+{
+ PxVehicleWheels* vehicles[1] = { mVehicle };
+
+ PxVehicleUpdates(timestep, gravity, *mSurfaceTirePairs, 1, vehicles, &mVehicleWheelQueryResults);
+}
+
+void VehicleManager::create4WVehicle(PxScene& scene, PxPhysics& physics, PxCooking& cooking, const PxMaterial& material,
+ const PxF32 chassisMass, const PxVec3* wheelCentreOffsets4, PxConvexMesh* chassisConvexMesh, PxConvexMesh** wheelConvexMeshes4,
+ const PxTransform& startTransform, const bool useAutoGearFlag)
+{
+ PxVehicleWheelsSimData* wheelsSimData = PxVehicleWheelsSimData::allocate(4);
+ PxVehicleDriveSimData4W driveSimData;
+ PxVehicleChassisData chassisData;
+
+ createVehicle4WSimulationData
+ (chassisMass, chassisConvexMesh,
+ 20.0f, wheelConvexMeshes4, wheelCentreOffsets4,
+ *wheelsSimData, driveSimData, chassisData);
+
+ //Instantiate and finalize the vehicle using physx.
+ PxRigidDynamic* vehActor = createVehicleActor4W(chassisData, wheelConvexMeshes4, chassisConvexMesh, scene, physics, material);
+
+ //Create a car.
+ PxVehicleDrive4W* car = PxVehicleDrive4W::allocate(4);
+ car->setup(&physics, vehActor, *wheelsSimData, driveSimData, 0);
+
+ //Free the sim data because we don't need that any more.
+ wheelsSimData->free();
+
+ //Don't forget to add the actor to the scene.
+ {
+ PxSceneWriteLock scopedLock(scene);
+ scene.addActor(*vehActor);
+ }
+
+ //Set up the mapping between wheel and actor shape.
+ car->mWheelsSimData.setWheelShapeMapping(0, 0);
+ car->mWheelsSimData.setWheelShapeMapping(1, 1);
+ car->mWheelsSimData.setWheelShapeMapping(2, 2);
+ car->mWheelsSimData.setWheelShapeMapping(3, 3);
+
+ //Set up the scene query filter data for each suspension line.
+ PxFilterData vehQryFilterData;
+ VehicleSetupVehicleShapeQueryFilterData(&vehQryFilterData);
+ car->mWheelsSimData.setSceneQueryFilterData(0, vehQryFilterData);
+ car->mWheelsSimData.setSceneQueryFilterData(1, vehQryFilterData);
+ car->mWheelsSimData.setSceneQueryFilterData(2, vehQryFilterData);
+ car->mWheelsSimData.setSceneQueryFilterData(3, vehQryFilterData);
+
+ //Set the autogear mode of the instantiate car.
+ car->mDriveDynData.setUseAutoGears(useAutoGearFlag);
+ car->mDriveDynData.forceGearChange(PxVehicleGearsData::eFIRST);
+
+ //Increment the number of vehicles
+ mVehicle = car;
+ mVehicleWheelQueryResults.nbWheelQueryResults = 4;
+ mVehicleWheelQueryResults.wheelQueryResults = mWheelQueryResults->addVehicle(4);
+
+ PxQuat rotation(3.1415 / 2.f, PxVec3(0.f, 0.f, 1.f));
+
+ PxD6Joint* joint = PxD6JointCreate(physics, vehActor, PxTransform(rotation), NULL, PxTransform(rotation));
+
+ joint->setMotion(PxD6Axis::eX, PxD6Motion::eFREE);
+ joint->setMotion(PxD6Axis::eY, PxD6Motion::eFREE);
+ joint->setMotion(PxD6Axis::eZ, PxD6Motion::eFREE);
+
+ joint->setMotion(PxD6Axis::eTWIST, PxD6Motion::eFREE);
+ joint->setMotion(PxD6Axis::eSWING1, PxD6Motion::eLIMITED);
+ joint->setMotion(PxD6Axis::eSWING2, PxD6Motion::eLIMITED);
+
+ PxJointLimitCone limitCone(3.1415/4.f, 3.1415 / 4.f);
+ joint->setSwingLimit(limitCone);
+
+}
+
+
+