mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-10 14:51:40 +00:00
Added real-time client camera tracking for texture cams
This commit is contained in:
parent
e4ea5ad307
commit
a1a916a823
3 changed files with 45 additions and 15 deletions
|
@ -500,6 +500,7 @@ enum ActorRenderFlag2
|
||||||
RF2_BILLBOARDNOFACECAMERA = 0x0008, // Sprite billboard face camera angle (override gl_billboard_faces_camera)
|
RF2_BILLBOARDNOFACECAMERA = 0x0008, // Sprite billboard face camera angle (override gl_billboard_faces_camera)
|
||||||
RF2_FLIPSPRITEOFFSETX = 0x0010,
|
RF2_FLIPSPRITEOFFSETX = 0x0010,
|
||||||
RF2_FLIPSPRITEOFFSETY = 0x0020,
|
RF2_FLIPSPRITEOFFSETY = 0x0020,
|
||||||
|
RF2_CAMFOLLOWSPLAYER = 0x0040, // Matches the cam's base position and angles to the main viewpoint.
|
||||||
};
|
};
|
||||||
|
|
||||||
// This translucency value produces the closest match to Heretic's TINTTAB.
|
// This translucency value produces the closest match to Heretic's TINTTAB.
|
||||||
|
|
|
@ -837,12 +837,44 @@ void R_SetupFrame (FRenderViewpoint &viewpoint, FViewWindow &viewwindow, AActor
|
||||||
iview->otic = nowtic;
|
iview->otic = nowtic;
|
||||||
iview->Old = iview->New;
|
iview->Old = iview->New;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto& mainView = r_viewpoint;
|
||||||
|
AActor* const client = players[consoleplayer].mo;
|
||||||
|
const bool matchPlayer = gamestate != GS_TITLELEVEL && viewpoint.camera->player == nullptr && (viewpoint.camera->renderflags2 & RF2_CAMFOLLOWSPLAYER);
|
||||||
|
const bool usePawn = matchPlayer ? mainView.camera != client : false;
|
||||||
//==============================================================================================
|
//==============================================================================================
|
||||||
// Handles offsetting the camera with ChaseCam and/or viewpos.
|
// Handles offsetting the camera with ChaseCam and/or viewpos.
|
||||||
{
|
{
|
||||||
AActor *mo = viewpoint.camera;
|
AActor *mo = viewpoint.camera;
|
||||||
DViewPosition *VP = mo->ViewPos;
|
DViewPosition *VP = mo->ViewPos;
|
||||||
const DVector3 orig = { mo->Pos().XY(), mo->player ? mo->player->viewz : mo->Z() + mo->GetCameraHeight() };
|
DVector3 orig;
|
||||||
|
if (matchPlayer)
|
||||||
|
{
|
||||||
|
if (usePawn)
|
||||||
|
{
|
||||||
|
orig = DVector3(client->Pos().XY(), client->player->viewz);
|
||||||
|
const DViewPosition* const pawnVP = client->ViewPos;
|
||||||
|
if (pawnVP != nullptr)
|
||||||
|
{
|
||||||
|
// Avoid portal checking for now until the need for more accuracy arises.
|
||||||
|
if (pawnVP->Flags & VPSF_ABSOLUTEPOS)
|
||||||
|
orig = pawnVP->Offset;
|
||||||
|
else if (pawnVP->Flags & VPSF_ABSOLUTEOFFSET)
|
||||||
|
orig += pawnVP->Offset;
|
||||||
|
else
|
||||||
|
orig += DQuaternion::FromAngles(client->Angles.Yaw, client->Angles.Pitch, client->Angles.Roll) * pawnVP->Offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
orig = mainView.Pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
orig = { mo->Pos().XY(), mo->player ? mo->player->viewz : mo->Z() + mo->GetCameraHeight() };
|
||||||
|
}
|
||||||
|
|
||||||
viewpoint.ActorPos = orig;
|
viewpoint.ActorPos = orig;
|
||||||
|
|
||||||
bool DefaultDraw = true;
|
bool DefaultDraw = true;
|
||||||
|
@ -902,19 +934,7 @@ void R_SetupFrame (FRenderViewpoint &viewpoint, FViewWindow &viewwindow, AActor
|
||||||
// [MC] Do NOT handle portals here! Trace must have the unportaled (absolute) position to
|
// [MC] Do NOT handle portals here! Trace must have the unportaled (absolute) position to
|
||||||
// get the correct angle and distance. Trace automatically handles portals by itself.
|
// get the correct angle and distance. Trace automatically handles portals by itself.
|
||||||
// Note: viewpos does not include view angles, and ViewZ/CameraHeight are applied before this.
|
// Note: viewpos does not include view angles, and ViewZ/CameraHeight are applied before this.
|
||||||
|
next += DQuaternion::FromAngles(mo->Angles.Yaw, mo->Angles.Pitch, mo->Angles.Roll) * VP->Offset;
|
||||||
DAngle yaw = mo->Angles.Yaw;
|
|
||||||
DAngle pitch = mo->Angles.Pitch;
|
|
||||||
DAngle roll = mo->Angles.Roll;
|
|
||||||
DVector3 relx, rely, relz, Off = VP->Offset;
|
|
||||||
DMatrix3x3 rot =
|
|
||||||
DMatrix3x3(DVector3(0., 0., 1.), yaw.Cos(), yaw.Sin()) *
|
|
||||||
DMatrix3x3(DVector3(0., 1., 0.), pitch.Cos(), pitch.Sin()) *
|
|
||||||
DMatrix3x3(DVector3(1., 0., 0.), roll.Cos(), roll.Sin());
|
|
||||||
relx = DVector3(1., 0., 0.)*rot;
|
|
||||||
rely = DVector3(0., 1., 0.)*rot;
|
|
||||||
relz = DVector3(0., 0., 1.)*rot;
|
|
||||||
next += relx * Off.X + rely * Off.Y + relz * Off.Z;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (next != orig)
|
if (next != orig)
|
||||||
|
@ -947,12 +967,20 @@ void R_SetupFrame (FRenderViewpoint &viewpoint, FViewWindow &viewwindow, AActor
|
||||||
}
|
}
|
||||||
|
|
||||||
// [MR] Apply view angles as the viewpoint angles if asked to do so.
|
// [MR] Apply view angles as the viewpoint angles if asked to do so.
|
||||||
iview->New.Angles = !(viewpoint.camera->flags8 & MF8_ABSVIEWANGLES) ? viewpoint.camera->Angles : viewpoint.camera->ViewAngles;
|
if (matchPlayer)
|
||||||
|
iview->New.Angles = usePawn ? (client->flags8 & MF8_ABSVIEWANGLES ? client->ViewAngles : client->Angles + client->ViewAngles) : mainView.Angles;
|
||||||
|
else
|
||||||
|
iview->New.Angles = !(viewpoint.camera->flags8 & MF8_ABSVIEWANGLES) ? viewpoint.camera->Angles : viewpoint.camera->ViewAngles;
|
||||||
|
|
||||||
iview->New.ViewAngles = viewpoint.camera->ViewAngles;
|
iview->New.ViewAngles = viewpoint.camera->ViewAngles;
|
||||||
// [MR] Process player angle changes if permitted to do so.
|
// [MR] Process player angle changes if permitted to do so.
|
||||||
if (player && (player->cheats & CF_SCALEDNOLERP) && P_NoInterpolation(player, viewpoint.camera))
|
if (player && (player->cheats & CF_SCALEDNOLERP) && P_NoInterpolation(player, viewpoint.camera))
|
||||||
R_DoActorTickerAngleChanges(player, iview->New.Angles, viewpoint.TicFrac);
|
R_DoActorTickerAngleChanges(player, iview->New.Angles, viewpoint.TicFrac);
|
||||||
|
|
||||||
|
// If currently tracking the player's real view, don't do any sort of interpolating.
|
||||||
|
if (matchPlayer && !usePawn)
|
||||||
|
viewpoint.camera->renderflags |= RF_NOINTERPOLATEVIEW;
|
||||||
|
|
||||||
if (viewpoint.camera->player != 0)
|
if (viewpoint.camera->player != 0)
|
||||||
{
|
{
|
||||||
player = viewpoint.camera->player;
|
player = viewpoint.camera->player;
|
||||||
|
|
|
@ -383,6 +383,7 @@ static FFlagDef ActorFlagDefs[]=
|
||||||
DEFINE_FLAG(RF2, BILLBOARDNOFACECAMERA, AActor, renderflags2),
|
DEFINE_FLAG(RF2, BILLBOARDNOFACECAMERA, AActor, renderflags2),
|
||||||
DEFINE_FLAG(RF2, FLIPSPRITEOFFSETX, AActor, renderflags2),
|
DEFINE_FLAG(RF2, FLIPSPRITEOFFSETX, AActor, renderflags2),
|
||||||
DEFINE_FLAG(RF2, FLIPSPRITEOFFSETY, AActor, renderflags2),
|
DEFINE_FLAG(RF2, FLIPSPRITEOFFSETY, AActor, renderflags2),
|
||||||
|
DEFINE_FLAG(RF2, CAMFOLLOWSPLAYER, AActor, renderflags2),
|
||||||
|
|
||||||
// Bounce flags
|
// Bounce flags
|
||||||
DEFINE_FLAG2(BOUNCE_Walls, BOUNCEONWALLS, AActor, BounceFlags),
|
DEFINE_FLAG2(BOUNCE_Walls, BOUNCEONWALLS, AActor, BounceFlags),
|
||||||
|
|
Loading…
Reference in a new issue