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

pull/9830/head
Lukas Neubert 2021-04-20 16:16:35 +02:00 committed by GitHub
parent dff50686d6
commit 16e79bc3ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
38 changed files with 471 additions and 433 deletions

View File

@ -18,12 +18,18 @@ const (
'examples/term.ui', 'examples/term.ui',
] ]
verify_known_failing_exceptions = [ verify_known_failing_exceptions = [
// Handcrafted meaningful formatting of code parts (mostly arrays)
'examples/sokol/02_cubes_glsl/cube_glsl.v',
'examples/sokol/03_march_tracing_glsl/rt_glsl.v',
'examples/sokol/04_multi_shader_glsl/rt_glsl.v',
'examples/sokol/05_instancing_glsl/rt_glsl.v',
'vlib/gg/m4/graphic.v',
'vlib/gg/m4/m4_test.v',
'vlib/gg/m4/matrix.v',
'vlib/builtin/int_test.v' /* special number formatting that should be tested */, 'vlib/builtin/int_test.v' /* special number formatting that should be tested */,
// TODOs and unfixed vfmt bugs
'vlib/builtin/int.v' /* TODO byteptr: vfmt converts `pub fn (nn byteptr) str() string {` to `nn &byte` and that conflicts with `nn byte` */, 'vlib/builtin/int.v' /* TODO byteptr: vfmt converts `pub fn (nn byteptr) str() string {` to `nn &byte` and that conflicts with `nn byte` */,
'vlib/builtin/string_charptr_byteptr_helpers.v' /* TODO byteptr: a temporary shim to ease the byteptr=>&byte transition */, 'vlib/builtin/string_charptr_byteptr_helpers.v' /* TODO byteptr: a temporary shim to ease the byteptr=>&byte transition */,
'vlib/gg/m4/graphic.v' /* has hand crafted meaningful formatting of matrices */,
'vlib/gg/m4/m4_test.v' /* has hand crafted meaningful formatting of matrices */,
'vlib/gg/m4/matrix.v' /* has hand crafted meaningful formatting of matrices */,
'vlib/v/tests/array_append_short_struct_test.v', /* extra empty line */ 'vlib/v/tests/array_append_short_struct_test.v', /* extra empty line */
'vlib/v/tests/fixed_array_const_size_test.v', /* fixed arr type is changed */ 'vlib/v/tests/fixed_array_const_size_test.v', /* fixed arr type is changed */
'vlib/v/tests/fn_high_test.v', /* param name removed */ 'vlib/v/tests/fn_high_test.v', /* param name removed */
@ -34,9 +40,13 @@ const (
'vlib/v/tests/string_interpolation_test.v' /* TODO byteptr: &byte.str() behaves differently than byteptr.str() */, 'vlib/v/tests/string_interpolation_test.v' /* TODO byteptr: &byte.str() behaves differently than byteptr.str() */,
'vlib/v/gen/js/tests/js.v', /* local `hello` fn, gets replaced with module `hello` aliased as `hl` */ 'vlib/v/gen/js/tests/js.v', /* local `hello` fn, gets replaced with module `hello` aliased as `hl` */
'vlib/v/gen/c/cheaders.v' /* the preprocessor directives are formated to the V standard, even though they are in a string literal */, 'vlib/v/gen/c/cheaders.v' /* the preprocessor directives are formated to the V standard, even though they are in a string literal */,
'examples/c_interop_wkhtmltopdf.v', /* &charptr --> &&char */
'examples/path_tracing.v', /* block --> line comments corrupts code */
] ]
vfmt_verify_list = [ vfmt_verify_list = [
'cmd/', 'cmd/',
'examples/',
'tutorials/',
'vlib/arrays/', 'vlib/arrays/',
'vlib/benchmark/', 'vlib/benchmark/',
'vlib/bitfield/', 'vlib/bitfield/',

View File

@ -6,8 +6,8 @@ fn main() {
mov eax, a mov eax, a
add eax, b add eax, b
mov c, eax mov c, eax
; =r (c) // output ; =r (c) // output
; r (a) // input ; r (a) // input
r (b) r (b)
} }
println('a: $a') // 100 println('a: $a') // 100

View File

@ -32,9 +32,9 @@ fn main() {
description: 'Number of times the message gets printed.' description: 'Number of times the message gets printed.'
}) })
greet_cmd.add_flag(Flag{ greet_cmd.add_flag(Flag{
flag: .string_array flag: .string_array
name: 'fun' name: 'fun'
description: 'Just a dumby flags to show multiple.' description: 'Just a dumby flags to show multiple.'
}) })
cmd.add_command(greet_cmd) cmd.add_command(greet_cmd)
cmd.setup() cmd.setup()

View File

@ -1,12 +1,18 @@
struct App {} struct App {}
fn (mut app App) method_one() {} fn (mut app App) method_one() {}
fn (mut app App) method_two() int { return 0 }
fn (mut app App) method_three(s string) string { return s } fn (mut app App) method_two() int {
return 0
}
fn (mut app App) method_three(s string) string {
return s
}
fn main() { fn main() {
$for method in App.methods { $for method in App.methods {
$if method.typ is fn(string) string { $if method.typ is fn (string) string {
println('$method.name IS `fn(string) string`') println('$method.name IS `fn(string) string`')
} $else { } $else {
println('$method.name is NOT `fn(string) string`') println('$method.name is NOT `fn(string) string`')
@ -17,12 +23,12 @@ fn main() {
println('$method.name DOES return `int`') println('$method.name DOES return `int`')
} }
$if method.args[0].typ !is string { $if method.args[0].typ !is string {
println("${method.name}'s first arg is NOT `string`") println("$method.name's first arg is NOT `string`")
} $else { } $else {
println("${method.name}'s first arg IS `string`") println("$method.name's first arg IS `string`")
} }
// TODO: Double inversion, should this even be allowed? // TODO: Double inversion, should this even be allowed?
$if method.typ is fn() { $if method.typ is fn () {
println('$method.name IS a void method') println('$method.name IS a void method')
} $else { } $else {
println('$method.name is NOT a void method') println('$method.name is NOT a void method')

View File

@ -4,7 +4,7 @@ import time
fn vlang_time(mut wg sync.WaitGroup) ?string { fn vlang_time(mut wg sync.WaitGroup) ?string {
start := time.ticks() start := time.ticks()
data := http.get('https://vlang.io/utc_now')? data := http.get('https://vlang.io/utc_now') ?
finish := time.ticks() finish := time.ticks()
println('Finish getting time ${finish - start} ms') println('Finish getting time ${finish - start} ms')
println(data.text) println(data.text)
@ -14,7 +14,7 @@ fn vlang_time(mut wg sync.WaitGroup) ?string {
fn remote_ip(mut wg sync.WaitGroup) ?string { fn remote_ip(mut wg sync.WaitGroup) ?string {
start := time.ticks() start := time.ticks()
data := http.get('https://api.ipify.org')? data := http.get('https://api.ipify.org') ?
finish := time.ticks() finish := time.ticks()
println('Finish getting ip ${finish - start} ms') println('Finish getting ip ${finish - start} ms')
println(data.text) println(data.text)

View File

@ -1,7 +1,7 @@
import sqlite import sqlite
fn main() { fn main() {
db := sqlite.connect(':memory:')? db := sqlite.connect(':memory:') ?
db.exec("create table users (id integer primary key, name text default '');") db.exec("create table users (id integer primary key, name text default '');")
db.exec("insert into users (name) values ('Sam')") db.exec("insert into users (name) values ('Sam')")
@ -15,7 +15,7 @@ fn main() {
assert name == 'Sam' assert name == 'Sam'
users, code := db.exec('select * from users') users, code := db.exec('select * from users')
println("SQL Result code: $code") println('SQL Result code: $code')
for row in users { for row in users {
println(row.vals) println(row.vals)
} }

View File

@ -2,9 +2,9 @@ module main
import some_module import some_module
fn main(){ fn main() {
mut sub := some_module.get_subscriber() mut sub := some_module.get_subscriber()
sub.subscribe("error", on_error) sub.subscribe('error', on_error)
some_module.do_work() some_module.do_work()
} }

View File

@ -16,19 +16,19 @@ pub:
message string message string
} }
pub fn do_work(){ pub fn do_work() {
work := Work{20} work := Work{20}
for i in 0..20 { for i in 0 .. 20 {
println("working...") println('working...')
if i == 15 { if i == 15 {
error := &MyError{"There was an error."} error := &MyError{'There was an error.'}
eb.publish("error", work, error) some_module.eb.publish('error', work, error)
eb.publish("error", work, error) some_module.eb.publish('error', work, error)
return return
} }
} }
} }
pub fn get_subscriber() eventbus.Subscriber { pub fn get_subscriber() eventbus.Subscriber {
return *eb.subscriber return *some_module.eb.subscriber
} }

View File

@ -3,15 +3,15 @@
fn main() { fn main() {
// Check for user input // Check for user input
//if os.args.len != 2 { // if os.args.len != 2 {
// println('usage: fibonacci [rank]') // println('usage: fibonacci [rank]')
// Exit // Exit
// return // return
// } // }
// Parse first argument and cast it to int // Parse first argument and cast it to int
// stop := os.args[1].int() // stop := os.args[1].int()
stop := 23 stop := 23
// Can only calculate correctly until rank 92 // Can only calculate correctly until rank 92
if stop > 92 { if stop > 92 {
@ -23,7 +23,7 @@ fn main() {
mut a := 0 mut a := 0
mut b := 0 mut b := 0
mut c := 1 mut c := 1
println(a+c+c) println(a + c + c)
for _ in 0 .. stop { for _ in 0 .. stop {
// Set a and b to the next term // Set a and b to the next term
a = b a = b

View File

@ -61,14 +61,18 @@ fn on_frame(mut app App) {
fn on_event(e &gg.Event, mut app App) { fn on_event(e &gg.Event, mut app App) {
match e.typ { match e.typ {
.resized, .resumed { app.resize() } .resized, .resumed {
.iconified { app.draw_flag = false } app.resize()
.restored { }
.iconified {
app.draw_flag = false
}
.restored {
app.draw_flag = true app.draw_flag = true
app.resize() app.resize()
} }
else { else {
//println("Type ${e.typ}") // println("Type ${e.typ}")
} }
} }
} }
@ -80,16 +84,17 @@ fn (mut app App) resize() {
return return
} }
mut s := gg.dpi_scale() mut s := gg.dpi_scale()
if s == 0.0 { if s == 0.0 {
s = 1.0 s = 1.0
} }
app.ui.dpi_scale = s app.ui.dpi_scale = s
app.ui.width = size.width app.ui.width = size.width
app.ui.height = size.height app.ui.height = size.height
} }
[console] // is needed for easier diagnostics on windows // is needed for easier diagnostics on windows
[console]
fn main() { fn main() {
mut font_path := os.resource_abs_path(os.join_path('../assets/fonts/', 'RobotoMono-Regular.ttf')) mut font_path := os.resource_abs_path(os.join_path('../assets/fonts/', 'RobotoMono-Regular.ttf'))
$if android { $if android {

View File

@ -29,7 +29,7 @@ fn (mut n Neuron) populate(nb int) {
} }
struct Layer { struct Layer {
id int id int
mut: mut:
neurons []Neuron neurons []Neuron
} }
@ -50,7 +50,7 @@ mut:
fn (mut n Network) populate(network []int) { fn (mut n Network) populate(network []int) {
assert network.len >= 2 assert network.len >= 2
input := network[0] input := network[0]
hiddens := network[1..network.len-1] hiddens := network[1..network.len - 1]
output := network[network.len - 1] output := network[network.len - 1]
mut index := 0 mut index := 0
mut previous_neurons := 0 mut previous_neurons := 0
@ -232,8 +232,8 @@ fn (g Generation) next(population int) []Save {
pub struct Generations { pub struct Generations {
pub: pub:
population int population int
network []int network []int
mut: mut:
generations []Generation generations []Generation
} }

View File

@ -42,7 +42,7 @@ fn main() {
gg: 0 gg: 0
a: automaton.gun() a: automaton.gun()
} }
app.gg = gg.new_context({ app.gg = gg.new_context(
bg_color: gx.white bg_color: gx.white
frame_fn: frame frame_fn: frame
user_data: &app user_data: &app
@ -52,6 +52,6 @@ fn main() {
create_window: true create_window: true
resizable: false resizable: false
window_title: 'v life (with gg, gx)' window_title: 'v life (with gg, gx)'
}) )
app.gg.run() app.gg.run()
} }

View File

@ -79,15 +79,11 @@ pub fn (mut aa Automaton) update() {
for y := 1; y < aa.field.maxy; y++ { for y := 1; y < aa.field.maxy; y++ {
for x := 1; x < aa.field.maxx; x++ { for x := 1; x < aa.field.maxx; x++ {
moore_sum := (0 + aa.field.get(x - 1, y - 1) + aa.field.get(x, y - 1) + aa.field.get(x + moore_sum := (0 + aa.field.get(x - 1, y - 1) + aa.field.get(x, y - 1) + aa.field.get(x +
1, y - 1) + aa.field.get(x - 1, y) + 0 + aa.field.get(x + 1, y) + aa.field.get(x - 1, y + 1) + 1, y - 1) + aa.field.get(x - 1, y) + 0 + aa.field.get(x + 1, y) +
aa.field.get(x, y + 1) + aa.field.get(x + 1, y + 1)) aa.field.get(x - 1, y + 1) + aa.field.get(x, y + 1) + aa.field.get(x + 1, y + 1))
cell := aa.field.get(x, y) cell := aa.field.get(x, y)
v := if cell == 1 { moore_sum in [2, 3] } else { moore_sum == 3 } v := if cell == 1 { moore_sum in [2, 3] } else { moore_sum == 3 }
aa.new_field.set(x, y, if v { aa.new_field.set(x, y, if v { 1 } else { 0 })
1
} else {
0
})
} }
} }
tmp := aa.field tmp := aa.field

View File

@ -19,7 +19,7 @@ fn main() {
mut app := &App{ mut app := &App{
gg: 0 gg: 0
} }
app.gg = gg.new_context({ app.gg = gg.new_context(
bg_color: gx.white bg_color: gx.white
width: win_width width: win_width
height: win_height height: win_height
@ -29,7 +29,7 @@ fn main() {
frame_fn: frame frame_fn: frame
user_data: app user_data: app
init_fn: init_images init_fn: init_images
}) )
app.image = app.gg.create_image(os.resource_abs_path('logo.png')) app.image = app.gg.create_image(os.resource_abs_path('logo.png'))
app.gg.run() app.gg.run()
} }

View File

@ -73,7 +73,7 @@ fn (ctx &Context) draw() {
// y = x * x + stime * stime // y = x * x + stime * stime
// y = stime // y = stime
// y = stime * h // y = stime * h
y = stime * 1.0 * math.sin((x) + stime + atime / 32) * ((h / 256) + x) y = stime * 1.0 * math.sin(x + stime + atime / 32) * ((h / 256) + x)
// y = (stime * x) * x + stime // y = (stime * x) * x + stime
// y = (x + 3) * (x + 3) / stime + stime*2.5 // y = (x + 3) * (x + 3) / stime + stime*2.5
// y = math.sqrt(30.0 - x * x) * stime // y = math.sqrt(30.0 - x * x) * stime

View File

@ -24,6 +24,7 @@ struct Lander {
fn (l Lander) deorbit() { fn (l Lander) deorbit() {
println('leaving orbit') println('leaving orbit')
} }
fn (l Lander) open_parachutes(n int) { fn (l Lander) open_parachutes(n int) {
println('opening $n parachutes') println('opening $n parachutes')
} }

View File

@ -19,7 +19,6 @@ fn hello_response() string {
return 'Hello, World!' return 'Hello, World!'
} }
fn callback(req picohttpparser.Request, mut res picohttpparser.Response) { fn callback(req picohttpparser.Request, mut res picohttpparser.Response) {
if picohttpparser.cmpn(req.method, 'GET ', 4) { if picohttpparser.cmpn(req.method, 'GET ', 4) {
if picohttpparser.cmp(req.path, '/t') { if picohttpparser.cmp(req.path, '/t') {
@ -28,19 +27,16 @@ fn callback(req picohttpparser.Request, mut res picohttpparser.Response) {
res.header_date() res.header_date()
res.plain() res.plain()
res.body(hello_response()) res.body(hello_response())
} } else if picohttpparser.cmp(req.path, '/j') {
else if picohttpparser.cmp(req.path, '/j') {
res.http_ok() res.http_ok()
res.header_server() res.header_server()
res.header_date() res.header_date()
res.json() res.json()
res.body(json_response()) res.body(json_response())
} } else {
else {
res.http_404() res.http_404()
} }
} } else {
else {
res.http_405() res.http_405()
} }
} }

View File

@ -31,10 +31,6 @@ fn main() {
body_type: .html body_type: .html
body: body body: body
} }
mut client := smtp.new_client(client_cfg) or { mut client := smtp.new_client(client_cfg) or { panic('Error configuring smtp') }
panic('Error configuring smtp') client.send(send_cfg) or { panic('Error resolving email address') }
}
client.send(send_cfg) or {
panic('Error resolving email address')
}
} }

View File

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

View File

@ -9,6 +9,7 @@
* TODO: * TODO:
**********************************************************************/ **********************************************************************/
module obj module obj
import sokol.gfx import sokol.gfx
import gg.m4 import gg.m4
import math 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 { 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) stbi.set_flip_vertically_on_load(true)
img := stbi.load_from_memory(buffer.data, buffer.len) or { img := stbi.load_from_memory(buffer.data, buffer.len) or {
eprintln("Texure file: [$file_name] ERROR!") eprintln('Texure file: [$file_name] ERROR!')
exit(0) exit(0)
} }
res := create_texture(int(img.width), int(img.height), img.data) 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 // index buffer
mut index_buffer_desc := C.sg_buffer_desc{} 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.size = size_t(obj_buf.ibuf.len * int(sizeof(u32)))
index_buffer_desc.data = C.sg_range{ 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))) size: size_t(obj_buf.ibuf.len * int(sizeof(u32)))
} }
index_buffer_desc.@type = .indexbuffer index_buffer_desc.@type = .indexbuffer
index_buffer_desc.label = "indbuf_part_${in_part:03}".str index_buffer_desc.label = 'indbuf_part_${in_part:03}'.str
ibuf := gfx.make_buffer(&index_buffer_desc) ibuf := gfx.make_buffer(&index_buffer_desc)
mut pipdesc := C.sg_pipeline_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)) 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 // 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_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_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_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 = .float2 // u,v as f32
// pipdesc.layout.attrs[C.ATTR_vs_a_Texcoord0].format = .short2n // u,v as u16 // pipdesc.layout.attrs[C.ATTR_vs_a_Texcoord0].format = .short2n // u,v as u16
pipdesc.index_type = .uint32 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.index_buffer = ibuf
res.bind.fs_images[C.SLOT_tex] = texture res.bind.fs_images[C.SLOT_tex] = texture
res.pipeline = gfx.make_pipeline(&pipdesc) res.pipeline = gfx.make_pipeline(&pipdesc)
//println('Buffers part [$in_part] init done!') // println('Buffers part [$in_part] init done!')
return res return res
} }
@ -151,10 +152,10 @@ pub fn (mut obj_part ObjPart) init_render_data(texture C.sg_image) {
} }
} }
obj_part.rend_data.clear() 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 { for k, v in part_dict {
//println("$k => Parts $v") // println("$k => Parts $v")
mut txt := texture 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'] file_name := mat_map.maps['map_Kd']
if file_name in obj_part.texture { if file_name in obj_part.texture {
txt = obj_part.texture[file_name] txt = obj_part.texture[file_name]
//println("Texture [${file_name}] => from CACHE") // println("Texture [${file_name}] => from CACHE")
} else { } else {
txt = obj.load_texture(file_name) txt = load_texture(file_name)
obj_part.texture[file_name] = txt obj_part.texture[file_name] = txt
//println("Texture [${file_name}] => LOADED") // println("Texture [${file_name}] => LOADED")
} }
} }
} }
//key := obj_part.texture.keys()[0] // 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, obj_part.texture[key])
obj_part.rend_data << obj_part.create_pipeline(v, shader, txt) obj_part.rend_data << obj_part.create_pipeline(v, shader, txt)
} }
//println("Texture array len: ${obj_part.texture.len}") // println("Texture array len: ${obj_part.texture.len}")
//println("Calc bounding box.") // println("Calc bounding box.")
obj_part.calc_bbox() 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 { 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] mut part_render_data := obj_part.rend_data[rend_data_index]
// pass light position // 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 tmp_fs_params.ligth = in_data.fs_data.ligth
if part_render_data.material in obj_part.mat_map { 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 { pub fn (obj_part ObjPart) bind_and_draw_all(in_data Shader_data) u32 {
mut n_vert := u32(0) 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 { 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 return n_vert
} }
pub fn (mut obj_part ObjPart) calc_bbox() { 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.max = m4.Vec4{
obj_part.min = m4.Vec4{e:[f32( math.max_f32), math.max_f32, math.max_f32, 0]!} 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 { 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[0] > obj_part.max.e[0] {
if v.e[1] > obj_part.max.e[1] { obj_part.max.e[1] = v.e[1] } obj_part.max.e[0] = v.e[0]
if v.e[2] > obj_part.max.e[2] { obj_part.max.e[2] = v.e[2] } }
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[0] < obj_part.min.e[0] {
if v.e[1] < obj_part.min.e[1] { obj_part.min.e[1] = v.e[1] } obj_part.min.e[0] = v.e[0]
if v.e[2] < obj_part.min.e[2] { obj_part.min.e[2] = v.e[2] } }
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() val1 := obj_part.max.mod3()
val2 := obj_part.min.mod3() val2 := obj_part.min.mod3()
if val1 > val2 { obj_part.radius = f32(val1) } else { obj_part.radius = f32(val2) } if val1 > val2 {
//println("BBox: ${obj_part.min} <=> ${obj_part.max}\nRadius: ${obj_part.radius}") 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: * TODO:
**********************************************************************/ **********************************************************************/
module obj module obj
import gg.m4 import gg.m4
// part struct mantain the fae indexes list // part struct mantain the fae indexes list
pub struct Part { pub struct Part {
pub mut: pub mut:
faces [][][3]int // v n t index order, if -1 not available faces [][][3]int // v n t index order, if -1 not available
name string name string
material string material string
} }
// materias struct, all Ks and Ns are stored as maps of string // materias struct, all Ks and Ns are stored as maps of string
pub struct Material { pub struct Material {
pub mut: pub mut:
name string name string
ks map[string]m4.Vec4 ks map[string]m4.Vec4
ns map[string]f32 ns map[string]f32
maps map[string]string maps map[string]string
} }
// render data used for the rendering // render data used for the rendering
pub struct Render_data{ pub struct Render_data {
pub mut: pub mut:
pipeline C.sg_pipeline pipeline C.sg_pipeline
bind C.sg_bindings bind C.sg_bindings
@ -40,41 +41,40 @@ pub mut:
// base object parts struct // base object parts struct
pub struct ObjPart { pub struct ObjPart {
pub mut: pub mut:
v []m4.Vec4 // position v []m4.Vec4 // position
vn []m4.Vec4 // normals vn []m4.Vec4 // normals
vp []m4.Vec4 // vertex params vp []m4.Vec4 // vertex params
vt []m4.Vec4 // textures vt []m4.Vec4 // textures
name string name string
part []Part // parts of the ObjPart part []Part // parts of the ObjPart
mat []Material // list of the materials of the ObjPart mat []Material // list of the materials of the ObjPart
mat_map map[string]int // maping material name to its material index mat_map map[string]int // maping material name to its material index
texture map[string]C.sg_image // GPU loaded texture map texture map[string]C.sg_image // GPU loaded texture map
material_file string // .mtl file name for the .obj material_file string // .mtl file name for the .obj
rend_data []Render_data // render data used for the rendering rend_data []Render_data // render data used for the rendering
t_m m4.Mat4 = m4.unit_m4() // transform matrix for this ObjPart t_m m4.Mat4 = m4.unit_m4() // transform matrix for this ObjPart
//child []ObjPart // childs // child []ObjPart // childs
// stats // stats
min m4.Vec4 // min 3d position in the ObjPart min m4.Vec4 // min 3d position in the ObjPart
max m4.Vec4 // max 3d position in the ObjPart max m4.Vec4 // max 3d position in the ObjPart
radius f32 // bounding circle radius of the ObjPart radius f32 // bounding circle radius of the ObjPart
} }
// used in to pass the matrices to the shader // used in to pass the matrices to the shader
pub struct Mats { pub struct Mats {
pub mut: pub mut:
mv m4.Mat4 mv m4.Mat4
mvp m4.Mat4 mvp m4.Mat4
nm m4.Mat4 nm m4.Mat4
} }
// data passed to the vertex shader // data passed to the vertex shader
pub struct Tmp_vs_param { pub struct Tmp_vs_param {
pub mut: pub mut:
mv m4.Mat4 mv m4.Mat4
mvp m4.Mat4 mvp m4.Mat4
nm m4.Mat4 nm m4.Mat4
} }
@ -83,9 +83,15 @@ pub mut:
pub struct Tmp_fs_param { pub struct Tmp_fs_param {
pub mut: pub mut:
ligth m4.Vec4 ligth m4.Vec4
ka m4.Vec4 = m4.Vec4{e:[f32(0.1), 0.0, 0.0, 1.0]!} ka m4.Vec4 = m4.Vec4{
kd m4.Vec4 = m4.Vec4{e:[f32(0.5), 0.5, 0.5, 1.0]!} e: [f32(0.1), 0.0, 0.0, 1.0]!
ks m4.Vec4 = m4.Vec4{e:[f32(1.0), 1.0, 1.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 // shader data for the rendering
@ -95,4 +101,4 @@ pub mut:
vs_len int vs_len int
fs_data &Tmp_fs_param fs_data &Tmp_fs_param
fs_len int fs_len int
} }

View File

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

View File

@ -44,7 +44,6 @@ import sokol.sapp
import sokol.gfx import sokol.gfx
import sokol.sgl import sokol.sgl
import time import time
import os import os
import obj import obj
@ -52,6 +51,7 @@ import obj
#flag -I @VMODROOT/. #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) #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 fn C.gouraud_shader_desc(gfx.Backend) &C.sg_shader_desc
const ( const (
@ -67,19 +67,16 @@ mut:
init_flag bool init_flag bool
frame_count int frame_count int
mouse_x int = -1 mouse_x int = -1
mouse_y int = -1 mouse_y int = -1
scroll_y int //mouse wheel value scroll_y int // mouse wheel value
// time // time
ticks i64 ticks i64
// model // model
obj_part &obj.ObjPart obj_part &obj.ObjPart
n_vertex u32 n_vertex u32
// init parameters // init parameters
file_name string file_name string
single_material_flag bool single_material_flag bool
} }
@ -88,12 +85,15 @@ mut:
******************************************************************************/ ******************************************************************************/
[inline] [inline]
fn vec4(x f32, y f32, z f32, w f32) m4.Vec4 { 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 { 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 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 := 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 view_proj := view * proj
rxm := m4.rotate(m4.rad(rx), vec4(f32(1), 0, 0, 0)) 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_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)) 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 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 { 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() ws := gg.window_size_real_pixels()
dw := ws.width/2 dw := ws.width / 2
dh := ws.height/2 dh := ws.height / 2
mut scale := f32(1) mut scale := f32(1)
if app.obj_part.radius > 1 { if app.obj_part.radius > 1 {
scale = 1/(app.obj_part.radius) scale = 1 / (app.obj_part.radius)
} else { } else {
scale = app.obj_part.radius scale = app.obj_part.radius
} }
@ -130,29 +134,29 @@ fn draw_model(app App, model_pos m4.Vec4) u32 {
// *** vertex shader uniforms *** // *** vertex shader uniforms ***
rot := [f32(app.mouse_y), f32(app.mouse_x)] rot := [f32(app.mouse_y), f32(app.mouse_x)]
mut zoom_scale := scale + f32(app.scroll_y) / (app.obj_part.radius*4) 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) mats := calc_matrices(dw, dh, rot[0], rot[1], zoom_scale, model_pos)
mut tmp_vs_param := obj.Tmp_vs_param{ mut tmp_vs_param := obj.Tmp_vs_param{
mv: mats.mv, mv: mats.mv
mvp: mats.mvp, mvp: mats.mvp
nm: mats.nm nm: mats.nm
} }
// *** fragment shader uniforms *** // *** fragment shader uniforms ***
time_ticks := f32(time.ticks() - app.ticks) / 1000 time_ticks := f32(time.ticks() - app.ticks) / 1000
radius_light := f32(app.obj_part.radius) radius_light := f32(app.obj_part.radius)
x_light := f32(math.cos(time_ticks) * radius_light) x_light := f32(math.cos(time_ticks) * radius_light)
z_light := f32(math.sin(time_ticks) * radius_light) z_light := f32(math.sin(time_ticks) * radius_light)
mut tmp_fs_params := obj.Tmp_fs_param{} mut tmp_fs_params := obj.Tmp_fs_param{}
tmp_fs_params.ligth = m4.vec3(x_light, radius_light, z_light) tmp_fs_params.ligth = m4.vec3(x_light, radius_light, z_light)
sd := obj.Shader_data{ sd := obj.Shader_data{
vs_data: &tmp_vs_param 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_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) return app.obj_part.bind_and_draw_all(sd)
@ -179,8 +183,8 @@ fn frame(mut app App) {
// render the data // render the data
draw_start_glsl(app) draw_start_glsl(app)
draw_model(app, m4.Vec4{}) 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) mut n_vertex_drawn := u32(0)
n_x_obj := 20 n_x_obj := 20
@ -191,14 +195,14 @@ fn frame(mut app App) {
} }
} }
} }
*/ */
draw_end_glsl(app) draw_end_glsl(app)
//println("v:$n_vertex_drawn") // println("v:$n_vertex_drawn")
app.frame_count++ app.frame_count++
} }
fn draw_start_glsl(app App){ fn draw_start_glsl(app App) {
if app.init_flag == false { if app.init_flag == false {
return return
} }
@ -206,7 +210,7 @@ fn draw_start_glsl(app App){
gfx.apply_viewport(0, 0, ws.width, ws.height, true) 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.end_pass()
gfx.commit() gfx.commit()
} }
@ -240,7 +244,6 @@ fn my_init(mut app App) {
app.texture = obj.create_texture(1, 1, tmp_txt) app.texture = obj.create_texture(1, 1, tmp_txt)
free(tmp_txt) free(tmp_txt)
} }
// glsl // glsl
app.obj_part.init_render_data(app.texture) app.obj_part.init_render_data(app.texture)
app.init_flag = true app.init_flag = true
@ -248,11 +251,11 @@ fn my_init(mut app App) {
fn cleanup(mut app App) { fn cleanup(mut app App) {
gfx.shutdown() gfx.shutdown()
/* /*
for _, mat in app.obj_part.texture { for _, mat in app.obj_part.texture {
obj.destroy_texture(mat) obj.destroy_texture(mat)
} }
*/ */
} }
/****************************************************************************** /******************************************************************************
@ -280,20 +283,21 @@ fn my_event_manager(mut ev gg.Event, mut app App) {
/****************************************************************************** /******************************************************************************
* Main * Main
******************************************************************************/ ******************************************************************************/
[console] // is needed for easier diagnostics on windows // is needed for easier diagnostics on windows
[console]
fn main() { fn main() {
/* /*
obj.tst() obj.tst()
exit(0) exit(0)
*/ */
// App init // App init
mut app := &App{ mut app := &App{
gg: 0 gg: 0
obj_part: 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 app.single_material_flag = false
$if !android { $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('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 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(' 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) exit(0)
} }
@ -312,8 +316,8 @@ fn main() {
if os.args.len >= 3 { if os.args.len >= 3 {
app.single_material_flag = os.args[2].bool() app.single_material_flag = os.args[2].bool()
} }
println("Loading model: $app.file_name") println('Loading model: $app.file_name')
println("Using single material: $app.single_material_flag") println('Using single material: $app.single_material_flag')
} }
app.gg = gg.new_context( app.gg = gg.new_context(

View File

@ -48,7 +48,8 @@ fn init(mut state AppState) {
// or use DroidSerif-Regular.ttf // or use DroidSerif-Regular.ttf
if bytes := os.read_bytes(os.resource_abs_path('../assets/fonts/RobotoMono-Regular.ttf')) { if bytes := os.read_bytes(os.resource_abs_path('../assets/fonts/RobotoMono-Regular.ttf')) {
println('loaded font: $bytes.len') 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.fonsSetSize(state.fons, 20.0)
C.fonsSetFont(state.fons, state.font_normal) C.fonsSetFont(state.fons, state.font_normal)
C.fonsSetColor(state.fons, blue) 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 dx = 300
dy = 350 dy = 350
C.fonsSetAlign(state.fons, C.FONS_ALIGN_LEFT | C.FONS_ALIGN_BASELINE) C.fonsSetAlign(state.fons, C.FONS_ALIGN_LEFT | C.FONS_ALIGN_BASELINE)

View File

@ -6,9 +6,8 @@ import sokol.sfons
import os import os
import time import time
const ( const (
text = ' text = '
Once upon a midnight dreary, while I pondered, weak and weary, Once upon a midnight dreary, while I pondered, weak and weary,
Over many a quaint and curious volume of forgotten lore Over many a quaint and curious volume of forgotten lore
While I nodded, nearly napping, suddenly there came a tapping, 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; Let my heart be still a moment and this mystery explore;
Tis the wind and nothing more! Tis the wind and nothing more!
' '
lines = text.split('\n') lines = text.split('\n')
) )
struct AppState { struct AppState {
@ -59,7 +58,7 @@ mut:
pass_action C.sg_pass_action pass_action C.sg_pass_action
fons &C.FONScontext fons &C.FONScontext
font_normal int font_normal int
inited bool inited bool
} }
fn main() { fn main() {
@ -102,7 +101,8 @@ fn init(user_data voidptr) {
// or use DroidSerif-Regular.ttf // or use DroidSerif-Regular.ttf
if bytes := os.read_bytes(os.resource_abs_path('../assets/fonts/RobotoMono-Regular.ttf')) { if bytes := os.read_bytes(os.resource_abs_path('../assets/fonts/RobotoMono-Regular.ttf')) {
println('loaded font: $bytes.len') 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() sgl.draw()
gfx.end_pass() gfx.end_pass()
gfx.commit() gfx.commit()
println(time.ticks()-t) println(time.ticks() - t)
} }
const ( const (
black = C.sfons_rgba(0, 0, 0, 255)
black = C.sfons_rgba(0, 0, 0, 255)
) )
fn (mut state AppState) render_font() { 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 // Use of this source code is governed by an MIT license file distributed with this software package
module particle module particle
import vec2 import particle.vec2
import sokol.sgl import sokol.sgl
const ( const (
@ -16,9 +16,9 @@ pub fn new(location vec2.Vec2) &Particle {
location: location location: location
velocity: vec2.Vec2{0, 0} velocity: vec2.Vec2{0, 0}
acceleration: vec2.Vec2{0, 0} acceleration: vec2.Vec2{0, 0}
color: default_v_color color: particle.default_v_color
life_time: default_life_time life_time: particle.default_life_time
life_time_init: default_life_time life_time_init: particle.default_life_time
} }
return p return p
} }
@ -75,7 +75,7 @@ pub fn (mut p Particle) reset() {
p.acceleration.zero() p.acceleration.zero()
p.velocity.zero() p.velocity.zero()
// p.color = Color{93, 136, 193, 255} // p.color = Color{93, 136, 193, 255}
p.color = default_v_color p.color = particle.default_v_color
p.life_time = default_life_time p.life_time = particle.default_life_time
p.life_time_init = p.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 // Use of this source code is governed by an MIT license file distributed with this software package
module particle module particle
import vec2 import particle.vec2
import rand import rand
import sokol.sgl import sokol.sgl
@ -14,8 +14,8 @@ pub struct System {
width int width int
height int height int
mut: mut:
pool []&Particle pool []&Particle
bin []&Particle bin []&Particle
} }
pub fn (mut s System) init(sc SystemConfig) { pub fn (mut s System) init(sc SystemConfig) {
@ -82,7 +82,7 @@ pub fn (mut s System) free() {
print(ptr_str(p) + ' ouch') print(ptr_str(p) + ' ouch')
continue continue
} }
unsafe {free(p)} unsafe { free(p) }
} }
s.pool.clear() s.pool.clear()
for p in s.bin { for p in s.bin {

View File

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

View File

@ -26,12 +26,12 @@ fn main() {
struct App { struct App {
pass_action C.sg_pass_action pass_action C.sg_pass_action
mut: mut:
width int width int
height int height int
frame i64 frame i64
last i64 last i64
ps particle.System ps particle.System
alpha_pip C.sgl_pipeline alpha_pip C.sgl_pipeline
} }
fn (mut a App) init() { fn (mut a App) init() {
@ -80,7 +80,7 @@ fn init(user_data voidptr) {
} }
sgl.setup(&sgl_desc) sgl.setup(&sgl_desc)
mut pipdesc := C.sg_pipeline_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{ color_state := C.sg_color_state{
blend: C.sg_blend_state{ blend: C.sg_blend_state{

View File

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

View File

@ -71,7 +71,9 @@ fn data_get() []SiteConfig {
cat: .web cat: .web
alias: 'marketplace' alias: 'marketplace'
path_code: '/Users/despiegk/codewww/github/threefoldfoundation/www_threefold_marketplace' path_code: '/Users/despiegk/codewww/github/threefoldfoundation/www_threefold_marketplace'
domains: ['now.threefold.io', 'marketplace.threefold.io', 'now.threefold.me', 'marketplace.threefold.me'] domains: ['now.threefold.io', 'marketplace.threefold.io', 'now.threefold.me',
'marketplace.threefold.me',
]
descr: 'apps for community builders, runs on top of evdc' descr: 'apps for community builders, runs on top of evdc'
}, SiteConfig{ }, SiteConfig{
name: 'www_conscious_internet' name: 'www_conscious_internet'
@ -81,9 +83,8 @@ fn data_get() []SiteConfig {
cat: .web cat: .web
alias: 'conscious_internet' alias: 'conscious_internet'
path_code: '/Users/despiegk/codewww/github/threefoldfoundation/www_conscious_internet' path_code: '/Users/despiegk/codewww/github/threefoldfoundation/www_conscious_internet'
domains: ['www.consciousinternet.org', 'eco.threefold.io', 'community.threefold.io', 'eco.threefold.me', domains: ['www.consciousinternet.org', 'eco.threefold.io', 'community.threefold.io',
'community.threefold.me', 'eco.threefold.me', 'community.threefold.me']
]
descr: 'community around threefold, partners, friends, ...' descr: 'community around threefold, partners, friends, ...'
}, SiteConfig{ }, SiteConfig{
name: 'www_threefold_tech' name: 'www_threefold_tech'

View File

@ -300,7 +300,7 @@ fn (mut b Buffer) free() {
eprintln(@MOD + '.' + @STRUCT + '::' + @FN) eprintln(@MOD + '.' + @STRUCT + '::' + @FN)
} }
for line in b.lines { for line in b.lines {
unsafe {line.free()} unsafe { line.free() }
} }
unsafe { b.lines.free() } unsafe { b.lines.free() }
} }
@ -374,12 +374,12 @@ fn (mut b Buffer) move_to_word(movement Movement) {
} }
// first, move past all non-`a-zA-Z0-9_` characters // first, move past all non-`a-zA-Z0-9_` characters
for x + a >= 0 && x + a < line.len && !(line[x + a].is_letter() for x + a >= 0 && x + a < line.len && !(line[x + a].is_letter()
|| line[x + a].is_digit()|| line[x + a] == `_`) { || line[x + a].is_digit() || line[x + a] == `_`) {
x += a x += a
} }
// then, move past all the letters and numbers // then, move past all the letters and numbers
for x + a >= 0 && x + a < line.len && (line[x + a].is_letter() for x + a >= 0 && x + a < line.len && (line[x + a].is_letter()
|| line[x + a].is_digit()|| line[x + a] == `_`) { || line[x + a].is_digit() || line[x + a] == `_`) {
x += a x += a
} }
// if the cursor is out of bounds, move it to the next/previous line // if the cursor is out of bounds, move it to the next/previous line
@ -393,19 +393,11 @@ fn (mut b Buffer) move_to_word(movement Movement) {
} }
fn imax(x int, y int) int { fn imax(x int, y int) int {
return if x < y { return if x < y { y } else { x }
y
} else {
x
}
} }
fn imin(x int, y int) int { fn imin(x int, y int) int {
return if x < y { return if x < y { x } else { y }
x
} else {
y
}
} }
struct Cursor { struct Cursor {

View File

@ -396,7 +396,7 @@ fn (a App) check_capture() bool {
snake_pos := a.snake.get_head().pos snake_pos := a.snake.get_head().pos
rat_pos := a.rat.pos rat_pos := a.rat.pos
return snake_pos.x <= rat_pos.x + block_size && snake_pos.x + block_size >= rat_pos.x return snake_pos.x <= rat_pos.x + block_size && snake_pos.x + block_size >= rat_pos.x
&& snake_pos.y <= rat_pos.y + block_size&& snake_pos.y + block_size >= rat_pos.y && snake_pos.y <= rat_pos.y + block_size && snake_pos.y + block_size >= rat_pos.y
} }
fn (mut a App) draw_snake() { fn (mut a App) draw_snake() {

5
examples/v_script.vsh 100755 → 100644
View File

@ -1,9 +1,10 @@
#!/usr/local/bin/v run #!/usr/local/bin/v run
// The shebang above associates the file to V on Unix-like systems, // The shebang above associates the file to V on Unix-like systems,
// so it can be run just by specifying the path to the file // so it can be run just by specifying the path to the file
// once it's made executable using `chmod +x`. // once it's made executable using `chmod +x`.
for _ in 0..3 { for _ in 0 .. 3 {
println('V script') println('V script')
} }
@ -16,7 +17,7 @@ files := ls('.') or { panic(err.msg) }
println(files) println(files)
println('\nCreating foo.txt') println('\nCreating foo.txt')
create('foo.txt')? create('foo.txt') ?
println('\nFiles:') println('\nFiles:')
again_ls := ls('.') or { panic(err.msg) } again_ls := ls('.') or { panic(err.msg) }

View File

@ -18,15 +18,14 @@ pub fn (mut app App) index() vweb.Result {
return $vweb.html() return $vweb.html()
} }
[post] ['/upload'; post]
['/upload']
pub fn (mut app App) upload() vweb.Result { pub fn (mut app App) upload() vweb.Result {
fdata := app.files['upfile'] fdata := app.files['upfile']
mut files := []vweb.RawHtml{} mut files := []vweb.RawHtml{}
for d in fdata { for d in fdata {
files << d.data.replace_each(['\n', '<br>', '\n\r', '<br>' '\t', ' ', ' ', '&nbsp;']) files << d.data.replace_each(['\n', '<br>', '\n\r', '<br>', '\t', ' ', ' ', '&nbsp;'])
} }
return $vweb.html() return $vweb.html()

View File

@ -1,7 +1,7 @@
module main module main
import vweb import vweb
//import vweb.assets // import vweb.assets
import time import time
const ( const (

View File

@ -1,7 +1,6 @@
// Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved. // Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved.
// Use of this source code is governed by an MIT license // Use of this source code is governed by an MIT license
// that can be found in the LICENSE file. // that can be found in the LICENSE file.
import os import os
fn main() { fn main() {
@ -9,15 +8,14 @@ fn main() {
if os.args.len != 2 { if os.args.len != 2 {
println('usage: word_counter [text_file]') println('usage: word_counter [text_file]')
println('using $path') println('using $path')
} } else {
else {
path = os.args[1] path = os.args[1]
} }
contents := os.read_file(path.trim_space()) or { contents := os.read_file(path.trim_space()) or {
println('failed to open $path') println('failed to open $path')
return return
} }
mut m := map[string]int mut m := map[string]int{}
for word in extract_words(contents) { for word in extract_words(contents) {
m[word]++ m[word]++
} }
@ -37,8 +35,7 @@ fn extract_words(contents string) []string {
for space_splitted in contents.to_lower().split(' ') { for space_splitted in contents.to_lower().split(' ') {
if space_splitted.contains('\n') { if space_splitted.contains('\n') {
splitted << space_splitted.split('\n') splitted << space_splitted.split('\n')
} } else {
else {
splitted << space_splitted splitted << space_splitted
} }
} }

View File

@ -1,21 +1,20 @@
//fn println(s string) { } // fn println(s string) { }
//fn test_fn() { // fn test_fn() {
//println('test fn') // println('test fn')
//} //}
fn main() { fn main() {
println('x64 test') println('x64 test')
//i := 0 // i := 0
//for i < 5 { // for i < 5 {
for _ in 1..5 { for _ in 1 .. 5 {
println('Hello world from V x64 machine code generator!') println('Hello world from V x64 machine code generator!')
//i++ // i++
} }
/* /*
println('Hello again!') println('Hello again!')
//test_fn() //test_fn()
println('done') println('done')
*/ */
} }