From 25f1407228be4604693df78d1a771b78df1ce601 Mon Sep 17 00:00:00 2001 From: "Dileep V. Reddy" Date: Thu, 25 Jan 2024 21:40:25 -0700 Subject: [PATCH] Cleaning up implementation of isometric camera with optional orthographic projection. All CVars, mapinfo variables, and playerinfo/playerpawn variables are gone. A Camera actor named 'SpectatorCamera' is defined in warsrc/static/zscript/actors/shared/camera.zs The following new flag bits were defined in the 'DViewPosition' struct for use with actor->ViewPos in src/playsim/actor.h: VPSF_ALLOWOUTOFBOUNDS = 1 << 3, // Allow viewpoint to go out of bounds (hardware renderer only). VPSF_ORTHOGRAPHIC = 1 << 4, // Use orthographic projection. VPSF_ISOMETRICSPRITES = 1 << 5, // Displace sprites towards camera and don't billboard (drawn from isometric perspective). Basically, spawn a SpectatorCamera actor with the appropriate flags and set it to player.camera. See example template: https://www.mediafire.com/file/fv8rytayjt9l6g1/isometric_actor_wads.zip/file Has been tested with multiplayer death and disconnection (and respawns). Not tested with portals. Still only works with hardware renderer (mostly). But should be compatible with older mods and libraries. --- .../rendering/hwrenderer/data/hw_cvars.h | 6 --- src/g_level.cpp | 8 ---- src/g_levellocals.h | 13 ------ src/gamedata/g_mapinfo.cpp | 19 -------- src/gamedata/g_mapinfo.h | 7 --- src/playsim/actor.h | 3 ++ src/playsim/d_player.h | 2 - src/playsim/p_user.cpp | 3 -- src/rendering/hwrenderer/hw_entrypoint.cpp | 42 ++++-------------- src/rendering/hwrenderer/scene/hw_sprites.cpp | 20 ++++++--- src/rendering/r_utility.cpp | 43 +++++-------------- src/scripting/vmthunks.cpp | 16 ------- wadsrc/static/zscript/actors/player/player.zs | 1 - wadsrc/static/zscript/actors/shared/camera.zs | 41 ++++++++++++++++++ wadsrc/static/zscript/constants.zs | 3 ++ wadsrc/static/zscript/doombase.zs | 1 - 16 files changed, 80 insertions(+), 148 deletions(-) diff --git a/src/common/rendering/hwrenderer/data/hw_cvars.h b/src/common/rendering/hwrenderer/data/hw_cvars.h index 2f90807eb..ba8c9cec6 100644 --- a/src/common/rendering/hwrenderer/data/hw_cvars.h +++ b/src/common/rendering/hwrenderer/data/hw_cvars.h @@ -55,10 +55,4 @@ EXTERN_CVAR(Bool, gl_brightfog) EXTERN_CVAR(Bool, gl_lightadditivesurfaces) EXTERN_CVAR(Bool, gl_notexturefill) -EXTERN_CVAR(Bool, r_isocam) -EXTERN_CVAR(Int, r_isoviewpoint) -EXTERN_CVAR(Float, r_iso_camdist) -EXTERN_CVAR(Float, r_iso_dist) -EXTERN_CVAR(Float, r_iso_pitch) EXTERN_CVAR(Bool, r_drawplayersprites) -EXTERN_CVAR(Bool, r_orthographic) diff --git a/src/g_level.cpp b/src/g_level.cpp index cad0a9f86..ff42656da 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -1803,8 +1803,6 @@ void FLevelLocals::Init() flags3 = 0; ImpactDecalCount = 0; frozenstate = 0; - isocam_pitch = 30.f; - iso_dist = 300.f; info = FindLevelInfo (MapName.GetChars()); @@ -1835,12 +1833,6 @@ void FLevelLocals::Init() if (info->gravity == DBL_MAX) gravity = 0; else gravity = info->gravity * 35/TICRATE; } - if (info->isocam_pitch < 0.f) isocam_pitch = 0.f; - else if (info->isocam_pitch > 89.f) isocam_pitch = 89.f; - else isocam_pitch = info->isocam_pitch; - if (info->iso_dist < 1.f) iso_dist = 1.f; - if (info->iso_dist > 1000.f) iso_dist = 1000.f; - else iso_dist = info->iso_dist; if (info->aircontrol != 0.f) { aircontrol = info->aircontrol; diff --git a/src/g_levellocals.h b/src/g_levellocals.h index 799915d4c..cf63f81b2 100644 --- a/src/g_levellocals.h +++ b/src/g_levellocals.h @@ -664,8 +664,6 @@ public: double airfriction; int airsupply; int DefaultEnvironment; // Default sound environment. - float isocam_pitch; - float iso_dist; DSeqNode *SequenceListHead; @@ -755,17 +753,6 @@ public: return !(flags & LEVEL_FREELOOK_NO); } - //========================================================================== - // - // - //========================================================================== - - bool IsIsometricMode() const - { - return (flags3 & LEVEL3_ISOMETRICMODE); - // What to do about multiplayer flags? Add a dmflags3 bit? - } - node_t *HeadNode() const { return nodes.Size() == 0 ? nullptr : &nodes[nodes.Size() - 1]; diff --git a/src/gamedata/g_mapinfo.cpp b/src/gamedata/g_mapinfo.cpp index f79f0a5db..dfe90b2c9 100644 --- a/src/gamedata/g_mapinfo.cpp +++ b/src/gamedata/g_mapinfo.cpp @@ -295,8 +295,6 @@ void level_info_t::Reset() outsidefogdensity = 0; skyfog = 0; pixelstretch = 1.2f; - isocam_pitch = 30.f; - iso_dist = 300.f; specialactions.Clear(); DefaultEnvironment = 0; @@ -1218,20 +1216,6 @@ DEFINE_MAP_OPTION(gravity, true) info->gravity = parse.sc.Float; } -DEFINE_MAP_OPTION(isocam_pitch, true) -{ - parse.ParseAssign(); - parse.sc.MustGetFloat(); - info->isocam_pitch = parse.sc.Float; -} - -DEFINE_MAP_OPTION(iso_dist, true) -{ - parse.ParseAssign(); - parse.sc.MustGetFloat(); - info->iso_dist = parse.sc.Float; -} - DEFINE_MAP_OPTION(nogravity, true) { info->gravity = DBL_MAX; @@ -1835,9 +1819,6 @@ MapFlagHandlers[] = { "disableskyboxao", MITYPE_CLRFLAG3, LEVEL3_SKYBOXAO, 0 }, { "avoidmelee", MITYPE_SETFLAG3, LEVEL3_AVOIDMELEE, 0 }, { "attenuatelights", MITYPE_SETFLAG3, LEVEL3_ATTENUATE, 0 }, - { "isometricmode", MITYPE_SETFLAG3, LEVEL3_ISOMETRICMODE, 0 }, - { "orthographic", MITYPE_SETFLAG3, LEVEL3_ORTHOGRAPHIC, 0 }, - { "isometricsprites", MITYPE_SETFLAG3, LEVEL3_ISOMETRICSPRITES, 0 }, { "nobotnodes", MITYPE_IGNORE, 0, 0 }, // Skulltag option: nobotnodes { "nopassover", MITYPE_COMPATFLAG, COMPATF_NO_PASSMOBJ, 0 }, { "passover", MITYPE_CLRCOMPATFLAG, COMPATF_NO_PASSMOBJ, 0 }, diff --git a/src/gamedata/g_mapinfo.h b/src/gamedata/g_mapinfo.h index 1bd379b17..b56d3b632 100644 --- a/src/gamedata/g_mapinfo.h +++ b/src/gamedata/g_mapinfo.h @@ -270,10 +270,6 @@ enum ELevelFlags : unsigned int LEVEL3_AVOIDMELEE = 0x00020000, // global flag needed for proper MBF support. LEVEL3_NOJUMPDOWN = 0x00040000, // only for MBF21. Inverse of MBF's dog_jumping flag. LEVEL3_LIGHTCREATED = 0x00080000, // a light had been created in the last frame - - LEVEL3_ISOMETRICMODE = 0x00100000, // render map in isometric camera mode - LEVEL3_ORTHOGRAPHIC = 0x00200000, // render with orthographic projection (only in isometric camera mode) - LEVEL3_ISOMETRICSPRITES = 0x00400000, // displace isometrically drawn sprites towards isometric camera }; @@ -380,9 +376,6 @@ struct level_info_t int skyfog; float pixelstretch; - float isocam_pitch; - float iso_dist; - // Redirection: If any player is carrying the specified item, then // you go to the RedirectMap instead of this one. FName RedirectType; diff --git a/src/playsim/actor.h b/src/playsim/actor.h index 35fc44598..4a1faa5da 100644 --- a/src/playsim/actor.h +++ b/src/playsim/actor.h @@ -692,6 +692,9 @@ enum EViewPosFlags // [MC] Flags for SetViewPos. { VPSF_ABSOLUTEOFFSET = 1 << 1, // Don't include angles. VPSF_ABSOLUTEPOS = 1 << 2, // Use absolute position. + VPSF_ALLOWOUTOFBOUNDS = 1 << 3, // Allow viewpoint to go out of bounds (hardware renderer only). + VPSF_ORTHOGRAPHIC = 1 << 4, // Use orthographic projection. + VPSF_ISOMETRICSPRITES = 1 << 5, // Displace sprites towards camera and don't billboard (drawn from isometric perspective). }; enum EAnimOverrideFlags diff --git a/src/playsim/d_player.h b/src/playsim/d_player.h index e7c703ad1..675813873 100644 --- a/src/playsim/d_player.h +++ b/src/playsim/d_player.h @@ -324,8 +324,6 @@ public: // This only represents the thrust that the player applies himself. // This avoids anomalies with such things as Boom ice and conveyors. DVector2 Vel = { 0,0 }; - // Used by isometric camera (See RenderViewpoint() in src/rendering/hwrenderer/hw_entrypoint.cpp) - int isoyaw = 225; // degrees bool centering = false; uint8_t turnticks = 0; diff --git a/src/playsim/p_user.cpp b/src/playsim/p_user.cpp index 121db3f64..a4e2c6485 100644 --- a/src/playsim/p_user.cpp +++ b/src/playsim/p_user.cpp @@ -270,7 +270,6 @@ void player_t::CopyFrom(player_t &p, bool copyPSP) deltaviewheight = p.deltaviewheight; bob = p.bob; Vel = p.Vel; - isoyaw = p.isoyaw; centering = p.centering; turnticks = p.turnticks; attackdown = p.attackdown; @@ -1636,7 +1635,6 @@ void player_t::Serialize(FSerializer &arc) ("deltaviewheight", deltaviewheight) ("bob", bob) ("vel", Vel) - ("isoyaw", isoyaw) ("centering", centering) ("health", health) ("inventorytics", inventorytics) @@ -1744,7 +1742,6 @@ DEFINE_FIELD_X(PlayerInfo, player_t, viewheight) DEFINE_FIELD_X(PlayerInfo, player_t, deltaviewheight) DEFINE_FIELD_X(PlayerInfo, player_t, bob) DEFINE_FIELD_X(PlayerInfo, player_t, Vel) -DEFINE_FIELD_X(PlayerInfo, player_t, isoyaw) DEFINE_FIELD_X(PlayerInfo, player_t, centering) DEFINE_FIELD_X(PlayerInfo, player_t, turnticks) DEFINE_FIELD_X(PlayerInfo, player_t, attackdown) diff --git a/src/rendering/hwrenderer/hw_entrypoint.cpp b/src/rendering/hwrenderer/hw_entrypoint.cpp index df8371c49..03c68dee0 100644 --- a/src/rendering/hwrenderer/hw_entrypoint.cpp +++ b/src/rendering/hwrenderer/hw_entrypoint.cpp @@ -162,40 +162,14 @@ sector_t* RenderViewpoint(FRenderViewpoint& mainvp, AActor* camera, IntRect* bou di->Viewpoint.FieldOfView = DAngle::fromDeg(fov); // Set the real FOV for the current scene (it's not necessarily the same as the global setting in r_viewpoint) - // Switch viewpoint for isometric camera - if((r_isocam || (camera->Level->flags3 & LEVEL3_ISOMETRICMODE)) && camera->player != NULL) - { - float camdist = camera->Level->iso_dist; - float isocam_pitch = camera->Level->isocam_pitch; - if (r_isoviewpoint > 0) - { - isocam_pitch = r_iso_pitch; - camdist = r_iso_dist; - camera->player->isoyaw = 45.0 * (r_isoviewpoint - 1); // The eight cardinal directions - } - float inv_iso_dist = 1.0f/camdist; // camdist can change in next line - bool iso_ortho = ((r_isoviewpoint > 0) && r_orthographic) || ((r_isoviewpoint == 0) && camera->Level->flags3 & LEVEL3_ORTHOGRAPHIC); - if (iso_ortho) camdist = r_iso_camdist; - vp.Pos.X -= camdist * DAngle::fromDeg(camera->player->isoyaw).Cos(); - vp.Pos.Y -= camdist * DAngle::fromDeg(camera->player->isoyaw).Sin(); - vp.Pos.Z += camdist * FAngle::fromDeg(isocam_pitch).Tan() - 0.5 * camera->player->viewheight; - vp.HWAngles.Pitch = FAngle::fromDeg(isocam_pitch); - vp.Angles.Pitch = DAngle::fromDeg(isocam_pitch); - vp.Angles.Yaw = DAngle::fromDeg(camera->player->isoyaw); - vp.Angles.Roll = DAngle::fromDeg(0); - vp.showviewer = true; // Draw player sprite - r_drawplayersprites = false; // Don't draw first-person hands/weapons - // Stereo mode specific perspective projection - if (!iso_ortho) inv_iso_dist = 1.0f; - di->VPUniforms.mProjectionMatrix = eye.GetProjection(fov, ratio, fovratio * inv_iso_dist, iso_ortho); - } - else // Regular first-person viewpoint - { - vp.showviewer = false; - r_drawplayersprites = true; // Restore first-person hands/weapons - // Stereo mode specific perspective projection - di->VPUniforms.mProjectionMatrix = eye.GetProjection(fov, ratio, fovratio, false); - } + if(mainview && (camera->ViewPos != NULL) && (camera->ViewPos->Offset.XY().Length() > 0)) r_drawplayersprites = false; + else r_drawplayersprites = true; // Restore first-person hands/weapons + // Stereo mode specific perspective projection + float inv_iso_dist = 1.0f; + bool iso_ortho = (camera->ViewPos != NULL) && (camera->ViewPos->Flags & VPSF_ORTHOGRAPHIC); + if (iso_ortho && (camera->ViewPos->Offset.XY().Length() > 0)) inv_iso_dist = 3.0f/camera->ViewPos->Offset.XY().Length(); + di->VPUniforms.mProjectionMatrix = eye.GetProjection(fov, ratio, fovratio * inv_iso_dist, iso_ortho); + // Stereo mode specific viewpoint adjustment vp.Pos += eye.GetViewShift(vp.HWAngles.Yaw.Degrees()); di->SetupView(RenderState, vp.Pos.X, vp.Pos.Y, vp.Pos.Z, false, false); diff --git a/src/rendering/hwrenderer/scene/hw_sprites.cpp b/src/rendering/hwrenderer/scene/hw_sprites.cpp index 7c896a10e..d82b0972c 100644 --- a/src/rendering/hwrenderer/scene/hw_sprites.cpp +++ b/src/rendering/hwrenderer/scene/hw_sprites.cpp @@ -477,9 +477,7 @@ bool HWSprite::CalculateVertices(HWDrawInfo* di, FVector3* v, DVector3* vp) // Rotate the sprite about the vector starting at the center of the sprite // triangle strip and with direction orthogonal to where the player is looking // in the x/y plane. - if(r_isocam || (di->Level->flags3 & LEVEL3_ISOMETRICMODE)) mat.Translate(0.0, z2 - center.Z, 0.0); mat.Rotate(-sin(angleRad), 0, cos(angleRad), -HWAngles.Pitch.Degrees()); - if(r_isocam || (di->Level->flags3 & LEVEL3_ISOMETRICMODE)) mat.Translate(0.0, center.Z - z2, 0.0); } mat.Translate(-center.X, -center.Z, -center.Y); // retreat from sprite center @@ -491,7 +489,7 @@ bool HWSprite::CalculateVertices(HWDrawInfo* di, FVector3* v, DVector3* vp) } else // traditional "Y" billboard mode { - if (doRoll || !offset.isZero()) + if (doRoll || !offset.isZero() || ((di->Viewpoint.camera->ViewPos != NULL) && (di->Viewpoint.camera->ViewPos->Flags & VPSF_ISOMETRICSPRITES))) { mat.MakeIdentity(); @@ -509,6 +507,16 @@ bool HWSprite::CalculateVertices(HWDrawInfo* di, FVector3* v, DVector3* vp) mat.Translate(-center.X, -center.Z, -center.Y); } + if ((di->Viewpoint.camera->ViewPos != NULL) && (di->Viewpoint.camera->ViewPos->Flags & VPSF_ISOMETRICSPRITES)) + { + float angleRad = (FAngle::fromDeg(270.) - HWAngles.Yaw).Radians(); + mat.Translate(center.X, center.Z, center.Y); + mat.Translate(0.0, z2 - center.Z, 0.0); + mat.Rotate(-sin(angleRad), 0, cos(angleRad), -HWAngles.Pitch.Degrees()); + mat.Translate(0.0, center.Z - z2, 0.0); + mat.Translate(-center.X, -center.Z, -center.Y); + } + v[0] = mat * FVector3(x1, z1, y1); v[1] = mat * FVector3(x2, z1, y2); v[2] = mat * FVector3(x1, z2, y1); @@ -902,7 +910,7 @@ void HWSprite::Process(HWDrawInfo *di, AActor* thing, sector_t * sector, area_t { bool mirror = false; DAngle ang = (thingpos - vp.Pos).Angle(); - if(r_isocam || (di->Level->flags3 & LEVEL3_ISOMETRICMODE)) ang = vp.Angles.Yaw; + if((di->Viewpoint.camera->ViewPos != NULL) && (di->Viewpoint.camera->ViewPos->Flags & VPSF_ISOMETRICSPRITES)) ang = vp.Angles.Yaw; FTextureID patch; // [ZZ] add direct picnum override if (isPicnumOverride) @@ -1022,7 +1030,7 @@ void HWSprite::Process(HWDrawInfo *di, AActor* thing, sector_t * sector, area_t x2 = x - viewvecY*rightfac; y1 = y + viewvecX*leftfac; y2 = y + viewvecX*rightfac; - if(di->Level->flags3 & LEVEL3_ISOMETRICSPRITES && (r_isocam || (di->Level->flags3 & LEVEL3_ISOMETRICMODE))) // If sprites are drawn from an isometric perspective + if((di->Viewpoint.camera->ViewPos != NULL) && (di->Viewpoint.camera->ViewPos->Flags & VPSF_ISOMETRICSPRITES)) // If sprites are drawn from an isometric perspective { float signX = 1.0; float signY = 1.0; @@ -1076,7 +1084,7 @@ void HWSprite::Process(HWDrawInfo *di, AActor* thing, sector_t * sector, area_t } depth = (float)((x - vp.Pos.X) * vp.TanCos + (y - vp.Pos.Y) * vp.TanSin); - if(r_isocam || (di->Level->flags3 & LEVEL3_ISOMETRICMODE)) depth = depth * vp.PitchCos - vp.PitchSin * z2; // Helps with stacking actors with small xy offsets + if(((di->Viewpoint.camera->ViewPos != NULL) && (di->Viewpoint.camera->ViewPos->Flags & VPSF_ISOMETRICSPRITES))) depth = depth * vp.PitchCos - vp.PitchSin * z2; // Helps with stacking actors with small xy offsets if (isSpriteShadow) depth += 1.f/65536.f; // always sort shadows behind the sprite. // light calculation diff --git a/src/rendering/r_utility.cpp b/src/rendering/r_utility.cpp index a72e1832b..e4851906b 100644 --- a/src/rendering/r_utility.cpp +++ b/src/rendering/r_utility.cpp @@ -66,6 +66,7 @@ #include "i_system.h" #include "v_draw.h" #include "i_interface.h" +#include "d_main.h" // EXTERNAL DATA DECLARATIONS ---------------------------------------------- @@ -101,35 +102,6 @@ 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_isocam, false, CVAR_ARCHIVE | CVAR_SERVERINFO | CVAR_CHEAT, "render from isometric viewpoint.") -CVARD (Bool, r_orthographic, true, CVAR_ARCHIVE | CVAR_SERVERINFO | CVAR_CHEAT, "render orthographic projection. Only used with r_isocam") -CUSTOM_CVARD(Float, r_iso_pitch, 30.0f, CVAR_ARCHIVE | CVAR_SERVERINFO | CVAR_CHEAT, "pitch for isometric camera: 0 to 89 degrees. Used only if r_isoviewpoint > 0.") -{ - if (self < 0.f) - self = 0.f; - else if (self > 89.f) - self = 89.f; -} -CUSTOM_CVAR(Float, r_iso_camdist, 1000.0f, CVAR_ARCHIVE | CVAR_SERVERINFO | CVAR_CHEAT) -{ - // Keep this large to avoid texture clipping, not used if r_orthographic is false - if (self < 1000.f) - self = 1000.f; -} -CUSTOM_CVARD(Int, r_isoviewpoint, 0, CVAR_ARCHIVE, "Isometric viewpoint angle. 1 to 8 for cardinal directions using r_iso_pitch and r_iso_dist. 0 for ignore and use player->isoyaw, level->isocam_pitch and level->iso_dist (from mapinfo).") -{ - if (self < 0) - self = 0; - else if (self > 8) - self = 8; -} -CUSTOM_CVARD(Float, r_iso_dist, 300.0, CVAR_ARCHIVE | CVAR_SERVERINFO | CVAR_CHEAT, "how far the isometric camera (r_isocam) is in the XY plane. Used only if r_isoviewpoint > 0.") -{ - if (self < 0.f) - self = 0.f; - else if (self > 1000.f) - self = 1000.f; -} CUSTOM_CVAR(Float, r_quakeintensity, 1.0f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) { if (self < 0.f) self = 0.f; @@ -983,7 +955,11 @@ void R_SetupFrame (FRenderViewpoint &viewpoint, FViewWindow &viewwindow, AActor // Interpolation still happens with everything else though and seems to work fine. DefaultDraw = false; viewpoint.NoPortalPath = true; - P_AdjustViewPos(mo, orig, next, viewpoint.sector, unlinked, VP, &viewpoint); + // Allow VPSF_ALLOWOUTOFBOUNDS camera viewpoints to go out of bounds when using HW renderer + if (!(VP->Flags & VPSF_ALLOWOUTOFBOUNDS) || !V_IsHardwareRenderer()) + { + P_AdjustViewPos(mo, orig, next, viewpoint.sector, unlinked, VP, &viewpoint); + } if (viewpoint.sector->PortalGroup != oldsector->PortalGroup || (unlinked && ((iview->New.Pos.XY() - iview->Old.Pos.XY()).LengthSquared()) > 256 * 256)) { @@ -1030,7 +1006,10 @@ void R_SetupFrame (FRenderViewpoint &viewpoint, FViewWindow &viewwindow, AActor 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 + bool disembodied = false; + if (viewpoint.camera->ViewPos != NULL) disembodied = viewpoint.camera->ViewPos->Flags & VPSF_ALLOWOUTOFBOUNDS; + if (viewpoint.sector->PortalBlocksMovement(sector_t::ceiling) && (!disembodied || !V_IsHardwareRenderer())) { double theZ = viewpoint.sector->ceilingplane.ZatPoint(viewpoint.Pos) - 4; if (viewpoint.Pos.Z > theZ) @@ -1039,7 +1018,7 @@ void R_SetupFrame (FRenderViewpoint &viewpoint, FViewWindow &viewwindow, AActor } } - if (viewpoint.sector->PortalBlocksMovement(sector_t::floor)) + if (viewpoint.sector->PortalBlocksMovement(sector_t::floor) && (!disembodied || !V_IsHardwareRenderer())) { double theZ = viewpoint.sector->floorplane.ZatPoint(viewpoint.Pos) + 4; if (viewpoint.Pos.Z < theZ) diff --git a/src/scripting/vmthunks.cpp b/src/scripting/vmthunks.cpp index 6a43dde5a..3dc8b974d 100644 --- a/src/scripting/vmthunks.cpp +++ b/src/scripting/vmthunks.cpp @@ -1693,22 +1693,6 @@ DEFINE_ACTION_FUNCTION_NATIVE(_Sector, SetXOffset, SetXOffset) PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals); ACTION_RETURN_BOOL(self->IsFreelookAllowed()); } - - //========================================================================== - // - // - //========================================================================== - - static int IsIsometricMode(FLevelLocals *self) - { - return self->IsIsometricMode(); - } - - DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, IsIsometricMode, IsIsometricMode) - { - PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals); - ACTION_RETURN_BOOL(self->IsIsometricMode()); - } //========================================================================== // diff --git a/wadsrc/static/zscript/actors/player/player.zs b/wadsrc/static/zscript/actors/player/player.zs index 6c687210b..235b97c8d 100644 --- a/wadsrc/static/zscript/actors/player/player.zs +++ b/wadsrc/static/zscript/actors/player/player.zs @@ -2744,7 +2744,6 @@ struct PlayerInfo native play // self is what internally is known as player_t native double deltaviewheight; native double bob; native vector2 vel; - native int isoyaw; native bool centering; native uint8 turnticks; native bool attackdown; diff --git a/wadsrc/static/zscript/actors/shared/camera.zs b/wadsrc/static/zscript/actors/shared/camera.zs index d7826c051..08f969dc2 100644 --- a/wadsrc/static/zscript/actors/shared/camera.zs +++ b/wadsrc/static/zscript/actors/shared/camera.zs @@ -128,3 +128,44 @@ class AimingCamera : SecurityCamera } } + +class SpectatorCamera : Actor +{ + + default + { + +NOBLOCKMAP + +NOGRAVITY + +NOSECTOR + +NOINTERACTION + RenderStyle "None"; + CameraHeight 0; + } + + void Init(double dist, double yaw, double inpitch, int inflags) + { + if((inflags & VPSF_ORTHOGRAPHIC) || ((inflags == -1) && (ViewPos.Flags & VPSF_ORTHOGRAPHIC))) dist *= 3.0; + SetViewPos((-dist*Cos(yaw), -dist*Sin(yaw), dist*Tan(inpitch)-0.5*players[consoleplayer].mo.height), inflags); + // CameraHeight = players[consoleplayer].mo.viewheight; // Not used + LookAtSelf(inpitch); + } + + void LookAtSelf(double inpitch) + { + if(ViewPos.Offset != (0., 0., 0.)) + { + Vector3 negviewpos = (-1.0) * ViewPos.Offset; + angle = negviewpos.Angle(); + pitch = inpitch; + } + } + + override void Tick() + { + if(player != NULL) + { + cameraFOV = player.FOV; + SetOrigin(player.mo.pos, true); + } + } +} diff --git a/wadsrc/static/zscript/constants.zs b/wadsrc/static/zscript/constants.zs index 71b0fb99d..3eab8cf2e 100644 --- a/wadsrc/static/zscript/constants.zs +++ b/wadsrc/static/zscript/constants.zs @@ -420,6 +420,9 @@ enum EViewPosFlags { VPSF_ABSOLUTEOFFSET = 1 << 1, // Don't include angles. VPSF_ABSOLUTEPOS = 1 << 2, // Use absolute position. + VPSF_ALLOWOUTOFBOUNDS = 1 << 3, // Allow viewpoint to go out of bounds (hardware renderer only). + VPSF_ORTHOGRAPHIC = 1 << 4, // Use orthographic projection. + VPSF_ISOMETRICSPRITES = 1 << 5, // Displace sprites towards camera and don't billboard (drawn from isometric perspective). }; // Flags for A_TakeInventory and A_TakeFromTarget diff --git a/wadsrc/static/zscript/doombase.zs b/wadsrc/static/zscript/doombase.zs index d2bd8a21a..5a99de9e6 100644 --- a/wadsrc/static/zscript/doombase.zs +++ b/wadsrc/static/zscript/doombase.zs @@ -490,7 +490,6 @@ struct LevelLocals native native bool IsJumpingAllowed() const; native bool IsCrouchingAllowed() const; native bool IsFreelookAllowed() const; - native bool IsIsometricMode() const; native void StartIntermission(Name type, int state) const; native play SpotState GetSpotState(bool create = true); native int FindUniqueTid(int start = 0, int limit = 0);