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

Robert Bragg robert at sixbynine.org
Wed Jun 20 03:33:30 PDT 2012


Cool, this looks good to me.

Reviewed-by: Robert Bragg <robert at linux.intel.com>

thanks,
- Robert

On Thu, May 17, 2012 at 11:40 PM, Neil Roberts <neil at linux.intel.com> wrote:
> 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
>
> _______________________________________________
> Cogl mailing list
> Cogl at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/cogl


More information about the Cogl mailing list