mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-11 07:12:16 +00:00
Merge branch 'floatcvt' of https://github.com/rheit/zdoom into floatcvt
# Conflicts: # src/actor.h
This commit is contained in:
commit
466c4c75df
36 changed files with 609 additions and 1079 deletions
117
src/actor.h
117
src/actor.h
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
42
src/m_bbox.h
42
src/m_bbox.h
|
@ -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];
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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)))
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
||||
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;
|
||||
double xo = (M_Random() - 128)*actor->radius / 128;
|
||||
double yo = (M_Random() - 128)*actor->radius / 128;
|
||||
double zo = M_Random()*actor->Height / 256;
|
||||
|
||||
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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
510
src/p_maputl.cpp
510
src/p_maputl.cpp
|
@ -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;
|
||||
}
|
||||
yintercept = int(_y1>>MAPBTOFRAC) + FixedMul (partialx, ystep);
|
||||
partialx = 1.;
|
||||
ystep = 256;
|
||||
}
|
||||
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;
|
||||
}
|
||||
xintercept = int(_x1>>MAPBTOFRAC) + FixedMul (partialy, xstep);
|
||||
partialy = 1;
|
||||
xstep = 256;
|
||||
}
|
||||
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)
|
||||
|
|
161
src/p_maputl.h
161
src/p_maputl.h
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
||||
|
|
|
@ -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 };
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
181
src/portal.cpp
181
src/portal.cpp
|
@ -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");
|
||||
}
|
||||
|
|
62
src/portal.h
62
src/portal.h
|
@ -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
|
|
@ -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;
|
||||
|
|
60
src/r_defs.h
60
src/r_defs.h
|
@ -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];
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 &&
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue