From b469770eccf306ff9a3c4c9a253e1a805ae5fd90 Mon Sep 17 00:00:00 2001 From: Boondorl Date: Wed, 28 Feb 2024 00:32:15 -0500 Subject: [PATCH] Reworked view offsetting View offsets are now added after the base position and angles (accounting for interpolation) are calculated. Behavior was centralized into a singular tracer that all view offsets now use to prevent clipping out of the map. Cleaned up camera rendering behavior. Angles are now properly normalized after all offsetting is accounted for. The chase cam can now update in real-time instead of forcing interpolation. --- src/playsim/a_sharedglobal.h | 10 +- src/playsim/actor.h | 2 +- src/playsim/p_local.h | 7 +- src/playsim/p_map.cpp | 82 +- src/rendering/hwrenderer/scene/hw_sprites.cpp | 2 +- src/rendering/r_utility.cpp | 745 ++++++++---------- src/rendering/r_utility.h | 7 +- 7 files changed, 366 insertions(+), 489 deletions(-) diff --git a/src/playsim/a_sharedglobal.h b/src/playsim/a_sharedglobal.h index 83d3a471d..ecaa74b52 100644 --- a/src/playsim/a_sharedglobal.h +++ b/src/playsim/a_sharedglobal.h @@ -125,11 +125,11 @@ enum struct FQuakeJiggers { - DVector3 Intensity; - DVector3 RelIntensity; - DVector3 Offset; - DVector3 RelOffset; - double RollIntensity, RollWave; + DVector3 Intensity = {}; + DVector3 RelIntensity = {}; + DVector3 Offset = {}; + DVector3 RelOffset = {}; + double RollIntensity = 0.0, RollWave = 0.0; }; class DEarthquake : public DThinker diff --git a/src/playsim/actor.h b/src/playsim/actor.h index 2cab5b76d..25b51b8ef 100644 --- a/src/playsim/actor.h +++ b/src/playsim/actor.h @@ -770,7 +770,7 @@ public: Flags = f; } - bool isZero() + bool isZero() const { return Offset.isZero(); } diff --git a/src/playsim/p_local.h b/src/playsim/p_local.h index 19c1c98e9..ea40d386a 100644 --- a/src/playsim/p_local.h +++ b/src/playsim/p_local.h @@ -393,11 +393,8 @@ bool P_CheckMissileSpawn(AActor *missile, double maxdist); void P_PlaySpawnSound(AActor *missile, AActor *spawner); -// [RH] Position the chasecam -void P_AimCamera (AActor *t1, DVector3 &, DAngle &, sector_t *&sec, bool &unlinked); - -// [MC] Aiming for ViewPos -void P_AdjustViewPos(AActor *t1, DVector3 orig, DVector3 &, sector_t *&sec, bool &unlinked, FRenderViewpoint *view); +// [RH] Position the cam's view offsets. +void R_OffsetView(FRenderViewpoint& viewPoint, const DVector3& dir, const double distance); // [RH] Means of death diff --git a/src/playsim/p_map.cpp b/src/playsim/p_map.cpp index 1ca25e559..d6a828024 100644 --- a/src/playsim/p_map.cpp +++ b/src/playsim/p_map.cpp @@ -5573,77 +5573,39 @@ void P_RailAttack(FRailParams *p) CVAR(Float, chase_height, -8.f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(Float, chase_dist, 90.f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) -void P_AimCamera(AActor *t1, DVector3 &campos, DAngle &camangle, sector_t *&CameraSector, bool &unlinked) +void R_OffsetView(FRenderViewpoint& viewPoint, const DVector3& dir, const double distance) { - double distance = clamp(chase_dist, 0, 30000); - DAngle angle = t1->Angles.Yaw - DAngle::fromDeg(180); - DAngle pitch = t1->Angles.Pitch; - FTraceResults trace; - DVector3 vvec; - double sz; - - double pc = pitch.Cos(); - - vvec = { pc * angle.Cos(), pc * angle.Sin(), pitch.Sin() }; - sz = t1->Top() - t1->Floorclip + clamp(chase_height, -1000, 1000); - - if (Trace(t1->PosAtZ(sz), t1->Sector, vvec, distance, 0, 0, NULL, trace) && - trace.Distance > 10) + const DAngle baseYaw = dir.Angle(); + FTraceResults trace = {}; + if (Trace(viewPoint.Pos, viewPoint.sector, dir, distance, 0u, 0u, nullptr, trace)) { - // Position camera slightly in front of hit thing - campos = t1->PosAtZ(sz) + vvec *(trace.Distance - 5); + viewPoint.Pos = trace.HitPos - trace.HitVector * min(5.0, trace.Distance); + viewPoint.sector = viewPoint.ViewLevel->PointInRenderSubsector(viewPoint.Pos)->sector; } else { - campos = trace.HitPos - trace.HitVector * 1/256.; + viewPoint.Pos = trace.HitPos; + viewPoint.sector = trace.Sector; } - CameraSector = trace.Sector; - unlinked = trace.unlinked; - camangle = trace.SrcAngleFromTarget - DAngle::fromDeg(180.); -} -struct ViewPosPortal -{ - int counter; -}; - -static ETraceStatus VPos_CheckPortal(FTraceResults &res, void *userdata) -{ - //[MC] Mirror how third person works. - ViewPosPortal *pc = (ViewPosPortal *)userdata; - - if (res.HitType == TRACE_CrossingPortal) + viewPoint.Angles.Yaw += deltaangle(baseYaw, trace.SrcAngleFromTarget); + // TODO: Why does this even need to be done? Please fix tracers already. + if (dir.Z < 0.0) { - res.HitType = TRACE_HitNone; // Needed to force the trace to continue appropriately. - pc->counter++; - return TRACE_Skip; + while (!viewPoint.sector->PortalBlocksMovement(sector_t::floor) && viewPoint.Pos.Z < viewPoint.sector->GetPortalPlaneZ(sector_t::floor)) + { + viewPoint.Pos += viewPoint.sector->GetPortalDisplacement(sector_t::floor); + viewPoint.sector = viewPoint.sector->GetPortal(sector_t::floor)->mDestination; + } } - if (res.HitType == TRACE_HitActor) + else if (dir.Z > 0.0) { - return TRACE_Skip; + while (!viewPoint.sector->PortalBlocksMovement(sector_t::ceiling) && viewPoint.Pos.Z > viewPoint.sector->GetPortalPlaneZ(sector_t::ceiling)) + { + viewPoint.Pos += viewPoint.sector->GetPortalDisplacement(sector_t::ceiling); + viewPoint.sector = viewPoint.sector->GetPortal(sector_t::ceiling)->mDestination; + } } - return TRACE_Stop; -} - -// [MC] Used for ViewPos. Uses code borrowed from P_AimCamera. -void P_AdjustViewPos(AActor *t1, DVector3 orig, DVector3 &campos, sector_t *&CameraSector, bool &unlinked, FRenderViewpoint *view) -{ - FTraceResults trace; - ViewPosPortal pc; - pc.counter = 0; - const DVector3 vvec = campos - orig; - const double distance = vvec.Length(); - - // Trace handles all of the portal crossing, which is why there is no usage of Vec#Offset(Z). - if (Trace(orig, CameraSector, vvec.Unit(), distance, 0, 0, t1, trace, TRACE_ReportPortals, VPos_CheckPortal, &pc) && - trace.Distance > 5) - campos = orig + vvec.Unit() * (trace.Distance - 5); - else - campos = trace.HitPos - trace.HitVector * 1 / 256.; - - - CameraSector = trace.Sector; - unlinked = trace.unlinked; } //========================================================================== diff --git a/src/rendering/hwrenderer/scene/hw_sprites.cpp b/src/rendering/hwrenderer/scene/hw_sprites.cpp index 09db1101d..3fa433133 100644 --- a/src/rendering/hwrenderer/scene/hw_sprites.cpp +++ b/src/rendering/hwrenderer/scene/hw_sprites.cpp @@ -800,7 +800,7 @@ void HWSprite::Process(HWDrawInfo *di, AActor* thing, sector_t * sector, area_t // Some added checks if the camera actor is not supposed to be seen. It can happen that some portal setup has this actor in view in which case it may not be skipped here if (viewmaster == camera && !vp.showviewer) { - if (vp.noviewer || (viewmaster->player && viewmaster->player->crossingPortal)) return; + if (vp.bForceNoViewer || (viewmaster->player && viewmaster->player->crossingPortal)) return; DVector3 vieworigin = viewmaster->Pos(); if (thruportal == 1) vieworigin += di->Level->Displacements.getOffset(viewmaster->Sector->PortalGroup, sector->PortalGroup); if (fabs(vieworigin.X - vp.ActorPos.X) < 2 && fabs(vieworigin.Y - vp.ActorPos.Y) < 2) return; diff --git a/src/rendering/r_utility.cpp b/src/rendering/r_utility.cpp index 908866389..09cab0583 100644 --- a/src/rendering/r_utility.cpp +++ b/src/rendering/r_utility.cpp @@ -83,8 +83,10 @@ struct InterpolationViewer DRotator ViewAngles; }; - AActor *ViewActor; - int otic; + AActor* ViewActor; + DVector3 ViewOffset, RelativeViewOffset; // This has to be a separate field since it needs the real-time mouse angles. + DRotator AngleOffsets; + int prevTic; instance Old, New; }; @@ -443,18 +445,18 @@ EXTERN_CVAR (Bool, cl_noprediction) bool P_NoInterpolation(player_t const *player, AActor const *actor) { - return player != NULL && - !(player->cheats & CF_INTERPVIEW) && - player - players == consoleplayer && - actor == player->mo && - !demoplayback && - !(player->cheats & (CF_TOTALLYFROZEN | CF_FROZEN)) && - player->playerstate == PST_LIVE && - player->mo->reactiontime == 0 && - !NoInterpolateView && - !paused && - (!netgame || !cl_noprediction) && - !LocalKeyboardTurner; + return player != nullptr + && !(player->cheats & CF_INTERPVIEW) + && player - players == consoleplayer + && actor == player->mo + && !demoplayback + && !(player->cheats & (CF_TOTALLYFROZEN | CF_FROZEN)) + && player->playerstate == PST_LIVE + && player->mo->reactiontime == 0 + && !NoInterpolateView + && !paused + && (!netgame || !cl_noprediction) + && !LocalKeyboardTurner; } //========================================================================== @@ -463,146 +465,178 @@ bool P_NoInterpolation(player_t const *player, AActor const *actor) // //========================================================================== -void R_InterpolateView (FRenderViewpoint &viewpoint, player_t *player, double Frac, InterpolationViewer *iview) +void R_InterpolateView(FRenderViewpoint& viewPoint, const player_t* const player, const double ticFrac, InterpolationViewer* const iView) { if (NoInterpolateView) { InterpolationPath.Clear(); NoInterpolateView = false; - iview->Old = iview->New; + iView->Old = iView->New; } - auto Level = viewpoint.ViewLevel; - int oldgroup = Level->PointInRenderSubsector(iview->Old.Pos)->sector->PortalGroup; - int newgroup = Level->PointInRenderSubsector(iview->New.Pos)->sector->PortalGroup; - DAngle oviewangle = iview->Old.Angles.Yaw; - DAngle nviewangle = iview->New.Angles.Yaw; + const double inverseTicFrac = 1.0 - ticFrac; + const auto viewLvl = viewPoint.ViewLevel; + + DAngle prevYaw = iView->Old.Angles.Yaw; + DAngle curYaw = iView->New.Angles.Yaw; if (!cl_capfps) { - if ((iview->Old.Pos.X != iview->New.Pos.X || iview->Old.Pos.Y != iview->New.Pos.Y) && InterpolationPath.Size() > 0) + if ((iView->Old.Pos.X != iView->New.Pos.X || iView->Old.Pos.Y != iView->New.Pos.Y) && InterpolationPath.Size() > 0) { - 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 or viewpos. - if (!viewpoint.showviewer && !viewpoint.NoPortalPath) + double totalPathLength = 0.0; + double totalZDiff = 0.0; + DAngle totalYawDiff = nullAngle; + DVector3a oldPos = { { iView->Old.Pos.X, iView->Old.Pos.Y, 0.0 }, nullAngle }; + DVector3a newPos = { { iView->New.Pos.X, iView->New.Pos.Y, 0.0 }, nullAngle }; + InterpolationPath.Push(newPos); // Add this to the array to simplify the loops below. + + for (size_t i = 0u; i < InterpolationPath.Size(); i += 2u) { - double pathlen = 0; - double zdiff = 0; - double totalzdiff = 0; - DAngle adiff = nullAngle; - DAngle totaladiff = nullAngle; - double oviewz = iview->Old.Pos.Z; - double nviewz = iview->New.Pos.Z; - DVector3a oldpos = { { iview->Old.Pos.X, iview->Old.Pos.Y, 0 }, nullAngle }; - DVector3a newpos = { { iview->New.Pos.X, iview->New.Pos.Y, 0 }, nullAngle }; - 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]; - pathlen += (end.pos - start.pos).Length(); - totalzdiff += start.pos.Z; - totaladiff += start.angle; - } - double interpolatedlen = Frac * pathlen; - - 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) - { - interpolatedlen -= fraglen; - } - else - { - double fragfrac = interpolatedlen / fraglen; - oviewz += zdiff; - nviewz -= totalzdiff - zdiff; - oviewangle += adiff; - nviewangle -= totaladiff - adiff; - DVector2 viewpos = start.pos.XY() + (fragfrac * (end.pos - start.pos).XY()); - viewpoint.Pos = { viewpos, oviewz + Frac * (nviewz - oviewz) }; - break; - } - } - InterpolationPath.Pop(); - viewpoint.Path[0] = iview->Old.Pos; - viewpoint.Path[1] = viewpoint.Path[0] + (InterpolationPath[0].pos - viewpoint.Path[0]).XY().MakeResize(pathlen); + const DVector3a& start = !i ? oldPos : InterpolationPath[i - 1u]; + const DVector3a& end = InterpolationPath[i]; + totalPathLength += (end.pos - start.pos).Length(); + totalZDiff += start.pos.Z; + totalYawDiff += start.angle; } + + double interpolatedLength = totalPathLength * ticFrac; + double zDiff = 0.0; + DAngle yawDiff = nullAngle; + double prevViewZ = iView->Old.Pos.Z; + double curViewZ = iView->New.Pos.Z; + for (size_t i = 0u; i < InterpolationPath.Size(); i += 2u) + { + const DVector3a& start = !i ? oldPos : InterpolationPath[i - 1u]; + const DVector3a& end = InterpolationPath[i]; + const double fragmentLength = (end.pos - start.pos).Length(); + zDiff += start.pos.Z; + yawDiff += start.angle; + + if (fragmentLength <= interpolatedLength) + { + interpolatedLength -= fragmentLength; + } + else + { + prevViewZ += zDiff; + curViewZ -= totalZDiff - zDiff; + prevYaw += yawDiff; + curYaw -= totalYawDiff - yawDiff; + + const DVector2 viewPos = start.pos.XY() + ((interpolatedLength / fragmentLength) * (end.pos - start.pos).XY()); + viewPoint.Pos = { viewPos, prevViewZ * inverseTicFrac + curViewZ * ticFrac }; + break; + } + } + + InterpolationPath.Pop(); + viewPoint.Path[0] = iView->Old.Pos; + viewPoint.Path[1] = viewPoint.Path[0] + (InterpolationPath[0].pos - viewPoint.Path[0]).XY().MakeResize(totalPathLength); } else { - DVector2 disp = viewpoint.ViewLevel->Displacements.getOffset(oldgroup, newgroup); - viewpoint.Pos = iview->Old.Pos + (iview->New.Pos - iview->Old.Pos - disp) * Frac; - viewpoint.Path[0] = viewpoint.Path[1] = iview->New.Pos; + const int prevPortalGroup = viewLvl->PointInRenderSubsector(iView->Old.Pos)->sector->PortalGroup; + const int curPortalGroup = viewLvl->PointInRenderSubsector(iView->New.Pos)->sector->PortalGroup; + + const DVector2 portalOffset = viewLvl->Displacements.getOffset(prevPortalGroup, curPortalGroup); + viewPoint.Pos = iView->Old.Pos * inverseTicFrac + (iView->New.Pos - portalOffset) * ticFrac; + viewPoint.Path[0] = viewPoint.Path[1] = iView->New.Pos; } } else { - viewpoint.Pos = iview->New.Pos; - viewpoint.Path[0] = viewpoint.Path[1] = iview->New.Pos; - } - if (P_NoInterpolation(player, viewpoint.camera) && - // TODO: This is only temporarily disabled until R_SetupFrame can be reworked to take up-to-date angles into account. - !(player->cheats & CF_CHASECAM) && (!r_deathcamera || viewpoint.camera->health > 0) && - iview->New.Pos.X == viewpoint.ActorPos.X && - iview->New.Pos.Y == viewpoint.ActorPos.Y) - { - viewpoint.Angles.Yaw = (nviewangle + DAngle::fromBam(LocalViewAngle)).Normalized180(); - DAngle delta = player->centering ? nullAngle : DAngle::fromBam(LocalViewPitch); - viewpoint.Angles.Pitch = clamp((iview->New.Angles.Pitch - delta).Normalized180(), player->MinPitch, player->MaxPitch); - viewpoint.Angles.Roll = iview->New.Angles.Roll.Normalized180(); - } - else - { - viewpoint.Angles.Pitch = (iview->Old.Angles.Pitch + deltaangle(iview->Old.Angles.Pitch, iview->New.Angles.Pitch) * Frac).Normalized180(); - viewpoint.Angles.Yaw = (oviewangle + deltaangle(oviewangle, nviewangle) * Frac).Normalized180(); - viewpoint.Angles.Roll = (iview->Old.Angles.Roll + deltaangle(iview->Old.Angles.Roll, iview->New.Angles.Roll) * Frac).Normalized180(); - } - - // [MR] Apply the view angles as an offset if ABSVIEWANGLES isn't specified. - if (!(viewpoint.camera->flags8 & MF8_ABSVIEWANGLES)) - { - viewpoint.Angles += (!player || (player->cheats & CF_INTERPVIEWANGLES)) ? interpolatedvalue(iview->Old.ViewAngles, iview->New.ViewAngles, Frac) : iview->New.ViewAngles; + viewPoint.Pos = iView->New.Pos; + viewPoint.Path[0] = viewPoint.Path[1] = iView->New.Pos; } // Due to interpolation this is not necessarily the same as the sector the camera is in. - viewpoint.sector = Level->PointInRenderSubsector(viewpoint.Pos)->sector; + viewPoint.sector = viewLvl->PointInRenderSubsector(viewPoint.Pos)->sector; bool moved = false; - while (!viewpoint.sector->PortalBlocksMovement(sector_t::ceiling)) + while (!viewPoint.sector->PortalBlocksMovement(sector_t::ceiling)) { - if (viewpoint.Pos.Z > viewpoint.sector->GetPortalPlaneZ(sector_t::ceiling)) + if (viewPoint.Pos.Z > viewPoint.sector->GetPortalPlaneZ(sector_t::ceiling)) { - viewpoint.Pos += viewpoint.sector->GetPortalDisplacement(sector_t::ceiling); - viewpoint.ActorPos += viewpoint.sector->GetPortalDisplacement(sector_t::ceiling); - viewpoint.sector = Level->PointInRenderSubsector(viewpoint.Pos)->sector; + const DVector2 offset = viewPoint.sector->GetPortalDisplacement(sector_t::ceiling); + viewPoint.Pos += offset; + viewPoint.ActorPos += offset; + viewPoint.sector = viewPoint.sector->GetPortal(sector_t::ceiling)->mDestination; moved = true; } - else break; - } - if (!moved) - { - while (!viewpoint.sector->PortalBlocksMovement(sector_t::floor)) + else { - if (viewpoint.Pos.Z < viewpoint.sector->GetPortalPlaneZ(sector_t::floor)) - { - viewpoint.Pos += viewpoint.sector->GetPortalDisplacement(sector_t::floor); - viewpoint.ActorPos += viewpoint.sector->GetPortalDisplacement(sector_t::floor); - viewpoint.sector = Level->PointInRenderSubsector(viewpoint.Pos)->sector; - moved = true; - } - else break; + break; } } - if (moved) viewpoint.noviewer = true; + + if (!moved) + { + while (!viewPoint.sector->PortalBlocksMovement(sector_t::floor)) + { + if (viewPoint.Pos.Z < viewPoint.sector->GetPortalPlaneZ(sector_t::floor)) + { + const DVector2 offset = viewPoint.sector->GetPortalDisplacement(sector_t::floor); + viewPoint.Pos += offset; + viewPoint.ActorPos += offset; + viewPoint.sector = viewPoint.sector->GetPortal(sector_t::floor)->mDestination; + } + else + { + break; + } + } + } + + if (P_NoInterpolation(player, viewPoint.camera)) + { + viewPoint.Angles.Yaw = curYaw + DAngle::fromBam(LocalViewAngle); + const DAngle delta = player->centering ? nullAngle : DAngle::fromBam(LocalViewPitch); + viewPoint.Angles.Pitch = clamp((iView->New.Angles.Pitch - delta).Normalized180(), player->MinPitch, player->MaxPitch); + viewPoint.Angles.Roll = iView->New.Angles.Roll; + } + else + { + viewPoint.Angles.Pitch = iView->Old.Angles.Pitch * inverseTicFrac + iView->New.Angles.Pitch * ticFrac; + viewPoint.Angles.Yaw = prevYaw * inverseTicFrac + curYaw * ticFrac; + viewPoint.Angles.Roll = iView->Old.Angles.Roll * inverseTicFrac + iView->New.Angles.Roll * ticFrac; + } + + // Now that the base position and angles are set, add offsets. + + DVector3 posOfs = iView->ViewOffset; + if (!iView->RelativeViewOffset.isZero()) + posOfs += DQuaternion::FromAngles(viewPoint.Angles.Yaw, viewPoint.Angles.Pitch, viewPoint.Angles.Roll) * iView->RelativeViewOffset; + + // Now that we have the current interpolated position, offset from that directly (for view offset + chase cam). + if (!posOfs.isZero()) + { + const double distance = posOfs.Length(); + posOfs /= distance; + R_OffsetView(viewPoint, posOfs, distance); + } + + viewPoint.Angles += iView->AngleOffsets; + + // [MR] Apply the view angles as an offset if ABSVIEWANGLES isn't specified. + if (!(viewPoint.camera->flags8 & MF8_ABSVIEWANGLES)) + { + if (player == nullptr || (player->cheats & CF_INTERPVIEWANGLES)) + { + viewPoint.Angles.Yaw += iView->Old.ViewAngles.Yaw * inverseTicFrac + iView->New.ViewAngles.Yaw * ticFrac; + viewPoint.Angles.Pitch += iView->Old.ViewAngles.Pitch * inverseTicFrac + iView->New.ViewAngles.Pitch * ticFrac; + viewPoint.Angles.Roll += iView->Old.ViewAngles.Roll * inverseTicFrac + iView->New.ViewAngles.Roll * ticFrac; + } + else + { + viewPoint.Angles += iView->New.ViewAngles; + } + } + + viewPoint.Angles.Yaw = viewPoint.Angles.Yaw.Normalized180(); + viewPoint.Angles.Pitch = viewPoint.Angles.Pitch.Normalized180(); + viewPoint.Angles.Roll = viewPoint.Angles.Roll.Normalized180(); } //========================================================================== @@ -619,24 +653,23 @@ void R_ResetViewInterpolation () //========================================================================== // -// R_SetViewAngle -// sets all values derived from the view angle. +// R_SetViewAngle +// sets all values derived from the view yaw. // //========================================================================== -void FRenderViewpoint::SetViewAngle (const FViewWindow &viewwindow) +void FRenderViewpoint::SetViewAngle(const FViewWindow& viewWindow) { Sin = Angles.Yaw.Sin(); Cos = Angles.Yaw.Cos(); - TanSin = viewwindow.FocalTangent * Sin; - TanCos = viewwindow.FocalTangent * Cos; + TanSin = viewWindow.FocalTangent * Sin; + TanCos = viewWindow.FocalTangent * Cos; - DVector2 v = Angles.Yaw.ToVector(); + const DVector2 v = Angles.Yaw.ToVector(); ViewVector.X = v.X; ViewVector.Y = v.Y; HWAngles.Yaw = FAngle::fromDeg(270.0 - Angles.Yaw.Degrees()); - } //========================================================================== @@ -659,7 +692,7 @@ static InterpolationViewer *FindPastViewer (AActor *actor) InterpolationViewer iview; memset(&iview, 0, sizeof(iview)); iview.ViewActor = actor; - iview.otic = -1; + iview.prevTic = -1; InterpolationPath.Clear(); return &PastViewers[PastViewers.Push (iview)]; } @@ -800,368 +833,263 @@ static void R_DoActorTickerAngleChanges(player_t* const player, DRotator& angles // //========================================================================== -void R_SetupFrame (FRenderViewpoint &viewpoint, FViewWindow &viewwindow, AActor *actor) +EXTERN_CVAR(Float, chase_dist) +EXTERN_CVAR(Float, chase_height) + +void R_SetupFrame(FRenderViewpoint& viewPoint, const FViewWindow& viewWindow, AActor* const actor) { - if (actor == NULL) + viewPoint.TicFrac = I_GetTimeFrac(); + if (cl_capfps || r_NoInterpolate) + viewPoint.TicFrac = 1.0; + + const int curTic = I_GetTime(); + + if (actor == nullptr) + I_Error("Tried to render from a null actor."); + + viewPoint.ViewLevel = actor->Level; + + player_t* player = actor->player; + if (player != nullptr && player->mo == actor) { - I_Error ("Tried to render from a NULL actor."); - } - viewpoint.ViewLevel = actor->Level; + if (player->camera == nullptr) + player->camera = player->mo; - player_t *player = actor->player; - unsigned int newblend; - InterpolationViewer *iview; - bool unlinked = false; - - if (player != NULL && player->mo == actor) - { // [RH] Use camera instead of viewplayer - viewpoint.camera = player->camera; - if (viewpoint.camera == NULL) - { - viewpoint.camera = player->camera = player->mo; - } + viewPoint.camera = player->camera; // [RH] Use camera instead of view player. } else { - viewpoint.camera = actor; + viewPoint.camera = actor; } - if (viewpoint.camera == NULL) - { - I_Error ("You lost your body. Bad dehacked work is likely to blame."); - } + if (viewPoint.camera == nullptr) + I_Error("You lost your body. Bad dehacked work is likely to blame."); - iview = FindPastViewer (viewpoint.camera); - - int nowtic = I_GetTime (); - if (iview->otic != -1 && nowtic > iview->otic) + InterpolationViewer* const iView = FindPastViewer(viewPoint.camera); + // Always reset these back to zero. + iView->ViewOffset.Zero(); + iView->RelativeViewOffset.Zero(); + iView->AngleOffsets.Zero(); + if (iView->prevTic != -1 && curTic > iView->prevTic) { - iview->otic = nowtic; - iview->Old = iview->New; + iView->prevTic = curTic; + iView->Old = iView->New; } const auto& mainView = r_viewpoint; AActor* const client = players[consoleplayer].mo; - const bool matchPlayer = gamestate != GS_TITLELEVEL && viewpoint.camera->player == nullptr && (viewpoint.camera->renderflags2 & RF2_CAMFOLLOWSPLAYER); + const bool matchPlayer = gamestate != GS_TITLELEVEL && viewPoint.camera->player == nullptr && (viewPoint.camera->renderflags2 & RF2_CAMFOLLOWSPLAYER); const bool usePawn = matchPlayer ? mainView.camera != client : false; //============================================================================================== - // Handles offsetting the camera with ChaseCam and/or viewpos. + // Sets up the view position offset. { - AActor *mo = viewpoint.camera; - DViewPosition *VP = mo->ViewPos; - DVector3 orig; + AActor* const mo = viewPoint.camera; + const DViewPosition* const viewOffset = mo->ViewPos; + DVector3 camPos; if (matchPlayer) { if (usePawn) { - orig = DVector3(client->Pos().XY(), client->player->viewz); + camPos = DVector3(client->Pos().XY(), client->player->viewz); const DViewPosition* const pawnVP = client->ViewPos; if (pawnVP != nullptr) { - // Avoid portal checking for now until the need for more accuracy arises. + // Add these directly to the view position offset (not 100% accurate but close enough). if (pawnVP->Flags & VPSF_ABSOLUTEPOS) - orig = pawnVP->Offset; + camPos = pawnVP->Offset; else if (pawnVP->Flags & VPSF_ABSOLUTEOFFSET) - orig += pawnVP->Offset; + iView->ViewOffset = pawnVP->Offset; else - orig += DQuaternion::FromAngles(client->Angles.Yaw, client->Angles.Pitch, client->Angles.Roll) * pawnVP->Offset; + iView->ViewOffset = DQuaternion::FromAngles(client->Angles.Yaw, client->Angles.Pitch, client->Angles.Roll) * pawnVP->Offset; } } else { - orig = mainView.Pos; + camPos = mainView.Pos; } } else { - orig = { mo->Pos().XY(), mo->player ? mo->player->viewz : mo->Z() + mo->GetCameraHeight() }; + camPos = { mo->Pos().XY(), mo->player != nullptr ? mo->player->viewz : mo->Z() + mo->GetCameraHeight() }; } - viewpoint.ActorPos = orig; + viewPoint.showviewer = false; + viewPoint.bForceNoViewer = matchPlayer; - bool DefaultDraw = true; - - sector_t *oldsector = viewpoint.ViewLevel->PointInRenderSubsector(iview->Old.Pos)->sector; if (gamestate != GS_TITLELEVEL && - ((player && (player->cheats & CF_CHASECAM)) || (r_deathcamera && viewpoint.camera->health <= 0))) + ((player != nullptr && (player->cheats & CF_CHASECAM)) || (r_deathcamera && (viewPoint.camera->flags6 & MF6_KILLED)))) { - // [RH] Use chasecam view - DefaultDraw = false; - DVector3 campos; - DAngle camangle; - P_AimCamera(viewpoint.camera, campos, camangle, viewpoint.sector, unlinked); // fixme: This needs to translate the angle, too. - iview->New.Pos = campos; - iview->New.Angles.Yaw = camangle; - - viewpoint.showviewer = true; - // Interpolating this is a very complicated thing because nothing keeps track of the aim camera's movement, so whenever we detect a portal transition - // it's probably best to just reset the interpolation for this move. - // Note that this can still cause problems with unusually linked portals - if (viewpoint.sector->PortalGroup != oldsector->PortalGroup || (unlinked && ((iview->New.Pos.XY() - iview->Old.Pos.XY()).LengthSquared()) > 256 * 256)) - viewpoint.camera->renderflags |= RF_NOINTERPOLATEVIEW; - - viewpoint.ActorPos = campos; + // The cam Actor should probably be visible in third person. + viewPoint.showviewer = true; + camPos.Z = mo->Top() - mo->Floorclip; + iView->ViewOffset.Z = clamp(chase_height, -1000.0, 1000.0); + iView->RelativeViewOffset.X = -clamp(chase_dist, 0.0, 30000.0); } - else if (VP) // No chase/death cam and player is alive, wants viewpos. + else if (viewOffset != nullptr) { - viewpoint.showviewer = false; - - // [MC] Ignores all portal portal transitions since it's meant to be absolute. - // Modders must handle performing offsetting with the appropriate functions to get it to work. - // Hint: Check P_AdjustViewPos. - if (VP->Flags & VPSF_ABSOLUTEPOS) + // No chase/death cam, so use the view offset. + if (!viewPoint.bForceNoViewer) + viewPoint.bForceNoViewer = (viewOffset->Flags & VPSF_ABSOLUTEPOS) || !viewOffset->Offset.isZero(); + + if (viewOffset->Flags & VPSF_ABSOLUTEPOS) { - iview->New.Pos = VP->Offset; - DefaultDraw = false; - viewpoint.sector = viewpoint.ViewLevel->PointInRenderSubsector(iview->New.Pos.XY())->sector; - viewpoint.showviewer = viewpoint.NoPortalPath = false; - viewpoint.noviewer = true; + if (!matchPlayer) + camPos = viewOffset->Offset; + } + else if (viewOffset->Flags & VPSF_ABSOLUTEOFFSET) + { + iView->ViewOffset += viewOffset->Offset; } else { - viewpoint.sector = viewpoint.ViewLevel->PointInRenderSubsector(iview->New.Pos.XY())->sector; - DVector3 next = orig; - - if (VP->isZero()) - { - // Since viewpos isn't being used, it's safe to enable path interpolation - viewpoint.NoPortalPath = false; - } - else if (VP->Flags & VPSF_ABSOLUTEOFFSET) - { - // No relativity added from angles. - next += VP->Offset; - } - else - { - // [MC] Do NOT handle portals here! Trace must have the unportaled (absolute) position to - // get the correct angle and distance. Trace automatically handles portals by itself. - // Note: viewpos does not include view angles, and ViewZ/CameraHeight are applied before this. - next += DQuaternion::FromAngles(mo->Angles.Yaw, mo->Angles.Pitch, mo->Angles.Roll) * VP->Offset; - } - - if (next != orig) - { - // [MC] Disable interpolation if the camera view is crossing through a portal. Sometimes - // the player is made visible when crossing a portal and it's extremely jarring. - // Also, disable the portal interpolation pathing entirely when using the viewpos feature. - // Interpolation still happens with everything else though and seems to work fine. - DefaultDraw = false; - viewpoint.noviewer = true; - viewpoint.NoPortalPath = true; - P_AdjustViewPos(mo, orig, next, viewpoint.sector, unlinked, &viewpoint); - iview->New.Pos = next; - - if (viewpoint.sector->PortalGroup != oldsector->PortalGroup || (unlinked && ((iview->New.Pos.XY() - iview->Old.Pos.XY()).LengthSquared()) > 256 * 256)) - viewpoint.camera->renderflags |= RF_NOINTERPOLATEVIEW; - } + iView->RelativeViewOffset = viewOffset->Offset; } - - viewpoint.ActorPos = iview->New.Pos; } - - if (DefaultDraw) - { - iview->New.Pos = orig; - viewpoint.sector = viewpoint.camera->Sector; - viewpoint.showviewer = viewpoint.NoPortalPath = false; - } - } - // [MR] Apply view angles as the viewpoint angles if asked to do so. - if (matchPlayer) - iview->New.Angles = usePawn ? (client->flags8 & MF8_ABSVIEWANGLES ? client->ViewAngles : client->Angles + client->ViewAngles) : mainView.Angles; - else - iview->New.Angles = !(viewpoint.camera->flags8 & MF8_ABSVIEWANGLES) ? viewpoint.camera->Angles : viewpoint.camera->ViewAngles; - - iview->New.ViewAngles = viewpoint.camera->ViewAngles; - // [MR] Process player angle changes if permitted to do so. - if (player && (player->cheats & CF_SCALEDNOLERP) && P_NoInterpolation(player, viewpoint.camera)) - R_DoActorTickerAngleChanges(player, iview->New.Angles, viewpoint.TicFrac); - - // If currently tracking the player's real view, don't do any sort of interpolating. - if (matchPlayer && !usePawn) - viewpoint.camera->renderflags |= RF_NOINTERPOLATEVIEW; - - if (viewpoint.camera->player != 0) - { - player = viewpoint.camera->player; - } - - if (iview->otic == -1 || r_NoInterpolate || (viewpoint.camera->renderflags & RF_NOINTERPOLATEVIEW)) - { - viewpoint.camera->renderflags &= ~RF_NOINTERPOLATEVIEW; - R_ResetViewInterpolation (); - iview->otic = nowtic; - } - - viewpoint.TicFrac = I_GetTimeFrac (); - if (cl_capfps || r_NoInterpolate) - { - viewpoint.TicFrac = 1.; - } - R_InterpolateView (viewpoint, player, viewpoint.TicFrac, iview); - - viewpoint.SetViewAngle (viewwindow); - - // Keep the view within the sector's floor and ceiling - if (viewpoint.sector->PortalBlocksMovement(sector_t::ceiling)) - { - double theZ = viewpoint.sector->ceilingplane.ZatPoint(viewpoint.Pos) - 4; - if (viewpoint.Pos.Z > theZ) - { - viewpoint.Pos.Z = theZ; - } - } - - if (viewpoint.sector->PortalBlocksMovement(sector_t::floor)) - { - double theZ = viewpoint.sector->floorplane.ZatPoint(viewpoint.Pos) + 4; - if (viewpoint.Pos.Z < theZ) - { - viewpoint.Pos.Z = theZ; - } + viewPoint.ActorPos = iView->New.Pos = camPos; + viewPoint.sector = viewPoint.ViewLevel->PointInRenderSubsector(camPos)->sector; } if (!paused) { FQuakeJiggers jiggers; - - memset(&jiggers, 0, sizeof(jiggers)); - if (DEarthquake::StaticGetQuakeIntensities(viewpoint.TicFrac, viewpoint.camera, jiggers) > 0) + if (DEarthquake::StaticGetQuakeIntensities(viewPoint.TicFrac, viewPoint.camera, jiggers) > 0) { - double quakefactor = r_quakeintensity; - DVector3 pos; pos.Zero(); - if (jiggers.RollIntensity != 0 || jiggers.RollWave != 0) - { - viewpoint.Angles.Roll += DAngle::fromDeg(QuakePower(quakefactor, jiggers.RollIntensity, jiggers.RollWave)); - } - if (jiggers.RelIntensity.X != 0 || jiggers.RelOffset.X != 0) - { - pos.X += QuakePower(quakefactor, jiggers.RelIntensity.X, jiggers.RelOffset.X); - } - if (jiggers.RelIntensity.Y != 0 || jiggers.RelOffset.Y != 0) - { - pos.Y += QuakePower(quakefactor, jiggers.RelIntensity.Y, jiggers.RelOffset.Y); - } - if (jiggers.RelIntensity.Z != 0 || jiggers.RelOffset.Z != 0) - { - pos.Z += QuakePower(quakefactor, jiggers.RelIntensity.Z, jiggers.RelOffset.Z); - } - // [MC] Tremendous thanks to Marisa Kirisame for helping me with this. - // Use a rotation matrix to make the view relative. - if (!pos.isZero()) - { - DAngle yaw = viewpoint.camera->Angles.Yaw; - DAngle pitch = viewpoint.camera->Angles.Pitch; - DAngle roll = viewpoint.camera->Angles.Roll; - DVector3 relx, rely, relz; - DMatrix3x3 rot = - DMatrix3x3(DVector3(0., 0., 1.), yaw.Cos(), yaw.Sin()) * - DMatrix3x3(DVector3(0., 1., 0.), pitch.Cos(), pitch.Sin()) * - DMatrix3x3(DVector3(1., 0., 0.), roll.Cos(), roll.Sin()); - relx = DVector3(1., 0., 0.)*rot; - rely = DVector3(0., 1., 0.)*rot; - relz = DVector3(0., 0., 1.)*rot; - viewpoint.Pos += relx * pos.X + rely * pos.Y + relz * pos.Z; - } + const double quakeFactor = r_quakeintensity; + if (jiggers.RollIntensity || jiggers.RollWave) + iView->AngleOffsets.Roll = DAngle::fromDeg(QuakePower(quakeFactor, jiggers.RollIntensity, jiggers.RollWave)); - if (jiggers.Intensity.X != 0 || jiggers.Offset.X != 0) - { - viewpoint.Pos.X += QuakePower(quakefactor, jiggers.Intensity.X, jiggers.Offset.X); - } - if (jiggers.Intensity.Y != 0 || jiggers.Offset.Y != 0) - { - viewpoint.Pos.Y += QuakePower(quakefactor, jiggers.Intensity.Y, jiggers.Offset.Y); - } - if (jiggers.Intensity.Z != 0 || jiggers.Offset.Z != 0) - { - viewpoint.Pos.Z += QuakePower(quakefactor, jiggers.Intensity.Z, jiggers.Offset.Z); - } + if (jiggers.RelIntensity.X || jiggers.RelOffset.X) + iView->RelativeViewOffset.X += QuakePower(quakeFactor, jiggers.RelIntensity.X, jiggers.RelOffset.X); + if (jiggers.RelIntensity.Y || jiggers.RelOffset.Y) + iView->RelativeViewOffset.Y += QuakePower(quakeFactor, jiggers.RelIntensity.Y, jiggers.RelOffset.Y); + if (jiggers.RelIntensity.Z || jiggers.RelOffset.Z) + iView->RelativeViewOffset.Z += QuakePower(quakeFactor, jiggers.RelIntensity.Z, jiggers.RelOffset.Z); + + if (jiggers.Intensity.X || jiggers.Offset.X) + iView->ViewOffset.X += QuakePower(quakeFactor, jiggers.Intensity.X, jiggers.Offset.X); + if (jiggers.Intensity.Y || jiggers.Offset.Y) + iView->ViewOffset.Y += QuakePower(quakeFactor, jiggers.Intensity.Y, jiggers.Offset.Y); + if (jiggers.Intensity.Z || jiggers.Offset.Z) + iView->ViewOffset.Z += QuakePower(quakeFactor, jiggers.Intensity.Z, jiggers.Offset.Z); } } - viewpoint.extralight = viewpoint.camera->player ? viewpoint.camera->player->extralight : 0; + // [MR] Apply view angles as the viewpoint angles if asked to do so. + if (matchPlayer) + iView->New.Angles = usePawn ? (client->flags8 & MF8_ABSVIEWANGLES ? client->ViewAngles : client->Angles + client->ViewAngles) : mainView.Angles; + else + iView->New.Angles = !(viewPoint.camera->flags8 & MF8_ABSVIEWANGLES) ? viewPoint.camera->Angles : viewPoint.camera->ViewAngles; + + iView->New.ViewAngles = viewPoint.camera->ViewAngles; + // [MR] Process player angle changes if permitted to do so. + if (player != nullptr && (player->cheats & CF_SCALEDNOLERP) && P_NoInterpolation(player, viewPoint.camera)) + R_DoActorTickerAngleChanges(player, iView->New.Angles, viewPoint.TicFrac); + + // If currently tracking the player's real view, don't do any sort of interpolating. + if (matchPlayer && !usePawn) + viewPoint.camera->renderflags |= RF_NOINTERPOLATEVIEW; + + if (viewPoint.camera->player != nullptr) + player = viewPoint.camera->player; + + if (iView->prevTic == -1 || r_NoInterpolate || (viewPoint.camera->renderflags & RF_NOINTERPOLATEVIEW)) + { + viewPoint.camera->renderflags &= ~RF_NOINTERPOLATEVIEW; + R_ResetViewInterpolation(); + iView->prevTic = curTic; + } + + R_InterpolateView(viewPoint, player, viewPoint.TicFrac, iView); + + viewPoint.SetViewAngle(viewWindow); + + // Keep the view within the sector's floor and ceiling + if (viewPoint.sector->PortalBlocksMovement(sector_t::ceiling)) + { + const double z = viewPoint.sector->ceilingplane.ZatPoint(viewPoint.Pos) - 4.0; + if (viewPoint.Pos.Z > z) + viewPoint.Pos.Z = z; + } + + if (viewPoint.sector->PortalBlocksMovement(sector_t::floor)) + { + const double z = viewPoint.sector->floorplane.ZatPoint(viewPoint.Pos) + 4.0; + if (viewPoint.Pos.Z < z) + viewPoint.Pos.Z = z; + } + + viewPoint.extralight = viewPoint.camera->player != nullptr ? viewPoint.camera->player->extralight : 0; // killough 3/20/98, 4/4/98: select colormap based on player status // [RH] Can also select a blend - newblend = 0; - - TArray &lightlist = viewpoint.sector->e->XFloor.lightlist; + unsigned int newBlend = 0u; + const TArray& lightlist = viewPoint.sector->e->XFloor.lightlist; if (lightlist.Size() > 0) { - for(unsigned int i = 0; i < lightlist.Size(); i++) + for (size_t i = 0u; i < lightlist.Size(); ++i) { - secplane_t *plane; - int viewside; - plane = (i < lightlist.Size()-1) ? &lightlist[i+1].plane : &viewpoint.sector->floorplane; - viewside = plane->PointOnSide(viewpoint.Pos); + const secplane_t& plane = (i < lightlist.Size() - 1u) ? lightlist[i + 1u].plane : viewPoint.sector->floorplane; + int viewSide = plane.PointOnSide(viewPoint.Pos); + // Reverse the direction of the test if the plane was downward facing. // We want to know if the view is above it, whatever its orientation may be. - if (plane->fC() < 0) - viewside = -viewside; - if (viewside > 0) - { - // 3d floor 'fog' is rendered as a blending value - PalEntry blendv = lightlist[i].blend; + if (plane.fC() < 0.0) + viewSide = -viewSide; - // If no alpha is set, use 50% - if (blendv.a==0 && blendv!=0) blendv.a=128; - newblend = blendv.d; + if (viewSide > 0) + { + // 3d floor 'fog' is rendered as a blending value. + PalEntry blend = lightlist[i].blend; + + // If no alpha is set, use 50%. + if (!blend.a && blend != 0) + blend.a = 128u; + + newBlend = blend.d; break; } } } else { - const sector_t *s = viewpoint.sector->GetHeightSec(); - if (s != NULL) + const sector_t* const sec = viewPoint.sector->GetHeightSec(); + if (sec != nullptr) { - newblend = s->floorplane.PointOnSide(viewpoint.Pos) < 0 - ? s->bottommap - : s->ceilingplane.PointOnSide(viewpoint.Pos) < 0 - ? s->topmap - : s->midmap; - if (APART(newblend) == 0 && newblend >= fakecmaps.Size()) - newblend = 0; + newBlend = sec->floorplane.PointOnSide(viewPoint.Pos) < 0 + ? sec->bottommap + : sec->ceilingplane.PointOnSide(viewPoint.Pos) < 0 + ? sec->topmap + : sec->midmap; + + if (APART(newBlend) == 0u && newBlend >= fakecmaps.Size()) + newBlend = 0u; } } // [RH] Don't override testblend unless entering a sector with a // blend different from the previous sector's. Same goes with // NormalLight's maps pointer. - if (R_OldBlend != newblend) - { - R_OldBlend = newblend; - } + if (R_OldBlend != newBlend) + R_OldBlend = newBlend; - validcount++; + ++validcount; if (r_clearbuffer != 0) { - int color; + int color = 0; int hom = r_clearbuffer; - if (hom == 3) - { hom = ((screen->FrameTime / 128) & 1) + 1; - } if (hom == 1) - { color = GPalette.BlackIndex; - } else if (hom == 2) - { color = GPalette.WhiteIndex; - } else if (hom == 4) - { color = (screen->FrameTime / 32) & 255; - } else - { color = pr_hom(); - } + screen->SetClearColor(color); SWRenderer->SetClearColor(color); } @@ -1175,25 +1103,16 @@ void R_SetupFrame (FRenderViewpoint &viewpoint, FViewWindow &viewwindow, AActor // Scale the pitch to account for the pixel stretching, because the playsim doesn't know about this and treats it as 1:1. // However, to set up a projection matrix this needs to be adjusted. - double radPitch = viewpoint.Angles.Pitch.Normalized180().Radians(); - double angx = cos(radPitch); - double angy = sin(radPitch) * actor->Level->info->pixelstretch; - double alen = sqrt(angx*angx + angy*angy); - viewpoint.HWAngles.Pitch = FAngle::fromRad((float)asin(angy / alen)); - - viewpoint.HWAngles.Roll = FAngle::fromDeg(viewpoint.Angles.Roll.Degrees()); // copied for convenience. - - // ViewActor only gets set, if the camera actor should not be rendered - if (actor->player && actor->player - players == consoleplayer && - ((actor->player->cheats & CF_CHASECAM) || (r_deathcamera && actor->health <= 0)) && actor == actor->player->mo) - { - viewpoint.ViewActor = nullptr; - } - else - { - viewpoint.ViewActor = actor; - } + const double radPitch = viewPoint.Angles.Pitch.Normalized180().Radians(); + const double angx = cos(radPitch); + const double angy = sin(radPitch) * actor->Level->info->pixelstretch; + const double alen = sqrt(angx*angx + angy*angy); + + viewPoint.HWAngles.Pitch = FAngle::fromRad((float)asin(angy / alen)); + viewPoint.HWAngles.Roll = FAngle::fromDeg(viewPoint.Angles.Roll.Degrees()); + // ViewActor only gets set if the camera actor shouldn't be rendered. + viewPoint.ViewActor = viewPoint.showviewer ? nullptr : actor; } diff --git a/src/rendering/r_utility.h b/src/rendering/r_utility.h index 7ba6e738c..3013961eb 100644 --- a/src/rendering/r_utility.h +++ b/src/rendering/r_utility.h @@ -43,9 +43,8 @@ struct FRenderViewpoint int extralight; // extralight to be added to this viewpoint bool showviewer; // show the camera actor? - bool NoPortalPath; // Disable portal interpolation path for actor viewpos. - bool noviewer; // Force camera sprite off for first person. - void SetViewAngle(const FViewWindow &viewwindow); + bool bForceNoViewer; // Never show the camera Actor. + void SetViewAngle(const FViewWindow& viewWindow); }; @@ -118,7 +117,7 @@ void R_ClearInterpolationPath(); void R_AddInterpolationPoint(const DVector3a &vec); void R_SetViewSize (int blocks); void R_SetFOV (FRenderViewpoint &viewpoint, DAngle fov); -void R_SetupFrame (FRenderViewpoint &viewpoint, FViewWindow &viewwindow, AActor * camera); +void R_SetupFrame(FRenderViewpoint& viewPoint, const FViewWindow& viewWindow, AActor* const camera); void R_SetViewAngle (FRenderViewpoint &viewpoint, const FViewWindow &viewwindow); // Called by startup code.