mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-14 00:21:34 +00:00
- optimized the portal translation functions by precalculating the rotation angle, sine and cosine.
This commit is contained in:
parent
ede07f93b2
commit
14a0567343
5 changed files with 66 additions and 69 deletions
|
@ -1041,8 +1041,8 @@ static bool PIT_CheckPortal(FMultiBlockLinesIterator &mit, FMultiBlockLinesItera
|
||||||
line_t *lp = cres.line->getPortalDestination();
|
line_t *lp = cres.line->getPortalDestination();
|
||||||
fixed_t zofs = 0;
|
fixed_t zofs = 0;
|
||||||
|
|
||||||
P_TranslatePortalXY(cres.line, lp, cres.position.x, cres.position.y);
|
P_TranslatePortalXY(cres.line, cres.position.x, cres.position.y);
|
||||||
P_TranslatePortalZ(cres.line, lp, zofs);
|
P_TranslatePortalZ(cres.line, zofs);
|
||||||
|
|
||||||
// fudge a bit with the portal line so that this gets included in the checks that normally only get run on two-sided lines
|
// fudge a bit with the portal line so that this gets included in the checks that normally only get run on two-sided lines
|
||||||
sector_t *sec = lp->backsector;
|
sector_t *sec = lp->backsector;
|
||||||
|
@ -2325,14 +2325,13 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y,
|
||||||
}
|
}
|
||||||
else if (!portalcrossed)
|
else if (!portalcrossed)
|
||||||
{
|
{
|
||||||
line_t *out = port->mDestination;
|
|
||||||
fixedvec3 pos = { tm.x, tm.y, thing->Z() };
|
fixedvec3 pos = { tm.x, tm.y, thing->Z() };
|
||||||
fixedvec3 oldthingpos = thing->Pos();
|
fixedvec3 oldthingpos = thing->Pos();
|
||||||
fixedvec2 thingpos = oldthingpos;
|
fixedvec2 thingpos = oldthingpos;
|
||||||
|
|
||||||
P_TranslatePortalXY(ld, out, pos.x, pos.y);
|
P_TranslatePortalXY(ld, pos.x, pos.y);
|
||||||
P_TranslatePortalXY(ld, out, thingpos.x, thingpos.y);
|
P_TranslatePortalXY(ld, thingpos.x, thingpos.y);
|
||||||
P_TranslatePortalZ(ld, out, pos.z);
|
P_TranslatePortalZ(ld, pos.z);
|
||||||
thing->SetXYZ(thingpos.x, thingpos.y, pos.z);
|
thing->SetXYZ(thingpos.x, thingpos.y, pos.z);
|
||||||
if (!P_CheckPosition(thing, pos.x, pos.y, true)) // check if some actor blocks us on the other side. (No line checks, because of the mess that'd create.)
|
if (!P_CheckPosition(thing, pos.x, pos.y, true)) // check if some actor blocks us on the other side. (No line checks, because of the mess that'd create.)
|
||||||
{
|
{
|
||||||
|
@ -2342,8 +2341,8 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y,
|
||||||
}
|
}
|
||||||
thing->UnlinkFromWorld();
|
thing->UnlinkFromWorld();
|
||||||
thing->SetXYZ(pos);
|
thing->SetXYZ(pos);
|
||||||
P_TranslatePortalVXVY(ld, out, thing->velx, thing->vely);
|
P_TranslatePortalVXVY(ld, thing->velx, thing->vely);
|
||||||
P_TranslatePortalAngle(ld, out, thing->angle);
|
P_TranslatePortalAngle(ld, thing->angle);
|
||||||
thing->LinkToWorld();
|
thing->LinkToWorld();
|
||||||
P_FindFloorCeiling(thing);
|
P_FindFloorCeiling(thing);
|
||||||
thing->ClearInterpolation();
|
thing->ClearInterpolation();
|
||||||
|
@ -2355,7 +2354,6 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y,
|
||||||
{
|
{
|
||||||
divline_t dl1 = { besthit.oldrefpos.x,besthit. oldrefpos.y, besthit.refpos.x - besthit.oldrefpos.x, besthit.refpos.y - besthit.oldrefpos.y };
|
divline_t dl1 = { besthit.oldrefpos.x,besthit. oldrefpos.y, besthit.refpos.x - besthit.oldrefpos.x, besthit.refpos.y - besthit.oldrefpos.y };
|
||||||
fixedvec3a hit = { dl1.x + FixedMul(dl1.dx, bestfrac), dl1.y + FixedMul(dl1.dy, bestfrac), 0, 0 };
|
fixedvec3a hit = { dl1.x + FixedMul(dl1.dx, bestfrac), dl1.y + FixedMul(dl1.dy, bestfrac), 0, 0 };
|
||||||
line_t *out = port->mDestination;
|
|
||||||
|
|
||||||
R_AddInterpolationPoint(hit);
|
R_AddInterpolationPoint(hit);
|
||||||
if (port->mType == PORTT_LINKED)
|
if (port->mType == PORTT_LINKED)
|
||||||
|
@ -2365,10 +2363,10 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
P_TranslatePortalXY(ld, out, hit.x, hit.y);
|
P_TranslatePortalXY(ld, hit.x, hit.y);
|
||||||
P_TranslatePortalZ(ld, out, hit.z);
|
P_TranslatePortalZ(ld, hit.z);
|
||||||
players[consoleplayer].viewz += hit.z; // needs to be done here because otherwise the renderer will not catch the change.
|
players[consoleplayer].viewz += hit.z; // needs to be done here because otherwise the renderer will not catch the change.
|
||||||
P_TranslatePortalAngle(ld, out, hit.angle);
|
P_TranslatePortalAngle(ld, hit.angle);
|
||||||
}
|
}
|
||||||
R_AddInterpolationPoint(hit);
|
R_AddInterpolationPoint(hit);
|
||||||
}
|
}
|
||||||
|
@ -3700,7 +3698,6 @@ struct aim_t
|
||||||
aim_t newtrace = Clone();
|
aim_t newtrace = Clone();
|
||||||
|
|
||||||
FLinePortal *port = li->getPortal();
|
FLinePortal *port = li->getPortal();
|
||||||
line_t *dest = port->mDestination;
|
|
||||||
|
|
||||||
newtrace.toppitch = toppitch;
|
newtrace.toppitch = toppitch;
|
||||||
newtrace.bottompitch = bottompitch;
|
newtrace.bottompitch = bottompitch;
|
||||||
|
@ -3708,9 +3705,9 @@ struct aim_t
|
||||||
newtrace.unlinked = (port->mType != PORTT_LINKED);
|
newtrace.unlinked = (port->mType != PORTT_LINKED);
|
||||||
newtrace.startpos = startpos;
|
newtrace.startpos = startpos;
|
||||||
newtrace.aimtrace = aimtrace;
|
newtrace.aimtrace = aimtrace;
|
||||||
P_TranslatePortalXY(li, dest, newtrace.startpos.x, newtrace.startpos.y);
|
P_TranslatePortalXY(li, newtrace.startpos.x, newtrace.startpos.y);
|
||||||
P_TranslatePortalZ(li, dest, newtrace.startpos.z);
|
P_TranslatePortalZ(li, newtrace.startpos.z);
|
||||||
P_TranslatePortalVXVY(li, dest, newtrace.aimtrace.x, newtrace.aimtrace.y);
|
P_TranslatePortalVXVY(li, newtrace.aimtrace.x, newtrace.aimtrace.y);
|
||||||
|
|
||||||
newtrace.startfrac = frac + FixedDiv(FRACUNIT, attackrange); // this is to skip the transition line to the portal which would produce a bogus opening
|
newtrace.startfrac = frac + FixedDiv(FRACUNIT, attackrange); // this is to skip the transition line to the portal which would produce a bogus opening
|
||||||
|
|
||||||
|
@ -3718,7 +3715,7 @@ struct aim_t
|
||||||
fixed_t y = newtrace.startpos.y + FixedMul(newtrace.aimtrace.y, newtrace.startfrac);
|
fixed_t y = newtrace.startpos.y + FixedMul(newtrace.aimtrace.y, newtrace.startfrac);
|
||||||
|
|
||||||
newtrace.lastsector = P_PointInSector(x, y);
|
newtrace.lastsector = P_PointInSector(x, y);
|
||||||
P_TranslatePortalZ(li, dest, limitz);
|
P_TranslatePortalZ(li, limitz);
|
||||||
Printf("-----Entering line portal from sector %d to sector %d\n", lastsector->sectornum, newtrace.lastsector->sectornum);
|
Printf("-----Entering line portal from sector %d to sector %d\n", lastsector->sectornum, newtrace.lastsector->sectornum);
|
||||||
newtrace.AimTraverse();
|
newtrace.AimTraverse();
|
||||||
SetResult(linetarget, newtrace.linetarget);
|
SetResult(linetarget, newtrace.linetarget);
|
||||||
|
|
|
@ -1660,14 +1660,13 @@ int FPathTraverse::PortalRelocate(intercept_t *in, int flags, fixedvec3 *optpos)
|
||||||
fixed_t hity = trace.y;
|
fixed_t hity = trace.y;
|
||||||
fixed_t endx = trace.x + trace.dx;
|
fixed_t endx = trace.x + trace.dx;
|
||||||
fixed_t endy = trace.y + trace.dy;
|
fixed_t endy = trace.y + trace.dy;
|
||||||
line_t *out = in->d.line->getPortalDestination();
|
|
||||||
|
|
||||||
P_TranslatePortalXY(in->d.line, out, hitx, hity);
|
P_TranslatePortalXY(in->d.line, hitx, hity);
|
||||||
P_TranslatePortalXY(in->d.line, out, endx, endy);
|
P_TranslatePortalXY(in->d.line, endx, endy);
|
||||||
if (optpos != NULL)
|
if (optpos != NULL)
|
||||||
{
|
{
|
||||||
P_TranslatePortalXY(in->d.line, out, optpos->x, optpos->y);
|
P_TranslatePortalXY(in->d.line, optpos->x, optpos->y);
|
||||||
P_TranslatePortalZ(in->d.line, out, optpos->z);
|
P_TranslatePortalZ(in->d.line, optpos->z);
|
||||||
}
|
}
|
||||||
intercepts.Resize(intercept_index);
|
intercepts.Resize(intercept_index);
|
||||||
init(hitx, hity, endx, endy, flags, in->frac);
|
init(hitx, hity, endx, endy, flags, in->frac);
|
||||||
|
|
|
@ -265,9 +265,17 @@ void P_SpawnLinePortal(line_t* line)
|
||||||
if (port->mDestination != NULL)
|
if (port->mDestination != NULL)
|
||||||
{
|
{
|
||||||
port->mDefFlags = port->mType == PORTT_VISUAL ? PORTF_VISIBLE : port->mType == PORTT_TELEPORT ? PORTF_TYPETELEPORT : PORTF_TYPEINTERACTIVE;
|
port->mDefFlags = port->mType == PORTT_VISUAL ? PORTF_VISIBLE : port->mType == PORTT_TELEPORT ? PORTF_TYPETELEPORT : PORTF_TYPEINTERACTIVE;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the angle between the two linedefs, for rotating
|
||||||
|
// orientation and velocity. Rotate 180 degrees, and flip
|
||||||
|
// the position across the exit linedef, if reversed.
|
||||||
|
|
||||||
|
double angle = atan2(dst->dy, dst->dx) - atan2(line->dy, line->dx) + M_PI;
|
||||||
|
port->mSinRot = FLOAT2FIXED(sin(angle));
|
||||||
|
port->mCosRot = FLOAT2FIXED(cos(angle));
|
||||||
|
port->mAngleDiff = RAD2ANGLE(angle);
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (line->args[2] == PORTT_LINKEDEE && line->args[0] == 0)
|
else if (line->args[2] == PORTT_LINKEDEE && line->args[0] == 0)
|
||||||
{
|
{
|
||||||
|
@ -546,30 +554,22 @@ bool P_ClipLineToPortal(line_t* line, line_t* portal, fixed_t viewx, fixed_t vie
|
||||||
//
|
//
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
void P_TranslatePortalXY(line_t* src, line_t* dst, fixed_t& x, fixed_t& y)
|
void P_TranslatePortalXY(line_t* src, fixed_t& x, fixed_t& y)
|
||||||
{
|
{
|
||||||
if (!src || !dst)
|
if (!src) return;
|
||||||
return;
|
FLinePortal *port = src->getPortal();
|
||||||
|
if (!port) return;
|
||||||
|
|
||||||
fixed_t nposx, nposy; // offsets from line
|
// offsets from line
|
||||||
|
fixed_t nposx = x - src->v1->x;
|
||||||
// Get the angle between the two linedefs, for rotating
|
fixed_t nposy = y - src->v1->y;
|
||||||
// orientation and velocity. Rotate 180 degrees, and flip
|
|
||||||
// the position across the exit linedef, if reversed.
|
|
||||||
|
|
||||||
double angle = atan2(dst->dy, dst->dx) - atan2(src->dy, src->dx) + M_PI;
|
|
||||||
fixed_t s = FLOAT2FIXED(sin(angle));
|
|
||||||
fixed_t c = FLOAT2FIXED(cos(angle));
|
|
||||||
|
|
||||||
nposx = x - src->v1->x;
|
|
||||||
nposy = y - src->v1->y;
|
|
||||||
|
|
||||||
// Rotate position along normal to match exit linedef
|
// Rotate position along normal to match exit linedef
|
||||||
fixed_t tx = FixedMul(nposx, c) - FixedMul(nposy, s);
|
fixed_t tx = FixedMul(nposx, port->mCosRot) - FixedMul(nposy, port->mSinRot);
|
||||||
fixed_t ty = FixedMul(nposy, c) + FixedMul(nposx, s);
|
fixed_t ty = FixedMul(nposy, port->mCosRot) + FixedMul(nposx, port->mSinRot);
|
||||||
|
|
||||||
tx += dst->v2->x;
|
tx += port->mDestination->v2->x;
|
||||||
ty += dst->v2->y;
|
ty += port->mDestination->v2->y;
|
||||||
|
|
||||||
x = tx;
|
x = tx;
|
||||||
y = ty;
|
y = ty;
|
||||||
|
@ -581,16 +581,16 @@ void P_TranslatePortalXY(line_t* src, line_t* dst, fixed_t& x, fixed_t& y)
|
||||||
//
|
//
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
void P_TranslatePortalVXVY(line_t* src, line_t* dst, fixed_t& vx, fixed_t& vy)
|
void P_TranslatePortalVXVY(line_t* src, fixed_t& vx, fixed_t& vy)
|
||||||
{
|
{
|
||||||
double angle = atan2(dst->dy, dst->dx) - atan2(src->dy, src->dx) + M_PI;
|
if (!src) return;
|
||||||
fixed_t s = FLOAT2FIXED(sin(angle));
|
FLinePortal *port = src->getPortal();
|
||||||
fixed_t c = FLOAT2FIXED(cos(angle));
|
if (!port) return;
|
||||||
|
|
||||||
fixed_t orig_velx = vx;
|
fixed_t orig_velx = vx;
|
||||||
fixed_t orig_vely = vy;
|
fixed_t orig_vely = vy;
|
||||||
vx = FixedMul(orig_velx, c) - FixedMul(orig_vely, s);
|
vx = FixedMul(orig_velx, port->mCosRot) - FixedMul(orig_vely, port->mSinRot);
|
||||||
vy = FixedMul(orig_vely, c) + FixedMul(orig_velx, s);
|
vy = FixedMul(orig_vely, port->mCosRot) + FixedMul(orig_velx, port->mSinRot);
|
||||||
}
|
}
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
@ -599,15 +599,12 @@ void P_TranslatePortalVXVY(line_t* src, line_t* dst, fixed_t& vx, fixed_t& vy)
|
||||||
//
|
//
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
void P_TranslatePortalAngle(line_t* src, line_t* dst, angle_t& angle)
|
void P_TranslatePortalAngle(line_t* src, angle_t& angle)
|
||||||
{
|
{
|
||||||
if (!src || !dst)
|
if (!src) return;
|
||||||
return;
|
FLinePortal *port = src->getPortal();
|
||||||
|
if (!port) return;
|
||||||
// Get the angle between the two linedefs, for rotating
|
angle += port->mAngleDiff;
|
||||||
// orientation and velocity. Rotate 180 degrees, and flip
|
|
||||||
// the position across the exit linedef, if reversed.
|
|
||||||
angle += RAD2ANGLE(atan2(dst->dy, dst->dx) - atan2(src->dy, src->dx)) + ANGLE_180;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
@ -616,12 +613,14 @@ void P_TranslatePortalAngle(line_t* src, line_t* dst, angle_t& angle)
|
||||||
//
|
//
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
void P_TranslatePortalZ(line_t* src, line_t* dst, fixed_t& z)
|
void P_TranslatePortalZ(line_t* src, fixed_t& z)
|
||||||
{
|
{
|
||||||
// args[2] = 0 - no adjustment
|
// args[2] = 0 - no adjustment
|
||||||
// args[2] = 1 - adjust by floor difference
|
// args[2] = 1 - adjust by floor difference
|
||||||
// args[2] = 2 - adjust by ceiling difference
|
// args[2] = 2 - adjust by ceiling difference
|
||||||
|
|
||||||
|
// This cannot be precalculated because heights may change.
|
||||||
|
line_t *dst = src->getPortalDestination();
|
||||||
switch (src->getPortalAlignment())
|
switch (src->getPortalAlignment())
|
||||||
{
|
{
|
||||||
case PORG_FLOOR:
|
case PORG_FLOOR:
|
||||||
|
@ -704,7 +703,6 @@ fixedvec2 P_GetOffsetPosition(fixed_t x, fixed_t y, fixed_t dx, fixed_t dy)
|
||||||
// hit a portal line.
|
// hit a portal line.
|
||||||
line_t *line = in->d.line;
|
line_t *line = in->d.line;
|
||||||
FLinePortal *port = line->getPortal();
|
FLinePortal *port = line->getPortal();
|
||||||
line_t* out = port->mDestination;
|
|
||||||
|
|
||||||
// Teleport portals are intentionally ignored since skipping this stuff is their entire reason for existence.
|
// Teleport portals are intentionally ignored since skipping this stuff is their entire reason for existence.
|
||||||
if (port->mFlags & PORTF_INTERACTIVE)
|
if (port->mFlags & PORTF_INTERACTIVE)
|
||||||
|
@ -723,8 +721,8 @@ fixedvec2 P_GetOffsetPosition(fixed_t x, fixed_t y, fixed_t dx, fixed_t dy)
|
||||||
{
|
{
|
||||||
// interactive ones are more complex because the vector may be rotated.
|
// interactive ones are more complex because the vector may be rotated.
|
||||||
// Note: There is no z-translation here, there's just too much code in the engine that wouldn't be able to handle interactive portals with a height difference.
|
// Note: There is no z-translation here, there's just too much code in the engine that wouldn't be able to handle interactive portals with a height difference.
|
||||||
P_TranslatePortalXY(line, out, hit.x, hit.y);
|
P_TranslatePortalXY(line, hit.x, hit.y);
|
||||||
P_TranslatePortalXY(line, out, dest.x, dest.y);
|
P_TranslatePortalXY(line, dest.x, dest.y);
|
||||||
}
|
}
|
||||||
// update the fields, end this trace and restart from the new position
|
// update the fields, end this trace and restart from the new position
|
||||||
dx = dest.x - hit.x;
|
dx = dest.x - hit.x;
|
||||||
|
|
11
src/portal.h
11
src/portal.h
|
@ -173,6 +173,9 @@ struct FLinePortal
|
||||||
BYTE mFlags;
|
BYTE mFlags;
|
||||||
BYTE mDefFlags;
|
BYTE mDefFlags;
|
||||||
BYTE mAlign;
|
BYTE mAlign;
|
||||||
|
angle_t mAngleDiff;
|
||||||
|
fixed_t mSinRot;
|
||||||
|
fixed_t mCosRot;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern TArray<FLinePortal> linePortals;
|
extern TArray<FLinePortal> linePortals;
|
||||||
|
@ -192,10 +195,10 @@ inline int P_NumPortalGroups()
|
||||||
|
|
||||||
/* code ported from prototype */
|
/* code ported from prototype */
|
||||||
bool P_ClipLineToPortal(line_t* line, line_t* portal, fixed_t viewx, fixed_t viewy, bool partial = true, bool samebehind = true);
|
bool P_ClipLineToPortal(line_t* line, line_t* portal, fixed_t viewx, fixed_t viewy, bool partial = true, bool samebehind = true);
|
||||||
void P_TranslatePortalXY(line_t* src, line_t* dst, fixed_t& x, fixed_t& y);
|
void P_TranslatePortalXY(line_t* src, fixed_t& x, fixed_t& y);
|
||||||
void P_TranslatePortalVXVY(line_t* src, line_t* dst, fixed_t& vx, fixed_t& vy);
|
void P_TranslatePortalVXVY(line_t* src, fixed_t& vx, fixed_t& vy);
|
||||||
void P_TranslatePortalAngle(line_t* src, line_t* dst, angle_t& angle);
|
void P_TranslatePortalAngle(line_t* src, angle_t& angle);
|
||||||
void P_TranslatePortalZ(line_t* src, line_t* dst, fixed_t& z);
|
void P_TranslatePortalZ(line_t* src, fixed_t& z);
|
||||||
void P_NormalizeVXVY(fixed_t& vx, fixed_t& vy);
|
void P_NormalizeVXVY(fixed_t& vx, fixed_t& vy);
|
||||||
fixed_t P_PointLineDistance(line_t* line, fixed_t x, fixed_t y);
|
fixed_t P_PointLineDistance(line_t* line, fixed_t x, fixed_t y);
|
||||||
fixedvec2 P_GetOffsetPosition(fixed_t x, fixed_t y, fixed_t dx, fixed_t dy);
|
fixedvec2 P_GetOffsetPosition(fixed_t x, fixed_t y, fixed_t dx, fixed_t dy);
|
||||||
|
|
|
@ -732,9 +732,9 @@ void R_EnterPortal (PortalDrawseg* pds, int depth)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
P_TranslatePortalXY(pds->src, pds->dst, viewx, viewy);
|
P_TranslatePortalXY(pds->src, viewx, viewy);
|
||||||
P_TranslatePortalZ(pds->src, pds->dst, viewz);
|
P_TranslatePortalZ(pds->src, viewz);
|
||||||
P_TranslatePortalAngle(pds->src, pds->dst, viewangle);
|
P_TranslatePortalAngle(pds->src, viewangle);
|
||||||
}
|
}
|
||||||
|
|
||||||
viewsin = finesine[viewangle>>ANGLETOFINESHIFT];
|
viewsin = finesine[viewangle>>ANGLETOFINESHIFT];
|
||||||
|
|
Loading…
Reference in a new issue