X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=model.h;h=ae19f6f090d57848ff97fdb9d8f9df2533377a6e;hb=8d336ea2cde7c596296dbaf0d3ce27a82c6c6cf0;hp=430ed26d7425d684670bddeb0931a9b9b45039de;hpb=e36cb7e44611855d39ba84710a7007ca659e9cd5;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/model.h b/model.h index 430ed26..ae19f6f 100644 --- a/model.h +++ b/model.h @@ -1,227 +1,320 @@ -#ifndef MODEL_H -#define MODEL_H - -#include "vg/vg.h" - -typedef struct model model; -typedef struct glmesh glmesh; -typedef struct submodel submodel; -typedef struct model_vert model_vert; -typedef struct model_marker model_marker; -typedef struct sdf_primative sdf_primative; -typedef enum esdf_type esdf_type; - -#pragma pack(push,1) -struct model -{ - u32 identifier; +/* + * Copyright (C) 2021-2024 Mt.ZERO Software, Harry Godden - All Rights Reserved + */ - u32 vertex_count, - indice_count, - layer_count, - marker_count; +#pragma once + +#define MDL_VERSION_MIN 101 +#define MDL_VERSION_NR 105 + +enum mdl_shader{ + k_shader_standard = 0, + k_shader_standard_cutout = 1, + k_shader_terrain_blend = 2, + k_shader_standard_vertex_blend = 3, + k_shader_water = 4, + k_shader_invisible = 5, + k_shader_boundary = 6, + k_shader_fxglow = 7, + k_shader_cubemap = 8, + k_shader_walking = 9, + k_shader_foliage = 10, + k_shader_override = 30000 }; -struct submodel -{ - u32 indice_start, - indice_count, - vertex_start, - vertex_count; - - boxf bbx; - v3f pivot; /* same as co? */ - v4f q; - char name[32]; - char material[32]; +enum mdl_surface_prop{ + k_surface_prop_concrete = 0, + k_surface_prop_wood = 1, + k_surface_prop_grass = 2, + k_surface_prop_tiles = 3, + k_surface_prop_metal = 4, + k_surface_prop_snow = 5, + k_surface_prop_sand = 6 }; -struct classtype_gate -{ - u32 target; +enum material_flag{ + k_material_flag_skate_target = 0x0001, + k_material_flag_collision = 0x0002, + k_material_flag_grow_grass = 0x0004, + k_material_flag_grindable = 0x0008, + k_material_flag_invisible = 0x0010, + k_material_flag_boundary = 0x0020, + k_material_flag_preview_visibile = 0x0040, + k_material_flag_walking = 0x0080, + + k_material_flag_ghosts = + k_material_flag_boundary| + k_material_flag_invisible| + k_material_flag_walking }; -struct model_marker -{ - v3f co; - v4f q; - v3f s; - u32 classtype; - u32 offset; - char name[32]; -}; +#pragma pack(push,1) -struct model_vert +/* 48 byte */ +struct mdl_vert { - v3f co, - norm; - v4f colour; - v2f uv; + v3f co, /* 3*32 */ + norm; /* 3*32 */ + v2f uv; /* 2*32 */ + + u8 colour[4]; /* 4*8 */ + u16 weights[4];/* 4*16 */ + u8 groups[4]; /* 4*8 */ }; + #pragma pack(pop) +typedef u32 mdl_indice; + +typedef struct mdl_context mdl_context; +typedef struct mdl_array_ptr mdl_array_ptr; +typedef struct mdl_vert mdl_vert; +typedef struct mdl_transform mdl_transform; +typedef struct mdl_submesh mdl_submesh; +typedef struct mdl_material mdl_material; +typedef struct mdl_bone mdl_bone; +typedef struct mdl_armature mdl_armature; +typedef struct mdl_animation mdl_animation; +typedef struct mdl_transform mdl_keyframe; +typedef struct mdl_mesh mdl_mesh; +typedef struct mdl_file mdl_file; +typedef struct mdl_texture mdl_texture; +typedef struct mdl_array mdl_array; +typedef struct mdl_header mdl_header; + +typedef struct glmesh glmesh; struct glmesh { GLuint vao, vbo, ebo; u32 indice_count; + u32 loaded; }; -static void mesh_upload( glmesh *mesh, - model_vert *verts, u32 vert_count, - u32 *indices, u32 indice_count ) -{ - glGenVertexArrays( 1, &mesh->vao ); - glGenBuffers( 1, &mesh->vbo ); - glGenBuffers( 1, &mesh->ebo ); - glBindVertexArray( mesh->vao ); - - glBindBuffer( GL_ARRAY_BUFFER, mesh->vbo ); - glBufferData( GL_ARRAY_BUFFER, vert_count*sizeof(model_vert), - verts, GL_STATIC_DRAW ); - - glBindVertexArray( mesh->vao ); - glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, mesh->ebo ); - glBufferData( GL_ELEMENT_ARRAY_BUFFER, indice_count*sizeof(u32), - indices, GL_STATIC_DRAW ); - - glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, - sizeof(model_vert), (void*)0 ); - glEnableVertexAttribArray( 0 ); - - glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE, - sizeof(model_vert), (void *)offsetof(model_vert, norm) ); - glEnableVertexAttribArray( 1 ); - - glVertexAttribPointer( 2, 4, GL_FLOAT, GL_FALSE, - sizeof(model_vert), (void *)offsetof(model_vert, colour) ); - glEnableVertexAttribArray( 2 ); - - glVertexAttribPointer( 3, 2, GL_FLOAT, GL_FALSE, - sizeof(model_vert), (void *)offsetof(model_vert, uv) ); - glEnableVertexAttribArray( 3 ); - - VG_CHECK_GL(); - mesh->indice_count = indice_count; -} - -static void mesh_bind( glmesh *mesh ) +struct mdl_transform { - glBindVertexArray( mesh->vao ); -} + v3f co, s; + v4f q; +}; -static void mesh_drawn( u32 start, u32 count ) +static void transform_identity( mdl_transform *transform ) { - glDrawElements( GL_TRIANGLES, count, GL_UNSIGNED_INT, - (void *)(start*sizeof(u32)) ); + v3_zero( transform->co ); + q_identity( transform->q ); + v3_fill( transform->s, 1.0f ); } -static void mesh_draw( glmesh *mesh ) +static void mdl_transform_vector( mdl_transform *transform, v3f vec, v3f dest ) { - mesh_drawn( 0, mesh->indice_count ); + v3_mul( transform->s, vec, dest ); + q_mulv( transform->q, dest, dest ); } -/* - * Helper functions for file offsets - * TODO: Revise this - */ -static submodel *model_get_submodel( model *mdl, int id ) +static void mdl_transform_point( mdl_transform *transform, v3f co, v3f dest ) { - return ((submodel*)(mdl+1)) + id; + mdl_transform_vector( transform, co, dest ); + v3_add( transform->co, dest, dest ); } -static model_marker *model_get_marker( model *mdl, int id ) +static void mdl_transform_mul( mdl_transform *a, mdl_transform *b, + mdl_transform *d ) { - return ((model_marker*)model_get_submodel(mdl,mdl->layer_count)) + id; + mdl_transform_point( a, b->co, d->co ); + q_mul( a->q, b->q, d->q ); + q_normalize( d->q ); + v3_mul( a->s, b->s, d->s ); } -static model_vert *model_vertex_base( model *mdl ) +struct mdl_material { - return (model_vert *)model_get_marker( mdl, mdl->marker_count ); -} + u32 pstr_name, + shader, + flags, + surface_prop; + + v4f colour, + colour1; -static u32 *model_indice_base( model *mdl ) + u32 tex_diffuse, /* Indexes start from 1. 0 if missing. */ + tex_none0, + tex_none1; +}; + +struct mdl_bone { - return (u32 *)(model_vertex_base( mdl ) + mdl->vertex_count); -} + v3f co, end; + u32 parent, + collider, + ik_target, + ik_pole, + flags, + pstr_name; + + boxf hitbox; + v3f conevx, conevy, coneva; + float conet; +}; -static model_vert *submodel_vert_data( model *mdl, submodel *sub ) +enum bone_flag { - return model_vertex_base(mdl) + sub->vertex_start; -} + k_bone_flag_deform = 0x00000001, + k_bone_flag_ik = 0x00000002, + k_bone_flag_cone_constraint = 0x00000004 +}; -static u32 *submodel_indice_data( model *mdl, submodel *sub ) +enum bone_collider { - return model_indice_base(mdl) + sub->indice_start; -} + k_bone_collider_none = 0, + k_bone_collider_box = 1, + k_bone_collider_capsule = 2 +}; + +struct mdl_armature +{ + mdl_transform transform; + u32 bone_start, + bone_count, + anim_start, + anim_count; +}; -static void *get_entdata_raw( model *mdl, model_marker *marker ) +struct mdl_animation { - return ((void *)(model_indice_base(mdl) + mdl->indice_count)) + - marker->offset; -} + u32 pstr_name, + length; + float rate; + u32 offset; +}; -static submodel *submodel_get( model *mdl, const char *name ) +struct mdl_submesh { - for( int i=0; ilayer_count; i++ ) - { - submodel *pmdl =model_get_submodel(mdl,i); + u32 indice_start, + indice_count, + vertex_start, + vertex_count; - if( !strcmp( pmdl->name, name ) ) - return pmdl; - } - - return NULL; -} + boxf bbx; + u16 material_id, flags; +}; -static model_marker *model_marker_get( model *mdl, const char *name ) +enum esubmesh_flags { - for( int i=0; imarker_count; i++ ) - { - model_marker *mk = model_get_marker( mdl,i ); + k_submesh_flag_none = 0x0000, + k_submesh_flag_consumed = 0x0001 +}; - if( !strcmp( mk->name, name ) ) - return mk; - } - - return NULL; -} +struct mdl_mesh +{ + mdl_transform transform; + u32 submesh_start, + submesh_count, + pstr_name, + entity_id, /* upper 16 bits: type, lower 16 bits: index */ + armature_id; +}; -static void submodel_draw( submodel *sm ) +struct mdl_file { - mesh_drawn( sm->indice_start, sm->indice_count ); -} + u32 pstr_path, + pack_offset, + pack_size; +}; -static void model_unpack_submodel( model *model, glmesh *mesh, submodel *sm ) +struct mdl_texture { - mesh_upload( mesh, - model_vertex_base( model ) + sm->vertex_start, sm->vertex_count, - model_indice_base( model ) + sm->indice_start, sm->indice_count ); -} + mdl_file file; + u32 glname; +}; -static void model_unpack( model *model, glmesh *mesh ) +struct mdl_array { - u32 offset = model_get_submodel( model, 0 )->vertex_count; + u32 file_offset, + item_count, + item_size; - for( int i=1; ilayer_count; i++ ) - { - submodel *sm = model_get_submodel( model, i ); - u32 *indices = submodel_indice_data( model, sm ); + char name[16]; +}; - for( u32 j=0; jindice_count; j++ ) - indices[j] += offset; +struct mdl_header +{ + u32 version; + mdl_array index; +}; - offset += sm->vertex_count; +struct mdl_context{ + FILE *file; + mdl_header info; + + struct mdl_array_ptr + { + void *data; + u32 count, stride; } + index, + + /* metadata */ + strings, + meshs, + submeshs, + materials, + textures, + armatures, + bones, + animations, + + /* animation buffers */ + keyframes, + + /* mesh buffers */ + verts, + indices; + u32 pack_base_offset; + + /* runtime */ + glmesh mesh; +}; - mesh_upload( mesh, model_vertex_base( model ), model->vertex_count, - model_indice_base( model ), model->indice_count ); -} +void mesh_bind( glmesh *mesh ); +void mesh_drawn( u32 start, u32 count ); +void mesh_draw( glmesh *mesh ); +void mesh_free( glmesh *mesh ); -static void mesh_free( glmesh *mesh ) -{ - glDeleteVertexArrays( 1, &mesh->vao ); - glDeleteBuffers( 1, &mesh->ebo ); - glDeleteBuffers( 1, &mesh->vbo ); -} +/* file context management */ +void mdl_open( mdl_context *mdl, const char *path, void *lin_alloc ); +void mdl_close( mdl_context *mdl ); + +/* array loading */ +int _mdl_load_array( mdl_context *mdl, mdl_array_ptr *ptr, + const char *name, void *lin_alloc, u32 stride ); +#define MDL_LOAD_ARRAY( MDL, PTR, STRUCT, ALLOCATOR ) \ + _mdl_load_array( MDL, PTR, #STRUCT, ALLOCATOR, sizeof(STRUCT) ) + +/* array access */ +void *mdl_arritm( mdl_array_ptr *arr, u32 index ); +u32 mdl_arrcount( mdl_array_ptr *arr ); + +/* pack access */ +void mdl_fread_pack_file( mdl_context *mdl, mdl_file *info, void *dst ); + +/* standard array groups */ +int mdl_load_animation_block( mdl_context *mdl, void *lin_alloc ); +int mdl_load_metadata_block( mdl_context *mdl, void *lin_alloc ); +int mdl_load_mesh_block( mdl_context *mdl, void *lin_alloc ); + +/* load mesh */ +void mdl_async_load_glmesh( mdl_context *mdl, glmesh *mesh, u32 *fixup_table ); + +/* load textures and mesh */ +void mdl_async_full_load_std( mdl_context *mdl ); + +/* rendering */ +void mdl_draw_submesh( mdl_submesh *sm ); +mdl_mesh *mdl_find_mesh( mdl_context *mdl, const char *name ); + +/* pstrs */ +const char *mdl_pstr( mdl_context *mdl, u32 pstr ); +int mdl_pstreq( mdl_context *mdl, u32 pstr, const char *str, u32 djb2 ); +#define MDL_CONST_PSTREQ( MDL, Q, CONSTSTR )\ + mdl_pstreq( MDL, Q, CONSTSTR, vg_strdjb2( CONSTSTR ) ) + +void mdl_transform_m4x3( mdl_transform *transform, m4x3f mtx ); -#endif