X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=character.h;fp=character.h;h=f5a9d676ab710686aa7cefcc9807607d1bbf2eb1;hb=d2fa06a21b490b38352195005c3134683679f9c0;hp=70c1727a8c68308002c34ad7cb9b57edfd47846d;hpb=7bf2284094c18d0e7de1c8823264bdfa36bc7f2e;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/character.h b/character.h index 70c1727..f5a9d67 100644 --- a/character.h +++ b/character.h @@ -3,7 +3,9 @@ #include "vg/vg.h" #include "model.h" +#include "scene.h" #include "ik.h" +#include "rigidbody.h" SHADER_DEFINE( shader_player, @@ -87,7 +89,6 @@ static const char *character_part_strings[] = FOREACH_PART( MAKE_STRING ) }; - struct character { glmesh mesh; @@ -97,6 +98,7 @@ struct character /* Auxillary information */ v3f offsets[ PART_COUNT ]; + rigidbody ragdoll[ PART_COUNT ]; /* * Controls @@ -564,4 +566,284 @@ static void character_shader_register(void) SHADER_INIT(shader_player); } + +/* + * Ragdoll Stuff + */ + +static void character_rd_box( struct character *ch, enum character_part id, + v3f dims ) +{ + v3_muls( dims, -0.5f, ch->ragdoll[id].bbx[0] ); + v3_muls( dims, 0.5f, ch->ragdoll[id].bbx[1] ); +} + +struct rd_joint +{ + enum character_part ia, ib; + v3f lca, lcb; + + struct rd_joint_axis + { + v3f va, vb; + float spring, ang; + } + min, maj; +}; + +static const float k_human_major = 0.9f, + k_human_minor = 0.9f, + k_human_major_max = 1.4f, + k_human_minor_max = 0.4f; + +#define HUMAN_VERTICAL_DEFAULT \ +.min = { \ + .va = {1.0f,0.0f,0.0f}, .vb = {1.0f,0.0f,0.0f}, \ + .spring = k_human_minor, .ang = k_human_minor_max \ +}, \ +.maj = { \ + .va = {0.0f,1.0f,0.0f}, .vb = {0.0f,1.0f,0.0f}, \ + .spring = k_human_major, .ang = k_human_major_max \ +} + +#define HUMAN_ARM_LEFT \ +.min = { \ + .va = {1.0f,0.0f,0.0f}, .vb = {1.0f,0.0f,0.0f}, \ + .spring = k_human_minor, .ang = k_human_minor_max \ +}, \ +.maj = { \ + .va = {0.0f,0.0f,1.0f}, .vb = {0.0f,0.0f,1.0f}, \ + .spring = k_human_major, .ang = k_human_major_max \ +} + +#define HUMAN_ARM_RIGHT \ +.min = { \ + .va = {1.0f,0.0f,0.0f}, .vb = {1.0f,0.0f,0.0f}, \ + .spring = k_human_minor, .ang = k_human_minor_max \ +}, \ +.maj = { \ + .va = {0.0f,0.0f,-1.0f}, .vb = {0.0f,0.0f,-1.0f}, \ + .spring = k_human_major, .ang = k_human_major_max \ +} + +static struct rd_joint rd_joints[] = +{ + { .ia = k_chpart_body0, .ib = k_chpart_body1, HUMAN_VERTICAL_DEFAULT }, + { .ia = k_chpart_body1, .ib = k_chpart_neck, HUMAN_VERTICAL_DEFAULT }, + { .ia = k_chpart_neck, .ib = k_chpart_head, HUMAN_VERTICAL_DEFAULT }, + { .ia = k_chpart_body0, .ib = k_chpart_leg_l0, HUMAN_VERTICAL_DEFAULT }, + { .ia = k_chpart_leg_l0, .ib = k_chpart_leg_l1, HUMAN_VERTICAL_DEFAULT }, + { .ia = k_chpart_body0, .ib = k_chpart_leg_r0, HUMAN_VERTICAL_DEFAULT }, + { .ia = k_chpart_leg_r0, .ib = k_chpart_leg_r1, HUMAN_VERTICAL_DEFAULT }, + + { .ia = k_chpart_body1, .ib = k_chpart_arm_l0, HUMAN_ARM_LEFT }, + { .ia = k_chpart_arm_l0, .ib = k_chpart_arm_l1, HUMAN_ARM_LEFT }, + { .ia = k_chpart_arm_l1, .ib = k_chpart_hand_l, HUMAN_ARM_LEFT }, + + { .ia = k_chpart_body1, .ib = k_chpart_arm_r0, HUMAN_ARM_RIGHT }, + { .ia = k_chpart_arm_r0, .ib = k_chpart_arm_r1, HUMAN_ARM_RIGHT }, + { .ia = k_chpart_arm_r1, .ib = k_chpart_hand_r, HUMAN_ARM_RIGHT }, +}; + +static void character_init_ragdoll_joints( struct character *ch ) +{ + for( int i=0; iparts[joint->ib].pivot; + v3_sub( hinge, ch->ragdoll[joint->ia].co, joint->lca ); + v3_sub( hinge, ch->ragdoll[joint->ib].co, joint->lcb ); + } +} + +static void character_init_ragdoll( struct character *ch ) +{ + v3f *offs = ch->offsets; + rigidbody *rbs = ch->ragdoll; + + /* CHest */ + float chest_width = fabsf(offs[k_chpart_arm_r0][2])*2.0f, + chest_depth = chest_width * 0.571f, + chest_height = offs[k_chpart_neck][1]; + v3f chest_dims = { chest_depth, chest_height, chest_width }; + character_rd_box( ch, k_chpart_body1, chest_dims ); + + v3_copy( ch->parts[k_chpart_body1].pivot, rbs[k_chpart_body1].co ); + rbs[k_chpart_body1].co[1] += chest_height*0.5f; + + /* Torso */ + v3f torso_dims = { chest_depth, + offs[k_chpart_body1][1]-offs[k_chpart_leg_l0][1], + chest_width*0.85f }; + v3_copy( ch->parts[k_chpart_body0].pivot, rbs[k_chpart_body0].co ); + character_rd_box( ch, k_chpart_body0, torso_dims ); + + /* Neck */ + v3f neck_dims = { chest_depth*0.5f, + offs[k_chpart_head][1], + chest_depth*0.5f }; + v3_copy( ch->parts[k_chpart_neck].pivot, rbs[k_chpart_neck].co ); + rbs[k_chpart_neck].co[1] += neck_dims[1]*0.5f; + character_rd_box( ch, k_chpart_neck, neck_dims ); + + /* Head */ + v3f head_dims = { chest_width*0.5f, chest_width*0.5f, chest_width*0.5f }; + v3_copy( ch->parts[k_chpart_head].pivot, rbs[k_chpart_head].co ); + rbs[k_chpart_head].co[1] += head_dims[1]*0.5f; + character_rd_box( ch, k_chpart_head, head_dims ); + + /* ARms */ + v3f ua_dims = { 0.0f, 0.0f, fabsf(offs[k_chpart_arm_l1][2]) }; + ua_dims[1] = 0.38f*ua_dims[2]; + ua_dims[0] = 0.38f*ua_dims[2]; + v3f la_dims = { ua_dims[0], ua_dims[1], fabsf(offs[k_chpart_hand_l][2]) }; + v3f hand_dims = { ua_dims[1], ua_dims[1]*0.5f, ua_dims[1] }; + + character_rd_box( ch, k_chpart_arm_l0, ua_dims ); + character_rd_box( ch, k_chpart_arm_r0, ua_dims ); + character_rd_box( ch, k_chpart_arm_l1, la_dims ); + character_rd_box( ch, k_chpart_arm_r1, la_dims ); + character_rd_box( ch, k_chpart_hand_l, hand_dims ); + character_rd_box( ch, k_chpart_hand_r, hand_dims ); + + v3_copy( ch->parts[k_chpart_arm_l0].pivot, rbs[k_chpart_arm_l0].co ); + rbs[k_chpart_arm_l0].co[2] += ua_dims[2] * 0.5f; + v3_copy( ch->parts[k_chpart_arm_l1].pivot, rbs[k_chpart_arm_l1].co ); + rbs[k_chpart_arm_l1].co[2] += la_dims[2] * 0.5f; + v3_copy( ch->parts[k_chpart_hand_l].pivot, rbs[k_chpart_hand_l].co ); + rbs[k_chpart_hand_l].co[2] += hand_dims[2] * 0.5f; + + v3_copy( ch->parts[k_chpart_arm_r0].pivot, rbs[k_chpart_arm_r0].co ); + rbs[k_chpart_arm_r0].co[2] -= ua_dims[2] * 0.5f; + v3_copy( ch->parts[k_chpart_arm_r1].pivot, rbs[k_chpart_arm_r1].co ); + rbs[k_chpart_arm_r1].co[2] -= la_dims[2] * 0.5f; + v3_copy( ch->parts[k_chpart_hand_r].pivot, rbs[k_chpart_hand_r].co ); + rbs[k_chpart_hand_r].co[2] -= hand_dims[2] * 0.5f; + + /* LEgs */ + v3f ul_dims = { 0.0f, fabsf(offs[k_chpart_leg_l1][1]), 0.0f }; + ul_dims[0] = 0.38f*ul_dims[1]; + ul_dims[2] = 0.38f*ul_dims[1]; + v3f ll_dims = { ul_dims[0], fabsf(offs[k_chpart_foot_l][1]), ul_dims[2] }; + v3f foot_dims = { 2.0f*ul_dims[0], ul_dims[0], ul_dims[0] }; + + character_rd_box( ch, k_chpart_leg_l0, ul_dims ); + character_rd_box( ch, k_chpart_leg_r0, ul_dims ); + character_rd_box( ch, k_chpart_leg_l1, ll_dims ); + character_rd_box( ch, k_chpart_leg_r1, ll_dims ); + character_rd_box( ch, k_chpart_foot_l, foot_dims ); + character_rd_box( ch, k_chpart_foot_r, foot_dims ); + + v3_copy( ch->parts[k_chpart_leg_l0].pivot, rbs[k_chpart_leg_l0].co ); + rbs[k_chpart_leg_l0].co[1] -= ul_dims[1] * 0.5f; + v3_copy( ch->parts[k_chpart_leg_l1].pivot, rbs[k_chpart_leg_l1].co ); + rbs[k_chpart_leg_l1].co[1] -= ll_dims[1] * 0.5f; + v3_copy( ch->parts[k_chpart_foot_l].pivot, rbs[k_chpart_foot_l].co ); + rbs[k_chpart_foot_l].co[1] -= foot_dims[1] * 0.5f; + rbs[k_chpart_foot_l].co[0] -= foot_dims[0] * 0.5f; + + v3_copy( ch->parts[k_chpart_leg_r0].pivot, rbs[k_chpart_leg_r0].co ); + rbs[k_chpart_leg_r0].co[1] -= ul_dims[1] * 0.5f; + v3_copy( ch->parts[k_chpart_leg_r1].pivot, rbs[k_chpart_leg_r1].co ); + rbs[k_chpart_leg_r1].co[1] -= ll_dims[1] * 0.5f; + v3_copy( ch->parts[k_chpart_foot_r].pivot, rbs[k_chpart_foot_r].co ); + rbs[k_chpart_foot_r].co[1] -= foot_dims[1] * 0.5f; + rbs[k_chpart_foot_r].co[0] -= foot_dims[0] * 0.5f; + + character_init_ragdoll_joints( ch ); + + for( int i=0; iragdoll[i] ); +} + +static void character_ragdoll_go( struct character *ch, v3f pos ) +{ + character_init_ragdoll( ch ); + for( int i=0; iragdoll[i].co, ch->ragdoll[i].co ); +} + +static void character_ragdoll_copypose( struct character *ch, v3f v ) +{ + character_init_ragdoll(ch); + + for( int i=0; iragdoll[i]; + + v3_sub( rb->co, ch->parts[i].pivot, offset ); + + m4x3_mulv( ch->matrices[i], offset, rb->co ); + m3x3_q( ch->matrices[i], rb->q ); + v3_copy( v, rb->v ); + v3_zero( rb->I ); + rb->manifold_count = 0; /* ? */ + + rb_update_transform( rb ); + } +} + +static void character_debug_ragdoll( struct character *ch ) +{ + rb_debug( &ch->ragdoll[k_chpart_body0], 0xffffffff ); + rb_debug( &ch->ragdoll[k_chpart_body1], 0xffffffff ); + rb_debug( &ch->ragdoll[k_chpart_neck], 0xff00ff00 ); + rb_debug( &ch->ragdoll[k_chpart_head], 0xff00ff00 ); + + rb_debug( &ch->ragdoll[k_chpart_arm_l0], 0xffffa500 ); + rb_debug( &ch->ragdoll[k_chpart_arm_l1], 0xffffa500 ); + rb_debug( &ch->ragdoll[k_chpart_hand_l], 0xffffa500 ); + + rb_debug( &ch->ragdoll[k_chpart_arm_r0], 0xff00a5ff ); + rb_debug( &ch->ragdoll[k_chpart_arm_r1], 0xff00a5ff ); + rb_debug( &ch->ragdoll[k_chpart_hand_r], 0xff00a5ff ); + + rb_debug( &ch->ragdoll[k_chpart_leg_l0], 0xffffa500 ); + rb_debug( &ch->ragdoll[k_chpart_leg_l1], 0xffffa500 ); + rb_debug( &ch->ragdoll[k_chpart_foot_l], 0xffffa500 ); + rb_debug( &ch->ragdoll[k_chpart_leg_r0], 0xff00a5ff ); + rb_debug( &ch->ragdoll[k_chpart_leg_r1], 0xff00a5ff ); + rb_debug( &ch->ragdoll[k_chpart_foot_r], 0xff00a5ff ); +} + +static void character_ragdoll_iter( struct character *ch, scene *sc ) +{ + for( int i=0; iragdoll[i], sc ); + } + + for( int i=0; i<20; i++ ) + { + float const k_springfactor = 1.0f/20.0f; + + for( int j=0; jragdoll[j] ); + + for( int j=0; jragdoll[joint->ia], + *rbb = &ch->ragdoll[joint->ib]; + + rb_constraint_position( rba, joint->lca, rbb, joint->lcb ); + rb_constraint_angle( rba, joint->maj.va, rbb, joint->maj.vb, + joint->maj.ang, + joint->maj.spring * k_springfactor ); + + rb_constraint_angle( rba, joint->min.va, rbb, joint->min.vb, + joint->min.ang, + joint->min.spring * k_springfactor ); + } + } + + for( int i=0; iragdoll[i] ); + + for( int i=0; iragdoll[i] ); +} + #endif