From 567c7c097f613a42b9253ccdbecc8515c26e66d2 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, 9 Feb 2019 21:22:45 -0800 Subject: [PATCH] Adding more bounds overlap tests. --- examples/29-debugdraw/debugdraw.cpp | 7 +- examples/common/bounds.cpp | 112 +++++++++++++++++++++++- examples/common/debugdraw/debugdraw.cpp | 73 ++++++--------- examples/common/debugdraw/debugdraw.h | 4 +- 4 files changed, 144 insertions(+), 52 deletions(-) diff --git a/examples/29-debugdraw/debugdraw.cpp b/examples/29-debugdraw/debugdraw.cpp index 3bc759e4c..fad86f6e6 100644 --- a/examples/29-debugdraw/debugdraw.cpp +++ b/examples/29-debugdraw/debugdraw.cpp @@ -846,10 +846,7 @@ public: _dde->setColor(0xff0000ff); - const bx::Vec3 tmp = bx::mul(hit.plane.normal, 0.7f); - const bx::Vec3 end = bx::add(hit.pos, tmp); - - _dde->drawCone(hit.pos, end, 0.1f); + _dde->drawCone(hit.pos, bx::mad(hit.plane.normal, 0.7f, hit.pos), 0.1f); _dde->pop(); @@ -1145,6 +1142,7 @@ public: 0xffffffff, kOverlapA, 0xff666666, + 0xff6666ff, }; constexpr uint32_t colorB[] = @@ -1152,6 +1150,7 @@ public: 0xffffffff, kOverlapB, 0xff888888, + 0xff8888ff, }; constexpr float kStep = 3.0f; diff --git a/examples/common/bounds.cpp b/examples/common/bounds.cpp index c7c440d60..9b704aaaf 100644 --- a/examples/common/bounds.cpp +++ b/examples/common/bounds.cpp @@ -1021,6 +1021,11 @@ struct LineSegment Vec3 end; }; +inline Vec3 getPointAt(const LineSegment& _line, float _t) +{ + return lerp(_line.pos, _line.end, _t); +} + bool nearZero(float _v) { return bx::abs(_v) < 0.0001f; @@ -1806,10 +1811,113 @@ bool overlap(const Triangle& _triangle, const Cylinder& _cylinder) return false; } +bool intersect(const LineSegment& _line, const Plane& _plane, Hit* _hit) +{ + const float dist = distance(_plane, _line.pos); + const float flip = sign(dist); + const Vec3 dir = normalize(sub(_line.end, _line.pos) ); + const float ndotd = dot(dir, _plane.normal); + const float tt = -dist/ndotd; + const float len = length(sub(_line.end, _line.pos) ); + + if (tt < 0.0f || tt > len) + { + return false; + } + + if (NULL != _hit) + { + _hit->pos = mad(dir, tt, _line.pos); + + _hit->plane.normal = mul(_plane.normal, flip); + _hit->plane.dist = -dot(_hit->plane.normal, _hit->pos); + } + + return true; +} + bool overlap(const Triangle& _triangle, const Capsule& _capsule) { - BX_UNUSED(_triangle, _capsule); - return false; + Plane plane; + calcPlane(plane, _triangle); + + plane.normal = neg(plane.normal); + plane.dist = -plane.dist; + + const LineSegment line = + { + _capsule.pos, + _capsule.end, + }; + + Hit hit; + if (!intersect(line, plane, &hit) ) + { + return false; + } + + const Vec3 pos = closestPoint(plane, hit.pos); + const Vec3 uvw = barycentric(_triangle, pos); + + const float nr = -_capsule.radius; + + if (uvw.x >= nr + && uvw.y >= nr + && uvw.z >= nr) + { + return true; + } + + const LineSegment ab = LineSegment{_triangle.v0, _triangle.v1}; + const LineSegment bc = LineSegment{_triangle.v1, _triangle.v2}; + const LineSegment ca = LineSegment{_triangle.v2, _triangle.v0}; + + float ta0, tb0; + 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) + { + return false; + } + + 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 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) + { + return overlap(_capsule, pa0); + } + else if (d1 <= d2) + { + return overlap(_capsule, pa1); + } + + return overlap(_capsule, pa2); } bool overlap(const Triangle& _triangle, const Cone& _cone) diff --git a/examples/common/debugdraw/debugdraw.cpp b/examples/common/debugdraw/debugdraw.cpp index 976216aca..b34e0e0e7 100644 --- a/examples/common/debugdraw/debugdraw.cpp +++ b/examples/common/debugdraw/debugdraw.cpp @@ -1315,14 +1315,6 @@ struct DebugDrawEncoderImpl m_vertexPos = m_pos; } - void moveTo(const void* _pos) - { - BX_CHECK(State::Count != m_state); - - const float* pos = (const float*)_pos; - moveTo(pos[0], pos[1], pos[2]); - } - void moveTo(const bx::Vec3& _pos) { BX_CHECK(State::Count != m_state); @@ -1387,14 +1379,6 @@ struct DebugDrawEncoderImpl m_indices[m_indexPos++] = curr; } - void lineTo(const void* _pos) - { - BX_CHECK(State::Count != m_state); - - const float* pos = (const float*)_pos; - lineTo(pos[0], pos[1], pos[2]); - } - void lineTo(const bx::Vec3& _pos) { BX_CHECK(State::Count != m_state); @@ -1650,7 +1634,6 @@ struct DebugDrawEncoderImpl , false ); - bgfx::allocTransientIndexBuffer(&tib, numIndices); bgfx::topologyConvert( bgfx::TopologyConvert::TriListToLineList @@ -1684,39 +1667,41 @@ struct DebugDrawEncoderImpl bx::Plane planes[6]; buildFrustumPlanes(planes, _viewProj); - bx::Vec3 points[8]; - points[0] = intersectPlanes(planes[0], planes[2], planes[4]); - points[1] = intersectPlanes(planes[0], planes[3], planes[4]); - points[2] = intersectPlanes(planes[0], planes[3], planes[5]); - points[3] = intersectPlanes(planes[0], planes[2], planes[5]); - points[4] = intersectPlanes(planes[1], planes[2], planes[4]); - points[5] = intersectPlanes(planes[1], planes[3], planes[4]); - points[6] = intersectPlanes(planes[1], planes[3], planes[5]); - points[7] = intersectPlanes(planes[1], planes[2], planes[5]); + const bx::Vec3 points[8] = + { + intersectPlanes(planes[0], planes[2], planes[4]), + intersectPlanes(planes[0], planes[3], planes[4]), + intersectPlanes(planes[0], planes[3], planes[5]), + intersectPlanes(planes[0], planes[2], planes[5]), + intersectPlanes(planes[1], planes[2], planes[4]), + intersectPlanes(planes[1], planes[3], planes[4]), + intersectPlanes(planes[1], planes[3], planes[5]), + intersectPlanes(planes[1], planes[2], planes[5]), + }; - moveTo(&points[0].x); - lineTo(&points[1].x); - lineTo(&points[2].x); - lineTo(&points[3].x); + moveTo(points[0]); + lineTo(points[1]); + lineTo(points[2]); + lineTo(points[3]); close(); - moveTo(&points[4].x); - lineTo(&points[5].x); - lineTo(&points[6].x); - lineTo(&points[7].x); + moveTo(points[4]); + lineTo(points[5]); + lineTo(points[6]); + lineTo(points[7]); close(); - moveTo(&points[0].x); - lineTo(&points[4].x); + moveTo(points[0]); + lineTo(points[4]); - moveTo(&points[1].x); - lineTo(&points[5].x); + moveTo(points[1]); + lineTo(points[5]); - moveTo(&points[2].x); - lineTo(&points[6].x); + moveTo(points[2]); + lineTo(points[6]); - moveTo(&points[3].x); - lineTo(&points[7].x); + moveTo(points[3]); + lineTo(points[7]); } void drawFrustum(const void* _viewProj) @@ -2434,7 +2419,7 @@ void DebugDrawEncoder::moveTo(float _x, float _y, float _z) DEBUG_DRAW_ENCODER(moveTo(_x, _y, _z) ); } -void DebugDrawEncoder::moveTo(const void* _pos) +void DebugDrawEncoder::moveTo(const bx::Vec3& _pos) { DEBUG_DRAW_ENCODER(moveTo(_pos) ); } @@ -2444,7 +2429,7 @@ void DebugDrawEncoder::lineTo(float _x, float _y, float _z) DEBUG_DRAW_ENCODER(lineTo(_x, _y, _z) ); } -void DebugDrawEncoder::lineTo(const void* _pos) +void DebugDrawEncoder::lineTo(const bx::Vec3& _pos) { DEBUG_DRAW_ENCODER(lineTo(_pos) ); } diff --git a/examples/common/debugdraw/debugdraw.h b/examples/common/debugdraw/debugdraw.h index 2b98374f3..0404c8936 100644 --- a/examples/common/debugdraw/debugdraw.h +++ b/examples/common/debugdraw/debugdraw.h @@ -109,13 +109,13 @@ struct DebugDrawEncoder void moveTo(float _x, float _y, float _z = 0.0f); /// - void moveTo(const void* _pos); + void moveTo(const bx::Vec3& _pos); /// void lineTo(float _x, float _y, float _z = 0.0f); /// - void lineTo(const void* _pos); + void lineTo(const bx::Vec3& _pos); /// void close();