-
Notifications
You must be signed in to change notification settings - Fork 6
Better player mesh collision #308
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,79 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include <algorithm> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include <patch_common/CallHook.h> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include <patch_common/FunHook.h> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include <patch_common/CodeInjection.h> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include <patch_common/AsmWriter.h> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include <xlog/xlog.h> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include "../rf/vmesh.h" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include "../rf/physics.h" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include "../rf/object.h" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Mesh collision in the RF engine uses per-triangle intersection tests (vmesh_collide) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // rather than BSP-based solid collision (GSolid::collide). This makes it fundamentally | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // less robust: triangle soup has gaps at edges/seams, no concept of a closed solid | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // volume, and limited multi-hit resolution. These patches improve mesh collision | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // reliability to reduce "falling through" and "getting stuck" on mesh surfaces. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Small margin added to the collision sphere radius when testing physics collision | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // against mesh triangles. This closes gaps at triangle edges/seams by making the | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // effective collision volume slightly larger, preventing the sphere from slipping | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // between adjacent triangles. The margin is small enough to not noticeably affect | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // gameplay feel. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| static constexpr float mesh_radius_margin = 0.02f; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Small amount subtracted from hit_time after mesh collision detection. This ensures | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // the object stops slightly before the mesh surface, providing clearance that prevents | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // the object from getting embedded in the mesh on the next frame. This reduces the | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // oscillation/"stuck" behavior that occurs when conflicting normals from adjacent | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // triangles push the player back and forth. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| static constexpr float mesh_hit_time_safety = 0.005f; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Hook vmesh_collide (0x005031F0) at its call sites in the physics collision paths. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // This inflates the collision radius for the duration of the mesh test only, making | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // the swept sphere slightly larger and closing edge gaps between mesh triangles. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Call sites: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // 0x00499BD2 - collide_spheres_mesh: ground contact and stick-to-ground tests | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // 0x0049B332 - collide_object_object_mesh: object-pair mesh collision | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Other vmesh_collide callers (weapon raycasts, line-of-sight, glare occlusion) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // are intentionally not hooked as they need precise triangle-level accuracy. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CallHook<bool(rf::VMesh*, rf::VMeshCollisionInput*, rf::VMeshCollisionOutput*, bool)> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| mesh_physics_collide_radius_hook{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 0x00499BD2, // in collide_spheres_mesh | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+31
to
+44
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Hook vmesh_collide (0x005031F0) at its call sites in the physics collision paths. | |
| // This inflates the collision radius for the duration of the mesh test only, making | |
| // the swept sphere slightly larger and closing edge gaps between mesh triangles. | |
| // | |
| // Call sites: | |
| // 0x00499BD2 - collide_spheres_mesh: ground contact and stick-to-ground tests | |
| // 0x0049B332 - collide_object_object_mesh: object-pair mesh collision | |
| // | |
| // Other vmesh_collide callers (weapon raycasts, line-of-sight, glare occlusion) | |
| // are intentionally not hooked as they need precise triangle-level accuracy. | |
| CallHook<bool(rf::VMesh*, rf::VMeshCollisionInput*, rf::VMeshCollisionOutput*, bool)> | |
| mesh_physics_collide_radius_hook{ | |
| { | |
| 0x00499BD2, // in collide_spheres_mesh | |
| // Hook vmesh_collide (0x005031F0) at selected call sites in the physics collision paths. | |
| // This inflates the collision radius for the duration of the mesh test only, making | |
| // the swept sphere slightly larger and closing edge gaps between mesh triangles. | |
| // | |
| // Call sites: | |
| // 0x0049B332 - collide_object_object_mesh: object-pair mesh collision | |
| // | |
| // The collide_spheres_mesh path at 0x00499BD2 is handled by the vmesh_col_fix | |
| // CodeInjection in game_patch/misc/misc.cpp. Installing a CallHook there would | |
| // overlap with that injection and risk corrupting the patched code. | |
| // | |
| // Other vmesh_collide callers (weapon raycasts, line-of-sight, glare occlusion) | |
| // are intentionally not hooked as they need precise triangle-level accuracy. | |
| CallHook<bool(rf::VMesh*, rf::VMeshCollisionInput*, rf::VMeshCollisionOutput*, bool)> | |
| mesh_physics_collide_radius_hook{ | |
| { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file includes several headers that aren't used by the current implementation (, <patch_common/CodeInjection.h>, <patch_common/AsmWriter.h>, <xlog/xlog.h>, and ../rf/physics.h). Please remove unused includes to reduce compile time and avoid accidental dependency on transitive includes.