google / mathfu

C++ math library developed primarily for games focused on simplicity and efficiency.

Home Page:http://google.github.io/mathfu

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Why LookAt from mathfu differs from GLM?

oblitum opened this issue · comments

mat4::LookAt(vec3(0, 0, 0), vec3(0, 0, 1), vec3(0, 1, 0)):

-1,  0,  0,  0
 0,  1,  0,  0
 0,  0, -1,  0
 0,  0,  1,  1

glm::lookAt(glm::vec3(0, 0, 1), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0)):

 1,  0,  0,  0
 0,  1,  0,  0
 0,  0,  1,  0
 0,  0, -1,  1

I'm trying to setup a simple OpenGL sample using the mat4::LookAt function, but while I had no problems with GLM, this LookAt matrix is strange and I just get a black screen.

I just confirmed in my sample the sole problem I have is this behavior of LookAt when changing from GLM to mathfu. I've created my initial camera from raw data using the GLM output and the rest of the sample using mathfu API and it's working.

I've applied this patch to resemble GLM and use mathfu:

diff --git a/include/mathfu/matrix.h b/include/mathfu/matrix.h
index 38dfe6b..cf18181 100644
--- a/include/mathfu/matrix.h
+++ b/include/mathfu/matrix.h
@@ -1299,11 +1299,11 @@ static void LookAtHelperCalculateAxes(
     const Vector<T, 3>& at, const Vector<T, 3>& eye, const Vector<T, 3>& up,
     Vector<T, 3> * const axes) {
   axes[2] = (at - eye).Normalized();
-  axes[0] = Vector<T, 3>::CrossProduct(up, axes[2]).Normalized();
-  axes[1] = Vector<T, 3>::CrossProduct(axes[2], axes[0]);
+  axes[0] = Vector<T, 3>::CrossProduct(axes[2], up).Normalized();
+  axes[1] = Vector<T, 3>::CrossProduct(axes[0], axes[2]);
   axes[3] = Vector<T, 3>(-Vector<T, 3>::DotProduct(axes[0], eye),
                          -Vector<T, 3>::DotProduct(axes[1], eye),
-                         -Vector<T, 3>::DotProduct(axes[2], eye));
+                          Vector<T, 3>::DotProduct(axes[2], eye));
 }
 /// @endcond

@@ -1314,9 +1314,9 @@ static inline Matrix<T, 4, 4> LookAtHelper(
     const Vector<T, 3>& at, const Vector<T, 3>& eye, const Vector<T, 3>& up) {
   Vector<T, 3> axes[4];
   LookAtHelperCalculateAxes(at, eye, up, axes);
-  const Vector<T, 4> column0(axes[0][0], axes[1][0], axes[2][0], 0);
-  const Vector<T, 4> column1(axes[0][1], axes[1][1], axes[2][1], 0);
-  const Vector<T, 4> column2(axes[0][2], axes[1][2], axes[2][2], 0);
+  const Vector<T, 4> column0(axes[0][0], axes[1][0], -axes[2][0], 0);
+  const Vector<T, 4> column1(axes[0][1], axes[1][1], -axes[2][1], 0);
+  const Vector<T, 4> column2(axes[0][2], axes[1][2], -axes[2][2], 0);
   const Vector<T, 4> column3(axes[3], 1);
   return Matrix<T, 4, 4>(column0, column1, column2, column3);
 }

It looks like we didn't add a handed-ness parameter for this method (unlike
Perspective -
http://google.github.io/mathfu/classmathfu_1_1_matrix.html#a6e66814f9b9659706588dc99362cbe4a
).

On Sun, Feb 1, 2015 at 7:53 PM, Francisco Lopes notifications@github.com
wrote:

I've applied this path to resemble GLM and use mathfu:

diff --git a/include/mathfu/matrix.h b/include/mathfu/matrix.h
index 38dfe6b..cf18181 100644--- a/include/mathfu/matrix.h+++ b/include/mathfu/matrix.h@@ -1299,11 +1299,11 @@ static void LookAtHelperCalculateAxes(
const Vector<T, 3>& at, const Vector<T, 3>& eye, const Vector<T, 3>& up,
Vector<T, 3> * const axes) {
axes[2] = (at - eye).Normalized();- axes[0] = Vector<T, 3>::CrossProduct(up, axes[2]).Normalized();- axes[1] = Vector<T, 3>::CrossProduct(axes[2], axes[0]);+ axes[0] = Vector<T, 3>::CrossProduct(axes[2], up).Normalized();+ axes[1] = Vector<T, 3>::CrossProduct(axes[0], axes[2]);
axes[3] = Vector<T, 3>(-Vector<T, 3>::DotProduct(axes[0], eye),
-Vector<T, 3>::DotProduct(axes[1], eye),- -Vector<T, 3>::DotProduct(axes[2], eye));+ Vector<T, 3>::DotProduct(axes[2], eye));
}
/// @endcond
@@ -1314,9 +1314,9 @@ static inline Matrix<T, 4, 4> LookAtHelper(
const Vector<T, 3>& at, const Vector<T, 3>& eye, const Vector<T, 3>& up) {
Vector<T, 3> axes[4];
LookAtHelperCalculateAxes(at, eye, up, axes);- const Vector<T, 4> column0(axes[0][0], axes[1][0], axes[2][0], 0);- const Vector<T, 4> column1(axes[0][1], axes[1][1], axes[2][1], 0);- const Vector<T, 4> column2(axes[0][2], axes[1][2], axes[2][2], 0);+ const Vector<T, 4> column0(axes[0][0], axes[1][0], -axes[2][0], 0);+ const Vector<T, 4> column1(axes[0][1], axes[1][1], -axes[2][1], 0);+ const Vector<T, 4> column2(axes[0][2], axes[1][2], -axes[2][2], 0);
const Vector<T, 4> column3(axes[3], 1);
return Matrix<T, 4, 4>(column0, column1, column2, column3);
}


Reply to this email directly or view it on GitHub
#3 (comment).

@stewartmiles I did notice that.

This was fixed (kinda) in 72ab10e . We left the default behavior of LookAt() which we know is inconsistent with the other methods that have a handedness parameter to maintain compatibility for existing users.