Skip to content

Commit

Permalink
- fixed player visibility determination by tracking and translating t…
Browse files Browse the repository at this point in the history
…he actual actor position in addition to the camera position through portals. I hope this fixes the randomly appearing player sprites for good.
  • Loading branch information
Christoph Oelckers committed Dec 29, 2016
1 parent f52744e commit a000b57
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 36 deletions.
47 changes: 20 additions & 27 deletions src/gl/scene/gl_portal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -283,11 +283,11 @@ bool GLPortal::Start(bool usestencil, bool doquery)

// save viewpoint
savedViewPos = ViewPos;
savedViewActorPos = ViewActorPos;
savedshowviewer = r_showviewer;
savedAngle = ViewAngle;
savedviewactor=GLRenderer->mViewActor;
savedviewarea=in_area;
savedviewpath[0] = ViewPath[0];
savedviewpath[1] = ViewPath[1];
savedvisibility = camera ? camera->renderflags & RF_INVISIBLE : ActorRenderFlags::FromInt(0);


Expand Down Expand Up @@ -350,9 +350,9 @@ 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;
Expand Down Expand Up @@ -409,6 +409,8 @@ void GLPortal::End(bool usestencil)
glDepthMask(true);
}
// Restore the old view
r_showviewer = savedshowviewer;
ViewActorPos = savedViewActorPos;
ViewPos = savedViewPos;
ViewAngle = savedAngle;
GLRenderer->mViewActor=savedviewactor;
Expand Down Expand Up @@ -628,6 +630,7 @@ void GLSkyboxPortal::DrawContents()

bool oldclamp = gl_RenderState.SetDepthClamp(false);
ViewPos = origin->InterpolatedPosition(r_TicFracF);
ViewActorPos = origin->Pos();
ViewAngle += (origin->PrevAngles.Yaw + deltaangle(origin->PrevAngles.Yaw, origin->Angles.Yaw) * r_TicFracF);

// Don't let the viewpoint be too close to a floor or ceiling
Expand Down Expand Up @@ -729,6 +732,7 @@ void GLSectorStackPortal::DrawContents()
FPortal *portal = origin;

ViewPos += origin->mDisplacement;
ViewActorPos += origin->mDisplacement;
GLRenderer->mViewActor = NULL;

// avoid recursions!
Expand Down Expand Up @@ -772,30 +776,33 @@ void GLSectorStackPortal::DrawContents()

void GLPlaneMirrorPortal::DrawContents()
{
if (renderdepth>r_mirror_recursions)
if (renderdepth > r_mirror_recursions)
{
ClearScreen();
return;
}
// A plane mirror needs to flip the portal exclusion logic because inside the mirror, up is down and down is up.
std::swap(instack[sector_t::floor], instack[sector_t::ceiling]);

int old_pm=PlaneMirrorMode;
int old_pm = PlaneMirrorMode;

// the player is always visible in a mirror.
r_showviewer = true;

double planez = origin->ZatPoint(ViewPos);
ViewPos.Z = 2 * planez - ViewPos.Z;
GLRenderer->mViewActor = NULL;
PlaneMirrorMode = origin->fC() < 0 ? -1 : 1;

PlaneMirrorFlag++;
GLRenderer->SetupView(ViewPos.X, ViewPos.Y, ViewPos.Z, ViewAngle, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1));
GLRenderer->SetupView(ViewPos.X, ViewPos.Y, ViewPos.Z, ViewAngle, !!(MirrorFlag & 1), !!(PlaneMirrorFlag & 1));
ClearClipper();

gl_RenderState.SetClipHeight(planez, PlaneMirrorMode < 0? -1.f : 1.f);
gl_RenderState.SetClipHeight(planez, PlaneMirrorMode < 0 ? -1.f : 1.f);
GLRenderer->DrawScene(DM_PORTAL);
gl_RenderState.SetClipHeight(0.f, 0.f);
PlaneMirrorFlag--;
PlaneMirrorMode=old_pm;
PlaneMirrorMode = old_pm;
std::swap(instack[sector_t::floor], instack[sector_t::ceiling]);
}

Expand Down Expand Up @@ -903,6 +910,8 @@ void GLMirrorPortal::DrawContents()
vertex_t *v1 = linedef->v1;
vertex_t *v2 = linedef->v2;

// the player is always visible in a mirror.
r_showviewer = true;
// Reflect the current view behind the mirror.
if (linedef->Delta().X == 0)
{
Expand Down Expand Up @@ -999,25 +1008,9 @@ void GLLineToLinePortal::DrawContents()

line_t *origin = glport->lines[0]->mOrigin;
P_TranslatePortalXY(origin, ViewPos.X, ViewPos.Y);
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_INVISIBLE;
}
}
}


SaveMapSection();

Expand Down
3 changes: 2 additions & 1 deletion src/gl/scene/gl_portal.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,12 @@ class GLPortal
void DrawPortalStencil();

DVector3 savedViewPos;
DVector3 savedViewActorPos;
DAngle savedAngle;
bool savedshowviewer;
AActor * savedviewactor;
area_t savedviewarea;
ActorRenderFlags savedvisibility;
DVector3 savedviewpath[2];
GLPortal *PrevPortal;
GLPortal *PrevClipPortal;
TArray<BYTE> savedmapsection;
Expand Down
4 changes: 0 additions & 4 deletions src/gl/scene/gl_scene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -498,10 +498,6 @@ void FGLRenderer::DrawScene(int drawmode)
if (camera != nullptr)
{
ActorRenderFlags savedflags = camera->renderflags;
if (drawmode != DM_PORTAL && !r_showviewer)
{
camera->renderflags |= RF_INVISIBLE;
}
CreateScene();
camera->renderflags = savedflags;
}
Expand Down
12 changes: 9 additions & 3 deletions src/gl/scene/gl_sprite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ EXTERN_CVAR (Float, transsouls)
extern TArray<spritedef_t> sprites;
extern TArray<spriteframe_t> SpriteFrames;
extern TArray<PalEntry> BloodTranslationColors;
extern bool r_showviewer;

enum HWRenderStyle
{
Expand Down Expand Up @@ -655,7 +656,6 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal)
if (!(thing->flags & MF_STEALTH) || !gl_fixedcolormap || !gl_enhanced_nightvision || thing == camera)
return;
}

int spritenum = thing->sprite;
DVector2 sprscale = thing->Scale;
if (thing->player != NULL)
Expand All @@ -670,6 +670,14 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal)
DVector3 thingpos = thing->InterpolatedPosition(r_TicFracF);
if (thruportal == 1) thingpos += Displacements.getOffset(thing->Sector->PortalGroup, sector->PortalGroup);

// 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 (thing == camera && !r_showviewer)
{
DVector3 thingorigin = thing->Pos();
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;
}

// 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)
{
Expand Down Expand Up @@ -1202,9 +1210,7 @@ void gl_RenderActorsInPortal(FGLLinePortal *glport)
th->Prev += newpos - savedpos;

GLSprite spr;
th->fillcolor = 0xff0000ff;
spr.Process(th, gl_FakeFlat(th->Sector, &fakesector, false), 2);
th->fillcolor = 0xffffffff;
th->Angles.Yaw = savedangle;
th->SetXYZ(savedpos);
th->Prev -= newpos - savedpos;
Expand Down
4 changes: 3 additions & 1 deletion src/r_utility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ int viewwindowx;
int viewwindowy;

DVector3 ViewPos;
DVector3 ViewActorPos; // the actual position of the viewing actor, without interpolation and quake offsets.
DAngle ViewAngle;
DAngle ViewPitch;
DAngle ViewRoll;
Expand Down Expand Up @@ -743,10 +744,11 @@ void R_SetupFrame (AActor *actor)
iview->Old = iview->New;
r_NoInterpolate = true;
}
ViewActorPos = campos;
}
else
{
iview->New.Pos = { camera->Pos().XY(), camera->player ? camera->player->viewz : camera->Z() + camera->GetCameraHeight() };
ViewActorPos = iview->New.Pos = { camera->Pos().XY(), camera->player ? camera->player->viewz : camera->Z() + camera->GetCameraHeight() };
viewsector = camera->Sector;
r_showviewer = false;
}
Expand Down
1 change: 1 addition & 0 deletions src/r_utility.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class FSerializer;
extern DCanvas *RenderTarget;

extern DVector3 ViewPos;
extern DVector3 ViewActorPos;
extern DAngle ViewAngle;
extern DAngle ViewPitch;
extern DAngle ViewRoll;
Expand Down

0 comments on commit a000b57

Please sign in to comment.