Reworked view offsetting
View offsets are now added after the base position and angles (accounting for interpolation) are calculated. Behavior was centralized into a singular tracer that all view offsets now use to prevent clipping out of the map. Cleaned up camera rendering behavior. Angles are now properly normalized after all offsetting is accounted for. The chase cam can now update in real-time instead of forcing interpolation.
This commit is contained in:
parent
08a093ffda
commit
b469770ecc
7 changed files with 341 additions and 464 deletions
|
|
@ -5573,77 +5573,39 @@ void P_RailAttack(FRailParams *p)
|
|||
CVAR(Float, chase_height, -8.f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
CVAR(Float, chase_dist, 90.f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
|
||||
void P_AimCamera(AActor *t1, DVector3 &campos, DAngle &camangle, sector_t *&CameraSector, bool &unlinked)
|
||||
void R_OffsetView(FRenderViewpoint& viewPoint, const DVector3& dir, const double distance)
|
||||
{
|
||||
double distance = clamp<double>(chase_dist, 0, 30000);
|
||||
DAngle angle = t1->Angles.Yaw - DAngle::fromDeg(180);
|
||||
DAngle pitch = t1->Angles.Pitch;
|
||||
FTraceResults trace;
|
||||
DVector3 vvec;
|
||||
double sz;
|
||||
|
||||
double pc = pitch.Cos();
|
||||
|
||||
vvec = { pc * angle.Cos(), pc * angle.Sin(), pitch.Sin() };
|
||||
sz = t1->Top() - t1->Floorclip + clamp<double>(chase_height, -1000, 1000);
|
||||
|
||||
if (Trace(t1->PosAtZ(sz), t1->Sector, vvec, distance, 0, 0, NULL, trace) &&
|
||||
trace.Distance > 10)
|
||||
const DAngle baseYaw = dir.Angle();
|
||||
FTraceResults trace = {};
|
||||
if (Trace(viewPoint.Pos, viewPoint.sector, dir, distance, 0u, 0u, nullptr, trace))
|
||||
{
|
||||
// Position camera slightly in front of hit thing
|
||||
campos = t1->PosAtZ(sz) + vvec *(trace.Distance - 5);
|
||||
viewPoint.Pos = trace.HitPos - trace.HitVector * min<double>(5.0, trace.Distance);
|
||||
viewPoint.sector = viewPoint.ViewLevel->PointInRenderSubsector(viewPoint.Pos)->sector;
|
||||
}
|
||||
else
|
||||
{
|
||||
campos = trace.HitPos - trace.HitVector * 1/256.;
|
||||
viewPoint.Pos = trace.HitPos;
|
||||
viewPoint.sector = trace.Sector;
|
||||
}
|
||||
CameraSector = trace.Sector;
|
||||
unlinked = trace.unlinked;
|
||||
camangle = trace.SrcAngleFromTarget - DAngle::fromDeg(180.);
|
||||
}
|
||||
|
||||
struct ViewPosPortal
|
||||
{
|
||||
int counter;
|
||||
};
|
||||
|
||||
static ETraceStatus VPos_CheckPortal(FTraceResults &res, void *userdata)
|
||||
{
|
||||
//[MC] Mirror how third person works.
|
||||
ViewPosPortal *pc = (ViewPosPortal *)userdata;
|
||||
|
||||
if (res.HitType == TRACE_CrossingPortal)
|
||||
viewPoint.Angles.Yaw += deltaangle(baseYaw, trace.SrcAngleFromTarget);
|
||||
// TODO: Why does this even need to be done? Please fix tracers already.
|
||||
if (dir.Z < 0.0)
|
||||
{
|
||||
res.HitType = TRACE_HitNone; // Needed to force the trace to continue appropriately.
|
||||
pc->counter++;
|
||||
return TRACE_Skip;
|
||||
while (!viewPoint.sector->PortalBlocksMovement(sector_t::floor) && viewPoint.Pos.Z < viewPoint.sector->GetPortalPlaneZ(sector_t::floor))
|
||||
{
|
||||
viewPoint.Pos += viewPoint.sector->GetPortalDisplacement(sector_t::floor);
|
||||
viewPoint.sector = viewPoint.sector->GetPortal(sector_t::floor)->mDestination;
|
||||
}
|
||||
}
|
||||
if (res.HitType == TRACE_HitActor)
|
||||
else if (dir.Z > 0.0)
|
||||
{
|
||||
return TRACE_Skip;
|
||||
while (!viewPoint.sector->PortalBlocksMovement(sector_t::ceiling) && viewPoint.Pos.Z > viewPoint.sector->GetPortalPlaneZ(sector_t::ceiling))
|
||||
{
|
||||
viewPoint.Pos += viewPoint.sector->GetPortalDisplacement(sector_t::ceiling);
|
||||
viewPoint.sector = viewPoint.sector->GetPortal(sector_t::ceiling)->mDestination;
|
||||
}
|
||||
}
|
||||
return TRACE_Stop;
|
||||
}
|
||||
|
||||
// [MC] Used for ViewPos. Uses code borrowed from P_AimCamera.
|
||||
void P_AdjustViewPos(AActor *t1, DVector3 orig, DVector3 &campos, sector_t *&CameraSector, bool &unlinked, FRenderViewpoint *view)
|
||||
{
|
||||
FTraceResults trace;
|
||||
ViewPosPortal pc;
|
||||
pc.counter = 0;
|
||||
const DVector3 vvec = campos - orig;
|
||||
const double distance = vvec.Length();
|
||||
|
||||
// Trace handles all of the portal crossing, which is why there is no usage of Vec#Offset(Z).
|
||||
if (Trace(orig, CameraSector, vvec.Unit(), distance, 0, 0, t1, trace, TRACE_ReportPortals, VPos_CheckPortal, &pc) &&
|
||||
trace.Distance > 5)
|
||||
campos = orig + vvec.Unit() * (trace.Distance - 5);
|
||||
else
|
||||
campos = trace.HitPos - trace.HitVector * 1 / 256.;
|
||||
|
||||
|
||||
CameraSector = trace.Sector;
|
||||
unlinked = trace.unlinked;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue