From fa76acdf613baf7991fbceecbdbd7138620647f8 Mon Sep 17 00:00:00 2001 From: hgn Date: Thu, 16 Jun 2022 17:36:14 +0100 Subject: [PATCH] i forgo --- character.h | 131 ++++++++++++++++++++++++++---- gate.h | 4 + main.c | 228 ++++++++++++++++++++++++++++++++++++++++------------ rigidbody.h | 99 ++++++++++++++++++++--- scene.h | 19 +++-- vg_config.h | 9 ++- 6 files changed, 404 insertions(+), 86 deletions(-) create mode 100644 gate.h diff --git a/character.h b/character.h index f5a9d67..f161f7d 100644 --- a/character.h +++ b/character.h @@ -54,6 +54,10 @@ SHADER_DEFINE( shader_player, ) #define FOREACH_PART(FN) \ + FN( foot_l ) \ + FN( foot_r ) \ + FN( sock_l ) \ + FN( sock_r ) \ FN( body0 ) \ FN( body1 ) \ FN( neck ) \ @@ -66,10 +70,8 @@ SHADER_DEFINE( shader_player, FN( hand_r ) \ FN( leg_l0 ) \ FN( leg_l1 ) \ - FN( foot_l ) \ FN( leg_r0 ) \ FN( leg_r1 ) \ - FN( foot_r ) \ FN( wf ) \ FN( wb ) \ FN( board ) \ @@ -119,6 +121,8 @@ struct character v3f ground_normal; /* Feet will be aligned to this */ m4x3f mroot; + + int shoes[2]; }; static void character_offset( struct character *ch, enum character_part parent, @@ -554,11 +558,27 @@ static void character_draw( struct character *ch, float temp ) mesh_bind( &ch->mesh ); - for( int i=0; imatrices[i] ); submodel_draw( &ch->parts[i] ); } + + for( int i=0; i<2; i++ ) + { + if( ch->shoes[i] ) + { + glUniformMatrix4x3fv( kuMdl, 1, GL_FALSE, (float *)ch->matrices[i] ); + submodel_draw( &ch->parts[i] ); + } + else + { + glUniformMatrix4x3fv( kuMdl, 1, GL_FALSE, (float *)ch->matrices[i+2] ); + submodel_draw( &ch->parts[i] ); + glUniformMatrix4x3fv( kuMdl, 1, GL_FALSE, (float *)ch->matrices[i] ); + submodel_draw( &ch->parts[i+2] ); + } + } } static void character_shader_register(void) @@ -591,10 +611,10 @@ struct rd_joint 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; +static const float k_human_major = 0.5f, + k_human_minor = 0.5f, + k_human_major_max = 0.4f, + k_human_minor_max = 0.1f; #define HUMAN_VERTICAL_DEFAULT \ .min = { \ @@ -622,12 +642,15 @@ static const float k_human_major = 0.9f, .spring = k_human_minor, .ang = k_human_minor_max \ }, \ .maj = { \ - .va = {0.0f,0.0f,-1.0f}, .vb = {0.0f,0.0f,-1.0f}, \ + .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_leg_l1, .ib = k_chpart_foot_l, HUMAN_VERTICAL_DEFAULT }, + { .ia = k_chpart_leg_r1, .ib = k_chpart_foot_r, HUMAN_VERTICAL_DEFAULT }, + { .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 }, @@ -642,9 +665,10 @@ static struct rd_joint rd_joints[] = { .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 }, + { .ia = k_chpart_arm_r1, .ib = k_chpart_hand_r, HUMAN_ARM_RIGHT } }; +/* Ragdoll should be in rest pose when calling this function */ static void character_init_ragdoll_joints( struct character *ch ) { for( int i=0; iragdoll[joint->ia].co, joint->lca ); v3_sub( hinge, ch->ragdoll[joint->ib].co, joint->lcb ); } + + for( int i=0; iparts[i].pivot; + v3_sub( ch->ragdoll[i].co, pivot, ch->ragdoll[i].delta ); + } } static void character_init_ragdoll( struct character *ch ) @@ -751,10 +781,18 @@ static void character_init_ragdoll( struct character *ch ) 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 ); + character_rd_box( ch, k_chpart_sock_l, foot_dims ); + character_rd_box( ch, k_chpart_sock_r, foot_dims ); + v3_copy( rbs[k_chpart_foot_l].co, rbs[k_chpart_sock_l].co ); + v3_copy( rbs[k_chpart_foot_r].co, rbs[k_chpart_sock_r].co ); + + box_copy( (boxf){{-0.2f,-0.2f,-0.7f},{0.2f,0.2f,0.7f}}, + rbs[k_chpart_board].bbx ); for( int i=0; iragdoll[i] ); + + character_init_ragdoll_joints( ch ); } static void character_ragdoll_go( struct character *ch, v3f pos ) @@ -766,16 +804,11 @@ static void character_ragdoll_go( struct character *ch, v3f pos ) 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 ); + m4x3_mulv( ch->matrices[i], rb->delta, rb->co ); m3x3_q( ch->matrices[i], rb->q ); v3_copy( v, rb->v ); v3_zero( rb->I ); @@ -783,6 +816,33 @@ static void character_ragdoll_copypose( struct character *ch, v3f v ) rb_update_transform( rb ); } + + float vel = v3_length(v); + + ch->shoes[0] = 1; + ch->shoes[1] = 1; +} + +static void character_mimic_ragdoll( struct character *ch ) +{ + for( int i=0; iragdoll[i]; + v3f *mat = ch->matrices[i]; + + m3x3_copy( rb->to_world, mat ); + v3f inv_delta; + v3_negate( rb->delta, inv_delta ); + m4x3_mulv( rb->to_world, inv_delta, mat[3] ); + } + + /* Attach wheels to board */ + m3x3_copy( ch->matrices[k_chpart_board], ch->matrices[k_chpart_wb] ); + m3x3_copy( ch->matrices[k_chpart_board], ch->matrices[k_chpart_wf] ); + m4x3_mulv( ch->matrices[k_chpart_board], ch->offsets[k_chpart_wb], + ch->matrices[k_chpart_wb][3] ); + m4x3_mulv( ch->matrices[k_chpart_board], ch->offsets[k_chpart_wf], + ch->matrices[k_chpart_wf][3] ); } static void character_debug_ragdoll( struct character *ch ) @@ -815,6 +875,13 @@ static void character_ragdoll_iter( struct character *ch, scene *sc ) rb_build_manifold( &ch->ragdoll[i], sc ); } + v3f rv; + + float shoe_vel[2]; + for( int i=0; i<2; i++ ) + if( ch->shoes[i] ) + shoe_vel[i] = v3_length( ch->ragdoll[i].v ); + for( int i=0; i<20; i++ ) { float const k_springfactor = 1.0f/20.0f; @@ -839,8 +906,40 @@ static void character_ragdoll_iter( struct character *ch, scene *sc ) } } + for( int j=0; jragdoll[joint->ia], + *rbb = &ch->ragdoll[joint->ib]; + rb_angle_limit_force( rba, joint->min.va, rbb, joint->min.vb, + joint->min.ang ); + rb_angle_limit_force( rba, joint->maj.va, rbb, joint->maj.vb, + joint->maj.ang ); + } + for( int i=0; iragdoll[i] ); + + for( int i=0; i<2; i++ ) + { + if( ch->shoes[i] ) + { + float a = v3_length( ch->ragdoll[i].v ) - shoe_vel[i]; + + if( a > 2.0f ) + { + ch->shoes[i] = 0; + + rigidbody *src = &ch->ragdoll[k_chpart_foot_l]; + rigidbody *dst = &ch->ragdoll[k_chpart_sock_l]; + + v3_copy( src->co, dst->co ); + v3_copy( src->v, dst->v ); + v3_copy( src->q, dst->q ); + v3_copy( src->I, dst->I ); + } + } + } for( int i=0; iragdoll[i] ); diff --git a/gate.h b/gate.h new file mode 100644 index 0000000..541cec8 --- /dev/null +++ b/gate.h @@ -0,0 +1,4 @@ +#ifndef GATE_H +#define GATE_H + +#endif diff --git a/main.c b/main.c index 804a6cd..bdd8197 100644 --- a/main.c +++ b/main.c @@ -86,12 +86,13 @@ static struct gplayer reverse; float iY; /* Yaw inertia */ - int in_air; + int in_air, is_dead; /* Input */ v2f joy_l; v3f view; + v3f follow; v2f look_dir; /* TEMP */ v2f board_xy; float grab; @@ -99,6 +100,7 @@ static struct gplayer v3f land_target; v3f land_target_log[22]; + u32 land_target_colours[22]; int land_log_count; m3x3f vr; @@ -114,9 +116,9 @@ player; static struct gworld { scene geo; - submodel terrain, - terrain_rocks, - terrain_road; + submodel sm_road, sm_terrain; + + v3f tutorial; } world; @@ -149,10 +151,23 @@ static void player_transform_update(void) static int reset_player( int argc, char const *argv[] ) { v3_zero( player.co ); + + if( argc == 1 ) + { + if( !strcmp( argv[0], "tutorial" )) + v3_copy( world.tutorial, player.co ); + } + v3_copy( (v3f){ 0.0f, 0.0f, -0.2f }, player.v ); q_identity( player.rot ); player.vswitch = 1.0f; player.slip_last = 0.0f; + player.is_dead = 0; + player.in_air = 1; + m3x3_identity( player.vr ); + + player.mdl.shoes[0] = 1; + player.mdl.shoes[1] = 1; player_transform_update(); return 0; @@ -276,15 +291,18 @@ void vg_start(void) scene_add_model( &world.geo, mworld, submodel_get( mworld, "mp_dev" ), (v3f){0.0f,0.0f,0.0f}, 0.0f, 1.0f ); + scene_copy_slice( &world.geo, &world.sm_road ); scene_add_model( &world.geo, mworld, submodel_get( mworld, "terrain" ), (v3f){0.0f,0.0f,0.0f}, 0.0f, 1.0f ); + scene_copy_slice( &world.geo, &world.sm_terrain ); + + v3_copy( submodel_get( mworld, "tutorial" )->pivot, world.tutorial ); free( mworld ); scene_upload( &world.geo ); bvh_create( &world.geo ); - reset_player( 0, NULL ); player_transform_update(); @@ -377,6 +395,11 @@ static void apply_gravity( v3f vel, float const timestep ) v3_muladds( vel, gravity, timestep, vel ); } +static int ray_hit_is_ramp( ray_hit *hit ) +{ + return hit->tri[0] < world.sm_road.vertex_count; +} + static void player_start_air(void) { player.in_air = 1; @@ -432,6 +455,14 @@ static void player_start_air(void) if( bvh_raycast( &world.geo, pco1, vdir, &contact )) { float land_delta = v3_dot( pv, contact.normal ); + u32 scolour = (u8)(vg_minf(-land_delta * 2.0f, 255.0f)); + + /* Bias prediction towords ramps */ + if( ray_hit_is_ramp( &contact ) ) + { + land_delta *= 0.1f; + scolour |= 0x0000a000; + } if( (land_delta < 0.0f) && (land_delta > best_velocity_delta) ) { @@ -445,7 +476,12 @@ static void player_start_air(void) } v3_copy( contact.pos, - player.land_target_log[player.land_log_count ++] ); + player.land_target_log[player.land_log_count] ); + player.land_target_colours[player.land_log_count] = + 0xff000000 | scolour; + + player.land_log_count ++; + break; } } @@ -459,15 +495,16 @@ static void player_start_air(void) static int sample_if_resistant( v3f pos ) { - v3f ground, norm; + v3f ground; v3_copy( pos, ground ); - - if( bvh_scene_sample( &world.geo, ground, norm ) ) + + ray_hit hit; + if( bvh_scene_sample( &world.geo, ground, &hit ) ) { v3f angle; v3_copy( player.v, angle ); v3_normalize( angle ); - float resistance = v3_dot( norm, angle ); + float resistance = v3_dot( hit.normal, angle ); if( resistance < 0.25f ) { @@ -568,12 +605,31 @@ static void player_physics_ground(void) player.reverse = -vg_signf(vel[2]); float substep = ktimestep * 0.2f; + float fwd_resistance = (vg_get_button( "break" )? 5.0f: 0.02f) * -substep; + for( int i=0; i<5; i++ ) { - vel[2] = stable_force( vel[2], vg_signf( vel[2] ) * -0.02f*substep ); + vel[2] = stable_force( vel[2], vg_signf( vel[2] ) * fwd_resistance ); vel[0] = stable_force( vel[0], vg_signf( vel[0] ) * -7.0f *substep ); } + static double start_push = 0.0; + if( vg_get_button_down( "push" ) ) + start_push = vg_time; + + if( !vg_get_button("break") && vg_get_button( "push" ) ) + { + float const k_maxpush = 16.0f, + k_pushaccel = 5.0f; + + float cycle_time = vg_time-start_push, + amt = k_pushaccel * (sinf( cycle_time * 8.0f )*0.5f+0.5f)*ktimestep, + current = v3_length( vel ), + new_vel = vg_minf( current + amt, k_maxpush ); + new_vel -= vg_minf(current, k_maxpush); + vel[2] -= new_vel * player.reverse; + } + m3x3_mulv( player.to_world, vel, player.v ); if( vg_get_button( "yawl" ) ) @@ -609,18 +665,28 @@ static void player_physics_air(void) m3x3_mulv( player.vr, player.v, player.v ); for( int i=0; i player.co[1] ) { player.in_air = 0; + + if( !ray_hit_is_ramp( &hit ) ) + { + player.is_dead = 1; + m4x3_mulv( player.to_world, player.view, player.follow ); + character_ragdoll_copypose( &player.mdl, player.v ); + } + return; } } @@ -634,6 +700,9 @@ static void player_physics_air(void) v3f pco, pco1, pv; v3_copy( player.co, pco ); v3_copy( player.v, pv ); + + float time_to_impact = 0.0f; + float limiter = 1.0f; for( int i=0; i<50; i++ ) { @@ -649,7 +718,8 @@ static void player_physics_air(void) v3_sub( pco, pco1, vdir ); contact.dist = v3_length( vdir ); v3_divs( vdir, contact.dist, vdir); - + + float orig_dist = contact.dist; if( bvh_raycast( &world.geo, pco1, vdir, &contact )) { v3f localup; @@ -658,21 +728,42 @@ static void player_physics_air(void) float angle = v3_dot( localup, contact.normal ); v3f axis; v3_cross( localup, contact.normal, axis ); - + + time_to_impact += (contact.dist/orig_dist)*pstep; + limiter = vg_minf( 5.0f, time_to_impact )/5.0f; + limiter = 1.0f-limiter; + limiter *= limiter; + limiter = 1.0f-limiter; + if( angle < 0.99f ) { v4f correction; - q_axis_angle( correction, axis, acosf(angle)*0.05f ); + q_axis_angle( correction, axis, acosf(angle)*0.05f*(1.0f-limiter) ); q_mul( correction, player.rot, player.rot ); } draw_cross( contact.pos, 0xffff0000 ); - break; } + time_to_impact += pstep; } + player.iY -= vg_get_axis( "horizontal" ) * 3.6f * ktimestep; + { + + float iX = vg_get_axis( "vertical" ) * 3.6f * limiter * ktimestep; + static float siX = 0.0f; + siX = vg_lerpf( siX, iX, 0.3f ); + + v4f rotate; + v3f vside; + + m3x3_mulv( player.to_world, (v3f){1.0f,0.0f,0.0f}, vside ); + + q_axis_angle( rotate, vside, siX ); + q_mul( rotate, player.rot, player.rot ); + } v2f target = {0.0f,0.0f}; v2_muladds( target, (v2f){ vg_get_axis("h1"), vg_get_axis("v1") }, @@ -683,6 +774,12 @@ static void player_physics_air(void) static void player_animate(void); static void player_update(void) { + + if( vg_get_axis("grabl")>0.0f) + reset_player(0,NULL); + if( player.is_dead ) + return; + static int clock = 0; /* temp */ @@ -697,17 +794,6 @@ static void player_update(void) clock = 0; else return; - - if( vg_get_axis("grabl")>0.0f) - reset_player(0,NULL); - if( vg_get_button( "push" ) ) - { - v3f dir = { 0.0f, 0.0f, -1.0f }; - - m3x3_mulv( player.to_world, dir, dir ); - v3_muladds( player.v, dir, 5.0f * ktimestep, player.v ); - } - float horizontal = vg_get_axis("horizontal"), vertical = vg_get_axis("vertical"); @@ -762,7 +848,11 @@ void vg_update(void) character_ragdoll_go( &player.mdl, player.view ); if( glfwGetKey( vg_window, GLFW_KEY_G ) ) + { + player.is_dead = 1; + m4x3_mulv( player.to_world, player.view, player.follow ); character_ragdoll_copypose( &player.mdl, player.v ); + } static int clock = 0; @@ -770,8 +860,9 @@ void vg_update(void) if( clock >= clock_divider ) { character_debug_ragdoll( &player.mdl ); - character_ragdoll_iter( &player.mdl, &world.geo ); + if( player.is_dead ) + character_ragdoll_iter( &player.mdl, &world.geo ); rb_build_manifold( &mr_box, &world.geo ); rb_build_manifold( &mrs_box, &world.geo ); @@ -996,8 +1087,13 @@ static void draw_player(void) vg_tex2d_bind( &tex_pallet, 0 ); m4x3_copy( player.to_world, player.mdl.mroot ); - character_eval( &player.mdl ); - character_draw( &player.mdl, 1.0f ); + + if( player.is_dead ) + character_mimic_ragdoll( &player.mdl ); + else + character_eval( &player.mdl ); + + character_draw( &player.mdl, (player.is_dead|player.in_air)? 0.0f: 1.0f ); } static void vg_framebuffer_resize( int w, int h ) @@ -1026,7 +1122,14 @@ void vg_render(void) v3_lerp( cam_lerped, player.view, 0.08f, cam_lerped ); if( !freecam ) + { m4x3_mulv( player.to_world, cam_lerped, pos_inv ); + + static float air_blend = 0.0f; + + air_blend = vg_lerpf( air_blend, player.in_air, 0.04f ); + v3_muladds( pos_inv, player.v, -0.05f*air_blend, pos_inv ); + } else v3_add( player.co, player.view, pos_inv ); v3_negate( pos_inv, pos_inv ); @@ -1041,18 +1144,41 @@ void vg_render(void) static v2f cam_lerped_dir; - v2_lerp( cam_lerped_dir, player.look_dir, 0.04f, cam_lerped_dir ); - m4x3_identity( world_matrix ); - m4x3_rotate_x( world_matrix, - freecam? - cam_lerped_dir[1]: - 0.6f+shake[1]*0.04f+player.look_dir[1] ); - - m4x3_rotate_y( world_matrix, - freecam? - cam_lerped_dir[0]: - player.look_dir[0]+shake[0]*0.02f ); + if( player.is_dead ) + { + v3f delta; + v3_sub( player.mdl.ragdoll[k_chpart_head].co, player.follow, delta ); + v3_normalize(delta); + + v3f follow_pos; + v3_muladds( player.mdl.ragdoll[k_chpart_head].co, delta, + -1.5f, follow_pos ); + v3_lerp( player.follow, follow_pos, 0.1f, player.follow ); + v3_negate( player.follow, final ); + + + float yaw = atan2f( delta[0], -delta[2] ); + float pitch = asinf( delta[1] ); + m4x3_rotate_x( world_matrix, -pitch ); + m4x3_rotate_y( world_matrix, yaw ); + } + else + { + v2_lerp( cam_lerped_dir, player.look_dir, 0.04f, cam_lerped_dir ); + + m4x3_rotate_x( world_matrix, + freecam? + cam_lerped_dir[1]: + 0.6f+shake[1]*0.04f+player.look_dir[1] ); + + m4x3_rotate_y( world_matrix, + freecam? + cam_lerped_dir[0]: + player.look_dir[0]+shake[0]*0.02f ); + } + + m4x3_translate( world_matrix, final ); m4x4f world_4x4; @@ -1091,6 +1217,7 @@ void vg_render(void) scene_bind( &world.geo ); scene_draw( &world.geo ); +#if 0 if( !replay_record ) { m4x3f *base = &replay_buffer[(PART_COUNT)*replay_buffer_frame]; @@ -1107,6 +1234,7 @@ void vg_render(void) character_draw( &player.mdl, 0.0f ); player_animate(); } +#endif @@ -1122,11 +1250,10 @@ void vg_render(void) glBindFramebuffer( GL_FRAMEBUFFER, 0 ); glClearColor( 0.0f, 0.0f, 0.0f, 0.0f ); -#if 0 - glClear( GL_COLOR_BUFFER_BIT ); -#else - glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT ); -#endif + if( !player.is_dead ) + glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT ); + else + glClear( GL_COLOR_BUFFER_BIT ); draw_player(); @@ -1183,7 +1310,7 @@ void vg_render(void) glViewport( 0,0, vg_window_x, vg_window_y ); - +#if 0 if( replay_record ) { m4x3f *base = &replay_buffer[(PART_COUNT)*replay_buffer_frame]; @@ -1196,6 +1323,7 @@ void vg_render(void) if( replay_buffer_frame == REPLAY_LENGTH ) replay_buffer_frame = 0; } +#endif } void vg_ui(void) diff --git a/rigidbody.h b/rigidbody.h index cf258b8..4318d8c 100644 --- a/rigidbody.h +++ b/rigidbody.h @@ -1,8 +1,13 @@ -/* SHite fphysics */ +/* + * Resources: Box2D - Erin Catto + * qu3e - Randy Gaul + */ #ifndef RIGIDBODY_H #define RIGIDBODY_H +#define RB_DEPR + #include "vg/vg.h" #include "scene.h" @@ -14,6 +19,7 @@ struct rigidbody v3f co, v, I; v4f q; boxf bbx; + float inv_mass; struct contact { @@ -24,6 +30,7 @@ struct rigidbody manifold[4]; int manifold_count; + v3f delta; /* where is the origin of this in relation to a parent body */ m4x3f to_world, to_local; }; @@ -42,6 +49,11 @@ static void rb_init( rigidbody *rb ) v3_zero( rb->v ); v3_zero( rb->I ); + v3f dims; + v3_sub( rb->bbx[1], rb->bbx[0], dims ); + + rb->inv_mass = 1.0f/(8.0f*dims[0]*dims[1]*dims[2]); + rb_update_transform( rb ); } @@ -130,7 +142,10 @@ static void rb_build_manifold( rigidbody *rb, scene *sc ) v3f surface; v3_copy( point, surface ); - bvh_scene_sample( sc, surface, ct->n ); + + ray_hit hit; + bvh_scene_sample( sc, surface, &hit ); + v3_copy( hit.normal, ct->n ); float p = vg_minf( surface[1] - point[1], 1.0f ); @@ -158,7 +173,7 @@ static void rb_build_manifold( rigidbody *rb, scene *sc ) static void rb_constraint_manifold( rigidbody *rb ) { - float k_friction = 0.07f; + float k_friction = 0.1f; /* Friction Impulse */ for( int i=0; imanifold_count; i++ ) @@ -214,6 +229,52 @@ static void rb_constraint_manifold( rigidbody *rb ) } } +struct rb_angle_limit +{ + rigidbody *rba, *rbb; + v3f axis; + float impulse, bias; +}; + +static int rb_angle_limit_force( + rigidbody *rba, v3f va, + rigidbody *rbb, v3f vb, + float max ) +{ + v3f wva, wvb; + m3x3_mulv( rba->to_world, va, wva ); + m3x3_mulv( rbb->to_world, vb, wvb ); + + float dt = v3_dot(wva,wvb)*0.999f, + ang = fabsf(dt); + ang = acosf( dt ); + if( ang > max ) + { + float correction = max-ang; + + v3f axis; + v3_cross( wva, wvb, axis ); + + v4f rotation; + q_axis_angle( rotation, axis, -correction*0.25f ); + q_mul( rotation, rba->q, rba->q ); + + q_axis_angle( rotation, axis, correction*0.25f ); + q_mul( rotation, rbb->q, rbb->q ); + + return 1; + } + + return 0; +} + +static void rb_constraint_angle_limit( struct rb_angle_limit *limit ) +{ + +} + + +RB_DEPR static void rb_constraint_angle( rigidbody *rba, v3f va, rigidbody *rbb, v3f vb, float max, float spring ) @@ -248,11 +309,26 @@ static void rb_constraint_angle( rigidbody *rba, v3f va, } } +static void rb_relative_velocity( rigidbody *ra, v3f lca, + rigidbody *rb, v3f lcb, v3f rcv ) +{ + v3f wca, wcb; + m3x3_mulv( ra->to_world, lca, wca ); + m3x3_mulv( rb->to_world, lcb, wcb ); + + v3_sub( ra->v, rb->v, rcv ); + + v3f rcv_Ra, rcv_Rb; + v3_cross( ra->I, wca, rcv_Ra ); + v3_cross( rb->I, wcb, rcv_Rb ); + v3_add( rcv_Ra, rcv, rcv ); + v3_sub( rcv, rcv_Rb, rcv ); +} + static void rb_constraint_position( rigidbody *ra, v3f lca, rigidbody *rb, v3f lcb ) { /* C = (COa + Ra*LCa) - (COb + Rb*LCb) = 0 */ - v3f wca, wcb; m3x3_mulv( ra->to_world, lca, wca ); m3x3_mulv( rb->to_world, lcb, wcb ); @@ -273,19 +349,24 @@ static void rb_constraint_position( rigidbody *ra, v3f lca, v3_cross( rb->I, wcb, rcv_Rb ); v3_add( rcv_Ra, rcv, rcv ); v3_sub( rcv, rcv_Rb, rcv ); + + float nm = 0.5f/(rb->inv_mass + ra->inv_mass); + + float mass_a = 1.0f/ra->inv_mass, + mass_b = 1.0f/rb->inv_mass, + total_mass = mass_a+mass_b; v3f impulse; - v3_muls( rcv, 0.5f, impulse ); - v3_add( impulse, rb->v, rb->v ); + v3_muls( rcv, 1.0f, impulse ); + v3_muladds( rb->v, impulse, mass_b/total_mass, rb->v ); v3_cross( wcb, impulse, impulse ); v3_add( impulse, rb->I, rb->I ); - v3_muls( rcv, -0.5f, impulse ); - v3_add( impulse, ra->v, ra->v ); + v3_muls( rcv, -1.0f, impulse ); + v3_muladds( ra->v, impulse, mass_a/total_mass, ra->v ); v3_cross( wca, impulse, impulse ); v3_add( impulse, ra->I, ra->I ); - #if 0 v3f impulse; v3_muls( delta, 0.5f*spring, impulse ); diff --git a/scene.h b/scene.h index 23307ad..e00445a 100644 --- a/scene.h +++ b/scene.h @@ -421,8 +421,12 @@ static void scene_copy_slice( scene *pscene, submodel *sm ) { sm->indice_start = pscene->submesh.indice_start; sm->indice_count = pscene->indice_count - sm->indice_start; + + sm->vertex_start = pscene->submesh.vertex_start; + sm->vertex_count = pscene->vertex_count - sm->vertex_start; pscene->submesh.indice_start = pscene->indice_count; + pscene->submesh.vertex_start = pscene->vertex_count; } static void scene_shadow_sphere( scene *pscene, v3f sphere, @@ -1287,21 +1291,16 @@ static int bvh_scene_sample_h( scene *s, v3f pos, v3f norm) return bvh_scene_sample_node_h( s, 0, pos, norm ); } -static int bvh_scene_sample( scene *s, v3f pos, v3f norm ) +static int bvh_scene_sample( scene *s, v3f pos, ray_hit *hit ) { - ray_hit hit; - hit.dist = INFINITY; + hit->dist = INFINITY; v3f ray_pos; - v3_add( pos, (v3f){0.0f,16000.0f,0.0f}, ray_pos ); + v3_add( pos, (v3f){0.0f,4.0f,0.0f}, ray_pos ); - if( bvh_raycast( s, ray_pos, (v3f){0.0f,-1.0f,0.0f}, &hit )) + if( bvh_raycast( s, ray_pos, (v3f){0.0f,-1.0f,0.0f}, hit )) { - pos[1] = hit.pos[1]; - - if( norm ) - v3_copy( hit.normal, norm ); - + pos[1] = hit->pos[1]; return 1; } diff --git a/vg_config.h b/vg_config.h index fc153ed..4b305e9 100644 --- a/vg_config.h +++ b/vg_config.h @@ -1,5 +1,6 @@ // Copyright (C) 2021 Harry Godden (hgn) - All Rights Reserved #define VG_CONFIG +#include "vg/vg.h" static struct button_binding vg_button_binds[] = { @@ -13,7 +14,13 @@ static struct button_binding vg_button_binds[] = { .name = "down", .bind = GLFW_KEY_F }, { .name = "yawl", .bind = GLFW_KEY_Q }, { .name = "yawr", .bind = GLFW_KEY_E }, - { .name = "push", .controller = GLFW_GAMEPAD_BUTTON_B } + { .name = "push", .bind = GLFW_KEY_T } +}; + +static struct button_binding vg_controller_binds[] = +{ + { "push", GLFW_GAMEPAD_BUTTON_A }, + { "break", GLFW_GAMEPAD_BUTTON_B } }; static struct axis_binding vg_axis_binds[] = -- 2.25.1