Fix car wheel location by applying compression of the suspension spring

This commit is contained in:
Wojtek Figat
2021-08-09 15:22:10 +02:00
parent d194a06e59
commit 8c97a645e9
3 changed files with 54 additions and 5 deletions

View File

@@ -300,6 +300,7 @@ 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;
@@ -507,11 +508,25 @@ void WheeledVehicle::Setup()
void WheeledVehicle::DrawPhysicsDebug(RenderView& view)
{
// Wheels shapes
for (auto& wheel : _wheels)
for (auto& data : _wheelsData)
{
int32 wheelIndex = 0;
for (; wheelIndex < _wheels.Count(); wheelIndex++)
{
if (_wheels[wheelIndex].Collider == data.Collider)
break;
}
if (wheelIndex == _wheels.Count())
break;
auto& wheel = _wheels[wheelIndex];
if (wheel.Collider && wheel.Collider->GetParent() == this && !wheel.Collider->GetIsTrigger())
{
DEBUG_DRAW_WIRE_CYLINDER(wheel.Collider->GetPosition(), wheel.Collider->GetOrientation(), wheel.Radius, wheel.Width, Color::Red * 0.8f, 0, true);
const Vector3 basePos = wheel.Collider->GetPosition();
const Vector3 currentPos = basePos + 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);
}
}
}
@@ -519,11 +534,25 @@ void WheeledVehicle::DrawPhysicsDebug(RenderView& view)
void WheeledVehicle::OnDebugDrawSelected()
{
// Wheels shapes
for (auto& wheel : _wheels)
for (auto& data : _wheelsData)
{
int32 wheelIndex = 0;
for (; wheelIndex < _wheels.Count(); wheelIndex++)
{
if (_wheels[wheelIndex].Collider == data.Collider)
break;
}
if (wheelIndex == _wheels.Count())
break;
auto& wheel = _wheels[wheelIndex];
if (wheel.Collider && wheel.Collider->GetParent() == this && !wheel.Collider->GetIsTrigger())
{
DEBUG_DRAW_WIRE_CYLINDER(wheel.Collider->GetPosition(), wheel.Collider->GetOrientation(), wheel.Radius, wheel.Width, Color::Red * 0.4f, 0, false);
const Vector3 basePos = wheel.Collider->GetPosition();
const Vector3 currentPos = basePos + 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_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);
}
}

View File

@@ -285,6 +285,12 @@ private:
Collider* Collider;
Quaternion LocalOrientation;
WheelState State;
struct ChildPose
{
Actor* Child;
Vector3 Pose;
};
Array<ChildPose, InlinedAllocation<4>> ChildrenPoses;
};
void* _drive = nullptr;

View File

@@ -847,10 +847,24 @@ void Physics::CollectResults()
state.TireFriction = perWheel.tireFriction;
state.SteerAngle = RadiansToDegrees * perWheel.steerAngle;
state.RotationAngle = -RadiansToDegrees * drive->mWheelsDynData.getWheelRotationAngle(j);
const float suspensionOffsetDelta = perWheel.suspJounce - state.SuspensionOffset;
state.SuspensionOffset = perWheel.suspJounce;
// Rotate wheel
wheelData.Collider->SetLocalOrientation(Quaternion::Euler(0, state.SteerAngle, state.RotationAngle) * wheelData.LocalOrientation);
// 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));
}
}
}
}