Browse Source

Adding more bounds overlap tests.

Бранимир Караџић 6 years ago
parent
commit
649033599b

+ 61 - 33
examples/29-debugdraw/debugdraw.cpp

@@ -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();
 

+ 174 - 1
examples/common/bounds.cpp

@@ -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);

+ 30 - 0
examples/common/bounds.h

@@ -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);
 

+ 11 - 0
examples/common/debugdraw/debugdraw.cpp

@@ -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();
+}

+ 16 - 1
examples/common/debugdraw/debugdraw.h

@@ -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