[mutter/gbsneto/graphene2: 33/45] cogl/matrix: Rotate using graphene
- From: Georges Basile Stavracas Neto <gbsneto src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/gbsneto/graphene2: 33/45] cogl/matrix: Rotate using graphene
- Date: Sat, 7 Sep 2019 11:20:00 +0000 (UTC)
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]