diff --git a/src/r_main.cpp b/src/r_main.cpp index 3577b3c3b5..0a8a635129 100644 --- a/src/r_main.cpp +++ b/src/r_main.cpp @@ -692,6 +692,8 @@ void R_EnterPortal (PortalDrawseg* pds, int depth) fixed_t startx = viewx; fixed_t starty = viewy; fixed_t startz = viewz; + DVector3 savedpath[2] = { ViewPath[0], ViewPath[1] }; + int savedvisibility = camera->renderflags & RF_INVISIBLE; CurrentPortalUniq++; @@ -738,10 +740,27 @@ void R_EnterPortal (PortalDrawseg* pds, int depth) P_TranslatePortalXY(pds->src, view.X, view.Y); P_TranslatePortalZ(pds->src, view.Z); P_TranslatePortalAngle(pds->src, va); + P_TranslatePortalXY(pds->src, ViewPath[0].X, ViewPath[0].Y); + P_TranslatePortalXY(pds->src, ViewPath[1].X, ViewPath[1].Y); viewx = FLOAT2FIXED(view.X); viewy = FLOAT2FIXED(view.Y); viewz = FLOAT2FIXED(view.Z); viewangle = va.BAMs(); + + if (!r_showviewer) + { + double distp = (ViewPath[0] - ViewPath[1]).Length(); + if (distp > EQUAL_EPSILON) + { + double dist1 = (view - ViewPath[0]).Length(); + double dist2 = (view - ViewPath[1]).Length(); + + if (dist1 + dist2 < distp + 1) + { + camera->renderflags |= RF_INVISIBLE; + } + } + } } ViewAngle = AngleToFloat(viewangle); @@ -783,6 +802,7 @@ void R_EnterPortal (PortalDrawseg* pds, int depth) InSubsector = NULL; R_RenderBSPNode (nodes + numnodes - 1); R_3D_ResetClip(); // reset clips (floor/ceiling) + if (!savedvisibility) camera->renderflags &= ~RF_INVISIBLE; PlaneCycles.Clock(); R_DrawPlanes (); @@ -822,6 +842,8 @@ void R_EnterPortal (PortalDrawseg* pds, int depth) viewx = startx; viewy = starty; viewz = startz; + ViewPath[0] = savedpath[0]; + ViewPath[1] = savedpath[1]; ViewAngle = AngleToFloat(viewangle); } diff --git a/src/r_utility.cpp b/src/r_utility.cpp index 94c2b0c004..f2908c6faa 100644 --- a/src/r_utility.cpp +++ b/src/r_utility.cpp @@ -85,7 +85,7 @@ struct InterpolationViewer static TArray PastViewers; static FRandom pr_torchflicker ("TorchFlicker"); static FRandom pr_hom; -static bool NoInterpolateView; +bool NoInterpolateView; // GL needs access to this. static TArray InterpolationPath; // PUBLIC DATA DEFINITIONS ------------------------------------------------- @@ -108,6 +108,7 @@ int viewwindowy; DVector3 ViewPos; DAngle ViewAngle; DAngle ViewPitch; +DVector3 ViewPath[2]; extern "C" { @@ -590,67 +591,78 @@ void R_InterpolateView (player_t *player, double Frac, InterpolationViewer *ivie DAngle oviewangle = iview->Old.Angles.Yaw; DAngle nviewangle = iview->New.Angles.Yaw; - if ((iview->Old.Pos.X != iview->New.Pos.X || iview->Old.Pos.Y != iview->New.Pos.Y) && InterpolationPath.Size() > 0) + if (!cl_capfps) { - DVector3 view = iview->New.Pos; - - // Interpolating through line portals is a messy affair. - // What needs be done is to store the portal transitions of the camera actor as waypoints - // and then find out on which part of the path the current view lies. - // Needless to say, this doesn't work for chasecam mode. - if (!r_showviewer) + if ((iview->Old.Pos.X != iview->New.Pos.X || iview->Old.Pos.Y != iview->New.Pos.Y) && InterpolationPath.Size() > 0) { - double pathlen = 0; - double zdiff = 0; - double totalzdiff = 0; - DAngle adiff = 0.; - DAngle totaladiff = 0.; - double oviewz = iview->Old.Pos.Z; - double nviewz = iview->New.Pos.Z; - DVector3a oldpos = { { iview->Old.Pos.X, iview->Old.Pos.Y, 0 }, 0. }; - DVector3a newpos = { { iview->New.Pos.X, iview->New.Pos.Y, 0 }, 0. }; - InterpolationPath.Push(newpos); // add this to the array to simplify the loops below + DVector3 view = iview->New.Pos; - for (unsigned i = 0; i < InterpolationPath.Size(); i += 2) + // Interpolating through line portals is a messy affair. + // What needs be done is to store the portal transitions of the camera actor as waypoints + // and then find out on which part of the path the current view lies. + // Needless to say, this doesn't work for chasecam mode. + if (!r_showviewer) { - DVector3a &start = i == 0 ? oldpos : InterpolationPath[i - 1]; - DVector3a &end = InterpolationPath[i]; - pathlen += (end.pos-start.pos).Length(); - totalzdiff += start.pos.Z; - totaladiff += start.angle; - } - double interpolatedlen = Frac * pathlen; + double pathlen = 0; + double zdiff = 0; + double totalzdiff = 0; + DAngle adiff = 0.; + DAngle totaladiff = 0.; + double oviewz = iview->Old.Pos.Z; + double nviewz = iview->New.Pos.Z; + DVector3a oldpos = { { iview->Old.Pos.X, iview->Old.Pos.Y, 0 }, 0. }; + DVector3a newpos = { { iview->New.Pos.X, iview->New.Pos.Y, 0 }, 0. }; + InterpolationPath.Push(newpos); // add this to the array to simplify the loops below - for (unsigned i = 0; i < InterpolationPath.Size(); i += 2) - { - DVector3a &start = i == 0 ? oldpos : InterpolationPath[i - 1]; - DVector3a &end = InterpolationPath[i]; - double fraglen = (end.pos - start.pos).Length(); - zdiff += start.pos.Z; - adiff += start.angle; - if (fraglen <= interpolatedlen) + for (unsigned i = 0; i < InterpolationPath.Size(); i += 2) { - interpolatedlen -= fraglen; + DVector3a &start = i == 0 ? oldpos : InterpolationPath[i - 1]; + DVector3a &end = InterpolationPath[i]; + pathlen += (end.pos - start.pos).Length(); + totalzdiff += start.pos.Z; + totaladiff += start.angle; } - else + double interpolatedlen = Frac * pathlen; + + for (unsigned i = 0; i < InterpolationPath.Size(); i += 2) { - double fragfrac = interpolatedlen / fraglen; - oviewz += zdiff; - nviewz -= totalzdiff - zdiff; - oviewangle += adiff; - nviewangle -= totaladiff - adiff; - DVector2 viewpos = start.pos + (fragfrac * (end.pos - start.pos)); - ViewPos = { viewpos, oviewz + Frac * (nviewz - oviewz) }; - break; + DVector3a &start = i == 0 ? oldpos : InterpolationPath[i - 1]; + DVector3a &end = InterpolationPath[i]; + double fraglen = (end.pos - start.pos).Length(); + zdiff += start.pos.Z; + adiff += start.angle; + if (fraglen <= interpolatedlen) + { + interpolatedlen -= fraglen; + } + else + { + double fragfrac = interpolatedlen / fraglen; + oviewz += zdiff; + nviewz -= totalzdiff - zdiff; + oviewangle += adiff; + nviewangle -= totaladiff - adiff; + DVector2 viewpos = start.pos + (fragfrac * (end.pos - start.pos)); + ViewPos = { viewpos, oviewz + Frac * (nviewz - oviewz) }; + break; + } } + InterpolationPath.Pop(); + ViewPath[0] = iview->Old.Pos; } - InterpolationPath.Pop(); + } + else + { + DVector2 disp = Displacements.getOffset(oldgroup, newgroup); + ViewPos = iview->Old.Pos + (iview->New.Pos - iview->Old.Pos - disp) * Frac; + ViewPath[1] = iview->New.Pos; + ViewPath[0] = iview->Old.Pos; } } else { - DVector2 disp = Displacements.getOffset(oldgroup, newgroup); - ViewPos = iview->Old.Pos + (iview->New.Pos - iview->Old.Pos - disp) * Frac; + ViewPos = iview->New.Pos; + ViewPath[0] = ViewPath[1] = iview->New.Pos; } if (player != NULL && !(player->cheats & CF_INTERPVIEW) && diff --git a/src/r_utility.h b/src/r_utility.h index 9e2ccf3cf1..06ed296547 100644 --- a/src/r_utility.h +++ b/src/r_utility.h @@ -15,6 +15,7 @@ extern DCanvas *RenderTarget; extern DVector3 ViewPos; extern DAngle ViewAngle; extern DAngle ViewPitch; +extern DVector3 ViewPath[2]; extern fixed_t viewx, viewy, viewz; extern angle_t viewangle;