Add tank vehicle physics

This commit is contained in:
Mr. Capybara
2023-12-31 15:00:31 -04:00
parent b275ffc146
commit d016305690
3 changed files with 518 additions and 230 deletions
+68 -23
View File
@@ -14,7 +14,7 @@
#include "Engine/Core/Log.h"
#endif
WheeledVehicle::WheeledVehicle(const SpawnParams& params)
WheeledVehicle::WheeledVehicle(const SpawnParams &params)
: RigidBody(params)
{
_useCCD = 1;
@@ -33,12 +33,22 @@ void WheeledVehicle::SetDriveType(DriveTypes value)
Setup();
}
const Array<WheeledVehicle::Wheel>& WheeledVehicle::GetWheels() const
void WheeledVehicle::SetDriveMode(DriveModes value)
{
_driveMode = value;
}
WheeledVehicle::DriveModes WheeledVehicle::GetDriveMode() const
{
return _driveMode;
}
const Array<WheeledVehicle::Wheel> &WheeledVehicle::GetWheels() const
{
return _wheels;
}
void WheeledVehicle::SetWheels(const Array<Wheel>& value)
void WheeledVehicle::SetWheels(const Array<Wheel> &value)
{
#if WITH_VEHICLE
// Don't recreate whole vehicle when some wheel properties are only changed (eg. suspension)
@@ -47,8 +57,8 @@ void WheeledVehicle::SetWheels(const Array<Wheel>& value)
bool softUpdate = true;
for (int32 wheelIndex = 0; wheelIndex < value.Count(); wheelIndex++)
{
auto& oldWheel = _wheels.Get()[wheelIndex];
auto& newWheel = value.Get()[wheelIndex];
auto &oldWheel = _wheels.Get()[wheelIndex];
auto &newWheel = value.Get()[wheelIndex];
if (oldWheel.Type != newWheel.Type ||
Math::NotNearEqual(oldWheel.SuspensionForceOffset, newWheel.SuspensionForceOffset) ||
oldWheel.Collider != newWheel.Collider)
@@ -74,7 +84,7 @@ WheeledVehicle::EngineSettings WheeledVehicle::GetEngine() const
return _engine;
}
void WheeledVehicle::SetEngine(const EngineSettings& value)
void WheeledVehicle::SetEngine(const EngineSettings &value)
{
#if WITH_VEHICLE
if (_vehicle)
@@ -88,7 +98,7 @@ WheeledVehicle::DifferentialSettings WheeledVehicle::GetDifferential() const
return _differential;
}
void WheeledVehicle::SetDifferential(const DifferentialSettings& value)
void WheeledVehicle::SetDifferential(const DifferentialSettings &value)
{
#if WITH_VEHICLE
if (_vehicle)
@@ -102,7 +112,7 @@ WheeledVehicle::GearboxSettings WheeledVehicle::GetGearbox() const
return _gearbox;
}
void WheeledVehicle::SetGearbox(const GearboxSettings& value)
void WheeledVehicle::SetGearbox(const GearboxSettings &value)
{
#if WITH_VEHICLE
if (_vehicle)
@@ -131,11 +141,35 @@ void WheeledVehicle::SetHandbrake(float value)
_handBrake = Math::Saturate(value);
}
void WheeledVehicle::SetTankLeftThrottle(float value)
{
_tankLeftThrottle = Math::Clamp(value, -1.0f, 1.0f);
}
void WheeledVehicle::SetTankRightThrottle(float value)
{
_tankRightThrottle = Math::Clamp(value, -1.0f, 1.0f);
}
void WheeledVehicle::SetTankLeftBrake(float value)
{
_tankLeftBrake = Math::Saturate(value);
}
void WheeledVehicle::SetTankRightBrake(float value)
{
_tankRightBrake = Math::Saturate(value);
}
void WheeledVehicle::ClearInput()
{
_throttle = 0;
_steering = 0;
_brake = 0;
_tankLeftThrottle = 0;
_tankRightThrottle = 0;
_tankLeftBrake = 0;
_tankRightBrake = 0;
_handBrake = 0;
}
@@ -200,12 +234,12 @@ void WheeledVehicle::SetTargetGear(int32 value)
#endif
}
void WheeledVehicle::GetWheelState(int32 index, WheelState& result)
void WheeledVehicle::GetWheelState(int32 index, WheelState &result)
{
if (index >= 0 && index < _wheels.Count())
{
const auto collider = _wheels[index].Collider.Get();
for (auto& wheelData : _wheelsData)
for (auto &wheelData : _wheelsData)
{
if (wheelData.Collider == collider)
{
@@ -223,7 +257,7 @@ void WheeledVehicle::Setup()
return;
// Release previous
void* scene = GetPhysicsScene()->GetPhysicsScene();
void *scene = GetPhysicsScene()->GetPhysicsScene();
if (_vehicle)
{
PhysicsBackend::RemoveVehicle(scene, this);
@@ -246,10 +280,10 @@ void WheeledVehicle::Setup()
#if USE_EDITOR
void WheeledVehicle::DrawPhysicsDebug(RenderView& view)
void WheeledVehicle::DrawPhysicsDebug(RenderView &view)
{
// Wheels shapes
for (const auto& data : _wheelsData)
for (const auto &data : _wheelsData)
{
int32 wheelIndex = 0;
for (; wheelIndex < _wheels.Count(); wheelIndex++)
@@ -259,7 +293,7 @@ void WheeledVehicle::DrawPhysicsDebug(RenderView& view)
}
if (wheelIndex == _wheels.Count())
break;
const auto& wheel = _wheels[wheelIndex];
const auto &wheel = _wheels[wheelIndex];
if (wheel.Collider && wheel.Collider->GetParent() == this && !wheel.Collider->GetIsTrigger())
{
const Vector3 currentPos = wheel.Collider->GetPosition();
@@ -280,7 +314,7 @@ void WheeledVehicle::DrawPhysicsDebug(RenderView& view)
void WheeledVehicle::OnDebugDrawSelected()
{
// Wheels shapes
for (const auto& data : _wheelsData)
for (const auto &data : _wheelsData)
{
int32 wheelIndex = 0;
for (; wheelIndex < _wheels.Count(); wheelIndex++)
@@ -290,7 +324,7 @@ void WheeledVehicle::OnDebugDrawSelected()
}
if (wheelIndex == _wheels.Count())
break;
const auto& wheel = _wheels[wheelIndex];
const auto &wheel = _wheels[wheelIndex];
if (wheel.Collider && wheel.Collider->GetParent() == this && !wheel.Collider->GetIsTrigger())
{
const Vector3 currentPos = wheel.Collider->GetPosition();
@@ -314,6 +348,14 @@ void WheeledVehicle::OnDebugDrawSelected()
DEBUG_DRAW_WIRE_SPHERE(BoundingSphere(data.State.TireContactPoint, 5.0f), Color::Green, 0, false);
}
}
// Draw wheels axes
if (wheelIndex % 2 == 0 && wheelIndex + 1 < _wheels.Count())
{
const Vector3 wheelPos = _wheels[wheelIndex].Collider->GetPosition();
const Vector3 nextWheelPos = _wheels[wheelIndex + 1].Collider->GetPosition();
DEBUG_DRAW_LINE(wheelPos, nextWheelPos, Color::Yellow, 0, false);
}
}
// Center of mass
@@ -324,13 +366,14 @@ void WheeledVehicle::OnDebugDrawSelected()
#endif
void WheeledVehicle::Serialize(SerializeStream& stream, const void* otherObj)
void WheeledVehicle::Serialize(SerializeStream &stream, const void *otherObj)
{
RigidBody::Serialize(stream, otherObj);
SERIALIZE_GET_OTHER_OBJ(WheeledVehicle);
SERIALIZE_MEMBER(DriveType, _driveType);
SERIALIZE_MEMBER(DriveModes, _driveMode);
SERIALIZE_MEMBER(Wheels, _wheels);
SERIALIZE(UseReverseAsBrake);
SERIALIZE(UseAnalogSteering);
@@ -339,11 +382,12 @@ void WheeledVehicle::Serialize(SerializeStream& stream, const void* otherObj)
SERIALIZE_MEMBER(Gearbox, _gearbox);
}
void WheeledVehicle::Deserialize(DeserializeStream& stream, ISerializeModifier* modifier)
void WheeledVehicle::Deserialize(DeserializeStream &stream, ISerializeModifier *modifier)
{
RigidBody::Deserialize(stream, modifier);
DESERIALIZE_MEMBER(DriveType, _driveType);
DESERIALIZE_MEMBER(DriveModes, _driveMode);
DESERIALIZE_MEMBER(Wheels, _wheels);
DESERIALIZE(UseReverseAsBrake);
DESERIALIZE(UseAnalogSteering);
@@ -355,7 +399,7 @@ void WheeledVehicle::Deserialize(DeserializeStream& stream, ISerializeModifier*
_fixInvalidForwardDir |= modifier->EngineBuild < 6341;
}
void WheeledVehicle::OnColliderChanged(Collider* c)
void WheeledVehicle::OnColliderChanged(Collider *c)
{
RigidBody::OnColliderChanged(c);
@@ -378,7 +422,7 @@ void WheeledVehicle::OnActiveInTreeChanged()
Setup();
}
void WheeledVehicle::OnPhysicsSceneChanged(PhysicsScene* previous)
void WheeledVehicle::OnPhysicsSceneChanged(PhysicsScene *previous)
{
RigidBody::OnPhysicsSceneChanged(previous);
@@ -401,9 +445,10 @@ void WheeledVehicle::OnTransformChanged()
// Transform all vehicle children around the vehicle origin to fix the vehicle facing direction
const Quaternion rotationDelta(0.0f, -0.7071068f, 0.0f, 0.7071068f);
const Vector3 origin = GetPosition();
for (Actor* child : Children)
for (Actor *child : Children)
{
Transform trans = child->GetTransform();;
Transform trans = child->GetTransform();
;
const Vector3 pivotOffset = trans.Translation - origin;
if (pivotOffset.IsZero())
{
@@ -423,7 +468,7 @@ void WheeledVehicle::OnTransformChanged()
}
}
void WheeledVehicle::BeginPlay(SceneBeginData* data)
void WheeledVehicle::BeginPlay(SceneBeginData *data)
{
RigidBody::BeginPlay(data);
+60 -6
View File
@@ -26,6 +26,18 @@ API_CLASS(Attributes="ActorContextMenu(\"New/Physics/Wheeled Vehicle\"), ActorTo
DriveNW,
// Non-drivable vehicle.
NoDrive,
Tank,
};
/// <summary>
/// Vehicle driving types.
/// Used only on tanks to specify the drive mode.
/// </summary>
API_ENUM() enum class DriveModes
{
// Drive turning the vehicle using only one track
Standard,
// Drive turning the vehicle using all tracks inverse direction.
Special
};
/// <summary>
@@ -128,6 +140,11 @@ API_CLASS(Attributes="ActorContextMenu(\"New/Physics/Wheeled Vehicle\"), ActorTo
/// </summary>
API_FIELD() bool AutoGear = true;
/// <summary>
/// Number of gears to move to forward
/// </summary>
API_FIELD(Attributes = "Limit(1, 30)") int ForwardGearsRatios = 5;
/// <summary>
/// Time it takes to switch gear. Specified in seconds (s).
/// </summary>
@@ -322,8 +339,9 @@ private:
void* _vehicle = nullptr;
DriveTypes _driveType = DriveTypes::Drive4W, _driveTypeCurrent;
DriveModes _driveMode = DriveModes::Standard;
Array<WheelData, FixedAllocation<20>> _wheelsData;
float _throttle = 0.0f, _steering = 0.0f, _brake = 0.0f, _handBrake = 0.0f;
float _throttle = 0.0f, _steering = 0.0f, _brake = 0.0f, _handBrake = 0.0f, _tankLeftThrottle, _tankRightThrottle, _tankLeftBrake, _tankRightBrake;
Array<Wheel> _wheels;
EngineSettings _engine;
DifferentialSettings _differential;
@@ -347,17 +365,27 @@ public:
/// <summary>
/// Gets the vehicle driving model type.
/// </summary>
API_PROPERTY(Attributes="EditorOrder(1), EditorDisplay(\"Vehicle\")") DriveTypes GetDriveType() const;
API_PROPERTY(Attributes="EditorOrder(2), EditorDisplay(\"Vehicle\")") DriveTypes GetDriveType() const;
/// <summary>
/// Sets the vehicle driving model type.
/// </summary>
API_PROPERTY() void SetDriveType(DriveTypes value);
/// <summary>
/// Used only for tanks, set the drive mode.
/// </summary>
API_PROPERTY() void SetDriveMode(DriveModes value);
/// <summary>
/// Gets the vehicle driving mode. Used only on tanks
/// </summary>
API_PROPERTY(Attributes="EditorOrder(3), EditorDisplay(\"Vehicle\")") DriveModes GetDriveMode() const;
/// <summary>
/// Gets the vehicle wheels settings.
/// </summary>
API_PROPERTY(Attributes="EditorOrder(2), EditorDisplay(\"Vehicle\")") const Array<Wheel>& GetWheels() const;
API_PROPERTY(Attributes="EditorOrder(4), EditorDisplay(\"Vehicle\")") const Array<Wheel>& GetWheels() const;
/// <summary>
/// Sets the vehicle wheels settings.
@@ -367,7 +395,7 @@ public:
/// <summary>
/// Gets the vehicle engine settings.
/// </summary>
API_PROPERTY(Attributes="EditorOrder(3), EditorDisplay(\"Vehicle\")") EngineSettings GetEngine() const;
API_PROPERTY(Attributes="EditorOrder(5), EditorDisplay(\"Vehicle\")") EngineSettings GetEngine() const;
/// <summary>
/// Sets the vehicle engine settings.
@@ -377,7 +405,7 @@ public:
/// <summary>
/// Gets the vehicle differential settings.
/// </summary>
API_PROPERTY(Attributes="EditorOrder(4), EditorDisplay(\"Vehicle\")") DifferentialSettings GetDifferential() const;
API_PROPERTY(Attributes="EditorOrder(6), EditorDisplay(\"Vehicle\")") DifferentialSettings GetDifferential() const;
/// <summary>
/// Sets the vehicle differential settings.
@@ -387,7 +415,7 @@ public:
/// <summary>
/// Gets the vehicle gearbox settings.
/// </summary>
API_PROPERTY(Attributes="EditorOrder(5), EditorDisplay(\"Vehicle\")") GearboxSettings GetGearbox() const;
API_PROPERTY(Attributes="EditorOrder(7), EditorDisplay(\"Vehicle\")") GearboxSettings GetGearbox() const;
/// <summary>
/// Sets the vehicle gearbox settings.
@@ -419,6 +447,32 @@ public:
/// <param name="value">The value (0,1 range).</param>
API_FUNCTION() void SetHandbrake(float value);
/// <summary>
/// Sets the input for tank left track throttle. It is the analog accelerator pedal value in range (-1,1) where 1 represents the pedal fully pressed to move to forward, 0 to represents the
/// pedal in its rest state and -1 represents the pedal fully pressed to move to backward. The track direction will be inverted if the vehicle current gear is rear.
/// </summary>
/// <param name="value">The value (-1,1 range).</param>
API_FUNCTION() void SetTankLeftThrottle(float value);
/// <summary>
/// Sets the input for tank right track throttle. It is the analog accelerator pedal value in range (-1,1) where 1 represents the pedal fully pressed to move to forward, 0 to represents the
/// pedal in its rest state and -1 represents the pedal fully pressed to move to backward. The track direction will be inverted if the vehicle current gear is rear.
/// </summary>
/// <param name="value">The value (-1,1 range).</param>
API_FUNCTION() void SetTankRightThrottle(float value);
/// <summary>
/// Sets the input for tank brakes the left track. Brake is the analog brake pedal value in range (0,1) where 1 represents the pedal fully pressed and 0 represents the pedal in its rest state.
/// </summary>
/// <param name="value">The value (0,1 range).</param>
API_FUNCTION() void SetTankLeftBrake(float value);
/// <summary>
/// Sets the input for tank brakes the right track. Brake is the analog brake pedal value in range (0,1) where 1 represents the pedal fully pressed and 0 represents the pedal in its rest state.
/// </summary>
/// <param name="value">The value (0,1 range).</param>
API_FUNCTION() void SetTankRightBrake(float value);
/// <summary>
/// Clears all the vehicle control inputs to the default values (throttle, steering, breaks).
/// </summary>
@@ -37,6 +37,7 @@
#include <ThirdParty/PhysX/vehicle/PxVehicleNoDrive.h>
#include <ThirdParty/PhysX/vehicle/PxVehicleDrive4W.h>
#include <ThirdParty/PhysX/vehicle/PxVehicleDriveNW.h>
#include <ThirdParty/PhysX/vehicle/PxVehicleDriveTank.h>
#include <ThirdParty/PhysX/vehicle/PxVehicleUtilSetup.h>
#include <ThirdParty/PhysX/PxFiltering.h>
#endif
@@ -961,7 +962,6 @@ void PhysicalMaterial::UpdatePhysicsMaterial()
bool CollisionCooking::CookConvexMesh(CookingInput& input, BytesContainer& output)
{
PROFILE_CPU();
ENSURE_CAN_COOK;
if (input.VertexCount == 0)
LOG(Warning, "Empty mesh data for collision cooking.");
@@ -1005,7 +1005,6 @@ bool CollisionCooking::CookConvexMesh(CookingInput& input, BytesContainer& outpu
bool CollisionCooking::CookTriangleMesh(CookingInput& input, BytesContainer& output)
{
PROFILE_CPU();
ENSURE_CAN_COOK;
if (input.VertexCount == 0 || input.IndexCount == 0)
LOG(Warning, "Empty mesh data for collision cooking.");
@@ -1040,7 +1039,6 @@ bool CollisionCooking::CookTriangleMesh(CookingInput& input, BytesContainer& out
bool CollisionCooking::CookHeightField(int32 cols, int32 rows, const PhysicsBackend::HeightFieldSample* data, WriteStream& stream)
{
PROFILE_CPU();
ENSURE_CAN_COOK;
PxHeightFieldDesc heightFieldDesc;
@@ -1386,62 +1384,172 @@ void PhysicsBackend::EndSimulateScene(void* scene)
WheelVehiclesCache.Add(drive);
wheelsCount += drive->mWheelsSimData.getNbWheels();
const float deadZone = 0.1f;
bool isTank = wheelVehicle->_driveType == WheeledVehicle::DriveTypes::Tank;
float throttle = wheelVehicle->_throttle;
float steering = wheelVehicle->_steering;
float brake = wheelVehicle->_brake;
float leftThrottle = wheelVehicle->_tankLeftThrottle;
float rightThrottle = wheelVehicle->_tankRightThrottle;
float leftBrake = Math::Max(wheelVehicle->_tankLeftBrake, wheelVehicle->_handBrake);
float rightBrake = Math::Max(wheelVehicle->_tankRightBrake, wheelVehicle->_handBrake);
WheeledVehicle::DriveModes vehicleDriveMode = wheelVehicle->_driveMode;
if (isTank)
{
// Converting default vehicle controls to tank controls.
if (throttle != 0 || steering != 0)
{
leftThrottle = throttle + steering;
rightThrottle = throttle - steering;
}
}
// Converting special tank drive mode to standard tank mode when is turning.
if (isTank && vehicleDriveMode == WheeledVehicle::DriveModes::Standard)
{
// Special inputs when turning vehicle -1 1 to left or 1 -1 to turn right
// to:
// Standard inputs when turning vehicle 0 1 to left or 1 0 to turn right
if (leftThrottle < -deadZone && rightThrottle > deadZone)
{
leftThrottle = 0;
}
else if (leftThrottle > deadZone && rightThrottle < -deadZone)
{
rightThrottle = 0;
}
}
if (wheelVehicle->UseReverseAsBrake)
{
const float invalidDirectionThreshold = 80.0f;
const float breakThreshold = 8.0f;
const float forwardSpeed = wheelVehicle->GetForwardSpeed();
int currentGear = wheelVehicle->GetCurrentGear();
// Tank tracks direction: 1 forward -1 backward 0 neutral
bool toForward = false;
toForward |= throttle > deadZone;
toForward |= (leftThrottle > deadZone) && (rightThrottle > deadZone); // 1 1
bool toBackward = false;
toBackward |= throttle < -deadZone;
toBackward |= (leftThrottle < -deadZone) && (rightThrottle < -deadZone); // -1 -1
toBackward |= (leftThrottle < -deadZone) && (rightThrottle < deadZone); // -1 0
toBackward |= (leftThrottle < deadZone) && (rightThrottle < -deadZone); // 0 -1
bool isTankTurning = false;
if (isTank)
{
isTankTurning |= leftThrottle > deadZone && rightThrottle < -deadZone; // 1 -1
isTankTurning |= leftThrottle < -deadZone && rightThrottle > deadZone; // -1 1
isTankTurning |= leftThrottle < deadZone && rightThrottle > deadZone; // 0 1
isTankTurning |= leftThrottle > deadZone && rightThrottle < deadZone; // 1 0
isTankTurning |= leftThrottle < -deadZone && rightThrottle < deadZone; // -1 0
isTankTurning |= leftThrottle < deadZone && rightThrottle < -deadZone; // 0 -1
if (toForward || toBackward)
{
isTankTurning = false;
}
}
// Automatic gear change when changing driving direction
if (Math::Abs(forwardSpeed) < invalidDirectionThreshold)
{
if (throttle < -ZeroTolerance && wheelVehicle->GetCurrentGear() >= 0 && wheelVehicle->GetTargetGear() >= 0)
int targetGear = wheelVehicle->GetTargetGear();
if (toBackward && currentGear > 0 && targetGear >= 0)
{
wheelVehicle->SetCurrentGear(-1);
currentGear = -1;
}
else if (throttle > ZeroTolerance && wheelVehicle->GetCurrentGear() <= 0 && wheelVehicle->GetTargetGear() <= 0)
else if (!toBackward && currentGear <= 0 && targetGear <= 0)
{
wheelVehicle->SetCurrentGear(1);
currentGear = 1;
}
else if (isTankTurning && currentGear <= 0)
{
currentGear = 1;
}
if (wheelVehicle->GetCurrentGear() != currentGear)
{
wheelVehicle->SetCurrentGear(currentGear);
}
}
// Automatic break when changing driving direction
if (throttle > 0.0f)
if (toForward)
{
if (forwardSpeed < -invalidDirectionThreshold)
{
brake = 1.0f;
leftBrake = 1.0f;
rightBrake = 1.0f;
}
}
else if (throttle < 0.0f)
else if (toBackward)
{
if (forwardSpeed > invalidDirectionThreshold)
{
brake = 1.0f;
leftBrake = 1.0f;
rightBrake = 1.0f;
}
}
else
{
if (forwardSpeed < breakThreshold && forwardSpeed > -breakThreshold)
if (forwardSpeed < breakThreshold && forwardSpeed > -breakThreshold && !isTankTurning) // not accelerating, very slow speed -> stop
{
brake = 1.0f;
leftBrake = 1.0f;
rightBrake = 1.0f;
}
}
// Block throttle if user is changing driving direction
if ((throttle > 0.0f && wheelVehicle->GetTargetGear() < 0) || (throttle < 0.0f && wheelVehicle->GetTargetGear() > 0))
if ((toForward && currentGear < 0) || (toBackward && currentGear > 0))
{
throttle = 0.0f;
leftThrottle = 0;
rightThrottle = 0;
}
throttle = Math::Abs(throttle);
if (isTank)
{
// invert acceleration when moving to backward because tank inputs can be < 0
if (currentGear < 0)
{
float lt = -leftThrottle;
float rt = -rightThrottle;
float lb = leftBrake;
float rb = rightBrake;
leftThrottle = rt;
rightThrottle = lt;
leftBrake = rb;
rightBrake = lb;
}
}
}
else
{
throttle = Math::Max(throttle, 0.0f);
}
// Force brake the another side track to turn more faster.
if (Math::Abs(leftThrottle) > deadZone && Math::Abs(rightThrottle) < deadZone)
{
rightBrake = 1.0f;
}
if (Math::Abs(rightThrottle) > deadZone && Math::Abs(leftThrottle) < deadZone)
{
leftBrake = 1.0f;
}
// @formatter:off
// Reference: PhysX SDK docs
// TODO: expose input control smoothing data
@@ -1518,11 +1626,23 @@ void PhysicsBackend::EndSimulateScene(void* scene)
PxVehicleDriveNWSmoothAnalogRawInputsAndSetAnalogInputs(padSmoothing, steerVsForwardSpeed, rawInputData, scenePhysX->LastDeltaTime, false, *(PxVehicleDriveNW*)drive);
break;
}
case WheeledVehicle::DriveTypes::Tank:
{
PxVehicleDriveTankRawInputData driveMode = vehicleDriveMode == WheeledVehicle::DriveModes::Standard ? PxVehicleDriveTankControlModel::eSTANDARD : PxVehicleDriveTankControlModel::eSPECIAL;
PxVehicleDriveTankRawInputData rawInputData = PxVehicleDriveTankRawInputData(driveMode);
rawInputData.setAnalogAccel(Math::Max(Math::Abs(leftThrottle), Math::Abs(rightThrottle)));
rawInputData.setAnalogLeftBrake(leftBrake);
rawInputData.setAnalogRightBrake(rightBrake);
rawInputData.setAnalogLeftThrust(leftThrottle);
rawInputData.setAnalogRightThrust(rightThrottle);
PxVehicleDriveTankSmoothAnalogRawInputsAndSetAnalogInputs(padSmoothing, rawInputData, scenePhysX->LastDeltaTime, *(PxVehicleDriveTank*)drive);
break;
}
}
}
else
{
const float deadZone = 0.1f;
{
switch (wheelVehicle->_driveTypeCurrent)
{
case WheeledVehicle::DriveTypes::Drive4W:
@@ -1547,6 +1667,26 @@ void PhysicsBackend::EndSimulateScene(void* scene)
PxVehicleDriveNWSmoothDigitalRawInputsAndSetAnalogInputs(keySmoothing, steerVsForwardSpeed, rawInputData, scenePhysX->LastDeltaTime, false, *(PxVehicleDriveNW*)drive);
break;
}
case WheeledVehicle::DriveTypes::Tank:
{
// Convert analogic inputs to digital inputs.
leftThrottle = Math::Round(leftThrottle);
rightThrottle = Math::Round(rightThrottle);
leftBrake = Math::Round(leftBrake);
rightBrake = Math::Round(rightBrake);
PxVehicleDriveTankRawInputData driveMode = vehicleDriveMode == WheeledVehicle::DriveModes::Standard ? PxVehicleDriveTankControlModel::eSTANDARD : PxVehicleDriveTankControlModel::eSPECIAL;
PxVehicleDriveTankRawInputData rawInputData = PxVehicleDriveTankRawInputData(driveMode);
rawInputData.setAnalogAccel(Math::Max(Math::Abs(leftThrottle), Math::Abs(rightThrottle)));
rawInputData.setAnalogLeftBrake(leftBrake);
rawInputData.setAnalogRightBrake(rightBrake);
rawInputData.setAnalogLeftThrust(leftThrottle);
rawInputData.setAnalogRightThrust(rightThrottle);
// Needs to pass analogic values to vehicle to maintein current moviment direction because digital inputs accept only true/false values to tracks thrust instead of -1 to 1
PxVehicleDriveTankSmoothAnalogRawInputsAndSetAnalogInputs(padSmoothing, rawInputData, scenePhysX->LastDeltaTime, *(PxVehicleDriveTank *)drive);
break;
}
}
}
}
@@ -2803,7 +2943,7 @@ void PhysicsBackend::SetHingeJointLimit(void* joint, const LimitAngularRange& va
void PhysicsBackend::SetHingeJointDrive(void* joint, const HingeJointDrive& value)
{
auto jointPhysX = (PxRevoluteJoint*)joint;
jointPhysX->setDriveVelocity(value.Velocity);
jointPhysX->setDriveVelocity(Math::Max(value.Velocity, 0.0f));
jointPhysX->setDriveForceLimit(Math::Max(value.ForceLimit, 0.0f));
jointPhysX->setDriveGearRatio(Math::Max(value.GearRatio, 0.0f));
jointPhysX->setRevoluteJointFlag(PxRevoluteJointFlag::eDRIVE_FREESPIN, value.FreeSpin);
@@ -3086,6 +3226,147 @@ int32 PhysicsBackend::MoveController(void* controller, void* shape, const Vector
#if WITH_VEHICLE
PxVehicleDifferential4WData CreatePxVehicleDifferential4WData(const WheeledVehicle::DifferentialSettings& settings)
{
PxVehicleDifferential4WData differential4WData;
differential4WData.mType = (PxVehicleDifferential4WData::Enum)settings.Type;
differential4WData.mFrontRearSplit = settings.FrontRearSplit;
differential4WData.mFrontLeftRightSplit = settings.FrontLeftRightSplit;
differential4WData.mRearLeftRightSplit = settings.RearLeftRightSplit;
differential4WData.mCentreBias = settings.CentreBias;
differential4WData.mFrontBias = settings.FrontBias;
differential4WData.mRearBias = settings.RearBias;
return differential4WData;
}
PxVehicleDifferentialNWData CreatePxVehicleDifferentialNWData(const WheeledVehicle::DifferentialSettings& settings, const Array<WheeledVehicle::Wheel*, FixedAllocation<PX_MAX_NB_WHEELS>>& wheels)
{
PxVehicleDifferentialNWData differentialNwData;
for (int32 i = 0; i < wheels.Count(); i++)
differentialNwData.setDrivenWheel(i, true);
return differentialNwData;
}
PxVehicleEngineData CreatePxVehicleEngineData(const WheeledVehicle::EngineSettings& settings)
{
PxVehicleEngineData engineData;
engineData.mMOI = M2ToCm2(settings.MOI);
engineData.mPeakTorque = M2ToCm2(settings.MaxTorque);
engineData.mMaxOmega = RpmToRadPerS(settings.MaxRotationSpeed);
engineData.mDampingRateFullThrottle = M2ToCm2(0.15f);
engineData.mDampingRateZeroThrottleClutchEngaged = M2ToCm2(2.0f);
engineData.mDampingRateZeroThrottleClutchDisengaged = M2ToCm2(0.35f);
return engineData;
}
PxVehicleGearsData CreatePxVehicleGearsData(const WheeledVehicle::GearboxSettings& settings)
{
PxVehicleGearsData gears;
// Total gears is forward gears + neutral/rear gears
int gearsAmount = settings.ForwardGearsRatios + 2;
// Setup gears torque/top speed relations
// Higher torque = less speed
// Low torque = high speed
// Example:
// ForwardGearsRatios = 4
// GearRev = -5
// Gear0 = 0
// Gear1 = 4.2
// Gear2 = 3.4
// Gear3 = 2.6
// Gear4 = 1.8
// Gear5 = 1
gears.mRatios[0] = -(gearsAmount - 2); // reverse
gears.mRatios[1] = 0; // neutral
// Setup all gears except neutral and reverse
for (int i = gearsAmount; i > 2; i--) {
float gearsRatios = settings.ForwardGearsRatios;
float currentGear = i - 2;
gears.mRatios[i] = Math::Lerp(gearsRatios, 1.0f, (currentGear / gearsRatios));
}
// reset unused gears
for (int i = gearsAmount; i < PxVehicleGearsData::eGEARSRATIO_COUNT; i++)
gears.mRatios[i] = 0;
gears.mSwitchTime = Math::Max(settings.SwitchTime, 0.0f);
gears.mNbRatios = Math::Clamp(gearsAmount, 2, (int)PxVehicleGearsData::eGEARSRATIO_COUNT);
return gears;
}
PxVehicleAutoBoxData CreatePxVehicleAutoBoxData()
{
return PxVehicleAutoBoxData();
}
PxVehicleClutchData CreatePxVehicleClutchData(const WheeledVehicle::GearboxSettings& settings)
{
PxVehicleClutchData clutch;
clutch.mStrength = M2ToCm2(settings.ClutchStrength);
return clutch;
}
PxVehicleSuspensionData CreatePxVehicleSuspensionData(const WheeledVehicle::Wheel& settings, const PxReal wheelSprungMass)
{
PxVehicleSuspensionData suspensionData;
const float suspensionFrequency = 7.0f;
suspensionData.mMaxCompression = settings.SuspensionMaxRaise;
suspensionData.mMaxDroop = settings.SuspensionMaxDrop;
suspensionData.mSprungMass = wheelSprungMass;
suspensionData.mSpringStrength = Math::Square(suspensionFrequency) * suspensionData.mSprungMass;
suspensionData.mSpringDamperRate = settings.SuspensionDampingRate * 2.0f * Math::Sqrt(suspensionData.mSpringStrength * suspensionData.mSprungMass);
return suspensionData;
}
PxVehicleTireData CreatePxVehicleTireData(const WheeledVehicle::Wheel& settings)
{
PxVehicleTireData tire;
int32 tireIndex = WheelTireTypes.Find(settings.TireFrictionScale);
if (tireIndex == -1)
{
// New tire type
tireIndex = WheelTireTypes.Count();
WheelTireTypes.Add(settings.TireFrictionScale);
WheelTireFrictionsDirty = true;
}
tire.mType = tireIndex;
tire.mLatStiffX = settings.TireLateralMax;
tire.mLatStiffY = settings.TireLateralStiffness;
tire.mLongitudinalStiffnessPerUnitGravity = settings.TireLongitudinalStiffness;
return tire;
}
PxVehicleWheelData CreatePxVehicleWheelData(const WheeledVehicle::Wheel& settings)
{
PxVehicleWheelData wheelData;
wheelData.mMass = settings.Mass;
wheelData.mRadius = settings.Radius;
wheelData.mWidth = settings.Width;
wheelData.mMOI = 0.5f * wheelData.mMass * Math::Square(wheelData.mRadius);
wheelData.mDampingRate = M2ToCm2(settings.DampingRate);
wheelData.mMaxSteer = settings.MaxSteerAngle * DegreesToRadians;
wheelData.mMaxBrakeTorque = M2ToCm2(settings.MaxBrakeTorque);
wheelData.mMaxHandBrakeTorque = M2ToCm2(settings.MaxHandBrakeTorque);
return wheelData;
}
PxVehicleAckermannGeometryData CreatePxVehicleAckermannGeometryData(PxVehicleWheelsSimData* wheelsSimData)
{
PxVehicleAckermannGeometryData ackermann;
ackermann.mAxleSeparation = Math::Abs(wheelsSimData->getWheelCentreOffset(PxVehicleDrive4WWheelOrder::eFRONT_LEFT).z - wheelsSimData->getWheelCentreOffset(PxVehicleDrive4WWheelOrder::eREAR_LEFT).z);
ackermann.mFrontWidth = Math::Abs(wheelsSimData->getWheelCentreOffset(PxVehicleDrive4WWheelOrder::eFRONT_RIGHT).x - wheelsSimData->getWheelCentreOffset(PxVehicleDrive4WWheelOrder::eFRONT_LEFT).x);
ackermann.mRearWidth = Math::Abs(wheelsSimData->getWheelCentreOffset(PxVehicleDrive4WWheelOrder::eREAR_RIGHT).x - wheelsSimData->getWheelCentreOffset(PxVehicleDrive4WWheelOrder::eREAR_LEFT).x);
return ackermann;
}
bool SortWheels(WheeledVehicle::Wheel const& a, WheeledVehicle::Wheel const& b)
{
return (int32)a.Type < (int32)b.Type;
@@ -3158,42 +3439,14 @@ void* PhysicsBackend::CreateVehicle(WheeledVehicle* actor)
data.Collider = wheel.Collider;
data.LocalOrientation = wheel.Collider->GetLocalOrientation();
PxVehicleSuspensionData suspensionData;
const float suspensionFrequency = 7.0f;
suspensionData.mMaxCompression = wheel.SuspensionMaxRaise;
suspensionData.mMaxDroop = wheel.SuspensionMaxDrop;
suspensionData.mSprungMass = sprungMasses[i];
suspensionData.mSpringStrength = Math::Square(suspensionFrequency) * suspensionData.mSprungMass;
suspensionData.mSpringDamperRate = wheel.SuspensionDampingRate * 2.0f * Math::Sqrt(suspensionData.mSpringStrength * suspensionData.mSprungMass);
PxVehicleTireData tire;
int32 tireIndex = WheelTireTypes.Find(wheel.TireFrictionScale);
if (tireIndex == -1)
{
// New tire type
tireIndex = WheelTireTypes.Count();
WheelTireTypes.Add(wheel.TireFrictionScale);
WheelTireFrictionsDirty = true;
}
tire.mType = tireIndex;
tire.mLatStiffX = wheel.TireLateralMax;
tire.mLatStiffY = wheel.TireLateralStiffness;
tire.mLongitudinalStiffnessPerUnitGravity = wheel.TireLongitudinalStiffness;
PxVehicleWheelData wheelData;
wheelData.mMass = wheel.Mass;
wheelData.mRadius = wheel.Radius;
wheelData.mWidth = wheel.Width;
wheelData.mMOI = 0.5f * wheelData.mMass * Math::Square(wheelData.mRadius);
wheelData.mDampingRate = M2ToCm2(wheel.DampingRate);
wheelData.mMaxSteer = wheel.MaxSteerAngle * DegreesToRadians;
wheelData.mMaxBrakeTorque = M2ToCm2(wheel.MaxBrakeTorque);
wheelData.mMaxHandBrakeTorque = M2ToCm2(wheel.MaxHandBrakeTorque);
PxVec3 centreOffset = centerOfMassOffset.transformInv(offsets[i]);
PxVec3 forceAppPointOffset(centreOffset.x, wheel.SuspensionForceOffset, centreOffset.z);
wheelsSimData->setTireData(i, tire);
const PxVehicleTireData& tireData = CreatePxVehicleTireData(wheel);
const PxVehicleWheelData& wheelData = CreatePxVehicleWheelData(wheel);
const PxVehicleSuspensionData& suspensionData = CreatePxVehicleSuspensionData(wheel, sprungMasses[i]);
wheelsSimData->setTireData(i,tireData);
wheelsSimData->setWheelData(i, wheelData);
wheelsSimData->setSuspensionData(i, suspensionData);
wheelsSimData->setSuspTravelDirection(i, centerOfMassOffset.rotate(PxVec3(0.0f, -1.0f, 0.0f)));
@@ -3260,48 +3513,19 @@ void* PhysicsBackend::CreateVehicle(WheeledVehicle* actor)
case WheeledVehicle::DriveTypes::Drive4W:
{
PxVehicleDriveSimData4W driveSimData;
const PxVehicleDifferential4WData& differentialData = CreatePxVehicleDifferential4WData(differential);
const PxVehicleEngineData& engineData = CreatePxVehicleEngineData(engine);
const PxVehicleGearsData& gearsData = CreatePxVehicleGearsData(gearbox);
const PxVehicleAutoBoxData& autoBoxData = CreatePxVehicleAutoBoxData();
const PxVehicleClutchData& cluchData = CreatePxVehicleClutchData(gearbox);
const PxVehicleAckermannGeometryData& geometryData = CreatePxVehicleAckermannGeometryData(wheelsSimData);
// Differential
PxVehicleDifferential4WData differential4WData;
differential4WData.mType = (PxVehicleDifferential4WData::Enum)differential.Type;
differential4WData.mFrontRearSplit = differential.FrontRearSplit;
differential4WData.mFrontLeftRightSplit = differential.FrontLeftRightSplit;
differential4WData.mRearLeftRightSplit = differential.RearLeftRightSplit;
differential4WData.mCentreBias = differential.CentreBias;
differential4WData.mFrontBias = differential.FrontBias;
differential4WData.mRearBias = differential.RearBias;
driveSimData.setDiffData(differential4WData);
// Engine
PxVehicleEngineData engineData;
engineData.mMOI = M2ToCm2(engine.MOI);
engineData.mPeakTorque = M2ToCm2(engine.MaxTorque);
engineData.mMaxOmega = RpmToRadPerS(engine.MaxRotationSpeed);
engineData.mDampingRateFullThrottle = M2ToCm2(0.15f);
engineData.mDampingRateZeroThrottleClutchEngaged = M2ToCm2(2.0f);
engineData.mDampingRateZeroThrottleClutchDisengaged = M2ToCm2(0.35f);
driveSimData.setDiffData(differentialData);
driveSimData.setEngineData(engineData);
// Gears
PxVehicleGearsData gears;
gears.mSwitchTime = Math::Max(gearbox.SwitchTime, 0.0f);
driveSimData.setGearsData(gears);
// Auto Box
PxVehicleAutoBoxData autoBox;
driveSimData.setAutoBoxData(autoBox);
// Clutch
PxVehicleClutchData clutch;
clutch.mStrength = M2ToCm2(gearbox.ClutchStrength);
driveSimData.setClutchData(clutch);
// Ackermann steer accuracy
PxVehicleAckermannGeometryData ackermann;
ackermann.mAxleSeparation = Math::Abs(wheelsSimData->getWheelCentreOffset(PxVehicleDrive4WWheelOrder::eFRONT_LEFT).z - wheelsSimData->getWheelCentreOffset(PxVehicleDrive4WWheelOrder::eREAR_LEFT).z);
ackermann.mFrontWidth = Math::Abs(wheelsSimData->getWheelCentreOffset(PxVehicleDrive4WWheelOrder::eFRONT_RIGHT).x - wheelsSimData->getWheelCentreOffset(PxVehicleDrive4WWheelOrder::eFRONT_LEFT).x);
ackermann.mRearWidth = Math::Abs(wheelsSimData->getWheelCentreOffset(PxVehicleDrive4WWheelOrder::eREAR_RIGHT).x - wheelsSimData->getWheelCentreOffset(PxVehicleDrive4WWheelOrder::eREAR_LEFT).x);
driveSimData.setAckermannGeometryData(ackermann);
driveSimData.setGearsData(gearsData);
driveSimData.setAutoBoxData(autoBoxData);
driveSimData.setClutchData(cluchData);
driveSimData.setAckermannGeometryData(geometryData);
// Create vehicle drive
auto drive4W = PxVehicleDrive4W::allocate(wheels.Count());
@@ -3315,36 +3539,18 @@ void* PhysicsBackend::CreateVehicle(WheeledVehicle* actor)
case WheeledVehicle::DriveTypes::DriveNW:
{
PxVehicleDriveSimDataNW driveSimData;
const PxVehicleDifferentialNWData& differentialData = CreatePxVehicleDifferentialNWData(differential, wheels);
const PxVehicleEngineData& engineData = CreatePxVehicleEngineData(engine);
const PxVehicleGearsData& gearsData = CreatePxVehicleGearsData(gearbox);
const PxVehicleAutoBoxData& autoBoxData = CreatePxVehicleAutoBoxData();
const PxVehicleClutchData& cluchData = CreatePxVehicleClutchData(gearbox);
const PxVehicleAckermannGeometryData& geometryData = CreatePxVehicleAckermannGeometryData(wheelsSimData);
// Differential
PxVehicleDifferentialNWData differentialNwData;
for (int32 i = 0; i < wheels.Count(); i++)
differentialNwData.setDrivenWheel(i, true);
driveSimData.setDiffData(differentialNwData);
// Engine
PxVehicleEngineData engineData;
engineData.mMOI = M2ToCm2(engine.MOI);
engineData.mPeakTorque = M2ToCm2(engine.MaxTorque);
engineData.mMaxOmega = RpmToRadPerS(engine.MaxRotationSpeed);
engineData.mDampingRateFullThrottle = M2ToCm2(0.15f);
engineData.mDampingRateZeroThrottleClutchEngaged = M2ToCm2(2.0f);
engineData.mDampingRateZeroThrottleClutchDisengaged = M2ToCm2(0.35f);
driveSimData.setDiffData(differentialData);
driveSimData.setEngineData(engineData);
// Gears
PxVehicleGearsData gears;
gears.mSwitchTime = Math::Max(gearbox.SwitchTime, 0.0f);
driveSimData.setGearsData(gears);
// Auto Box
PxVehicleAutoBoxData autoBox;
driveSimData.setAutoBoxData(autoBox);
// Clutch
PxVehicleClutchData clutch;
clutch.mStrength = M2ToCm2(gearbox.ClutchStrength);
driveSimData.setClutchData(clutch);
driveSimData.setGearsData(gearsData);
driveSimData.setAutoBoxData(autoBoxData);
driveSimData.setClutchData(cluchData);
// Create vehicle drive
auto driveNW = PxVehicleDriveNW::allocate(wheels.Count());
@@ -3364,6 +3570,32 @@ void* PhysicsBackend::CreateVehicle(WheeledVehicle* actor)
vehicle = driveNo;
break;
}
case WheeledVehicle::DriveTypes::Tank:
{
PxVehicleDriveSimData4W driveSimData;
const PxVehicleDifferential4WData &differentialData = CreatePxVehicleDifferential4WData(differential);
const PxVehicleEngineData &engineData = CreatePxVehicleEngineData(engine);
const PxVehicleGearsData &gearsData = CreatePxVehicleGearsData(gearbox);
const PxVehicleAutoBoxData &autoBoxData = CreatePxVehicleAutoBoxData();
const PxVehicleClutchData &cluchData = CreatePxVehicleClutchData(gearbox);
const PxVehicleAckermannGeometryData &geometryData = CreatePxVehicleAckermannGeometryData(wheelsSimData);
driveSimData.setDiffData(differentialData);
driveSimData.setEngineData(engineData);
driveSimData.setGearsData(gearsData);
driveSimData.setAutoBoxData(autoBoxData);
driveSimData.setClutchData(cluchData);
driveSimData.setAckermannGeometryData(geometryData);
// Create vehicle drive
auto driveTank = PxVehicleDriveTank::allocate(wheels.Count());
driveTank->setup(PhysX, actorPhysX, *wheelsSimData, driveSimData, wheels.Count());
driveTank->setToRestState();
driveTank->mDriveDynData.forceGearChange(PxVehicleGearsData::eFIRST);
driveTank->mDriveDynData.setUseAutoGears(gearbox.AutoGear);
vehicle = driveTank;
break;
}
default:
CRASH;
}
@@ -3385,6 +3617,9 @@ void PhysicsBackend::DestroyVehicle(void* vehicle, int32 driveType)
case WheeledVehicle::DriveTypes::NoDrive:
((PxVehicleNoDrive*)vehicle)->free();
break;
case WheeledVehicle::DriveTypes::Tank:
((PxVehicleDriveTank*)vehicle)->free();
break;
}
}
@@ -3395,42 +3630,11 @@ void PhysicsBackend::UpdateVehicleWheels(WheeledVehicle* actor)
for (uint32 i = 0; i < wheelsSimData->getNbWheels(); i++)
{
auto& wheel = actor->_wheels[i];
// Update suspension data
PxVehicleSuspensionData suspensionData = wheelsSimData->getSuspensionData(i);
const float suspensionFrequency = 7.0f;
suspensionData.mMaxCompression = wheel.SuspensionMaxRaise;
suspensionData.mMaxDroop = wheel.SuspensionMaxDrop;
suspensionData.mSpringStrength = Math::Square(suspensionFrequency) * suspensionData.mSprungMass;
suspensionData.mSpringDamperRate = wheel.SuspensionDampingRate * 2.0f * Math::Sqrt(suspensionData.mSpringStrength * suspensionData.mSprungMass);
const PxVehicleSuspensionData& suspensionData = CreatePxVehicleSuspensionData(wheel, wheelsSimData->getSuspensionData(i).mSprungMass);
const PxVehicleTireData& tireData = CreatePxVehicleTireData(wheel);
const PxVehicleWheelData& wheelData = CreatePxVehicleWheelData(wheel);
wheelsSimData->setSuspensionData(i, suspensionData);
// Update tire data
PxVehicleTireData tire;
int32 tireIndex = WheelTireTypes.Find(wheel.TireFrictionScale);
if (tireIndex == -1)
{
// New tire type
tireIndex = WheelTireTypes.Count();
WheelTireTypes.Add(wheel.TireFrictionScale);
WheelTireFrictionsDirty = true;
}
tire.mType = tireIndex;
tire.mLatStiffX = wheel.TireLateralMax;
tire.mLatStiffY = wheel.TireLateralStiffness;
tire.mLongitudinalStiffnessPerUnitGravity = wheel.TireLongitudinalStiffness;
wheelsSimData->setTireData(i, tire);
// Update wheel data
PxVehicleWheelData wheelData;
wheelData.mMass = wheel.Mass;
wheelData.mRadius = wheel.Radius;
wheelData.mWidth = wheel.Width;
wheelData.mMOI = 0.5f * wheelData.mMass * Math::Square(wheelData.mRadius);
wheelData.mDampingRate = M2ToCm2(wheel.DampingRate);
wheelData.mMaxSteer = wheel.MaxSteerAngle * DegreesToRadians;
wheelData.mMaxBrakeTorque = M2ToCm2(wheel.MaxBrakeTorque);
wheelData.mMaxHandBrakeTorque = M2ToCm2(wheel.MaxHandBrakeTorque);
wheelsSimData->setTireData(i, tireData);
wheelsSimData->setWheelData(i, wheelData);
}
}
@@ -3444,28 +3648,24 @@ void PhysicsBackend::SetVehicleEngine(void* vehicle, const void* value)
case PxVehicleTypes::eDRIVE4W:
{
auto drive4W = (PxVehicleDrive4W*)drive;
const PxVehicleEngineData& engineData = CreatePxVehicleEngineData(engine);
PxVehicleDriveSimData4W& driveSimData = drive4W->mDriveSimData;
PxVehicleEngineData engineData;
engineData.mMOI = M2ToCm2(engine.MOI);
engineData.mPeakTorque = M2ToCm2(engine.MaxTorque);
engineData.mMaxOmega = RpmToRadPerS(engine.MaxRotationSpeed);
engineData.mDampingRateFullThrottle = M2ToCm2(0.15f);
engineData.mDampingRateZeroThrottleClutchEngaged = M2ToCm2(2.0f);
engineData.mDampingRateZeroThrottleClutchDisengaged = M2ToCm2(0.35f);
driveSimData.setEngineData(engineData);
break;
}
case PxVehicleTypes::eDRIVENW:
{
auto drive4W = (PxVehicleDriveNW*)drive;
const PxVehicleEngineData& engineData = CreatePxVehicleEngineData(engine);
PxVehicleDriveSimDataNW& driveSimData = drive4W->mDriveSimData;
PxVehicleEngineData engineData;
engineData.mMOI = M2ToCm2(engine.MOI);
engineData.mPeakTorque = M2ToCm2(engine.MaxTorque);
engineData.mMaxOmega = RpmToRadPerS(engine.MaxRotationSpeed);
engineData.mDampingRateFullThrottle = M2ToCm2(0.15f);
engineData.mDampingRateZeroThrottleClutchEngaged = M2ToCm2(2.0f);
engineData.mDampingRateZeroThrottleClutchDisengaged = M2ToCm2(0.35f);
driveSimData.setEngineData(engineData);
break;
}
case PxVehicleTypes::eDRIVETANK:
{
auto driveTank = (PxVehicleDriveTank*)drive;
const PxVehicleEngineData &engineData = CreatePxVehicleEngineData(engine);
PxVehicleDriveSimData &driveSimData = driveTank->mDriveSimData;
driveSimData.setEngineData(engineData);
break;
}
@@ -3481,16 +3681,9 @@ void PhysicsBackend::SetVehicleDifferential(void* vehicle, const void* value)
case PxVehicleTypes::eDRIVE4W:
{
auto drive4W = (PxVehicleDrive4W*)drive;
const PxVehicleDifferential4WData& differentialData = CreatePxVehicleDifferential4WData(differential);
PxVehicleDriveSimData4W& driveSimData = drive4W->mDriveSimData;
PxVehicleDifferential4WData differential4WData;
differential4WData.mType = (PxVehicleDifferential4WData::Enum)differential.Type;
differential4WData.mFrontRearSplit = differential.FrontRearSplit;
differential4WData.mFrontLeftRightSplit = differential.FrontLeftRightSplit;
differential4WData.mRearLeftRightSplit = differential.RearLeftRightSplit;
differential4WData.mCentreBias = differential.CentreBias;
differential4WData.mFrontBias = differential.FrontBias;
differential4WData.mRearBias = differential.RearBias;
driveSimData.setDiffData(differential4WData);
driveSimData.setDiffData(differentialData);
break;
}
}
@@ -3507,41 +3700,37 @@ void PhysicsBackend::SetVehicleGearbox(void* vehicle, const void* value)
case PxVehicleTypes::eDRIVE4W:
{
auto drive4W = (PxVehicleDrive4W*)drive;
const PxVehicleGearsData& gearData = CreatePxVehicleGearsData(gearbox);
const PxVehicleClutchData& clutchData = CreatePxVehicleClutchData(gearbox);
const PxVehicleAutoBoxData& autoBoxData = CreatePxVehicleAutoBoxData();
PxVehicleDriveSimData4W& driveSimData = drive4W->mDriveSimData;
// Gears
PxVehicleGearsData gears;
gears.mSwitchTime = Math::Max(gearbox.SwitchTime, 0.0f);
driveSimData.setGearsData(gears);
// Auto Box
PxVehicleAutoBoxData autoBox;
driveSimData.setAutoBoxData(autoBox);
// Clutch
PxVehicleClutchData clutch;
clutch.mStrength = M2ToCm2(gearbox.ClutchStrength);
driveSimData.setClutchData(clutch);
driveSimData.setGearsData(gearData);
driveSimData.setAutoBoxData(autoBoxData);
driveSimData.setClutchData(clutchData);
break;
}
case PxVehicleTypes::eDRIVENW:
{
auto drive4W = (PxVehicleDriveNW*)drive;
const PxVehicleGearsData& gearData = CreatePxVehicleGearsData(gearbox);
const PxVehicleClutchData& clutchData = CreatePxVehicleClutchData(gearbox);
const PxVehicleAutoBoxData& autoBoxData = CreatePxVehicleAutoBoxData();
PxVehicleDriveSimDataNW& driveSimData = drive4W->mDriveSimData;
// Gears
PxVehicleGearsData gears;
gears.mSwitchTime = Math::Max(gearbox.SwitchTime, 0.0f);
driveSimData.setGearsData(gears);
// Auto Box
PxVehicleAutoBoxData autoBox;
driveSimData.setAutoBoxData(autoBox);
// Clutch
PxVehicleClutchData clutch;
clutch.mStrength = M2ToCm2(gearbox.ClutchStrength);
driveSimData.setClutchData(clutch);
driveSimData.setGearsData(gearData);
driveSimData.setAutoBoxData(autoBoxData);
driveSimData.setClutchData(clutchData);
break;
}
case PxVehicleTypes::eDRIVETANK:
{
auto driveTank = (PxVehicleDriveTank *)drive;
const PxVehicleGearsData &gearData = CreatePxVehicleGearsData(gearbox);
const PxVehicleClutchData &clutchData = CreatePxVehicleClutchData(gearbox);
const PxVehicleAutoBoxData &autoBoxData = CreatePxVehicleAutoBoxData();
PxVehicleDriveSimData &driveSimData = driveTank->mDriveSimData;
driveSimData.setGearsData(gearData);
driveSimData.setAutoBoxData(autoBoxData);
driveSimData.setClutchData(clutchData);
break;
}
}