gg.m4: fixed some bugs, added ortho projection (#9140)

pull/9153/head
penguindark 2021-03-06 11:14:43 +01:00 committed by GitHub
parent c802515e71
commit 270df58057
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 68 additions and 26 deletions

View File

@ -24,14 +24,40 @@ pub fn deg(grad f32) f32 {
return (180.0 / math.pi) * grad return (180.0 / math.pi) * grad
} }
// Calculate the perspective matrix // calculate the Orthographic projection matrix
pub fn ortho(left f32, right f32, bottom f32, top f32, z_near f32, z_far f32) Mat4 {
rml := right - left
rpl := right + left
tmb := top - bottom
tpb := top + bottom
fmn := z_far - z_near
fpn := z_far + z_near
if fmn != 0 {
return Mat4{ e: [
2 / rml, 0 , 0, -(rpl / rml),
0 , 2 / tmb, 0, -(tpb / tmb),
0 , 0, 2 / fmn, -(fpn / fmn),
0 , 0, 0, 1,
]!
}
}
return Mat4{ e: [
2 / rml, 0 , 0, -(rpl / rml),
0 , 2 / tmb, 0, -(tpb / tmb),
0 , 0, 0, 0,
0 , 0, 0, 1,
]!
}
}
// Calculate the perspective matrix using (fov:fov, ar:aspect_ratio ,n:near_pane, f:far_plane) as parameters
pub fn perspective(fov f32, ar f32, n f32, f f32) Mat4 { pub fn perspective(fov f32, ar f32, n f32, f f32) Mat4 {
ctan := f32(1.0 / math.tan(fov * (f32(math.pi) / 360.0))) // for the FOV we use 360 instead 180 ctan := f32(1.0 / math.tan(fov * (f32(math.pi) / 360.0))) // for the FOV we use 360 instead 180
return Mat4{ e: [ return Mat4{ e: [
ctan / ar, 0, 0, 0, ctan / ar, 0, 0, 0,
0, ctan, 0, 0, 0, ctan, 0, 0,
0, 0, (n + f) / (n - f), -1.0, 0, 0, (n + f) / (n - f), -1.0,
0, 0, (2.0 * n * f) / (n - f), 0, 0, 0, (2.0 * n * f) / (n - f), 0,
]! ]!
} }
} }
@ -66,21 +92,6 @@ pub fn look_at(eye Vec4, center Vec4, up Vec4) Mat4 {
} }
} }
/*
hmm_mat4 proj = HMM_Perspective(60.0f, w/h, 0.01f, 10.0f);
hmm_mat4 view = HMM_LookAt(HMM_Vec3(0.0f, 1.5f, 6.0f), HMM_Vec3(0.0f, 0.0f, 0.0f), HMM_Vec3(0.0f, 1.0f, 0.0f));
hmm_mat4 view_proj = HMM_MultiplyMat4(proj, view);
//state.rx += 1.0f; state.ry += 2.0f;
hmm_mat4 rxm = HMM_Rotate(rx, HMM_Vec3(1.0f, 0.0f, 0.0f));
hmm_mat4 rym = HMM_Rotate(ry, HMM_Vec3(0.0f, 1.0f, 0.0f));
hmm_mat4 model = HMM_MultiplyMat4(rxm, rym);
hmm_mat4 scale_mx = HMM_Scale(HMM_Vec3(scale, scale, scale));
model = HMM_MultiplyMat4(model, scale_mx);
hmm_mat4 tmp_res = HMM_MultiplyMat4(view_proj, model);
*/
// Get the complete transformation matrix for GLSL demos // Get the complete transformation matrix for GLSL demos
pub fn calc_tr_matrices(w f32, h f32, rx f32, ry f32, in_scale f32) Mat4 { pub fn calc_tr_matrices(w f32, h f32, rx f32, ry f32, in_scale f32) Mat4 {

View File

@ -185,6 +185,7 @@ fn test_det() {
fn test_vec4() { fn test_vec4() {
// Test Vec4 // Test Vec4
// println("*** Vector4 ****") // println("*** Vector4 ****")
assert m4.vec3(1,2,3) == m4.Vec4{[f32(1), 2, 3, 1]!}
mut v := m4.Vec4{[f32(1), 2, 3, 4]!} mut v := m4.Vec4{[f32(1), 2, 3, 4]!}
assert v * v.inv() == 4 assert v * v.inv() == 4
assert v.mul_scalar(1.0 / v.mod()).mod() == 1 assert v.mul_scalar(1.0 / v.mod()).mod() == 1
@ -195,13 +196,22 @@ fn test_vec4() {
v = m4.Vec4{[f32(1), 2, 3, 0]!} v = m4.Vec4{[f32(1), 2, 3, 0]!}
assert m4.abs(v.normalize3().mod3() - 1) < m4.precision assert m4.abs(v.normalize3().mod3() - 1) < m4.precision
assert m4.abs(v.normalize3().mod() - 1) < m4.precision assert m4.abs(v.normalize3().mod() - 1) < m4.precision
// cross product
// x y z // x y z
// 1 2 3 ==> -3 6 -3 0 // 1 2 3 ==> -3 6 -3 0
// 4 5 6 // 4 5 6
// println(m4.Vec4{[f32(1),2,3,2]!} % m4.Vec4{[f32(4),5,6,2]!}) // println(m4.Vec4{[f32(1),2,3,2]!} % m4.Vec4{[f32(4),5,6,2]!})
assert m4.Vec4{[f32(1), 2, 3, 0]!} % m4.Vec4{[f32(4), 5, 6, 0]!} == m4.Vec4{[ f32(-3), 6, -3, 0, ]!} assert m4.Vec4{[f32(1), 2, 3, 0]!} % m4.Vec4{[f32(4), 5, 6, 0]!} == m4.Vec4{[ f32(-3), 6, -3, 0, ]!}
assert m4.Vec4{[f32(1), 2, 3, 13]!} % m4.Vec4{[f32(4), 5, 6, 11]!} == m4.Vec4{[ f32(-3), 6, -3, 0, ]!} assert m4.Vec4{[f32(1), 2, 3, 13]!} % m4.Vec4{[f32(4), 5, 6, 11]!} == m4.Vec4{[ f32(-3), 6, -3, 0, ]!}
// matrix * vector
a := m4.Mat4{ e: [
f32(1),2,3,4
5,6,7,8
9,10,11,12
13,14,15,16
]!
}
assert m4.mul_vec(a, m4.Vec4{[f32(1), 2, 3, 4]!}) == m4.Vec4{[ f32(30), 70, 110,150, ]!}
// Rotation // Rotation
// println("*** Rotation ****") // println("*** Rotation ****")
rotx := m4.rotate(m4.rad(-90), m4.Vec4{ e: [f32(1.0), 0, 0, 0]! }).clean() rotx := m4.rotate(m4.rad(-90), m4.Vec4{ e: [f32(1.0), 0, 0, 0]! }).clean()
@ -211,8 +221,15 @@ fn test_vec4() {
// println( roty ) // println( roty )
// println( rotz ) // println( rotz )
// println( m4.mul_vec(rotx, m4.Vec4{e:[f32(0),0,1,0]!}).clean()) // println( m4.mul_vec(rotx, m4.Vec4{e:[f32(0),0,1,0]!}).clean())
assert m4.mul_vec(roty, m4.Vec4{ e: [f32(1.0), 0.0, 0, 0]! }).clean() == m4.Vec4{ e: [f32(0), 0.0, 1, 0]! } assert m4.mul_vec(roty, m4.Vec4{ e: [f32(1.0), 0.0, 0, 0]! }).clean() == m4.Vec4{ e: [f32(0), 0.0, -1, 0]! }
assert m4.mul_vec(rotz, m4.Vec4{ e: [f32(1.0), 0.0, 0, 0]! }).clean() == m4.Vec4{ e: [f32(0), -1, 0, 0]! } assert m4.mul_vec(rotz, m4.Vec4{ e: [f32(1.0), 0.0, 0, 0]! }).clean() == m4.Vec4{ e: [f32(0), 1, 0, 0]! }
assert m4.mul_vec(rotx, m4.Vec4{ e: [f32(0), 0, 1, 0]! }).clean() == m4.Vec4{ e: [f32(0), 1, 0, 0]! } assert m4.mul_vec(rotx, m4.Vec4{ e: [f32(0), 0, 1, 0]! }).clean() == m4.Vec4{ e: [f32(0), -1, 0, 0]! }
// println("****************") // println("****************")
} }
fn test_proj() {
ort := m4.ortho(0,300,0,200,0,0)
assert m4.mul_vec(ort, m4.Vec4{[ f32(150), 100, 0, 1]!}) == m4.Vec4{[ f32(0), 0, 0, 1]!}
assert m4.mul_vec(ort, m4.Vec4{[ f32(0), 0, 0, 1]!}) == m4.Vec4{[ f32(-1), -1, 0, 1]!}
assert m4.mul_vec(ort, m4.Vec4{[ f32(300), 200, 0, 1]!}) == m4.Vec4{[ f32(1), 1, 0, 1]!}
}

View File

@ -41,7 +41,7 @@ pub fn (x Mat4) str() string {
return '|${x.e[0]:-6.3},${x.e[1]:-6.3},${x.e[2]:-6.3},${x.e[3]:-6.3}|\n' + return '|${x.e[0]:-6.3},${x.e[1]:-6.3},${x.e[2]:-6.3},${x.e[3]:-6.3}|\n' +
'|${x.e[4]:-6.3},${x.e[5]:-6.3},${x.e[6]:-6.3},${x.e[7]:-6.3}|\n' + '|${x.e[4]:-6.3},${x.e[5]:-6.3},${x.e[6]:-6.3},${x.e[7]:-6.3}|\n' +
'|${x.e[8]:-6.3},${x.e[9]:-6.3},${x.e[10]:-6.3},${x.e[11]:-6.3}|\n' + '|${x.e[8]:-6.3},${x.e[9]:-6.3},${x.e[10]:-6.3},${x.e[11]:-6.3}|\n' +
'|${x.e[12]:-6.3},${x.e[13]:-6.3},${x.e[14]:-6.3},${x.e[15]:-6.3}|\n' '|${x.e[12]:-6.3},${x.e[13]:-6.3},${x.e[14]:-6.3},${x.e[15]:-6.3}|'
} }
} }
@ -410,6 +410,7 @@ pub fn mul(a Mat4, b Mat4) Mat4 {
// Multiply a Matrix by a vector // Multiply a Matrix by a vector
pub fn mul_vec(a Mat4, v Vec4) Vec4 { pub fn mul_vec(a Mat4, v Vec4) Vec4 {
unsafe { unsafe {
/*
return Vec4{ e: [ return Vec4{ e: [
a.e[0] * v.e[0] + a.e[4] * v.e[1] + a.e[8] * v.e[2] + a.e[12] * v.e[3], a.e[0] * v.e[0] + a.e[4] * v.e[1] + a.e[8] * v.e[2] + a.e[12] * v.e[3],
a.e[1] * v.e[0] + a.e[5] * v.e[1] + a.e[9] * v.e[2] + a.e[13] * v.e[3], a.e[1] * v.e[0] + a.e[5] * v.e[1] + a.e[9] * v.e[2] + a.e[13] * v.e[3],
@ -417,6 +418,14 @@ pub fn mul_vec(a Mat4, v Vec4) Vec4 {
a.e[3] * v.e[0] + a.e[7] * v.e[1] + a.e[11] * v.e[2] + a.e[15] * v.e[3], a.e[3] * v.e[0] + a.e[7] * v.e[1] + a.e[11] * v.e[2] + a.e[15] * v.e[3],
]! ]!
} }
*/
return Vec4{ e: [
a.e[0] * v.e[0] + a.e[1] * v.e[1] + a.e[2] * v.e[2] + a.e[3] * v.e[3],
a.e[4] * v.e[0] + a.e[5] * v.e[1] + a.e[6] * v.e[2] + a.e[7] * v.e[3],
a.e[8] * v.e[0] + a.e[9] * v.e[1] + a.e[10] * v.e[2] + a.e[11] * v.e[3],
a.e[12] * v.e[0] + a.e[13] * v.e[1] + a.e[14] * v.e[2] + a.e[15] * v.e[3],
]!
}
} }
} }

View File

@ -23,7 +23,12 @@ pub mut:
* *
*********************************************************************/ *********************************************************************/
pub fn (x Vec4) str() string { pub fn (x Vec4) str() string {
return '|${x.e[0]:-6.3},${x.e[1]:-6.3},${x.e[2]:-6.3},${x.e[3]:-6.3}|\n' return '|${x.e[0]:-6.3},${x.e[1]:-6.3},${x.e[2]:-6.3},${x.e[3]:-6.3}|'
}
// create a Vec4 function passing x,y,z as parameteres. w is set to 1
pub fn vec3(x f32, y f32, z f32) Vec4 {
return m4.Vec4{e:[x, y, z, 1]!}
} }
// Remove all the raw zeros // Remove all the raw zeros