Exemple #1
0
void
graphene_matrix_untransform_bounds (const graphene_matrix_t *m,
                                    const graphene_rect_t   *r,
                                    const graphene_rect_t   *bounds,
                                    graphene_rect_t         *res)
{
  graphene_matrix_t inverse;
  graphene_rect_t bounds_t;
  graphene_rect_t rect;

  g_return_if_fail (m != NULL && r != NULL);
  g_return_if_fail (bounds != NULL);
  g_return_if_fail (res != NULL);

  if (graphene_matrix_is_2d (m))
    {
      graphene_matrix_inverse (m, &inverse);
      graphene_matrix_transform_bounds (&inverse, r, res);
      return;
    }

  graphene_matrix_transform_bounds (m, bounds, &bounds_t);
  if (!graphene_rect_intersection (r, &bounds_t, &rect))
    {
      graphene_rect_init (res, 0.f, 0.f, 0.f, 0.f);
      return;
    }

  graphene_matrix_inverse (m, &inverse);
  graphene_matrix_project_rect_bounds (&inverse, &rect, res);
}
Exemple #2
0
gboolean
graphene_matrix_untransform_point (const graphene_matrix_t *m,
                                   const graphene_point_t  *p,
                                   const graphene_rect_t   *bounds,
                                   graphene_point_t        *res)
{
  graphene_matrix_t inverse;
  graphene_rect_t bounds_t;

  g_return_val_if_fail (m != NULL, FALSE);
  g_return_val_if_fail (p != NULL, FALSE);
  g_return_val_if_fail (bounds != NULL, FALSE);
  g_return_val_if_fail (res != NULL, FALSE);

  if (graphene_matrix_is_2d (m))
    {
      graphene_matrix_inverse (m, &inverse);
      graphene_matrix_transform_point (&inverse, p, res);
      return TRUE;
    }

  graphene_matrix_transform_bounds (m, bounds, &bounds_t);
  if (!graphene_rect_contains_point (&bounds_t, p))
    return FALSE;

  graphene_matrix_inverse (m, &inverse);
  graphene_matrix_project_point (&inverse, p, res);

  return TRUE;
}
/**
 * graphene_matrix_untransform_point:
 * @m: a #graphene_matrix_t
 * @p: a #graphene_point_t
 * @bounds: the bounds of the transformation
 * @res: (out caller-allocates): return location for the
 *   untransformed point
 *
 * Undoes the transformation of a #graphene_point_t using the
 * given matrix, within the given rectangular @bounds.
 *
 * Returns: %true if the point was successfully untransformed
 *
 * Since: 1.0
 */
bool
graphene_matrix_untransform_point (const graphene_matrix_t *m,
                                   const graphene_point_t  *p,
                                   const graphene_rect_t   *bounds,
                                   graphene_point_t        *res)
{
  graphene_matrix_t inverse;
  graphene_rect_t bounds_t;

  if (graphene_matrix_is_2d (m))
    {
      graphene_matrix_inverse (m, &inverse);
      graphene_matrix_transform_point (&inverse, p, res);
      return true;
    }

  graphene_matrix_transform_bounds (m, bounds, &bounds_t);
  if (!graphene_rect_contains_point (&bounds_t, p))
    return false;

  graphene_matrix_inverse (m, &inverse);
  graphene_matrix_project_point (&inverse, p, res);

  return true;
}
Exemple #4
0
/**
 * graphene_matrix_interpolate:
 * @a: ...
 * @b: ...
 * @factor: ...
 * @res: (out caller-allocates): ...
 *
 * ...
 *
 * Since: 1.0
 */
void
graphene_matrix_interpolate (const graphene_matrix_t *a,
                             const graphene_matrix_t *b,
                             double                   factor,
                             graphene_matrix_t       *res)
{
  graphene_point3d_t scale_a = { 1.f, 1.f, 1.f }, translate_a;
  graphene_vec4_t perspective_a;
  graphene_quaternion_t rotate_a;
  float shear_a[3] = { 0.f, 0.f, 0.f };

  graphene_point3d_t scale_b = { 1.f, 1.f, 1.f }, translate_b;
  graphene_vec4_t perspective_b;
  graphene_quaternion_t rotate_b;
  float shear_b[3] = { 0.f, 0.f, 0.f };

  graphene_point3d_t scale_r = { 1.f, 1.f, 1.f }, translate_r;
  graphene_quaternion_t rotate_r;
  graphene_matrix_t tmp;
  float shear;

  g_return_if_fail (a != NULL && b != NULL);
  g_return_if_fail (res != NULL);

  if (graphene_matrix_is_2d (a) &&
      graphene_matrix_is_2d (b))
    {
      graphene_vec4_init (&perspective_a, 0.f, 0.f, 0.f, 1.f);
      graphene_vec4_init (&perspective_b, 0.f, 0.f, 0.f, 1.f);
      matrix_decompose_2d (a, &scale_a, shear_a, &rotate_a, &translate_a);
      matrix_decompose_2d (b, &scale_b, shear_b, &rotate_b, &translate_b);
    }
  else
    {
      matrix_decompose_3d (a, &scale_a, shear_a, &rotate_a, &translate_a, &perspective_a);
      matrix_decompose_3d (b, &scale_b, shear_b, &rotate_b, &translate_b, &perspective_b);
    }

  res->value.w = graphene_simd4f_interpolate (perspective_a.value,
                                              perspective_b.value,
                                              factor);

  graphene_point3d_interpolate (&translate_a, &translate_b, factor, &translate_r);
  graphene_matrix_translate (res, &translate_r);

  graphene_quaternion_slerp (&rotate_a, &rotate_b, factor, &rotate_r);
  graphene_quaternion_to_matrix (&rotate_r, &tmp);
  if (!graphene_matrix_is_identity (&tmp))
    graphene_matrix_multiply (&tmp, res, res);

  shear = shear_a[YZ_SHEAR] + (shear_b[YZ_SHEAR] - shear_a[YZ_SHEAR]) * factor;
  if (shear != 0.f)
    graphene_matrix_skew_yz (res, shear);

  shear = shear_a[XZ_SHEAR] + (shear_b[XZ_SHEAR] - shear_a[XZ_SHEAR]) * factor;
  if (shear != 0.f)
    graphene_matrix_skew_xz (res, shear);

  shear = shear_a[XY_SHEAR] + (shear_b[XY_SHEAR] - shear_a[XY_SHEAR]) * factor;
  if (shear != 0.f)
    graphene_matrix_skew_xy (res, shear);

  graphene_point3d_interpolate (&scale_a, &scale_b, factor, &scale_r);
  if (scale_r.x != 1.f && scale_r.y != 1.f && scale_r.z != 0.f)
    graphene_matrix_scale (res, scale_r.x, scale_r.y, scale_r.z);
}