/** * 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)); }
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; }
/** * 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; } }
/** * 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)); }