Adding more bounds overlap tests.

This commit is contained in:
Бранимир Караџић 2019-02-05 18:31:42 -08:00
parent 01a5acaca6
commit 649033599b
5 changed files with 292 additions and 35 deletions

View File

@ -667,7 +667,8 @@ public:
);
constexpr uint32_t kSelected = 0xff80ffff;
constexpr uint32_t kOverlap = 0xff0000ff;
constexpr uint32_t kOverlapA = 0xff0000ff;
constexpr uint32_t kOverlapB = 0xff8080ff;
DebugDrawEncoder dde;
@ -883,11 +884,11 @@ public:
Sphere sphereB = { { xx+kStepX*0.0f, yy, zz+kStepZ*0.0f }, 0.5f };
olp = overlap(sphereA, sphereB);;
dde.setColor(olp ? kOverlap : 0xffffffff);
dde.setColor(olp ? kOverlapA : 0xffffffff);
dde.setWireframe(false);
dde.draw(sphereA);
dde.setColor(olp ? kOverlap : 0xffffffff);
dde.setColor(olp ? kOverlapB : 0xffffffff);
dde.setWireframe(true);
dde.draw(sphereB);
}
@ -898,11 +899,11 @@ public:
toAabb(aabbB, { xx+kStepX*1.0f, yy, zz+kStepZ*0.0f }, { 0.5f, 0.5f, 0.5f });
olp = overlap(sphereA, aabbB);
dde.setColor(olp ? kOverlap : 0xffffffff);
dde.setColor(olp ? kOverlapA : 0xffffffff);
dde.setWireframe(false);
dde.draw(sphereA);
dde.setColor(olp ? kOverlap : 0xffffffff);
dde.setColor(olp ? kOverlapB : 0xffffffff);
dde.setWireframe(true);
dde.draw(aabbB);
}
@ -920,11 +921,11 @@ public:
olp = overlap(sphereA, triangleB);
dde.setColor(olp ? kOverlap : 0xffffffff);
dde.setColor(olp ? kOverlapA : 0xffffffff);
dde.setWireframe(false);
dde.draw(sphereA);
dde.setColor(olp ? kOverlap : 0xffffffff);
dde.setColor(olp ? kOverlapB : 0xffffffff);
dde.setWireframe(true);
dde.draw(triangleB);
}
@ -945,11 +946,11 @@ public:
olp = overlap(sphereA, planeB);
dde.setColor(olp ? kOverlap : 0xffffffff);
dde.setColor(olp ? kOverlapA : 0xffffffff);
dde.setWireframe(false);
dde.draw(sphereA);
dde.setColor(olp ? kOverlap : 0xffffffff);
dde.setColor(olp ? kOverlapB : 0xffffffff);
dde.setWireframe(true);
dde.drawGrid(planeB.normal, triangleB.v0, 10, 0.3f);
}
@ -972,11 +973,11 @@ public:
olp = overlap(sphereA, diskB);
dde.setColor(olp ? kOverlap : 0xffffffff);
dde.setColor(olp ? kOverlapA : 0xffffffff);
dde.setWireframe(false);
dde.draw(sphereA);
dde.setColor(olp ? kOverlap : 0xffffffff);
dde.setColor(olp ? kOverlapB : 0xffffffff);
dde.setWireframe(true);
dde.draw(diskB);
}
@ -999,11 +1000,11 @@ public:
olp = overlap(sphereA, obbB);
dde.setColor(olp ? kOverlap : 0xffffffff);
dde.setColor(olp ? kOverlapA : 0xffffffff);
dde.setWireframe(false);
dde.draw(sphereA);
dde.setColor(olp ? kOverlap : 0xffffffff);
dde.setColor(olp ? kOverlapB : 0xffffffff);
dde.setWireframe(true);
dde.draw(obbB);
}
@ -1020,11 +1021,11 @@ public:
olp = overlap(sphereA, capsuleB);
dde.setColor(olp ? kOverlap : 0xffffffff);
dde.setColor(olp ? kOverlapA : 0xffffffff);
dde.setWireframe(false);
dde.draw(sphereA);
dde.setColor(olp ? kOverlap : 0xffffffff);
dde.setColor(olp ? kOverlapB : 0xffffffff);
dde.setWireframe(true);
dde.draw(capsuleB);
}
@ -1041,11 +1042,11 @@ public:
olp = overlap(sphereA, cylinderB);
dde.setColor(olp ? kOverlap : 0xffffffff);
dde.setColor(olp ? kOverlapA : 0xffffffff);
dde.setWireframe(false);
dde.draw(sphereA);
dde.setColor(olp ? kOverlap : 0xffffffff);
dde.setColor(olp ? kOverlapB : 0xffffffff);
dde.setWireframe(true);
dde.draw(cylinderB);
}
@ -1062,11 +1063,11 @@ public:
olp = overlap(sphereA, coneB);
dde.setColor(olp ? kOverlap : 0xffffffff);
dde.setColor(olp ? kOverlapA : 0xffffffff);
dde.setWireframe(false);
dde.draw(sphereA);
dde.setColor(olp ? kOverlap : 0xffffffff);
dde.setColor(olp ? kOverlapB : 0xffffffff);
dde.setWireframe(true);
dde.draw(coneB);
}
@ -1078,11 +1079,11 @@ public:
toAabb(aabbB, { xx+kStepX*1.0f, yy, zz+kStepZ*1.0f }, { 0.5f, 0.5f, 0.5f });
olp = overlap(aabbA, aabbB);
dde.setColor(olp ? kOverlap : 0xffffffff);
dde.setColor(olp ? kOverlapA : 0xffffffff);
dde.setWireframe(false);
dde.draw(aabbA);
dde.setColor(olp ? kOverlap : 0xffffffff);
dde.setColor(olp ? kOverlapB : 0xffffffff);
dde.setWireframe(true);
dde.draw(aabbB);
}
@ -1101,11 +1102,11 @@ public:
olp = overlap(aabbA, triangleB);
dde.setColor(olp ? kOverlap : 0xffffffff);
dde.setColor(olp ? kOverlapA : 0xffffffff);
dde.setWireframe(false);
dde.draw(aabbA);
dde.setColor(olp ? kOverlap : 0xffffffff);
dde.setColor(olp ? kOverlapB : 0xffffffff);
dde.setWireframe(true);
dde.draw(triangleB);
}
@ -1127,11 +1128,11 @@ public:
olp = overlap(aabbA, planeB);
dde.setColor(olp ? kOverlap : 0xffffffff);
dde.setColor(olp ? kOverlapA : 0xffffffff);
dde.setWireframe(false);
dde.draw(aabbA);
dde.setColor(olp ? kOverlap : 0xffffffff);
dde.setColor(olp ? kOverlapB : 0xffffffff);
dde.setWireframe(true);
dde.drawGrid(planeB.normal, triangleB.v0, 10, 0.3f);
}
@ -1155,11 +1156,11 @@ public:
olp = overlap(aabbA, diskB);
dde.setColor(olp ? kOverlap : 0xffffffff);
dde.setColor(olp ? kOverlapA : 0xffffffff);
dde.setWireframe(false);
dde.draw(aabbA);
dde.setColor(olp ? kOverlap : 0xffffffff);
dde.setColor(olp ? kOverlapB : 0xffffffff);
dde.setWireframe(true);
dde.draw(diskB);
}
@ -1186,11 +1187,11 @@ public:
olp = overlap(triangleA, triangleB);
dde.setColor(olp ? kOverlap : 0xffffffff);
dde.setColor(olp ? kOverlapA : 0xffffffff);
dde.setWireframe(false);
dde.draw(triangleA);
dde.setColor(olp ? kOverlap : 0xffffffff);
dde.setColor(olp ? kOverlapB : 0xffffffff);
dde.setWireframe(true);
dde.draw(triangleB);
}
@ -1219,11 +1220,11 @@ public:
olp = overlap(triangleA, planeB);
dde.setColor(olp ? kOverlap : 0xffffffff);
dde.setColor(olp ? kOverlapA : 0xffffffff);
dde.setWireframe(false);
dde.draw(triangleA);
dde.setColor(olp ? kOverlap : 0xffffffff);
dde.setColor(olp ? kOverlapB : 0xffffffff);
dde.setWireframe(true);
dde.drawGrid(planeB.normal, triangleB.v0, 10, 0.3f);
}
@ -1254,14 +1255,41 @@ public:
olp = overlap(triangleA, diskB);
dde.setColor(olp ? kOverlap : 0xffffffff);
dde.setColor(olp ? kOverlapA : 0xffffffff);
dde.setWireframe(false);
dde.draw(triangleA);
dde.setColor(olp ? kOverlap : 0xffffffff);
dde.setColor(olp ? kOverlapB : 0xffffffff);
dde.setWireframe(true);
dde.draw(diskB);
}
// Capsule ---
{
Capsule capsuleA =
{
{ px+kStepX*6.0f, py-1.0f, pz+kStepZ*3.0f },
{ px+kStepX*6.0f, py+1.0f, pz+kStepZ*3.0f },
0.5f,
};
Capsule capsuleB =
{
{ xx+kStepX*5.9f, yy-1.0f, zz+kStepZ*3.0f+0.1f },
{ xx+kStepX*6.0f, yy+1.0f, zz+kStepZ*3.0f },
0.2f,
};
olp = overlap(capsuleA, capsuleB);
dde.setColor(olp ? kOverlapA : 0xffffffff);
dde.setWireframe(false);
dde.draw(capsuleA);
dde.setColor(olp ? kOverlapB : 0xffffffff);
dde.setWireframe(true);
dde.draw(capsuleB);
}
}
dde.pop();

View File

@ -3,7 +3,6 @@
* License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
*/
#include <bx/debug.h>
#include <bx/rng.h>
#include <bx/math.h>
#include "bounds.h"
@ -1024,6 +1023,58 @@ struct LineSegment
Vec3 end;
};
bool nearZero(float _v)
{
return bx::abs(_v) < 0.0001f;
}
bool nearZero(const Vec3& _v)
{
return nearZero(dot(_v, _v) );
}
bool intersect(float& _outTa, float& _outTb, const LineSegment& _a, const LineSegment _b)
{
// Reference(s):
//
// - The shortest line between two lines in 3D
// https://web.archive.org/web/20120309093234/http://paulbourke.net/geometry/lineline3d/
const Vec3 bd = sub(_b.end, _b.pos);
if (nearZero(bd) )
{
return false;
}
const Vec3 ad = sub(_a.end, _a.pos);
if (nearZero(ad) )
{
return false;
}
const Vec3 ab = sub(_a.pos, _b.pos);
const float d0 = projectToAxis(ab, bd);
const float d1 = projectToAxis(ad, bd);
const float d2 = projectToAxis(ab, ad);
const float d3 = projectToAxis(bd, bd);
const float d4 = projectToAxis(ad, ad);
const float denom = d4*d3 - square(d1);
float ta = 0.0f;
if (!nearZero(denom) )
{
ta = (d0*d1 - d2*d3)/denom;
}
_outTa = ta;
_outTb = (d0+d1*ta)/d3;
return true;
}
Vec3 closestPoint(const LineSegment& _line, const Vec3& _point, float& _outT)
{
const Vec3 axis = sub(_line.end, _line.pos);
@ -1320,6 +1371,128 @@ bool overlap(const Aabb& _aabb, const Obb& _obb)
return false;
}
bool overlap(const Capsule& _capsule, const bx::Vec3& _pos)
{
const Vec3 pos = closestPoint(LineSegment{_capsule.pos, _capsule.end}, _pos);
return overlap(Sphere{pos, _capsule.radius}, _pos);
}
bool overlap(const Capsule& _capsule, const Sphere& _sphere)
{
return overlap(_sphere, _capsule);
}
bool overlap(const Capsule& _capsule, const Aabb& _aabb)
{
return overlap(_aabb, _capsule);
}
bool overlap(const Capsule& _capsule, const bx::Plane& _plane)
{
BX_UNUSED(_capsule, _plane);
return false;
}
bool overlap(const Capsule& _capsule, const Triangle& _triangle)
{
return overlap(_triangle, _capsule);
}
bool overlap(const Capsule& _capsule, const Cylinder& _cylinder)
{
BX_UNUSED(_capsule, _cylinder);
return false;
}
bool overlap(const Capsule& _capsuleA, const Capsule& _capsuleB)
{
float ta, tb;
if (!intersect(ta, tb, {_capsuleA.pos, _capsuleA.end}, {_capsuleB.pos, _capsuleB.end}) )
{
return false;
}
if (0.0f <= ta
&& 1.0f >= ta
&& 0.0f <= tb
&& 1.0f >= tb)
{
const Vec3 ad = sub(_capsuleA.end, _capsuleA.pos);
const Vec3 bd = sub(_capsuleB.end, _capsuleB.pos);
return overlap(
Sphere{mad(ad, ta, _capsuleA.pos), _capsuleA.radius}
, Sphere{mad(bd, tb, _capsuleB.pos), _capsuleB.radius}
);
}
if (0.0f <= ta
&& 1.0f >= ta)
{
Sphere sphereB;
sphereB.radius = _capsuleB.radius;
if (0.0f >= tb)
{
sphereB.center = _capsuleB.pos;
}
else
{
sphereB.center = _capsuleB.end;
}
return overlap(_capsuleA, sphereB);
}
if (0.0f <= tb
&& 1.0f >= tb)
{
Sphere sphereA;
sphereA.radius = _capsuleA.radius;
if (0.0f >= ta)
{
sphereA.center = _capsuleA.pos;
}
else
{
sphereA.center = _capsuleA.end;
}
return overlap(_capsuleB, sphereA);
}
const Vec3 pa = 0.0f > ta ? _capsuleA.pos : _capsuleA.end;
const Vec3 pb = 0.0f > tb ? _capsuleB.pos : _capsuleB.end;
const Vec3 closestA = closestPoint(LineSegment{_capsuleA.pos, _capsuleA.end}, pb);
const Vec3 closestB = closestPoint(LineSegment{_capsuleB.pos, _capsuleB.end}, pa);
if (dot(closestA, pb) <= dot(closestB, pa) )
{
return overlap(_capsuleA, Sphere{closestB, _capsuleB.radius});
}
return overlap(_capsuleB, Sphere{closestA, _capsuleA.radius});
}
bool overlap(const Capsule& _capsule, const Cone& _cone)
{
BX_UNUSED(_capsule, _cone);
return false;
}
bool overlap(const Capsule& _capsule, const Disk& _disk)
{
BX_UNUSED(_capsule, _disk);
return false;
}
bool overlap(const Capsule& _capsule, const Obb& _obb)
{
BX_UNUSED(_capsule, _obb);
return false;
}
bool overlap(const Triangle& _triangle, const Vec3& _pos)
{
const Vec3 uvw = barycentric(_triangle, _pos);

View File

@ -225,6 +225,36 @@ bool overlap(const Aabb& _aabb, const Disk& _disk);
///
bool overlap(const Aabb& _aabb, const Obb& _obb);
///
bool overlap(const Capsule& _capsule, const bx::Vec3& _pos);
///
bool overlap(const Capsule& _capsule, const Sphere& _sphere);
///
bool overlap(const Capsule& _capsule, const Aabb& _aabb);
///
bool overlap(const Capsule& _capsule, const bx::Plane& _plane);
///
bool overlap(const Capsule& _capsule, const Triangle& _triangle);
///
bool overlap(const Capsule& _capsule, const Cylinder& _cylinder);
///
bool overlap(const Capsule& _capsuleA, const Capsule& _capsuleB);
///
bool overlap(const Capsule& _capsule, const Cone& _cone);
///
bool overlap(const Capsule& _capsule, const Disk& _disk);
///
bool overlap(const Capsule& _capsule, const Obb& _obb);
///
bool overlap(const Triangle& _triangle, const bx::Vec3& _pos);

View File

@ -2578,3 +2578,14 @@ void DebugDrawEncoder::drawOrb(float _x, float _y, float _z, float _radius, Axis
{
DEBUG_DRAW_ENCODER(drawOrb(_x, _y, _z, _radius, _highlight) );
}
DebugDrawEncoderScopePush::DebugDrawEncoderScopePush(DebugDrawEncoder& _dde)
: m_dde(_dde)
{
m_dde.push();
}
DebugDrawEncoderScopePush::~DebugDrawEncoderScopePush()
{
m_dde.pop();
}

View File

@ -7,6 +7,7 @@
#define DEBUGDRAW_H_HEADER_GUARD
#include <bx/allocator.h>
#include <bgfx/bgfx.h>
#include "../bounds.h"
struct Axis
@ -50,7 +51,7 @@ GeometryHandle ddCreateGeometry(uint32_t _numVertices, const DdVertex* _vertices
///
void ddDestroy(GeometryHandle _handle);
///
struct DebugDrawEncoder
{
///
@ -197,4 +198,18 @@ struct DebugDrawEncoder
BX_ALIGN_DECL_CACHE_LINE(uint8_t) m_internal[50<<10];
};
///
class DebugDrawEncoderScopePush
{
public:
///
DebugDrawEncoderScopePush(DebugDrawEncoder& _dde);
///
~DebugDrawEncoderScopePush();
private:
DebugDrawEncoder& m_dde;
};
#endif // DEBUGDRAW_H_HEADER_GUARD