mirror of
https://github.com/bkaradzic/bx.git
synced 2026-06-08 03:03:48 +00:00
Implemented all bounds tests. (#380)
This commit is contained in:
committed by
GitHub
parent
cac72f6cfa
commit
b259cfbd3f
File diff suppressed because it is too large
Load Diff
@@ -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)
|
||||
|
||||
1149
include/bx/math.h
1149
include/bx/math.h
File diff suppressed because it is too large
Load Diff
345
src/bounds.cpp
345
src/bounds.cpp
@@ -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 =
|
||||
{
|
||||
|
||||
23
src/math.cpp
23
src/math.cpp
@@ -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
1024
tests/bounds_test.cpp
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user