add move sound to ui
[carveJwlIkooP6JGAAIwe30JlM.git] / player_ragdoll.h
index 7fff465d8766ebd61858bc33fd3061c564b6d61c..08ab5e75d9ff56ce37129ed4b7ed248d7c3d913e 100644 (file)
-#ifndef PLAYER_RAGDOLL_H
-#define PLAYER_RAGDOLL_H
-
-#include "player.h"
-
-static float k_ragdoll_floatyiness = 10.0f,
-             k_ragdoll_floatydrag  = 1.0f;
+#pragma once
 
 /*
- * Setup ragdoll colliders 
+ * Copyright (C) 2021-2024 Mt.ZERO Software - All Rights Reserved
+ *
+ * Ragdoll system
  */
-static void player_init_ragdoll( mdl_header *src )
-{
-   struct player_model *mdl = &player.mdl;
-
-   if( !mdl->sk.collider_count )
-   {
-      mdl->ragdoll_count = 0;
-      return;
-   }
 
-   mdl->ragdoll = vg_alloc(sizeof(struct ragdoll_part)*mdl->sk.collider_count);
-   mdl->ragdoll_count = 0;
+#include "player_api.h"
+#include "skeleton.h"
+#include "vg/vg_rigidbody.h"
+#include "vg/vg_rigidbody_constraints.h"
 
-   for( u32 i=0; i<mdl->sk.bone_count; i ++ )
-   {
-      struct skeleton_bone *bone = &mdl->sk.bones[i];
+struct player_ragdoll{
+   struct ragdoll_part{
+      u32 bone_id;
       
-      if( bone->collider )
-      {
-         struct ragdoll_part *rp = &mdl->ragdoll[ mdl->ragdoll_count ++ ];
-         rp->bone_id = i;
-         
-         v3f delta;
-         v3_sub( bone->hitbox[1], bone->hitbox[0], delta );
-         v3_muls( delta, 0.5f, delta );
-
-         v3_add( bone->hitbox[0], delta, rp->offset );
+      /* Collider transform relative to bone */
+      m4x3f collider_mtx,
+            inv_collider_mtx;
 
-         v3_copy( delta, rp->rb.bbx[1] );
-         v3_muls( delta, -1.0f, rp->rb.bbx[0] );
+      v4f prev_q;
+      v3f prev_co;
 
-         q_identity( rp->rb.q );
-         v3_add( bone->co, rp->offset, rp->rb.co );
-         rp->rb.type = k_rb_shape_box;
-         rp->rb.is_world = 0;
-         rp->parent = 0xffffffff;
+      u32 use_limits;
+      v3f limits[2];
 
-         if( bone->parent )
-         {
-            for( u32 j=0; j<mdl->ragdoll_count; j++ )
-            {
-               if( mdl->ragdoll[ j ].bone_id == bone->parent )
-               {
-                  rp->parent = j;
-                  break;
-               }
-            }
-         }
-         
-         /* TODO: refactor to use this style elswhere */
-         struct mdl_node *pnode = mdl_node_from_id( src, bone->orig_node );
-         struct classtype_bone *bone_inf = mdl_get_entdata( src, pnode );
+      u32 parent;
+      u32 colour;
 
-         rp->use_limits = bone_inf->use_limits;
-         v3_copy( bone_inf->angle_limits[0], rp->limits[0] );
-         v3_copy( bone_inf->angle_limits[1], rp->limits[1] );
+      rigidbody rb;
+      enum bone_collider type;
 
-         rb_init( &rp->rb );
+      union {
+         rb_capsule capsule;
+         boxf box;
       }
+      inf;
    }
-}
-
-/*
- * Make the player model copy the ragdoll
- */
-static void player_model_copy_ragdoll(void)
-{
-   struct player_model *mdl = &player.mdl;
-
-   for( int i=0; i<mdl->ragdoll_count; i++ )
-   {
-      struct ragdoll_part *part = &mdl->ragdoll[i];
-      m4x3f offset;
-      m3x3_identity(offset);
-      v3_negate( part->offset, offset[3] );
-      m4x3_mul( part->rb.to_world, offset, mdl->sk.final_mtx[part->bone_id] );
-   }
-
-   skeleton_apply_inverses( &mdl->sk );
-}
-
-/*
- * Make the ragdoll copy the player model
- */
-static void player_ragdoll_copy_model( v3f v )
-{
-   struct player_model *mdl = &player.mdl;
-
-   for( int i=0; i<mdl->ragdoll_count; i++ )
-   {
-      struct ragdoll_part *part = &mdl->ragdoll[i];
-
-      v3f pos, offset;
-      u32 bone = part->bone_id;
-      
-      m4x3_mulv( mdl->sk.final_mtx[bone], mdl->sk.bones[bone].co, pos );
-      m3x3_mulv( mdl->sk.final_mtx[bone], part->offset, offset );
-      v3_add( pos, offset, part->rb.co );
-      m3x3_q( mdl->sk.final_mtx[bone], part->rb.q );
-      v3_copy( v, part->rb.v );
-      v3_zero( part->rb.w );
-      
-      rb_update_transform( &part->rb );
-   }
-}
-
-/*
- * Draw rigidbody colliders for ragdoll
- */
-static void player_debug_ragdoll(void)
-{
-   struct player_model *mdl = &player.mdl;
-
-   for( u32 i=0; i<mdl->ragdoll_count; i ++ )
-      rb_debug( &mdl->ragdoll[i].rb, 0xff00ff00 );
-}
-
-/*
- * Ragdoll physics step
- */
-static void player_ragdoll_iter(void)
-{
-   struct player_model *mdl = &player.mdl;
-   rb_solver_reset();
-
-   for( int i=0; i<mdl->ragdoll_count; i ++ )
-      rb_collide( &mdl->ragdoll[i].rb, &world.rb_geo );
-
-   rb_presolve_contacts( rb_contact_buffer, rb_contact_count );
-
-   v3f rv;
-
-#if 0
-   float shoe_vel[2] = {0.0f,0.0f};
-   for( int i=0; i<2; i++ )
-      if( mdl->shoes[i] )
-         shoe_vel[i] = v3_length( mdl->ragdoll[i].rb.v );
-#endif
-   
-   for( int j=0; j<mdl->ragdoll_count; j++ )
-   {
-      struct ragdoll_part *pj = &mdl->ragdoll[j];
-      struct skeleton_bone *bj = &mdl->sk.bones[pj->bone_id];
-
-      if( pj->parent != 0xffffffff )
-      {
-         struct ragdoll_part *pp = &mdl->ragdoll[pj->parent];
-         struct skeleton_bone *bp = &mdl->sk.bones[pp->bone_id];
-
-         v3f lca, lcb;
-         v3_negate( pj->offset, lca );
-         v3_add( bp->co, pp->offset, lcb );
-         v3_sub( bj->co, lcb, lcb );
-
-         rb_debug_constraint_position( &pj->rb, lca, &pp->rb, lcb );
-
-         if( pj->use_limits )
-         {
-            rb_debug_constraint_limits( &pj->rb, &pp->rb, lca, pj->limits );
-         }
-      }
-
-      v4f plane = {0.0f,1.0f,0.0f,0.0f};
-      rb_effect_simple_bouyency( &pj->rb, plane, k_ragdoll_floatyiness,
-                                                 k_ragdoll_floatydrag );
-   }
-
-   /* CONSTRAINTS */
-   for( int i=0; i<10; i++ )
-   {
-      rb_solve_contacts( rb_contact_buffer, rb_contact_count );
-
-      for( int j=0; j<mdl->ragdoll_count; j++ )
-      {
-         struct ragdoll_part *pj = &mdl->ragdoll[j];
-         struct skeleton_bone *bj = &mdl->sk.bones[pj->bone_id];
-
-         if( (pj->parent != 0xffffffff) && pj->use_limits )
-         {
-            struct ragdoll_part *pp = &mdl->ragdoll[pj->parent];
-            struct skeleton_bone *bp = &mdl->sk.bones[pp->bone_id];
-
-            v3f lca, lcb;
-            v3_negate( pj->offset, lca );
-            v3_add( bp->co, pp->offset, lcb );
-            v3_sub( bj->co, lcb, lcb );
-
-            rb_constraint_position( &pj->rb, lca, &pp->rb, lcb );
-
-            rb_constraint_limits( &pj->rb, lca, &pp->rb, lcb, pj->limits );
-         }
-      }
-   }
-
-   /* INTEGRATION */
-   for( int i=0; i<mdl->ragdoll_count; i++ )
-      rb_iter( &mdl->ragdoll[i].rb );
-   
-   /* SHOES */
-   for( int i=0; i<mdl->ragdoll_count; i++ )
-      rb_update_transform( &mdl->ragdoll[i].rb );
-}
-
-#endif /* PLAYER_RAGDOLL_H */
+   parts[32];
+   u32 part_count;
+
+   rb_constr_pos  position_constraints[32];
+   u32            position_constraints_count;
+
+   rb_constr_swingtwist cone_constraints[32];
+   u32                  cone_constraints_count;
+
+   /* TODO: Fix duplicated data */
+   u32 constraint_associations[32][2];
+   int shoes[2];
+};
+
+enum player_die_type {
+   k_player_die_type_generic,
+   k_player_die_type_head,
+   k_player_die_type_feet
+};
+
+void player_ragdoll_init(void);
+void player_init_ragdoll_bone_collider( struct skeleton_bone *bone,
+                                           struct ragdoll_part *rp );
+u32 ragdoll_bone_parent( struct player_ragdoll *rd, u32 bone_id );
+void setup_ragdoll_from_skeleton( struct skeleton *sk,
+                                  struct player_ragdoll *rd );
+void copy_ragdoll_pose_to_localplayer( struct player_ragdoll *rd );
+void copy_localplayer_to_ragdoll( struct player_ragdoll *rd, 
+                                  enum player_die_type type );
+                                   
+void player_debug_ragdoll(void);
+void player_ragdoll_iter( struct player_ragdoll *rd );