Ejemplo n.º 1
0
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 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);
	});
}
Ejemplo n.º 3
0
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);
}
Ejemplo n.º 4
0
void CreateVehicle4WSimulationData( PxConvexMesh* chassisConvexMesh, PxConvexMesh** wheelConvexMeshes, 
	const PxVec3* wheelCenterOffsets, PxVehicleWheelsSimData& wheelsData, PxVehicleDriveSimData4W& driveData, 
	PhysXVehicleInitData* generalData, PhysXVehicleInitData** wheelDatas )
{
	float chassisMass = generalData->GetFloatParameter( "massChassis" );

	PxF32 wheelWidths[ 4 ];
	PxF32 wheelRadii[ 4 ];
	ComputeWheelWidthsAndRadii( wheelConvexMeshes, wheelWidths, wheelRadii );

	//Wheels
	for( int n = 0; n < 4; n++ )
	{
		PhysXVehicleInitData* wheelInitData = wheelDatas[ n ];

		PxVehicleWheelData wheelData;
		wheelData.mRadius = wheelRadii[ n ];
		wheelData.mMass = wheelInitData->GetFloatParameter( "mass" );
		wheelData.mMOI = 0.5f * wheelData.mMass * wheelRadii[ n ] * wheelRadii[ n ];
		wheelData.mWidth = wheelWidths[ n ];
		wheelData.mDampingRate = wheelInitData->GetFloatParameter( "wheelDampingRate" );
		wheelData.mMaxBrakeTorque = wheelInitData->GetFloatParameter( "wheelMaxBrakeTorque" );
		wheelData.mMaxHandBrakeTorque = wheelInitData->GetFloatParameter( "wheelMaxHandBrakeTorque" );
		wheelData.mMaxSteer = DegToRad( wheelInitData->GetFloatParameter("wheelMaxSteer") );
		wheelData.mToeAngle = DegToRad( wheelInitData->GetFloatParameter("wheelToeAngle") );
		wheelsData.setWheelData( n, wheelData );

		PxVehicleTireData tireData;
		tireData.mLatStiffX = wheelInitData->GetFloatParameter( "tireLatStiffX" );
		tireData.mLatStiffY = wheelInitData->GetFloatParameter( "tireLatStiffY" );
		tireData.mLongitudinalStiffnessPerUnitGravity = wheelInitData->GetFloatParameter( "tireLongitudinalStiffnessPerUnitGravity" );
		tireData.mCamberStiffness = wheelInitData->GetFloatParameter( "tireCamberStiffness" );
		tireData.mFrictionVsSlipGraph[ 0 ][ 1 ] = wheelInitData->GetFloatParameter( "frictionVsSlipGraphZeroLongitudinalSlip" );
		tireData.mFrictionVsSlipGraph[ 1 ][ 0 ] = wheelInitData->GetFloatParameter( "frictionVsSlipGraphLongitudinalSlipWithMaximumFriction" );
		tireData.mFrictionVsSlipGraph[ 1 ][ 1 ] = wheelInitData->GetFloatParameter( "frictionVsSlipGraphMaximumFriction" );
		tireData.mFrictionVsSlipGraph[ 2 ][ 0 ] = wheelInitData->GetFloatParameter( "frictionVsSlipGraphEndPointOfGraph" );
		tireData.mFrictionVsSlipGraph[ 2 ][ 1 ] = wheelInitData->GetFloatParameter( "frictionVsSlipGraphValueOfFrictionForSlipsGreaterThanEndPointOfGraph" );
		wheelsData.setTireData( n, tireData );

		PxVehicleSuspensionData suspensionData;
		suspensionData.mMaxCompression = wheelInitData->GetFloatParameter( "suspensionMaxCompression" );
		suspensionData.mMaxDroop = wheelInitData->GetFloatParameter( "suspensionMaxDroop" );
		suspensionData.mSpringStrength = wheelInitData->GetFloatParameter( "suspensionSpringStrength" );
		suspensionData.mSpringDamperRate = wheelInitData->GetFloatParameter( "suspensionSpringDamperRate" );
		suspensionData.mSprungMass = chassisMass * wheelInitData->GetFloatParameter( "suspensionSprungMassCoefficient" );
		wheelsData.setSuspensionData( n, suspensionData );

		PxVec3 suspensionForceApplicationPointOffset = PxVec3(
			wheelInitData->GetFloatParameter( "suspensionForceApplicationPointOffset.X" ),
			wheelInitData->GetFloatParameter( "suspensionForceApplicationPointOffset.Y" ),
			wheelInitData->GetFloatParameter( "suspensionForceApplicationPointOffset.Z" ) );
		PxVec3 tireForceApplicationPointOffset = PxVec3(
			wheelInitData->GetFloatParameter( "tireForceApplicationPointOffset.X" ),
			wheelInitData->GetFloatParameter( "tireForceApplicationPointOffset.Y" ),
			wheelInitData->GetFloatParameter( "tireForceApplicationPointOffset.Z" ) );
		wheelsData.setSuspTravelDirection( n, PxVec3( 0, 0, -1 ) );
		wheelsData.setWheelCentreOffset( n, wheelCenterOffsets[ n ] );
		wheelsData.setSuspForceAppPointOffset( n, wheelCenterOffsets[ n ] + suspensionForceApplicationPointOffset );
		wheelsData.setTireForceAppPointOffset( n, wheelCenterOffsets[ n ] + tireForceApplicationPointOffset );
	}

	//Differential
	{
		PxVehicleDifferential4WData differential;
		differential.mType = (int)( generalData->GetFloatParameter( "differentialType" ) + .0001f );
		differential.mFrontRearSplit = generalData->GetFloatParameter( "differentialFrontRearSplit" );
		differential.mFrontLeftRightSplit = generalData->GetFloatParameter( "differentialFrontLeftRightSplit" );
		differential.mRearLeftRightSplit = generalData->GetFloatParameter( "differentialRearLeftRightSplit" );
		differential.mCentreBias = generalData->GetFloatParameter( "differentialCenterBias" );
		differential.mFrontBias = generalData->GetFloatParameter( "differentialFrontBias" );
		differential.mRearBias = generalData->GetFloatParameter( "differentialRearBias" );
		driveData.setDiffData( differential );
	}
	
	//Engine
	{
		PxVehicleEngineData engine;
		engine.mPeakTorque = generalData->GetFloatParameter("enginePeakTorque");// 500.0f;
		engine.mMaxOmega = generalData->GetFloatParameter("engineMaxRPM") * PI * 2.0f / 60.0f;//600.0f;//approx 6000 rpm
		engine.mDampingRateFullThrottle = generalData->GetFloatParameter("engineDampingRateFullThrottle");
		engine.mDampingRateZeroThrottleClutchEngaged = generalData->GetFloatParameter("engineDampingRateZeroThrottleClutchEngaged");
		engine.mDampingRateZeroThrottleClutchDisengaged = generalData->GetFloatParameter("engineDampingRateZeroThrottleClutchDisengaged");

		PxFixedSizeLookupTable<PxVehicleEngineData::eMAX_NUM_ENGINE_TORQUE_CURVE_ENTRIES> torqueCurve;
		for( int n = 0; n < PxVehicleEngineData::eMAX_NUM_ENGINE_TORQUE_CURVE_ENTRIES; n++ )
		{
			char s[50];
			sprintf(s, "engineTorqueCurveTorque%d", n);
			if(!generalData->IsFloatParameterExist(s))
				break;
			float torque = generalData->GetFloatParameter(s);
			sprintf(s, "engineTorqueCurveRev%d", n);
			float rev = generalData->GetFloatParameter(s);
			torqueCurve.addPair(torque, rev);
		}
		engine.mTorqueCurve = torqueCurve;

		driveData.setEngineData( engine );
	}

	//Gears
	{
		PxVehicleGearsData gears;
		for( int n = 0; n < PxVehicleGearsData::eMAX_NUM_GEAR_RATIOS; n++)
			gears.mRatios[ n ] = 0;

		int minNumber = 100000;
		int maxNumber = -100000;
		for( int number = -1; number <= 30; number++ )
		{
			char s[25];
			sprintf(s, "gear%d", number);
			if(generalData->IsFloatParameterExist(s))
			{
				float ratio = generalData->GetFloatParameter(s);
				gears.mRatios[ number + 1 ] = ratio;

				if(number < minNumber)
					minNumber = number;
				if(number > maxNumber)
					maxNumber = number;
			}
		}
		gears.mFinalRatio = 1;
		gears.mNumRatios = maxNumber - minNumber + 1;
		gears.mSwitchTime = generalData->GetFloatParameter(L"gearsSwitchTime");//0.5f;

		driveData.setGearsData(gears);
	}

	//Clutch
	PxVehicleClutchData clutch;
	clutch.mStrength = generalData->GetFloatParameter(L"clutchStrength");
	driveData.setClutchData(clutch);

	//Ackermann steer accuracy
	PxVehicleAckermannGeometryData ackermann;
	ackermann.mAccuracy = generalData->GetFloatParameter(L"ackermannSteerAccuracy");
	ackermann.mAxleSeparation = fabs(
		wheelCenterOffsets[PxVehicleDrive4W::eFRONT_LEFT_WHEEL].x -
		wheelCenterOffsets[PxVehicleDrive4W::eREAR_LEFT_WHEEL].x);
	ackermann.mFrontWidth = fabs(
		wheelCenterOffsets[PxVehicleDrive4W::eFRONT_RIGHT_WHEEL].y -
		wheelCenterOffsets[PxVehicleDrive4W::eFRONT_LEFT_WHEEL].y);
	ackermann.mRearWidth = fabs(
		wheelCenterOffsets[PxVehicleDrive4W::eREAR_LEFT_WHEEL].y -
		wheelCenterOffsets[PxVehicleDrive4W::eREAR_RIGHT_WHEEL].y);
	driveData.setAckermannGeometryData(ackermann);
}
void SampleVehicle_CameraController::update(const PxReal dtime, const PxRigidDynamic* actor, PxScene& 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;

	PxRaycastHit hit;
	PxSceneQueryFilterData filterData(PxSceneQueryFilterFlag::eSTATIC);
	scene.raycastSingle(target, -direction, camDist, PxSceneQueryFlag::eDISTANCE, hit, filterData, NULL, NULL);
	if (hit.shape != NULL)
	{
		camDist = hit.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;
}