# Something I don't understand about smoothed rotations?

Discussion in 'Physics for ECS' started by PhilSA, Jan 1, 2021.

1. ### PhilSA

Joined:
Jul 11, 2013
Posts:
1,926
I need to calculate the rotation delta of a smoothed/interpolated transform from frame to frame, so that I can make another object rotate by exactly the same amount every frame. I calculate this rotation delta like this in a system that updates after TransformSystemGroup:

Code (CSharp):
1. [GenerateAuthoringComponent]
2. public struct TestRotationCopier : IComponentData
3. {
4.     public Entity Target;
5.     public LocalToWorld PreviousLocalToWorld;
6. }
7.
8. [UpdateAfter(typeof(TransformSystemGroup))]
9. public class CopyRotationDeltaFromInterpolationSystem : SystemBase
10. {
11.     protected override void OnUpdate()
12.     {
13.         Entities.ForEach((Entity entity, ref TestRotationCopier rotationCopier) =>
14.         {
15.             // Calculate rotation delta of target
16.             LocalToWorld targetLocalToWorld = GetComponent<LocalToWorld>(rotationCopier.Target);
17.             quaternion targetRotationDelta = math.mul(math.inverse(rotationCopier.PreviousLocalToWorld.Rotation), targetLocalToWorld.Rotation);
18.
19.             // Apply rotation delta to self
20.             LocalToWorld selfLocalToWorld = GetComponent<LocalToWorld>(entity);
21.             selfLocalToWorld.Value = new float4x4(math.mul(targetRotationDelta, selfLocalToWorld.Rotation), selfLocalToWorld.Position);
22.             SetComponent(entity, selfLocalToWorld);
23.
24.             // Remember previous LtW
25.             rotationCopier.PreviousLocalToWorld = targetLocalToWorld;
26.         }).Schedule();
27.     }
28. }
Now here's the problem: my other object that's supposed to rotate by the same amount as the tracked object rotates slightly faster, and also rotates by a huge rotation every now and then. For example, here the camera tries to track the rotation of the orange platform: https://i.gyazo.com/53cb69c19b435a952ae7fa72a45acbcd.mp4

What's weird is that if instead of using the LocalToWorld.Rotation, I just use the Rotation (from the actual transform), the issue disappears completely (but there's another issue because now my camera rotation isn't properly interpolated anymore, which means this causes visual jitter of the platform): https://i.gyazo.com/106d9e5a5a56c4aec062d4c747ca9bb5.mp4

Last edited: Jan 1, 2021
2. ### PhilSA

Joined:
Jul 11, 2013
Posts:
1,926
Update:
I found out that scale has something to do with it. If the object that I'm trying to track the rotation of has a scale of (1,1,1), the problem disappears

I'm guessing this has nothing to do with physics graphics smoothing, but just with me not knowing the particularities of getting LocalToWorld.Rotation when there are non-unit scales? This thread seems to mention that issue as well

In the meantime, I've worked around the issue by getting the rotation like this instead:
Code (CSharp):
1. quaternion.LookRotationSafe(targetLocalToWorld.Forward, targetLocalToWorld.Up);

Last edited: Jan 1, 2021
3. ### milos85miki

Joined:
Nov 29, 2019
Posts:
197
Hi @PhilSA,

That's correct, you should use quaternion.LookRotationSafe or Unity.Physics.Math.DecomposeRigidBodyOrientation to get actual rotation. We're doing the same thing in CreateRigidBodies job in BuildPhysicsWorld.
Scale is multiplied with rotation matrix in LocalToWorld, to spare 1 matrix multiplication as you usually need to multiply with rotation and scale.

Hoping this clarifies things, please let us know if there's anything else to help with.