Browse Source

Adding more bounds overlap tests.

Бранимир Караџић 6 years ago
parent
commit
567c7c097f

+ 3 - 4
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;

+ 110 - 2
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)

+ 30 - 45
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]);
-
-		moveTo(&points[0].x);
-		lineTo(&points[1].x);
-		lineTo(&points[2].x);
-		lineTo(&points[3].x);
+		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]);
+		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) );
 }

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