mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-27 14:22:13 +00:00
- handle display of player sprite during portal transition properly.
This checks if the current viewpoint lies on the interpolation path, translated by all active portals.
This commit is contained in:
parent
47e20aead4
commit
0cbdb9ab72
3 changed files with 83 additions and 48 deletions
|
@ -692,6 +692,8 @@ void R_EnterPortal (PortalDrawseg* pds, int depth)
|
||||||
fixed_t startx = viewx;
|
fixed_t startx = viewx;
|
||||||
fixed_t starty = viewy;
|
fixed_t starty = viewy;
|
||||||
fixed_t startz = viewz;
|
fixed_t startz = viewz;
|
||||||
|
DVector3 savedpath[2] = { ViewPath[0], ViewPath[1] };
|
||||||
|
int savedvisibility = camera->renderflags & RF_INVISIBLE;
|
||||||
|
|
||||||
CurrentPortalUniq++;
|
CurrentPortalUniq++;
|
||||||
|
|
||||||
|
@ -738,10 +740,27 @@ void R_EnterPortal (PortalDrawseg* pds, int depth)
|
||||||
P_TranslatePortalXY(pds->src, view.X, view.Y);
|
P_TranslatePortalXY(pds->src, view.X, view.Y);
|
||||||
P_TranslatePortalZ(pds->src, view.Z);
|
P_TranslatePortalZ(pds->src, view.Z);
|
||||||
P_TranslatePortalAngle(pds->src, va);
|
P_TranslatePortalAngle(pds->src, va);
|
||||||
|
P_TranslatePortalXY(pds->src, ViewPath[0].X, ViewPath[0].Y);
|
||||||
|
P_TranslatePortalXY(pds->src, ViewPath[1].X, ViewPath[1].Y);
|
||||||
viewx = FLOAT2FIXED(view.X);
|
viewx = FLOAT2FIXED(view.X);
|
||||||
viewy = FLOAT2FIXED(view.Y);
|
viewy = FLOAT2FIXED(view.Y);
|
||||||
viewz = FLOAT2FIXED(view.Z);
|
viewz = FLOAT2FIXED(view.Z);
|
||||||
viewangle = va.BAMs();
|
viewangle = va.BAMs();
|
||||||
|
|
||||||
|
if (!r_showviewer)
|
||||||
|
{
|
||||||
|
double distp = (ViewPath[0] - ViewPath[1]).Length();
|
||||||
|
if (distp > EQUAL_EPSILON)
|
||||||
|
{
|
||||||
|
double dist1 = (view - ViewPath[0]).Length();
|
||||||
|
double dist2 = (view - ViewPath[1]).Length();
|
||||||
|
|
||||||
|
if (dist1 + dist2 < distp + 1)
|
||||||
|
{
|
||||||
|
camera->renderflags |= RF_INVISIBLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ViewAngle = AngleToFloat(viewangle);
|
ViewAngle = AngleToFloat(viewangle);
|
||||||
|
|
||||||
|
@ -783,6 +802,7 @@ void R_EnterPortal (PortalDrawseg* pds, int depth)
|
||||||
InSubsector = NULL;
|
InSubsector = NULL;
|
||||||
R_RenderBSPNode (nodes + numnodes - 1);
|
R_RenderBSPNode (nodes + numnodes - 1);
|
||||||
R_3D_ResetClip(); // reset clips (floor/ceiling)
|
R_3D_ResetClip(); // reset clips (floor/ceiling)
|
||||||
|
if (!savedvisibility) camera->renderflags &= ~RF_INVISIBLE;
|
||||||
|
|
||||||
PlaneCycles.Clock();
|
PlaneCycles.Clock();
|
||||||
R_DrawPlanes ();
|
R_DrawPlanes ();
|
||||||
|
@ -822,6 +842,8 @@ void R_EnterPortal (PortalDrawseg* pds, int depth)
|
||||||
viewx = startx;
|
viewx = startx;
|
||||||
viewy = starty;
|
viewy = starty;
|
||||||
viewz = startz;
|
viewz = startz;
|
||||||
|
ViewPath[0] = savedpath[0];
|
||||||
|
ViewPath[1] = savedpath[1];
|
||||||
ViewAngle = AngleToFloat(viewangle);
|
ViewAngle = AngleToFloat(viewangle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,7 +85,7 @@ struct InterpolationViewer
|
||||||
static TArray<InterpolationViewer> PastViewers;
|
static TArray<InterpolationViewer> PastViewers;
|
||||||
static FRandom pr_torchflicker ("TorchFlicker");
|
static FRandom pr_torchflicker ("TorchFlicker");
|
||||||
static FRandom pr_hom;
|
static FRandom pr_hom;
|
||||||
static bool NoInterpolateView;
|
bool NoInterpolateView; // GL needs access to this.
|
||||||
static TArray<DVector3a> InterpolationPath;
|
static TArray<DVector3a> InterpolationPath;
|
||||||
|
|
||||||
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
||||||
|
@ -108,6 +108,7 @@ int viewwindowy;
|
||||||
DVector3 ViewPos;
|
DVector3 ViewPos;
|
||||||
DAngle ViewAngle;
|
DAngle ViewAngle;
|
||||||
DAngle ViewPitch;
|
DAngle ViewPitch;
|
||||||
|
DVector3 ViewPath[2];
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
|
@ -590,67 +591,78 @@ void R_InterpolateView (player_t *player, double Frac, InterpolationViewer *ivie
|
||||||
|
|
||||||
DAngle oviewangle = iview->Old.Angles.Yaw;
|
DAngle oviewangle = iview->Old.Angles.Yaw;
|
||||||
DAngle nviewangle = iview->New.Angles.Yaw;
|
DAngle nviewangle = iview->New.Angles.Yaw;
|
||||||
if ((iview->Old.Pos.X != iview->New.Pos.X || iview->Old.Pos.Y != iview->New.Pos.Y) && InterpolationPath.Size() > 0)
|
if (!cl_capfps)
|
||||||
{
|
{
|
||||||
DVector3 view = iview->New.Pos;
|
if ((iview->Old.Pos.X != iview->New.Pos.X || iview->Old.Pos.Y != iview->New.Pos.Y) && InterpolationPath.Size() > 0)
|
||||||
|
|
||||||
// Interpolating through line portals is a messy affair.
|
|
||||||
// What needs be done is to store the portal transitions of the camera actor as waypoints
|
|
||||||
// and then find out on which part of the path the current view lies.
|
|
||||||
// Needless to say, this doesn't work for chasecam mode.
|
|
||||||
if (!r_showviewer)
|
|
||||||
{
|
{
|
||||||
double pathlen = 0;
|
DVector3 view = iview->New.Pos;
|
||||||
double zdiff = 0;
|
|
||||||
double totalzdiff = 0;
|
|
||||||
DAngle adiff = 0.;
|
|
||||||
DAngle totaladiff = 0.;
|
|
||||||
double oviewz = iview->Old.Pos.Z;
|
|
||||||
double nviewz = iview->New.Pos.Z;
|
|
||||||
DVector3a oldpos = { { iview->Old.Pos.X, iview->Old.Pos.Y, 0 }, 0. };
|
|
||||||
DVector3a newpos = { { iview->New.Pos.X, iview->New.Pos.Y, 0 }, 0. };
|
|
||||||
InterpolationPath.Push(newpos); // add this to the array to simplify the loops below
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < InterpolationPath.Size(); i += 2)
|
// Interpolating through line portals is a messy affair.
|
||||||
|
// What needs be done is to store the portal transitions of the camera actor as waypoints
|
||||||
|
// and then find out on which part of the path the current view lies.
|
||||||
|
// Needless to say, this doesn't work for chasecam mode.
|
||||||
|
if (!r_showviewer)
|
||||||
{
|
{
|
||||||
DVector3a &start = i == 0 ? oldpos : InterpolationPath[i - 1];
|
double pathlen = 0;
|
||||||
DVector3a &end = InterpolationPath[i];
|
double zdiff = 0;
|
||||||
pathlen += (end.pos-start.pos).Length();
|
double totalzdiff = 0;
|
||||||
totalzdiff += start.pos.Z;
|
DAngle adiff = 0.;
|
||||||
totaladiff += start.angle;
|
DAngle totaladiff = 0.;
|
||||||
}
|
double oviewz = iview->Old.Pos.Z;
|
||||||
double interpolatedlen = Frac * pathlen;
|
double nviewz = iview->New.Pos.Z;
|
||||||
|
DVector3a oldpos = { { iview->Old.Pos.X, iview->Old.Pos.Y, 0 }, 0. };
|
||||||
|
DVector3a newpos = { { iview->New.Pos.X, iview->New.Pos.Y, 0 }, 0. };
|
||||||
|
InterpolationPath.Push(newpos); // add this to the array to simplify the loops below
|
||||||
|
|
||||||
for (unsigned i = 0; i < InterpolationPath.Size(); i += 2)
|
for (unsigned i = 0; i < InterpolationPath.Size(); i += 2)
|
||||||
{
|
|
||||||
DVector3a &start = i == 0 ? oldpos : InterpolationPath[i - 1];
|
|
||||||
DVector3a &end = InterpolationPath[i];
|
|
||||||
double fraglen = (end.pos - start.pos).Length();
|
|
||||||
zdiff += start.pos.Z;
|
|
||||||
adiff += start.angle;
|
|
||||||
if (fraglen <= interpolatedlen)
|
|
||||||
{
|
{
|
||||||
interpolatedlen -= fraglen;
|
DVector3a &start = i == 0 ? oldpos : InterpolationPath[i - 1];
|
||||||
|
DVector3a &end = InterpolationPath[i];
|
||||||
|
pathlen += (end.pos - start.pos).Length();
|
||||||
|
totalzdiff += start.pos.Z;
|
||||||
|
totaladiff += start.angle;
|
||||||
}
|
}
|
||||||
else
|
double interpolatedlen = Frac * pathlen;
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < InterpolationPath.Size(); i += 2)
|
||||||
{
|
{
|
||||||
double fragfrac = interpolatedlen / fraglen;
|
DVector3a &start = i == 0 ? oldpos : InterpolationPath[i - 1];
|
||||||
oviewz += zdiff;
|
DVector3a &end = InterpolationPath[i];
|
||||||
nviewz -= totalzdiff - zdiff;
|
double fraglen = (end.pos - start.pos).Length();
|
||||||
oviewangle += adiff;
|
zdiff += start.pos.Z;
|
||||||
nviewangle -= totaladiff - adiff;
|
adiff += start.angle;
|
||||||
DVector2 viewpos = start.pos + (fragfrac * (end.pos - start.pos));
|
if (fraglen <= interpolatedlen)
|
||||||
ViewPos = { viewpos, oviewz + Frac * (nviewz - oviewz) };
|
{
|
||||||
break;
|
interpolatedlen -= fraglen;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
double fragfrac = interpolatedlen / fraglen;
|
||||||
|
oviewz += zdiff;
|
||||||
|
nviewz -= totalzdiff - zdiff;
|
||||||
|
oviewangle += adiff;
|
||||||
|
nviewangle -= totaladiff - adiff;
|
||||||
|
DVector2 viewpos = start.pos + (fragfrac * (end.pos - start.pos));
|
||||||
|
ViewPos = { viewpos, oviewz + Frac * (nviewz - oviewz) };
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
InterpolationPath.Pop();
|
||||||
|
ViewPath[0] = iview->Old.Pos;
|
||||||
}
|
}
|
||||||
InterpolationPath.Pop();
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DVector2 disp = Displacements.getOffset(oldgroup, newgroup);
|
||||||
|
ViewPos = iview->Old.Pos + (iview->New.Pos - iview->Old.Pos - disp) * Frac;
|
||||||
|
ViewPath[1] = iview->New.Pos;
|
||||||
|
ViewPath[0] = iview->Old.Pos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DVector2 disp = Displacements.getOffset(oldgroup, newgroup);
|
ViewPos = iview->New.Pos;
|
||||||
ViewPos = iview->Old.Pos + (iview->New.Pos - iview->Old.Pos - disp) * Frac;
|
ViewPath[0] = ViewPath[1] = iview->New.Pos;
|
||||||
}
|
}
|
||||||
if (player != NULL &&
|
if (player != NULL &&
|
||||||
!(player->cheats & CF_INTERPVIEW) &&
|
!(player->cheats & CF_INTERPVIEW) &&
|
||||||
|
|
|
@ -15,6 +15,7 @@ extern DCanvas *RenderTarget;
|
||||||
extern DVector3 ViewPos;
|
extern DVector3 ViewPos;
|
||||||
extern DAngle ViewAngle;
|
extern DAngle ViewAngle;
|
||||||
extern DAngle ViewPitch;
|
extern DAngle ViewPitch;
|
||||||
|
extern DVector3 ViewPath[2];
|
||||||
|
|
||||||
extern fixed_t viewx, viewy, viewz;
|
extern fixed_t viewx, viewy, viewz;
|
||||||
extern angle_t viewangle;
|
extern angle_t viewangle;
|
||||||
|
|
Loading…
Reference in a new issue