diff --git a/src/trx/config/map.def b/src/trx/config/map.def index a05bd62f67..8bf68b96d7 100644 --- a/src/trx/config/map.def +++ b/src/trx/config/map.def @@ -7,6 +7,7 @@ X_CFG_BOOL(audio.enable_underwater_anim_sfx, true) X_CFG_BOOL(audio.fix_chainblock_secret_sound, true) X_CFG_BOOL(audio.mute_out_of_focus, true) X_CFG_BOOL(debug.enable_debug_camera, false) +X_CFG_BOOL(debug.enable_debug_collision, false) X_CFG_BOOL(debug.enable_debug_cuboids, false) X_CFG_BOOL(debug.enable_debug_portals, false) X_CFG_BOOL(debug.enable_debug_pos, false) diff --git a/src/trx/config/types.h b/src/trx/config/types.h index 35ac76f1d9..7fb4e2f9c5 100644 --- a/src/trx/config/types.h +++ b/src/trx/config/types.h @@ -277,6 +277,7 @@ typedef struct { bool enable_debug_room_clip; bool enable_debug_spheres; bool enable_debug_cuboids; + bool enable_debug_collision; bool enable_debug_pos; bool enable_debug_camera; bool enable_review_markers; diff --git a/src/trx/game/collision.c b/src/trx/game/collision.c index 94b3ab0c85..3cdeb3c4c4 100644 --- a/src/trx/game/collision.c +++ b/src/trx/game/collision.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -25,7 +26,7 @@ static bool M_IsOnWalkable( static void M_FillSide( const COLL_INFO *const coll, COLL_SIDE *const side, const int32_t x_pos, const int32_t z_pos, const int32_t y_pos, const int32_t obj_height, - int16_t *const room_num) + int16_t *const room_num, int32_t sphere_num) { const int32_t y = y_pos - obj_height; const int32_t y_top = y - M_HEADROOM; @@ -76,6 +77,13 @@ static void M_FillSide( side->floor = NO_HEIGHT; side->ceiling = NO_HEIGHT; } + + if (g_Config.debug.enable_debug_collision) { + LARA_INFO *const lara = Lara_GetLaraInfo(); + const XYZ_32 pos = { .x = x_pos, .y = y_pos, .z = z_pos }; + const DEBUG_COLLISION_SPHERE sphere = { .pos = pos, coll->radius }; + lara->debug_collision[sphere_num] = sphere; + } } int32_t Collide_GetSpheres( @@ -321,24 +329,24 @@ void Collide_GetCollisionInfo( M_FillSide( coll, &coll->side_front, x_pos + x_front, z_pos + z_front, y_pos, - obj_height, &room_num); + obj_height, &room_num, 0); int16_t room_num2; room_num2 = prev_room_num; M_FillSide( coll, &coll->side_left, x_pos + x_left, z_pos + z_left, y_pos, - obj_height, &room_num2); + obj_height, &room_num2, 1); room_num2 = prev_room_num; M_FillSide( coll, &coll->side_right, x_pos + x_right, z_pos + z_right, y_pos, - obj_height, &room_num2); + obj_height, &room_num2, 2); M_FillSide( coll, &coll->side_left2, x_pos + x_left, z_pos + z_left, y_pos, - obj_height, &room_num); + obj_height, &room_num, 3); M_FillSide( coll, &coll->side_right2, x_pos + x_right, z_pos + z_right, y_pos, - obj_height, &room_num); + obj_height, &room_num, 4); const int16_t static_room_num = g_TRVersion >= 3 ? prev_room_num : room_num; if (Collide_CollideStaticObjects( diff --git a/src/trx/game/console/cmd/debug.c b/src/trx/game/console/cmd/debug.c index 6d43cca173..0854202865 100644 --- a/src/trx/game/console/cmd/debug.c +++ b/src/trx/game/console/cmd/debug.c @@ -17,6 +17,7 @@ static DEBUG_OPTION_ENTRY m_AllOptions[] = { { &g_Config.debug.enable_debug_triggers, nullptr }, { &g_Config.debug.enable_debug_spheres, nullptr }, { &g_Config.debug.enable_debug_cuboids, nullptr }, + { &g_Config.debug.enable_debug_collision, nullptr }, { &g_Config.debug.enable_debug_pos, nullptr }, { &g_Config.debug.enable_debug_camera, nullptr }, { nullptr, nullptr } diff --git a/src/trx/game/lara/draw.c b/src/trx/game/lara/draw.c index 04cd6145b0..9519e5f9fa 100644 --- a/src/trx/game/lara/draw.c +++ b/src/trx/game/lara/draw.c @@ -14,6 +14,17 @@ static bool m_CacheMatrices = false; +static void M_DrawCollisionBounds( + const LARA_INFO *const lara, int32_t sphere_num) +{ + Matrix_PushUnit(); + Matrix_TranslateAbs32(lara->debug_collision[sphere_num].pos); + Output_DrawSphereAbs32( + lara->debug_collision[sphere_num].pos, + lara->debug_collision[sphere_num].radius); + Matrix_Pop(); +} + static void M_CacheMatrix(const LARA_MESH mesh) { if (!m_CacheMatrices) { @@ -125,6 +136,12 @@ static bool M_Draw_I( Output_DrawCuboid(&frame1->bounds); } + if (g_Config.debug.enable_debug_collision) { + for (int i = 0; i < DEBUG_COLL_SPHERES_MAX; i++) { + M_DrawCollisionBounds(lara, i); + } + } + m_CacheMatrices = is_lara; if (m_CacheMatrices) { lara->mesh_pos_matrices_valid = false; @@ -423,6 +440,12 @@ bool Lara_Draw(const ITEM *const item) Output_DrawCuboid(&frame->bounds); } + if (g_Config.debug.enable_debug_collision) { + for (int i = 0; i < 5; i++) { + M_DrawCollisionBounds(lara, i); + } + } + m_CacheMatrices = is_lara; if (m_CacheMatrices) { lara->mesh_pos_matrices_valid = false; diff --git a/src/trx/game/lara/types.h b/src/trx/game/lara/types.h index b5ca772765..d89d4c9fd8 100644 --- a/src/trx/game/lara/types.h +++ b/src/trx/game/lara/types.h @@ -9,6 +9,13 @@ #include #include +#define DEBUG_COLL_SPHERES_MAX 5 + +typedef struct { + XYZ_32 pos; // world space + int32_t radius; // world units +} DEBUG_COLLISION_SPHERE; + typedef struct { ANIM_FRAME *frame_base; int16_t frame_num; @@ -111,6 +118,7 @@ typedef struct { MATRIX mesh_pos_matrices[LM_NUMBER_OF]; bool mesh_pos_matrices_valid; + DEBUG_COLLISION_SPHERE debug_collision[DEBUG_COLL_SPHERES_MAX]; // TR3: persistent gun smoke spawned from muzzle after firing. int32_t tr3_smoke_count_l; diff --git a/src/trx/game/output/draw.c b/src/trx/game/output/draw.c index df41522747..ec6880ca64 100644 --- a/src/trx/game/output/draw.c +++ b/src/trx/game/output/draw.c @@ -403,6 +403,15 @@ void Output_DrawSphere(const XYZ_16 center, const int32_t radius) Matrix_Pop(); } +void Output_DrawSphereAbs32(const XYZ_32 center, const int32_t radius) +{ + Matrix_PushUnit(); + Matrix_TranslateAbs32(center); + Matrix_Scale(radius << W2V_SHIFT); + OutputSource_Misc_StageSphere(); + Matrix_Pop(); +} + void Output_DrawCuboid(const BOUNDS_16 *const bounds) { const int32_t x0 = bounds->min.x; diff --git a/src/trx/game/output/draw.h b/src/trx/game/output/draw.h index a1c171e4ae..16332831c1 100644 --- a/src/trx/game/output/draw.h +++ b/src/trx/game/output/draw.h @@ -33,4 +33,5 @@ void Output_DrawScreenFrame( RGBA_8888 col_light, float thickness); void Output_DrawSphere(XYZ_16 center, int32_t radius); +void Output_DrawSphereAbs32(XYZ_32 center, int32_t radius); void Output_DrawCuboid(const BOUNDS_16 *bounds);