Expose vehicle relationship between speed and steer to driver
This commit is contained in:
@@ -55,6 +55,48 @@ 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
|
||||
while (value.SteerVsSpeed.Count() > 4)
|
||||
value.SteerVsSpeed.RemoveLast();
|
||||
|
||||
// Maintain all values clamped to have a ordened speed list
|
||||
int steerVsSpeedCount = value.SteerVsSpeed.Count();
|
||||
for (int i = 0; i < steerVsSpeedCount; i++)
|
||||
{
|
||||
// Apply only on changed value
|
||||
if (_driveControl.SteerVsSpeed[i].Speed != value.SteerVsSpeed[i].Speed || _driveControl.SteerVsSpeed[i].Steer != value.SteerVsSpeed[i].Steer)
|
||||
{
|
||||
WheeledVehicle::SteerControl &steerVsSpeed = value.SteerVsSpeed[i];
|
||||
steerVsSpeed.Steer = Math::Saturate(steerVsSpeed.Steer);
|
||||
steerVsSpeed.Speed = Math::Max(steerVsSpeed.Speed, 10.0f);
|
||||
|
||||
// Clamp speeds to have an ordened list.
|
||||
if (i >= 1)
|
||||
{
|
||||
WheeledVehicle::SteerControl &lastSteerVsSpeed = value.SteerVsSpeed[i - 1];
|
||||
WheeledVehicle::SteerControl &nextSteerVsSpeed = value.SteerVsSpeed[Math::Clamp(i + 1, 0, steerVsSpeedCount - 1)];
|
||||
float minSpeed = lastSteerVsSpeed.Speed;
|
||||
float maxSpeed = nextSteerVsSpeed.Speed;
|
||||
|
||||
if (i + 1 < steerVsSpeedCount - 1)
|
||||
steerVsSpeed.Speed = Math::Clamp(steerVsSpeed.Speed, minSpeed, maxSpeed);
|
||||
else
|
||||
steerVsSpeed.Speed = Math::Max(steerVsSpeed.Speed, minSpeed);
|
||||
}
|
||||
else if (steerVsSpeedCount > 1)
|
||||
{
|
||||
WheeledVehicle::SteerControl &nextSteerVsSpeed = value.SteerVsSpeed[i + 1];
|
||||
steerVsSpeed.Speed = Math::Min(steerVsSpeed.Speed, nextSteerVsSpeed.Speed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_driveControl = value;
|
||||
}
|
||||
|
||||
@@ -392,7 +434,6 @@ void WheeledVehicle::Serialize(SerializeStream &stream, const void *otherObj)
|
||||
SERIALIZE_MEMBER(Engine, _engine);
|
||||
SERIALIZE_MEMBER(Differential, _differential);
|
||||
SERIALIZE_MEMBER(Gearbox, _gearbox);
|
||||
|
||||
}
|
||||
|
||||
void WheeledVehicle::Deserialize(DeserializeStream &stream, ISerializeModifier *modifier)
|
||||
|
||||
@@ -40,6 +40,45 @@ API_CLASS(Attributes="ActorContextMenu(\"New/Physics/Wheeled Vehicle\"), ActorTo
|
||||
Special
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Storage the relationship between speed and steer.
|
||||
/// </summary>
|
||||
API_STRUCT() struct SteerControl : ISerializable
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_MINIMAL(SteerControl);
|
||||
API_AUTO_SERIALIZATION();
|
||||
|
||||
/// <summary>
|
||||
/// The vehicle speed.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes = "Limit(0)") float Speed;
|
||||
|
||||
/// <summary>
|
||||
/// The target max steer of the speed.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes = "Limit(0, 1)") float Steer;
|
||||
|
||||
/// <summary>
|
||||
/// Create a Steer/Speed relationship structure.
|
||||
/// </summary>
|
||||
SteerControl()
|
||||
{
|
||||
Speed = 1000;
|
||||
Steer = 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a Steer/Speed relationship structure.
|
||||
/// <param name="speed">The vehicle speed.</param>
|
||||
/// <param name="steer">The target max steer of the speed.</param>
|
||||
/// </summary>
|
||||
SteerControl(float speed, float steer)
|
||||
{
|
||||
Speed = speed;
|
||||
Steer = steer;
|
||||
}
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Vehicle engine settings.
|
||||
/// </summary>
|
||||
@@ -94,42 +133,54 @@ API_CLASS(Attributes="ActorContextMenu(\"New/Physics/Wheeled Vehicle\"), ActorTo
|
||||
/// <summary>
|
||||
/// Acceleration input sensitive.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="Limit(0), EditorDisplay(\"Inputs\"), EditorOrder(10)") float RiseRateAcceleration = 6.0f;
|
||||
API_FIELD(Attributes="Limit(0), EditorOrder(10)") float RiseRateAcceleration = 6.0f;
|
||||
|
||||
/// <summary>
|
||||
/// Deceleration input sensitive.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="Limit(0), EditorDisplay(\"Inputs\"), EditorOrder(11)") float FallRateAcceleration = 10.0f;
|
||||
API_FIELD(Attributes="Limit(0), EditorOrder(11)") float FallRateAcceleration = 10.0f;
|
||||
|
||||
/// <summary>
|
||||
/// Brake input sensitive.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="Limit(0), EditorDisplay(\"Inputs\"), EditorOrder(12)") float RiseRateBrake = 6.0f;
|
||||
API_FIELD(Attributes="Limit(0), EditorOrder(12)") float RiseRateBrake = 6.0f;
|
||||
|
||||
/// <summary>
|
||||
/// Release brake sensitive.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="Limit(0), EditorDisplay(\"Inputs\"), EditorOrder(13)") float FallRateBrake = 10.0f;
|
||||
API_FIELD(Attributes="Limit(0), EditorOrder(13)") float FallRateBrake = 10.0f;
|
||||
|
||||
/// <summary>
|
||||
/// Brake input sensitive.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="Limit(0), EditorDisplay(\"Inputs\"), EditorOrder(14)") float RiseRateHandBrake = 12.0f;
|
||||
API_FIELD(Attributes="Limit(0), EditorOrder(14)") float RiseRateHandBrake = 12.0f;
|
||||
|
||||
/// <summary>
|
||||
/// Release handbrake sensitive.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="Limit(0), EditorDisplay(\"Inputs\"), EditorOrder(15)") float FallRateHandBrake = 12.0f;
|
||||
API_FIELD(Attributes="Limit(0), EditorOrder(15)") float FallRateHandBrake = 12.0f;
|
||||
|
||||
/// <summary>
|
||||
/// Steer input sensitive.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="Limit(0), EditorDisplay(\"Inputs\"), EditorOrder(16)") float RiseRateSteer = 2.5f;
|
||||
API_FIELD(Attributes="Limit(0), EditorOrder(16)") float RiseRateSteer = 2.5f;
|
||||
|
||||
/// <summary>
|
||||
/// Release steer input sensitive.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="Limit(0), EditorDisplay(\"Inputs\"), EditorOrder(17)") float FallRateSteer = 5.0f;
|
||||
API_FIELD(Attributes="Limit(0), EditorOrder(17)") float FallRateSteer = 5.0f;
|
||||
|
||||
/// <summary>
|
||||
/// Vehicle control relationship between speed and steer. The higher is the speed,
|
||||
/// decrease steer to make vehicle more maneuverable (limited only 4 relationships).
|
||||
/// </summary>
|
||||
API_FIELD() Array<WheeledVehicle::SteerControl> SteerVsSpeed = Array<WheeledVehicle::SteerControl>
|
||||
{
|
||||
SteerControl(800, 1.0f),
|
||||
SteerControl(1500, 0.7f),
|
||||
SteerControl(2500, 0.5f),
|
||||
SteerControl(5000, 0.2f),
|
||||
};
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1554,9 +1554,7 @@ void PhysicsBackend::EndSimulateScene(void* scene)
|
||||
leftBrake = 1.0f;
|
||||
}
|
||||
|
||||
// @formatter:off
|
||||
// Reference: PhysX SDK docs
|
||||
// TODO: expose input control smoothing data
|
||||
// Smooth input controls
|
||||
PxVehiclePadSmoothingData padSmoothing =
|
||||
{
|
||||
{
|
||||
@@ -1591,20 +1589,31 @@ void PhysicsBackend::EndSimulateScene(void* scene)
|
||||
wheelVehicle->_driveControl.FallRateSteer, // fall rate eANALOG_INPUT_STEER_RIGHT
|
||||
}
|
||||
};
|
||||
// Reference: PhysX SDK docs
|
||||
// TODO: expose steer vs forward curve into per-vehicle (up to 8 points, values clamped into 0/1 range)
|
||||
static constexpr PxF32 steerVsForwardSpeedData[] =
|
||||
|
||||
// Reduce steer by speed to make vehicle more easier to maneuver
|
||||
|
||||
constexpr int steerVsSpeedN = 8;
|
||||
PxF32 steerVsForwardSpeedData[steerVsSpeedN];
|
||||
const int lastSteerVsSpeedIndex = wheelVehicle->_driveControl.SteerVsSpeed.Count() - 1;
|
||||
int steerVsSpeedIndex = 0;
|
||||
|
||||
// Steer vs speed data structure example:
|
||||
// array:
|
||||
// speed, steer
|
||||
// 1000, 1.0,
|
||||
// 2000, 0.7,
|
||||
// 5000, 0.5,
|
||||
// ..
|
||||
|
||||
// fill the steerVsForwardSpeedData with the speed and steer
|
||||
for (int i = 0; i < 8; i += 2)
|
||||
{
|
||||
0.0f, 1.0f,
|
||||
20.0f, 0.9f,
|
||||
65.0f, 0.8f,
|
||||
120.0f, 0.7f,
|
||||
PX_MAX_F32, PX_MAX_F32,
|
||||
PX_MAX_F32, PX_MAX_F32,
|
||||
PX_MAX_F32, PX_MAX_F32,
|
||||
PX_MAX_F32, PX_MAX_F32,
|
||||
};
|
||||
const PxFixedSizeLookupTable<8> steerVsForwardSpeed(steerVsForwardSpeedData, 4);
|
||||
steerVsForwardSpeedData[i] = wheelVehicle->_driveControl.SteerVsSpeed[steerVsSpeedIndex].Speed;
|
||||
steerVsForwardSpeedData[i + 1] = wheelVehicle->_driveControl.SteerVsSpeed[steerVsSpeedIndex].Steer;
|
||||
steerVsSpeedIndex = Math::Min(steerVsSpeedIndex + 1, lastSteerVsSpeedIndex);
|
||||
}
|
||||
const PxFixedSizeLookupTable<steerVsSpeedN> steerVsForwardSpeed(steerVsForwardSpeedData, 4);
|
||||
|
||||
// @formatter:on
|
||||
if (wheelVehicle->UseAnalogSteering)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user