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:
parent
cd33fb8607
commit
4e8d59951b
10 changed files with 283 additions and 29 deletions
|
|
@ -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;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue