예제 #1
0
/**
 * graphene_matrix_project_point:
 * @m: ...
 * @p: ...
 * @res: (out caller-allocates): ...
 *
 * ...
 *
 * Since: 1.0
 */
void
graphene_matrix_project_point (const graphene_matrix_t *m,
                               const graphene_point_t  *p,
                               graphene_point_t        *res)
{
  graphene_vec3_t pa, qa;
  graphene_vec3_t pback, qback, uback;
  float p_z, u_z, t;

  g_return_if_fail (m != NULL);
  g_return_if_fail (p != NULL);
  g_return_if_fail (res != NULL);

  graphene_vec3_init (&pa, p->x, p->y, 0.0f);
  graphene_vec3_init (&qa, p->x, p->y, 1.0f);

  graphene_matrix_transform_vec3 (m, &pa, &pback);
  graphene_matrix_transform_vec3 (m, &qa, &qback);

  graphene_vec3_subtract (&qback, &pback, &uback);

  p_z = graphene_vec3_get_z (&pback);
  u_z = graphene_vec3_get_z (&uback);
  t = -p_z / u_z;

  graphene_point_init (res,
                       graphene_vec3_get_x (&pback) + t * graphene_vec3_get_x (&uback),
                       graphene_vec3_get_y (&pback) + t * graphene_vec3_get_y (&uback));
}
예제 #2
0
static gboolean
_set_uniform (GQuark field_id, const GValue * value, gpointer user_data)
{
  GstGLShader *shader = user_data;
  const gchar *field_name = g_quark_to_string (field_id);

  if (G_TYPE_CHECK_VALUE_TYPE ((value), G_TYPE_INT)) {
    gst_gl_shader_set_uniform_1i (shader, field_name, g_value_get_int (value));
  } else if (G_TYPE_CHECK_VALUE_TYPE ((value), G_TYPE_FLOAT)) {
    gst_gl_shader_set_uniform_1f (shader, field_name,
        g_value_get_float (value));
#ifdef HAVE_GRAPHENE
  } else if (G_TYPE_CHECK_VALUE_TYPE ((value), GRAPHENE_TYPE_VEC2)) {
    graphene_vec2_t *vec2 = g_value_get_boxed (value);
    float x = graphene_vec2_get_x (vec2);
    float y = graphene_vec2_get_y (vec2);
    gst_gl_shader_set_uniform_2f (shader, field_name, x, y);
  } else if (G_TYPE_CHECK_VALUE_TYPE ((value), GRAPHENE_TYPE_VEC3)) {
    graphene_vec3_t *vec3 = g_value_get_boxed (value);
    float x = graphene_vec3_get_x (vec3);
    float y = graphene_vec3_get_y (vec3);
    float z = graphene_vec3_get_z (vec3);
    gst_gl_shader_set_uniform_3f (shader, field_name, x, y, z);
  } else if (G_TYPE_CHECK_VALUE_TYPE ((value), GRAPHENE_TYPE_VEC4)) {
    graphene_vec4_t *vec4 = g_value_get_boxed (value);
    float x = graphene_vec4_get_x (vec4);
    float y = graphene_vec4_get_y (vec4);
    float z = graphene_vec4_get_z (vec4);
    float w = graphene_vec4_get_w (vec4);
    gst_gl_shader_set_uniform_4f (shader, field_name, x, y, z, w);
  } else if (G_TYPE_CHECK_VALUE_TYPE ((value), GRAPHENE_TYPE_MATRIX)) {
    graphene_matrix_t *matrix = g_value_get_boxed (value);
    float matrix_f[16];
    graphene_matrix_to_float (matrix, matrix_f);
    gst_gl_shader_set_uniform_matrix_4fv (shader, field_name, 1, FALSE,
        matrix_f);
#endif
  } else {
    /* FIXME: Add support for unsigned ints, non 4x4 matrices, etc */
    GST_FIXME ("Don't know how to set the \'%s\' paramater.  Unknown type",
        field_name);
    return TRUE;
  }

  return TRUE;
}
예제 #3
0
/**
 * graphene_euler_to_matrix:
 * @e: a #graphene_euler_t
 * @res: (out caller-allocates): return location for a #graphene_matrix_t
 *
 * Converts a #graphene_euler_t into a transformation matrix expressing
 * the extrinsic composition of rotations described by the Euler angles.
 *
 * The rotations are applied over the reference frame axes in the order
 * associated with the #graphene_euler_t; for instance, if the order
 * used to initialize @e is %GRAPHENE_EULER_ORDER_XYZ:
 *
 *  * the first rotation moves the body around the X axis with
 *    an angle φ
 *  * the second rotation moves the body around the Y axis with
 *    an angle of ϑ
 *  * the third rotation moves the body around the Z axis with
 *    an angle of ψ
 *
 * The rotation sign convention is left-handed, to preserve compatibility
 * between Euler-based, quaternion-based, and angle-axis-based rotations.
 *
 * Since: 1.2
 */
void
graphene_euler_to_matrix (const graphene_euler_t *e,
                          graphene_matrix_t      *res)
{
  graphene_euler_order_t order = graphene_euler_get_order (e);

  const float x = graphene_vec3_get_x (&e->angles);
  const float y = graphene_vec3_get_y (&e->angles);
  const float z = graphene_vec3_get_z (&e->angles);

  float c1, s1, c2, s2, c3, s3;
  float c3c2, s3c1, c3s2s1, s3s1;
  float c3s2c1, s3c2, c3c1, s3s2s1;
  float c3s1, s3s2c1, c2s1, c2c1;

  graphene_sincos (x, &c1, &s1);
  graphene_sincos (y, &c2, &s2);
  graphene_sincos (z, &c3, &s3);

  c3c2 = c3 * c2;
  s3c1 = s3 * c1;
  c3s2s1 = c3 * s2 * s1;
  s3s1 = s3 * s1;
  c3s2c1 = c3 * s2 * c1;
  s3c2 = s3 * c2;
  c3c1 = c3 * c1;
  s3s2s1 = s3 * s2 * s1;
  c3s1 = c3 * s1;
  s3s2c1 = s3 * s2 * c1;
  c2s1 = c2 * s1;
  c2c1 = c2 * c1;

  switch (order)
    {
    case GRAPHENE_EULER_ORDER_XYZ:
      {
        /* ⎡  c3 s3 0 ⎤ ⎡ c2  0 -s2 ⎤ ⎡ 1   0  0 ⎤
         * ⎢ -s3 c3 0 ⎥ ⎢  0  1   0 ⎥ ⎢ 0  c1 s1 ⎥
         * ⎣   0  0 1 ⎦ ⎣ s2  0  c2 ⎦ ⎣ 0 -s1 c1 ⎦
         */
        res->value.x = graphene_simd4f_init ( c3c2, s3c1 + c3s2s1, s3s1 - c3s2c1, 0.f);
        res->value.y = graphene_simd4f_init (-s3c2, c3c1 - s3s2s1, c3s1 + s3s2c1, 0.f);
        res->value.z = graphene_simd4f_init (   s2,         -c2s1,          c2c1, 0.f);
        res->value.w = graphene_simd4f_init (  0.f,           0.f,           0.f, 1.f);
      }
      break;

    case GRAPHENE_EULER_ORDER_YXZ:
      {
        /* ⎡  c3 s3 0 ⎤ ⎡ 1   0  0 ⎤ ⎡ c1 0 -s1 ⎤
         * ⎢ -s2 c3 0 ⎥ ⎢ 0  c2 s2 ⎥ ⎢  0 1   0 ⎥
         * ⎣   0  0 1 ⎦ ⎣ 0 -s2 c2 ⎦ ⎣ s1 0  c1 ⎦
         */
        res->value.x = graphene_simd4f_init ( c3c1 + s3s2s1, s3c2, -c3s1 + s3s2c1, 0.f);
        res->value.y = graphene_simd4f_init (-s3c1 + c3s2s1, c3c2,  s3s1 + c3s2c1, 0.f);
        res->value.z = graphene_simd4f_init (          c2s1,  -s2,           c2c1, 0.f);
        res->value.w = graphene_simd4f_init (           0.f,  0.f,            0.f, 1.f);
      }
      break;

    case GRAPHENE_EULER_ORDER_ZXY:
      {
        /* ⎡ 1   0  0 ⎤ ⎡ c2  0 -s2 ⎤ ⎡  c1 s1 0 ⎤
         * ⎢ 0  c3 s3 ⎥ ⎢  0  1   0 ⎥ ⎢ -s1 c1 0 ⎥
         * ⎣ 0 -s3 c3 ⎦ ⎣ s2  0  c2 ⎦ ⎣   0  0 1 ⎦
         */
        res->value.x = graphene_simd4f_init (c3c1 - s3s2s1, c3s1 + s3s2c1, -s3c2, 0.f);
        res->value.y = graphene_simd4f_init (        -c2s1,          c2c1,    s2, 0.f);
        res->value.z = graphene_simd4f_init (s3c1 + c3s2s1, s3s1 - c3s2c1,  c3c2, 0.f);
        res->value.w = graphene_simd4f_init (          0.f,           0.f,   0.f, 1.f);
      }
      break;

    case GRAPHENE_EULER_ORDER_ZYX:
      {
        /* ⎡ 1   0  0 ⎤ ⎡ c2  0 -s2 ⎤ ⎡  c1 s1 0 ⎤
         * ⎢ 0  c3 s3 ⎥ ⎢  0  1   0 ⎥ ⎢ -s1 c1 0 ⎥
         * ⎣ 0 -s3 c3 ⎦ ⎣ s2  0  c2 ⎦ ⎣   0  0 1 ⎦
         */
        res->value.x = graphene_simd4f_init (         c2c1,          c2s1,  -s2, 0.f);
        res->value.y = graphene_simd4f_init (s3s2c1 - c3s1, s3s2s1 + c3c1, s3c2, 0.f);
        res->value.z = graphene_simd4f_init (c3s2c1 + s3s1, c3s2s1 - s3c1, c3c2, 0.f);
        res->value.w = graphene_simd4f_init (          0.f,           0.f,  0.f, 1.f);
      }
      break;

    case GRAPHENE_EULER_ORDER_YZX:
      {
        /* ⎡ 1   0  0 ⎤ ⎡  c2 s2 0 ⎤ ⎡ c1 0 -s1 ⎤
         * ⎢ 0  c3 s3 ⎥ ⎢ -s2 c2 0 ⎥ ⎢  0 1   0 ⎥
         * ⎣ 0 -s3 c3 ⎦ ⎣   0  0 1 ⎦ ⎣ s1 0  c1 ⎦
         */
        res->value.x = graphene_simd4f_init (          c2c1,    s2,          -c2s1, 0.f);
        res->value.y = graphene_simd4f_init (-c3s2c1 + s3s1,  c3c2,  c3s2s1 + s3c1, 0.f);
        res->value.z = graphene_simd4f_init ( s3s2c1 + c3s1, -s3c2, -s3s2s1 + c3c1, 0.f);
        res->value.w = graphene_simd4f_init (           0.f,   0.f,            0.f, 1.f);
      }
      break;

    case GRAPHENE_EULER_ORDER_XZY:
      {
        /* ⎡ c3 0 -s3 ⎤ ⎡  c2 s2 0 ⎤ ⎡ 1   0  0 ⎤
         * ⎢  0 1   0 ⎥ ⎢ -s2 c2 0 ⎥ ⎢ 0  c1 s1 ⎥
         * ⎣ s3 0  c3 ⎦ ⎣   0  0 1 ⎦ ⎣ 0 -s1 c1 ⎦
         */
        res->value.x = graphene_simd4f_init (c3c2, c3s2c1 + s3s1, c3s2s1 - s3c1, 0.f);
        res->value.y = graphene_simd4f_init ( -s2,          c2c1,          c2s1, 0.f);
        res->value.z = graphene_simd4f_init (s3c2, s3s2c1 - c3s1, s3s2s1 + c3c1, 0.f);
        res->value.w = graphene_simd4f_init ( 0.f,           0.f,           0.f, 1.f);
      }
      break;

    default:
      graphene_matrix_init_identity (res);
      break;
    }
}
예제 #4
0
/**
 * graphene_euler_get_y:
 * @e: a #graphene_euler_t
 *
 * Retrieves the rotation angle on the Y axis, in degrees.
 *
 * Returns: the rotation angle
 *
 * Since: 1.2
 */
float
graphene_euler_get_y (const graphene_euler_t *e)
{
  return GRAPHENE_RAD_TO_DEG (graphene_vec3_get_y (&e->angles));
}