Exemple #1
0
static gpointer
matrix_setup (void)
{
  MatrixBench *res = g_new0 (MatrixBench, 1);
  int i;

  res->a = alloc_n_matrix (N_ROUNDS);
  res->b = alloc_n_matrix (N_ROUNDS);
  res->c = alloc_n_matrix (N_ROUNDS);

  res->pa = alloc_n_vec (N_ROUNDS);
  res->qa = alloc_n_vec (N_ROUNDS);
  res->ra = alloc_n_vec (N_ROUNDS);

  for (i = 0; i < N_ROUNDS; i++)
    {
      graphene_simd4f_t p, q;

      p = graphene_simd4f_init (i, i, i, i);
      q = graphene_simd4f_init (N_ROUNDS - i, N_ROUNDS - i, N_ROUNDS - i, N_ROUNDS - i);

      res->a[i] = graphene_simd4x4f_init (p, p, p, p);
      res->b[i] = graphene_simd4x4f_init (q, q, q, q);

      res->pa[i] = graphene_simd4f_init (i, i, 0.f, 0.f);
      res->qa[i] = graphene_simd4f_init (N_ROUNDS - i, N_ROUNDS - 1, 1.f, 0.f);
    }

  return res;
}
/**
 * graphene_quaternion_slerp:
 * @a: a #graphene_quaternion_t
 * @b: a #graphene_quaternion_t
 * @factor: the linear interpolation factor
 * @res: (out caller-allocates): return location for the interpolated
 *   quaternion
 *
 * Interpolates between the two given quaternions using a spherical
 * linear interpolation, or [SLERP](http://en.wikipedia.org/wiki/Slerp),
 * using the given interpolation @factor.
 *
 * Since: 1.0
 */
void
graphene_quaternion_slerp (const graphene_quaternion_t *a,
                           const graphene_quaternion_t *b,
                           float                        factor,
                           graphene_quaternion_t       *res)
{
  float theta, r_sin_theta, right_v, left_v, dot;
  graphene_simd4f_t v_a, v_b, left, right, sum;

  v_a = graphene_simd4f_init (a->x, a->y, a->z, a->w);
  v_b = graphene_simd4f_init (b->x, b->y, b->z, b->w);

  dot = CLAMP (graphene_simd4f_get_x (graphene_simd4f_dot4 (v_a, v_b)), -1.f, 1.f);
  if (dot == 1.f)
    {
      *res = *a;
      return;
    }

  theta = acos (dot);
  r_sin_theta = 1.f / sqrtf (1.f - dot * dot);
  right_v = sinf (factor * theta) * r_sin_theta;
  left_v = cosf (factor * theta) - dot * right_v;

  left = graphene_simd4f_init (a->x, a->y, a->z, a->w);
  right = graphene_simd4f_init (b->x, b->y, b->z, b->w);

  left = graphene_simd4f_mul (left, graphene_simd4f_splat (left_v));
  right = graphene_simd4f_mul (right, graphene_simd4f_splat (right_v));
  sum = graphene_simd4f_add (left, right);

  graphene_quaternion_init_from_simd4f (res, sum);
}
Exemple #3
0
static void
init_static_vec2_once (void)
{
  static_vec2[VEC2_ZERO].value = graphene_simd4f_init_zero ();
  static_vec2[VEC2_ONE].value = graphene_simd4f_init (1.f, 1.f, 0.f, 0.f);
  static_vec2[VEC2_X_AXIS].value = graphene_simd4f_init (1.f, 0.f, 0.f, 0.f);
  static_vec2[VEC2_Y_AXIS].value = graphene_simd4f_init (0.f, 1.f, 0.f, 0.f);
}
Exemple #4
0
static void
init_static_vec4_once (void)
{
  static_vec4[VEC4_ZERO].value = graphene_simd4f_init_zero ();
  static_vec4[VEC4_ONE].value = graphene_simd4f_splat (1.f);
  static_vec4[VEC4_X_AXIS].value = graphene_simd4f_init (1.f, 0.f, 0.f, 0.f);
  static_vec4[VEC4_Y_AXIS].value = graphene_simd4f_init (0.f, 1.f, 0.f, 0.f);
  static_vec4[VEC4_Z_AXIS].value = graphene_simd4f_init (0.f, 0.f, 1.f, 0.f);
  static_vec4[VEC4_W_AXIS].value = graphene_simd4f_init (0.f, 0.f, 0.f, 1.f);
}
/**
 * graphene_quaternion_dot:
 * @a: a #graphene_quaternion_t
 * @b: a #graphene_quaternion_t
 *
 * Computes the dot product of two #graphene_quaternion_t.
 *
 * Returns: the value of the dot products
 *
 * Since: 1.0
 */
float
graphene_quaternion_dot (const graphene_quaternion_t *a,
                         const graphene_quaternion_t *b)
{
  graphene_simd4f_t v_a, v_b;

  v_a = graphene_simd4f_init (a->x, a->y, a->z, a->w);
  v_b = graphene_simd4f_init (b->x, b->y, b->z, b->w);

  return graphene_simd4f_get_x (graphene_simd4f_dot4 (v_a, v_b));
}
/**
 * graphene_matrix_init_translate:
 * @m: a #graphene_matrix_t
 * @p: the translation coordinates
 *
 * Initializes a #graphene_matrix_t with a translation to the
 * given coordinates.
 *
 * Returns: (transfer none): the initialized matrix
 *
 * Since: 1.0
 */
graphene_matrix_t *
graphene_matrix_init_translate (graphene_matrix_t        *m,
                                const graphene_point3d_t *p)
{
  m->value =
    graphene_simd4x4f_init (graphene_simd4f_init (1.0f, 0.0f, 0.0f, 0.0f),
                            graphene_simd4f_init (0.0f, 1.0f, 0.0f, 0.0f),
                            graphene_simd4f_init (0.0f, 0.0f, 1.0f, 0.0f),
                            graphene_simd4f_init (p->x, p->y, p->z, 1.0f));

  return m;
}
/**
 * graphene_matrix_init_scale:
 * @m: a #graphene_matrix_t
 * @x: the scale factor on the X axis
 * @y: the scale factor on the Y axis
 * @z: the scale factor on the Z axis
 *
 * Initializes a #graphene_matrix_t with the given scaling factors.
 *
 * Returns: (transfer none): the initialized matrix
 *
 * Since: 1.0
 */
graphene_matrix_t *
graphene_matrix_init_scale (graphene_matrix_t *m,
                            float              x,
                            float              y,
                            float              z)
{
  m->value =
    graphene_simd4x4f_init (graphene_simd4f_init (   x, 0.0f, 0.0f, 0.0f),
                            graphene_simd4f_init (0.0f,    y, 0.0f, 0.0f),
                            graphene_simd4f_init (0.0f, 0.0f,    z, 0.0f),
                            graphene_simd4f_init (0.0f, 0.0f, 0.0f, 1.0f));

  return m;
}
Exemple #8
0
graphene_matrix_t *
graphene_matrix_init_translate (graphene_matrix_t        *m,
                                const graphene_point3d_t *p)
{
  g_return_val_if_fail (m != NULL, NULL);
  g_return_val_if_fail (p != NULL, m);

  m->value =
    graphene_simd4x4f_init (graphene_simd4f_init (1.0f, 0.0f, 0.0f, 0.0f),
                            graphene_simd4f_init (0.0f, 1.0f, 0.0f, 0.0f),
                            graphene_simd4f_init (0.0f, 0.0f, 1.0f, 0.0f),
                            graphene_simd4f_init (p->x, p->y, p->z, 1.0f));

  return m;
}
Exemple #9
0
/**
 * graphene_vec3_get_xyz1:
 * @v: a #graphene_vec3_t
 * @res: (out caller-allocates): return location for the vector
 *
 * Converts a #graphene_vec3_t in a #graphene_vec4_t using 1.0
 * as the value for the fourth component of the resulting vector.
 *
 * Since: 1.0
 */
void
graphene_vec3_get_xyz1 (const graphene_vec3_t *v,
                        graphene_vec4_t       *res)
{
  res->value = graphene_simd4f_add (graphene_simd4f_zero_w (v->value),
                                    graphene_simd4f_init (0.f, 0.f, 0.f, 1.f));
}
Exemple #10
0
graphene_matrix_t *
graphene_matrix_init_scale (graphene_matrix_t *m,
                            float              x,
                            float              y,
                            float              z)
{
  g_return_val_if_fail (m != NULL, NULL);

  m->value =
    graphene_simd4x4f_init (graphene_simd4f_init (   x, 0.0f, 0.0f, 0.0f),
                            graphene_simd4f_init (0.0f,    y, 0.0f, 0.0f),
                            graphene_simd4f_init (0.0f, 0.0f,    z, 0.0f),
                            graphene_simd4f_init (0.0f, 0.0f, 0.0f, 1.0f));

  return m;
}
Exemple #11
0
/**
 * graphene_matrix_init_from_2d:
 * @m: a #graphene_matrix_t
 * @xx: the xx member
 * @yx: the yx member
 * @xy: the xy member
 * @yy: the yy member
 * @x_0: the x0 member
 * @y_0: the y0 member
 *
 * Initializes a #graphene_matrix_t from the values of an affine
 * transformation matrix.
 *
 * The arguments map to the following matrix layout:
 *
 * |[
 *   | xx yx |   |  a  b  0 |
 *   | xy yy | = |  c  d  0 |
 *   | x0 y0 |   | tx ty  1 |
 * ]|
 *
 * This function can be used to convert between a matrix type from
 * other libraries and a #graphene_matrix_t.
 *
 * Returns: (transfer none): the initialized matrix
 *
 * Since: 1.0
 */
graphene_matrix_t *
graphene_matrix_init_from_2d (graphene_matrix_t *m,
                              double             xx,
                              double             yx,
                              double             xy,
                              double             yy,
                              double             x_0,
                              double             y_0)
{
  m->value = graphene_simd4x4f_init (graphene_simd4f_init ( xx,  yx, 0.f, 0.f),
                                     graphene_simd4f_init ( yx,  yy, 0.f, 0.f),
                                     graphene_simd4f_init (0.f, 0.f, 1.f, 0.f),
                                     graphene_simd4f_init (x_0, y_0, 0.f, 1.f));

  return m;
}
/**
 * graphene_quaternion_equal:
 * @a: a #graphene_quaternion_t
 * @b: a #graphene_quaternion_t
 *
 * Checks whether the given quaternions are equal.
 *
 * Returns: `true` if the quaternions are equal
 *
 * Since: 1.0
 */
bool
graphene_quaternion_equal (const graphene_quaternion_t *a,
                           const graphene_quaternion_t *b)
{
  graphene_simd4f_t v_a, v_b;

  if (a == b)
    return true;

  if (a == NULL || b == NULL)
    return false;

  v_a = graphene_simd4f_init (a->x, a->y, a->z, a->w);
  v_b = graphene_simd4f_init (b->x, b->y, b->z, b->w);

  return graphene_simd4f_cmp_eq (v_a, v_b);
}
Exemple #13
0
/**
 * graphene_point_near:
 * @a: a #graphene_point_t
 * @b: a #graphene_point_t
 * @epsilon: threshold between the two points
 *
 * Checks whether the two points @a and @b are within
 * the threshold of @epsilon.
 *
 * Returns: `true` if the distance is within @epsilon
 *
 * Since: 1.0
 */
bool
graphene_point_near (const graphene_point_t *a,
                     const graphene_point_t *b,
                     float                   epsilon)
{
  graphene_simd4f_t s_a, s_b, res;

  if (a == b)
    return true;

  s_a = graphene_simd4f_init (a->x, a->y, 0.f, 0.f);
  s_b = graphene_simd4f_init (b->x, b->y, 0.f, 0.f);
  res = graphene_simd4f_sub (s_a, s_b);

  return fabsf (graphene_simd4f_get_x (res)) < epsilon &&
         fabsf (graphene_simd4f_get_y (res)) < epsilon;
}
Exemple #14
0
/**
 * graphene_simd4f_init:
 * @x: the first component of the vector
 * @y: the second component of the vector
 * @z: the third component of the vector
 * @w: the fourth component of the vector
 *
 * Initializes a #graphene_simd4f_t with the given values.
 *
 * Returns: the initialized #graphene_simd4f_t
 *
 * Since: 1.0
 */
graphene_simd4f_t
(graphene_simd4f_init) (float x,
                        float y,
                        float z,
                        float w)
{
  return graphene_simd4f_init (x, y, z, w);
}
Exemple #15
0
/**
 * graphene_matrix_init_skew:
 * @m: a #graphene_matrix_t
 * @x_skew: skew factor on the X axis
 * @y_skew: skew factor on the Y axis
 *
 * Initializes a #graphene_matrix_t with a skew transformation
 * with the given factors.
 *
 * Returns: (transfer none): the initialized matrix
 *
 * Since: 1.0
 */
graphene_matrix_t *
graphene_matrix_init_skew (graphene_matrix_t *m,
                           float              x_skew,
                           float              y_skew)
{
  float t_x, t_y;

  t_x = tanf (x_skew);
  t_y = tanf (y_skew);

  m->value =
    graphene_simd4x4f_init (graphene_simd4f_init (1.0f,  t_y, 0.0f, 0.0f),
                            graphene_simd4f_init ( t_x, 1.0f, 0.0f, 0.0f),
                            graphene_simd4f_init (0.0f, 0.0f, 1.0f, 0.0f),
                            graphene_simd4f_init (0.0f, 0.0f, 0.0f, 1.0f));

  return m;
}
Exemple #16
0
graphene_simd4f_t
(graphene_simd4f_cross3) (const graphene_simd4f_t a,
                          const graphene_simd4f_t b)
{
  return graphene_simd4f_init (a.y * b.z - a.z * b.y,
                               a.z * b.x - a.x * b.z,
                               a.x * b.y - a.y * b.x,
                               0.f);
}
Exemple #17
0
graphene_simd4f_t
(graphene_simd4f_min) (const graphene_simd4f_t a,
                       const graphene_simd4f_t b)
{
  return graphene_simd4f_init (a.x < b.x ? a.x : b.x,
                               a.y < b.y ? a.y : b.y,
                               a.z < b.z ? a.z : b.z,
                               a.w < b.w ? a.w : b.w);
}
Exemple #18
0
graphene_simd4f_t
(graphene_simd4f_max) (const graphene_simd4f_t a,
                       const graphene_simd4f_t b)
{
  return graphene_simd4f_init (a.x > b.x ? a.x : b.x,
                               a.y > b.y ? a.y : b.y,
                               a.z > b.z ? a.z : b.z,
                               a.w > b.w ? a.w : b.w);
}
Exemple #19
0
/**
 * graphene_vec2_init:
 * @v: a #graphene_vec2_t
 * @x: the X field of the vector
 * @y: the Y field of the vector
 *
 * Initializes a #graphene_vec2_t using the given values.
 *
 * This function can be called multiple times.
 *
 * Returns: (transfer none): the initialized vector
 *
 * Since: 1.0
 */
graphene_vec2_t *
graphene_vec2_init (graphene_vec2_t *v,
                    float            x,
                    float            y)
{
  v->value = graphene_simd4f_init (x, y, 0.f, 0.f);

  return v;
}
Exemple #20
0
/**
 * graphene_vec4_init_from_vec2:
 * @v: a #graphene_vec4_t
 * @src: a #graphene_vec2_t
 * @z: the value for the third component of @v
 * @w: the value for the fourth component of @v
 *
 * Initializes a #graphene_vec4_t using the components of a
 * #graphene_vec2_t and the values of @z and @w.
 *
 * Returns: (transfer none): the initialized vector
 *
 * Since: 1.0
 */
graphene_vec4_t *
graphene_vec4_init_from_vec2 (graphene_vec4_t       *v,
                              const graphene_vec2_t *src,
                              float                  z,
                              float                  w)
{
  v->value = graphene_simd4f_merge_low (src->value, graphene_simd4f_init (z, w, 0, 0));

  return v;
}
Exemple #21
0
/**
 * graphene_vec3_init:
 * @v: a #graphene_vec3_t
 * @x: the X field of the vector
 * @y: the Y field of the vector
 * @z: the Z field of the vector
 *
 * Initializes a #graphene_vec3_t using the given values.
 *
 * This function can be called multiple times.
 *
 * Returns: (transfer none): a pointer to the initialized
 *   vector
 *
 * Since: 1.0
 */
graphene_vec3_t *
graphene_vec3_init (graphene_vec3_t *v,
                    float            x,
                    float            y,
                    float            z)
{
  v->value = graphene_simd4f_init (x, y, z, 0.f);

  return v;
}
/**
 * graphene_quaternion_normalize:
 * @q: a #graphene_quaternion_t
 * @res: (out caller-allocates): return location for the normalized
 *   quaternion
 *
 * Normalizes a #graphene_quaternion_t.
 *
 * Since: 1.0
 */
void
graphene_quaternion_normalize (const graphene_quaternion_t *q,
                               graphene_quaternion_t       *res)
{
  graphene_simd4f_t v_q;

  v_q = graphene_simd4f_init (q->x, q->y, q->z, q->w);
  v_q = graphene_simd4f_normalize4 (v_q);

  graphene_quaternion_init_from_simd4f (res, v_q);
}
Exemple #23
0
/**
 * graphene_vec4_init:
 * @v: a #graphene_vec4_t
 * @x: the X field of the vector
 * @y: the Y field of the vector
 * @z: the Z field of the vector
 * @w: the W field of the vector
 *
 * Initializes a #graphene_vec4_t using the given values.
 *
 * This function can be called multiple times.
 *
 * Returns: (transfer none): a pointer to the initialized
 *   vector
 *
 * Since: 1.0
 */
graphene_vec4_t *
graphene_vec4_init (graphene_vec4_t *v,
                    float            x,
                    float            y,
                    float            z,
                    float            w)
{
  v->value = graphene_simd4f_init (x, y, z, w);

  return v;
}
Exemple #24
0
/**
 * graphene_matrix_transform_point:
 * @m: a #graphene_matrix_t
 * @p: a #graphene_point_t
 * @res: (out caller-allocates): return location for the
 *   transformed #graphene_point_t
 *
 * Transforms the given #graphene_point_t using the matrix @m.
 *
 * Since: 1.0
 */
void
graphene_matrix_transform_point (const graphene_matrix_t *m,
                                 const graphene_point_t  *p,
                                 graphene_point_t        *res)
{
  graphene_simd4f_t vec3;

  vec3 = graphene_simd4f_init (p->x, p->y, 0.0f, 0.0f);
  graphene_simd4x4f_vec3_mul (&m->value, &vec3, &vec3);

  res->x = graphene_simd4f_get_x (vec3);
  res->y = graphene_simd4f_get_y (vec3);
}
/**
 * graphene_quaternion_to_matrix:
 * @q: a #graphene_quaternion_t
 * @m: (out caller-allocates): a #graphene_matrix_t
 *
 * Converts a quaternion into a transformation matrix expressing
 * the rotation defined by the #graphene_quaternion_t.
 *
 * Since: 1.0
 */
void
graphene_quaternion_to_matrix (const graphene_quaternion_t *q,
                               graphene_matrix_t           *m)
{
  graphene_simd4f_t m_x, m_y, m_z, m_w;

  m_x = graphene_simd4f_init (1.f - 2.f * (q->y * q->y + q->z * q->z),
                                    2.f * (q->x * q->y + q->w * q->z),
                                    2.f * (q->x * q->z - q->w * q->y),
                              0.f);
  m_y = graphene_simd4f_init (      2.f * (q->x * q->y - q->w * q->z),
                              1.f - 2.f * (q->x * q->x + q->z * q->z),
                                    2.f * (q->y * q->z + q->w * q->x),
                              0.f);
  m_z = graphene_simd4f_init (      2.f * (q->x * q->z + q->w * q->y),
                                    2.f * (q->y * q->z - q->w * q->x),
                              1.f - 2.f * (q->x * q->x + q->y * q->y),
                              0.f);
  m_w = graphene_simd4f_init (0.f, 0.f, 0.f, 1.f);

  m->value = graphene_simd4x4f_init (m_x, m_y, m_z, m_w);
}
Exemple #26
0
/**
 * graphene_point_distance:
 * @a: a #graphene_point_t
 * @b: a #graphene_point_t
 * @d_x: (out) (optional): distance component on the X axis
 * @d_y: (out) (optional): distance component on the Y axis
 *
 * Computes the distance between @a and @b.
 *
 * Returns: the distance between the two points
 *
 * Since: 1.0
 */
float
graphene_point_distance (const graphene_point_t *a,
                         const graphene_point_t *b,
                         float                  *d_x,
                         float                  *d_y)
{
  graphene_simd4f_t s_a, s_b, res;

  if (a == b)
    return 0.f;

  s_a = graphene_simd4f_init (a->x, a->y, 0.f, 0.f);
  s_b = graphene_simd4f_init (b->x, b->y, 0.f, 0.f);
  res = graphene_simd4f_sub (s_a, s_b);

  if (d_x != NULL)
    *d_x = fabsf (graphene_simd4f_get_x (res));

  if (d_y != NULL)
    *d_y = fabsf (graphene_simd4f_get_y (res));

  return graphene_simd4f_get_x (graphene_simd4f_length2 (res));
}
Exemple #27
0
static void
matrix_project (gpointer data_)
{
  MatrixBench *data = data_;
  int i;

  for (i = 0; i < N_ROUNDS; i++)
    {
      graphene_simd4f_t pback, qback, uback;
      float t, x, y;

      graphene_simd4x4f_vec3_mul (&(data->a[i]), &(data->pa[i]), &pback);
      graphene_simd4x4f_vec3_mul (&(data->a[i]), &(data->qa[i]), &qback);

      uback = graphene_simd4f_sub (data->pa[i], pback);
      t = -1.0f * graphene_simd4f_get_z (pback) / graphene_simd4f_get_z (uback);
      x = graphene_simd4f_get_x (pback) + t * graphene_simd4f_get_x (uback);
      y = graphene_simd4f_get_y (pback) + t * graphene_simd4f_get_y (uback);

      data->ra[i] = graphene_simd4f_init (x, y, 0.f, 0.f);
    }
}
Exemple #28
0
graphene_simd4f_t
(graphene_simd4f_neg) (const graphene_simd4f_t s)
{
  return graphene_simd4f_init (-s.x, -s.y, -s.z, -s.w);
}
Exemple #29
0
graphene_simd4f_t
(graphene_simd4f_flip_sign_1010) (const graphene_simd4f_t s)
{
  return graphene_simd4f_init (-s.x, s.y, -s.z, s.w);
}
Exemple #30
0
graphene_simd4f_t
(graphene_simd4f_flip_sign_0101) (const graphene_simd4f_t s)
{
  return graphene_simd4f_init (s.x, -s.y, s.z, -s.w);
}