-
-
Notifications
You must be signed in to change notification settings - Fork 21.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[C#] Fix Transform3D.InterpolateWith
applying rotation before scale
#89843
[C#] Fix Transform3D.InterpolateWith
applying rotation before scale
#89843
Conversation
Transform3D.InterpolateWith
applying applying rotation before scaleTransform3D.InterpolateWith
applying rotation before scale
f13ddc5
to
e2ed63b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I remember I saw a PR similar to this for 2D (for GDScript, not C#) somewhere, but I forget. It might be better to have @aaronfranke check it as well since we discussed there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR is correct, and it matches C++ as noted.
Aside from everything already mentioned, also note that in Godot it's the convention that "thing" is parent-relative (rotation * self) and "local thing" is relative to the object's own transform (self * rotation), which this fix is consistent with.
AFAICT this seems to be bugged the same way in 3.5/3.x/4.1/4.2 and seems to be safe change, so I guess this PR should be cherry-picked to all of them? 🤔 |
Thanks! |
Cherry-picked for 4.2.2. |
Cherry-picked for 4.1.4. |
Cherry-picked for 3.6. |
Seen a user confused by
Transform3D transformC = transformA.InterpolateWith(transformB, 0.0f);
resulting in atransformC
being way different thantransformA
(specificallytransformC.Scale
not matchingtransformA.Scale
). Turns out there's a bug in the C# implementation of the method.Transform3D.InterpolateWith(Transform3D, real_t)
has the same implementation as in the core:godot/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs
Lines 129 to 146 in 99ff024
godot/core/math/transform_3d.cpp
Lines 97 to 112 in 99ff024
The issue is hidden in
Basis.SetQuaternionScale(Quaternion, Vector3)
which itself is the same as in the core, but the privateBasis.Rotate(Quaternion)
method used within is rotating locally instead of parentwise, as in the core:godot/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs
Lines 207 to 216 in 99ff024
godot/core/math/basis.cpp
Lines 889 to 892 in 99ff024
godot/core/math/basis.cpp
Lines 379 to 385 in 99ff024
This PR fixes this. Both
private Basis.Rotate(Quaternion)
andinternal Basis.SetQuaternionScale(Quaternion, Vector3)
affected by this change are not used anywhere else so shouldn't break anything else.Example:
Before (v4.2.1.stable.mono.official [b09f793]):
(
Transform3D transformC = transformA.InterpolateWith(transformB, 0.0f);
)After (this PR):