Jump to content
  • Advertisement
Sign in to follow this  
HermanssoN

OpenGL rotating stuff in OpenGL using quaternions

This topic is 3481 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello. I'm trying to rotate stuff in OpenGL using quaternions. I made a camera that works nice, but when I'm trying to rotate using glRotatef I'm getting wrong results. I was not sure if I should put this in the GL forum or the math forum. anyways, what I do is: on every frame. Quaternion Q; Q = Quaternion.FromAxisAngle(Vector3.UnitY, 0.005f); m_Rotation = Quaternion.Mult(Q, m_Rotation ); Normaly I use my own quaternion class but now I use OpenTKs quaternions to be sure that the math is correct when it is time to render. float Angle; Vector3 Axis; m_Rotation .ToAxisAngle(out Axis, out Angle); Gl.glRotatef(Angle, Axis.X, Axis.Y, Axis.Z); The result is not correct, the cube in this case, starts to rotate correctly but after a litle while, the Axis vector flipps from Y= 1 to Y = -1. And i don't know why :/ The most anoying thing is that my camera use tha same code for rotation. and it works like a charm. the difference is that i use gluLookAt so i don't have to use glRotatef. I have functions for extracting Right,At and Up from a quatenrion. I't would be nice if there where an example somewhere, like the spinning trinagle, that used quaternions.

Share this post


Link to post
Share on other sites
Advertisement
Here are a few things you might double-check:

1. Make sure you're not missing a radians<->degrees conversion.

2. If you're not doing this already, you should normalize m_Rotation after it's updated to compensate for numerical drift.

3. If the *observed* behavior is correct, but if you're just concerned because you're getting an axis with y = -1 rather than y = 1, it's probably just an aliasing issue (remember that [angle, 0, 1, 0] and [-angle, 0, -1, 0] represent the same rotation).

Not all of these would explain the behavior you're seeing, but it's probably worth double-checking these things anyway.

Also, although the axis-angle method should work, you could instead use glMultMatrixf() and see if that makes any difference (that is, build a matrix using the object position and the direction vectors as extracted from the quaternion, and submit it to OpenGL directly).

Share this post


Link to post
Share on other sites
Thnx for reply.
I just can't find the problem!

So i'm going to post the whole code snippet, I removed all but the vital code:


public class ECRenderer
{

private Quaternion m_Rot;
public ECRenderer()
{

m_Rot = Quaternion.Identity;
}


public void Render()
{
RotateY();
Vector3 Axis;
float Angle;

m_Rot.ToAxisAngle( out Axis, out Angle );
Gl.glRotatef(Angle, Axis.X, Axis.Y, Axis.Z);

Gl.glBegin(Gl.GL_TRIANGLES);

Gl.glColor3f(1, 0, 0);
Gl.glVertex3f(0, 20, 20);
Gl.glColor3f(0, 1, 0);
Gl.glVertex3f(8, 0, 20);
Gl.glColor3f(0, 0, 1);
Gl.glVertex3f(-8, 0, 20);

Gl.glEnd();


}
public void RotateY()
{
//Will be unit length, OpenTK return normalized
Quaternion Q2 = Quaternion.FromAxisAngle(Vector3.UnitY, 0.005f);
//Don't realy need to make a copy when pasing by ref, but just to rule it out
Quaternion Q1 = m_Rot;
Quaternion.Mult(ref Q1, ref Q2, out m_Rot);

m_Rot = Quaternion.Normalize(m_Rot);
}

}


This should, In my opinion, rotate the Triangle. The result is like before, it rotates like it should for a short while until that Axis flip. Worth mentioning is that Angle goes up to around 5 and than down again.

It feels like there is something I'm missing, or rather there must be :/

Share this post


Link to post
Share on other sites
Did you check all of the things I mentioned in my previous post? Have you confirmed that none of them is the problem?

Share this post


Link to post
Share on other sites
What you see there is all that happens.

there are no conversion from degrees to radians.

Quaternion.FromAxisAngle(Vector3.UnitY, 0.005f) return a normalized Quaternion

all that happens is

ECRenderer R = new ECRenderer();
while( !quit )
{
Update();//Check is 'Q' is pressed, if so quit
R.Render();
}


Share this post


Link to post
Share on other sites
radians

source from OpenTK:

public void ToAxisAngle(out Vector3 axis, out float angle)
{
Vector4 result = ToAxisAngle();
axis = result.Xyz;
angle = result.W;
}

/// <summary>
/// Convert this instance to an axis-angle representation.
/// </summary>
/// <returns>A Vector4 that is the axis-angle representation of this quaternion.</returns>
public Vector4 ToAxisAngle()
{
Quaternion q = this;
if (q.W > 1.0f)
q.Normalize();

Vector4 result = new Vector4();

result.W = 2.0f * (float)System.Math.Acos(q.W); // angle
float den = (float)System.Math.Sqrt(1.0 - q.W * q.W);
if (den > 0.0001f)
{
result.Xyz = q.Xyz / den;
}
else
{
// This occurs when the angle is zero.
// Not a problem: just set an arbitrary normalized axis.
result.Xyz = Vector3.UnitX;
}

return result;
}



Share this post


Link to post
Share on other sites
Holy hell, this is awkward.

just checked up glRotatef, and yes..it's in degrees..

Nice to know i got my math right, to bad I'm stupid :)

Thnx for your help!!

[Edited by - HermanssoN on March 15, 2009 4:16:32 PM]

Share this post


Link to post
Share on other sites
Quote:
It's the normal glRotatef, so i gues radians.
All OpenGL implementations that I'm aware of use degrees.
Quote:
But eaven if it was degrees, the only thing that would happe is that the rotation would be very slow, right?
Not necessarily - depending on how periodicity and so on is handled by OpenGL and by your application, leaving the conversion out could lead to fairly unpredictable results.

Anyway, I'd try adding the conversion - it probably needs to be in there anyway, and who knows, it might fix the problem :)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!