From 470e85ea3a8938a60b77c9b9c7ec9a95b2ecbba6 Mon Sep 17 00:00:00 2001 From: Ed_ Date: Fri, 29 Dec 2023 14:53:00 -0500 Subject: [PATCH] Day 45 complete --- README.md | 2 +- project/codegen/engine_gen.cpp | 11 +- project/engine/engine.cpp | 218 ++++++++++++++++++++------------- project/engine/gen/physics.hpp | 18 +++ project/engine/gen/vectors.hpp | 6 + project/engine/tile_map.cpp | 28 ++++- project/handmade_engine.cpp | 1 + 7 files changed, 188 insertions(+), 96 deletions(-) diff --git a/README.md b/README.md index 2af0ebe..1127c7a 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ Module build order: ## Milestone -Day 43 : The Equations of Motion +Day 45 : Geometric vs. Temporal Movement Search Features Done so far: diff --git a/project/codegen/engine_gen.cpp b/project/codegen/engine_gen.cpp index 7bf3f60..8b83f3c 100644 --- a/project/codegen/engine_gen.cpp +++ b/project/codegen/engine_gen.cpp @@ -46,7 +46,7 @@ constexpr char const* vec2f_ops = stringize( result = sqrt( v.x * v.x + v.y * v.y ); return result; } - + inline normalize( v ) { square_size = v.x * v.x + v.y * v.y; @@ -63,11 +63,16 @@ constexpr char const* vec2f_ops = stringize( } inline - scalar_product( a, b ) - { + scalar_product( a, b ) { result = a.x * b.x + a.y * b.y; return result; } + + inline + magnitude_squared( v ) { + result = scalar_product( v, v ); + return result; + } inline operator - ( v ) { diff --git a/project/engine/engine.cpp b/project/engine/engine.cpp index 5c9d42b..4343253 100644 --- a/project/engine/engine.cpp +++ b/project/engine/engine.cpp @@ -876,7 +876,8 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back move_accel = 94.f; } - Pos2_f32 new_player_pos = { player->position.rel_pos.x, player->position.rel_pos.y }; + TileMapPos old_pos = player->position; + Pos2_f32 new_player_pos = { old_pos.rel_pos.x, old_pos.rel_pos.y }; Vec2 player_move_vec = {}; if ( player_actions.player_x_move_analog || player_actions.player_y_move_analog ) @@ -900,109 +901,154 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back player->move_velocity += player_move_accel * 0.5f; new_player_pos += player->move_velocity; - b32 collision_nw = false; - b32 collision_ne = false; - b32 collision_sw = false; - b32 collision_se = false; - do + // Old collision implmentation + #if 1 { - // Base position - //TileMapPos test_pos = { - //new_player_pos.x, new_player_pos.y, - //player->position.tile_x, player->position.tile_y, player->position.tile_z - //}; - //test_pos = recannonicalize_position( tile_map, test_pos ); - - // TODO(Ed) : Need a delta-function that auto-reconnonicalizes. - - TileMapPos test_pos_nw { - new_player_pos.x - player_half_width, new_player_pos.y + player_quarter_height, - player->position.tile_x, player->position.tile_y, player->position.tile_z - }; - test_pos_nw = recannonicalize_position( tile_map, test_pos_nw ); - collision_nw = ! TileMap_is_point_empty( tile_map, test_pos_nw ); - - TileMapPos test_pos_ne { - new_player_pos.x + player_half_width, new_player_pos.y + player_quarter_height, - player->position.tile_x, player->position.tile_y, player->position.tile_z - }; - test_pos_ne = recannonicalize_position( tile_map, test_pos_ne ); - collision_ne = ! TileMap_is_point_empty( tile_map, test_pos_ne ); - - TileMapPos test_pos_sw { - new_player_pos.x - player_half_width, new_player_pos.y, - player->position.tile_x, player->position.tile_y, player->position.tile_z - }; - test_pos_sw = recannonicalize_position( tile_map, test_pos_sw ); - collision_sw = ! TileMap_is_point_empty( tile_map, test_pos_sw ); - - TileMapPos test_pos_se { - new_player_pos.x + player_half_width, new_player_pos.y, - player->position.tile_x, player->position.tile_y, player->position.tile_z - }; - test_pos_se = recannonicalize_position( tile_map, test_pos_se ); - collision_se = ! TileMap_is_point_empty( tile_map, test_pos_se ); - } - while(0); - - if ( collision_se || collision_sw || collision_ne || collision_nw ) - { - // Should be colliding with a wall - - Vec2 wall_vector = { 0, 0 }; - if ( collision_nw && collision_sw ) + b32 collision_nw = false; + b32 collision_ne = false; + b32 collision_sw = false; + b32 collision_se = false; + do { - wall_vector = { 1.f, 0.f }; - } - if ( collision_ne && collision_se ) + // Base position + //TileMapPos test_pos = { + //new_player_pos.x, new_player_pos.y, + //old_pos.tile_x, old_pos.tile_y, old_pos.tile_z + //}; + //test_pos = recannonicalize_position( tile_map, test_pos ); + + // TODO(Ed) : Need a delta-function that auto-reconnonicalizes. + + TileMapPos test_pos_nw { + new_player_pos.x - player_half_width, new_player_pos.y + player_quarter_height, + old_pos.tile_x, old_pos.tile_y, old_pos.tile_z + }; + test_pos_nw = recannonicalize_position( tile_map, test_pos_nw ); + collision_nw = ! TileMap_is_point_empty( tile_map, test_pos_nw ); + + TileMapPos test_pos_ne { + new_player_pos.x + player_half_width, new_player_pos.y + player_quarter_height, + old_pos.tile_x, old_pos.tile_y, old_pos.tile_z + }; + test_pos_ne = recannonicalize_position( tile_map, test_pos_ne ); + collision_ne = ! TileMap_is_point_empty( tile_map, test_pos_ne ); + + TileMapPos test_pos_sw { + new_player_pos.x - player_half_width, new_player_pos.y, + old_pos.tile_x, old_pos.tile_y, old_pos.tile_z + }; + test_pos_sw = recannonicalize_position( tile_map, test_pos_sw ); + collision_sw = ! TileMap_is_point_empty( tile_map, test_pos_sw ); + + TileMapPos test_pos_se { + new_player_pos.x + player_half_width, new_player_pos.y, + old_pos.tile_x, old_pos.tile_y, old_pos.tile_z + }; + test_pos_se = recannonicalize_position( tile_map, test_pos_se ); + collision_se = ! TileMap_is_point_empty( tile_map, test_pos_se ); + } + while(0); + + if ( collision_se || collision_sw || collision_ne || collision_nw ) { - wall_vector = { -1.f, 0.f }; - } - if ( collision_nw && collision_ne ) - { - wall_vector = { 0.f, 1.f }; - } - if ( collision_se && collision_sw ) - { - wall_vector = { 0.f, -1.f }; + // Should be colliding with a wall + + Vec2 wall_vector = { 0, 0 }; + if ( collision_nw && collision_sw ) + { + wall_vector = { 1.f, 0.f }; + } + { + wall_vector = { -1.f, 0.f }; + } + if ( collision_nw && collision_ne ) + { + wall_vector = { 0.f, 1.f }; + } + if ( collision_se && collision_sw ) + { + wall_vector = { 0.f, -1.f }; + } + + //if ( collision_nw && !collision_ne && !collision_sw && !collision_se ) + //{ + // wall_vector = { 1.f, 1.f }; + //} + + // The 2x multiplier allows for the the "bounce off" velocity to occur instead of the player just looking like they impacted the wall and stopped + player->move_velocity -= cast( Vel2, 1.f * scalar_product( Vec2( player->move_velocity ), wall_vector ) * wall_vector ); + + new_player_pos = { old_pos.rel_pos.x, old_pos.rel_pos.y }; + new_player_pos += player->move_velocity; } - //if ( collision_nw && !collision_ne && !collision_sw && !collision_se ) - //{ - // wall_vector = { 1.f, 1.f }; - //} - - // The 2x multiplier allows for the the "bounce off" velocity to occur instead of the player just looking like they impacted the wall and stopped - player->move_velocity -= cast( Vel2, 1.f * scalar_product( Vec2( player->move_velocity ), wall_vector ) * wall_vector ); - - - new_player_pos = { player->position.rel_pos.x, player->position.rel_pos.y }; - new_player_pos += player->move_velocity; + TileMapPos new_pos = { + new_player_pos.x, new_player_pos.y, + old_pos.tile_x, old_pos.tile_y, old_pos.tile_z + }; + new_pos = recannonicalize_position( tile_map, new_pos ); + player->position = new_pos; } + #else + { + TileMapPos new_pos = { + new_player_pos.x, new_player_pos.y, + old_pos.tile_x, old_pos.tile_y, old_pos.tile_z + }; + new_pos = recannonicalize_position( tile_map, new_pos ); - TileMapPos new_pos = { - new_player_pos.x, new_player_pos.y, - player->position.tile_x, player->position.tile_y, player->position.tile_z - }; - new_pos = recannonicalize_position( tile_map, new_pos ); - - bool on_new_tile = TileMap_are_on_same_tile( & new_pos, & player->position ); + s32 min_tile_x = 0; + s32 min_tile_y = 0; + + TileMapPos best_position = old_pos; + Dist2 best_distance2 = cast(Dist2, magnitude_squared( player->move_velocity ) ); + + for ( s32 tile_y = 0; tile_y <= min_tile_y; ++ tile_y ) + { + for ( s32 tile_x = 0; tile_x <= min_tile_x; ++ tile_x ) + { + TileMapPos test_tile_pos = centered_tile_point( tile_x, tile_y, new_pos.tile_z ); + s32 tile_value = TileMap_get_tile_value( tile_map, test_tile_pos ); + + if ( TileMap_is_tile_value_empty( tile_value ) ) + { + Vec2 tile_xy_in_meters = Vec2 { tile_map->tile_size_in_meters, tile_map->tile_size_in_meters }; + + Vec2 min_corner = -0.5f * tile_xy_in_meters; + Vec2 max_corner = 0.5f * tile_xy_in_meters; + + TileMapPos rel_new_player_pos = subtract( test_tile_pos, new_pos ); + Vec2 test_pos = closest_point_in_rectangle( min_corner, max_corner, rel_new_player_pos ); + + f32 test_dist2 = ; + if ( best_distance2 > test_dst ) + { + best_position = ; + best_distance2 = ; + } + } + } + } + + player->position = new_pos; + } + #endif + + bool on_new_tile = TileMap_are_on_same_tile( & player->position, & old_pos ); if ( ! on_new_tile ) { - u32 new_tile_value = TileMap_get_tile_value( tile_map, new_pos ); + u32 new_tile_value = TileMap_get_tile_value( tile_map, player->position ); if ( new_tile_value == 3 ) { - ++ new_pos.tile_z; + ++ player->position.tile_z; } else if ( new_tile_value == 4 ) { - -- new_pos.tile_z; + -- player->position.tile_z; } } - player->position = new_pos; - if ( player_actions.player_y_move_digital > 0 || player_actions.player_y_move_analog > 0 ) { game_state->hero_direction = HeroBitmaps_Back; diff --git a/project/engine/gen/physics.hpp b/project/engine/gen/physics.hpp index 4ae6a7f..ac44c21 100644 --- a/project/engine/gen/physics.hpp +++ b/project/engine/gen/physics.hpp @@ -66,6 +66,12 @@ inline f32 scalar_product( Pos2_f32 a, Pos2_f32 b ) return result; } +inline f32 magnitude_squared( Pos2_f32 v ) +{ + f32 result = scalar_product( v, v ); + return result; +} + inline Pos2_f32 operator-( Pos2_f32 v ) { Pos2_f32 result { -v.x, -v.y }; @@ -201,6 +207,12 @@ inline f32 scalar_product( Vel2_f32 a, Vel2_f32 b ) return result; } +inline f32 magnitude_squared( Vel2_f32 v ) +{ + f32 result = scalar_product( v, v ); + return result; +} + inline Vel2_f32 operator-( Vel2_f32 v ) { Vel2_f32 result { -v.x, -v.y }; @@ -326,6 +338,12 @@ inline f32 scalar_product( Accel2_f32 a, Accel2_f32 b ) return result; } +inline f32 magnitude_squared( Accel2_f32 v ) +{ + f32 result = scalar_product( v, v ); + return result; +} + inline Accel2_f32 operator-( Accel2_f32 v ) { Accel2_f32 result { -v.x, -v.y }; diff --git a/project/engine/gen/vectors.hpp b/project/engine/gen/vectors.hpp index 98cd0f1..12b66f2 100644 --- a/project/engine/gen/vectors.hpp +++ b/project/engine/gen/vectors.hpp @@ -55,6 +55,12 @@ inline f32 scalar_product( Vec2_f32 a, Vec2_f32 b ) return result; } +inline f32 magnitude_squared( Vec2_f32 v ) +{ + f32 result = scalar_product( v, v ); + return result; +} + inline Vec2_f32 operator-( Vec2_f32 v ) { Vec2_f32 result { -v.x, -v.y }; diff --git a/project/engine/tile_map.cpp b/project/engine/tile_map.cpp index 020fbda..5487376 100644 --- a/project/engine/tile_map.cpp +++ b/project/engine/tile_map.cpp @@ -94,7 +94,7 @@ TileChunk* TileMap_get_chunk( TileMap* tile_map, s32 tile_chunk_x, s32 tile_chun } inline -TileChunkPosition get_tile_chunk_position_for( TileMap* tile_map, u32 abs_tile_x, u32 abs_tile_y, u32 abs_tile_z ) +TileChunkPosition get_tile_chunk_position_for( TileMap* tile_map, s32 abs_tile_x, s32 abs_tile_y, s32 abs_tile_z ) { assert( tile_map != nullptr ); @@ -130,6 +130,16 @@ u32 TileMap_get_tile_value( TileMap* tile_map, TileMapPos position ) return value; } +internal +b32 TileMap_is_tile_value_empty(s32 tile_value) +{ + b32 + is_empty = tile_value == 1; + is_empty |= tile_value == 3; + is_empty |= tile_value == 4; + return is_empty; +} + internal b32 TileMap_is_point_empty( TileMap* tile_map, TileMapPos position ) { @@ -137,11 +147,7 @@ b32 TileMap_is_point_empty( TileMap* tile_map, TileMapPos position ) u32 chunk_value = TileMap_get_tile_value( tile_map, position.tile_x, position.tile_y, position.tile_z ); - b32 - is_empty = chunk_value == 1; - is_empty |= chunk_value == 3; - is_empty |= chunk_value == 4; - return is_empty; + return TileMap_is_tile_value_empty( chunk_value ); } internal @@ -177,4 +183,14 @@ b32 TileMap_are_on_same_tile( TileMapPos* pos_a, TileMapPos* pos_b ) return result; } +inline +TileMapPos centered_tile_point( s32 tile_x, s32 tile_y, s32 tile_z ) +{ + TileMapPos result {}; + result.tile_x = tile_x; + result.tile_y = tile_y; + result.tile_z = tile_z; + return result; +} + NS_ENGINE_END diff --git a/project/handmade_engine.cpp b/project/handmade_engine.cpp index 8bdcd00..331685e 100644 --- a/project/handmade_engine.cpp +++ b/project/handmade_engine.cpp @@ -34,3 +34,4 @@ Handmade Engine Translation Unit #include "tile_map.cpp" #include "random.cpp" #include "engine.cpp" +