Search In
• More options...
Find results that contain...
Find results in...

# Tweening three.js quaternions

## Recommended Posts

There are quite a few posts about this, but they're many years old, and many of them mention a plugin that can handle quaternions. What's the state today? Can GSAP tween quaternions, or do we still need a plugin?

Specifically, i'd like to use interpolate() with three.js quaternions.

(I know about three.js quaternion.slerp, but i need to interpolate over a dynamic number of values.)

##### Share on other sites

I don't have personal experience of this so I will bow out to anyone else that wants to help, but I didn't want to leave you hanging.

I did a bit of googling and stumbled on this thread on the three.js discourse site - does this help at all?

https://discourse.threejs.org/t/interpolate-between-different-poses/15202/4

https://jsfiddle.net/fqcs6epr/

• 1
##### Share on other sites
14 minutes ago, Cassie said:

I did a bit of googling and stumbled on this thread on the three.js discourse site - does this help at all?

Thanks for your response, but unfortunately that does not help.

Interpolating any linear values (like a 3D position) with GSAP is not a problem, but Quaternions can't be interpolated that way. The interpolating code must be aware of the meaning of the values. E.g. when you wanted to interpolate a rotation in degrees from 350 to 10, the code should go from 350...359..0...10, instead of going backwards from 350 to 10.

• 1
##### Share on other sites

Ah, I see. I'm afraid I'm not going to be able to help here.

Maybe @OSUblake or @Rodrigo will be able to help?

##### Share on other sites
7 minutes ago, 321dev said:

E.g. when you wanted to interpolate a rotation in degrees from 350 to 10, the code should go from 350...359..0...10, instead of going backwards from 350 to 10.

This seems like it could be a good use case for gsap's modifiers. Like @Cassie I'm not super familiar with what you are trying to do... can you set up a basic CodePen of what GSAP should/could be tweening?

https://greensock.com/docs/v3/GSAP/CorePlugins/ModifiersPlugin

• 3
##### Share on other sites

Yeah, I'd love to see. I'm really fascinated by this. It sounds like crazy sci-fi tweening.

##### Share on other sites

The modifiers might work, if i knew how to interpolate quaternions at low level - which i don't.

For now, i'll try to use "normal" Euler rotations like i found here:

See the Pen GRooLza by ste-vg (@ste-vg) on CodePen

and see how it goes.

• 1
##### Share on other sites
8 hours ago, 321dev said:

There are quite a few posts about this, but they're many years old, and many of them mention a plugin that can handle quaternions. What's the state today? Can GSAP tween quaternions, or do we still need a plugin?

That's from the flash days.

You should be able to just use onUpdate kind of like what shown here... although they are using Tween.js

• 1
##### Share on other sites
2 hours ago, 321dev said:

E.g. when you wanted to interpolate a rotation in degrees from 350 to 10, the code should go from 350...359..0...10, instead of going backwards from 350 to 10.

@GreenSock do you have some code for this? I can't find my demos that show this.

• 1
##### Share on other sites
10 minutes ago, OSUblake said:

@GreenSock do you have some code for this? I can't find my demos that show this.

That was just an example showing why the "normal" interpolation doesn't work with angles. I don't have code for this.

##### Share on other sites

I know, that's why I tagged someone else 😉

##### Share on other sites
19 minutes ago, OSUblake said:

You should be able to just use onUpdate kind of like what shown here... although they are using Tween.js

Yes, thanks. But as i mentioned in my OP, i know how to interpolate between two Quaternions using three.js method.

But i need to interpolate between more values, but i don't think just interpolating between 0 and 1, then 1 and 2, etc. will give a smooth result. But maybe i should try it out and check how bad it looks.

##### Share on other sites

What properties are you trying to animate? Do you have some psuedo code?

• 1
##### Share on other sites
45 minutes ago, OSUblake said:

What properties are you trying to animate? Do you have some psuedo code?

In an ideal world, i 'd like to use gsap.utils.interpolate like this:

```let q1 = new THREE.Quaternion()

let q2 = new THREE.Quaternion()

let q3 = new THREE.Quaternion()

var interp = gsap.utils.interpolate([q1, q2, q3]);

let qx = interp(0.3)```

##### Share on other sites

So using three.js's slerp is fine, you just need to interpolate an array of them?

Would something like this work?

```const interp = interpolate([q1, q2, q3]);

let qx = interp(0.3);

function interpolate(targets) {

const interpolators = [];
let len = targets.length;
const iLen = len - 2;
const q = new THREE.Quaternion();

for (let i = 1; i < len; i++) {
interpolators.push(slerp(targets[i - 1], targets[i], q));
}

len--;

return p => {
p *= len;
let i = Math.min(iLen, ~~p);
return interpolators[i](p - i);
}
}

function slerp(a, b, q) {
return p => {
// three.js slerp
return q.slerpQuaternions(a, b, p);
}
}```

• 1
##### Share on other sites

So this would first interpolate between items 0 and 1, then 1 and 2, and so on. That's what i planed to do, but i wasn't sure if the transitions were smooth (enough). I'll try it out tomorrow.

BTW:  Maybe gsap.utils.interpolate() could be expanded so that you could pass a custom function that interpolates between two elements?

Thanks a lot for your time and effort!

##### Share on other sites
1 minute ago, 321dev said:

So this would first interpolate between items 0 and 1, then 1 and 2, and so on.

Yep.

2 minutes ago, 321dev said:

BTW:  Maybe gsap.utils.interpolate() could be expanded so that you could pass a custom function that interpolates between two elements?

That's not a bad idea. Any thoughts on this @GreenSock?

##### Share on other sites
4 minutes ago, 321dev said:

That's what i planed to do, but i wasn't sure if the transitions were smooth (enough).

If it's not smooth, maybe make a simple demo so we can mess around and tweak it.

##### Share on other sites
2 hours ago, OSUblake said:

3 hours ago, 321dev said:

BTW:  Maybe gsap.utils.interpolate() could be expanded so that you could pass a custom function that interpolates between two elements?

That's not a bad idea. Any thoughts on this @GreenSock?

An interpolator for an interpolator? I'm a little fuzzy on what exactly you mean here - got a sketch of an API and a sample use case?

##### Share on other sites
18 minutes ago, GreenSock said:

An interpolator for an interpolator? I'm a little fuzzy on what exactly you mean here - got a sketch of an API and a sample use case?

The purpose is to enable gsap.utils.interpolate() to interpolate values it can't interpolate (correctly) otherwise, in my example a THREE.Quaternion

##### Share on other sites
19 minutes ago, 321dev said:

The purpose is to enable gsap.utils.interpolate() to interpolate values it can't interpolate (correctly) otherwise, in my example a THREE.Quaternion

Ha ha - I figured that much.  I'm asking about implementation details. What would this function look like exactly? How would it integrate with gsap.utils.interpolate()? Got pseudo code?

##### Share on other sites

Maybe like this?

```const interp = interpolate([q1, q2, q3], (start, end, progress) => {
// custom interpolation
return ...;
});```

##### Share on other sites
On 5/5/2021 at 6:02 PM, OSUblake said:

Maybe like this?

```
const interp = interpolate([q1, q2, q3], (start, end, progress) => {
// custom interpolation
return ...;
});```

Yeah, I'm not seeing a very clean way of fitting that in there. It'd take a lot of extra code to accommodate, and it would definitely muddy the API - it already has 4 different method signatures; this would literally double that.

I think for a situation like this, a custom plugin or an effect would be a more intuitive option. Or just a straight-up helper function like you suggested earlier.