**1 div and 3 muls vs 7 muls**,

They are as fast or maybe slightly faster than quaternions, please stop answering that made up by Ginger Bill issue, there are real problems with Gibbs vectors to solve than this.

3D rotations with 3D Gibbs vectors in place of 4D quaternions

Actually wait, I forgot @vurtun send me a link yesterday: https://gist.github.com/vurtun/82f65d6f88127d2e779949e61c2283e4

**1 div and 3 muls vs 7 muls**,

They are as fast or maybe slightly faster than quaternions, please stop answering that made up by Ginger Bill issue, there are real problems with Gibbs vectors to solve than this.

They are as fast or maybe slightly faster than quaternions, please stop answering that made up by Ginger Bill issue, there are real problems with Gibbs vectors to solve than this.

3D rotations with 3D Gibbs vectors in place of 4D quaternions

Edited by
Mārtiņš Možeiko
on
Benchmark for transforming a lot of vectors against the same quaternion or gibbs rotation: https://gist.github.com/mmozeiko/3d415e0e4783e7ab35b8a2eb1fcaec40

GCC 7.1.0 with "-ffast-math -O3":

MSVC2017 with "/fp:fast /Ox /Ot":

Using unique q/g per every vector trasnformation (so q and g are arrays with COUNT elements) doesn't change the timings much.

GCC 7.1.0 with "-ffast-math -O3":

1 2 | quats = 108.15msec gibbs = 137.24msec |

MSVC2017 with "/fp:fast /Ox /Ot":

1 2 | quats = 240.48msec gibbs = 257.08msec |

Using unique q/g per every vector trasnformation (so q and g are arrays with COUNT elements) doesn't change the timings much.

3D rotations with 3D Gibbs vectors in place of 4D quaternions

Try removing `if (unlikely(dot==1.0f)) return (v3){0,0,0}; /* a == b */`

3D rotations with 3D Gibbs vectors in place of 4D quaternions

Edited by
Mārtiņš Možeiko
on
GCC:

MSVC:

MSVC shows worse numbers than GCC here because it decides to not inline qrot/grot functions. If I force inlining with " /Dinline=__forceinline /fp:fast /Ox /Ot" the results are:

1 2 | quats = 107.97msec gibbs = 118.78msec |

MSVC:

1 2 | quats = 240.22msec gibbs = 222.37msec |

MSVC shows worse numbers than GCC here because it decides to not inline qrot/grot functions. If I force inlining with " /Dinline=__forceinline /fp:fast /Ox /Ot" the results are:

1 2 | quats = 114.57msec gibbs = 158.63msec |

3D rotations with 3D Gibbs vectors in place of 4D quaternions

Edited by
Procedural
on
Yeah, seeing same results on MSVC2017,

with "/fp:fast /Ox /Ot":

with "/Dinline=__forceinline /fp:fast /Ox /Ot":

with "/Dinline=__forceinline /fp:fast /Ox /Ot /arch:AVX2":

with "/fp:fast /Ox /Ot":

1 2 | quats = 252.16msec gibbs = 207.01msec |

with "/Dinline=__forceinline /fp:fast /Ox /Ot":

1 2 | quats = 122.35msec gibbs = 205.53msec |

with "/Dinline=__forceinline /fp:fast /Ox /Ot /arch:AVX2":

1 2 | quats = 94.28msec gibbs = 177.75msec |

3D rotations with 3D Gibbs vectors in place of 4D quaternions

Yes you can, I don't mind. WTFPL license :)

3D rotations with 3D Gibbs vectors in place of 4D quaternions

Edited by
Procedural
on
The real deal breaker for me is interpolation: while Gibbs vectors **can** interpolate just like quaternions, the error gets progressively worse as angle between the interpolated vectors approaches 180°.

For 45° the error is just 1°, from 45° to 90° the maximum error is 8°, from 90° to 135° is where it starts to break: 35° difference, from 135° to 180° it just becomes unusable. The error resembles an exponential curve or a parabola or something like that, I guess in theory one can find a way to weight 0.0 to 1.0 lerp's `t` values.

The code from the first post is updated.

I also added an example of compressing and restoring quaternions from Gibbs vectors: the orientation stays the same, but for a >180° quaternion Gibbs vector flips the axis and rotates to the same place from the opposite direction so that its angle stays under 180° :) If you don't care from which direction rotation happened and just want to rotate points to the same position, this can give you the same result compressed to 3 values.

For 45° the error is just 1°, from 45° to 90° the maximum error is 8°, from 90° to 135° is where it starts to break: 35° difference, from 135° to 180° it just becomes unusable. The error resembles an exponential curve or a parabola or something like that, I guess in theory one can find a way to weight 0.0 to 1.0 lerp's `t` values.

The code from the first post is updated.

I also added an example of compressing and restoring quaternions from Gibbs vectors: the orientation stays the same, but for a >180° quaternion Gibbs vector flips the axis and rotates to the same place from the opposite direction so that its angle stays under 180° :) If you don't care from which direction rotation happened and just want to rotate points to the same position, this can give you the same result compressed to 3 values.

3D rotations with 3D Gibbs vectors in place of 4D quaternions

mmozeiko, thank you! I mentioned you in repo's commit.

3D rotations with 3D Gibbs vectors in place of 4D quaternions

Here I plotted 9 correct weight values for Gibbs vector to interpolate from 0° to 180° exactly like quaternion, tried to fit a parabola between them but failed, maybe someone smarter than me will figure it out eventually :)

Casey Muratori

801 posts
/ 1 project

Casey Muratori is a programmer at Molly Rocket on the game 1935 and is the host of the educational programming series Handmade Hero.

3D rotations with 3D Gibbs vectors in place of 4D quaternions

Generally speaking, you do not want to use the exponential map for anything that isn't a differential rotation. It is properly the "angular velocity" vector, and behaves as it should for the operations one would want to perform there, so it makes some sense to use it thusly.

I do not know of any other scenario where you would prefer it over quaternions. Quaternions are better at just about everything, including interpolation, blending, joint behavior, orientation, and rotation.

Although I infer that the goal of the OP was to gain computation/space efficiency going from 4 parameters to 3, but I would point out that it is actually not the case that the fourth parameter of a quaternion is redundant. It actually encodes important information, which is where in the 720 degree angle space you are. When you go from [x,y,z,w] to [x/w,y/w,z/w], not only have you destroyed the stability of the representation by introducing an unnecessary divide, but you have also destroyed knowledge of the proper signs. [-x,-y,-z,w] and [x,y,z,-w] both map to [-x/w,-y/w,-z/w], and there's no way to ever get back.

Since most orientations in games encode the offset from parent space of a joint, 720 degrees is actually the right number of degrees because it prevents angles near 360 from appearing similar, when in fact they are not (since the organic joints we care about in games cannot "rotate through 360 degrees").

Even if somehow you found that you could eek out a small performance win with Gibbs vectors due to the reduced parameter space, I would certainly not be willing to trade all the benefits of quaternions away for it. I think people often forget that quaternions encode a larger space of rotations than matrices or the exponential map, and contrary to perhaps the prevailing wisdom, it is valuable that they do so, even if you're not a theoretical physicist :P

- Casey

I do not know of any other scenario where you would prefer it over quaternions. Quaternions are better at just about everything, including interpolation, blending, joint behavior, orientation, and rotation.

Although I infer that the goal of the OP was to gain computation/space efficiency going from 4 parameters to 3, but I would point out that it is actually not the case that the fourth parameter of a quaternion is redundant. It actually encodes important information, which is where in the 720 degree angle space you are. When you go from [x,y,z,w] to [x/w,y/w,z/w], not only have you destroyed the stability of the representation by introducing an unnecessary divide, but you have also destroyed knowledge of the proper signs. [-x,-y,-z,w] and [x,y,z,-w] both map to [-x/w,-y/w,-z/w], and there's no way to ever get back.

Since most orientations in games encode the offset from parent space of a joint, 720 degrees is actually the right number of degrees because it prevents angles near 360 from appearing similar, when in fact they are not (since the organic joints we care about in games cannot "rotate through 360 degrees").

Even if somehow you found that you could eek out a small performance win with Gibbs vectors due to the reduced parameter space, I would certainly not be willing to trade all the benefits of quaternions away for it. I think people often forget that quaternions encode a larger space of rotations than matrices or the exponential map, and contrary to perhaps the prevailing wisdom, it is valuable that they do so, even if you're not a theoretical physicist :P

- Casey

3D rotations with 3D Gibbs vectors in place of 4D quaternions

cmuratori

When you go from [x,y,z,w] to [x/w,y/w,z/w], not only have you destroyed the stability of the representation by introducing an unnecessary divide,

The only difference between a Gibbs vector and a quaternion is divide, if divide is unnecessary then it would become just a regular quaternion, isn't it? :)

Also, "destroyed" is a strong word to apply here, it's as if saying a plane crashes every time it lands on the runway, technically it's true, realistically this crash is controlled and not going to fully "destroy" a plane. If you're in a certain safe zone of operations, you're not going to "destroy" Gibbs vector stability.

cmuratori

but you have also destroyed knowledge of the proper signs. [-x,-y,-z,w] and [x,y,z,-w] both map to [-x/w,-y/w,-z/w], and there's no way to ever get back.

Depends on what you mean by getting back, [-x,-y,-z,w] and [x,y,z,-w] result in the same position in 3D, if you don't care from which direction rotation should happen and just want to point a vector in a specific direction, then the job can be done with both quaternion and Gibbs vector.

The code from the first post is updated with direction example.

3D rotations with 3D Gibbs vectors in place of 4D quaternions

Proceduralcmuratori

When you go from [x,y,z,w] to [x/w,y/w,z/w], not only have you destroyed the stability of the representation by introducing an unnecessary divide,

The only difference between a Gibbs vector and a quaternion is divide, if divide is unnecessary then it would become just a regular quaternion, isn't it? :)

Also, "destroyed" is a strong word to apply here, it's as if saying a plane crashes every time it lands on the runway, technically it's true, realistically this crash is controlled and not going to fully "destroy" a plane. If you're in a certain safe zone of operations, you're not going to "destroy" Gibbs vector stability.

cmuratori

but you have also destroyed knowledge of the proper signs. [-x,-y,-z,w] and [x,y,z,-w] both map to [-x/w,-y/w,-z/w], and there's no way to ever get back.

Depends on what you mean by getting back, [-x,-y,-z,w] and [x,y,z,-w] result in the same position in 3D, if you don't care from which direction rotation should happen and just want to point a vector in a specific direction, then the job can be done with both quaternion and Gibbs vector.

The code from the first post is updated with direction example.

his point that more often than not you

3D rotations with 3D Gibbs vectors in place of 4D quaternions

ratchetfreak

his point that more often than not you do care about the direction of rotation. If you set the quaternions up properly from the start you don't ever need to test the sign of dot(q1, q2) the 2 quaternions will just be correct from the get go.

Not sure what you mean...

3D rotations with 3D Gibbs vectors in place of 4D quaternions

Edited by
Procedural
on
ratchetfreak, I can only guess you meant that you need to check dot(g1, g2) if the angle between the Gibbs vector approaches 180°? I already said Gibbs vector interpolation is currently a real deal breaker (while an immediate rotation is as correct as quaternion one), but one can find the right weights for an exponential-like curve I posted in the screenshot above, if you weight them right you'll be able to interpolate correctly, and given 181° rotation Gibbs vector wraps to 179° in the other direction, any interpolation will always be in between 180°...