396 lines
8.4 KiB
V
396 lines
8.4 KiB
V
// Copyright (c) 2019-2020 Alexander Medvednikov. All rights reserved.
|
|
// Use of this source code is governed by an MIT license
|
|
// that can be found in the LICENSE file.
|
|
|
|
module glm
|
|
|
|
import math
|
|
|
|
/*
|
|
#flag -lmyglm
|
|
# f32* myglm_ortho(f32, f32, f32, f32);
|
|
# f32* myglm_translate(f32, f32, f32);
|
|
*/
|
|
// # f32* myglm_rotate(f32 *m, f32 angle, f32, f32, f32);
|
|
// # f32* myglm_perspective(f32, f32, f32, f32);
|
|
// # f32* myglm_look_at(glm__Vec3, glm__Vec3, glm__Vec3);
|
|
// # glm__Vec3 myglm_mult(glm__Vec3, glm__Vec3);
|
|
// # glm__Vec3 myglm_cross(glm__Vec3, glm__Vec3);
|
|
// # glm__Vec3 myglm_normalize(glm__Vec3);
|
|
pub struct Mat4 {
|
|
pub:
|
|
data &f32
|
|
}
|
|
|
|
struct Vec2 {
|
|
x f32
|
|
y f32
|
|
}
|
|
|
|
struct Vec3 {
|
|
x f32
|
|
y f32
|
|
z f32
|
|
}
|
|
|
|
pub fn vec3(x, y, z f32) Vec3 {
|
|
res := Vec3 {
|
|
x: x,
|
|
y: y,
|
|
z: z,
|
|
}
|
|
return res
|
|
}
|
|
|
|
fn mat4(f &f32) Mat4 {
|
|
res := Mat4 {
|
|
data: f
|
|
}
|
|
return res
|
|
}
|
|
|
|
pub fn (v Vec3) str() string {
|
|
return 'Vec3{ $v.x, $v.y, $v.z }'
|
|
}
|
|
|
|
pub fn (v Vec2) str() string {
|
|
return 'Vec3{ $v.x, $v.y }'
|
|
}
|
|
|
|
pub fn (m Mat4) str() string {
|
|
mut s := '[ '
|
|
for i in 0..4 {
|
|
if i != 0 {
|
|
s += ' '
|
|
}
|
|
for j in 0..4 {
|
|
val := m.data[i * 4 + j]
|
|
s += '${val:.2f} '
|
|
}
|
|
if i != 3 {
|
|
s += '\n'
|
|
}
|
|
}
|
|
s += ']'
|
|
return s
|
|
}
|
|
|
|
fn vec2(x, y int) Vec2 {
|
|
res := Vec2 {
|
|
x: x,
|
|
y: y,
|
|
}
|
|
return res
|
|
}
|
|
|
|
fn (a Vec3) add(b Vec3) Vec3 {
|
|
res := Vec3 {
|
|
x: a.x + b.x,
|
|
y: a.y + b.y,
|
|
z: a.z + b.z,
|
|
}
|
|
return res
|
|
}
|
|
|
|
fn (a Vec3) sub(b Vec3) Vec3 {
|
|
res := Vec3 {
|
|
x: a.x - b.x,
|
|
y: a.y - b.y,
|
|
z: a.z - b.z,
|
|
}
|
|
return res
|
|
}
|
|
|
|
// fn (a Vec3) mult(b Vec3) Vec3 {
|
|
// # return myglm_mult(a,b);
|
|
// }
|
|
fn (a Vec3) mult_scalar(b f32) Vec3 {
|
|
res := Vec3 {
|
|
x: a.x * b,
|
|
y: a.y * b,
|
|
z: a.z * b,
|
|
}
|
|
return res
|
|
}
|
|
|
|
fn (a Vec3) print() {
|
|
x := a.x
|
|
y := a.y
|
|
z := a.z
|
|
C.printf('vec3{%f,%f,%f}\n',x,y,z)
|
|
// println('vec3{$x,$y,$z}')
|
|
}
|
|
|
|
/*
|
|
fn rotate(m Mat4, angle f32, vec Vec3) Mat4 {
|
|
// # t_mat4 m;
|
|
// println('rotate done')
|
|
# return glm__mat4( myglm_rotate(m.data, angle, vec.x,vec.y,vec.z) );
|
|
return Mat4{}
|
|
}
|
|
*/
|
|
|
|
fn f32_calloc(n int) &f32 {
|
|
return &f32(vcalloc(n * sizeof(f32)))
|
|
}
|
|
// fn translate(vec Vec3) *f32 {
|
|
pub fn translate(m Mat4, v Vec3) Mat4 {
|
|
// # return glm__mat4(myglm_translate(vec.x,vec.y,vec.z) );
|
|
a := m.data
|
|
mut out := f32_calloc(16)
|
|
x := v.x
|
|
y := v.y
|
|
z := v.z
|
|
a00 := a[0]a01 := a[1]a02 := a[2]a03 := a[3]
|
|
a10 := a[4]a11 := a[5]a12 := a[6]a13 := a[7]
|
|
a20 := a[8]a21 := a[9]a22 := a[10]a23 := a[11]
|
|
out[0] = a00 out[1] = a01 out[2] = a02 out[3] = a03
|
|
out[4] = a10 out[5] = a11 out[6] = a12 out[7] = a13
|
|
out[8] = a20 out[9] = a21 out[10] = a22 out[11] = a23
|
|
out[12] = a00 * x + a10 * y + a20 * z + a[12]
|
|
out[13] = a01 * x + a11 * y + a21 * z + a[13]
|
|
out[14] = a02 * x + a12 * y + a22 * z + a[14]
|
|
out[15] = a03 * x + a13 * y + a23 * z + a[15]
|
|
return mat4(out)
|
|
}
|
|
|
|
/*
|
|
fn normalize(vec Vec3) Vec3 {
|
|
# return myglm_normalize(vec);
|
|
return Vec3{}
|
|
}
|
|
*/
|
|
// https://github.com/g-truc/glm/blob/0ceb2b755fb155d593854aefe3e45d416ce153a4/glm/ext/matrix_clip_space.inl
|
|
pub fn ortho(left, right, bottom, top f32) Mat4 {
|
|
//println('glm ortho($left, $right, $bottom, $top)')
|
|
// mat<4, 4, T, defaultp> Result(static_cast<T>(1));
|
|
n := 16
|
|
mut res := f32_calloc(n)
|
|
res[0] = 2.0 / (right - left)
|
|
res[5] = 2.0 / (top - bottom)
|
|
res[10] = 1.0
|
|
res[12] = - (right + left) / (right - left)
|
|
res[13] = - (top + bottom) / (top - bottom)
|
|
res[15] = 1.0
|
|
return mat4(res)
|
|
}
|
|
|
|
// https://github.com/g-truc/glm/blob/0ceb2b755fb155d593854aefe3e45d416ce153a4/glm/ext/matrix_clip_space.inl
|
|
pub fn ortho_zo(left, right, bottom, top, zNear, zFar f32) Mat4 {
|
|
//println('glm ortho($left, $right, $bottom, $top)')
|
|
// mat<4, 4, T, defaultp> Result(static_cast<T>(1));
|
|
n := 16
|
|
mut res := f32_calloc(n)
|
|
res[0] = 2.0 / (right - left)
|
|
res[5] = 2.0 / (top - bottom)
|
|
res[10] = 1.0
|
|
res[12] = - (right + left) / (right - left)
|
|
res[13] = - (top + bottom) / (top - bottom)
|
|
res[14] = - zNear / (zFar - zNear)
|
|
res[15] = 1.0
|
|
return mat4(res)
|
|
}
|
|
|
|
// fn scale(a *f32, v Vec3) *f32 {
|
|
pub fn scale(m Mat4, v Vec3) Mat4 {
|
|
a := m.data
|
|
mut out := f32_calloc(16)
|
|
x := v.x
|
|
y := v.y
|
|
z := v.z
|
|
out[0] = a[0] * v.x
|
|
out[1] = a[1] * x
|
|
out[2] = a[2] * x
|
|
out[3] = a[3] * x
|
|
out[4] = a[4] * y
|
|
out[5] = a[5] * y
|
|
out[6] = a[6] * y
|
|
out[7] = a[7] * y
|
|
out[8] = a[8] * z
|
|
out[9] = a[9] * z
|
|
out[10] = a[10] * z
|
|
out[11] = a[11] * z
|
|
out[12] = a[12]
|
|
out[13] = a[13]
|
|
out[14] = a[14]
|
|
out[15] = a[15]
|
|
return mat4(out)
|
|
}
|
|
|
|
// multiplicates two matrices
|
|
pub fn mult(a, b Mat4) Mat4 {
|
|
da := a.data
|
|
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
|
|
|
|
return mat4(out)
|
|
}
|
|
|
|
// fn rotate_z(a *f32, rad f32) *f32 {
|
|
pub fn rotate_z(m Mat4, rad f32) Mat4 {
|
|
a := m.data
|
|
mut out := f32_calloc(16)
|
|
s := math.sin(rad)
|
|
c := math.cos(rad)
|
|
a00 := a[0]
|
|
a01 := a[1]
|
|
a02 := a[2]
|
|
a03 := a[3]
|
|
a10 := a[4]
|
|
a11 := a[5]
|
|
a12 := a[6]
|
|
a13 := a[7]
|
|
out[8] = a[8]
|
|
out[9] = a[9]
|
|
out[10] = a[10]
|
|
out[11] = a[11]
|
|
out[12] = a[12]
|
|
out[13] = a[13]
|
|
out[14] = a[14]
|
|
out[15] = a[15]
|
|
// Perform axis-specific matrix multiplication
|
|
out[0] = a00 * c + a10 * s
|
|
out[1] = a01 * c + a11 * s
|
|
out[2] = a02 * c + a12 * s
|
|
out[3] = a03 * c + a13 * s
|
|
out[4] = a10 * c - a00 * s
|
|
out[5] = a11 * c - a01 * s
|
|
out[6] = a12 * c - a02 * s
|
|
out[7] = a13 * c - a03 * s
|
|
return mat4(out)
|
|
}
|
|
|
|
pub fn identity() Mat4 {
|
|
// 1 0 0 0
|
|
// 0 1 0 0
|
|
// 0 0 1 0
|
|
// 0 0 0 1
|
|
n := 16
|
|
mut res := f32_calloc(sizeof(f32) * n)
|
|
res[0] = 1
|
|
res[5] = 1
|
|
res[10] = 1
|
|
res[15] = 1
|
|
return mat4(res)
|
|
}
|
|
|
|
// returns *f32 without allocation
|
|
pub fn identity2(res mut &f32) {
|
|
res[0] = 1
|
|
res[5] = 1
|
|
res[10] = 1
|
|
res[15] = 1
|
|
// # f32 f[16]={0};// for (int i =0;i<16;i++)
|
|
// # printf("!!%d\n", f[0]);
|
|
// # glm__identity2(&f);
|
|
// # gl__Shader_set_mat4(shader, tos2("projection"), f) ;
|
|
}
|
|
|
|
pub fn identity3() []f32 {
|
|
res := [f32(1.0), 0, 0, 0,
|
|
0, 1, 0, 0,
|
|
0, 0, 1, 0,
|
|
0, 0, 0, 1,
|
|
]
|
|
return res
|
|
}
|
|
|
|
// https://github.com/toji/gl-matrix/blob/1549cf21dfa14a2bc845993485343d519cf064fe/src/gl-matrix/mat4.js
|
|
fn ortho_js(left, right, bottom, top f32) &f32 {
|
|
// mynear := 1
|
|
// myfar := 1
|
|
lr := 1.0 / (left - right)
|
|
bt := 1.0 / (bottom - top)
|
|
nf := 1.0 / 1.0// (mynear -myfar)
|
|
mut out := &f32(0)
|
|
unsafe { out = &f32( malloc (sizeof(f32) * 16)) }
|
|
out[0] = -2.0 * lr
|
|
out[1] = 0
|
|
out[2] = 0
|
|
out[3] = 0
|
|
out[4] = 0
|
|
out[5] = -2.0 * bt
|
|
out[6] = 0
|
|
out[7] = 0
|
|
out[8] = 0
|
|
out[9] = 0
|
|
out[10] = 2.0 * nf
|
|
out[11] = 0
|
|
out[12] = (left + right) * lr
|
|
out[13] = (top + bottom) * bt
|
|
out[14] = 1.0 * nf//(far + near) * nf;
|
|
out[15] = 1
|
|
return out
|
|
//f := 0.0
|
|
//return &f
|
|
}
|
|
|
|
// fn ortho_old(a, b, c, d f32) *f32 {
|
|
// # return myglm_ortho(a,b,c,d);
|
|
// }
|
|
fn cross(a, b Vec3) Vec3 {
|
|
// # return myglm_cross(a,b);
|
|
return Vec3{}
|
|
}
|
|
|
|
/*
|
|
fn perspective(degrees f32, ratio f32, a, b f32) Mat4 {
|
|
// println('lang per degrees=$degrees ratio=$ratio a=$a b=$b')
|
|
// # printf("lang pers degrees=%f ratio=%f a=%f b=%f\n", degrees, ratio, a,b);
|
|
# return glm__mat4( myglm_perspective(degrees, ratio, a,b) ) ;
|
|
return Mat4{}
|
|
}
|
|
|
|
fn look_at(eye, center, up Vec3) Mat4 {
|
|
# return glm__mat4( myglm_look_at(eye, center, up) ) ;
|
|
return Mat4{}
|
|
}
|
|
*/
|