Description
I've been playing around with ragdoll-like setups using SixDOFConstraint for angular limits after exposing the API in Godot, and found that the engine is ignoring some of the angular limits.
Precisely, if the joint is at the proximal end of a limb, and the body's centre of mass is near the middle of the limb, under sustained torque, the constrained body can rotate well past the configured angular limits.
SixDOFConstraint with ESwingType::Pyramid does not robustly enforce angular limits when the constraint anchor is offset from the dynamic body's centre of mass.
The issue seems specific to the Pyramid swing path. Simple cases where the anchor is at the body's centre of mass, or where the torque axis is collinear with the anchor offset, clamp correctly.
Repro case
Important to separate single-joint and multi-joint. In the latter, the offset would have an accumulative effect
The two-joint chain repro case:
- static anchor -> upper limb -> lower limb
- joint anchors at limb ends, COMs at limb centres
- locked translation
- Pyramid swing
- asymmetric twist limit:
[-4, 135] deg
- swing Y/Z limits:
[-60, +60] deg
- steady mixed-axis torque for 360 simulation steps
Find tests attached:
Add_regression_tests_to_showcase_failures_with_pyramid_swing_limit_clamping.patch
Expected vs Actual results
For the two-joint test, the measured swing/twist values should remain within:
- twist:
[-19, +150] deg, ~ 26 deg with a 10 deg lim
- swing Y/Z:
[-75, +75] deg, offset ~-41 deg with a lower lim of -4 deg
Possible fix
In SwingTwistConstraintPart::CalculateConstraintProperties, the Pyramid swing path appears to use a single combined swing correction axis based on the clamped and current swing directions.
That works better for cone/elliptical swing limits, but Pyramid swing is rectangular in (swing_y, swing_z) space. When both Y and Z swing are limited, violations should be handled independently.
Description
I've been playing around with ragdoll-like setups using
SixDOFConstraintfor angular limits after exposing the API in Godot, and found that the engine is ignoring some of the angular limits.Precisely, if the joint is at the proximal end of a limb, and the body's centre of mass is near the middle of the limb, under sustained torque, the constrained body can rotate well past the configured angular limits.
SixDOFConstraintwithESwingType::Pyramiddoes not robustly enforce angular limits when the constraint anchor is offset from the dynamic body's centre of mass.The issue seems specific to the Pyramid swing path. Simple cases where the anchor is at the body's centre of mass, or where the torque axis is collinear with the anchor offset, clamp correctly.
Repro case
Important to separate single-joint and multi-joint. In the latter, the offset would have an accumulative effect
The two-joint chain repro case:
[-4, 135] deg[-60, +60] degFind tests attached:
Add_regression_tests_to_showcase_failures_with_pyramid_swing_limit_clamping.patch
Expected vs Actual results
For the two-joint test, the measured swing/twist values should remain within:
[-19, +150] deg, ~26 degwith a10 deglim[-75, +75] deg, offset ~-41 degwith a lower lim of-4 degPossible fix
In
SwingTwistConstraintPart::CalculateConstraintProperties, the Pyramid swing path appears to use a single combined swing correction axis based on the clamped and current swing directions.That works better for cone/elliptical swing limits, but Pyramid swing is rectangular in
(swing_y, swing_z)space. When both Y and Z swing are limited, violations should be handled independently.