/** * 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); }
/** * graphene_vec3_add: * @a: a #graphene_vec3_t * @b: a #graphene_vec3_t * @res: (out caller-allocates): return location for the resulting vector * * Adds each component of the two given vectors. * * Since: 1.0 */ void graphene_vec3_add (const graphene_vec3_t *a, const graphene_vec3_t *b, graphene_vec3_t *res) { res->value = graphene_simd4f_add (a->value, b->value); }
/** * 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)); }
/** * graphene_matrix_skew_yz: * @m: a #graphene_matrix_t * @factor: skew factor * * Adds a skew of @factor on the Y and Z axis to the given matrix. * * Since: 1.0 */ void graphene_matrix_skew_yz (graphene_matrix_t *m, float factor) { graphene_simd4f_t m_y, m_z; m_y = m->value.y; m_z = m->value.z; m->value.z = graphene_simd4f_add (m_z, graphene_simd4f_mul (m_y, graphene_simd4f_splat (factor))); }
/** * graphene_matrix_skew_xy: * @m: a #graphene_matrix_t * @factor: skew factor * * Adds a skew of @factor on the X and Y axis to the given matrix. * * Since: 1.0 */ void graphene_matrix_skew_xy (graphene_matrix_t *m, float factor) { graphene_simd4f_t m_x, m_y; m_x = m->value.x; m_y = m->value.y; m->value.y = graphene_simd4f_add (m_y, graphene_simd4f_mul (m_x, graphene_simd4f_splat (factor))); }
void graphene_matrix_skew_xz (graphene_matrix_t *m, float factor) { graphene_simd4f_t m_x, m_z; g_return_if_fail (m != NULL); m_x = m->value.x; m_z = m->value.z; m->value.z = graphene_simd4f_add (m_z, graphene_simd4f_mul (m_x, graphene_simd4f_splat (factor))); }
/** * graphene_simd4f_add: * @a: a #graphene_simd4f_t * @b: a #graphene_simd4f_t * * Creates a new #graphene_simd4f_t vector where each * component is the sum of the respective components * in @a and @b. * * |[<!-- lanugage="plain" --> * { * .x = a.x + b.x, * .y = a.y + b.y, * .z = a.z + b.z, * .w = a.w + b.w * } * ]| * * Returns: the sum vector * * Since: 1.0 */ graphene_simd4f_t (graphene_simd4f_add) (const graphene_simd4f_t a, const graphene_simd4f_t b) { return graphene_simd4f_add (a, b); }