custom walk filtering
authorhgn <hgodden00@gmail.com>
Sun, 6 Aug 2023 20:16:05 +0000 (21:16 +0100)
committerhgn <hgodden00@gmail.com>
Sun, 6 Aug 2023 20:16:05 +0000 (21:16 +0100)
blender_export.py
maps_src/mp_spawn/main.mdl
model.h
player_walk.c

index 8d202983d765851a3f14164de6ddefe3bd6656ab..70bb5ef494d9db15433bd6159e945fde98a4bdb5 100644 (file)
@@ -794,6 +794,7 @@ def sr_compile_material( mat ):#{
       #}
       if mat.SR_data.shader == 'invisible': flags |= 0x10
       if mat.SR_data.shader == 'boundary': flags |= (0x10|0x20)
+      if mat.SR_data.shader == 'walking': flags |= (0x10|0x80)
    #}
 
    m.flags = flags
@@ -856,6 +857,10 @@ def sr_compile_material( mat ):#{
       m.colour[2]  = pow( mat.SR_data.tint[2], 1.0/2.2 )
       m.colour[3]  = pow( mat.SR_data.tint[3], 1.0/2.2 )
    #}
+
+   if mat.SR_data.shader == 'walking':#{
+      m.shader = 9
+   #}
    
    if mat.SR_data.shader in ['standard', 'standard_cutout', 'terrain_blend', \
                              'vertex_blend', 'fxglow', 'cubemap' ]: #{
@@ -2419,7 +2424,8 @@ class SR_MATERIAL_PANEL(bpy.types.Panel):
          row = box.row()
 
          if (active_mat.SR_data.shader != 'invisible') and \
-            (active_mat.SR_data.shader != 'boundary'):#{
+            (active_mat.SR_data.shader != 'boundary') and \
+            (active_mat.SR_data.shader != 'walking'):#{
             row.prop( active_mat.SR_data, "skate_surface" )
             row.prop( active_mat.SR_data, "grind_surface" )
             row.prop( active_mat.SR_data, "grow_grass" )
@@ -3360,7 +3366,8 @@ class SR_MATERIAL_PROPERTIES(bpy.types.PropertyGroup):
       ('invisible','Invisible',''),
       ('boundary','Boundary',''),
       ('fxglow','FX Glow',''),
-      ('cubemap','Cubemap','')
+      ('cubemap','Cubemap',''),
+      ('walking','Walking','')
       ])
 
    surface_prop: bpy.props.EnumProperty(
index 5adf5d29079a334679ed48a08df675e119ca9df9..fcd2e0ac4af4797c8e40807158d3cb7caf410968 100644 (file)
Binary files a/maps_src/mp_spawn/main.mdl and b/maps_src/mp_spawn/main.mdl differ
diff --git a/model.h b/model.h
index 00d7cae1f1d94e5ee6eb85312cd3989584a1f9c5..43245edacf38d65fcd8349f3102b1adb2c57377a 100644 (file)
--- a/model.h
+++ b/model.h
@@ -37,7 +37,8 @@ enum material_flag{
    k_material_flag_grindable        = 0x00000008,
    k_material_flag_invisible        = 0x00000010,
    k_material_flag_boundary         = 0x00000020,
-   k_material_flag_preview_visibile = 0x00000040
+   k_material_flag_preview_visibile = 0x00000040,
+   k_material_flag_walking          = 0x00000080
 };
 
 #pragma pack(push,1)
index 87c2246fe6960a662852f3210d95abfc8e1c062d..3cefc295068cf8ff5b4cd666663ee2e4b7ad5ba4 100644 (file)
@@ -370,6 +370,43 @@ VG_STATIC void player_friction( v3f v ){
    v3_muls( v, newspeed, v );
 }
 
+VG_STATIC void player_walk_custom_filter( world_instance *world,
+                                          rb_ct *man, int len, f32 w ){
+   for( int i=0; i<len; i++ ){
+      rb_ct *ci = &man[i];
+      if( ci->type == k_contact_type_disabled ||
+          ci->type == k_contact_type_edge ) 
+         continue;
+
+
+      float d1 = v3_dot( ci->co, ci->n );
+
+      for( int j=0; j<len; j++ ){
+         if( j == i )
+            continue;
+
+         rb_ct *cj = &man[j];
+         if( cj->type == k_contact_type_disabled ) 
+            continue;
+
+         struct world_surface *si = world_contact_surface( world, ci ),
+                              *sj = world_contact_surface( world, cj );
+
+         if(  (sj->info.flags & k_material_flag_walking) &&
+             !(si->info.flags & k_material_flag_walking)){
+            continue;
+         }
+         
+         float d2 = v3_dot( cj->co, ci->n ),
+               d  = d2-d1;
+
+         if( fabsf( d ) <= w ){
+            cj->type = k_contact_type_disabled;
+         }
+      }
+   }
+}
+
 VG_STATIC void player__walk_update( player_instance *player ){
    struct player_walk *w = &player->_walk;
    v3_copy( player->rb.co, w->state.prev_pos );
@@ -421,7 +458,7 @@ VG_STATIC void player__walk_update( player_instance *player ){
 
    len = rb_capsule__scene( mtx, &w->collider, NULL, 
                             &world->rb_geo.inf.scene, manifold );
-   rb_manifold_filter_coplanar( manifold, len, 0.01f );
+   player_walk_custom_filter( world, manifold, len, 0.01f );
    len = rb_manifold_apply_filtered( manifold, len );
 
    v3f surface_avg = { 0.0f, 0.0f, 0.0f };