Init
This commit is contained in:
321
physx/snippets/snippetvehiclecommon/SnippetVehicle4WCreate.cpp
Normal file
321
physx/snippets/snippetvehiclecommon/SnippetVehicle4WCreate.cpp
Normal file
@ -0,0 +1,321 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 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
|
||||
|
||||
|
||||
122
physx/snippets/snippetvehiclecommon/SnippetVehicleConcurrency.h
Normal file
122
physx/snippets/snippetvehiclecommon/SnippetVehicleConcurrency.h
Normal file
@ -0,0 +1,122 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 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
|
||||
339
physx/snippets/snippetvehiclecommon/SnippetVehicleCreate.cpp
Normal file
339
physx/snippets/snippetvehiclecommon/SnippetVehicleCreate.cpp
Normal file
@ -0,0 +1,339 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 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
|
||||
142
physx/snippets/snippetvehiclecommon/SnippetVehicleCreate.h
Normal file
142
physx/snippets/snippetvehiclecommon/SnippetVehicleCreate.h
Normal file
@ -0,0 +1,142 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 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
|
||||
@ -0,0 +1,58 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 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
|
||||
@ -0,0 +1,62 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 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
|
||||
@ -0,0 +1,246 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 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
|
||||
|
||||
215
physx/snippets/snippetvehiclecommon/SnippetVehicleSceneQuery.cpp
Normal file
215
physx/snippets/snippetvehiclecommon/SnippetVehicleSceneQuery.cpp
Normal file
@ -0,0 +1,215 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 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
|
||||
126
physx/snippets/snippetvehiclecommon/SnippetVehicleSceneQuery.h
Normal file
126
physx/snippets/snippetvehiclecommon/SnippetVehicleSceneQuery.h
Normal file
@ -0,0 +1,126 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 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
|
||||
238
physx/snippets/snippetvehiclecommon/SnippetVehicleTankCreate.cpp
Normal file
238
physx/snippets/snippetvehiclecommon/SnippetVehicleTankCreate.cpp
Normal file
@ -0,0 +1,238 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 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
|
||||
@ -0,0 +1,69 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 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
|
||||
@ -0,0 +1,59 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 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
|
||||
@ -0,0 +1,97 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 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
|
||||
Reference in New Issue
Block a user