# Extract eye/camera position from a view Matrix

I'm trying to improve my Camera. This camera owns a target (vec3 _at), a position (vec3 _eye) and a view mat4. When I move the mouse, I perform a rotation to the view matrix, according to 2 angles (_angleY, _angleZ), so that it gives the feeling the world is turning and not the cam.

Here is what I have, which works :

// Called each frame
void Camera::look(bool rotation)
{
// Computes view Matrix
_view.lookAt(_eye.X,_eye.Y,_eye.Z,
_at.X, _at.Y, _at.Z,
0, 0, 1);

// Apply rotation to the matrix, according to angles
if(rotation) {
_view.rotate(_angleY, 0, 1, 0, _at);
_view.rotate(_angleZ, 0, 0, 1, _at);
}
}


This perfectly works. I'm able to make my world rotating around a selected target (vec3). My problem is that my eye position is not updated each frame since I update my angles which apply a new rotation. Then my eye position is wrong and I need it to be updated each frame for another calculation.

Then, I'm trying to extract the eye position after the rotation, update it, and set angles to 0 (hoping it's the best solution...)

Therefore, I need to extract the eye position of my camera, from my modelview matrix. Here is what I'm trying to do, according to what I read here , in the last comment :

void Camera::look(bool rotation)
{
// Computes view Matrix
_view.lookAt(_eye.X,_eye.Y,_eye.Z,
_at.X, _at.Y, _at.Z,
0, 0, 1);
if(_angleY != 0 || _angleZ !=0)
{
if(rotation) {
_view.rotate(_angleY, 0, 1, 0, _at);
_view.rotate(_angleZ, 0, 0, 1, _at);
}

Vector3D d;
d.X = _view[3];
d.Y = _view[7];
d.Z = _view[11];
// This creates a vector by multiplying -d by the mat3 part of the view matrix.
Vector3D retVec = _view.mul3(-d);
_eye = retVec;
}
}


few things which might be need :

void Matrix4::lookAt(float eyeX, float eyeY, float eyeZ, float targetX, float targetY, float targetZ, float upX, float upY, float upZ)
{
Vector3D axe (upX, upY, upZ);
Vector3D forward(targetX - eyeX, targetY - eyeY, targetZ - eyeZ);
Vector3D normal = Vector3D::crossProduct(forward, axe);   // normal = regard x Axe
Vector3D newAxe = Vector3D::crossProduct(normal, forward); // newAxe = normal x regard

// Normalize new vectors
forward.normalize();
normal.normalize();
newAxe.normalize();

// lookAt matrix
Matrix4 Matrix4;
Matrix4.values_[0] = (float)normal[0];
Matrix4.values_[1] = (float)normal[1];
Matrix4.values_[2] = (float)normal[2];
Matrix4.values_[4] = (float)newAxe[0];
Matrix4.values_[5] = (float)newAxe[1];
Matrix4.values_[6] = (float)newAxe[2];
Matrix4.values_[8] = (float)-forward[0];
Matrix4.values_[9] = (float)-forward[1];
Matrix4.values_[10] = (float)-forward[2];
Matrix4.values_[15] = 1.0f;

*this *= Matrix4;

// translation is part of the lookAt function
translate(-eyeX, -eyeY, -eyeZ);
}


If someone understands what I'm doing wrong, it might help a lot, I spent a while with this problem... Thanks,

The lookAt matrix is like this:

RightX      RightY      RightZ      0
UpX         UpY         UpZ         0
LookX       LookY       LookZ       0
PosX        PosY        PosZ        1


normal[0]   normal[1]   normal[2]     0
newAxe[0]   newAxe[1]   newAxe[2]     0
-forward[0] -forward[1] -forward[2]   0
eyeX        eyeY       eyeZ           1


With the indexes in the matrix as follows:

0           1           2             3
4           5           6             7
8           9           10            11
12          13          14            15


As you can see, you should be reading the indexes 12, 13 and 14:

d.X = _view[12];
d.Y = _view[13];
d.Z = _view[14];


This is quote from the OpenGL FAQ on Transformations:

For programming purposes, OpenGL matrices are 16-value arrays with base vectors laid out contiguously in memory. The translation components occupy the 13th, 14th, and 15th elements of the 16-element matrix, where indices are numbered from 1 to 16 as described in section 2.11.2 of the OpenGL 2.1 Specification.

Of course, we are using 0 based indexes, so the 13th, 14th, and 15th elements are the indexes 12, 13 and 14.

• It seems that I've much more : normal[0] normal[1] normal[2] eyeX newAxe[0] newAxe[1] newAxe[2] eyeY -forward[0] -forward[1] -forward[2] eyeZ  0 0 0 1 Is that possible ? :/ It's actually working well exect for eye position extraction. Mar 5 '17 at 12:42
• void Matrix4::translate(float X, float Y, float Z) { Matrix4 translation; translation.loadIdentity(); translation.values_[3] = X; translation.values_[7] = Y; translation.values_[11] = Z; *this *= translation; } Mar 5 '17 at 12:45
• @QuentinTealrod the four vectors should be oriented in the matrix in the same way. Edit: Based on that I would say that the translation is wrong, I would review the multiplication also. Mar 5 '17 at 14:56