aboutsummaryrefslogtreecommitdiff
path: root/PhysX_3.4/Snippets/SnippetVehicleCommon
diff options
context:
space:
mode:
Diffstat (limited to 'PhysX_3.4/Snippets/SnippetVehicleCommon')
-rw-r--r--PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicle4WCreate.cpp321
-rw-r--r--PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicleConcurrency.h122
-rw-r--r--PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicleCreate.cpp339
-rw-r--r--PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicleCreate.h142
-rw-r--r--PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicleFilterShader.cpp58
-rw-r--r--PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicleFilterShader.h62
-rw-r--r--PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicleNoDriveCreate.cpp246
-rw-r--r--PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicleSceneQuery.cpp215
-rw-r--r--PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicleSceneQuery.h126
-rw-r--r--PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicleTankCreate.cpp238
-rw-r--r--PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicleTireFriction.cpp69
-rw-r--r--PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicleTireFriction.h59
-rw-r--r--PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicleWheelQueryResult.h97
13 files changed, 2094 insertions, 0 deletions
diff --git a/PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicle4WCreate.cpp b/PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicle4WCreate.cpp
new file mode 100644
index 00000000..7f21faa2
--- /dev/null
+++ b/PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicle4WCreate.cpp
@@ -0,0 +1,321 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#include "SnippetVehicleCreate.h"
+#include "SnippetVehicleTireFriction.h"
+#include "SnippetVehicleSceneQuery.h"
+
+
+namespace snippetvehicle
+{
+
+using namespace physx;
+
+namespace fourwheel
+{
+
+void computeWheelCenterActorOffsets4W(const PxF32 wheelFrontZ, const PxF32 wheelRearZ, const PxVec3& chassisDims, const PxF32 wheelWidth, const PxF32 wheelRadius, const PxU32 numWheels, PxVec3* wheelCentreOffsets)
+{
+ //chassisDims.z is the distance from the rear of the chassis to the front of the chassis.
+ //The front has z = 0.5*chassisDims.z and the rear has z = -0.5*chassisDims.z.
+ //Compute a position for the front wheel and the rear wheel along the z-axis.
+ //Compute the separation between each wheel along the z-axis.
+ const PxF32 numLeftWheels = numWheels/2.0f;
+ const PxF32 deltaZ = (wheelFrontZ - wheelRearZ)/(numLeftWheels-1.0f);
+ //Set the outside of the left and right wheels to be flush with the chassis.
+ //Set the top of the wheel to be just touching the underside of the chassis.
+ //Begin by setting the rear-left/rear-right/front-left,front-right wheels.
+ wheelCentreOffsets[PxVehicleDrive4WWheelOrder::eREAR_LEFT] = PxVec3((-chassisDims.x + wheelWidth)*0.5f, -(chassisDims.y/2 + wheelRadius), wheelRearZ + 0*deltaZ*0.5f);
+ wheelCentreOffsets[PxVehicleDrive4WWheelOrder::eREAR_RIGHT] = PxVec3((+chassisDims.x - wheelWidth)*0.5f, -(chassisDims.y/2 + wheelRadius), wheelRearZ + 0*deltaZ*0.5f);
+ wheelCentreOffsets[PxVehicleDrive4WWheelOrder::eFRONT_LEFT] = PxVec3((-chassisDims.x + wheelWidth)*0.5f, -(chassisDims.y/2 + wheelRadius), wheelRearZ + (numLeftWheels-1)*deltaZ);
+ wheelCentreOffsets[PxVehicleDrive4WWheelOrder::eFRONT_RIGHT] = PxVec3((+chassisDims.x - wheelWidth)*0.5f, -(chassisDims.y/2 + wheelRadius), wheelRearZ + (numLeftWheels-1)*deltaZ);
+ //Set the remaining wheels.
+ for(PxU32 i = 2, wheelCount = 4; i < numWheels-2; i+=2, wheelCount+=2)
+ {
+ wheelCentreOffsets[wheelCount + 0] = PxVec3((-chassisDims.x + wheelWidth)*0.5f, -(chassisDims.y/2 + wheelRadius), wheelRearZ + i*deltaZ*0.5f);
+ wheelCentreOffsets[wheelCount + 1] = PxVec3((+chassisDims.x - wheelWidth)*0.5f, -(chassisDims.y/2 + wheelRadius), wheelRearZ + i*deltaZ*0.5f);
+ }
+}
+
+void setupWheelsSimulationData
+(const PxF32 wheelMass, const PxF32 wheelMOI, const PxF32 wheelRadius, const PxF32 wheelWidth,
+ const PxU32 numWheels, const PxVec3* wheelCenterActorOffsets,
+ const PxVec3& chassisCMOffset, const PxF32 chassisMass,
+ PxVehicleWheelsSimData* wheelsSimData)
+{
+ //Set up the wheels.
+ PxVehicleWheelData wheels[PX_MAX_NB_WHEELS];
+ {
+ //Set up the wheel data structures with mass, moi, radius, width.
+ for(PxU32 i = 0; i < numWheels; i++)
+ {
+ wheels[i].mMass = wheelMass;
+ wheels[i].mMOI = wheelMOI;
+ wheels[i].mRadius = wheelRadius;
+ wheels[i].mWidth = wheelWidth;
+ }
+
+ //Enable the handbrake for the rear wheels only.
+ wheels[PxVehicleDrive4WWheelOrder::eREAR_LEFT].mMaxHandBrakeTorque=4000.0f;
+ wheels[PxVehicleDrive4WWheelOrder::eREAR_RIGHT].mMaxHandBrakeTorque=4000.0f;
+ //Enable steering for the front wheels only.
+ wheels[PxVehicleDrive4WWheelOrder::eFRONT_LEFT].mMaxSteer=PxPi*0.3333f;
+ wheels[PxVehicleDrive4WWheelOrder::eFRONT_RIGHT].mMaxSteer=PxPi*0.3333f;
+ }
+
+ //Set up the tires.
+ PxVehicleTireData tires[PX_MAX_NB_WHEELS];
+ {
+ //Set up the tires.
+ for(PxU32 i = 0; i < numWheels; i++)
+ {
+ tires[i].mType = TIRE_TYPE_NORMAL;
+ }
+ }
+
+ //Set up the suspensions
+ PxVehicleSuspensionData suspensions[PX_MAX_NB_WHEELS];
+ {
+ //Compute the mass supported by each suspension spring.
+ PxF32 suspSprungMasses[PX_MAX_NB_WHEELS];
+ PxVehicleComputeSprungMasses
+ (numWheels, wheelCenterActorOffsets,
+ chassisCMOffset, chassisMass, 1, suspSprungMasses);
+
+ //Set the suspension data.
+ for(PxU32 i = 0; i < numWheels; i++)
+ {
+ suspensions[i].mMaxCompression = 0.3f;
+ suspensions[i].mMaxDroop = 0.1f;
+ suspensions[i].mSpringStrength = 35000.0f;
+ suspensions[i].mSpringDamperRate = 4500.0f;
+ suspensions[i].mSprungMass = suspSprungMasses[i];
+ }
+
+ //Set the camber angles.
+ const PxF32 camberAngleAtRest=0.0;
+ const PxF32 camberAngleAtMaxDroop=0.01f;
+ const PxF32 camberAngleAtMaxCompression=-0.01f;
+ for(PxU32 i = 0; i < numWheels; i+=2)
+ {
+ suspensions[i + 0].mCamberAtRest = camberAngleAtRest;
+ suspensions[i + 1].mCamberAtRest = -camberAngleAtRest;
+ suspensions[i + 0].mCamberAtMaxDroop = camberAngleAtMaxDroop;
+ suspensions[i + 1].mCamberAtMaxDroop = -camberAngleAtMaxDroop;
+ suspensions[i + 0].mCamberAtMaxCompression = camberAngleAtMaxCompression;
+ suspensions[i + 1].mCamberAtMaxCompression = -camberAngleAtMaxCompression;
+ }
+ }
+
+ //Set up the wheel geometry.
+ PxVec3 suspTravelDirections[PX_MAX_NB_WHEELS];
+ PxVec3 wheelCentreCMOffsets[PX_MAX_NB_WHEELS];
+ PxVec3 suspForceAppCMOffsets[PX_MAX_NB_WHEELS];
+ PxVec3 tireForceAppCMOffsets[PX_MAX_NB_WHEELS];
+ {
+ //Set the geometry data.
+ for(PxU32 i = 0; i < numWheels; i++)
+ {
+ //Vertical suspension travel.
+ suspTravelDirections[i] = PxVec3(0,-1,0);
+
+ //Wheel center offset is offset from rigid body center of mass.
+ wheelCentreCMOffsets[i] =
+ wheelCenterActorOffsets[i] - chassisCMOffset;
+
+ //Suspension force application point 0.3 metres below
+ //rigid body center of mass.
+ suspForceAppCMOffsets[i] =
+ PxVec3(wheelCentreCMOffsets[i].x,-0.3f,wheelCentreCMOffsets[i].z);
+
+ //Tire force application point 0.3 metres below
+ //rigid body center of mass.
+ tireForceAppCMOffsets[i] =
+ PxVec3(wheelCentreCMOffsets[i].x,-0.3f,wheelCentreCMOffsets[i].z);
+ }
+ }
+
+ //Set up the filter data of the raycast that will be issued by each suspension.
+ PxFilterData qryFilterData;
+ setupNonDrivableSurface(qryFilterData);
+
+ //Set the wheel, tire and suspension data.
+ //Set the geometry data.
+ //Set the query filter data
+ for(PxU32 i = 0; i < numWheels; i++)
+ {
+ wheelsSimData->setWheelData(i, wheels[i]);
+ wheelsSimData->setTireData(i, tires[i]);
+ wheelsSimData->setSuspensionData(i, suspensions[i]);
+ wheelsSimData->setSuspTravelDirection(i, suspTravelDirections[i]);
+ wheelsSimData->setWheelCentreOffset(i, wheelCentreCMOffsets[i]);
+ wheelsSimData->setSuspForceAppPointOffset(i, suspForceAppCMOffsets[i]);
+ wheelsSimData->setTireForceAppPointOffset(i, tireForceAppCMOffsets[i]);
+ wheelsSimData->setSceneQueryFilterData(i, qryFilterData);
+ wheelsSimData->setWheelShapeMapping(i, PxI32(i));
+ }
+
+ //Add a front and rear anti-roll bar
+ PxVehicleAntiRollBarData barFront;
+ barFront.mWheel0 = PxVehicleDrive4WWheelOrder::eFRONT_LEFT;
+ barFront.mWheel1 = PxVehicleDrive4WWheelOrder::eFRONT_RIGHT;
+ barFront.mStiffness = 10000.0f;
+ wheelsSimData->addAntiRollBarData(barFront);
+ PxVehicleAntiRollBarData barRear;
+ barRear.mWheel0 = PxVehicleDrive4WWheelOrder::eREAR_LEFT;
+ barRear.mWheel1 = PxVehicleDrive4WWheelOrder::eREAR_RIGHT;
+ barRear.mStiffness = 10000.0f;
+ wheelsSimData->addAntiRollBarData(barRear);
+}
+
+} //namespace fourwheel
+
+PxVehicleDrive4W* createVehicle4W(const VehicleDesc& vehicle4WDesc, PxPhysics* physics, PxCooking* cooking)
+{
+ const PxVec3 chassisDims = vehicle4WDesc.chassisDims;
+ const PxF32 wheelWidth = vehicle4WDesc.wheelWidth;
+ const PxF32 wheelRadius = vehicle4WDesc.wheelRadius;
+ const PxU32 numWheels = vehicle4WDesc.numWheels;
+
+ const PxFilterData& chassisSimFilterData = vehicle4WDesc.chassisSimFilterData;
+ const PxFilterData& wheelSimFilterData = vehicle4WDesc.wheelSimFilterData;
+
+ //Construct a physx actor with shapes for the chassis and wheels.
+ //Set the rigid body mass, moment of inertia, and center of mass offset.
+ PxRigidDynamic* veh4WActor = NULL;
+ {
+ //Construct a convex mesh for a cylindrical wheel.
+ PxConvexMesh* wheelMesh = createWheelMesh(wheelWidth, wheelRadius, *physics, *cooking);
+ //Assume all wheels are identical for simplicity.
+ PxConvexMesh* wheelConvexMeshes[PX_MAX_NB_WHEELS];
+ PxMaterial* wheelMaterials[PX_MAX_NB_WHEELS];
+
+ //Set the meshes and materials for the driven wheels.
+ for(PxU32 i = PxVehicleDrive4WWheelOrder::eFRONT_LEFT; i <= PxVehicleDrive4WWheelOrder::eREAR_RIGHT; i++)
+ {
+ wheelConvexMeshes[i] = wheelMesh;
+ wheelMaterials[i] = vehicle4WDesc.wheelMaterial;
+ }
+ //Set the meshes and materials for the non-driven wheels
+ for(PxU32 i = PxVehicleDrive4WWheelOrder::eREAR_RIGHT + 1; i < numWheels; i++)
+ {
+ wheelConvexMeshes[i] = wheelMesh;
+ wheelMaterials[i] = vehicle4WDesc.wheelMaterial;
+ }
+
+ //Chassis just has a single convex shape for simplicity.
+ PxConvexMesh* chassisConvexMesh = createChassisMesh(chassisDims, *physics, *cooking);
+ PxConvexMesh* chassisConvexMeshes[1] = {chassisConvexMesh};
+ PxMaterial* chassisMaterials[1] = {vehicle4WDesc.chassisMaterial};
+
+ //Rigid body data.
+ PxVehicleChassisData rigidBodyData;
+ rigidBodyData.mMOI = vehicle4WDesc.chassisMOI;
+ rigidBodyData.mMass = vehicle4WDesc.chassisMass;
+ rigidBodyData.mCMOffset = vehicle4WDesc.chassisCMOffset;
+
+ veh4WActor = createVehicleActor
+ (rigidBodyData,
+ wheelMaterials, wheelConvexMeshes, numWheels, wheelSimFilterData,
+ chassisMaterials, chassisConvexMeshes, 1, chassisSimFilterData,
+ *physics);
+ }
+
+ //Set up the sim data for the wheels.
+ PxVehicleWheelsSimData* wheelsSimData = PxVehicleWheelsSimData::allocate(numWheels);
+ {
+ //Compute the wheel center offsets from the origin.
+ PxVec3 wheelCenterActorOffsets[PX_MAX_NB_WHEELS];
+ const PxF32 frontZ = chassisDims.z*0.3f;
+ const PxF32 rearZ = -chassisDims.z*0.3f;
+ fourwheel::computeWheelCenterActorOffsets4W(frontZ, rearZ, chassisDims, wheelWidth, wheelRadius, numWheels, wheelCenterActorOffsets);
+
+ //Set up the simulation data for all wheels.
+ fourwheel::setupWheelsSimulationData
+ (vehicle4WDesc.wheelMass, vehicle4WDesc.wheelMOI, wheelRadius, wheelWidth,
+ numWheels, wheelCenterActorOffsets,
+ vehicle4WDesc.chassisCMOffset, vehicle4WDesc.chassisMass,
+ wheelsSimData);
+ }
+
+ //Set up the sim data for the vehicle drive model.
+ PxVehicleDriveSimData4W driveSimData;
+ {
+ //Diff
+ PxVehicleDifferential4WData diff;
+ diff.mType=PxVehicleDifferential4WData::eDIFF_TYPE_LS_4WD;
+ driveSimData.setDiffData(diff);
+
+ //Engine
+ PxVehicleEngineData engine;
+ engine.mPeakTorque=500.0f;
+ engine.mMaxOmega=600.0f;//approx 6000 rpm
+ driveSimData.setEngineData(engine);
+
+ //Gears
+ PxVehicleGearsData gears;
+ gears.mSwitchTime=0.5f;
+ driveSimData.setGearsData(gears);
+
+ //Clutch
+ PxVehicleClutchData clutch;
+ clutch.mStrength=10.0f;
+ driveSimData.setClutchData(clutch);
+
+ //Ackermann steer accuracy
+ PxVehicleAckermannGeometryData ackermann;
+ ackermann.mAccuracy=1.0f;
+ ackermann.mAxleSeparation=
+ wheelsSimData->getWheelCentreOffset(PxVehicleDrive4WWheelOrder::eFRONT_LEFT).z-
+ wheelsSimData->getWheelCentreOffset(PxVehicleDrive4WWheelOrder::eREAR_LEFT).z;
+ ackermann.mFrontWidth=
+ wheelsSimData->getWheelCentreOffset(PxVehicleDrive4WWheelOrder::eFRONT_RIGHT).x-
+ wheelsSimData->getWheelCentreOffset(PxVehicleDrive4WWheelOrder::eFRONT_LEFT).x;
+ ackermann.mRearWidth=
+ wheelsSimData->getWheelCentreOffset(PxVehicleDrive4WWheelOrder::eREAR_RIGHT).x -
+ wheelsSimData->getWheelCentreOffset(PxVehicleDrive4WWheelOrder::eREAR_LEFT).x;
+ driveSimData.setAckermannGeometryData(ackermann);
+ }
+
+ //Create a vehicle from the wheels and drive sim data.
+ PxVehicleDrive4W* vehDrive4W = PxVehicleDrive4W::allocate(numWheels);
+ vehDrive4W->setup(physics, veh4WActor, *wheelsSimData, driveSimData, numWheels - 4);
+
+ //Configure the userdata
+ configureUserData(vehDrive4W, vehicle4WDesc.actorUserData, vehicle4WDesc.shapeUserDatas);
+
+ //Free the sim data because we don't need that any more.
+ wheelsSimData->free();
+
+ return vehDrive4W;
+}
+
+} //namespace snippetvehicle
+
+
diff --git a/PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicleConcurrency.h b/PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicleConcurrency.h
new file mode 100644
index 00000000..02f03147
--- /dev/null
+++ b/PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicleConcurrency.h
@@ -0,0 +1,122 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#ifndef SNIPPET_VEHICLE_CONCURRENCY_H
+#define SNIPPET_VEHICLE_CONCURRENCY_H
+
+#include "PxPhysicsAPI.h"
+#include <new>
+
+namespace snippetvehicle
+{
+using namespace physx;
+
+//Data structure for quick setup of wheel query data structures.
+class VehicleConcurrency
+{
+public:
+
+ VehicleConcurrency()
+ : mMaxNumVehicles(0),
+ mMaxNumWheelsPerVehicle(0),
+ mVehicleConcurrentUpdates(NULL)
+ {
+ }
+
+ ~VehicleConcurrency()
+ {
+ }
+
+ static VehicleConcurrency* allocate(const PxU32 maxNumVehicles, const PxU32 maxNumWheelsPerVehicle, PxAllocatorCallback& allocator)
+ {
+ const PxU32 byteSize =
+ sizeof(VehicleConcurrency) +
+ sizeof(PxVehicleConcurrentUpdateData)*maxNumVehicles +
+ sizeof(PxVehicleWheelConcurrentUpdateData)*maxNumWheelsPerVehicle*maxNumVehicles;
+
+ PxU8* buffer = static_cast<PxU8*>(allocator.allocate(byteSize, NULL, NULL, 0));
+
+ VehicleConcurrency* vc = reinterpret_cast<VehicleConcurrency*>(buffer);
+ new(vc) VehicleConcurrency();
+ buffer += sizeof(VehicleConcurrency);
+
+ vc->mMaxNumVehicles = maxNumVehicles;
+ vc->mMaxNumWheelsPerVehicle = maxNumWheelsPerVehicle;
+
+ vc->mVehicleConcurrentUpdates = reinterpret_cast<PxVehicleConcurrentUpdateData*>(buffer);
+ buffer += sizeof(PxVehicleConcurrentUpdateData)*maxNumVehicles;
+
+ for(PxU32 i=0;i<maxNumVehicles;i++)
+ {
+ new(vc->mVehicleConcurrentUpdates + i) PxVehicleConcurrentUpdateData();
+
+ vc->mVehicleConcurrentUpdates[i].nbConcurrentWheelUpdates = maxNumWheelsPerVehicle;
+
+ vc->mVehicleConcurrentUpdates[i].concurrentWheelUpdates = reinterpret_cast<PxVehicleWheelConcurrentUpdateData*>(buffer);
+ buffer += sizeof(PxVehicleWheelConcurrentUpdateData)*maxNumWheelsPerVehicle;
+
+ for(PxU32 j = 0; j < maxNumWheelsPerVehicle; j++)
+ {
+ new(vc->mVehicleConcurrentUpdates[i].concurrentWheelUpdates + j) PxVehicleWheelConcurrentUpdateData();
+ }
+
+ }
+
+
+ return vc;
+ }
+
+ //Free allocated buffer for scene queries of suspension raycasts.
+ void free(PxAllocatorCallback& allocator)
+ {
+ allocator.deallocate(this);
+ }
+
+ //Return the PxVehicleConcurrentUpdate for a vehicle specified by an index.
+ PxVehicleConcurrentUpdateData* getVehicleConcurrentUpdate(const PxU32 id)
+ {
+ return (mVehicleConcurrentUpdates + id);
+ }
+
+ //Return the entire array of PxVehicleConcurrentUpdates
+ PxVehicleConcurrentUpdateData* getVehicleConcurrentUpdateBuffer()
+ {
+ return mVehicleConcurrentUpdates;
+ }
+
+private:
+
+ PxU32 mMaxNumVehicles;
+ PxU32 mMaxNumWheelsPerVehicle;
+ PxVehicleConcurrentUpdateData* mVehicleConcurrentUpdates;
+};
+
+} // namespace snippetvehicle
+
+#endif //SNIPPET_VEHICLE_CONCURRENCY_H
diff --git a/PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicleCreate.cpp b/PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicleCreate.cpp
new file mode 100644
index 00000000..1a20da5d
--- /dev/null
+++ b/PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicleCreate.cpp
@@ -0,0 +1,339 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#include <new>
+#include "SnippetVehicleCreate.h"
+#include "SnippetVehicleSceneQuery.h"
+#include "SnippetVehicleFilterShader.h"
+#include "SnippetVehicleTireFriction.h"
+#include "PxPhysicsAPI.h"
+
+namespace snippetvehicle
+{
+
+using namespace physx;
+
+PxRigidStatic* createDrivablePlane(const PxFilterData& simFilterData, PxMaterial* material, PxPhysics* physics)
+{
+ //Add a plane to the scene.
+ PxRigidStatic* groundPlane = PxCreatePlane(*physics, PxPlane(0,1,0,0), *material);
+
+ //Get the plane shape so we can set query and simulation filter data.
+ PxShape* shapes[1];
+ groundPlane->getShapes(shapes, 1);
+
+ //Set the query filter data of the ground plane so that the vehicle raycasts can hit the ground.
+ PxFilterData qryFilterData;
+ setupDrivableSurface(qryFilterData);
+ shapes[0]->setQueryFilterData(qryFilterData);
+
+ //Set the simulation filter data of the ground plane so that it collides with the chassis of a vehicle but not the wheels.
+ shapes[0]->setSimulationFilterData(simFilterData);
+
+ return groundPlane;
+}
+
+static PxConvexMesh* createConvexMesh(const PxVec3* verts, const PxU32 numVerts, PxPhysics& physics, PxCooking& cooking)
+{
+ // Create descriptor for convex mesh
+ PxConvexMeshDesc convexDesc;
+ convexDesc.points.count = numVerts;
+ convexDesc.points.stride = sizeof(PxVec3);
+ convexDesc.points.data = verts;
+ convexDesc.flags = PxConvexFlag::eCOMPUTE_CONVEX;
+
+ PxConvexMesh* convexMesh = NULL;
+ PxDefaultMemoryOutputStream buf;
+ if(cooking.cookConvexMesh(convexDesc, buf))
+ {
+ PxDefaultMemoryInputData id(buf.getData(), buf.getSize());
+ convexMesh = physics.createConvexMesh(id);
+ }
+
+ return convexMesh;
+}
+
+PxConvexMesh* createChassisMesh(const PxVec3 dims, PxPhysics& physics, PxCooking& cooking)
+{
+ const PxF32 x = dims.x*0.5f;
+ const PxF32 y = dims.y*0.5f;
+ const PxF32 z = dims.z*0.5f;
+ PxVec3 verts[8] =
+ {
+ PxVec3(x,y,-z),
+ PxVec3(x,y,z),
+ PxVec3(x,-y,z),
+ PxVec3(x,-y,-z),
+ PxVec3(-x,y,-z),
+ PxVec3(-x,y,z),
+ PxVec3(-x,-y,z),
+ PxVec3(-x,-y,-z)
+ };
+
+ return createConvexMesh(verts,8,physics,cooking);
+}
+
+PxConvexMesh* createWheelMesh(const PxF32 width, const PxF32 radius, PxPhysics& physics, PxCooking& cooking)
+{
+ PxVec3 points[2*16];
+ for(PxU32 i = 0; i < 16; i++)
+ {
+ const PxF32 cosTheta = PxCos(i*PxPi*2.0f/16.0f);
+ const PxF32 sinTheta = PxSin(i*PxPi*2.0f/16.0f);
+ const PxF32 y = radius*cosTheta;
+ const PxF32 z = radius*sinTheta;
+ points[2*i+0] = PxVec3(-width/2.0f, y, z);
+ points[2*i+1] = PxVec3(+width/2.0f, y, z);
+ }
+
+ return createConvexMesh(points,32,physics,cooking);
+}
+
+PxRigidDynamic* createVehicleActor
+(const PxVehicleChassisData& chassisData,
+ PxMaterial** wheelMaterials, PxConvexMesh** wheelConvexMeshes, const PxU32 numWheels, const PxFilterData& wheelSimFilterData,
+ PxMaterial** chassisMaterials, PxConvexMesh** chassisConvexMeshes, const PxU32 numChassisMeshes, const PxFilterData& chassisSimFilterData,
+ PxPhysics& physics)
+{
+ //We need a rigid body actor for the vehicle.
+ //Don't forget to add the actor to the scene after setting up the associated vehicle.
+ PxRigidDynamic* vehActor = physics.createRigidDynamic(PxTransform(PxIdentity));
+
+ //Wheel and chassis query filter data.
+ //Optional: cars don't drive on other cars.
+ PxFilterData wheelQryFilterData;
+ setupNonDrivableSurface(wheelQryFilterData);
+ PxFilterData chassisQryFilterData;
+ setupNonDrivableSurface(chassisQryFilterData);
+
+ //Add all the wheel shapes to the actor.
+ for(PxU32 i = 0; i < numWheels; i++)
+ {
+ PxConvexMeshGeometry geom(wheelConvexMeshes[i]);
+ PxShape* wheelShape=PxRigidActorExt::createExclusiveShape(*vehActor, geom, *wheelMaterials[i]);
+ wheelShape->setQueryFilterData(wheelQryFilterData);
+ wheelShape->setSimulationFilterData(wheelSimFilterData);
+ wheelShape->setLocalPose(PxTransform(PxIdentity));
+ }
+
+ //Add the chassis shapes to the actor.
+ for(PxU32 i = 0; i < numChassisMeshes; i++)
+ {
+ PxShape* chassisShape=PxRigidActorExt::createExclusiveShape(*vehActor, PxConvexMeshGeometry(chassisConvexMeshes[i]), *chassisMaterials[i]);
+ chassisShape->setQueryFilterData(chassisQryFilterData);
+ chassisShape->setSimulationFilterData(chassisSimFilterData);
+ chassisShape->setLocalPose(PxTransform(PxIdentity));
+ }
+
+ vehActor->setMass(chassisData.mMass);
+ vehActor->setMassSpaceInertiaTensor(chassisData.mMOI);
+ vehActor->setCMassLocalPose(PxTransform(chassisData.mCMOffset,PxQuat(PxIdentity)));
+
+ return vehActor;
+}
+
+void configureUserData(PxVehicleWheels* vehicle, ActorUserData* actorUserData, ShapeUserData* shapeUserDatas)
+{
+ if(actorUserData)
+ {
+ vehicle->getRigidDynamicActor()->userData = actorUserData;
+ actorUserData->vehicle = vehicle;
+ }
+
+ if(shapeUserDatas)
+ {
+ PxShape* shapes[PX_MAX_NB_WHEELS + 1];
+ vehicle->getRigidDynamicActor()->getShapes(shapes, PX_MAX_NB_WHEELS + 1);
+ for(PxU32 i = 0; i < vehicle->mWheelsSimData.getNbWheels(); i++)
+ {
+ const PxI32 shapeId = vehicle->mWheelsSimData.getWheelShapeMapping(i);
+ shapes[shapeId]->userData = &shapeUserDatas[i];
+ shapeUserDatas[i].isWheel = true;
+ shapeUserDatas[i].wheelId = i;
+ }
+ }
+}
+
+void customizeVehicleToLengthScale(const PxReal lengthScale, PxRigidDynamic* rigidDynamic, PxVehicleWheelsSimData* wheelsSimData, PxVehicleDriveSimData* driveSimData)
+{
+ //Rigid body center of mass and moment of inertia.
+ {
+ PxTransform t = rigidDynamic->getCMassLocalPose();
+ t.p *= lengthScale;
+ rigidDynamic->setCMassLocalPose(t);
+
+ PxVec3 moi = rigidDynamic->getMassSpaceInertiaTensor();
+ moi *= (lengthScale*lengthScale);
+ rigidDynamic->setMassSpaceInertiaTensor(moi);
+ }
+
+ //Wheels, suspensions, wheel centers, tire/susp force application points.
+ {
+ for(PxU32 i = 0; i < wheelsSimData->getNbWheels(); i++)
+ {
+ PxVehicleWheelData wheelData = wheelsSimData->getWheelData(i);
+ wheelData.mRadius *= lengthScale;
+ wheelData.mWidth *= lengthScale;
+ wheelData.mDampingRate *= lengthScale*lengthScale;
+ wheelData.mMaxBrakeTorque *= lengthScale*lengthScale;
+ wheelData.mMaxHandBrakeTorque *= lengthScale*lengthScale;
+ wheelData.mMOI *= lengthScale*lengthScale;
+ wheelsSimData->setWheelData(i, wheelData);
+
+ PxVehicleSuspensionData suspData = wheelsSimData->getSuspensionData(i);
+ suspData.mMaxCompression *= lengthScale;
+ suspData.mMaxDroop *= lengthScale;
+ wheelsSimData->setSuspensionData(i, suspData);
+
+ PxVec3 v = wheelsSimData->getWheelCentreOffset(i);
+ v *= lengthScale;
+ wheelsSimData->setWheelCentreOffset(i,v);
+
+ v = wheelsSimData->getSuspForceAppPointOffset(i);
+ v *= lengthScale;
+ wheelsSimData->setSuspForceAppPointOffset(i,v);
+
+ v = wheelsSimData->getTireForceAppPointOffset(i);
+ v *= lengthScale;
+ wheelsSimData->setTireForceAppPointOffset(i,v);
+ }
+ }
+
+ //Slow forward speed correction.
+ {
+ wheelsSimData->setSubStepCount(5.0f*lengthScale, 3, 1);
+ wheelsSimData->setMinLongSlipDenominator(4.0f*lengthScale);
+ }
+
+ //Engine
+ if(driveSimData)
+ {
+ PxVehicleEngineData engineData = driveSimData->getEngineData();
+ engineData.mMOI *= lengthScale*lengthScale;
+ engineData.mPeakTorque *= lengthScale*lengthScale;
+ engineData.mDampingRateFullThrottle *= lengthScale*lengthScale;
+ engineData.mDampingRateZeroThrottleClutchEngaged *= lengthScale*lengthScale;
+ engineData.mDampingRateZeroThrottleClutchDisengaged *= lengthScale*lengthScale;
+ driveSimData->setEngineData(engineData);
+ }
+
+ //Clutch.
+ if(driveSimData)
+ {
+ PxVehicleClutchData clutchData = driveSimData->getClutchData();
+ clutchData.mStrength *= lengthScale*lengthScale;
+ driveSimData->setClutchData(clutchData);
+ }
+
+ //Scale the collision meshes too.
+ {
+ PxShape* shapes[16];
+ const PxU32 nbShapes = rigidDynamic->getShapes(shapes, 16);
+ for(PxU32 i = 0; i < nbShapes; i++)
+ {
+ switch(shapes[i]->getGeometryType())
+ {
+ case PxGeometryType::eSPHERE:
+ {
+ PxSphereGeometry sphere;
+ shapes[i]->getSphereGeometry(sphere);
+ sphere.radius *= lengthScale;
+ shapes[i]->setGeometry(sphere);
+ }
+ break;
+ case PxGeometryType::ePLANE:
+ PX_ASSERT(false);
+ break;
+ case PxGeometryType::eCAPSULE:
+ {
+ PxCapsuleGeometry capsule;
+ shapes[i]->getCapsuleGeometry(capsule);
+ capsule.radius *= lengthScale;
+ capsule.halfHeight*= lengthScale;
+ shapes[i]->setGeometry(capsule);
+ }
+ break;
+ case PxGeometryType::eBOX:
+ {
+ PxBoxGeometry box;
+ shapes[i]->getBoxGeometry(box);
+ box.halfExtents *= lengthScale;
+ shapes[i]->setGeometry(box);
+ }
+ break;
+ case PxGeometryType::eCONVEXMESH:
+ {
+ PxConvexMeshGeometry convexMesh;
+ shapes[i]->getConvexMeshGeometry(convexMesh);
+ convexMesh.scale.scale *= lengthScale;
+ shapes[i]->setGeometry(convexMesh);
+ }
+ break;
+ case PxGeometryType::eTRIANGLEMESH:
+ {
+ PxTriangleMeshGeometry triMesh;
+ shapes[i]->getTriangleMeshGeometry(triMesh);
+ triMesh.scale.scale *= lengthScale;
+ shapes[i]->setGeometry(triMesh);
+ }
+ break;
+ case PxGeometryType::eHEIGHTFIELD:
+ {
+ PxHeightFieldGeometry hf;
+ shapes[i]->getHeightFieldGeometry(hf);
+ hf.columnScale *= lengthScale;
+ hf.heightScale *= lengthScale;
+ hf.rowScale *= lengthScale;
+ shapes[i]->setGeometry(hf);
+ }
+ break;
+ case PxGeometryType::eINVALID:
+ case PxGeometryType::eGEOMETRY_COUNT:
+ break;
+ }
+ }
+ }
+}
+
+void customizeVehicleToLengthScale(const PxReal lengthScale, PxRigidDynamic* rigidDynamic, PxVehicleWheelsSimData* wheelsSimData, PxVehicleDriveSimData4W* driveSimData)
+{
+ customizeVehicleToLengthScale(lengthScale, rigidDynamic, wheelsSimData, static_cast<PxVehicleDriveSimData*>(driveSimData));
+
+ //Ackermann geometry.
+ if(driveSimData)
+ {
+ PxVehicleAckermannGeometryData ackermannData = driveSimData->getAckermannGeometryData();
+ ackermannData.mAxleSeparation *= lengthScale;
+ ackermannData.mFrontWidth *= lengthScale;
+ ackermannData.mRearWidth *= lengthScale;
+ driveSimData->setAckermannGeometryData(ackermannData);
+ }
+}
+
+} // namespace snippetvehicle
diff --git a/PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicleCreate.h b/PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicleCreate.h
new file mode 100644
index 00000000..ccd35cb7
--- /dev/null
+++ b/PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicleCreate.h
@@ -0,0 +1,142 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#ifndef SNIPPET_VEHICLE_COMMON_H
+#define SNIPPET_VEHICLE_COMMON_H
+
+#include "PxPhysicsAPI.h"
+#include "vehicle/PxVehicleDriveTank.h"
+#include "vehicle/PxVehicleNoDrive.h"
+
+namespace snippetvehicle
+{
+
+using namespace physx;
+
+////////////////////////////////////////////////
+
+PxRigidStatic* createDrivablePlane(const PxFilterData& simFilterData, PxMaterial* material, PxPhysics* physics);
+
+////////////////////////////////////////////////
+
+struct ActorUserData
+{
+ ActorUserData()
+ : vehicle(NULL),
+ actor(NULL)
+ {
+ }
+
+ const PxVehicleWheels* vehicle;
+ const PxActor* actor;
+};
+
+struct ShapeUserData
+{
+ ShapeUserData()
+ : isWheel(false),
+ wheelId(0xffffffff)
+ {
+ }
+
+ bool isWheel;
+ PxU32 wheelId;
+};
+
+
+struct VehicleDesc
+{
+ VehicleDesc()
+ : chassisMass(0.0f),
+ chassisDims(PxVec3(0.0f, 0.0f, 0.0f)),
+ chassisMOI(PxVec3(0.0f, 0.0f, 0.0f)),
+ chassisCMOffset(PxVec3(0.0f, 0.0f, 0.0f)),
+ chassisMaterial(NULL),
+ wheelMass(0.0f),
+ wheelWidth(0.0f),
+ wheelRadius(0.0f),
+ wheelMOI(0.0f),
+ wheelMaterial(NULL),
+ actorUserData(NULL),
+ shapeUserDatas(NULL)
+ {
+ }
+
+ PxF32 chassisMass;
+ PxVec3 chassisDims;
+ PxVec3 chassisMOI;
+ PxVec3 chassisCMOffset;
+ PxMaterial* chassisMaterial;
+ PxFilterData chassisSimFilterData; //word0 = collide type, word1 = collide against types, word2 = PxPairFlags
+
+ PxF32 wheelMass;
+ PxF32 wheelWidth;
+ PxF32 wheelRadius;
+ PxF32 wheelMOI;
+ PxMaterial* wheelMaterial;
+ PxU32 numWheels;
+ PxFilterData wheelSimFilterData; //word0 = collide type, word1 = collide against types, word2 = PxPairFlags
+
+ ActorUserData* actorUserData;
+ ShapeUserData* shapeUserDatas;
+};
+
+PxVehicleDrive4W* createVehicle4W(const VehicleDesc& vehDesc, PxPhysics* physics, PxCooking* cooking);
+
+PxVehicleDriveTank* createVehicleTank(const VehicleDesc& vehDesc, PxPhysics* physics, PxCooking* cooking);
+
+PxVehicleNoDrive* createVehicleNoDrive(const VehicleDesc& vehDesc, PxPhysics* physics, PxCooking* cooking);
+
+////////////////////////////////////////////////
+
+PxConvexMesh* createChassisMesh(const PxVec3 dims, PxPhysics& physics, PxCooking& cooking);
+
+PxConvexMesh* createWheelMesh(const PxF32 width, const PxF32 radius, PxPhysics& physics, PxCooking& cooking);
+
+////////////////////////////////////////////////
+
+void customizeVehicleToLengthScale(const PxReal lengthScale, PxRigidDynamic* rigidDynamic, PxVehicleWheelsSimData* wheelsSimData, PxVehicleDriveSimData* driveSimData);
+
+void customizeVehicleToLengthScale(const PxReal lengthScale, PxRigidDynamic* rigidDynamic, PxVehicleWheelsSimData* wheelsSimData, PxVehicleDriveSimData4W* driveSimData);
+
+////////////////////////////////////////////////
+
+PxRigidDynamic* createVehicleActor
+(const PxVehicleChassisData& chassisData,
+ PxMaterial** wheelMaterials, PxConvexMesh** wheelConvexMeshes, const PxU32 numWheels, const PxFilterData& wheelSimFilterData,
+ PxMaterial** chassisMaterials, PxConvexMesh** chassisConvexMeshes, const PxU32 numChassisMeshes, const PxFilterData& chassisSimFilterData,
+ PxPhysics& physics);
+
+void configureUserData(PxVehicleWheels* vehicle, ActorUserData* actorUserData, ShapeUserData* shapeUserDatas);
+
+////////////////////////////////////////////////
+
+} // namespace snippetvehicle
+
+#endif //SNIPPET_VEHICLE_COMMON_H
diff --git a/PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicleFilterShader.cpp b/PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicleFilterShader.cpp
new file mode 100644
index 00000000..bde10029
--- /dev/null
+++ b/PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicleFilterShader.cpp
@@ -0,0 +1,58 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#include <new>
+#include "SnippetVehicleFilterShader.h"
+#include "PxPhysicsAPI.h"
+
+namespace snippetvehicle
+{
+
+using namespace physx;
+
+PxFilterFlags VehicleFilterShader
+(PxFilterObjectAttributes attributes0, PxFilterData filterData0,
+ PxFilterObjectAttributes attributes1, PxFilterData filterData1,
+ PxPairFlags& pairFlags, const void* constantBlock, PxU32 constantBlockSize)
+{
+ PX_UNUSED(attributes0);
+ PX_UNUSED(attributes1);
+ PX_UNUSED(constantBlock);
+ PX_UNUSED(constantBlockSize);
+
+ if( (0 == (filterData0.word0 & filterData1.word1)) && (0 == (filterData1.word0 & filterData0.word1)) )
+ return PxFilterFlag::eSUPPRESS;
+
+ pairFlags = PxPairFlag::eCONTACT_DEFAULT;
+ pairFlags |= PxPairFlags(PxU16(filterData0.word2 | filterData1.word2));
+
+ return PxFilterFlags();
+}
+
+} // namespace snippetvehicle
diff --git a/PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicleFilterShader.h b/PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicleFilterShader.h
new file mode 100644
index 00000000..e6ada9fa
--- /dev/null
+++ b/PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicleFilterShader.h
@@ -0,0 +1,62 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#ifndef SNIPPET_VEHICLE_FILTERSHADER_H
+#define SNIPPET_VEHICLE_FILTERSHADER_H
+
+#include "PxPhysicsAPI.h"
+
+namespace snippetvehicle
+{
+
+using namespace physx;
+
+enum
+{
+ COLLISION_FLAG_GROUND = 1 << 0,
+ COLLISION_FLAG_WHEEL = 1 << 1,
+ COLLISION_FLAG_CHASSIS = 1 << 2,
+ COLLISION_FLAG_OBSTACLE = 1 << 3,
+ COLLISION_FLAG_DRIVABLE_OBSTACLE= 1 << 4,
+
+ COLLISION_FLAG_GROUND_AGAINST = COLLISION_FLAG_CHASSIS | COLLISION_FLAG_OBSTACLE | COLLISION_FLAG_DRIVABLE_OBSTACLE,
+ COLLISION_FLAG_WHEEL_AGAINST = COLLISION_FLAG_WHEEL | COLLISION_FLAG_CHASSIS | COLLISION_FLAG_OBSTACLE,
+ COLLISION_FLAG_CHASSIS_AGAINST = COLLISION_FLAG_GROUND | COLLISION_FLAG_WHEEL | COLLISION_FLAG_CHASSIS | COLLISION_FLAG_OBSTACLE | COLLISION_FLAG_DRIVABLE_OBSTACLE,
+ COLLISION_FLAG_OBSTACLE_AGAINST = COLLISION_FLAG_GROUND | COLLISION_FLAG_WHEEL | COLLISION_FLAG_CHASSIS | COLLISION_FLAG_OBSTACLE | COLLISION_FLAG_DRIVABLE_OBSTACLE,
+ COLLISION_FLAG_DRIVABLE_OBSTACLE_AGAINST= COLLISION_FLAG_GROUND | COLLISION_FLAG_CHASSIS | COLLISION_FLAG_OBSTACLE | COLLISION_FLAG_DRIVABLE_OBSTACLE
+};
+
+PxFilterFlags VehicleFilterShader
+(PxFilterObjectAttributes attributes0, PxFilterData filterData0,
+ PxFilterObjectAttributes attributes1, PxFilterData filterData1,
+ PxPairFlags& pairFlags, const void* constantBlock, PxU32 constantBlockSize);
+
+} // namespace snippetvehicle
+
+#endif //SNIPPET_VEHICLE_FILTERSHADER_H
diff --git a/PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicleNoDriveCreate.cpp b/PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicleNoDriveCreate.cpp
new file mode 100644
index 00000000..6f08b9dd
--- /dev/null
+++ b/PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicleNoDriveCreate.cpp
@@ -0,0 +1,246 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#include "SnippetVehicleCreate.h"
+#include "SnippetVehicleTireFriction.h"
+#include "SnippetVehicleSceneQuery.h"
+
+
+
+namespace snippetvehicle
+{
+
+using namespace physx;
+
+namespace nodrive
+{
+
+void computeWheelCenterActorOffsets
+(const PxF32 wheelFrontZ, const PxF32 wheelRearZ, const PxVec3& chassisDims, const PxF32 wheelWidth, const PxF32 wheelRadius, const PxU32 numWheels, PxVec3* wheelCentreOffsets)
+{
+ //chassisDims.z is the distance from the rear of the chassis to the front of the chassis.
+ //The front has z = 0.5*chassisDims.z and the rear has z = -0.5*chassisDims.z.
+ //Compute a position for the front wheel and the rear wheel along the z-axis.
+ //Compute the separation between each wheel along the z-axis.
+ const PxF32 numLeftWheels = numWheels/2.0f;
+ const PxF32 deltaZ = (wheelFrontZ - wheelRearZ)/(numLeftWheels-1.0f);
+ //Set the outside of the left and right wheels to be flush with the chassis.
+ //Set the top of the wheel to be just touching the underside of the chassis.
+ for(PxU32 i = 0; i < numWheels; i+=2)
+ {
+ //Left wheel offset from origin.
+ wheelCentreOffsets[i + 0] = PxVec3((-chassisDims.x + wheelWidth)*0.5f, -(chassisDims.y/2 + wheelRadius), wheelRearZ + i*deltaZ*0.5f);
+ //Right wheel offsets from origin.
+ wheelCentreOffsets[i + 1] = PxVec3((+chassisDims.x - wheelWidth)*0.5f, -(chassisDims.y/2 + wheelRadius), wheelRearZ + i*deltaZ*0.5f);
+ }
+}
+
+void setupWheelsSimulationData
+(const PxF32 wheelMass, const PxF32 wheelMOI, const PxF32 wheelRadius, const PxF32 wheelWidth,
+ const PxU32 numWheels, const PxVec3* wheelCenterActorOffsets,
+ const PxVec3& chassisCMOffset, const PxF32 chassisMass,
+ PxVehicleWheelsSimData* wheelsSimData)
+{
+ //Set up the wheels.
+ PxVehicleWheelData wheels[PX_MAX_NB_WHEELS];
+ {
+ //Set up the wheel data structures with mass, moi, radius, width.
+ for(PxU32 i = 0; i < numWheels; i++)
+ {
+ wheels[i].mMass = wheelMass;
+ wheels[i].mMOI = wheelMOI;
+ wheels[i].mRadius = wheelRadius;
+ wheels[i].mWidth = wheelWidth;
+ }
+ }
+
+ //Set up the tires.
+ PxVehicleTireData tires[PX_MAX_NB_WHEELS];
+ {
+ //Set up the tires.
+ for(PxU32 i = 0; i < numWheels; i++)
+ {
+ tires[i].mType = TIRE_TYPE_NORMAL;
+ }
+ }
+
+ //Set up the suspensions
+ PxVehicleSuspensionData suspensions[PX_MAX_NB_WHEELS];
+ {
+ //Compute the mass supported by each suspension spring.
+ PxF32 suspSprungMasses[PX_MAX_NB_WHEELS];
+ PxVehicleComputeSprungMasses(numWheels, wheelCenterActorOffsets, chassisCMOffset, chassisMass, 1, suspSprungMasses);
+
+ //Set the suspension data.
+ for(PxU32 i = 0; i < numWheels; i++)
+ {
+ suspensions[i].mMaxCompression = 0.3f;
+ suspensions[i].mMaxDroop = 0.1f;
+ suspensions[i].mSpringStrength = 35000.0f;
+ suspensions[i].mSpringDamperRate = 4500.0f;
+ suspensions[i].mSprungMass = suspSprungMasses[i];
+ }
+
+ //Set the camber angles.
+ const PxF32 camberAngleAtRest=0.0;
+ const PxF32 camberAngleAtMaxDroop=0.01f;
+ const PxF32 camberAngleAtMaxCompression=-0.01f;
+ for(PxU32 i = 0; i < numWheels; i+=2)
+ {
+ suspensions[i + 0].mCamberAtRest = camberAngleAtRest;
+ suspensions[i + 1].mCamberAtRest = -camberAngleAtRest;
+ suspensions[i + 0].mCamberAtMaxDroop = camberAngleAtMaxDroop;
+ suspensions[i + 1].mCamberAtMaxDroop = -camberAngleAtMaxDroop;
+ suspensions[i + 0].mCamberAtMaxCompression = camberAngleAtMaxCompression;
+ suspensions[i + 1].mCamberAtMaxCompression = -camberAngleAtMaxCompression;
+ }
+ }
+
+ //Set up the wheel geometry.
+ PxVec3 suspTravelDirections[PX_MAX_NB_WHEELS];
+ PxVec3 wheelCentreCMOffsets[PX_MAX_NB_WHEELS];
+ PxVec3 suspForceAppCMOffsets[PX_MAX_NB_WHEELS];
+ PxVec3 tireForceAppCMOffsets[PX_MAX_NB_WHEELS];
+ {
+ //Set the geometry data.
+ for(PxU32 i = 0; i < numWheels; i++)
+ {
+ //Vertical suspension travel.
+ suspTravelDirections[i] = PxVec3(0,-1,0);
+
+ //Wheel center offset is offset from rigid body center of mass.
+ wheelCentreCMOffsets[i] = wheelCenterActorOffsets[i] - chassisCMOffset;
+
+ //Suspension force application point 0.3 metres below rigid body center of mass.
+ suspForceAppCMOffsets[i]=PxVec3(wheelCentreCMOffsets[i].x,-0.3f,wheelCentreCMOffsets[i].z);
+
+ //Tire force application point 0.3 metres below rigid body center of mass.
+ tireForceAppCMOffsets[i]=PxVec3(wheelCentreCMOffsets[i].x,-0.3f,wheelCentreCMOffsets[i].z);
+ }
+ }
+
+ //Set up the filter data of the raycast that will be issued by each suspension.
+ PxFilterData qryFilterData;
+ setupNonDrivableSurface(qryFilterData);
+
+ //Set the wheel, tire and suspension data.
+ //Set the geometry data.
+ //Set the query filter data
+ for(PxU32 i = 0; i < numWheels; i++)
+ {
+ wheelsSimData->setWheelData(i, wheels[i]);
+ wheelsSimData->setTireData(i, tires[i]);
+ wheelsSimData->setSuspensionData(i, suspensions[i]);
+ wheelsSimData->setSuspTravelDirection(i, suspTravelDirections[i]);
+ wheelsSimData->setWheelCentreOffset(i, wheelCentreCMOffsets[i]);
+ wheelsSimData->setSuspForceAppPointOffset(i, suspForceAppCMOffsets[i]);
+ wheelsSimData->setTireForceAppPointOffset(i, tireForceAppCMOffsets[i]);
+ wheelsSimData->setSceneQueryFilterData(i, qryFilterData);
+ wheelsSimData->setWheelShapeMapping(i, PxI32(i));
+ }
+}
+
+}// namespace nodrive
+
+PxVehicleNoDrive* createVehicleNoDrive(const VehicleDesc& vehicleDesc, PxPhysics* physics, PxCooking* cooking)
+{
+ const PxVec3 chassisDims = vehicleDesc.chassisDims;
+ const PxF32 wheelWidth = vehicleDesc.wheelWidth;
+ const PxF32 wheelRadius = vehicleDesc.wheelRadius;
+ const PxU32 numWheels = vehicleDesc.numWheels;
+
+ const PxFilterData& chassisSimFilterData = vehicleDesc.chassisSimFilterData;
+ const PxFilterData& wheelSimFilterData = vehicleDesc.wheelSimFilterData;
+
+ //Construct a physx actor with shapes for the chassis and wheels.
+ //Set the rigid body mass, moment of inertia, and center of mass offset.
+ PxRigidDynamic* vehActor = NULL;
+ {
+ //Construct a convex mesh for a cylindrical wheel.
+ PxConvexMesh* wheelMesh = createWheelMesh(wheelWidth, wheelRadius, *physics, *cooking);
+ //Assume all wheels are identical for simplicity.
+ PxConvexMesh* wheelConvexMeshes[PX_MAX_NB_WHEELS];
+ PxMaterial* wheelMaterials[PX_MAX_NB_WHEELS];
+
+ //Set the meshes and materials for the driven wheels.
+ for(PxU32 i = 0; i < numWheels; i++)
+ {
+ wheelConvexMeshes[i] = wheelMesh;
+ wheelMaterials[i] = vehicleDesc.wheelMaterial;
+ }
+
+ //Chassis just has a single convex shape for simplicity.
+ PxConvexMesh* chassisConvexMesh = createChassisMesh(chassisDims, *physics, *cooking);
+ PxConvexMesh* chassisConvexMeshes[1] = {chassisConvexMesh};
+ PxMaterial* chassisMaterials[1] = {vehicleDesc.chassisMaterial};
+
+ //Rigid body data.
+ PxVehicleChassisData rigidBodyData;
+ rigidBodyData.mMOI = vehicleDesc.chassisMOI;
+ rigidBodyData.mMass = vehicleDesc.chassisMass;
+ rigidBodyData.mCMOffset = vehicleDesc.chassisCMOffset;
+
+ vehActor = createVehicleActor
+ (rigidBodyData,
+ wheelMaterials, wheelConvexMeshes, numWheels, wheelSimFilterData,
+ chassisMaterials, chassisConvexMeshes, 1, chassisSimFilterData,
+ *physics);
+ }
+
+ //Set up the sim data for the wheels.
+ PxVehicleWheelsSimData* wheelsSimData = PxVehicleWheelsSimData::allocate(numWheels);
+ {
+ //Compute the wheel center offsets from the origin.
+ PxVec3 wheelCentreActorOffsets[PX_MAX_NB_WHEELS];
+ const PxF32 frontZ = chassisDims.z*0.3f;
+ const PxF32 rearZ = -chassisDims.z*0.3f;
+ nodrive::computeWheelCenterActorOffsets(frontZ, rearZ, chassisDims, wheelWidth, wheelRadius, numWheels, wheelCentreActorOffsets);
+
+ nodrive::setupWheelsSimulationData
+ (vehicleDesc.wheelMass, vehicleDesc.wheelMOI, wheelRadius, wheelWidth,
+ numWheels, wheelCentreActorOffsets,
+ vehicleDesc.chassisCMOffset, vehicleDesc.chassisMass,
+ wheelsSimData);
+ }
+
+ //Create a vehicle from the wheels and drive sim data.
+ PxVehicleNoDrive* vehDriveNoDrive = PxVehicleNoDrive::allocate(numWheels);
+ vehDriveNoDrive->setup(physics, vehActor, *wheelsSimData);
+
+ //Configure the userdata
+ configureUserData(vehDriveNoDrive, vehicleDesc.actorUserData, vehicleDesc.shapeUserDatas);
+
+ //Free the sim data because we don't need that any more.
+ wheelsSimData->free();
+
+ return vehDriveNoDrive;
+}
+
+} // namespace snippetvehicle
+
diff --git a/PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicleSceneQuery.cpp b/PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicleSceneQuery.cpp
new file mode 100644
index 00000000..bba25679
--- /dev/null
+++ b/PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicleSceneQuery.cpp
@@ -0,0 +1,215 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#include <new>
+#include "SnippetVehicleSceneQuery.h"
+#include "PxPhysicsAPI.h"
+
+namespace snippetvehicle
+{
+
+using namespace physx;
+
+void setupDrivableSurface(PxFilterData& filterData)
+{
+ filterData.word3 = static_cast<PxU32>(DRIVABLE_SURFACE);
+}
+
+void setupNonDrivableSurface(PxFilterData& filterData)
+{
+ filterData.word3 = UNDRIVABLE_SURFACE;
+}
+
+PxQueryHitType::Enum WheelSceneQueryPreFilterBlocking
+(PxFilterData filterData0, PxFilterData filterData1,
+ const void* constantBlock, PxU32 constantBlockSize,
+ PxHitFlags& queryFlags)
+{
+ //filterData0 is the vehicle suspension query.
+ //filterData1 is the shape potentially hit by the query.
+ PX_UNUSED(filterData0);
+ PX_UNUSED(constantBlock);
+ PX_UNUSED(constantBlockSize);
+ PX_UNUSED(queryFlags);
+ return ((0 == (filterData1.word3 & DRIVABLE_SURFACE)) ? PxQueryHitType::eNONE : PxQueryHitType::eBLOCK);
+}
+
+PxQueryHitType::Enum WheelSceneQueryPostFilterBlocking
+(PxFilterData filterData0, PxFilterData filterData1,
+ const void* constantBlock, PxU32 constantBlockSize,
+ const PxQueryHit& hit)
+{
+ PX_UNUSED(filterData0);
+ PX_UNUSED(filterData1);
+ PX_UNUSED(constantBlock);
+ PX_UNUSED(constantBlockSize);
+ if((static_cast<const PxSweepHit&>(hit)).hadInitialOverlap())
+ return PxQueryHitType::eNONE;
+ return PxQueryHitType::eBLOCK;
+}
+
+PxQueryHitType::Enum WheelSceneQueryPreFilterNonBlocking
+(PxFilterData filterData0, PxFilterData filterData1,
+const void* constantBlock, PxU32 constantBlockSize,
+PxHitFlags& queryFlags)
+{
+ //filterData0 is the vehicle suspension query.
+ //filterData1 is the shape potentially hit by the query.
+ PX_UNUSED(filterData0);
+ PX_UNUSED(constantBlock);
+ PX_UNUSED(constantBlockSize);
+ PX_UNUSED(queryFlags);
+ return ((0 == (filterData1.word3 & DRIVABLE_SURFACE)) ? PxQueryHitType::eNONE : PxQueryHitType::eTOUCH);
+}
+
+PxQueryHitType::Enum WheelSceneQueryPostFilterNonBlocking
+(PxFilterData filterData0, PxFilterData filterData1,
+const void* constantBlock, PxU32 constantBlockSize,
+const PxQueryHit& hit)
+{
+ PX_UNUSED(filterData0);
+ PX_UNUSED(filterData1);
+ PX_UNUSED(constantBlock);
+ PX_UNUSED(constantBlockSize);
+ if ((static_cast<const PxSweepHit&>(hit)).hadInitialOverlap())
+ return PxQueryHitType::eNONE;
+ return PxQueryHitType::eTOUCH;
+}
+
+VehicleSceneQueryData::VehicleSceneQueryData()
+: mNumQueriesPerBatch(0),
+ mNumHitResultsPerQuery(0),
+ mRaycastResults(NULL),
+ mRaycastHitBuffer(NULL),
+ mPreFilterShader(NULL),
+ mPostFilterShader(NULL)
+{
+}
+
+VehicleSceneQueryData::~VehicleSceneQueryData()
+{
+}
+
+VehicleSceneQueryData* VehicleSceneQueryData::allocate
+(const PxU32 maxNumVehicles, const PxU32 maxNumWheelsPerVehicle, const PxU32 maxNumHitPointsPerWheel, const PxU32 numVehiclesInBatch,
+ PxBatchQueryPreFilterShader preFilterShader, PxBatchQueryPostFilterShader postFilterShader,
+ PxAllocatorCallback& allocator)
+{
+ const PxU32 sqDataSize = ((sizeof(VehicleSceneQueryData) + 15) & ~15);
+
+ const PxU32 maxNumWheels = maxNumVehicles*maxNumWheelsPerVehicle;
+ const PxU32 raycastResultSize = ((sizeof(PxRaycastQueryResult)*maxNumWheels + 15) & ~15);
+ const PxU32 sweepResultSize = ((sizeof(PxSweepQueryResult)*maxNumWheels + 15) & ~15);
+
+ const PxU32 maxNumHitPoints = maxNumWheels*maxNumHitPointsPerWheel;
+ const PxU32 raycastHitSize = ((sizeof(PxRaycastHit)*maxNumHitPoints + 15) & ~15);
+ const PxU32 sweepHitSize = ((sizeof(PxSweepHit)*maxNumHitPoints + 15) & ~15);
+
+ const PxU32 size = sqDataSize + raycastResultSize + raycastHitSize + sweepResultSize + sweepHitSize;
+ PxU8* buffer = static_cast<PxU8*>(allocator.allocate(size, NULL, NULL, 0));
+
+ VehicleSceneQueryData* sqData = new(buffer) VehicleSceneQueryData();
+ sqData->mNumQueriesPerBatch = numVehiclesInBatch*maxNumWheelsPerVehicle;
+ sqData->mNumHitResultsPerQuery = maxNumHitPointsPerWheel;
+ buffer += sqDataSize;
+
+ sqData->mRaycastResults = reinterpret_cast<PxRaycastQueryResult*>(buffer);
+ buffer += raycastResultSize;
+
+ sqData->mRaycastHitBuffer = reinterpret_cast<PxRaycastHit*>(buffer);
+ buffer += raycastHitSize;
+
+ sqData->mSweepResults = reinterpret_cast<PxSweepQueryResult*>(buffer);
+ buffer += sweepResultSize;
+
+ sqData->mSweepHitBuffer = reinterpret_cast<PxSweepHit*>(buffer);
+ buffer += sweepHitSize;
+
+ for (PxU32 i = 0; i < maxNumWheels; i++)
+ {
+ new(sqData->mRaycastResults + i) PxRaycastQueryResult();
+ new(sqData->mSweepResults + i) PxSweepQueryResult();
+ }
+
+ for (PxU32 i = 0; i < maxNumHitPoints; i++)
+ {
+ new(sqData->mRaycastHitBuffer + i) PxRaycastHit();
+ new(sqData->mSweepHitBuffer + i) PxSweepHit();
+ }
+
+ sqData->mPreFilterShader = preFilterShader;
+ sqData->mPostFilterShader = postFilterShader;
+
+ return sqData;
+}
+
+void VehicleSceneQueryData::free(PxAllocatorCallback& allocator)
+{
+ allocator.deallocate(this);
+}
+
+PxBatchQuery* VehicleSceneQueryData::setUpBatchedSceneQuery(const PxU32 batchId, const VehicleSceneQueryData& vehicleSceneQueryData, PxScene* scene)
+{
+ const PxU32 maxNumQueriesInBatch = vehicleSceneQueryData.mNumQueriesPerBatch;
+ const PxU32 maxNumHitResultsInBatch = vehicleSceneQueryData.mNumQueriesPerBatch*vehicleSceneQueryData.mNumHitResultsPerQuery;
+
+ PxBatchQueryDesc sqDesc(maxNumQueriesInBatch, maxNumQueriesInBatch, 0);
+
+ sqDesc.queryMemory.userRaycastResultBuffer = vehicleSceneQueryData.mRaycastResults + batchId*maxNumQueriesInBatch;
+ sqDesc.queryMemory.userRaycastTouchBuffer = vehicleSceneQueryData.mRaycastHitBuffer + batchId*maxNumHitResultsInBatch;
+ sqDesc.queryMemory.raycastTouchBufferSize = maxNumHitResultsInBatch;
+
+ sqDesc.queryMemory.userSweepResultBuffer = vehicleSceneQueryData.mSweepResults + batchId*maxNumQueriesInBatch;
+ sqDesc.queryMemory.userSweepTouchBuffer = vehicleSceneQueryData.mSweepHitBuffer + batchId*maxNumHitResultsInBatch;
+ sqDesc.queryMemory.sweepTouchBufferSize = maxNumHitResultsInBatch;
+
+ sqDesc.preFilterShader = vehicleSceneQueryData.mPreFilterShader;
+
+ sqDesc.postFilterShader = vehicleSceneQueryData.mPostFilterShader;
+
+ return scene->createBatchQuery(sqDesc);
+}
+
+PxRaycastQueryResult* VehicleSceneQueryData::getRaycastQueryResultBuffer(const PxU32 batchId)
+{
+ return (mRaycastResults + batchId*mNumQueriesPerBatch);
+}
+
+PxSweepQueryResult* VehicleSceneQueryData::getSweepQueryResultBuffer(const PxU32 batchId)
+{
+ return (mSweepResults + batchId*mNumQueriesPerBatch);
+}
+
+
+PxU32 VehicleSceneQueryData::getQueryResultBufferSize() const
+{
+ return mNumQueriesPerBatch;
+}
+
+} // namespace snippetvehicle
diff --git a/PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicleSceneQuery.h b/PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicleSceneQuery.h
new file mode 100644
index 00000000..5e25e835
--- /dev/null
+++ b/PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicleSceneQuery.h
@@ -0,0 +1,126 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#ifndef SNIPPET_VEHICLE_SCENEQUERY_H
+#define SNIPPET_VEHICLE_SCENEQUERY_H
+
+#include "PxPhysicsAPI.h"
+
+namespace snippetvehicle
+{
+
+using namespace physx;
+
+enum
+{
+ DRIVABLE_SURFACE = 0xffff0000,
+ UNDRIVABLE_SURFACE = 0x0000ffff
+};
+
+void setupDrivableSurface(PxFilterData& filterData);
+
+void setupNonDrivableSurface(PxFilterData& filterData);
+
+
+PxQueryHitType::Enum WheelSceneQueryPreFilterBlocking
+(PxFilterData filterData0, PxFilterData filterData1,
+ const void* constantBlock, PxU32 constantBlockSize,
+ PxHitFlags& queryFlags);
+
+PxQueryHitType::Enum WheelSceneQueryPostFilterBlocking
+(PxFilterData queryFilterData, PxFilterData objectFilterData,
+ const void* constantBlock, PxU32 constantBlockSize,
+ const PxQueryHit& hit);
+
+PxQueryHitType::Enum WheelSceneQueryPreFilterNonBlocking
+(PxFilterData filterData0, PxFilterData filterData1,
+const void* constantBlock, PxU32 constantBlockSize,
+PxHitFlags& queryFlags);
+
+PxQueryHitType::Enum WheelSceneQueryPostFilterNonBlocking
+(PxFilterData queryFilterData, PxFilterData objectFilterData,
+const void* constantBlock, PxU32 constantBlockSize,
+const PxQueryHit& hit);
+
+
+//Data structure for quick setup of scene queries for suspension queries.
+class VehicleSceneQueryData
+{
+public:
+ VehicleSceneQueryData();
+ ~VehicleSceneQueryData();
+
+ //Allocate scene query data for up to maxNumVehicles and up to maxNumWheelsPerVehicle with numVehiclesInBatch per batch query.
+ static VehicleSceneQueryData* allocate
+ (const PxU32 maxNumVehicles, const PxU32 maxNumWheelsPerVehicle, const PxU32 maxNumHitPointsPerWheel, const PxU32 numVehiclesInBatch,
+ PxBatchQueryPreFilterShader preFilterShader, PxBatchQueryPostFilterShader postFilterShader,
+ PxAllocatorCallback& allocator);
+
+ //Free allocated buffers.
+ void free(PxAllocatorCallback& allocator);
+
+ //Create a PxBatchQuery instance that will be used for a single specified batch.
+ static PxBatchQuery* setUpBatchedSceneQuery(const PxU32 batchId, const VehicleSceneQueryData& vehicleSceneQueryData, PxScene* scene);
+
+ //Return an array of scene query results for a single specified batch.
+ PxRaycastQueryResult* getRaycastQueryResultBuffer(const PxU32 batchId);
+
+ //Return an array of scene query results for a single specified batch.
+ PxSweepQueryResult* getSweepQueryResultBuffer(const PxU32 batchId);
+
+ //Get the number of scene query results that have been allocated for a single batch.
+ PxU32 getQueryResultBufferSize() const;
+
+private:
+
+ //Number of queries per batch
+ PxU32 mNumQueriesPerBatch;
+
+ //Number of hit results per query
+ PxU32 mNumHitResultsPerQuery;
+
+ //One result for each wheel.
+ PxRaycastQueryResult* mRaycastResults;
+ PxSweepQueryResult* mSweepResults;
+
+ //One hit for each wheel.
+ PxRaycastHit* mRaycastHitBuffer;
+ PxSweepHit* mSweepHitBuffer;
+
+ //Filter shader used to filter drivable and non-drivable surfaces
+ PxBatchQueryPreFilterShader mPreFilterShader;
+
+ //Filter shader used to reject hit shapes that initially overlap sweeps.
+ PxBatchQueryPostFilterShader mPostFilterShader;
+
+};
+
+} // namespace snippetvehicle
+
+#endif //SNIPPET_VEHICLE_SCENEQUERY_H
diff --git a/PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicleTankCreate.cpp b/PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicleTankCreate.cpp
new file mode 100644
index 00000000..77f5c250
--- /dev/null
+++ b/PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicleTankCreate.cpp
@@ -0,0 +1,238 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#include "SnippetVehicleCreate.h"
+#include "SnippetVehicleTireFriction.h"
+#include "SnippetVehicleSceneQuery.h"
+
+namespace snippetvehicle
+{
+namespace tank
+{
+
+void computeWheelCenterActorOffsets
+(const PxF32 wheelFrontZ, const PxF32 wheelRearZ, const PxVec3& chassisDims, const PxF32 wheelWidth, const PxF32 wheelRadius, const PxU32 numWheels, PxVec3* wheelCentreOffsets)
+{
+ //chassisDims.z is the distance from the rear of the chassis to the front of the chassis.
+ //The front has z = 0.5*chassisDims.z and the rear has z = -0.5*chassisDims.z.
+ //Compute a position for the front wheel and the rear wheel along the z-axis.
+ //Compute the separation between each wheel along the z-axis.
+ const PxF32 numLeftWheels = numWheels/2.0f;
+ const PxF32 deltaZ = (wheelFrontZ - wheelRearZ)/(numLeftWheels-1.0f);
+ //Set the outside of the left and right wheels to be flush with the chassis.
+ //Set the top of the wheel to be just touching the underside of the chassis.
+ for(PxU32 i = 0; i < numWheels; i+=2)
+ {
+ //Left wheel offset from origin.
+ wheelCentreOffsets[i + 0] = PxVec3((-chassisDims.x + wheelWidth)*0.5f, -(chassisDims.y/2 + wheelRadius), wheelRearZ + i*deltaZ*0.5f);
+ //Right wheel offsets from origin.
+ wheelCentreOffsets[i + 1] = PxVec3((+chassisDims.x - wheelWidth)*0.5f, -(chassisDims.y/2 + wheelRadius), wheelRearZ + i*deltaZ*0.5f);
+ }
+}
+
+void setupWheelsSimulationData
+(const PxF32 wheelMass, const PxF32 wheelMOI, const PxF32 wheelRadius, const PxF32 wheelWidth,
+ const PxU32 numWheels, const PxVec3* wheelCenterActorOffsets,
+ const PxVec3& chassisCMOffset, const PxF32 chassisMass,
+ PxVehicleWheelsSimData* wheelsSimData)
+{
+
+ //Set up the wheels.
+ PxVehicleWheelData wheels[PX_MAX_NB_WHEELS];
+ {
+ //Set up the wheel data structures with mass, moi, radius, width.
+ //Increase the damping on the wheel.
+ for(PxU32 i = 0; i < numWheels; i++)
+ {
+ wheels[i].mMass = wheelMass;
+ wheels[i].mMOI = wheelMOI;
+ wheels[i].mRadius = wheelRadius;
+ wheels[i].mWidth = wheelWidth;
+ wheels[i].mDampingRate = 2.0f;
+ }
+ }
+
+ //Set up the tires.
+ PxVehicleTireData tires[PX_MAX_NB_WHEELS];
+ {
+ //Set all tire types to "normal" type.
+ for(PxU32 i = 0; i < numWheels; i++)
+ {
+ tires[i].mType = TIRE_TYPE_NORMAL;
+ }
+ }
+
+ //Set up the suspensions
+ PxVehicleSuspensionData suspensions[PX_MAX_NB_WHEELS];
+ {
+ //Compute the mass supported by each suspension spring.
+ PxF32 suspSprungMasses[PX_MAX_NB_WHEELS];
+ PxVehicleComputeSprungMasses(numWheels, wheelCenterActorOffsets, chassisCMOffset, chassisMass, 1, suspSprungMasses);
+
+ //Set the suspension data.
+ for(PxU32 i = 0; i < numWheels; i++)
+ {
+ suspensions[i].mMaxCompression = 0.3f;
+ suspensions[i].mMaxDroop = 0.1f;
+ suspensions[i].mSpringStrength = 10000.0f;
+ suspensions[i].mSpringDamperRate = 1500.0f;
+ suspensions[i].mSprungMass = suspSprungMasses[i];
+ }
+ }
+
+ //Set up the wheel geometry.
+ PxVec3 suspTravelDirections[PX_MAX_NB_WHEELS];
+ PxVec3 wheelCentreCMOffsets[PX_MAX_NB_WHEELS];
+ PxVec3 suspForceAppCMOffsets[PX_MAX_NB_WHEELS];
+ PxVec3 tireForceAppCMOffsets[PX_MAX_NB_WHEELS];
+ {
+ for(PxU32 i = 0; i < numWheels; i++)
+ {
+ //Vertical suspension travel.
+ suspTravelDirections[i] = PxVec3(0,-1,0);
+
+ //Wheel center offset is offset from rigid body center of mass.
+ wheelCentreCMOffsets[i] = wheelCenterActorOffsets[i] - chassisCMOffset;
+
+ //Suspension force application point 0.3 metres below rigid body center of mass.
+ suspForceAppCMOffsets[i]=PxVec3(wheelCentreCMOffsets[i].x,-0.3f,wheelCentreCMOffsets[i].z);
+
+ //Tire force application point 0.3 metres below rigid body center of mass.
+ tireForceAppCMOffsets[i]=PxVec3(wheelCentreCMOffsets[i].x,-0.3f,wheelCentreCMOffsets[i].z);
+ }
+ }
+
+ //Set up the filter data of the raycast that will be issued by each suspension.
+ PxFilterData qryFilterData;
+ setupNonDrivableSurface(qryFilterData);
+
+ //Set the wheel, tire and suspension data.
+ //Set the geometry data.
+ //Set the query filter data
+ for(PxU32 i = 0; i < numWheels; i++)
+ {
+ wheelsSimData->setWheelData(i, wheels[i]);
+ wheelsSimData->setTireData(i, tires[i]);
+ wheelsSimData->setSuspensionData(i, suspensions[i]);
+ wheelsSimData->setSuspTravelDirection(i, suspTravelDirections[i]);
+ wheelsSimData->setWheelCentreOffset(i, wheelCentreCMOffsets[i]);
+ wheelsSimData->setSuspForceAppPointOffset(i, suspForceAppCMOffsets[i]);
+ wheelsSimData->setTireForceAppPointOffset(i, tireForceAppCMOffsets[i]);
+ wheelsSimData->setSceneQueryFilterData(i, qryFilterData);
+ wheelsSimData->setWheelShapeMapping(i, PxI32(i));
+ }
+}
+
+}// namespace tank
+
+PxVehicleDriveTank* createVehicleTank(const VehicleDesc& tankDesc, PxPhysics* physics, PxCooking* cooking)
+{
+ const PxVec3 chassisDims = tankDesc.chassisDims;
+ const PxF32 wheelWidth = tankDesc.wheelWidth;
+ const PxF32 wheelRadius = tankDesc.wheelRadius;
+ const PxU32 numWheels = tankDesc.numWheels;
+
+ const PxFilterData& chassisSimFilterData = tankDesc.chassisSimFilterData;
+ const PxFilterData& wheelSimFilterData = tankDesc.wheelSimFilterData;
+
+ //Construct a physx actor with shapes for the chassis and wheels.
+ //Set the rigid body mass, moment of inertia, and center of mass offset.
+ PxRigidDynamic* tankActor = NULL;
+ {
+ //Construct a convex mesh for a cylindrical wheel.
+ PxConvexMesh* wheelMesh = createWheelMesh(wheelWidth, wheelRadius, *physics, *cooking);
+ //Assume all wheels are identical for simplicity.
+ PxConvexMesh* wheelConvexMeshes[PX_MAX_NB_WHEELS];
+ PxMaterial* wheelMaterials[PX_MAX_NB_WHEELS];
+ for(PxU32 i = 0; i < numWheels; i++)
+ {
+ wheelConvexMeshes[i] = wheelMesh;
+ wheelMaterials[i] = tankDesc.wheelMaterial;
+ }
+
+ //Chassis just has a single convex shape for simplicity.
+ PxConvexMesh* chassisConvexMesh = createChassisMesh(chassisDims, *physics, *cooking);
+ PxConvexMesh* chassisConvexMeshes[1] = {chassisConvexMesh};
+ PxMaterial* chassisMaterials[1] = {tankDesc.chassisMaterial};
+
+ //Rigid body data.
+ PxVehicleChassisData rigidBodyData;
+ rigidBodyData.mMOI = tankDesc.chassisMOI;
+ rigidBodyData.mMass = tankDesc.chassisMass;
+ rigidBodyData.mCMOffset = tankDesc.chassisCMOffset;
+
+ tankActor = createVehicleActor
+ (rigidBodyData,
+ wheelMaterials, wheelConvexMeshes, numWheels, wheelSimFilterData,
+ chassisMaterials, chassisConvexMeshes, 1, chassisSimFilterData,
+ *physics);
+ }
+
+ //Set up the sim data for the wheels.
+ PxVehicleWheelsSimData* wheelsSimData = PxVehicleWheelsSimData::allocate(numWheels);
+ {
+ //Compute the wheel center offsets from the origin.
+ PxVec3 wheelCentreActorOffsets[PX_MAX_NB_WHEELS];
+ const PxF32 frontZ = chassisDims.z*0.35f;
+ const PxF32 rearZ = -chassisDims.z*0.35f;
+ tank::computeWheelCenterActorOffsets(frontZ, rearZ, chassisDims, wheelWidth, wheelRadius, numWheels, wheelCentreActorOffsets);
+
+ tank::setupWheelsSimulationData
+ (tankDesc.wheelMass, tankDesc.wheelMOI, wheelRadius, wheelWidth,
+ numWheels, wheelCentreActorOffsets,
+ tankDesc.chassisCMOffset, tankDesc.chassisMass,
+ wheelsSimData);
+ }
+
+ //Set up the sim data for the tank drive model.
+ PxVehicleDriveSimData driveSimData;
+ {
+ //Set up the engine to be more powerful but also more damped than the default engine.
+ PxVehicleEngineData engineData = driveSimData.getEngineData();
+ engineData.mPeakTorque *= 2.0f;
+ engineData.mDampingRateZeroThrottleClutchEngaged = 2.0f;
+ engineData.mDampingRateZeroThrottleClutchDisengaged = 0.5f;
+ engineData.mDampingRateFullThrottle = 0.5f;
+ driveSimData.setEngineData(engineData);
+ }
+
+ //Create a tank from the wheels and drive sim data.
+ PxVehicleDriveTank* vehDriveTank = PxVehicleDriveTank::allocate(numWheels);
+ vehDriveTank->setup(physics, tankActor, *wheelsSimData, driveSimData, numWheels);
+
+ //Configure the userdata
+ configureUserData(vehDriveTank, tankDesc.actorUserData, tankDesc.shapeUserDatas);
+
+ //Free the sim data because we don't need that any more.
+ wheelsSimData->free();
+
+ return vehDriveTank;
+}
+
+} // namespace snippetvehicle
diff --git a/PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicleTireFriction.cpp b/PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicleTireFriction.cpp
new file mode 100644
index 00000000..bf9458d3
--- /dev/null
+++ b/PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicleTireFriction.cpp
@@ -0,0 +1,69 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#include <new>
+#include "SnippetVehicleTireFriction.h"
+#include "PxPhysicsAPI.h"
+
+namespace snippetvehicle
+{
+
+using namespace physx;
+
+//Tire model friction for each combination of drivable surface type and tire type.
+static PxF32 gTireFrictionMultipliers[MAX_NUM_SURFACE_TYPES][MAX_NUM_TIRE_TYPES]=
+{
+ //NORMAL, WORN
+ {1.00f, 0.1f}//TARMAC
+};
+
+PxVehicleDrivableSurfaceToTireFrictionPairs* createFrictionPairs(const PxMaterial* defaultMaterial)
+{
+ PxVehicleDrivableSurfaceType surfaceTypes[1];
+ surfaceTypes[0].mType = SURFACE_TYPE_TARMAC;
+
+ const PxMaterial* surfaceMaterials[1];
+ surfaceMaterials[0] = defaultMaterial;
+
+ PxVehicleDrivableSurfaceToTireFrictionPairs* surfaceTirePairs =
+ PxVehicleDrivableSurfaceToTireFrictionPairs::allocate(MAX_NUM_TIRE_TYPES,MAX_NUM_SURFACE_TYPES);
+
+ surfaceTirePairs->setup(MAX_NUM_TIRE_TYPES, MAX_NUM_SURFACE_TYPES, surfaceMaterials, surfaceTypes);
+
+ for(PxU32 i = 0; i < MAX_NUM_SURFACE_TYPES; i++)
+ {
+ for(PxU32 j = 0; j < MAX_NUM_TIRE_TYPES; j++)
+ {
+ surfaceTirePairs->setTypePairFriction(i,j,gTireFrictionMultipliers[i][j]);
+ }
+ }
+ return surfaceTirePairs;
+}
+
+} // namespace snippetvehicle
diff --git a/PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicleTireFriction.h b/PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicleTireFriction.h
new file mode 100644
index 00000000..5f9420cd
--- /dev/null
+++ b/PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicleTireFriction.h
@@ -0,0 +1,59 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#ifndef SNIPPET_VEHICLE_TIREFRICTION_H
+#define SNIPPET_VEHICLE_TIREFRICTION_H
+
+#include "PxPhysicsAPI.h"
+
+namespace snippetvehicle
+{
+
+using namespace physx;
+
+//Drivable surface types.
+enum
+{
+ SURFACE_TYPE_TARMAC,
+ MAX_NUM_SURFACE_TYPES
+};
+
+//Tire types.
+enum
+{
+ TIRE_TYPE_NORMAL=0,
+ TIRE_TYPE_WORN,
+ MAX_NUM_TIRE_TYPES
+};
+
+PxVehicleDrivableSurfaceToTireFrictionPairs* createFrictionPairs(const PxMaterial* defaultMaterial);
+
+} // namespace snippetvehicle
+
+#endif //SNIPPET_VEHICLE_TIREFRICTION_H
diff --git a/PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicleWheelQueryResult.h b/PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicleWheelQueryResult.h
new file mode 100644
index 00000000..66c2dea4
--- /dev/null
+++ b/PhysX_3.4/Snippets/SnippetVehicleCommon/SnippetVehicleWheelQueryResult.h
@@ -0,0 +1,97 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#ifndef SNIPPET_VEHICLE_WHEELQUERYRESULT_H
+#define SNIPPET_VEHICLE_WHEELQUERYRESULT_H
+
+#include "PxPhysicsAPI.h"
+#include <new>
+
+namespace snippetvehicle
+{
+using namespace physx;
+
+//Data structure for quick setup of wheel query data structures.
+class VehicleWheelQueryResults
+{
+public:
+
+ VehicleWheelQueryResults()
+ : mVehicleWheelQueryResults(NULL)
+ {
+ }
+
+ ~VehicleWheelQueryResults()
+ {
+ }
+
+ //Allocate wheel results for up to maxNumVehicles with up to maxNumWheelsPerVehicle.
+ static VehicleWheelQueryResults* allocate(const PxU32 maxNumVehicles, const PxU32 maxNumWheelsPerVehicle, PxAllocatorCallback& allocator)
+ {
+ const PxU32 byteSize = sizeof(VehicleWheelQueryResults) + sizeof(PxVehicleWheelQueryResult)*maxNumVehicles + sizeof(PxWheelQueryResult)*maxNumWheelsPerVehicle*maxNumVehicles;
+
+ PxU8* buffer = static_cast<PxU8*>(allocator.allocate(byteSize, NULL, NULL, 0));
+
+ VehicleWheelQueryResults* vwqr = reinterpret_cast<VehicleWheelQueryResults*>(buffer);
+ buffer += sizeof(VehicleWheelQueryResults);
+
+ vwqr->mVehicleWheelQueryResults = reinterpret_cast<PxVehicleWheelQueryResult*>(buffer);
+ buffer+=sizeof(PxVehicleWheelQueryResult)*maxNumVehicles;
+
+ for(PxU32 i=0;i<maxNumVehicles;i++)
+ {
+ new(buffer) PxWheelQueryResult();
+ vwqr->mVehicleWheelQueryResults[i].wheelQueryResults = reinterpret_cast<PxWheelQueryResult*>(buffer);
+ vwqr->mVehicleWheelQueryResults[i].nbWheelQueryResults = maxNumWheelsPerVehicle;
+ buffer += sizeof(PxWheelQueryResult)*maxNumWheelsPerVehicle;
+ }
+
+ return vwqr;
+ }
+
+ //Free allocated buffer for scene queries of suspension raycasts.
+ void free(PxAllocatorCallback& allocator)
+ {
+ allocator.deallocate(this);
+ }
+
+ //Return the PxVehicleWheelQueryResult for a vehicle specified by an index.
+ PxVehicleWheelQueryResult* getVehicleWheelQueryResults(const PxU32 id)
+ {
+ return (mVehicleWheelQueryResults + id);
+ }
+
+private:
+
+ PxVehicleWheelQueryResult* mVehicleWheelQueryResults;
+};
+
+} // namespace snippetvehicle
+
+#endif //SNIPPET_VEHICLE_WHEELQUERYRESULT_H