mirror of
https://github.com/ZDoom/Raze.git
synced 2024-11-15 08:51:24 +00:00
- rewrite from scratch of neartag.
This commit is contained in:
parent
600648939a
commit
ef2f781e09
5 changed files with 90 additions and 126 deletions
|
@ -173,22 +173,6 @@ inline int hitscan(const DVector3& start, const sectortype* startsect, const vec
|
|||
return hitscan(istart, startsect, direction, hitinfo, cliptype);
|
||||
}
|
||||
|
||||
void neartag(const vec3_t& pos, sectortype* sect, int angle, HitInfoBase& result, int neartagrange, int tagsearch);
|
||||
inline void neartag(const DVector3& start, sectortype* sect, DAngle angle, HitInfoBase& result, int neartagrange, int tagsearch)
|
||||
{
|
||||
vec3_t vec(start.X * worldtoint, start.Y * worldtoint, start.Z * zworldtoint);
|
||||
neartag(vec, sect, angle.Buildang(), result, neartagrange, tagsearch);
|
||||
}
|
||||
inline void neartag(const DVector3& start, sectortype* sect, DAngle angle, HitInfoBase& result, double neartagrange, int tagsearch)
|
||||
{
|
||||
vec3_t vec(start.X * worldtoint, start.Y * worldtoint, start.Z * zworldtoint);
|
||||
neartag(vec, sect, angle.Buildang(), result, int(neartagrange * worldtoint), tagsearch);
|
||||
}
|
||||
|
||||
int32_t try_facespr_intersect(DCoreActor* spr, vec3_t const in,
|
||||
int32_t vx, int32_t vy, int32_t vz,
|
||||
vec3_t * const intp, int32_t strictly_smaller_than_p);
|
||||
|
||||
|
||||
extern const int16_t *chsecptr_onextwall;
|
||||
|
||||
|
|
|
@ -59,87 +59,6 @@ void engineInit(void)
|
|||
|
||||
}
|
||||
|
||||
//
|
||||
// neartag
|
||||
//
|
||||
|
||||
void neartag(const vec3_t& sv, sectortype* sect, int ange, HitInfoBase& result, int neartagrange, int tagsearch)
|
||||
{
|
||||
const int32_t vx = MulScale(bcos(ange), neartagrange, 14);
|
||||
const int32_t vy = MulScale(bsin(ange), neartagrange, 14);
|
||||
vec3_t hitv = { sv.X+vx, sv.Y+vy, 0 };
|
||||
|
||||
result.clearObj();
|
||||
result.hitpos.X = 0;
|
||||
|
||||
if (!sect || (tagsearch & 3) == 0)
|
||||
return;
|
||||
|
||||
BFSSectorSearch search(sect);
|
||||
|
||||
while (auto dasect = search.GetNext())
|
||||
{
|
||||
for (auto& w : wallsofsector(dasect))
|
||||
{
|
||||
auto wal = &w;
|
||||
auto const wal2 = wal->point2Wall();
|
||||
const auto nextsect = wal->nextSector();
|
||||
|
||||
const int32_t x1 = wal->wall_int_pos().X, y1 = wal->wall_int_pos().Y, x2 = wal2->wall_int_pos().X, y2 = wal2->wall_int_pos().Y;
|
||||
int32_t intx, inty, intz, good = 0;
|
||||
|
||||
if (wal->twoSided())
|
||||
{
|
||||
if ((tagsearch & 1) && nextsect->lotag) good |= 1;
|
||||
if ((tagsearch & 2) && nextsect->hitag) good |= 1;
|
||||
}
|
||||
|
||||
if ((tagsearch & 1) && wal->lotag) good |= 2;
|
||||
if ((tagsearch & 2) && wal->hitag) good |= 2;
|
||||
|
||||
if ((good == 0) && (!wal->twoSided())) continue;
|
||||
if ((coord_t)(x1 - sv.X) * (y2 - sv.Y) < (coord_t)(x2 - sv.X) * (y1 - sv.Y)) continue;
|
||||
|
||||
if (lintersect(sv.X, sv.Y, sv.Z, hitv.X, hitv.Y, hitv.Z, x1, y1, x2, y2, &intx, &inty, &intz) == 1)
|
||||
{
|
||||
if (good != 0)
|
||||
{
|
||||
if (good & 1) result.hitSector = nextsect;
|
||||
if (good & 2) result.hitWall = wal;
|
||||
result.hitpos.X = DMulScale(intx - sv.X, bcos(ange), inty - sv.Y, bsin(ange), 14) * inttoworld;
|
||||
hitv.X = intx; hitv.Y = inty; hitv.Z = intz;
|
||||
}
|
||||
|
||||
if (wal->twoSided())
|
||||
{
|
||||
search.Add(nextsect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tagsearch & 4)
|
||||
continue; // skip sprite search
|
||||
|
||||
TSectIterator<DCoreActor> it(dasect);
|
||||
while (auto actor = it.Next())
|
||||
{
|
||||
if (actor->spr.cstat2 & CSTAT2_SPRITE_NOFIND)
|
||||
continue;
|
||||
|
||||
if (((tagsearch&1) && actor->spr.lotag) || ((tagsearch&2) && actor->spr.hitag))
|
||||
{
|
||||
DVector3 v;
|
||||
if (intersectSprite(actor, DVector3(sv.X * inttoworld, sv.Y * inttoworld, sv.Z * zinttoworld),
|
||||
DVector3(vx * inttoworld, vy * inttoworld, 0), v, 1 / 256.))
|
||||
{
|
||||
vec3_t hitv(v.X * worldtoint, v.Y * worldtoint, v.Z * zworldtoint);
|
||||
result.hitActor = actor;
|
||||
result.hitpos.X = DMulScale(hitv.X-sv.X, bcos(ange), hitv.Y-sv.Y, bsin(ange), 14) * inttoworld;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int tilehasmodelorvoxel(int const tilenume, int pal)
|
||||
{
|
||||
|
|
|
@ -623,7 +623,95 @@ bool intersectSprite(DCoreActor* actor, const DVector3& start, const DVector3& d
|
|||
return 1;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void neartag(const DVector3& pos, sectortype* startsect, DAngle angle, HitInfoBase& result, double range, int flags)
|
||||
{
|
||||
auto checkTag = [=](const auto* object)
|
||||
{
|
||||
return (((flags & NT_Lotag) && object->lotag) || ((flags & NT_Hitag) && object->hitag));
|
||||
};
|
||||
|
||||
auto v = DVector3(angle.ToVector() * range * 1.000001, 0); // extend the range a tiny bit so that we really find everything we need.
|
||||
|
||||
result.clearObj();
|
||||
result.hitpos.X = result.hitpos.Y = 0;
|
||||
|
||||
if (!startsect || (flags & (NT_Lotag | NT_Hitag)) == 0)
|
||||
return;
|
||||
|
||||
BFSSectorSearch search(startsect);
|
||||
|
||||
while (auto sect = search.GetNext())
|
||||
{
|
||||
for (auto& wal : wallsofsector(sect))
|
||||
{
|
||||
const auto nextsect = wal.nextSector();
|
||||
|
||||
if (PointOnLineSide(pos.XY(), &wal) > 0) continue;
|
||||
|
||||
double factor = InterceptLineSegments(pos.X, pos.Y, v.X, v.Y, wal.pos.X, wal.pos.Y, wal.delta().X, wal.delta().Y);
|
||||
if (factor > 0 && factor < 1)
|
||||
{
|
||||
bool foundsector = (wal.twoSided() && checkTag(nextsect));
|
||||
bool foundwall = checkTag(&wal);
|
||||
#if 0 // does not work if the trace goes right through the vertex between two walls.
|
||||
if (!wal.twoSided() && !foundwall && !foundsector)
|
||||
{
|
||||
// this case was not handled by Build:
|
||||
// If we hit an untagged one-sided wall it should both shorten the scan trace and clear all hits beyond.
|
||||
// Otherwise this may cause problems with some weirdly shaped sectors.
|
||||
result.hitSector = nullptr;
|
||||
result.hitWall = nullptr;
|
||||
result.hitpos.X = 0;
|
||||
v *= factor;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (foundsector) result.hitSector = nextsect;
|
||||
if (foundwall) result.hitWall = &wal;
|
||||
|
||||
if (foundwall || foundsector)
|
||||
{
|
||||
v *= factor;
|
||||
result.hitpos.X = v.XY().Length();
|
||||
}
|
||||
|
||||
if (wal.twoSided())
|
||||
{
|
||||
search.Add(nextsect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!(flags & NT_NoSpriteCheck))
|
||||
{
|
||||
TSectIterator<DCoreActor> it(sect);
|
||||
while (auto actor = it.Next())
|
||||
{
|
||||
if (actor->spr.cstat2 & CSTAT2_SPRITE_NOFIND)
|
||||
continue;
|
||||
|
||||
if (checkTag(&actor->spr))
|
||||
{
|
||||
DVector3 spot;
|
||||
if (intersectSprite(actor, pos, v, spot, 1 / 256.))
|
||||
{
|
||||
result.hitActor = actor;
|
||||
// return distance to sprite in a separate variable because there is
|
||||
// no means to determine what is for if both a sprite and wall are found.
|
||||
// Only SW's NearTagList actually uses it.
|
||||
result.hitpos.Y = (spot - pos).XY().Length();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
|
|
@ -263,6 +263,7 @@ bool calcChaseCamPos(DVector3& ppos, DCoreActor* pspr, sectortype** psectnum, DA
|
|||
int getslopeval(sectortype* sect, const DVector3& pos, double bazez);
|
||||
bool cansee(const DVector3& start, sectortype* sect1, const DVector3& end, sectortype* sect2);
|
||||
bool intersectSprite(DCoreActor* actor, const DVector3& start, const DVector3& end, DVector3& result, double displacement);
|
||||
void neartag(const DVector3& start, sectortype* sect, DAngle angle, HitInfoBase& result, double neartagrange, int tagsearch);
|
||||
|
||||
|
||||
|
||||
|
@ -584,15 +585,6 @@ inline double GetRayIntersect(const DVector3& start1, const DVector3& vect1, con
|
|||
return factor2;
|
||||
}
|
||||
|
||||
inline bool GetLineIntersect(const DVector3& start1, const DVector3& vect1, const DVector2& start2, const DVector2& vect2, DVector3& retv)
|
||||
{
|
||||
double factor = InterceptLineSegments(start1.X, start1.Y, vect1.X, vect1.Y, start2.X, start2.Y, vect2.X, vect2.Y);
|
||||
if (factor <= 0 || factor > 1) return false;
|
||||
retv = start1 + (factor) * vect1;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
inline void alignceilslope(sectortype* sect, const DVector3& pos)
|
||||
{
|
||||
sect->setceilingslope(getslopeval(sect, pos, sect->ceilingz));
|
||||
|
@ -657,25 +649,6 @@ inline int rintersect(int x1, int y1, int z1, int vx, int vy, int vz, int x3, in
|
|||
return FloatToFixed(result);
|
||||
}
|
||||
|
||||
[[deprecated]]
|
||||
inline int32_t lintersect(const int32_t originX, const int32_t originY, const int32_t originZ,
|
||||
const int32_t destX, const int32_t destY, const int32_t destZ,
|
||||
const int32_t lineStartX, const int32_t lineStartY, const int32_t lineEndX, const int32_t lineEndY,
|
||||
int32_t* intersectionX, int32_t* intersectionY, int32_t* intersectionZ)
|
||||
{
|
||||
DVector3 retv;
|
||||
bool result = GetLineIntersect(DVector3(originX * inttoworld, originY * inttoworld, originZ * zinttoworld),
|
||||
DVector3((destX - originX) * inttoworld, (destY - originY) * inttoworld, (destZ - originZ) * zinttoworld),
|
||||
DVector2(lineStartX * inttoworld, lineStartY * inttoworld), DVector2((lineEndX - lineStartX) * inttoworld, (lineEndY - lineStartY) * inttoworld), retv);
|
||||
if (result)
|
||||
{
|
||||
*intersectionX = retv.X * worldtoint;
|
||||
*intersectionY = retv.Y * worldtoint;
|
||||
*intersectionZ = retv.Z * zworldtoint;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
[[deprecated]]
|
||||
inline int cansee(int x1, int y1, int z1, sectortype* sect1, int x2, int y2, int z2, sectortype* sect2)
|
||||
{
|
||||
|
|
|
@ -2282,7 +2282,7 @@ void NearTagList(NEAR_TAG_INFO* ntip, PLAYER* pp, double z, double dist, int typ
|
|||
save_lotag = actor->spr.lotag;
|
||||
save_hitag = actor->spr.hitag;
|
||||
|
||||
ntip->Dist = near.hitpos.X;
|
||||
ntip->Dist = near.hitpos.Y;
|
||||
ntip->sectp = nullptr;
|
||||
ntip->wallp = nullptr;
|
||||
ntip->actor = actor;
|
||||
|
|
Loading…
Reference in a new issue