mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-10 14:51:40 +00:00
- fixed player visibility determination by tracking and translating the actual actor position in addition to the camera position through portals. I hope this fixes the randomly appearing player sprites for good.
This commit is contained in:
parent
f52744e8a4
commit
a000b57204
6 changed files with 35 additions and 36 deletions
|
@ -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);
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -729,6 +732,7 @@ void GLSectorStackPortal::DrawContents()
|
|||
FPortal *portal = origin;
|
||||
|
||||
ViewPos += origin->mDisplacement;
|
||||
ViewActorPos += origin->mDisplacement;
|
||||
GLRenderer->mViewActor = NULL;
|
||||
|
||||
// avoid recursions!
|
||||
|
@ -772,7 +776,7 @@ void GLSectorStackPortal::DrawContents()
|
|||
|
||||
void GLPlaneMirrorPortal::DrawContents()
|
||||
{
|
||||
if (renderdepth>r_mirror_recursions)
|
||||
if (renderdepth > r_mirror_recursions)
|
||||
{
|
||||
ClearScreen();
|
||||
return;
|
||||
|
@ -780,22 +784,25 @@ void GLPlaneMirrorPortal::DrawContents()
|
|||
// 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]);
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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();
|
||||
|
||||
|
|
|
@ -102,11 +102,12 @@ private:
|
|||
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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ class FSerializer;
|
|||
extern DCanvas *RenderTarget;
|
||||
|
||||
extern DVector3 ViewPos;
|
||||
extern DVector3 ViewActorPos;
|
||||
extern DAngle ViewAngle;
|
||||
extern DAngle ViewPitch;
|
||||
extern DAngle ViewRoll;
|
||||
|
|
Loading…
Reference in a new issue