PhysX Vehicles
1
PhysX Vehicles 1 PhysX Collision and Dynamics SDK (now) owned by - - PowerPoint PPT Presentation
PhysX Vehicles 1 PhysX Collision and Dynamics SDK (now) owned by Nvidia Most common physics library used in games for this course Includes lots of vehicle specific features, which we strongly recommend using We used to allow
1
course
strongly recommend using
required building driving model from scratch
challenge for teams, and was often holding back game quality significantly
– Set up library – Create some meshes – Allocate simulation data – Allocate actor and add to world – Per frame : Setup inputs to drive and steering – Per frame : Wheel raycasts – Per frame : Tick simulation
PxAllocatorCallback* allocator = &gDefaultAllocatorCallback; mFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, *allocator, getSampleErrorCallback()); mPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *mFoundation, scale, recordMemoryAllocations, mProfileZoneManager);
– Base context for all operations
PxCookingParams params(scale); params.meshWeldTolerance = 0.001f; params.meshPreprocessParams = PxMeshPreprocessingFlags(PxMeshPreprocessingFlag::eWELD_VERTICES | PxMeshPreprocessingFlag::eREMOVE_UNREFERENCED_VERTICES | PxMeshPreprocessingFlag::eREMOVE_DUPLICATED_TRIANGLES); mCooking = PxCreateCooking(PX_PHYSICS_VERSION, *mFoundation, params);
– Utility class for creating meshes in physics – PhysX vehicles uses meshes for all objects in vehicle system
mScene = mPhysics->createScene(sceneDesc); mScene.setGravity(PxVec3(0.0f, -9.81f, 0.0f)); mMaterials = getPhysics().createMaterial(staticFriction, dynamicFriction, restitution); PxRigidStatic* plane = PxCreatePlane(*mPhysics, PxPlane(PxVec3(0,1,0), 0), *mMaterial); mScene->addActor(*plane);
– Container for all object in simulation – Global world properties (i.e. gravity) – Any objects not in vehicle system can be added straight to this with minimal extra work – Probably going to want to add at least one static object
PxInitVehicleSDK(physics); PxVec3 up(0,1,0); PxVec3 forward(0,0,1); PxVehicleSetBasisVectors(up,forward); //Set the vehicle update mode to be immediate velocity changes. PxVehicleSetUpdateMode(PxVehicleUpdateMode::eVELOCITY_CHANGE);
PxConvexMeshDesc convexDesc; convexDesc.points.count = numVerts; convexDesc.points.stride = sizeof(PxVec3); convexDesc.points.data = verts; convexDesc.flags = PxConvexFlag::eCOMPUTE_CONVEX | PxConvexFlag::eINFLATE_CONVEX; PxConvexMesh* convexMesh = NULL; PxDefaultMemoryOutputStream buf; if(cooking.cookConvexMesh(convexDesc, buf)) { PxDefaultMemoryInputData id(buf.getData(), buf.getSize()); convexMesh = physics.createConvexMesh(id); }
PxVehicleWheelsSimData* wheelsSimData=PxVehicleWheelsSimData::allocate(4); PxVehicleDriveSimData4W driveSimData; PxVehicleChassisData chassisData; createVehicle4WSimulationData (chassisMass,chassisConvexMesh, 20.0f,wheelConvexMeshes4,wheelCentreOffsets4, *wheelsSimData,driveSimData,chassisData);
const PxVec3 chassisCMOffset=PxVec3(0.0f,-chassisDims.y*0.5f+0.65f,0.25f); chassisData.mCMOffset=chassisCMOffset;
PxVehicleSuspensionData susps[4]; for(PxU32 i=0;i<4;i++) { susps[i].mMaxCompression=0.3f; susps[i].mMaxDroop=0.1f; susps[i].mSpringStrength=35000.0f; susps[i].mSpringDamperRate=4500.0f; } for(PxU32 i=0;i<4;i++) { wheelsData.setSuspensionData(i,susps[i]); //... } PxVehicleEngineData engine; engine.mPeakTorque=500.0f; engine.mMaxOmega=600.0f;//approx 6000 rpm driveData.setEngineData(engine);
PxRigidDynamic* vehActor = physics.createRigidDynamic(PxTransform(PxIdentity)); for(PxU32 i=0;i<numWheelGeometries;i++) { PxShape* wheelShape=vehActor->createShape(*wheelGeometries[i],*wheelMaterial); wheelShape->setQueryFilterData(vehQryFilterData); wheelShape->setSimulationFilterData(wheelCollFilterData); wheelShape->setLocalPose(wheelLocalPoses[i]); } // Need to add chassis as well //... PxVehicleDrive4W* car = PxVehicleDrive4W::allocate(4); car->setup(&physics,vehActor,*wheelsSimData,driveSimData,0); mScene.addActor(*vehActor);
as well
PxVehicleDrive4WRawInputData carRawInputs; carRawInputs.setAnalogAccel(mGamepadAccel); carRawInputs.setAnalogBrake(mGamepadCarBrake); carRawInputs.setAnalogSteer(mGamepadCarSteer); PxVehicleDrive4WSmoothAnalogRawInputsAndSetAnalogInputs (gCarPadSmoothingData,gSteerVsForwardSpeedTable, carRawInputs,timestep,isInAir,(PxVehicleDrive4W&)focusVehicle); if(NULL==mSqWheelRaycastBatchQuery) { mSqWheelRaycastBatchQuery=mSqData->setUpBatchedSceneQuery(scene); } PxVehicleSuspensionRaycasts(mSqWheelRaycastBatchQuery,mNumVehicles,mVehicles, mSqData->getRaycastQueryResultBufferSize(),mSqData->getRaycastQueryResultBuffer());
PxVehicleUpdates(timestep,gravity,*mSurfaceTirePairs, numVehicles,vehicles,vehicleWheelQueryResults); scene->simulate(mStepSize, NULL, scratchBlock, scratchBlockSize);
good reason not to
– Spoiler : you don’t have a good reason
the PhysX sample code
baseline, need to make it better if you want good marks