void PxVehicleDrive4WSmoothAnalogRawInputsAndSetAnalogInputs (const PxVehiclePadSmoothingData& padSmoothing, const PxFixedSizeLookupTable<8>& steerVsForwardSpeedTable, const PxVehicleDrive4WRawInputData& rawInputData, const PxF32 timestep, PxVehicleDrive4W& focusVehicle) { //gearup/geardown const bool gearup=rawInputData.getGearUp(); const bool geardown=rawInputData.getGearDown(); focusVehicle.mDriveDynData.setGearUp(gearup); focusVehicle.mDriveDynData.setGearDown(geardown); //Update analog inputs for focus vehicle. //Process the accel. { const PxF32 riseRate=padSmoothing.mRiseRates[PxVehicleDrive4W::eANALOG_INPUT_ACCEL]; const PxF32 fallRate=padSmoothing.mFallRates[PxVehicleDrive4W::eANALOG_INPUT_ACCEL]; const PxF32 currentVal=focusVehicle.mDriveDynData.getAnalogInput(PxVehicleDrive4W::eANALOG_INPUT_ACCEL); const PxF32 targetVal=rawInputData.getAnalogAccel(); const PxF32 accel=processPositiveAnalogValue(riseRate,fallRate,currentVal,targetVal,timestep); focusVehicle.mDriveDynData.setAnalogInput(accel,PxVehicleDrive4W::eANALOG_INPUT_ACCEL); } //Process the brake { const PxF32 riseRate=padSmoothing.mRiseRates[PxVehicleDrive4W::eANALOG_INPUT_BRAKE]; const PxF32 fallRate=padSmoothing.mFallRates[PxVehicleDrive4W::eANALOG_INPUT_BRAKE]; const PxF32 currentVal=focusVehicle.mDriveDynData.getAnalogInput(PxVehicleDrive4W::eANALOG_INPUT_BRAKE); const PxF32 targetVal=rawInputData.getAnalogBrake(); const PxF32 brake=processPositiveAnalogValue(riseRate,fallRate,currentVal,targetVal,timestep); focusVehicle.mDriveDynData.setAnalogInput(brake,PxVehicleDrive4W::eANALOG_INPUT_BRAKE); } //Process the handbrake. { const PxF32 riseRate=padSmoothing.mRiseRates[PxVehicleDrive4W::eANALOG_INPUT_HANDBRAKE]; const PxF32 fallRate=padSmoothing.mFallRates[PxVehicleDrive4W::eANALOG_INPUT_HANDBRAKE]; const PxF32 currentVal=focusVehicle.mDriveDynData.getAnalogInput(PxVehicleDrive4W::eANALOG_INPUT_HANDBRAKE); const PxF32 targetVal=rawInputData.getAnalogHandbrake(); const PxF32 handbrake=processPositiveAnalogValue(riseRate,fallRate,currentVal,targetVal,timestep); focusVehicle.mDriveDynData.setAnalogInput(handbrake,PxVehicleDrive4W::eANALOG_INPUT_HANDBRAKE); } //Process the steer { const PxF32 vz=focusVehicle.computeForwardSpeed(); const PxF32 vzAbs=PxAbs(vz); const bool isInAir=focusVehicle.isInAir(); const PxF32 riseRate=padSmoothing.mRiseRates[PxVehicleDrive4W::eANALOG_INPUT_STEER_RIGHT]; const PxF32 fallRate=padSmoothing.mFallRates[PxVehicleDrive4W::eANALOG_INPUT_STEER_RIGHT]; const PxF32 currentVal=focusVehicle.mDriveDynData.getAnalogInput(PxVehicleDrive4W::eANALOG_INPUT_STEER_RIGHT)-focusVehicle.mDriveDynData.getAnalogInput(PxVehicleDrive4W::eANALOG_INPUT_STEER_LEFT); const PxF32 targetVal=rawInputData.getAnalogSteer()*(isInAir ? 1.0f :steerVsForwardSpeedTable.getYVal(vzAbs)); const PxF32 steer=processAnalogValue(riseRate,fallRate,currentVal,targetVal,timestep); focusVehicle.mDriveDynData.setAnalogInput(0.0f, PxVehicleDrive4W::eANALOG_INPUT_STEER_LEFT); focusVehicle.mDriveDynData.setAnalogInput(steer, PxVehicleDrive4W::eANALOG_INPUT_STEER_RIGHT); } }
void PhysicsEngine::createVehicle(Vehicle* vehicle, PxTransform transform) { VehicleTuning* tuning = &vehicle->tuning; tuningFromUserTuning(vehicle); PxVehicleDrive4W* physVehicle = vehCreator->createVehicle4W(vehicle); //PxTransform startTransform(PxVec3(0, (tuning->chassisDims.y*0.5f + tuning->wheelRadius + 1.0f), 0), PxQuat(PxIdentity)); PxRigidDynamic* actor = physVehicle->getRigidDynamicActor(); actor->setGlobalPose(transform); scene->addActor(*actor); physVehicle->setToRestState(); physVehicle->mDriveDynData.forceGearChange(PxVehicleGearsData::eFIRST); physVehicle->mDriveDynData.setUseAutoGears(true); vehicle->setActor(actor); vehicle->setPhysicsVehicle(physVehicle); actor->userData = vehicle; vehicles.push_back(physVehicle); }
void SampleVehicle_VehicleManager::create4WVehicle (PxScene& scene, PxPhysics& physics, PxCooking& cooking, const PxMaterial& material, const PxF32 chassisMass, const PxVec3* wheelCentreOffsets4, PxConvexMesh* chassisConvexMesh, PxConvexMesh** wheelConvexMeshes4, const PxTransform& startTransform, const bool useAutoGearFlag) { PX_ASSERT(mNumVehicles<MAX_NUM_4W_VEHICLES); PxVehicleWheelsSimData* wheelsSimData=PxVehicleWheelsSimData::allocate(4); PxVehicleDriveSimData4W driveSimData; PxVehicleChassisData chassisData; createVehicle4WSimulationData (chassisMass,chassisConvexMesh, 20.0f,wheelConvexMeshes4,wheelCentreOffsets4, *wheelsSimData,driveSimData,chassisData); //Instantiate and finalize the vehicle using physx. PxRigidDynamic* vehActor=createVehicleActor4W(chassisData,wheelConvexMeshes4,chassisConvexMesh,scene,physics,material); //Create a car. PxVehicleDrive4W* car = PxVehicleDrive4W::allocate(4); car->setup(&physics,vehActor,*wheelsSimData,driveSimData,0); //Free the sim data because we don't need that any more. wheelsSimData->free(); //Don't forget to add the actor to the scene. scene.addActor(*vehActor); //Set the transform and the instantiated car and set it be to be at rest. resetNWCar(startTransform,car); //Set the autogear mode of the instantiate car. car->mDriveDynData.setUseAutoGears(useAutoGearFlag); //Increment the number of vehicles mVehicles[mNumVehicles]=car; mNumVehicles++; }
void PxVehicleDrive4WSmoothDigitalRawInputsAndSetAnalogInputs (const PxVehicleKeySmoothingData& keySmoothing, const PxFixedSizeLookupTable<8>& steerVsForwardSpeedTable, const PxVehicleDrive4WRawInputData& rawInputData, const PxF32 timestep, PxVehicleDrive4W& focusVehicle) { const bool gearup=rawInputData.getGearUp(); const bool geardown=rawInputData.getGearDown(); focusVehicle.mDriveDynData.setGearDown(geardown); focusVehicle.mDriveDynData.setGearUp(gearup); const PxF32 accel=processDigitalValue(PxVehicleDrive4W::eANALOG_INPUT_ACCEL,keySmoothing,rawInputData.getDigitalAccel(),timestep,focusVehicle.mDriveDynData.getAnalogInput(PxVehicleDrive4W::eANALOG_INPUT_ACCEL)); focusVehicle.mDriveDynData.setAnalogInput(accel,PxVehicleDrive4W::eANALOG_INPUT_ACCEL); const PxF32 brake=processDigitalValue(PxVehicleDrive4W::eANALOG_INPUT_BRAKE,keySmoothing,rawInputData.getDigitalBrake(),timestep,focusVehicle.mDriveDynData.getAnalogInput(PxVehicleDrive4W::eANALOG_INPUT_BRAKE)); focusVehicle.mDriveDynData.setAnalogInput(brake,PxVehicleDrive4W::eANALOG_INPUT_BRAKE); const PxF32 handbrake=processDigitalValue(PxVehicleDrive4W::eANALOG_INPUT_HANDBRAKE,keySmoothing,rawInputData.getDigitalHandbrake(),timestep,focusVehicle.mDriveDynData.getAnalogInput(PxVehicleDrive4W::eANALOG_INPUT_HANDBRAKE)); focusVehicle.mDriveDynData.setAnalogInput(handbrake,PxVehicleDrive4W::eANALOG_INPUT_HANDBRAKE); PxF32 steerLeft=processDigitalValue(PxVehicleDrive4W::eANALOG_INPUT_STEER_LEFT,keySmoothing,rawInputData.getDigitalSteerLeft(),timestep,focusVehicle.mDriveDynData.getAnalogInput(PxVehicleDrive4W::eANALOG_INPUT_STEER_LEFT)); PxF32 steerRight=processDigitalValue(PxVehicleDrive4W::eANALOG_INPUT_STEER_RIGHT,keySmoothing,rawInputData.getDigitalSteerRight(),timestep,focusVehicle.mDriveDynData.getAnalogInput(PxVehicleDrive4W::eANALOG_INPUT_STEER_RIGHT)); const PxF32 vz=focusVehicle.computeForwardSpeed(); const PxF32 vzAbs=PxAbs(vz); const bool isInAir=focusVehicle.isInAir(); const PxF32 maxSteer=(isInAir ? 1.0f :steerVsForwardSpeedTable.getYVal(vzAbs)); const PxF32 steer=PxAbs(steerRight-steerLeft); if(steer>maxSteer) { const PxF32 k=maxSteer/steer; steerLeft*=k; steerRight*=k; } focusVehicle.mDriveDynData.setAnalogInput(steerLeft, PxVehicleDrive4W::eANALOG_INPUT_STEER_LEFT); focusVehicle.mDriveDynData.setAnalogInput(steerRight, PxVehicleDrive4W::eANALOG_INPUT_STEER_RIGHT); }
void initPhysics() { ///////////////////////////////////////////// //Initialise the sdk and scene ///////////////////////////////////////////// gFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gAllocator, gErrorCallback); PxProfileZoneManager* profileZoneManager = &PxProfileZoneManager::createProfileZoneManager(gFoundation); gPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *gFoundation, PxTolerancesScale(),true, profileZoneManager); if(gPhysics->getPvdConnectionManager()) { gPhysics->getVisualDebugger()->setVisualizeConstraints(true); gPhysics->getVisualDebugger()->setVisualDebuggerFlag(PxVisualDebuggerFlag::eTRANSMIT_CONTACTS, false); gPhysics->getVisualDebugger()->setVisualDebuggerFlag(PxVisualDebuggerFlag::eTRANSMIT_SCENEQUERIES, false); gPhysics->getVisualDebugger()->setVisualDebuggerFlag(PxVisualDebuggerFlag::eTRANSMIT_CONSTRAINTS, false); gConnection = PxVisualDebuggerExt::createConnection(gPhysics->getPvdConnectionManager(), PVD_HOST, 5425, 10, gConnectionFlags); } PxSceneDesc sceneDesc(gPhysics->getTolerancesScale()); sceneDesc.gravity = PxVec3(0.0f, -9.81f, 0.0f); gDispatcher = PxDefaultCpuDispatcherCreate(NUM_WORKER_THREADS); sceneDesc.cpuDispatcher = gDispatcher; sceneDesc.filterShader = VehicleFilterShader; gScene = gPhysics->createScene(sceneDesc); gCooking = PxCreateCooking(PX_PHYSICS_VERSION, *gFoundation, PxCookingParams(PxTolerancesScale())); ///////////////////////////////////////////// //Create a task manager that will be used to //update the vehicles concurrently across //multiple threads. ///////////////////////////////////////////// gTaskManager = physx::PxTaskManager::createTaskManager(gDispatcher, NULL, NULL); ///////////////////////////////////////////// //Initialise the vehicle sdk and create //vehicles that will drive on a plane ///////////////////////////////////////////// PxInitVehicleSDK(*gPhysics); PxVehicleSetBasisVectors(PxVec3(0,1,0), PxVec3(0,0,1)); PxVehicleSetUpdateMode(PxVehicleUpdateMode::eVELOCITY_CHANGE); //Create the batched scene queries for the suspension raycasts. gVehicleSceneQueryData = VehicleSceneQueryData::allocate(NUM_VEHICLES, PX_MAX_NB_WHEELS, 1, gAllocator); for(PxU32 i = 0; i < NUM_VEHICLES; i++) { gBatchQueries[i] = VehicleSceneQueryData::setUpBatchedSceneQuery(i, *gVehicleSceneQueryData, gScene); } //Create the friction table for each combination of tire and surface type. //For simplicity we only have a single surface type. gMaterial = gPhysics->createMaterial(0.5f, 0.5f, 0.6f); gFrictionPairs = createFrictionPairs(gMaterial); //Create a plane to drive on. gGroundPlane = createDrivablePlane(gMaterial, gPhysics); gScene->addActor(*gGroundPlane); //Create vehicles that will drive on the plane. for(PxU32 i = 0; i < NUM_VEHICLES; i++) { VehicleDesc vehicleDesc = initVehicleDesc(); PxVehicleDrive4W* vehicle = createVehicle4W(vehicleDesc, gPhysics, gCooking); PxTransform startTransform(PxVec3(vehicleDesc.chassisDims.x*3.0f*i, (vehicleDesc.chassisDims.y*0.5f + vehicleDesc.wheelRadius + 1.0f), 0), PxQuat(PxIdentity)); vehicle->getRigidDynamicActor()->setGlobalPose(startTransform); gScene->addActor(*vehicle->getRigidDynamicActor()); //Set the vehicle to rest in first gear. //Set the vehicle to use auto-gears. vehicle->setToRestState(); vehicle->mDriveDynData.forceGearChange(PxVehicleGearsData::eFIRST); vehicle->mDriveDynData.setUseAutoGears(true); //Set each car to accelerate forwards vehicle->mDriveDynData.setAnalogInput(PxVehicleDrive4WControl::eANALOG_INPUT_ACCEL, 1.0f); gVehicles[i] = vehicle; } //Set up the wheel query results that are used to query the state of the vehicle after calling PxVehicleUpdates gVehicleWheelQueryResults = VehicleWheelQueryResults::allocate(NUM_VEHICLES, PX_MAX_NB_WHEELS, gAllocator); //Set up the data required for concurrent calls to PxVehicleUpdates gVehicleConcurrency = VehicleConcurrency::allocate(NUM_VEHICLES, PX_MAX_NB_WHEELS, gAllocator); //Set up the profile zones so that the advantages of parallelism can be measured in pvd. #ifdef PX_PROFILE gProfiler = VehicleProfiler::allocate(gProfileZoneNames, eMAX_NUM_PROFILES, profileZoneManager, gAllocator); #endif }