From d3839b5d684502006a980639fd13fd70322ad6ae Mon Sep 17 00:00:00 2001 From: Louis Schmieder Date: Mon, 8 Jun 2020 15:31:55 +0200 Subject: [PATCH] glm: improve matrix mult function and add tests --- vlib/glm/glm.v | 58 +++++++-------------------------------------- vlib/glm/glm_test.v | 49 ++++++++++++++++++++++++++++++++------ 2 files changed, 51 insertions(+), 56 deletions(-) diff --git a/vlib/glm/glm.v b/vlib/glm/glm.v index e55cf5fa5b..d065cbf106 100644 --- a/vlib/glm/glm.v +++ b/vlib/glm/glm.v @@ -219,56 +219,16 @@ pub fn scale(m Mat4, v Vec3) Mat4 { // multiplicates two matrices pub fn mult(a, b Mat4) Mat4 { - db := b.data mut out := f32_calloc(16) - mut row0 := f32_calloc(4) - mut row1 := f32_calloc(4) - mut row2 := f32_calloc(4) - mut row3 := f32_calloc(4) - - row0[0] = db[0]row0[1] = db[1]row0[2] = db[2]row0[3] = db[3] - row1[0] = db[4]row1[1] = db[5]row1[2] = db[6]row1[3] = db[7] - row2[0] = db[8]row2[1] = db[9]row2[2] = db[10]row2[3] = db[11] - row3[0] = db[12]row3[1] = db[13]row3[2] = db[14]row3[3] = db[15] - - a_ := mult_mat_point(a, mat4(row0)) - b_ := mult_mat_point(a, mat4(row1)) - c_ := mult_mat_point(a, mat4(row2)) - d_ := mult_mat_point(a, mat4(row3)) - - res0 := a_.data res1 := b_.data res2 := c_.data res3 := d_.data - - out[0] = res0[0] out[1] = res0[1] out[2] = res0[2] out[3] = res0[3] - out[4] = res1[0] out[5] = res1[1] out[6] = res1[2] out[7] = res1[3] - out[8] = res2[0] out[9] = res2[1] out[10] = res2[2] out[11] = res2[3] - out[12] = res3[0] out[13] = res3[1] out[14] = res3[2] out[15] = res3[3] - - return mat4(out) -} - -// helper function for mult -fn mult_mat_point(a Mat4, point Mat4) Mat4 { - data := a.data - c0r0 := data[0]c1r0 := data[1]c2r0 := data[2]c3r0 := data[3] - c0r1 := data[4]c1r1 := data[5]c2r1 := data[6]c3r1 := data[7] - c0r2 := data[8]c1r2 := data[9]c2r2 := data[10]c3r2 := data[11] - c0r3 := data[12]c1r3 := data[13]c2r3 := data[14]c3r3 := data[15] - - pdata := point.data - x := pdata[0] - y := pdata[1] - z := pdata[2] - w := pdata[3] - - mut out := f32_calloc(4) - - rx := (x * c0r0) + (y * c0r1) + (z * c0r2) + (w * c0r3) - ry := (x * c1r0) + (y * c1r1) + (z * c1r2) + (w * c1r3) - rz := (x * c2r0) + (y * c2r1) + (z * c2r2) + (w * c2r3) - rw := (x * c3r0) + (y * c3r1) + (z * c3r2) + (w * c3r3) - - out[0] = rx out[1] = ry out[2] = rz out[3] = rw - + for i in 0..4 { + for r in 0..4 { + mut prod := f32(0) + for c in 0..4 { + prod += a.data[c*4+r] * b.data[i*4+c] + } + out[i*4+r] = prod + } + } return mat4(out) } diff --git a/vlib/glm/glm_test.v b/vlib/glm/glm_test.v index 90c65be4ff..c7642bc17c 100644 --- a/vlib/glm/glm_test.v +++ b/vlib/glm/glm_test.v @@ -110,13 +110,48 @@ fn test_translate() { assert m.data[15] == 1.0 } -fn test_mult() { - //TODO improve test - mut a := glm.identity() - mut b := glm.identity() - mut c := glm.identity() +fn f32_calloc(n int) &f32 { + return voidptr(vcalloc(n * int(sizeof(f32)))) +} + +fn test_mult1() { + mut adata := f32_calloc(16) + adata[1*4+1] = 6 + adata[2*4+3] = 2 + adata[0*4+2] = 3 + adata[2*4+1] = 1 + + mut bdata := f32_calloc(16) + bdata[1*4+1] = -2 + bdata[2*4+3] = 1 + bdata[0*4+2] = 6 + bdata[2*4+1] = -3 + + mut expected := f32_calloc(16) + expected[0*4+0] = 0 /* 0*0+0*0+0*6+0*0 */ + expected[0*4+1] = 6 /* 0*0+0*6+1*6+0*0 */ + expected[0*4+2] = 0 /* 3*0+0*0+0*6+0*0 */ + expected[0*4+3] = 12 /* 0*0+0*0+2*6+0*0 */ + + expected[1*4+0] = 0 /* 0*0+0*-2+0*0+0*0 */ + expected[1*4+1] = -12 /* 0*0­+6*-2+1*0­+0*0 */ + expected[1*4+2] = 0 /* 3*0­+0*-2­+0*0­+0*0 */ + expected[1*4+3] = 0 /* 0*0­+0*-2­+2*0­+0*0 */ + + expected[2*4+0] = 0 /* 0*0­+0*-3­+0*0­+0*1 */ + expected[2*4+1] = -18 /* 0*0­+6*-3­+1*0­+0*1 */ + expected[2*4+2] = 0 /* 3*0­+0*-3+0*0­+0*1 */ + expected[2*4+3] = 0 /* 0*0­+0*-3­+2*0­+0*1 */ + + expected[3*4+0] = 0 /* 0*0­+0*0­+0*0­+0*0 */ + expected[3*4+1] = 0 /* 0*0­+6*0­+1*0­+0*0 */ + expected[3*4+2] = 0 /* 3*0­+0*0­+0*0­+0*0 */ + expected[3*4+3] = 0 /* 0*0­+0*0­+2*0­+0*0 */ + + mut a := glm.Mat4{adata} + b := glm.Mat4{bdata} a = glm.mult(a, b) for i in 0..15 { - assert a.data[i] == c.data[i] + assert a.data[i] == expected[i] } -} +} \ No newline at end of file