g_object_thaw_notify (G_OBJECT (self));
}
+/* like ClutterVertex, but using CoglFixed and with a w component */
+typedef struct {
+ CoglFixed x;
+ CoglFixed y;
+ CoglFixed z;
+ CoglFixed w;
+} fixed_vertex_t;
+
+/* copies a fixed vertex into a ClutterVertex */
+static inline void
+fixed_vertex_to_units (const fixed_vertex_t *f,
+ ClutterVertex *u)
+{
+ u->x = CLUTTER_UNITS_FROM_FIXED (f->x);
+ u->y = CLUTTER_UNITS_FROM_FIXED (f->y);
+ u->z = CLUTTER_UNITS_FROM_FIXED (f->z);
+}
+
/*
* Utility functions for manipulating transformation matrix
*
*/
#define M(m,row,col) (m)[(col) * 4 + (row)]
-/* Transform point (x,y,z) by matrix */
-static void
-mtx_transform (ClutterFixed m[16],
- ClutterFixed *x, ClutterFixed *y, ClutterFixed *z,
- ClutterFixed *w)
-{
- ClutterFixed _x, _y, _z, _w;
- _x = *x;
- _y = *y;
- _z = *z;
- _w = *w;
-
- /* We care lot about precision here, so have to use QMUL */
- *x = COGL_FIXED_MUL (M (m, 0, 0), _x)
- + COGL_FIXED_MUL (M (m, 0, 1), _y)
- + COGL_FIXED_MUL (M (m, 0, 2), _z)
- + COGL_FIXED_MUL (M (m, 0, 3), _w);
-
- *y = COGL_FIXED_MUL (M (m, 1, 0), _x)
- + COGL_FIXED_MUL (M (m, 1, 1), _y)
- + COGL_FIXED_MUL (M (m, 1, 2), _z)
- + COGL_FIXED_MUL (M (m, 1, 3), _w);
-
- *z = COGL_FIXED_MUL (M (m, 2, 0), _x)
- + COGL_FIXED_MUL (M (m, 2, 1), _y)
- + COGL_FIXED_MUL (M (m, 2, 2), _z)
- + COGL_FIXED_MUL (M (m, 2, 3), _w);
-
- *w = COGL_FIXED_MUL (M (m, 3, 0), _x)
- + COGL_FIXED_MUL (M (m, 3, 1), _y)
- + COGL_FIXED_MUL (M (m, 3, 2), _z)
- + COGL_FIXED_MUL (M (m, 3, 3), _w);
-
- /* Specially for Matthew: was going to put a comment here, but could not
- * think of anything at all to say ;)
- */
+/* Transforms a vertex using the passed matrix; vertex is
+ * an in-out parameter
+ */
+static inline void
+mtx_transform (const ClutterFixed m[],
+ fixed_vertex_t *vertex)
+{
+ ClutterFixed _x, _y, _z, _w;
+
+ _x = vertex->x;
+ _y = vertex->y;
+ _z = vertex->z;
+ _w = vertex->w;
+
+ /* We care lot about precision here, so have to use MUL instead
+ * of FAST_MUL
+ */
+ vertex->x = COGL_FIXED_MUL (M (m, 0, 0), _x)
+ + COGL_FIXED_MUL (M (m, 0, 1), _y)
+ + COGL_FIXED_MUL (M (m, 0, 2), _z)
+ + COGL_FIXED_MUL (M (m, 0, 3), _w);
+
+ vertex->y = COGL_FIXED_MUL (M (m, 1, 0), _x)
+ + COGL_FIXED_MUL (M (m, 1, 1), _y)
+ + COGL_FIXED_MUL (M (m, 1, 2), _z)
+ + COGL_FIXED_MUL (M (m, 1, 3), _w);
+
+ vertex->z = COGL_FIXED_MUL (M (m, 2, 0), _x)
+ + COGL_FIXED_MUL (M (m, 2, 1), _y)
+ + COGL_FIXED_MUL (M (m, 2, 2), _z)
+ + COGL_FIXED_MUL (M (m, 2, 3), _w);
+
+ vertex->w = COGL_FIXED_MUL (M (m, 3, 0), _x)
+ + COGL_FIXED_MUL (M (m, 3, 1), _y)
+ + COGL_FIXED_MUL (M (m, 3, 2), _z)
+ + COGL_FIXED_MUL (M (m, 3, 3), _w);
+
+ /* Specially for Matthew: was going to put a comment here, but could not
+ * think of anything at all to say ;)
+ */
}
#undef M
+/* Help macros to scale from OpenGL <-1,1> coordinates system to our
+ * X-window based <0,window-size> coordinates
+ */
+#define MTX_GL_SCALE_X(x,w,v1,v2) (COGL_FIXED_MUL (((COGL_FIXED_DIV ((x), (w)) + COGL_FIXED_1) >> 1), (v1)) + (v2))
+#define MTX_GL_SCALE_Y(y,w,v1,v2) ((v1) - COGL_FIXED_MUL (((COGL_FIXED_DIV ((y), (w)) + COGL_FIXED_1) >> 1), (v1)) + (v2))
+#define MTX_GL_SCALE_Z(z,w,v1,v2) (MTX_GL_SCALE_X ((z), (w), (v1), (v2)))
+
+/* transforms a 4-tuple of coordinates using @matrix and
+ * places the result into a fixed @vertex
+ */
+static inline void
+fixed_vertex_transform (const ClutterFixed matrix[],
+ ClutterFixed x,
+ ClutterFixed y,
+ ClutterFixed z,
+ ClutterFixed w,
+ fixed_vertex_t *vertex)
+{
+ fixed_vertex_t tmp = { 0, };
+
+ tmp.x = x;
+ tmp.y = y;
+ tmp.z = z;
+ tmp.w = w;
+
+ mtx_transform (matrix, &tmp);
+
+ *vertex = tmp;
+}
+
+/* scales a fixed @vertex using @matrix and @viewport, and
+ * transforms the result into ClutterUnits, filling @vertex_p
+ */
+static inline void
+fixed_vertex_scale (const ClutterFixed matrix[],
+ const fixed_vertex_t *vertex,
+ const ClutterFixed viewport[],
+ ClutterVertex *vertex_p)
+{
+ ClutterFixed v_x, v_y, v_width, v_height;
+ fixed_vertex_t tmp = { 0, };
+
+ tmp = *vertex;
+
+ mtx_transform (matrix, &tmp);
+
+ v_x = viewport[0];
+ v_y = viewport[1];
+ v_width = viewport[2];
+ v_height = viewport[3];
+
+ tmp.x = MTX_GL_SCALE_X (tmp.x, tmp.w, v_width, v_x);
+ tmp.y = MTX_GL_SCALE_Y (tmp.y, tmp.w, v_height, v_y);
+ tmp.z = MTX_GL_SCALE_Z (tmp.z, tmp.w, v_width, v_x);
+ tmp.w = 0;
+
+ fixed_vertex_to_units (&tmp, vertex_p);
+}
+
/* Applies the transforms associated with this actor and its ancestors,
* retrieves the resulting OpenGL modelview matrix, and uses the matrix
* to transform the supplied point
+ *
+ * The point coordinates are in-out parameters
*/
static void
clutter_actor_transform_point_relative (ClutterActor *actor,
ClutterUnit *w)
{
ClutterFixed mtx[16];
+ fixed_vertex_t vertex = { 0, };
+
+ vertex.x = (x != NULL) ? CLUTTER_UNITS_TO_FIXED (*x) : 0;
+ vertex.y = (y != NULL) ? CLUTTER_UNITS_TO_FIXED (*y) : 0;
+ vertex.z = (z != NULL) ? CLUTTER_UNITS_TO_FIXED (*z) : 0;
+ vertex.w = (w != NULL) ? CLUTTER_UNITS_TO_FIXED (*w) : 0;
cogl_push_matrix();
_clutter_actor_apply_modelview_transform_recursive (actor, ancestor);
+
cogl_get_modelview_matrix (mtx);
- mtx_transform (mtx, x, y, z, w);
+ mtx_transform (mtx, &vertex);
cogl_pop_matrix();
+
+ if (x)
+ *x = CLUTTER_UNITS_FROM_FIXED (vertex.x);
+
+ if (y)
+ *y = CLUTTER_UNITS_FROM_FIXED (vertex.y);
+
+ if (z)
+ *z = CLUTTER_UNITS_FROM_FIXED (vertex.z);
+
+ if (w)
+ *w = CLUTTER_UNITS_FROM_FIXED (vertex.w);
}
/* Applies the transforms associated with this actor and its ancestors,
ClutterUnit *w)
{
ClutterFixed mtx[16];
+ fixed_vertex_t vertex = { 0, };
+
+ vertex.x = (x != NULL) ? CLUTTER_UNITS_TO_FIXED (*x) : 0;
+ vertex.y = (y != NULL) ? CLUTTER_UNITS_TO_FIXED (*y) : 0;
+ vertex.z = (z != NULL) ? CLUTTER_UNITS_TO_FIXED (*z) : 0;
+ vertex.w = (w != NULL) ? CLUTTER_UNITS_TO_FIXED (*w) : 0;
cogl_push_matrix();
_clutter_actor_apply_modelview_transform_recursive (actor, NULL);
+
cogl_get_modelview_matrix (mtx);
- mtx_transform (mtx, x, y, z, w);
+ mtx_transform (mtx, &vertex);
cogl_pop_matrix();
-}
-/* Help macros to scale from OpenGL <-1,1> coordinates system to our
- * X-window based <0,window-size> coordinates
- */
-#define MTX_GL_SCALE_X(x,w,v1,v2) (COGL_FIXED_MUL (((COGL_FIXED_DIV ((x), (w)) + COGL_FIXED_1) >> 1), (v1)) + (v2))
-#define MTX_GL_SCALE_Y(y,w,v1,v2) ((v1) - COGL_FIXED_MUL (((COGL_FIXED_DIV ((y), (w)) + COGL_FIXED_1) >> 1), (v1)) + (v2))
-#define MTX_GL_SCALE_Z(z,w,v1,v2) (MTX_GL_SCALE_X ((z), (w), (v1), (v2)))
+ if (x)
+ *x = CLUTTER_UNITS_FROM_FIXED (vertex.x);
+
+ if (y)
+ *y = CLUTTER_UNITS_FROM_FIXED (vertex.y);
+
+ if (z)
+ *z = CLUTTER_UNITS_FROM_FIXED (vertex.z);
+
+ if (w)
+ *w = CLUTTER_UNITS_FROM_FIXED (vertex.w);
+}
/**
* clutter_actor_apply_relative_transform_to_point:
const ClutterVertex *point,
ClutterVertex *vertex)
{
- ClutterVertex tmp = { 0, };
ClutterFixed v[4];
- ClutterFixed w = COGL_FIXED_1;
+ ClutterFixed x, y, z, w;
g_return_if_fail (CLUTTER_IS_ACTOR (self));
g_return_if_fail (ancestor == NULL || CLUTTER_IS_ACTOR (ancestor));
g_return_if_fail (point != NULL);
g_return_if_fail (vertex != NULL);
- tmp = *point;
+ x = CLUTTER_UNITS_TO_FIXED (vertex->x);
+ y = CLUTTER_UNITS_TO_FIXED (vertex->y);
+ z = CLUTTER_UNITS_TO_FIXED (vertex->z);
+ w = COGL_FIXED_1;
/* First we tranform the point using the OpenGL modelview matrix */
clutter_actor_transform_point_relative (self, ancestor,
- &tmp.x, &tmp.y, &tmp.z,
- &w);
+ &x, &y, &z, &w);
cogl_get_viewport (v);
* The w[3] parameter should always be 1.0 here, so we ignore it; otherwise
* we would have to divide the original verts with it.
*/
- vertex->x = COGL_FIXED_MUL ((tmp.x + COGL_FIXED_0_5), v[2]);
- vertex->y = COGL_FIXED_MUL ((COGL_FIXED_0_5 - tmp.y), v[3]);
- vertex->z = COGL_FIXED_MUL ((tmp.z + COGL_FIXED_0_5), v[2]);
+ vertex->x =
+ CLUTTER_UNITS_FROM_FIXED (COGL_FIXED_MUL ((x + COGL_FIXED_0_5), v[2]));
+ vertex->y =
+ CLUTTER_UNITS_FROM_FIXED (COGL_FIXED_MUL ((COGL_FIXED_0_5 - y), v[3]));
+ vertex->z =
+ CLUTTER_UNITS_FROM_FIXED (COGL_FIXED_MUL ((z + COGL_FIXED_0_5), v[2]));
}
/**
const ClutterVertex *point,
ClutterVertex *vertex)
{
- ClutterVertex tmp = { 0, };
ClutterFixed mtx_p[16];
ClutterFixed v[4];
- ClutterFixed w = COGL_FIXED_1;
+ fixed_vertex_t tmp = { 0, };
g_return_if_fail (CLUTTER_IS_ACTOR (self));
g_return_if_fail (point != NULL);
g_return_if_fail (vertex != NULL);
- tmp = *point;
+ tmp.x = CLUTTER_UNITS_TO_FIXED (vertex->x);
+ tmp.y = CLUTTER_UNITS_TO_FIXED (vertex->y);
+ tmp.z = CLUTTER_UNITS_TO_FIXED (vertex->z);
+ tmp.w = COGL_FIXED_1;
/* First we tranform the point using the OpenGL modelview matrix */
- clutter_actor_transform_point (self, &tmp.x, &tmp.y, &tmp.z, &w);
+ clutter_actor_transform_point (self, &tmp.x, &tmp.y, &tmp.z, &tmp.w);
cogl_get_projection_matrix (mtx_p);
cogl_get_viewport (v);
/* Now, transform it again with the projection matrix */
- mtx_transform (mtx_p, &tmp.x, &tmp.y, &tmp.z, &w);
+ mtx_transform (mtx_p, &tmp);
/* Finaly translate from OpenGL coords to window coords */
- vertex->x = MTX_GL_SCALE_X (tmp.x, w, v[2], v[0]);
- vertex->y = MTX_GL_SCALE_Y (tmp.y, w, v[3], v[1]);
- vertex->z = MTX_GL_SCALE_Z (tmp.z, w, v[2], v[0]);
+ vertex->x =
+ CLUTTER_UNITS_FROM_FIXED (MTX_GL_SCALE_X (tmp.x, tmp.w, v[2], v[0]));
+ vertex->y =
+ CLUTTER_UNITS_FROM_FIXED (MTX_GL_SCALE_Y (tmp.y, tmp.w, v[3], v[1]));
+ vertex->z =
+ CLUTTER_UNITS_FROM_FIXED (MTX_GL_SCALE_Z (tmp.z, tmp.w, v[2], v[0]));
}
/* Recursively tranform supplied vertices with the tranform for the current
* for all the vertices in one go).
*/
static void
-clutter_actor_transform_vertices_relative (ClutterActor *self,
- ClutterActor *ancestor,
- ClutterVertex verts[4],
- ClutterFixed w[4])
+clutter_actor_transform_vertices_relative (ClutterActor *self,
+ ClutterActor *ancestor,
+ fixed_vertex_t vertices[])
{
- ClutterFixed mtx[16];
- ClutterFixed _x, _y, _z, _w;
+ ClutterActorPrivate *priv = self->priv;
+ ClutterFixed mtx[16];
+ ClutterFixed width, height;
+
+ width = CLUTTER_UNITS_TO_FIXED (priv->allocation.x2 - priv->allocation.x1);
+ height = CLUTTER_UNITS_TO_FIXED (priv->allocation.y2 - priv->allocation.y1);
cogl_push_matrix();
_clutter_actor_apply_modelview_transform_recursive (self, ancestor);
- cogl_get_modelview_matrix (mtx);
-
- _x = 0;
- _y = 0;
- _z = 0;
- _w = COGL_FIXED_1;
-
- mtx_transform (mtx, &_x, &_y, &_z, &_w);
-
- verts[0].x = _x;
- verts[0].y = _y;
- verts[0].z = _z;
- w[0] = _w;
-
- _x = self->priv->allocation.x2 - self->priv->allocation.x1;
- _y = 0;
- _z = 0;
- _w = COGL_FIXED_1;
-
- mtx_transform (mtx, &_x, &_y, &_z, &_w);
-
- verts[1].x = _x;
- verts[1].y = _y;
- verts[1].z = _z;
- w[1] = _w;
- _x = 0;
- _y = self->priv->allocation.y2 - self->priv->allocation.y1;
- _z = 0;
- _w = COGL_FIXED_1;
-
- mtx_transform (mtx, &_x, &_y, &_z, &_w);
-
- verts[2].x = _x;
- verts[2].y = _y;
- verts[2].z = _z;
- w[2] = _w;
-
- _x = self->priv->allocation.x2 - self->priv->allocation.x1;
- _y = self->priv->allocation.y2 - self->priv->allocation.y1;
- _z = 0;
- _w = COGL_FIXED_1;
-
- mtx_transform (mtx, &_x, &_y, &_z, &_w);
+ cogl_get_modelview_matrix (mtx);
- verts[3].x = _x;
- verts[3].y = _y;
- verts[3].z = _z;
- w[3] = _w;
+ fixed_vertex_transform (mtx, 0, 0, 0, COGL_FIXED_1, &vertices[0]);
+ fixed_vertex_transform (mtx, width, 0, 0, COGL_FIXED_1, &vertices[1]);
+ fixed_vertex_transform (mtx, 0, height, 0, COGL_FIXED_1, &vertices[2]);
+ fixed_vertex_transform (mtx, width, height, 0, COGL_FIXED_1, &vertices[3]);
cogl_pop_matrix();
}
const ClutterActorBox *box,
ClutterVertex verts[4])
{
- ClutterActor *stage;
- ClutterFixed mtx[16];
- ClutterFixed mtx_p[16];
- ClutterFixed _x, _y, _z, _w;
- ClutterFixed w[4];
- ClutterFixed v[4];
+ ClutterActor *stage;
+ ClutterFixed mtx[16];
+ ClutterFixed mtx_p[16];
+ ClutterFixed v[4];
+ ClutterFixed width, height;
+ fixed_vertex_t vertices[4];
+
+ width = CLUTTER_UNITS_TO_FIXED (box->x2 - box->x1);
+ height = CLUTTER_UNITS_TO_FIXED (box->y2 - box->y1);
/* We essentially have to dupe some code from clutter_redraw() here
* to make sure GL Matrices etc are initialised if we're called and we
_clutter_stage_maybe_setup_viewport (CLUTTER_STAGE (stage));
cogl_push_matrix();
+
_clutter_actor_apply_modelview_transform_recursive (self, NULL);
cogl_get_modelview_matrix (mtx);
- _x = 0;
- _y = 0;
- _z = 0;
- _w = COGL_FIXED_1;
-
- mtx_transform (mtx, &_x, &_y, &_z, &_w);
-
- verts[0].x = _x;
- verts[0].y = _y;
- verts[0].z = _z;
- w[0] = _w;
-
- _x = box->x2 - box->x1;
- _y = 0;
- _z = 0;
- _w = COGL_FIXED_1;
-
- mtx_transform (mtx, &_x, &_y, &_z, &_w);
-
- verts[1].x = _x;
- verts[1].y = _y;
- verts[1].z = _z;
- w[1] = _w;
-
- _x = 0;
- _y = box->y2 - box->y1;
- _z = 0;
- _w = COGL_FIXED_1;
-
- mtx_transform (mtx, &_x, &_y, &_z, &_w);
-
- verts[2].x = _x;
- verts[2].y = _y;
- verts[2].z = _z;
- w[2] = _w;
-
- _x = box->x2 - box->x1;
- _y = box->y2 - box->y1;
- _z = 0;
- _w = COGL_FIXED_1;
-
- mtx_transform (mtx, &_x, &_y, &_z, &_w);
-
- verts[3].x = _x;
- verts[3].y = _y;
- verts[3].z = _z;
- w[3] = _w;
+ fixed_vertex_transform (mtx, 0, 0, 0, COGL_FIXED_1, &vertices[0]);
+ fixed_vertex_transform (mtx, width, 0, 0, COGL_FIXED_1, &vertices[1]);
+ fixed_vertex_transform (mtx, 0, height, 0, COGL_FIXED_1, &vertices[2]);
+ fixed_vertex_transform (mtx, width, height, 0, COGL_FIXED_1, &vertices[3]);
cogl_pop_matrix();
cogl_get_projection_matrix (mtx_p);
cogl_get_viewport (v);
- mtx_transform (mtx_p,
- &verts[0].x,
- &verts[0].y,
- &verts[0].z,
- &w[0]);
-
- verts[0].x = MTX_GL_SCALE_X (verts[0].x, w[0], v[2], v[0]);
- verts[0].y = MTX_GL_SCALE_Y (verts[0].y, w[0], v[3], v[1]);
- verts[0].z = MTX_GL_SCALE_Z (verts[0].z, w[0], v[2], v[0]);
-
- mtx_transform (mtx_p,
- &verts[1].x,
- &verts[1].y,
- &verts[1].z,
- &w[1]);
-
- verts[1].x = MTX_GL_SCALE_X (verts[1].x, w[1], v[2], v[0]);
- verts[1].y = MTX_GL_SCALE_Y (verts[1].y, w[1], v[3], v[1]);
- verts[1].z = MTX_GL_SCALE_Z (verts[1].z, w[1], v[2], v[0]);
-
- mtx_transform (mtx_p,
- &verts[2].x,
- &verts[2].y,
- &verts[2].z,
- &w[2]);
-
- verts[2].x = MTX_GL_SCALE_X (verts[2].x, w[2], v[2], v[0]);
- verts[2].y = MTX_GL_SCALE_Y (verts[2].y, w[2], v[3], v[1]);
- verts[2].z = MTX_GL_SCALE_Z (verts[2].z, w[2], v[2], v[0]);
-
- mtx_transform (mtx_p,
- &verts[3].x,
- &verts[3].y,
- &verts[3].z,
- &w[3]);
-
- verts[3].x = MTX_GL_SCALE_X (verts[3].x, w[3], v[2], v[0]);
- verts[3].y = MTX_GL_SCALE_Y (verts[3].y, w[3], v[3], v[1]);
- verts[3].z = MTX_GL_SCALE_Z (verts[3].z, w[3], v[2], v[0]);
+ fixed_vertex_scale (mtx_p, &vertices[0], v, &verts[0]);
+ fixed_vertex_scale (mtx_p, &vertices[1], v, &verts[1]);
+ fixed_vertex_scale (mtx_p, &vertices[2], v, &verts[2]);
+ fixed_vertex_scale (mtx_p, &vertices[3], v, &verts[3]);
}
/**
* actor in the plane of @ancestor. The returned vertices relate to
* the #ClutterActorBox coordinates as follows:
* <itemizedlist>
- * <listitem><para>v[0] contains (x1, y1)</para></listitem>
- * <listitem><para>v[1] contains (x2, y1)</para></listitem>
- * <listitem><para>v[2] contains (x1, y2)</para></listitem>
- * <listitem><para>v[3] contains (x2, y2)</para></listitem>
+ * <listitem><para>@verts[0] contains (x1, y1)</para></listitem>
+ * <listitem><para>@verts[1] contains (x2, y1)</para></listitem>
+ * <listitem><para>@verts[2] contains (x1, y2)</para></listitem>
+ * <listitem><para>@verts[3] contains (x2, y2)</para></listitem>
* </itemizedlist>
*
* If @ancestor is %NULL the ancestor will be the #ClutterStage. In
void
clutter_actor_get_allocation_vertices (ClutterActor *self,
ClutterActor *ancestor,
- ClutterVertex verts[4])
+ ClutterVertex verts[])
{
- ClutterFixed v[4];
- ClutterFixed w[4];
- ClutterActorPrivate *priv;
- ClutterActor *stage;
+ ClutterActorPrivate *priv;
+ ClutterActor *stage;
+ ClutterFixed v[4];
+ fixed_vertex_t vertices[4];
+ fixed_vertex_t tmp = { 0, };
g_return_if_fail (CLUTTER_IS_ACTOR (self));
g_return_if_fail (ancestor == NULL || CLUTTER_IS_ACTOR (ancestor));
if (priv->needs_allocation)
_clutter_stage_maybe_relayout (stage);
- clutter_actor_transform_vertices_relative (self, ancestor, verts, w);
+ clutter_actor_transform_vertices_relative (self, ancestor, vertices);
+
cogl_get_viewport (v);
/*
- * The w[3] parameter should always be 1.0 here, so we ignore it; otherwise
- * we would have to devide the original verts with it.
+ * The w[3] parameter should always be 1.0 here, so we ignore it;
+ * otherwise we would have to divide the original verts with it.
*/
- verts[0].x = COGL_FIXED_MUL ((verts[0].x + COGL_FIXED_0_5), v[2]);
- verts[0].y = COGL_FIXED_MUL ((COGL_FIXED_0_5 - verts[0].y), v[3]);
- verts[0].z = COGL_FIXED_MUL ((verts[0].z + COGL_FIXED_0_5), v[2]);
+ tmp.x = COGL_FIXED_MUL ((vertices[0].x + COGL_FIXED_0_5), v[2]);
+ tmp.y = COGL_FIXED_MUL ((COGL_FIXED_0_5 - vertices[0].y), v[3]);
+ tmp.z = COGL_FIXED_MUL ((vertices[0].z + COGL_FIXED_0_5), v[2]);
+ fixed_vertex_to_units (&tmp, &verts[0]);
- verts[1].x = COGL_FIXED_MUL ((verts[1].x + COGL_FIXED_0_5), v[2]);
- verts[1].y = COGL_FIXED_MUL ((COGL_FIXED_0_5 - verts[1].y), v[3]);
- verts[1].z = COGL_FIXED_MUL ((verts[1].z + COGL_FIXED_0_5), v[2]);
+ tmp.x = COGL_FIXED_MUL ((vertices[1].x + COGL_FIXED_0_5), v[2]);
+ tmp.y = COGL_FIXED_MUL ((COGL_FIXED_0_5 - vertices[1].y), v[3]);
+ tmp.z = COGL_FIXED_MUL ((vertices[1].z + COGL_FIXED_0_5), v[2]);
+ fixed_vertex_to_units (&tmp, &verts[1]);
- verts[2].x = COGL_FIXED_MUL ((verts[2].x + COGL_FIXED_0_5), v[2]);
- verts[2].y = COGL_FIXED_MUL ((COGL_FIXED_0_5 - verts[2].y), v[3]);
- verts[2].z = COGL_FIXED_MUL ((verts[2].z + COGL_FIXED_0_5), v[2]);
+ tmp.x = COGL_FIXED_MUL ((vertices[2].x + COGL_FIXED_0_5), v[2]);
+ tmp.y = COGL_FIXED_MUL ((COGL_FIXED_0_5 - vertices[2].y), v[3]);
+ tmp.z = COGL_FIXED_MUL ((vertices[2].z + COGL_FIXED_0_5), v[2]);
+ fixed_vertex_to_units (&tmp, &verts[2]);
- verts[3].x = COGL_FIXED_MUL ((verts[3].x + COGL_FIXED_0_5), v[2]);
- verts[3].y = COGL_FIXED_MUL ((COGL_FIXED_0_5 - verts[3].y), v[3]);
- verts[3].z = COGL_FIXED_MUL ((verts[3].z + COGL_FIXED_0_5), v[2]);
+ tmp.x = COGL_FIXED_MUL ((vertices[3].x + COGL_FIXED_0_5), v[2]);
+ tmp.y = COGL_FIXED_MUL ((COGL_FIXED_0_5 - vertices[3].y), v[3]);
+ tmp.z = COGL_FIXED_MUL ((vertices[3].z + COGL_FIXED_0_5), v[2]);
+ fixed_vertex_to_units (&tmp, &verts[3]);
}
/**
* Since: 0.6
*/
gboolean
-clutter_actor_transform_stage_point (ClutterActor *self,
- ClutterUnit x,
- ClutterUnit y,
- ClutterUnit *x_out,
- ClutterUnit *y_out)
+clutter_actor_transform_stage_point (ClutterActor *self,
+ ClutterUnit x,
+ ClutterUnit y,
+ ClutterUnit *x_out,
+ ClutterUnit *y_out)
{
ClutterVertex v[4];
ClutterFixed ST[3][3];
ClutterFixed RQ[3][3];
int du, dv, xi, yi;
- ClutterFixed xf, yf, wf, px, py, det;
+ ClutterUnit px, py;
+ ClutterFixed xf, yf, wf, det;
ClutterActorPrivate *priv;
g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE);
*
* http://www.cs.cmu.edu/~ph/texfund/texfund.pdf
*
- * and the sample implementaion at http://www.cs.cmu.edu/~ph/src/texfund/.
+ * and the sample implementation at http://www.cs.cmu.edu/~ph/src/texfund/.
*
- * Our texture is a rectangle with origin [0,0], so we are mapping from quad
- * to rectangle only, which significantly simplifies things; the function
- * calls have been unrolled, and most of the math is done in fixed point.
+ * Our texture is a rectangle with origin [0, 0], so we are mapping from
+ * quad to rectangle only, which significantly simplifies things; the
+ * function calls have been unrolled, and most of the math is done in fixed
+ * point.
*/
clutter_actor_get_abs_allocation_vertices (self, v);
#define FP2FX COGL_FIXED_FROM_FLOAT
#define FX2FP COGL_FIXED_TO_DOUBLE
+#define UX2FP CLUTTER_UNITS_TO_FLOAT
+#define UX2FX CLUTTER_UNITS_TO_FIXED
#define FP2INT CLUTTER_FLOAT_TO_INT
-#define DET2X(a,b,c,d) (COGL_FIXED_MUL (a, d) - COGL_FIXED_MUL (b, c))
-#define DET2FP(a,b,c,d) (a*d - b*c)
+#define DET2X(a,b,c,d) (COGL_FIXED_MUL ((a), (d)) - COGL_FIXED_MUL ((b), (c)))
+#define DET2FP(a,b,c,d) ((a) * (d) - (b) * (c))
/*
* First, find mapping from unit uv square to xy quadrilateral; this
py = v[0].y - v[1].y + v[3].y - v[2].y;
if (!px && !py)
- { /* affine transform */
- RQ[0][0] = v[1].x - v[0].x;
- RQ[1][0] = v[3].x - v[1].x;
- RQ[2][0] = v[0].x;
- RQ[0][1] = v[1].y - v[0].y;
- RQ[1][1] = v[3].y - v[1].y;
- RQ[2][1] = v[0].y;
+ {
+ /* affine transform */
+ RQ[0][0] = UX2FX (v[1].x - v[0].x);
+ RQ[1][0] = UX2FX (v[3].x - v[1].x);
+ RQ[2][0] = UX2FX (v[0].x);
+ RQ[0][1] = UX2FX (v[1].y - v[0].y);
+ RQ[1][1] = UX2FX (v[3].y - v[1].y);
+ RQ[2][1] = UX2FX (v[0].y);
RQ[0][2] = 0;
RQ[1][2] = 0;
RQ[2][2] = COGL_FIXED_1;
}
else
- { /*
- * projective transform
+ {
+ /* projective transform
*
* Must do this in floating point, as the del value can overflow the
* range of ClutterFixed for large actors.
*/
double dx1, dx2, dy1, dy2, del;
- dx1 = FX2FP (v[1].x - v[3].x);
- dx2 = FX2FP (v[2].x - v[3].x);
- dy1 = FX2FP (v[1].y - v[3].y);
- dy2 = FX2FP (v[2].y - v[3].y);
-
- del = DET2FP (dx1,dx2, dy1,dy2);
+ dx1 = UX2FP (v[1].x - v[3].x);
+ dx2 = UX2FP (v[2].x - v[3].x);
+ dy1 = UX2FP (v[1].y - v[3].y);
+ dy2 = UX2FP (v[2].y - v[3].y);
+ del = DET2FP (dx1, dx2, dy1, dy2);
if (!del)
return FALSE;
* The division here needs to be done in floating point for
* precisions reasons.
*/
- RQ[0][2] = FP2FX (DET2FP (FX2FP(px),dx2, FX2FP(py),dy2) / del);
- RQ[1][2] = FP2FX (DET2FP (dx1,FX2FP(px), dy1,FX2FP(py)) / del);
- RQ[1][2] = FP2FX (DET2FP(dx1,FX2FP(px), dy1,FX2FP(py))/del);
+ RQ[0][2] = FP2FX (DET2FP (UX2FP (px), dx2, UX2FP (py), dy2) / del);
+ RQ[1][2] = FP2FX (DET2FP (dx1, UX2FP (px), dy1, UX2FP (py)) / del);
+ RQ[1][2] = FP2FX (DET2FP (dx1, UX2FP (px), dy1, UX2FP (py)) / del);
RQ[2][2] = COGL_FIXED_1;
- RQ[0][0] = v[1].x - v[0].x + COGL_FIXED_MUL (RQ[0][2], v[1].x);
- RQ[1][0] = v[2].x - v[0].x + COGL_FIXED_MUL (RQ[1][2], v[2].x);
- RQ[2][0] = v[0].x;
- RQ[0][1] = v[1].y - v[0].y + COGL_FIXED_MUL (RQ[0][2], v[1].y);
- RQ[1][1] = v[2].y - v[0].y + COGL_FIXED_MUL (RQ[1][2], v[2].y);
- RQ[2][1] = v[0].y;
+ RQ[0][0] = UX2FX (v[1].x - v[0].x)
+ + COGL_FIXED_MUL (RQ[0][2], UX2FX (v[1].x));
+ RQ[1][0] = UX2FX (v[2].x - v[0].x)
+ + COGL_FIXED_MUL (RQ[1][2], UX2FX (v[2].x));
+ RQ[2][0] = UX2FX (v[0].x);
+ RQ[0][1] = UX2FX (v[1].y - v[0].y)
+ + COGL_FIXED_MUL (RQ[0][2], UX2FX (v[1].y));
+ RQ[1][1] = UX2FX (v[2].y - v[0].y)
+ + COGL_FIXED_MUL (RQ[1][2], UX2FX (v[2].y));
+ RQ[2][1] = UX2FX (v[0].y);
}
/*
return FALSE;
/*
- * Now transform our point with the ST matrix; the notional w coordiance
- * is 1, hence the last part is simply added.
+ * Now transform our point with the ST matrix; the notional w
+ * coordinate is 1, hence the last part is simply added.
*/
xi = CLUTTER_UNITS_TO_DEVICE (x);
yi = CLUTTER_UNITS_TO_DEVICE (y);
- xf = xi*ST[0][0] + yi*ST[1][0] + ST[2][0];
- yf = xi*ST[0][1] + yi*ST[1][1] + ST[2][1];
- wf = xi*ST[0][2] + yi*ST[1][2] + ST[2][2];
+ xf = xi * ST[0][0] + yi * ST[1][0] + ST[2][0];
+ yf = xi * ST[0][1] + yi * ST[1][1] + ST[2][1];
+ wf = xi * ST[0][2] + yi * ST[1][2] + ST[2][2];
/*
* The division needs to be done in floating point for precision reasons.
*/
if (x_out)
*x_out = CLUTTER_UNITS_FROM_FLOAT (FX2FP (xf) / FX2FP (wf));
+
if (y_out)
*y_out = CLUTTER_UNITS_FROM_FLOAT (FX2FP (yf) / FX2FP (wf));
+#undef UX2FX
+#undef UX2FP
#undef FP2FX
#undef FX2FP
#undef FP2INT