Init
This commit is contained in:
2271
physx/samples/samplevehicle/SampleVehicle.cpp
Normal file
2271
physx/samples/samplevehicle/SampleVehicle.cpp
Normal file
File diff suppressed because it is too large
Load Diff
198
physx/samples/samplevehicle/SampleVehicle.h
Normal file
198
physx/samples/samplevehicle/SampleVehicle.h
Normal file
@ -0,0 +1,198 @@
|
||||
//
|
||||
// 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 SAMPLE_VEHICLE_H
|
||||
#define SAMPLE_VEHICLE_H
|
||||
|
||||
#include "PhysXSample.h"
|
||||
#include "SampleVehicle_ControlInputs.h"
|
||||
#include "SampleVehicle_CameraController.h"
|
||||
#include "SampleVehicle_VehicleController.h"
|
||||
#include "SampleVehicle_VehicleManager.h"
|
||||
#include "SampleVehicle_GameLogic.h"
|
||||
#include "vehicle/PxVehicleTireFriction.h"
|
||||
|
||||
class SampleVehicle : public PhysXSample
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
SampleVehicle(PhysXSampleApplication& app);
|
||||
virtual ~SampleVehicle();
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Implements RAWImportCallback
|
||||
virtual void newMesh(const RAWMesh&);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Implements SampleApplication
|
||||
virtual void onInit();
|
||||
virtual void onInit(bool restart) { onInit(); }
|
||||
virtual void onShutdown();
|
||||
|
||||
virtual void onTickPreRender(PxF32 dtime);
|
||||
virtual void onTickPostRender(PxF32 dtime);
|
||||
|
||||
virtual void onDigitalInputEvent(const SampleFramework::InputEvent& , bool val);
|
||||
virtual void onAnalogInputEvent(const SampleFramework::InputEvent& , float val);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Implements PhysXSampleApplication
|
||||
virtual void helpRender(PxU32 x, PxU32 y, PxU8 textAlpha);
|
||||
virtual void descriptionRender(PxU32 x, PxU32 y, PxU8 textAlpha);
|
||||
virtual void customizeSample(SampleSetup&);
|
||||
virtual void customizeSceneDesc(PxSceneDesc&);
|
||||
virtual void customizeRender();
|
||||
virtual void onSubstep(PxF32 dtime);
|
||||
virtual void collectInputEvents(std::vector<const SampleFramework::InputEvent*>& inputEvents);
|
||||
|
||||
private:
|
||||
|
||||
SampleVehicle_ControlInputs mControlInputs;
|
||||
SampleVehicle_CameraController mCameraController;
|
||||
SampleVehicle_VehicleController mVehicleController;
|
||||
|
||||
|
||||
//Terrain
|
||||
|
||||
PxF32* mTerrainVB;
|
||||
PxU32 mNbTerrainVerts;
|
||||
|
||||
enum
|
||||
{
|
||||
MAX_NUM_INDEX_BUFFERS = 16
|
||||
};
|
||||
PxU32 mNbIB;
|
||||
PxU32* mIB[MAX_NUM_INDEX_BUFFERS];
|
||||
PxU32 mNbTriangles[MAX_NUM_INDEX_BUFFERS];
|
||||
PxU32 mRenderMaterial[MAX_NUM_INDEX_BUFFERS];
|
||||
|
||||
//Materials
|
||||
|
||||
PxVehicleDrivableSurfaceType mVehicleDrivableSurfaceTypes[MAX_NUM_INDEX_BUFFERS];
|
||||
PxMaterial* mStandardMaterials[MAX_NUM_INDEX_BUFFERS];
|
||||
PxMaterial* mChassisMaterialDrivable;
|
||||
PxMaterial* mChassisMaterialNonDrivable;
|
||||
|
||||
|
||||
RenderMaterial* mTerrainMaterial;
|
||||
RenderMaterial* mRoadMaterial;
|
||||
RenderMaterial* mRoadIceMaterial;
|
||||
RenderMaterial* mRoadGravelMaterial;
|
||||
|
||||
void createStandardMaterials();
|
||||
|
||||
enum eFocusVehicleType
|
||||
{
|
||||
ePLAYER_VEHICLE_TYPE_VEHICLE4W=0,
|
||||
ePLAYER_VEHICLE_TYPE_VEHICLE6W,
|
||||
ePLAYER_VEHICLE_TYPE_TANK4W,
|
||||
ePLAYER_VEHICLE_TYPE_TANK6W,
|
||||
eMAX_NUM_FOCUS_VEHICLE_TYPES
|
||||
};
|
||||
|
||||
// Vehicles
|
||||
SampleVehicle_VehicleManager mVehicleManager;
|
||||
std::vector<RenderMeshActor*> mVehicleGraphics;
|
||||
PxU32 mPlayerVehicle;
|
||||
eFocusVehicleType mPlayerVehicleType;
|
||||
PxVehicleDriveTankControlModel::Enum mTankDriveModel;
|
||||
|
||||
const char* getFocusVehicleName();
|
||||
void createVehicles();
|
||||
|
||||
PxU32 mTerrainSize;
|
||||
PxF32 mTerrainWidth;
|
||||
PxRigidActor* mHFActor;
|
||||
|
||||
void createTrack(PxU32 size, PxF32 width, PxF32 chaos);
|
||||
void createTerrain(PxU32 size, PxF32 width, PxF32 chaos);
|
||||
void addRenderMesh(PxF32* verts, PxU32 nVerts, PxU32* indices, PxU32 mIndices, PxU32 matID);
|
||||
void addMesh(PxRigidActor* actor, PxF32* verts, PxU32 nVerts, PxU32* indices, PxU32 mIndices, PxU32 materialIndex, const char* filename);
|
||||
void createLandscapeMesh();
|
||||
|
||||
//Obstacles
|
||||
|
||||
void createObstacles();
|
||||
PxRigidStatic* addStaticObstacle(const PxTransform& transform, const PxU32 numShapes, PxTransform* shapeTransforms, PxGeometry** shapeGeometries, PxMaterial** shapeMaterials);
|
||||
PxRigidDynamic* addDynamicObstacle(const PxTransform& transform, const PxF32 mass, const PxU32 numShapes, PxTransform* transforms, PxGeometry** geometries, PxMaterial** materials);
|
||||
PxRigidDynamic* addDynamicDrivableObstacle(const PxTransform& transform, const PxF32 mass, const PxU32 numShapes, PxTransform* transforms, PxGeometry** geometries, PxMaterial** materials);
|
||||
void createStack(PxU32 size, PxF32 boxSize, const PxVec3& pos, const PxQuat& quat);
|
||||
void createWall(const PxU32 numHorizontalBoxes, const PxU32 numVerticalBoxes, const PxF32 boxSize, const PxVec3& pos, const PxQuat& quat);
|
||||
|
||||
//Debug render
|
||||
|
||||
bool mHideScreenText;
|
||||
bool mDebugRenderFlag;
|
||||
#if PX_DEBUG_VEHICLE_ON
|
||||
PxU32 mDebugRenderActiveGraphChannelWheel;
|
||||
PxU32 mDebugRenderActiveGraphChannelEngine;
|
||||
PxVehicleTelemetryData* mTelemetryData4W;
|
||||
PxVehicleTelemetryData* mTelemetryData6W;
|
||||
#endif
|
||||
void setupTelemetryData();
|
||||
void clearTelemetryData();
|
||||
|
||||
void drawWheels();
|
||||
void drawVehicleDebug();
|
||||
void drawHud();
|
||||
void drawGraphsAndPrintTireSurfaceTypes(const PxVehicleWheels& focusVehicle, const PxVehicleWheelQueryResult& focusVehicleWheelQueryResults);
|
||||
void drawFocusVehicleGraphsAndPrintTireSurfaces();
|
||||
|
||||
//Waypoints
|
||||
SampleVehicleWayPoints mWayPoints;
|
||||
bool mFixCar;
|
||||
bool mBackToStart;
|
||||
|
||||
//3W and 4W modes
|
||||
bool m3WModeIncremented;
|
||||
PxU32 m3WMode;
|
||||
|
||||
PxF32 mForwardSpeedHud;
|
||||
|
||||
#if defined(SERIALIZE_VEHICLE_BINARY)
|
||||
void* mMemory;
|
||||
#endif
|
||||
|
||||
void updateCameraController(const PxF32 dtime, PxScene& scene);
|
||||
void updateVehicleController(const PxF32 dtime);
|
||||
void updateVehicleManager(const PxF32 dtime, const PxVec3& gravity);
|
||||
|
||||
void resetFocusVehicleAtWaypoint();
|
||||
PxRigidDynamic* getFocusVehicleRigidDynamicActor();
|
||||
bool getFocusVehicleUsesAutoGears();
|
||||
char mVehicleFilePath[256];
|
||||
};
|
||||
|
||||
#endif
|
||||
367
physx/samples/samplevehicle/SampleVehicleDebugRender.cpp
Normal file
367
physx/samples/samplevehicle/SampleVehicleDebugRender.cpp
Normal file
@ -0,0 +1,367 @@
|
||||
//
|
||||
// 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 "SampleVehicle.h"
|
||||
#include "RenderPhysX3Debug.h"
|
||||
#include "PxRigidDynamic.h"
|
||||
#include "SampleVehicle_VehicleManager.h"
|
||||
|
||||
using namespace SampleRenderer;
|
||||
|
||||
// PT: this file contains the part of SampleVehicle dealing with cars' debug rendering
|
||||
|
||||
void SampleVehicle::drawWheels()
|
||||
{
|
||||
PxSceneReadLock scopedLock(*mScene);
|
||||
const RendererColor colorPurple(255, 0, 255);
|
||||
|
||||
for(PxU32 i=0;i<mVehicleManager.getNbVehicles();i++)
|
||||
{
|
||||
//Draw a rotating arrow to get an idea of the wheel rotation speed.
|
||||
PxVehicleWheels* veh=mVehicleManager.getVehicle(i);
|
||||
const PxRigidDynamic* actor=veh->getRigidDynamicActor();
|
||||
PxShape* shapeBuffer[PX_MAX_NB_WHEELS];
|
||||
actor->getShapes(shapeBuffer,veh->mWheelsSimData.getNbWheels());
|
||||
const PxTransform vehGlobalPose=actor->getGlobalPose();
|
||||
const PxU32 numWheels=veh->mWheelsSimData.getNbWheels();
|
||||
for(PxU32 j=0;j<numWheels;j++)
|
||||
{
|
||||
const PxTransform wheelTransform=vehGlobalPose.transform(shapeBuffer[j]->getLocalPose());
|
||||
const PxF32 wheelRadius=veh->mWheelsSimData.getWheelData(j).mRadius;
|
||||
const PxF32 wheelHalfWidth=veh->mWheelsSimData.getWheelData(j).mWidth*0.5f;
|
||||
PxVec3 offset=wheelTransform.q.getBasisVector0()*wheelHalfWidth;
|
||||
offset*= (veh->mWheelsSimData.getWheelCentreOffset(j).x > 0) ? 1.0f : -1.0f;
|
||||
const PxVec3 arrow=wheelTransform.rotate(PxVec3(0,0,1));
|
||||
getDebugRenderer()->addLine(wheelTransform.p+offset, wheelTransform.p+offset+arrow*wheelRadius, colorPurple);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SampleVehicle::drawVehicleDebug()
|
||||
{
|
||||
PxSceneReadLock scopedLock(*mScene);
|
||||
const RendererColor colorColl(255, 0, 0);
|
||||
const RendererColor colorCol2(0, 255, 0);
|
||||
const RendererColor colorCol3(0, 0, 255);
|
||||
|
||||
#if PX_DEBUG_VEHICLE_ON
|
||||
const PxVec3* tireForceAppPoints=NULL;
|
||||
const PxVec3* suspForceAppPoints=NULL;
|
||||
switch(mPlayerVehicleType)
|
||||
{
|
||||
case ePLAYER_VEHICLE_TYPE_VEHICLE4W:
|
||||
case ePLAYER_VEHICLE_TYPE_TANK4W:
|
||||
tireForceAppPoints=mTelemetryData4W->getTireforceAppPoints();
|
||||
suspForceAppPoints=mTelemetryData4W->getSuspforceAppPoints();
|
||||
break;
|
||||
case ePLAYER_VEHICLE_TYPE_VEHICLE6W:
|
||||
case ePLAYER_VEHICLE_TYPE_TANK6W:
|
||||
tireForceAppPoints=mTelemetryData6W->getTireforceAppPoints();
|
||||
suspForceAppPoints=mTelemetryData6W->getSuspforceAppPoints();
|
||||
break;
|
||||
default:
|
||||
PX_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
const PxVehicleWheels& vehicle4W=*mVehicleManager.getVehicle(mPlayerVehicle);
|
||||
const PxVehicleWheelQueryResult& vehicleWheelQueryResults=mVehicleManager.getVehicleWheelQueryResults(mPlayerVehicle);
|
||||
const PxRigidDynamic* actor=vehicle4W.getRigidDynamicActor();
|
||||
const PxU32 numWheels=vehicle4W.mWheelsSimData.getNbWheels();
|
||||
PxVec3 v[8];
|
||||
PxVec3 w[8];
|
||||
PxF32 l[8];
|
||||
for(PxU32 i=0;i<numWheels;i++)
|
||||
{
|
||||
v[i] = vehicleWheelQueryResults.wheelQueryResults[i].suspLineStart;
|
||||
w[i] = vehicleWheelQueryResults.wheelQueryResults[i].suspLineDir;
|
||||
l[i] = vehicleWheelQueryResults.wheelQueryResults[i].suspLineLength;
|
||||
}
|
||||
|
||||
|
||||
const PxTransform t=actor->getGlobalPose().transform(actor->getCMassLocalPose());
|
||||
const PxVec3 dirs[3]={t.rotate(PxVec3(1,0,0)),t.rotate(PxVec3(0,1,0)),t.rotate(PxVec3(0,0,1))};
|
||||
getDebugRenderer()->addLine(t.p, t.p + dirs[0]*4.0f, colorColl);
|
||||
getDebugRenderer()->addLine(t.p, t.p + dirs[1]*4.0f, colorColl);
|
||||
getDebugRenderer()->addLine(t.p, t.p + dirs[2]*4.0f, colorColl);
|
||||
|
||||
for(PxU32 j=0;j<numWheels;j++)
|
||||
{
|
||||
getDebugRenderer()->addLine(v[j], v[j]+w[j]*l[j], colorColl);
|
||||
|
||||
#if PX_DEBUG_VEHICLE_ON
|
||||
//Draw all tire force app points.
|
||||
const PxVec3& appPoint = tireForceAppPoints[j];
|
||||
getDebugRenderer()->addLine(appPoint - dirs[0], appPoint + dirs[0], colorCol2);
|
||||
getDebugRenderer()->addLine(appPoint - dirs[2], appPoint + dirs[2], colorCol2);
|
||||
|
||||
//Draw all susp force app points.
|
||||
const PxVec3& appPoint2 = suspForceAppPoints[j];
|
||||
getDebugRenderer()->addLine(appPoint2 - dirs[0], appPoint2 + dirs[0], colorCol3);
|
||||
getDebugRenderer()->addLine(appPoint2 - dirs[2], appPoint2 + dirs[2], colorCol3);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static void drawBox2D(Renderer* renderer, PxF32 minX, PxF32 maxX, PxF32 minY, PxF32 maxY, const RendererColor& color, PxF32 alpha)
|
||||
{
|
||||
ScreenQuad sq;
|
||||
sq.mX0 = minX;
|
||||
sq.mY0 = 1.0f - minY;
|
||||
sq.mX1 = maxX;
|
||||
sq.mY1 = 1.0f - maxY;
|
||||
sq.mLeftUpColor = color;
|
||||
sq.mRightUpColor = color;
|
||||
sq.mLeftDownColor = color;
|
||||
sq.mRightDownColor = color;
|
||||
sq.mAlpha = alpha;
|
||||
|
||||
renderer->drawScreenQuad(sq);
|
||||
}
|
||||
|
||||
static void print(Renderer* renderer, PxF32 x, PxF32 y, PxF32 scale_, const char* text)
|
||||
{
|
||||
PxU32 width, height;
|
||||
renderer->getWindowSize(width, height);
|
||||
|
||||
y = 1.0f - y;
|
||||
|
||||
const PxReal scale = scale_*20.0f;
|
||||
const PxReal shadowOffset = 6.0f;
|
||||
const RendererColor textColor(255, 255, 255, 255);
|
||||
|
||||
renderer->print(PxU32(x*PxF32(width)), PxU32(y*PxF32(height)), text, scale, shadowOffset, textColor);
|
||||
}
|
||||
|
||||
void SampleVehicle::drawHud()
|
||||
{
|
||||
const PxVehicleWheels& focusVehicle = *mVehicleManager.getVehicle(mPlayerVehicle);
|
||||
PxVehicleDriveDynData* driveDynData=NULL;
|
||||
PxVehicleDriveSimData* driveSimData=NULL;
|
||||
switch(focusVehicle.getVehicleType())
|
||||
{
|
||||
case PxVehicleTypes::eDRIVE4W:
|
||||
{
|
||||
PxVehicleDrive4W& vehDrive4W=(PxVehicleDrive4W&)focusVehicle;
|
||||
driveDynData=&vehDrive4W.mDriveDynData;
|
||||
driveSimData=&vehDrive4W.mDriveSimData;
|
||||
}
|
||||
break;
|
||||
case PxVehicleTypes::eDRIVENW:
|
||||
{
|
||||
PxVehicleDriveNW& vehDriveNW=(PxVehicleDriveNW&)focusVehicle;
|
||||
driveDynData=&vehDriveNW.mDriveDynData;
|
||||
driveSimData=&vehDriveNW.mDriveSimData;
|
||||
}
|
||||
break;
|
||||
case PxVehicleTypes::eDRIVETANK:
|
||||
{
|
||||
PxVehicleDriveTank& vehDriveTank=(PxVehicleDriveTank&)focusVehicle;
|
||||
driveDynData=&vehDriveTank.mDriveDynData;
|
||||
driveSimData=&vehDriveTank.mDriveSimData;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
PX_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
|
||||
const PxU32 currentGear=driveDynData->getCurrentGear();
|
||||
const PxF32 vz=mForwardSpeedHud*3.6f;
|
||||
const PxF32 revs=driveDynData->getEngineRotationSpeed();
|
||||
const PxF32 maxRevs=driveSimData->getEngineData().mMaxOmega*60*0.5f/PxPi;//Convert from radians per second to rpm
|
||||
const PxF32 invMaxRevs=driveSimData->getEngineData().getRecipMaxOmega();
|
||||
|
||||
//Draw gears and speed.
|
||||
|
||||
const PxF32 x=0.5f;
|
||||
const PxF32 y=0.18f;
|
||||
const PxF32 length=0.1f;
|
||||
const PxF32 textheight=0.02f;
|
||||
|
||||
Renderer* renderer = getRenderer();
|
||||
drawBox2D(renderer, x-length-textheight, x+length+textheight, y, y+length+textheight, RendererColor(255, 255, 255), 0.5f);
|
||||
|
||||
//Gear
|
||||
char gear[PxVehicleGearsData::eGEARSRATIO_COUNT][64]=
|
||||
{
|
||||
"R","N","1","2","3","4","5"
|
||||
};
|
||||
print(renderer, x-0.25f*textheight, y+0.02f, 0.02f, gear[currentGear]);
|
||||
|
||||
//Speed
|
||||
char speed[64];
|
||||
sprintf(speed, "%1.0f %s", PxAbs(vz), "kmph");
|
||||
print(renderer, x-textheight, y+length-textheight, textheight, speed);
|
||||
|
||||
//Revs
|
||||
{
|
||||
const PxF32 xy[4]={x, 1.0f-y, x-length, 1.0f-(y+length)};
|
||||
renderer->drawLines2D(2, xy, RendererColor(0, 0, 255));
|
||||
|
||||
char buffer[64];
|
||||
sprintf(buffer, "%d \n", 0);
|
||||
print(renderer, x-length, y+length, textheight, buffer);
|
||||
}
|
||||
{
|
||||
const PxF32 xy[4]={x, 1.0f-y, x+length, 1.0f-(y+length)};
|
||||
renderer->drawLines2D(2, xy, RendererColor(0, 0, 255));
|
||||
|
||||
char buffer[64];
|
||||
sprintf(buffer, "%1.0f \n", maxRevs);
|
||||
print(renderer, x+length-2*textheight, y+length, textheight, buffer);
|
||||
}
|
||||
{
|
||||
const PxF32 alpha=revs*invMaxRevs;
|
||||
const PxF32 dx=-(1.0f-alpha)*length + alpha*length;
|
||||
const PxF32 xy[4]={x, 1.0f-y, x+dx, 1.0f-(y+length)};
|
||||
renderer->drawLines2D(2, xy, RendererColor(255, 0, 0));
|
||||
}
|
||||
}
|
||||
|
||||
#if PX_DEBUG_VEHICLE_ON
|
||||
|
||||
static PX_FORCE_INLINE RendererColor getColor(const PxVec3& c)
|
||||
{
|
||||
return RendererColor(PxU8(c.x), PxU8(c.y), PxU8(c.z));
|
||||
}
|
||||
|
||||
static PX_FORCE_INLINE void convertColors(const PxVec3* src, RendererColor* dst)
|
||||
{
|
||||
for(PxU32 i=0;i<PxVehicleGraph::eMAX_NB_SAMPLES;i++)
|
||||
*dst++ = getColor(src[i]);
|
||||
}
|
||||
|
||||
static void convertY(PxF32* xy)
|
||||
{
|
||||
for(PxU32 i=0;i<PxVehicleGraph::eMAX_NB_SAMPLES;i++)
|
||||
xy[2*i+1]=1.0f-xy[2*i+1];
|
||||
}
|
||||
|
||||
#endif //PX_DEBUG_VEHICLE_ON
|
||||
|
||||
#if PX_DEBUG_VEHICLE_ON
|
||||
|
||||
void drawGraphsAndPrintTireSurfaceTypesN
|
||||
(const PxVehicleTelemetryData& telemetryData, const PxU32* tireTypes, const PxU32* surfaceTypes,
|
||||
const PxU32 activeEngineGraphChannel, const PxU32 activeWheelGraphChannel,
|
||||
SampleRenderer::Renderer* renderer)
|
||||
{
|
||||
|
||||
PxF32 xy[2*PxVehicleGraph::eMAX_NB_SAMPLES];
|
||||
PxVec3 color[PxVehicleGraph::eMAX_NB_SAMPLES];
|
||||
RendererColor rendererColor[PxVehicleGraph::eMAX_NB_SAMPLES];
|
||||
char title[PxVehicleGraph::eMAX_NB_TITLE_CHARS];
|
||||
|
||||
const PxU32 numWheelGraphs=telemetryData.getNbWheelGraphs();
|
||||
|
||||
for(PxU32 i=0;i<numWheelGraphs;i++)
|
||||
{
|
||||
PxF32 xMin,xMax,yMin,yMax;
|
||||
telemetryData.getWheelGraph(i).getBackgroundCoords(xMin,yMin,xMax,yMax);
|
||||
const PxVec3& backgroundColor=telemetryData.getWheelGraph(i).getBackgroundColor();
|
||||
const PxF32 alpha=telemetryData.getWheelGraph(i).getBackgroundAlpha();
|
||||
drawBox2D(renderer, xMin,xMax,yMin,yMax, getColor(backgroundColor),alpha);
|
||||
|
||||
telemetryData.getWheelGraph(i).computeGraphChannel(activeWheelGraphChannel,xy,color,title);
|
||||
convertY(xy);
|
||||
convertColors(color, rendererColor);
|
||||
renderer->drawLines2D(PxVehicleGraph::eMAX_NB_SAMPLES, xy, rendererColor);
|
||||
|
||||
print(renderer, xMin,yMax-0.02f, 0.02f, title);
|
||||
|
||||
const PxU32 tireType=tireTypes[i];
|
||||
const PxU32 tireSurfaceType=surfaceTypes[i];
|
||||
|
||||
if (PxVehicleDrivableSurfaceType::eSURFACE_TYPE_UNKNOWN!=tireSurfaceType)
|
||||
{
|
||||
const char* surfaceType= SurfaceTypeNames::getName(tireSurfaceType);
|
||||
const PxF32 friction=TireFrictionMultipliers::getValue(tireSurfaceType, tireType);
|
||||
char surfaceDetails[64];
|
||||
sprintf(surfaceDetails, "%s %1.2f \n", surfaceType, friction);
|
||||
print(renderer, xMin+0.1f, yMax-0.12f, 0.02f, surfaceDetails);
|
||||
}
|
||||
}
|
||||
|
||||
PxF32 xMin,xMax,yMin,yMax;
|
||||
telemetryData.getEngineGraph().getBackgroundCoords(xMin,yMin,xMax,yMax);
|
||||
const PxVec3& backgroundColor=telemetryData.getEngineGraph().getBackgroundColor();
|
||||
const PxF32 alpha=telemetryData.getEngineGraph().getBackgroundAlpha();
|
||||
drawBox2D(renderer, xMin,xMax,yMin,yMax, getColor(backgroundColor),alpha);
|
||||
|
||||
telemetryData.getEngineGraph().computeGraphChannel(activeEngineGraphChannel,xy,color,title);
|
||||
convertY(xy);
|
||||
convertColors(color, rendererColor);
|
||||
renderer->drawLines2D(PxVehicleGraph::eMAX_NB_SAMPLES, xy, rendererColor);
|
||||
|
||||
print(renderer, xMin,yMax-0.02f,0.02f,title);
|
||||
}
|
||||
|
||||
#endif //PX_DEBUG_VEHICLE_GRAPH_ON
|
||||
|
||||
void SampleVehicle::drawGraphsAndPrintTireSurfaceTypes(const PxVehicleWheels& focusVehicle, const PxVehicleWheelQueryResult& focusVehicleWheelQueryResults)
|
||||
{
|
||||
#if PX_DEBUG_VEHICLE_ON
|
||||
|
||||
PxU32 tireTypes[8];
|
||||
PxU32 surfaceTypes[8];
|
||||
const PxU32 numWheels=focusVehicle.mWheelsSimData.getNbWheels();
|
||||
PX_ASSERT(numWheels<=8);
|
||||
for(PxU32 i=0;i<numWheels;i++)
|
||||
{
|
||||
tireTypes[i]=focusVehicle.mWheelsSimData.getTireData(i).mType;
|
||||
surfaceTypes[i]=focusVehicleWheelQueryResults.wheelQueryResults[i].tireSurfaceType;
|
||||
}
|
||||
|
||||
PxVehicleTelemetryData* vehTelData=NULL;
|
||||
switch(mPlayerVehicleType)
|
||||
{
|
||||
case ePLAYER_VEHICLE_TYPE_VEHICLE4W:
|
||||
case ePLAYER_VEHICLE_TYPE_TANK4W:
|
||||
vehTelData=mTelemetryData4W;
|
||||
break;
|
||||
case ePLAYER_VEHICLE_TYPE_VEHICLE6W:
|
||||
case ePLAYER_VEHICLE_TYPE_TANK6W:
|
||||
vehTelData=mTelemetryData6W;
|
||||
break;
|
||||
default:
|
||||
PX_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
|
||||
drawGraphsAndPrintTireSurfaceTypesN(
|
||||
*vehTelData,tireTypes,surfaceTypes,
|
||||
mDebugRenderActiveGraphChannelEngine,mDebugRenderActiveGraphChannelWheel,
|
||||
getRenderer());
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
98
physx/samples/samplevehicle/SampleVehicleInputEventIds.h
Normal file
98
physx/samples/samplevehicle/SampleVehicleInputEventIds.h
Normal file
@ -0,0 +1,98 @@
|
||||
//
|
||||
// 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.
|
||||
#ifndef _SAMPLE_VEHICLE_INPUT_EVENT_IDS_H
|
||||
#define _SAMPLE_VEHICLE_INPUT_EVENT_IDS_H
|
||||
|
||||
#include <SampleBaseInputEventIds.h>
|
||||
|
||||
// InputEvents used by SampleVehicle
|
||||
enum SampleVehicleInputEventIds
|
||||
{
|
||||
SAMPLE_VEHICLE_FIRST_ID = NUM_SAMPLE_BASE_INPUT_EVENT_IDS,
|
||||
|
||||
CAR_ACCELERATE_BRAKE,
|
||||
|
||||
//KEYBOARD (car+tank)
|
||||
VEH_ACCELERATE_KBD,
|
||||
VEH_GEAR_UP_KBD,
|
||||
VEH_GEAR_DOWN_KBD,
|
||||
|
||||
VEH_SAVE_KBD,
|
||||
|
||||
//KEYBOARD (car)
|
||||
CAR_BRAKE_KBD,
|
||||
CAR_HANDBRAKE_KBD,
|
||||
CAR_STEER_LEFT_KBD,
|
||||
CAR_STEER_RIGHT_KBD,
|
||||
|
||||
//KEYBOARD (tank)
|
||||
TANK_THRUST_LEFT_KBD,
|
||||
TANK_THRUST_RIGHT_KBD,
|
||||
TANK_BRAKE_LEFT_KBD,
|
||||
TANK_BRAKE_RIGHT_KBD,
|
||||
|
||||
//KEYBOARD (camera)
|
||||
CAMERA_ROTATE_LEFT_KBD,
|
||||
CAMERA_ROTATE_RIGHT_KBD,
|
||||
CAMERA_ROTATE_UP_KBD,
|
||||
CAMERA_ROTATE_DOWN_KBD,
|
||||
|
||||
//GAMEPAD (car+tank)
|
||||
VEH_ACCELERATE_PAD,
|
||||
VEH_GEAR_UP_PAD,
|
||||
VEH_GEAR_DOWN_PAD,
|
||||
|
||||
//GAMEPAD (car)
|
||||
CAR_BRAKE_PAD,
|
||||
CAR_HANDBRAKE_PAD,
|
||||
CAR_STEER_PAD,
|
||||
|
||||
//GAMEPAD (tank)
|
||||
TANK_THRUST_LEFT_PAD,
|
||||
TANK_THRUST_RIGHT_PAD,
|
||||
TANK_BRAKE_LEFT_PAD,
|
||||
TANK_BRAKE_RIGHT_PAD,
|
||||
|
||||
//GAMEPAD (camera)
|
||||
CAMERA_ROTATE_LEFT_RIGHT_PAD,
|
||||
CAMERA_ROTATE_UP_DOWN_PAD,
|
||||
|
||||
//
|
||||
AUTOMATIC_GEAR,
|
||||
DEBUG_RENDER_FLAG,
|
||||
DEBUG_RENDER_WHEEL ,
|
||||
DEBUG_RENDER_ENGINE,
|
||||
RETRY,
|
||||
FIX_CAR,
|
||||
CAMERA_LOCK,
|
||||
W3MODE,
|
||||
|
||||
|
||||
NUM_SAMPLE_VEHICLE_INPUT_EVENT_IDS,
|
||||
};
|
||||
|
||||
#endif
|
||||
547
physx/samples/samplevehicle/SampleVehicleTerrain.cpp
Normal file
547
physx/samples/samplevehicle/SampleVehicleTerrain.cpp
Normal file
@ -0,0 +1,547 @@
|
||||
//
|
||||
// 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 "SampleVehicle.h"
|
||||
#include "SampleVehicle_SceneQuery.h"
|
||||
#include "SampleRandomPrecomputed.h"
|
||||
#include "SampleAllocatorSDKClasses.h"
|
||||
#include "RendererMemoryMacros.h"
|
||||
#include "RenderMaterial.h"
|
||||
#include "RenderMeshActor.h"
|
||||
#include "cooking/PxTriangleMeshDesc.h"
|
||||
#include "geometry/PxHeightFieldGeometry.h"
|
||||
#include "geometry/PxHeightFieldSample.h"
|
||||
#include "geometry/PxHeightFieldDesc.h"
|
||||
#include "cooking/PxCooking.h"
|
||||
#include "PxScene.h"
|
||||
#include "PxRigidStatic.h"
|
||||
#include "PxTkStream.h"
|
||||
#include "PxTkFile.h"
|
||||
|
||||
//using namespace physx;
|
||||
using namespace PxToolkit;
|
||||
|
||||
//Use a mesh (instead of a height field)
|
||||
static bool gRecook = false;
|
||||
|
||||
enum MaterialID
|
||||
{
|
||||
MATERIAL_TERRAIN_MUD = 1000,
|
||||
MATERIAL_ROAD_TARMAC = 1001,
|
||||
MATERIAL_ROAD_SNOW = 1002,
|
||||
MATERIAL_ROAD_GRASS = 1003,
|
||||
};
|
||||
|
||||
static void computeTerrain(bool* done, float* pVB, PxU32 x0, PxU32 y0, PxU32 currentSize, float value, PxU32 initSize, SampleRandomPrecomputed& randomPrecomputed)
|
||||
{
|
||||
// Compute new size
|
||||
currentSize>>=1;
|
||||
if(currentSize > 0)
|
||||
{
|
||||
const PxU32 x1 = (x0+currentSize) % initSize;
|
||||
const PxU32 x2 = (x0+currentSize+currentSize) % initSize;
|
||||
const PxU32 y1 = (y0+currentSize) % initSize;
|
||||
const PxU32 y2 = (y0+currentSize+currentSize) % initSize;
|
||||
|
||||
if(!done[x1 + y0*initSize]) pVB[(x1 + y0*initSize)*9+1] = randomPrecomputed.getRandomInRange(-0.5f*value, 0.5f*value) + 0.5f * (pVB[(x0 + y0*initSize)*9+1] + pVB[(x2 + y0*initSize)*9+1]);
|
||||
if(!done[x0 + y1*initSize]) pVB[(x0 + y1*initSize)*9+1] = randomPrecomputed.getRandomInRange(-0.5f*value, 0.5f*value) + 0.5f * (pVB[(x0 + y0*initSize)*9+1] + pVB[(x0 + y2*initSize)*9+1]);
|
||||
if(!done[x2 + y1*initSize]) pVB[(x2 + y1*initSize)*9+1] = randomPrecomputed.getRandomInRange(-0.5f*value, 0.5f*value) + 0.5f * (pVB[(x2 + y0*initSize)*9+1] + pVB[(x2 + y2*initSize)*9+1]);
|
||||
if(!done[x1 + y2*initSize]) pVB[(x1 + y2*initSize)*9+1] = randomPrecomputed.getRandomInRange(-0.5f*value, 0.5f*value) + 0.5f * (pVB[(x0 + y2*initSize)*9+1] + pVB[(x2 + y2*initSize)*9+1]);
|
||||
if(!done[x1 + y1*initSize]) pVB[(x1 + y1*initSize)*9+1] = randomPrecomputed.getRandomInRange(-0.5f*value, 0.5f*value) + 0.5f * (pVB[(x0 + y1*initSize)*9+1] + pVB[(x2 + y1*initSize)*9+1]);
|
||||
|
||||
done[x1 + y0*initSize] = true;
|
||||
done[x0 + y1*initSize] = true;
|
||||
done[x2 + y1*initSize] = true;
|
||||
done[x1 + y2*initSize] = true;
|
||||
done[x1 + y1*initSize] = true;
|
||||
|
||||
// Recurse through 4 corners
|
||||
value *= 0.5f;
|
||||
computeTerrain(done, pVB, x0, y0, currentSize, value, initSize, randomPrecomputed);
|
||||
computeTerrain(done, pVB, x0, y1, currentSize, value, initSize, randomPrecomputed);
|
||||
computeTerrain(done, pVB, x1, y0, currentSize, value, initSize, randomPrecomputed);
|
||||
computeTerrain(done, pVB, x1, y1, currentSize, value, initSize, randomPrecomputed);
|
||||
}
|
||||
}
|
||||
|
||||
void SampleVehicle::createTerrain(PxU32 size, float width, float chaos)
|
||||
{
|
||||
mNbTerrainVerts = size*size;
|
||||
|
||||
// Vertex buffer
|
||||
mTerrainVB = (float*)SAMPLE_ALLOC(sizeof(float)*mNbTerrainVerts*3*3);
|
||||
for(PxU32 y=0;y<size;y++)
|
||||
{
|
||||
for(PxU32 x=0;x<size;x++)
|
||||
{
|
||||
mTerrainVB[(x+y*size)*9+0] = (float(x)-(float(size-1)*0.5f))* width;
|
||||
mTerrainVB[(x+y*size)*9+1] = 0.0f;
|
||||
mTerrainVB[(x+y*size)*9+2] = (float(y)-(float(size-1)*0.5f))* width;
|
||||
mTerrainVB[(x+y*size)*9+3] = 0.0f; mTerrainVB[(x+y*size)*9+4] = 1.0f; mTerrainVB[(x+y*size)*9+5] = 0.0f;
|
||||
mTerrainVB[(x+y*size)*9+6] = 0.5f; mTerrainVB[(x+y*size)*9+7] = 0.4f; mTerrainVB[(x+y*size)*9+8] = 0.2f;
|
||||
}
|
||||
}
|
||||
|
||||
// Fractalize
|
||||
bool* doneBuffer = (bool*)SAMPLE_ALLOC(sizeof(bool)*mNbTerrainVerts);
|
||||
PxU32* tagBuffer = (PxU32*)SAMPLE_ALLOC(sizeof(PxU32)*mNbTerrainVerts);
|
||||
for(PxU32 i=0;i<mNbTerrainVerts;i++)
|
||||
{
|
||||
doneBuffer[i] = false;
|
||||
tagBuffer[i] = 0;
|
||||
}
|
||||
mTerrainVB[1] = 10.0f;
|
||||
mTerrainVB[(size-1)*9+1] = 10.0f;
|
||||
mTerrainVB[(size*(size-1))*9+1] = 10.0f;
|
||||
mTerrainVB[(mNbTerrainVerts-1)*9+1] = 10.0f;
|
||||
|
||||
SampleRandomPrecomputed randomPrecomputed(*this);
|
||||
computeTerrain(doneBuffer, mTerrainVB, 0, 0, size, chaos/16.0f, size, randomPrecomputed);
|
||||
|
||||
const PxU32 street0 = (PxU32)(size/3.0f);
|
||||
const PxU32 streetSize = (PxU32)(size/30.0f);
|
||||
float ay = 0.0f;
|
||||
|
||||
for(PxU32 y=0;y<size;y++)
|
||||
{
|
||||
for(PxU32 x=street0;x<street0+streetSize;x++)
|
||||
{
|
||||
ay+=mTerrainVB[(x+y*size)*9+1];
|
||||
ay+=mTerrainVB[(y+x*size)*9+1];
|
||||
}
|
||||
}
|
||||
|
||||
const float cx = size/2.0f;
|
||||
const float cy = size/2.0f;
|
||||
const float r = size/3.0f;
|
||||
const float g = streetSize/2.0f;
|
||||
|
||||
for(PxU32 i=0;i<mNbTerrainVerts;i++)
|
||||
tagBuffer[i] = false;
|
||||
|
||||
ay/=streetSize*size;
|
||||
ay-=streetSize;
|
||||
for(PxU32 y=15;y<size-15;y++)
|
||||
{
|
||||
bool smoothBorder = true;
|
||||
|
||||
for(PxU32 x=street0;x<street0+streetSize;x++)
|
||||
{
|
||||
if(y > size*0.5f && y < size*0.7f)
|
||||
{
|
||||
mTerrainVB[(x+y*size)*9+1]=ay+sinf(((float)y)*12.0f+4.0f)*2.0f;
|
||||
smoothBorder = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
mTerrainVB[(x+y*size)*9+1]=ay;
|
||||
}
|
||||
|
||||
if(y > size*0.55f && y < size*0.75f)
|
||||
{
|
||||
mTerrainVB[(y+x*size)*9+1]=ay+sinf(y*12.0f)*0.75f;
|
||||
//mTerrainVB[(y+x*size)*9+1]=ay;
|
||||
tagBuffer[y+x*size] = 3;
|
||||
tagBuffer[x+y*size] = 3;
|
||||
smoothBorder = false;
|
||||
}
|
||||
else if(y < size*0.15f)
|
||||
{
|
||||
const float s = size*0.15f-(float)y;
|
||||
mTerrainVB[(y+x*size)*9+1]=ay+s*0.25f;
|
||||
smoothBorder = false;
|
||||
}
|
||||
else if(y > size*0.85f)
|
||||
{
|
||||
const float s = (float)y-size*0.85f;
|
||||
mTerrainVB[(y+x*size)*9+1]=ay+s*0.7f;
|
||||
smoothBorder = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
mTerrainVB[(y+x*size)*9+1]=ay;
|
||||
tagBuffer[y+x*size] = 1;
|
||||
tagBuffer[x+y*size] = 1;
|
||||
}
|
||||
|
||||
}
|
||||
if(smoothBorder)
|
||||
{
|
||||
mTerrainVB[((street0-1)+y*size)*9+1]=ay*0.5f+mTerrainVB[((street0-1)+y*size)*9+1]*0.5f;
|
||||
mTerrainVB[(y+(street0-1)*size)*9+1]=ay*0.5f+mTerrainVB[(y+(street0-1)*size)*9+1]*0.5f;
|
||||
mTerrainVB[((street0+1)+y*size)*9+1]=ay*0.5f+mTerrainVB[((street0+1)+y*size)*9+1]*0.5f;
|
||||
mTerrainVB[(y+(street0+1)*size)*9+1]=ay*0.5f+mTerrainVB[(y+(street0+1)*size)*9+1]*0.5f;
|
||||
}
|
||||
}
|
||||
|
||||
// Circle street
|
||||
for(PxU32 y=0;y<size;y++)
|
||||
{
|
||||
for(PxU32 x=0;x<size;x++)
|
||||
{
|
||||
const float x0 = x-cx;
|
||||
const float y0 = y-cy;
|
||||
const float d = sqrtf(x0*x0+y0*y0);
|
||||
if(d >= r && d < r+streetSize)
|
||||
{
|
||||
mTerrainVB[(y+x*size)*9+1]=ay;
|
||||
|
||||
if(y > size*0.55f && y < size*0.75f)
|
||||
tagBuffer[y+x*size] = 2;
|
||||
else
|
||||
tagBuffer[y+x*size] = 1;
|
||||
|
||||
}
|
||||
else if(d >= r+streetSize && d < r+streetSize+g)
|
||||
{
|
||||
const float a = (d-(r+streetSize))/g;
|
||||
mTerrainVB[(y+x*size)*9+1]=ay*(1.0f-a) + mTerrainVB[(y+x*size)*9+1]*a;
|
||||
}
|
||||
else if(d >= r-g && d < r)
|
||||
{
|
||||
const float a = (d-(r-g))/g;
|
||||
mTerrainVB[(y+x*size)*9+1]=ay*a+mTerrainVB[(y+x*size)*9+1]*(1.0f-a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Borders
|
||||
const float b = size/25.0f;
|
||||
const float bd = size/2.0f-b;
|
||||
for(PxU32 y=0;y<size;y++)
|
||||
{
|
||||
for(PxU32 x=0;x<size;x++)
|
||||
{
|
||||
const float x0 = fabsf(x-cx);
|
||||
const float y0 = fabsf(y-cy);
|
||||
if(x0 > bd || y0 > bd)
|
||||
{
|
||||
float a0 = (x0-bd)/b;
|
||||
float a1 = (y0-bd)/b;
|
||||
if(a1 > a0)
|
||||
a0 = a1;
|
||||
mTerrainVB[(y+x*size)*9+1]=20.0f*a0 + mTerrainVB[(y+x*size)*9+1]*(1-a0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sobel filter
|
||||
for(PxU32 y=1;y<size-1;y++)
|
||||
{
|
||||
for(PxU32 x=1;x<size-1;x++)
|
||||
{
|
||||
// 1 0 -1
|
||||
// 2 0 -2
|
||||
// 1 0 -1
|
||||
float dx;
|
||||
dx = mTerrainVB[((x-1)+(y-1)*size)*9+1];
|
||||
dx -= mTerrainVB[((x+1)+(y-1)*size)*9+1];
|
||||
dx += 2.0f*mTerrainVB[((x-1)+(y+0)*size)*9+1];
|
||||
dx -= 2.0f*mTerrainVB[((x+1)+(y+0)*size)*9+1];
|
||||
dx += mTerrainVB[((x-1)+(y+1)*size)*9+1];
|
||||
dx -= mTerrainVB[((x+1)+(y+1)*size)*9+1];
|
||||
|
||||
// 1 2 1
|
||||
// 0 0 0
|
||||
// -1 -2 -1
|
||||
float dy;
|
||||
dy = mTerrainVB[((x-1)+(y-1)*size)*9+1];
|
||||
dy += 2.0f*mTerrainVB[((x+0)+(y-1)*size)*9+1];
|
||||
dy += mTerrainVB[((x+1)+(y-1)*size)*9+1];
|
||||
dy -= mTerrainVB[((x-1)+(y+1)*size)*9+1];
|
||||
dy -= 2.0f*mTerrainVB[((x+0)+(y+1)*size)*9+1];
|
||||
dy -= mTerrainVB[((x+1)+(y+1)*size)*9+1];
|
||||
|
||||
const float nx = dx/width*0.15f;
|
||||
const float ny = 1.0f;
|
||||
const float nz = dy/width*0.15f;
|
||||
|
||||
const float len = sqrtf(nx*nx+ny*ny+nz*nz);
|
||||
|
||||
mTerrainVB[(x+y*size)*9+3] = nx/len;
|
||||
mTerrainVB[(x+y*size)*9+4] = ny/len;
|
||||
mTerrainVB[(x+y*size)*9+5] = nz/len;
|
||||
}
|
||||
}
|
||||
|
||||
// Static lighting (two directional lights)
|
||||
const float l0[3] = {0.25f/0.8292f, 0.75f/0.8292f, 0.25f/0.8292f};
|
||||
const float l1[3] = {0.65f/0.963f, 0.55f/0.963f, 0.45f/0.963f};
|
||||
//const float len = sqrtf(l1[0]*l1[0]+l1[1]*l1[1]+l1[2]*l1[2]);
|
||||
for(PxU32 y=0;y<size;y++)
|
||||
{
|
||||
for(PxU32 x=0;x<size;x++)
|
||||
{
|
||||
const float nx = mTerrainVB[(x+y*size)*9+3], ny = mTerrainVB[(x+y*size)*9+4], nz = mTerrainVB[(x+y*size)*9+5];
|
||||
|
||||
const float a = 0.3f;
|
||||
float dot0 = l0[0]*nx + l0[1]*ny + l0[2]*nz;
|
||||
float dot1 = l1[0]*nx + l1[1]*ny + l1[2]*nz;
|
||||
if(dot0 < 0.0f) { dot0 = 0.0f; }
|
||||
if(dot1 < 0.0f) { dot1 = 0.0f; }
|
||||
|
||||
const float l = dot0*0.7f + dot1*0.3f;
|
||||
|
||||
mTerrainVB[(x+y*size)*9+6] = mTerrainVB[(x+y*size)*9+6]*(l + a);
|
||||
mTerrainVB[(x+y*size)*9+7] = mTerrainVB[(x+y*size)*9+7]*(l + a);
|
||||
mTerrainVB[(x+y*size)*9+8] = mTerrainVB[(x+y*size)*9+8]*(l + a);
|
||||
|
||||
/*mTerrainVB[(x+y*size)*9+3] = 0.0f;
|
||||
mTerrainVB[(x+y*size)*9+4] = -1.0f;
|
||||
mTerrainVB[(x+y*size)*9+5] = 0.0f;*/
|
||||
}
|
||||
}
|
||||
|
||||
// Index buffers
|
||||
const PxU32 maxNbTerrainTriangles = (size-1)*(size-1)*2;
|
||||
|
||||
mNbIB = 4;
|
||||
mRenderMaterial[0] = MATERIAL_TERRAIN_MUD;
|
||||
mRenderMaterial[1] = MATERIAL_ROAD_TARMAC;
|
||||
mRenderMaterial[2] = MATERIAL_ROAD_SNOW;
|
||||
mRenderMaterial[3] = MATERIAL_ROAD_GRASS;
|
||||
|
||||
for(PxU32 i=0;i<mNbIB;i++)
|
||||
{
|
||||
mIB[i] = (PxU32*)SAMPLE_ALLOC(sizeof(PxU32)*maxNbTerrainTriangles*3);
|
||||
mNbTriangles[i] = 0;
|
||||
}
|
||||
|
||||
for(PxU32 j=0;j<size-1;j++)
|
||||
{
|
||||
for(PxU32 i=0;i<size-1;i++)
|
||||
{
|
||||
PxU32 tris[6];
|
||||
tris[0] = i + j*size; tris[1] = i + (j+1)*size; tris[2] = i+1 + (j+1)*size;
|
||||
tris[3] = i + j*size; tris[4] = i+1 + (j+1)*size; tris[5] = i+1 + j*size;
|
||||
|
||||
for(PxU32 t=0;t<2;t++)
|
||||
{
|
||||
const PxU32 vt0 = tagBuffer[tris[t*3+0]];
|
||||
const PxU32 vt1 = tagBuffer[tris[t*3+1]];
|
||||
const PxU32 vt2 = tagBuffer[tris[t*3+2]];
|
||||
|
||||
PxU32 buffer = 0;
|
||||
if(vt0 == vt1 && vt0 == vt2)
|
||||
buffer = vt0;
|
||||
|
||||
mIB[buffer][mNbTriangles[buffer]*3+0] = tris[t*3+0];
|
||||
mIB[buffer][mNbTriangles[buffer]*3+1] = tris[t*3+1];
|
||||
mIB[buffer][mNbTriangles[buffer]*3+2] = tris[t*3+2];
|
||||
mNbTriangles[buffer]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SAMPLE_FREE(tagBuffer);
|
||||
SAMPLE_FREE(doneBuffer);
|
||||
}
|
||||
|
||||
void SampleVehicle::addMesh(PxRigidActor* actor, float* verts, PxU32 nVerts, PxU32* indices, PxU32 mIndices, PxU32 materialIndex, const char* filename)
|
||||
{
|
||||
const char* filenameCooked = getSampleOutputFilePath(filename, "");
|
||||
PX_ASSERT(NULL != filenameCooked);
|
||||
|
||||
bool ok = false;
|
||||
if(!gRecook)
|
||||
{
|
||||
SampleFramework::File* fp = NULL;
|
||||
PxToolkit::fopen_s(&fp, filenameCooked, "rb");
|
||||
if(fp)
|
||||
{
|
||||
fseek(fp, 0, SEEK_END);
|
||||
PxU32 filesize = (PxU32)ftell(fp);
|
||||
|
||||
fclose(fp);
|
||||
|
||||
|
||||
ok = (filesize != 0);
|
||||
}
|
||||
}
|
||||
|
||||
if(!ok)
|
||||
{
|
||||
PxTriangleMeshDesc meshDesc;
|
||||
meshDesc.points.count = nVerts;
|
||||
meshDesc.triangles.count = mIndices;
|
||||
meshDesc.points.stride = sizeof(float)*3*3;
|
||||
meshDesc.triangles.stride = sizeof(PxU32)*3;
|
||||
meshDesc.points.data = verts;
|
||||
meshDesc.triangles.data = indices;
|
||||
meshDesc.flags = PxMeshFlags(0);
|
||||
|
||||
//
|
||||
shdfnd::printFormatted("Cooking object... %s", filenameCooked);
|
||||
PxDefaultFileOutputStream stream(filenameCooked);
|
||||
ok = getCooking().cookTriangleMesh(meshDesc, stream);
|
||||
shdfnd::printFormatted(" - Done\n");
|
||||
}
|
||||
|
||||
{
|
||||
PxDefaultFileInputData stream(filenameCooked);
|
||||
PxTriangleMesh* triangleMesh = getPhysics().createTriangleMesh(stream);
|
||||
|
||||
if(triangleMesh)
|
||||
{
|
||||
PxRigidActorExt::createExclusiveShape(*actor, PxTriangleMeshGeometry(triangleMesh), *mStandardMaterials[materialIndex] /**mStandardMaterial*/);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PT: the renderer also expects 16bit indices so we still have to cut a big mesh to pieces
|
||||
void SampleVehicle::addRenderMesh(float* verts, PxU32 nVerts, PxU32* indices, PxU32 mIndices, PxU32 matID)
|
||||
{
|
||||
float minX=1000000.0f;
|
||||
float minZ=1000000.0f;
|
||||
float maxX=-1000000.0f;
|
||||
float maxZ=-1000000.0f;
|
||||
|
||||
// PT: the VB uses interleaved data so we need a temp buffer
|
||||
PxVec3Alloc* v = SAMPLE_NEW(PxVec3Alloc)[nVerts];
|
||||
float* curVerts = verts;
|
||||
PxBounds3 meshBound = PxBounds3::empty();
|
||||
for(PxU32 i=0;i<nVerts;i++)
|
||||
{
|
||||
v[i].x = curVerts[0];
|
||||
v[i].y = curVerts[1];
|
||||
v[i].z = curVerts[2];
|
||||
if (v[i].x < minX) { minX = v[i].x; }
|
||||
if (v[i].z < minZ) { minZ = v[i].z; }
|
||||
if (v[i].x > maxX) { maxX = v[i].x; }
|
||||
if (v[i].z > maxZ) { maxZ = v[i].z; }
|
||||
curVerts += 3*3;
|
||||
|
||||
meshBound.include(v[i]);
|
||||
}
|
||||
|
||||
PxReal* uv = (PxReal*)SAMPLE_ALLOC(sizeof(PxReal)*nVerts*2);
|
||||
curVerts = verts;
|
||||
const float scaleX = (maxX-minX)/64.0f;
|
||||
const float scaleZ = (maxZ-minZ)/64.0f;
|
||||
for(PxU32 i=0;i<nVerts;i++)
|
||||
{
|
||||
uv[i*2+0] = (curVerts[0]-minX)/scaleX;
|
||||
uv[i*2+1] = (curVerts[2]-minZ)/scaleZ;
|
||||
curVerts += 3*3;
|
||||
}
|
||||
|
||||
RAWMesh data;
|
||||
data.mMaterialID = matID;
|
||||
data.mNbVerts = nVerts;
|
||||
data.mNbFaces = mIndices;
|
||||
data.mVerts = v;
|
||||
data.mUVs = uv;
|
||||
data.mIndices = indices;
|
||||
RenderMeshActor* renderActor = createRenderMeshFromRawMesh(data);
|
||||
if( renderActor != NULL )
|
||||
{
|
||||
renderActor->setWorldBounds(meshBound);
|
||||
renderActor->setEnableCameraCull(true);
|
||||
}
|
||||
|
||||
SAMPLE_FREE(uv);
|
||||
DELETEARRAY(v);
|
||||
}
|
||||
|
||||
void SampleVehicle::createTrack(PxU32 size, float width, float chaos)
|
||||
{
|
||||
createTerrain(size, width, chaos);
|
||||
createLandscapeMesh();
|
||||
}
|
||||
|
||||
void SampleVehicle::createLandscapeMesh()
|
||||
{
|
||||
RAWTexture data;
|
||||
data.mName = "gravel_diffuse.dds";
|
||||
RenderTexture* gravelTexture = createRenderTextureFromRawTexture(data);
|
||||
|
||||
mTerrainMaterial = SAMPLE_NEW(RenderMaterial)(*getRenderer(), PxVec3(0.5f, 0.25f, 0.125f), 1.0f, false, MATERIAL_TERRAIN_MUD, gravelTexture);
|
||||
mRenderMaterials.push_back(mTerrainMaterial);
|
||||
|
||||
data.mName = "asphalt_diffuse.dds";
|
||||
RenderTexture* asphaltTexture = createRenderTextureFromRawTexture(data);
|
||||
|
||||
mRoadMaterial = SAMPLE_NEW(RenderMaterial)(*getRenderer(), PxVec3(1.0f, 1.0f, 1.0f), 1.0f, false, MATERIAL_ROAD_TARMAC, asphaltTexture);
|
||||
mRenderMaterials.push_back(mRoadMaterial);
|
||||
|
||||
data.mName = "ice_diffuse.dds";
|
||||
RenderTexture* snowTexture = createRenderTextureFromRawTexture(data);
|
||||
|
||||
mRoadIceMaterial = SAMPLE_NEW(RenderMaterial)(*getRenderer(), PxVec3(0.05f, 0.05f, 0.75f), 1.0f, false, MATERIAL_ROAD_SNOW, snowTexture);
|
||||
mRenderMaterials.push_back(mRoadIceMaterial);
|
||||
|
||||
data.mName = "grass_diffuse.dds";
|
||||
RenderTexture* grassTexture = createRenderTextureFromRawTexture(data);
|
||||
|
||||
mRoadGravelMaterial = SAMPLE_NEW(RenderMaterial)(*getRenderer(), PxVec3(1.0f, 1.0f, 1.0f), 1.0f, false, MATERIAL_ROAD_GRASS, grassTexture);
|
||||
mRenderMaterials.push_back(mRoadGravelMaterial);
|
||||
|
||||
PxTransform pose;
|
||||
pose = PxTransform(PxIdentity);
|
||||
// pose.p.y -= 10.0f;
|
||||
mHFActor = getPhysics().createRigidStatic(pose);
|
||||
|
||||
for(PxU32 i=0;i<mNbIB;i++)
|
||||
{
|
||||
if(mNbTriangles[i] > 0)
|
||||
{
|
||||
char filename[512];
|
||||
sprintf(filename, "SampleVehicleGroundMeshes_Part%d", i);
|
||||
addMesh(mHFActor, mTerrainVB, mNbTerrainVerts, mIB[i], mNbTriangles[i], i, filename);
|
||||
if (mNbTriangles[i] > (1<<16))
|
||||
{
|
||||
PxU32 firstBatch = mNbTriangles[i]/2;
|
||||
addRenderMesh(mTerrainVB, mNbTerrainVerts, mIB[i], firstBatch, MATERIAL_TERRAIN_MUD);
|
||||
addRenderMesh(mTerrainVB, mNbTerrainVerts, mIB[i]+(firstBatch*3), mNbTriangles[i]-firstBatch, mRenderMaterial[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
addRenderMesh(mTerrainVB, mNbTerrainVerts, mIB[i], mNbTriangles[i], mRenderMaterial[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PxSceneWriteLock scopedLock(*mScene);
|
||||
mScene->addActor(*mHFActor);
|
||||
|
||||
PxShape* shapeBuffer[MAX_NUM_INDEX_BUFFERS];
|
||||
mHFActor->getShapes(shapeBuffer, MAX_NUM_INDEX_BUFFERS);
|
||||
PxFilterData simulationFilterData;
|
||||
simulationFilterData.word0=COLLISION_FLAG_GROUND;
|
||||
simulationFilterData.word1=COLLISION_FLAG_GROUND_AGAINST;
|
||||
PxFilterData queryFilterData;
|
||||
SampleVehicleSetupDrivableShapeQueryFilterData(&queryFilterData);
|
||||
|
||||
for(PxU32 i=0;i<mNbIB;i++)
|
||||
{
|
||||
shapeBuffer[i]->setSimulationFilterData(simulationFilterData);
|
||||
shapeBuffer[i]->setQueryFilterData(queryFilterData);
|
||||
shapeBuffer[i]->setFlag(PxShapeFlag::eVISUALIZATION,false);
|
||||
}
|
||||
}
|
||||
164
physx/samples/samplevehicle/SampleVehicle_CameraController.cpp
Normal file
164
physx/samples/samplevehicle/SampleVehicle_CameraController.cpp
Normal file
@ -0,0 +1,164 @@
|
||||
//
|
||||
// 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 "SampleVehicle_CameraController.h"
|
||||
#include "PhysXSampleApplication.h"
|
||||
#include "PxRigidDynamic.h"
|
||||
#include "PxQueryFiltering.h"
|
||||
#include "PxScene.h"
|
||||
#include "PxSceneLock.h"
|
||||
#include "vehicle/PxVehicleWheels.h"
|
||||
|
||||
using namespace SampleRenderer;
|
||||
using namespace SampleFramework;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
SampleVehicle_CameraController::SampleVehicle_CameraController()
|
||||
: mRotateInputY (0.0f),
|
||||
mRotateInputZ (0.0f),
|
||||
mMaxCameraRotateSpeed (5.0f),
|
||||
mCameraRotateAngleY (0.0f),
|
||||
mCameraRotateAngleZ (0.33f),
|
||||
mCameraPos (PxVec3(0,0,0)),
|
||||
mCameraTargetPos (PxVec3(0,0,0)),
|
||||
mLastCarPos (PxVec3(0,0,0)),
|
||||
mLastCarVelocity (PxVec3(0,0,0)),
|
||||
mCameraInit (false),
|
||||
mLockOnFocusVehTransform (true),
|
||||
mLastFocusVehTransform (PxTransform(PxIdentity))
|
||||
{
|
||||
}
|
||||
|
||||
SampleVehicle_CameraController::~SampleVehicle_CameraController()
|
||||
{
|
||||
}
|
||||
|
||||
static void dampVec3(const PxVec3& oldPosition, PxVec3& newPosition, PxF32 timestep)
|
||||
{
|
||||
PxF32 t = 0.7f * timestep * 8.0f;
|
||||
t = PxMin(t, 1.0f);
|
||||
newPosition = oldPosition * (1 - t) + newPosition * t;
|
||||
}
|
||||
|
||||
void SampleVehicle_CameraController::update(const PxReal dtime, const PxRigidDynamic* actor, PxScene& scene)
|
||||
{
|
||||
PxSceneReadLock scopedLock(scene);
|
||||
PxTransform carChassisTransfm;
|
||||
if(mLockOnFocusVehTransform)
|
||||
{
|
||||
carChassisTransfm = actor->getGlobalPose();
|
||||
mLastFocusVehTransform = carChassisTransfm;
|
||||
}
|
||||
else
|
||||
{
|
||||
carChassisTransfm = mLastFocusVehTransform;
|
||||
}
|
||||
|
||||
PxF32 camDist = 15.0f;
|
||||
PxF32 cameraYRotExtra = 0.0f;
|
||||
|
||||
PxVec3 velocity = mLastCarPos-carChassisTransfm.p;
|
||||
|
||||
if (mCameraInit)
|
||||
{
|
||||
//Work out the forward and sideways directions.
|
||||
PxVec3 unitZ(0,0,1);
|
||||
PxVec3 carDirection = carChassisTransfm.q.rotate(unitZ);
|
||||
PxVec3 unitX(1,0,0);
|
||||
PxVec3 carSideDirection = carChassisTransfm.q.rotate(unitX);
|
||||
|
||||
//Acceleration (note that is not scaled by time).
|
||||
PxVec3 acclVec = mLastCarVelocity-velocity;
|
||||
|
||||
//Higher forward accelerations allow the car to speed away from the camera.
|
||||
PxF32 acclZ = carDirection.dot(acclVec);
|
||||
camDist = PxMax(camDist+acclZ*400.0f, 5.0f);
|
||||
|
||||
//Higher sideways accelerations allow the car's rotation to speed away from the camera's rotation.
|
||||
PxF32 acclX = carSideDirection.dot(acclVec);
|
||||
cameraYRotExtra = -acclX*10.0f;
|
||||
//At very small sideways speeds the camera greatly amplifies any numeric error in the body and leads to a slight jitter.
|
||||
//Scale cameraYRotExtra by a value in range (0,1) for side speeds in range (0.1,1.0) and by zero for side speeds less than 0.1.
|
||||
PxFixedSizeLookupTable<4> table;
|
||||
table.addPair(0.0f, 0.0f);
|
||||
table.addPair(0.1f*dtime, 0);
|
||||
table.addPair(1.0f*dtime, 1);
|
||||
PxF32 velX = carSideDirection.dot(velocity);
|
||||
cameraYRotExtra *= table.getYVal(PxAbs(velX));
|
||||
}
|
||||
|
||||
mCameraRotateAngleY+=mRotateInputY*mMaxCameraRotateSpeed*dtime;
|
||||
mCameraRotateAngleY=physx::intrinsics::fsel(mCameraRotateAngleY-10*PxPi, mCameraRotateAngleY-10*PxPi, physx::intrinsics::fsel(-mCameraRotateAngleY-10*PxPi, mCameraRotateAngleY + 10*PxPi, mCameraRotateAngleY));
|
||||
mCameraRotateAngleZ+=mRotateInputZ*mMaxCameraRotateSpeed*dtime;
|
||||
mCameraRotateAngleZ=PxClamp(mCameraRotateAngleZ,-PxPi*0.05f,PxPi*0.45f);
|
||||
|
||||
PxVec3 cameraDir=PxVec3(0,0,1)*PxCos(mCameraRotateAngleY+cameraYRotExtra) + PxVec3(1,0,0)*PxSin(mCameraRotateAngleY+cameraYRotExtra);
|
||||
|
||||
cameraDir=cameraDir*PxCos(mCameraRotateAngleZ)-PxVec3(0,1,0)*PxSin(mCameraRotateAngleZ);
|
||||
|
||||
const PxVec3 direction = carChassisTransfm.q.rotate(cameraDir);
|
||||
PxVec3 target = carChassisTransfm.p;
|
||||
target.y+=0.5f;
|
||||
|
||||
PxRaycastBuffer hit;
|
||||
PxQueryFilterData filterData(PxQueryFlag::eSTATIC);
|
||||
scene.raycast(target, -direction, camDist, hit, PxHitFlags(0), filterData);
|
||||
if (hit.hasBlock && hit.block.shape != NULL)
|
||||
{
|
||||
camDist = hit.block.distance-0.25f;
|
||||
}
|
||||
|
||||
camDist = PxMax(5.0f, PxMin(camDist, 50.0f));
|
||||
|
||||
PxVec3 position = target-direction*camDist;
|
||||
|
||||
if (mCameraInit)
|
||||
{
|
||||
dampVec3(mCameraPos, position, dtime);
|
||||
dampVec3(mCameraTargetPos, target, dtime);
|
||||
}
|
||||
|
||||
mCameraPos = position;
|
||||
mCameraTargetPos = target;
|
||||
mCameraInit = true;
|
||||
|
||||
mLastCarVelocity = velocity;
|
||||
mLastCarPos = carChassisTransfm.p;
|
||||
}
|
||||
|
||||
void SampleVehicle_CameraController::update(const PxReal dtime, const PxVehicleWheels& focusVehicle, PxScene& scene)
|
||||
{
|
||||
const PxRigidDynamic* actor=focusVehicle.getRigidDynamicActor();
|
||||
update(dtime,actor,scene);
|
||||
}
|
||||
|
||||
|
||||
92
physx/samples/samplevehicle/SampleVehicle_CameraController.h
Normal file
92
physx/samples/samplevehicle/SampleVehicle_CameraController.h
Normal file
@ -0,0 +1,92 @@
|
||||
//
|
||||
// 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 SAMPLE_VEHICLE_CAMERA_CONTROLLER_H
|
||||
#define SAMPLE_VEHICLE_CAMERA_CONTROLLER_H
|
||||
|
||||
#include "common/PxPhysXCommonConfig.h"
|
||||
#include "foundation/PxVec3.h"
|
||||
#include "foundation/PxTransform.h"
|
||||
|
||||
using namespace physx;
|
||||
|
||||
namespace physx
|
||||
{
|
||||
class PxScene;
|
||||
class PxVehicleWheels;
|
||||
class PxRigidDynamic;
|
||||
}
|
||||
|
||||
class Camera;
|
||||
|
||||
class SampleVehicle_CameraController
|
||||
{
|
||||
public:
|
||||
|
||||
SampleVehicle_CameraController();
|
||||
~SampleVehicle_CameraController();
|
||||
|
||||
void setInputs(const PxF32 rotateInputY, const PxF32 rotateInputZ)
|
||||
{
|
||||
mRotateInputY=rotateInputY;
|
||||
mRotateInputZ=rotateInputZ;
|
||||
}
|
||||
|
||||
void update(const PxF32 dtime, const PxVehicleWheels& focusVehicle, PxScene& scene);
|
||||
|
||||
void restart() {}
|
||||
|
||||
bool getIsLockedOnVehicleTransform() const {return mLockOnFocusVehTransform;}
|
||||
void toggleLockOnVehTransform() {mLockOnFocusVehTransform = !mLockOnFocusVehTransform;}
|
||||
|
||||
const PxVec3& getCameraPos() const {return mCameraPos;}
|
||||
const PxVec3& getCameraTar() const {return mCameraTargetPos;}
|
||||
|
||||
private:
|
||||
|
||||
PxF32 mRotateInputY;
|
||||
PxF32 mRotateInputZ;
|
||||
|
||||
PxF32 mMaxCameraRotateSpeed;
|
||||
PxF32 mCameraRotateAngleY;
|
||||
PxF32 mCameraRotateAngleZ;
|
||||
PxVec3 mCameraPos;
|
||||
PxVec3 mCameraTargetPos;
|
||||
PxVec3 mLastCarPos;
|
||||
PxVec3 mLastCarVelocity;
|
||||
bool mCameraInit;
|
||||
|
||||
bool mLockOnFocusVehTransform;
|
||||
PxTransform mLastFocusVehTransform;
|
||||
|
||||
void update(const PxReal dtime, const PxRigidDynamic* actor, PxScene& scene);
|
||||
};
|
||||
|
||||
#endif //SAMPLE_VEHICLE_CAMERA_CONTROLLER_H
|
||||
68
physx/samples/samplevehicle/SampleVehicle_ControlInputs.cpp
Normal file
68
physx/samples/samplevehicle/SampleVehicle_ControlInputs.cpp
Normal file
@ -0,0 +1,68 @@
|
||||
//
|
||||
// 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 "SampleVehicle_ControlInputs.h"
|
||||
#include "PhysXSampleApplication.h"
|
||||
|
||||
using namespace SampleRenderer;
|
||||
using namespace SampleFramework;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SampleVehicle_ControlInputs::SampleVehicle_ControlInputs()
|
||||
: mCameraRotateInputY (0.0f),
|
||||
mCameraRotateInputZ (0.0f),
|
||||
mAccelKeyPressed (false),
|
||||
mGearUpKeyPressed (false),
|
||||
mGearDownKeyPressed (false),
|
||||
mBrakeKeyPressed (false),
|
||||
mHandbrakeKeyPressed (false),
|
||||
mSteerLeftKeyPressed (false),
|
||||
mSteerRightKeyPressed (false),
|
||||
mBrakeLeftKeyPressed (false),
|
||||
mBrakeRightKeyPressed (false),
|
||||
mThrustLeftKeyPressed (false),
|
||||
mThrustRightKeyPressed (false),
|
||||
mAccel (0.0f),
|
||||
mGearup (false),
|
||||
mGeardown (false),
|
||||
mBrake (0.0f),
|
||||
mSteer (0.0f),
|
||||
mHandbrake (false),
|
||||
mThrustLeft (0.0f),
|
||||
mThrustRight (0.0f),
|
||||
mBrakeLeft (0.0f),
|
||||
mBrakeRight (0.0f)
|
||||
{
|
||||
}
|
||||
|
||||
SampleVehicle_ControlInputs::~SampleVehicle_ControlInputs()
|
||||
{
|
||||
}
|
||||
|
||||
145
physx/samples/samplevehicle/SampleVehicle_ControlInputs.h
Normal file
145
physx/samples/samplevehicle/SampleVehicle_ControlInputs.h
Normal file
@ -0,0 +1,145 @@
|
||||
//
|
||||
// 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 SAMPLE_VEHICLE_CONTROL_INPUTS_H
|
||||
#define SAMPLE_VEHICLE_CONTROL_INPUTS_H
|
||||
|
||||
#include "common/PxPhysXCommonConfig.h"
|
||||
|
||||
using namespace physx;
|
||||
|
||||
class SampleVehicle_ControlInputs
|
||||
{
|
||||
public:
|
||||
|
||||
SampleVehicle_ControlInputs();
|
||||
~SampleVehicle_ControlInputs();
|
||||
|
||||
//Camera inputs
|
||||
void setRotateY(const PxF32 f) {mCameraRotateInputY=f;}
|
||||
void setRotateZ(const PxF32 f) {mCameraRotateInputZ=f;}
|
||||
PxF32 getRotateY() const {return mCameraRotateInputY;}
|
||||
PxF32 getRotateZ() const {return mCameraRotateInputZ;}
|
||||
|
||||
//Keyboard driving inputs - (car + tank)
|
||||
void setAccelKeyPressed(const bool b) {mAccelKeyPressed=b;}
|
||||
void setGearUpKeyPressed(const bool b) {mGearUpKeyPressed=b;}
|
||||
void setGearDownKeyPressed(const bool b) {mGearDownKeyPressed=b;}
|
||||
bool getAccelKeyPressed() const {return mAccelKeyPressed;}
|
||||
bool getGearUpKeyPressed() const {return mGearUpKeyPressed;}
|
||||
bool getGearDownKeyPressed() const {return mGearDownKeyPressed;}
|
||||
|
||||
//Keyboard driving inputs - (car only)
|
||||
void setBrakeKeyPressed(const bool b) {mBrakeKeyPressed=b;}
|
||||
void setHandbrakeKeyPressed(const bool b) {mHandbrakeKeyPressed=b;}
|
||||
void setSteerLeftKeyPressed(const bool b) {mSteerLeftKeyPressed=b;}
|
||||
void setSteerRightKeyPressed(const bool b) {mSteerRightKeyPressed=b;}
|
||||
bool getBrakeKeyPressed() const {return mBrakeKeyPressed;}
|
||||
bool getHandbrakeKeyPressed() const {return mHandbrakeKeyPressed;}
|
||||
bool getSteerLeftKeyPressed() const {return mSteerLeftKeyPressed;}
|
||||
bool getSteerRightKeyPressed() const {return mSteerRightKeyPressed;}
|
||||
|
||||
//Keyboard driving inputs - (tank only)
|
||||
void setBrakeLeftKeyPressed(const bool b) {mBrakeLeftKeyPressed=b;}
|
||||
void setBrakeRightKeyPressed(const bool b) {mBrakeRightKeyPressed=b;}
|
||||
void setThrustLeftKeyPressed(const bool b) {mThrustLeftKeyPressed=b;}
|
||||
void setThrustRightKeyPressed(const bool b) {mThrustRightKeyPressed=b;}
|
||||
bool getBrakeLeftKeyPressed() const {return mBrakeLeftKeyPressed;}
|
||||
bool getBrakeRightKeyPressed() const {return mBrakeRightKeyPressed;}
|
||||
bool getThrustLeftKeyPressed() const {return mThrustLeftKeyPressed;}
|
||||
bool getThrustRightKeyPressed() const {return mThrustRightKeyPressed;}
|
||||
|
||||
//Gamepad driving inputs (car + tank)
|
||||
void setAccel(const PxF32 f) {mAccel=f;}
|
||||
void setGearUp(const bool b) {mGearup=b;}
|
||||
void setGearDown(const bool b) {mGeardown=b;}
|
||||
PxF32 getAccel() const {return mAccel;}
|
||||
bool getGearUp() const {return mGearup;}
|
||||
bool getGearDown() const {return mGeardown;}
|
||||
|
||||
//Gamepad driving inputs (car only)
|
||||
void setBrake(const PxF32 f) {mBrake=f;}
|
||||
void setSteer(const PxF32 f) {mSteer=f;}
|
||||
void setHandbrake(const bool b) {mHandbrake=b;}
|
||||
PxF32 getBrake() const {return mBrake;}
|
||||
PxF32 getSteer() const {return mSteer;}
|
||||
bool getHandbrake() const {return mHandbrake;}
|
||||
|
||||
//Gamepad driving inputs (tank only)
|
||||
void setThrustLeft(const PxF32 f) {mThrustLeft=f;}
|
||||
void setThrustRight(const PxF32 f) {mThrustRight=f;}
|
||||
PxF32 getThrustLeft() const {return mThrustLeft;}
|
||||
PxF32 getThrustRight() const {return mThrustRight;}
|
||||
void setBrakeLeft(const PxF32 f) {mBrakeLeft=f;}
|
||||
void setBrakeRight(const PxF32 f) {mBrakeRight=f;}
|
||||
PxF32 getBrakeLeft() const {return mBrakeLeft;}
|
||||
PxF32 getBrakeRight() const {return mBrakeRight;}
|
||||
|
||||
private:
|
||||
|
||||
//Camera inputs.
|
||||
PxF32 mCameraRotateInputY;
|
||||
PxF32 mCameraRotateInputZ;
|
||||
|
||||
//keyboard inputs (car and tank)
|
||||
bool mAccelKeyPressed;
|
||||
bool mGearUpKeyPressed;
|
||||
bool mGearDownKeyPressed;
|
||||
|
||||
//keyboard inputs (car only)
|
||||
bool mBrakeKeyPressed;
|
||||
bool mHandbrakeKeyPressed;
|
||||
bool mSteerLeftKeyPressed;
|
||||
bool mSteerRightKeyPressed;
|
||||
|
||||
//keyboard inputs (tank only)
|
||||
bool mBrakeLeftKeyPressed;
|
||||
bool mBrakeRightKeyPressed;
|
||||
bool mThrustLeftKeyPressed;
|
||||
bool mThrustRightKeyPressed;
|
||||
|
||||
//gamepad inputs (car and tank)
|
||||
PxF32 mAccel;
|
||||
bool mGearup;
|
||||
bool mGeardown;
|
||||
|
||||
//gamepad inputs (car only)
|
||||
PxF32 mBrake;
|
||||
PxF32 mSteer;
|
||||
bool mHandbrake;
|
||||
|
||||
//gamepad inputs (tank only)
|
||||
PxF32 mThrustLeft;
|
||||
PxF32 mThrustRight;
|
||||
PxF32 mBrakeLeft;
|
||||
PxF32 mBrakeRight;
|
||||
};
|
||||
|
||||
#endif //SAMPLE_VEHICLE_CONTROL_INPUTS_H
|
||||
91
physx/samples/samplevehicle/SampleVehicle_GameLogic.cpp
Normal file
91
physx/samples/samplevehicle/SampleVehicle_GameLogic.cpp
Normal file
@ -0,0 +1,91 @@
|
||||
//
|
||||
// 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 "SampleVehicle_GameLogic.h"
|
||||
|
||||
void SampleVehicleWayPoints::getNextWayPointsAndLineDirs(PxU32& numPoints, PxVec3& v0, PxVec3& v1, PxVec3& v2, PxVec3& w0, PxVec3& w1, PxVec3& w2) const
|
||||
{
|
||||
numPoints=0;
|
||||
if((mProgress+1) < mNumWayPoints)
|
||||
{
|
||||
v0=mWayPoints[mProgress+1].p;
|
||||
w0=mWayPoints[mProgress+1].q.getBasisVector0();
|
||||
numPoints++;
|
||||
|
||||
if((mProgress+2) < mNumWayPoints)
|
||||
{
|
||||
v1=mWayPoints[mProgress+2].p;
|
||||
w1=mWayPoints[mProgress+2].q.getBasisVector0();
|
||||
numPoints++;
|
||||
|
||||
if((mProgress+3) < mNumWayPoints)
|
||||
{
|
||||
v2=mWayPoints[mProgress+3].p;
|
||||
w2=mWayPoints[mProgress+3].q.getBasisVector0();
|
||||
numPoints++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define LINEWIDTH 8
|
||||
#define LINEDISTANCE2 3*3
|
||||
void SampleVehicleWayPoints::update(const PxTransform& playerTransform, const PxF32 timestep)
|
||||
{
|
||||
//Increment the elapsed time
|
||||
mTimeElapsed+=timestep;
|
||||
|
||||
//Work out the point on the crossing line of the next way-point that is closest to the player.
|
||||
const PxTransform& nextWayPoint=mWayPoints[mProgress+1];
|
||||
const PxVec3 v=nextWayPoint.p;
|
||||
const PxVec3 w=nextWayPoint.q.getBasisVector0();
|
||||
const PxVec3 p=playerTransform.p;
|
||||
const PxVec3 pv=p-v;
|
||||
const PxF32 t=pv.dot(w);
|
||||
|
||||
//Test if the player's position is inside the width of the line crossing the next way-point.
|
||||
if(PxAbs(t) < LINEWIDTH)
|
||||
{
|
||||
//Now test if the shortest distance to the next crossing line is smaller than a threshold.
|
||||
const PxVec3 linePos=v+w*t;
|
||||
const PxVec3 diff=p-linePos;
|
||||
const PxF32 dist2=diff.magnitudeSquared();
|
||||
if(dist2<LINEDISTANCE2)
|
||||
{
|
||||
mProgress++;
|
||||
}
|
||||
}
|
||||
|
||||
if(mProgress == mNumWayPoints-1)
|
||||
{
|
||||
mMinTimeElapsed=PxMin(mTimeElapsed, mMinTimeElapsed);
|
||||
mTimeElapsed=0;
|
||||
mProgress=0;
|
||||
}
|
||||
}
|
||||
97
physx/samples/samplevehicle/SampleVehicle_GameLogic.h
Normal file
97
physx/samples/samplevehicle/SampleVehicle_GameLogic.h
Normal file
@ -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 SAMPLE_VEHICLE_GAME_LOGIC_H
|
||||
#define SAMPLE_VEHICLE_GAME_LOGIC_H
|
||||
|
||||
#include "common/PxPhysXCommonConfig.h"
|
||||
#include "foundation/PxTransform.h"
|
||||
|
||||
using namespace physx;
|
||||
|
||||
class SampleVehicleWayPoints
|
||||
{
|
||||
public:
|
||||
|
||||
SampleVehicleWayPoints()
|
||||
: mWayPoints(NULL),
|
||||
mNumWayPoints(0),
|
||||
mProgress(0),
|
||||
mTimeElapsed(0),
|
||||
mMinTimeElapsed(100000)
|
||||
{
|
||||
}
|
||||
|
||||
~SampleVehicleWayPoints()
|
||||
{
|
||||
}
|
||||
|
||||
//Setup.
|
||||
void setWayPoints(const PxTransform* wayPoints, const PxU32 numWayPoints)
|
||||
{
|
||||
mWayPoints=wayPoints;
|
||||
mNumWayPoints=numWayPoints;
|
||||
}
|
||||
|
||||
//Update.
|
||||
void update(const PxTransform& playerTransform, const PxF32 timestep);
|
||||
|
||||
//Imagine we are starting the lap again.
|
||||
PxTransform setBackAtStart()
|
||||
{
|
||||
mTimeElapsed=0;
|
||||
mProgress=0;
|
||||
return mWayPoints[0];
|
||||
}
|
||||
|
||||
//Get the next three points and the crossing line of each way-point.
|
||||
void getNextWayPointsAndLineDirs(PxU32& numPoints, PxVec3& v0, PxVec3& v1, PxVec3& v2, PxVec3& w0, PxVec3& w1, PxVec3& w2) const;
|
||||
|
||||
//Get lap time and best lap time.
|
||||
PxF32 getTimeElapsed() const {return mTimeElapsed;}
|
||||
PxF32 getMinTimeElapsed() const {return mMinTimeElapsed;}
|
||||
|
||||
//Get the transform to reset the car at the last passed way-point.
|
||||
PxTransform getResetTransform() const {return mWayPoints[mProgress];}
|
||||
|
||||
private:
|
||||
|
||||
//Array of way points.
|
||||
const PxTransform* mWayPoints;
|
||||
PxU32 mNumWayPoints;
|
||||
|
||||
//Progress and time elapsed.
|
||||
PxU32 mProgress;
|
||||
PxF32 mTimeElapsed;
|
||||
PxF32 mMinTimeElapsed;
|
||||
};
|
||||
|
||||
|
||||
#endif //SAMPLE_VEHICLE_GAME_LOGIC_H
|
||||
90
physx/samples/samplevehicle/SampleVehicle_SceneQuery.cpp
Normal file
90
physx/samples/samplevehicle/SampleVehicle_SceneQuery.cpp
Normal file
@ -0,0 +1,90 @@
|
||||
//
|
||||
// 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 "SampleVehicle_SceneQuery.h"
|
||||
#include "vehicle/PxVehicleSDK.h"
|
||||
#include "PxFiltering.h"
|
||||
#include "PsFoundation.h"
|
||||
#include "PsUtilities.h"
|
||||
|
||||
#define CHECK_MSG(exp, msg) (!!(exp) || (physx::shdfnd::getFoundation().error(physx::PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, msg), 0) )
|
||||
#define SIZEALIGN16(size) (((unsigned)(size)+15)&((unsigned)(~15)));
|
||||
|
||||
void SampleVehicleSetupDrivableShapeQueryFilterData(PxFilterData* qryFilterData)
|
||||
{
|
||||
CHECK_MSG(0==qryFilterData->word3, "word3 is reserved for filter data for vehicle raycast queries");
|
||||
qryFilterData->word3 = (PxU32)SAMPLEVEHICLE_DRIVABLE_SURFACE;
|
||||
}
|
||||
|
||||
void SampleVehicleSetupNonDrivableShapeQueryFilterData(PxFilterData* qryFilterData)
|
||||
{
|
||||
CHECK_MSG(0==qryFilterData->word3, "word3 is reserved for filter data for vehicle raycast queries");
|
||||
qryFilterData->word3 = (PxU32)SAMPLEVEHICLE_UNDRIVABLE_SURFACE;
|
||||
}
|
||||
|
||||
void SampleVehicleSetupVehicleShapeQueryFilterData(PxFilterData* qryFilterData)
|
||||
{
|
||||
CHECK_MSG(0==qryFilterData->word3, "word3 is reserved for filter data for vehicle raycast queries");
|
||||
qryFilterData->word3 = (PxU32)SAMPLEVEHICLE_UNDRIVABLE_SURFACE;
|
||||
}
|
||||
|
||||
SampleVehicleSceneQueryData* SampleVehicleSceneQueryData::allocate(const PxU32 maxNumWheels)
|
||||
{
|
||||
const PxU32 size0 = SIZEALIGN16(sizeof(SampleVehicleSceneQueryData));
|
||||
const PxU32 size1 = SIZEALIGN16(sizeof(PxRaycastQueryResult)*maxNumWheels);
|
||||
const PxU32 size2 = SIZEALIGN16(sizeof(PxRaycastHit)*maxNumWheels);
|
||||
const PxU32 size = size0 + size1 + size2;
|
||||
SampleVehicleSceneQueryData* sqData = (SampleVehicleSceneQueryData*)PX_ALLOC(size, "PxVehicleNWSceneQueryData");
|
||||
sqData->init();
|
||||
PxU8* ptr = (PxU8*) sqData;
|
||||
ptr += size0;
|
||||
sqData->mSqResults = (PxRaycastQueryResult*)ptr;
|
||||
sqData->mNbSqResults = maxNumWheels;
|
||||
ptr += size1;
|
||||
sqData->mSqHitBuffer = (PxRaycastHit*)ptr;
|
||||
ptr += size2;
|
||||
sqData->mNumQueries = maxNumWheels;
|
||||
return sqData;
|
||||
}
|
||||
|
||||
void SampleVehicleSceneQueryData::free()
|
||||
{
|
||||
PX_FREE(this);
|
||||
}
|
||||
|
||||
PxBatchQuery* SampleVehicleSceneQueryData::setUpBatchedSceneQuery(PxScene* scene)
|
||||
{
|
||||
PxBatchQueryDesc sqDesc(mNbSqResults, 0, 0);
|
||||
sqDesc.queryMemory.userRaycastResultBuffer = mSqResults;
|
||||
sqDesc.queryMemory.userRaycastTouchBuffer = mSqHitBuffer;
|
||||
sqDesc.queryMemory.raycastTouchBufferSize = mNumQueries;
|
||||
sqDesc.preFilterShader = mPreFilterShader;
|
||||
return scene->createBatchQuery(sqDesc);
|
||||
}
|
||||
|
||||
132
physx/samples/samplevehicle/SampleVehicle_SceneQuery.h
Normal file
132
physx/samples/samplevehicle/SampleVehicle_SceneQuery.h
Normal file
@ -0,0 +1,132 @@
|
||||
//
|
||||
// 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 SAMPLEVEHICLE_UTILSCENEQUERY_H
|
||||
#define SAMPLEVEHICLE_UTILSCENEQUERY_H
|
||||
|
||||
#include "common/PxPhysXCommonConfig.h"
|
||||
#include "vehicle/PxVehicleSDK.h"
|
||||
#include "foundation/PxPreprocessor.h"
|
||||
#include "PxScene.h"
|
||||
#include "PxBatchQueryDesc.h"
|
||||
|
||||
using namespace physx;
|
||||
|
||||
//Make sure that suspension raycasts only consider shapes flagged as drivable that don't belong to the owner vehicle.
|
||||
enum
|
||||
{
|
||||
SAMPLEVEHICLE_DRIVABLE_SURFACE = 0xffff0000,
|
||||
SAMPLEVEHICLE_UNDRIVABLE_SURFACE = 0x0000ffff
|
||||
};
|
||||
|
||||
static PxQueryHitType::Enum SampleVehicleWheelRaycastPreFilter(
|
||||
PxFilterData filterData0,
|
||||
PxFilterData filterData1,
|
||||
const void* constantBlock, PxU32 constantBlockSize,
|
||||
PxHitFlags& queryFlags)
|
||||
{
|
||||
//filterData0 is the vehicle suspension raycast.
|
||||
//filterData1 is the shape potentially hit by the raycast.
|
||||
PX_UNUSED(queryFlags);
|
||||
PX_UNUSED(constantBlockSize);
|
||||
PX_UNUSED(constantBlock);
|
||||
PX_UNUSED(filterData0);
|
||||
return ((0 == (filterData1.word3 & SAMPLEVEHICLE_DRIVABLE_SURFACE)) ? PxQueryHitType::eNONE : PxQueryHitType::eBLOCK);
|
||||
}
|
||||
|
||||
|
||||
//Set up query filter data so that vehicles can drive on shapes with this filter data.
|
||||
//Note that we have reserved word3 of the PxFilterData for vehicle raycast query filtering.
|
||||
void SampleVehicleSetupDrivableShapeQueryFilterData(PxFilterData* qryFilterData);
|
||||
|
||||
//Set up query filter data so that vehicles cannot drive on shapes with this filter data.
|
||||
//Note that we have reserved word3 of the PxFilterData for vehicle raycast query filtering.
|
||||
void SampleVehicleSetupNonDrivableShapeQueryFilterData(PxFilterData* qryFilterData);
|
||||
|
||||
//Set up query filter data for the shapes of a vehicle to ensure that vehicles cannot drive on themselves
|
||||
//but can drive on the shapes of other vehicles.
|
||||
//Note that we have reserved word3 of the PxFilterData for vehicle raycast query filtering.
|
||||
void SampleVehicleSetupVehicleShapeQueryFilterData(PxFilterData* qryFilterData);
|
||||
|
||||
//Data structure for quick setup of scene queries for suspension raycasts.
|
||||
class SampleVehicleSceneQueryData
|
||||
{
|
||||
public:
|
||||
|
||||
//Allocate scene query data for up to maxNumWheels suspension raycasts.
|
||||
static SampleVehicleSceneQueryData* allocate(const PxU32 maxNumWheels);
|
||||
|
||||
//Free allocated buffer for scene queries of suspension raycasts.
|
||||
void free();
|
||||
|
||||
//Create a PxBatchQuery instance that will be used as a single batched raycast of multiple suspension lines of multiple vehicles
|
||||
PxBatchQuery* setUpBatchedSceneQuery(PxScene* scene);
|
||||
|
||||
//Get the buffer of scene query results that will be used by PxVehicleNWSuspensionRaycasts
|
||||
PxRaycastQueryResult* getRaycastQueryResultBuffer() {return mSqResults;}
|
||||
|
||||
//Get the number of scene query results that have been allocated for use by PxVehicleNWSuspensionRaycasts
|
||||
PxU32 getRaycastQueryResultBufferSize() const {return mNumQueries;}
|
||||
|
||||
//Set the pre-filter shader
|
||||
void setPreFilterShader(PxBatchQueryPreFilterShader preFilterShader) {mPreFilterShader=preFilterShader;}
|
||||
|
||||
private:
|
||||
|
||||
//One result for each wheel.
|
||||
PxRaycastQueryResult* mSqResults;
|
||||
PxU32 mNbSqResults;
|
||||
|
||||
//One hit for each wheel.
|
||||
PxRaycastHit* mSqHitBuffer;
|
||||
|
||||
//Filter shader used to filter drivable and non-drivable surfaces
|
||||
PxBatchQueryPreFilterShader mPreFilterShader;
|
||||
|
||||
//Maximum number of suspension raycasts that can be supported by the allocated buffers
|
||||
//assuming a single query and hit per suspension line.
|
||||
PxU32 mNumQueries;
|
||||
|
||||
void init()
|
||||
{
|
||||
mPreFilterShader=SampleVehicleWheelRaycastPreFilter;
|
||||
}
|
||||
|
||||
SampleVehicleSceneQueryData()
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
~SampleVehicleSceneQueryData()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif //SAMPLEVEHICLE_UTILSCENEQUERY_H
|
||||
840
physx/samples/samplevehicle/SampleVehicle_VehicleController.cpp
Normal file
840
physx/samples/samplevehicle/SampleVehicle_VehicleController.cpp
Normal file
@ -0,0 +1,840 @@
|
||||
//
|
||||
// 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 "SampleVehicle_VehicleController.h"
|
||||
#include "PhysXSample.h"
|
||||
#include "vehicle/PxVehicleDrive4W.h"
|
||||
#include "vehicle/PxVehicleDriveNW.h"
|
||||
#include "vehicle/PxVehicleUtilControl.h"
|
||||
#include "vehicle/PxVehicleUtil.h"
|
||||
|
||||
using namespace SampleRenderer;
|
||||
using namespace SampleFramework;
|
||||
|
||||
PxVehicleKeySmoothingData gKeySmoothingData=
|
||||
{
|
||||
{
|
||||
3.0f, //rise rate eANALOG_INPUT_ACCEL
|
||||
3.0f, //rise rate eANALOG_INPUT_BRAKE
|
||||
10.0f, //rise rate eANALOG_INPUT_HANDBRAKE
|
||||
2.5f, //rise rate eANALOG_INPUT_STEER_LEFT
|
||||
2.5f, //rise rate eANALOG_INPUT_STEER_RIGHT
|
||||
},
|
||||
{
|
||||
5.0f, //fall rate eANALOG_INPUT__ACCEL
|
||||
5.0f, //fall rate eANALOG_INPUT__BRAKE
|
||||
10.0f, //fall rate eANALOG_INPUT__HANDBRAKE
|
||||
5.0f, //fall rate eANALOG_INPUT_STEER_LEFT
|
||||
5.0f //fall rate eANALOG_INPUT_STEER_RIGHT
|
||||
}
|
||||
};
|
||||
|
||||
PxVehiclePadSmoothingData gCarPadSmoothingData=
|
||||
{
|
||||
{
|
||||
6.0f, //rise rate eANALOG_INPUT_ACCEL
|
||||
6.0f, //rise rate eANALOG_INPUT_BRAKE
|
||||
12.0f, //rise rate eANALOG_INPUT_HANDBRAKE
|
||||
2.5f, //rise rate eANALOG_INPUT_STEER_LEFT
|
||||
2.5f, //rise rate eANALOG_INPUT_STEER_RIGHT
|
||||
},
|
||||
{
|
||||
10.0f, //fall rate eANALOG_INPUT_ACCEL
|
||||
10.0f, //fall rate eANALOG_INPUT_BRAKE
|
||||
12.0f, //fall rate eANALOG_INPUT_HANDBRAKE
|
||||
5.0f, //fall rate eANALOG_INPUT_STEER_LEFT
|
||||
5.0f //fall rate eANALOG_INPUT_STEER_RIGHT
|
||||
}
|
||||
};
|
||||
|
||||
PxF32 gSteerVsForwardSpeedData[2*8]=
|
||||
{
|
||||
0.0f, 0.75f,
|
||||
5.0f, 0.75f,
|
||||
30.0f, 0.125f,
|
||||
120.0f, 0.1f,
|
||||
PX_MAX_F32, PX_MAX_F32,
|
||||
PX_MAX_F32, PX_MAX_F32,
|
||||
PX_MAX_F32, PX_MAX_F32,
|
||||
PX_MAX_F32, PX_MAX_F32
|
||||
};
|
||||
PxFixedSizeLookupTable<8> gSteerVsForwardSpeedTable(gSteerVsForwardSpeedData,4);
|
||||
|
||||
//Tank smoothing data.
|
||||
PxVehiclePadSmoothingData gTankPadSmoothingData=
|
||||
{
|
||||
{
|
||||
6.0f, //rise rate eTANK_ANALOG_INPUT_ACCEL
|
||||
6.0f, //rise rate eTANK_ANALOG_INPUT_BRAKE_LEFT
|
||||
6.0f, //rise rate eTANK_ANALOG_INPUT_BRAKE_RIGHT
|
||||
2.5f, //rise rate eTANK_ANALOG_INPUT_THRUST_LEFT
|
||||
2.5f, //rise rate eTANK_ANALOG_INPUT_THRUST_RIGHT
|
||||
},
|
||||
{
|
||||
10.0f, //fall rate eTANK_ANALOG_INPUT_ACCEL
|
||||
10.0f, //fall rate eTANK_ANALOG_INPUT_BRAKE_LEFT
|
||||
10.0f, //fall rate eTANK_ANALOG_INPUT_BRAKE_RIGHT
|
||||
5.0f, //fall rate eTANK_ANALOG_INPUT_THRUST_LEFT
|
||||
5.0f //fall rate eTANK_ANALOG_INPUT_THRUST_RIGHT
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SampleVehicle_VehicleController::SampleVehicle_VehicleController()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
SampleVehicle_VehicleController::~SampleVehicle_VehicleController()
|
||||
{
|
||||
}
|
||||
|
||||
void SampleVehicle_VehicleController::clear()
|
||||
{
|
||||
mKeyPressedAccel = false;
|
||||
mKeyPressedGearUp = false;
|
||||
mKeyPressedGearDown = false;
|
||||
|
||||
mKeyPressedBrake = false;
|
||||
mKeyPressedHandbrake = false;
|
||||
mKeyPressedSteerLeft = false;
|
||||
mKeyPressedSteerRight = false;
|
||||
|
||||
mKeyPressedThrustLeft = false;
|
||||
mKeyPressedThrustRight = false;
|
||||
mKeyPressedBrakeLeft = false;
|
||||
mKeyPressedBrakeRight = false;
|
||||
|
||||
mGamepadAccel = 0.0f;
|
||||
mGamepadGearup = false;
|
||||
mGamepadGeardown = false;
|
||||
|
||||
mGamepadCarBrake = 0.0f;
|
||||
mGamepadCarSteer = 0.0f;
|
||||
mGamepadCarHandbrake = false;
|
||||
|
||||
mTankThrustLeft = 0.0f;
|
||||
mTankThrustRight = 0.0f;
|
||||
mTankBrakeLeft = 0.0f;
|
||||
mTankBrakeRight = 0.0f;
|
||||
|
||||
mRecord = false;
|
||||
mReplay = false;
|
||||
mNumSamples = 0;
|
||||
mNumRecordedSamples = 0;
|
||||
mUseKeyInputs = true;
|
||||
mToggleAutoGears = false;
|
||||
mIsMovingForwardSlowly = true;
|
||||
mInReverseMode = false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
bool SampleVehicle_VehicleController::processAutoReverse
|
||||
(const PxF32 timestep, const bool isInAir, const PxF32 forwardSpeed, const PxF32 sidewaysSpeed, const PxVehicleDriveTankRawInputData& rawInputData)
|
||||
{
|
||||
//Keyboard controls for tank not implemented yet.
|
||||
bool brakeLeft,brakeRight,accelLeft,accelRight;
|
||||
if(mUseKeyInputs)
|
||||
{
|
||||
//Keyboard controls for tank not implemented yet.
|
||||
brakeLeft=false;
|
||||
brakeRight=false;
|
||||
accelLeft=false;
|
||||
accelRight=false;
|
||||
}
|
||||
else if(PxVehicleDriveTank::eDRIVE_MODEL_STANDARD==rawInputData.getDriveModel())
|
||||
{
|
||||
brakeLeft = mInReverseMode ? rawInputData.getAnalogLeftThrust() > 0 : rawInputData.getAnalogLeftBrake() > 0.0f;
|
||||
brakeRight = mInReverseMode ? rawInputData.getAnalogRightThrust() > 0 : rawInputData.getAnalogRightBrake() > 0.0f;
|
||||
accelLeft = mInReverseMode ? rawInputData.getAnalogLeftBrake() > 0 : rawInputData.getAnalogLeftThrust() > 0.0f;
|
||||
accelRight = mInReverseMode ? rawInputData.getAnalogRightBrake() > 0 : rawInputData.getAnalogRightThrust() > 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Not much point in auto-reverse for tanks that can just spin both wheels backwards.
|
||||
return false;
|
||||
}
|
||||
|
||||
//If the car has been brought to rest by pressing the brake then raise a flag.
|
||||
bool justRaisedFlag=false;
|
||||
if(brakeLeft && brakeRight && !mAtRestUnderBraking)
|
||||
{
|
||||
if(!isInAir && forwardSpeed < THRESHOLD_FORWARD_SPEED && sidewaysSpeed < THRESHOLD_SIDEWAYS_SPEED)
|
||||
{
|
||||
justRaisedFlag=true;
|
||||
mAtRestUnderBraking = true;
|
||||
mTimeElapsedSinceAtRestUnderBraking = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
//If the flag is raised and the player pressed accelerate then lower the flag.
|
||||
if(mAtRestUnderBraking && (accelLeft || accelRight))
|
||||
{
|
||||
mAtRestUnderBraking = false;
|
||||
mTimeElapsedSinceAtRestUnderBraking = 0.0f;
|
||||
}
|
||||
|
||||
//If the flag is raised and the player doesn't press brake then increment the timer.
|
||||
if(!brakeLeft && !brakeRight && mAtRestUnderBraking && !justRaisedFlag)
|
||||
{
|
||||
mTimeElapsedSinceAtRestUnderBraking += timestep;
|
||||
}
|
||||
|
||||
//If the flag is raised and the player pressed brake again then switch auto-reverse.
|
||||
if(brakeLeft && brakeRight && mAtRestUnderBraking && !justRaisedFlag && mTimeElapsedSinceAtRestUnderBraking > 0.0f)
|
||||
{
|
||||
mAtRestUnderBraking = false;
|
||||
mTimeElapsedSinceAtRestUnderBraking = 0.0f;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
|
||||
void SampleVehicle_VehicleController::processRawInputs
|
||||
(const PxF32 dtime, const bool useAutoGears, PxVehicleDrive4WRawInputData& rawInputData)
|
||||
{
|
||||
// Keyboard
|
||||
{
|
||||
if(mRecord)
|
||||
{
|
||||
if(mNumSamples<MAX_NUM_RECORD_REPLAY_SAMPLES)
|
||||
{
|
||||
mKeyboardAccelValues[mNumSamples] = mKeyPressedAccel;
|
||||
mKeyboardBrakeValues[mNumSamples] = mKeyPressedBrake;
|
||||
mKeyboardHandbrakeValues[mNumSamples] = mKeyPressedHandbrake;
|
||||
mKeyboardSteerLeftValues[mNumSamples] = mKeyPressedSteerLeft;
|
||||
mKeyboardSteerRightValues[mNumSamples] = mKeyPressedSteerRight;
|
||||
mKeyboardGearupValues[mNumSamples] = mKeyPressedGearUp;
|
||||
mKeyboardGeardownValues[mNumSamples] = mKeyPressedGearDown;
|
||||
}
|
||||
}
|
||||
else if(mReplay)
|
||||
{
|
||||
if(mNumSamples<mNumRecordedSamples)
|
||||
{
|
||||
mKeyPressedAccel = mKeyboardAccelValues[mNumSamples];
|
||||
mKeyPressedBrake = mKeyboardBrakeValues[mNumSamples];
|
||||
mKeyPressedHandbrake = mKeyboardHandbrakeValues[mNumSamples];
|
||||
mKeyPressedSteerLeft = mKeyboardSteerLeftValues[mNumSamples];
|
||||
mKeyPressedSteerRight = mKeyboardSteerRightValues[mNumSamples];
|
||||
mKeyPressedGearUp = mKeyboardGearupValues[mNumSamples];
|
||||
mKeyPressedGearDown = mKeyboardGeardownValues[mNumSamples];
|
||||
}
|
||||
}
|
||||
|
||||
rawInputData.setDigitalAccel(mKeyPressedAccel);
|
||||
rawInputData.setDigitalBrake(mKeyPressedBrake);
|
||||
rawInputData.setDigitalHandbrake(mKeyPressedHandbrake);
|
||||
rawInputData.setDigitalSteerLeft(mKeyPressedSteerLeft);
|
||||
rawInputData.setDigitalSteerRight(mKeyPressedSteerRight);
|
||||
rawInputData.setGearUp(mKeyPressedGearUp);
|
||||
rawInputData.setGearDown(mKeyPressedGearDown);
|
||||
|
||||
mUseKeyInputs=
|
||||
(mKeyPressedAccel || mKeyPressedBrake || mKeyPressedHandbrake ||
|
||||
mKeyPressedSteerLeft || mKeyPressedSteerRight ||
|
||||
mKeyPressedGearUp || mKeyPressedGearDown);
|
||||
}
|
||||
|
||||
// Gamepad
|
||||
{
|
||||
if(mRecord)
|
||||
{
|
||||
if(mNumSamples<MAX_NUM_RECORD_REPLAY_SAMPLES)
|
||||
{
|
||||
mGamepadAccelValues[mNumSamples] = mGamepadAccel;
|
||||
mGamepadCarBrakeValues[mNumSamples] = mGamepadCarBrake;
|
||||
mGamepadCarSteerValues[mNumSamples] = mGamepadCarSteer;
|
||||
mGamepadGearupValues[mNumSamples] = mGamepadGearup;
|
||||
mGamepadGeardownValues[mNumSamples] = mGamepadGeardown;
|
||||
mGamepadCarHandbrakeValues[mNumSamples] = mGamepadCarHandbrake;
|
||||
}
|
||||
}
|
||||
else if(mReplay)
|
||||
{
|
||||
if(mNumSamples<mNumRecordedSamples)
|
||||
{
|
||||
mGamepadAccel = mGamepadAccelValues[mNumSamples];
|
||||
mGamepadCarBrake = mGamepadCarBrakeValues[mNumSamples];
|
||||
mGamepadCarSteer = mGamepadCarSteerValues[mNumSamples];
|
||||
mGamepadGearup = mGamepadGearupValues[mNumSamples];
|
||||
mGamepadGeardown = mGamepadGeardownValues[mNumSamples];
|
||||
mGamepadCarHandbrake = mGamepadCarHandbrakeValues[mNumSamples];
|
||||
}
|
||||
}
|
||||
|
||||
if(mGamepadAccel<0.0f || mGamepadAccel>1.01f)
|
||||
getSampleErrorCallback().reportError(PxErrorCode::eINTERNAL_ERROR, "Illegal accel value from gamepad", __FILE__, __LINE__);
|
||||
|
||||
if(mGamepadCarBrake<0.0f || mGamepadCarBrake>1.01f)
|
||||
getSampleErrorCallback().reportError(PxErrorCode::eINTERNAL_ERROR, "Illegal brake value from gamepad", __FILE__, __LINE__);
|
||||
|
||||
if(PxAbs(mGamepadCarSteer)>1.01f)
|
||||
getSampleErrorCallback().reportError(PxErrorCode::eINTERNAL_ERROR, "Illegal steer value from gamepad", __FILE__, __LINE__);
|
||||
|
||||
if(mUseKeyInputs && ((mGamepadAccel+mGamepadCarBrake+mGamepadCarSteer)!=0.0f || mGamepadGearup || mGamepadGeardown || mGamepadCarHandbrake))
|
||||
{
|
||||
mUseKeyInputs=false;
|
||||
}
|
||||
|
||||
if(!mUseKeyInputs)
|
||||
{
|
||||
rawInputData.setAnalogAccel(mGamepadAccel);
|
||||
rawInputData.setAnalogBrake(mGamepadCarBrake);
|
||||
rawInputData.setAnalogHandbrake(mGamepadCarHandbrake ? 1.0f : 0.0f);
|
||||
rawInputData.setAnalogSteer(mGamepadCarSteer);
|
||||
rawInputData.setGearUp(mGamepadGearup);
|
||||
rawInputData.setGearDown(mGamepadGeardown);
|
||||
}
|
||||
}
|
||||
|
||||
if(useAutoGears && (rawInputData.getGearDown() || rawInputData.getGearUp()))
|
||||
{
|
||||
rawInputData.setGearDown(false);
|
||||
rawInputData.setGearUp(false);
|
||||
}
|
||||
|
||||
mNumSamples++;
|
||||
}
|
||||
|
||||
void SampleVehicle_VehicleController::processRawInputs
|
||||
(const PxF32 dtime, const bool useAutoGears, PxVehicleDriveTankRawInputData& rawInputData)
|
||||
{
|
||||
// Keyboard
|
||||
//Keyboard controls for tank not implemented yet.
|
||||
{
|
||||
/*
|
||||
if(mRecord)
|
||||
{
|
||||
if(mNumSamples<MAX_NUM_RECORD_REPLAY_SAMPLES)
|
||||
{
|
||||
mKeyboardAccelValues[mNumSamples] = mAccelKeyPressed;
|
||||
mKeyboardBrakeValues[mNumSamples] = mBrakeKeyPressed;
|
||||
mKeyboardHandbrakeValues[mNumSamples] = mHandbrakeKeyPressed;
|
||||
mKeyboardSteerLeftValues[mNumSamples] = mSteerLeftKeyPressed;
|
||||
mKeyboardSteerRightValues[mNumSamples] = mSteerRightKeyPressed;
|
||||
mKeyboardGearupValues[mNumSamples] = mGearUpKeyPressed;
|
||||
mKeyboardGeardownValues[mNumSamples] = mGearDownKeyPressed;
|
||||
}
|
||||
}
|
||||
else if(mReplay)
|
||||
{
|
||||
if(mNumSamples<mNumRecordedSamples)
|
||||
{
|
||||
mAccelKeyPressed = mKeyboardAccelValues[mNumSamples];
|
||||
mBrakeKeyPressed = mKeyboardBrakeValues[mNumSamples];
|
||||
mHandbrakeKeyPressed = mKeyboardHandbrakeValues[mNumSamples];
|
||||
mSteerLeftKeyPressed = mKeyboardSteerLeftValues[mNumSamples];
|
||||
mSteerRightKeyPressed = mKeyboardSteerRightValues[mNumSamples];
|
||||
mGearUpKeyPressed = mKeyboardGearupValues[mNumSamples];
|
||||
mGearDownKeyPressed = mKeyboardGeardownValues[mNumSamples];
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
rawInputData.setDigitalAccel(mKeyPressedAccel);
|
||||
rawInputData.setDigitalLeftThrust(mKeyPressedThrustLeft);
|
||||
rawInputData.setDigitalRightThrust(mKeyPressedThrustRight);
|
||||
rawInputData.setDigitalLeftBrake(mKeyPressedBrakeLeft);
|
||||
rawInputData.setDigitalRightBrake(mKeyPressedBrakeRight);
|
||||
rawInputData.setGearUp(mKeyPressedGearUp);
|
||||
rawInputData.setGearDown(mKeyPressedGearDown);
|
||||
|
||||
mUseKeyInputs=
|
||||
(mKeyPressedAccel || mKeyPressedThrustLeft || mKeyPressedThrustRight ||
|
||||
mKeyPressedBrakeLeft || mKeyPressedBrakeRight ||
|
||||
mKeyPressedGearUp || mKeyPressedGearDown);
|
||||
}
|
||||
|
||||
|
||||
// Gamepad
|
||||
{
|
||||
if(mRecord)
|
||||
{
|
||||
if(mNumSamples<MAX_NUM_RECORD_REPLAY_SAMPLES)
|
||||
{
|
||||
mGamepadAccelValues[mNumSamples] = mGamepadAccel;
|
||||
mGamepadTankThrustLeftValues[mNumSamples] = mTankThrustLeft;
|
||||
mGamepadTankThrustRightValues[mNumSamples] = mTankThrustRight;
|
||||
mGamepadGearupValues[mNumSamples] = mGamepadGearup;
|
||||
mGamepadGeardownValues[mNumSamples] = mGamepadGeardown;
|
||||
}
|
||||
}
|
||||
else if(mReplay)
|
||||
{
|
||||
if(mNumSamples<mNumRecordedSamples)
|
||||
{
|
||||
mGamepadAccel = mGamepadAccelValues[mNumSamples];
|
||||
mTankThrustLeft = mGamepadTankThrustLeftValues[mNumSamples];
|
||||
mTankThrustRight= mGamepadTankThrustRightValues[mNumSamples];
|
||||
mGamepadGearup = mGamepadGearupValues[mNumSamples];
|
||||
mGamepadGeardown = mGamepadGeardownValues[mNumSamples];
|
||||
}
|
||||
}
|
||||
|
||||
if(mGamepadAccel<0.0f || mGamepadAccel>1.01f)
|
||||
getSampleErrorCallback().reportError(PxErrorCode::eINTERNAL_ERROR, "Illegal accel value from gamepad", __FILE__, __LINE__);
|
||||
|
||||
if(mTankThrustLeft<-1.01f || mTankThrustLeft>1.01f)
|
||||
getSampleErrorCallback().reportError(PxErrorCode::eINTERNAL_ERROR, "Illegal brake value from gamepad", __FILE__, __LINE__);
|
||||
|
||||
if(mTankThrustRight<-1.01f || mTankThrustRight>1.01f)
|
||||
getSampleErrorCallback().reportError(PxErrorCode::eINTERNAL_ERROR, "Illegal steer value from gamepad", __FILE__, __LINE__);
|
||||
|
||||
if(mUseKeyInputs && ((mGamepadAccel+mTankThrustLeft+mTankThrustRight)!=0.0f || mGamepadGearup || mGamepadGeardown))
|
||||
{
|
||||
mUseKeyInputs=false;
|
||||
}
|
||||
|
||||
if(!mUseKeyInputs)
|
||||
{
|
||||
rawInputData.setAnalogAccel(mGamepadAccel);
|
||||
rawInputData.setAnalogLeftThrust(mTankThrustLeft);
|
||||
rawInputData.setAnalogRightThrust(mTankThrustRight);
|
||||
rawInputData.setAnalogLeftBrake(mTankBrakeLeft);
|
||||
rawInputData.setAnalogRightBrake(mTankBrakeRight);
|
||||
rawInputData.setGearUp(mGamepadGearup);
|
||||
rawInputData.setGearDown(mGamepadGeardown);
|
||||
}
|
||||
}
|
||||
|
||||
if(useAutoGears && (rawInputData.getGearDown() || rawInputData.getGearUp()))
|
||||
{
|
||||
rawInputData.setGearDown(false);
|
||||
rawInputData.setGearUp(false);
|
||||
}
|
||||
|
||||
mNumSamples++;
|
||||
}
|
||||
|
||||
#define THRESHOLD_FORWARD_SPEED (0.1f)
|
||||
#define THRESHOLD_SIDEWAYS_SPEED (0.2f)
|
||||
#define THRESHOLD_ROLLING_BACKWARDS_SPEED (0.1f)
|
||||
|
||||
void SampleVehicle_VehicleController::processAutoReverse
|
||||
(const PxVehicleWheels& focusVehicle, const PxVehicleDriveDynData& driveDynData, const PxVehicleWheelQueryResult& vehicleWheelQueryResults,
|
||||
const PxVehicleDrive4WRawInputData& carRawInputs,
|
||||
bool& toggleAutoReverse, bool& newIsMovingForwardSlowly) const
|
||||
{
|
||||
newIsMovingForwardSlowly = false;
|
||||
toggleAutoReverse = false;
|
||||
|
||||
if(driveDynData.getUseAutoGears())
|
||||
{
|
||||
//If the car is travelling very slowly in forward gear without player input and the player subsequently presses the brake then we want the car to go into reverse gear
|
||||
//If the car is travelling very slowly in reverse gear without player input and the player subsequently presses the accel then we want the car to go into forward gear
|
||||
//If the car is in forward gear and is travelling backwards then we want to automatically put the car into reverse gear.
|
||||
//If the car is in reverse gear and is travelling forwards then we want to automatically put the car into forward gear.
|
||||
//(If the player brings the car to rest with the brake the player needs to release the brake then reapply it
|
||||
//to indicate they want to toggle between forward and reverse.)
|
||||
|
||||
const bool prevIsMovingForwardSlowly=mIsMovingForwardSlowly;
|
||||
bool isMovingForwardSlowly=false;
|
||||
bool isMovingBackwards=false;
|
||||
const bool isInAir = PxVehicleIsInAir(vehicleWheelQueryResults);
|
||||
if(!isInAir)
|
||||
{
|
||||
bool accelRaw,brakeRaw,handbrakeRaw;
|
||||
if(mUseKeyInputs)
|
||||
{
|
||||
accelRaw=carRawInputs.getDigitalAccel();
|
||||
brakeRaw=carRawInputs.getDigitalBrake();
|
||||
handbrakeRaw=carRawInputs.getDigitalHandbrake();
|
||||
}
|
||||
else
|
||||
{
|
||||
accelRaw=carRawInputs.getAnalogAccel() > 0 ? true : false;
|
||||
brakeRaw=carRawInputs.getAnalogBrake() > 0 ? true : false;
|
||||
handbrakeRaw=carRawInputs.getAnalogHandbrake() > 0 ? true : false;
|
||||
}
|
||||
|
||||
const PxF32 forwardSpeed = focusVehicle.computeForwardSpeed();
|
||||
const PxF32 forwardSpeedAbs = PxAbs(forwardSpeed);
|
||||
const PxF32 sidewaysSpeedAbs = PxAbs(focusVehicle.computeSidewaysSpeed());
|
||||
const PxU32 currentGear = driveDynData.getCurrentGear();
|
||||
const PxU32 targetGear = driveDynData.getTargetGear();
|
||||
|
||||
//Check if the car is rolling against the gear (backwards in forward gear or forwards in reverse gear).
|
||||
if(PxVehicleGearsData::eFIRST == currentGear && forwardSpeed < -THRESHOLD_ROLLING_BACKWARDS_SPEED)
|
||||
{
|
||||
isMovingBackwards = true;
|
||||
}
|
||||
else if(PxVehicleGearsData::eREVERSE == currentGear && forwardSpeed > THRESHOLD_ROLLING_BACKWARDS_SPEED)
|
||||
{
|
||||
isMovingBackwards = true;
|
||||
}
|
||||
|
||||
//Check if the car is moving slowly.
|
||||
if(forwardSpeedAbs < THRESHOLD_FORWARD_SPEED && sidewaysSpeedAbs < THRESHOLD_SIDEWAYS_SPEED)
|
||||
{
|
||||
isMovingForwardSlowly=true;
|
||||
}
|
||||
|
||||
//Now work if we need to toggle from forwards gear to reverse gear or vice versa.
|
||||
if(isMovingBackwards)
|
||||
{
|
||||
if(!accelRaw && !brakeRaw && !handbrakeRaw && (currentGear == targetGear))
|
||||
{
|
||||
//The car is rolling against the gear and the player is doing nothing to stop this.
|
||||
toggleAutoReverse = true;
|
||||
}
|
||||
}
|
||||
else if(prevIsMovingForwardSlowly && isMovingForwardSlowly)
|
||||
{
|
||||
if((currentGear > PxVehicleGearsData::eNEUTRAL) && brakeRaw && !accelRaw && (currentGear == targetGear))
|
||||
{
|
||||
//The car was moving slowly in forward gear without player input and is now moving slowly with player input that indicates the
|
||||
//player wants to switch to reverse gear.
|
||||
toggleAutoReverse = true;
|
||||
}
|
||||
else if(currentGear == PxVehicleGearsData::eREVERSE && accelRaw && !brakeRaw && (currentGear == targetGear))
|
||||
{
|
||||
//The car was moving slowly in reverse gear without player input and is now moving slowly with player input that indicates the
|
||||
//player wants to switch to forward gear.
|
||||
toggleAutoReverse = true;
|
||||
}
|
||||
}
|
||||
|
||||
//If the car was brought to rest through braking then the player needs to release the brake then reapply
|
||||
//to indicate that the gears should toggle between reverse and forward.
|
||||
if(isMovingForwardSlowly && !brakeRaw && !accelRaw && !handbrakeRaw)
|
||||
{
|
||||
newIsMovingForwardSlowly = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SampleVehicle_VehicleController::processAutoReverse
|
||||
(const PxVehicleWheels& focusVehicle, const PxVehicleDriveDynData& driveDynData, const PxVehicleWheelQueryResult& vehicleWheelQueryResults,
|
||||
const PxVehicleDriveTankRawInputData& tankRawInputs,
|
||||
bool& toggleAutoReverse, bool& newIsMovingForwardSlowly) const
|
||||
{
|
||||
newIsMovingForwardSlowly = false;
|
||||
toggleAutoReverse = false;
|
||||
|
||||
if(driveDynData.getUseAutoGears())
|
||||
{
|
||||
//If the car is travelling very slowly in forward gear without player input and the player subsequently presses the brake then we want the car to go into reverse gear
|
||||
//If the car is travelling very slowly in reverse gear without player input and the player subsequently presses the accel then we want the car to go into forward gear
|
||||
//If the car is in forward gear and is travelling backwards then we want to automatically put the car into reverse gear.
|
||||
//If the car is in reverse gear and is travelling forwards then we want to automatically put the car into forward gear.
|
||||
//(If the player brings the car to rest with the brake the player needs to release the brake then reapply it
|
||||
//to indicate they want to toggle between forward and reverse.)
|
||||
|
||||
const bool prevIsMovingForwardSlowly=mIsMovingForwardSlowly;
|
||||
bool isMovingForwardSlowly=false;
|
||||
bool isMovingBackwards=false;
|
||||
const bool isInAir = PxVehicleIsInAir(vehicleWheelQueryResults);
|
||||
if(!isInAir)
|
||||
{
|
||||
bool accelLeft,accelRight,brakeLeft,brakeRight;
|
||||
if(mUseKeyInputs)
|
||||
{
|
||||
accelLeft=tankRawInputs.getDigitalLeftThrust();
|
||||
accelRight=tankRawInputs.getDigitalRightThrust();
|
||||
brakeLeft=tankRawInputs.getDigitalLeftBrake();
|
||||
brakeRight=tankRawInputs.getDigitalRightBrake();
|
||||
}
|
||||
else
|
||||
{
|
||||
accelLeft = tankRawInputs.getAnalogLeftThrust() > 0 ? true : false;
|
||||
accelRight = tankRawInputs.getAnalogRightThrust() > 0 ? true : false;
|
||||
brakeLeft = tankRawInputs.getAnalogLeftBrake() > 0 ? true : false;
|
||||
brakeRight = tankRawInputs.getAnalogRightBrake() > 0 ? true : false;
|
||||
|
||||
/*
|
||||
if(accelLeft && accelLeft==accelRight && !brakeLeft && !brakeRight)
|
||||
{
|
||||
shdfnd::printFormatted("aligned accel\n");
|
||||
}
|
||||
|
||||
if(brakeLeft && brakeLeft==brakeRight && !accelLeft && !accelRight)
|
||||
{
|
||||
shdfnd::printFormatted("aligned brake\n");
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
const PxF32 forwardSpeed = focusVehicle.computeForwardSpeed();
|
||||
const PxF32 forwardSpeedAbs = PxAbs(forwardSpeed);
|
||||
const PxF32 sidewaysSpeedAbs = PxAbs(focusVehicle.computeSidewaysSpeed());
|
||||
const PxU32 currentGear = driveDynData.getCurrentGear();
|
||||
const PxU32 targetGear = driveDynData.getTargetGear();
|
||||
|
||||
//Check if the car is rolling against the gear (backwards in forward gear or forwards in reverse gear).
|
||||
if(PxVehicleGearsData::eFIRST == currentGear && forwardSpeed < -THRESHOLD_ROLLING_BACKWARDS_SPEED)
|
||||
{
|
||||
isMovingBackwards = true;
|
||||
}
|
||||
else if(PxVehicleGearsData::eREVERSE == currentGear && forwardSpeed > THRESHOLD_ROLLING_BACKWARDS_SPEED)
|
||||
{
|
||||
isMovingBackwards = true;
|
||||
}
|
||||
|
||||
//Check if the car is moving slowly.
|
||||
if(forwardSpeedAbs < THRESHOLD_FORWARD_SPEED && sidewaysSpeedAbs < THRESHOLD_SIDEWAYS_SPEED)
|
||||
{
|
||||
isMovingForwardSlowly=true;
|
||||
}
|
||||
|
||||
//Now work if we need to toggle from forwards gear to reverse gear or vice versa.
|
||||
if(isMovingBackwards)
|
||||
{
|
||||
if(!accelLeft && !accelRight && !brakeLeft && !brakeRight && (currentGear == targetGear))
|
||||
{
|
||||
//The car is rolling against the gear and the player is doing nothing to stop this.
|
||||
toggleAutoReverse = true;
|
||||
}
|
||||
}
|
||||
else if(prevIsMovingForwardSlowly && isMovingForwardSlowly)
|
||||
{
|
||||
if((currentGear > PxVehicleGearsData::eNEUTRAL) && brakeLeft && brakeRight && !accelLeft && !accelRight && (currentGear == targetGear))
|
||||
{
|
||||
//The car was moving slowly in forward gear without player input and is now moving slowly with player input that indicates the
|
||||
//player wants to switch to reverse gear.
|
||||
toggleAutoReverse = true;
|
||||
}
|
||||
else if(currentGear == PxVehicleGearsData::eREVERSE && accelLeft && accelRight && !brakeLeft && !brakeRight && (currentGear == targetGear))
|
||||
{
|
||||
//The car was moving slowly in reverse gear without player input and is now moving slowly with player input that indicates the
|
||||
//player wants to switch to forward gear.
|
||||
toggleAutoReverse = true;
|
||||
}
|
||||
}
|
||||
|
||||
//If the car was brought to rest through braking then the player needs to release the brake then reapply
|
||||
//to indicate that the gears should toggle between reverse and forward.
|
||||
if(isMovingForwardSlowly && (!brakeLeft || !brakeRight) && (!accelLeft || !accelRight))
|
||||
{
|
||||
newIsMovingForwardSlowly = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SampleVehicle_VehicleController::update(const PxF32 timestep, const PxVehicleWheelQueryResult& vehicleWheelQueryResults, PxVehicleWheels& focusVehicle)
|
||||
{
|
||||
PxVehicleDriveDynData* driveDynData=NULL;
|
||||
bool isTank=false;
|
||||
PxVehicleDriveTankControlModel::Enum tankDriveModel=PxVehicleDriveTankControlModel::eSTANDARD;
|
||||
switch(focusVehicle.getVehicleType())
|
||||
{
|
||||
case PxVehicleTypes::eDRIVE4W:
|
||||
{
|
||||
PxVehicleDrive4W& vehDrive4W=(PxVehicleDrive4W&)focusVehicle;
|
||||
driveDynData=&vehDrive4W.mDriveDynData;
|
||||
isTank=false;
|
||||
}
|
||||
break;
|
||||
case PxVehicleTypes::eDRIVENW:
|
||||
{
|
||||
PxVehicleDriveNW& vehDriveNW=(PxVehicleDriveNW&)focusVehicle;
|
||||
driveDynData=&vehDriveNW.mDriveDynData;
|
||||
isTank=false;
|
||||
}
|
||||
break;
|
||||
case PxVehicleTypes::eDRIVETANK:
|
||||
{
|
||||
PxVehicleDriveTank& vehDriveTank=(PxVehicleDriveTank&)focusVehicle;
|
||||
driveDynData=&vehDriveTank.mDriveDynData;
|
||||
isTank=true;
|
||||
tankDriveModel=vehDriveTank.getDriveModel();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
PX_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
|
||||
//Toggle autogear flag
|
||||
if(mToggleAutoGears)
|
||||
{
|
||||
driveDynData->toggleAutoGears();
|
||||
mToggleAutoGears = false;
|
||||
}
|
||||
|
||||
//Store raw inputs in replay stream if in recording mode.
|
||||
//Set raw inputs from replay stream if in replay mode.
|
||||
//Store raw inputs from active stream in handy arrays so we don't need to worry
|
||||
//about which stream (live input or replay) is active.
|
||||
//Work out if we are using keys or gamepad controls depending on which is being used
|
||||
//(gamepad selected if both are being used).
|
||||
PxVehicleDrive4WRawInputData carRawInputs;
|
||||
PxVehicleDriveTankRawInputData tankRawInputs(tankDriveModel);
|
||||
if(!isTank)
|
||||
{
|
||||
processRawInputs(timestep,driveDynData->getUseAutoGears(),carRawInputs);
|
||||
}
|
||||
else
|
||||
{
|
||||
processRawInputs(timestep,driveDynData->getUseAutoGears(),tankRawInputs);
|
||||
}
|
||||
|
||||
//Work out if the car is to flip from reverse to forward gear or from forward gear to reverse.
|
||||
bool toggleAutoReverse = false;
|
||||
bool newIsMovingForwardSlowly = false;
|
||||
if(!isTank)
|
||||
{
|
||||
processAutoReverse(focusVehicle, *driveDynData, vehicleWheelQueryResults, carRawInputs, toggleAutoReverse, newIsMovingForwardSlowly);
|
||||
}
|
||||
else
|
||||
{
|
||||
processAutoReverse(focusVehicle, *driveDynData, vehicleWheelQueryResults, tankRawInputs, toggleAutoReverse, newIsMovingForwardSlowly);
|
||||
}
|
||||
mIsMovingForwardSlowly = newIsMovingForwardSlowly;
|
||||
|
||||
|
||||
//If the car is to flip gear direction then switch gear as appropriate.
|
||||
if(toggleAutoReverse)
|
||||
{
|
||||
mInReverseMode = !mInReverseMode;
|
||||
|
||||
if(mInReverseMode)
|
||||
{
|
||||
driveDynData->forceGearChange(PxVehicleGearsData::eREVERSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
driveDynData->forceGearChange(PxVehicleGearsData::eFIRST);
|
||||
}
|
||||
}
|
||||
|
||||
//If in reverse mode then swap the accel and brake.
|
||||
if(mInReverseMode)
|
||||
{
|
||||
if(mUseKeyInputs)
|
||||
{
|
||||
if(!isTank)
|
||||
{
|
||||
const bool accel=carRawInputs.getDigitalAccel();
|
||||
const bool brake=carRawInputs.getDigitalBrake();
|
||||
carRawInputs.setDigitalAccel(brake);
|
||||
carRawInputs.setDigitalBrake(accel);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Keyboard controls for tank not implemented yet.
|
||||
const bool accelLeft=tankRawInputs.getDigitalLeftThrust();
|
||||
const bool accelRight=tankRawInputs.getDigitalRightThrust();
|
||||
const bool brakeLeft=tankRawInputs.getDigitalLeftBrake();
|
||||
const bool brakeRight=tankRawInputs.getDigitalRightBrake();
|
||||
tankRawInputs.setDigitalLeftThrust(brakeLeft);
|
||||
tankRawInputs.setDigitalRightThrust(brakeRight);
|
||||
tankRawInputs.setDigitalLeftBrake(accelLeft);
|
||||
tankRawInputs.setDigitalRightBrake(accelRight);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!isTank)
|
||||
{
|
||||
const PxF32 accel=carRawInputs.getAnalogAccel();
|
||||
const PxF32 brake=carRawInputs.getAnalogBrake();
|
||||
carRawInputs.setAnalogAccel(brake);
|
||||
carRawInputs.setAnalogBrake(accel);
|
||||
}
|
||||
else if(PxVehicleDriveTankControlModel::eSPECIAL==tankDriveModel)
|
||||
{
|
||||
const PxF32 thrustLeft=tankRawInputs.getAnalogLeftThrust();
|
||||
const PxF32 thrustRight=tankRawInputs.getAnalogRightThrust();
|
||||
tankRawInputs.setAnalogLeftThrust(-thrustLeft);
|
||||
tankRawInputs.setAnalogRightThrust(-thrustRight);
|
||||
}
|
||||
else
|
||||
{
|
||||
const PxF32 thrustLeft=tankRawInputs.getAnalogLeftThrust();
|
||||
const PxF32 thrustRight=tankRawInputs.getAnalogRightThrust();
|
||||
const PxF32 brakeLeft=tankRawInputs.getAnalogLeftBrake();
|
||||
const PxF32 brakeRight=tankRawInputs.getAnalogRightBrake();
|
||||
tankRawInputs.setAnalogLeftThrust(brakeLeft);
|
||||
tankRawInputs.setAnalogLeftBrake(thrustLeft);
|
||||
tankRawInputs.setAnalogRightThrust(brakeRight);
|
||||
tankRawInputs.setAnalogRightBrake(thrustRight);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now filter the raw input values and apply them to focus vehicle
|
||||
// as floats for brake,accel,handbrake,steer and bools for gearup,geardown.
|
||||
if(mUseKeyInputs)
|
||||
{
|
||||
if(!isTank)
|
||||
{
|
||||
const bool isInAir = PxVehicleIsInAir(vehicleWheelQueryResults);
|
||||
PxVehicleDrive4WSmoothDigitalRawInputsAndSetAnalogInputs
|
||||
(gKeySmoothingData,gSteerVsForwardSpeedTable,carRawInputs,timestep,isInAir,(PxVehicleDrive4W&)focusVehicle);
|
||||
}
|
||||
else
|
||||
{
|
||||
PxVehicleDriveTankSmoothDigitalRawInputsAndSetAnalogInputs
|
||||
(gKeySmoothingData,tankRawInputs,timestep,(PxVehicleDriveTank&)focusVehicle);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!isTank)
|
||||
{
|
||||
const bool isInAir = PxVehicleIsInAir(vehicleWheelQueryResults);
|
||||
PxVehicleDrive4WSmoothAnalogRawInputsAndSetAnalogInputs
|
||||
(gCarPadSmoothingData,gSteerVsForwardSpeedTable,carRawInputs,timestep,isInAir,(PxVehicleDrive4W&)focusVehicle);
|
||||
}
|
||||
else
|
||||
{
|
||||
PxVehicleDriveTankSmoothAnalogRawInputsAndSetAnalogInputs
|
||||
(gTankPadSmoothingData,tankRawInputs,timestep,(PxVehicleDriveTank&)focusVehicle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SampleVehicle_VehicleController::restart()
|
||||
{
|
||||
const bool record=mRecord;
|
||||
const bool replay=mReplay;
|
||||
const PxU32 numSamples=mNumSamples;
|
||||
const PxU32 numRecordedSamples=mNumRecordedSamples;
|
||||
clear();
|
||||
mRecord=record;
|
||||
mReplay=replay;
|
||||
mNumRecordedSamples=numRecordedSamples;
|
||||
|
||||
if(record)
|
||||
{
|
||||
PX_ASSERT(!replay);
|
||||
mNumRecordedSamples = numSamples;
|
||||
mRecord = false;
|
||||
mReplay = true;
|
||||
}
|
||||
}
|
||||
226
physx/samples/samplevehicle/SampleVehicle_VehicleController.h
Normal file
226
physx/samples/samplevehicle/SampleVehicle_VehicleController.h
Normal file
@ -0,0 +1,226 @@
|
||||
//
|
||||
// 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 SAMPLE_VEHICLE_VEHICLE_CONTROLLER_H
|
||||
#define SAMPLE_VEHICLE_VEHICLE_CONTROLLER_H
|
||||
|
||||
#include "common/PxPhysXCommonConfig.h"
|
||||
#include "foundation/PxVec3.h"
|
||||
#include "vehicle/PxVehicleSDK.h"
|
||||
#include "vehicle/PxVehicleUpdate.h"
|
||||
#include "vehicle/PxVehicleUtilControl.h"
|
||||
|
||||
using namespace physx;
|
||||
|
||||
class SampleVehicle_VehicleController
|
||||
{
|
||||
public:
|
||||
|
||||
SampleVehicle_VehicleController();
|
||||
~SampleVehicle_VehicleController();
|
||||
|
||||
void setCarKeyboardInputs
|
||||
(const bool accel, const bool brake, const bool handbrake,
|
||||
const bool steerleft, const bool steerright,
|
||||
const bool gearup, const bool geardown)
|
||||
{
|
||||
mKeyPressedAccel=accel;
|
||||
mKeyPressedBrake=brake;
|
||||
mKeyPressedHandbrake=handbrake;
|
||||
mKeyPressedSteerLeft=steerleft;
|
||||
mKeyPressedSteerRight=steerright;
|
||||
mKeyPressedGearUp=gearup;
|
||||
mKeyPressedGearDown=geardown;
|
||||
}
|
||||
|
||||
void setCarGamepadInputs
|
||||
(const PxF32 accel, const PxF32 brake,
|
||||
const PxF32 steer,
|
||||
const bool gearup, const bool geardown,
|
||||
const bool handbrake)
|
||||
{
|
||||
mGamepadAccel=accel;
|
||||
mGamepadCarBrake=brake;
|
||||
mGamepadCarSteer=steer;
|
||||
mGamepadGearup=gearup;
|
||||
mGamepadGeardown=geardown;
|
||||
mGamepadCarHandbrake=handbrake;
|
||||
}
|
||||
|
||||
void setTankKeyboardInputs
|
||||
(const bool accel, const bool thrustLeft, const bool thrustRight, const bool brakeLeft, const bool brakeRight, const bool gearUp, const bool gearDown)
|
||||
{
|
||||
mKeyPressedAccel=accel;
|
||||
mKeyPressedThrustLeft=thrustLeft;
|
||||
mKeyPressedThrustRight=thrustRight;
|
||||
mKeyPressedBrakeLeft=brakeLeft;
|
||||
mKeyPressedBrakeRight=brakeRight;
|
||||
mKeyPressedGearUp=gearUp;
|
||||
mKeyPressedGearDown=gearDown;
|
||||
}
|
||||
|
||||
void setTankGamepadInputs
|
||||
(const PxF32 accel, const PxF32 thrustLeft, const PxF32 thrustRight, const PxF32 brakeLeft, const PxF32 brakeRight, const bool gearUp, const bool gearDown)
|
||||
{
|
||||
mGamepadAccel=accel;
|
||||
mTankThrustLeft=thrustLeft;
|
||||
mTankThrustRight=thrustRight;
|
||||
mTankBrakeLeft=brakeLeft;
|
||||
mTankBrakeRight=brakeRight;
|
||||
mGamepadGearup=gearUp;
|
||||
mGamepadGeardown=gearDown;
|
||||
}
|
||||
|
||||
void toggleAutoGearFlag()
|
||||
{
|
||||
mToggleAutoGears = true;
|
||||
}
|
||||
|
||||
void update(const PxF32 dtime, const PxVehicleWheelQueryResult& vehicleWheelQueryResults, PxVehicleWheels& focusVehicle);
|
||||
|
||||
void clear();
|
||||
|
||||
private:
|
||||
|
||||
//Raw driving inputs - keys (car + tank)
|
||||
bool mKeyPressedAccel;
|
||||
bool mKeyPressedGearUp;
|
||||
bool mKeyPressedGearDown;
|
||||
|
||||
//Raw driving inputs - keys (car only)
|
||||
bool mKeyPressedBrake;
|
||||
bool mKeyPressedHandbrake;
|
||||
bool mKeyPressedSteerLeft;
|
||||
bool mKeyPressedSteerRight;
|
||||
|
||||
//Raw driving inputs - keys (tank only)
|
||||
bool mKeyPressedThrustLeft;
|
||||
bool mKeyPressedThrustRight;
|
||||
bool mKeyPressedBrakeLeft;
|
||||
bool mKeyPressedBrakeRight;
|
||||
|
||||
//Raw driving inputs - gamepad (car + tank)
|
||||
PxF32 mGamepadAccel;
|
||||
bool mGamepadGearup;
|
||||
bool mGamepadGeardown;
|
||||
|
||||
//Raw driving inputs - gamepad (car only)
|
||||
PxF32 mGamepadCarBrake;
|
||||
PxF32 mGamepadCarSteer;
|
||||
bool mGamepadCarHandbrake;
|
||||
|
||||
//Raw driving inputs - (tank only)
|
||||
PxF32 mTankThrustLeft;
|
||||
PxF32 mTankThrustRight;
|
||||
PxF32 mTankBrakeLeft;
|
||||
PxF32 mTankBrakeRight;
|
||||
|
||||
//Record and replay using raw driving inputs.
|
||||
bool mRecord;
|
||||
bool mReplay;
|
||||
enum
|
||||
{
|
||||
MAX_NUM_RECORD_REPLAY_SAMPLES=8192
|
||||
};
|
||||
// Keyboard
|
||||
bool mKeyboardAccelValues[MAX_NUM_RECORD_REPLAY_SAMPLES];
|
||||
bool mKeyboardBrakeValues[MAX_NUM_RECORD_REPLAY_SAMPLES];
|
||||
bool mKeyboardHandbrakeValues[MAX_NUM_RECORD_REPLAY_SAMPLES];
|
||||
bool mKeyboardSteerLeftValues[MAX_NUM_RECORD_REPLAY_SAMPLES];
|
||||
bool mKeyboardSteerRightValues[MAX_NUM_RECORD_REPLAY_SAMPLES];
|
||||
bool mKeyboardGearupValues[MAX_NUM_RECORD_REPLAY_SAMPLES];
|
||||
bool mKeyboardGeardownValues[MAX_NUM_RECORD_REPLAY_SAMPLES];
|
||||
// Gamepad - (tank + car)
|
||||
PxF32 mGamepadAccelValues[MAX_NUM_RECORD_REPLAY_SAMPLES];
|
||||
bool mGamepadGearupValues[MAX_NUM_RECORD_REPLAY_SAMPLES];
|
||||
bool mGamepadGeardownValues[MAX_NUM_RECORD_REPLAY_SAMPLES];
|
||||
// Gamepad - car only
|
||||
PxF32 mGamepadCarBrakeValues[MAX_NUM_RECORD_REPLAY_SAMPLES];
|
||||
PxF32 mGamepadCarSteerValues[MAX_NUM_RECORD_REPLAY_SAMPLES];
|
||||
bool mGamepadCarHandbrakeValues[MAX_NUM_RECORD_REPLAY_SAMPLES];
|
||||
//Gamepad - tank only.
|
||||
PxF32 mGamepadTankThrustLeftValues[MAX_NUM_RECORD_REPLAY_SAMPLES];
|
||||
PxF32 mGamepadTankThrustRightValues[MAX_NUM_RECORD_REPLAY_SAMPLES];
|
||||
|
||||
PxU32 mNumSamples;
|
||||
PxU32 mNumRecordedSamples;
|
||||
|
||||
// Raw data taken from the correct stream (live input stream or replay stream)
|
||||
bool mUseKeyInputs;
|
||||
|
||||
// Toggle autogears flag on focus vehicle
|
||||
bool mToggleAutoGears;
|
||||
|
||||
//Auto-reverse mode.
|
||||
bool mIsMovingForwardSlowly;
|
||||
bool mInReverseMode;
|
||||
|
||||
//Update
|
||||
void processRawInputs(const PxF32 timestep, const bool useAutoGears, PxVehicleDrive4WRawInputData& rawInputData);
|
||||
void processRawInputs(const PxF32 timestep, const bool useAutoGears, PxVehicleDriveTankRawInputData& rawInputData);
|
||||
void processAutoReverse(
|
||||
const PxVehicleWheels& focusVehicle, const PxVehicleDriveDynData& driveDynData, const PxVehicleWheelQueryResult& vehicleWheelQueryResults,
|
||||
const PxVehicleDrive4WRawInputData& rawInputData,
|
||||
bool& toggleAutoReverse, bool& newIsMovingForwardSlowly) const;
|
||||
void processAutoReverse(
|
||||
const PxVehicleWheels& focusVehicle, const PxVehicleDriveDynData& driveDynData, const PxVehicleWheelQueryResult& vehicleWheelQueryResults,
|
||||
const PxVehicleDriveTankRawInputData& rawInputData,
|
||||
bool& toggleAutoReverse, bool& newIsMovingForwardSlowly) const;
|
||||
|
||||
////////////////////////////////
|
||||
//Record and replay deprecated at the moment.
|
||||
//Setting functions as private to avoid them being used.
|
||||
///////////////////////////////
|
||||
bool getIsInRecordReplayMode() const {return (mRecord || mReplay);}
|
||||
bool getIsRecording() const {return mRecord;}
|
||||
bool getIsReplaying() const {return mReplay;}
|
||||
|
||||
void enableRecordReplayMode()
|
||||
{
|
||||
PX_ASSERT(!getIsInRecordReplayMode());
|
||||
mRecord=true;
|
||||
mReplay=false;
|
||||
mNumRecordedSamples=0;
|
||||
}
|
||||
|
||||
void disableRecordReplayMode()
|
||||
{
|
||||
PX_ASSERT(getIsInRecordReplayMode());
|
||||
mRecord=false;
|
||||
mReplay=false;
|
||||
mNumRecordedSamples=0;
|
||||
}
|
||||
|
||||
void restart();
|
||||
////////////////////////////
|
||||
|
||||
};
|
||||
|
||||
#endif //SAMPLE_VEHICLE_VEHICLE_CONTROLLER_H
|
||||
171
physx/samples/samplevehicle/SampleVehicle_VehicleCooking.cpp
Normal file
171
physx/samples/samplevehicle/SampleVehicle_VehicleCooking.cpp
Normal file
@ -0,0 +1,171 @@
|
||||
//
|
||||
// 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 "SampleVehicle_VehicleCooking.h"
|
||||
#include "PxTkStream.h"
|
||||
#include "extensions/PxDefaultStreams.h"
|
||||
|
||||
|
||||
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* createCuboidConvexMesh(const PxVec3& halfExtents, PxPhysics& physics, PxCooking& cooking)
|
||||
{
|
||||
PxVec3 verts[8]=
|
||||
{
|
||||
PxVec3(-halfExtents.x, -halfExtents.y, -halfExtents.z),
|
||||
PxVec3(-halfExtents.x, -halfExtents.y, +halfExtents.z),
|
||||
PxVec3(-halfExtents.x, +halfExtents.y, -halfExtents.z),
|
||||
PxVec3(-halfExtents.x, +halfExtents.y, +halfExtents.z),
|
||||
PxVec3(+halfExtents.x, -halfExtents.y, -halfExtents.z),
|
||||
PxVec3(+halfExtents.x, -halfExtents.y, +halfExtents.z),
|
||||
PxVec3(+halfExtents.x, +halfExtents.y, -halfExtents.z),
|
||||
PxVec3(+halfExtents.x, +halfExtents.y, +halfExtents.z)
|
||||
};
|
||||
PxU32 numVerts=8;
|
||||
|
||||
return createConvexMesh(verts,numVerts,physics,cooking);
|
||||
}
|
||||
|
||||
PxConvexMesh* createWedgeConvexMesh(const PxVec3& halfExtents, PxPhysics& physics, PxCooking& cooking)
|
||||
{
|
||||
PxVec3 verts[6]=
|
||||
{
|
||||
PxVec3(-halfExtents.x, -halfExtents.y, -halfExtents.z),
|
||||
PxVec3(-halfExtents.x, -halfExtents.y, +halfExtents.z),
|
||||
PxVec3(-halfExtents.x, +halfExtents.y, -halfExtents.z),
|
||||
PxVec3(+halfExtents.x, -halfExtents.y, -halfExtents.z),
|
||||
PxVec3(+halfExtents.x, -halfExtents.y, +halfExtents.z),
|
||||
PxVec3(+halfExtents.x, +halfExtents.y, -halfExtents.z)
|
||||
};
|
||||
PxU32 numVerts=6;
|
||||
|
||||
return createConvexMesh(verts,numVerts,physics,cooking);
|
||||
}
|
||||
|
||||
PxConvexMesh* createCylinderConvexMesh(const PxF32 width, const PxF32 radius, const PxU32 numCirclePoints, PxPhysics& physics, PxCooking& cooking)
|
||||
{
|
||||
#define MAX_NUM_VERTS_IN_CIRCLE 16
|
||||
PX_ASSERT(numCirclePoints<MAX_NUM_VERTS_IN_CIRCLE);
|
||||
PxVec3 verts[2*MAX_NUM_VERTS_IN_CIRCLE];
|
||||
PxU32 numVerts=2*numCirclePoints;
|
||||
const PxF32 dtheta=2*PxPi/(1.0f*numCirclePoints);
|
||||
for(PxU32 i=0;i<MAX_NUM_VERTS_IN_CIRCLE;i++)
|
||||
{
|
||||
const PxF32 theta=dtheta*i;
|
||||
const PxF32 cosTheta=radius*PxCos(theta);
|
||||
const PxF32 sinTheta=radius*PxSin(theta);
|
||||
verts[2*i+0]=PxVec3(-0.5f*width, cosTheta, sinTheta);
|
||||
verts[2*i+1]=PxVec3(+0.5f*width, cosTheta, sinTheta);
|
||||
}
|
||||
|
||||
return createConvexMesh(verts,numVerts,physics,cooking);
|
||||
}
|
||||
|
||||
PxConvexMesh* createSquashedCuboidMesh(const PxF32 baseLength, const PxF32 baseDepth, const PxF32 height1, const PxF32 height2, PxPhysics& physics, PxCooking& cooking)
|
||||
{
|
||||
const PxF32 x=baseLength*0.5f;
|
||||
const PxF32 z=baseDepth*0.5f;
|
||||
PxVec3 verts[8]=
|
||||
{
|
||||
PxVec3(-x,-0.5f*height1,-z),
|
||||
PxVec3(-x,-0.5f*height1,+z),
|
||||
PxVec3(+x,-0.5f*height1,-z),
|
||||
PxVec3(+x,-0.5f*height1,+z),
|
||||
PxVec3(-x,-0.5f*height1+height2,-z),
|
||||
PxVec3(-x,+0.5f*height1,+z),
|
||||
PxVec3(+x,-0.5f*height1+height2,-z),
|
||||
PxVec3(+x,+0.5f*height1,+z)
|
||||
};
|
||||
PxU32 numVerts=8;
|
||||
|
||||
return createConvexMesh(verts,numVerts,physics,cooking);
|
||||
}
|
||||
|
||||
|
||||
PxConvexMesh* createPrismConvexMesh(const PxF32 baseLength, const PxF32 baseDepth, const PxF32 height, PxPhysics& physics, PxCooking& cooking)
|
||||
{
|
||||
const PxF32 x=baseLength*0.5f;
|
||||
const PxF32 z=baseDepth*0.5f;
|
||||
|
||||
PxVec3 verts[6]=
|
||||
{
|
||||
PxVec3(-x, 0, -z),
|
||||
PxVec3(-x, 0, +z),
|
||||
PxVec3(+x, 0, -z),
|
||||
PxVec3(+x, 0, +z),
|
||||
PxVec3(-x, height, 0),
|
||||
PxVec3(+x, height, 0),
|
||||
};
|
||||
PxU32 numVerts=6;
|
||||
|
||||
return createConvexMesh(verts,numVerts,physics,cooking);
|
||||
}
|
||||
|
||||
PxConvexMesh* createChassisConvexMesh(const PxVec3* verts, const PxU32 numVerts, PxPhysics& physics, PxCooking& cooking)
|
||||
{
|
||||
return createConvexMesh(verts,numVerts,physics,cooking);
|
||||
}
|
||||
|
||||
PxConvexMesh* createWheelConvexMesh(const PxVec3* verts, const PxU32 numVerts, PxPhysics& physics, PxCooking& cooking)
|
||||
{
|
||||
//Extract the wheel radius and width from the aabb of the wheel convex mesh.
|
||||
PxVec3 wheelMin(PX_MAX_F32,PX_MAX_F32,PX_MAX_F32);
|
||||
PxVec3 wheelMax(-PX_MAX_F32,-PX_MAX_F32,-PX_MAX_F32);
|
||||
for(PxU32 i=0;i<numVerts;i++)
|
||||
{
|
||||
wheelMin.x=PxMin(wheelMin.x,verts[i].x);
|
||||
wheelMin.y=PxMin(wheelMin.y,verts[i].y);
|
||||
wheelMin.z=PxMin(wheelMin.z,verts[i].z);
|
||||
wheelMax.x=PxMax(wheelMax.x,verts[i].x);
|
||||
wheelMax.y=PxMax(wheelMax.y,verts[i].y);
|
||||
wheelMax.z=PxMax(wheelMax.z,verts[i].z);
|
||||
}
|
||||
const PxF32 wheelWidth=wheelMax.x-wheelMin.x;
|
||||
const PxF32 wheelRadius=PxMax(wheelMax.y,wheelMax.z);
|
||||
|
||||
return createCylinderConvexMesh(wheelWidth,wheelRadius,8,physics,cooking);
|
||||
}
|
||||
48
physx/samples/samplevehicle/SampleVehicle_VehicleCooking.h
Normal file
48
physx/samples/samplevehicle/SampleVehicle_VehicleCooking.h
Normal file
@ -0,0 +1,48 @@
|
||||
//
|
||||
// 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 VEHICLE_COOKING_H
|
||||
#define VEHICLE_COOKING_H
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
|
||||
using namespace physx;
|
||||
|
||||
|
||||
PxConvexMesh* createConvexMesh(const PxVec3* verts, const PxU32 numVerts, PxPhysics& physics, PxCooking& cooking);
|
||||
PxConvexMesh* createCuboidConvexMesh(const PxVec3& halfExtents, PxPhysics& physics, PxCooking& cooking);
|
||||
PxConvexMesh* createWedgeConvexMesh(const PxVec3& halfExtents, PxPhysics& physics, PxCooking& cooking);
|
||||
PxConvexMesh* createCylinderConvexMesh(const PxF32 width, const PxF32 radius, const PxU32 numCirclePoints, PxPhysics& physics, PxCooking& cooking);
|
||||
PxConvexMesh* createSquashedCuboidMesh(const PxF32 baseLength, const PxF32 baseDepth, const PxF32 height1, const PxF32 height2, PxPhysics& physics, PxCooking& cooking);
|
||||
PxConvexMesh* createPrismConvexMesh(const PxF32 baseLength, const PxF32 baseDepth, const PxF32 height, PxPhysics& physics, PxCooking& cooking);
|
||||
PxConvexMesh* createWheelConvexMesh(const PxVec3* verts, const PxU32 numVerts, PxPhysics& physics, PxCooking& cooking);
|
||||
PxConvexMesh* createChassisConvexMesh(const PxVec3* verts, const PxU32 numVerts, PxPhysics& physics, PxCooking& cooking);
|
||||
|
||||
|
||||
#endif //VEHICLE_COOKING_H
|
||||
1169
physx/samples/samplevehicle/SampleVehicle_VehicleManager.cpp
Normal file
1169
physx/samples/samplevehicle/SampleVehicle_VehicleManager.cpp
Normal file
File diff suppressed because it is too large
Load Diff
226
physx/samples/samplevehicle/SampleVehicle_VehicleManager.h
Normal file
226
physx/samples/samplevehicle/SampleVehicle_VehicleManager.h
Normal file
@ -0,0 +1,226 @@
|
||||
//
|
||||
// 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 SAMPLE_VEHICLE_VEHICLE_MANAGER_H
|
||||
#define SAMPLE_VEHICLE_VEHICLE_MANAGER_H
|
||||
|
||||
#include "vehicle/PxVehicleSDK.h"
|
||||
#include "vehicle/PxVehicleDrive4W.h"
|
||||
#include "vehicle/PxVehicleDriveNW.h"
|
||||
#include "vehicle/PxVehicleDriveTank.h"
|
||||
#include "vehicle/PxVehicleUpdate.h"
|
||||
#include "PxFoundation.h"
|
||||
|
||||
#if PX_DEBUG_VEHICLE_ON
|
||||
#include "vehicle/PxVehicleUtilTelemetry.h"
|
||||
#endif
|
||||
|
||||
using namespace physx;
|
||||
|
||||
namespace physx
|
||||
{
|
||||
class PxScene;
|
||||
class PxBatchQuery;
|
||||
class PxCooking;
|
||||
class PxMaterial;
|
||||
class PxConvexMesh;
|
||||
struct PxVehicleDrivableSurfaceType;
|
||||
}
|
||||
|
||||
class SampleVehicleSceneQueryData;
|
||||
class SampleVehicleWheelQueryResults;
|
||||
|
||||
class PxVehicle4WAlloc;
|
||||
|
||||
//Collision types and flags describing collision interactions of each collision type.
|
||||
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,
|
||||
};
|
||||
|
||||
//Id of drivable surface (used by suspension raycast filtering).
|
||||
enum
|
||||
{
|
||||
DRIVABLE_SURFACE_ID=0xffffffff
|
||||
};
|
||||
|
||||
//Drivable surface types.
|
||||
enum
|
||||
{
|
||||
SURFACE_TYPE_MUD=0,
|
||||
SURFACE_TYPE_TARMAC,
|
||||
SURFACE_TYPE_SNOW,
|
||||
SURFACE_TYPE_GRASS,
|
||||
MAX_NUM_SURFACE_TYPES
|
||||
};
|
||||
|
||||
struct SurfaceTypeNames
|
||||
{
|
||||
static const char* getName(PxU32 type)
|
||||
{
|
||||
static char surfaceTypes[MAX_NUM_SURFACE_TYPES+1][64]=
|
||||
{
|
||||
"mud",
|
||||
"tarmac",
|
||||
"ice",
|
||||
"grass",
|
||||
};
|
||||
|
||||
return surfaceTypes[type];
|
||||
}
|
||||
};
|
||||
|
||||
//Tire types.
|
||||
enum
|
||||
{
|
||||
TIRE_TYPE_WETS=0,
|
||||
TIRE_TYPE_SLICKS,
|
||||
TIRE_TYPE_ICE,
|
||||
TIRE_TYPE_MUD,
|
||||
MAX_NUM_TIRE_TYPES
|
||||
};
|
||||
|
||||
struct TireFrictionMultipliers
|
||||
{
|
||||
static float getValue(PxU32 surfaceType, PxU32 tireType)
|
||||
{
|
||||
//Tire model friction for each combination of drivable surface type and tire type.
|
||||
static PxF32 tireFrictionMultipliers[MAX_NUM_SURFACE_TYPES][MAX_NUM_TIRE_TYPES]=
|
||||
{
|
||||
//WETS SLICKS ICE MUD
|
||||
{0.95f, 0.95f, 0.95f, 0.95f}, //MUD
|
||||
{1.10f, 1.15f, 1.10f, 1.10f}, //TARMAC
|
||||
{0.70f, 0.70f, 0.70f, 0.70f}, //ICE
|
||||
{0.80f, 0.80f, 0.80f, 0.80f} //GRASS
|
||||
};
|
||||
return tireFrictionMultipliers[surfaceType][tireType];
|
||||
}
|
||||
};
|
||||
|
||||
class SampleVehicle_VehicleManager
|
||||
{
|
||||
public:
|
||||
|
||||
enum
|
||||
{
|
||||
MAX_NUM_4W_VEHICLES=8,
|
||||
MAX_NUM_6W_VEHICLES=2,
|
||||
MAX_NUM_4W_TANKS=2
|
||||
};
|
||||
|
||||
SampleVehicle_VehicleManager();
|
||||
~SampleVehicle_VehicleManager();
|
||||
|
||||
void init(PxPhysics& physics, const PxMaterial** drivableSurfaceMaterials, const PxVehicleDrivableSurfaceType* drivableSurfaceTypes);
|
||||
|
||||
void shutdown();
|
||||
|
||||
//Create a vehicle ready to drive.
|
||||
void create4WVehicle
|
||||
(PxScene& scene, PxPhysics& physics, PxCooking& cooking, const PxMaterial& material,
|
||||
const PxF32 chassisMass, const PxVec3* wheelCentreOffsets4, PxConvexMesh* chassisConvexMesh, PxConvexMesh** wheelConvexMeshes4,
|
||||
const PxTransform& startTransform, const bool useAutoGearFlag);
|
||||
void create6WVehicle
|
||||
(PxScene& scene, PxPhysics& physics, PxCooking& cooking, const PxMaterial& material,
|
||||
const PxF32 chassisMass, const PxVec3* wheelCentreOffsets4, PxConvexMesh* chassisConvexMesh, PxConvexMesh** wheelConvexMeshes4,
|
||||
const PxTransform& startTransform, const bool useAutoGearFlag);
|
||||
void create4WTank
|
||||
(PxScene& scene, PxPhysics& physics, PxCooking& cooking, const PxMaterial& material,
|
||||
const PxF32 chassisMass, const PxVec3* wheelCentreOffsets4, PxConvexMesh* chassisConvexMesh, PxConvexMesh** wheelConvexMeshes4,
|
||||
const PxTransform& startTransform, const bool useAutoGearFlag, const PxVehicleDriveTankControlModel::Enum tankDriveModel);
|
||||
void create6WTank
|
||||
(PxScene& scene, PxPhysics& physics, PxCooking& cooking, const PxMaterial& material,
|
||||
const PxF32 chassisMass, const PxVec3* wheelCentreOffsets4, PxConvexMesh* chassisConvexMesh, PxConvexMesh** wheelConvexMeshes4,
|
||||
const PxTransform& startTransform, const bool useAutoGearFlag, const PxVehicleDriveTankControlModel::Enum tankDriveModel);
|
||||
|
||||
PX_FORCE_INLINE PxU32 getNbVehicles() const { return mNumVehicles; }
|
||||
PX_FORCE_INLINE PxVehicleWheels* getVehicle(const PxU32 i) { return mVehicles[i]; }
|
||||
PX_FORCE_INLINE const PxVehicleWheelQueryResult& getVehicleWheelQueryResults(const PxU32 i) const { return mVehicleWheelQueryResults[i]; }
|
||||
void addVehicle(const PxU32 i, PxVehicleWheels* vehicle);
|
||||
|
||||
//Start the suspension raycasts (always call before calling update)
|
||||
void suspensionRaycasts(PxScene* scene);
|
||||
|
||||
//Update vehicle dynamics and compute forces/torques to apply to sdk rigid bodies.
|
||||
#if PX_DEBUG_VEHICLE_ON
|
||||
void updateAndRecordTelemetryData(const PxF32 timestep, const PxVec3& gravity, PxVehicleWheels* focusVehicleNW, PxVehicleTelemetryData* telemetryDataNW);
|
||||
#else
|
||||
void update(const PxF32 timestep, const PxVec3& gravity);
|
||||
#endif
|
||||
|
||||
//Reset the car back to its rest state with a specified transform.
|
||||
void resetNWCar(const PxTransform& transform, const PxU32 vehicleId);
|
||||
|
||||
//Switch the player's vehicle to 3-wheeled modes and back to 4-wheeled mode.
|
||||
void switchTo3WDeltaMode(const PxU32 vehicleId);
|
||||
void switchTo3WTadpoleMode(const PxU32 vehicleId);
|
||||
void switchTo4WMode(const PxU32 vehicleId);
|
||||
|
||||
PxSerializationRegistry* getSerializationRegistry() { return mSerializationRegistry; }
|
||||
private:
|
||||
|
||||
//Array of all cars and report data for each car.
|
||||
PxVehicleWheels* mVehicles[MAX_NUM_4W_VEHICLES+MAX_NUM_6W_VEHICLES];
|
||||
PxVehicleWheelQueryResult mVehicleWheelQueryResults[MAX_NUM_4W_VEHICLES+MAX_NUM_6W_VEHICLES];
|
||||
PxU32 mNumVehicles;
|
||||
|
||||
//sdk raycasts (for the suspension lines).
|
||||
SampleVehicleSceneQueryData* mSqData;
|
||||
PxBatchQuery* mSqWheelRaycastBatchQuery;
|
||||
|
||||
//Reports for each wheel.
|
||||
SampleVehicleWheelQueryResults* mWheelQueryResults;
|
||||
|
||||
//Cached simulation data of focus vehicle in 4W mode.
|
||||
PxVehicleWheelsSimData* mWheelsSimData4W;
|
||||
PxVehicleDriveSimData4W mDriveSimData4W;
|
||||
bool mIsIn3WMode;
|
||||
|
||||
//Friction from combinations of tire and surface types.
|
||||
PxVehicleDrivableSurfaceToTireFrictionPairs* mSurfaceTirePairs;
|
||||
|
||||
|
||||
//Initialise a car back to its start transform and state.
|
||||
void resetNWCar(const PxTransform& startTransform, PxVehicleWheels* car);
|
||||
|
||||
//Serialization
|
||||
PxSerializationRegistry* mSerializationRegistry;
|
||||
};
|
||||
|
||||
#endif //SAMPLE_VEHICLE_VEHICLE_MANAGER_H
|
||||
@ -0,0 +1,73 @@
|
||||
//
|
||||
// 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 "SampleVehicle_WheelQueryResults.h"
|
||||
#include "vehicle/PxVehicleSDK.h"
|
||||
#include "PsFoundation.h"
|
||||
#include "PsUtilities.h"
|
||||
|
||||
|
||||
//#define CHECK_MSG(exp, msg) (!!(exp) || (physx::shdfnd::getFoundation().error(physx::PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, msg), 0) )
|
||||
|
||||
|
||||
SampleVehicleWheelQueryResults* SampleVehicleWheelQueryResults::allocate(const PxU32 maxNumWheels)
|
||||
{
|
||||
const PxU32 size = sizeof(SampleVehicleWheelQueryResults) + sizeof(PxWheelQueryResult)*maxNumWheels;
|
||||
SampleVehicleWheelQueryResults* resData = (SampleVehicleWheelQueryResults*)PX_ALLOC(size, "SampleVehicleWheelQueryResults");
|
||||
resData->init();
|
||||
PxU8* ptr = (PxU8*) resData;
|
||||
ptr += sizeof(SampleVehicleWheelQueryResults);
|
||||
resData->mWheelQueryResults = (PxWheelQueryResult*)ptr;
|
||||
ptr += sizeof(PxWheelQueryResult)*maxNumWheels;
|
||||
resData->mMaxNumWheels=maxNumWheels;
|
||||
for(PxU32 i=0;i<maxNumWheels;i++)
|
||||
{
|
||||
new(&resData->mWheelQueryResults[i]) PxWheelQueryResult();
|
||||
}
|
||||
return resData;
|
||||
}
|
||||
|
||||
void SampleVehicleWheelQueryResults::free()
|
||||
{
|
||||
PX_FREE(this);
|
||||
}
|
||||
|
||||
PxWheelQueryResult* SampleVehicleWheelQueryResults::addVehicle(const PxU32 numWheels)
|
||||
{
|
||||
PX_ASSERT((mNumWheels + numWheels) <= mMaxNumWheels);
|
||||
PxWheelQueryResult* r = &mWheelQueryResults[mNumWheels];
|
||||
mNumWheels += numWheels;
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,82 @@
|
||||
//
|
||||
// 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 SAMPLEVEHICLE_WHEELQUERYRESULTS_H
|
||||
#define SAMPLEVEHICLE_WHEELQUERYRESULTS_H
|
||||
|
||||
#include "vehicle/PxVehicleSDK.h"
|
||||
#include "vehicle/PxVehicleUpdate.h"
|
||||
|
||||
using namespace physx;
|
||||
|
||||
//Data structure to store reports for each wheel.
|
||||
class SampleVehicleWheelQueryResults
|
||||
{
|
||||
public:
|
||||
|
||||
//Allocate a buffer of wheel query results for up to maxNumWheels.
|
||||
static SampleVehicleWheelQueryResults* allocate(const PxU32 maxNumWheels);
|
||||
|
||||
//Free allocated buffer.
|
||||
void free();
|
||||
|
||||
PxWheelQueryResult* addVehicle(const PxU32 numWheels);
|
||||
|
||||
private:
|
||||
|
||||
//One result for each wheel.
|
||||
PxWheelQueryResult* mWheelQueryResults;
|
||||
|
||||
//Maximum number of wheels.
|
||||
PxU32 mMaxNumWheels;
|
||||
|
||||
//Number of wheels
|
||||
PxU32 mNumWheels;
|
||||
|
||||
|
||||
SampleVehicleWheelQueryResults()
|
||||
: mWheelQueryResults(NULL),mMaxNumWheels(0), mNumWheels(0)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
~SampleVehicleWheelQueryResults()
|
||||
{
|
||||
}
|
||||
|
||||
void init()
|
||||
{
|
||||
mWheelQueryResults=NULL;
|
||||
mMaxNumWheels=0;
|
||||
mNumWheels=0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif //SAMPLEVEHICLE_WHEELQUERYRESULTS_H
|
||||
Reference in New Issue
Block a user