diff --git a/game/assets/assets.odin b/game/assets/assets.odin index e8b53b8..5840084 100644 --- a/game/assets/assets.odin +++ b/game/assets/assets.odin @@ -1,6 +1,9 @@ package assets +import "core:bytes" import "core:c" +import "core:encoding/csv" +import "core:io" import "core:log" import "core:math" import lg "core:math/linalg" @@ -40,6 +43,10 @@ Loaded_Convex :: struct { inertia_tensor: lg.Matrix3f32, } +Loaded_Curve_2D :: struct { + points: [][2]f32, +} + destroy_loaded_bvh :: proc(loaded_bvh: Loaded_BVH) { tracy.Zone() @@ -53,6 +60,7 @@ Asset_Manager :: struct { textures: map[cstring]Loaded_Texture, models: map[cstring]Loaded_Model, bvhs: map[cstring]Loaded_BVH, + curves: map[cstring]Loaded_Curve_2D, } get_texture :: proc(assetman: ^Asset_Manager, path: cstring) -> rl.Texture2D { @@ -177,31 +185,69 @@ get_bvh :: proc(assetman: ^Asset_Manager, path: cstring) -> Loaded_BVH { return assetman.bvhs[path] } -Curve_2D :: struct { - points: [][2]f32, -} - +// TODO: cache result // Reads a two column comma separated csv file as a curve -// get_curve_2d :: proc(assetman: ^Asset_Manager, path: string) -> (curve: Curve_2D) { -// data, err := os2.read_entire_file_from_path(path, context.allocator) -// if err != nil { -// log.errorf("Failed to read curve: %s", path) -// return -// } -// defer delete(data) -// -// str := string(data) -// scan: scanner.Scanner -// scanner.init(&scan, str, path) -// scan.whitespace = scanner.Whitespace{' ', '\t', '\r'} -// scan.flags = scanner.Scan_Flags{.Scan_Ints, .Scan_Floats, .Scan_Idents} -// -// for tok := scanner.scan(&scan); tok != scanner.EOF; tok = scanner.scan(&scan) { -// -// } -// -// return -// } +get_curve_2d :: proc(assetman: ^Asset_Manager, path: string) -> (curve: Loaded_Curve_2D) { + data, err := os2.read_entire_file_from_path(path, context.temp_allocator) + if err != nil { + log.errorf("Failed to read curve: %s", path) + return + } + + bytes_reader: bytes.Reader + bytes.reader_init(&bytes_reader, data) + bytes_stream := bytes.reader_to_stream(&bytes_reader) + + csv_reader: csv.Reader + csv.reader_init(&csv_reader, bytes_stream, context.temp_allocator) + + tmp_result := make([dynamic][2]f32, context.temp_allocator) + + skipped_header := false + for { + row, err := csv.read(&csv_reader, context.temp_allocator) + if err != nil { + if err != io.Error.EOF { + log.errorf("Failed to read curve %v", err) + } + break + } + + if len(row) != 2 { + log.errorf("Curve expected 2 columns, got %v", len(row)) + break + } + + ok: bool + key: f64 + val: f64 + key, ok = strconv.parse_f64(row[0]) + if !ok { + if skipped_header { + log.errorf("Curve expected numbers, got %s", row[0]) + break + } + skipped_header = true + continue + } + val, ok = strconv.parse_f64(row[1]) + if !ok { + if skipped_header { + log.errorf("Curve expected numbers, got %s", row[1]) + break + } + skipped_header = true + continue + } + + append(&tmp_result, [2]f32{f32(key), f32(val)}) + } + + curve.points = make([][2]f32, len(tmp_result), context.temp_allocator) + copy(curve.points, tmp_result[:]) + + return +} get_convex :: proc(assetman: ^Asset_Manager, path: cstring) -> (result: Loaded_Convex) { bytes, err := os2.read_entire_file(string(path), context.temp_allocator)