Implemented all bounds tests. (#380)

This commit is contained in:
Branimir Karadžić
2026-04-04 21:51:34 -07:00
committed by GitHub
parent cac72f6cfa
commit b259cfbd3f
6 changed files with 3000 additions and 361 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -814,6 +814,11 @@ namespace bx
return result;
}
inline BX_CONSTEXPR_FUNC bool isNearZero(float _v)
{
return isEqual(_v, 0.0f, 0.00001f);
}
inline BX_CONSTEXPR_FUNC float wrap(float _a, float _wrap)
{
const float tmp0 = mod(_a, _wrap);
@@ -969,7 +974,7 @@ namespace bx
{
}
inline BX_CONSTEXPR_FUNC Vec3 round(const Vec3 _a)
inline BX_CONSTEXPR_FUNC Vec3 round(const Vec3& _a)
{
return
{
@@ -979,7 +984,7 @@ namespace bx
};
}
inline BX_CONSTEXPR_FUNC Vec3 abs(const Vec3 _a)
inline BX_CONSTEXPR_FUNC Vec3 abs(const Vec3& _a)
{
return
{
@@ -989,7 +994,7 @@ namespace bx
};
}
inline BX_CONSTEXPR_FUNC Vec3 neg(const Vec3 _a)
inline BX_CONSTEXPR_FUNC Vec3 neg(const Vec3& _a)
{
return
{
@@ -999,7 +1004,7 @@ namespace bx
};
}
inline BX_CONSTEXPR_FUNC Vec3 add(const Vec3 _a, const Vec3 _b)
inline BX_CONSTEXPR_FUNC Vec3 add(const Vec3& _a, const Vec3& _b)
{
return
{
@@ -1009,7 +1014,7 @@ namespace bx
};
}
inline BX_CONSTEXPR_FUNC Vec3 add(const Vec3 _a, float _b)
inline BX_CONSTEXPR_FUNC Vec3 add(const Vec3& _a, float _b)
{
return
{
@@ -1019,7 +1024,7 @@ namespace bx
};
}
inline BX_CONSTEXPR_FUNC Vec3 sub(const Vec3 _a, const Vec3 _b)
inline BX_CONSTEXPR_FUNC Vec3 sub(const Vec3& _a, const Vec3& _b)
{
return
{
@@ -1029,7 +1034,7 @@ namespace bx
};
}
inline BX_CONSTEXPR_FUNC Vec3 sub(const Vec3 _a, float _b)
inline BX_CONSTEXPR_FUNC Vec3 sub(const Vec3& _a, float _b)
{
return
{
@@ -1039,7 +1044,7 @@ namespace bx
};
}
inline BX_CONSTEXPR_FUNC Vec3 mul(const Vec3 _a, const Vec3 _b)
inline BX_CONSTEXPR_FUNC Vec3 mul(const Vec3& _a, const Vec3& _b)
{
return
{
@@ -1049,7 +1054,7 @@ namespace bx
};
}
inline BX_CONSTEXPR_FUNC Vec3 mul(const Vec3 _a, float _b)
inline BX_CONSTEXPR_FUNC Vec3 mul(const Vec3& _a, float _b)
{
return
{
@@ -1059,52 +1064,52 @@ namespace bx
};
}
inline BX_CONSTEXPR_FUNC Vec3 div(const Vec3 _a, const Vec3 _b)
inline BX_CONSTEXPR_FUNC Vec3 div(const Vec3& _a, const Vec3& _b)
{
return mul(_a, rcp(_b) );
}
inline BX_CONSTEXPR_FUNC Vec3 divSafe(const Vec3 _a, const Vec3 _b)
inline BX_CONSTEXPR_FUNC Vec3 divSafe(const Vec3& _a, const Vec3& _b)
{
return mul(_a, rcpSafe(_b) );
}
inline BX_CONSTEXPR_FUNC Vec3 div(const Vec3 _a, float _b)
inline BX_CONSTEXPR_FUNC Vec3 div(const Vec3& _a, float _b)
{
return mul(_a, rcp(_b) );
}
inline BX_CONSTEXPR_FUNC Vec3 divSafe(const Vec3 _a, float _b)
inline BX_CONSTEXPR_FUNC Vec3 divSafe(const Vec3& _a, float _b)
{
return mul(_a, rcpSafe(_b) );
}
inline BX_CONSTEXPR_FUNC Vec3 nms(const Vec3 _a, const float _b, const Vec3 _c)
inline BX_CONSTEXPR_FUNC Vec3 nms(const Vec3& _a, const float _b, const Vec3& _c)
{
return sub(_c, mul(_a, _b) );
}
inline BX_CONSTEXPR_FUNC Vec3 nms(const Vec3 _a, const Vec3 _b, const Vec3 _c)
inline BX_CONSTEXPR_FUNC Vec3 nms(const Vec3& _a, const Vec3& _b, const Vec3& _c)
{
return sub(_c, mul(_a, _b) );
}
inline BX_CONSTEXPR_FUNC Vec3 mad(const Vec3 _a, const float _b, const Vec3 _c)
inline BX_CONSTEXPR_FUNC Vec3 mad(const Vec3& _a, const float _b, const Vec3& _c)
{
return add(mul(_a, _b), _c);
}
inline BX_CONSTEXPR_FUNC Vec3 mad(const Vec3 _a, const Vec3 _b, const Vec3 _c)
inline BX_CONSTEXPR_FUNC Vec3 mad(const Vec3& _a, const Vec3& _b, const Vec3& _c)
{
return add(mul(_a, _b), _c);
}
inline BX_CONSTEXPR_FUNC float dot(const Vec3 _a, const Vec3 _b)
inline BX_CONSTEXPR_FUNC float dot(const Vec3& _a, const Vec3& _b)
{
return _a.x*_b.x + _a.y*_b.y + _a.z*_b.z;
}
inline BX_CONSTEXPR_FUNC Vec3 cross(const Vec3 _a, const Vec3 _b)
inline BX_CONSTEXPR_FUNC Vec3 cross(const Vec3& _a, const Vec3& _b)
{
return
{
@@ -1114,23 +1119,23 @@ namespace bx
};
}
inline BX_CONSTEXPR_FUNC float length(const Vec3 _a)
inline BX_CONSTEXPR_FUNC float length(const Vec3& _a)
{
return sqrt(dot(_a, _a) );
}
inline BX_CONSTEXPR_FUNC float distanceSq(const Vec3 _a, const Vec3 _b)
inline BX_CONSTEXPR_FUNC float distanceSq(const Vec3& _a, const Vec3& _b)
{
const Vec3 ba = sub(_b, _a);
return dot(ba, ba);
}
inline BX_CONSTEXPR_FUNC float distance(const Vec3 _a, const Vec3 _b)
inline BX_CONSTEXPR_FUNC float distance(const Vec3& _a, const Vec3& _b)
{
return length(sub(_b, _a) );
}
inline BX_CONSTEXPR_FUNC Vec3 lerp(const Vec3 _a, const Vec3 _b, float _t)
inline BX_CONSTEXPR_FUNC Vec3 lerp(const Vec3& _a, const Vec3& _b, float _t)
{
return
{
@@ -1140,7 +1145,7 @@ namespace bx
};
}
inline BX_CONSTEXPR_FUNC Vec3 lerp(const Vec3 _a, const Vec3 _b, const Vec3 _t)
inline BX_CONSTEXPR_FUNC Vec3 lerp(const Vec3& _a, const Vec3& _b, const Vec3& _t)
{
return
{
@@ -1150,14 +1155,14 @@ namespace bx
};
}
inline BX_CONSTEXPR_FUNC Vec3 normalize(const Vec3 _a)
inline BX_CONSTEXPR_FUNC Vec3 normalize(const Vec3& _a)
{
const float len = length(_a);
const Vec3 result = divSafe(_a, len);
return result;
}
inline BX_CONSTEXPR_FUNC Vec3 min(const Vec3 _a, const Vec3 _b)
inline BX_CONSTEXPR_FUNC Vec3 min(const Vec3& _a, const Vec3& _b)
{
return
{
@@ -1167,7 +1172,7 @@ namespace bx
};
}
inline BX_CONSTEXPR_FUNC Vec3 max(const Vec3 _a, const Vec3 _b)
inline BX_CONSTEXPR_FUNC Vec3 max(const Vec3& _a, const Vec3& _b)
{
return
{
@@ -1177,7 +1182,7 @@ namespace bx
};
}
inline BX_CONSTEXPR_FUNC Vec3 rcp(const Vec3 _a)
inline BX_CONSTEXPR_FUNC Vec3 rcp(const Vec3& _a)
{
return
{
@@ -1187,7 +1192,7 @@ namespace bx
};
}
inline BX_CONSTEXPR_FUNC Vec3 rcpSafe(const Vec3 _a)
inline BX_CONSTEXPR_FUNC Vec3 rcpSafe(const Vec3& _a)
{
return
{
@@ -1197,7 +1202,7 @@ namespace bx
};
}
inline BX_CONSTEXPR_FUNC bool isEqual(const Vec3 _a, const Vec3 _b, float _epsilon)
inline BX_CONSTEXPR_FUNC bool isEqual(const Vec3& _a, const Vec3& _b, float _epsilon)
{
return isEqual(_a.x, _b.x, _epsilon)
&& isEqual(_a.y, _b.y, _epsilon)
@@ -1205,7 +1210,12 @@ namespace bx
;
}
inline void calcTangentFrame(Vec3& _outT, Vec3& _outB, const Vec3 _n)
inline BX_CONSTEXPR_FUNC bool isNearZero(const Vec3& _v)
{
return isNearZero(dot(_v, _v) );
}
inline void calcTangentFrame(Vec3& _outT, Vec3& _outB, const Vec3& _n)
{
const float nx = _n.x;
const float ny = _n.y;
@@ -1229,7 +1239,7 @@ namespace bx
_outB = cross(_n, _outT);
}
inline void calcTangentFrame(Vec3& _outT, Vec3& _outB, const Vec3 _n, float _angle)
inline void calcTangentFrame(Vec3& _outT, Vec3& _outB, const Vec3& _n, float _angle)
{
calcTangentFrame(_outT, _outB, _n);
@@ -1261,7 +1271,7 @@ namespace bx
};
}
inline void toLatLong(float* _outU, float* _outV, const Vec3 _dir)
inline void toLatLong(float* _outU, float* _outV, const Vec3& _dir)
{
const float phi = atan2(_dir.x, _dir.z);
const float theta = acos(_dir.y);
@@ -1270,7 +1280,18 @@ namespace bx
*_outV = theta*kInvPi;
}
inline BX_CONSTEXPR_FUNC Quaternion invert(const Quaternion _a)
inline BX_CONSTEXPR_FUNC Quaternion neg(const Quaternion& _a)
{
return
{
-_a.x,
-_a.y,
-_a.z,
-_a.w,
};
}
inline BX_CONSTEXPR_FUNC Quaternion conjugate(const Quaternion& _a)
{
return
{
@@ -1281,7 +1302,7 @@ namespace bx
};
}
inline BX_CONSTEXPR_FUNC Vec3 mulXyz(const Quaternion _a, const Quaternion _b)
inline BX_CONSTEXPR_FUNC Vec3 mulXyz(const Quaternion& _a, const Quaternion& _b)
{
const float ax = _a.x;
const float ay = _a.y;
@@ -1301,7 +1322,7 @@ namespace bx
};
}
inline BX_CONSTEXPR_FUNC Quaternion add(const Quaternion _a, const Quaternion _b)
inline BX_CONSTEXPR_FUNC Quaternion add(const Quaternion& _a, const Quaternion& _b)
{
return
{
@@ -1312,7 +1333,7 @@ namespace bx
};
}
inline BX_CONSTEXPR_FUNC Quaternion sub(const Quaternion _a, const Quaternion _b)
inline BX_CONSTEXPR_FUNC Quaternion sub(const Quaternion& _a, const Quaternion& _b)
{
return
{
@@ -1323,7 +1344,7 @@ namespace bx
};
}
inline BX_CONSTEXPR_FUNC Quaternion mul(const Quaternion _a, float _b)
inline BX_CONSTEXPR_FUNC Quaternion mul(const Quaternion& _a, float _b)
{
return
{
@@ -1334,7 +1355,7 @@ namespace bx
};
}
inline BX_CONSTEXPR_FUNC Quaternion mul(const Quaternion _a, const Quaternion _b)
inline BX_CONSTEXPR_FUNC Quaternion mul(const Quaternion& _a, const Quaternion& _b)
{
const float ax = _a.x;
const float ay = _a.y;
@@ -1355,17 +1376,16 @@ namespace bx
};
}
inline BX_CONSTEXPR_FUNC Vec3 mul(const Vec3 _v, const Quaternion _q)
inline BX_CONSTEXPR_FUNC Vec3 mul(const Vec3& _v, const Quaternion& _q)
{
const Quaternion tmp0 = invert(_q);
const Quaternion qv = { _v.x, _v.y, _v.z, 0.0f };
const Quaternion tmp1 = mul(tmp0, qv);
const Vec3 result = mulXyz(tmp1, _q);
const Quaternion tmp0 = mul(_q, qv);
const Vec3 result = mulXyz(tmp0, conjugate(_q) );
return result;
}
inline BX_CONSTEXPR_FUNC float dot(const Quaternion _a, const Quaternion _b)
inline BX_CONSTEXPR_FUNC float dot(const Quaternion& _a, const Quaternion& _b)
{
return
_a.x * _b.x
@@ -1375,7 +1395,7 @@ namespace bx
;
}
inline BX_CONSTEXPR_FUNC Quaternion normalize(const Quaternion _a)
inline BX_CONSTEXPR_FUNC Quaternion normalize(const Quaternion& _a)
{
const float norm = dot(_a, _a);
if (0.0f < norm)
@@ -1394,7 +1414,7 @@ namespace bx
};
}
inline BX_CONSTEXPR_FUNC Quaternion lerp(const Quaternion _a, const Quaternion _b, float _t)
inline BX_CONSTEXPR_FUNC Quaternion lerp(const Quaternion& _a, const Quaternion& _b, float _t)
{
const float sa = 1.0f - _t;
const float adotb = dot(_a, _b);
@@ -1407,7 +1427,37 @@ namespace bx
return normalize(qq);
}
inline BX_CONST_FUNC Quaternion fromEuler(const Vec3 _euler)
inline BX_CONST_FUNC Quaternion slerp(const Quaternion& _a, const Quaternion& _b, float _t)
{
float cosTheta = dot(_a, _b);
Quaternion bb = _b;
if (cosTheta < 0.0f)
{
cosTheta = -cosTheta;
bb = neg(_b);
}
if (cosTheta > 0.9995f)
{
return lerp(_a, bb, _t);
}
const float theta = acos(cosTheta);
const float invSin = rcp(sin(theta) );
const float sa = sin( (1.0f - _t) * theta) * invSin;
const float sb = sin(_t * theta) * invSin;
return
{
_a.x * sa + bb.x * sb,
_a.y * sa + bb.y * sb,
_a.z * sa + bb.z * sb,
_a.w * sa + bb.w * sb,
};
}
inline BX_CONST_FUNC Quaternion fromEuler(const Vec3& _euler)
{
const float sx = sin(_euler.x * 0.5f);
const float cx = cos(_euler.x * 0.5f);
@@ -1425,7 +1475,7 @@ namespace bx
};
}
inline BX_CONST_FUNC Vec3 toEuler(const Quaternion _a)
inline BX_CONST_FUNC Vec3 toEuler(const Quaternion& _a)
{
const float xx = _a.x;
const float yy = _a.y;
@@ -1443,7 +1493,7 @@ namespace bx
};
}
inline BX_CONST_FUNC Vec3 toXAxis(const Quaternion _a)
inline BX_CONST_FUNC Vec3 toXAxis(const Quaternion& _a)
{
const float xx = _a.x;
const float yy = _a.y;
@@ -1460,7 +1510,7 @@ namespace bx
};
}
inline BX_CONST_FUNC Vec3 toYAxis(const Quaternion _a)
inline BX_CONST_FUNC Vec3 toYAxis(const Quaternion& _a)
{
const float xx = _a.x;
const float yy = _a.y;
@@ -1477,7 +1527,7 @@ namespace bx
};
}
inline BX_CONST_FUNC Vec3 toZAxis(const Quaternion _a)
inline BX_CONST_FUNC Vec3 toZAxis(const Quaternion& _a)
{
const float xx = _a.x;
const float yy = _a.y;
@@ -1494,7 +1544,7 @@ namespace bx
};
}
inline BX_CONST_FUNC Quaternion fromAxisAngle(const Vec3 _axis, float _angle)
inline BX_CONST_FUNC Quaternion fromAxisAngle(const Vec3& _axis, float _angle)
{
const float ha = _angle * 0.5f;
const float sa = sin(ha);
@@ -1508,7 +1558,7 @@ namespace bx
};
}
inline void toAxisAngle(Vec3& _outAxis, float& _outAngle, const Quaternion _a)
inline void toAxisAngle(Vec3& _outAxis, float& _outAngle, const Quaternion& _a)
{
const float ww = _a.w;
const float sa = sqrt(1.0f - square(ww) );
@@ -1565,7 +1615,7 @@ namespace bx
};
}
inline BX_CONSTEXPR_FUNC bool isEqual(const Quaternion _a, const Quaternion _b, float _epsilon)
inline BX_CONSTEXPR_FUNC bool isEqual(const Quaternion& _a, const Quaternion& _b, float _epsilon)
{
return isEqual(_a.x, _b.x, _epsilon)
&& isEqual(_a.y, _b.y, _epsilon)

File diff suppressed because it is too large Load Diff

View File

@@ -72,7 +72,7 @@ namespace bx
const Vec3 nsq = mul(_disk.normal, _disk.normal);
const Vec3 one = { 1.0f, 1.0f, 1.0f };
const Vec3 tmp = sub(one, nsq);
const float inv = 1.0f / (tmp.x*tmp.y*tmp.z);
const float inv = rcpSafe(tmp.x*tmp.y*tmp.z);
const Vec3 extent =
{
@@ -425,7 +425,7 @@ namespace bx
bool intersect(const Ray& _ray, const Aabb& _aabb, Hit* _hit)
{
const Vec3 invDir = rcp(_ray.dir);
const Vec3 invDir = rcpSafe(_ray.dir);
const Vec3 tmp0 = sub(_aabb.min, _ray.pos);
const Vec3 t0 = mul(tmp0, invDir);
const Vec3 tmp1 = sub(_aabb.max, _ray.pos);
@@ -933,7 +933,7 @@ namespace bx
sqrt(zx*zx + zy*zy + zz*zz),
};
const Vec3 invScale = rcp(result.scale);
const Vec3 invScale = rcpSafe(result.scale);
xx *= invScale.x;
xy *= invScale.x;
@@ -1010,16 +1010,6 @@ namespace bx
store<Vec3>(&_outMtx[12], _srt.translation);
}
bool isNearZero(float _v)
{
return isEqual(_v, 0.0f, 0.00001f);
}
bool isNearZero(const Vec3& _v)
{
return isNearZero(dot(_v, _v) );
}
bool intersect(Line& _outLine, const Plane& _planeA, const Plane& _planeB)
{
const Vec3 axb = cross(_planeA.normal, _planeB.normal);
@@ -1158,7 +1148,7 @@ namespace bx
{
const Vec3 axis = sub(_line.end, _line.pos);
const float lengthSq = dot(axis, axis);
const float tt = clamp(projectToAxis(axis, sub(_point, _line.pos) ) / lengthSq, 0.0f, 1.0f);
const float tt = clamp(divSafe(projectToAxis(axis, sub(_point, _line.pos) ), lengthSq), 0.0f, 1.0f);
_outT = tt;
return mad(axis, tt, _line.pos);
}
@@ -1169,6 +1159,59 @@ namespace bx
return closestPoint(_line, _point, ignored);
}
void closestPoint(const LineSegment& _a, const LineSegment& _b, float& _outS, float& _outT)
{
const Vec3 d1 = sub(_a.end, _a.pos);
const Vec3 d2 = sub(_b.end, _b.pos);
const Vec3 r = sub(_a.pos, _b.pos);
const float a = dot(d1, d1);
const float e = dot(d2, d2);
const float f = dot(d2, r);
if (a <= kFloatSmallest && e <= kFloatSmallest)
{
_outS = _outT = 0.0f;
return;
}
if (a <= kFloatSmallest)
{
_outS = 0.0f;
_outT = clamp(divSafe(f, e), 0.0f, 1.0f);
return;
}
const float c = dot(d1, r);
if (e <= kFloatSmallest)
{
_outT = 0.0f;
_outS = clamp(divSafe(-c, a), 0.0f, 1.0f);
return;
}
const float b = dot(d1, d2);
const float denom = a * e - b * b;
_outS = (denom > kFloatSmallest)
? clamp(divSafe(b * f - c * e, denom), 0.0f, 1.0f)
: 0.0f
;
_outT = divSafe(b * _outS + f, e);
if (_outT < 0.0f)
{
_outT = 0.0f;
_outS = clamp(divSafe(-c, a), 0.0f, 1.0f);
}
else if (_outT > 1.0f)
{
_outT = 1.0f;
_outS = clamp(divSafe(b - c, a), 0.0f, 1.0f);
}
}
Vec3 closestPoint(const Plane& _plane, const Vec3& _point)
{
const float dist = distance(_plane, _point);
@@ -1187,11 +1230,21 @@ namespace bx
Aabb aabb;
toAabb(aabb, srt.scale);
const Quaternion invRotation = invert(srt.rotation);
const Vec3 obbSpacePos = mul(sub(_point, srt.translation), srt.rotation);
const Vec3 obbSpacePos = mul(sub(_point, srt.translation), conjugate(srt.rotation) );
const Vec3 pos = closestPoint(aabb, obbSpacePos);
return add(mul(pos, invRotation), srt.translation);
return add(mul(pos, srt.rotation), srt.translation);
}
Vec3 closestPoint(const Vec3& _center, const Vec3& _halfExtents, const Quaternion& _rotation, const Vec3& _point)
{
const Vec3 local = mul(sub(_point, _center), conjugate(_rotation) );
const Vec3 clamped = {
clamp(local.x, -_halfExtents.x, _halfExtents.x),
clamp(local.y, -_halfExtents.y, _halfExtents.y),
clamp(local.z, -_halfExtents.z, _halfExtents.z),
};
return add(_center, mul(clamped, _rotation) );
}
Vec3 closestPoint(const Triangle& _triangle, const Vec3& _point)
@@ -1465,32 +1518,89 @@ namespace bx
bool overlap(const Cone& _cone, const Cylinder& _cylinder)
{
BX_UNUSED(_cone, _cylinder);
return false;
float ta, tb;
if (!intersect(ta, tb, {_cone.pos, _cone.end}, {_cylinder.pos, _cylinder.end}) )
{
return false;
}
ta = clamp(ta, 0.0f, 1.0f);
tb = clamp(tb, 0.0f, 1.0f);
const Vec3 coneAxis = sub(_cone.end, _cone.pos);
const Vec3 cylAxis = sub(_cylinder.end, _cylinder.pos);
const Vec3 pa = mad(coneAxis, ta, _cone.pos);
const Vec3 pb = mad(cylAxis, tb, _cylinder.pos);
const float dist = distance(pa, pb);
return dist <= lerp(_cone.radius, 0.0f, ta) + _cylinder.radius;
}
bool overlap(const Cone& _cone, const Capsule& _capsule)
{
BX_UNUSED(_cone, _capsule);
return false;
float ta, tb;
if (!intersect(ta, tb, {_cone.pos, _cone.end}, {_capsule.pos, _capsule.end}) )
{
return false;
}
ta = clamp(ta, 0.0f, 1.0f);
tb = clamp(tb, 0.0f, 1.0f);
const Vec3 coneAxis = sub(_cone.end, _cone.pos);
const Vec3 capAxis = sub(_capsule.end, _capsule.pos);
const Vec3 pa = mad(coneAxis, ta, _cone.pos);
const Vec3 pb = mad(capAxis, tb, _capsule.pos);
const float dist = distance(pa, pb);
return dist <= lerp(_cone.radius, 0.0f, ta) + _capsule.radius;
}
bool overlap(const Cone& _coneA, const Cone& _coneB)
{
BX_UNUSED(_coneA, _coneB);
return false;
float ta, tb;
if (!intersect(ta, tb, {_coneA.pos, _coneA.end}, {_coneB.pos, _coneB.end}) )
{
return false;
}
ta = clamp(ta, 0.0f, 1.0f);
tb = clamp(tb, 0.0f, 1.0f);
const Vec3 axisA = sub(_coneA.end, _coneA.pos);
const Vec3 axisB = sub(_coneB.end, _coneB.pos);
const Vec3 pa = mad(axisA, ta, _coneA.pos);
const Vec3 pb = mad(axisB, tb, _coneB.pos);
const float dist = distance(pa, pb);
return dist <= lerp(_coneA.radius, 0.0f, ta) + lerp(_coneB.radius, 0.0f, tb);
}
bool overlap(const Cone& _cone, const Disk& _disk)
{
BX_UNUSED(_cone, _disk);
return false;
float tt;
const Vec3 pos = closestPoint(LineSegment{_cone.pos, _cone.end}, _disk.center, tt);
const float coneRadius = lerp(_cone.radius, 0.0f, tt);
return overlap(Disk{pos, normalize(sub(_cone.end, _cone.pos) ), coneRadius}, _disk);
}
bool overlap(const Cone& _cone, const Obb& _obb)
{
BX_UNUSED(_cone, _obb);
return false;
const Srt srt = toSrt(_obb.mtx);
Aabb aabb;
toAabb(aabb, srt.scale);
const Quaternion invRotation = conjugate(srt.rotation);
const Cone cone =
{
mul(sub(_cone.pos, srt.translation), invRotation),
mul(sub(_cone.end, srt.translation), invRotation),
_cone.radius,
};
return overlap(aabb, cone);
}
bool overlap(const Cylinder& _cylinder, const Vec3& _pos)
@@ -1513,32 +1623,86 @@ namespace bx
bool overlap(const Cylinder& _cylinder, const Plane& _plane)
{
BX_UNUSED(_cylinder, _plane);
return false;
const float distPos = distance(_plane, _cylinder.pos);
const float distEnd = distance(_plane, _cylinder.end);
if (distPos * distEnd < 0.0f)
{
return true;
}
const Vec3 axis = sub(_cylinder.end, _cylinder.pos);
const float lenSq = dot(axis, axis);
const float cosA = (lenSq > 0.0f) ? dot(axis, _plane.normal) / sqrt(lenSq) : 0.0f;
const float sinA = sqrt(max(0.0f, 1.0f - cosA * cosA) );
const float diskExt = _cylinder.radius * sinA;
return min(abs(distPos), abs(distEnd) ) <= diskExt;
}
bool overlap(const Cylinder& _cylinderA, const Cylinder& _cylinderB)
{
BX_UNUSED(_cylinderA, _cylinderB);
return false;
float ta, tb;
if (!intersect(ta, tb, {_cylinderA.pos, _cylinderA.end}, {_cylinderB.pos, _cylinderB.end}) )
{
return false;
}
ta = clamp(ta, 0.0f, 1.0f);
tb = clamp(tb, 0.0f, 1.0f);
const Vec3 axisA = sub(_cylinderA.end, _cylinderA.pos);
const Vec3 axisB = sub(_cylinderB.end, _cylinderB.pos);
const Vec3 pa = mad(axisA, ta, _cylinderA.pos);
const Vec3 pb = mad(axisB, tb, _cylinderB.pos);
const float dist = distance(pa, pb);
return dist <= _cylinderA.radius + _cylinderB.radius;
}
bool overlap(const Cylinder& _cylinder, const Capsule& _capsule)
{
BX_UNUSED(_cylinder, _capsule);
return false;
float ta, tb;
if (!intersect(ta, tb, {_cylinder.pos, _cylinder.end}, {_capsule.pos, _capsule.end}) )
{
return false;
}
ta = clamp(ta, 0.0f, 1.0f);
tb = clamp(tb, 0.0f, 1.0f);
const Vec3 cylAxis = sub(_cylinder.end, _cylinder.pos);
const Vec3 capAxis = sub(_capsule.end, _capsule.pos);
const Vec3 pa = mad(cylAxis, ta, _cylinder.pos);
const Vec3 pb = mad(capAxis, tb, _capsule.pos);
const float dist = distance(pa, pb);
return dist <= _cylinder.radius + _capsule.radius;
}
bool overlap(const Cylinder& _cylinder, const Disk& _disk)
{
BX_UNUSED(_cylinder, _disk);
return false;
const Vec3 pos = closestPoint(LineSegment{_cylinder.pos, _cylinder.end}, _disk.center);
return overlap(Disk{pos, normalize(sub(_cylinder.end, _cylinder.pos) ), _cylinder.radius}, _disk);
}
bool overlap(const Cylinder& _cylinder, const Obb& _obb)
{
BX_UNUSED(_cylinder, _obb);
return false;
const Srt srt = toSrt(_obb.mtx);
Aabb aabb;
toAabb(aabb, srt.scale);
const Quaternion invRotation = conjugate(srt.rotation);
const Cylinder cylinder =
{
mul(sub(_cylinder.pos, srt.translation), invRotation),
mul(sub(_cylinder.end, srt.translation), invRotation),
_cylinder.radius,
};
return overlap(cylinder, aabb);
}
bool overlap(const Disk& _disk, const Vec3& _pos)
@@ -1622,27 +1786,30 @@ namespace bx
bool overlap(const Obb& _obb, const Vec3& _pos)
{
const Srt srt = toSrt(_obb.mtx);
const float* mtx = _obb.mtx;
Aabb aabb;
toAabb(aabb, srt.scale);
const Vec3 center = { mtx[12], mtx[13], mtx[14] };
const Vec3 d = sub(_pos, center);
const Quaternion invRotation = invert(srt.rotation);
const Vec3 pos = mul(sub(_pos, srt.translation), invRotation);
const Vec3 ax = { mtx[ 0], mtx[ 1], mtx[ 2] };
const Vec3 ay = { mtx[ 4], mtx[ 5], mtx[ 6] };
const Vec3 az = { mtx[ 8], mtx[ 9], mtx[10] };
return overlap(aabb, pos);
return abs(dot(d, ax) ) <= dot(ax, ax)
&& abs(dot(d, ay) ) <= dot(ay, ay)
&& abs(dot(d, az) ) <= dot(az, az)
;
}
bool overlap(const Obb& _obb, const Plane& _plane)
{
const Srt srt = toSrt(_obb.mtx);
const Quaternion invRotation = invert(srt.rotation);
const Vec3 axis =
{
projectToAxis(_plane.normal, mul(Vec3{1.0f, 0.0f, 0.0f}, invRotation) ),
projectToAxis(_plane.normal, mul(Vec3{0.0f, 1.0f, 0.0f}, invRotation) ),
projectToAxis(_plane.normal, mul(Vec3{0.0f, 0.0f, 1.0f}, invRotation) ),
projectToAxis(_plane.normal, mul(Vec3{1.0f, 0.0f, 0.0f}, srt.rotation) ),
projectToAxis(_plane.normal, mul(Vec3{0.0f, 1.0f, 0.0f}, srt.rotation) ),
projectToAxis(_plane.normal, mul(Vec3{0.0f, 0.0f, 1.0f}, srt.rotation) ),
};
const float dist = abs(distance(_plane, srt.translation) );
@@ -1658,7 +1825,7 @@ namespace bx
Aabb aabb;
toAabb(aabb, srt.scale);
const Quaternion invRotation = invert(srt.rotation);
const Quaternion invRotation = conjugate(srt.rotation);
const Capsule capsule =
{
@@ -1926,7 +2093,8 @@ namespace bx
{
return overlap(_ty, pa0);
}
else if (d1 <= d2)
if (d1 <= d2)
{
return overlap(_ty, pa1);
}
@@ -1946,62 +2114,47 @@ namespace bx
bool overlap(const Triangle& _triangle, const Cone& _cone)
{
const LineSegment ab = LineSegment{_triangle.v0, _triangle.v1};
const LineSegment bc = LineSegment{_triangle.v1, _triangle.v2};
const LineSegment ca = LineSegment{_triangle.v2, _triangle.v0};
const LineSegment line =
if (overlap(_cone, _triangle.v0)
|| overlap(_cone, _triangle.v1)
|| overlap(_cone, _triangle.v2) )
{
_cone.pos,
_cone.end,
return true;
}
const LineSegment axis = { _cone.pos, _cone.end };
const LineSegment edges[3] =
{
{ _triangle.v0, _triangle.v1 },
{ _triangle.v1, _triangle.v2 },
{ _triangle.v2, _triangle.v0 },
};
float ta0 = 0.0f, tb0 = 0.0f;
const bool i0 = intersect(ta0, tb0, ab, line);
float ta1, tb1;
const bool i1 = intersect(ta1, tb1, bc, line);
float ta2, tb2;
const bool i2 = intersect(ta2, tb2, ca, line);
if (!i0
|| !i1
|| !i2)
for (uint32_t ii = 0; ii < 3; ++ii)
{
return false;
float sa, sb;
closestPoint(edges[ii], axis, sa, sb);
const Vec3 pa = getPointAt(edges[ii], sa);
if (overlap(_cone, pa) )
{
return true;
}
}
ta0 = clamp(ta0, 0.0f, 1.0f);
ta1 = clamp(ta1, 0.0f, 1.0f);
ta2 = clamp(ta2, 0.0f, 1.0f);
tb0 = clamp(tb0, 0.0f, 1.0f);
tb1 = clamp(tb1, 0.0f, 1.0f);
tb2 = clamp(tb2, 0.0f, 1.0f);
const Vec3 cp = closestPoint(_triangle, _cone.pos);
const Vec3 pa0 = getPointAt(ab, ta0);
const Vec3 pa1 = getPointAt(bc, ta1);
const Vec3 pa2 = getPointAt(ca, ta2);
const Vec3 pb0 = getPointAt(line, tb0);
const Vec3 pb1 = getPointAt(line, tb1);
const Vec3 pb2 = getPointAt(line, tb2);
const float d0 = distanceSq(pa0, pb0);
const float d1 = distanceSq(pa1, pb1);
const float d2 = distanceSq(pa2, pb2);
if (d0 <= d1
&& d0 <= d2)
if (overlap(_cone, cp) )
{
return overlap(_cone, pa0);
}
else if (d1 <= d2)
{
return overlap(_cone, pa1);
return true;
}
return overlap(_cone, pa2);
const Vec3 ce = closestPoint(_triangle, _cone.end);
if (overlap(_cone, ce) )
{
return true;
}
return false;
}
bool overlap(const Triangle& _triangle, const Disk& _disk)
@@ -2024,7 +2177,7 @@ namespace bx
Aabb aabb;
toAabb(aabb, srt.scale);
const Quaternion invRotation = invert(srt.rotation);
const Quaternion invRotation = conjugate(srt.rotation);
const Triangle triangle =
{

View File

@@ -273,8 +273,8 @@ namespace bx
memSet(_result, 0, sizeof(float)*16);
_result[ 0] = cy*cz;
_result[ 1] = cz*sx*sy-cx*sz;
_result[ 2] = cx*cz*sy+sx*sz;
_result[ 1] = cz*sx*sy - cx*sz;
_result[ 2] = cx*cz*sy + sx*sz;
_result[ 4] = cy*sz;
_result[ 5] = cx*cz + sx*sy*sz;
_result[ 6] = -cz*sx + cx*sy*sz;
@@ -293,21 +293,18 @@ namespace bx
const float sz = sin(_az);
const float cz = cos(_az);
const float sxsz = sx*sz;
const float cycz = cy*cz;
_result[ 0] = _sx * (cycz - sxsz*sy);
_result[ 1] = _sx * -cx*sz;
_result[ 2] = _sx * (cz*sy + cy*sxsz);
_result[ 0] = _sx * cy*cz;
_result[ 1] = _sx * (cz*sx*sy - cx*sz);
_result[ 2] = _sx * (cx*cz*sy + sx*sz);
_result[ 3] = 0.0f;
_result[ 4] = _sy * (cz*sx*sy + cy*sz);
_result[ 5] = _sy * cx*cz;
_result[ 6] = _sy * (sy*sz -cycz*sx);
_result[ 4] = _sy * cy*sz;
_result[ 5] = _sy * (cx*cz + sx*sy*sz);
_result[ 6] = _sy * (-cz*sx + cx*sy*sz);
_result[ 7] = 0.0f;
_result[ 8] = _sz * -cx*sy;
_result[ 9] = _sz * sx;
_result[ 8] = _sz * -sy;
_result[ 9] = _sz * cy*sx;
_result[10] = _sz * cx*cy;
_result[11] = 0.0f;

1024
tests/bounds_test.cpp Normal file

File diff suppressed because it is too large Load Diff