code wiki / (root) / nx_objload.nx

nx_objload.nx source

↩ module page · 119 lines · 4959 B

1// nx_objload.nx -- ★sovereign Wavefront OBJ loader (the Stanford-corpus rung of the field-evidence foundation): parse 2// `v x y z` + `f a b c` ASCII into nx_trimesh, bbox-normalized to a target extent. Signed 6-decimal coords are read in 3// MICRO units (x1e6) so the bunny's 0.15-metre scale survives integer parsing. Two passes (bbox, emit). license_tier: ORIGINAL 4import "nx_syscalls.nx" 5import "nx_trimesh.nx" 6const K_MAGIC_1000000: i64 = 1000000 7const K_MAGIC_100000: i64 = 100000 8const K_MAGIC_2000000000: i64 = 2000000000 9const K_MAGIC_1024: i64 = 1024 10 11// parse a signed decimal at p (skips leading spaces) -> micro (x1e6). out[0]=value, returns new position. 12func obj_num(buf: *u8, end: i64, p0: i64, out: *i64) -> i64 { 13 var p: i64 = p0 14 var sk: i64 = 1 15 while sk == 1 { if p < end { if (buf[p] as i64) == 32 { p = p + 1 } else { sk = 0 } } else { sk = 0 } } 16 var neg: i64 = 0 17 if p < end { if (buf[p] as i64) == 45 { neg = 1; p = p + 1 } } 18 var ip: i64 = 0 19 var go: i64 = 1 20 while go == 1 { 21 if p < end { 22 let c: i64 = buf[p] as i64 23 var isd: i64 = 0 24 if c >= 48 { if c <= 57 { isd = 1 } } 25 if isd == 1 { ip = ip*10 + (c-48); p = p + 1 } else { go = 0 } 26 } else { go = 0 } 27 } 28 var micro: i64 = ip * K_MAGIC_1000000 29 if p < end { if (buf[p] as i64) == 46 { 30 p = p + 1 31 var fd: i64 = 0 32 var mul: i64 = K_MAGIC_100000 33 go = 1 34 while go == 1 { 35 if p < end { 36 let c: i64 = buf[p] as i64 37 var isd: i64 = 0 38 if c >= 48 { if c <= 57 { isd = 1 } } 39 if isd == 1 { 40 if fd < 6 { micro = micro + (c-48)*mul; mul = mul/10; fd = fd + 1 } 41 p = p + 1 42 } else { go = 0 } 43 } else { go = 0 } 44 } 45 } } 46 if neg == 1 { micro = 0 - micro } 47 out[0] = micro 48 return p 49} 50// is position p the start of a line whose first two bytes are ch,' '? 51func obj_linestart(buf: *u8, p: i64, ch: i64) -> i64 { 52 var atstart: i64 = 0 53 if p == 0 { atstart = 1 } 54 if p > 0 { if (buf[p-1] as i64) == 10 { atstart = 1 } } 55 if atstart == 0 { return 0 } 56 if (buf[p] as i64) != ch { return 0 } 57 if (buf[p+1] as i64) != 32 { return 0 } 58 return 1 59} 60// ★load an OBJ into trimesh, normalized to `target` extent about the origin. col = base vertex colour. 1 ok. 61func obj_load(path: *u8, target: i64, col: i64) -> i64 { 62 let szp: *i64 = sys_mmap(16) as *i64 63 let buf: *u8 = sys_read_file(path, szp) 64 let size: i64 = szp[0] 65 if (buf as i64) == 0 { return 0 } 66 if size < 32 { return 0 } 67 let num: *i64 = sys_mmap(8) as *i64 68 // ---- pass 1: bbox over v lines ---- 69 var minx: i64 = K_MAGIC_2000000000; var miny: i64 = K_MAGIC_2000000000; var minz: i64 = K_MAGIC_2000000000 70 var maxx: i64 = 0-K_MAGIC_2000000000; var maxy: i64 = 0-K_MAGIC_2000000000; var maxz: i64 = 0-K_MAGIC_2000000000 71 var p: i64 = 0 72 while p < size { 73 if obj_linestart(buf, p, 118) == 1 { // 'v ' 74 var q: i64 = p + 2 75 q = obj_num(buf, size, q, num); let x: i64 = num[0] 76 q = obj_num(buf, size, q, num); let y: i64 = num[0] 77 q = obj_num(buf, size, q, num); let z: i64 = num[0] 78 if x<minx {minx=x} if x>maxx {maxx=x} 79 if y<miny {miny=y} if y>maxy {maxy=y} 80 if z<minz {minz=z} if z>maxz {maxz=z} 81 p = q 82 } else { p = p + 1 } 83 } 84 var ext: i64 = maxx-minx 85 if maxy-miny > ext { ext = maxy-miny } 86 if maxz-minz > ext { ext = maxz-minz } 87 if ext < 1 { return 0 } 88 let s1024: i64 = target*K_MAGIC_1024/ext 89 if s1024 < 1 { return 0 } 90 let cx: i64 = (minx+maxx)/2; let cy: i64 = (miny+maxy)/2; let cz: i64 = (minz+maxz)/2 91 // ---- pass 2: emit ---- 92 tm_reset() 93 p = 0 94 while p < size { 95 var handled: i64 = 0 96 if obj_linestart(buf, p, 118) == 1 { // 'v ' 97 var q: i64 = p + 2 98 q = obj_num(buf, size, q, num); let x: i64 = (num[0]-cx)*s1024/K_MAGIC_1024 99 q = obj_num(buf, size, q, num); let y: i64 = (num[0]-cy)*s1024/K_MAGIC_1024 100 q = obj_num(buf, size, q, num); let z: i64 = (num[0]-cz)*s1024/K_MAGIC_1024 101 let idx: i64 = tm_vert(x, y, z) 102 tm_vcol(idx, col) 103 p = q 104 handled = 1 105 } 106 if handled == 0 { if obj_linestart(buf, p, 102) == 1 { // 'f ' 107 var q: i64 = p + 2 108 q = obj_num(buf, size, q, num); let a: i64 = num[0]/K_MAGIC_1000000 109 q = obj_num(buf, size, q, num); let b: i64 = num[0]/K_MAGIC_1000000 110 q = obj_num(buf, size, q, num); let c: i64 = num[0]/K_MAGIC_1000000 111 tm_tri(a-1, b-1, c-1, col) // OBJ is 1-indexed 112 p = q 113 handled = 1 114 } } 115 if handled == 0 { p = p + 1 } 116 } 117 tm_compute_normals() 118 return 1 119}