Merge branch 'floatcvt' of https://github.com/rheit/zdoom into floatcvt

# Conflicts:
#	src/actor.h
This commit is contained in:
Christoph Oelckers 2016-03-31 21:24:26 +02:00
commit 466c4c75df
36 changed files with 609 additions and 1079 deletions

View file

@ -561,11 +561,7 @@ public:
int Amount;
};
fixed_t P_AproxDistance (fixed_t dx, fixed_t dy); // since we cannot include p_local here...
angle_t R_PointToAngle2 (fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2); // same reason here with r_defs.h
const double MinVel = 1. / 65536;
const double Z_Epsilon = 1. / 65536.;
const double MinVel = EQUAL_EPSILON;
// Map Object definition.
class AActor : public DThinker
@ -752,17 +748,6 @@ public:
return BobSin(FloatBobPhase + level.maptime + ticfrac);
}
fixed_t _f_GetBobOffset(fixed_t ticfrac=0) const
{
if (!(flags2 & MF2_FLOATBOB))
{
return 0;
}
return finesine[MulScale22(((FloatBobPhase + level.maptime) << FRACBITS) + ticfrac, FINEANGLES) & FINEMASK] * 8;
}
// Enter the crash state
void Crash();
@ -850,8 +835,6 @@ public:
return VecToAngle(otherpos - Pos().XY());
}
DAngle AngleTo(AActor *other, fixed_t oxofs, fixed_t oyofs, bool absolute = false) const = delete;
DAngle AngleTo(AActor *other, double oxofs, double oyofs, bool absolute = false) const
{
DVector2 otherpos = absolute ? other->Pos() : other->PosRelative(this);
@ -906,21 +889,6 @@ public:
}
}
fixedvec3 Vec3Offset(fixed_t dx, fixed_t dy, fixed_t dz, bool absolute = false)
{
if (absolute)
{
fixedvec3 ret = { _f_X() + dx, _f_Y() + dy, _f_Z() + dz };
return ret;
}
else
{
fixedvec2 op = P_GetOffsetPosition(_f_X(), _f_Y(), dx, dy);
fixedvec3 pos = { op.x, op.y, _f_Z() + dz };
return pos;
}
}
DVector3 Vec3Offset(double dx, double dy, double dz, bool absolute = false)
{
if (absolute)
@ -959,22 +927,14 @@ public:
void ClearInterpolation();
void SetOrigin(const fixedvec3 & npos, bool moving)
{
SetOrigin(npos.x, npos.y, npos.z, moving);
}
void Move(const DVector3 &vel)
{
SetOrigin(Pos() + vel, true);
}
void SetOrigin(double x, double y, double z, bool moving)
{
SetOrigin(FLOAT2FIXED(x), FLOAT2FIXED(y), FLOAT2FIXED(z), moving);
}
virtual void SetOrigin(double x, double y, double z, bool moving);
void SetOrigin(const DVector3 & npos, bool moving)
{
SetOrigin(FLOAT2FIXED(npos.X), FLOAT2FIXED(npos.Y), FLOAT2FIXED(npos.Z), moving);
SetOrigin(npos.X, npos.Y, npos.Z, moving);
}
inline void SetFriendPlayer(player_t *player);
@ -1021,11 +981,6 @@ public:
double floorz, ceilingz; // closest together of contacted secs
double dropoffz; // killough 11/98: the lowest floor over all contacted Sectors.
inline fixed_t _f_floorz()
{
return FLOAT2FIXED(floorz);
}
struct sector_t *floorsector;
FTextureID floorpic; // contacted sec floorpic
int floorterrain;
@ -1033,15 +988,6 @@ public:
FTextureID ceilingpic; // contacted sec ceilingpic
double radius, Height; // for movement checking
inline fixed_t _f_radius() const
{
return FLOAT2FIXED(radius);
}
inline fixed_t _f_height() const
{
return FLOAT2FIXED(Height);
}
double projectilepassheight; // height for clipping projectile movement against this actor
SDWORD tics; // state tic counter
@ -1092,10 +1038,6 @@ public:
TObjPtr<AActor> tracer; // Thing being chased/attacked for tracers
TObjPtr<AActor> master; // Thing which spawned this one (prevents mutual attacks)
double Floorclip; // value to use for floor clipping
fixed_t _f_floorclip()
{
return FLOAT2FIXED(Floorclip);
}
int tid; // thing identifier
int special; // special
@ -1222,7 +1164,6 @@ public:
void LinkToWorld (bool spawningmapthing=false, sector_t *sector = NULL);
void UnlinkFromWorld ();
void AdjustFloorClip ();
virtual void SetOrigin (fixed_t x, fixed_t y, fixed_t z, bool moving = false);
bool InStateSequence(FState * newstate, FState * basestate);
int GetTics(FState * newstate);
bool SetState (FState *newstate, bool nofunction=false);
@ -1260,14 +1201,6 @@ public:
{
return FLOAT2FIXED(__Pos.Y);
}
fixed_t _f_Z() const
{
return FLOAT2FIXED(__Pos.Z);
}
fixedvec3 _f_Pos() const
{
return{ _f_X(), _f_Y(), _f_Z() };
}
double X() const
{
@ -1289,15 +1222,15 @@ public:
// Comparing with floorz is ok because those values come from the same calculations.
bool isAbove(double checkz) const
{
return Z() > checkz + Z_Epsilon;
return Z() > checkz + EQUAL_EPSILON;
}
bool isBelow(double checkz) const
{
return Z() < checkz - Z_Epsilon;
return Z() < checkz - EQUAL_EPSILON;
}
bool isAtZ(double checkz) const
{
return fabs(Z() - checkz) < Z_Epsilon;
return fabs(Z() - checkz) < EQUAL_EPSILON;
}
DVector3 PosRelative(int grp) const;
@ -1307,18 +1240,14 @@ public:
FVector3 SoundPos() const
{
// the sound system switches y and z axes so this function must, too.
// fixme: This still needs portal handling
return{ float(X()), float(Y()), float(Z()) };
return{ float(X()), float(Z()), float(Y()) };
}
DVector3 InterpolatedPosition(double ticFrac) const
{
return Prev + (ticFrac * (Pos() - Prev));
}
fixedvec3 PosPlusZ(fixed_t zadd) const
{
fixedvec3 ret = { _f_X(), _f_Y(), _f_Z() + zadd };
return ret;
}
DVector3 PosPlusZ(double zadd) const
{
return { X(), Y(), Z() + zadd };
@ -1327,18 +1256,6 @@ public:
{
return{ X(), Y(), zadd };
}
fixed_t _f_Top() const
{
return _f_Z() + FLOAT2FIXED(Height);
}
void _f_SetZ(fixed_t newz, bool moving = true)
{
__Pos.Z = FIXED2DBL(newz);
}
void _f_AddZ(fixed_t newz, bool moving = true)
{
__Pos.Z += FIXED2DBL(newz);
}
double Top() const
{
return Z() + Height;
@ -1363,11 +1280,6 @@ public:
__Pos.X = FIXED2DBL(xx);
__Pos.Y = FIXED2DBL(yy);
}
void SetXY(const fixedvec2 &npos)
{
__Pos.X = FIXED2DBL(npos.x);
__Pos.Y = FIXED2DBL(npos.y);
}
void SetXY(const DVector2 &npos)
{
__Pos.X = npos.X;
@ -1383,12 +1295,6 @@ public:
{
__Pos = { xx,yy,zz };
}
void SetXYZ(const fixedvec3 &npos)
{
__Pos.X = FIXED2DBL(npos.x);
__Pos.Y = FIXED2DBL(npos.y);
__Pos.Z = FIXED2DBL(npos.z);
}
void SetXYZ(const DVector3 &npos)
{
__Pos = npos;
@ -1578,13 +1484,6 @@ template<class T> inline T *Spawn() // for inventory items we do not need coordi
return static_cast<T *>(AActor::StaticSpawn(RUNTIME_TEMPLATE_CLASS(T), DVector3(0, 0, 0), NO_REPLACE));
}
inline fixedvec2 Vec2Angle(fixed_t length, angle_t angle)
{
fixedvec2 ret = { FixedMul(length, finecosine[angle >> ANGLETOFINESHIFT]),
FixedMul(length, finesine[angle >> ANGLETOFINESHIFT]) };
return ret;
}
void PrintMiscActorInfo(AActor * query);
AActor *P_LinePickActor(AActor *t1, DAngle angle, double distance, DAngle pitch, ActorFlags actorMask, DWORD wallMask);

View file

@ -55,7 +55,7 @@ bool DBot::Reachable (AActor *rtarget)
double dist;
sector_t *s;
frac = in->Frac - 4 /MAX_TRAVERSE_DIST;
frac = in->frac - 4 /MAX_TRAVERSE_DIST;
dist = frac * MAX_TRAVERSE_DIST;
hitx = it.Trace().x + player->mo->Vel.X * frac;

View file

@ -66,89 +66,6 @@ union QWORD_UNION
typedef SDWORD fixed_t;
typedef DWORD dsfixed_t; // fixedpt used by span drawer
struct fixedvec2
{
fixed_t x, y;
fixedvec2 &operator +=(const fixedvec2 &other)
{
x += other.x;
y += other.y;
return *this;
}
};
struct fixedvec3
{
fixed_t x, y, z;
fixedvec3 &operator +=(const fixedvec3 &other)
{
x += other.x;
y += other.y;
z += other.z;
return *this;
}
fixedvec3 &operator +=(const fixedvec2 &other)
{
x += other.x;
y += other.y;
return *this;
}
fixedvec3 &operator -=(const fixedvec2 &other)
{
x -= other.x;
y -= other.y;
return *this;
}
fixedvec3 &operator -=(const fixedvec3 &other)
{
x -= other.x;
y -= other.y;
z -= other.z;
return *this;
}
operator fixedvec2()
{
return { x, y };
}
};
inline fixedvec2 operator +(const fixedvec2 &v1, const fixedvec2 &v2)
{
return { v1.x + v2.x, v1.y + v2.y };
}
inline fixedvec2 operator -(const fixedvec2 &v1, const fixedvec2 &v2)
{
return { v1.x - v2.x, v1.y - v2.y };
}
inline fixedvec3 operator +(const fixedvec3 &v1, const fixedvec3 &v2)
{
return { v1.x + v2.x, v1.y + v2.y, v1.z + v2.z };
}
inline fixedvec3 operator +(const fixedvec3 &v1, const fixedvec2 &v2)
{
return { v1.x + v2.x, v1.y + v2.y, v1.z };
}
inline fixedvec3 operator -(const fixedvec3 &v1, const fixedvec2 &v2)
{
return{ v1.x - v2.x, v1.y - v2.y, v1.z };
}
inline fixedvec3 operator -(const fixedvec3 &v1, const fixedvec3 &v2)
{
return{ v1.x - v2.x, v1.y - v2.y, v1.z - v2.z };
}
#define FIXED_MAX (signed)(0x7fffffff)
#define FIXED_MIN (signed)(0x80000000)

View file

@ -340,7 +340,7 @@ enum : unsigned int
COMPATF2_BADANGLES = 1 << 0, // It is impossible to face directly NSEW.
COMPATF2_FLOORMOVE = 1 << 1, // Use the same floor motion behavior as Doom.
COMPATF2_SOUNDCUTOFF = 1 << 2, // Cut off sounds when an actor vanishes instead of making it owner-less
COMPATF2_POINTONLINE = 1 << 3, // Use original but buggy P_PointOnLineSide() and P_PointOnDivlineSide()
COMPATF2_POINTONLINE = 1 << 3, // Use original but buggy P_PointOnLineSide() and P_PointOnDivlineSideCompat()
COMPATF2_MULTIEXIT = 1 << 4, // Level exit can be triggered multiple times (required by Daedalus's travel tubes, thanks to a faulty script)
};

View file

@ -213,7 +213,7 @@ static AActor *FrontBlockCheck (AActor *mo, int index, void *)
{
if (link->Me != mo)
{
if (P_PointOnDivlineSidePrecise(link->Me->X(), link->Me->Y(), &BlockCheckLine) == 0 &&
if (P_PointOnDivlineSide(link->Me->X(), link->Me->Y(), &BlockCheckLine) == 0 &&
mo->IsOkayToAttack (link->Me))
{
return link->Me;

View file

@ -34,32 +34,17 @@
//
//==========================================================================
void FBoundingBox::setBox(fixed_t x, fixed_t y, fixed_t radius)
void FBoundingBox::AddToBox (const DVector2 &pos)
{
m_Box[BOXTOP] = (fixed_t)MIN<SQWORD>((SQWORD)y + radius, FIXED_MAX);
m_Box[BOXLEFT] = (fixed_t)MAX<SQWORD>((SQWORD)x - radius, FIXED_MIN);
m_Box[BOXRIGHT] = (fixed_t)MIN<SQWORD>((SQWORD)x + radius, FIXED_MAX);
m_Box[BOXBOTTOM] = (fixed_t)MAX<SQWORD>((SQWORD)y - radius, FIXED_MIN);
}
if (pos.X < m_Box[BOXLEFT])
m_Box[BOXLEFT] = pos.X;
if (pos.X > m_Box[BOXRIGHT])
m_Box[BOXRIGHT] = pos.X;
//==========================================================================
//
//
//
//==========================================================================
void FBoundingBox::AddToBox (fixed_t x, fixed_t y)
{
if (x < m_Box[BOXLEFT])
m_Box[BOXLEFT] = x;
if (x > m_Box[BOXRIGHT])
m_Box[BOXRIGHT] = x;
if (y < m_Box[BOXBOTTOM])
m_Box[BOXBOTTOM] = y;
if (y > m_Box[BOXTOP])
m_Box[BOXTOP] = y;
if (pos.Y < m_Box[BOXBOTTOM])
m_Box[BOXBOTTOM] = pos.Y;
if (pos.Y > m_Box[BOXTOP])
m_Box[BOXTOP] = pos.Y;
}
//==========================================================================
@ -78,8 +63,8 @@ int FBoundingBox::BoxOnLineSide (const line_t *ld) const
if (ld->Delta().X == 0)
{ // ST_VERTICAL
p1 = m_Box[BOXRIGHT] < ld->v1->fixX();
p2 = m_Box[BOXLEFT] < ld->v1->fixX();
p1 = m_Box[BOXRIGHT] < ld->v1->fX();
p2 = m_Box[BOXLEFT] < ld->v1->fX();
if (ld->Delta().Y < 0)
{
p1 ^= 1;
@ -88,8 +73,8 @@ int FBoundingBox::BoxOnLineSide (const line_t *ld) const
}
else if (ld->Delta().Y == 0)
{ // ST_HORIZONTAL:
p1 = m_Box[BOXTOP] > ld->v1->fixY();
p2 = m_Box[BOXBOTTOM] > ld->v1->fixY();
p1 = m_Box[BOXTOP] > ld->v1->fY();
p2 = m_Box[BOXBOTTOM] > ld->v1->fY();
if (ld->Delta().X < 0)
{
p1 ^= 1;

View file

@ -22,7 +22,8 @@
#ifndef __M_BBOX_H__
#define __M_BBOX_H__
#include "doomtype.h"
#include <float.h>
#include "vectors.h"
#include "m_fixed.h"
struct line_t;
@ -36,7 +37,7 @@ public:
ClearBox();
}
FBoundingBox(fixed_t left, fixed_t bottom, fixed_t right, fixed_t top)
FBoundingBox(double left, double bottom, double right, double top)
{
m_Box[BOXTOP] = top;
m_Box[BOXLEFT] = left;
@ -44,35 +45,24 @@ public:
m_Box[BOXBOTTOM] = bottom;
}
FBoundingBox(double left, double bottom, double right, double top)
{
m_Box[BOXTOP] = FLOAT2FIXED(top);
m_Box[BOXLEFT] = FLOAT2FIXED(left);
m_Box[BOXRIGHT] = FLOAT2FIXED(right);
m_Box[BOXBOTTOM] = FLOAT2FIXED(bottom);
}
FBoundingBox(fixed_t x, fixed_t y, fixed_t radius)
{
setBox(x, y, radius);
}
FBoundingBox(double x, double y, double radius)
{
setBox(x, y, radius);
}
void setBox(fixed_t x, fixed_t y, fixed_t radius);
void setBox(double x, double y, double radius)
{
setBox(FLOAT2FIXED(x), FLOAT2FIXED(y), FLOAT2FIXED(radius));
m_Box[BOXTOP] = y + radius;
m_Box[BOXLEFT] = x - radius;
m_Box[BOXRIGHT] = x + radius;
m_Box[BOXBOTTOM] = y - radius;
}
void ClearBox ()
{
m_Box[BOXTOP] = m_Box[BOXRIGHT] = FIXED_MIN;
m_Box[BOXBOTTOM] = m_Box[BOXLEFT] = FIXED_MAX;
m_Box[BOXTOP] = m_Box[BOXRIGHT] = -FLT_MAX;
m_Box[BOXBOTTOM] = m_Box[BOXLEFT] = FLT_MAX;
}
// Returns a bounding box that encloses both bounding boxes
@ -84,21 +74,21 @@ public:
m_Box[BOXTOP] > box2.m_Box[BOXTOP] ? m_Box[BOXTOP] : box2.m_Box[BOXTOP]);
}
void AddToBox (fixed_t x, fixed_t y);
void AddToBox(const DVector2 &pos);
inline fixed_t Top () const { return m_Box[BOXTOP]; }
inline fixed_t Bottom () const { return m_Box[BOXBOTTOM]; }
inline fixed_t Left () const { return m_Box[BOXLEFT]; }
inline fixed_t Right () const { return m_Box[BOXRIGHT]; }
inline double Top () const { return m_Box[BOXTOP]; }
inline double Bottom () const { return m_Box[BOXBOTTOM]; }
inline double Left () const { return m_Box[BOXLEFT]; }
inline double Right () const { return m_Box[BOXRIGHT]; }
bool inRange(const line_t *ld) const;
int BoxOnLineSide (const line_t *ld) const;
void Set(int index, fixed_t value) {m_Box[index] = value;}
void Set(int index, double value) {m_Box[index] = value;}
protected:
fixed_t m_Box[4];
double m_Box[4];
};

View file

@ -48,6 +48,7 @@ public:
extern FFastTrig fasttrig;
// This must use xs_Float to guarantee proper integer wraparound.
#define DEG2BAM(f) ((unsigned)xs_CRoundToInt((f) * (0x40000000/90.)))
#define RAD2BAM(f) ((unsigned)xs_CRoundToInt((f) * (0x80000000/3.14159265358979323846)))

View file

@ -279,9 +279,9 @@ void P_ThinkParticles ()
continue;
}
fixedvec2 newxy = P_GetOffsetPosition(particle->x, particle->y, particle->vel.x, particle->vel.y);
particle->x = newxy.x;
particle->y = newxy.y;
DVector2 newxy = P_GetOffsetPosition(FIXED2DBL(particle->x), FIXED2DBL(particle->y), FIXED2DBL(particle->vel.x), FIXED2DBL(particle->vel.y));
particle->x = FLOAT2FIXED(newxy.X);
particle->y = FLOAT2FIXED(newxy.Y);
//particle->x += particle->vel.x;
//particle->y += particle->vel.y;
particle->z += particle->vel.z;
@ -408,14 +408,14 @@ static void MakeFountain (AActor *actor, int color1, int color2)
if (particle)
{
angle_t an = M_Random()<<(24-ANGLETOFINESHIFT);
fixed_t out = FixedMul (actor->_f_radius(), M_Random()<<8);
DAngle an = M_Random() * (360. / 256);
double out = actor->radius * M_Random() / 256.;
fixedvec3 pos = actor->Vec3Offset(FixedMul(out, finecosine[an]), FixedMul(out, finesine[an]), actor->_f_height() + FRACUNIT);
particle->x = pos.x;
particle->y = pos.y;
particle->z = pos.z;
if (out < actor->_f_radius()/8)
DVector3 pos = actor->Vec3Angle(out, an, actor->Height + 1);
particle->x = FLOAT2FIXED(pos.X);
particle->y = FLOAT2FIXED(pos.Y);
particle->z = FLOAT2FIXED(pos.Z);
if (out < actor->radius/8)
particle->vel.z += FRACUNIT*10/3;
else
particle->vel.z += FRACUNIT*3;
@ -449,14 +449,14 @@ void P_RunEffect (AActor *actor, int effects)
particle = JitterParticle (3 + (M_Random() & 31));
if (particle) {
fixed_t pathdist = M_Random()<<8;
fixedvec3 pos = actor->Vec3Offset(
FLOAT2FIXED(backx) - fixed_t(actor->Vel.X * pathdist),
FLOAT2FIXED(backy) - fixed_t(actor->Vel.Y * pathdist),
FLOAT2FIXED(backz) - fixed_t(actor->Vel.Z * pathdist));
particle->x = pos.x;
particle->y = pos.y;
particle->z = pos.z;
double pathdist = M_Random() / 256.;
DVector3 pos = actor->Vec3Offset(
backx - actor->Vel.X * pathdist,
backy - actor->Vel.Y * pathdist,
backz - actor->Vel.Z * pathdist);
particle->x = FLOAT2FIXED(pos.X);
particle->y = FLOAT2FIXED(pos.Y);
particle->z = FLOAT2FIXED(pos.Z);
speed = (M_Random () - 128) * (FRACUNIT/200);
particle->vel.x += fixed_t(speed * an.Cos());
particle->vel.y += fixed_t(speed * an.Sin());
@ -468,14 +468,15 @@ void P_RunEffect (AActor *actor, int effects)
for (i = 6; i; i--) {
particle_t *particle = JitterParticle (3 + (M_Random() & 31));
if (particle) {
fixed_t pathdist = M_Random()<<8;
fixedvec3 pos = actor->Vec3Offset(
FLOAT2FIXED(backx) - fixed_t(actor->Vel.X * pathdist),
FLOAT2FIXED(backy) - fixed_t(actor->Vel.Y * pathdist),
FLOAT2FIXED(backz) - fixed_t(actor->Vel.Z * pathdist) + (M_Random() << 10));
particle->x = pos.x;
particle->y = pos.y;
particle->z = pos.z;
double pathdist = M_Random() / 256.;
DVector3 pos = actor->Vec3Offset(
backx - actor->Vel.X * pathdist,
backy - actor->Vel.Y * pathdist,
backz - actor->Vel.Z * pathdist + (M_Random() / 64.));
particle->x = FLOAT2FIXED(pos.X);
particle->y = FLOAT2FIXED(pos.Y);
particle->z = FLOAT2FIXED(pos.Z);
speed = (M_Random () - 128) * (FRACUNIT/200);
particle->vel.x += fixed_t(speed * an.Cos());
particle->vel.y += fixed_t(speed * an.Sin());
@ -526,18 +527,18 @@ void P_RunEffect (AActor *actor, int effects)
particle = JitterParticle (16);
if (particle != NULL)
{
angle_t ang = M_Random () << (32-ANGLETOFINESHIFT-8);
fixedvec3 pos = actor->Vec3Offset(FixedMul (actor->_f_radius(), finecosine[ang]), FixedMul (actor->_f_radius(), finesine[ang]), 0);
particle->x = pos.x;
particle->y = pos.y;
particle->z = pos.z;
DAngle ang = M_Random() * (360 / 256.);
DVector3 pos = actor->Vec3Angle(actor->radius, ang, 0);
particle->x = FLOAT2FIXED(pos.X);
particle->y = FLOAT2FIXED(pos.Y);
particle->z = FLOAT2FIXED(pos.Z);
particle->color = *protectColors[M_Random() & 1];
particle->vel.z = FRACUNIT;
particle->accz = M_Random () << 7;
particle->size = 1;
if (M_Random () < 128)
{ // make particle fall from top of actor
particle->z += actor->_f_height();
particle->z += FLOAT2FIXED(actor->Height);
particle->vel.z = -particle->vel.z;
particle->accz = -particle->accz;
}
@ -882,14 +883,14 @@ void P_DisconnectEffect (AActor *actor)
if (!p)
break;
double xo = (M_Random() - 128)*actor->radius / 128;
double yo = (M_Random() - 128)*actor->radius / 128;
double zo = M_Random()*actor->Height / 256;
fixed_t xo = ((M_Random() - 128) << 9) * int(actor->radius);
fixed_t yo = ((M_Random() - 128) << 9) * int(actor->radius);
fixed_t zo = (M_Random() << 8) * int(actor->Height);
fixedvec3 pos = actor->Vec3Offset(xo, yo, zo);
p->x = pos.x;
p->y = pos.y;
p->z = pos.z;
DVector3 pos = actor->Vec3Offset(xo, yo, zo);
p->x = FLOAT2FIXED(pos.X);
p->y = FLOAT2FIXED(pos.Y);
p->z = FLOAT2FIXED(pos.Z);
p->accz -= FRACUNIT/4096;
p->color = M_Random() < 128 ? maroon1 : maroon2;
p->size = 4;

View file

@ -52,6 +52,12 @@
struct subsector_t;
// [RH] Particle details
struct fixedvec3
{
fixed_t x, y, z;
};
struct particle_t
{
fixed_t x,y,z;

View file

@ -162,12 +162,12 @@ void P_RecursiveSound (sector_t *sec, AActor *soundtarget, bool splash, int soun
// I wish there was a better method to do this than randomly looking through the portal at a few places...
if (checkabove)
{
sector_t *upper = P_PointInSector(check->V1() + check->Delta() / 2 + sec->SkyBoxes[sector_t::ceiling]->Scale);
sector_t *upper = P_PointInSector(check->v1->fPos() + check->Delta() / 2 + sec->SkyBoxes[sector_t::ceiling]->Scale);
P_RecursiveSound(upper, soundtarget, splash, soundblocks, emitter, maxdist);
}
if (checkbelow)
{
sector_t *lower = P_PointInSector(check->V1() + check->Delta() / 2 + sec->SkyBoxes[sector_t::floor]->Scale);
sector_t *lower = P_PointInSector(check->v1->fPos() + check->Delta() / 2 + sec->SkyBoxes[sector_t::floor]->Scale);
P_RecursiveSound(lower, soundtarget, splash, soundblocks, emitter, maxdist);
}
FLinePortal *port = check->getPortal();
@ -195,18 +195,18 @@ void P_RecursiveSound (sector_t *sec, AActor *soundtarget, bool splash, int soun
other = check->sidedef[0]->sector;
// check for closed door
if ((sec->floorplane.ZatPoint (check->V1()) >=
other->ceilingplane.ZatPoint (check->V1()) &&
sec->floorplane.ZatPoint (check->V2()) >=
other->ceilingplane.ZatPoint (check->V2()))
|| (other->floorplane.ZatPoint (check->V1()) >=
sec->ceilingplane.ZatPoint (check->V1()) &&
other->floorplane.ZatPoint (check->V2()) >=
sec->ceilingplane.ZatPoint (check->V2()))
|| (other->floorplane.ZatPoint (check->V1()) >=
other->ceilingplane.ZatPoint (check->V1()) &&
other->floorplane.ZatPoint (check->V2()) >=
other->ceilingplane.ZatPoint (check->V2())))
if ((sec->floorplane.ZatPoint (check->v1->fPos()) >=
other->ceilingplane.ZatPoint (check->v1->fPos()) &&
sec->floorplane.ZatPoint (check->v2->fPos()) >=
other->ceilingplane.ZatPoint (check->v2->fPos()))
|| (other->floorplane.ZatPoint (check->v1->fPos()) >=
sec->ceilingplane.ZatPoint (check->v1->fPos()) &&
other->floorplane.ZatPoint (check->v2->fPos()) >=
sec->ceilingplane.ZatPoint (check->v2->fPos()))
|| (other->floorplane.ZatPoint (check->v1->fPos()) >=
other->ceilingplane.ZatPoint (check->v1->fPos()) &&
other->floorplane.ZatPoint (check->v2->fPos()) >=
other->ceilingplane.ZatPoint (check->v2->fPos())))
{
continue;
}

View file

@ -81,7 +81,7 @@ static void CreateCachedNodes(MapData *map);
// fixed 32 bit gl_vert format v2.0+ (glBsp 1.91)
struct mapglvertex_t
{
fixed_t x,y;
SDWORD x,y;
};
struct gl3_mapsubsector_t
@ -1333,7 +1333,7 @@ CCMD(clearnodecache)
//
//==========================================================================
subsector_t *P_PointInSubsector (fixed_t x, fixed_t y)
subsector_t *P_PointInSubsector (double x, double y)
{
node_t *node;
int side;

View file

@ -52,9 +52,6 @@ struct FTranslatedLineTarget;
// against lines and things
#define MAPBLOCKUNITS 128
#define MAPBLOCKSIZE (MAPBLOCKUNITS*FRACUNIT)
#define MAPBLOCKSHIFT (FRACBITS+7)
#define MAPBMASK (MAPBLOCKSIZE-1)
#define MAPBTOFRAC (MAPBLOCKSHIFT-FRACBITS)
// Inspired by Maes
extern int bmapnegx;
@ -202,7 +199,7 @@ AActor *P_RoughMonsterSearch (AActor *mo, int distance, bool onlyseekable=false)
// If "floatok" true, move would be ok
// if within "tmfloorz - tm_f_ceilingz()".
// if within "tmfloorz - tmceilingz".
extern msecnode_t *sector_list; // phares 3/16/98
struct spechit_t
@ -264,7 +261,6 @@ enum
void P_FindFloorCeiling (AActor *actor, int flags=0);
bool P_ChangeSector (sector_t* sector, int crunch, double amt, int floorOrCeil, bool isreset);
inline bool P_ChangeSector(sector_t* sector, int crunch, int amt, int floorOrCeil, bool isreset) = delete;
DAngle P_AimLineAttack(AActor *t1, DAngle angle, double distance, FTranslatedLineTarget *pLineTarget = NULL, DAngle vrange = 0., int flags = 0, AActor *target = NULL, AActor *friender = NULL);

View file

@ -109,7 +109,7 @@ static DVector2 FindRefPoint(line_t *ld, const DVector2 &pos)
!ld->frontsector->PortalBlocksMovement(sector_t::floor))
{
DVector2 v1 = ld->V1();
DVector2 v1 = ld->v1->fPos();
DVector2 d = ld->Delta();
double r = clamp(((pos.X - v1.X) * d.X + (pos.Y - v1.Y) * d.Y) / (d.X*d.X + d.Y*d.Y), 0., 1.);
return v1 + d*r;
@ -2728,11 +2728,11 @@ void FSlide::SlideTraverse(const DVector2 &start, const DVector2 &end)
// the line does block movement,
// see if it is closer than best so far
isblocking:
if (in->Frac < bestSlidefrac)
if (in->frac < bestSlidefrac)
{
secondSlidefrac = bestSlidefrac;
secondslideline = bestslideline;
bestSlidefrac = in->Frac;
bestSlidefrac = in->frac;
bestslideline = li;
}
@ -3057,11 +3057,11 @@ bool FSlide::BounceTraverse(const DVector2 &start, const DVector2 &end)
// the line does block movement, see if it is closer than best so far
bounceblocking:
if (in->Frac < bestSlidefrac)
if (in->frac < bestSlidefrac)
{
secondSlidefrac = bestSlidefrac;
secondslideline = bestslideline;
bestSlidefrac = in->Frac;
bestSlidefrac = in->frac;
bestslideline = li;
}
return false; // stop
@ -3419,9 +3419,9 @@ struct aim_t
F3DFloor* rover;
DAngle highpitch, lowpitch;
double trX = trace.x + trace.dx * in->Frac;
double trY = trace.y + trace.dy * in->Frac;
double dist = attackrange * in->Frac;
double trX = trace.x + trace.dx * in->frac;
double trY = trace.y + trace.dy * in->frac;
double dist = attackrange * in->frac;
// 3D floor check. This is not 100% accurate but normally sufficient when
// combined with a final sight check
@ -3632,7 +3632,7 @@ struct aim_t
double dist;
DAngle thingpitch;
if (linetarget.linetarget != NULL && in->Frac > linetarget.frac) return; // we already found something better in another portal section.
if (linetarget.linetarget != NULL && in->frac > linetarget.frac) return; // we already found something better in another portal section.
if (in->isaline)
{
@ -3644,7 +3644,7 @@ struct aim_t
if (li->isLinePortal() && frontflag == 0)
{
EnterLinePortal(li, in->Frac);
EnterLinePortal(li, in->frac);
return;
}
@ -3662,7 +3662,7 @@ struct aim_t
if (open.range <= 0 || open.bottom >= open.top)
return;
dist = attackrange * in->Frac;
dist = attackrange * in->frac;
if (open.bottom != LINEOPEN_MIN)
{
@ -3692,11 +3692,11 @@ struct aim_t
// check portal in backsector when aiming up/downward is possible, the line doesn't have portals on both sides and there's actually a portal in the backsector
if ((planestocheck & aim_up) && toppitch < 0 && open.top != LINEOPEN_MAX && !entersec->PortalBlocksMovement(sector_t::ceiling))
{
EnterSectorPortal(sector_t::ceiling, in->Frac, entersec, toppitch, MIN<DAngle>(0., bottompitch));
EnterSectorPortal(sector_t::ceiling, in->frac, entersec, toppitch, MIN<DAngle>(0., bottompitch));
}
if ((planestocheck & aim_down) && bottompitch > 0 && open.bottom != LINEOPEN_MIN && !entersec->PortalBlocksMovement(sector_t::floor))
{
EnterSectorPortal(sector_t::floor, in->Frac, entersec, MAX<DAngle>(0., toppitch), bottompitch);
EnterSectorPortal(sector_t::floor, in->frac, entersec, MAX<DAngle>(0., toppitch), bottompitch);
}
continue; // shot continues
}
@ -3728,7 +3728,7 @@ struct aim_t
}
}
}
dist = attackrange * in->Frac;
dist = attackrange * in->frac;
// Don't autoaim certain special actors
if (!cl_doautoaim && th->flags6 & MF6_NOTAUTOAIMED)
@ -3811,7 +3811,7 @@ struct aim_t
if (cosine != 0)
{
double tracelen = DVector2(it.Trace().dx, it.Trace().dy).Length();
double d3 = tracelen * in->Frac / cosine;
double d3 = tracelen * in->frac / cosine;
if (d3 > attackrange)
{
return;
@ -3834,7 +3834,7 @@ struct aim_t
// friends don't aim at friends (except players), at least not first
if (aimdebug)
Printf("Hit friend %s at %f,%f,%f\n", th->GetClass()->TypeName.GetChars(), th->X(), th->Y(), th->Z());
SetResult(thing_friend, in->Frac, th, thingpitch);
SetResult(thing_friend, in->frac, th, thingpitch);
}
}
else if (!(th->flags3 & MF3_ISMONSTER) && th->player == NULL)
@ -3844,14 +3844,14 @@ struct aim_t
// don't autoaim at barrels and other shootable stuff unless no monsters have been found
if (aimdebug)
Printf("Hit other %s at %f,%f,%f\n", th->GetClass()->TypeName.GetChars(), th->X(), th->Y(), th->Z());
SetResult(thing_other, in->Frac, th, thingpitch);
SetResult(thing_other, in->frac, th, thingpitch);
}
}
else
{
if (aimdebug)
Printf("Hit target %s at %f,%f,%f\n", th->GetClass()->TypeName.GetChars(), th->X(), th->Y(), th->Z());
SetResult(linetarget, in->Frac, th, thingpitch);
SetResult(linetarget, in->frac, th, thingpitch);
return;
}
}
@ -3859,7 +3859,7 @@ struct aim_t
{
if (aimdebug)
Printf("Hit target %s at %f,%f,%f\n", th->GetClass()->TypeName.GetChars(), th->X(), th->Y(), th->Z());
SetResult(linetarget, in->Frac, th, thingpitch);
SetResult(linetarget, in->frac, th, thingpitch);
return;
}
}

View file

@ -46,8 +46,8 @@
#include "po_man.h"
static AActor *RoughBlockCheck (AActor *mo, int index, void *);
static int R_PointOnSideSlow(fixed_t x, fixed_t y, node_t *node);
sector_t *P_PointInSectorBuggy(fixed_t x, fixed_t y);
sector_t *P_PointInSectorBuggy(double x, double y);
int P_VanillaPointOnDivlineSide(double x, double y, const divline_t* line);
//==========================================================================
@ -58,13 +58,28 @@ sector_t *P_PointInSectorBuggy(fixed_t x, fixed_t y);
//
//==========================================================================
fixed_t P_AproxDistance (fixed_t dx, fixed_t dy)
int P_AproxDistance (int dx, int dy)
{
dx = abs(dx);
dy = abs(dy);
return (dx < dy) ? dx+dy-(dx>>1) : dx+dy-(dy>>1);
}
//==========================================================================
//
// P_PointOnDivlineSideCompat
//
// Returns the fractional intercept point along the first divline
// with compatibility flag handling
//
//==========================================================================
inline int P_PointOnDivlineSideCompat(double x, double y, const divline_t *line)
{
return (i_compatflags2 & COMPATF2_POINTONLINE)
? P_VanillaPointOnDivlineSide(x, y, line) : P_PointOnDivlineSide(x, y, line);
}
//==========================================================================
//
// P_InterceptVector
@ -96,69 +111,6 @@ double P_InterceptVector(const divline_t *v2, const divline_t *v1)
return num / den;
}
fixed_t P_InterceptVector (const fdivline_t *v2, const fdivline_t *v1)
{
#if 0 // [RH] Use 64 bit ints, so long divlines don't overflow
SQWORD den = ( ((SQWORD)v1->dy*v2->dx - (SQWORD)v1->dx*v2->dy) >> FRACBITS );
if (den == 0)
return 0; // parallel
SQWORD num = ((SQWORD)(v1->fixX() - v2->fixX())*v1->dy + (SQWORD)(v2->fixY() - v1->fixY())*v1->dx);
return (fixed_t)(num / den);
#elif 0 // This is the original Doom version
fixed_t frac;
fixed_t num;
fixed_t den;
den = FixedMul (v1->dy>>8,v2->dx) - FixedMul(v1->dx>>8,v2->dy);
if (den == 0)
return 0;
// I_Error ("P_InterceptVector: parallel");
num =
FixedMul ( (v1->fixX() - v2->fixX())>>8 ,v1->dy )
+FixedMul ( (v2->fixY() - v1->fixY())>>8, v1->dx );
frac = FixedDiv (num , den);
return frac;
#else // optimized version of the float debug version. A lot faster on modern systens.
double frac;
double num;
double den;
// There's no need to divide by FRACUNIT here.
// At the end both num and den will contain a factor
// 1/(FRACUNIT*FRACUNIT) so they'll cancel each other out.
double v1x = (double)v1->x;
double v1y = (double)v1->y;
double v1dx = (double)v1->dx;
double v1dy = (double)v1->dy;
double v2x = (double)v2->x;
double v2y = (double)v2->y;
double v2dx = (double)v2->dx;
double v2dy = (double)v2->dy;
den = v1dy*v2dx - v1dx*v2dy;
if (den == 0)
return 0; // parallel
num = (v1x - v2x)*v1dy + (v2y - v1y)*v1dx;
frac = num / den;
return FLOAT2FIXED(frac);
#endif
}
//==========================================================================
//
// P_LineOpening
@ -374,7 +326,7 @@ void AActor::UnlinkFromWorld ()
bool AActor::FixMapthingPos()
{
sector_t *secstart = P_PointInSectorBuggy(_f_X(), _f_Y());
sector_t *secstart = P_PointInSectorBuggy(X(), Y());
int blockx = GetBlockX(X());
int blocky = GetBlockY(Y());
@ -472,12 +424,12 @@ void AActor::LinkToWorld(bool spawningmapthing, sector_t *sector)
}
else
{
sector = P_PointInSectorBuggy(_f_X(), _f_Y());
sector = P_PointInSectorBuggy(X(), Y());
}
}
Sector = sector;
subsector = R_PointInSubsector(_f_X(), _f_Y()); // this is from the rendering nodes, not the gameplay nodes!
subsector = R_PointInSubsector(Pos()); // this is from the rendering nodes, not the gameplay nodes!
if (!(flags & MF_NOSECTOR))
{
@ -515,7 +467,7 @@ void AActor::LinkToWorld(bool spawningmapthing, sector_t *sector)
{
FPortalGroupArray check(FPortalGroupArray::PGA_NoSectorPortals);
P_CollectConnectedGroups(Sector->PortalGroup, _f_Pos(), _f_Top(), _f_radius(), check);
P_CollectConnectedGroups(Sector->PortalGroup, Pos(), Top(), radius, check);
for (int i = -1; i < (int)check.Size(); i++)
{
@ -564,10 +516,10 @@ void AActor::LinkToWorld(bool spawningmapthing, sector_t *sector)
}
}
void AActor::SetOrigin (fixed_t ix, fixed_t iy, fixed_t iz, bool moving)
void AActor::SetOrigin(double x, double y, double z, bool moving)
{
UnlinkFromWorld ();
SetXYZ(ix, iy, iz);
SetXYZ(x, y, z);
LinkToWorld ();
P_FindFloorCeiling(this, FFCF_ONLYSPAWNPOS);
if (!moving) ClearInterpolation();
@ -638,10 +590,10 @@ FBlockLinesIterator::FBlockLinesIterator(int _minx, int _miny, int _maxx, int _m
void FBlockLinesIterator::init(const FBoundingBox &box)
{
validcount++;
maxy = GetBlockY(FIXED2DBL(box.Top()));
miny = GetBlockY(FIXED2DBL(box.Bottom()));
maxx = GetBlockX(FIXED2DBL(box.Right()));
minx = GetBlockX(FIXED2DBL(box.Left()));
maxy = GetBlockY(box.Top());
miny = GetBlockY(box.Bottom());
maxx = GetBlockX(box.Right());
minx = GetBlockX(box.Left());
Reset();
}
@ -756,28 +708,26 @@ line_t *FBlockLinesIterator::Next()
//
//===========================================================================
FMultiBlockLinesIterator::FMultiBlockLinesIterator(FPortalGroupArray &check, AActor *origin, fixed_t checkradius)
FMultiBlockLinesIterator::FMultiBlockLinesIterator(FPortalGroupArray &check, AActor *origin, double checkradius)
: checklist(check)
{
checkpoint = origin->_f_Pos();
if (!check.inited) P_CollectConnectedGroups(origin->Sector->PortalGroup, checkpoint, origin->_f_Top(), checkradius, checklist);
checkpoint.z = checkradius == -1? origin->_f_radius() : checkradius;
checkpoint = origin->Pos();
if (!check.inited) P_CollectConnectedGroups(origin->Sector->PortalGroup, checkpoint, origin->Top(), checkradius, checklist);
checkpoint.Z = checkradius == -1? origin->radius : checkradius;
basegroup = origin->Sector->PortalGroup;
startsector = origin->Sector;
Reset();
}
FMultiBlockLinesIterator::FMultiBlockLinesIterator(FPortalGroupArray &check, fixed_t checkx, fixed_t checky, fixed_t checkz, fixed_t checkh, fixed_t checkradius, sector_t *newsec)
FMultiBlockLinesIterator::FMultiBlockLinesIterator(FPortalGroupArray &check, double checkx, double checky, double checkz, double checkh, double checkradius, sector_t *newsec)
: checklist(check)
{
checkpoint.x = checkx;
checkpoint.y = checky;
checkpoint.z = checkz;
checkpoint = { checkx, checky, checkz };
if (newsec == NULL) newsec = P_PointInSector(checkx, checky);
startsector = newsec;
basegroup = newsec->PortalGroup;
if (!check.inited) P_CollectConnectedGroups(basegroup, checkpoint, checkz + checkh, checkradius, checklist);
checkpoint.z = checkradius;
checkpoint.Z = checkradius;
Reset();
}
@ -787,7 +737,7 @@ FMultiBlockLinesIterator::FMultiBlockLinesIterator(FPortalGroupArray &check, fix
//
//===========================================================================
bool FMultiBlockLinesIterator::GoUp(fixed_t x, fixed_t y)
bool FMultiBlockLinesIterator::GoUp(double x, double y)
{
if (continueup)
{
@ -808,7 +758,7 @@ bool FMultiBlockLinesIterator::GoUp(fixed_t x, fixed_t y)
//
//===========================================================================
bool FMultiBlockLinesIterator::GoDown(fixed_t x, fixed_t y)
bool FMultiBlockLinesIterator::GoDown(double x, double y)
{
if (continuedown)
{
@ -835,10 +785,8 @@ bool FMultiBlockLinesIterator::Next(FMultiBlockLinesIterator::CheckResult *item)
if (line != NULL)
{
item->line = line;
item->position.x = offset.x;
item->position.y = offset.y;
// same as above in floating point. This is here so that this stuff can be converted piece by piece.
item->Position = { FIXED2DBL(item->position.x), FIXED2DBL(item->position.y), FIXED2DBL(item->position.z) };
item->Position.X = offset.X;
item->Position.Y = offset.Y;
item->portalflags = portalflags;
return true;
}
@ -848,19 +796,19 @@ bool FMultiBlockLinesIterator::Next(FMultiBlockLinesIterator::CheckResult *item)
if (portalflags == FFCF_NOFLOOR && nextflags != FPortalGroupArray::UPPER)
{
// if this is the last upper portal in the list, check if we need to go further up to find the real ceiling.
if (GoUp(offset.x, offset.y)) return Next(item);
if (GoUp(offset.X, offset.Y)) return Next(item);
}
else if (portalflags == FFCF_NOCEILING && nextflags != FPortalGroupArray::LOWER)
{
// if this is the last lower portal in the list, check if we need to go further down to find the real floor.
if (GoDown(offset.x, offset.y)) return Next(item);
if (GoDown(offset.X, offset.Y)) return Next(item);
}
if (onlast)
{
cursector = startsector;
// We reached the end of the list. Check if we still need to check up- and downwards.
if (GoUp(checkpoint.x, checkpoint.y) ||
GoDown(checkpoint.x, checkpoint.y))
if (GoUp(checkpoint.X, checkpoint.Y) ||
GoDown(checkpoint.X, checkpoint.Y))
{
return Next(item);
}
@ -894,11 +842,11 @@ bool FMultiBlockLinesIterator::Next(FMultiBlockLinesIterator::CheckResult *item)
void FMultiBlockLinesIterator::startIteratorForGroup(int group)
{
offset = Displacements._f_getOffset(basegroup, group);
offset.x += checkpoint.x;
offset.y += checkpoint.y;
cursector = group == startsector->PortalGroup ? startsector : P_PointInSector(offset.x, offset.y);
bbox.setBox(offset.x, offset.y, checkpoint.z);
offset = Displacements.getOffset(basegroup, group);
offset.X += checkpoint.X;
offset.Y += checkpoint.Y;
cursector = group == startsector->PortalGroup ? startsector : P_PointInSector(offset);
bbox.setBox(offset.X, offset.Y, checkpoint.Z);
blockIterator.init(bbox);
}
@ -944,10 +892,10 @@ FBlockThingsIterator::FBlockThingsIterator(int _minx, int _miny, int _maxx, int
void FBlockThingsIterator::init(const FBoundingBox &box)
{
maxy = GetBlockY(FIXED2DBL(box.Top()));
miny = GetBlockY(FIXED2DBL(box.Bottom()));
maxx = GetBlockX(FIXED2DBL(box.Right()));
minx = GetBlockX(FIXED2DBL(box.Left()));
maxy = GetBlockY(box.Top());
miny = GetBlockY(box.Bottom());
maxx = GetBlockX(box.Right());
minx = GetBlockX(box.Left());
ClearHash();
Reset();
}
@ -1025,14 +973,14 @@ AActor *FBlockThingsIterator::Next(bool centeronly)
if (centeronly)
{
// Block boundaries for compatibility mode
fixed_t blockleft = (curx << MAPBLOCKSHIFT) + FLOAT2FIXED(bmaporgx);
fixed_t blockright = blockleft + MAPBLOCKSIZE;
fixed_t blockbottom = (cury << MAPBLOCKSHIFT) + FLOAT2FIXED(bmaporgy);
fixed_t blocktop = blockbottom + MAPBLOCKSIZE;
double blockleft = (curx * MAPBLOCKUNITS) + bmaporgx;
double blockright = blockleft + MAPBLOCKUNITS;
double blockbottom = (cury * MAPBLOCKUNITS) + bmaporgy;
double blocktop = blockbottom + MAPBLOCKUNITS;
// only return actors with the center in this block
if (me->_f_X() >= blockleft && me->_f_X() < blockright &&
me->_f_Y() >= blockbottom && me->_f_Y() < blocktop)
if (me->X() >= blockleft && me->X() < blockright &&
me->Y() >= blockbottom && me->Y() < blocktop)
{
return me;
}
@ -1093,26 +1041,26 @@ AActor *FBlockThingsIterator::Next(bool centeronly)
//
//===========================================================================
FMultiBlockThingsIterator::FMultiBlockThingsIterator(FPortalGroupArray &check, AActor *origin, fixed_t checkradius, bool ignorerestricted)
FMultiBlockThingsIterator::FMultiBlockThingsIterator(FPortalGroupArray &check, AActor *origin, double checkradius, bool ignorerestricted)
: checklist(check)
{
checkpoint = origin->_f_Pos();
if (!check.inited) P_CollectConnectedGroups(origin->Sector->PortalGroup, checkpoint, origin->_f_Top(), checkradius, checklist);
checkpoint.z = checkradius == -1? origin->_f_radius() : checkradius;
checkpoint = origin->Pos();
if (!check.inited) P_CollectConnectedGroups(origin->Sector->PortalGroup, checkpoint, origin->Top(), checkradius, checklist);
checkpoint.Z = checkradius == -1? origin->radius : checkradius;
basegroup = origin->Sector->PortalGroup;
Reset();
}
FMultiBlockThingsIterator::FMultiBlockThingsIterator(FPortalGroupArray &check, fixed_t checkx, fixed_t checky, fixed_t checkz, fixed_t checkh, fixed_t checkradius, bool ignorerestricted, sector_t *newsec)
FMultiBlockThingsIterator::FMultiBlockThingsIterator(FPortalGroupArray &check, double checkx, double checky, double checkz, double checkh, double checkradius, bool ignorerestricted, sector_t *newsec)
: checklist(check)
{
checkpoint.x = checkx;
checkpoint.y = checky;
checkpoint.z = checkz;
checkpoint.X = checkx;
checkpoint.Y = checky;
checkpoint.Z = checkz;
if (newsec == NULL) newsec = P_PointInSector(checkx, checky);
basegroup = newsec->PortalGroup;
if (!check.inited) P_CollectConnectedGroups(basegroup, checkpoint, checkz + checkh, checkradius, checklist);
checkpoint.z = checkradius;
checkpoint.Z = checkradius;
Reset();
}
@ -1128,11 +1076,8 @@ bool FMultiBlockThingsIterator::Next(FMultiBlockThingsIterator::CheckResult *ite
if (thing != NULL)
{
item->thing = thing;
item->position = checkpoint + Displacements._f_getOffset(basegroup, thing->Sector->PortalGroup);
item->Position = checkpoint + Displacements.getOffset(basegroup, thing->Sector->PortalGroup);
item->portalflags = portalflags;
// same as above in floating point. This is here so that this stuff can be converted piece by piece.
item->Position = { FIXED2DBL(item->position.x), FIXED2DBL(item->position.y), FIXED2DBL(item->position.z) };
return true;
}
bool onlast = unsigned(index + 1) >= checklist.Size();
@ -1170,10 +1115,10 @@ bool FMultiBlockThingsIterator::Next(FMultiBlockThingsIterator::CheckResult *ite
void FMultiBlockThingsIterator::startIteratorForGroup(int group)
{
fixedvec2 offset = Displacements._f_getOffset(basegroup, group);
offset.x += checkpoint.x;
offset.y += checkpoint.y;
bbox.setBox(offset.x, offset.y, checkpoint.z);
DVector2 offset = Displacements.getOffset(basegroup, group);
offset.X += checkpoint.X;
offset.Y += checkpoint.Y;
bbox.setBox(offset.X, offset.Y, checkpoint.Z);
blockIterator.init(bbox);
}
@ -1220,17 +1165,17 @@ void FPathTraverse::AddLineIntercepts(int bx, int by)
{
int s1;
int s2;
fixed_t frac;
fdivline_t dl;
double frac;
divline_t dl;
// avoid precision problems with two routines
if ( trace.dx > FRACUNIT*16
|| trace.dy > FRACUNIT*16
|| trace.dx < -FRACUNIT*16
|| trace.dy < -FRACUNIT*16)
if ( trace.dx > 16
|| trace.dy > 16
|| trace.dx < -16
|| trace.dy < -16)
{
s1 = P_PointOnDivlineSide (ld->v1->fixX(), ld->v1->fixY(), &trace);
s2 = P_PointOnDivlineSide (ld->v2->fixX(), ld->v2->fixY(), &trace);
s1 = P_PointOnDivlineSideCompat (ld->v1->fX(), ld->v1->fY(), &trace);
s2 = P_PointOnDivlineSideCompat (ld->v2->fX(), ld->v2->fY(), &trace);
}
else
{
@ -1244,7 +1189,7 @@ void FPathTraverse::AddLineIntercepts(int bx, int by)
P_MakeDivline (ld, &dl);
frac = P_InterceptVector (&trace, &dl);
if (frac < startfrac || frac > FRACUNIT) continue; // behind source or beyond end point
if (frac < Startfrac || frac > 1.) continue; // behind source or beyond end point
intercept_t newintercept;
@ -1271,7 +1216,7 @@ void FPathTraverse::AddThingIntercepts (int bx, int by, FBlockThingsIterator &it
while ((thing = it.Next(compatible)))
{
int numfronts = 0;
fdivline_t line;
divline_t line;
int i;
@ -1287,69 +1232,69 @@ void FPathTraverse::AddThingIntercepts (int bx, int by, FBlockThingsIterator &it
switch (i)
{
case 0: // Top edge
line.x = thing->_f_X() + thing->_f_radius();
line.y = thing->_f_Y() + thing->_f_radius();
line.dx = -thing->_f_radius() * 2;
line.x = thing->X() + thing->radius;
line.y = thing->Y() + thing->radius;
line.dx = -thing->radius * 2;
line.dy = 0;
break;
case 1: // Right edge
line.x = thing->_f_X() + thing->_f_radius();
line.y = thing->_f_Y() - thing->_f_radius();
line.x = thing->X() + thing->radius;
line.y = thing->Y() - thing->radius;
line.dx = 0;
line.dy = thing->_f_radius() * 2;
line.dy = thing->radius * 2;
break;
case 2: // Bottom edge
line.x = thing->_f_X() - thing->_f_radius();
line.y = thing->_f_Y() - thing->_f_radius();
line.dx = thing->_f_radius() * 2;
line.x = thing->X() - thing->radius;
line.y = thing->Y() - thing->radius;
line.dx = thing->radius * 2;
line.dy = 0;
break;
case 3: // Left edge
line.x = thing->_f_X() - thing->_f_radius();
line.y = thing->_f_Y() + thing->_f_radius();
line.x = thing->X() - thing->radius;
line.y = thing->Y() + thing->radius;
line.dx = 0;
line.dy = thing->_f_radius() * -2;
line.dy = thing->radius * -2;
break;
}
// Check if this side is facing the trace origin
if (P_PointOnDivlineSidePrecise (trace.x, trace.y, &line) == 0)
if (P_PointOnDivlineSide (trace.x, trace.y, &line) == 0)
{
numfronts++;
// If it is, see if the trace crosses it
if (P_PointOnDivlineSidePrecise (line.x, line.y, &trace) !=
P_PointOnDivlineSidePrecise (line.x + line.dx, line.y + line.dy, &trace))
if (P_PointOnDivlineSide (line.x, line.y, &trace) !=
P_PointOnDivlineSide (line.x + line.dx, line.y + line.dy, &trace))
{
// It's a hit
fixed_t frac = P_InterceptVector (&trace, &line);
if (frac < startfrac)
double frac = P_InterceptVector (&trace, &line);
if (frac < Startfrac)
{ // behind source
if (startfrac > 0)
if (Startfrac > 0)
{
// check if the trace starts within this actor
switch (i)
{
case 0:
line.y -= 2 * thing->_f_radius();
line.y -= 2 * thing->radius;
break;
case 1:
line.x -= 2 * thing->_f_radius();
line.x -= 2 * thing->radius;
break;
case 2:
line.y += 2 * thing->_f_radius();
line.y += 2 * thing->radius;
break;
case 3:
line.x += 2 * thing->_f_radius();
line.x += 2 * thing->radius;
break;
}
fixed_t frac2 = P_InterceptVector(&trace, &line);
if (frac2 >= startfrac) goto addit;
double frac2 = P_InterceptVector(&trace, &line);
if (frac2 >= Startfrac) goto addit;
}
continue;
}
@ -1380,33 +1325,33 @@ void FPathTraverse::AddThingIntercepts (int bx, int by, FBlockThingsIterator &it
else
{
// Old code for compatibility purposes
fixed_t x1, y1, x2, y2;
double x1, y1, x2, y2;
int s1, s2;
fdivline_t dl;
fixed_t frac;
divline_t dl;
double frac;
bool tracepositive = (trace.dx ^ trace.dy)>0;
bool tracepositive = (trace.dx * trace.dy)>0;
// check a corner to corner crossection for hit
if (tracepositive)
{
x1 = thing->_f_X() - thing->_f_radius();
y1 = thing->_f_Y() + thing->_f_radius();
x1 = thing->X() - thing->radius;
y1 = thing->Y() + thing->radius;
x2 = thing->_f_X() + thing->_f_radius();
y2 = thing->_f_Y() - thing->_f_radius();
x2 = thing->X() + thing->radius;
y2 = thing->Y() - thing->radius;
}
else
{
x1 = thing->_f_X() - thing->_f_radius();
y1 = thing->_f_Y() - thing->_f_radius();
x1 = thing->X() - thing->radius;
y1 = thing->Y() - thing->radius;
x2 = thing->_f_X() + thing->_f_radius();
y2 = thing->_f_Y() + thing->_f_radius();
x2 = thing->X() + thing->radius;
y2 = thing->Y() + thing->radius;
}
s1 = P_PointOnDivlineSide (x1, y1, &trace);
s2 = P_PointOnDivlineSide (x2, y2, &trace);
s1 = P_PointOnDivlineSideCompat (x1, y1, &trace);
s2 = P_PointOnDivlineSideCompat (x2, y2, &trace);
if (s1 != s2)
{
@ -1417,7 +1362,7 @@ void FPathTraverse::AddThingIntercepts (int bx, int by, FBlockThingsIterator &it
frac = P_InterceptVector (&trace, &dl);
if (frac >= startfrac)
if (frac >= Startfrac)
{
intercept_t newintercept;
newintercept.frac = frac;
@ -1442,7 +1387,7 @@ intercept_t *FPathTraverse::Next()
{
intercept_t *in = NULL;
fixed_t dist = FIXED_MAX;
double dist = FLT_MAX;
for (unsigned scanpos = intercept_index; scanpos < intercepts.Size (); scanpos++)
{
intercept_t *scan = &intercepts[scanpos];
@ -1450,11 +1395,10 @@ intercept_t *FPathTraverse::Next()
{
dist = scan->frac;
in = scan;
in->Frac = FIXED2FLOAT(in->frac);
}
}
if (dist > FRACUNIT || in == NULL) return NULL; // checked everything in range
if (dist > 1. || in == NULL) return NULL; // checked everything in range
in->done = true;
return in;
}
@ -1466,19 +1410,12 @@ intercept_t *FPathTraverse::Next()
//
//===========================================================================
void FPathTraverse::init (fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2, int flags, fixed_t startfrac)
void FPathTraverse::init(double x1, double y1, double x2, double y2, int flags, double startfrac)
{
fixed_t xt1, xt2;
fixed_t yt1, yt2;
long long _x1, _x2, _y1, _y2;
fixed_t xstep;
fixed_t ystep;
fixed_t partialx, partialy;
fixed_t xintercept;
fixed_t yintercept;
double xt1, yt1, xt2, yt2;
double xstep, ystep;
double partialx, partialy;
double xintercept, yintercept;
int mapx;
int mapy;
@ -1502,8 +1439,8 @@ void FPathTraverse::init (fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2, int fl
}
if (startfrac > 0)
{
fixed_t startdx = FixedMul(trace.dx, startfrac);
fixed_t startdy = FixedMul(trace.dy, startfrac);
double startdx = trace.dx * startfrac;
double startdy = trace.dy * startfrac;
x1 += startdx;
y1 += startdy;
@ -1514,110 +1451,95 @@ void FPathTraverse::init (fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2, int fl
validcount++;
intercept_index = intercepts.Size();
this->startfrac = startfrac;
fixed_t _f_bmaporgx = FLOAT2FIXED(bmaporgx);
fixed_t _f_bmaporgy = FLOAT2FIXED(bmaporgy);
if ( ((x1-_f_bmaporgx)&(MAPBLOCKSIZE-1)) == 0)
x1 += FRACUNIT; // don't side exactly on a line
if ( ((y1-_f_bmaporgy)&(MAPBLOCKSIZE-1)) == 0)
y1 += FRACUNIT; // don't side exactly on a line
_x1 = (long long)x1 - _f_bmaporgx;
_y1 = (long long)y1 - _f_bmaporgy;
x1 -= _f_bmaporgx;
y1 -= _f_bmaporgy;
xt1 = int(_x1 >> MAPBLOCKSHIFT);
yt1 = int(_y1 >> MAPBLOCKSHIFT);
Startfrac = startfrac;
if (flags & PT_DELTA)
{
_x2 = _x1 + x2;
_y2 = _y1 + y2;
xt2 = int(_x2 >> MAPBLOCKSHIFT);
yt2 = int(_y2 >> MAPBLOCKSHIFT);
x2 = (int)_x2;
y2 = (int)_y2;
}
else
{
_x2 = (long long)x2 - _f_bmaporgx;
_y2 = (long long)y2 - _f_bmaporgy;
x2 -= _f_bmaporgx;
y2 -= _f_bmaporgy;
xt2 = int(_x2 >> MAPBLOCKSHIFT);
yt2 = int(_y2 >> MAPBLOCKSHIFT);
x2 += x1;
y2 += y2;
}
if (xt2 > xt1)
x1 -= bmaporgx;
y1 -= bmaporgy;
xt1 = x1 / MAPBLOCKUNITS;
yt1 = y1 / MAPBLOCKUNITS;
x2 -= bmaporgx;
y2 -= bmaporgy;
xt2 = x2 / MAPBLOCKUNITS;
yt2 = y2 / MAPBLOCKUNITS;
mapx = int(xt1);
mapy = int(yt1);
int mapex = int(xt2);
int mapey = int(yt2);
if (mapex > mapx)
{
mapxstep = 1;
partialx = FRACUNIT - ((x1>>MAPBTOFRAC)&(FRACUNIT-1));
ystep = FixedDiv (y2-y1,abs(x2-x1));
partialx = xs_CeilToInt(xt1) - xt1;
ystep = (y2 - y1) / fabs(x2 - x1);
}
else if (xt2 < xt1)
else if (mapex < mapx)
{
mapxstep = -1;
partialx = (x1>>MAPBTOFRAC)&(FRACUNIT-1);
ystep = FixedDiv (y2-y1,abs(x2-x1));
partialx = xt1 - xs_FloorToInt(xt1);
ystep = (y2 - y1) / fabs(x2 - x1);
}
else
{
mapxstep = 0;
partialx = FRACUNIT;
ystep = 256*FRACUNIT;
partialx = 1.;
ystep = 256;
}
yintercept = int(_y1>>MAPBTOFRAC) + FixedMul (partialx, ystep);
yintercept = yt1 + partialx * ystep;
if (yt2 > yt1)
if (mapey > mapy)
{
mapystep = 1;
partialy = FRACUNIT - ((y1>>MAPBTOFRAC)&(FRACUNIT-1));
xstep = FixedDiv (x2-x1,abs(y2-y1));
partialy = xs_CeilToInt(yt1) - yt1;
xstep = (x2 - x1) / fabs(y2 - y1);
}
else if (yt2 < yt1)
else if (mapey < mapy)
{
mapystep = -1;
partialy = (y1>>MAPBTOFRAC)&(FRACUNIT-1);
xstep = FixedDiv (x2-x1,abs(y2-y1));
partialy = yt1 - xs_FloorToInt(yt1);
xstep = (x2 - x1) / fabs(y2 - y1);
}
else
{
mapystep = 0;
partialy = FRACUNIT;
xstep = 256*FRACUNIT;
partialy = 1;
xstep = 256;
}
xintercept = int(_x1>>MAPBTOFRAC) + FixedMul (partialy, xstep);
xintercept = xt1 + partialy * xstep;
// [RH] Fix for traces that pass only through blockmap corners. In that case,
// xintercept and yintercept can both be set ahead of mapx and mapy, so the
// for loop would never advance anywhere.
if (abs(xstep) == FRACUNIT && abs(ystep) == FRACUNIT)
if (fabs(xstep) == 1. && fabs(ystep) == 1.)
{
if (ystep < 0)
{
partialx = FRACUNIT - partialx;
partialx = 1. - partialx;
}
if (xstep < 0)
{
partialy = FRACUNIT - partialy;
partialy = 1. - partialy;
}
if (partialx == partialy)
{
xintercept = xt1 << FRACBITS;
yintercept = yt1 << FRACBITS;
xintercept = xt1;
yintercept = yt1;
}
}
// Step through map blocks.
// Count is present to prevent a round off error
// from skipping the break statement.
mapx = xt1;
mapy = yt1;
bool compatible = (flags & PT_COMPATIBLE) && (i_compatflags & COMPATF_HITSCAN);
@ -1641,7 +1563,7 @@ void FPathTraverse::init (fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2, int fl
}
// [RH] Handle corner cases properly instead of pretending they don't exist.
switch ((((yintercept >> FRACBITS) == mapy) << 1) | ((xintercept >> FRACBITS) == mapx))
switch (((int(yintercept) == mapy) << 1) | (int(xintercept) == mapx))
{
case 0: // neither xintercept nor yintercept match!
count = 100; // Stop traversing, because somebody screwed up.
@ -1687,10 +1609,6 @@ void FPathTraverse::init (fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2, int fl
break;
}
}
ftrace.dx = FIXED2DBL(trace.dx);
ftrace.dy = FIXED2DBL(trace.dy);
ftrace.x = FIXED2DBL(trace.x);
ftrace.y = FIXED2DBL(trace.y);
}
//===========================================================================
@ -1704,10 +1622,10 @@ int FPathTraverse::PortalRelocate(intercept_t *in, int flags, DVector3 *optpos)
if (!in->isaline || !in->d.line->isLinePortal()) return false;
if (P_PointOnLineSidePrecise(trace.x, trace.y, in->d.line) == 1) return false;
fixed_t hitx = trace.x;
fixed_t hity = trace.y;
fixed_t endx = trace.x + trace.dx;
fixed_t endy = trace.y + trace.dy;
double hitx = trace.x;
double hity = trace.y;
double endx = trace.x + trace.dx;
double endy = trace.y + trace.dy;
P_TranslatePortalXY(in->d.line, hitx, hity);
P_TranslatePortalXY(in->d.line, endx, endy);
@ -1873,12 +1791,12 @@ static AActor *RoughBlockCheck (AActor *mo, int index, void *param)
//
//==========================================================================
static int R_PointOnSideSlow(fixed_t x, fixed_t y, node_t *node)
static int R_PointOnSideSlow(double xx, double yy, node_t *node)
{
// [RH] This might have been faster than two multiplies and an
// add on a 386/486, but it certainly isn't on anything newer than that.
fixed_t dx;
fixed_t dy;
auto x = FloatToFixed(xx);
auto y = FloatToFixed(yy);
double left;
double right;
@ -1897,8 +1815,8 @@ static int R_PointOnSideSlow(fixed_t x, fixed_t y, node_t *node)
return node->dx > 0;
}
dx = (x - node->x);
dy = (y - node->y);
auto dx = (x - node->x);
auto dy = (y - node->y);
// Try to quickly decide by looking at sign bits.
if ((node->dy ^ node->dx ^ dx ^ dy) & 0x80000000)
@ -1912,6 +1830,7 @@ static int R_PointOnSideSlow(fixed_t x, fixed_t y, node_t *node)
}
// we must use doubles here because the fixed point code will produce errors due to loss of precision for extremely short linedefs.
// Note that this function is used for all map spawned actors and not just a compatibility fallback!
left = (double)node->dy * (double)dx;
right = (double)dy * (double)node->dx;
@ -1932,24 +1851,20 @@ static int R_PointOnSideSlow(fixed_t x, fixed_t y, node_t *node)
//
//===========================================================================
int P_VanillaPointOnLineSide(fixed_t x, fixed_t y, const line_t* line)
int P_VanillaPointOnLineSide(double x, double y, const line_t* line)
{
fixed_t dx;
fixed_t dy;
fixed_t left;
fixed_t right;
DVector2 delta = line->Delta();
if (delta.X == 0)
{
if (x <= line->v1->fixX())
if (x <= line->v1->fX())
return delta.Y > 0;
return delta.Y < 0;
}
if (delta.Y == 0)
{
if (y <= line->v1->fixY())
if (y <= line->v1->fY())
return delta.X < 0;
return delta.X > 0;
@ -1957,13 +1872,13 @@ int P_VanillaPointOnLineSide(fixed_t x, fixed_t y, const line_t* line)
// Note: This cannot really be converted to floating point
// without breaking the intended use of this function
// (i.e. to emulate the horrible imprecision of the entire methpd)
// (i.e. to emulate the horrible imprecision of the entire method)
dx = (x - line->v1->fixX());
dy = (y - line->v1->fixY());
auto dx = FloatToFixed(x - line->v1->fX());
auto dy = FloatToFixed(y - line->v1->fY());
left = FixedMul ( int(delta.Y * 256) , dx );
right = FixedMul ( dy , int(delta.X * 256) );
auto left = MulScale16( int(delta.Y * 256) , dx );
auto right = MulScale16( dy , int(delta.X * 256) );
if (right < left)
return 0; // front side
@ -1973,16 +1888,18 @@ int P_VanillaPointOnLineSide(fixed_t x, fixed_t y, const line_t* line)
//===========================================================================
//
// P_VanillaPointOnDivlineSide
// P_PointOnDivlineSide() from the initial Doom source code release
// P_PointOnDivlineSideCompat() from the initial Doom source code release
//
//===========================================================================
int P_VanillaPointOnDivlineSide(fixed_t x, fixed_t y, const fdivline_t* line)
int P_VanillaPointOnDivlineSide(double x, double y, const divline_t* line)
{
fixed_t dx;
fixed_t dy;
fixed_t left;
fixed_t right;
int dx;
int dy;
int left;
int right;
int ldx;
int ldy;
if (!line->dx)
{
@ -1999,26 +1916,37 @@ int P_VanillaPointOnDivlineSide(fixed_t x, fixed_t y, const fdivline_t* line)
return line->dx > 0;
}
dx = (x - line->x);
dy = (y - line->y);
// This is supposed to be compatible so the rest needs to be done
// with the same broken fixed point checks as the original
dx = FloatToFixed(x - line->x);
dy = FloatToFixed(y - line->y);
ldx = FloatToFixed(line->dx);
ldy = FloatToFixed(line->dy);
// try to quickly decide by looking at sign bits
if ( (line->dy ^ line->dx ^ dx ^ dy)&0x80000000 )
if ( (ldy ^ ldx ^ dx ^ dy)&0x80000000 )
{
if ( (line->dy ^ dx) & 0x80000000 )
if ( (ldy ^ dx) & 0x80000000 )
return 1; // (left is negative)
return 0;
}
left = FixedMul ( line->dy>>8, dx>>8 );
right = FixedMul ( dy>>8 , line->dx>>8 );
left = MulScale16( ldy>>8, dx>>8 );
right = MulScale16( dy>>8 , ldx>>8 );
if (right < left)
return 0; // front side
return 1; // back side
}
sector_t *P_PointInSectorBuggy(fixed_t x, fixed_t y)
//==========================================================================
//
// Use buggy PointOnSide and fix actors that lie on
// lines to compensate for some IWAD maps.
//
//==========================================================================
sector_t *P_PointInSectorBuggy(double x, double y)
{
// single subsector is a special case
if (numgamenodes == 0)

View file

@ -8,14 +8,6 @@
extern int validcount;
struct fdivline_t
{
fixed_t x;
fixed_t y;
fixed_t dx;
fixed_t dy;
};
struct divline_t
{
double x;
@ -26,8 +18,7 @@ struct divline_t
struct intercept_t
{
double Frac;
fixed_t frac; // along trace line
double frac;
bool isaline;
bool done;
union {
@ -45,74 +36,49 @@ struct intercept_t
//
//==========================================================================
const double POL_Epsilon = -1. / 65536.;
inline int P_PointOnLineSide (fixed_t x, fixed_t y, const line_t *line)
{
extern int P_VanillaPointOnLineSide(fixed_t x, fixed_t y, const line_t* line);
return i_compatflags2 & COMPATF2_POINTONLINE
? P_VanillaPointOnLineSide(x, y, line)
: DMulScale32 (y-line->v1->fixY(), line->fixDx(), line->v1->fixX()-x, line->fixDy()) > 0;
}
inline int P_PointOnLineSidePrecise (fixed_t x, fixed_t y, const line_t *line)
{
return DMulScale32 (y-line->v1->fixY(), line->fixDx(), line->v1->fixX()-x, line->fixDy()) > 0;
}
inline int P_PointOnLineSide(double x, double y, const line_t *line)
{
return P_PointOnLineSide(FLOAT2FIXED(x), FLOAT2FIXED(y), line);
}
inline int P_PointOnLineSide(const DVector2 & p, const line_t *line)
{
return P_PointOnLineSide(FLOAT2FIXED(p.X), FLOAT2FIXED(p.Y), line);
}
inline int P_PointOnLineSidePrecise(double x, double y, const line_t *line)
{
return (y - line->v1->fY()) * line->Delta().X + (line->v1->fX() - x) * line->Delta().Y > POL_Epsilon ;
return (y - line->v1->fY()) * line->Delta().X + (line->v1->fX() - x) * line->Delta().Y > -EQUAL_EPSILON;
}
inline int P_PointOnLineSidePrecise(const DVector2 &pt, const line_t *line)
{
return (pt.Y - line->v1->fY()) * line->Delta().X + (line->v1->fX() - pt.X) * line->Delta().Y > POL_Epsilon;
return (pt.Y - line->v1->fY()) * line->Delta().X + (line->v1->fX() - pt.X) * line->Delta().Y > -EQUAL_EPSILON;
}
inline int P_PointOnLineSide (double x, double y, const line_t *line)
{
extern int P_VanillaPointOnLineSide(double x, double y, const line_t* line);
return i_compatflags2 & COMPATF2_POINTONLINE
? P_VanillaPointOnLineSide(x, y, line) : P_PointOnLineSidePrecise(x, y, line);
}
inline int P_PointOnLineSide(const DVector2 & p, const line_t *line)
{
return P_PointOnLineSide(p.X, p.Y, line);
}
//==========================================================================
//
// P_PointOnDivlineSide
// P_PointOnDivlineSideCompat
//
// Same as P_PointOnLineSide except it uses divlines
// [RH] inlined, stripped down, and made more precise
//
//==========================================================================
inline int P_PointOnDivlineSide (fixed_t x, fixed_t y, const fdivline_t *line)
inline int P_PointOnDivlineSide(double x, double y, const divline_t *line)
{
extern int P_VanillaPointOnDivlineSide(fixed_t x, fixed_t y, const fdivline_t* line);
return (i_compatflags2 & COMPATF2_POINTONLINE)
? P_VanillaPointOnDivlineSide(x, y, line)
: (DMulScale32 (y-line->y, line->dx, line->x-x, line->dy) > 0);
return (y - line->y) * line->dx + (line->x - x) * line->dy > -EQUAL_EPSILON;
}
inline int P_PointOnDivlineSidePrecise (fixed_t x, fixed_t y, const fdivline_t *line)
inline int P_PointOnDivlineSide(const DVector2 &pos, const divline_t *line)
{
return DMulScale32 (y-line->y, line->dx, line->x-x, line->dy) > 0;
}
inline int P_PointOnDivlineSidePrecise(double x, double y, const divline_t *line)
{
return (y - line->y) * line->dx + (line->x - x) * line->dy > 0;
}
inline int P_PointOnDivlineSidePrecise(const DVector2 &pos, const divline_t *line)
{
return (pos.Y - line->y) * line->dx + (line->x - pos.X) * line->dy > 0;
return (pos.Y - line->y) * line->dx + (line->x - pos.X) * line->dy > -EQUAL_EPSILON;
}
//==========================================================================
@ -121,14 +87,6 @@ inline int P_PointOnDivlineSidePrecise(const DVector2 &pos, const divline_t *lin
//
//==========================================================================
inline void P_MakeDivline (const line_t *li, fdivline_t *dl)
{
dl->x = li->v1->fixX();
dl->y = li->v1->fixY();
dl->dx = li->fixDx();
dl->dy = li->fixDy();
}
inline void P_MakeDivline(const line_t *li, divline_t *dl)
{
dl->x = li->v1->fX();
@ -163,15 +121,6 @@ inline void P_LineOpening(FLineOpening &open, AActor *thing, const line_t *lined
P_LineOpening(open, thing, linedef, xy, reinterpret_cast<const DVector2*>(ref), flags);
}
inline void P_LineOpening(FLineOpening &open, AActor *thing, const line_t *linedef, fixed_t x, fixed_t y, fixed_t refx = FIXED_MIN, fixed_t refy = 0, int flags = 0)
{
P_LineOpening(open, thing, linedef, DVector2(FIXED2DBL(x), FIXED2DBL(y)), &DVector2(FIXED2DBL(refx), FIXED2DBL(refy)), flags);
}
inline void P_LineOpening(FLineOpening &open, AActor *thing, const line_t *linedef, fixedvec2 xy, fixed_t refx = FIXED_MIN, fixed_t refy = 0, int flags = 0)
{
P_LineOpening(open, thing, linedef, xy.x, xy.y, refx, refy, flags);
}
class FBoundingBox;
struct polyblock_t;
@ -277,8 +226,8 @@ public:
class FMultiBlockLinesIterator
{
FPortalGroupArray &checklist;
fixedvec3 checkpoint;
fixedvec2 offset;
DVector3 checkpoint;
DVector2 offset;
sector_t *startsector;
sector_t *cursector;
short basegroup;
@ -289,8 +238,8 @@ class FMultiBlockLinesIterator
FBlockLinesIterator blockIterator;
FBoundingBox bbox;
bool GoUp(fixed_t x, fixed_t y);
bool GoDown(fixed_t x, fixed_t y);
bool GoUp(double x, double y);
bool GoDown(double x, double y);
void startIteratorForGroup(int group);
public:
@ -298,18 +247,12 @@ public:
struct CheckResult
{
line_t *line;
fixedvec3 position;
DVector3 Position;
int portalflags;
};
FMultiBlockLinesIterator(FPortalGroupArray &check, AActor *origin, fixed_t checkradius = -1);
FMultiBlockLinesIterator(FPortalGroupArray &check, fixed_t checkx, fixed_t checky, fixed_t checkz, fixed_t checkh, fixed_t checkradius, sector_t *newsec);
FMultiBlockLinesIterator(FPortalGroupArray &check, double checkx, double checky, double checkz, double checkh, double checkradius, sector_t *newsec)
: FMultiBlockLinesIterator(check, FLOAT2FIXED(checkx), FLOAT2FIXED(checky), FLOAT2FIXED(checkz), FLOAT2FIXED(checkh), FLOAT2FIXED(checkradius), newsec)
{
}
FMultiBlockLinesIterator(FPortalGroupArray &check, AActor *origin, double checkradius = -1);
FMultiBlockLinesIterator(FPortalGroupArray &check, double checkx, double checky, double checkz, double checkh, double checkradius, sector_t *newsec);
bool Next(CheckResult *item);
void Reset();
@ -376,7 +319,7 @@ public:
class FMultiBlockThingsIterator
{
FPortalGroupArray &checklist;
fixedvec3 checkpoint;
DVector3 checkpoint;
short basegroup;
short portalflags;
short index;
@ -390,17 +333,12 @@ public:
struct CheckResult
{
AActor *thing;
fixedvec3 position; // keep these both until the fixed version can be removed.
DVector3 Position;
int portalflags;
};
FMultiBlockThingsIterator(FPortalGroupArray &check, AActor *origin, fixed_t checkradius = -1, bool ignorerestricted = false);
FMultiBlockThingsIterator(FPortalGroupArray &check, fixed_t checkx, fixed_t checky, fixed_t checkz, fixed_t checkh, fixed_t checkradius, bool ignorerestricted, sector_t *newsec);
FMultiBlockThingsIterator(FPortalGroupArray &check, double checkx, double checky, double checkz, double checkh, double checkradius, bool ignorerestricted, sector_t *newsec)
: FMultiBlockThingsIterator(check, FLOAT2FIXED(checkx), FLOAT2FIXED(checky), FLOAT2FIXED(checkz), FLOAT2FIXED(checkh), FLOAT2FIXED(checkradius), ignorerestricted, newsec)
{
}
FMultiBlockThingsIterator(FPortalGroupArray &check, AActor *origin, double checkradius = -1, bool ignorerestricted = false);
FMultiBlockThingsIterator(FPortalGroupArray &check, double checkx, double checky, double checkz, double checkh, double checkradius, bool ignorerestricted, sector_t *newsec);
bool Next(CheckResult *item);
void Reset();
const FBoundingBox &Box() const
@ -416,9 +354,8 @@ class FPathTraverse
protected:
static TArray<intercept_t> intercepts;
divline_t ftrace;
fdivline_t trace;
fixed_t startfrac;
divline_t trace;
double Startfrac;
unsigned int intercept_index;
unsigned int intercept_count;
unsigned int count;
@ -430,34 +367,21 @@ public:
intercept_t *Next();
FPathTraverse(fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2, int flags, fixed_t startfrac = 0)
FPathTraverse(double x1, double y1, double x2, double y2, int flags, double startfrac = 0)
{
init(x1, y1, x2, y2, flags, startfrac);
}
FPathTraverse(double x1, double y1, double x2, double y2, int flags, double startfrac = 0)
{
init(FLOAT2FIXED(x1), FLOAT2FIXED(y1), FLOAT2FIXED(x2), FLOAT2FIXED(y2), flags, FLOAT2FIXED(startfrac));
}
void init(fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2, int flags, fixed_t startfrac = 0);
void init(double x1, double y1, double x2, double y2, int flags, double startfrac = 0);
int PortalRelocate(intercept_t *in, int flags, DVector3 *optpos = NULL);
virtual ~FPathTraverse();
const fdivline_t &_f_Trace() const { return trace; }
const divline_t &Trace() const { return ftrace; }
const divline_t &Trace() const { return trace; }
inline fixedvec2 _f_InterceptPoint(const intercept_t *in)
{
return
{
trace.x + FixedMul(trace.dx, in->frac),
trace.y + FixedMul(trace.dy, in->frac)
};
}
inline DVector2 InterceptPoint(const intercept_t *in)
{
return
{
FIXED2DBL(trace.x + FixedMul(trace.dx, in->frac)),
FIXED2DBL(trace.y + FixedMul(trace.dy, in->frac))
trace.x + trace.dx * in->frac,
trace.y + trace.dy * in->frac
};
}
@ -480,18 +404,13 @@ public:
}
};
//
// P_MAPUTL
//
typedef bool(*traverser_t) (intercept_t *in);
fixed_t P_AproxDistance (fixed_t dx, fixed_t dy);
fixed_t P_InterceptVector (const fdivline_t *v2, const fdivline_t *v1);
int P_AproxDistance (int dx, int dy);
double P_InterceptVector(const divline_t *v2, const divline_t *v1);
#define PT_ADDLINES 1

View file

@ -1401,9 +1401,9 @@ void P_ExplodeMissile (AActor *mo, line_t *line, AActor *target)
den = line->Delta().LengthSquared();
if (den != 0)
{
frac = clamp<double>((mo->Pos() - line->V1()) | line->Delta(), 0, den) / den;
frac = clamp<double>((mo->Pos().XY() - line->v1->fPos()) | line->Delta(), 0, den) / den;
linepos = DVector3(line->V1() + line->Delta() * frac, pos.Z);
linepos = DVector3(line->v1->fPos() + line->Delta() * frac, pos.Z);
F3DFloor * ffloor=NULL;
if (line->sidedef[side^1] != NULL)

View file

@ -232,7 +232,7 @@ void DPusher::Tick ()
// point pusher. Crosses sectors, so use blockmap.
FPortalGroupArray check(FPortalGroupArray::PGA_NoSectorPortals); // no sector portals because this thing is utterly z-unaware.
FMultiBlockThingsIterator it(check, m_Source, FLOAT2FIXED(m_Radius));
FMultiBlockThingsIterator it(check, m_Source, m_Radius);
FMultiBlockThingsIterator::CheckResult cres;

View file

@ -714,10 +714,10 @@ void sector_t::SetFade(int r, int g, int b)
//
//===========================================================================
void sector_t::ClosestPoint(fixed_t fx, fixed_t fy, fixed_t &ox, fixed_t &oy) const
void sector_t::ClosestPoint(const DVector2 &in, DVector2 &out) const
{
int i;
double x = fx, y = fy;
double x = in.X, y = in.Y;
double bestdist = HUGE_VAL;
double bestx = 0, besty = 0;
@ -725,34 +725,34 @@ void sector_t::ClosestPoint(fixed_t fx, fixed_t fy, fixed_t &ox, fixed_t &oy) co
{
vertex_t *v1 = lines[i]->v1;
vertex_t *v2 = lines[i]->v2;
double a = v2->fixX() - v1->fixX();
double b = v2->fixY() - v1->fixY();
double a = v2->fX() - v1->fX();
double b = v2->fY() - v1->fY();
double den = a*a + b*b;
double ix, iy, dist;
if (den == 0)
{ // Line is actually a point!
ix = v1->fixX();
iy = v1->fixY();
ix = v1->fX();
iy = v1->fY();
}
else
{
double num = (x - v1->fixX()) * a + (y - v1->fixY()) * b;
double num = (x - v1->fX()) * a + (y - v1->fY()) * b;
double u = num / den;
if (u <= 0)
{
ix = v1->fixX();
iy = v1->fixY();
ix = v1->fX();
iy = v1->fY();
}
else if (u >= 1)
{
ix = v2->fixX();
iy = v2->fixY();
ix = v2->fX();
iy = v2->fY();
}
else
{
ix = v1->fixX() + u * a;
iy = v1->fixY() + u * b;
ix = v1->fX() + u * a;
iy = v1->fY() + u * b;
}
}
a = (ix - x);
@ -765,8 +765,7 @@ void sector_t::ClosestPoint(fixed_t fx, fixed_t fy, fixed_t &ox, fixed_t &oy) co
besty = iy;
}
}
ox = fixed_t(bestx);
oy = fixed_t(besty);
out = { bestx, besty };
}

View file

@ -3208,14 +3208,14 @@ static void P_GroupLines (bool buildmap)
for (j = 0; j < sector->linecount; ++j)
{
li = sector->lines[j];
bbox.AddToBox (li->v1->fixX(), li->v1->fixY());
bbox.AddToBox (li->v2->fixX(), li->v2->fixY());
bbox.AddToBox (li->v1->fPos());
bbox.AddToBox (li->v2->fPos());
}
}
// set the center to the middle of the bounding box
sector->centerspot.X = FIXED2DBL(bbox.Right()/2 + bbox.Left()/2);
sector->centerspot.Y = FIXED2DBL(bbox.Top()/2 + bbox.Bottom()/2);
sector->centerspot.X = (bbox.Right() + bbox.Left()/2);
sector->centerspot.Y = (bbox.Top() + bbox.Bottom()/2);
// For triangular sectors the above does not calculate good points unless the longest of the triangle's lines is perfectly horizontal and vertical
if (sector->linecount == 3)
@ -3917,8 +3917,8 @@ void P_SetupLevel (const char *lumpname, int position)
seg_t * seg=&segs[i];
if (seg->backsector == seg->frontsector && seg->linedef)
{
fixed_t d1=P_AproxDistance(seg->v1->fixX()-seg->linedef->v1->fixX(),seg->v1->fixY()-seg->linedef->v1->fixY());
fixed_t d2=P_AproxDistance(seg->v2->fixX()-seg->linedef->v1->fixX(),seg->v2->fixY()-seg->linedef->v1->fixY());
double d1 = (seg->v1->fPos() - seg->linedef->v1->fPos()).LengthSquared();
double d2 = (seg->v2->fPos() - seg->linedef->v1->fPos()).LengthSquared();
if (d2<d1) // backside
{

View file

@ -207,8 +207,8 @@ bool SightCheck::PTR_SightTraverse (intercept_t *in)
if ((i_compatflags & COMPATF_TRACE) && li->frontsector == li->backsector)
return true;
double trX = Trace.x + Trace.dx * in->Frac;
double trY = Trace.y + Trace.dy * in->Frac;
double trX = Trace.x + Trace.dx * in->frac;
double trY = Trace.y + Trace.dy * in->frac;
P_SightOpening (open, li, trX, trY);
FLinePortal *lport = li->getPortal();
@ -219,7 +219,7 @@ bool SightCheck::PTR_SightTraverse (intercept_t *in)
// check bottom
if (open.bottom > LINEOPEN_MIN)
{
slope = (open.bottom - sightstart.Z) / in->Frac;
slope = (open.bottom - sightstart.Z) / in->frac;
if (slope > bottomslope)
bottomslope = slope;
}
@ -227,7 +227,7 @@ bool SightCheck::PTR_SightTraverse (intercept_t *in)
// check top
if (open.top < LINEOPEN_MAX)
{
slope = (open.top - sightstart.Z) / in->Frac;
slope = (open.top - sightstart.Z) / in->frac;
if (slope < topslope)
topslope = slope;
}
@ -251,16 +251,16 @@ bool SightCheck::PTR_SightTraverse (intercept_t *in)
if (portaldir != sector_t::floor && (open.portalflags & SO_TOPBACK) && !(open.portalflags & SO_TOPFRONT))
{
portals.Push({ in->Frac, topslope, bottomslope, sector_t::ceiling, backsec->SkyBoxes[sector_t::ceiling]->Sector->PortalGroup });
portals.Push({ in->frac, topslope, bottomslope, sector_t::ceiling, backsec->SkyBoxes[sector_t::ceiling]->Sector->PortalGroup });
}
if (portaldir != sector_t::ceiling && (open.portalflags & SO_BOTTOMBACK) && !(open.portalflags & SO_BOTTOMFRONT))
{
portals.Push({ in->Frac, topslope, bottomslope, sector_t::floor, backsec->SkyBoxes[sector_t::floor]->Sector->PortalGroup });
portals.Push({ in->frac, topslope, bottomslope, sector_t::floor, backsec->SkyBoxes[sector_t::floor]->Sector->PortalGroup });
}
}
if (lport)
{
portals.Push({ in->Frac, topslope, bottomslope, portaldir, lport->mDestination->frontsector->PortalGroup });
portals.Push({ in->frac, topslope, bottomslope, portaldir, lport->mDestination->frontsector->PortalGroup });
return false;
}
@ -278,8 +278,8 @@ bool SightCheck::PTR_SightTraverse (intercept_t *in)
sector_t * s=i==1? li->frontsector:li->backsector;
double highslope, lowslope;
double topz= topslope * in->Frac + sightstart.Z;
double bottomz= bottomslope * in->Frac + sightstart.Z;
double topz= topslope * in->frac + sightstart.Z;
double bottomz= bottomslope * in->frac + sightstart.Z;
for (auto rover : s->e->XFloor.ffloors)
{
@ -289,8 +289,8 @@ bool SightCheck::PTR_SightTraverse (intercept_t *in)
double ff_bottom = rover->bottom.plane->ZatPoint(trX, trY);
double ff_top = rover->top.plane->ZatPoint(trX, trY);
highslope = (ff_top - sightstart.Z) / in->Frac;
lowslope = (ff_bottom - sightstart.Z) / in->Frac;
highslope = (ff_top - sightstart.Z) / in->frac;
lowslope = (ff_bottom - sightstart.Z) / in->frac;
if (highslope >= topslope)
{
@ -350,8 +350,8 @@ bool SightCheck::PTR_SightTraverse (intercept_t *in)
}
else lastsector=NULL; // don't need it if there are no 3D-floors
Lastztop = (topslope * in->Frac) + sightstart.Z;
Lastzbottom = (bottomslope * in->Frac) + sightstart.Z;
Lastztop = (topslope * in->frac) + sightstart.Z;
Lastzbottom = (bottomslope * in->frac) + sightstart.Z;
return true; // keep going
}
@ -375,14 +375,14 @@ bool SightCheck::P_SightCheckLine (line_t *ld)
return true;
}
ld->validcount = validcount;
if (P_PointOnDivlineSidePrecise (ld->V1(), &Trace) ==
P_PointOnDivlineSidePrecise (ld->V2(), &Trace))
if (P_PointOnDivlineSide (ld->v1->fPos(), &Trace) ==
P_PointOnDivlineSide (ld->v2->fPos(), &Trace))
{
return true; // line isn't crossed
}
P_MakeDivline (ld, &dl);
if (P_PointOnDivlineSidePrecise (Trace.x, Trace.y, &dl) ==
P_PointOnDivlineSidePrecise (Trace.x+Trace.dx, Trace.y+Trace.dy, &dl))
if (P_PointOnDivlineSide (Trace.x, Trace.y, &dl) ==
P_PointOnDivlineSide (Trace.x+Trace.dx, Trace.y+Trace.dy, &dl))
{
return true; // line isn't crossed
}
@ -514,10 +514,10 @@ bool SightCheck::P_SightTraverseIntercepts ()
{
scan = &intercepts[scanpos];
P_MakeDivline (scan->d.line, &dl);
scan->Frac = P_InterceptVector (&Trace, &dl);
if (scan->Frac < Startfrac)
scan->frac = P_InterceptVector (&Trace, &dl);
if (scan->frac < Startfrac)
{
scan->Frac = INT_MAX;
scan->frac = INT_MAX;
count--;
}
}
@ -534,9 +534,9 @@ bool SightCheck::P_SightTraverseIntercepts ()
for (scanpos = 0; scanpos < intercepts.Size (); scanpos++)
{
scan = &intercepts[scanpos];
if (scan->Frac < dist)
if (scan->frac < dist)
{
dist = scan->Frac;
dist = scan->frac;
in = scan;
}
}
@ -545,7 +545,7 @@ bool SightCheck::P_SightTraverseIntercepts ()
{
if (!PTR_SightTraverse (in))
return false; // don't bother going farther
in->Frac = INT_MAX;
in->frac = INT_MAX;
}
}

View file

@ -69,7 +69,6 @@ typedef enum
// Factor to scale scrolling effect into mobj-carrying properties = 3/32.
// (This is so scrolling floors and objects on them can move at same speed.)
enum { _f_CARRYFACTOR = (3*FRACUNIT >> 5) };
const double CARRYFACTOR = 3 / 32.;
// Define values for map objects

View file

@ -291,7 +291,7 @@ bool P_ChangeSwitchTexture (side_t *side, int useAgain, BYTE special, bool *ques
// which wasn't necessarily anywhere near the switch if it was
// facing a big sector (and which wasn't necessarily for the
// button just activated, either).
DVector2 pt(side->linedef->V1() + side->linedef->Delta() / 2);
DVector2 pt(side->linedef->v1->fPos() + side->linedef->Delta() / 2);
bool playsound;
side->SetTexture(texture, Switch->frames[0].Texture);

View file

@ -438,7 +438,7 @@ bool EV_SilentLineTeleport (line_t *line, int side, AActor *thing, int id, INTBO
}
else
{
double num = (thing->Pos().XY() - line->V1()) | line->Delta();
double num = (thing->Pos().XY() - line->v1->fPos()) | line->Delta();
if (num <= 0)
{
pos = 0;
@ -451,7 +451,7 @@ bool EV_SilentLineTeleport (line_t *line, int side, AActor *thing, int id, INTBO
{
pos = num / den;
}
npos = thing->Pos().XY() - line->V1() - line->Delta() * pos;
npos = thing->Pos().XY() - line->v1->fPos() - line->Delta() * pos;
}
// Get the angle between the two linedefs, for rotating
@ -476,7 +476,7 @@ bool EV_SilentLineTeleport (line_t *line, int side, AActor *thing, int id, INTBO
p.Y = npos.Y*c + npos.X*s;
// Interpolate position across the exit linedef
p += l->V1() + pos*l->Delta();
p += l->v1->fPos() + pos*l->Delta();
// Whether this is a player, and if so, a pointer to its player_t.
// Voodoo dolls are excluded by making sure thing->player->mo==thing.

View file

@ -359,7 +359,7 @@ bool FTraceInfo::LineCheck(intercept_t *in)
int lineside;
sector_t *entersector;
double dist = MaxDist * in->Frac;
double dist = MaxDist * in->frac;
DVector3 hit = Start + Vec * dist;
double ff, fc, bf = 0, bc = 0;
@ -468,7 +468,7 @@ bool FTraceInfo::LineCheck(intercept_t *in)
{
if (entersector == NULL || (hit.Z >= bf && hit.Z <= bc))
{
int res = EnterLinePortal(in->d.line, in->Frac);
int res = EnterLinePortal(in->d.line, in->frac);
if (res != -1)
{
aimdir = INT_MAX; // flag for ending the traverse
@ -610,7 +610,7 @@ cont:
Results->HitPos = hit;
SetSourcePosition();
Results->Distance = dist;
Results->Fraction = in->Frac;
Results->Fraction = in->frac;
Results->Line = in->d.line;
Results->Side = lineside;
}
@ -648,7 +648,7 @@ cont:
bool FTraceInfo::ThingCheck(intercept_t *in)
{
double dist = MaxDist * in->Frac;
double dist = MaxDist * in->frac;
DVector3 hit = Start + Vec * dist;
if (hit.Z > in->d.thing->Top())
@ -660,7 +660,7 @@ bool FTraceInfo::ThingCheck(intercept_t *in)
dist = (in->d.thing->Top() - Start.Z) / Vec.Z;
if (dist > MaxDist) return true;
in->Frac = dist / MaxDist;
in->frac = dist / MaxDist;
hit = Start + Vec * dist;
@ -675,7 +675,7 @@ bool FTraceInfo::ThingCheck(intercept_t *in)
// Does it hit the bottom of the actor?
dist = (in->d.thing->Z() - Start.Z) / Vec.Z;
if (dist > MaxDist) return true;
in->Frac = dist / MaxDist;
in->frac = dist / MaxDist;
hit = Start + Vec * dist;
@ -731,7 +731,7 @@ cont1:
Results->HitPos = hit;
SetSourcePosition();
Results->Distance = dist;
Results->Fraction = in->Frac;
Results->Fraction = in->frac;
Results->Actor = in->d.thing;
if (TraceCallback != NULL)
@ -785,7 +785,7 @@ bool FTraceInfo::TraceTraverse (int ptflags)
}
// We have something closer in the storage for portal subtraces.
if (TempResults->HitType != TRACE_HitNone && in->Frac > TempResults->Fraction)
if (TempResults->HitType != TRACE_HitNone && in->frac > TempResults->Fraction)
{
break;
}

View file

@ -1216,14 +1216,14 @@ void FPolyObj::LinkPolyobj ()
vertex_t *vt;
vt = Sidedefs[i]->linedef->v1;
Bounds.AddToBox(vt->fixX(), vt->fixY());
Bounds.AddToBox(vt->fPos());
vt = Sidedefs[i]->linedef->v2;
Bounds.AddToBox(vt->fixX(), vt->fixY());
Bounds.AddToBox(vt->fPos());
}
bbox[BOXRIGHT] = GetBlockX(FIXED2DBL(Bounds.Right()));
bbox[BOXLEFT] = GetBlockX(FIXED2DBL(Bounds.Left()));
bbox[BOXTOP] = GetBlockY(FIXED2DBL(Bounds.Top()));
bbox[BOXBOTTOM] = GetBlockY(FIXED2DBL(Bounds.Bottom()));
bbox[BOXRIGHT] = GetBlockX(Bounds.Right());
bbox[BOXLEFT] = GetBlockX(Bounds.Left());
bbox[BOXTOP] = GetBlockY(Bounds.Top());
bbox[BOXBOTTOM] = GetBlockY(Bounds.Bottom());
// add the polyobj to each blockmap section
for(int j = bbox[BOXBOTTOM]*bmapwidth; j <= bbox[BOXTOP]*bmapwidth;
j += bmapwidth)

View file

@ -163,19 +163,19 @@ void FLinePortalTraverse::AddLineIntercepts(int bx, int by)
for (unsigned i = 0; i<block.portallines.Size(); i++)
{
line_t *ld = block.portallines[i];
fixed_t frac;
fdivline_t dl;
double frac;
divline_t dl;
if (ld->validcount == validcount) continue; // already processed
if (P_PointOnDivlineSidePrecise (ld->v1->fixX(), ld->v1->fixY(), &trace) ==
P_PointOnDivlineSidePrecise (ld->v2->fixX(), ld->v2->fixY(), &trace))
if (P_PointOnDivlineSide (ld->v1->fPos(), &trace) ==
P_PointOnDivlineSide (ld->v2->fPos(), &trace))
{
continue; // line isn't crossed
}
P_MakeDivline (ld, &dl);
if (P_PointOnDivlineSidePrecise (trace.x, trace.y, &dl) != 0 ||
P_PointOnDivlineSidePrecise (trace.x+trace.dx, trace.y+trace.dy, &dl) != 1)
if (P_PointOnDivlineSide(trace.x, trace.y, &dl) != 0 ||
P_PointOnDivlineSide(trace.x + trace.dx, trace.y + trace.dy, &dl) != 1)
{
continue; // line isn't crossed from the front side
}
@ -183,7 +183,7 @@ void FLinePortalTraverse::AddLineIntercepts(int bx, int by)
// hit the line
P_MakeDivline(ld, &dl);
frac = P_InterceptVector(&trace, &dl);
if (frac < 0 || frac > FRACUNIT) continue; // behind source
if (frac < 0 || frac > 1.) continue; // behind source
intercept_t newintercept;
@ -252,8 +252,8 @@ static void SetRotation(FLinePortal *port)
line_t *dst = port->mDestination;
line_t *line = port->mOrigin;
DAngle angle = dst->Delta().Angle() - line->Delta().Angle() + 180.;
port->mSinRot = FLOAT2FIXED(angle.Sin());
port->mCosRot = FLOAT2FIXED(angle.Cos());
port->mSinRot = sindeg(angle.Degrees); // Here precision matters so use the slower but more precise versions.
port->mCosRot = cosdeg(angle.Degrees);
port->mAngleDiff = angle;
}
}
@ -500,26 +500,22 @@ void P_ClearPortals()
}
inline int P_PointOnLineSideExplicit (fixed_t x, fixed_t y, fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2)
{
return DMulScale32 (y-y1, x2-x1, x1-x, y2-y1) > 0;
}
//============================================================================
//
// check if this line is between portal and the viewer. clip away if it is.
//
//============================================================================
inline int P_GetLineSide(fixed_t x, fixed_t y, const line_t *line)
inline int P_GetLineSide(const DVector2 &pos, const line_t *line)
{
return DMulScale32(y - line->v1->fixY(), line->fixDx(), line->v1->fixX() - x, line->fixDy());
double v = (pos.Y - line->v1->fY()) * line->Delta().X + (line->v1->fX() - pos.X) * line->Delta().Y;
return v < -1. / 65536. ? -1 : v > 1. / 65536 ? 1 : 0;
}
bool P_ClipLineToPortal(line_t* line, line_t* portal, fixed_t viewx, fixed_t viewy, bool partial, bool samebehind)
bool P_ClipLineToPortal(line_t* line, line_t* portal, DVector2 view, bool partial, bool samebehind)
{
int behind1 = P_GetLineSide(line->v1->fixX(), line->v1->fixY(), portal);
int behind2 = P_GetLineSide(line->v2->fixX(), line->v2->fixY(), portal);
int behind1 = P_GetLineSide(line->v1->fPos(), portal);
int behind2 = P_GetLineSide(line->v2->fPos(), portal);
if (behind1 == 0 && behind2 == 0)
{
@ -543,14 +539,12 @@ bool P_ClipLineToPortal(line_t* line, line_t* portal, fixed_t viewx, fixed_t vie
else
{
// The line intersects with the portal straight, so we need to do another check to see how both ends of the portal lie in relation to the viewer.
int viewside = P_PointOnLineSidePrecise(viewx, viewy, line);
int p1side = P_GetLineSide(portal->v1->fixX(), portal->v1->fixY(), line);
int p2side = P_GetLineSide(portal->v2->fixX(), portal->v2->fixY(), line);
// Do the same handling of points on the portal straight than above.
int viewside = P_GetLineSide(view, line);
int p1side = P_GetLineSide(portal->v1->fPos(), line);
int p2side = P_GetLineSide(portal->v2->fPos(), line);
// Do the same handling of points on the portal straight as above.
if (p1side == 0) p1side = p2side;
else if (p2side == 0) p2side = p1side;
p1side = p1side > 0;
p2side = p2side > 0;
// If the portal is on the other side of the line than the viewpoint, there is no possibility to see this line inside the portal.
return (p1side == p2side && viewside != p1side);
}
@ -562,22 +556,22 @@ bool P_ClipLineToPortal(line_t* line, line_t* portal, fixed_t viewx, fixed_t vie
//
//============================================================================
void P_TranslatePortalXY(line_t* src, fixed_t& x, fixed_t& y)
void P_TranslatePortalXY(line_t* src, double& x, double& y)
{
if (!src) return;
FLinePortal *port = src->getPortal();
if (!port) return;
// offsets from line
fixed_t nposx = x - src->v1->fixX();
fixed_t nposy = y - src->v1->fixY();
double nposx = x - src->v1->fX();
double nposy = y - src->v1->fY();
// Rotate position along normal to match exit linedef
fixed_t tx = FixedMul(nposx, port->mCosRot) - FixedMul(nposy, port->mSinRot);
fixed_t ty = FixedMul(nposy, port->mCosRot) + FixedMul(nposx, port->mSinRot);
double tx = nposx * port->mCosRot - nposy * port->mSinRot;
double ty = nposy * port->mCosRot + nposx * port->mSinRot;
tx += port->mDestination->v2->fixX();
ty += port->mDestination->v2->fixY();
tx += port->mDestination->v2->fX();
ty += port->mDestination->v2->fY();
x = tx;
y = ty;
@ -589,16 +583,16 @@ void P_TranslatePortalXY(line_t* src, fixed_t& x, fixed_t& y)
//
//============================================================================
void P_TranslatePortalVXVY(line_t* src, fixed_t& vx, fixed_t& vy)
void P_TranslatePortalVXVY(line_t* src, double &velx, double &vely)
{
if (!src) return;
FLinePortal *port = src->getPortal();
if (!port) return;
fixed_t orig_velx = vx;
fixed_t orig_vely = vy;
vx = FixedMul(orig_velx, port->mCosRot) - FixedMul(orig_vely, port->mSinRot);
vy = FixedMul(orig_vely, port->mCosRot) + FixedMul(orig_velx, port->mSinRot);
double orig_velx = velx;
double orig_vely = vely;
velx = orig_velx * port->mCosRot - orig_vely * port->mSinRot;
vely = orig_vely * port->mCosRot - orig_velx * port->mSinRot;
}
//============================================================================
@ -621,7 +615,7 @@ void P_TranslatePortalAngle(line_t* src, DAngle& angle)
//
//============================================================================
void P_TranslatePortalZ(line_t* src, fixed_t& z)
void P_TranslatePortalZ(line_t* src, double& z)
{
// args[2] = 0 - no adjustment
// args[2] = 1 - adjust by floor difference
@ -632,11 +626,11 @@ void P_TranslatePortalZ(line_t* src, fixed_t& z)
switch (src->getPortalAlignment())
{
case PORG_FLOOR:
z = z - src->frontsector->floorplane.ZatPoint(src->v1->fixX(), src->v1->fixY()) + dst->frontsector->floorplane.ZatPoint(dst->v2->fixX(), dst->v2->fixY());
z = z - src->frontsector->floorplane.ZatPoint(src->v1) + dst->frontsector->floorplane.ZatPoint(dst->v2);
return;
case PORG_CEILING:
z = z - src->frontsector->ceilingplane.ZatPoint(src->v1->fixX(), src->v1->fixY()) + dst->frontsector->ceilingplane.ZatPoint(dst->v2->fixX(), dst->v2->fixY());
z = z - src->frontsector->ceilingplane.ZatPoint(src->v1) + dst->frontsector->ceilingplane.ZatPoint(dst->v2);
return;
default:
@ -644,37 +638,6 @@ void P_TranslatePortalZ(line_t* src, fixed_t& z)
}
}
//============================================================================
//
// calculate shortest distance from a point (x,y) to a linedef
//
//============================================================================
fixed_t P_PointLineDistance(line_t* line, fixed_t x, fixed_t y)
{
angle_t angle = R_PointToAngle2(0, 0, line->fixDx(), line->fixDy());
angle += ANGLE_180;
fixed_t dx = line->v1->fixX() - x;
fixed_t dy = line->v1->fixY() - y;
fixed_t s = finesine[angle>>ANGLETOFINESHIFT];
fixed_t c = finecosine[angle>>ANGLETOFINESHIFT];
fixed_t d2x = FixedMul(dx, c) - FixedMul(dy, s);
return abs(d2x);
}
void P_NormalizeVXVY(fixed_t& vx, fixed_t& vy)
{
double _vx = FIXED2DBL(vx);
double _vy = FIXED2DBL(vy);
double len = g_sqrt(_vx*_vx+_vy*_vy);
vx = FLOAT2FIXED(_vx/len);
vy = FLOAT2FIXED(_vy/len);
}
//============================================================================
//
// P_GetOffsetPosition
@ -684,17 +647,17 @@ void P_NormalizeVXVY(fixed_t& vx, fixed_t& vy)
//
//============================================================================
fixedvec2 P_GetOffsetPosition(fixed_t x, fixed_t y, fixed_t dx, fixed_t dy)
DVector2 P_GetOffsetPosition(double x, double y, double dx, double dy)
{
fixedvec2 dest = { x + dx, y + dy };
DVector2 dest(x + dx, y + dy);
if (PortalBlockmap.containsLines)
{
fixed_t actx = x, acty = y;
double actx = x, acty = y;
// Try some easily discoverable early-out first. If we know that the trace cannot possibly find a portal, this saves us from calling the traverser completely for vast parts of the map.
if (dx < 128 * FRACUNIT && dy < 128 * FRACUNIT)
if (dx < 128 && dy < 128)
{
int blockx = GetBlockX(FIXED2DBL(actx));
int blocky = GetBlockY(FIXED2DBL(acty));
int blockx = GetBlockX(actx);
int blocky = GetBlockY(acty);
if (blockx < 0 || blocky < 0 || blockx >= bmapwidth || blocky >= bmapheight || !PortalBlockmap(blockx, blocky).neighborContainsLines) return dest;
}
@ -715,26 +678,24 @@ fixedvec2 P_GetOffsetPosition(fixed_t x, fixed_t y, fixed_t dx, fixed_t dy)
// Teleport portals are intentionally ignored since skipping this stuff is their entire reason for existence.
if (port->mFlags & PORTF_INTERACTIVE)
{
fixedvec2 hit = it._f_InterceptPoint(in);
DVector2 hit = it.InterceptPoint(in);
if (port->mType == PORTT_LINKED)
{
// optimized handling for linked portals where we only need to add an offset.
hit.x += FLOAT2FIXED(port->mDisplacement.X);
hit.y += FLOAT2FIXED(port->mDisplacement.Y);
dest.x += FLOAT2FIXED(port->mDisplacement.X);
dest.y += FLOAT2FIXED(port->mDisplacement.Y);
hit += port->mDisplacement;
dest += port->mDisplacement;
}
else
{
// 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.
P_TranslatePortalXY(line, hit.x, hit.y);
P_TranslatePortalXY(line, dest.x, dest.y);
P_TranslatePortalXY(line, hit.X, hit.Y);
P_TranslatePortalXY(line, dest.X, dest.Y);
}
// update the fields, end this trace and restart from the new position
dx = dest.x - hit.x;
dy = dest.y - hit.y;
dx = dest.X - hit.X;
dy = dest.Y - hit.Y;
repeat = true;
}
@ -814,13 +775,12 @@ static void AddDisplacementForPortal(AStackPoint *portal)
FDisplacement & disp = Displacements(thisgroup, othergroup);
if (!disp.isSet)
{
disp.pos.x = FLOAT2FIXED(portal->Scale.X);
disp.pos.y = FLOAT2FIXED(portal->Scale.Y);
disp.pos = portal->Scale;
disp.isSet = true;
}
else
{
if (disp.pos.x != FLOAT2FIXED(portal->Scale.X) || disp.pos.y != FLOAT2FIXED(portal->Scale.Y))
if (disp.pos != portal->Scale)
{
Printf("Portal between sectors %d and %d has displacement mismatch and will be disabled\n", portal->Sector->sectornum, portal->Mate->Sector->sectornum);
portal->special1 = portal->Mate->special1 = SKYBOX_PORTAL;
@ -850,13 +810,12 @@ static void AddDisplacementForPortal(FLinePortal *portal)
FDisplacement & disp = Displacements(thisgroup, othergroup);
if (!disp.isSet)
{
disp.pos.x = FLOAT2FIXED(portal->mDisplacement.X);
disp.pos.y = FLOAT2FIXED(portal->mDisplacement.Y);
disp.pos = portal->mDisplacement;
disp.isSet = true;
}
else
{
if (disp.pos.x != FLOAT2FIXED(portal->mDisplacement.X) || disp.pos.y != FLOAT2FIXED(portal->mDisplacement.Y))
if (disp.pos != portal->mDisplacement)
{
Printf("Portal between lines %d and %d has displacement mismatch\n", int(portal->mOrigin - lines), int(portal->mDestination - lines));
portal->mType = linePortals[portal->mDestination->portalindex].mType = PORTT_TELEPORT;
@ -897,7 +856,7 @@ static bool ConnectGroups()
FDisplacement &dispxz = Displacements(x, z);
if (dispxz.isSet)
{
if (dispxy.pos.x + dispyz.pos.x != dispxz.pos.x || dispxy.pos.y + dispyz.pos.y != dispxz.pos.y)
if (dispxy.pos.X + dispyz.pos.X != dispxz.pos.X || dispxy.pos.Y + dispyz.pos.Y != dispxz.pos.Y)
{
bogus = true;
}
@ -1033,7 +992,7 @@ void P_CreateLinkedPortals()
FDisplacement &dispxy = Displacements(x, y);
FDisplacement &dispyx = Displacements(y, x);
if (dispxy.isSet && dispyx.isSet &&
(dispxy.pos.x != -dispyx.pos.x || dispxy.pos.y != -dispyx.pos.y))
(dispxy.pos.X != -dispyx.pos.X || dispxy.pos.Y != -dispyx.pos.Y))
{
int sec1 = -1, sec2 = -1;
for (int i = 0; i < numsectors && (sec1 == -1 || sec2 == -1); i++)
@ -1119,7 +1078,7 @@ void P_CreateLinkedPortals()
if (!(actor->flags & MF_NOBLOCKMAP))
{
FPortalGroupArray check(FPortalGroupArray::PGA_NoSectorPortals);
P_CollectConnectedGroups(actor->Sector->PortalGroup, actor->_f_Pos(), actor->_f_Top(), actor->_f_radius(), check);
P_CollectConnectedGroups(actor->Sector->PortalGroup, actor->Pos(), actor->Top(), actor->radius, check);
if (check.Size() > 0)
{
actor->UnlinkFromWorld();
@ -1138,7 +1097,7 @@ void P_CreateLinkedPortals()
//
//============================================================================
bool P_CollectConnectedGroups(int startgroup, const fixedvec3 &position, fixed_t upperz, fixed_t checkradius, FPortalGroupArray &out)
bool P_CollectConnectedGroups(int startgroup, const DVector3 &position, double upperz, double checkradius, FPortalGroupArray &out)
{
// Keep this temporary work stuff static. This function can never be called recursively
// and this would have to be reallocated for each call otherwise.
@ -1172,7 +1131,7 @@ bool P_CollectConnectedGroups(int startgroup, const fixedvec3 &position, fixed_t
FDisplacement &disp = Displacements(thisgroup, othergroup);
if (!disp.isSet) continue; // no connection.
FBoundingBox box(position.x + disp.pos.x, position.y + disp.pos.y, checkradius);
FBoundingBox box(position.X + disp.pos.X, position.Y + disp.pos.Y, checkradius);
if (!box.inRange(ld) || box.BoxOnLineSide(linkedPortals[i]->mOrigin) != -1) continue; // not touched
foundPortals.Push(linkedPortals[i]);
@ -1197,29 +1156,25 @@ bool P_CollectConnectedGroups(int startgroup, const fixedvec3 &position, fixed_t
}
if (out.method != FPortalGroupArray::PGA_NoSectorPortals)
{
sector_t *sec = P_PointInSector(position.x, position.y);
sector_t *sec = P_PointInSector(position);
sector_t *wsec = sec;
while (!wsec->PortalBlocksMovement(sector_t::ceiling) && upperz > FLOAT2FIXED(wsec->SkyBoxes[sector_t::ceiling]->specialf1))
while (!wsec->PortalBlocksMovement(sector_t::ceiling) && upperz > wsec->SkyBoxes[sector_t::ceiling]->specialf1)
{
sector_t *othersec = wsec->SkyBoxes[sector_t::ceiling]->Sector;
fixedvec2 pos = Displacements._f_getOffset(startgroup, othersec->PortalGroup);
fixed_t dx = position.x + pos.x;
fixed_t dy = position.y + pos.y;
DVector2 pos = Displacements.getOffset(startgroup, othersec->PortalGroup) + position;
processMask.setBit(othersec->PortalGroup);
out.Add(othersec->PortalGroup | FPortalGroupArray::UPPER);
wsec = P_PointInSector(dx, dy); // get upper sector at the exact spot we want to check and repeat
wsec = P_PointInSector(pos); // get upper sector at the exact spot we want to check and repeat
retval = true;
}
wsec = sec;
while (!wsec->PortalBlocksMovement(sector_t::floor) && position.z < FLOAT2FIXED(wsec->SkyBoxes[sector_t::floor]->specialf1))
while (!wsec->PortalBlocksMovement(sector_t::floor) && position.Z < wsec->SkyBoxes[sector_t::floor]->specialf1)
{
sector_t *othersec = wsec->SkyBoxes[sector_t::floor]->Sector;
fixedvec2 pos = Displacements._f_getOffset(startgroup, othersec->PortalGroup);
fixed_t dx = position.x + pos.x;
fixed_t dy = position.y + pos.y;
DVector2 pos = Displacements.getOffset(startgroup, othersec->PortalGroup) + position;
processMask.setBit(othersec->PortalGroup | FPortalGroupArray::LOWER);
out.Add(othersec->PortalGroup);
wsec = P_PointInSector(dx, dy); // get lower sector at the exact spot we want to check and repeat
wsec = P_PointInSector(pos); // get lower sector at the exact spot we want to check and repeat
retval = true;
}
if (out.method == FPortalGroupArray::PGA_Full3d && PortalBlockmap.hasLinkedSectorPortals)
@ -1229,8 +1184,8 @@ bool P_CollectConnectedGroups(int startgroup, const fixedvec3 &position, fixed_t
int thisgroup = startgroup;
for (unsigned i = 0; i < groupsToCheck.Size();i++)
{
fixedvec2 disp = Displacements._f_getOffset(startgroup, thisgroup & ~FPortalGroupArray::FLAT);
FBoundingBox box(position.x + disp.x, position.y + disp.y, checkradius);
DVector2 disp = Displacements.getOffset(startgroup, thisgroup & ~FPortalGroupArray::FLAT);
FBoundingBox box(position.X + disp.X, position.Y + disp.Y, checkradius);
FBlockLinesIterator it(box);
line_t *ld;
while ((ld = it.Next()))
@ -1245,7 +1200,7 @@ bool P_CollectConnectedGroups(int startgroup, const fixedvec3 &position, fixed_t
sector_t *sec = s ? ld->backsector : ld->frontsector;
if (sec && !(sec->PortalBlocksMovement(sector_t::ceiling)))
{
if (FLOAT2FIXED(sec->SkyBoxes[sector_t::ceiling]->specialf1) < upperz)
if (sec->SkyBoxes[sector_t::ceiling]->specialf1 < upperz)
{
int grp = sec->SkyBoxes[sector_t::ceiling]->Sector->PortalGroup;
if (!(processMask.getBit(grp)))
@ -1264,7 +1219,7 @@ bool P_CollectConnectedGroups(int startgroup, const fixedvec3 &position, fixed_t
sector_t *sec = s ? ld->backsector : ld->frontsector;
if (sec && !(sec->PortalBlocksMovement(sector_t::floor)))
{
if (FLOAT2FIXED(sec->SkyBoxes[sector_t::floor]->specialf1) > position.z)
if (sec->SkyBoxes[sector_t::floor]->specialf1 > position.Z)
{
int grp = sec->SkyBoxes[sector_t::floor]->Sector->PortalGroup;
if (!(processMask.getBit(grp)))
@ -1297,7 +1252,7 @@ CCMD(dumplinktable)
for (int y = 1; y < Displacements.size; y++)
{
FDisplacement &disp = Displacements(x, y);
Printf("%c%c(%6d, %6d)", TEXTCOLOR_ESCAPE, 'C' + disp.indirect, disp.pos.x >> FRACBITS, disp.pos.y >> FRACBITS);
Printf("%c%c(%6d, %6d)", TEXTCOLOR_ESCAPE, 'C' + disp.indirect, int(disp.pos.X), int(disp.pos.Y));
}
Printf("\n");
}

View file

@ -26,7 +26,7 @@ struct FPortalGroupArray;
struct FDisplacement
{
fixedvec2 pos;
DVector2 pos;
bool isSet;
BYTE indirect; // just for illustration.
@ -54,16 +54,6 @@ struct FDisplacementTable
return data[x + size*y];
}
fixedvec2 _f_getOffset(int x, int y) const
{
if (x == y)
{
fixedvec2 nulvec = { 0,0 };
return nulvec; // shortcut for the most common case
}
return data[x + size*y].pos;
}
DVector2 getOffset(int x, int y) const
{
if (x == y)
@ -71,8 +61,7 @@ struct FDisplacementTable
DVector2 nulvec = { 0,0 };
return nulvec; // shortcut for the most common case
}
fixedvec2 &p = data[x + size*y].pos;
return{ FIXED2DBL(p.x), FIXED2DBL(p.y) };
return data[x + size*y].pos;
}
};
@ -191,8 +180,8 @@ struct FLinePortal
BYTE mDefFlags;
BYTE mAlign;
DAngle mAngleDiff;
fixed_t mSinRot;
fixed_t mCosRot;
double mSinRot;
double mCosRot;
};
extern TArray<FLinePortal> linePortals;
@ -202,7 +191,7 @@ void P_SpawnLinePortal(line_t* line);
void P_FinalizePortals();
bool P_ChangePortal(line_t *ln, int thisid, int destid);
void P_CreateLinkedPortals();
bool P_CollectConnectedGroups(int startgroup, const fixedvec3 &position, fixed_t upperz, fixed_t checkradius, FPortalGroupArray &out);
bool P_CollectConnectedGroups(int startgroup, const DVector3 &position, double upperz, double checkradius, FPortalGroupArray &out);
void P_CollectLinkedPortals();
inline int P_NumPortalGroups()
{
@ -211,43 +200,12 @@ inline int P_NumPortalGroups()
/* 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);
void P_TranslatePortalXY(line_t* src, fixed_t& x, fixed_t& y);
inline void P_TranslatePortalXY(line_t* src, double& vx, double& vy)
{
fixed_t x = FLOAT2FIXED(vx);
fixed_t y = FLOAT2FIXED(vy);
P_TranslatePortalXY(src, x, y);
vx = FIXED2DBL(x);
vx = FIXED2DBL(y);
}
void P_TranslatePortalVXVY(line_t* src, fixed_t& vx, fixed_t& vy);
inline void P_TranslatePortalVXVY(line_t* src, double& vx, double& vy)
{
fixed_t x = FLOAT2FIXED(vx);
fixed_t y = FLOAT2FIXED(vy);
P_TranslatePortalVXVY(src, x, y);
vx = FIXED2DBL(x);
vx = FIXED2DBL(y);
}
bool P_ClipLineToPortal(line_t* line, line_t* portal, DVector2 view, bool partial = true, bool samebehind = true);
void P_TranslatePortalXY(line_t* src, double& vx, double& vy);
void P_TranslatePortalVXVY(line_t* src, double &velx, double &vely);
void P_TranslatePortalAngle(line_t* src, DAngle& angle);
void P_TranslatePortalZ(line_t* src, fixed_t& z);
inline void P_TranslatePortalZ(line_t* src, double& vz)
{
fixed_t x = FLOAT2FIXED(vz);
P_TranslatePortalZ(src, x);
vz = FIXED2DBL(x);
}
void P_NormalizeVXVY(fixed_t& vx, fixed_t& vy);
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);
inline DVector2 P_GetOffsetPosition(double x, double y, double dx, double dy)
{
fixedvec2 v = P_GetOffsetPosition(FLOAT2FIXED(x), FLOAT2FIXED(y), FLOAT2FIXED(dx), FLOAT2FIXED(dy));
return{ FIXED2DBL(v.x), FIXED2DBL(v.y) };
}
void P_TranslatePortalZ(line_t* src, double& vz);
DVector2 P_GetOffsetPosition(double x, double y, double dx, double dy);
#endif

View file

@ -555,7 +555,7 @@ void R_AddLine (seg_t *line)
// reject lines that aren't seen from the portal (if any)
// [ZZ] 10.01.2016: lines inside a skybox shouldn't be clipped, although this imposes some limitations on portals in skyboxes.
if (!CurrentPortalInSkybox && CurrentPortal && P_ClipLineToPortal(line->linedef, CurrentPortal->dst, viewx, viewy))
if (!CurrentPortalInSkybox && CurrentPortal && P_ClipLineToPortal(line->linedef, CurrentPortal->dst, DVector2(FIXED2DBL(viewx), FIXED2DBL(viewy))))
return;
vertex_t *v1, *v2;

View file

@ -389,16 +389,6 @@ public:
return ic < 0 ? d : -d;
}
fixed_t ZatPoint(const fixedvec2 &spot) const
{
return FixedMul(ic, -d - DMulScale16(a, spot.x, b, spot.y));
}
fixed_t ZatPoint(const fixedvec3 &spot) const
{
return FixedMul(ic, -d - DMulScale16(a, spot.x, b, spot.y));
}
// Returns the value of z at (x,y)
fixed_t ZatPoint (fixed_t x, fixed_t y) const
{
@ -489,11 +479,6 @@ public:
return -TMulScale16 (a, x, y, b, z, c);
}
fixed_t PointToDist(fixedvec2 xy, fixed_t z) const
{
return -TMulScale16(a, xy.x, xy.y, b, z, c);
}
fixed_t PointToDist (const vertex_t *v, fixed_t z) const
{
return -TMulScale16 (a, v->fixX(), b, v->fixY(), z, c);
@ -714,7 +699,7 @@ struct sector_t
void AdjustFloorClip () const;
void SetColor(int r, int g, int b, int desat);
void SetFade(int r, int g, int b);
void ClosestPoint(fixed_t x, fixed_t y, fixed_t &ox, fixed_t &oy) const;
void ClosestPoint(const DVector2 &pos, DVector2 &out) const;
int GetFloorLight () const;
int GetCeilingLight () const;
sector_t *GetHeightSec() const;
@ -1135,11 +1120,6 @@ struct sector_t
int validcount; // if == validcount, already checked
AActor* thinglist; // list of mobjs in sector
fixedvec2 _f_centerspot() const
{
return{ FLOAT2FIXED(centerspot.X), FLOAT2FIXED(centerspot.Y) };
}
// killough 8/28/98: friction is a sector property, not an mobj property.
// these fields used to be in AActor, but presented performance problems
// when processed as mobj properties. Fix is to make them sector properties.
@ -1477,31 +1457,11 @@ public:
unsigned portalindex;
TObjPtr<ASkyViewpoint> skybox;
DVector2 V1() const
{
return v1->fPos();
}
DVector2 V2() const
{
return v1->fPos();
}
DVector2 Delta() const
{
return{ FIXED2DBL(dx), FIXED2DBL(dy) };
}
fixed_t fixDx() const
{
return dx;
}
fixed_t fixDy() const
{
return dy;
}
void setDelta(fixed_t x, fixed_t y)
{
dx = x;
@ -1705,20 +1665,16 @@ struct visstyle_t
// not the same as R_PointInSubsector
//
//----------------------------------------------------------------------------------
subsector_t *P_PointInSubsector(fixed_t x, fixed_t y);
inline sector_t *P_PointInSector(fixed_t x, fixed_t y)
{
return P_PointInSubsector(x, y)->sector;
}
subsector_t *P_PointInSubsector(double x, double y);
inline sector_t *P_PointInSector(const DVector2 &pos)
{
return P_PointInSubsector(FLOAT2FIXED(pos.X), FLOAT2FIXED(pos.Y))->sector;
return P_PointInSubsector(pos.X, pos.Y)->sector;
}
inline sector_t *P_PointInSector(double X, double Y)
{
return P_PointInSubsector(FLOAT2FIXED(X), FLOAT2FIXED(Y))->sector;
return P_PointInSubsector(X, Y)->sector;
}
inline DVector3 AActor::PosRelative(int portalgroup) const
@ -1757,10 +1713,10 @@ inline void AActor::ClearInterpolation()
inline bool FBoundingBox::inRange(const line_t *ld) const
{
return FIXED2DBL(Left()) < ld->bbox[BOXRIGHT] &&
FIXED2DBL(Right()) > ld->bbox[BOXLEFT] &&
FIXED2DBL(Top()) > ld->bbox[BOXBOTTOM] &&
FIXED2DBL(Bottom()) < ld->bbox[BOXTOP];
return Left() < ld->bbox[BOXRIGHT] &&
Right() > ld->bbox[BOXLEFT] &&
Top() > ld->bbox[BOXBOTTOM] &&
Bottom() < ld->bbox[BOXTOP];
}

View file

@ -733,10 +733,14 @@ void R_EnterPortal (PortalDrawseg* pds, int depth)
}
else
{
P_TranslatePortalXY(pds->src, viewx, viewy);
P_TranslatePortalZ(pds->src, viewz);
DVector3 view(FIXED2DBL(viewx), FIXED2DBL(viewy), FIXED2DBL(viewz));
DAngle va = ANGLE2DBL(viewangle);
P_TranslatePortalXY(pds->src, view.X, view.Y);
P_TranslatePortalZ(pds->src, view.Z);
P_TranslatePortalAngle(pds->src, va);
viewx = FLOAT2FIXED(view.X);
viewy = FLOAT2FIXED(view.Y);
viewz = FLOAT2FIXED(view.Z);
viewangle = va.BAMs();
}

View file

@ -374,7 +374,7 @@ static inline bool R_ClipSpriteColumnWithPortals(fixed_t x, fixed_t y, vissprite
line_t* line = seg->curline->linedef;
// don't clip if the sprite is in front of the portal
if (!P_PointOnLineSidePrecise(x, y, line))
if (!P_PointOnLineSidePrecise(FIXED2DBL(x), FIXED2DBL(y), line))
continue;
// now if current column is covered by this drawseg, we clip it away

View file

@ -57,6 +57,7 @@
#include "r_utility.h"
#include "d_player.h"
#include "p_local.h"
#include "p_maputl.h"
#include "math/cmath.h"
@ -652,9 +653,9 @@ void R_InterpolateView (player_t *player, double Frac, InterpolationViewer *ivie
}
else
{
fixedvec2 disp = Displacements._f_getOffset(oldgroup, newgroup);
viewx = iview->oviewx + FixedMul(frac, iview->nviewx - iview->oviewx - disp.x);
viewy = iview->oviewy + FixedMul(frac, iview->nviewy - iview->oviewy - disp.y);
DVector2 disp = Displacements.getOffset(oldgroup, newgroup);
viewx = iview->oviewx + FixedMul(frac, iview->nviewx - iview->oviewx - FLOAT2FIXED(disp.X));
viewy = iview->oviewy + FixedMul(frac, iview->nviewy - iview->oviewy - FLOAT2FIXED(disp.Y));
viewz = iview->oviewz + FixedMul(frac, iview->nviewz - iview->oviewz);
}
if (player != NULL &&

View file

@ -55,6 +55,10 @@ inline int R_PointOnSide (fixed_t x, fixed_t y, const node_t *node)
{
return DMulScale32 (y-node->y, node->dx, node->x-x, node->dy) > 0;
}
inline int R_PointOnSide(double x, double y, const node_t *node)
{
return DMulScale32(FLOAT2FIXED(y) - node->y, node->dx, node->x - FLOAT2FIXED(x), node->dy) > 0;
}
inline int R_PointOnSide(const DVector2 &pos, const node_t *node)
{
return DMulScale32(FLOAT2FIXED(pos.Y) - node->y, node->dx, node->x - FLOAT2FIXED(pos.X), node->dy) > 0;

View file

@ -104,8 +104,8 @@ static void S_ActivatePlayList(bool goBack);
static void CalcPosVel(FSoundChan *chan, FVector3 *pos, FVector3 *vel);
static void CalcPosVel(int type, const AActor *actor, const sector_t *sector, const FPolyObj *poly,
const float pt[3], int channel, int chanflags, FVector3 *pos, FVector3 *vel);
static void CalcSectorSoundOrg(const sector_t *sec, int channum, fixed_t *x, fixed_t *y, fixed_t *z);
static void CalcPolyobjSoundOrg(const FPolyObj *poly, fixed_t *x, fixed_t *y, fixed_t *z);
static void CalcSectorSoundOrg(const DVector3 &listenpos, const sector_t *sec, int channum, FVector3 &res);
static void CalcPolyobjSoundOrg(const DVector3 &listenpos, const FPolyObj *poly, FVector3 &res);
static FSoundChan *S_StartSound(AActor *mover, const sector_t *sec, const FPolyObj *poly,
const FVector3 *pt, int channel, FSoundID sound_id, float volume, float attenuation, FRolloffInfo *rolloff);
static void S_SetListener(SoundListener &listener, AActor *listenactor);
@ -658,27 +658,30 @@ static void CalcPosVel(int type, const AActor *actor, const sector_t *sector,
{
if (pos != NULL)
{
fixed_t x, y, z;
DVector3 listenpos;
int pgroup;
AActor *listener = players[consoleplayer].camera;
if (players[consoleplayer].camera != NULL)
if (listener != NULL)
{
FVector3 v = players[consoleplayer].camera->SoundPos();
x = FLOAT2FIXED(v.X);
y = FLOAT2FIXED(v.Y);
z = FLOAT2FIXED(v.Z);
listenpos = listener->Pos();
pgroup = listener->Sector->PortalGroup;
}
else
{
z = y = x = 0;
listenpos.Zero();
pgroup = 0;
}
// [BL] Moved this case out of the switch statement to make code easier
// on static analysis.
if(type == SOURCE_Unattached)
{
pos->X = pt[0];
pos->Y = !(chanflags & CHAN_LISTENERZ) ? pt[1] : FIXED2FLOAT(y);
pos->Z = pt[2];
sector_t *sec = P_PointInSector(pt[0], pt[2]);
DVector2 disp = Displacements.getOffset(pgroup, sec->PortalGroup);
pos->X = pt[0] + (float)disp.X;
pos->Y = !(chanflags & CHAN_LISTENERZ) ? pt[1] : (float)listenpos.Z;
pos->Z = pt[2] + (float)disp.Y;
}
else
{
@ -692,10 +695,9 @@ static void CalcPosVel(int type, const AActor *actor, const sector_t *sector,
//assert(actor != NULL);
if (actor != NULL)
{
FVector3 v = actor->SoundPos();
x = FLOAT2FIXED(v.X);
y = FLOAT2FIXED(v.Y);
z = FLOAT2FIXED(v.Z);
DVector2 disp = Displacements.getOffset(pgroup, actor->Sector->PortalGroup);
DVector3 posi = actor->Pos() + disp;
*pos = { (float)posi.X, (float)posi.Z, (float)posi.Y };
}
break;
@ -703,14 +705,19 @@ static void CalcPosVel(int type, const AActor *actor, const sector_t *sector,
assert(sector != NULL);
if (sector != NULL)
{
DVector2 disp = Displacements.getOffset(pgroup, sector->PortalGroup);
if (chanflags & CHAN_AREA)
{
CalcSectorSoundOrg(sector, channum, &x, &z, &y);
// listener must be reversely offset to calculate the proper sound origin.
CalcSectorSoundOrg(listenpos-disp, sector, channum, *pos);
pos->X += (float)disp.X;
pos->Z += (float)disp.Y;
}
else
{
x = sector->_f_centerspot().x;
z = sector->_f_centerspot().y;
pos->X = (float)(sector->centerspot.X + disp.X);
pos->Z = (float)(sector->centerspot.Y + disp.Y);
chanflags |= CHAN_LISTENERZ;
}
}
@ -718,17 +725,20 @@ static void CalcPosVel(int type, const AActor *actor, const sector_t *sector,
case SOURCE_Polyobj:
assert(poly != NULL);
CalcPolyobjSoundOrg(poly, &x, &z, &y);
if (poly != NULL)
{
DVector2 disp = Displacements.getOffset(pgroup, poly->CenterSubsector->sector->PortalGroup);
CalcPolyobjSoundOrg(listenpos-disp, poly, *pos);
pos->X += (float)disp.X;
pos->Z += (float)disp.Y;
}
break;
}
if ((chanflags & CHAN_LISTENERZ) && players[consoleplayer].camera != NULL)
{
y = players[consoleplayer].camera != NULL ? FLOAT2FIXED(players[consoleplayer].camera->SoundPos().Z) : 0;
pos->Y = (float)listenpos.Z;
}
pos->X = FIXED2FLOAT(x);
pos->Y = FIXED2FLOAT(y);
pos->Z = FIXED2FLOAT(z);
}
}
if (vel != NULL)
@ -757,42 +767,44 @@ static void CalcPosVel(int type, const AActor *actor, const sector_t *sector,
//
//==========================================================================
static void CalcSectorSoundOrg(const sector_t *sec, int channum, fixed_t *x, fixed_t *y, fixed_t *z)
static void CalcSectorSoundOrg(const DVector3 &listenpos, const sector_t *sec, int channum, FVector3 &pos)
{
if (!(i_compatflags & COMPATF_SECTORSOUNDS))
{
// Are we inside the sector? If yes, the closest point is the one we're on.
if (P_PointInSector(*x, *y) == sec)
if (P_PointInSector(pos.X, pos.Y) == sec)
{
FVector3 p = players[consoleplayer].camera->SoundPos();
*x = FLOAT2FIXED(p.X);
*y = FLOAT2FIXED(p.Y);
pos.X = (float)listenpos.X;
pos.Z = (float)listenpos.Y;
}
else
{
// Find the closest point on the sector's boundary lines and use
// that as the perceived origin of the sound.
sec->ClosestPoint(*x, *y, *x, *y);
DVector2 xy;
sec->ClosestPoint(listenpos, xy);
pos.X = (float)xy.X;
pos.Z = (float)xy.Y;
}
}
else
{
*x = sec->_f_centerspot().x;
*y = sec->_f_centerspot().y;
pos.X = float(sec->centerspot.X);
pos.Z = float(sec->centerspot.Y);
}
// Set sound vertical position based on channel.
if (channum == CHAN_FLOOR)
{
*z = MIN(sec->floorplane.ZatPoint(*x, *y), *z);
pos.Y = (float)MIN<double>(sec->floorplane.ZatPoint(listenpos), listenpos.Z);
}
else if (channum == CHAN_CEILING)
{
*z = MAX(sec->ceilingplane.ZatPoint(*x, *y), *z);
pos.Y = (float)MAX<double>(sec->ceilingplane.ZatPoint(listenpos), listenpos.Z);
}
else if (channum == CHAN_INTERIOR)
{
*z = clamp(*z, sec->floorplane.ZatPoint(*x, *y), sec->ceilingplane.ZatPoint(*x, *y));
pos.Y = (float)clamp<double>(listenpos.Z, sec->floorplane.ZatPoint(listenpos), sec->ceilingplane.ZatPoint(listenpos));
}
}
@ -807,17 +819,17 @@ static void CalcSectorSoundOrg(const sector_t *sec, int channum, fixed_t *x, fix
//
//==========================================================================
static void CalcPolyobjSoundOrg(const FPolyObj *poly, fixed_t *x, fixed_t *y, fixed_t *z)
static void CalcPolyobjSoundOrg(const DVector3 &listenpos, const FPolyObj *poly, FVector3 &pos)
{
side_t *side;
sector_t *sec;
DVector2 pos(FIXED2DBL(*x), FIXED2DBL(*y));
poly->ClosestPoint(pos, pos, &side);
*x = FLOAT2FIXED(pos.X);
*y = FLOAT2FIXED(pos.Y);
DVector2 ppos;
poly->ClosestPoint(listenpos, ppos, &side);
pos.X = (float)ppos.X;
pos.Z = (float)ppos.Y;
sec = side->sector;
*z = clamp(*z, sec->floorplane.ZatPoint(*x, *y), sec->ceilingplane.ZatPoint(*x, *y));
pos.Y = (float)clamp<double>(listenpos.Z, sec->floorplane.ZatPoint(listenpos), sec->ceilingplane.ZatPoint(listenpos));
}
//==========================================================================

View file

@ -46,7 +46,7 @@
#include "math/cmath.h"
#define EQUAL_EPSILON (1/65536.f)
#define EQUAL_EPSILON (1/65536.)
// make this a local inline function to avoid any dependencies on other headers and not pollute the global namespace
namespace pi
@ -493,6 +493,11 @@ struct TVector3
return TVector3(v3.X + v2.X, v3.Y + v2.Y, v3.Z);
}
friend TVector3 operator- (const TVector3 &v3, const Vector2 &v2)
{
return TVector3(v3.X - v2.X, v3.Y - v2.Y, v3.Z);
}
friend Vector2 operator+ (const Vector2 &v2, const TVector3 &v3)
{
return Vector2(v2.X + v3.X, v2.Y + v3.Y);
@ -500,11 +505,6 @@ struct TVector3
// Subtract a 3D vector and a 2D vector.
// Discards the Z component of the 3D vector and returns a 2D vector.
friend Vector2 operator- (const TVector3 &v3, const Vector2 &v2)
{
return Vector2(v3.X - v2.X, v3.Y - v2.Y);
}
friend Vector2 operator- (const TVector2<vec_t> &v2, const TVector3 &v3)
{
return Vector2(v2.X - v3.X, v2.Y - v3.Y);