From a5c68a573a6d5d342cc1ccf20b0b1dcd07dca691 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 31 Aug 2020 22:43:35 -0400 Subject: [PATCH 1/2] Fix handling of projective transforms When transforming points with projective matrices, we must divide the resulting vector by w, in order to get the normalized result. This commit fixes graphene_matrix_transform_point, graphene_matrix_transform_point3d and graphene_matrix_transform_bounds. I suspect that some of the remaining transform functions need similar fixes, but they are not used in GTK, so I couldn't verify that. --- src/graphene-matrix.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/graphene-matrix.c b/src/graphene-matrix.c index b73d7575..fe6d24ea 100644 --- a/src/graphene-matrix.c +++ b/src/graphene-matrix.c @@ -921,8 +921,8 @@ graphene_matrix_transform_point (const graphene_matrix_t *m, vec3 = graphene_simd4f_init (p->x, p->y, 0.0f, 1.0f); graphene_simd4x4f_point3_mul (&m->value, &vec3, &vec3); - res->x = graphene_simd4f_get_x (vec3); - res->y = graphene_simd4f_get_y (vec3); + res->x = graphene_simd4f_get_x (vec3) / graphene_simd4f_get_w (vec3); + res->y = graphene_simd4f_get_y (vec3) / graphene_simd4f_get_w (vec3); } /** @@ -951,9 +951,9 @@ graphene_matrix_transform_point3d (const graphene_matrix_t *m, vec3 = graphene_simd4f_init (p->x, p->y, p->z, 1.f); graphene_simd4x4f_point3_mul (&m->value, &vec3, &vec3); - res->x = graphene_simd4f_get_x (vec3); - res->y = graphene_simd4f_get_y (vec3); - res->z = graphene_simd4f_get_z (vec3); + res->x = graphene_simd4f_get_x (vec3) / graphene_simd4f_get_w (vec3); + res->y = graphene_simd4f_get_y (vec3) / graphene_simd4f_get_w (vec3); + res->z = graphene_simd4f_get_y (vec3) / graphene_simd4f_get_w (vec3); } /** @@ -1034,9 +1034,9 @@ graphene_matrix_transform_bounds (const graphene_matrix_t *m, graphene_point_t __p; \ graphene_rect_get_ ## corner (rect, &__p); \ __s = graphene_simd4f_init (__p.x, __p.y, 0.f, 1.f); \ - graphene_simd4x4f_vec4_mul (&matrix->value, &__s, &__s); \ - out_p.x = graphene_simd4f_get_x (__s); \ - out_p.y = graphene_simd4f_get_y (__s); } while (0) + graphene_simd4x4f_point3_mul (&matrix->value, &__s, &__s); \ + out_p.x = graphene_simd4f_get_x (__s) / graphene_simd4f_get_w (__s); \ + out_p.y = graphene_simd4f_get_y (__s) / graphene_simd4f_get_w (__s); } while (0) TRANSFORM_POINT (m, &rr, top_left, ret[0]); TRANSFORM_POINT (m, &rr, top_right, ret[1]); From f80eb04e5ba2b29b475663fa1030d3a06c6d5027 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 31 Aug 2020 23:32:45 -0400 Subject: [PATCH 2/2] fixup! Fix handling of projective transforms MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix a copy-paste error Pointed out by Timm Bäder. --- src/graphene-matrix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graphene-matrix.c b/src/graphene-matrix.c index fe6d24ea..a292aaf3 100644 --- a/src/graphene-matrix.c +++ b/src/graphene-matrix.c @@ -953,7 +953,7 @@ graphene_matrix_transform_point3d (const graphene_matrix_t *m, res->x = graphene_simd4f_get_x (vec3) / graphene_simd4f_get_w (vec3); res->y = graphene_simd4f_get_y (vec3) / graphene_simd4f_get_w (vec3); - res->z = graphene_simd4f_get_y (vec3) / graphene_simd4f_get_w (vec3); + res->z = graphene_simd4f_get_z (vec3) / graphene_simd4f_get_w (vec3); } /**