Exemple #1
0
static void
graphene_matrix_transpose_transform_vec4 (const graphene_matrix_t *m,
                                          const graphene_vec4_t   *v,
                                          graphene_vec4_t         *res)
{
  float x, y, z, w;

  x = graphene_simd4f_get_x (graphene_simd4f_sum (graphene_simd4f_mul (m->value.x, v->value)));
  y = graphene_simd4f_get_x (graphene_simd4f_sum (graphene_simd4f_mul (m->value.y, v->value)));
  z = graphene_simd4f_get_x (graphene_simd4f_sum (graphene_simd4f_mul (m->value.z, v->value)));
  w = graphene_simd4f_get_x (graphene_simd4f_sum (graphene_simd4f_mul (m->value.w, v->value)));

  graphene_vec4_init (res, x, y, z, w);
}
Exemple #2
0
static void
quaternion_vec4_to_from (mutest_spec_t *spec)
{
  graphene_quaternion_t *q;
  graphene_vec4_t v, check;

  graphene_vec4_init (&v, 1.f, 2.f, 3.f, 4.f);

  q = graphene_quaternion_init_from_vec4 (graphene_quaternion_alloc (), &v);
  graphene_quaternion_to_vec4 (q, &check);

  mutest_expect ("roundtrip between init_from_vec4 and to_vec4 to yield the same vector",
                 mutest_bool_value (graphene_vec4_near (&v, &check, 0.0001f)),
                 mutest_to_be_true,
                 NULL);

  graphene_quaternion_free (q);
}
Exemple #3
0
static void
quaternion_operators_normalize (mutest_spec_t *spec)
{
  graphene_quaternion_t q1, q2;
  graphene_vec4_t v1, v2;

  graphene_quaternion_init (&q1, 1.f, 2.f, 3.f, 4.f);
  graphene_quaternion_normalize (&q1, &q2);

  graphene_vec4_init (&v1, 1.f, 2.f, 3.f, 4.f);
  graphene_vec4_normalize (&v1, &v1);

  graphene_quaternion_to_vec4 (&q2, &v2);

  mutest_expect ("normalizing a quaternion is the same as normalizing the equivalent vec4",
                 mutest_bool_value (graphene_vec4_near (&v1, &v2, 0.00001f)),
                 mutest_to_be_true,
                 NULL);
}
static void
gthree_basic_material_real_set_uniforms (GthreeMaterial *material,
                                         GthreeUniforms *uniforms,
                                         GthreeCamera   *camera)
{
  GthreeBasicMaterial *basic = GTHREE_BASIC_MATERIAL (material);
  GthreeBasicMaterialPrivate *priv = gthree_basic_material_get_instance_private (basic);
  GthreeTexture *scale_map;
  GthreeUniform *uni;

  GTHREE_MATERIAL_CLASS (gthree_basic_material_parent_class)->set_uniforms (material, uniforms, camera);

  uni = gthree_uniforms_lookup_from_string (uniforms, "diffuse");
  if (uni != NULL)
    gthree_uniform_set_color (uni, &priv->color);

  uni = gthree_uniforms_lookup_from_string (uniforms, "map");
  if (uni != NULL)
    gthree_uniform_set_texture (uni, priv->map);

  /* uv repeat and offset setting priorities
   * 1. color map
   * 2. specular map
   * 3. normal map
   * 4. bump map
   * 5. alpha map
   */
  scale_map = NULL;
  if (priv->map != NULL)
    scale_map = priv->map;
  // ... other maps

  if (scale_map != NULL)
    {
      const graphene_vec2_t *repeat = gthree_texture_get_repeat (scale_map);
      const graphene_vec2_t *offset = gthree_texture_get_offset (scale_map);
      graphene_vec4_t offset_repeat;

      graphene_vec4_init (&offset_repeat,
                          graphene_vec2_get_x (offset),
                          graphene_vec2_get_y (offset),
                          graphene_vec2_get_x (repeat),
                          graphene_vec2_get_y (repeat));

      uni = gthree_uniforms_lookup_from_string (uniforms, "offsetRepeat");
      if (uni != NULL)
        gthree_uniform_set_vec4 (uni, &offset_repeat);
    }

  uni = gthree_uniforms_lookup_from_string (uniforms, "envMap");
  if (uni != NULL)
    gthree_uniform_set_texture (uni, priv->env_map);

  uni = gthree_uniforms_lookup_from_string (uniforms, "useRefract");
  if (uni != NULL)
    gthree_uniform_set_int (uni,
                            priv->env_map && gthree_texture_get_mapping (priv->env_map) == GTHREE_MAPPING_CUBE_REFRACTION);

  uni = gthree_uniforms_lookup_from_string (uniforms, "flipEnvMap");
  if (uni != NULL)
    gthree_uniform_set_float (uni, (TRUE /* TODO: material.envMap instanceof THREE.WebGLRenderTargetCube */) ? 1 : -1);

  uni = gthree_uniforms_lookup_from_string (uniforms, "combine");
  if (uni != NULL)
    gthree_uniform_set_int (uni, priv->combine);

  uni = gthree_uniforms_lookup_from_string (uniforms, "refractionRatio");
  if (uni != NULL)
    gthree_uniform_set_float (uni, priv->refraction_ratio);


  // TODO: More from refreshUniformsCommon
}
Exemple #5
0
static gboolean
matrix_decompose_3d (const graphene_matrix_t *m,
                     graphene_point3d_t      *scale_r,
                     float                    shear_r[3],
                     graphene_quaternion_t   *rotate_r,
                     graphene_point3d_t      *translate_r,
                     graphene_vec4_t         *perspective_r)
{
  graphene_matrix_t local, perspective;
  float shear_xy, shear_xz, shear_yz;
  float scale_x, scale_y, scale_z;
  graphene_simd4f_t dot, cross;

  if (graphene_matrix_get_value (m, 3, 3) == 0.f)
    return FALSE;

  local = *m;

  /* normalize the matrix */
  graphene_matrix_normalize (&local, &local);

  /* perspective is used to solve for the perspective component,
   * but it also provides an easy way to test for singularity of
   * the upper 3x3 component
   */
  perspective = local;
  perspective.value.w = graphene_simd4f_init (0.f, 0.f, 0.f, 1.f);

  if (graphene_matrix_determinant (&perspective) == 0.f)
    return FALSE;

  /* isolate the perspective */
  if (graphene_simd4f_is_zero3 (local.value.w))
    {
      graphene_matrix_t tmp;

      /* perspective_r is the right hand side of the equation */
      perspective_r->value = local.value.w;

      /* solve the equation by inverting perspective and multiplying
       * the inverse with the perspective vector
       */
      graphene_matrix_inverse (&perspective, &tmp);
      graphene_matrix_transpose_transform_vec4 (&tmp, perspective_r, perspective_r);

      /* clear the perspective partition */
      local.value.w = graphene_simd4f_init (0.f, 0.f, 0.f, 1.f);
    }
  else
    graphene_vec4_init (perspective_r, 0.f, 0.f, 0.f, 1.f);

  /* next, take care of the translation partition */
  translate_r->x = graphene_simd4f_get_x (local.value.w);
  translate_r->y = graphene_simd4f_get_y (local.value.w);
  translate_r->z = graphene_simd4f_get_z (local.value.w);
  local.value.w = graphene_simd4f_init (0.f, 0.f, 0.f, graphene_simd4f_get_w (local.value.w));

  /* now get scale and shear */

  /* compute the X scale factor and normalize the first row */
  scale_x = graphene_simd4f_get_x (graphene_simd4f_length4 (local.value.x));
  local.value.x = graphene_simd4f_div (local.value.x, graphene_simd4f_splat (scale_x));

  /* compute XY shear factor and the second row orthogonal to the first */
  shear_xy = graphene_simd4f_get_x (graphene_simd4f_dot4 (local.value.x, local.value.y));
  local.value.y = graphene_simd4f_sub (local.value.y, graphene_simd4f_mul (local.value.x, graphene_simd4f_splat (shear_xy)));

  /* now, compute the Y scale factor and normalize the second row */
  scale_y = graphene_simd4f_get_x (graphene_simd4f_length4 (local.value.y));
  local.value.y = graphene_simd4f_div (local.value.y, graphene_simd4f_splat (scale_y));
  shear_xy /= scale_y;

  /* compute XZ and YZ shears, make the third row orthogonal */
  shear_xz = graphene_simd4f_get_x (graphene_simd4f_dot4 (local.value.x, local.value.z));
  local.value.z = graphene_simd4f_sub (local.value.z, graphene_simd4f_mul (local.value.x, graphene_simd4f_splat (shear_xz)));
  shear_yz = graphene_simd4f_get_x (graphene_simd4f_dot4 (local.value.y, local.value.z));
  local.value.z = graphene_simd4f_sub (local.value.z, graphene_simd4f_mul (local.value.y, graphene_simd4f_splat (shear_yz)));

  /* next, get the Z scale and normalize the third row */
  scale_z = graphene_simd4f_get_x (graphene_simd4f_length4 (local.value.z));
  local.value.z = graphene_simd4f_div (local.value.z, graphene_simd4f_splat (scale_z));

  shear_xz /= scale_z;
  shear_yz /= scale_z;

  shear_r[XY_SHEAR] = shear_xy;
  shear_r[XZ_SHEAR] = shear_xz;
  shear_r[YZ_SHEAR] = shear_yz;

  /* at this point, the matrix is orthonormal. we check for a
   * coordinate system flip. if the determinant is -1, then
   * negate the matrix and the scaling factors
   */
  dot = graphene_simd4f_cross3 (local.value.y, local.value.z);
  cross = graphene_simd4f_dot4 (local.value.x, dot);
  if (graphene_simd4f_get_x (cross) < 0.f)
    {
      scale_x *= -1.f;
      scale_y *= -1.f;
      scale_z *= -1.f;

      graphene_simd4f_mul (local.value.x, graphene_simd4f_splat (-1.f));
      graphene_simd4f_mul (local.value.y, graphene_simd4f_splat (-1.f));
      graphene_simd4f_mul (local.value.z, graphene_simd4f_splat (-1.f));
    }

  graphene_point3d_init (scale_r, scale_x, scale_y, scale_z);

  /* get the rotations out */
  graphene_quaternion_init_from_matrix (rotate_r, &local);

  return TRUE;
}
Exemple #6
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);
}