void UWheeledVehicleMovementComponent4W::UpdateSimulation(float DeltaTime) { if (PVehicleDrive == NULL) return; PxVehicleDrive4WRawInputData RawInputData; RawInputData.setAnalogAccel(ThrottleInput); RawInputData.setAnalogSteer(SteeringInput); RawInputData.setAnalogBrake(BrakeInput); RawInputData.setAnalogHandbrake(HandbrakeInput); if (!PVehicleDrive->mDriveDynData.getUseAutoGears()) { RawInputData.setGearUp(bRawGearUpInput); RawInputData.setGearDown(bRawGearDownInput); } PxFixedSizeLookupTable<8> SpeedSteerLookup(SteeringMap,4); PxVehiclePadSmoothingData SmoothData = { { ThrottleInputRate.RiseRate, BrakeInputRate.RiseRate, HandbrakeInputRate.RiseRate, SteeringInputRate.RiseRate, SteeringInputRate.RiseRate }, { ThrottleInputRate.FallRate, BrakeInputRate.FallRate, HandbrakeInputRate.FallRate, SteeringInputRate.FallRate, SteeringInputRate.FallRate } }; PxVehicleDrive4W* PVehicleDrive4W = (PxVehicleDrive4W*)PVehicleDrive; PxVehicleDrive4WSmoothAnalogRawInputsAndSetAnalogInputs(SmoothData, SpeedSteerLookup, RawInputData, DeltaTime, false, *PVehicleDrive4W); }
void UWheeledVehicleMovementComponent4W::UpdateSimulation(float DeltaTime) { if (PVehicleDrive == NULL) return; UpdatedPrimitive->GetBodyInstance()->ExecuteOnPhysicsReadWrite([&] { PxVehicleDrive4WRawInputData RawInputData; RawInputData.setAnalogAccel(ThrottleInput); RawInputData.setAnalogSteer(SteeringInput); RawInputData.setAnalogBrake(BrakeInput); RawInputData.setAnalogHandbrake(HandbrakeInput); if (!PVehicleDrive->mDriveDynData.getUseAutoGears()) { RawInputData.setGearUp(bRawGearUpInput); RawInputData.setGearDown(bRawGearDownInput); } // Convert from our curve to PxFixedSizeLookupTable PxFixedSizeLookupTable<8> SpeedSteerLookup; TArray<FRichCurveKey> SteerKeys = SteeringCurve.GetRichCurve()->GetCopyOfKeys(); const int32 MaxSteeringSamples = FMath::Min(8, SteerKeys.Num()); for (int32 KeyIdx = 0; KeyIdx < MaxSteeringSamples; KeyIdx++) { FRichCurveKey& Key = SteerKeys[KeyIdx]; SpeedSteerLookup.addPair(KmHToCmS(Key.Time), FMath::Clamp(Key.Value, 0.f, 1.f)); } PxVehiclePadSmoothingData SmoothData = { { ThrottleInputRate.RiseRate, BrakeInputRate.RiseRate, HandbrakeInputRate.RiseRate, SteeringInputRate.RiseRate, SteeringInputRate.RiseRate }, { ThrottleInputRate.FallRate, BrakeInputRate.FallRate, HandbrakeInputRate.FallRate, SteeringInputRate.FallRate, SteeringInputRate.FallRate } }; PxVehicleDrive4W* PVehicleDrive4W = (PxVehicleDrive4W*)PVehicleDrive; PxVehicleDrive4WSmoothAnalogRawInputsAndSetAnalogInputs(SmoothData, SpeedSteerLookup, RawInputData, DeltaTime, false, *PVehicleDrive4W); }); }
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::update(const PxF32 timestep, PxVehicleWheels& focusVehicle) { PX_ASSERT(eVEHICLE_TYPE_DRIVE4W==focusVehicle.getVehicleType()); PxVehicleDrive4W& vehDrive4W=(PxVehicleDrive4W&)focusVehicle; PxVehicleDriveDynData& driveDynData=vehDrive4W.mDriveDynData; //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; processRawInputs(timestep,driveDynData.getUseAutoGears(),carRawInputs); //Work out if the car is to flip from reverse to forward gear or from forward gear to reverse. //Store if the car is moving slowly to help decide if the car is to toggle from reverse to forward in the next update. bool toggleAutoReverse = false; bool newIsMovingForwardSlowly = false; processAutoReverse(focusVehicle, driveDynData, carRawInputs, 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) { const bool accel=carRawInputs.getDigitalAccel(); const bool brake=carRawInputs.getDigitalBrake(); carRawInputs.setDigitalAccel(brake); carRawInputs.setDigitalBrake(accel); } else { const PxF32 accel=carRawInputs.getAnalogAccel(); const PxF32 brake=carRawInputs.getAnalogBrake(); carRawInputs.setAnalogAccel(brake); carRawInputs.setAnalogBrake(accel); } } // 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) { PxVehicleDrive4WSmoothDigitalRawInputsAndSetAnalogInputs(gKeySmoothingData,gSteerVsForwardSpeedTable,carRawInputs,timestep,(PxVehicleDrive4W&)focusVehicle); } else { PxVehicleDrive4WSmoothAnalogRawInputsAndSetAnalogInputs(gCarPadSmoothingData,gSteerVsForwardSpeedTable,carRawInputs,timestep,(PxVehicleDrive4W&)focusVehicle); } }
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); } } }