Last active
September 2, 2024 19:22
-
-
Save Kiokiok/b891f69e68ac7985b8f935e1ce11fe11 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package main | |
| import "core:os"; | |
| import "core:fmt"; | |
| import "core:strconv"; | |
| import "core:strings" | |
| Vec3 :: [3]f32 | |
| Vec2 :: [2]f32 | |
| Model_Data :: struct { | |
| vertex_positions: [dynamic]Vec3, | |
| vertex_normals: [dynamic]Vec3, | |
| vertex_uvs: [dynamic]Vec2, | |
| indices_positions: [dynamic]u32, | |
| indices_normals: [dynamic]u32, | |
| indices_uvs: [dynamic]u32, | |
| } | |
| free_model_data :: proc(using model_data: Model_Data) { | |
| delete(vertex_positions); | |
| delete(vertex_normals); | |
| delete(vertex_uvs); | |
| delete(indices_positions); | |
| delete(indices_normals); | |
| delete(indices_uvs); | |
| } | |
| stream: string; | |
| is_whitespace :: proc(c: u8) -> bool { | |
| switch c { | |
| case ' ', '\t', '\n', '\v', '\f', '\r', '/': return true; | |
| } | |
| return false; | |
| } | |
| to_f32 :: proc(str : string) -> f32 { | |
| val, _ := strconv.parse_f32(str) | |
| return val | |
| } | |
| to_u32 :: proc(str: string) -> u32 { | |
| val, _ := strconv.parse_int(str) | |
| return cast(u32)val | |
| } | |
| get_next_word :: proc (i : ^int, line : string) -> string { | |
| skip_whitespace(i, line) | |
| start := i^ | |
| for { | |
| if is_whitespace(line[i^]) || i^ == len(line)-1 { | |
| current_word := line[start:i^]; | |
| return current_word; | |
| } | |
| i^ += 1 | |
| } | |
| return ""; | |
| } | |
| skip_whitespace :: proc(i : ^int, line : string) { | |
| for { | |
| if !is_whitespace(line[i^]) { | |
| return | |
| } | |
| i^ += 1 | |
| } | |
| for stream != "" && is_whitespace(stream[0]) do stream = stream[1:]; | |
| } | |
| // @WARNING! This assumes the obj file is well formed. | |
| // | |
| // Each v, vn line has to have at least 3 elements. Every element after the third is discarded | |
| // Each vt line has to have at least 2 elements. Every element after the second is discarded | |
| // Each f line has to have at least 9 elements. Every element after the ninth is discarded | |
| // | |
| // Note that we only support files where the faces are specified as A/A/A B/B/B C/C/C | |
| // Note also that '/' is regarded as whitespace, to simplify the face parsing | |
| read_obj_simple :: proc(file_path : string) -> Model_Data { | |
| data, _ := os.read_entire_file_from_filename(file_path, context.temp_allocator) | |
| defer delete(data, context.temp_allocator) | |
| data_str : string = string(data) | |
| vertex_positions: [dynamic]Vec3 | |
| vertex_normals: [dynamic]Vec3 | |
| vertex_uvs: [dynamic]Vec2 | |
| indices_positions: [dynamic]u32 | |
| indices_normals: [dynamic]u32 | |
| indices_uvs: [dynamic]u32 | |
| for line in strings.split_lines_after_iterator(&data_str) { | |
| count := 0 | |
| curr_word := get_next_word(&count, line) | |
| switch curr_word { | |
| case "v": | |
| append(&vertex_positions, Vec3{to_f32(get_next_word(&count, line)), to_f32(get_next_word(&count, line)), to_f32(get_next_word(&count, line))}) | |
| case "vn": | |
| append(&vertex_normals, Vec3{to_f32(get_next_word(&count, line)), to_f32(get_next_word(&count, line)), to_f32(get_next_word(&count, line))}) | |
| case "vt": | |
| append(&vertex_uvs, Vec2{to_f32(get_next_word(&count, line)), to_f32(get_next_word(&count, line))}) | |
| case "f": | |
| indices: [9]u32 | |
| for i in 0..<9 do indices[i] = to_u32(get_next_word(&count, line))-1 | |
| append(&indices_positions, indices[0], indices[3], indices[6]) | |
| append(&indices_normals, indices[2], indices[5], indices[8]) | |
| append(&indices_uvs, indices[1], indices[4], indices[7]) | |
| } | |
| } | |
| fmt.printf("vertex positions = %d, vertex normals = %d, vertex uvs = %d\n", len(vertex_positions), len(vertex_normals), len(vertex_uvs)) | |
| fmt.printf("indices positions = %d, indices normals = %d, indices uvs = %d\n", len(indices_positions), len(indices_normals), len(indices_uvs)) | |
| return Model_Data { | |
| vertex_positions, | |
| vertex_normals, | |
| vertex_uvs, | |
| indices_positions, | |
| indices_normals, | |
| indices_uvs } | |
| } | |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Based on :
https://gist.github.com/vassvik/f4c19c35ba72ad52eaa51d1091d379d8
Made up to date with current Odin version