static void quaternion_operators_equal (mutest_spec_t *spec) { graphene_quaternion_t q1, q2, q3; graphene_quaternion_init (&q1, 1.f, 1.f, 1.f, 1.f); graphene_quaternion_init (&q2, 1.f, 2.f, 3.f, 1.f); graphene_quaternion_invert (&q1, &q3); mutest_expect ("a quaternion to be equal to itself", mutest_bool_value (graphene_quaternion_equal (&q1, &q1)), mutest_to_be_true, NULL); mutest_expect ("a quaternion not to be equal to null", mutest_bool_value (graphene_quaternion_equal (&q1, NULL)), mutest_not, mutest_to_be_true, NULL); mutest_expect ("null not to be equal to a quaternion", mutest_bool_value (graphene_quaternion_equal (NULL, &q1)), mutest_not, mutest_to_be_true, NULL); mutest_expect ("two different quaternions not to be equal", mutest_bool_value (graphene_quaternion_equal (&q1, &q2)), mutest_not, mutest_to_be_true, NULL); mutest_expect ("a quaternion to be equal to its invert", mutest_bool_value (graphene_quaternion_equal (&q1, &q3)), mutest_to_be_true, NULL); }
static void quaternion_operators_invert (mutest_spec_t *spec) { graphene_quaternion_t q1, q2, tmp; graphene_quaternion_init_identity (&q1); graphene_quaternion_invert (&q1, &q2); mutest_expect ("inverting identity gives back an identity", mutest_bool_value (graphene_quaternion_equal (&q1, &q2)), mutest_to_be_true, NULL); graphene_quaternion_init (&q1, 1.f, 1.f, 1.f, 1.f); graphene_quaternion_invert (&q1, &q2); mutest_expect ("inverting a quaternion flips the sign of the first three fields", mutest_bool_value (graphene_quaternion_equal (&q2, graphene_quaternion_init (&tmp, -1.f, -1.f, -1.f, 1.f))), mutest_to_be_true, NULL); }
static gboolean matrix_decompose_2d (const graphene_matrix_t *m, graphene_point3d_t *scale_r, float shear_r[3], graphene_quaternion_t *rotate_r, graphene_point3d_t *translate_r) { float A = graphene_matrix_get_value (m, 0, 0); float B = graphene_matrix_get_value (m, 1, 0); float C = graphene_matrix_get_value (m, 0, 1); float D = graphene_matrix_get_value (m, 1, 1); float scale_x, scale_y; float shear_xy; float rotate; if (A * D == B * C) return FALSE; scale_x = sqrtf (A * A + B * B); A /= scale_x; B /= scale_x; shear_xy = A * C + B * D; C -= A * shear_xy; D -= B * shear_xy; scale_y = sqrtf (C * C + D * D); C /= scale_y; D /= scale_y; shear_xy /= scale_y; if (A * D < B * C) { A = -A; B = -B; C = -C; D = -D; shear_xy = -shear_xy; scale_x = -scale_x; } rotate = atan2f (B, A); graphene_quaternion_init (rotate_r, 0.f, 0.f, sin (rotate / 2.f), cos (rotate / 2.f)); shear_r[XY_SHEAR] = shear_xy; graphene_point3d_init (scale_r, scale_x, scale_y, 1.f); graphene_point3d_init (translate_r, graphene_matrix_get_value (m, 3, 0), graphene_matrix_get_value (m, 3, 1), 0.f); return TRUE; }
static void quaternion_operators_dot (mutest_spec_t *spec) { graphene_quaternion_t q1, q2; graphene_quaternion_init (&q1, 1.f, 1.f, 1.f, 1.f); graphene_quaternion_invert (&q1, &q2); mutest_expect ("dot(q, inv(q)) with q = (1, 1, 1, 1) to be -2", mutest_float_value (graphene_quaternion_dot (&q1, &q2)), mutest_to_be_close_to, -2.0, 0.0001, NULL); }
static void quaternion_init (mutest_spec_t *spec) { graphene_quaternion_t q1, q2; graphene_quaternion_init (&q1, 0.f, 0.f, 0.f, 1.f); graphene_quaternion_init_identity (&q2); mutest_expect ("identity to set (0, 0, 0, 1)", mutest_bool_value (graphene_quaternion_equal (&q1, &q2)), mutest_to_be_true, NULL); graphene_quaternion_init (&q1, 1.f, 1.f, 1.f, 1.f); mutest_expect ("initialization sets all fields", mutest_bool_value (graphene_quaternion_equal (&q1, &q2)), mutest_not, mutest_to_be_true, NULL); graphene_quaternion_init_from_quaternion (&q2, &q1); mutest_expect ("initialization from quaternion makes a copy", mutest_bool_value (graphene_quaternion_equal (&q1, &q2)), mutest_to_be_true, NULL); }
static void quaternion_slerp (mutest_spec_t *spec) { graphene_quaternion_t q1, q2, q3; graphene_quaternion_init (&q1, 0.0f, 0.0f, 0.0f, 1.0f); graphene_quaternion_init (&q2, 0.2f, 0.3f, 0.4f, 0.5f); mutest_expect ("initial and final states are different", mutest_bool_value (graphene_quaternion_equal (&q1, &q2)), mutest_to_be_false, NULL); graphene_quaternion_slerp (&q1, &q2, 0.33f, &q3); mutest_expect ("interpolated result is different from the initial state", mutest_bool_value (graphene_quaternion_equal (&q1, &q3)), mutest_to_be_false, NULL); graphene_quaternion_slerp (&q1, &q2, 0.66f, &q3); mutest_expect ("interpolated result is different from the final state", mutest_bool_value (graphene_quaternion_equal (&q2, &q3)), mutest_to_be_false, NULL); }
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); }