From f5417038101cfa36e3a83d622b8574186d7538dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Branimir=20Karad=C5=BEi=C4=87?= Date: Tue, 26 Sep 2017 21:09:26 -0700 Subject: [PATCH] Added intersection test to example-29-debugdraw. --- examples/29-debugdraw/debugdraw.cpp | 92 ++++++++++++++++++------- examples/common/bounds.cpp | 63 +++++++++++++++++ examples/common/bounds.h | 8 ++- examples/common/debugdraw/debugdraw.cpp | 14 +++- examples/common/debugdraw/debugdraw.h | 8 ++- 5 files changed, 155 insertions(+), 30 deletions(-) diff --git a/examples/29-debugdraw/debugdraw.cpp b/examples/29-debugdraw/debugdraw.cpp index 8b3d8d6e7..149c4d5f0 100644 --- a/examples/29-debugdraw/debugdraw.cpp +++ b/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 mvp[16]; + float mtxInvVp[16]; + bx::mtxInverse(mtxInvVp, mtxVp); + + 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); + + 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); - bx::mtxSRT(obb.m_mtx, 1.0f, 1.0f, 1.0f, 0.0f, time, 0.0f, 3.0f, 0.0f, 0.0f); - ddSetWireframe(false); - ddDraw(obb); - 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 ); - } + Cone cone = + { + { -11.0f, 4.0f, 0.0f }, + { -13.0f, 6.0f, 1.0f }, + 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 ); + 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); diff --git a/examples/common/bounds.cpp b/examples/common/bounds.cpp index d73b247c6..346fea9bc 100644 --- a/examples/common/bounds.cpp +++ b/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; diff --git a/examples/common/bounds.h b/examples/common/bounds.h index 59556b428..19a88b558 100644 --- a/examples/common/bounds.h +++ b/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); diff --git a/examples/common/debugdraw/debugdraw.cpp b/examples/common/debugdraw/debugdraw.cpp index df3774d8c..8f0a0f159 100644 --- a/examples/common/debugdraw/debugdraw.cpp +++ b/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); diff --git a/examples/common/debugdraw/debugdraw.h b/examples/common/debugdraw/debugdraw.h index 222c05fd6..f43d0a6e7 100644 --- a/examples/common/debugdraw/debugdraw.h +++ b/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);