• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
IggyPop

Decompressing Quaternion Problem

13 posts in this topic

Hi,

I'm a little bit stuck with decompressing my Quaternions used in key frame animation. Angles that are close to 180 are some times negative when they should not and vise versa.

Instead of -179.6 it should be 179.6 which causes a whole ~360 degree rotation when translating between say frame 5-10 since I drop certain frames.

My compression code:

[source lang="cpp"]
if(q.w < 0)
q.Flip(); // positive so i don't have to store sign

double scale = sqrt( q.v.x * q.v.x + q.v.y * q.v.y + q.v.z * q.v.z + q.w * q.w);

scale = (32767.0 / scale ) + 0.5;

floor(q.v.x * scale);
floor(q.v.y * scale);
floor(q.v.z * scale);
[/source]

Which gives me 3 signed __int16 values.

My Decompression code:
[source lang="cpp"]
static double scale = 32767.0 - 0.5;

q.v.x /= scale;
q.v.y /= scale;
q.v.z /= scale;

double temp = ( (q.v.x * q.v.x) + (q.v.y * q.v.y) + (q.v.z * q.v.z) );
if(temp > 1)
{
// wtf
}
q.w = sqrt(1 - temp);

[/source]

Also I sometimes get values of 'temp' that are > 1 which makes no sense (to me).

So if anyone can spot the error that would be great, I'm still learning [img]http://public.gamedev.net//public/style_emoticons/default/smile.png[/img]



[u]Results of my searching around before making a topic:[/u]

I came across a post on here that seamed relevant but I'm unsure as to what extra checks are required.
(Snip of post)
[quote]

There are a couple of issues with this. First you need an additional sign bit to distinguish between w being posive and negative, both of which are possible. You can avoid this though by checking the sign of w before compressing and if it's negative multiply the whole quaternion by -1, so w is always positive and you take the positive square root when decompressing. But this can cause problems for some data - e.g. by introducing jumps into a sequence of keyframes of an animation, requiring extra checks when interpolating them.
[/quote]

Original Topic: [url="http://www.gamedev.net/topic/461253-compressed-quaternions/"]http://www.gamedev.n...ed-quaternions/[/url]


I've also read: [b]Game Programming Gems 3: Section 2.4[/b] on quaternion compression be to no avial.


Thanks for your time.
0

Share this post


Link to post
Share on other sites
You seem to be partially aware of the fact that q and -q both represent the same rotation. When you try to interpolate between two rotations, make sure the dot product of the two is positive, and flip one of them if it isn't.

Also, this seems wrong to me:
[code] scale = (32767.0 / scale ) + 0.5;

floor(q.v.x * scale);
//...[/code]

You probably meant this:
[code] scale = 32767.0 / scale;

floor(q.v.x * scale + 0.5); // Add 0.5 so effectively we round, instead of flooring (can be implemented as a `round' function)
//...[/code]
0

Share this post


Link to post
Share on other sites
[quote name='alvaro' timestamp='1341457549' post='4955831']
You seem to be partially aware of the fact that q and -q both represent the same rotation. When you try to interpolate between two rotations, make sure the dot product of the two is positive, and flip one of them if it isn't.
[/quote]

Yer I'm aware that both (-x, -y, -z, -w) and (x, y, z ,w) are the same angle.

And I flip it so I can take the postive square root.

[quote name='alvaro' timestamp='1341457549' post='4955831']
When you try to interpolate between two rotations, make sure the dot product of the two is positive, and flip one of them if it isn't.
[/quote]

wait what your talking about when decompressing or compressing ?

My code works fine in terms of correct angle just when translating between 2 animation key frames it gets messed up.


[quote name='alvaro' timestamp='1341457549' post='4955831']
Also, this seems wrong to me:
[code] scale = (32767.0 / scale ) + 0.5;

floor(q.v.x * scale);
//...[/code]

You probably meant this:
[code] scale = 32767.0 / scale;

floor(q.v.x * scale + 0.5); // Add 0.5 so effectively we round, instead of flooring (can be implemented as a `round' function)
//...[/code]
[/quote]

In my code I have the later I just made fails when removing my rnd() macro when posting topic, it makes no sense why i added 0.5 on the end of scale reading it myself lol.
0

Share this post


Link to post
Share on other sites
[quote name='IggyPop' timestamp='1341466706' post='4955846']
[quote name='alvaro' timestamp='1341457549' post='4955831']
When you try to interpolate between two rotations, make sure the dot product of the two is positive, and flip one of them if it isn't.
[/quote]

wait what your talking about when decompressing or compressing ?[/quote]
Neither.

[quote]My code works fine in terms of correct angle just when translating between 2 animation key frames it gets messed up.[/quote]
This is what I am talking about. I don't know what "translating between 2 animation key frames" means, but one typically needs to fill in the frames between key frames, and does so by interpolating the data. When you interpolate between two rotations that are represented as quaternions, you need to do what I said: Check that the dot product of the two quaternions is positive, and flip one of them if it isn't.

[quote]In my code I have the later I just made fails when removing my rnd() macro when posting topic, it makes no sense why i added 0.5 on the end of scale reading it myself lol.
[/quote]
It's kind of annoying when people post edited code instead of what they are actually using, because very frequently they introduce new mistakes. I understand the need to simplify the code to show the problem more clearly, but you need to make sure the code you are posting still behaves the way you describe, so compile it and test it.

Particularly if you need help figuring out something like why sometimes the length is more than 1, post real code.
0

Share this post


Link to post
Share on other sites
[quote name='alvaro' timestamp='1341488534' post='4955930']
This is what I am talking about. I don't know what "translating between 2 animation key frames" means, but one typically needs to fill in the frames between key frames, and does so by interpolating the data. When you interpolate between two rotations that are represented as quaternions, you need to do what I said: Check that the dot product of the two quaternions is positive, and flip one of them if it isn't.
[/quote]

A thanks that might be the tip I needed.

I'll be more clear about what I'm doing interms of "[i]translating between 2 animation key frames[/i]"

I'm reading the compressed quaternion and then converting it to Euler so that I can set a bones rotation via MEL in Maya.

For example sake I have rotation data for frames 1, 5, 10

some example data (made up):

Frame 1: -90, 0 , 179.2
Frame 5: -85, 2, - 179.8
Frame 10: -88, 3, 178.4


When the animation is played the bone rotates allmost 360 between the two keyframes when there should only be 2-3 degrees of rotation.




[quote name='alvaro' timestamp='1341457549' post='4955831']
It's kind of annoying when people post edited code instead of what they are actually using, because very frequently they introduce new mistakes. I understand the need to simplify the code to show the problem more clearly, but you need to make sure the code you are posting still behaves the way you describe, so compile it and test it.

Particularly if you need help figuring out something like why sometimes the length is more than 1, post real code.
[/quote]

no problem I won't post edited code again, also was not a good idear to edit it after been awake for 26hrs lmao.
0

Share this post


Link to post
Share on other sites
[quote name='IggyPop' timestamp='1341501640' post='4956005']
I'll be more clear about what I'm doing interms of "[i]translating between 2 animation key frames[/i]"

I'm reading the compressed quaternion and then converting it to Euler so that I can set a bones rotation via MEL in Maya.

[...]

When the animation is played the bone rotates allmost 360 between the two keyframes when there should only be 2-3 degrees of rotation.
[/quote]

Well, Euler angles are a notoriously bad representation to interpolate, so you shouldn't do that regardless. Interpolate the quaternions (look up slerp and nlerp), then convert to Euler angles if you really have to because of the particularities of some API.
0

Share this post


Link to post
Share on other sites
[quote name='alvaro' timestamp='1341504390' post='4956016']
[quote name='IggyPop' timestamp='1341501640' post='4956005']
I'll be more clear about what I'm doing interms of "[i]translating between 2 animation key frames[/i]"

I'm reading the compressed quaternion and then converting it to Euler so that I can set a bones rotation via MEL in Maya.

[...]

When the animation is played the bone rotates allmost 360 between the two keyframes when there should only be 2-3 degrees of rotation.
[/quote]

Well, Euler angles are a notoriously bad representation to interpolate, so you shouldn't do that regardless. Interpolate the quaternions (look up slerp and nlerp), then convert to Euler angles if you really have to because of the particularities of some API.
[/quote]

Would that not require the quaternions to be correct ?

Since if I slerp it's just going to give me values between frame 1 - 5 which is not what I need but frames 5 angles to be correct.
0

Share this post


Link to post
Share on other sites
I don't think you understand what the problem is. Or perhaps I don't. It's not that the angles at frame 5 are incorrect, but it's that interpolating angles doesn't do what you want. So interpolate quaternions instead, which behaves much much better.
0

Share this post


Link to post
Share on other sites
[quote name='alvaro' timestamp='1341595484' post='4956386']
I don't think you understand what the problem is. Or perhaps I don't. It's not that the angles at frame 5 are incorrect, but it's that interpolating angles doesn't do what you want. So interpolate quaternions instead, which behaves much much better.
[/quote]

Ok I explain again just to make sure, thanks for you help so far.


Some frames have angles that are negative for example -179.9 when THEY should be 179.9 in order for the animation to be correct.

So when I key frame 1 as 179.9 and frame 5 as -179.9(the incorrect angle) maya translates between frames rotating 360 degrees (to get from -179 to 179) instead of there been very little rotation if the correct angles are used.


-179.9 is the same as 180.1 which would only cause 0.2 degress of rotation between frames like it should be.
Is there a reason the anlge is negative when it shouldn't be, maybe it's todo with been so close to 180. Edited by IggyPop
0

Share this post


Link to post
Share on other sites
-179.9 and 180.1 are the same angle. So the angle isn't "incorrect" in any meaningful way. If the point is that it should be 179.9 and not 180.1, you need to make your code more robust.

Again, if you use quaternions during the interpolation, many problems will go away. Edited by alvaro
0

Share this post


Link to post
Share on other sites
[quote name='alvaro' timestamp='1341666279' post='4956629']
-179.9 and 180.1 are the same angle. So the angle isn't "incorrect" in any meaningful way. If the point is that it should be 179.9 and not 180.1, you need to make your code more robust.

Again, if you use quaternions during the interpolation, many problems will go away.
[/quote]

yes they are the same angle but Maya requires Euler angles. so the problem arises when maya translates between them.

The top is what I want but the bottom is what happens: (since it dose a whole 360 spin to get from negative 180 to postivie 180)

[img]http://www.tom-bmx.com/img/jss/20120707-5g9-46kb.jpg[/img]
0

Share this post


Link to post
Share on other sites
[quote name='alvaro' timestamp='1341671464' post='4956645']
Can you tell Maya what the angles are at every frame, instead of letting it interpolate?
[/quote]

Yes I can Id need to generate the values myself tho.

I've been looking into the curve editor in Maya and wrote the basias of a c++ plugin for maya gonna have a play with that see what happens.
0

Share this post


Link to post
Share on other sites
Ok After more and more time spent on google, I finaly stumble apon this:

[url="http://download.autodesk.com/global/docs/maya2013/en_us/index.html?url=files/Keyframe_Animation_Set_rotation_interpolation_for_curves.htm,topicNumber=d30e220991"]http://download.autodesk.com/global/docs/maya2013/en_us/index.html?url=files/Keyframe_Animation_Set_rotation_interpolation_for_curves.htm,topicNumber=d30e220991[/url]

[img]http://www.tom-bmx.com/img/jss/20120710-psx-156kb.jpg[/img]

This now makes animation curves take the shortest route to the next angle, fixing the 359 degress of rotation, instead of the 1 degree intended.


Thanks for all your input [b]alvaro[/b] :)
0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0