Add tank vehicle physics
This commit is contained in:
@@ -14,7 +14,7 @@
|
||||
#include "Engine/Core/Log.h"
|
||||
#endif
|
||||
|
||||
WheeledVehicle::WheeledVehicle(const SpawnParams& params)
|
||||
WheeledVehicle::WheeledVehicle(const SpawnParams ¶ms)
|
||||
: 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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user