Add ClutterActor.transform

The :transform property controls the modelview matrix of an actor; it
can be used to set a custom modelview matrix on the actor, as opposed
to the decomposed transformations (rotation, scaling, translation)
provided by the ClutterActor class.
This commit is contained in:
Emmanuele Bassi 2012-07-20 16:56:43 -04:00
parent 25ba5374fe
commit 178e6b2294
5 changed files with 172 additions and 20 deletions

View File

@ -209,6 +209,9 @@ struct _ClutterTransformInfo
/* transformation center */ /* transformation center */
ClutterPoint pivot; ClutterPoint pivot;
gfloat pivot_z; gfloat pivot_z;
CoglMatrix transform;
guint transform_set : 1;
}; };
const ClutterTransformInfo * _clutter_actor_get_transform_info_or_defaults (ClutterActor *self); const ClutterTransformInfo * _clutter_actor_get_transform_info_or_defaults (ClutterActor *self);

View File

@ -899,6 +899,9 @@ enum
PROP_TRANSLATION_Y, PROP_TRANSLATION_Y,
PROP_TRANSLATION_Z, PROP_TRANSLATION_Z,
PROP_TRANSFORM,
PROP_TRANSFORM_SET,
PROP_SHOW_ON_SET_PARENT, /*XXX:2.0 remove */ PROP_SHOW_ON_SET_PARENT, /*XXX:2.0 remove */
PROP_TEXT_DIRECTION, PROP_TEXT_DIRECTION,
@ -2947,8 +2950,8 @@ clutter_actor_get_abs_allocation_vertices (ClutterActor *self,
} }
static void static void
clutter_actor_real_apply_transform (ClutterActor *self, clutter_actor_real_apply_transform (ClutterActor *self,
CoglMatrix *matrix) ClutterMatrix *matrix)
{ {
ClutterActorPrivate *priv = self->priv; ClutterActorPrivate *priv = self->priv;
@ -2979,6 +2982,17 @@ clutter_actor_real_apply_transform (ClutterActor *self,
cogl_matrix_init_identity (transform); cogl_matrix_init_identity (transform);
/* if we have an overriding transformation, we use that, and get out */
if (info->transform_set)
{
cogl_matrix_translate (transform,
priv->allocation.x1 + pivot_x,
priv->allocation.y1 + pivot_y,
info->pivot_z);
cogl_matrix_multiply (transform, transform, &info->transform);
goto out;
}
/* basic translation: :allocation's origin and :z-position; instead /* basic translation: :allocation's origin and :z-position; instead
* of decomposing the pivot and translation info separate operations, * of decomposing the pivot and translation info separate operations,
* we just compose everything into a single translation * we just compose everything into a single translation
@ -3049,6 +3063,7 @@ clutter_actor_real_apply_transform (ClutterActor *self,
if (pivot_x != 0.f || pivot_y != 0.f || info->pivot_z != 0.f) if (pivot_x != 0.f || pivot_y != 0.f || info->pivot_z != 0.f)
cogl_matrix_translate (transform, -pivot_x, -pivot_y, -info->pivot_z); cogl_matrix_translate (transform, -pivot_x, -pivot_y, -info->pivot_z);
out:
priv->transform_valid = TRUE; priv->transform_valid = TRUE;
} }
@ -3058,8 +3073,8 @@ clutter_actor_real_apply_transform (ClutterActor *self,
/* Applies the transforms associated with this actor to the given /* Applies the transforms associated with this actor to the given
* matrix. */ * matrix. */
void void
_clutter_actor_apply_modelview_transform (ClutterActor *self, _clutter_actor_apply_modelview_transform (ClutterActor *self,
CoglMatrix *matrix) ClutterMatrix *matrix)
{ {
CLUTTER_ACTOR_GET_CLASS (self)->apply_transform (self, matrix); CLUTTER_ACTOR_GET_CLASS (self)->apply_transform (self, matrix);
} }
@ -3069,7 +3084,7 @@ _clutter_actor_apply_modelview_transform (ClutterActor *self,
* @self: The actor whose coordinate space you want to transform from. * @self: The actor whose coordinate space you want to transform from.
* @ancestor: The ancestor actor whose coordinate space you want to transform too * @ancestor: The ancestor actor whose coordinate space you want to transform too
* or %NULL if you want to transform all the way to eye coordinates. * or %NULL if you want to transform all the way to eye coordinates.
* @matrix: A #CoglMatrix to apply the transformation too. * @matrix: A #ClutterMatrix to apply the transformation too.
* *
* This multiplies a transform with @matrix that will transform coordinates * This multiplies a transform with @matrix that will transform coordinates
* from the coordinate space of @self into the coordinate space of @ancestor. * from the coordinate space of @self into the coordinate space of @ancestor.
@ -4123,7 +4138,9 @@ static const ClutterTransformInfo default_transform_info = {
0.f, /* z-position */ 0.f, /* z-position */
CLUTTER_POINT_INIT_ZERO, /* pivot */ CLUTTER_POINT_INIT_ZERO, /* pivot */
0.f /* pivot-z */ 0.f, /* pivot-z */
{ 0.0, }, FALSE, /* transform */
}; };
/*< private > /*< private >
@ -4977,22 +4994,26 @@ clutter_actor_set_property (GObject *object,
} }
break; break;
case PROP_ANCHOR_X: case PROP_ANCHOR_X: /* XXX:2.0 - remove */
clutter_actor_set_anchor_coord (actor, CLUTTER_X_AXIS, clutter_actor_set_anchor_coord (actor, CLUTTER_X_AXIS,
g_value_get_float (value)); g_value_get_float (value));
break; break;
case PROP_ANCHOR_Y: case PROP_ANCHOR_Y: /* XXX:2.0 - remove */
clutter_actor_set_anchor_coord (actor, CLUTTER_Y_AXIS, clutter_actor_set_anchor_coord (actor, CLUTTER_Y_AXIS,
g_value_get_float (value)); g_value_get_float (value));
break; break;
case PROP_ANCHOR_GRAVITY: case PROP_ANCHOR_GRAVITY: /* XXX:2.0 - remove */
clutter_actor_set_anchor_point_from_gravity (actor, clutter_actor_set_anchor_point_from_gravity (actor,
g_value_get_enum (value)); g_value_get_enum (value));
break; break;
case PROP_SHOW_ON_SET_PARENT: case PROP_TRANSFORM:
clutter_actor_set_transform (actor, g_value_get_boxed (value));
break;
case PROP_SHOW_ON_SET_PARENT: /* XXX:2.0 - remove */
priv->show_on_set_parent = g_value_get_boolean (value); priv->show_on_set_parent = g_value_get_boolean (value);
break; break;
@ -5464,11 +5485,29 @@ clutter_actor_get_property (GObject *object,
} }
break; break;
case PROP_ANCHOR_GRAVITY: case PROP_ANCHOR_GRAVITY: /* XXX:2.0 - remove */
g_value_set_enum (value, clutter_actor_get_anchor_point_gravity (actor)); g_value_set_enum (value, clutter_actor_get_anchor_point_gravity (actor));
break; break;
case PROP_SHOW_ON_SET_PARENT: case PROP_TRANSFORM:
{
ClutterMatrix m;
clutter_actor_get_transform (actor, &m);
g_value_set_boxed (value, &m);
}
break;
case PROP_TRANSFORM_SET:
{
const ClutterTransformInfo *info;
info = _clutter_actor_get_transform_info_or_defaults (actor);
g_value_set_boolean (value, info->transform_set);
}
break;
case PROP_SHOW_ON_SET_PARENT: /* XXX:2.0 - remove */
g_value_set_boolean (value, priv->show_on_set_parent); g_value_set_boolean (value, priv->show_on_set_parent);
break; break;
@ -7003,6 +7042,48 @@ clutter_actor_class_init (ClutterActorClass *klass)
G_PARAM_STATIC_STRINGS | G_PARAM_STATIC_STRINGS |
CLUTTER_PARAM_ANIMATABLE); CLUTTER_PARAM_ANIMATABLE);
/**
* ClutterActor:transform:
*
* Overrides the transformations of a #ClutterActor with a custom
* matrix.
*
* The matrix specified by the #ClutterActor:transform property is
* applied to the actor and its children relative to the actor's
* #ClutterActor:allocation and #ClutterActor:pivot-point.
*
* Application code should rarely need to use this function directly.
*
* Setting this property with a #ClutterMatrix will set the
* #ClutterActor:transform-set property to %TRUE as a side effect;
* setting this property with %NULL will set the
* #ClutterActor:transform-set property to %FALSE.
*
* Since: 1.12
*/
obj_props[PROP_TRANSFORM] =
g_param_spec_boxed ("transform",
P_("Transform"),
P_("Transformation matrix"),
CLUTTER_TYPE_MATRIX,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
/**
* ClutterActor:transform-set:
*
* Whether the #ClutterActor:transform property is set.
*
* Since: 1.12
*/
obj_props[PROP_TRANSFORM_SET] =
g_param_spec_boolean ("transform-set",
P_("Transform Set"),
P_("Whether the transform property is set"),
FALSE,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
/** /**
* ClutterActor:show-on-set-parent: * ClutterActor:show-on-set-parent:
* *
@ -15588,22 +15669,81 @@ clutter_actor_unset_flags (ClutterActor *self,
/** /**
* clutter_actor_get_transformation_matrix: * clutter_actor_get_transformation_matrix:
* @self: a #ClutterActor * @self: a #ClutterActor
* @matrix: (out caller-allocates): the return location for a #CoglMatrix * @matrix: (out caller-allocates): the return location for a #ClutterMatrix
* *
* Retrieves the transformations applied to @self relative to its * Retrieves the transformations applied to @self relative to its
* parent. * parent.
* *
* Since: 1.0 * Since: 1.0
*
* Deprecated: 1.12: Use clutter_actor_get_transform() instead
*/ */
void void
clutter_actor_get_transformation_matrix (ClutterActor *self, clutter_actor_get_transformation_matrix (ClutterActor *self,
CoglMatrix *matrix) ClutterMatrix *matrix)
{ {
clutter_actor_get_transform (self, matrix);
}
/**
* clutter_actor_set_transform:
* @self: a #ClutterActor
* @transform: (allow-none): a #ClutterMatrix, or %NULL to
* unset a custom transformation
*
* Overrides the transformations of a #ClutterActor with a custom
* matrix, which will be applied relative to the origin of the
* actor's allocation and to the actor's pivot point.
*
* Since: 1.12
*/
void
clutter_actor_set_transform (ClutterActor *self,
const ClutterMatrix *transform)
{
ClutterTransformInfo *info;
GObject *obj;
g_return_if_fail (CLUTTER_IS_ACTOR (self)); g_return_if_fail (CLUTTER_IS_ACTOR (self));
cogl_matrix_init_identity (matrix); obj = G_OBJECT (self);
_clutter_actor_apply_modelview_transform (self, matrix); info = _clutter_actor_get_transform_info (self);
if (transform != NULL)
{
info->transform = *transform;
info->transform_set = TRUE;
}
else
info->transform_set = FALSE;
self->priv->transform_valid = FALSE;
clutter_actor_queue_redraw (self);
g_object_notify_by_pspec (obj, obj_props[PROP_TRANSFORM]);
g_object_notify_by_pspec (obj, obj_props[PROP_TRANSFORM_SET]);
}
/**
* clutter_actor_get_transform:
* @self: a #ClutterActor
* @transform: (out caller-allocates): a #ClutterMatrix
*
* Retrieves the current transformation matrix of a #ClutterActor.
*
* Since: 1.12
*/
void
clutter_actor_get_transform (ClutterActor *self,
ClutterMatrix *transform)
{
g_return_if_fail (CLUTTER_IS_ACTOR (self));
g_return_if_fail (transform != NULL);
cogl_matrix_init_identity (transform);
_clutter_actor_apply_modelview_transform (self, transform);
} }
void void

View File

@ -225,7 +225,7 @@ struct _ClutterActorClass
/* transformations */ /* transformations */
void (* apply_transform) (ClutterActor *actor, void (* apply_transform) (ClutterActor *actor,
CoglMatrix *matrix); ClutterMatrix *matrix);
/* event signals */ /* event signals */
gboolean (* event) (ClutterActor *actor, gboolean (* event) (ClutterActor *actor,
@ -666,6 +666,12 @@ void clutter_actor_get_translation
gfloat *translate_x, gfloat *translate_x,
gfloat *translate_y, gfloat *translate_y,
gfloat *translate_z); gfloat *translate_z);
CLUTTER_AVAILABLE_IN_1_12
void clutter_actor_set_transform (ClutterActor *self,
const ClutterMatrix *transform);
CLUTTER_AVAILABLE_IN_1_12
void clutter_actor_get_transform (ClutterActor *self,
ClutterMatrix *transform);
void clutter_actor_get_transformed_position (ClutterActor *self, void clutter_actor_get_transformed_position (ClutterActor *self,
gfloat *x, gfloat *x,
gfloat *y); gfloat *y);
@ -686,8 +692,6 @@ void clutter_actor_apply_relative_transform_to_point
ClutterActor *ancestor, ClutterActor *ancestor,
const ClutterVertex *point, const ClutterVertex *point,
ClutterVertex *vertex); ClutterVertex *vertex);
void clutter_actor_get_transformation_matrix (ClutterActor *self,
CoglMatrix *matrix);
/* Implicit animations */ /* Implicit animations */
CLUTTER_AVAILABLE_IN_1_10 CLUTTER_AVAILABLE_IN_1_10

View File

@ -149,6 +149,7 @@ clutter_actor_get_shader
clutter_actor_get_size clutter_actor_get_size
clutter_actor_get_stage clutter_actor_get_stage
clutter_actor_get_text_direction clutter_actor_get_text_direction
clutter_actor_get_transform
clutter_actor_get_transformation_matrix clutter_actor_get_transformation_matrix
clutter_actor_get_transformed_paint_volume clutter_actor_get_transformed_paint_volume
clutter_actor_get_transformed_position clutter_actor_get_transformed_position
@ -274,6 +275,7 @@ clutter_actor_set_shader_param_float
clutter_actor_set_shader_param_int clutter_actor_set_shader_param_int
clutter_actor_set_size clutter_actor_set_size
clutter_actor_set_text_direction clutter_actor_set_text_direction
clutter_actor_set_transform
clutter_actor_set_translation clutter_actor_set_translation
clutter_actor_set_width clutter_actor_set_width
clutter_actor_set_x_align clutter_actor_set_x_align

View File

@ -148,6 +148,9 @@ void clutter_actor_set_anchor_point_from_gravity (ClutterActor
CLUTTER_DEPRECATED_IN_1_12 CLUTTER_DEPRECATED_IN_1_12
void clutter_actor_move_anchor_point_from_gravity (ClutterActor *self, void clutter_actor_move_anchor_point_from_gravity (ClutterActor *self,
ClutterGravity gravity); ClutterGravity gravity);
CLUTTER_DEPRECATED_IN_1_12
void clutter_actor_get_transformation_matrix (ClutterActor *self,
ClutterMatrix *matrix);
G_END_DECLS G_END_DECLS