Added A_SetViewPos(Vector3 Offset, int Flags = -1)

- Offset: The offset from the actor's view to move the camera about.
 - Flags: (Default is -1, which means don't change flags)
  - VPSF_ABSOLUTEOFFSET: Don't include actor angles in calculation.
  - VPSF_ABSOLUTEPOS: Position is absolute, and disables all transformations. Modders are responsible for being portal aware!

Notes:
- `ViewPos` in Actor will be `null` until A_SetViewPos is called for the first time.

**Issues:**
- Hiding sprite while in portal incomplete.
This commit is contained in:
Major Cooke 2021-12-05 13:51:47 -06:00 committed by Rachael Alexanderson
commit 4e8d59951b
10 changed files with 283 additions and 29 deletions

View file

@ -5423,6 +5423,62 @@ void P_AimCamera(AActor *t1, DVector3 &campos, DAngle &camangle, sector_t *&Came
camangle = trace.SrcAngleFromTarget - 180.;
}
// [MC] Used for ViewPos. Uses code borrowed from P_AimCamera.
void P_AdjustViewPos(AActor *t1, DVector3 orig, DVector3 &campos, sector_t *&CameraSector, bool &unlinked, FViewPosition *VP)
{
FTraceResults trace;
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, t1->Sector, vvec.Unit(), distance, 0, 0, t1, trace) &&
trace.Distance > 5)
{
// Position camera slightly in front of hit thing
campos = orig + vvec.Unit() * (trace.Distance - 5);
}
else
{
campos = trace.HitPos - trace.HitVector * 1 / 256.;
}
// DVector3 cpos = campos;
CameraSector = trace.Sector;
unlinked = trace.unlinked;
// Save the info for the renderers. Needed to disable sprites across portals.
VP->Distance = distance;
VP->isUsed = true;
}
struct EViewPosFinder
{
AActor *Owner;
};
static ETraceStatus TraceToOwner(FTraceResults &res, void *userdata)
{
// Try to guarantee hitting the owner if possible.
if (res.HitType != TRACE_HitActor)
return TRACE_Skip;
EViewPosFinder *data = (EViewPosFinder *)userdata;
ETraceStatus ret = (res.Actor == data->Owner) ? TRACE_Stop : TRACE_Skip;
return ret;
}
bool FViewPosition::TraceBack(AActor *Owner)
{
if (!isUsed || !Owner)
return false;
DVector3 vvec = (CamPos - PlrPos).Unit() * -1.0;
FTraceResults res;
EViewPosFinder TrcBack = {Owner};
bool ret = Trace(CamPos, CamSec, vvec, Distance, 0, 0, nullptr, res, TRACE_ReportPortals, TraceToOwner, &TrcBack);
return ret;
}
//==========================================================================
//