[Cogl] [PATCH 5/6] Add functions to directly transform from a euler or a quaternion

Neil Roberts neil at linux.intel.com
Thu May 17 15:40:17 PDT 2012


This adds the following new functions to apply a rotation described by
a euler or a quaternion to either a CoglMatrix or directly to the
modelview stack of a framebuffer:

cogl_matrix_rotate_quaternion
cogl_matrix_rotate_euler
cogl_framebuffer_rotate_quaternion
cogl_framebuffer_rotate_euler

The direct framebuffer functions have corresponding functions in the
CoglMatrixStack to store an entry describing the rotation.
---
 cogl/cogl-framebuffer.c                |   26 ++++++++
 cogl/cogl-framebuffer.h                |   38 ++++++++++++
 cogl/cogl-matrix-stack.c               |  103 ++++++++++++++++++++++++++++++++
 cogl/cogl-matrix-stack.h               |   32 ++++++++++-
 cogl/cogl-matrix.c                     |   20 ++++++
 cogl/cogl-matrix.h                     |   30 +++++++++
 doc/reference/cogl2/cogl2-sections.txt |    4 +
 7 files changed, 252 insertions(+), 1 deletions(-)

diff --git a/cogl/cogl-framebuffer.c b/cogl/cogl-framebuffer.c
index 9b254aa..8ea41fb 100644
--- a/cogl/cogl-framebuffer.c
+++ b/cogl/cogl-framebuffer.c
@@ -2636,6 +2636,32 @@ cogl_framebuffer_rotate (CoglFramebuffer *framebuffer,
 }
 
 void
+cogl_framebuffer_rotate_quaternion (CoglFramebuffer *framebuffer,
+                                    const CoglQuaternion *quaternion)
+{
+  CoglMatrixStack *modelview_stack =
+    _cogl_framebuffer_get_modelview_stack (framebuffer);
+  _cogl_matrix_stack_rotate_quaternion (modelview_stack, quaternion);
+
+  if (framebuffer->context->current_draw_buffer == framebuffer)
+    framebuffer->context->current_draw_buffer_changes |=
+      COGL_FRAMEBUFFER_STATE_MODELVIEW;
+}
+
+void
+cogl_framebuffer_rotate_euler (CoglFramebuffer *framebuffer,
+                               const CoglEuler *euler)
+{
+  CoglMatrixStack *modelview_stack =
+    _cogl_framebuffer_get_modelview_stack (framebuffer);
+  _cogl_matrix_stack_rotate_euler (modelview_stack, euler);
+
+  if (framebuffer->context->current_draw_buffer == framebuffer)
+    framebuffer->context->current_draw_buffer_changes |=
+      COGL_FRAMEBUFFER_STATE_MODELVIEW;
+}
+
+void
 cogl_framebuffer_transform (CoglFramebuffer *framebuffer,
                             const CoglMatrix *matrix)
 {
diff --git a/cogl/cogl-framebuffer.h b/cogl/cogl-framebuffer.h
index 0b030a2..f491ca2 100644
--- a/cogl/cogl-framebuffer.h
+++ b/cogl/cogl-framebuffer.h
@@ -38,6 +38,10 @@
 #include <cogl/cogl-pipeline.h>
 #include <cogl/cogl-indices.h>
 #include <cogl/cogl-bitmap.h>
+#ifdef COGL_ENABLE_EXPERIMENTAL_API
+#include <cogl/cogl-quaternion.h>
+#include <cogl/cogl-euler.h>
+#endif
 
 G_BEGIN_DECLS
 
@@ -342,6 +346,40 @@ cogl_framebuffer_rotate (CoglFramebuffer *framebuffer,
                          float y,
                          float z);
 
+#ifdef COGL_ENABLE_EXPERIMENTAL_API
+
+/**
+ * cogl_framebuffer_rotate_quaternion:
+ * @framebuffer: A #CoglFramebuffer pointer
+ * @quaternion: A #CoglQuaternion
+ *
+ * Multiplies the current model-view matrix by one that rotates the
+ * according the rotation described by @quaternion.
+ *
+ * Since: 2.0
+ * Stability: unstable
+ */
+void
+cogl_framebuffer_rotate_quaternion (CoglFramebuffer *framebuffer,
+                                    const CoglQuaternion *quaternion);
+
+/**
+ * cogl_framebuffer_rotate_euler:
+ * @framebuffer: A #CoglFramebuffer pointer
+ * @euler: A #CoglEuler
+ *
+ * Multiplies the current model-view matrix by one that rotates the
+ * according the rotation described by @euler.
+ *
+ * Since: 2.0
+ * Stability: unstable
+ */
+void
+cogl_framebuffer_rotate_euler (CoglFramebuffer *framebuffer,
+                               const CoglEuler *euler);
+
+#endif /* COGL_ENABLE_EXPERIMENTAL_API */
+
 /**
  * cogl_framebuffer_transform:
  * @framebuffer: A #CoglFramebuffer pointer
diff --git a/cogl/cogl-matrix-stack.c b/cogl/cogl-matrix-stack.c
index a8b42e7..14a9040 100644
--- a/cogl/cogl-matrix-stack.c
+++ b/cogl/cogl-matrix-stack.c
@@ -123,6 +123,37 @@ _cogl_matrix_stack_rotate (CoglMatrixStack *stack,
 }
 
 void
+_cogl_matrix_stack_rotate_quaternion (CoglMatrixStack *stack,
+                                      const CoglQuaternion *quaternion)
+{
+  CoglMatrixEntryRotateQuaternion *entry;
+
+  entry = _cogl_matrix_stack_push_entry (stack,
+                                         sizeof (CoglMatrixEntryRotate),
+                                         COGL_MATRIX_OP_ROTATE_QUATERNION);
+
+  entry->values[0] = quaternion->w;
+  entry->values[1] = quaternion->x;
+  entry->values[2] = quaternion->y;
+  entry->values[3] = quaternion->z;
+}
+
+void
+_cogl_matrix_stack_rotate_euler (CoglMatrixStack *stack,
+                                 const CoglEuler *euler)
+{
+  CoglMatrixEntryRotateEuler *entry;
+
+  entry = _cogl_matrix_stack_push_entry (stack,
+                                         sizeof (CoglMatrixEntryRotate),
+                                         COGL_MATRIX_OP_ROTATE_EULER);
+
+  entry->heading = euler->heading;
+  entry->pitch = euler->pitch;
+  entry->roll = euler->roll;
+}
+
+void
 _cogl_matrix_stack_scale (CoglMatrixStack *stack,
                           float x,
                           float y,
@@ -272,6 +303,8 @@ _cogl_matrix_entry_unref (CoglMatrixEntry *entry)
         case COGL_MATRIX_OP_LOAD_IDENTITY:
         case COGL_MATRIX_OP_TRANSLATE:
         case COGL_MATRIX_OP_ROTATE:
+        case COGL_MATRIX_OP_ROTATE_QUATERNION:
+        case COGL_MATRIX_OP_ROTATE_EULER:
         case COGL_MATRIX_OP_SCALE:
           break;
         case COGL_MATRIX_OP_MULTIPLY:
@@ -411,6 +444,8 @@ initialized:
         case COGL_MATRIX_OP_LOAD_IDENTITY:
         case COGL_MATRIX_OP_TRANSLATE:
         case COGL_MATRIX_OP_ROTATE:
+        case COGL_MATRIX_OP_ROTATE_QUATERNION:
+        case COGL_MATRIX_OP_ROTATE_EULER:
         case COGL_MATRIX_OP_SCALE:
         case COGL_MATRIX_OP_MULTIPLY:
           return NULL;
@@ -485,6 +520,28 @@ initialized:
                                 rotate->z);
             continue;
           }
+        case COGL_MATRIX_OP_ROTATE_EULER:
+          {
+            CoglMatrixEntryRotateEuler *rotate =
+              (CoglMatrixEntryRotateEuler *)children[i];
+            CoglEuler euler;
+            cogl_euler_init (&euler,
+                             rotate->heading,
+                             rotate->pitch,
+                             rotate->roll);
+            cogl_matrix_rotate_euler (matrix,
+                                      &euler);
+            continue;
+          }
+        case COGL_MATRIX_OP_ROTATE_QUATERNION:
+          {
+            CoglMatrixEntryRotateQuaternion *rotate =
+              (CoglMatrixEntryRotateQuaternion *)children[i];
+            CoglQuaternion quaternion;
+            cogl_quaternion_init_from_array (&quaternion, rotate->values);
+            cogl_matrix_rotate_quaternion (matrix, &quaternion);
+            continue;
+          }
         case COGL_MATRIX_OP_SCALE:
           {
             CoglMatrixEntryScale *scale =
@@ -877,6 +934,31 @@ _cogl_matrix_entry_equal (CoglMatrixEntry *entry0,
               return FALSE;
           }
           break;
+        case COGL_MATRIX_OP_ROTATE_QUATERNION:
+          {
+            CoglMatrixEntryRotateQuaternion *rotate0 =
+              (CoglMatrixEntryRotateQuaternion *)entry0;
+            CoglMatrixEntryRotateQuaternion *rotate1 =
+              (CoglMatrixEntryRotateQuaternion *)entry1;
+            int i;
+            for (i = 0; i < 4; i++)
+              if (rotate0->values[i] != rotate1->values[i])
+                return FALSE;
+          }
+          break;
+        case COGL_MATRIX_OP_ROTATE_EULER:
+          {
+            CoglMatrixEntryRotateEuler *rotate0 =
+              (CoglMatrixEntryRotateEuler *)entry0;
+            CoglMatrixEntryRotateEuler *rotate1 =
+              (CoglMatrixEntryRotateEuler *)entry1;
+
+            if (rotate0->heading != rotate1->heading ||
+                rotate0->pitch != rotate1->pitch ||
+                rotate0->roll != rotate1->roll)
+              return FALSE;
+          }
+          break;
         case COGL_MATRIX_OP_SCALE:
           {
             CoglMatrixEntryScale *scale0 = (CoglMatrixEntryScale *)entry0;
@@ -965,6 +1047,27 @@ _cogl_matrix_entry_print (CoglMatrixEntry *entry)
                      rotate->z);
             continue;
           }
+        case COGL_MATRIX_OP_ROTATE_QUATERNION:
+          {
+            CoglMatrixEntryRotateQuaternion *rotate =
+              (CoglMatrixEntryRotateQuaternion *)entry;
+            g_print ("  ROTATE QUATERNION w=%f x=%f y=%f z=%f\n",
+                     rotate->values[0],
+                     rotate->values[1],
+                     rotate->values[2],
+                     rotate->values[3]);
+            continue;
+          }
+        case COGL_MATRIX_OP_ROTATE_EULER:
+          {
+            CoglMatrixEntryRotateEuler *rotate =
+              (CoglMatrixEntryRotateEuler *)entry;
+            g_print ("  ROTATE EULER heading=%f pitch=%f roll=%f\n",
+                     rotate->heading,
+                     rotate->pitch,
+                     rotate->roll);
+            continue;
+          }
         case COGL_MATRIX_OP_SCALE:
           {
             CoglMatrixEntryScale *scale = (CoglMatrixEntryScale *)entry;
diff --git a/cogl/cogl-matrix-stack.h b/cogl/cogl-matrix-stack.h
index db957d6..8b942e3 100644
--- a/cogl/cogl-matrix-stack.h
+++ b/cogl/cogl-matrix-stack.h
@@ -39,6 +39,8 @@ typedef enum _CoglMatrixOp
   COGL_MATRIX_OP_LOAD_IDENTITY,
   COGL_MATRIX_OP_TRANSLATE,
   COGL_MATRIX_OP_ROTATE,
+  COGL_MATRIX_OP_ROTATE_QUATERNION,
+  COGL_MATRIX_OP_ROTATE_EULER,
   COGL_MATRIX_OP_SCALE,
   COGL_MATRIX_OP_MULTIPLY,
   COGL_MATRIX_OP_LOAD,
@@ -78,6 +80,26 @@ typedef struct _CoglMatrixEntryRotate
 
 } CoglMatrixEntryRotate;
 
+typedef struct _CoglMatrixEntryRotateEuler
+{
+  CoglMatrixEntry _parent_data;
+
+  /* This doesn't store an actual CoglEuler in order to avoid the
+   * padding */
+  float heading;
+  float pitch;
+  float roll;
+} CoglMatrixEntryRotateEuler;
+
+typedef struct _CoglMatrixEntryRotateQuaternion
+{
+  CoglMatrixEntry _parent_data;
+
+  /* This doesn't store an actual CoglQuaternion in order to avoid the
+   * padding */
+  float values[4];
+} CoglMatrixEntryRotateQuaternion;
+
 typedef struct _CoglMatrixEntryScale
 {
   CoglMatrixEntry _parent_data;
@@ -117,7 +139,9 @@ typedef union _CoglMatrixEntryFull
 {
   CoglMatrixEntry any;
   CoglMatrixEntryTranslate translate;
-  CoglMatrixEntryRotate rotae;
+  CoglMatrixEntryRotate rotate;
+  CoglMatrixEntryRotateEuler rotate_euler;
+  CoglMatrixEntryRotateQuaternion rotate_quaternion;
   CoglMatrixEntryScale scale;
   CoglMatrixEntryMultiply multiply;
   CoglMatrixEntryLoad load;
@@ -170,6 +194,12 @@ _cogl_matrix_stack_rotate (CoglMatrixStack *stack,
                            float y,
                            float z);
 void
+_cogl_matrix_stack_rotate_quaternion (CoglMatrixStack *stack,
+                                      const CoglQuaternion *quaternion);
+void
+_cogl_matrix_stack_rotate_euler (CoglMatrixStack *stack,
+                                 const CoglEuler *euler);
+void
 _cogl_matrix_stack_multiply (CoglMatrixStack *stack,
                              const CoglMatrix *matrix);
 void
diff --git a/cogl/cogl-matrix.c b/cogl/cogl-matrix.c
index b9b72ee..021caac 100644
--- a/cogl/cogl-matrix.c
+++ b/cogl/cogl-matrix.c
@@ -1352,6 +1352,26 @@ cogl_matrix_rotate (CoglMatrix *matrix,
   _COGL_MATRIX_DEBUG_PRINT (matrix);
 }
 
+void
+cogl_matrix_rotate_quaternion (CoglMatrix *matrix,
+                               const CoglQuaternion *quaternion)
+{
+  CoglMatrix rotation_transform;
+
+  cogl_matrix_init_from_quaternion (&rotation_transform, quaternion);
+  cogl_matrix_multiply (matrix, matrix, &rotation_transform);
+}
+
+void
+cogl_matrix_rotate_euler (CoglMatrix *matrix,
+                          const CoglEuler *euler)
+{
+  CoglMatrix rotation_transform;
+
+  cogl_matrix_init_from_euler (&rotation_transform, euler);
+  cogl_matrix_multiply (matrix, matrix, &rotation_transform);
+}
+
 /*
  * Apply a perspective projection matrix.
  *
diff --git a/cogl/cogl-matrix.h b/cogl/cogl-matrix.h
index 10d0d8a..dac9209 100644
--- a/cogl/cogl-matrix.h
+++ b/cogl/cogl-matrix.h
@@ -185,6 +185,36 @@ cogl_matrix_rotate (CoglMatrix *matrix,
 		    float y,
 		    float z);
 
+#ifdef COGL_ENABLE_EXPERIMENTAL_API
+/**
+ * cogl_matrix_rotate_quaternion:
+ * @matrix: A 4x4 transformation matrix
+ * @quaternion: A quaternion describing a rotation
+ *
+ * Multiplies @matrix with a rotation transformation described by the
+ * given #CoglQuaternion.
+ *
+ * Since: 2.0
+ */
+void
+cogl_matrix_rotate_quaternion (CoglMatrix *matrix,
+                               const CoglQuaternion *quaternion);
+
+/**
+ * cogl_matrix_rotate_euler:
+ * @matrix: A 4x4 transformation matrix
+ * @euler: A euler describing a rotation
+ *
+ * Multiplies @matrix with a rotation transformation described by the
+ * given #CoglEuler.
+ *
+ * Since: 2.0
+ */
+void
+cogl_matrix_rotate_euler (CoglMatrix *matrix,
+                          const CoglEuler *euler);
+#endif
+
 /**
  * cogl_matrix_translate:
  * @matrix: A 4x4 transformation matrix
diff --git a/doc/reference/cogl2/cogl2-sections.txt b/doc/reference/cogl2/cogl2-sections.txt
index 7223334..bd7b996 100644
--- a/doc/reference/cogl2/cogl2-sections.txt
+++ b/doc/reference/cogl2/cogl2-sections.txt
@@ -392,6 +392,8 @@ cogl_framebuffer_identity_matrix
 cogl_framebuffer_scale
 cogl_framebuffer_translate
 cogl_framebuffer_rotate
+cogl_framebuffer_rotate_euler
+cogl_framebuffer_rotate_quaternion
 cogl_framebuffer_transform
 cogl_framebuffer_get_modelview_matrix
 cogl_framebuffer_set_modelview_matrix
@@ -509,6 +511,8 @@ cogl_matrix_perspective
 cogl_matrix_look_at
 cogl_matrix_multiply
 cogl_matrix_rotate
+cogl_matrix_rotate_quaternion
+cogl_matrix_rotate_euler
 cogl_matrix_translate
 cogl_matrix_scale
 cogl_matrix_transpose
-- 
1.7.3.16.g9464b



More information about the Cogl mailing list