Add functions to directly transform from a euler or a quaternion

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.

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

(cherry picked from commit 5064315678b496395e1d01f266f322d73e55e324)
This commit is contained in:
Neil Roberts 2012-05-17 22:22:01 +01:00 committed by Robert Bragg
parent aa749bb177
commit 5e8ff248d2
7 changed files with 252 additions and 1 deletions

View File

@ -2651,6 +2651,32 @@ cogl_framebuffer_rotate (CoglFramebuffer *framebuffer,
COGL_FRAMEBUFFER_STATE_MODELVIEW; COGL_FRAMEBUFFER_STATE_MODELVIEW;
} }
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 void
cogl_framebuffer_transform (CoglFramebuffer *framebuffer, cogl_framebuffer_transform (CoglFramebuffer *framebuffer,
const CoglMatrix *matrix) const CoglMatrix *matrix)

View File

@ -43,6 +43,10 @@
#include <cogl/cogl-pipeline.h> #include <cogl/cogl-pipeline.h>
#include <cogl/cogl-indices.h> #include <cogl/cogl-indices.h>
#include <cogl/cogl-bitmap.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 G_BEGIN_DECLS
@ -347,6 +351,40 @@ cogl_framebuffer_rotate (CoglFramebuffer *framebuffer,
float y, float y,
float z); 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
* according to 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
* according to 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: * cogl_framebuffer_transform:
* @framebuffer: A #CoglFramebuffer pointer * @framebuffer: A #CoglFramebuffer pointer

View File

@ -122,6 +122,37 @@ _cogl_matrix_stack_rotate (CoglMatrixStack *stack,
entry->z = z; entry->z = z;
} }
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 void
_cogl_matrix_stack_scale (CoglMatrixStack *stack, _cogl_matrix_stack_scale (CoglMatrixStack *stack,
float x, float x,
@ -272,6 +303,8 @@ _cogl_matrix_entry_unref (CoglMatrixEntry *entry)
case COGL_MATRIX_OP_LOAD_IDENTITY: case COGL_MATRIX_OP_LOAD_IDENTITY:
case COGL_MATRIX_OP_TRANSLATE: case COGL_MATRIX_OP_TRANSLATE:
case COGL_MATRIX_OP_ROTATE: 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_SCALE:
break; break;
case COGL_MATRIX_OP_MULTIPLY: case COGL_MATRIX_OP_MULTIPLY:
@ -411,6 +444,8 @@ initialized:
case COGL_MATRIX_OP_LOAD_IDENTITY: case COGL_MATRIX_OP_LOAD_IDENTITY:
case COGL_MATRIX_OP_TRANSLATE: case COGL_MATRIX_OP_TRANSLATE:
case COGL_MATRIX_OP_ROTATE: 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_SCALE:
case COGL_MATRIX_OP_MULTIPLY: case COGL_MATRIX_OP_MULTIPLY:
return NULL; return NULL;
@ -485,6 +520,28 @@ initialized:
rotate->z); rotate->z);
continue; 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: case COGL_MATRIX_OP_SCALE:
{ {
CoglMatrixEntryScale *scale = CoglMatrixEntryScale *scale =
@ -877,6 +934,31 @@ _cogl_matrix_entry_equal (CoglMatrixEntry *entry0,
return FALSE; return FALSE;
} }
break; 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: case COGL_MATRIX_OP_SCALE:
{ {
CoglMatrixEntryScale *scale0 = (CoglMatrixEntryScale *)entry0; CoglMatrixEntryScale *scale0 = (CoglMatrixEntryScale *)entry0;
@ -965,6 +1047,27 @@ _cogl_matrix_entry_print (CoglMatrixEntry *entry)
rotate->z); rotate->z);
continue; 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: case COGL_MATRIX_OP_SCALE:
{ {
CoglMatrixEntryScale *scale = (CoglMatrixEntryScale *)entry; CoglMatrixEntryScale *scale = (CoglMatrixEntryScale *)entry;

View File

@ -39,6 +39,8 @@ typedef enum _CoglMatrixOp
COGL_MATRIX_OP_LOAD_IDENTITY, COGL_MATRIX_OP_LOAD_IDENTITY,
COGL_MATRIX_OP_TRANSLATE, COGL_MATRIX_OP_TRANSLATE,
COGL_MATRIX_OP_ROTATE, COGL_MATRIX_OP_ROTATE,
COGL_MATRIX_OP_ROTATE_QUATERNION,
COGL_MATRIX_OP_ROTATE_EULER,
COGL_MATRIX_OP_SCALE, COGL_MATRIX_OP_SCALE,
COGL_MATRIX_OP_MULTIPLY, COGL_MATRIX_OP_MULTIPLY,
COGL_MATRIX_OP_LOAD, COGL_MATRIX_OP_LOAD,
@ -78,6 +80,26 @@ typedef struct _CoglMatrixEntryRotate
} 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 typedef struct _CoglMatrixEntryScale
{ {
CoglMatrixEntry _parent_data; CoglMatrixEntry _parent_data;
@ -117,7 +139,9 @@ typedef union _CoglMatrixEntryFull
{ {
CoglMatrixEntry any; CoglMatrixEntry any;
CoglMatrixEntryTranslate translate; CoglMatrixEntryTranslate translate;
CoglMatrixEntryRotate rotae; CoglMatrixEntryRotate rotate;
CoglMatrixEntryRotateEuler rotate_euler;
CoglMatrixEntryRotateQuaternion rotate_quaternion;
CoglMatrixEntryScale scale; CoglMatrixEntryScale scale;
CoglMatrixEntryMultiply multiply; CoglMatrixEntryMultiply multiply;
CoglMatrixEntryLoad load; CoglMatrixEntryLoad load;
@ -170,6 +194,12 @@ _cogl_matrix_stack_rotate (CoglMatrixStack *stack,
float y, float y,
float z); float z);
void 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, _cogl_matrix_stack_multiply (CoglMatrixStack *stack,
const CoglMatrix *matrix); const CoglMatrix *matrix);
void void

View File

@ -1352,6 +1352,26 @@ cogl_matrix_rotate (CoglMatrix *matrix,
_COGL_MATRIX_DEBUG_PRINT (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. * Apply a perspective projection matrix.
* *

View File

@ -185,6 +185,36 @@ cogl_matrix_rotate (CoglMatrix *matrix,
float y, float y,
float z); 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: * cogl_matrix_translate:
* @matrix: A 4x4 transformation matrix * @matrix: A 4x4 transformation matrix

View File

@ -440,6 +440,8 @@ cogl_framebuffer_identity_matrix
cogl_framebuffer_scale cogl_framebuffer_scale
cogl_framebuffer_translate cogl_framebuffer_translate
cogl_framebuffer_rotate cogl_framebuffer_rotate
cogl_framebuffer_rotate_euler
cogl_framebuffer_rotate_quaternion
cogl_framebuffer_transform cogl_framebuffer_transform
cogl_framebuffer_get_modelview_matrix cogl_framebuffer_get_modelview_matrix
cogl_framebuffer_set_modelview_matrix cogl_framebuffer_set_modelview_matrix
@ -557,6 +559,8 @@ cogl_matrix_perspective
cogl_matrix_look_at cogl_matrix_look_at
cogl_matrix_multiply cogl_matrix_multiply
cogl_matrix_rotate cogl_matrix_rotate
cogl_matrix_rotate_quaternion
cogl_matrix_rotate_euler
cogl_matrix_translate cogl_matrix_translate
cogl_matrix_scale cogl_matrix_scale
cogl_matrix_transpose cogl_matrix_transpose