diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 5feef98b2..cc1b6b8f3 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1843,7 +1843,7 @@ static void CL_ReloadReceivedSavegame(void) for (i = 0; i < MAXSPLITSCREENPLAYERS; i++) { - camera[i].subsector = R_PointInSubsector(camera[i].x, camera[i].y); + camera[i].subsector = R_PointInSubsectorFast(camera[i].x, camera[i].y); } cl_redownloadinggamestate = false; diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 40b488a8e..06d4e75a6 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -3103,7 +3103,7 @@ static void HWR_RenderBSPNode(INT32 bspnum) bsp = &nodes[bspnum]; // Decide which side the view point is on. - side = R_PointOnSide(viewx, viewy, bsp); + side = R_PointOnSideFast(viewx, viewy, bsp); // Recursively divide front space. if (HWR_PortalCheckBBox(bsp->bbox[side])) @@ -3177,7 +3177,7 @@ static gl_vissprite_t *HWR_NewVisSprite(void) // Finds a floor through which light does not pass. static fixed_t HWR_OpaqueFloorAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height) { - const sector_t *sec = R_PointInSubsector(x, y)->sector; + const sector_t *sec = R_PointInSubsectorFast(x, y)->sector; fixed_t floorz = sec->floorheight; if (sec->ffloors) diff --git a/src/hardware/hw_portal.c b/src/hardware/hw_portal.c index d433b78cd..120e59e6c 100644 --- a/src/hardware/hw_portal.c +++ b/src/hardware/hw_portal.c @@ -132,7 +132,7 @@ void HWR_PortalFrame(gl_portal_t* portal) { portalclipline = NULL; portalcullsector = NULL; - viewsector = R_PointInSubsector(viewx, viewy)->sector; + viewsector = R_PointInSubsectorFast(viewx, viewy)->sector; } } diff --git a/src/p_mobj.c b/src/p_mobj.c index 2420d2a50..8dbb3232f 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -3307,7 +3307,7 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled P_CheckCameraPosition(thiscam->x, thiscam->y, thiscam); #endif - thiscam->subsector = R_PointInSubsector(thiscam->x, thiscam->y); + thiscam->subsector = R_PointInSubsectorFast(thiscam->x, thiscam->y); thiscam->floorz = tmfloorz; thiscam->ceilingz = tmceilingz; @@ -10354,7 +10354,7 @@ void P_PrecipitationEffects(void) for (y = yl; y <= yh; y += RADIUSSTEP) for (x = xl; x <= xh; x += RADIUSSTEP) { - if (R_PointInSubsector((fixed_t)x, (fixed_t)y)->sector->ceilingpic != skyflatnum) // Found the outdoors! + if (R_PointInSubsectorFast((fixed_t)x, (fixed_t)y)->sector->ceilingpic != skyflatnum) // Found the outdoors! continue; newdist = S_CalculateSoundDistance(players[displayplayers[0]].mo->x, players[displayplayers[0]].mo->y, 0, (fixed_t)x, (fixed_t)y, 0); diff --git a/src/p_setup.c b/src/p_setup.c index 27bd62eb7..8c0b0d238 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2338,7 +2338,7 @@ static void P_SetupCamera(UINT8 pnum, camera_t *cam) cam->y = players[pnum].mo->y; cam->z = players[pnum].mo->z; cam->angle = players[pnum].mo->angle; - cam->subsector = R_PointInSubsector(cam->x, cam->y); // make sure camera has a subsector set -- Monster Iestyn (12/11/18) + cam->subsector = R_PointInSubsectorFast(cam->x, cam->y); // make sure camera has a subsector set -- Monster Iestyn (12/11/18) } else { @@ -2362,7 +2362,7 @@ static void P_SetupCamera(UINT8 pnum, camera_t *cam) cam->y = thing->y; cam->z = thing->z; cam->angle = FixedAngle((fixed_t)thing->angle << FRACBITS); - cam->subsector = R_PointInSubsector(cam->x, cam->y); // make sure camera has a subsector set -- Monster Iestyn (12/11/18) + cam->subsector = R_PointInSubsectorFast(cam->x, cam->y); // make sure camera has a subsector set -- Monster Iestyn (12/11/18) } } diff --git a/src/p_user.c b/src/p_user.c index 49916ce77..3f6ab2d4a 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -3228,7 +3228,7 @@ void P_DemoCameraMovement(camera_t *cam) democam.soundmobj = awayviewmobj_hack; // update subsector to avoid crashes; - cam->subsector = R_PointInSubsector(cam->x, cam->y); + cam->subsector = R_PointInSubsectorFast(cam->x, cam->y); } void P_ResetCamera(player_t *player, camera_t *thiscam) @@ -3263,7 +3263,7 @@ void P_ResetCamera(player_t *player, camera_t *thiscam) thiscam->aiming = 0; thiscam->relativex = 0; - thiscam->subsector = R_PointInSubsector(thiscam->x,thiscam->y); + thiscam->subsector = R_PointInSubsectorFast(thiscam->x,thiscam->y); thiscam->radius = 20*FRACUNIT; thiscam->height = 16*FRACUNIT; diff --git a/src/r_bsp.c b/src/r_bsp.c index 989939860..490540eaa 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -1335,7 +1335,8 @@ void R_RenderBSPNode(INT32 bspnum) bsp = &nodes[bspnum]; // Decide which side the view point is on. - side = R_PointOnSide(viewx, viewy, bsp); + side = R_PointOnSideFast(viewx, viewy, bsp); + // Recursively divide front space. R_RenderBSPNode(bsp->children[side]); diff --git a/src/r_fps.c b/src/r_fps.c index feb2ac8f2..4dd7fa044 100644 --- a/src/r_fps.c +++ b/src/r_fps.c @@ -193,7 +193,7 @@ void R_InterpolateView(fixed_t frac, boolean forceinvalid) viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT); viewplayer = newview->player; - viewsector = R_PointInSubsector(viewx, viewy)->sector; + viewsector = R_PointInSubsectorFast(viewx, viewy)->sector; R_SetupFreelook(); } diff --git a/src/r_main.c b/src/r_main.c index 59e5c5e90..28b31de5b 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1080,7 +1080,8 @@ subsector_t *R_IsPointInSubsector(fixed_t x, fixed_t y) while (!(nodenum & NF_SUBSECTOR)) { node = &nodes[nodenum]; - side = R_PointOnSide(x, y, node); + //side = R_PointOnSide(x, y, node); + side = R_PointOnSideFast(x, y, node); // this is fine since R_IsPointInSubsector is only used for precip spawn unless you disable noclipcam lol nodenum = node->children[side]; } diff --git a/src/r_main.h b/src/r_main.h index 804dd543c..553f6a79f 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -74,6 +74,14 @@ extern lighttable_t *zlight[LIGHTLEVELS][MAXLIGHTZ]; // Utility functions. INT32 R_PointOnSide(fixed_t x, fixed_t y, const node_t *node); +// This is not as accurate +// SHOULD NOT BE USED FOR ANYTHING GAMEPLAY RELATED!! +FUNCINLINE static ATTRINLINE PUREFUNC INT32 R_PointOnSideFast(fixed_t x, fixed_t y, const node_t *node) +{ + // use cross product to determine side quickly + return ((INT64)y - node->y) * node->dx - ((INT64)x - node->x) * node->dy > 0; +} + FUNCINLINE static ATTRINLINE PUREFUNC INT32 R_PointOnSegSide(fixed_t x, fixed_t y, const seg_t *line) { fixed_t lx = line->v1->x; @@ -94,6 +102,18 @@ fixed_t R_ScaleFromGlobalAngle(angle_t visangle); subsector_t *R_PointInSubsector(fixed_t x, fixed_t y); subsector_t *R_IsPointInSubsector(fixed_t x, fixed_t y); +// uses R_PointOnSideFast +// SHOULD NOT BE USED FOR ANYTHING GAMEPLAY RELATED!! +FUNCINLINE static ATTRINLINE subsector_t *R_PointInSubsectorFast(fixed_t x, fixed_t y) +{ + size_t nodenum = numnodes-1; + + while (!(nodenum & NF_SUBSECTOR)) + nodenum = nodes[nodenum].children[R_PointOnSideFast(x, y, nodes+nodenum)]; + + return &subsectors[nodenum & ~NF_SUBSECTOR]; +} + #define R_PointToDist(x, y) R_PointToDist2(viewx, viewy, x, y) #define R_PointToDist2(px2, py2, px1, py1) FixedHypot((px1) - (px2), (py1) - (py2)) diff --git a/src/s_sound.c b/src/s_sound.c index 065d56082..33fe7d0a4 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -987,7 +987,7 @@ boolean S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 INT64 x, y, yl, yh, xl, xh; fixed_t newdist; - if (R_PointInSubsector(listensource.x, listensource.y)->sector->ceilingpic == skyflatnum) + if (R_PointInSubsectorFast(listensource.x, listensource.y)->sector->ceilingpic == skyflatnum) approx_dist = 0; else { @@ -1000,7 +1000,7 @@ boolean S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 for (y = yl; y <= yh; y += FRACUNIT*64) for (x = xl; x <= xh; x += FRACUNIT*64) { - if (R_PointInSubsector(x, y)->sector->ceilingpic == skyflatnum) + if (R_PointInSubsectorFast(x, y)->sector->ceilingpic == skyflatnum) { // Found the outdoors! newdist = S_CalculateSoundDistance(listensource.x, listensource.y, 0, x, y, 0);