Public Group

# Third person rotation

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

## Recommended Posts

Hi all, I was trying to do a third person view for days now, but could get nothing to work properly. According to the gamedev tutorial http://www.gamedev.net/reference/articles/article1591.asp I was able to get this thing running quite good. But... I can only rotate around the y axis. So, if I want to rotate around the x axis I tried to add this: float cameray = cameradist * Math.sin((xrot * Math.PI / 180.0) + ypos); Works fine but the rotation gets inversed wehen i get too low or too high. What to do about that?

##### Share on other sites
That's called Gimbal lock, and is a problem inherent in trying to represent rotations with Euler angles, which is probably what you are doing.

To remedy this, you need a different representation of rotations. The most straightforward is probably to use a rotation matrix. I recommend using a ready-made math library (such as CML) for usable matrix and vector data types.

##### Share on other sites
ahh okay... got that. Heard of the Gimbal Lock before, but never experienced. Am kind a new to 3D programming. Can you tell me where to find good tutorials on matrices? I really want to understand the whole thing instead of (before) using pre-coded classes an functions.
Uhm... do you know any good Java Math Libs, beside VecMath?

##### Share on other sites
There's a sample chapter here that gives some great explanations for how to understand matrices geometrically, though it would be best if you already understand vectors before reading it. If you don't, there's a long sample chapter here that covers them.

##### Share on other sites
Quote:
 Original post by HnefiThat's called Gimbal lock, and is a problem inherent in trying to represent rotations with Euler angles, which is probably what you are doing.
Umm, no. This has nothing whatsoever to do with gimbal lock - nor does gimbal lock have much to do with the particular representation.

Quote:
 Original post by hasta84Works fine but the rotation gets inversed wehen i get too low or too high.
At what point does the inversion happen, and which axis becomes inverted? I assume the y axis, but does it flip before the vertical (since obviously, it will flip if you go past vertical).

Also, why is + ypos inside the Math.sin() cal in your code snippet there?

##### Share on other sites
Quote:
Original post by swiftcoder
Quote:
 Original post by HnefiThat's called Gimbal lock, and is a problem inherent in trying to represent rotations with Euler angles, which is probably what you are doing.
Umm, no. This has nothing whatsoever to do with gimbal lock

Oops. You are right. I used the wrong terminology. I'm unable to find any terminology to describe this phenomenon. What's it called?
Quote:
 - nor does gimbal lock have much to do with the particular representation.

Actually, it does. Quaternions, for example, does not suffer from gimbal lock.

##### Share on other sites
Hi,

I spent the last days now almost only for studying matrices and quaternions and I think I now know what those are and what you can do. But... I just can't understand how to describe my desired rotation with one of them. That just won't go in my head. I read many tutorials on quaternions and matrices to do rotations... I now almost think I'm an idiot because I can't do a rotation...
I work with Java and lwjgl by the way...

There are so many questions...
Some tutorials work with the "right-vector", what's that?
One says the Up Vector can be ignored, the other that it's important?
What's true?
All tutorials I found were on opengl and C or C# or C++, isn't there any tutorial on Java so I can understand how it works in code?

Greetings, hasta

##### Share on other sites
Hey, I tried to solve it with gluLookAt, but how to combine the rotX and rotY?

import java.util.logging.Level;import java.util.logging.Logger;import org.lwjgl.LWJGLException;import org.lwjgl.input.Keyboard;import org.lwjgl.input.Mouse;import org.lwjgl.opengl.*;import org.lwjgl.util.glu.GLU;import org.lwjgl.util.vector.Vector3f;public class test { static Vector3f camPos = new Vector3f(); static float distance = 4.0f; static float angleY = 0.0f; static float angleX = 0.0f; public static void main(String[] args){ try { DisplayMode displayMode = null; Display.setFullscreen(false); DisplayMode[] d = Display.getAvailableDisplayModes(); for (int i = 0; i < d.length; i++) { if (d.getWidth() == 640 && d.getHeight() == 480 && d.getBitsPerPixel() == 32) { displayMode = d; break; } } Display.setDisplayMode(displayMode); Display.setTitle("test"); Display.create(); GL11.glShadeModel(GL11.GL_SMOOTH); GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); GL11.glClearDepth(1.0f); GL11.glEnable(GL11.GL_DEPTH_TEST); GL11.glDepthFunc(GL11.GL_LEQUAL); GL11.glMatrixMode(GL11.GL_PROJECTION); GL11.glLoadIdentity(); GLU.gluPerspective(45.0f, (float) displayMode.getWidth() / (float) displayMode.getWidth(),0.1f,100.0f); GL11.glMatrixMode(GL11.GL_MODELVIEW); GL11.glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT, GL11.GL_NICEST); boolean running = true; Mouse.create(); while(running){ if(Mouse.isButtonDown(0)){ angleY += Mouse.getDX() * 0.5f; angleX += Mouse.getDY() * 0.5f; } if(Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)) { // Exit if Escape is pressed running = false; } if(Display.isCloseRequested()) { // Exit if window is closed running = false; } GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT); GL11.glMatrixMode(GL11.GL_MODELVIEW); GL11.glLoadIdentity(); float camX = (float) (distance * Math.sin(angleY * Math.PI / 180.0)); float camZ = (float) (distance * Math.cos(angleY * Math.PI / 180.0)); Vector3f rotY = new Vector3f(camX, camPos.y, camZ); float camY = (float) (distance * Math.sin(angleX * Math.PI / 180.0)); camZ = (float) (distance * Math.cos(angleX * Math.PI / 180.0)); Vector3f rotX = new Vector3f(camPos.x, camY, camZ); //Take the Y rotation camPos.x = rotY.x; camPos.z = rotY.z; //Take the X rotation //camPos.y = rotX.y; //camPos.z = rotX.z; GLU.gluLookAt(camPos.x, camPos.y, camPos.z, 0, 0, 0, 0, 1, 0); GL11.glBegin(GL11.GL_TRIANGLES); GL11.glColor3f(1.0f,0.0f,0.0f); GL11.glVertex3f( 0.0f, 1.0f, 0.0f); GL11.glColor3f(0.0f,1.0f,0.0f); GL11.glVertex3f(-1.0f,-1.0f, 1.0f); GL11.glColor3f(0.0f,0.0f,1.0f); GL11.glVertex3f( 1.0f,-1.0f, 1.0f); GL11.glColor3f(1.0f,0.0f,0.0f); GL11.glVertex3f( 0.0f, 1.0f, 0.0f); GL11.glColor3f(0.0f,0.0f,1.0f); GL11.glVertex3f( 1.0f,-1.0f, 1.0f); GL11.glColor3f(0.0f,1.0f,0.0f); GL11.glVertex3f( 1.0f,-1.0f, -1.0f); GL11.glColor3f(1.0f,0.0f,0.0f); GL11.glVertex3f( 0.0f, 1.0f, 0.0f); GL11.glColor3f(0.0f,1.0f,0.0f); GL11.glVertex3f( 1.0f,-1.0f, -1.0f); GL11.glColor3f(0.0f,0.0f,1.0f); GL11.glVertex3f(-1.0f,-1.0f, -1.0f); GL11.glColor3f(1.0f,0.0f,0.0f); GL11.glVertex3f( 0.0f, 1.0f, 0.0f); GL11.glColor3f(0.0f,0.0f,1.0f); GL11.glVertex3f(-1.0f,-1.0f,-1.0f); GL11.glColor3f(0.0f,1.0f,0.0f); GL11.glVertex3f(-1.0f,-1.0f, 1.0f); GL11.glEnd(); Display.update(); } Display.destroy(); } catch (LWJGLException ex) { Logger.getLogger(test.class.getName()).log(Level.SEVERE, null, ex); System.exit(0); } }}

This is what i have so far to test...

##### Share on other sites
Quote:
Original post by Hnefi
Quote:
 Original post by swiftcoder- nor does gimbal lock have much to do with the particular representation.

Actually, it does. Quaternions, for example, does not suffer from gimbal lock.

swiftcoder has it right - you can run into gimbal lock while using quaternions, and you can also avoid them if you use vectors and matrices appropriately. See the third post, followed quickly by the second, here for a full discussion.

##### Share on other sites
Okay, but that doesn't help me with my problem...

How do I combine the two rotations into one?

• ### What is your GameDev Story?

In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us.

• 27
• 16
• 10
• 10
• 11
• ### Forum Statistics

• Total Topics
634100
• Total Posts
3015527
×