Add Vehicle anti roll bar and suspension sprung force multiplier
This commit is contained in:
@@ -56,9 +56,6 @@ WheeledVehicle::DriveControlSettings WheeledVehicle::GetDriveControl() const
|
||||
void WheeledVehicle::SetDriveControl(DriveControlSettings &value)
|
||||
{
|
||||
// Don't let have an invalid steer vs speed list.
|
||||
if (&value.SteerVsSpeed == nullptr)
|
||||
value.SteerVsSpeed = Array<WheeledVehicle::SteerControl>();
|
||||
|
||||
if (value.SteerVsSpeed.Count() < 1)
|
||||
value.SteerVsSpeed.Add(WheeledVehicle::SteerControl());
|
||||
else // physx backend requires the max of 4 values only
|
||||
@@ -171,6 +168,20 @@ void WheeledVehicle::SetGearbox(const GearboxSettings &value)
|
||||
_gearbox = value;
|
||||
}
|
||||
|
||||
void WheeledVehicle::SetAntiRollBars(const Array<AntiRollBar> &value)
|
||||
{
|
||||
_antiRollBars = value;
|
||||
#if WITH_VEHICLE
|
||||
if (_vehicle)
|
||||
PhysicsBackend::UpdateVehicleAntiRollBars(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
const Array<WheeledVehicle::AntiRollBar> &WheeledVehicle::GetAntiRollBars() const
|
||||
{
|
||||
return _antiRollBars;
|
||||
}
|
||||
|
||||
void WheeledVehicle::SetThrottle(float value)
|
||||
{
|
||||
_throttle = Math::Clamp(value, -1.0f, 1.0f);
|
||||
@@ -398,20 +409,24 @@ 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())
|
||||
{
|
||||
if (!_wheels[wheelIndex].Collider || !_wheels[wheelIndex + 1].Collider)
|
||||
continue;
|
||||
|
||||
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
|
||||
// Draw anti roll bars axes
|
||||
int wheelsCount = _wheels.Count();
|
||||
for (int i = 0; i < GetAntiRollBars().Count(); i++)
|
||||
{
|
||||
int axleIndex = GetAntiRollBars()[i].Axle;
|
||||
int leftWheelIndex = axleIndex * 2;
|
||||
int rightWheelIndex = leftWheelIndex + 1;
|
||||
|
||||
if (leftWheelIndex >= wheelsCount || rightWheelIndex >= wheelsCount)
|
||||
continue;
|
||||
if (!_wheels[leftWheelIndex].Collider || !_wheels[rightWheelIndex].Collider)
|
||||
continue;
|
||||
|
||||
DEBUG_DRAW_LINE(_wheels[leftWheelIndex].Collider->GetPosition(), _wheels[rightWheelIndex].Collider->GetPosition(), Color::Yellow, 0, false);
|
||||
}
|
||||
// Center of mass
|
||||
DEBUG_DRAW_WIRE_SPHERE(BoundingSphere(_transform.LocalToWorld(_centerOfMassOffset), 10.0f), Color::Blue, 0, false);
|
||||
|
||||
RigidBody::OnDebugDrawSelected();
|
||||
@@ -434,6 +449,7 @@ void WheeledVehicle::Serialize(SerializeStream &stream, const void *otherObj)
|
||||
SERIALIZE_MEMBER(Engine, _engine);
|
||||
SERIALIZE_MEMBER(Differential, _differential);
|
||||
SERIALIZE_MEMBER(Gearbox, _gearbox);
|
||||
SERIALIZE_MEMBER(AntiRollBars, _antiRollBars);
|
||||
}
|
||||
|
||||
void WheeledVehicle::Deserialize(DeserializeStream &stream, ISerializeModifier *modifier)
|
||||
@@ -449,6 +465,7 @@ void WheeledVehicle::Deserialize(DeserializeStream &stream, ISerializeModifier *
|
||||
DESERIALIZE_MEMBER(Engine, _engine);
|
||||
DESERIALIZE_MEMBER(Differential, _differential);
|
||||
DESERIALIZE_MEMBER(Gearbox, _gearbox);
|
||||
DESERIALIZE_MEMBER(AntiRollBars, _antiRollBars);
|
||||
|
||||
// [Deprecated on 13.06.2023, expires on 13.06.2025]
|
||||
_fixInvalidForwardDir |= modifier->EngineBuild < 6341;
|
||||
|
||||
@@ -306,6 +306,11 @@ API_CLASS(Attributes="ActorContextMenu(\"New/Physics/Wheeled Vehicle\"), ActorTo
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(4)") ScriptingObjectReference<Collider> Collider;
|
||||
|
||||
/// <summary>
|
||||
/// Spring sprung mass force multiplier.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="Limit(0.01f), EditorDisplay(\"Suspension\"), EditorOrder(19)") float SprungMassMultiplier = 1.0f;
|
||||
|
||||
/// <summary>
|
||||
/// Spring damper rate of suspension unit.
|
||||
/// </summary>
|
||||
@@ -407,6 +412,25 @@ API_CLASS(Attributes="ActorContextMenu(\"New/Physics/Wheeled Vehicle\"), ActorTo
|
||||
#endif
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Vehicle axle anti roll bar.
|
||||
/// </summary>
|
||||
API_STRUCT() struct AntiRollBar : ISerializable
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_MINIMAL(AntiRollBar);
|
||||
API_AUTO_SERIALIZATION();
|
||||
|
||||
/// <summary>
|
||||
/// The specific axle with wheels to apply anti roll.
|
||||
/// </summary>
|
||||
API_FIELD() int Axle;
|
||||
|
||||
/// <summary>
|
||||
/// The anti roll stiffness.
|
||||
/// </summary>
|
||||
API_FIELD() float Stiffness;
|
||||
};
|
||||
|
||||
private:
|
||||
struct WheelData
|
||||
{
|
||||
@@ -420,7 +444,8 @@ private:
|
||||
DriveModes _driveMode = DriveModes::Standard;
|
||||
Array<WheelData, FixedAllocation<20>> _wheelsData;
|
||||
float _throttle = 0.0f, _steering = 0.0f, _brake = 0.0f, _handBrake = 0.0f, _tankLeftThrottle, _tankRightThrottle, _tankLeftBrake, _tankRightBrake;
|
||||
Array<Wheel> _wheels;
|
||||
Array<WheeledVehicle::Wheel> _wheels;
|
||||
Array<WheeledVehicle::AntiRollBar> _antiRollBars;
|
||||
DriveControlSettings _driveControl;
|
||||
EngineSettings _engine;
|
||||
DifferentialSettings _differential;
|
||||
@@ -511,6 +536,16 @@ public:
|
||||
/// </summary>
|
||||
API_PROPERTY() void SetGearbox(const GearboxSettings& value);
|
||||
|
||||
// <summary>
|
||||
/// Sets axles anti roll bars to increase vehicle estability.
|
||||
/// </summary>
|
||||
API_PROPERTY() void SetAntiRollBars(const Array<AntiRollBar>& value);
|
||||
|
||||
// <summary>
|
||||
/// Gets axles anti roll bars.
|
||||
/// </summary>
|
||||
API_PROPERTY() const Array<AntiRollBar>& GetAntiRollBars() const;
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Sets the input for vehicle throttle. It is the analog accelerator pedal value in range (0,1) where 1 represents the pedal fully pressed and 0 represents the pedal in its rest state.
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include <ThirdParty/PhysX/vehicle/PxVehicleDriveNW.h>
|
||||
#include <ThirdParty/PhysX/vehicle/PxVehicleDriveTank.h>
|
||||
#include <ThirdParty/PhysX/vehicle/PxVehicleUtilSetup.h>
|
||||
#include <ThirdParty/PhysX/vehicle/PxVehicleComponents.h>
|
||||
#include <ThirdParty/PhysX/PxFiltering.h>
|
||||
#endif
|
||||
#if WITH_CLOTH
|
||||
@@ -3333,7 +3334,7 @@ PxVehicleSuspensionData CreatePxVehicleSuspensionData(const WheeledVehicle::Whee
|
||||
const float suspensionFrequency = 7.0f;
|
||||
suspensionData.mMaxCompression = settings.SuspensionMaxRaise;
|
||||
suspensionData.mMaxDroop = settings.SuspensionMaxDrop;
|
||||
suspensionData.mSprungMass = wheelSprungMass;
|
||||
suspensionData.mSprungMass = wheelSprungMass * settings.SprungMassMultiplier;
|
||||
suspensionData.mSpringStrength = Math::Square(suspensionFrequency) * suspensionData.mSprungMass;
|
||||
suspensionData.mSpringDamperRate = settings.SuspensionDampingRate * 2.0f * Math::Sqrt(suspensionData.mSpringStrength * suspensionData.mSprungMass);
|
||||
return suspensionData;
|
||||
@@ -3380,23 +3381,29 @@ PxVehicleAckermannGeometryData CreatePxVehicleAckermannGeometryData(PxVehicleWhe
|
||||
return ackermann;
|
||||
}
|
||||
|
||||
bool SortWheelsFrontToBack(WheeledVehicle::Wheel const& a, WheeledVehicle::Wheel const& b)
|
||||
PxVehicleAntiRollBarData CreatePxPxVehicleAntiRollBarData(const WheeledVehicle::AntiRollBar& settings, int leftWheelIndex, int rightWheelIndex)
|
||||
{
|
||||
PxVehicleAntiRollBarData antiRollBar;
|
||||
antiRollBar.mWheel0 = leftWheelIndex;
|
||||
antiRollBar.mWheel1 = rightWheelIndex;
|
||||
antiRollBar.mStiffness = settings.Stiffness;
|
||||
return antiRollBar;
|
||||
}
|
||||
|
||||
bool SortWheelsFrontToBack(WheeledVehicle::Wheel const &a, WheeledVehicle::Wheel const &b)
|
||||
{
|
||||
return a.Collider && b.Collider && a.Collider->GetLocalPosition().Z > b.Collider->GetLocalPosition().Z;
|
||||
}
|
||||
|
||||
void* PhysicsBackend::CreateVehicle(WheeledVehicle* actor)
|
||||
{
|
||||
#if USE_EDITOR
|
||||
if (Editor::IsPlayMode)
|
||||
#endif
|
||||
// Physx vehicles needs to have all wheels sorted to apply controls correctly.
|
||||
// Its needs to know what wheels are on front to turn wheel to correctly side
|
||||
// and needs to know wheel side to apply throttle to correctly direction for each track when using tanks.
|
||||
// Anti roll bars needs to have all wheels sorted to get correctly wheel index too.
|
||||
if (actor->_driveType != WheeledVehicle::DriveTypes::NoDrive)
|
||||
{
|
||||
// Physx vehicles needs to have all wheels sorted to apply controls correctly.
|
||||
// Its needs to know what wheels are on front to turn wheel to correctly side
|
||||
// and needs to know wheel side to apply throttle to correctly direction for each track when using tanks.
|
||||
|
||||
if (actor->_driveType == WheeledVehicle::DriveTypes::Drive4W)
|
||||
Sorting::QuickSort(actor->_wheels.Get(), actor->_wheels.Count(), SortWheelsFrontToBack);
|
||||
Sorting::QuickSort(actor->_wheels.Get(), actor->_wheels.Count(), SortWheelsFrontToBack);
|
||||
|
||||
// sort wheels by side
|
||||
if (actor->_driveType == WheeledVehicle::DriveTypes::Tank)
|
||||
@@ -3468,7 +3475,8 @@ void* PhysicsBackend::CreateVehicle(WheeledVehicle* actor)
|
||||
// TODO: get gravityDirection from scenePhysX->Scene->getGravity()
|
||||
PxVehicleComputeSprungMasses(wheels.Count(), offsets, centerOfMassOffset.p, mass, 1, sprungMasses);
|
||||
PxVehicleWheelsSimData* wheelsSimData = PxVehicleWheelsSimData::allocate(wheels.Count());
|
||||
for (int32 i = 0; i < wheels.Count(); i++)
|
||||
int wheelsCount = wheels.Count();
|
||||
for (int32 i = 0; i < wheelsCount; i++)
|
||||
{
|
||||
auto& wheel = *wheels[i];
|
||||
|
||||
@@ -3514,6 +3522,19 @@ void* PhysicsBackend::CreateVehicle(WheeledVehicle* actor)
|
||||
wheelsSimData->disableWheel(i);
|
||||
}
|
||||
}
|
||||
// Add Anti roll bars for wheels axles
|
||||
for (int i = 0; i < actor->GetAntiRollBars().Count(); i++)
|
||||
{
|
||||
int axleIndex = actor->GetAntiRollBars()[i].Axle;
|
||||
int leftWheelIndex = axleIndex * 2;
|
||||
int rightWheelIndex = leftWheelIndex + 1;
|
||||
|
||||
if (leftWheelIndex >= wheelsCount || rightWheelIndex >= wheelsCount)
|
||||
continue;
|
||||
|
||||
const PxVehicleAntiRollBarData &antiRollBar = CreatePxPxVehicleAntiRollBarData(actor->GetAntiRollBars()[i], leftWheelIndex, rightWheelIndex);
|
||||
wheelsSimData->addAntiRollBarData(antiRollBar);
|
||||
}
|
||||
for (auto child : actor->Children)
|
||||
{
|
||||
auto collider = ScriptingObject::Cast<Collider>(child);
|
||||
@@ -3676,6 +3697,34 @@ void PhysicsBackend::UpdateVehicleWheels(WheeledVehicle* actor)
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsBackend::UpdateVehicleAntiRollBars(WheeledVehicle *actor)
|
||||
{
|
||||
int wheelsCount = actor->_wheels.Count();
|
||||
auto drive = (PxVehicleWheels *)actor->_vehicle;
|
||||
PxVehicleWheelsSimData *wheelsSimData = &drive->mWheelsSimData;
|
||||
|
||||
// Update Anti roll bars for wheels axles
|
||||
for (int i = 0; i < actor->GetAntiRollBars().Count(); i++)
|
||||
{
|
||||
int axleIndex = actor->GetAntiRollBars()[i].Axle;
|
||||
int leftWheelIndex = axleIndex * 2;
|
||||
int rightWheelIndex = leftWheelIndex + 1;
|
||||
|
||||
if (leftWheelIndex >= wheelsCount || rightWheelIndex >= wheelsCount)
|
||||
continue;
|
||||
|
||||
const PxVehicleAntiRollBarData &antiRollBar = CreatePxPxVehicleAntiRollBarData(actor->GetAntiRollBars()[i], leftWheelIndex, rightWheelIndex);
|
||||
if (wheelsSimData->getNbAntiRollBarData() - 1 < i)
|
||||
{
|
||||
wheelsSimData->addAntiRollBarData(antiRollBar);
|
||||
}
|
||||
else
|
||||
{
|
||||
wheelsSimData->setAntiRollBarData(axleIndex, antiRollBar);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsBackend::SetVehicleEngine(void* vehicle, const void* value)
|
||||
{
|
||||
auto drive = (PxVehicleDrive*)vehicle;
|
||||
|
||||
@@ -262,6 +262,7 @@ public:
|
||||
static void* CreateVehicle(class WheeledVehicle* actor);
|
||||
static void DestroyVehicle(void* vehicle, int32 driveType);
|
||||
static void UpdateVehicleWheels(WheeledVehicle* actor);
|
||||
static void UpdateVehicleAntiRollBars(WheeledVehicle* actor);
|
||||
static void SetVehicleEngine(void* vehicle, const void* value);
|
||||
static void SetVehicleDifferential(void* vehicle, const void* value);
|
||||
static void SetVehicleGearbox(void* vehicle, const void* value);
|
||||
|
||||
Reference in New Issue
Block a user