diff options
| author | 2lag <96544487+2lag@users.noreply.github.com> | 2026-03-15 19:15:13 +0100 |
|---|---|---|
| committer | 2lag <96544487+2lag@users.noreply.github.com> | 2026-03-15 19:15:13 +0100 |
| commit | c205cb8ac24c0a34960c41879708e7c25c19a353 (patch) | |
| tree | e814f431c57e6119829628ce5ada27f75f5372eb | |
| parent | c2a4f7c2e6e4651dda6350a80a57e177f5ff2f55 (diff) | |
finishing parsing
| -rw-r--r-- | src/render/model.h | 198 |
1 files changed, 145 insertions, 53 deletions
diff --git a/src/render/model.h b/src/render/model.h index c2db042..0c61fdc 100644 --- a/src/render/model.h +++ b/src/render/model.h @@ -9,6 +9,140 @@ struct MODEL { }; +static inline char* skip_space( char* s ) { + while( *s == ' ' || *s == '\t' ) ++s; + return s; +} + +static inline VEC3 read_vec3( char* s ) { + VEC3 temp{}; + s = skip_space( s ); + temp.x = strtof( s, &s ); + s = skip_space( s ); + temp.y = strtof( s, &s ); + s = skip_space( s ); + temp.z = strtof( s, &s ); + return temp; +} + +namespace MTL { + enum LINE_TYPES : U16 { + comment = ( '#' | ( ' ' << 8 ) ), + newmtl = ( 'n' | ( 'e' << 8 ) ), + Ns = ( 'N' | ( 's' << 8 ) ), + Ka = ( 'K' | ( 'a' << 8 ) ), + Kd = ( 'K' | ( 'd' << 8 ) ), + Ks = ( 'K' | ( 's' << 8 ) ), + Ke = ( 'K' | ( 'e' << 8 ) ), + Ni = ( 'N' | ( 'i' << 8 ) ), + d = ( 'd' | ( ' ' << 8 ) ), + illum = ( 'i' | ( 'l' << 8 ) ) + }; + + struct MTLDATA { + STR name; + F32 Ns; + VEC3 Ka; + VEC3 Kd; + VEC3 Ks; + VEC3 Ke; + F32 Ni; + F32 d; + I32 illum; + }; + + struct MTLLIB { + STR name; + LIST<MTLDATA> data; + }; + + inline MTLLIB mtl_from_file( const char* path, const char* name ) { + U64 mtl_size = 0; + STR mtl_path( path ); + mtl_path += name; + char* f_mtl = (char*)file_read( mtl_path.data, &mtl_size ); + if( !f_mtl ) { + dlog( "mtl_from_file() : failed to read mtl file %s\n", mtl_path.data ); + return {}; + } + + MTLLIB mtl; + mtl.name = name; + for( U64 i = 0; i < mtl_size - 1 && f_mtl[i]; ++i ) { + if( f_mtl[i] == '\n' ) + continue; + + I32 c0 = f_mtl[i]; + U16 c1 = f_mtl[i + 1]; + I32 first_two = c0 | c1 << 8; + + switch( first_two ) { + case LINE_TYPES::newmtl: { + char* start = f_mtl + i + 7; + char* end = start; + while( *end && *end != '\n' ) ++end; + U32 len = end - start; + STR temp; + temp.reserve( len + 1 ); + memcpy( temp, start, len ); + temp.data[len] = 0; + mtl.data.resize( mtl.data.size + 1 ); + mtl.data[mtl.data.size - 1].name = temp.data; + } break; + case LINE_TYPES::d: + case LINE_TYPES::Ni: + case LINE_TYPES::Ns: { + char* s = f_mtl + i + 2; + s = skip_space( s ); + F32 temp = strtof( s, &s ); + switch( first_two ) { + case LINE_TYPES::d: + mtl.data[mtl.data.size - 1].d = temp; + break; + case LINE_TYPES::Ni: + mtl.data[mtl.data.size - 1].Ni = temp; + break; + case LINE_TYPES::Ns: + mtl.data[mtl.data.size - 1].Ns = temp; + break; + } + } break; + case LINE_TYPES::illum: { + char* s = f_mtl + i + 6; + mtl.data[mtl.data.size - 1].illum = (I32)strtol( s, &s, 10 ); + } break; + case LINE_TYPES::Ka: + case LINE_TYPES::Kd: + case LINE_TYPES::Ke: + case LINE_TYPES::Ks: { + char* s = f_mtl + i + 3; + switch( first_two ) { + case LINE_TYPES::Ka: + mtl.data[mtl.data.size - 1].Ka = read_vec3( s ); + break; + case LINE_TYPES::Kd: + mtl.data[mtl.data.size - 1].Kd = read_vec3( s ); + break; + case LINE_TYPES::Ke: + mtl.data[mtl.data.size - 1].Ke = read_vec3( s ); + break; + case LINE_TYPES::Ks: + mtl.data[mtl.data.size - 1].Ks = read_vec3( s ); + break; + } + } break; + case LINE_TYPES::comment: break; + default: dlog( "unhandled char combo %c%c\n", c0, c1 ); break; + } + + while( f_mtl[i] && f_mtl[i] != '\n' ) ++i; + } + + free( (void*)f_mtl ); + return mtl; + } +}; + namespace OBJ { enum LINE_TYPES : U16 { comment = ( '#' | ( ' ' << 8 ) ), @@ -41,31 +175,12 @@ namespace OBJ { constexpr U32 STR_LEN = 0x40; - static inline char* skip_space( char* s ) { - while( *s == ' ' || *s == '\t' ) ++s; - return s; - } - - static inline char* read_f32( char* s, F32* out ) { - *out = strtof( s, &s ); - return s; - } - - static inline char* read_u32( char* s, U32* out ) { - *out = strtoul( s, &s, 10 ); - return s; - } - - struct MTLDATA { - STR name; - }; - struct OBJDATA { LIST<VEC2> uvs; LIST<VEC3> normals; LIST<VEC3> vertices; - LIST<MTLDATA> mtllib; + LIST<MTL::MTLLIB> mtllib; struct UseMtl { LIST<U32> indices; @@ -91,7 +206,6 @@ namespace OBJ { dlog( "obj_from_file() : failed to read obj file %s\n", obj_path.data ); return {}; } - dlog( "___modelfile___\n%s\n", f_obj ); OBJDATA obj; for( U64 i = 0; i < obj_size - 1 && f_obj[i]; ++i ) { @@ -115,21 +229,21 @@ namespace OBJ { while( *s && *s != '\n' ) { bool has_vt = 0, has_vn = 0; - U32 v = 0, vt = 0, vn = 0; - s = read_u32( s, &v ); + U32 v = strtoul( s, &s, 10 ); obj.indices.data.push( --v ); if( *s == '/' ) { ++s; if( *s != '/' ) { - s = read_u32( s, &vt ); + U32 vt = strtoul( s, &s, 10 ); obj.indices.data.push( --vt ); has_vt = 1; } if( *s == '/' ) { - s = read_u32( ++s, &vn ); + ++s; + U32 vn = strtoul( s, &s, 10 ); obj.indices.data.push( --vn ); has_vn = 1; } @@ -161,25 +275,18 @@ namespace OBJ { bool is_v = first_two == LINE_TYPES::v; U32 start = i + ( is_v ? 2 : 3 ); char* s = f_obj + start; - VEC3 temp{}; - s = skip_space( s ); - s = read_f32( s, &temp.x ); - s = skip_space( s ); - s = read_f32( s, &temp.y ); - s = skip_space( s ); - s = read_f32( s, &temp.z ); if( is_v ) - obj.vertices.push( temp ); + obj.vertices.push( read_vec3( s ) ); else - obj.normals.push( temp ); + obj.normals.push( read_vec3( s ) ); } break; case LINE_TYPES::vt: { char* s = f_obj + i + 3; VEC2 temp{}; s = skip_space( s ); - s = read_f32( s, &temp.x ); + temp.x = strtof( s, &s ); s = skip_space( s ); - s = read_f32( s, &temp.y ); + temp.y = strtof( s, &s ); obj.uvs.push( temp ); } break; case LINE_TYPES::mtllib: @@ -196,23 +303,8 @@ namespace OBJ { if( !is_mtllib ) { obj.usemtl.data.push( temp ); obj.usemtl.indices.push( obj.indices.data.size ); - } - else { - U64 mtl_size = 0; - STR mtl_path( path ); - mtl_path += temp.data; - char* f_mtl = (char*)file_read( mtl_path.data, &mtl_size ); - if( !f_mtl ) { - dlog( "obj_from_file() : failed to read mtl file %s\n", mtl_path.data ); - return {}; - } - dlog( "___mtlfile___\n%s\n", f_mtl ); - - // TODO: finish mtl parsing here into obj.mtllib - - obj.mtllib.push({ temp }); - free( (void*)f_mtl ); - } + } else + obj.mtllib.push( MTL::mtl_from_file( path, temp.data ) ); } break; case LINE_TYPES::comment: case LINE_TYPES::o: |
