Rotations with TWEEN.js and Needle

I’m creating positions in 3D space at witch I want a camera to be positioned, and decided to use Tween.js for interpolating between the current camera position and the target position.
But now I want to also use the target ´s rotation.

I tried something like this:

this._rotationTween = new Tween(this.gameObject.quaternion);
            this._rotationTween.easing(Easing.Quadratic.InOut);
            this._rotationTween?.to(newView.quaternion, 1000).start();

And also this:

this._rotationTween = new Tween(this.gameObject.quaternion);
            this._rotationTween.easing(Easing.Quadratic.InOut);
            this._rotationTween?.to(newView.quaternion, 1000).start().onUpdate((e, elapsed) => {
                this.gameObject.quaternion.set(e.x, e.y, e.z, e.w);
            });

The same technique i applied to positions, but when it comes to rotations, it just looks like it never properly updates. Can somebody tell me what I’m doing wrong?
PD: I tried the same with this.gameObject.rotation but the same behaviour happens

Original Post on Discord

by user 368204675922657280

Additional notes: The objects that I’m using are simply Emptyies in Unity.
I get a reference to those via:

    @serializable(GameObject)
    viewPositions : GameObject[] = [];

by user 368204675922657280

this works: Needle Engine Tweenjs Example (forked) - StackBlitz

the reason is: quaternions x y z w in three are properties: three.js/src/math/Quaternion.js at b447ff2911cbefcd650df5a18a905e7df882fc78 · mrdoob/three.js · GitHub

and tweenjs needs x y z w as keys in the input object to know what to animate

It kinda works, the tween part at least. Now question is, when it gets executed, I can se that the camera rotates down until it ends looking down the opposite way, I tried by inverting the target quaternion, but it doesn’t affect the result.

by user 368204675922657280

Current code looks like this:

            this._rotationTween = new Tween(this.gameObject.rotation);
            this._rotationTween.easing(Easing.Cubic.InOut);
            const targetRotation = newView.transform.getWorldQuaternion(new Quaternion()).invert();
            this._rotationTween?.to({x: targetRotation.x, y:targetRotation.y, z:targetRotation.z, w:targetRotation.w}, 1000).start();

PD: I was testing if using getWorldQuaterion() would make any difference.

by user 368204675922657280

Try with the getWorldQuaternion util method that needle engine has maybe.

Im not sure i understand what happens tho (rotating how? Can you show a video?)

I’m back :gentleblob:
@marcel :cactus: the thing its the next:
My idea is to mark certain locations inside Unity Editor by using empty objects (sometimes I want both position and rotation) so that I can loop between those, “extract” both properties and assign it to whatever I need at that moment (in this case is the camera, but it doesn’t have to be always).

Notes: I’m attaching two images, in this scene I have 2 buttons (the ones with numbers) that triggers a function which does exactly what I said above, the only problem is that the camera appears to look at the “reverse”.
Also important to note, I know that I can use the lookAt component, but I’m trying to avoid it on purpose, since as I said, it doesn’t have to be the camera all the times, I’m just using it to orient the forward vector of the empties towards a certain target inside Unity (thus the name of the objects inside the hierarchy in the first image).

Here’s the video to show exactly what is happening:

hierarchy.png

by user 368204675922657280

Hi! its me again with an update.
I Succeeded in fixing the thing, but I wanted to share my story for the case it happends to someone.
So the thing is: If you use the “standart method” directly on the camera object, weird things can happen (I disabled other components such as orbitControls.ts to be sure).

const newView = this.viewPositions[id];
const sourceRotation = this.gameObject.quaternion.clone();
const targetRotation = newView.transform.quaternion.clone();
this._rotationTween = new Tween(sourceRotation);
this._rotationTween.easing(Easing.Cubic.InOut);
this._rotationTween
  .to({x: targetRotation.x, y: targetRotation.y, z: targetRotation.z, w: targetRotation.w}, 1000)
  .onUpdate((updatedQuat, progress) => {
    this.gameObject.quaternion.slerp(updatedQuat, progress);
  })
  .start();

In this example, “viewPositions” is an array which inside unity would have references to empty objects, from witch I pretend to source their transformations (positions, and local rotation).

While fooling around trying things, at one point the interpolation distorted the render itself, at witch a lamp in my head turned on. I thought at that moment: What would happen if, instead of adding the component to the same object where the camera component is, I add it to an empty object which would serve as the parent to the ‘camera’ object?
And boom it worked just as intended!

If someone can explain to me why is it like that I would really love it!
So that’s all :gentleblob:

by user 368204675922657280

don’t know if i’m missing something but the example mixes Eulers (new Tween(this.gameObject.rotation)) and Quaternions (const anotherRotation = new Quaternion()...) so the tweened values do not make sense.

by user 395602247196737546

as far as i can see @De copied this in his snippets.

by user 395602247196737546

here’s one with using Eulers: Needle Engine Tweenjs Example (forked) - StackBlitz
(beware the Euler’sche limitations apply)

by user 395602247196737546

good catch!

and here with proper quaternion slerping: Needle Engine Tweenjs Example (forked) - StackBlitz

by user 395602247196737546

Thank you so much! your’e a hero
Yes I noticed the thing about the mixing between Eulers and Quaternions, but I’ll try this tomorrow, directly on the camera and i’ll be back with a follow up!

by user 368204675922657280

happy to help, it was a nice exercise for a tweenjs noob like myself :slightly_smiling_face:

by user 395602247196737546

@marcel :cactus: btw why do you guys use rotation in Euler form? kind of easy to trip over for unity devs :slightly_smiling_face:

by user 395602247196737546

Where do we? Typically we use quaternion. Three just exposes both “rotation” and “quaternion” which means that unfortunately it’s easy to confuse coming from Unity

I think it was my example from above which mixed rotation and quaternions :sweat_smile: