mirror of
https://github.com/ZDoom/Raze.git
synced 2025-04-01 05:30:38 +00:00
- redid lintersect with backend utilities.
I left out EDuke32's new handling for collinear traces because it not only was never active but also makes really no sense with neartag which is lintersect's only caller.
This commit is contained in:
parent
95cd74bdc0
commit
14a8dd451e
2 changed files with 28 additions and 83 deletions
|
@ -59,89 +59,6 @@ void engineInit(void)
|
|||
|
||||
}
|
||||
|
||||
//
|
||||
// lintersect (internal)
|
||||
//
|
||||
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)
|
||||
{
|
||||
const vec2_t ray = { destX-originX,
|
||||
destY-originY };
|
||||
const vec2_t lineVec = { lineEndX-lineStartX,
|
||||
lineEndY-lineStartY };
|
||||
const vec2_t originDiff = { lineStartX-originX,
|
||||
lineStartY-originY };
|
||||
|
||||
const int32_t rayCrossLineVec = ray.X*lineVec.Y - ray.Y*lineVec.X;
|
||||
const int32_t originDiffCrossRay = originDiff.X*ray.Y - originDiff.Y*ray.X;
|
||||
|
||||
if (rayCrossLineVec == 0)
|
||||
{
|
||||
if (originDiffCrossRay != 0 || enginecompatibility_mode != ENGINECOMPATIBILITY_NONE)
|
||||
{
|
||||
// line segments are parallel
|
||||
return 0;
|
||||
}
|
||||
|
||||
// line segments are collinear
|
||||
const int32_t rayLengthSquared = ray.X*ray.X + ray.Y*ray.Y;
|
||||
const int32_t rayDotOriginDiff = ray.X*originDiff.X + ray.Y*originDiff.Y;
|
||||
const int32_t rayDotLineEndDiff = rayDotOriginDiff + ray.X*lineVec.X + ray.Y*lineVec.Y;
|
||||
int64_t t = min(rayDotOriginDiff, rayDotLineEndDiff);
|
||||
if (rayDotOriginDiff < 0)
|
||||
{
|
||||
if (rayDotLineEndDiff < 0)
|
||||
return 0;
|
||||
|
||||
t = 0;
|
||||
}
|
||||
else if (rayDotOriginDiff > rayLengthSquared)
|
||||
{
|
||||
if (rayDotLineEndDiff > rayLengthSquared)
|
||||
return 0;
|
||||
|
||||
t = rayDotLineEndDiff;
|
||||
}
|
||||
t = (t << 24) / rayLengthSquared;
|
||||
|
||||
*intersectionX = originX + MulScale(ray.X, t, 24);
|
||||
*intersectionY = originY + MulScale(ray.Y, t, 24);
|
||||
*intersectionZ = originZ + MulScale(destZ-originZ, t, 24);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
const int32_t originDiffCrossLineVec = originDiff.X*lineVec.Y - originDiff.Y*lineVec.X;
|
||||
static const int32_t signBit = 1u<<31u;
|
||||
// Any point on either line can be expressed as p+t*r and q+u*s
|
||||
// The two line segments intersect when we can find a t & u such that p+t*r = q+u*s
|
||||
// If the point is outside of the bounds of the line segment, we know we don't have an intersection.
|
||||
// t is < 0 if (originDiffCrossLineVec^rayCrossLineVec) & signBit)
|
||||
// u is < 0 if (originDiffCrossRay^rayCrossLineVec) & signBit
|
||||
// t is > 1 if abs(originDiffCrossLineVec) > abs(rayCrossLineVec)
|
||||
// u is > 1 if abs(originDiffCrossRay) > abs(rayCrossLineVec)
|
||||
// where int32_t u = tabledivide64(((int64_t) originDiffCrossRay) << 24L, rayCrossLineVec);
|
||||
if (((originDiffCrossLineVec^rayCrossLineVec) & signBit) ||
|
||||
((originDiffCrossRay^rayCrossLineVec) & signBit) ||
|
||||
abs(originDiffCrossLineVec) > abs(rayCrossLineVec) ||
|
||||
abs(originDiffCrossRay) > abs(rayCrossLineVec))
|
||||
{
|
||||
// line segments do not overlap
|
||||
return 0;
|
||||
}
|
||||
|
||||
int64_t t = (int64_t(originDiffCrossLineVec) << 24) / rayCrossLineVec;
|
||||
// For sake of completeness/readability, alternative to the above approach for an early out & avoidance of an extra division:
|
||||
|
||||
*intersectionX = originX + MulScale(ray.X, t, 24);
|
||||
*intersectionY = originY + MulScale(ray.Y, t, 24);
|
||||
*intersectionZ = originZ + MulScale(destZ-originZ, t, 24);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//
|
||||
// cansee
|
||||
//
|
||||
|
|
|
@ -574,6 +574,14 @@ 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)
|
||||
{
|
||||
|
@ -639,5 +647,25 @@ 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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#include "updatesector.h"
|
||||
|
|
Loading…
Reference in a new issue