• 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

Making use of quaternions

5 posts in this topic

At the moment I'm rotating an object about its local yaw, pitch and roll axes using matrices as follows:


    D3DXMATRIX matYaw; D3DXMatrixRotationAxis(&matYaw, &up, OrientationDelta.x); //Build a yaw rotation axis

    D3DXVec3TransformCoord(&forward, &forward, &matYaw); D3DXVec3TransformCoord(&right, &right, &matYaw); //Apply the yaw transformation

    D3DXMATRIX matPitch; D3DXMatrixRotationAxis(&matPitch, &right, OrientationDelta.y); //Build a pitch rotation axis

    D3DXVec3TransformCoord(&forward, &forward, &matPitch); D3DXVec3TransformCoord(&up, &up, &matPitch); //Apply the pitch transformation

    D3DXMATRIX matRoll; D3DXMatrixRotationAxis(&matRoll, &forward, OrientationDelta.z); //Build a roll rotation axis

    D3DXVec3TransformCoord(&right, &right, &matRoll); D3DXVec3TransformCoord(&up, &up, &matRoll); //Apply the roll transformation

    OrientationMatrix *= matPitch*matYaw*matRoll; //Adjust the orientation matrix


Here, I'm rotating incrementally about three local axis vectors: up, forward and right. I am doing a small amount of rotation per frame (a delta value rather than an actual value) because I need to rotate the up, forward and right vectors along with my object to ensure that they stay as local axes.


I'm interested in converting this to use quaternions so that I don't have to worry about reorthogonalising my three local axis vectors every frame by taking vector cross products, etc... but I can't see how I'd do it. Surely to ensure that the object continues to rotate about its local yaw, pitch and roll axes, I'll need to keep using my three vectors and also my rotation matrices like I have above?


Thanks for your help!


Share this post

Link to post
Share on other sites

I'm interested in converting this to use quaternions so that I don't have to worry about reorthogonalising my three local axis vectors every frame by taking vector cross products, etc... but I can't see how I'd do it. Surely to ensure that the object continues to rotate about its local yaw, pitch and roll axes, I'll need to keep using my three vectors and also my rotation matrices like I have above?
Thanks for your help!


sorry dude, looks like its not happening.


i've been researching this myself.


see these recent threads...






in a nutshell, quats accumulate error less quickly, but still get whacked after a while.


even rolling your own long double or long long fixed point implementation of mats or quats will eventually get whacked due to cumulative incremental local rotation precision errors.  but depending on how long the game runs, long long fixed point might do it without getting too whacked by the end.


i've decided to stick with mats and gram shmitt for the moment, and hope that induced drift can be lived with.


note that selection of axes when normalizing will determine where the drift shows up and which turns will be accurate.

if you preserve the forward vector and adjust the other two, roll will work, and yaw and pitch will drift.

if you preserve up, yaw should work pixel perfect, and pitch and roll will drift.

if you preserve right, pitch will work, and yaw and roll will drift.


in the past i've preserved forward, and lived with drifting pitch at high screen resolutions.


but its probably better to preserve up or right (your preference), so either yaw or pitch drifts a bit, but not both.


there this whole rats nest mess of what type of  data structure to store orientation in, and how to rotate that orientation about local axes.


the graphics engine uses mats. orientation can be stored a number of ways (mat; quat; vector & roll; Eulers; fwd,up,right [i,j,k] vectors; etc). turning uses mat mul, quat mul, or rotation about arbitrary axis, and i think double or triple skew is another possible method. movement use direction vector. AI (mine at least) uses Euler angles.


rotation about an arbitrary axis may be a possibility. first time i got 3 degree rotational freedom working, i used fwd,up,right vectors, rotation about arbitrary axis formula, and gramm-shmitt.   but given that i was using gram-shmitt there, a float implementation of arb axis still wouldn't cut it.


so, given this rats nest, i've decided for the moment to use mats for orientation. mat mul turns them easily (orientation = local_rotation  * orientation), you can use gramm-shmitt to keep them orthogonal: normalize(&orientation). the graphics engine can use the mat directly (world = scale * orientation * translation). the movement engine can use the 3rd column vector (forward vector) directly (x+=speed*fwd.x, y+=speed*fwd.y, etc). and euler angles can be easily extracted for use by AI, etc. code for extracting eulers from mat is posted in the above mentioned threads.



note also that your turn rate, if very small, will induce error faster.


overhead of normalize() doesn't seem to be an issue in this day and age, even normalizing after every incremental rotation.

Edited by Norman Barrows

Share this post

Link to post
Share on other sites

here's the normalize routine i posted in the first thread mentioned above...




void normalize()
Prot is global player's rotation matix
D3DXVECTOR3 v1,v2,v3,   // 3 original axes
            v4,v5,v6;   // 3 ortho normal axes
note that this version keeps the forward (z) vector fixed, and adjusts up and right vectors.
for fixed y (up local axis):
y is column v2.
so its  v1 = norm(v2 x v3), v3=norm(v1 x v2), v2=norm(v2).
for fixed x (right local axis):
x is column v1.
so its  v2 = norm(v1 x v3), v3=norm(v1 x v2), v1=norm(v1).
you should be able to cut and paste this directly into any D3D app and pass a D3DXMATRIX directly to it.
consider it a freebie sample from Rockland Software Productions'   Z game library. <g>
note also that it actually uses a global player orientation matrix "Prot". you may want to change this to use a matrix passed by reference.

Share this post

Link to post
Share on other sites

I already do something similar - I hold three vectors called up, right and forward, and I renormalise and cross them every frame to make sure they stay orthonormal. I keep the up vector constant though. I think it's the same. Thanks anyway!


Share this post

Link to post
Share on other sites

now i'm checking into the QR decomposition mentioned in the thread you mentioned. but it may be overkill. we're using gram-schmidt to "fix up" skewed (imprecise) axes. since the axes are already imprecise, i don't see a hi-rez normalize making things any better, possibly not worse, but not any better. unless some of the drift is caused by the inaccuracy of gram-schmidt. yet another thing to test i guess.


the full local ortho-normal basis mentioned in that thread is similar to the fwd, up, and right axes that you use, and i've used in the past. most likely combined with rotation about an arbitrary axis. and using the rotation about axis formulas: x'= x*cos(theta) + y*sin(theta) kind thing. i think i recognize the add and mul counts (2 muls 4 adds per point, per axis, was it? been a long time since i did it that way). actually its the "5 2d rotations" in that thread that tipped me off. this is how i actually did it. 


you see, i was working on a starship flight sim. i was about to licence rend386. then MS bought the company, and took it off the market. they then spent a year turning it into directx v1.0.  so during that time, i was forced to write my own perspective correct texture mapped poly engine (my own version of directx). it didn't use matrices, just 2d rotations. same difference, but matrices do all the math at once, instead of one axis at a time.


but it looks like the slickest implementation will be:

orientation = local_rotation * orientation



when you get it up and running, splash some bogies for me!


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