custom walk filtering
[carveJwlIkooP6JGAAIwe30JlM.git] / model.h
diff --git a/model.h b/model.h
index 8f90d128ad0a9637edb7a2624eed66ee1c2cc35b..43245edacf38d65fcd8349f3102b1adb2c57377a 100644 (file)
--- a/model.h
+++ b/model.h
@@ -1,27 +1,28 @@
 /*
- * Copyright (C) 2021-2022 Mt.ZERO Software, Harry Godden - All Rights Reserved
+ * Copyright (C) 2021-2023 Mt.ZERO Software, Harry Godden - All Rights Reserved
  */
 
 #ifndef MODEL_H
 #define MODEL_H
 
-#include "common.h"
+#include "skaterift.h"
 
-#define MDL_VERSION_NR 100
+#define MDL_VERSION_MIN 101
+#define MDL_VERSION_NR 102
 
-enum mdl_shader
-{
+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_boundary                = 6,
+   k_shader_fxglow                  = 7,
+   k_shader_cubemap                 = 8
 };
 
-enum mdl_surface_prop
-{
+enum mdl_surface_prop{
    k_surface_prop_concrete          = 0,
    k_surface_prop_wood              = 1,
    k_surface_prop_grass             = 2,
@@ -29,14 +30,15 @@ enum mdl_surface_prop
    k_surface_prop_metal             = 4
 };
 
-enum material_flag
-{
+enum material_flag{
    k_material_flag_skate_target     = 0x00000001,
    k_material_flag_collision        = 0x00000002,
    k_material_flag_grow_grass       = 0x00000004,
    k_material_flag_grindable        = 0x00000008,
    k_material_flag_invisible        = 0x00000010,
-   k_material_flag_boundary         = 0x00000020
+   k_material_flag_boundary         = 0x00000020,
+   k_material_flag_preview_visibile = 0x00000040,
+   k_material_flag_walking          = 0x00000080
 };
 
 #pragma pack(push,1)
@@ -71,12 +73,48 @@ 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;
+};
+
 struct mdl_transform
 {
    v3f co, s;
    v4f q;
 };
 
+static void transform_identity( mdl_transform *transform )
+{
+   v3_zero( transform->co );
+   q_identity( transform->q );
+   v3_fill( transform->s, 1.0f );
+}
+
+static void mdl_transform_vector( mdl_transform *transform, v3f vec, v3f dest )
+{
+   v3_mul( transform->s, vec, dest );
+   q_mulv( transform->q, dest, dest );
+}
+
+static void mdl_transform_point( mdl_transform *transform, v3f co, v3f dest )
+{
+   mdl_transform_vector( transform, co, dest );
+   v3_add( transform->co, dest, dest );
+}
+
+static void mdl_transform_mul( mdl_transform *a, mdl_transform *b, 
+                               mdl_transform *d )
+{
+   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 );
+}
+
 struct mdl_material
 {
    u32 pstr_name,
@@ -193,13 +231,11 @@ struct mdl_header
    mdl_array index;
 };
 
-struct mdl_context
-{
+struct mdl_context{
    FILE *file;
    mdl_header info;
 
-   struct mdl_array_ptr
-   {
+   struct mdl_array_ptr{
       void *data;
       u32 count, stride;
    }
@@ -221,11 +257,10 @@ struct mdl_context
    /* mesh buffers */
    verts,
    indices;
-
    u32 pack_base_offset;
-   
-   /* pack data */
-   //pack;
+
+   /* runtime */
+   glmesh mesh;
 };
 
 
@@ -246,8 +281,7 @@ VG_STATIC u32 mdl_query_array_size( mdl_array *arr )
       u32 size = arr->item_size*arr->item_count;
       return vg_align8(size);
    }
-   else
-      return 0;
+   else return 0;
 }
 
 VG_STATIC const char *mdl_pstr( mdl_context *mdl, u32 pstr );
@@ -262,21 +296,18 @@ void mdl_fread_pack_file( mdl_context *mdl, mdl_file *info, void *dst )
    fseek( mdl->file, mdl->pack_base_offset+info->pack_offset, SEEK_SET );
    u64 l = fread( dst, info->pack_size, 1, mdl->file );
 
-   if( l != 1 )
-      mdl_load_fatal_corrupt( mdl );
+   if( l != 1 ) mdl_load_fatal_corrupt( mdl );
 }
 
 /* TODO: Rename these */
-VG_STATIC 
-void mdl_load_array_file_buffer( mdl_context *mdl, mdl_array *arr, 
-                                 void *buffer )
+VG_STATIC void mdl_load_array_file_buffer( mdl_context *mdl, mdl_array *arr, 
+                                           void *buffer )
 {
    if( arr->item_count ){
       fseek( mdl->file, arr->file_offset, SEEK_SET );
       u64 l = fread( buffer, arr->item_size*arr->item_count, 1, mdl->file );
 
-      if( l != 1 )
-         mdl_load_fatal_corrupt( mdl );
+      if( l != 1 ) mdl_load_fatal_corrupt( mdl );
    }
 }
 
@@ -383,10 +414,10 @@ VG_STATIC void mdl_open( mdl_context *mdl, const char *path, void *lin_alloc )
    if( l != 1 )
       mdl_load_fatal_corrupt( mdl );
 
-   if( mdl->info.version != MDL_VERSION_NR ){
+   if( mdl->info.version < MDL_VERSION_MIN ){
       vg_warn( "For model: %s\n", path );
-      vg_warn( "  version: %u (current: %u)\n", mdl->info.version
-               MDL_VERSION_NR );
+      vg_warn( "  version: %u (min: %u, current: %u)\n"
+               mdl->info.version, MDL_VERSION_MIN, MDL_VERSION_NR );
 
       vg_fatal_error( "Legacy model version incompatable" );
    }
@@ -420,22 +451,29 @@ VG_STATIC void mdl_transform_m4x3( mdl_transform *transform, m4x3f mtx )
 
 VG_STATIC const char *mdl_pstr( mdl_context *mdl, u32 pstr )
 {
-   return mdl_arritm( &mdl->strings, pstr );
+   return ((char *)mdl_arritm( &mdl->strings, pstr )) + 4;
 }
 
+
+VG_STATIC int 
+mdl_pstreq( mdl_context *mdl, u32 pstr, const char *str, u32 djb2 )
+{
+   u32 hash = *((u32 *)mdl_arritm( &mdl->strings, pstr ));
+   if( hash == djb2 ){
+      if( !strcmp( str, mdl_pstr( mdl, pstr ))) return 1;
+      else return 0;
+   }
+   else return 0;
+}
+
+#define MDL_CONST_PSTREQ( MDL, Q, CONSTSTR )\
+   mdl_pstreq( MDL, Q, CONSTSTR, vg_strdjb2( CONSTSTR ) )
+
 /*
  * Simple mesh interface for OpenGL
  * ----------------------------------------------------------------------------
  */
 
-typedef struct glmesh glmesh;
-struct glmesh
-{
-   GLuint vao, vbo, ebo;
-   u32 indice_count;
-   u32 loaded;
-};
-
 VG_STATIC void mesh_upload( glmesh *mesh,
                             mdl_vert *verts, u32 vert_count,
                             u32 *indices, u32 indice_count )
@@ -547,11 +585,11 @@ struct payload_glmesh_load{
 VG_STATIC void async_mdl_load_glmesh( void *payload, u32 size )
 {
    struct payload_glmesh_load *job = payload;
-
    mesh_upload( job->mesh, job->verts, job->vertex_count,
                            job->indices, job->indice_count );
 }
 
+/* TODO: Find out if this needs deprecating in favour of the new full loader */
 VG_STATIC void mdl_async_load_glmesh( mdl_context *mdl, glmesh *mesh )
 {
    mdl_array *arr_vertices = mdl_find_array( mdl, "mdl_vert" );
@@ -608,5 +646,21 @@ VG_STATIC void mdl_async_load_glmesh( mdl_context *mdl, glmesh *mesh )
       vg_fatal_error( "no vertex/indice data\n" );
    }
 }
+
+/* uploads the glmesh, and textures. everything is saved into the mdl_context */
+VG_STATIC void mdl_async_full_load_std( mdl_context *mdl ){
+   mdl_async_load_glmesh( mdl, &mdl->mesh );
+   
+   for( u32 i=0; i<mdl_arrcount( &mdl->textures ); i ++ ){
+      vg_linear_clear( vg_mem.scratch );
+      mdl_texture *tex = mdl_arritm( &mdl->textures, i );
+
+      void *data = vg_linear_alloc( vg_mem.scratch, tex->file.pack_size );
+      mdl_fread_pack_file( mdl, &tex->file, data );
+
+      vg_tex2d_load_qoi_async( data, tex->file.pack_size,
+                               VG_TEX2D_CLAMP|VG_TEX2D_NEAREST, &tex->glname );
+   }
+}
  
 #endif