From 6eb8864866babd26149729eac5e4774328b06b7a Mon Sep 17 00:00:00 2001 From: Neil Roberts Date: Thu, 17 May 2012 19:18:58 +0100 Subject: [PATCH] Add a cogl_matrix_init_from_euler function 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. Reviewed-by: Robert Bragg (cherry picked from commit e66d9965897999a4889063f6df9a20ea6abf97fe) --- cogl/cogl-matrix.c | 78 +++++++++++++++++++ cogl/cogl-matrix.h | 11 +++ .../cogl-2.0-experimental-sections.txt | 2 + 3 files changed, 91 insertions(+) diff --git a/cogl/cogl-matrix.c b/cogl/cogl-matrix.c index 512327f92..d82ca8271 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 4a237c2b0..53b786571 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/cogl-2.0-experimental/cogl-2.0-experimental-sections.txt b/doc/reference/cogl-2.0-experimental/cogl-2.0-experimental-sections.txt index 00dc8828c..8ba5e9ea7 100644 --- a/doc/reference/cogl-2.0-experimental/cogl-2.0-experimental-sections.txt +++ b/doc/reference/cogl-2.0-experimental/cogl-2.0-experimental-sections.txt @@ -546,6 +546,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