From 4d518a220c281d1d408a3e7b1dd5029a499e8c0b Mon Sep 17 00:00:00 2001 From: ZZYZX Date: Sun, 10 Jan 2016 05:22:33 +0200 Subject: [PATCH] Fixed skybox clipping: lines in a skybox shouldn't be clipped against current portal --- src/portal.cpp | 47 ++++++++++++----------------------------------- src/portal.h | 1 + src/r_bsp.cpp | 3 ++- src/r_main.cpp | 2 +- src/r_plane.cpp | 2 ++ src/r_things.cpp | 2 +- 6 files changed, 19 insertions(+), 38 deletions(-) diff --git a/src/portal.cpp b/src/portal.cpp index 055603d8c..1e3bf30a8 100644 --- a/src/portal.cpp +++ b/src/portal.cpp @@ -12,6 +12,7 @@ CVAR(Int, sv_portal_recursions, 4, CVAR_ARCHIVE|CVAR_SERVERINFO) PortalDrawseg* CurrentPortal = NULL; int CurrentPortalUniq = 0; +bool CurrentPortalInSkybox = false; // [ZZ] lots of floats here to avoid overflowing a lot bool R_IntersectLines(fixed_t o1x, fixed_t o1y, fixed_t p1x, fixed_t p1y, @@ -48,9 +49,14 @@ bool R_IntersectLines(fixed_t o1x, fixed_t o1y, fixed_t p1x, fixed_t p1y, return true; } +inline int P_PointOnLineSideExplicit (fixed_t x, fixed_t y, fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2) +{ + return DMulScale32 (y-y1, x2-x1, x1-x, y2-y1) > 0; +} + bool P_ClipLineToPortal(line_t* line, line_t* portal, fixed_t viewx, fixed_t viewy, bool partial, bool samebehind) { - // we do this only if simple check doesn't clip away the line + // check if this line is between portal and the viewer. clip away if it is. bool behind1 = !!P_PointOnLineSide(line->v1->x, line->v1->y, portal); bool behind2 = !!P_PointOnLineSide(line->v2->x, line->v2->y, portal); @@ -64,41 +70,12 @@ bool P_ClipLineToPortal(line_t* line, line_t* portal, fixed_t viewx, fixed_t vie behind2 = samebehind; if (behind1 && behind2) - return true; - - if ((behind1 || behind2) && partial) { - fixed_t v1x = line->v1->x; - fixed_t v1y = line->v1->y; - fixed_t v2x = line->v2->x; - fixed_t v2y = line->v2->y; - - fixed_t check1X = viewx; - fixed_t check1Y = viewy; - - fixed_t check2X = portal->v2->x; - fixed_t check2Y = portal->v2->y; - - fixed_t in1x = v1x; - fixed_t in1y = v1y; - - bool i1 = R_IntersectLines(check1X, check1Y, check2X, check2Y, v1x, v1y, v2x, v2y, in1x, in1y); - - check2X = portal->v1->x; - check2Y = portal->v1->y; - - fixed_t in2x = v2x; - fixed_t in2y = v2y; - - bool i2 = R_IntersectLines(check1X, check1Y, check2X, check2Y, v1x, v1y, v2x, v2y, in2x, in2y); - - //if (log) Printf("intersection = %d [at %.2f, %.2f]; %d [at %.2f, %.2f]\n", i1, FIXED2FLOAT(in1x), FIXED2FLOAT(in1y), i2, FIXED2FLOAT(in2x), FIXED2FLOAT(in2y)); - - // now, to cull the shitty line that obstructs the view, we check if any of intersected points are on behind of the portal :) - behind1 = !!P_PointOnLineSide(in1x, in1y, portal); - behind2 = !!P_PointOnLineSide(in2x, in2y, portal); - - if (behind1 && behind2) + // line is behind the portal plane. now check if it's in front of two view plane borders (i.e. if it will get in the way of rendering) + fixed_t dummyx, dummyy; + bool infront1 = R_IntersectLines(line->v1->x, line->v1->y, line->v2->x, line->v2->y, viewx, viewy, portal->v1->x, portal->v1->y, dummyx, dummyy); + bool infront2 = R_IntersectLines(line->v1->x, line->v1->y, line->v2->x, line->v2->y, viewx, viewy, portal->v2->x, portal->v2->y, dummyx, dummyy); + if (infront1 && infront2) return true; } diff --git a/src/portal.h b/src/portal.h index 5897622fd..103e3072b 100644 --- a/src/portal.h +++ b/src/portal.h @@ -26,6 +26,7 @@ struct PortalDrawseg extern PortalDrawseg* CurrentPortal; extern int CurrentPortalUniq; +extern bool CurrentPortalInSkybox; /* code ported from prototype */ bool P_ClipLineToPortal(line_t* line, line_t* portal, fixed_t viewx, fixed_t viewy, bool partial = true, bool samebehind = true); diff --git a/src/r_bsp.cpp b/src/r_bsp.cpp index 5605272e7..8a7e5c560 100644 --- a/src/r_bsp.cpp +++ b/src/r_bsp.cpp @@ -555,7 +555,8 @@ void R_AddLine (seg_t *line) } // reject lines that aren't seen from the portal (if any) - if (CurrentPortal && P_ClipLineToPortal(line->linedef, CurrentPortal->dst, viewx, viewy)) + // [ZZ] 10.01.2016: lines inside a skybox shouldn't be clipped, although this imposes some limitations on portals in skyboxes. + if (!CurrentPortalInSkybox && CurrentPortal && P_ClipLineToPortal(line->linedef, CurrentPortal->dst, viewx, viewy)) return; vertex_t *v1, *v2; diff --git a/src/r_main.cpp b/src/r_main.cpp index ef942734e..c0fe5819c 100644 --- a/src/r_main.cpp +++ b/src/r_main.cpp @@ -659,7 +659,7 @@ void R_HighlightPortal (PortalDrawseg* pds) void R_EnterPortal (PortalDrawseg* pds, int depth) { // [ZZ] check depth. fill portal with black if it's exceeding the visual recursion limit, and continue like nothing happened. - if (depth > r_portal_recursions) + if (depth >= r_portal_recursions) { BYTE color = (BYTE)BestColor((DWORD *)GPalette.BaseColors, 0, 0, 0, 0, 255); int spacing = RenderTarget->GetPitch(); diff --git a/src/r_plane.cpp b/src/r_plane.cpp index 394a77993..ed013b821 100644 --- a/src/r_plane.cpp +++ b/src/r_plane.cpp @@ -1193,6 +1193,7 @@ void R_DrawSkyBoxes () return; R_3D_EnterSkybox(); + CurrentPortalInSkybox = true; int savedextralight = extralight; fixed_t savedx = viewx; @@ -1367,6 +1368,7 @@ void R_DrawSkyBoxes () viewangle = savedangle; R_SetViewAngle (); + CurrentPortalInSkybox = false; R_3D_LeaveSkybox(); if(fakeActive) return; diff --git a/src/r_things.cpp b/src/r_things.cpp index 3a6773c70..9c3d5fe42 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -320,7 +320,7 @@ nextpost: // [ZZ] // R_ClipSpriteColumnWithPortals // -bool R_ClipSpriteColumnWithPortals (fixed_t x, fixed_t y, vissprite_t* spr) +static inline bool R_ClipSpriteColumnWithPortals (fixed_t x, fixed_t y, vissprite_t* spr) { for (drawseg_t* seg = ds_p; seg-- > firstdrawseg; ) // copied code from killough below {