From fd0681edda810c099df1b97299b84758844e4e63 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 7 Jan 2017 01:07:35 +0100 Subject: [PATCH] - fixed some edge cases with visible player sprites through non-static line portals. This required reinstating some code which I thought was no longer needed. --- src/actor.h | 1 + src/gl/scene/gl_portal.cpp | 25 +++++++++++++++++++++++-- src/gl/scene/gl_portal.h | 1 + src/gl/scene/gl_sprite.cpp | 17 +++++++++++++++++ 4 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/actor.h b/src/actor.h index ffe3cc1a4..439ae2644 100644 --- a/src/actor.h +++ b/src/actor.h @@ -418,6 +418,7 @@ enum ActorRenderFlag RF_FLATSPRITE = 0x2000, // Flat sprite RF_VOXELSPRITE = 0x3000, // Voxel object RF_INVISIBLE = 0x8000, // Don't bother drawing this actor + RF_MAYBEINVISIBLE = 0x10000, RF_ROLLSPRITE = 0x40000, //[marrub]roll the sprite billboard RF_DONTFLIP = 0x80000, // Don't flip it when viewed from behind. RF_ROLLCENTER = 0x00100000, // Rotate from the center of sprite instead of offsets diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index e1fed484a..4cf8b9e7b 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -288,7 +288,9 @@ bool GLPortal::Start(bool usestencil, bool doquery) savedAngle = ViewAngle; savedviewactor=GLRenderer->mViewActor; savedviewarea=in_area; - savedvisibility = camera ? camera->renderflags & RF_INVISIBLE : ActorRenderFlags::FromInt(0); + savedviewpath[0] = ViewPath[0]; + savedviewpath[1] = ViewPath[1]; + savedvisibility = camera ? camera->renderflags & RF_MAYBEINVISIBLE : ActorRenderFlags::FromInt(0); PrevPortal = GLRenderer->mCurrentPortal; @@ -350,13 +352,15 @@ void GLPortal::End(bool usestencil) if (needdepth) FDrawInfo::EndDrawInfo(); // Restore the old view + ViewPath[0] = savedviewpath[0]; + ViewPath[1] = savedviewpath[1]; ViewPos = savedViewPos; r_showviewer = savedshowviewer; ViewActorPos = savedViewActorPos; ViewAngle = savedAngle; GLRenderer->mViewActor=savedviewactor; in_area=savedviewarea; - if (camera != nullptr) camera->renderflags = (camera->renderflags & ~RF_INVISIBLE) | savedvisibility; + if (camera != nullptr) camera->renderflags = (camera->renderflags & ~RF_MAYBEINVISIBLE) | savedvisibility; GLRenderer->SetupView(ViewPos.X, ViewPos.Y, ViewPos.Z, ViewAngle, !!(MirrorFlag & 1), !!(PlaneMirrorFlag & 1)); { @@ -1011,6 +1015,23 @@ void GLLineToLinePortal::DrawContents() P_TranslatePortalXY(origin, ViewActorPos.X, ViewActorPos.Y); P_TranslatePortalAngle(origin, ViewAngle); P_TranslatePortalZ(origin, ViewPos.Z); + P_TranslatePortalXY(origin, ViewPath[0].X, ViewPath[0].Y); + P_TranslatePortalXY(origin, ViewPath[1].X, ViewPath[1].Y); + if (!r_showviewer && camera != nullptr && P_PointOnLineSidePrecise(ViewPath[0], glport->lines[0]->mDestination) != P_PointOnLineSidePrecise(ViewPath[1], glport->lines[0]->mDestination)) + { + double distp = (ViewPath[0] - ViewPath[1]).Length(); + if (distp > EQUAL_EPSILON) + { + double dist1 = (ViewPos - ViewPath[0]).Length(); + double dist2 = (ViewPos - ViewPath[1]).Length(); + + if (dist1 + dist2 < distp + 1) + { + camera->renderflags |= RF_MAYBEINVISIBLE; + } + } + } + SaveMapSection(); diff --git a/src/gl/scene/gl_portal.h b/src/gl/scene/gl_portal.h index 80f810cb5..8a40ec2e2 100644 --- a/src/gl/scene/gl_portal.h +++ b/src/gl/scene/gl_portal.h @@ -101,6 +101,7 @@ public: private: void DrawPortalStencil(); + DVector3 savedviewpath[2]; DVector3 savedViewPos; DVector3 savedViewActorPos; DAngle savedAngle; diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index 7ed4199a1..4eda8aac1 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -677,6 +677,11 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal) if (thruportal == 1) thingorigin += Displacements.getOffset(thing->Sector->PortalGroup, sector->PortalGroup); if (fabs(thingorigin.X - ViewActorPos.X) < 2 && fabs(thingorigin.Y - ViewActorPos.Y) < 2) return; } + // Thing is invisible if close to the camera. + if (thing->renderflags & RF_MAYBEINVISIBLE) + { + if (fabs(thingpos.X - ViewPos.X) < 32 && fabs(thingpos.Y - ViewPos.Y) < 32) return; + } // Too close to the camera. This doesn't look good if it is a sprite. if (fabs(thingpos.X - ViewPos.X) < 2 && fabs(thingpos.Y - ViewPos.Y) < 2) @@ -693,6 +698,10 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal) } } } + if (thing == camera) + { + int a = 0; + } // don't draw first frame of a player missile if (thing->flags&MF_MISSILE) @@ -1203,6 +1212,14 @@ void gl_RenderActorsInPortal(FGLLinePortal *glport) DVector3 newpos = savedpos; sector_t fakesector; + if (!r_showviewer && th == camera) + { + if (fabs(savedpos.X - ViewActorPos.X) < 2 && fabs(savedpos.Y - ViewActorPos.Y) < 2) + { + continue; + } + } + P_TranslatePortalXY(line, newpos.X, newpos.Y); P_TranslatePortalZ(line, newpos.Z); P_TranslatePortalAngle(line, th->Angles.Yaw);