feat: implement custom W2S and refactor skeleton ESP to fix line stretching#961
feat: implement custom W2S and refactor skeleton ESP to fix line stretching#961matveyel wants to merge 3 commits into
Conversation
…ustom CViewport W2S implementation
|
GET_SCREEN_COORD_FROM_WORLD_COORD returns false if the coordinates given are not visible to the rendering camera. See https://alloc8or.re/gta5/nativedb/enhanced/?n=0x34E82F05DF2974F5 |
Yes, but it's limited by the player's field of view, which makes it difficult to draw a skeleton bone if one of its points is outside the field of view but remains in front of the camera plane. |
Hi everyone! This is my first pull request to YimMenu, so I apologize in advance if I missed any code style conventions or formatting rules. I'm open to any feedback!
🐛 The Problem
While using the Skeleton ESP, I noticed a severe visual bug: whenever a part of a ped's skeleton goes out of the field of view (FOV), the ESP lines stretch across the entire screen towards the top-left corner.
After some debugging, I found that the native
GET_SCREEN_COORD_FROM_WORLD_COORDdoes not calculate actual off-screen coordinates. Instead, it forcefully returns(-1, -1)(or similar fallback values) when a point is outside the FOV. Because of this, the drawing logic connects the visible bone to these fallback coordinates, causing the massive line stretching.🛠️ The Solution
To fix this, I reverse-engineered the native function to see how it calculates projections under the hood. I recreated the mechanics by directly reading the engine's matrices, completely bypassing the native's fallback behavior.
Changes made:
CViewportpointer.WorldToScreenPointfunction that manually multiplies the View and Projection matrices. It calculates screen coordinates only if the point is in front of the camera (clipW > 0). If the point is behind the camera, it aborts the calculation and returns fallback coordinates(0.0f, 0.0f)alongside afalseboolean.DrawSkeletonfunction to utilize this boolean return value. It now safely evaluates both joints (via a lambda) and only adds a line to the draw list if both points are strictly in front of the camera, which completely eliminates the stretching bug.❓ Note on Architecture
Since I am new to the codebase, I wasn't entirely sure where the best place to put the
WorldToScreenPointfunction would be. For now, I placed it directly inesp.cpp.If there is a better place for it (e.g., a math/utility class or a specific rendering header), please let me know, and I will gladly move it!