RayVsModel && RayVsAABB tests added and working. Also adjusted RayVsModel,RayVsAABB with deltas when values are very close to each other (floatingprecision problems)
This commit is contained in:
@@ -6,6 +6,7 @@
|
|||||||
namespace Collision
|
namespace Collision
|
||||||
{
|
{
|
||||||
|
|
||||||
|
//note: this one hasnt been delta adjusted like RayVsAABB has
|
||||||
bool RayAABBIntr(const Ray& ray, const AABB& box)
|
bool RayAABBIntr(const Ray& ray, const AABB& box)
|
||||||
{
|
{
|
||||||
glm::vec3 w = 75.0f * ray.Direction;
|
glm::vec3 w = 75.0f * ray.Direction;
|
||||||
@@ -52,7 +53,10 @@ bool RayVsAABB(const Ray& ray, const AABB& box, float& outDistance)
|
|||||||
float tmin = std::max(std::max(std::min(t1, t2), std::min(t3, t4)), std::min(t5, t6));
|
float tmin = std::max(std::max(std::min(t1, t2), std::min(t3, t4)), std::min(t5, t6));
|
||||||
float tmax = std::min(std::min(std::max(t1, t2), std::max(t3, t4)), std::max(t5, t6));
|
float tmax = std::min(std::min(std::max(t1, t2), std::max(t3, t4)), std::max(t5, t6));
|
||||||
|
|
||||||
if (tmax < 0 || tmin > tmax)
|
//if (tmax < 0 || tmin > tmax)
|
||||||
|
//if tmin,tmax are almost the same (i.e. hitting exactly in the corner) then tmin might be slightly
|
||||||
|
//greater than tmax becuase of floating-precision problems. fixed by adding a small delta to tmax
|
||||||
|
if (tmax < 0 || tmin>(tmax + 0.0001f))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
outDistance = (tmin > 0) ? tmin : tmax;
|
outDistance = (tmin > 0) ? tmin : tmax;
|
||||||
@@ -93,7 +97,8 @@ bool RayVsModel(const Ray& ray,
|
|||||||
DetInv = 1.0f / DetInv;
|
DetInv = 1.0f / DetInv;
|
||||||
float u = glm::dot(m, DxE2) * DetInv;
|
float u = glm::dot(m, DxE2) * DetInv;
|
||||||
float v = glm::dot(ray.Direction, MxE1) * DetInv;
|
float v = glm::dot(ray.Direction, MxE1) * DetInv;
|
||||||
if (u < 0 || v < 0 || 1 < u + v) {
|
//u,v can be very close to 0 but still negative sometimes. added a deltafactor to compensate for that problem
|
||||||
|
if ((u + 0.001f) < 0 || (v + 0.001f) < 0 || 1 < u + v) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
//Here, u and v are positive, u+v <= 1, and if distance is positive - triangle is hit.
|
//Here, u and v are positive, u+v <= 1, and if distance is positive - triangle is hit.
|
||||||
@@ -131,8 +136,10 @@ bool RayVsModel(const Ray& ray,
|
|||||||
}
|
}
|
||||||
float u = glm::dot(m, DxE2) * DetInv;
|
float u = glm::dot(m, DxE2) * DetInv;
|
||||||
float v = glm::dot(ray.Direction, MxE1) * DetInv;
|
float v = glm::dot(ray.Direction, MxE1) * DetInv;
|
||||||
|
|
||||||
|
//u,v can be very close to 0 but still negative sometimes. added a deltafactor to compensate for that problem
|
||||||
//If u and v are positive, u+v <= 1, dist is positive, and less than closest.
|
//If u and v are positive, u+v <= 1, dist is positive, and less than closest.
|
||||||
if (0 <= u && 0 <= v && u + v <= 1 && 0 <= dist) {
|
if (0 <= (u + 0.001f) && 0 <= (v + 0.001f) && u + v <= 1 && 0 <= dist) {
|
||||||
outDistance = dist;
|
outDistance = dist;
|
||||||
outUCoord = u;
|
outUCoord = u;
|
||||||
outVCoord = v;
|
outVCoord = v;
|
||||||
|
|||||||
@@ -96,13 +96,12 @@ BOOST_AUTO_TEST_CASE(collisionTest2)
|
|||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(rayVsModelTest)
|
BOOST_AUTO_TEST_CASE(rayVsModelTest)
|
||||||
{
|
{
|
||||||
//simple test
|
//simple box test
|
||||||
|
|
||||||
Ray ray;
|
Ray ray;
|
||||||
ray.Origin = glm::vec3(-50, 0, 0);
|
ray.Origin = glm::vec3(-50, 0, 0);
|
||||||
//ray.Direction = glm::vec3(-1, 0, 0);
|
|
||||||
ray.Direction = glm::normalize(glm::vec3(1, 0, 0));
|
ray.Direction = glm::normalize(glm::vec3(1, 0, 0));
|
||||||
//inte model, det kräver renderar grejs tydligen
|
//using a rawmodel here, else we have to init the renderingsystem
|
||||||
ResourceManager::RegisterType<RawModel>("RawModel");
|
ResourceManager::RegisterType<RawModel>("RawModel");
|
||||||
auto unitBox = ResourceManager::Load<RawModel>("Models/Core/UnitBox.obj");
|
auto unitBox = ResourceManager::Load<RawModel>("Models/Core/UnitBox.obj");
|
||||||
BOOST_CHECK(unitBox != nullptr);
|
BOOST_CHECK(unitBox != nullptr);
|
||||||
@@ -115,19 +114,24 @@ BOOST_AUTO_TEST_CASE(rayVsModelTest)
|
|||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(rayVsModelTest2)
|
BOOST_AUTO_TEST_CASE(rayVsModelTest2)
|
||||||
{
|
{
|
||||||
//advanced test, based on ray vs AABB
|
//advanced test, this will check so rayVSAABB and rayVsModel(with boxmodel) gives the same result (hit/miss)
|
||||||
srand(7676762);
|
//testing with different seeds
|
||||||
|
// srand(7676762);
|
||||||
|
// srand(7676462);
|
||||||
|
// srand(7462);
|
||||||
|
srand(72);
|
||||||
Ray ray;
|
Ray ray;
|
||||||
AABB someAABB;
|
AABB someAABB;
|
||||||
glm::vec3 minPos;
|
glm::vec3 minPos;
|
||||||
glm::vec3 maxPos;
|
glm::vec3 maxPos;
|
||||||
bool z;
|
bool z;
|
||||||
int test = 0;
|
int test = 0;
|
||||||
|
//min/max is the same as the rawmodels boundaries ofcourse
|
||||||
minPos = glm::vec3(-0.5f, -0.5f, -0.5f);
|
minPos = glm::vec3(-0.5f, -0.5f, -0.5f);
|
||||||
maxPos = glm::vec3(0.5f, 0.5f, 0.5f);
|
maxPos = glm::vec3(0.5f, 0.5f, 0.5f);
|
||||||
someAABB = AABB(minPos, maxPos);
|
someAABB = AABB(minPos, maxPos);
|
||||||
|
//using a rawmodel here, else we have to init the renderingsystem
|
||||||
ResourceManager::RegisterType<RawModel>("RawModel");
|
ResourceManager::RegisterType<RawModel>("RawModel");
|
||||||
//auto unitBox = ResourceManager::Load<RawModel>("Models/Core/UnitBox.obj");
|
|
||||||
auto unitBox = ResourceManager::Load<RawModel>("Models/Core/UnitCube.obj");
|
auto unitBox = ResourceManager::Load<RawModel>("Models/Core/UnitCube.obj");
|
||||||
BOOST_CHECK(unitBox != nullptr);
|
BOOST_CHECK(unitBox != nullptr);
|
||||||
|
|
||||||
@@ -142,6 +146,9 @@ BOOST_AUTO_TEST_CASE(rayVsModelTest2)
|
|||||||
ray.Origin /= 100;
|
ray.Origin /= 100;
|
||||||
ray.Origin = glm::vec3(-2, 0, 0);
|
ray.Origin = glm::vec3(-2, 0, 0);
|
||||||
ray.Direction /= 100;
|
ray.Direction /= 100;
|
||||||
|
//if we normalize the ray.direction when its 0,0,0 then we get nan,nan,nan - thus we have this check to prevent that
|
||||||
|
if (ray.Direction.x < 0.0001f && ray.Direction.y < 0.0001f && ray.Direction.z < 0.0001f)
|
||||||
|
continue;
|
||||||
ray.Direction = glm::normalize(ray.Direction);
|
ray.Direction = glm::normalize(ray.Direction);
|
||||||
|
|
||||||
z = Collision::RayVsAABB(ray, someAABB);
|
z = Collision::RayVsAABB(ray, someAABB);
|
||||||
@@ -149,7 +156,7 @@ BOOST_AUTO_TEST_CASE(rayVsModelTest2)
|
|||||||
//hit
|
//hit
|
||||||
bool hit = Collision::RayVsModel(ray, unitBox->m_Vertices, unitBox->m_Indices);
|
bool hit = Collision::RayVsModel(ray, unitBox->m_Vertices, unitBox->m_Indices);
|
||||||
if (!hit) {
|
if (!hit) {
|
||||||
hit = hit;
|
//if rayvsaabb hit but rayvvmodel didnt hit, we get to here
|
||||||
glm::vec3 outtttttttt;
|
glm::vec3 outtttttttt;
|
||||||
hit = Collision::RayVsModel(ray, unitBox->m_Vertices, unitBox->m_Indices, outtttttttt);
|
hit = Collision::RayVsModel(ray, unitBox->m_Vertices, unitBox->m_Indices, outtttttttt);
|
||||||
hit = Collision::RayVsModel(ray, unitBox->m_Vertices, unitBox->m_Indices);
|
hit = Collision::RayVsModel(ray, unitBox->m_Vertices, unitBox->m_Indices);
|
||||||
@@ -159,13 +166,21 @@ BOOST_AUTO_TEST_CASE(rayVsModelTest2)
|
|||||||
}
|
}
|
||||||
BOOST_CHECK(hit);
|
BOOST_CHECK(hit);
|
||||||
}
|
}
|
||||||
|
////breakpoint test
|
||||||
|
//if (!z) {
|
||||||
|
// z = z;
|
||||||
|
//}
|
||||||
//
|
//
|
||||||
bool hit = Collision::RayVsModel(ray, unitBox->m_Vertices, unitBox->m_Indices);
|
bool hit = Collision::RayVsModel(ray, unitBox->m_Vertices, unitBox->m_Indices);
|
||||||
|
////breakpoint test
|
||||||
|
//if (!hit) {
|
||||||
|
// hit = hit;
|
||||||
|
//}
|
||||||
if (hit) {
|
if (hit) {
|
||||||
//hit
|
//hit
|
||||||
z = Collision::RayVsAABB(ray, someAABB);
|
z = Collision::RayVsAABB(ray, someAABB);
|
||||||
if (!z) {
|
if (!z) {
|
||||||
z = z;
|
//if rayvsmodel hit but rayvsaabb didnt hit then we get to here
|
||||||
z = Collision::RayVsAABB(ray, someAABB);
|
z = Collision::RayVsAABB(ray, someAABB);
|
||||||
glm::vec3 outtttttttt;
|
glm::vec3 outtttttttt;
|
||||||
hit = Collision::RayVsModel(ray, unitBox->m_Vertices, unitBox->m_Indices, outtttttttt);
|
hit = Collision::RayVsModel(ray, unitBox->m_Vertices, unitBox->m_Indices, outtttttttt);
|
||||||
@@ -180,7 +195,62 @@ BOOST_AUTO_TEST_CASE(rayVsModelTest2)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(rayVsModelTest3)
|
||||||
|
{
|
||||||
|
//simple test
|
||||||
|
|
||||||
|
Ray ray;
|
||||||
|
ray.Origin = glm::vec3(-50, 0, 0);
|
||||||
|
//ray.Direction = glm::vec3(-1, 0, 0);
|
||||||
|
ray.Direction = glm::normalize(glm::vec3(1, 0, 0));
|
||||||
|
//using a rawmodel here, else we have to init the renderingsystem
|
||||||
|
ResourceManager::RegisterType<RawModel>("RawModel");
|
||||||
|
auto unitBox = ResourceManager::Load<RawModel>("Models/Core/UnitSphere.obj");
|
||||||
|
BOOST_CHECK(unitBox != nullptr);
|
||||||
|
bool hit = Collision::RayVsModel(ray, unitBox->m_Vertices, unitBox->m_Indices);
|
||||||
|
BOOST_CHECK(hit);
|
||||||
|
ray.Direction = glm::normalize(glm::vec3(-1, 0, 0));
|
||||||
|
hit = Collision::RayVsModel(ray, unitBox->m_Vertices, unitBox->m_Indices);
|
||||||
|
BOOST_CHECK(!hit);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(rayVsModelTest4)
|
||||||
|
{
|
||||||
|
//simple test
|
||||||
|
|
||||||
|
Ray ray;
|
||||||
|
ray.Origin = glm::vec3(-50, 0, 0);
|
||||||
|
//ray.Direction = glm::vec3(-1, 0, 0);
|
||||||
|
ray.Direction = glm::normalize(glm::vec3(1, 0, 0));
|
||||||
|
//using a rawmodel here, else we have to init the renderingsystem
|
||||||
|
ResourceManager::RegisterType<RawModel>("RawModel");
|
||||||
|
auto unitBox = ResourceManager::Load<RawModel>("Models/Core/UnitCylinder.obj");
|
||||||
|
BOOST_CHECK(unitBox != nullptr);
|
||||||
|
bool hit = Collision::RayVsModel(ray, unitBox->m_Vertices, unitBox->m_Indices);
|
||||||
|
BOOST_CHECK(hit);
|
||||||
|
ray.Direction = glm::normalize(glm::vec3(-1, 0, 0));
|
||||||
|
hit = Collision::RayVsModel(ray, unitBox->m_Vertices, unitBox->m_Indices);
|
||||||
|
BOOST_CHECK(!hit);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(rayVsModelTest5)
|
||||||
|
{
|
||||||
|
//simple test
|
||||||
|
|
||||||
|
Ray ray;
|
||||||
|
ray.Origin = glm::vec3(-50, 0, 0);
|
||||||
|
//ray.Direction = glm::vec3(-1, 0, 0);
|
||||||
|
ray.Direction = glm::normalize(glm::vec3(1, 0, 0));
|
||||||
|
//using a rawmodel here, else we have to init the renderingsystem
|
||||||
|
ResourceManager::RegisterType<RawModel>("RawModel");
|
||||||
|
auto unitBox = ResourceManager::Load<RawModel>("Models/Core/UnitRaptor.obj");
|
||||||
|
BOOST_CHECK(unitBox != nullptr);
|
||||||
|
bool hit = Collision::RayVsModel(ray, unitBox->m_Vertices, unitBox->m_Indices);
|
||||||
|
BOOST_CHECK(hit);
|
||||||
|
ray.Direction = glm::normalize(glm::vec3(-1, 0, 0));
|
||||||
|
hit = Collision::RayVsModel(ray, unitBox->m_Vertices, unitBox->m_Indices);
|
||||||
|
BOOST_CHECK(!hit);
|
||||||
|
}
|
||||||
BOOST_AUTO_TEST_CASE(octTest)
|
BOOST_AUTO_TEST_CASE(octTest)
|
||||||
{
|
{
|
||||||
glm::vec3 mini = glm::vec3(-1, -1, -1);
|
glm::vec3 mini = glm::vec3(-1, -1, -1);
|
||||||
|
|||||||
Reference in New Issue
Block a user