1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

tools: format most examples and tutorials, add them to v test-cleancode (#9826)

This commit is contained in:
Lukas Neubert
2021-04-20 16:16:35 +02:00
committed by GitHub
parent dff50686d6
commit 16e79bc3ca
38 changed files with 471 additions and 433 deletions

View File

@ -9,10 +9,11 @@
* TODO:
**********************************************************************/
module obj
import gg.m4
import strconv
enum F_state{
enum F_state {
start
first
ints
@ -24,10 +25,10 @@ enum F_state{
// read a int from a string
fn get_int(s string, start_index int) (int, int) {
mut i := start_index
mut res := 0
mut sgn := 1
mut i := start_index
mut res := 0
mut sgn := 1
mut state := F_state.start
for true {
if i >= s.len {
@ -50,20 +51,20 @@ fn get_int(s string, start_index int) (int, int) {
`0`...`9` {
state = .ints
}
` `,`\t` {
` `, `\t` {
i++
continue
}
else{ // no number found
else { // no number found
break
}
}
}
if state == .ints {
match c {
`0`...`9` {
//println("$res => ${(int(c) - 48)}")
// println("$res => ${(int(c) - 48)}")
res = res * 10 + (int(c) - 48)
i++
continue
@ -73,55 +74,60 @@ fn get_int(s string, start_index int) (int, int) {
}
}
}
}
//println("---")
// println("---")
return res * sgn, i
}
// reas a float number from a string
fn get_float(s string, start_index int) (f64, int) {
mut i1 := start_index //+ 1
for i1 < s.len && s[i1] in [` `,`\t`] {
for i1 < s.len && s[i1] in [` `, `\t`] {
i1++
}
mut i := i1
for i < s.len {
if s[i] in [` `,`\t`] {
if s[i] in [` `, `\t`] {
break
}
i++
}
//println(" get_float: ($start_index,$i) [${s[start_index..i]}]")
//f_res := strconv.atof_quick(s[start_index..i])
}
// println(" get_float: ($start_index,$i) [${s[start_index..i]}]")
// f_res := strconv.atof_quick(s[start_index..i])
f_res := strconv.atof_quick(s[i1..i])
return f_res, i
}
// read 3 f32 in sequence from a string
fn parse_3f(row string, start_index int) m4.Vec4 {
//println(row)
// println(row)
mut i := start_index //+ 1
mut f1 := f64(0)
mut f2 := f64(0)
f0,mut p := get_float(row,i)
//print("Here f0: $f0 $p ")
f1, p = get_float(row,p+1)
//print("Here f1: $f1 $p ")
f2, p = get_float(row,p+1)
//print("Here f2: $f2 $p ")
return m4.Vec4{e:[f32(f0), f32(f1), f32(f2), 1]!}
f0, mut p := get_float(row, i)
// print("Here f0: $f0 $p ")
f1, p = get_float(row, p + 1)
// print("Here f1: $f1 $p ")
f2, p = get_float(row, p + 1)
// print("Here f2: $f2 $p ")
return m4.Vec4{
e: [f32(f0), f32(f1), f32(f2), 1]!
}
}
// reas a sequence of f32 from a string
fn (mut m ObjPart) parse_floats(row string, start_index int) m4.Vec4 {
mut i := start_index //+ 1
mut res_f := f64(0)
mut res := m4.Vec4{e:[f32(0), 0, 0, 1]!}
mut c := 0
mut i := start_index //+ 1
mut res_f := f64(0)
mut res := m4.Vec4{
e: [f32(0), 0, 0, 1]!
}
mut c := 0
for true {
res_f, i = get_float(row, i)
unsafe { res.e[c] = f32(res_f) }
unsafe {
res.e[c] = f32(res_f)
}
c++
i++
if i >= row.len {
@ -133,12 +139,12 @@ fn (mut m ObjPart) parse_floats(row string, start_index int) m4.Vec4 {
// read and manage all the faes from an .obj file data
fn (mut p Part) parse_faces(row string, start_index int, obj ObjPart) {
mut i := start_index + 1
mut res := [][3]int{}
mut v := 0
mut t := 0
mut n := 0
//println("row: ${row[i..]}")
mut i := start_index + 1
mut res := [][3]int{}
mut v := 0
mut t := 0
mut n := 0
// println("row: ${row[i..]}")
for true {
t = 0
n = 0
@ -146,29 +152,28 @@ fn (mut p Part) parse_faces(row string, start_index int, obj ObjPart) {
break
}
mut c := row[i]
if (c > `9` || c < `0`) && c != `-`{
if (c > `9` || c < `0`) && c != `-` {
i++
continue
}
v, i = get_int(row, i)
if i < row.len && row[i] == `/` {
if row[i+1] != `/` {
t,i = get_int(row, i+1)
if row[i + 1] != `/` {
t, i = get_int(row, i + 1)
if i < row.len && row[i] == `/` {
n,i = get_int(row, i+1)
n, i = get_int(row, i + 1)
}
} else {
i++
n,i = get_int(row, i+1)
n, i = get_int(row, i + 1)
}
}
// manage negative indexes
// NOTE: not well suporeted now
if v < 0 {
//println("${obj.v.len} ${obj.v.len-c}")
// println("${obj.v.len} ${obj.v.len-c}")
v = obj.v.len - v + 1
//exit(0)
// exit(0)
}
if n < 0 {
n = obj.vn.len - n + 1
@ -176,23 +181,24 @@ fn (mut p Part) parse_faces(row string, start_index int, obj ObjPart) {
if t < 0 {
t = obj.vt.len - t + 1
}
res << [v-1,n-1,t-1]!
res << [v - 1, n - 1, t - 1]!
}
//println("ok res: ${res}")
//println(p.faces.len)
// println("ok res: ${res}")
// println(p.faces.len)
p.faces << res
}
// parse the obj file, if single_material is true it use only one default material
pub fn (mut obj_part ObjPart) parse_obj_buffer(rows []string, single_material bool){
pub fn (mut obj_part ObjPart) parse_obj_buffer(rows []string, single_material bool) {
mut mat_count := 0
mut row_count := 0
default_part := Part{name:"default part"}
default_part := Part{
name: 'default part'
}
obj_part.part << default_part
//println("OBJ file has ${rows.len} rows")
// println("OBJ file has ${rows.len} rows")
for c, row in rows {
//println("$c $row")
// println("$c $row")
mut i := 0
row_count++
for true {
@ -204,32 +210,35 @@ pub fn (mut obj_part ObjPart) parse_obj_buffer(rows []string, single_material bo
break
}
`m` {
if row[i..i+6] == "mtllib" {
obj_part.material_file = row[i+7..].trim_space()
if row[i..i + 6] == 'mtllib' {
obj_part.material_file = row[i + 7..].trim_space()
obj_part.load_materials()
}
break
}
`o`, `g` {
mut part := Part{}
part.name = row[i+1..].trim_space()
part.name = row[i + 1..].trim_space()
obj_part.part << part
mat_count = 0
break
}
`u` {
if single_material == false && row[i..i+6] == "usemtl" {
material := row[i+7..].trim_space()
//println("material: $material")
if single_material == false && row[i..i + 6] == 'usemtl' {
material := row[i + 7..].trim_space()
// println("material: $material")
// manage multiple materials in an part
if obj_part.part[obj_part.part.len - 1].material.len > 0 {
mat_count++
mut part := Part{}
if mat_count > 1 {
li := obj_part.part[obj_part.part.len - 1].name.last_index("_m") or {obj_part.part[obj_part.part.len - 1].name.len - 1}
part.name = obj_part.part[obj_part.part.len - 1].name[..li] + "_m${mat_count:02}"
li := obj_part.part[obj_part.part.len - 1].name.last_index('_m') or {
obj_part.part[obj_part.part.len - 1].name.len - 1
}
part.name = obj_part.part[obj_part.part.len - 1].name[..li] +
'_m${mat_count:02}'
} else {
part.name = obj_part.part[obj_part.part.len - 1].name + "_m01"
part.name = obj_part.part[obj_part.part.len - 1].name + '_m01'
}
obj_part.part << part
}
@ -239,54 +248,53 @@ pub fn (mut obj_part ObjPart) parse_obj_buffer(rows []string, single_material bo
}
`v` {
i++
match row[i]{
match row[i] {
// normals
`n` {
obj_part.vn << parse_3f(row, i+2)
//println("Vertex line: $c")
obj_part.vn << parse_3f(row, i + 2)
// println("Vertex line: $c")
break
}
// parameteres uvw
`p` {
obj_part.vp << parse_3f(row, i+2)
//println("Vertex line: ${obj_part.vp.len}")
obj_part.vp << parse_3f(row, i + 2)
// println("Vertex line: ${obj_part.vp.len}")
break
}
// texture uvw
`t` {
obj_part.vt << obj_part.parse_floats(row, i+2)
//println("Vertex line: $c")
obj_part.vt << obj_part.parse_floats(row, i + 2)
// println("Vertex line: $c")
break
}
else {
obj_part.v << parse_3f(row, i+1)
//println("$row => ${obj_part.v[obj_part.v.len-1]}")
obj_part.v << parse_3f(row, i + 1)
// println("$row => ${obj_part.v[obj_part.v.len-1]}")
break
}
}
}
`f` {
//println("$c $row")
// println("$c $row")
obj_part.part[obj_part.part.len - 1].parse_faces(row, i, obj_part)
//println(obj_part.part[obj_part.part.len - 1].faces.len)
//println("Faces line: $c")
// println(obj_part.part[obj_part.part.len - 1].faces.len)
// println("Faces line: $c")
break
}
// end of the line, comments
`\n`,`#` {
`\n`, `#` {
break
}
else{}
else {}
}
i++
}
//if c == 2 { break }
if c % 100000 == 0 && c > 0{
println("$c rows parsed")
// if c == 2 { break }
if c % 100000 == 0 && c > 0 {
println('$c rows parsed')
}
}
println("$row_count .obj Rows parsed")
println('$row_count .obj Rows parsed')
// remove default part if empty
if obj_part.part.len > 1 && obj_part.part[0].faces.len == 0 {
obj_part.part = obj_part.part[1..]
@ -295,10 +303,10 @@ pub fn (mut obj_part ObjPart) parse_obj_buffer(rows []string, single_material bo
// load the materials if found the .mtl file
fn (mut obj_part ObjPart) load_materials() {
rows := obj.read_lines_from_file(obj_part.material_file)
println("Material file [${obj_part.material_file}] ${rows.len} Rows.")
rows := read_lines_from_file(obj_part.material_file)
println('Material file [$obj_part.material_file] $rows.len Rows.')
for row in rows {
//println("$row")
// println("$row")
mut i := 0
for true {
if i >= row.len {
@ -306,35 +314,37 @@ fn (mut obj_part ObjPart) load_materials() {
}
match row[i] {
`n` {
if row[i..i+6] == "newmtl" {
name := row[i+6..].trim_space()
mut mat := Material{name: name}
if row[i..i + 6] == 'newmtl' {
name := row[i + 6..].trim_space()
mut mat := Material{
name: name
}
obj_part.mat << mat
break
}
}
`K` {
if row[i+1] !in [`a`, `d`, `e`, `s`] {
if row[i + 1] !in [`a`, `d`, `e`, `s`] {
break
}
k_name := row[i..i+2]
k_name := row[i..i + 2]
i += 3
value := parse_3f(row, i)
obj_part.mat[obj_part.mat.len - 1].ks[k_name] = value
break
}
`N` {
n_name := row[i..i+2]
n_name := row[i..i + 2]
i += 3
value, _ := get_float(row, i)
obj_part.mat[obj_part.mat.len - 1].ns[n_name] = f32(value)
break
}
`m` {
if row[i..i+4] == "map_" {
name := row[i..i+6]
if row[i..i + 4] == 'map_' {
name := row[i..i + 6]
if (i + 7) < row.len {
file_name := row[i+7..].trim_space()
file_name := row[i + 7..].trim_space()
obj_part.mat[obj_part.mat.len - 1].maps[name] = file_name
}
break
@ -342,33 +352,33 @@ fn (mut obj_part ObjPart) load_materials() {
}
// trasparency
`d` {
if row[i+1] == ` ` {
value, _ := get_float(row, i+2)
if row[i + 1] == ` ` {
value, _ := get_float(row, i + 2)
obj_part.mat[obj_part.mat.len - 1].ns['Tr'] = f32(value)
}
}
`T` {
if row[i+1] == `r` {
value, _ := get_float(row, i+3)
if row[i + 1] == `r` {
value, _ := get_float(row, i + 3)
obj_part.mat[obj_part.mat.len - 1].ns['Tr'] = f32(1.0 - value)
}
}
// end of the line, comments
`\n`,`#` {
`\n`, `#` {
break
}
` `,`\t` {
` `, `\t` {
i++
continue
}
else{
else {
break
}
}
i++
}
}
// create map material name => material index
for i, m in obj_part.mat {
if m.name !in obj_part.mat_map {
@ -376,7 +386,7 @@ fn (mut obj_part ObjPart) load_materials() {
}
}
println("Material Loading Done!")
println('Material Loading Done!')
}
//==============================================================================
@ -392,7 +402,7 @@ pub mut:
nx f32 // normal
ny f32
nz f32
color u32 = 0xFFFFFFFF // color
color u32 = 0xFFFFFFFF // color
u f32 // uv
v f32
// u u16 // for compatibility with D3D11
@ -402,33 +412,33 @@ pub mut:
// struct used to pass the data to the sokol calls
pub struct Skl_buffer {
pub mut:
vbuf []Vertex_pnct
ibuf []u32
vbuf []Vertex_pnct
ibuf []u32
n_vertex u32
}
// transforms data from .obj format to buffer ready to be used in the render
pub fn (mut obj_part ObjPart) get_buffer(in_part_list []int) Skl_buffer {
//in_part := 0
// in_part := 0
mut v_count_index := 0
mut out_buf := Skl_buffer{}
mut cache := map[string]int
mut out_buf := Skl_buffer{}
mut cache := map[string]int{}
mut cache_hit := 0
//has_normals := obj_part.vn.len > 0
//has_uvs := obj_part.vt.len > 0
// has_normals := obj_part.vn.len > 0
// has_uvs := obj_part.vt.len > 0
for in_part in in_part_list {
part := obj_part.part[in_part]
for fc, face in part.faces {
//println("$fc $face")
// println("$fc $face")
// default 3 faces
mut v_seq := [0, 1, 2]
if face.len == 4 {
v_seq = [0, 1, 2, 0, 2, 3]
}
// if big faces => use the fan of triangles as solution
// Note: this trick doesn't work with concave faces
if face.len > 4 {
@ -437,42 +447,42 @@ pub fn (mut obj_part ObjPart) get_buffer(in_part_list []int) Skl_buffer {
for i < (face.len - 1) {
v_seq << 0
v_seq << i
v_seq << (i + 1)
v_seq << (i + 1)
i++
}
//println("BIG FACES! ${fc} ${face.len} v_seq:${v_seq.len}")
// println("BIG FACES! ${fc} ${face.len} v_seq:${v_seq.len}")
}
// no vertex index, generate normals
if face[0][1] == -1 && face.len >= 3 {
mut v_count := 0
v0 := face[v_count + 0][0]
v1 := face[v_count + 1][0]
v2 := face[v_count + 2][0]
vec0 := obj_part.v[v2] - obj_part.v[v1]
vec1 := obj_part.v[v0] - obj_part.v[v1]
tmp_normal := vec0 % vec1
for v_count < face.len {
obj_part.vn << tmp_normal
obj_part.part[in_part].faces[fc][v_count][1] = obj_part.vn.len - 1
v_count ++
v_count++
}
}
for vertex_index in v_seq {
// position
if vertex_index >= face.len {
continue
}
}
v_index := face[vertex_index][0] // vertex index
n_index := face[vertex_index][1] // normal index
t_index := face[vertex_index][2] // uv texture index
key := "${v_index}_${n_index}_${t_index}"
key := '${v_index}_${n_index}_$t_index'
if key !in cache {
cache[key] = v_count_index
mut pnct := Vertex_pnct {
mut pnct := Vertex_pnct{
x: obj_part.v[v_index].e[0]
y: obj_part.v[v_index].e[1]
z: obj_part.v[v_index].e[2]
@ -486,23 +496,21 @@ pub fn (mut obj_part ObjPart) get_buffer(in_part_list []int) Skl_buffer {
// texture uv
if t_index >= 0 {
pnct.u = obj_part.vt[t_index].e[0]
pnct.v = obj_part.vt[t_index].e[1]
pnct.v = obj_part.vt[t_index].e[1]
}
out_buf.vbuf << pnct
out_buf.ibuf << u32(v_count_index)
v_count_index++
} else {
//println("Cache used! $key")
// println("Cache used! $key")
out_buf.ibuf << u32(cache[key])
cache_hit++
}
}
}
}
/*
println("------------")
for c1, x1 in out_buf.vbuf[..10] {
@ -510,7 +518,7 @@ pub fn (mut obj_part ObjPart) get_buffer(in_part_list []int) Skl_buffer {
}
println(out_buf.ibuf[..10])
*/
//println("vbuf size: ${out_buf.vbuf.len} ibuf size: ${out_buf.ibuf.len} Cache hit: $cache_hit")
// println("vbuf size: ${out_buf.vbuf.len} ibuf size: ${out_buf.ibuf.len} Cache hit: $cache_hit")
out_buf.n_vertex = u32(out_buf.ibuf.len)
return out_buf
}
@ -520,36 +528,36 @@ pub fn (mut obj_part ObjPart) get_buffer(in_part_list []int) Skl_buffer {
//==============================================================================
// print on the console the summary of the .obj model loaded
pub fn (obj_part ObjPart) summary() {
println("---- Stats ----")
println("vertices: ${obj_part.v.len}")
println("normals : ${obj_part.vn.len}")
println("uv : ${obj_part.vt.len}")
println("parts : ${obj_part.part.len}")
println('---- Stats ----')
println('vertices: $obj_part.v.len')
println('normals : $obj_part.vn.len')
println('uv : $obj_part.vt.len')
println('parts : $obj_part.part.len')
// Parts
println("---- Parts ----")
println('---- Parts ----')
for c, x in obj_part.part {
println("${c:3} [${x.name:-16}] mat:[${x.material:-10}] ${x.faces.len:7} faces")
println('${c:3} [${x.name:-16}] mat:[${x.material:-10}] ${x.faces.len:7} faces')
}
// Materials
println("---- Materials ----")
println("Material dict: ${obj_part.mat_map.keys()}")
println('---- Materials ----')
println('Material dict: $obj_part.mat_map.keys()')
for c, mat in obj_part.mat {
println("${c:3} [${mat.name:-16}]")
for k,v in mat.ks {
print("$k = $v")
println('${c:3} [${mat.name:-16}]')
for k, v in mat.ks {
print('$k = $v')
}
for k,v in mat.ns {
println("$k = $v")
for k, v in mat.ns {
println('$k = $v')
}
for k,v in mat.maps {
println("$k = $v")
for k, v in mat.maps {
println('$k = $v')
}
}
}
// debug test function, do not remove.
pub fn tst(){
/*
pub fn tst() {
/*
//fname := "capsule.obj"
//fname := "Forklift.obj"
fname := "cube.obj"
@ -559,8 +567,8 @@ pub fn tst(){
buf := os.read_lines(fname) or { panic(err.msg) }
obj.parse_obj_buffer(buf)
obj.summary()
*/
/*
*/
/*
a :="f 7048 7070 7071 7072 7073 7074 7075 7076 7077 7078 7079 7080 7003"
mut f1 := 0
mut f2 := 0
@ -568,20 +576,20 @@ pub fn tst(){
f1, p = get_int(a,p)
f2, p = get_int(a,p)
println("res: ${f0} ${f1} ${f2}")
*/
/*
*/
/*
a :="v -0 0.107769 -0.755914"
println("${parse_3f(a,1)}")
*/
/*
*/
/*
ort := m4.ortho(0,300,0,200,0,0)
println(ort)
a := m4.vec3(0,0,0)
println("a: $a")
res := m4.mul_vec(ort, a)
println("res:\n${res}")
*/
s := "K 1 1 1"
r := strconv.atof_quick(s[1..s.len-1])
*/
s := 'K 1 1 1'
r := strconv.atof_quick(s[1..s.len - 1])
println(r)
}
}

View File

@ -9,6 +9,7 @@
* TODO:
**********************************************************************/
module obj
import sokol.gfx
import gg.m4
import math
@ -46,10 +47,10 @@ pub fn destroy_texture(sg_img C.sg_image) {
}
pub fn load_texture(file_name string) C.sg_image {
buffer := obj.read_bytes_from_file(file_name)
buffer := read_bytes_from_file(file_name)
stbi.set_flip_vertically_on_load(true)
img := stbi.load_from_memory(buffer.data, buffer.len) or {
eprintln("Texure file: [$file_name] ERROR!")
eprintln('Texure file: [$file_name] ERROR!')
exit(0)
}
res := create_texture(int(img.width), int(img.height), img.data)
@ -82,7 +83,7 @@ pub fn (mut obj_part ObjPart) create_pipeline(in_part []int, shader C.sg_shader,
// index buffer
mut index_buffer_desc := C.sg_buffer_desc{}
unsafe {C.memset(&index_buffer_desc, 0, sizeof(index_buffer_desc))}
unsafe { C.memset(&index_buffer_desc, 0, sizeof(index_buffer_desc)) }
index_buffer_desc.size = size_t(obj_buf.ibuf.len * int(sizeof(u32)))
index_buffer_desc.data = C.sg_range{
@ -90,8 +91,8 @@ pub fn (mut obj_part ObjPart) create_pipeline(in_part []int, shader C.sg_shader,
size: size_t(obj_buf.ibuf.len * int(sizeof(u32)))
}
index_buffer_desc.@type = .indexbuffer
index_buffer_desc.label = "indbuf_part_${in_part:03}".str
index_buffer_desc.@type = .indexbuffer
index_buffer_desc.label = 'indbuf_part_${in_part:03}'.str
ibuf := gfx.make_buffer(&index_buffer_desc)
mut pipdesc := C.sg_pipeline_desc{}
@ -99,10 +100,10 @@ pub fn (mut obj_part ObjPart) create_pipeline(in_part []int, shader C.sg_shader,
pipdesc.layout.buffers[0].stride = int(sizeof(Vertex_pnct))
// the constants [C.ATTR_vs_a_Position, C.ATTR_vs_a_Color, C.ATTR_vs_a_Texcoord0] are generated by sokol-shdc
pipdesc.layout.attrs[C.ATTR_vs_a_Position].format = .float3 // x,y,z as f32
pipdesc.layout.attrs[C.ATTR_vs_a_Normal ].format = .float3 // x,y,z as f32
pipdesc.layout.attrs[C.ATTR_vs_a_Color ].format = .ubyte4n // color as u32
pipdesc.layout.attrs[C.ATTR_vs_a_Texcoord0 ].format = .float2 // u,v as f32
pipdesc.layout.attrs[C.ATTR_vs_a_Position].format = .float3 // x,y,z as f32
pipdesc.layout.attrs[C.ATTR_vs_a_Normal].format = .float3 // x,y,z as f32
pipdesc.layout.attrs[C.ATTR_vs_a_Color].format = .ubyte4n // color as u32
pipdesc.layout.attrs[C.ATTR_vs_a_Texcoord0].format = .float2 // u,v as f32
// pipdesc.layout.attrs[C.ATTR_vs_a_Texcoord0].format = .short2n // u,v as u16
pipdesc.index_type = .uint32
@ -130,7 +131,7 @@ pub fn (mut obj_part ObjPart) create_pipeline(in_part []int, shader C.sg_shader,
res.bind.index_buffer = ibuf
res.bind.fs_images[C.SLOT_tex] = texture
res.pipeline = gfx.make_pipeline(&pipdesc)
//println('Buffers part [$in_part] init done!')
// println('Buffers part [$in_part] init done!')
return res
}
@ -151,10 +152,10 @@ pub fn (mut obj_part ObjPart) init_render_data(texture C.sg_image) {
}
}
obj_part.rend_data.clear()
//println("Material dict: ${obj_part.mat_map.keys()}")
// println("Material dict: ${obj_part.mat_map.keys()}")
for k, v in part_dict {
//println("$k => Parts $v")
// println("$k => Parts $v")
mut txt := texture
@ -164,22 +165,22 @@ pub fn (mut obj_part ObjPart) init_render_data(texture C.sg_image) {
file_name := mat_map.maps['map_Kd']
if file_name in obj_part.texture {
txt = obj_part.texture[file_name]
//println("Texture [${file_name}] => from CACHE")
// println("Texture [${file_name}] => from CACHE")
} else {
txt = obj.load_texture(file_name)
txt = load_texture(file_name)
obj_part.texture[file_name] = txt
//println("Texture [${file_name}] => LOADED")
// println("Texture [${file_name}] => LOADED")
}
}
}
//key := obj_part.texture.keys()[0]
//obj_part.rend_data << obj_part.create_pipeline(v, shader, obj_part.texture[key])
// key := obj_part.texture.keys()[0]
// obj_part.rend_data << obj_part.create_pipeline(v, shader, obj_part.texture[key])
obj_part.rend_data << obj_part.create_pipeline(v, shader, txt)
}
//println("Texture array len: ${obj_part.texture.len}")
//println("Calc bounding box.")
// println("Texture array len: ${obj_part.texture.len}")
// println("Calc bounding box.")
obj_part.calc_bbox()
println("init_render_data DONE!")
println('init_render_data DONE!')
}
pub fn (obj_part ObjPart) bind_and_draw(rend_data_index int, in_data Shader_data) u32 {
@ -187,7 +188,7 @@ pub fn (obj_part ObjPart) bind_and_draw(rend_data_index int, in_data Shader_data
mut part_render_data := obj_part.rend_data[rend_data_index]
// pass light position
mut tmp_fs_params := obj.Tmp_fs_param{}
mut tmp_fs_params := Tmp_fs_param{}
tmp_fs_params.ligth = in_data.fs_data.ligth
if part_render_data.material in obj_part.mat_map {
@ -246,27 +247,47 @@ pub fn (obj_part ObjPart) bind_and_draw(rend_data_index int, in_data Shader_data
pub fn (obj_part ObjPart) bind_and_draw_all(in_data Shader_data) u32 {
mut n_vert := u32(0)
//println("Parts: ${obj_part.rend_data.len}")
// println("Parts: ${obj_part.rend_data.len}")
for i, _ in obj_part.rend_data {
n_vert += obj_part.bind_and_draw(i,in_data)
n_vert += obj_part.bind_and_draw(i, in_data)
}
return n_vert
}
pub fn (mut obj_part ObjPart) calc_bbox() {
obj_part.max = m4.Vec4{e:[f32(-math.max_f32), -math.max_f32, -math.max_f32, 0]!}
obj_part.min = m4.Vec4{e:[f32( math.max_f32), math.max_f32, math.max_f32, 0]!}
obj_part.max = m4.Vec4{
e: [f32(-math.max_f32), -math.max_f32, -math.max_f32, 0]!
}
obj_part.min = m4.Vec4{
e: [f32(math.max_f32), math.max_f32, math.max_f32, 0]!
}
for v in obj_part.v {
if v.e[0] > obj_part.max.e[0] { obj_part.max.e[0] = v.e[0] }
if v.e[1] > obj_part.max.e[1] { obj_part.max.e[1] = v.e[1] }
if v.e[2] > obj_part.max.e[2] { obj_part.max.e[2] = v.e[2] }
if v.e[0] > obj_part.max.e[0] {
obj_part.max.e[0] = v.e[0]
}
if v.e[1] > obj_part.max.e[1] {
obj_part.max.e[1] = v.e[1]
}
if v.e[2] > obj_part.max.e[2] {
obj_part.max.e[2] = v.e[2]
}
if v.e[0] < obj_part.min.e[0] { obj_part.min.e[0] = v.e[0] }
if v.e[1] < obj_part.min.e[1] { obj_part.min.e[1] = v.e[1] }
if v.e[2] < obj_part.min.e[2] { obj_part.min.e[2] = v.e[2] }
if v.e[0] < obj_part.min.e[0] {
obj_part.min.e[0] = v.e[0]
}
if v.e[1] < obj_part.min.e[1] {
obj_part.min.e[1] = v.e[1]
}
if v.e[2] < obj_part.min.e[2] {
obj_part.min.e[2] = v.e[2]
}
}
val1 := obj_part.max.mod3()
val2 := obj_part.min.mod3()
if val1 > val2 { obj_part.radius = f32(val1) } else { obj_part.radius = f32(val2) }
//println("BBox: ${obj_part.min} <=> ${obj_part.max}\nRadius: ${obj_part.radius}")
if val1 > val2 {
obj_part.radius = f32(val1)
} else {
obj_part.radius = f32(val2)
}
// println("BBox: ${obj_part.min} <=> ${obj_part.max}\nRadius: ${obj_part.radius}")
}

View File

@ -9,27 +9,28 @@
* TODO:
**********************************************************************/
module obj
import gg.m4
// part struct mantain the fae indexes list
pub struct Part {
pub mut:
faces [][][3]int // v n t index order, if -1 not available
name string
material string
faces [][][3]int // v n t index order, if -1 not available
name string
material string
}
// materias struct, all Ks and Ns are stored as maps of string
pub struct Material {
pub mut:
name string
ks map[string]m4.Vec4
ns map[string]f32
maps map[string]string
name string
ks map[string]m4.Vec4
ns map[string]f32
maps map[string]string
}
// render data used for the rendering
pub struct Render_data{
pub struct Render_data {
pub mut:
pipeline C.sg_pipeline
bind C.sg_bindings
@ -40,41 +41,40 @@ pub mut:
// base object parts struct
pub struct ObjPart {
pub mut:
v []m4.Vec4 // position
vn []m4.Vec4 // normals
vp []m4.Vec4 // vertex params
vt []m4.Vec4 // textures
name string
part []Part // parts of the ObjPart
mat []Material // list of the materials of the ObjPart
mat_map map[string]int // maping material name to its material index
texture map[string]C.sg_image // GPU loaded texture map
material_file string // .mtl file name for the .obj
rend_data []Render_data // render data used for the rendering
t_m m4.Mat4 = m4.unit_m4() // transform matrix for this ObjPart
//child []ObjPart // childs
v []m4.Vec4 // position
vn []m4.Vec4 // normals
vp []m4.Vec4 // vertex params
vt []m4.Vec4 // textures
name string
part []Part // parts of the ObjPart
mat []Material // list of the materials of the ObjPart
mat_map map[string]int // maping material name to its material index
texture map[string]C.sg_image // GPU loaded texture map
material_file string // .mtl file name for the .obj
rend_data []Render_data // render data used for the rendering
t_m m4.Mat4 = m4.unit_m4() // transform matrix for this ObjPart
// child []ObjPart // childs
// stats
min m4.Vec4 // min 3d position in the ObjPart
max m4.Vec4 // max 3d position in the ObjPart
radius f32 // bounding circle radius of the ObjPart
min m4.Vec4 // min 3d position in the ObjPart
max m4.Vec4 // max 3d position in the ObjPart
radius f32 // bounding circle radius of the ObjPart
}
// used in to pass the matrices to the shader
pub struct Mats {
pub mut:
mv m4.Mat4
mvp m4.Mat4
nm m4.Mat4
mv m4.Mat4
mvp m4.Mat4
nm m4.Mat4
}
// data passed to the vertex shader
pub struct Tmp_vs_param {
pub mut:
mv m4.Mat4
mv m4.Mat4
mvp m4.Mat4
nm m4.Mat4
}
@ -83,9 +83,15 @@ pub mut:
pub struct Tmp_fs_param {
pub mut:
ligth m4.Vec4
ka m4.Vec4 = m4.Vec4{e:[f32(0.1), 0.0, 0.0, 1.0]!}
kd m4.Vec4 = m4.Vec4{e:[f32(0.5), 0.5, 0.5, 1.0]!}
ks m4.Vec4 = m4.Vec4{e:[f32(1.0), 1.0, 1.0, 1.0]!}
ka m4.Vec4 = m4.Vec4{
e: [f32(0.1), 0.0, 0.0, 1.0]!
}
kd m4.Vec4 = m4.Vec4{
e: [f32(0.5), 0.5, 0.5, 1.0]!
}
ks m4.Vec4 = m4.Vec4{
e: [f32(1.0), 1.0, 1.0, 1.0]!
}
}
// shader data for the rendering
@ -95,4 +101,4 @@ pub mut:
vs_len int
fs_data &Tmp_fs_param
fs_len int
}
}

View File

@ -1,21 +1,22 @@
module obj
import os
// read a file as single lines
pub fn read_lines_from_file(file_path string) []string {
mut path := ""
mut path := ''
mut rows := []string{}
$if android {
path = "models/"+file_path
path = 'models/' + file_path
bts := os.read_apk_asset(path) or {
eprintln("File [$path] NOT FOUND!")
eprintln('File [$path] NOT FOUND!')
return rows
}
rows = bts.bytestr().split_into_lines()
} $else {
path = "assets/models/"+file_path
path = 'assets/models/' + file_path
rows = os.read_lines(path) or {
eprintln("File [$path] NOT FOUND!")
eprintln('File [$path] NOT FOUND!')
return rows
}
}
@ -24,20 +25,20 @@ pub fn read_lines_from_file(file_path string) []string {
// read a file as []byte
pub fn read_bytes_from_file(file_path string) []byte {
mut path := ""
mut path := ''
mut buffer := []byte{}
$if android {
path = "models/"+file_path
path = 'models/' + file_path
buffer = os.read_apk_asset(path) or {
eprintln("Texure file: [$path] NOT FOUND!")
eprintln('Texure file: [$path] NOT FOUND!')
exit(0)
}
} $else {
path = "assets/models/"+file_path
path = 'assets/models/' + file_path
buffer = os.read_bytes(path) or {
eprintln("Texure file: [$path] NOT FOUND!")
eprintln('Texure file: [$path] NOT FOUND!')
exit(0)
}
}
return buffer
}
}

View File

@ -44,7 +44,6 @@ import sokol.sapp
import sokol.gfx
import sokol.sgl
import time
import os
import obj
@ -52,6 +51,7 @@ import obj
#flag -I @VMODROOT/.
#include "gouraud.h" #Please use sokol-shdc to generate the necessary rt_glsl.h file from rt_glsl.glsl (see the instructions at the top of this file)
fn C.gouraud_shader_desc(gfx.Backend) &C.sg_shader_desc
const (
@ -67,19 +67,16 @@ mut:
init_flag bool
frame_count int
mouse_x int = -1
mouse_y int = -1
scroll_y int //mouse wheel value
mouse_x int = -1
mouse_y int = -1
scroll_y int // mouse wheel value
// time
ticks i64
ticks i64
// model
obj_part &obj.ObjPart
n_vertex u32
obj_part &obj.ObjPart
n_vertex u32
// init parameters
file_name string
file_name string
single_material_flag bool
}
@ -88,12 +85,15 @@ mut:
******************************************************************************/
[inline]
fn vec4(x f32, y f32, z f32, w f32) m4.Vec4 {
return m4.Vec4{e:[x, y, z, w]!}
return m4.Vec4{
e: [x, y, z, w]!
}
}
fn calc_matrices(w f32, h f32, rx f32, ry f32, in_scale f32, pos m4.Vec4) obj.Mats {
proj := m4.perspective(60, w/h, 0.01, 100.0) // set far plane to 100 fro the zoom function
view := m4.look_at(vec4(f32(0.0) ,0 , 6, 0), vec4(f32(0), 0, 0, 0), vec4(f32(0), 1, 0, 0))
proj := m4.perspective(60, w / h, 0.01, 100.0) // set far plane to 100 fro the zoom function
view := m4.look_at(vec4(f32(0.0), 0, 6, 0), vec4(f32(0), 0, 0, 0), vec4(f32(0), 1,
0, 0))
view_proj := view * proj
rxm := m4.rotate(m4.rad(rx), vec4(f32(1), 0, 0, 0))
@ -101,14 +101,18 @@ fn calc_matrices(w f32, h f32, rx f32, ry f32, in_scale f32, pos m4.Vec4) obj.Ma
model_pos := m4.unit_m4().translate(pos)
model_m := (rym * rxm) * model_pos
model_m := (rym * rxm) * model_pos
scale_m := m4.scale(vec4(in_scale, in_scale, in_scale, 1))
mv := scale_m * model_m // model view
mv := scale_m * model_m // model view
nm := mv.inverse().transpose() // normal matrix
mvp := mv * view_proj // model view projection
mvp := mv * view_proj // model view projection
return obj.Mats{mv:mv, mvp:mvp, nm:nm}
return obj.Mats{
mv: mv
mvp: mvp
nm: nm
}
}
fn draw_model(app App, model_pos m4.Vec4) u32 {
@ -117,12 +121,12 @@ fn draw_model(app App, model_pos m4.Vec4) u32 {
}
ws := gg.window_size_real_pixels()
dw := ws.width/2
dh := ws.height/2
dw := ws.width / 2
dh := ws.height / 2
mut scale := f32(1)
if app.obj_part.radius > 1 {
scale = 1/(app.obj_part.radius)
scale = 1 / (app.obj_part.radius)
} else {
scale = app.obj_part.radius
}
@ -130,29 +134,29 @@ fn draw_model(app App, model_pos m4.Vec4) u32 {
// *** vertex shader uniforms ***
rot := [f32(app.mouse_y), f32(app.mouse_x)]
mut zoom_scale := scale + f32(app.scroll_y) / (app.obj_part.radius*4)
mats := calc_matrices(dw, dh, rot[0], rot[1] , zoom_scale, model_pos)
mut zoom_scale := scale + f32(app.scroll_y) / (app.obj_part.radius * 4)
mats := calc_matrices(dw, dh, rot[0], rot[1], zoom_scale, model_pos)
mut tmp_vs_param := obj.Tmp_vs_param{
mv: mats.mv,
mvp: mats.mvp,
nm: mats.nm
mv: mats.mv
mvp: mats.mvp
nm: mats.nm
}
// *** fragment shader uniforms ***
time_ticks := f32(time.ticks() - app.ticks) / 1000
radius_light := f32(app.obj_part.radius)
x_light := f32(math.cos(time_ticks) * radius_light)
z_light := f32(math.sin(time_ticks) * radius_light)
radius_light := f32(app.obj_part.radius)
x_light := f32(math.cos(time_ticks) * radius_light)
z_light := f32(math.sin(time_ticks) * radius_light)
mut tmp_fs_params := obj.Tmp_fs_param{}
tmp_fs_params.ligth = m4.vec3(x_light, radius_light, z_light)
sd := obj.Shader_data{
vs_data: &tmp_vs_param
vs_len: int(sizeof(tmp_vs_param))
vs_len: int(sizeof(tmp_vs_param))
fs_data: &tmp_fs_params
fs_len: int(sizeof(tmp_fs_params))
fs_len: int(sizeof(tmp_fs_params))
}
return app.obj_part.bind_and_draw_all(sd)
@ -179,8 +183,8 @@ fn frame(mut app App) {
// render the data
draw_start_glsl(app)
draw_model(app, m4.Vec4{})
// uncoment if you want a raw benchmark mode
/*
// uncoment if you want a raw benchmark mode
/*
mut n_vertex_drawn := u32(0)
n_x_obj := 20
@ -191,14 +195,14 @@ fn frame(mut app App) {
}
}
}
*/
*/
draw_end_glsl(app)
//println("v:$n_vertex_drawn")
// println("v:$n_vertex_drawn")
app.frame_count++
}
fn draw_start_glsl(app App){
fn draw_start_glsl(app App) {
if app.init_flag == false {
return
}
@ -206,7 +210,7 @@ fn draw_start_glsl(app App){
gfx.apply_viewport(0, 0, ws.width, ws.height, true)
}
fn draw_end_glsl(app App){
fn draw_end_glsl(app App) {
gfx.end_pass()
gfx.commit()
}
@ -240,7 +244,6 @@ fn my_init(mut app App) {
app.texture = obj.create_texture(1, 1, tmp_txt)
free(tmp_txt)
}
// glsl
app.obj_part.init_render_data(app.texture)
app.init_flag = true
@ -248,11 +251,11 @@ fn my_init(mut app App) {
fn cleanup(mut app App) {
gfx.shutdown()
/*
/*
for _, mat in app.obj_part.texture {
obj.destroy_texture(mat)
}
*/
*/
}
/******************************************************************************
@ -280,20 +283,21 @@ fn my_event_manager(mut ev gg.Event, mut app App) {
/******************************************************************************
* Main
******************************************************************************/
[console] // is needed for easier diagnostics on windows
// is needed for easier diagnostics on windows
[console]
fn main() {
/*
/*
obj.tst()
exit(0)
*/
*/
// App init
mut app := &App{
gg: 0
gg: 0
obj_part: 0
}
app.file_name = "v.obj_" // default object is the v logo
app.file_name = 'v.obj_' // default object is the v logo
app.single_material_flag = false
$if !android {
@ -302,7 +306,7 @@ fn main() {
eprintln('file_name : name of the .obj file, it must be in the folder "assets/models"')
eprintln(' if no file name is passed the default V logo will be showed.')
eprintln(' if you want custom models you can put them in the folder "assets/models".')
eprintln('single_material_flag: if true the viewer use for all the model\'s parts the default material\n')
eprintln("single_material_flag: if true the viewer use for all the model's parts the default material\n")
exit(0)
}
@ -312,8 +316,8 @@ fn main() {
if os.args.len >= 3 {
app.single_material_flag = os.args[2].bool()
}
println("Loading model: $app.file_name")
println("Using single material: $app.single_material_flag")
println('Loading model: $app.file_name')
println('Using single material: $app.single_material_flag')
}
app.gg = gg.new_context(

View File

@ -48,7 +48,8 @@ fn init(mut state AppState) {
// or use DroidSerif-Regular.ttf
if bytes := os.read_bytes(os.resource_abs_path('../assets/fonts/RobotoMono-Regular.ttf')) {
println('loaded font: $bytes.len')
state.font_normal = C.fonsAddFontMem(state.fons, 'sans', bytes.data, bytes.len, false)
state.font_normal = C.fonsAddFontMem(state.fons, 'sans', bytes.data, bytes.len,
false)
}
}
@ -101,7 +102,8 @@ fn (state &AppState) render_font() {
C.fonsSetSize(state.fons, 20.0)
C.fonsSetFont(state.fons, state.font_normal)
C.fonsSetColor(state.fons, blue)
C.fonsDrawText(state.fons, dx, dy, c'Now is the time for all good men to come to the aid of the party.', C.NULL)
C.fonsDrawText(state.fons, dx, dy, c'Now is the time for all good men to come to the aid of the party.',
C.NULL)
dx = 300
dy = 350
C.fonsSetAlign(state.fons, C.FONS_ALIGN_LEFT | C.FONS_ALIGN_BASELINE)

View File

@ -6,9 +6,8 @@ import sokol.sfons
import os
import time
const (
text = '
text = '
Once upon a midnight dreary, while I pondered, weak and weary,
Over many a quaint and curious volume of forgotten lore
While I nodded, nearly napping, suddenly there came a tapping,
@ -51,7 +50,7 @@ Soon again I heard a tapping somewhat louder than before.
Let my heart be still a moment and this mystery explore;
Tis the wind and nothing more!
'
lines = text.split('\n')
lines = text.split('\n')
)
struct AppState {
@ -59,7 +58,7 @@ mut:
pass_action C.sg_pass_action
fons &C.FONScontext
font_normal int
inited bool
inited bool
}
fn main() {
@ -102,7 +101,8 @@ fn init(user_data voidptr) {
// or use DroidSerif-Regular.ttf
if bytes := os.read_bytes(os.resource_abs_path('../assets/fonts/RobotoMono-Regular.ttf')) {
println('loaded font: $bytes.len')
state.font_normal = C.fonsAddFontMem(state.fons, 'sans', bytes.data, bytes.len, false)
state.font_normal = C.fonsAddFontMem(state.fons, 'sans', bytes.data, bytes.len,
false)
}
}
@ -114,12 +114,11 @@ fn frame(user_data voidptr) {
sgl.draw()
gfx.end_pass()
gfx.commit()
println(time.ticks()-t)
println(time.ticks() - t)
}
const (
black = C.sfons_rgba(0, 0, 0, 255)
black = C.sfons_rgba(0, 0, 0, 255)
)
fn (mut state AppState) render_font() {

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by an MIT license file distributed with this software package
module particle
import vec2
import particle.vec2
import sokol.sgl
const (
@ -16,9 +16,9 @@ pub fn new(location vec2.Vec2) &Particle {
location: location
velocity: vec2.Vec2{0, 0}
acceleration: vec2.Vec2{0, 0}
color: default_v_color
life_time: default_life_time
life_time_init: default_life_time
color: particle.default_v_color
life_time: particle.default_life_time
life_time_init: particle.default_life_time
}
return p
}
@ -75,7 +75,7 @@ pub fn (mut p Particle) reset() {
p.acceleration.zero()
p.velocity.zero()
// p.color = Color{93, 136, 193, 255}
p.color = default_v_color
p.life_time = default_life_time
p.color = particle.default_v_color
p.life_time = particle.default_life_time
p.life_time_init = p.life_time
}

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by an MIT license file distributed with this software package
module particle
import vec2
import particle.vec2
import rand
import sokol.sgl
@ -14,8 +14,8 @@ pub struct System {
width int
height int
mut:
pool []&Particle
bin []&Particle
pool []&Particle
bin []&Particle
}
pub fn (mut s System) init(sc SystemConfig) {
@ -82,7 +82,7 @@ pub fn (mut s System) free() {
print(ptr_str(p) + ' ouch')
continue
}
unsafe {free(p)}
unsafe { free(p) }
}
s.pool.clear()
for p in s.bin {

View File

@ -20,7 +20,7 @@ pub fn (mut v Vec2) from(src Vec2) {
// * Addition
// + operator overload. Adds two vectors
pub fn (v1 Vec2) +(v2 Vec2) Vec2 {
pub fn (v1 Vec2) + (v2 Vec2) Vec2 {
return Vec2{v1.x + v2.x, v1.y + v2.y}
}
@ -43,7 +43,7 @@ pub fn (mut v Vec2) plus_f64(scalar f64) {
}
// * Subtraction
pub fn (v1 Vec2) -(v2 Vec2) Vec2 {
pub fn (v1 Vec2) - (v2 Vec2) Vec2 {
return Vec2{v1.x - v2.x, v1.y - v2.y}
}
@ -66,7 +66,7 @@ pub fn (mut v Vec2) subtract_f64(scalar f64) {
}
// * Multiplication
pub fn (v1 Vec2) *(v2 Vec2) Vec2 {
pub fn (v1 Vec2) * (v2 Vec2) Vec2 {
return Vec2{v1.x * v2.x, v1.y * v2.y}
}

View File

@ -26,12 +26,12 @@ fn main() {
struct App {
pass_action C.sg_pass_action
mut:
width int
height int
frame i64
last i64
ps particle.System
alpha_pip C.sgl_pipeline
width int
height int
frame i64
last i64
ps particle.System
alpha_pip C.sgl_pipeline
}
fn (mut a App) init() {
@ -80,7 +80,7 @@ fn init(user_data voidptr) {
}
sgl.setup(&sgl_desc)
mut pipdesc := C.sg_pipeline_desc{}
unsafe {C.memset(&pipdesc, 0, sizeof(pipdesc))}
unsafe { C.memset(&pipdesc, 0, sizeof(pipdesc)) }
color_state := C.sg_color_state{
blend: C.sg_blend_state{

View File

@ -117,13 +117,12 @@ struct RIFFFormat {
}
fn read_wav_file_samples(fpath string) ?[]f32 {
mut res := []f32{}
// eprintln('> read_wav_file_samples: $fpath -------------------------------------------------')
mut bytes := os.read_bytes(fpath) ?
mut pbytes := &byte(bytes.data)
mut offset := u32(0)
rh := unsafe{ &RIFFHeader(pbytes) }
rh := unsafe { &RIFFHeader(pbytes) }
// eprintln('rh: $rh')
if rh.riff != [byte(`R`), `I`, `F`, `F`]! {
return error('WAV should start with `RIFF`')
@ -141,7 +140,7 @@ fn read_wav_file_samples(fpath string) ?[]f32 {
break
}
//
ch := unsafe{ &RIFFChunkHeader(pbytes + offset) }
ch := unsafe { &RIFFChunkHeader(pbytes + offset) }
offset += 8 + ch.chunk_size
// eprintln('ch: $ch')
// eprintln('p: $pbytes | offset: $offset | bytes.len: $bytes.len')
@ -176,20 +175,20 @@ fn read_wav_file_samples(fpath string) ?[]f32 {
}
// eprintln('`fmt ` chunk: $rf\n`data` chunk: $ch')
mut doffset := 0
mut dp := unsafe{ &byte(&ch.chunk_data) }
mut dp := unsafe { &byte(&ch.chunk_data) }
for doffset < ch.chunk_size {
for c := 0; c < rf.nchannels; c++ {
mut x := f32(0.0)
mut step := 0
ppos := unsafe { dp + doffset }
if rf.bits_per_sample == 8 {
d8 := unsafe{ &byte(ppos) }
d8 := unsafe { &byte(ppos) }
x = (f32(*d8) - 128) / 128.0
step = 1
doffset++
}
if rf.bits_per_sample == 16 {
d16 := unsafe{ &i16(ppos) }
d16 := unsafe { &i16(ppos) }
x = f32(*d16) / 32768.0
step = 2
}
@ -207,5 +206,4 @@ fn read_wav_file_samples(fpath string) ?[]f32 {
}
}
return res
}