[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