Isometric Mode and Robin (#2618)

* Feature-complete isometric mode fork.

* Dithered transparency condition tweaks.

* Dithered transparency for non-corpse monsters only (and missiles).

* SpectatorCamera vertical shift.

* Including math.h in hw_sprites.cpp to keep visual studio happy (it couldn't find M_SQRT2 definition).

* Defining MY_SQRT2 in hw_sprites.cpp to keep visual studio happy (it couldn't find M_SQRT2 definition).

* Defining MY_SQRT2 in r_utility.cpp also to keep visual studio happy.

* retrigger checks

* Have correct sprite angle-frame face the camera with orthographic projection enabled.

* Dithered Transparency now works properly on 3D floors. Moved that dither-trans flag setting code within hw_bsp.cpp to handle double-processing of linedefs. Added helper functions to FRenderViewpoint class 'bool IsOrtho()' and 'bool IsAllowedOoB()' to clean up checks everywhere in the code.

* Fixed indents. Added bbox property to subsector struct and use it instead of BSP nodes and Clippers (creating a bbox around viewpoint and checking for overlap) in orthographic mode when no fog of war is active. Turns out to be much faster. Though you need really big maps (Winter's Fury MAP01) to see a difference in fps.

* Non-linux checks don't like uint. Changed to unsigned int.

* Small change of a float to camera.zs. Ignore for testing. Should make no difference.

* Update actor.h to remain mergeable

RF2_NOMIPMAP was introduced, so I had to displace RF_ISOMETRICSPRITES to next bit.
This commit is contained in:
dileepvr 2024-08-11 08:04:40 -06:00 committed by GitHub
commit 95b264bdb6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
33 changed files with 819 additions and 84 deletions

View file

@ -66,7 +66,9 @@
#include "i_system.h"
#include "v_draw.h"
#include "i_interface.h"
#include "d_main.h"
const float MY_SQRT2 = 1.41421356237309504880; // sqrt(2)
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
extern bool DrawFSHUD; // [RH] Defined in d_main.cpp
@ -103,6 +105,8 @@ CVAR (Bool, r_deathcamera, false, CVAR_ARCHIVE)
CVAR (Int, r_clearbuffer, 0, 0)
CVAR (Bool, r_drawvoxels, true, 0)
CVAR (Bool, r_drawplayersprites, true, 0) // [RH] Draw player sprites?
CVARD (Bool, r_radarclipper, false, CVAR_ARCHIVE | CVAR_SERVERINFO | CVAR_CHEAT, "Use the horizontal clipper from camera->tracer's perspective")
CVARD (Bool, r_dithertransparency, false, CVAR_ARCHIVE | CVAR_SERVERINFO | CVAR_CHEAT, "Use dithered-transparency shading for actor-occluding level geometry")
CUSTOM_CVAR(Float, r_quakeintensity, 1.0f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
{
if (self < 0.f) self = 0.f;
@ -155,9 +159,14 @@ FRenderViewpoint::FRenderViewpoint()
Sin = 0.0;
TanCos = 0.0;
TanSin = 0.0;
PitchCos = 0.0;
PitchSin = 0.0;
floordistfact = 0.0;
cotfloor = 0.0;
camera = nullptr;
sector = nullptr;
FieldOfView = DAngle::fromDeg(90.); // Angles in the SCREENWIDTH wide window
ScreenProj = 0.0;
TicFrac = 0.0;
FrameTime = 0;
extralight = 0;
@ -552,39 +561,42 @@ void R_InterpolateView(FRenderViewpoint& viewPoint, const player_t* const player
// Due to interpolation this is not necessarily the same as the sector the camera is in.
viewPoint.sector = viewLvl->PointInRenderSubsector(viewPoint.Pos)->sector;
bool moved = false;
while (!viewPoint.sector->PortalBlocksMovement(sector_t::ceiling))
if (!viewPoint.IsAllowedOoB() || !V_IsHardwareRenderer())
{
if (viewPoint.Pos.Z > viewPoint.sector->GetPortalPlaneZ(sector_t::ceiling))
bool moved = false;
while (!viewPoint.sector->PortalBlocksMovement(sector_t::ceiling))
{
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))
{
if (viewPoint.Pos.Z < viewPoint.sector->GetPortalPlaneZ(sector_t::floor))
if (viewPoint.Pos.Z > viewPoint.sector->GetPortalPlaneZ(sector_t::ceiling))
{
const DVector2 offset = viewPoint.sector->GetPortalDisplacement(sector_t::floor);
const DVector2 offset = viewPoint.sector->GetPortalDisplacement(sector_t::ceiling);
viewPoint.Pos += offset;
viewPoint.ActorPos += offset;
viewPoint.sector = viewPoint.sector->GetPortal(sector_t::floor)->mDestination;
viewPoint.sector = viewPoint.sector->GetPortal(sector_t::ceiling)->mDestination;
moved = true;
}
else
{
break;
}
}
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))
@ -680,10 +692,46 @@ void FRenderViewpoint::SetViewAngle(const FViewWindow& viewWindow)
TanSin = viewWindow.FocalTangent * Sin;
TanCos = viewWindow.FocalTangent * Cos;
PitchSin = Angles.Pitch.Sin();
PitchCos = Angles.Pitch.Cos();
floordistfact = MY_SQRT2 + ( fabs(Cos) > fabs(Sin) ? 1.0/fabs(Cos) : 1.0/fabs(Sin) );
cotfloor = ( fabs(Cos) > fabs(Sin) ? fabs(Sin/Cos) : fabs(Cos/Sin) );
const DVector2 v = Angles.Yaw.ToVector();
ViewVector.X = v.X;
ViewVector.Y = v.Y;
HWAngles.Yaw = FAngle::fromDeg(270.0 - Angles.Yaw.Degrees());
if (IsOrtho() && (camera->ViewPos->Offset.XY().Length() > 0.0))
ScreenProj = 1.34396 / camera->ViewPos->Offset.Length(); // [DVR] Estimated. +/-1 should be top/bottom of screen.
}
//==========================================================================
//
// R_IsAllowedOoB()
// Checks if camera actor exists, has viewpos,
// and viewpos has VPSF_ALLOWOUTOFBOUNDS flag set.
//
//==========================================================================
bool FRenderViewpoint::IsAllowedOoB()
{
return (camera && camera->ViewPos && (camera->ViewPos->Flags & VPSF_ALLOWOUTOFBOUNDS));
}
//==========================================================================
//
// R_IsOrtho()
// Checks if camera actor exists, has viewpos,
// and viewpos has VPSF_ORTHOGRAPHIC flag set.
//
//==========================================================================
bool FRenderViewpoint::IsOrtho()
{
return (camera && camera->ViewPos && (camera->ViewPos->Flags & VPSF_ORTHOGRAPHIC));
}
//==========================================================================
@ -1017,14 +1065,15 @@ void R_SetupFrame(FRenderViewpoint& viewPoint, const FViewWindow& viewWindow, AA
viewPoint.SetViewAngle(viewWindow);
// Keep the view within the sector's floor and ceiling
if (viewPoint.sector->PortalBlocksMovement(sector_t::ceiling))
// But allow VPSF_ALLOWOUTOFBOUNDS camera viewpoints to go out of bounds when using hardware renderer
if (viewPoint.sector->PortalBlocksMovement(sector_t::ceiling) && (!viewPoint.IsAllowedOoB() || !V_IsHardwareRenderer()))
{
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))
if (viewPoint.sector->PortalBlocksMovement(sector_t::floor) && (!viewPoint.IsAllowedOoB() || !V_IsHardwareRenderer()))
{
const double z = viewPoint.sector->floorplane.ZatPoint(viewPoint.Pos) + 4.0;
if (viewPoint.Pos.Z < z)