Added intersection test to example-29-debugdraw.

This commit is contained in:
Branimir Karadžić 2017-09-26 21:09:26 -07:00
parent aa567d3d72
commit f541703810
5 changed files with 155 additions and 30 deletions

View File

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

View File

@ -19,6 +19,28 @@ void aabbToObb(Obb& _obb, const Aabb& _aabb)
_obb.m_mtx[15] = 1.0f; _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) void toAabb(Aabb& _aabb, const Sphere& _sphere)
{ {
float radius = _sphere.m_radius; float radius = _sphere.m_radius;
@ -512,6 +534,47 @@ bool intersect(const Ray& _ray, const Aabb& _aabb, Intersection* _intersection)
return true; 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) bool intersect(const Ray& _ray, const Disk& _disk, Intersection* _intersection)
{ {
Plane plane; Plane plane;

View File

@ -80,6 +80,9 @@ struct Intersection
/// Convert axis aligned bounding box to oriented bounding box. /// Convert axis aligned bounding box to oriented bounding box.
void aabbToObb(Obb& _obb, const Aabb& _aabb); 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. /// Convert sphere to axis aligned bounding box.
void toAabb(Aabb& _aabb, const Sphere& _sphere); 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. /// Make screen space ray from x, y coordinate and inverse view-projection matrix.
Ray makeRay(float _x, float _y, const float* _invVp); 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); 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. /// Intersect ray / cylinder.
bool intersect(const Ray& _ray, const Cylinder& _cylinder, Intersection* _intersection = NULL); bool intersect(const Ray& _ray, const Cylinder& _cylinder, Intersection* _intersection = NULL);

View File

@ -2157,9 +2157,14 @@ void ddDraw(const Aabb& _aabb)
s_dd.draw(_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) void ddDraw(const Disk& _disk)
@ -2177,6 +2182,11 @@ void ddDraw(const Sphere& _sphere)
s_dd.draw(_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) void ddDrawFrustum(const void* _viewProj)
{ {
s_dd.drawFrustum(_viewProj); s_dd.drawFrustum(_viewProj);

View File

@ -92,7 +92,10 @@ void ddClose();
void ddDraw(const Aabb& _aabb); 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); void ddDraw(const Disk& _disk);
@ -103,6 +106,9 @@ void ddDraw(const Obb& _obb);
/// ///
void ddDraw(const Sphere& _sphere); void ddDraw(const Sphere& _sphere);
///
void ddDraw(const Cone& _cone);
/// ///
void ddDrawFrustum(const void* _viewProj); void ddDrawFrustum(const void* _viewProj);