medfall

A super great game engine
Log | Files | Refs

commit 74d047d7eae558d25746bbe24a8c66c83f63587f
parent da1a6c3c7d1b656fd243c8ec479bbc029046c353
Author: Michael Savage <mikejsavage@gmail.com>
Date:   Mon Aug 21 21:01:03 +0300

Much improved player physics. Walking up hills works now, walking down is a bit rubbish

Diffstat:
hm.cc | 91++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
1 file changed, 53 insertions(+), 38 deletions(-)
diff --git a/hm.cc b/hm.cc @@ -229,55 +229,73 @@ GAME_FRAME( game_frame ) { while( remaining_t > 0 && spins < 5 ) { spins++; if( game->on_ground ) { - v3 start = game->pos + v3( 0, 0, 0.001f ); - v3 end = start + game->velocity * remaining_t; + const float step_height = 0.1f; - float t; - float step_t = FLT_MAX; - v3 normal, step_normal; + v3 low_start = game->pos; + v3 low_end = low_start + game->velocity * remaining_t; - const float step_height = 0.1f; - v3 step_start = game->pos + v3( 0, 0, step_height ); + v3 high_start = game->pos + v3( 0, 0, step_height ); + v3 high_end = high_start + game->velocity * remaining_t; - bool hit = segment_vs_terrain( &game->tm, start, end, &t, &normal ); - bool step_hit = false; + float low_t; + float high_t; + v3 low_normal, high_normal; - bool step_up_hit = segment_vs_terrain( &game->tm, start, step_start, NULL, NULL ); + bool low_hit = segment_vs_terrain( &game->tm, low_start, low_end, &low_t, &low_normal ); + bool high_hit = false; + + bool step_up_hit = segment_vs_terrain( &game->tm, low_start, high_start, NULL, NULL ); if( !step_up_hit ) { - v3 step_end = step_start + game->velocity * remaining_t; - step_hit = segment_vs_terrain( &game->tm, step_start, step_end, &step_t, &step_normal ); + high_hit = segment_vs_terrain( &game->tm, high_start, high_end, &high_t, &high_normal ); } - if( step_t > t ) { - v3 step_intersection = step_start + game->velocity * remaining_t * min( 1.0f, step_t ); - v3 step_down = step_intersection - v3( 0, 0, step_height ); + v3 step_down_start; + float step_down_distance; + bool should_step_down = false; - float step_down_t; - bool step_down_hit = segment_vs_terrain( &game->tm, step_intersection, step_down, &step_down_t, &step_normal ); - if( !step_down_hit ) { - step_t = 1.0f; - game->on_ground = false; + if( high_t > low_t ) { + if( high_hit ) { + game->pos = high_start + game->velocity * high_t * remaining_t; + remaining_t = ( 1.0f - high_t ) * remaining_t; + } + else { + step_down_start = high_end; + step_down_distance = step_height * 2; + should_step_down = true; + remaining_t = 0; } - } - - if( hit ) { - game->pos = start + game->velocity * t * remaining_t + v3( 0, 0, 0.001f ); - remaining_t = ( 1.0f - t ) * remaining_t; } else { - v3 down_end = end - v3( 0, 0, 0.2f ); - float down_t; - bool down_hit = segment_vs_terrain( &game->tm, end, down_end, &down_t, NULL ); - if( !down_hit ) { - game->on_ground = false; - down_t = 1; + if( low_hit ) { + game->pos = low_start + game->velocity * low_t * remaining_t; + remaining_t = ( 1.0f - low_t ) * remaining_t; } - game->pos = lerp( end, down_t, down_end ) + v3( 0, 0, 0.001f ); - // TODO: probably not right - remaining_t = 0; + else { + step_down_start = low_end; + step_down_distance = step_height; + should_step_down = true; + remaining_t = 0; + } + } + + if( should_step_down ) { + float step_down_t; + v3 step_down_end = step_down_start - v3( 0, 0, step_down_distance ); + + bool step_down_hit = segment_vs_terrain( &game->tm, step_down_start, step_down_end, &step_down_t, NULL ); + + game->pos = lerp( step_down_start, step_down_t, step_down_end ); + game->on_ground = step_down_hit; + } + + if( game->on_ground ) { + // move up 1mm so float imprecision doesn't make us fall through the world + game->pos.z += 0.001f; } } - else { + + if( !game->on_ground ) { + // TODO: rk4 integration const float gravity = -30.0f; game->velocity += v3( 0, 0, gravity ) * remaining_t; @@ -307,9 +325,6 @@ GAME_FRAME( game_frame ) { game->pos.z += dt * dz * speed; #endif - // game->pos.z = terrain_height( &game->tm, game->pos ) + 1.8f; - // game->pos.z += dz * 50.0f * dt; - terrain_update( &game->tm, game->pos ); v3 eye_pos = game->pos + v3( 0, 0, EYE_HEIGHT );