Serhiy
Serhiy

Reputation: 4141

Multiple rotation of the camera

I'm trying to do some simple camera rotation in WebGL app(using lesson 10 from Learning WebGL), but I'm definetly doing something wrong.. I mean the horizontal movement of camera seems good,movement with WASD seems also OK, but when I'm adding the vertical movement, in some points of the map, something goes wrong and the map starts to incline. Where is my mistake? (demo is here)

what I'm doing is:

function handleMouseMove(event) {
    var canvas = document.getElementById("quak-canvas"); 
    var newX = event.clientX;
    var newY = event.clientY;

    var newRotationMatrix = mat4.create();
    mat4.identity(newRotationMatrix);

    var deltaY = newY - lastMouseY;
    mat4.rotate(newRotationMatrix, degToRad(deltaY / 40), [1, 0, 0]);

    var deltaX = newX - lastMouseX;
    horizontalAngle = (event.pageX/(canvas.width/2))*180;
    mat4.rotate(newRotationMatrix, degToRad(deltaX / 3.75), [0, 1, 0]);

    mat4.multiply(newRotationMatrix, moonRotationMatrix, moonRotationMatrix);

    lastMouseX = newX
    lastMouseY = newY;

    window.moveBy(10, 10);
}

I think there is some translate is missing or something like, but I have tried some combinations but it wasn't successfull..

Thanks a lot
Serhiy.

Upvotes: 0

Views: 375

Answers (1)

Toji
Toji

Reputation: 34498

First off, let me say that you're demo actually looks okay to me. Maybe it's a side effect of the dampened vertical rotation, but I don't see anything that looks too terribly off. Your code looks okay too for the most part. I think the core of your problem may be the matrix multiply at the end. The fact that you're always building off the previous frame's results can lead to some complications.

In my FPS movement code I re-calculate the view matrix every frame like so:

 var viewMat = mat4.create();
 mat4.identity(viewMat);
 mat4.rotateX(viewMat, xAngle); // X angle comes from Y mouse movement
 mat4.rotateY(viewMat, yAngle); // Y angle comes from X mouse movement
 mat4.translate(viewMat, position);

The position is calculated when WASD are pressed like so:

var dir = vec3.create();
if (pressedKeys['W']) { dir[2] -= speed; }
if (pressedKeys['S']) { dir[2] += speed; }
if (pressedKeys['A']) { dir[0] -= speed; }
if (pressedKeys['D']) { dir[0] += speed; }
if (pressedKeys[32]) { dir[1] += speed; } // Space, moves up
if (pressedKeys[17]) { dir[1] -= speed; } // Ctrl, moves down

// Create an inverted rotation matrix to transform the direction of movement by
var cam = mat4.create();
mat4.identity(cam);
mat4.rotateY(cam, -yAngle);
mat4.rotateX(cam, -xAngle);

// Move the camera in the direction we are facing
mat4.multiplyVec3(cam, dir); 
vec3.add(position, dir);

Hopefully that helps you get a working solution for your own code!

Upvotes: 1

Related Questions