[Cogl] [PATCH 3/6] Add a cogl_matrix_init_from_euler function
Neil Roberts
neil at linux.intel.com
Thu May 17 15:40:15 PDT 2012
This creates a matrix to represent the given euler rotation. This
should be more efficient than creating the matrix by doing three
separate rotations because no separate intermediate matrices are
created and no matrix multiplication is needed.
---
cogl/cogl-matrix.c | 78 ++++++++++++++++++++++++++++++++
cogl/cogl-matrix.h | 11 +++++
doc/reference/cogl2/cogl2-sections.txt | 2 +
3 files changed, 91 insertions(+), 0 deletions(-)
diff --git a/cogl/cogl-matrix.c b/cogl/cogl-matrix.c
index 154203a..b9b72ee 100644
--- a/cogl/cogl-matrix.c
+++ b/cogl/cogl-matrix.c
@@ -1751,6 +1751,84 @@ cogl_matrix_init_from_quaternion (CoglMatrix *matrix,
_cogl_matrix_init_from_quaternion (matrix, quaternion);
}
+void
+cogl_matrix_init_from_euler (CoglMatrix *matrix,
+ const CoglEuler *euler)
+{
+ /* Convert angles to radians */
+ float heading_rad = euler->heading / 180.0f * G_PI;
+ float pitch_rad = euler->pitch / 180.0f * G_PI;
+ float roll_rad = euler->roll / 180.0f * G_PI;
+ /* Pre-calculate the sin and cos */
+ float sin_heading = sinf (heading_rad);
+ float cos_heading = cosf (heading_rad);
+ float sin_pitch = sinf (pitch_rad);
+ float cos_pitch = cosf (pitch_rad);
+ float sin_roll = sinf (roll_rad);
+ float cos_roll = cosf (roll_rad);
+
+ /* These calculations are based on the following website but they
+ * use a different order for the rotations so it has been modified
+ * slightly.
+ * http://www.euclideanspace.com/maths/geometry/
+ * rotations/conversions/eulerToMatrix/index.htm
+ */
+
+ /* Heading rotation x=0, y=1, z=0 gives:
+ *
+ * [ ch 0 sh 0 ]
+ * [ 0 1 0 0 ]
+ * [ -sh 0 ch 0 ]
+ * [ 0 0 0 1 ]
+ *
+ * Pitch rotation x=1, y=0, z=0 gives:
+ * [ 1 0 0 0 ]
+ * [ 0 cp -sp 0 ]
+ * [ 0 sp cp 0 ]
+ * [ 0 0 0 1 ]
+ *
+ * Roll rotation x=0, y=0, z=1 gives:
+ * [ cr -sr 0 0 ]
+ * [ sr cr 0 0 ]
+ * [ 0 0 1 0 ]
+ * [ 0 0 0 1 ]
+ *
+ * Heading matrix * pitch matrix =
+ * [ ch sh*sp cp*sh 0 ]
+ * [ 0 cp -sp 0 ]
+ * [ -sh ch*sp ch*cp 0 ]
+ * [ 0 0 0 1 ]
+ *
+ * That matrix * roll matrix =
+ * [ ch*cr + sh*sp*sr sh*sp*cr - ch*sr sh*cp 0 ]
+ * [ cp*sr cp*cr -sp 0 ]
+ * [ ch*sp*sr - sh*cr sh*sr + ch*sp*cr ch*cp 0 ]
+ * [ 0 0 0 1 ]
+ */
+
+ matrix->xx = cos_heading * cos_roll + sin_heading * sin_pitch * sin_roll;
+ matrix->yx = cos_pitch * sin_roll;
+ matrix->zx = cos_heading * sin_pitch * sin_roll - sin_heading * cos_roll;
+ matrix->wx = 0.0f;
+
+ matrix->xy = sin_heading * sin_pitch * cos_roll - cos_heading * sin_roll;
+ matrix->yy = cos_pitch * cos_roll;
+ matrix->zy = sin_heading * sin_roll + cos_heading * sin_pitch * cos_roll;
+ matrix->wy = 0.0f;
+
+ matrix->xz = sin_heading * cos_pitch;
+ matrix->yz = -sin_pitch;
+ matrix->zz = cos_heading * cos_pitch;
+ matrix->wz = 0;
+
+ matrix->xw = 0;
+ matrix->yw = 0;
+ matrix->zw = 0;
+ matrix->ww = 1;
+
+ matrix->flags = (MAT_FLAG_GENERAL | MAT_DIRTY_ALL);
+}
+
/*
* Transpose a float matrix.
*/
diff --git a/cogl/cogl-matrix.h b/cogl/cogl-matrix.h
index 0c3d31c..10d0d8a 100644
--- a/cogl/cogl-matrix.h
+++ b/cogl/cogl-matrix.h
@@ -491,6 +491,17 @@ cogl_matrix_get_array (const CoglMatrix *matrix);
void
cogl_matrix_init_from_quaternion (CoglMatrix *matrix,
const CoglQuaternion *quaternion);
+
+/**
+ * cogl_matrix_init_from_euler:
+ * @matrix: A 4x4 transformation matrix
+ * @euler: A #CoglEuler
+ *
+ * Initializes @matrix from a #CoglEuler rotation.
+ */
+void
+cogl_matrix_init_from_euler (CoglMatrix *matrix,
+ const CoglEuler *euler);
#endif
/**
diff --git a/doc/reference/cogl2/cogl2-sections.txt b/doc/reference/cogl2/cogl2-sections.txt
index 01d2d63..7223334 100644
--- a/doc/reference/cogl2/cogl2-sections.txt
+++ b/doc/reference/cogl2/cogl2-sections.txt
@@ -498,6 +498,8 @@ CoglMatrix
cogl_matrix_init_identity
cogl_matrix_init_from_array
cogl_matrix_init_translation
+cogl_matrix_init_from_quaternion
+cogl_matrix_init_from_euler
cogl_matrix_copy
cogl_matrix_equal
cogl_matrix_free
--
1.7.3.16.g9464b
More information about the Cogl
mailing list