X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=model.c;h=19f45f2d0466c8d3c55e1aca8160595b6e242431;hb=refs%2Fheads%2Fmenu2;hp=a04f5d5152cb2a2e922214a7e1c7aafaaac49082;hpb=ad9ece78cdcf550c34d28af276567d7d18b67668;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/model.c b/model.c index a04f5d5..19f45f2 100644 --- a/model.c +++ b/model.c @@ -4,13 +4,19 @@ #pragma once -#include "model.h" #include "vg/vg_io.h" + +#ifndef C0_STOPGAP #include "vg/vg_async.h" #include "vg/vg_tex.h" +#endif +#include "vg/vg_msg.h" +#include "vg/vg_string.h" #include #include #include +#include "model.h" +#include "shader_props.h" static void mdl_load_fatal_corrupt( mdl_context *mdl ) { @@ -54,12 +60,18 @@ static void mdl_load_array_file_buffer( mdl_context *mdl, mdl_array *arr, { vg_warn( "Applying alignment fixup to array @%p [%u -> %u] x %u\n", buffer, arr->item_size, stride, arr->item_count ); - if( stride < arr->item_size ) - vg_fatal_error( "not safe\n" ); + + if( stride > arr->item_size ) + memset( buffer, 0, stride*arr->item_count ); + + u32 read_size = VG_MIN( stride, arr->item_size ); for( u32 i=0; iitem_count; i++ ) { - u64 l = fread( buffer+i*stride, arr->item_size, 1, mdl->file ); + u64 l = fread( buffer+i*stride, read_size, 1, mdl->file ); + if( stride < arr->item_size ) + fseek( mdl->file, arr->item_size-stride, SEEK_CUR ); + if( l != 1 ) mdl_load_fatal_corrupt( mdl ); } } @@ -69,16 +81,11 @@ static void mdl_load_array_file_buffer( mdl_context *mdl, mdl_array *arr, static void mdl_load_array_file( mdl_context *mdl, mdl_array_ptr *ptr, mdl_array *arr, void *lin_alloc, u32 stride ) { - if( stride < arr->item_size ) - { - vg_error( "Structure max: %u. Got: %u\n", stride, arr->item_size ); - vg_fatal_error( "not safe\n" ); - } - if( arr->item_count ) { u32 size = stride*arr->item_count; - ptr->data = vg_linear_alloc( lin_alloc, vg_align8(size) ); + ptr->data = lin_alloc? vg_linear_alloc( lin_alloc, vg_align8(size) ): + malloc( size ); mdl_load_array_file_buffer( mdl, arr, ptr->data, stride ); } else @@ -149,12 +156,13 @@ int mdl_load_metadata_block( mdl_context *mdl, void *lin_alloc ) success &= _mdl_load_array( mdl, &mdl->strings, "strings", lin_alloc, 1 ); success &= MDL_LOAD_ARRAY( mdl, &mdl->meshs, mdl_mesh, lin_alloc ); success &= MDL_LOAD_ARRAY( mdl, &mdl->submeshs, mdl_submesh, lin_alloc ); - success &= MDL_LOAD_ARRAY( mdl, &mdl->materials, mdl_material, lin_alloc ); success &= MDL_LOAD_ARRAY( mdl, &mdl->textures, mdl_texture, lin_alloc ); success &= MDL_LOAD_ARRAY( mdl, &mdl->armatures, mdl_armature, lin_alloc ); success &= MDL_LOAD_ARRAY( mdl, &mdl->bones, mdl_bone, lin_alloc ); success &= MDL_LOAD_ARRAY( mdl, &mdl->animations,mdl_animation,lin_alloc ); + success &= mdl_load_materials( mdl, lin_alloc ); + return success; } @@ -163,6 +171,175 @@ int mdl_load_animation_block( mdl_context *mdl, void *lin_alloc ) return MDL_LOAD_ARRAY( mdl, &mdl->keyframes, mdl_keyframe, lin_alloc ); } +void *mdl_shader_standard( vg_msg *msg, void *alloc ) +{ + struct shader_props_standard *props = + vg_linear_alloc( alloc, sizeof(struct shader_props_standard) ); + + vg_msg_getkvintg( msg, "tex_diffuse", k_vg_msg_u32, &props->tex_diffuse, + NULL ); + + return props; +} + +void *mdl_shader_terrain( vg_msg *msg, void *alloc ) +{ + struct shader_props_terrain *props = + vg_linear_alloc( alloc, sizeof(struct shader_props_terrain) ); + + vg_msg_getkvintg( msg, "tex_diffuse", k_vg_msg_u32, &props->tex_diffuse, + NULL ); + vg_msg_getkvvecf( msg, "sand_colour", k_vg_msg_v4f, + props->sand_colour, (v4f){ 0.79, 0.63, 0.48, 1.0 } ); + vg_msg_getkvvecf( msg, "blend_offset", k_vg_msg_v2f, + props->blend_offset, (v2f){ 0.5, 0.0 } ); + + return props; +} + +void *mdl_shader_vertex_blend( vg_msg *msg, void *alloc ) +{ + struct shader_props_vertex_blend *props = + vg_linear_alloc( alloc, sizeof(struct shader_props_vertex_blend) ); + + vg_msg_getkvintg( msg, "tex_diffuse", k_vg_msg_u32, &props->tex_diffuse, + NULL ); + vg_msg_getkvvecf( msg, "blend_offset", k_vg_msg_v2f, + props->blend_offset, (v2f){ 0.5, 0.0 } ); + return props; +} + +void *mdl_shader_water( vg_msg *msg, void *alloc ) +{ + struct shader_props_water *props = + vg_linear_alloc( alloc, sizeof(struct shader_props_water) ); + + vg_msg_getkvvecf( msg, "shore_colour", k_vg_msg_v4f, + props->shore_colour, (v4f){0.03,0.32,0.61,1.0} ); + vg_msg_getkvvecf( msg, "deep_colour", k_vg_msg_v4f, + props->deep_colour, (v4f){0.0,0.006,0.03,1.0} ); + vg_msg_getkvintg( msg, "fog_scale", k_vg_msg_f32, &props->fog_scale, + (f32[]){0.04} ); + vg_msg_getkvintg( msg, "fresnel", k_vg_msg_f32, &props->fresnel, + (f32[]){5.0} ); + vg_msg_getkvintg( msg, "water_scale", k_vg_msg_f32, &props->water_sale, + (f32[]){ 0.008 } ); + vg_msg_getkvvecf( msg, "wave_speed", k_vg_msg_v4f, + props->wave_speed, (v4f){0.008,0.006,0.003,0.03} ); + return props; +} + +void *mdl_shader_cubemapped( vg_msg *msg, void *alloc ) +{ + struct shader_props_cubemapped *props = + vg_linear_alloc( alloc, sizeof(struct shader_props_cubemapped) ); + + vg_msg_getkvintg( msg, "tex_diffuse", k_vg_msg_u32, &props->tex_diffuse, + NULL ); + vg_msg_getkvintg( msg, "cubemap_entity", k_vg_msg_u32, + &props->cubemap_entity, NULL ); + vg_msg_getkvvecf( msg, "tint", k_vg_msg_v4f, + props->tint, (v4f){1.0,1.0,1.0,1.0} ); + return props; +} + +bool _mdl_legacy_v105_properties( struct mdl_material_v105 *mat, vg_msg *dst ) +{ + vg_msg_wkvnum( dst, "tex_diffuse", k_vg_msg_u32, 1, &mat->tex_diffuse ); + + if( mat->shader == k_shader_cubemap ) + { + vg_msg_wkvnum( dst, "cubemap", k_vg_msg_u32, 1, &mat->tex_none0 ); + vg_msg_wkvnum( dst, "tint", k_vg_msg_f32, 4, mat->colour ); + } + else if( mat->shader == k_shader_terrain_blend ) + { + vg_msg_wkvnum( dst, "sand_colour", k_vg_msg_f32, 4, mat->colour ); + vg_msg_wkvnum( dst, "blend_offset", k_vg_msg_f32, 2, mat->colour1 ); + } + else if( mat->shader == k_shader_standard_vertex_blend ) + { + vg_msg_wkvnum( dst, "blend_offset", k_vg_msg_f32, 2, mat->colour1 ); + } + else if( mat->shader == k_shader_water ) + { + vg_msg_wkvnum( dst, "shore_colour", k_vg_msg_f32, 4, mat->colour ); + vg_msg_wkvnum( dst, "deep_colour", k_vg_msg_f32, 4, mat->colour1 ); + } + + return 1; +} + +int mdl_load_materials( mdl_context *mdl, void *lin_alloc ) +{ + MDL_LOAD_ARRAY( mdl, &mdl->materials, mdl_material, lin_alloc ); + +#if (MDL_VERSION_MIN <= 105) + /* load legacy material data into scratch */ + mdl_array_ptr legacy_materials; + if( mdl->info.version <= 105 ) + { + _mdl_load_array( mdl, &legacy_materials, "mdl_material", vg_mem.scratch, + sizeof(struct mdl_material_v105) ); + } +#endif + + mdl_array_ptr data; + _mdl_load_array( mdl, &data, "shader_data", vg_mem.scratch, 1 ); + + if( !lin_alloc ) + return 1; + + for( u32 i=0; imaterials); i ++ ) + { + mdl_material *mat = mdl_arritm( &mdl->materials, i ); + vg_msg msg; + +#if (MDL_VERSION_MIN <= 105) + u8 legacy_buf[512]; + if( mdl->info.version <= 105 ) + { + vg_msg_init( &msg, legacy_buf, sizeof(legacy_buf) ); + _mdl_legacy_v105_properties( mdl_arritm( &legacy_materials,i ), &msg ); + vg_msg_init( &msg, legacy_buf, msg.cur.co ); + } + else +#endif + { + vg_msg_init( &msg, data.data + mat->props.kvs.offset, + mat->props.kvs.size ); + } + + if( mat->shader == k_shader_standard || + mat->shader == k_shader_standard_cutout || + mat->shader == k_shader_foliage || + mat->shader == k_shader_fxglow ) + { + mat->props.compiled = mdl_shader_standard( &msg, lin_alloc ); + } + else if( mat->shader == k_shader_standard_vertex_blend ) + { + mat->props.compiled = mdl_shader_vertex_blend( &msg, lin_alloc ); + } + else if( mat->shader == k_shader_cubemap ) + { + mat->props.compiled = mdl_shader_cubemapped( &msg, lin_alloc ); + } + else if( mat->shader == k_shader_terrain_blend ) + { + mat->props.compiled = mdl_shader_terrain( &msg, lin_alloc ); + } + else if( mat->shader == k_shader_water ) + { + mat->props.compiled = mdl_shader_water( &msg, lin_alloc ); + } + else + mat->props.compiled = NULL; + } + + return 1; +} + /* * if calling mdl_open, and the file does not exist, the game will fatal quit */ @@ -239,6 +416,7 @@ int mdl_pstreq( mdl_context *mdl, u32 pstr, const char *str, u32 djb2 ) * ---------------------------------------------------------------------------- */ +#ifndef C0_STOPGAP static void mesh_upload( glmesh *mesh, mdl_vert *verts, u32 vert_count, u32 *indices, u32 indice_count ) @@ -324,6 +502,7 @@ void mdl_draw_submesh( mdl_submesh *sm ) { mesh_drawn( sm->indice_start, sm->indice_count ); } +#endif mdl_mesh *mdl_find_mesh( mdl_context *mdl, const char *name ) { @@ -338,6 +517,17 @@ mdl_mesh *mdl_find_mesh( mdl_context *mdl, const char *name ) return NULL; } +mdl_submesh *mdl_find_submesh( mdl_context *mdl, const char *mesh_name ) +{ + mdl_mesh *mesh = mdl_find_mesh( mdl, mesh_name ); + + if( !mesh ) return NULL; + if( !mesh->submesh_count ) return NULL; + + return mdl_arritm( &mdl->submeshs, mesh->submesh_start ); +} + +#ifndef C0_STOPGAP struct payload_glmesh_load { mdl_vert *verts; @@ -449,3 +639,4 @@ void mdl_async_full_load_std( mdl_context *mdl ) VG_TEX2D_CLAMP|VG_TEX2D_NEAREST, &tex->glname ); } } +#endif