From 23994e7f23ec82769735bce6efa5c3d7aa126df8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D1=80=D0=B0=D0=BD=D0=B8=D0=BC=D0=B8=D1=80=20=D0=9A?= =?UTF-8?q?=D0=B0=D1=80=D0=B0=D1=9F=D0=B8=D1=9B?= Date: Sat, 25 Sep 2021 19:20:06 -0700 Subject: [PATCH] Bounds: Overlap aabb/obb, and obb/obb. --- examples/common/bounds.cpp | 144 ++++++++++++++++++++++++++++++++----- 1 file changed, 128 insertions(+), 16 deletions(-) diff --git a/examples/common/bounds.cpp b/examples/common/bounds.cpp index 3a249f197..514ee6da9 100644 --- a/examples/common/bounds.cpp +++ b/examples/common/bounds.cpp @@ -866,6 +866,30 @@ void calcPlane(Plane& _outPlane, const Triangle& _triangle) struct Interval { + Interval(float _val) + : start(_val) + , end(_val) + { + } + + Interval(float _start, float _end) + : start(_start) + , end(_end) + { + } + + void set(float _val) + { + start = _val; + end = _val; + } + + void expand(float _val) + { + start = min(_val, start); + end = max(_val, end); + } + float start; float end; }; @@ -882,10 +906,22 @@ float projectToAxis(const Vec3& _axis, const Vec3& _point) return dot(_axis, _point); } +Interval projectToAxis(const Vec3& _axis, const Vec3* _points, uint32_t _num) +{ + Interval interval(projectToAxis(_axis, _points[0]) ); + + for (uint32_t ii = 1; ii < _num; ++ii) + { + interval.expand(projectToAxis(_axis, _points[ii]) ); + } + + return interval; +} + Interval projectToAxis(const Vec3& _axis, const Aabb& _aabb) { - const float extent = bx::abs(dot(abs(_axis), getExtents(_aabb) ) ); - const float center = dot( _axis , getCenter (_aabb) ); + const float extent = bx::abs(projectToAxis(abs(_axis), getExtents(_aabb) ) ); + const float center = projectToAxis( _axis , getCenter (_aabb) ); return { center - extent, @@ -895,9 +931,9 @@ Interval projectToAxis(const Vec3& _axis, const Aabb& _aabb) Interval projectToAxis(const Vec3& _axis, const Triangle& _triangle) { - const float a0 = dot(_axis, _triangle.v0); - const float a1 = dot(_axis, _triangle.v1); - const float a2 = dot(_axis, _triangle.v2); + const float a0 = projectToAxis(_axis, _triangle.v0); + const float a1 = projectToAxis(_axis, _triangle.v1); + const float a2 = projectToAxis(_axis, _triangle.v2); return { min(a0, a1, a2), @@ -912,6 +948,11 @@ struct Srt Vec3 scale = init::Zero; }; +Srt toSrt(const Aabb& _aabb) +{ + return { init::Identity, getCenter(_aabb), getExtents(_aabb) }; +} + Srt toSrt(const void* _mtx) { Srt result; @@ -1208,7 +1249,7 @@ Vec3 closestPoint(const Aabb& _aabb, const Vec3& _point) Vec3 closestPoint(const Obb& _obb, const Vec3& _point) { - Srt srt = toSrt(_obb.mtx); + const Srt srt = toSrt(_obb.mtx); Aabb aabb; toAabb(aabb, srt.scale); @@ -1246,12 +1287,9 @@ bool overlap(const Aabb& _aabb, const Vec3& _pos) bool overlap(const Aabb& _aabbA, const Aabb& _aabbB) { return true - && _aabbA.max.x > _aabbB.min.x - && _aabbB.max.x > _aabbA.min.x - && _aabbA.max.y > _aabbB.min.y - && _aabbB.max.y > _aabbA.min.y - && _aabbA.max.z > _aabbB.min.z - && _aabbB.max.z > _aabbA.min.z + && overlap(Interval{_aabbA.min.x, _aabbA.max.x}, Interval{_aabbB.min.x, _aabbB.max.x}) + && overlap(Interval{_aabbA.min.y, _aabbA.max.y}, Interval{_aabbB.min.y, _aabbB.max.y}) + && overlap(Interval{_aabbA.min.z, _aabbA.max.z}, Interval{_aabbB.min.z, _aabbB.max.z}) ; } @@ -1349,10 +1387,82 @@ bool overlap(const Aabb& _aabb, const Disk& _disk) return overlap(_aabb, plane); } +static void calcObbVertices( + bx::Vec3* _outVertices + , const bx::Vec3& _axisX + , const bx::Vec3& _axisY + , const bx::Vec3& _axisZ + , const bx::Vec3& _pos + , const bx::Vec3& _scale + ) +{ + const Vec3 ax = mul(_axisX, _scale.x); + const Vec3 ay = mul(_axisY, _scale.y); + const Vec3 az = mul(_axisZ, _scale.z); + + const Vec3 ppx = add(_pos, ax); + const Vec3 pmx = sub(_pos, ax); + const Vec3 ypz = add(ay, az); + const Vec3 ymz = sub(ay, az); + + _outVertices[0] = sub(pmx, ymz); + _outVertices[1] = sub(ppx, ymz); + _outVertices[2] = add(ppx, ymz); + _outVertices[3] = add(pmx, ymz); + _outVertices[4] = sub(pmx, ypz); + _outVertices[5] = sub(ppx, ypz); + _outVertices[6] = add(ppx, ypz); + _outVertices[7] = add(pmx, ypz); +} + +static bool overlaps(const Vec3& _axis, const Vec3* _vertsA, const Vec3* _vertsB) +{ + Interval ia = projectToAxis(_axis, _vertsA, 8); + Interval ib = projectToAxis(_axis, _vertsB, 8); + + return overlap(ia, ib); +} + +static bool overlap(const Srt& _srtA, const Srt& _srtB) +{ + const Vec3 ax = toXAxis(_srtA.rotation); + const Vec3 ay = toYAxis(_srtA.rotation); + const Vec3 az = toZAxis(_srtA.rotation); + + const Vec3 bx = toXAxis(_srtB.rotation); + const Vec3 by = toYAxis(_srtB.rotation); + const Vec3 bz = toZAxis(_srtB.rotation); + + Vec3 vertsA[8] = { init::None, init::None, init::None, init::None, init::None, init::None, init::None, init::None }; + calcObbVertices(vertsA, ax, ay, az, init::Zero, _srtA.scale); + + Vec3 vertsB[8] = { init::None, init::None, init::None, init::None, init::None, init::None, init::None, init::None }; + calcObbVertices(vertsB, bx, by, bz, sub(_srtB.translation, _srtA.translation), _srtB.scale); + + return overlaps(ax, vertsA, vertsB) + && overlaps(ay, vertsA, vertsB) + && overlaps(az, vertsA, vertsB) + && overlaps(bx, vertsA, vertsB) + && overlaps(by, vertsA, vertsB) + && overlaps(bz, vertsA, vertsB) + && overlaps(cross(ax, bx), vertsA, vertsB) + && overlaps(cross(ax, by), vertsA, vertsB) + && overlaps(cross(ax, bz), vertsA, vertsB) + && overlaps(cross(ay, bx), vertsA, vertsB) + && overlaps(cross(ay, by), vertsA, vertsB) + && overlaps(cross(ay, bz), vertsA, vertsB) + && overlaps(cross(az, bx), vertsA, vertsB) + && overlaps(cross(az, by), vertsA, vertsB) + && overlaps(cross(az, bz), vertsA, vertsB) + ; +} + bool overlap(const Aabb& _aabb, const Obb& _obb) { - BX_UNUSED(_aabb, _obb); - return false; + const Srt srtA = toSrt(_aabb); + const Srt srtB = toSrt(_obb.mtx); + + return overlap(srtA, srtB); } bool overlap(const Capsule& _capsule, const Vec3& _pos) @@ -1629,8 +1739,10 @@ bool overlap(const Obb& _obb, const Capsule& _capsule) bool overlap(const Obb& _obbA, const Obb& _obbB) { - BX_UNUSED(_obbA, _obbB); - return false; + const Srt srtA = toSrt(_obbA.mtx); + const Srt srtB = toSrt(_obbB.mtx); + + return overlap(srtA, srtB); } bool overlap(const Plane& _plane, const LineSegment& _line)