[ClutterBehaviourRotate] Fix up some breakage from the cogl-float branch merge

The rotation angle calculated in clutter_behaviour_rotate_alpha_notify
gets applied to each actor using clutter_behaviour_actors_foreach. The
angle is a ClutterFixed value. Before the cogl float branch merge it
was stuffed into a gpointer using GPOINTER_TO_UINT. The pointer was
then converted back to a uint and cast to a ClutterFixed which worked
out fine even for negative numbers.

After the cogl-float merge the angle is effectively a gfloat. This
gets cast to a uint and stored in a pointer and converted back to a
float via a uint at the other end. However this fails for negative
numbers because a uint -> float conversion can't take advantage of
overflow to preserve the sign so you end up with a large number.

It also had the side effect that it only rotated in whole degrees.

This commit fixes the problem by just passing the ClutterFixed value
inside a closure struct instead of trying to stuff it into a pointer.
This commit is contained in:
Neil Roberts 2009-02-18 17:57:17 +00:00
parent deed85035f
commit a86b9834d3

View File

@ -83,12 +83,16 @@ enum
PROP_CENTER_Z PROP_CENTER_Z
}; };
typedef struct {
ClutterFixed angle;
} RotateFrameClosure;
static void static void
alpha_notify_foreach (ClutterBehaviour *behaviour, alpha_notify_foreach (ClutterBehaviour *behaviour,
ClutterActor *actor, ClutterActor *actor,
gpointer data) gpointer data)
{ {
ClutterFixed angle = GPOINTER_TO_UINT (data); RotateFrameClosure *closure = data;
ClutterBehaviourRotate *rotate_behaviour; ClutterBehaviourRotate *rotate_behaviour;
ClutterBehaviourRotatePrivate *priv; ClutterBehaviourRotatePrivate *priv;
@ -96,7 +100,7 @@ alpha_notify_foreach (ClutterBehaviour *behaviour,
priv = rotate_behaviour->priv; priv = rotate_behaviour->priv;
clutter_actor_set_rotation (actor, priv->axis, clutter_actor_set_rotation (actor, priv->axis,
CLUTTER_FIXED_TO_DOUBLE (angle), CLUTTER_FIXED_TO_DOUBLE (closure->angle),
priv->center_x, priv->center_x,
priv->center_y, priv->center_y,
priv->center_z); priv->center_z);
@ -119,17 +123,18 @@ static void
clutter_behaviour_rotate_alpha_notify (ClutterBehaviour *behaviour, clutter_behaviour_rotate_alpha_notify (ClutterBehaviour *behaviour,
gdouble alpha_value) gdouble alpha_value)
{ {
ClutterFixed factor, angle, start, end; ClutterFixed factor, start, end;
ClutterBehaviourRotate *rotate_behaviour; ClutterBehaviourRotate *rotate_behaviour;
ClutterBehaviourRotatePrivate *priv; ClutterBehaviourRotatePrivate *priv;
RotateFrameClosure closure;
rotate_behaviour = CLUTTER_BEHAVIOUR_ROTATE (behaviour); rotate_behaviour = CLUTTER_BEHAVIOUR_ROTATE (behaviour);
priv = rotate_behaviour->priv; priv = rotate_behaviour->priv;
factor = CLUTTER_FLOAT_TO_FIXED (alpha_value); factor = CLUTTER_FLOAT_TO_FIXED (alpha_value);
angle = 0; closure.angle = 0;
start = priv->angle_start; start = priv->angle_start;
end = priv->angle_end; end = priv->angle_end;
if (priv->direction == CLUTTER_ROTATE_CW && start >= end) if (priv->direction == CLUTTER_ROTATE_CW && start >= end)
{ {
@ -140,12 +145,11 @@ clutter_behaviour_rotate_alpha_notify (ClutterBehaviour *behaviour,
end -= 360.0; end -= 360.0;
} }
angle = CLUTTER_FIXED_MUL ((end - start), alpha_value) closure.angle = CLUTTER_FIXED_MUL (end - start, alpha_value) + start;
+ start;
clutter_behaviour_actors_foreach (behaviour, clutter_behaviour_actors_foreach (behaviour,
alpha_notify_foreach, alpha_notify_foreach,
GUINT_TO_POINTER ((guint)angle)); &closure);
} }
static void static void