~rycwo/forge

4dcd28c1a2edde932ef5f92334a0c9fd913a5ff8 — Ryan Chan 6 months ago e9a9001
Fix mat-vec multiply functions

If the "out" and "a" arguments of the multiply funcs were pointing
to the same arrays we'd get aliasing issues. Allocating a temporary
prevents this problem.
5 files changed, 27 insertions(+), 21 deletions(-)

M include/forge/matrix.h
M src/gui_input.c
M test/mat2_basic.c
M test/mat3_basic.c
M test/mat4_basic.c
M include/forge/matrix.h => include/forge/matrix.h +18 -12
@@ 35,15 35,17 @@ mat2_identity(mat2 out) {
}

static inline void
mat2_mult_vec2(vec2 out, mat2 const A, vec2 const a) {
	for (int i = 0; i < 2; ++i)
		out[i] = 0.0;
mat2_mul_vec2(vec2 out, mat2 const A, vec2 const a) {
	vec2 tmp = {0.0, 0.0};

	for (int j = 0; j < 2; ++j) {
		for (int i = 0; i < 2; ++i) {
			out[i] += mat2_get(A, i, j) * a[j];
			tmp[i] += mat2_get(A, i, j) * a[j];
		}
	}

	for (int i = 0; i < 2; ++i)
		out[i] = tmp[i];
}

static inline void


@@ 76,15 78,17 @@ mat3_identity(mat3 out) {
}

static inline void
mat3_mult_vec3(vec3 out, mat3 const A, vec3 const a) {
	for (int i = 0; i < 3; ++i)
		out[i] = 0.0;
mat3_mul_vec3(vec3 out, mat3 const A, vec3 const a) {
	vec3 tmp = {0.0, 0.0, 0.0};

	for (int j = 0; j < 3; ++j) {
		for (int i = 0; i < 3; ++i) {
			out[i] += mat3_get(A, i, j) * a[j];
			tmp[i] += mat3_get(A, i, j) * a[j];
		}
	}

	for (int i = 0; i < 3; ++i)
		out[i] = tmp[i];
}

static inline void


@@ 117,15 121,17 @@ mat4_identity(mat4 out) {
}

static inline void
mat4_mult_vec4(vec4 out, mat4 const A, vec4 const a) {
	for (int i = 0; i < 4; ++i)
		out[i] = 0.0;
mat4_mul_vec4(vec4 out, mat4 const A, vec4 const a) {
	vec4 tmp = {0.0, 0.0, 0.0, 0.0};

	for (int j = 0; j < 4; ++j) {
		for (int i = 0; i < 4; ++i) {
			out[i] += mat4_get(A, i, j) * a[j];
			tmp[i] += mat4_get(A, i, j) * a[j];
		}
	}

	for (int i = 0; i < 4; ++i)
		out[i] = tmp[i];
}

#endif  // MATRIX_H

M src/gui_input.c => src/gui_input.c +2 -2
@@ 17,8 17,8 @@ static inline void
transform_rect(vec4 out, mat4 const transform, vec4 const rect) {
	vec4 v1 = {rect[0], rect[1], 0.0, 1.0};
	vec4 v2 = {rect[0] + rect[2], rect[1] + rect[3], 0.0, 1.0};
	mat4_mult_vec4(out, transform, v1);
	mat4_mult_vec4(v1, transform, v2);
	mat4_mul_vec4(out, transform, v1);
	mat4_mul_vec4(v1, transform, v2);
	out[2] = v1[0] - out[0];
	out[3] = v1[1] - out[1];
}

M test/mat2_basic.c => test/mat2_basic.c +2 -2
@@ 42,10 42,10 @@ int main(void) {

	vec2 const a = {1.0, 2.0};
	vec2 result;
	mat2_mult_vec2(result, A, a);
	mat2_mul_vec2(result, A, a);
	test_assert(
			vec2_eq(result, (vec2){14.0, 20.0}),
			"matrix-vector mult expected (14.0  20.0)");
			"matrix-vector mul expected (14.0  20.0)");

	exit(EXIT_SUCCESS);
}

M test/mat3_basic.c => test/mat3_basic.c +2 -2
@@ 45,10 45,10 @@ int main(void) {

	vec3 const a = {1.0, 2.0, 3.0};
	vec3 result;
	mat3_mult_vec3(result, A, a);
	mat3_mul_vec3(result, A, a);
	test_assert(
			vec3_eq(result, (vec3){60.0, 72.0, 84.0}),
			"matrix-vector mult expected (60.0  72.0  84.0)");
			"matrix-vector mul expected (60.0  72.0  84.0)");

	exit(EXIT_SUCCESS);
}

M test/mat4_basic.c => test/mat4_basic.c +3 -3
@@ 42,16 42,16 @@ int main(void) {
		1.0, 0.0, 0.0, 0.0,  // col 0
		0.0, 1.0, 0.0, 0.0,  // col 1
		0.0, 0.0, 1.0, 0.0,  // col 2
		0.0, 0.0, 0.0, 1.0   // col 2
		0.0, 0.0, 0.0, 1.0   // col 3
	};
	test_assert(mat4_eq(B, identity), "matrix identity expected");

	vec4 const a = {1.0, 2.0, 3.0, 4.0};
	vec4 result;
	mat4_mult_vec4(result, A, a);
	mat4_mul_vec4(result, A, a);
	test_assert(
			vec4_eq(result, (vec4){166.0, 186.0, 206.0, 226.0}),
			"matrix-vector mult expected (166.0  186.0  206.0  226.0)");
			"matrix-vector mul expected (166.0  186.0  206.0  226.0)");

	exit(EXIT_SUCCESS);
}