Procedural
30 posts

#12726
3D rotations with 3D Gibbs vectors in place of 4D quaternions 2 weeks ago Edited by on Aug. 12, 2017, 6:04 p.m.
Recently I discovered that Gibbs vectors multiply and rotate exactly like quaternions (because they are quaternions), but using only 3 values instead of 4.
Here's C code to try them yourself, it can be compiled with no compile parameters in both Clang and Visual Studio:
Basically, Gibbs vectors encode quaternion's scalar part to the vector part with divisions on all vector elements. That's it. You can also try them in GpuLib's Instancing and MRT example, `build_vs2015.bat` and `build_vs2017.bat` are available. 
mmozeiko
Mārtiņš Možeiko 1436 posts
1 project

#12727
3D rotations with 3D Gibbs vectors in place of 4D quaternions 2 weeks ago Edited by Mārtiņš Možeiko on Aug. 3, 2017, 7:01 a.m.
Hmm... This looks very interesting!
If I understand correctly this cannot represent 180° rotations because of division by 0, right? Probably this is not issue for some cases, but with this limitation it cannot completely replace matrix. In your example this works because tan value is approximated to 13245402.0 which is "very large" number (but not infinity). I'm wondering if for some cases tan will return ±∞ and all calculations further will be incorrect... Maybe it will never happen because no floating point value will get close enough to ±π/2. 
Procedural
30 posts

#12728
3D rotations with 3D Gibbs vectors in place of 4D quaternions 2 weeks ago mmozeiko In the real world, in the actual reality of real time graphics, when we multiply at least 2 orientations, quaternions will always be cheaper than matrices, so even if Gibbs vectors fail somehow you can always fallback to them. mmozeiko Right, in that case I would write a custom tan that won't return infinity. mmozeiko This is correct too, in GpuLib example I never saw any issues like that. What are the chances of a camera rotation or animation hitting one of the axes exactly at floating point 0b0000_0000_0000_0000_0000_0000_0000_0000 or 0b0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000? Close to 0. :) 
ratchetfreak
290 posts

#12729
3D rotations with 3D Gibbs vectors in place of 4D quaternions 1 week, 6 days ago
there is also the chance that a.w * b.w  (a.x * b.x + a.y * b.y + a.z * b.z) = 1dot(A, B) will end up 0.
This is a very likely spot for catastrophic cancellation which will ruin your accuracy. 
mmozeiko
Mārtiņš Možeiko 1436 posts
1 project

#12730
3D rotations with 3D Gibbs vectors in place of 4D quaternions 1 week, 6 days ago Edited by Mārtiņš Možeiko on Aug. 3, 2017, 9:12 a.m. Procedural The problem is not about hitting value exactly 0 or 180 or any other. The problem with floats is that if you get close enough to some discontinuity which can happen with much higher probability, the calculations will become very unstable. The results produced will become very large or ∞ or NaN. And later calculations will propagate this error further. As a result you'll get weird glitches in rendering or sudden jumps in rotation which could be super annoying to debug or eliminate. 
Procedural
30 posts

#12731
3D rotations with 3D Gibbs vectors in place of 4D quaternions 1 week, 6 days ago mmozeiko Isn't any divide in any math code ever suffers from the same problem? I will not guard my code against divide by 0 anywhere other than in vector length procedure... Will you? 
gingerBill
Ginger Bill 211 posts
2 projects
I am ginger thus have no soul. 
#12732
3D rotations with 3D Gibbs vectors in place of 4D quaternions 1 week, 6 days ago
With unit quaternions, there is no worry with dividing by zero. However, with Rodrigues/Gibbs Parameters (RPs) as Mārtiņš has pointed out, 180° rotations cannot be represented, even in floating pointer.
Modified Rodrigues parameters (MRPs) can be used to solve this issue but it only pushes the problem to 360°. These objects are an exponential mapping of the 3D rotations (exponential map of so(3), the Lie algebra of SO(3)). To represent a 3D rotation, you need at a minimum 4 degrees of freedom (pieces of information): the axis of rotation (x, y, z) and the angle of rotation (θ). Quaternions encode this with no information loss as they have 4 values. RPs rely on the fact that the axis of rotation is unit length thus you can "lose" a degree of freedom. Even with this fact, you lose other niceties as you have found. Quaternions seem to be the best solution to the problem for representing 3D rotations on a computer. 
Procedural
30 posts

#12733
3D rotations with 3D Gibbs vectors in place of 4D quaternions 1 week, 6 days ago gingerBill The code is updated for extracting an axis and angle from a Gibbs vector. 
mmozeiko
Mārtiņš Možeiko 1436 posts
1 project

#12734
3D rotations with 3D Gibbs vectors in place of 4D quaternions 1 week, 6 days ago Edited by Mārtiņš Možeiko on Aug. 3, 2017, 4:57 p.m. Proceduralmmozeiko That's exactly my point  you don't guard against those because there is no solution. Nor in vector normalization, nor for this rotation. For vectors normalization this is not a problem, because you cannot normalize vector without length. You design your algorithms / functionality in a way that doesn't produce these invalid vectors. And if they occur, that's a bug or impossible situation. For example, let's say you need normalized direction from some object to light source to use in lighting equation. In real life this will always be non0 vector when you subtract object position from light position. Sure in case the positions are the same (or almost the same) the vector will be nonnormalizeable (the result will be huge or NaN). But that's ok, in such case it is ok to have a glitch. Because in realworld this never happens  light cannot be at same position as object. And if it is, then nobody knows what to expect result to be. So the software can do whatever it wants, no need to "guard" against divide by 0. But in Gibbs rotations the algorithm is designed to not work for 180° or in case ratchetfreak mentions. But these cases are perfectly normal, the expected result is strictly defined, but they will misbehave. Nevertheless, I like the idea. I'm sure this representation can work just fine for some use cases. Just not the 100% replacement for rotation matrix/quaternion. 
Procedural
30 posts

#12745
3D rotations with 3D Gibbs vectors in place of 4D quaternions 1 week, 5 days ago mmozeiko ratchetfreak's problem is not a problem for unit quaternions (and Gibbs vectors are of unit length) as Ginger Bill mentioned, you can check it yourself by printing dot product in `gmul` procedure. As of 180°, the only solution to this problem is: Deal With It™ :) I mean, the context is everything. Mouse / gamepad camera rotations? 180° rotations are not possible here. Character animation? If you can think of a character that can rotate its limbs for more than 180° in one operation? I personally can't. I don't know where else you can use >180° rotations, leave a comment below which real world example actually require this. In the context of gamedev I can't think of any! 
gingerBill
Ginger Bill 211 posts
2 projects
I am ginger thus have no soul. 
#12746
3D rotations with 3D Gibbs vectors in place of 4D quaternions 1 week, 5 days ago
It actually is a problem. RPs can be zero unlike quaternions.
Other than curiosity, I see no benefit to using RPs over quaternions for practical use. RPs cause more problems than they solve. Other than memory footprint, they have no advantage over quaternions. 
Procedural
30 posts

#12747
3D rotations with 3D Gibbs vectors in place of 4D quaternions 1 week, 5 days ago gingerBill It is not, until proven otherwise. I can't make dot product return 1, if you know how let us know. gingerBill By more problems you mean one? Saving space is not practical enough for you? gingerBill This is one MASSIVE advantage if we talk space for hundreds of thousands of vectors, and one 180° in one op problem no one even proved to be real so far, because in the real world, in animation, people always lerp. 
gingerBill
Ginger Bill 211 posts
2 projects
I am ginger thus have no soul. 
#12748
3D rotations with 3D Gibbs vectors in place of 4D quaternions 1 week, 5 days ago Edited by Ginger Bill on Aug. 4, 2017, 10:56 a.m.
First off, how do you encode an zero rotation, half a turn or a full turn around a particular axis? At these particular rotations (depending on the particular encoding), it removes all the information about its axis. With quaternions, all angles of rotation are unique and still keep all the information unlike RPs where the same rotation can be represented in multiple ways.
You lose information when you reduce the degrees of freedom. If saving space is that much of a concern, multiplying the axis by its angle will achieve the same thing whilst also removing most of the angle rotation problems but then the calculations become a little more costly. Another way to save space is to use a smaller type like 32bit float or a 16bit float. But personally, I don't think that saving one extra component outweighs the costs you get from the extra instructions needed to calculate the products. Show me the evidence that the memory saving cost is worth it over the performance one in the real world and not the theoretical one. 
ratchetfreak
290 posts

#12749
3D rotations with 3D Gibbs vectors in place of 4D quaternions 1 week, 5 days ago Edited by on Aug. 4, 2017, 11:02 a.m. Procedural eh no. The entire point of Gibbs is that the length encodes the rotation angle, so they are not of unit length. Procedural Rotations are composed from a base orientation. So any time the object is 180° in the other direction the Gibbs will break down. For example take a car on a flat surface turning in a circle. At some point it needs to be rotated 180° compared to the starting position. At that point your car will glitch out and depending on how you created the turning transform (iteratively or closed function) will add inaccuracies for the future. So it may recover or it will remain with a glitched transform until it gets reset. You can't lerp or slerp Gibbs and get the same result as the quaternions unless you normalize them to quaternions. So if you want space savings then just drop the w component and use sqrt(1dot(q3, q3)) to get it back when needed. 
gingerBill
Ginger Bill 211 posts
2 projects
I am ginger thus have no soul. 
#12750
3D rotations with 3D Gibbs vectors in place of 4D quaternions 1 week, 5 days ago Edited by Ginger Bill on Aug. 4, 2017, 11:12 a.m.
Quaternions are used for storing an orientation, not just rotations. RPs cannot do this. I'll repeat this again:
You lose information when you reduce the degrees of freedom. Exponential maps in general have this problem. Matrix: Easily composed; cannot interpolate Euler Angle: Not easily composed; you can sometimes interpolate them; can joint limit; has Gimbal lock Angle Axis: Not easily composed; can interpolate; can joint limit; avoids gimbal lock Quaternion: Easily composed; can interpolate; can joint limit (but difficult); avoids gimbal lock Exponential Map: Easily composed; cannot interpolate; cannot joint limit easily; can have gimbal lock 