diff --git a/Source/Engine/Physics/Actors/WheeledVehicle.cpp b/Source/Engine/Physics/Actors/WheeledVehicle.cpp index 9051c7eed..a68bc23c7 100644 --- a/Source/Engine/Physics/Actors/WheeledVehicle.cpp +++ b/Source/Engine/Physics/Actors/WheeledVehicle.cpp @@ -59,9 +59,7 @@ void WheeledVehicle::SetWheels(const Array &value) { 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) + if (Math::NotNearEqual(oldWheel.SuspensionForceOffset, newWheel.SuspensionForceOffset) || oldWheel.Collider != newWheel.Collider) { softUpdate = false; break; @@ -352,6 +350,9 @@ void WheeledVehicle::OnDebugDrawSelected() // 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); diff --git a/Source/Engine/Physics/Actors/WheeledVehicle.h b/Source/Engine/Physics/Actors/WheeledVehicle.h index 49c00b17a..acf20310f 100644 --- a/Source/Engine/Physics/Actors/WheeledVehicle.h +++ b/Source/Engine/Physics/Actors/WheeledVehicle.h @@ -158,23 +158,6 @@ API_CLASS(Attributes="ActorContextMenu(\"New/Physics/Wheeled Vehicle\"), ActorTo API_FIELD(Attributes="Limit(0)") float ClutchStrength = 10.0f; }; - /// - /// Vehicle wheel types. - /// - API_ENUM() enum class WheelTypes - { - // Left wheel of the front axle. - FrontLeft, - // Right wheel of the front axle. - FrontRight, - // Left wheel of the rear axle. - RearLeft, - // Right wheel of the rear axle. - RearRight, - // Non-drivable wheel. - NoDrive, - }; - /// /// Vehicle wheel settings. /// @@ -183,11 +166,6 @@ API_CLASS(Attributes="ActorContextMenu(\"New/Physics/Wheeled Vehicle\"), ActorTo DECLARE_SCRIPTING_TYPE_MINIMAL(Wheel); API_AUTO_SERIALIZATION(); - /// - /// Wheel placement type. - /// - API_FIELD(Attributes="EditorOrder(0)") WheelTypes Type = WheelTypes::FrontLeft; - /// /// 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. /// diff --git a/Source/Engine/Physics/PhysX/PhysicsBackendPhysX.cpp b/Source/Engine/Physics/PhysX/PhysicsBackendPhysX.cpp index 99bc093fc..e55b80008 100644 --- a/Source/Engine/Physics/PhysX/PhysicsBackendPhysX.cpp +++ b/Source/Engine/Physics/PhysX/PhysicsBackendPhysX.cpp @@ -58,7 +58,9 @@ #if WITH_PVD #include #endif - +#if USE_EDITOR +#include "Editor/Editor.h" +#endif // Temporary memory size used by the PhysX during the simulation. Must be multiply of 4kB and 16bit aligned. #define PHYSX_SCRATCH_BLOCK_SIZE (1024 * 128) @@ -3367,18 +3369,42 @@ PxVehicleAckermannGeometryData CreatePxVehicleAckermannGeometryData(PxVehicleWhe return ackermann; } -bool SortWheels(WheeledVehicle::Wheel const& a, WheeledVehicle::Wheel const& b) +bool SortWheelsFrontToBack(WheeledVehicle::Wheel const& a, WheeledVehicle::Wheel const& b) { - return (int32)a.Type < (int32)b.Type; + return a.Collider && b.Collider && a.Collider->GetLocalPosition().Z > b.Collider->GetLocalPosition().Z; } void* PhysicsBackend::CreateVehicle(WheeledVehicle* actor) { - // TODO: handle PxVehicleDrive4WWheelOrder internally rather than sorting wheels directly on the vehicle - if (actor->_driveType == WheeledVehicle::DriveTypes::Drive4W) +#if USE_EDITOR + if (Editor::IsPlayMode) +#endif { - // Drive4W requires wheels to match order from PxVehicleDrive4WWheelOrder enum - Sorting::QuickSort(actor->_wheels.Get(), actor->_wheels.Count(), SortWheels); + // 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); + + // sort wheels by side + if (actor->_driveType == WheeledVehicle::DriveTypes::Tank) + { + for (int i = 0; i < actor->_wheels.Count() - 1; i += 2) + { + auto a = actor->_wheels[i]; + auto b = actor->_wheels[i + 1]; + + if (!a.Collider || !b.Collider) + continue; + + if (a.Collider->GetLocalPosition().X > b.Collider->GetLocalPosition().X) + { + actor->_wheels[i] = b; + actor->_wheels[i + 1] = a; + } + } + } } // Get wheels