From 3c39edc1ef25003285f0edb01754c6d17a98857b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Sun, 15 Dec 2024 13:24:54 +0100 Subject: [PATCH] Fall back to old algorithm when on the line --- src/r_main.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ src/r_main.h | 13 +++++++++++-- 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/src/r_main.c b/src/r_main.c index c0b97616a..7cacbb610 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -246,6 +246,55 @@ static void FlipCam2_OnChange(void) SendWeaponPref2(); } +// +// R_PointOnSide +// Traverse BSP (sub) tree, +// check point against partition plane. +// Returns side 0 (front) or 1 (back). +// +// killough 5/2/98: reformatted +// +INT32 R_OldPointOnSide(fixed_t x, fixed_t y, node_t *restrict node) +{ + if (!node->dx) + return x <= node->x ? node->dy > 0 : node->dy < 0; + + if (!node->dy) + return y <= node->y ? node->dx < 0 : node->dx > 0; + + fixed_t dx = (x >> 1) - (node->x >> 1); + fixed_t dy = (y >> 1) - (node->y >> 1); + + // Try to quickly decide by looking at sign bits. + // also use a mask to avoid branch prediction + INT32 mask = (node->dy ^ node->dx ^ dx ^ dy) >> 31; + return (mask & ((node->dy ^ dx) < 0)) | // (left is negative) + (~mask & (FixedMul(dy, node->dx>>FRACBITS) >= FixedMul(node->dy>>FRACBITS, dx))); +} + +// killough 5/2/98: reformatted +INT32 R_OldPointOnSegSide(fixed_t x, fixed_t y, seg_t *line) +{ + fixed_t lx = line->v1->x; + fixed_t ly = line->v1->y; + fixed_t ldx = line->v2->x - lx; + fixed_t ldy = line->v2->y - ly; + + if (!ldx) + return x <= lx ? ldy > 0 : ldy < 0; + + if (!ldy) + return y <= ly ? ldx < 0 : ldx > 0; + + fixed_t dx = (x >> 1) - (lx >> 1); + fixed_t dy = (y >> 1) - (ly >> 1); + + // Try to quickly decide by looking at sign bits. + if ((ldy ^ ldx ^ dx ^ dy) < 0) + return (ldy ^ dx) < 0; // (left is negative) + return FixedMul(dy, ldx>>FRACBITS) >= FixedMul(ldy>>FRACBITS, dx); +} + // // R_PointToAngle // To get a global angle from cartesian coordinates, diff --git a/src/r_main.h b/src/r_main.h index c65154dd2..9767f4b69 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -71,11 +71,17 @@ extern lighttable_t *zlight[LIGHTLEVELS][MAXLIGHTZ]; // There a 0-31, i.e. 32 LUT in the COLORMAP lump. #define NUMCOLORMAPS 32 +INT32 R_OldPointOnSide(fixed_t x, fixed_t y, node_t *node); +INT32 R_OldPointOnSegSide(fixed_t x, fixed_t y, seg_t *line); + // Utility functions. static inline INT32 R_PointOnSide(fixed_t x, fixed_t y, node_t *node) { // use cross product to determine side quickly - return ((INT64)y - node->y) * node->dx - ((INT64)x - node->x) * node->dy > 0; + INT64 v = ((INT64)y - node->y) * node->dx - ((INT64)x - node->x) * node->dy; + if (v == 0) // if we're on the line, use the old algorithm + return R_OldPointOnSide(x, y, node); + return v > 0; } static inline INT32 R_PointOnSegSide(fixed_t x, fixed_t y, seg_t *line) @@ -86,7 +92,10 @@ static inline INT32 R_PointOnSegSide(fixed_t x, fixed_t y, seg_t *line) fixed_t ldy = line->v2->y - ly; // use cross product to determine side quickly - return ((INT64)y - ly) * ldx - ((INT64)x - lx) * ldy > 0; + INT64 v = ((INT64)y - ly) * ldx - ((INT64)x - lx) * ldy > 0; + if (v == 0) // if we're on the line, use the old algorithm + return R_OldPointOnSegSide(x, y, line); + return v > 0; } angle_t R_PointToAngle(fixed_t x, fixed_t y);