PadWorld-Entertainment / worldofpadman

World of PADMAN game repository
https://worldofpadman.net
Other
37 stars 8 forks source link

CG_WorldToScreen not working correct with new widescreen aspect ratio #228

Closed kai-li-wop closed 7 months ago

kai-li-wop commented 7 months ago

Seems, that all elements using CG_WorldToScreen are not working correctly since widescreen de-streched HUD got introduced. Especially all wallhack icons are floating around like crazy.

kai-li-wop commented 7 months ago

It seems that the fix works so far regarding the crazy floating around icons. But at a closer look, it seems that there is still some minor offset. The icon should be centred above the station but seem to be slight out of centre.

Image

mgerhardy commented 7 months ago

wip - not yet working. maybe I use the axis wrong

edit: a the scale to SCREEN_WIDTH and SCREEN_HEIGHT is missing (and cg_viewsize)

/**
 * @brief Converts a world-space point to screen-space coordinates.
 *
 * This function takes a world-space point and transforms it into screen-space coordinates
 * based on the current camera settings and field of view.
 *
 * @param point The world-space coordinates of the point to be transformed.
 * @param x Pointer to store the resulting x-coordinate in screen space. Pass NULL if not needed.
 * @param y Pointer to store the resulting y-coordinate in screen space. Pass NULL if not needed.
 *
 * @return Returns true if the point is in front of the camera and has valid screen-space coordinates,
 *         false otherwise. This check is based on a small epsilon value to avoid precision issues.
 */
qboolean CG_WorldToScreen(const vec3_t point, float *x, float *y) {
    vec3_t trans;
    vec3_t camera_point;
    vec3_t forward, right, up;
    float z;

    VectorSubtract(point, cg.refdef.vieworg, trans);
    VectorCopy(cg.refdef.viewaxis[0], forward);
    VectorCopy(cg.refdef.viewaxis[1], right);
    VectorCopy(cg.refdef.viewaxis[2], up);

    camera_point[0] = trans[0] * right[0] + trans[1] * up[0] + trans[2] * forward[0];
    camera_point[1] = trans[0] * right[1] + trans[1] * up[1] + trans[2] * forward[1];
    camera_point[2] = trans[0] * right[2] + trans[1] * up[2] + trans[2] * forward[2];

    // Apply perspective projection
    if (x) {
        *x = (cg.refdef.fov_x / camera_point[2]) * camera_point[0] + cg.refdef.width / 2.0f;
    }

    if (y) {
        *y = (cg.refdef.fov_y / camera_point[2]) * camera_point[1] + cg.refdef.height / 2.0f;
    }

    return camera_point[2] > 0.001f;
}

I also think, that this is more correct because it takes the cg_viewsize percentage into account.

diff --git a/code/cgame/cg_drawtools.c b/code/cgame/cg_drawtools.c
index 6807bcf4..6a956f37 100644
--- a/code/cgame/cg_drawtools.c
+++ b/code/cgame/cg_drawtools.c
@@ -763,11 +763,11 @@ qboolean CG_WorldToScreen(const vec3_t point, float *x, float *y) {
        }

        if (x) {
-               *x = (float)screenWidth * 0.5f - DotProduct(trans, cg.refdef.viewaxis[1]) * xc / (z * px);
+               *x = xc - DotProduct(trans, cg.refdef.viewaxis[1]) * xc / (z * px);
        }

        if (y) {
-               *y = (float)screenHeight * 0.5f - DotProduct(trans, cg.refdef.viewaxis[2]) * yc / (z * py);
+               *y = yc - DotProduct(trans, cg.refdef.viewaxis[2]) * yc / (z * py);
        }

        return front;
kai-li-wop commented 7 months ago

Should be fixed with #233, at least I can confirm it. Thx to everyone contributing!

3aTmE commented 7 months ago

Just tested it with regular ffa and Big Baloon and can confirm the fix! 👍

All icons are shown correctly so far.