[mutter/gbsneto/graphene2: 33/45] cogl/matrix: Rotate using graphene



commit 1aac180e8dc20d9d7ef92bfda754f24024ce7aeb
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Wed Feb 27 20:42:02 2019 -0300

    cogl/matrix: Rotate using graphene

 cogl/cogl/cogl-matrix.c | 221 +++---------------------------------------------
 1 file changed, 11 insertions(+), 210 deletions(-)
---
diff --git a/cogl/cogl/cogl-matrix.c b/cogl/cogl/cogl-matrix.c
index 97034ee7a..f61e33b1f 100644
--- a/cogl/cogl/cogl-matrix.c
+++ b/cogl/cogl/cogl-matrix.c
@@ -98,20 +98,6 @@ static float identity[16] = {
    0.0, 0.0, 0.0, 1.0
 };
 
-static void
-matrix_multiply_array_with_flags (CoglMatrix *result,
-                                  const float *array)
-{
-  graphene_matrix_t m1, m2, res;
-
-  cogl_matrix_to_graphene_matrix (result, &m1);
-  graphene_matrix_init_from_float (&m2, array);
-
-  graphene_matrix_multiply (&m2, &m1, &res);
-  graphene_matrix_to_cogl_matrix (&res, result);
-}
-
-
 void
 cogl_matrix_multiply (CoglMatrix *result,
                      const CoglMatrix *a,
@@ -166,201 +152,6 @@ cogl_matrix_get_inverse (const CoglMatrix *matrix, CoglMatrix *inverse)
   return success;
 }
 
-/*
- * Generate a 4x4 transformation matrix from glRotate parameters, and
- * post-multiply the input matrix by it.
- *
- * \author
- * This function was contributed by Erich Boleyn (erich uruk org).
- * Optimizations contributed by Rudolf Opalla (rudi khm de).
- */
-static void
-_cogl_matrix_rotate (CoglMatrix *matrix,
-                     float angle,
-                     float x,
-                     float y,
-                     float z)
-{
-  float xx, yy, zz, xy, yz, zx, xs, ys, zs, one_c, s, c;
-  float m[16];
-  gboolean optimized;
-
-  s = sinf (angle * DEG2RAD);
-  c = cosf (angle * DEG2RAD);
-
-  memcpy (m, identity, 16 * sizeof (float));
-  optimized = FALSE;
-
-#define M(row,col)  m[col*4+row]
-
-  if (x == 0.0f)
-    {
-      if (y == 0.0f)
-        {
-          if (z != 0.0f)
-            {
-              optimized = TRUE;
-              /* rotate only around z-axis */
-              M (0,0) = c;
-              M (1,1) = c;
-              if (z < 0.0f)
-                {
-                  M (0,1) = s;
-                  M (1,0) = -s;
-                }
-              else
-                {
-                  M (0,1) = -s;
-                  M (1,0) = s;
-                }
-            }
-        }
-      else if (z == 0.0f)
-        {
-          optimized = TRUE;
-          /* rotate only around y-axis */
-          M (0,0) = c;
-          M (2,2) = c;
-          if (y < 0.0f)
-            {
-              M (0,2) = -s;
-              M (2,0) = s;
-            }
-          else
-            {
-              M (0,2) = s;
-              M (2,0) = -s;
-            }
-        }
-    }
-  else if (y == 0.0f)
-    {
-      if (z == 0.0f)
-        {
-          optimized = TRUE;
-          /* rotate only around x-axis */
-          M (1,1) = c;
-          M (2,2) = c;
-          if (x < 0.0f)
-            {
-              M (1,2) = s;
-              M (2,1) = -s;
-            }
-          else
-            {
-              M (1,2) = -s;
-              M (2,1) = s;
-            }
-        }
-    }
-
-  if (!optimized)
-    {
-      const float mag = sqrtf (x * x + y * y + z * z);
-
-      if (mag <= 1.0e-4)
-        {
-          /* no rotation, leave mat as-is */
-          return;
-        }
-
-      x /= mag;
-      y /= mag;
-      z /= mag;
-
-
-      /*
-       *     Arbitrary axis rotation matrix.
-       *
-       *  This is composed of 5 matrices, Rz, Ry, T, Ry', Rz', multiplied
-       *  like so:  Rz * Ry * T * Ry' * Rz'.  T is the final rotation
-       *  (which is about the X-axis), and the two composite transforms
-       *  Ry' * Rz' and Rz * Ry are (respectively) the rotations necessary
-       *  from the arbitrary axis to the X-axis then back.  They are
-       *  all elementary rotations.
-       *
-       *  Rz' is a rotation about the Z-axis, to bring the axis vector
-       *  into the x-z plane.  Then Ry' is applied, rotating about the
-       *  Y-axis to bring the axis vector parallel with the X-axis.  The
-       *  rotation about the X-axis is then performed.  Ry and Rz are
-       *  simply the respective inverse transforms to bring the arbitrary
-       *  axis back to it's original orientation.  The first transforms
-       *  Rz' and Ry' are considered inverses, since the data from the
-       *  arbitrary axis gives you info on how to get to it, not how
-       *  to get away from it, and an inverse must be applied.
-       *
-       *  The basic calculation used is to recognize that the arbitrary
-       *  axis vector (x, y, z), since it is of unit length, actually
-       *  represents the sines and cosines of the angles to rotate the
-       *  X-axis to the same orientation, with theta being the angle about
-       *  Z and phi the angle about Y (in the order described above)
-       *  as follows:
-       *
-       *  cos ( theta ) = x / sqrt ( 1 - z^2 )
-       *  sin ( theta ) = y / sqrt ( 1 - z^2 )
-       *
-       *  cos ( phi ) = sqrt ( 1 - z^2 )
-       *  sin ( phi ) = z
-       *
-       *  Note that cos ( phi ) can further be inserted to the above
-       *  formulas:
-       *
-       *  cos ( theta ) = x / cos ( phi )
-       *  sin ( theta ) = y / sin ( phi )
-       *
-       *  ...etc.  Because of those relations and the standard trigonometric
-       *  relations, it is pssible to reduce the transforms down to what
-       *  is used below.  It may be that any primary axis chosen will give the
-       *  same results (modulo a sign convention) using thie method.
-       *
-       *  Particularly nice is to notice that all divisions that might
-       *  have caused trouble when parallel to certain planes or
-       *  axis go away with care paid to reducing the expressions.
-       *  After checking, it does perform correctly under all cases, since
-       *  in all the cases of division where the denominator would have
-       *  been zero, the numerator would have been zero as well, giving
-       *  the expected result.
-       */
-
-      xx = x * x;
-      yy = y * y;
-      zz = z * z;
-      xy = x * y;
-      yz = y * z;
-      zx = z * x;
-      xs = x * s;
-      ys = y * s;
-      zs = z * s;
-      one_c = 1.0f - c;
-
-      /* We already hold the identity-matrix so we can skip some statements */
-      M (0,0) = (one_c * xx) + c;
-      M (0,1) = (one_c * xy) - zs;
-      M (0,2) = (one_c * zx) + ys;
-      /*    M (0,3) = 0.0f; */
-
-      M (1,0) = (one_c * xy) + zs;
-      M (1,1) = (one_c * yy) + c;
-      M (1,2) = (one_c * yz) - xs;
-      /*    M (1,3) = 0.0f; */
-
-      M (2,0) = (one_c * zx) - ys;
-      M (2,1) = (one_c * yz) + xs;
-      M (2,2) = (one_c * zz) + c;
-      /*    M (2,3) = 0.0f; */
-
-      /*
-         M (3,0) = 0.0f;
-         M (3,1) = 0.0f;
-         M (3,2) = 0.0f;
-         M (3,3) = 1.0f;
-         */
-    }
-#undef M
-
-  matrix_multiply_array_with_flags (matrix, m);
-}
-
 void
 cogl_matrix_rotate (CoglMatrix *matrix,
                    float angle,
@@ -368,7 +159,17 @@ cogl_matrix_rotate (CoglMatrix *matrix,
                    float y,
                    float z)
 {
-  _cogl_matrix_rotate (matrix, angle, x, y, z);
+  graphene_matrix_t rotation, m;
+  graphene_vec3_t r;
+
+  cogl_matrix_to_graphene_matrix (matrix, &m);
+  graphene_matrix_transpose (&m, &m);
+
+  graphene_matrix_init_rotate (&rotation, angle, graphene_vec3_init (&r, x, y, z));
+  graphene_matrix_multiply (&rotation, &m, &m);
+
+  graphene_matrix_to_cogl_matrix (&m, matrix);
+
   _COGL_MATRIX_DEBUG_PRINT (matrix);
 }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]