Browse Source

Added intersection test to example-29-debugdraw.

Branimir Karadžić 8 years ago
parent
commit
f541703810

+ 65 - 25
examples/29-debugdraw/debugdraw.cpp

@@ -98,7 +98,8 @@ public:
 	{
 		if (!entry::processEvents(m_width, m_height, m_debug, m_reset, &m_mouseState) )
 		{
-			imguiBeginFrame(m_mouseState.m_mx
+			imguiBeginFrame(
+				   m_mouseState.m_mx
 				,  m_mouseState.m_my
 				, (m_mouseState.m_buttons[entry::MouseButton::Left  ] ? IMGUI_MBUT_LEFT   : 0)
 				| (m_mouseState.m_buttons[entry::MouseButton::Right ] ? IMGUI_MBUT_RIGHT  : 0)
@@ -145,25 +146,36 @@ public:
 				bgfx::setViewRect(0, 0, 0, uint16_t(m_width), uint16_t(m_height) );
 			}
 
-			float zero[3] = {};
+			float mtxVp[16];
+			bx::mtxMul(mtxVp, view, proj);
+
+			float mtxInvVp[16];
+			bx::mtxInverse(mtxInvVp, mtxVp);
 
-			float mvp[16];
+			float zero[3] = {};
 			float eye[] = { 5.0f, 10.0f, 5.0f };
 			bx::mtxLookAt(view, eye, zero);
 			bx::mtxProj(proj, 45.0f, float(m_width)/float(m_height), 1.0f, 15.0f, bgfx::getCaps()->homogeneousDepth);
-			bx::mtxMul(mvp, view, proj);
+			bx::mtxMul(mtxVp, view, proj);
+
+			Ray ray = makeRay(
+				   (float(m_mouseState.m_mx)/float(m_width)  * 2.0f - 1.0f)
+				, -(float(m_mouseState.m_my)/float(m_height) * 2.0f - 1.0f)
+				, mtxInvVp
+				);
+
+			const uint32_t selected = 0xff80ffff;
 
 			ddBegin(0);
 			ddDrawAxis(0.0f, 0.0f, 0.0f);
 
 			ddPush();
-				ddSetColor(0xff00ff00);
-
 				Aabb aabb =
 				{
 					{  5.0f, 1.0f, 1.0f },
 					{ 10.0f, 5.0f, 5.0f },
 				};
+				ddSetColor(intersect(ray, aabb) ? selected : 0xff00ff00);
 				ddDraw(aabb);
 			ddPop();
 
@@ -172,39 +184,46 @@ public:
 			Obb obb;
 			bx::mtxRotateX(obb.m_mtx, time);
 			ddSetWireframe(true);
+			ddSetColor(intersect(ray, obb) ? selected : 0xffffffff);
 			ddDraw(obb);
 
-			ddSetColor(0xffffffff);
-			bx::mtxSRT(obb.m_mtx, 1.0f, 1.0f, 1.0f, 0.0f, time, 0.0f, 3.0f, 0.0f, 0.0f);
+			bx::mtxSRT(obb.m_mtx, 1.0f, 1.0f, 1.0f, time*0.23f, time, 0.0f, 3.0f, 0.0f, 0.0f);
+
+			toAabb(aabb, obb);
+			ddSetColor(0xff0000ff);
+			ddDraw(aabb);
+
 			ddSetWireframe(false);
+			ddSetColor(intersect(ray, obb) ? selected : 0xffffffff);
 			ddDraw(obb);
 
+			ddSetColor(0xffffffff);
 			ddSetTranslate(0.0f, -2.0f, 0.0f);
 			ddDrawGrid(Axis::Y, zero, 20, 1.0f);
 			ddSetTransform(NULL);
 
-			ddDrawFrustum(mvp);
+			ddDrawFrustum(mtxVp);
 
 			ddPush();
 				Sphere sphere = { { 0.0f, 5.0f, 0.0f }, 1.0f };
-				ddSetColor(0xfff0c0ff);
+				ddSetColor(intersect(ray, sphere) ? selected : 0xfff0c0ff);
 				ddSetWireframe(true);
 				ddSetLod(3);
 				ddDraw(sphere);
 				ddSetWireframe(false);
 
-				ddSetColor(0xc0ffc0ff);
 				sphere.m_center[0] = -2.0f;
+				ddSetColor(intersect(ray, sphere) ? selected : 0xc0ffc0ff);
 				ddSetLod(2);
 				ddDraw(sphere);
 
-				ddSetColor(0xa0f0ffff);
 				sphere.m_center[0] = -4.0f;
+				ddSetColor(intersect(ray, sphere) ? selected : 0xa0f0ffff);
 				ddSetLod(1);
 				ddDraw(sphere);
 
-				ddSetColor(0xffc0ff00);
 				sphere.m_center[0] = -6.0f;
+				ddSetColor(intersect(ray, sphere) ? selected : 0xffc0ff00);
 				ddSetLod(0);
 				ddDraw(sphere);
 			ddPop();
@@ -237,22 +256,42 @@ public:
 				ddPush();
 					ddSetSpin(time*0.3f);
 					{
-						float from[3] = { -11.0f, 4.0f,  0.0f };
-						float to[3]   = { -13.0f, 6.0f,  1.0f };
-						ddDrawCone(from, to, 1.0f );
-					}
-
-					{
-						float from[3] = {  -9.0f, 2.0f, -1.0f };
-						float to[3]   = { -11.0f, 4.0f,  0.0f };
-						ddDrawCylinder(from, to, 0.5f );
+						Cone cone =
+						{
+							{ -11.0f, 4.0f,  0.0f },
+							{ -13.0f, 6.0f,  1.0f },
+							1.0f
+						};
+
+						Cylinder cylinder =
+						{
+							{  -9.0f, 2.0f, -1.0f },
+							{ -11.0f, 4.0f,  0.0f },
+							0.5f
+						};
+
+						ddSetColor(false
+							|| intersect(ray, cone)
+							|| intersect(ray, cylinder)
+							? selected
+							: 0xffffffff
+							);
+
+						ddDraw(cone);
+						ddDraw(cylinder);
 					}
 				ddPop();
 
 				{
-					float from[3] = {  0.0f, 7.0f, 0.0f };
-					float to[3]   = { -6.0f, 7.0f, 0.0f };
-					ddDrawCylinder(from, to, 0.5f, true);
+					ddSetLod(0);
+					Capsule capsule =
+					{
+						{  0.0f, 7.0f, 0.0f },
+						{ -6.0f, 7.0f, 0.0f },
+						0.5f
+					};
+					ddSetColor(intersect(ray, capsule) ? selected : 0xffffffff);
+					ddDraw(capsule);
 				}
 			ddPop();
 
@@ -274,6 +313,7 @@ public:
 
 				float up[3] = { 0.0f, 4.0f, 0.0f };
 				bx::vec3MulMtx(cylinder.m_end, up, mtx);
+				ddSetColor(intersect(ray, cylinder) ? selected : 0xffffffff);
 				ddDraw(cylinder);
 
 				toAabb(aabb, cylinder);

+ 63 - 0
examples/common/bounds.cpp

@@ -19,6 +19,28 @@ void aabbToObb(Obb& _obb, const Aabb& _aabb)
 	_obb.m_mtx[15] = 1.0f;
 }
 
+void toAabb(Aabb& _aabb, const Obb& _obb)
+{
+	float xyz[3] = { 1.0f, 1.0f, 1.0f };
+
+	float tmp[3];
+	bx::vec3MulMtx(tmp, xyz, _obb.m_mtx);
+
+	bx::vec3Move(_aabb.m_min, tmp);
+	bx::vec3Move(_aabb.m_max, tmp);
+
+	for (uint32_t ii = 1; ii < 8; ++ii)
+	{
+		xyz[0] = ii & 1 ? -1.0f : 1.0f;
+		xyz[1] = ii & 2 ? -1.0f : 1.0f;
+		xyz[2] = ii & 4 ? -1.0f : 1.0f;
+		bx::vec3MulMtx(tmp, xyz, _obb.m_mtx);
+
+		bx::vec3Min(_aabb.m_min, _aabb.m_min, tmp);
+		bx::vec3Max(_aabb.m_max, _aabb.m_max, tmp);
+	}
+}
+
 void toAabb(Aabb& _aabb, const Sphere& _sphere)
 {
 	float radius = _sphere.m_radius;
@@ -512,6 +534,47 @@ bool intersect(const Ray& _ray, const Aabb& _aabb, Intersection* _intersection)
 	return true;
 }
 
+static const Aabb s_kUnitAabb =
+{
+	{ -1.0f, -1.0f, -1.0f },
+	{  1.0f,  1.0f,  1.0f },
+};
+
+bool intersect(const Ray& _ray, const Obb& _obb, Intersection* _intersection)
+{
+	Aabb aabb;
+	toAabb(aabb, _obb);
+
+	if (!intersect(_ray, aabb) )
+	{
+		return false;
+	}
+
+	float mtxInv[16];
+	bx::mtxInverse(mtxInv, _obb.m_mtx);
+
+	Ray obbRay;
+	bx::vec3MulMtx(obbRay.m_pos, _ray.m_pos, mtxInv);
+	bx::vec3MulMtxXyz0(obbRay.m_dir, _ray.m_dir, mtxInv);
+
+	if (intersect(obbRay, s_kUnitAabb, _intersection) )
+	{
+		if (NULL != _intersection)
+		{
+			float tmp[3];
+			bx::vec3MulMtx(tmp, _intersection->m_pos, _obb.m_mtx);
+			bx::vec3Move(_intersection->m_pos, tmp);
+
+			bx::vec3MulMtxXyz0(tmp, _intersection->m_normal, _obb.m_mtx);
+			bx::vec3Norm(_intersection->m_normal, tmp);
+		}
+
+		return true;
+	}
+
+	return false;
+}
+
 bool intersect(const Ray& _ray, const Disk& _disk, Intersection* _intersection)
 {
 	Plane plane;

+ 7 - 1
examples/common/bounds.h

@@ -80,6 +80,9 @@ struct Intersection
 /// Convert axis aligned bounding box to oriented bounding box.
 void aabbToObb(Obb& _obb, const Aabb& _aabb);
 
+/// Convert oriented bounding box to axis aligned bounding box.
+void toAabb(Aabb& _aabb, const Obb& _obb);
+
 /// Convert sphere to axis aligned bounding box.
 void toAabb(Aabb& _aabb, const Sphere& _sphere);
 
@@ -126,9 +129,12 @@ void intersectPlanes(float _result[3], const Plane& _pa, const Plane& _pb, const
 /// Make screen space ray from x, y coordinate and inverse view-projection matrix.
 Ray makeRay(float _x, float _y, const float* _invVp);
 
-/// Intersect ray / aabb.
+/// Intersect ray / AABB.
 bool intersect(const Ray& _ray, const Aabb& _aabb, Intersection* _intersection = NULL);
 
+/// Intersect ray / OBB.
+bool intersect(const Ray& _ray, const Obb& _obb, Intersection* _intersection = NULL);
+
 /// Intersect ray / cylinder.
 bool intersect(const Ray& _ray, const Cylinder& _cylinder, Intersection* _intersection = NULL);
 

+ 12 - 2
examples/common/debugdraw/debugdraw.cpp

@@ -2157,9 +2157,14 @@ void ddDraw(const Aabb& _aabb)
 	s_dd.draw(_aabb);
 }
 
-void ddDraw(const Cylinder& _cylinder, bool _capsule)
+void ddDraw(const Cylinder& _cylinder)
 {
-	s_dd.draw(_cylinder, _capsule);
+	s_dd.draw(_cylinder, false);
+}
+
+void ddDraw(const Capsule& _capsule)
+{
+	s_dd.draw( *( (const Cylinder*)&_capsule), true);
 }
 
 void ddDraw(const Disk& _disk)
@@ -2177,6 +2182,11 @@ void ddDraw(const Sphere& _sphere)
 	s_dd.draw(_sphere);
 }
 
+void ddDraw(const Cone& _cone)
+{
+	ddDrawCone(_cone.m_pos, _cone.m_end, _cone.m_radius);
+}
+
 void ddDrawFrustum(const void* _viewProj)
 {
 	s_dd.drawFrustum(_viewProj);

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

@@ -92,7 +92,10 @@ void ddClose();
 void ddDraw(const Aabb& _aabb);
 
 ///
-void ddDraw(const Cylinder& _cylinder, bool _capsule = false);
+void ddDraw(const Cylinder& _cylinder);
+
+///
+void ddDraw(const Capsule& _capsule);
 
 ///
 void ddDraw(const Disk& _disk);
@@ -103,6 +106,9 @@ void ddDraw(const Obb& _obb);
 ///
 void ddDraw(const Sphere& _sphere);
 
+///
+void ddDraw(const Cone& _cone);
+
 ///
 void ddDrawFrustum(const void* _viewProj);