1
votes

Hello i have an issue with a returning value of the glm lookAt function. When i am executing in debug mode, i get at this point ... Result[3][2] = dot(f, eye); ... of the glm function a wrong value in the translate z-position of the matrix. The value is -2, that shows me that the forward and eye vector are in the opposite position. My eye, center and up vectors are eye(0,0,2), center(0,0,-1) and up(0,1,0). The cam coodinate vectors are: f(0,0,-1), s(1,0,0) and u(0,1,0). And the vantage point the user looks at is (0,0,0). So the right view matrix should be this one:

1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1

but i get this one:

1  -0  0   -0
-0  1 -0   -0
0   0   1  -2
0   0   0   1

My code is:

struct camera {
vec3 position = vec3(0.0f);         // position of the camera
vec3 view_direction = vec3(0.0f);   // forward vector (orientation)
vec3 side = vec3(0.0f);             // right vector (side)
vec3 up = vec3(0.0f, 1.0f, 0.0f);   // up vector
float speed = 0.1;
float yaw = 0.0f;                   // y-rotation
float cam_yaw_speed = 10.0f;        // 10 degrees per second
float pitch = 0.0f;                 // x-rotation
float roll = 0.0f;      

...
// calculate the orientation vector (forward) 
vec3 getOrientation(vec3 vantage_point) {
    // calc the difference and normalize the resulting vector
    vec3 result = vantage_point - position;
    result = normalize(result);
    return result;
}

// calculate the right (side) vector of the camera, by given orientation(forward) and up vectors
mat4 look_at_point(vec3 vantage_point) {
    view_direction = getOrientation(vantage_point);

    // calculate the lookat matrix
    return lookAt(position, position + view_direction, up);
}
};

I have tryied to figure out how to manage this problem but i still have no idea. Can someone help me?

The main function where i am executing the main_cam.look_at_point(vantage_point) function is showed below:

...
GLfloat points[] = {
0.0f, 0.5f, 0.0f,
0.5f,  0.0f, 0.0f,
-0.5f, 0.0f, 0.0f };

float speed = 1.0f; // move at 1 unit per second

float last_position = 0.0f;

// init camera
main_cam.position = vec3(0.0f, 0.0f, 2.0f);         // don't start at zero, or will be too close
main_cam.speed = 1.0f;                              // 1 unit per second
main_cam.cam_yaw_speed = 10.0f;                     // 10 degrees per second
vec3 vantage_point = vec3(0.0f, 0.0f, 0.0f);

mat4 T = translate(mat4(1.0), main_cam.position);
//mat4 R = rotate(mat4(), -main_cam.yaw, vec3(0.0, 1.0, 0.0));
mat4 R = main_cam.look_at_point(vantage_point);
mat4 view_matrix = R * T;

// input variables
float near = 0.1f;      // clipping plane
float far = 100.0f;     // clipping plane
float fov = 67.0f * ONE_DEG_IN_RAD; // convert 67 degrees to radians
float aspect = (float)g_gl_width / (float)g_gl_height;  // aspect ratio

mat4 proj_matrix = perspective(fov, aspect, near, far);

use_shader_program(shader_program);
set_uniform_matrix4fv(shader_program, "view", 1, GL_FALSE, &view_matrix[0][0]);
set_uniform_matrix4fv(shader_program, "proj", 1, GL_FALSE, &proj_matrix[0][0]);
...

Testing with the rotate function of glm the triangle is shown right.

Triangle shown with the rotate function of glm

1
If your camera is at eye=(0,0,2) then the second matrix is the correct one, not the first. Why do you think otherwise?LYakov Galka
You're right but why is my triangle not displayed. It looks like the camera looks in the oposite direction but why?Mike
What triangle? Please provide a Minimal, Complete, and Verifiable example. We cannot see your drawing code. You can verify your hypothesis by replacing position + view_direction with position - view_direction. If it won't work (and it shouldn't) then the problem must be somewhere else.Yakov Galka
Your'e right sorry, i have provided the code example aboveMike
Something else going on there perhaps. Culling enabled? Winding order correct? We don't know what shader_program is doing either.Robinson

1 Answers

1
votes

I suspect that the problem is here:

mat4 view_matrix = R * T; // <---

The matrix returned by lookAt already does the translation.

Try manually applying the transformation on the (0,0,0) point that is inside your triangle. T will translate it to (0,0,2), but now it coincides with the camera, so R will send it back into (0,0,0). Now you get a division by zero accident in the projective divide.

So remove the multiplication by T:

mat4 view_matrix = R;

Now (0,0,0) will be mapped to (0,0,-2), which is in the direction camera is looking. (In camera space the center-of-projection is at (0,0,0) and the camera is looking towards the negative Z direction).


EDIT: I want to point out that calculating the view_direction from vantage_point and then feeding position + view_direction back into lookAt is a rather contrived way of achieving your goals. What you do in getOrientation function is what lookAt already does inside. Instead you can get the view_direction from the result of lookAt:

mat4 look_at_point(vec3 vantage_point) {
    // calculate the lookat matrix
    mat4 M = lookAt(position, vantage_point, up);
    view_direction = -vec3(M[2][0], M[2][1], M[2][2]);
    return M;
}

However, considering that ultimately you're trying to implement yaw/pitch/roll camera controls, you are better off to not using lookAt at all.