- rewrite from scratch of neartag.

This commit is contained in:
Christoph Oelckers 2022-09-25 10:57:46 +02:00
parent 600648939a
commit ef2f781e09
5 changed files with 90 additions and 126 deletions

View file

@ -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;

View file

@ -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)
{

View file

@ -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();
}
}
}
}
}
}
//==========================================================================
//

View file

@ -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)
{

View file

@ -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;