LWJGL Camera Pitch and Yaw

Well I decided about a week ago to try (again) to learn LWJGL, and it’s actually a very easy library now that I have more experience. It’s a lot of fun to use. Once deciding to move onto 3D, which I’m more used to, I started following SHC’s tutorials. They’re very nice, thanks for them if you see this.

After following his tutorial for a camera class, I decided to add in a few of my own things primarily pitch, roll, and yaw in order to make a first person ‘flying’ type camera for the fun of it. I have almost everything working perfectly, but for some reason my pitch isn’t being applied to my movement correctly. If I look up at a slight angle I fly up at that angle perfectly fine, however if I look almost straight up, it just flies at what seems to be a 45 degree angle.
However, funnily enough when I go down while looking straight up, it works perfectly. The video below will show that as well.

Here’s what I’m doing to calculate the movement:


	public void move(float amount, float direction) {
		position.z += amount * Math.sin(Math.toRadians(rotation.y + 90 * direction + yaw));
		position.x += amount * Math.cos(Math.toRadians(rotation.y + 90 * direction + yaw));
		position.y += amount * Math.sin(Math.toRadians(pitch));
	}

The Y part is the part where I’m pretty much guessing, so that’s most likely what’s wrong.
As well as my rotations:


	public void apply() {
		view.setIdentity();

		Matrix4f.rotate((float) Math.toRadians(rotation.x + pitch), xAxis, view, view);
		Matrix4f.rotate((float) Math.toRadians(rotation.y + yaw), yAxis, view, view);
		Matrix4f.rotate((float) Math.toRadians(rotation.z), zAxis, view, view);

		Matrix4f.translate(position, view, view);
	}

I’m a little shaky on matrix math, so excuse me if it’s an elementary problem.

Also, here’s a video demonstrating the problem, note that when I do go straight up and down, I am pressing the Spacebar (up) and Control (down) buttons. I’m using WASD for movement.

BTJ9chsecoM

if you want this done correctly, the x, y , and z axis change every time you rotate.

This is how i did it in my 3D engine. In psuedo code


public class Object
{
         vector4 xAxis = (1, 0, 0, 0);
         vector4 yAxis = (0, 1, 0, 0);
         vector4 up     = (0, 1, 0, 0);
         vector3 zAxis = (0, 0, 1, 0);
         mat4 totalRotation = identity;
         
        public void move(Direction axis)
        {
               switch(axis)
               {
                       case X:
                             position += xAxis * speed;
                             break;
                             ...
               }
         }
        
         public void rotate(Direction axis, float amount)
         {
                  switch(axis)
                  {
                          case X:
                                Mat4 extraRot = createMat4(xAxis, amount);
                                yAxis = extraRot * yAxis;   
                                zAxis = extraRot * zAxis;
                                totalRot = extraRot * totalRot;
                                break;
                          case Y:  //if you are doing an fps camera use up axis
                                      //to form the matrix, else use yAxis
                                 Mat4 extraRot = createMat4(up, amount);
                                xAxis = extraRot * xAxis;   
                                yAxis = extraRot * yAxis;
                                zAxis = extraRot * zAxis;
                                totalRot = extraRot * totalRot;
                                break;
                        }
                  }
         }

Okay, I understand the movement part, however I’m not clear on the rotation. How would I create a matrix out of a vector and a float?

Look into using Quaterions or AngleAxis matrices.

heres a good explanation of angle- axis: and it has code/etc

http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToMatrix/index.htm

I use this function to move around.


/**
 * Move the camera with an amount in a direction.
 */
public void move(float amount, float direction)
{
    position.z += amount * Math.sin(Math.toRadians(rotation.y + 90 * direction));
    position.x += amount * Math.cos(Math.toRadians(rotation.y + 90 * direction));
}

And my apply method.


/**
 * Apply the camera's transformations.
 */
public void apply()
{
    // Make the view matrix an identity.
    view.setIdentity();

    // Rotate the view
    Matrix4f.rotate((float) Math.toRadians(rotation.x), xAxis, view, view);
    Matrix4f.rotate((float) Math.toRadians(rotation.y), yAxis, view, view);
    Matrix4f.rotate((float) Math.toRadians(rotation.z), zAxis, view, view);

    // Move the camera
    Matrix4f.translate(position, view, view);
}

And to move the model,


/**
 * Update logic
 */
public void update(long elapsedTime)
{
    if (isKeyDown(KEY_ESCAPE))
        end();

    // Look up
    if (isKeyDown(KEY_UP))
        camera.addRotation(-1f, 0, 0);

    // Look down
    if (isKeyDown(KEY_DOWN))
        camera.addRotation(1f, 0, 0);

    // Turn left
    if (isKeyDown(KEY_LEFT))
        camera.addRotation(0, -1f, 0);

    // Turn right
    if (isKeyDown(KEY_RIGHT))
        camera.addRotation(0, 1f, 0);

    // Move front
    if (isKeyDown(KEY_W))
        camera.move(0.1f, 1);

    // Move back
    if (isKeyDown(KEY_S))
        camera.move(-0.1f, 1);

    // Strafe left
    if (isKeyDown(KEY_A))
        camera.move(0.1f, 0);

    // Strafe right
    if (isKeyDown(KEY_D))
        camera.move(-0.1f, 0);

    // Move Up
    if (isKeyDown(KEY_Z))
        camera.addPosition(0, 0.1f, 0);

    // Move Down
    if (isKeyDown(KEY_X))
        camera.addPosition(0, -0.1f, 0);
}

I know, I’ve been following you’re tutorials as I said in the above post :slight_smile:
They’re really great, thanks for taking the time to write them.

Anyways, I’ve solved my issue by using Quaternions as my rotation stuff, as The Lion King suggested.

Thanks guys