From 9dfe31a5424805c51dffd246d6725f6b713dbaa7 Mon Sep 17 00:00:00 2001 From: Tomas Frydrych Date: Wed, 16 May 2007 11:32:50 +0000 Subject: [PATCH] implemented smoothstep alpha function --- ChangeLog | 10 ++ clutter/clutter-alpha.c | 127 +++++++++++++++++++++++++- clutter/clutter-alpha.h | 51 +++++++---- doc/reference/clutter-sections.txt | 5 + doc/reference/clutter.types | 1 + doc/reference/tmpl/clutter-alpha.sgml | 29 ++++++ 6 files changed, 206 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1087eda80..6d4764892 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2007-05-16 Tomas Frydrych + + * clutter/clutter-alpha.h: + * clutter/clutter-alpha.c: + * doc/reference/clutter-sections.txt: + * doc/rererence/clutter.types: + * doc/reference/tmpl/clutter-alpha.sgml: + clutter_smoothstep_func alpha function, + ClutterSmoothstep struct for smoothstep function data. + 2007-05-16 Matthew Allum * clutter/clutter-backend.c: diff --git a/clutter/clutter-alpha.c b/clutter/clutter-alpha.c index 069a6ccbe..6f084ada8 100644 --- a/clutter/clutter-alpha.c +++ b/clutter/clutter-alpha.c @@ -6,8 +6,9 @@ * Authored By Matthew Allum * Jorn Baayen * Emmanuele Bassi + * Tomas Frydrych * - * Copyright (C) 2006 OpenedHand + * Copyright (C) 2006, 2007 OpenedHand * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -647,3 +648,127 @@ clutter_square_func (ClutterAlpha *alpha, return (current_frame_num > (n_frames / 2)) ? CLUTTER_ALPHA_MAX_ALPHA : 0; } + +/** + * clutter_smoothstep_copy: + * @smoothstep: a #ClutterSmoothstep + * + * Makes an allocated copy of a smoothstep. + * + * Return value: the copied smoothstep. + * + * Since: 0.4 + */ +ClutterSmoothstep * +clutter_smoothstep_copy (const ClutterSmoothstep *smoothstep) +{ + ClutterSmoothstep *copy; + + copy = g_slice_new0 (ClutterSmoothstep); + + *copy = *smoothstep; + + return copy; +} + +/** + * clutter_smoothstep_free: + * @smoothstep: a #ClutterSmoothstep + * + * Frees the memory of an allocated smoothstep. + * + * Since: 0.4 + */ +void +clutter_smoothstep_free (ClutterSmoothstep *smoothstep) +{ + if (G_LIKELY (smoothstep)) + { + g_slice_free (ClutterSmoothstep, smoothstep); + } +} + +GType +clutter_smoothstep_get_type (void) +{ + static GType our_type = 0; + + if (G_UNLIKELY (!our_type)) + { + our_type = + g_boxed_type_register_static ("ClutterSmoothstep", + (GBoxedCopyFunc) clutter_smoothstep_copy, + (GBoxedFreeFunc) clutter_smoothstep_free); + } + + return our_type; +} + +/** + * clutter_smoothstep_func: + * @alpha: a #ClutterAlpha + * @data: pointer to a #ClutterSmoothstep defining the minimum and + * maximum thresholds for the smoothstep as supplied to + * clutter_alpha_set_func(). + * + * Convenience alpha function for a smoothstep curve. You can use this + * function as the alpha function for clutter_alpha_set_func(). + * + * Return value: an alpha value + * + * Since: 0.4 + */ +guint32 +clutter_smoothstep_func (ClutterAlpha * alpha, + gpointer * data) +{ + ClutterSmoothstep * smoothstep = data; + ClutterTimeline * timeline; + gint frame; + gint n_frames; + gint32 r; + gint32 x; + + /* + * The smoothstep function uses f(x) = -2x^3 + 3x^2 where x is from <0,1>, + * and precission is critical -- we use 8.24 fixed format for this operation. + * The earlier operations involve division, which we cannot do in 8.24 for + * numbers in <0,1> we use ClutterFixed. + */ + + g_return_val_if_fail (data, 0); + + timeline = clutter_alpha_get_timeline (alpha); + frame = clutter_timeline_get_current_frame (timeline); + n_frames = clutter_timeline_get_n_frames (timeline); + + r = CFX_DIV (frame, n_frames); + + if (r <= smoothstep->min) + return 0; + + if (r >= smoothstep->max) + return CLUTTER_ALPHA_MAX_ALPHA; + + /* + * Normalize x for the smoothstep polynomal. + * + * Convert result to 8.24 for next step. + */ + x = CFX_DIV ((r - smoothstep->min), (smoothstep->max - smoothstep->min)) + << 8; + + /* + * f(x) = -2x^3 + 3x^2 + * + * Convert result to ClutterFixed to avoid overflow in next step. + */ + r = ((x >> 12) * (x >> 12) * 3 - (x >> 15) * (x >> 16) * (x >> 16)) >> 8; + + g_debug ("Frame %d of %d, x %f, ret %f", + frame, n_frames, + CLUTTER_FIXED_TO_DOUBLE (x >> 8), + CLUTTER_FIXED_TO_DOUBLE (r)); + + return CFX_INT (r * CLUTTER_ALPHA_MAX_ALPHA); +} diff --git a/clutter/clutter-alpha.h b/clutter/clutter-alpha.h index 5faf704dd..cac98320e 100644 --- a/clutter/clutter-alpha.h +++ b/clutter/clutter-alpha.h @@ -6,8 +6,9 @@ * Authored By Matthew Allum * Jorn Baayen * Emmanuele Bassi + * Tomas Frydrych * - * Copyright (C) 2006 OpenedHand + * Copyright (C) 2006, 2007 OpenedHand * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -30,6 +31,7 @@ #include #include +#include G_BEGIN_DECLS @@ -100,23 +102,40 @@ void clutter_alpha_set_timeline (ClutterAlpha *alpha, ClutterTimeline *clutter_alpha_get_timeline (ClutterAlpha *alpha); /* convenience functions */ -#define CLUTTER_ALPHA_RAMP_INC clutter_ramp_inc_func -#define CLUTTER_ALPHA_RAMP_DEC clutter_ramp_dec_func -#define CLUTTER_ALPHA_RAMP clutter_ramp_func -#define CLUTTER_ALPHA_SINE clutter_sine_func +#define CLUTTER_ALPHA_RAMP_INC clutter_ramp_inc_func +#define CLUTTER_ALPHA_RAMP_DEC clutter_ramp_dec_func +#define CLUTTER_ALPHA_RAMP clutter_ramp_func +#define CLUTTER_ALPHA_SINE clutter_sine_func /* FIXME add SINE_INC/DEC */ -#define CLUTTER_ALPHA_SQUARE clutter_square_func +#define CLUTTER_ALPHA_SQUARE clutter_square_func +#define CLUTTER_ALPHA_SMOOTHSTEP clutter_smoothstep_func -guint32 clutter_ramp_inc_func (ClutterAlpha *alpha, - gpointer dummy); -guint32 clutter_ramp_dec_func (ClutterAlpha *alpha, - gpointer dummy); -guint32 clutter_ramp_func (ClutterAlpha *alpha, - gpointer dummy); -guint32 clutter_sine_func (ClutterAlpha *alpha, - gpointer dummy); -guint32 clutter_square_func (ClutterAlpha *alpha, - gpointer dummy); +#define CLUTTER_TYPE_SMOOTHSTEP (clutter_smoothstep_get_type ()) + +typedef struct _ClutterSmoothstep ClutterSmoothstep; + +struct _ClutterSmoothstep +{ + ClutterFixed min; + ClutterFixed max; +}; + +ClutterSmoothstep * clutter_smoothstep_copy (const ClutterSmoothstep *smoothstep); + +void clutter_smoothstep_free (ClutterSmoothstep *smoothstep); + +guint32 clutter_ramp_inc_func (ClutterAlpha *alpha, + gpointer dummy); +guint32 clutter_ramp_dec_func (ClutterAlpha *alpha, + gpointer dummy); +guint32 clutter_ramp_func (ClutterAlpha *alpha, + gpointer dummy); +guint32 clutter_sine_func (ClutterAlpha *alpha, + gpointer dummy); +guint32 clutter_square_func (ClutterAlpha *alpha, + gpointer dummy); +guint32 clutter_smoothstep_func (ClutterAlpha *alpha, + gpointer *data); G_END_DECLS diff --git a/doc/reference/clutter-sections.txt b/doc/reference/clutter-sections.txt index 01fa50b0d..ca97a8e47 100644 --- a/doc/reference/clutter-sections.txt +++ b/doc/reference/clutter-sections.txt @@ -101,6 +101,9 @@ ClutterAlphaFunc clutter_alpha_set_func clutter_alpha_set_timeline clutter_alpha_get_timeline +ClutterSmoothstep +clutter_smoothstep_copy +clutter_smoothstep_free CLUTTER_ALPHA_RAMP_INC clutter_ramp_inc_func CLUTTER_ALPHA_RAMP_DEC @@ -111,6 +114,8 @@ CLUTTER_ALPHA_SINE clutter_sine_func CLUTTER_ALPHA_SQUARE clutter_square_func +CLUTTER_ALPHA_SMOOTHSTEP +clutter_smoothstep_func CLUTTER_ALPHA CLUTTER_IS_ALPHA diff --git a/doc/reference/clutter.types b/doc/reference/clutter.types index 1d23a0f43..6039e4ca6 100644 --- a/doc/reference/clutter.types +++ b/doc/reference/clutter.types @@ -11,6 +11,7 @@ clutter_timeline_get_type clutter_media_get_type clutter_behaviour_get_type clutter_alpha_get_type +clutter_smoothstep_get_type clutter_behaviour_bspline_get_type clutter_behaviour_ellipse_get_type clutter_behaviour_opacity_get_type diff --git a/doc/reference/tmpl/clutter-alpha.sgml b/doc/reference/tmpl/clutter-alpha.sgml index 9c01bd988..e624b298a 100644 --- a/doc/reference/tmpl/clutter-alpha.sgml +++ b/doc/reference/tmpl/clutter-alpha.sgml @@ -123,6 +123,35 @@ transforming the current position in the timeline. @Returns: + + +Represents minimum and maximum thresholds for the smoothstep function. The +thresholds are values from <0,1> relative to the frame-length of the behaviour, +i.e., if the behaviour consists of 60 frames, threshold of 0.25 corresponds to +frame 15, and threshold of 1.0 to frame 60. + + +@min: lower threshold; a #ClutterFixed value from <0,1> +@max: upper threshold; a #ClutterFixed value from <0,1> + + + + + + + +@smoothstep: +@Returns: + + + + + + + +@smoothstep: + + Symbolic name for passing clutter_ramp_inc_func().