Merge branch 'FlaxEngine:master' into feature-tilespanel-margin
This commit is contained in:
@@ -291,7 +291,8 @@ void WheeledVehicle::Setup()
|
||||
offsets[i] = C2P(wheel.Collider->GetLocalPosition());
|
||||
}
|
||||
PxF32 sprungMasses[PX_MAX_NB_WHEELS];
|
||||
PxVehicleComputeSprungMasses(wheels.Count(), offsets, centerOfMassOffset.p, _actor->getMass(), 1, sprungMasses);
|
||||
const float mass = _actor->getMass();
|
||||
PxVehicleComputeSprungMasses(wheels.Count(), offsets, centerOfMassOffset.p, mass, 1, sprungMasses);
|
||||
PxVehicleWheelsSimData* wheelsSimData = PxVehicleWheelsSimData::allocate(wheels.Count());
|
||||
for (int32 i = 0; i < wheels.Count(); i++)
|
||||
{
|
||||
@@ -300,7 +301,6 @@ void WheeledVehicle::Setup()
|
||||
auto& data = _wheelsData[i];
|
||||
data.Collider = wheel.Collider;
|
||||
data.LocalOrientation = wheel.Collider->GetLocalOrientation();
|
||||
data.ChildrenPoses.Resize(0);
|
||||
|
||||
PxVehicleSuspensionData suspensionData;
|
||||
const float suspensionFrequency = 7.0f;
|
||||
@@ -312,6 +312,9 @@ void WheeledVehicle::Setup()
|
||||
|
||||
PxVehicleTireData tire;
|
||||
tire.mType = 0;
|
||||
tire.mLatStiffX = wheel.TireLateralMax;
|
||||
tire.mLatStiffY = wheel.TireLateralStiffness;
|
||||
tire.mLongitudinalStiffnessPerUnitGravity = wheel.TireLongitudinalStiffness;
|
||||
|
||||
PxVehicleWheelData wheelData;
|
||||
wheelData.mMass = wheel.Mass;
|
||||
@@ -324,7 +327,7 @@ void WheeledVehicle::Setup()
|
||||
wheelData.mMaxHandBrakeTorque = M2ToCm2(wheel.MaxHandBrakeTorque);
|
||||
|
||||
PxVec3 centreOffset = centerOfMassOffset.transformInv(offsets[i]);
|
||||
PxVec3 forceAppPointOffset(centreOffset.z, centreOffset.y + wheel.SuspensionForceOffset, centreOffset.z);
|
||||
PxVec3 forceAppPointOffset(centreOffset.x, wheel.SuspensionForceOffset, centreOffset.z);
|
||||
|
||||
wheelsSimData->setTireData(i, tire);
|
||||
wheelsSimData->setWheelData(i, wheelData);
|
||||
@@ -333,6 +336,8 @@ void WheeledVehicle::Setup()
|
||||
wheelsSimData->setWheelCentreOffset(i, centreOffset);
|
||||
wheelsSimData->setSuspForceAppPointOffset(i, forceAppPointOffset);
|
||||
wheelsSimData->setTireForceAppPointOffset(i, forceAppPointOffset);
|
||||
wheelsSimData->setSubStepCount(4.0f * 100.0f, 3, 1);
|
||||
wheelsSimData->setMinLongSlipDenominator(4.0f * 100.0f);
|
||||
|
||||
PxShape* wheelShape = wheel.Collider->GetPxShape();
|
||||
if (wheel.Collider->IsActiveInHierarchy())
|
||||
@@ -345,6 +350,9 @@ void WheeledVehicle::Setup()
|
||||
wheelShape->setQueryFilterData(filter);
|
||||
wheelShape->setSimulationFilterData(filter);
|
||||
wheelsSimData->setSceneQueryFilterData(i, filter);
|
||||
|
||||
// Remove wheels from the simulation (suspension force hold the vehicle)
|
||||
wheelShape->setFlag(PxShapeFlag::eSIMULATION_SHAPE, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -520,12 +528,16 @@ void WheeledVehicle::DrawPhysicsDebug(RenderView& view)
|
||||
auto& wheel = _wheels[wheelIndex];
|
||||
if (wheel.Collider && wheel.Collider->GetParent() == this && !wheel.Collider->GetIsTrigger())
|
||||
{
|
||||
const Vector3 basePos = wheel.Collider->GetPosition();
|
||||
const Vector3 currentPos = basePos + Vector3(0, data.State.SuspensionOffset, 0);
|
||||
const Vector3 currentPos = wheel.Collider->GetPosition();
|
||||
const Vector3 basePos = currentPos - Vector3(0, data.State.SuspensionOffset, 0);
|
||||
DEBUG_DRAW_WIRE_SPHERE(BoundingSphere(basePos, wheel.Radius * 0.07f), Color::Blue * 0.3f, 0, true);
|
||||
DEBUG_DRAW_WIRE_SPHERE(BoundingSphere(currentPos, wheel.Radius * 0.08f), Color::Blue * 0.8f, 0, true);
|
||||
DEBUG_DRAW_LINE(basePos, currentPos, Color::Blue, 0, true);
|
||||
DEBUG_DRAW_WIRE_CYLINDER(currentPos, wheel.Collider->GetOrientation(), wheel.Radius, wheel.Width, Color::Red * 0.8f, 0, true);
|
||||
if (!data.State.IsInAir)
|
||||
{
|
||||
DEBUG_DRAW_WIRE_SPHERE(BoundingSphere(data.State.TireContactPoint, 5.0f), Color::Green, 0, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -546,12 +558,22 @@ void WheeledVehicle::OnDebugDrawSelected()
|
||||
auto& wheel = _wheels[wheelIndex];
|
||||
if (wheel.Collider && wheel.Collider->GetParent() == this && !wheel.Collider->GetIsTrigger())
|
||||
{
|
||||
const Vector3 basePos = wheel.Collider->GetPosition();
|
||||
const Vector3 currentPos = basePos + Vector3(0, data.State.SuspensionOffset, 0);
|
||||
const Vector3 currentPos = wheel.Collider->GetPosition();
|
||||
const Vector3 basePos = currentPos - Vector3(0, data.State.SuspensionOffset, 0);
|
||||
DEBUG_DRAW_WIRE_SPHERE(BoundingSphere(basePos, wheel.Radius * 0.07f), Color::Blue * 0.3f, 0, false);
|
||||
DEBUG_DRAW_WIRE_SPHERE(BoundingSphere(currentPos, wheel.Radius * 0.08f), Color::Blue * 0.8f, 0, false);
|
||||
DEBUG_DRAW_WIRE_SPHERE(BoundingSphere(P2C(_actor->getGlobalPose().transform(wheel.Collider->GetPxShape()->getLocalPose()).p), wheel.Radius * 0.11f), Color::OrangeRed * 0.8f, 0, false);
|
||||
DEBUG_DRAW_LINE(basePos, currentPos, Color::Blue, 0, false);
|
||||
DEBUG_DRAW_WIRE_CYLINDER(currentPos, wheel.Collider->GetOrientation(), wheel.Radius, wheel.Width, Color::Red * 0.4f, 0, false);
|
||||
if (!data.State.SuspensionTraceStart.IsZero())
|
||||
{
|
||||
DEBUG_DRAW_WIRE_SPHERE(BoundingSphere(data.State.SuspensionTraceStart, 5.0f), Color::AliceBlue, 0, false);
|
||||
DEBUG_DRAW_LINE(data.State.SuspensionTraceStart, data.State.SuspensionTraceEnd, data.State.IsInAir ? Color::Red : Color::Green, 0, false);
|
||||
}
|
||||
if (!data.State.IsInAir)
|
||||
{
|
||||
DEBUG_DRAW_WIRE_SPHERE(BoundingSphere(data.State.TireContactPoint, 5.0f), Color::Green, 0, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -572,6 +594,7 @@ void WheeledVehicle::Serialize(SerializeStream& stream, const void* otherObj)
|
||||
SERIALIZE_MEMBER(DriveType, _driveType);
|
||||
SERIALIZE_MEMBER(Wheels, _wheels);
|
||||
SERIALIZE(UseReverseAsBrake);
|
||||
SERIALIZE(UseAnalogSteering);
|
||||
SERIALIZE_MEMBER(Engine, _engine);
|
||||
SERIALIZE_MEMBER(Differential, _differential);
|
||||
SERIALIZE_MEMBER(Gearbox, _gearbox);
|
||||
@@ -584,6 +607,7 @@ void WheeledVehicle::Deserialize(DeserializeStream& stream, ISerializeModifier*
|
||||
DESERIALIZE_MEMBER(DriveType, _driveType);
|
||||
DESERIALIZE_MEMBER(Wheels, _wheels);
|
||||
DESERIALIZE(UseReverseAsBrake);
|
||||
DESERIALIZE(UseAnalogSteering);
|
||||
DESERIALIZE_MEMBER(Engine, _engine);
|
||||
DESERIALIZE_MEMBER(Differential, _differential);
|
||||
DESERIALIZE_MEMBER(Gearbox, _gearbox);
|
||||
|
||||
@@ -172,67 +172,82 @@ public:
|
||||
/// <summary>
|
||||
/// Wheel placement type.
|
||||
/// </summary>
|
||||
API_FIELD() WheelTypes Type = WheelTypes::FrontLeft;
|
||||
API_FIELD(Attributes="EditorOrder(0)") WheelTypes Type = WheelTypes::FrontLeft;
|
||||
|
||||
/// <summary>
|
||||
/// Combined mass of the wheel and the tire in kg. Typically, a wheel has mass between 20Kg and 80Kg but can be lower and higher depending on the vehicle.
|
||||
/// </summary>
|
||||
API_FIELD() float Mass = 20.0f;
|
||||
API_FIELD(Attributes="EditorOrder(1)") float Mass = 20.0f;
|
||||
|
||||
/// <summary>
|
||||
/// Distance in metres between the center of the wheel and the outside rim of the tire. It is important that the value of the radius closely matches the radius of the render mesh of the wheel. Any mismatch will result in the wheels either hovering above the ground or intersecting the ground.
|
||||
/// </summary>
|
||||
API_FIELD() float Radius = 50.0f;
|
||||
API_FIELD(Attributes="EditorOrder(2)") float Radius = 50.0f;
|
||||
|
||||
/// <summary>
|
||||
/// Full width of the wheel in metres. This parameter has no bearing on the handling but is a very useful parameter to have when trying to render debug data relating to the wheel/tire/suspension.
|
||||
/// </summary>
|
||||
API_FIELD() float Width = 20.0f;
|
||||
API_FIELD(Attributes="EditorOrder(3)") float Width = 20.0f;
|
||||
|
||||
/// <summary>
|
||||
/// Max steer angle that can be achieved by the wheel (in degrees).
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="Limit(0)") float MaxSteerAngle = 0.0f;
|
||||
API_FIELD(Attributes="Limit(0), EditorDisplay(\"Steering\"), EditorOrder(10)") float MaxSteerAngle = 0.0f;
|
||||
|
||||
/// <summary>
|
||||
/// Damping rate applied to wheel. Specified in kilograms metres-squared per second (kg m^2 s^-1).
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="Limit(0)") float DampingRate = 0.25f;
|
||||
API_FIELD(Attributes="Limit(0), EditorDisplay(\"Steering\"), EditorOrder(11)") float DampingRate = 0.25f;
|
||||
|
||||
/// <summary>
|
||||
/// Max brake torque that can be applied to wheel. Specified in kilograms metres-squared per second-squared (kg m^2 s^-2)
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="Limit(0)") float MaxBrakeTorque = 1500.0f;
|
||||
API_FIELD(Attributes="Limit(0), EditorDisplay(\"Steering\"), EditorOrder(12)") float MaxBrakeTorque = 1500.0f;
|
||||
|
||||
/// <summary>
|
||||
/// Max handbrake torque that can be applied to wheel. Specified in kilograms metres-squared per second-squared (kg m^2 s^-2)
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="Limit(0)") float MaxHandBrakeTorque = 2000.0f;
|
||||
API_FIELD(Attributes="Limit(0), EditorDisplay(\"Steering\"), EditorOrder(13)") float MaxHandBrakeTorque = 2000.0f;
|
||||
|
||||
/// <summary>
|
||||
/// Collider that represents the wheel shape and it's placement. Has to be attached as a child to the vehicle. Triangle mesh collider is not supported (use convex mesh or basic shapes).
|
||||
/// </summary>
|
||||
API_FIELD() ScriptingObjectReference<Collider> Collider;
|
||||
API_FIELD(Attributes="EditorOrder(4)") ScriptingObjectReference<Collider> Collider;
|
||||
|
||||
/// <summary>
|
||||
/// Spring damper rate of suspension unit.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="Limit(0)") float SuspensionDampingRate = 1.0f;
|
||||
API_FIELD(Attributes="Limit(0), EditorDisplay(\"Suspension\"), EditorOrder(20)") float SuspensionDampingRate = 1.0f;
|
||||
|
||||
/// <summary>
|
||||
/// The maximum offset for the suspension that wheel can go above resting location.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="Limit(0)") float SuspensionMaxRaise = 10.0f;
|
||||
API_FIELD(Attributes="Limit(0), EditorDisplay(\"Suspension\"), EditorOrder(21)") float SuspensionMaxRaise = 10.0f;
|
||||
|
||||
/// <summary>
|
||||
/// The maximum offset for the suspension that wheel can go below resting location.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="Limit(0)") float SuspensionMaxDrop = 10.0f;
|
||||
API_FIELD(Attributes="Limit(0), EditorDisplay(\"Suspension\"), EditorOrder(22)") float SuspensionMaxDrop = 10.0f;
|
||||
|
||||
/// <summary>
|
||||
/// The vertical offset from where suspension forces are applied.
|
||||
/// The vertical offset from where suspension forces are applied (relative to the vehicle center of mass). The suspension force is applies on the vertical axis going though the wheel center.
|
||||
/// </summary>
|
||||
API_FIELD() float SuspensionForceOffset = 0.0f;
|
||||
API_FIELD(Attributes="EditorDisplay(\"Suspension\"), EditorOrder(23)") float SuspensionForceOffset = 0.0f;
|
||||
|
||||
/// <summary>
|
||||
/// The tire lateral stiffness to have given lateral slip.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorDisplay(\"Tire\"), EditorOrder(30)") float TireLateralStiffness = 17.0f;
|
||||
|
||||
/// <summary>
|
||||
/// The maximum tire load (normalized) at which tire cannot provide more lateral stiffness (no matter how much extra load is applied to it).
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorDisplay(\"Tire\"), EditorOrder(31)") float TireLateralMax = 2.0f;
|
||||
|
||||
/// <summary>
|
||||
/// The tire longitudinal stiffness to have given longitudinal slip.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorDisplay(\"Tire\"), EditorOrder(32)") float TireLongitudinalStiffness = 1000.0f;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
@@ -281,6 +296,18 @@ public:
|
||||
/// The compression of the suspension spring. Offsets the wheel location.
|
||||
/// </summary>
|
||||
API_FIELD() float SuspensionOffset = 0.0f;
|
||||
|
||||
#if USE_EDITOR
|
||||
/// <summary>
|
||||
/// The start location of the suspension raycast start (Editor only for debugging).
|
||||
/// </summary>
|
||||
API_FIELD() Vector3 SuspensionTraceStart = Vector3::Zero;
|
||||
|
||||
/// <summary>
|
||||
/// The start location of the suspension raycast end (Editor only for debugging).
|
||||
/// </summary>
|
||||
API_FIELD() Vector3 SuspensionTraceEnd = Vector3::Zero;
|
||||
#endif
|
||||
};
|
||||
|
||||
private:
|
||||
@@ -290,12 +317,6 @@ private:
|
||||
Collider* Collider;
|
||||
Quaternion LocalOrientation;
|
||||
WheelState State;
|
||||
struct ChildPose
|
||||
{
|
||||
Actor* Child;
|
||||
Vector3 Pose;
|
||||
};
|
||||
Array<ChildPose, InlinedAllocation<4>> ChildrenPoses;
|
||||
};
|
||||
|
||||
void* _drive = nullptr;
|
||||
@@ -315,6 +336,12 @@ public:
|
||||
API_FIELD(Attributes="EditorOrder(0), EditorDisplay(\"Vehicle\")")
|
||||
bool UseReverseAsBrake = true;
|
||||
|
||||
/// <summary>
|
||||
/// If checked, the vehicle driving and steering inputs will be used as analog values (from gamepad), otherwise will be used as digital input (from keyboard).
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(1), EditorDisplay(\"Vehicle\")")
|
||||
bool UseAnalogSteering = false;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the vehicle driving model type.
|
||||
/// </summary>
|
||||
|
||||
@@ -43,10 +43,10 @@ bool MeshCollider::CanAttach(RigidBody* rigidBody) const
|
||||
CollisionDataType type = CollisionDataType::None;
|
||||
if (CollisionData && CollisionData->IsLoaded())
|
||||
type = CollisionData->GetOptions().Type;
|
||||
#if USE_EDITOR
|
||||
#if USE_EDITOR || !BUILD_RELEASE
|
||||
if (type == CollisionDataType::TriangleMesh)
|
||||
{
|
||||
LOG(Warning, "Cannot attach {0} using Triangle Mesh collider {1} to RigidBody (not supported)", GetNamePath(), CollisionData->ToString());
|
||||
LOG(Warning, "Cannot attach '{0}' using Triangle Mesh collider '{1}' to Rigid Body (not supported)", GetNamePath(), CollisionData->ToString());
|
||||
}
|
||||
#endif
|
||||
return type != CollisionDataType::TriangleMesh;
|
||||
|
||||
@@ -31,6 +31,12 @@
|
||||
// Temporary memory size used by the PhysX during the simulation. Must be multiply of 4kB and 16bit aligned.
|
||||
#define SCRATCH_BLOCK_SIZE (1024 * 128)
|
||||
|
||||
#define PHYSX_VEHICLE_DEBUG_TELEMETRY 0
|
||||
|
||||
#if PHYSX_VEHICLE_DEBUG_TELEMETRY
|
||||
#include "Engine/Core/Utilities.h"
|
||||
#endif
|
||||
|
||||
class PhysXAllocator : public PxAllocatorCallback
|
||||
{
|
||||
public:
|
||||
@@ -744,6 +750,23 @@ void Physics::CollectResults()
|
||||
5.0f, // fall rate eANALOG_INPUT_STEER_RIGHT
|
||||
}
|
||||
};
|
||||
PxVehicleKeySmoothingData keySmoothing =
|
||||
{
|
||||
{
|
||||
3.0f, // rise rate eANALOG_INPUT_ACCEL
|
||||
3.0f, // rise rate eANALOG_INPUT_BRAKE
|
||||
10.0f, // rise rate eANALOG_INPUT_HANDBRAKE
|
||||
2.5f, // rise rate eANALOG_INPUT_STEER_LEFT
|
||||
2.5f, // rise rate eANALOG_INPUT_STEER_RIGHT
|
||||
},
|
||||
{
|
||||
5.0f, // fall rate eANALOG_INPUT__ACCEL
|
||||
5.0f, // fall rate eANALOG_INPUT__BRAKE
|
||||
10.0f, // fall rate eANALOG_INPUT__HANDBRAKE
|
||||
5.0f, // fall rate eANALOG_INPUT_STEER_LEFT
|
||||
5.0f // 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[] =
|
||||
@@ -759,28 +782,60 @@ void Physics::CollectResults()
|
||||
};
|
||||
const PxFixedSizeLookupTable<8> steerVsForwardSpeed(steerVsForwardSpeedData, 4);
|
||||
// @formatter:on
|
||||
switch (wheelVehicle->_driveTypeCurrent)
|
||||
if (wheelVehicle->UseAnalogSteering)
|
||||
{
|
||||
case WheeledVehicle::DriveTypes::Drive4W:
|
||||
{
|
||||
PxVehicleDrive4WRawInputData rawInputData;
|
||||
rawInputData.setAnalogAccel(throttle);
|
||||
rawInputData.setAnalogBrake(brake);
|
||||
rawInputData.setAnalogSteer(wheelVehicle->_steering);
|
||||
rawInputData.setAnalogHandbrake(wheelVehicle->_handBrake);
|
||||
PxVehicleDrive4WSmoothAnalogRawInputsAndSetAnalogInputs(padSmoothing, steerVsForwardSpeed, rawInputData, LastDeltaTime, false, *(PxVehicleDrive4W*)drive);
|
||||
break;
|
||||
switch (wheelVehicle->_driveTypeCurrent)
|
||||
{
|
||||
case WheeledVehicle::DriveTypes::Drive4W:
|
||||
{
|
||||
PxVehicleDrive4WRawInputData rawInputData;
|
||||
rawInputData.setAnalogAccel(throttle);
|
||||
rawInputData.setAnalogBrake(brake);
|
||||
rawInputData.setAnalogSteer(wheelVehicle->_steering);
|
||||
rawInputData.setAnalogHandbrake(wheelVehicle->_handBrake);
|
||||
PxVehicleDrive4WSmoothAnalogRawInputsAndSetAnalogInputs(padSmoothing, steerVsForwardSpeed, rawInputData, LastDeltaTime, false, *(PxVehicleDrive4W*)drive);
|
||||
break;
|
||||
}
|
||||
case WheeledVehicle::DriveTypes::DriveNW:
|
||||
{
|
||||
PxVehicleDriveNWRawInputData rawInputData;
|
||||
rawInputData.setAnalogAccel(throttle);
|
||||
rawInputData.setAnalogBrake(brake);
|
||||
rawInputData.setAnalogSteer(wheelVehicle->_steering);
|
||||
rawInputData.setAnalogHandbrake(wheelVehicle->_handBrake);
|
||||
PxVehicleDriveNWSmoothAnalogRawInputsAndSetAnalogInputs(padSmoothing, steerVsForwardSpeed, rawInputData, LastDeltaTime, false, *(PxVehicleDriveNW*)drive);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
case WheeledVehicle::DriveTypes::DriveNW:
|
||||
else
|
||||
{
|
||||
PxVehicleDriveNWRawInputData rawInputData;
|
||||
rawInputData.setAnalogAccel(throttle);
|
||||
rawInputData.setAnalogBrake(brake);
|
||||
rawInputData.setAnalogSteer(wheelVehicle->_steering);
|
||||
rawInputData.setAnalogHandbrake(wheelVehicle->_handBrake);
|
||||
PxVehicleDriveNWSmoothAnalogRawInputsAndSetAnalogInputs(padSmoothing, steerVsForwardSpeed, rawInputData, LastDeltaTime, false, *(PxVehicleDriveNW*)drive);
|
||||
break;
|
||||
}
|
||||
const float deadZone = 0.1f;
|
||||
switch (wheelVehicle->_driveTypeCurrent)
|
||||
{
|
||||
case WheeledVehicle::DriveTypes::Drive4W:
|
||||
{
|
||||
PxVehicleDrive4WRawInputData rawInputData;
|
||||
rawInputData.setDigitalAccel(throttle > deadZone);
|
||||
rawInputData.setDigitalBrake(brake > deadZone);
|
||||
rawInputData.setDigitalSteerLeft(wheelVehicle->_steering < -deadZone);
|
||||
rawInputData.setDigitalSteerRight(wheelVehicle->_steering > deadZone);
|
||||
rawInputData.setDigitalHandbrake(wheelVehicle->_handBrake > deadZone);
|
||||
PxVehicleDrive4WSmoothDigitalRawInputsAndSetAnalogInputs(keySmoothing, steerVsForwardSpeed, rawInputData, LastDeltaTime, false, *(PxVehicleDrive4W*)drive);
|
||||
break;
|
||||
}
|
||||
case WheeledVehicle::DriveTypes::DriveNW:
|
||||
{
|
||||
PxVehicleDriveNWRawInputData rawInputData;
|
||||
rawInputData.setDigitalAccel(throttle > deadZone);
|
||||
rawInputData.setDigitalBrake(brake > deadZone);
|
||||
rawInputData.setDigitalSteerLeft(wheelVehicle->_steering < -deadZone);
|
||||
rawInputData.setDigitalSteerRight(wheelVehicle->_steering > deadZone);
|
||||
rawInputData.setDigitalHandbrake(wheelVehicle->_handBrake > deadZone);
|
||||
PxVehicleDriveNWSmoothDigitalRawInputsAndSetAnalogInputs(keySmoothing, steerVsForwardSpeed, rawInputData, LastDeltaTime, false, *(PxVehicleDriveNW*)drive);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -789,8 +844,8 @@ void Physics::CollectResults()
|
||||
{
|
||||
if (WheelRaycastBatchQuery)
|
||||
WheelRaycastBatchQuery->release();
|
||||
WheelQueryResults.Resize(wheelsCount);
|
||||
WheelQueryResults.Resize(WheelQueryResults.Capacity());
|
||||
WheelQueryResults.Resize(wheelsCount, false);
|
||||
WheelHitResults.Resize(wheelsCount, false);
|
||||
PxBatchQueryDesc desc(wheelsCount, 0, 0);
|
||||
desc.queryMemory.userRaycastResultBuffer = WheelQueryResults.Get();
|
||||
desc.queryMemory.userRaycastTouchBuffer = WheelHitResults.Get();
|
||||
@@ -841,12 +896,18 @@ void Physics::CollectResults()
|
||||
auto drive = WheelVehiclesCache[ii];
|
||||
auto& perVehicle = WheelVehiclesResultsPerVehicle[ii];
|
||||
ii++;
|
||||
#if PHYSX_VEHICLE_DEBUG_TELEMETRY
|
||||
LOG(Info, "Vehicle[{}] Gear={}, RPM={}", ii, wheelVehicle->GetCurrentGear(), (int32)wheelVehicle->GetEngineRotationSpeed());
|
||||
#endif
|
||||
|
||||
// Update wheels
|
||||
for (int32 j = 0; j < wheelVehicle->_wheelsData.Count(); j++)
|
||||
{
|
||||
auto& wheelData = wheelVehicle->_wheelsData[j];
|
||||
auto& perWheel = perVehicle.wheelQueryResults[j];
|
||||
#if PHYSX_VEHICLE_DEBUG_TELEMETRY
|
||||
LOG(Info, "Vehicle[{}] Wheel[{}] longitudinalSlip={}, lateralSlip={}, suspSpringForce={}", ii, j, Utilities::RoundTo2DecimalPlaces(perWheel.longitudinalSlip), Utilities::RoundTo2DecimalPlaces(perWheel.lateralSlip), (int32)perWheel.suspSpringForce);
|
||||
#endif
|
||||
|
||||
auto& state = wheelData.State;
|
||||
state.IsInAir = perWheel.isInAir;
|
||||
@@ -857,23 +918,21 @@ void Physics::CollectResults()
|
||||
state.SteerAngle = RadiansToDegrees * perWheel.steerAngle;
|
||||
state.RotationAngle = -RadiansToDegrees * drive->mWheelsDynData.getWheelRotationAngle(j);
|
||||
state.SuspensionOffset = perWheel.suspJounce;
|
||||
#if USE_EDITOR
|
||||
state.SuspensionTraceStart = P2C(perWheel.suspLineStart);
|
||||
state.SuspensionTraceEnd = P2C(perWheel.suspLineStart + perWheel.suspLineDir * perWheel.suspLineLength);
|
||||
#endif
|
||||
|
||||
// Rotate wheel
|
||||
wheelData.Collider->SetLocalOrientation(Quaternion::Euler(0, state.SteerAngle, state.RotationAngle) * wheelData.LocalOrientation);
|
||||
if (!wheelData.Collider)
|
||||
continue;
|
||||
auto shape = wheelData.Collider->GetPxShape();
|
||||
|
||||
// Apply suspension offset (cannot move collider because it breaks driving so move it's children but preserve the initial pose)
|
||||
for (auto child : wheelData.Collider->Children)
|
||||
{
|
||||
int32 poseIndex = 0;
|
||||
for (; poseIndex < wheelData.ChildrenPoses.Count(); poseIndex++)
|
||||
{
|
||||
if (wheelData.ChildrenPoses[poseIndex].Child == child)
|
||||
break;
|
||||
}
|
||||
if (poseIndex == wheelData.ChildrenPoses.Count())
|
||||
wheelData.ChildrenPoses.Add({ child, child->GetLocalPosition() });
|
||||
child->SetPosition(wheelData.Collider->GetTransform().LocalToWorld(wheelData.ChildrenPoses[poseIndex].Pose) + Vector3(0, perWheel.suspJounce, 0));
|
||||
}
|
||||
// Update wheel collider transformation
|
||||
auto localPose = shape->getLocalPose();
|
||||
Transform t = wheelData.Collider->GetLocalTransform();
|
||||
t.Orientation = Quaternion::Euler(0, state.SteerAngle, state.RotationAngle) * wheelData.LocalOrientation;
|
||||
t.Translation = P2C(localPose.p) / wheelVehicle->GetScale() - t.Orientation * wheelData.Collider->GetCenter();
|
||||
wheelData.Collider->SetLocalTransform(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user