Made some optimizations in OctTree and added a unit test for BoxesInSameRegion.

This commit is contained in:
William Moberg
2015-12-09 17:16:11 +01:00
parent 14bcb7ea0d
commit e580540143
3 changed files with 58 additions and 26 deletions
+4 -5
View File
@@ -25,9 +25,6 @@ public:
OctTree(const OctTree&& other) = delete;
OctTree& operator= (const OctTree& other) = delete;
//Collision test function. WTODO: Probably remove or relocate elsewhere, Collision system?
void Update(float dt, World* world, Camera* cam);
void AddDynamicObject(const AABB& box);
void AddStaticObject(const AABB& box);
@@ -36,10 +33,13 @@ public:
void ClearObjects();
void ClearDynamicObjects();
//Collision test function. WTODO: Probably remove or relocate elsewhere, Collision system?
void Update(float dt, World* world, Camera* cam);
//Returns true if the ray collides with something in the tree. Result is written to [data].
bool RayCollides(const Ray& ray, Output& data) const;
//Returns true if the box collides with something in the tree.
//On collision with a box, that box is written to [outBoxIntersected].
//Note: More efficient than calling BoxesInSameRegion from outside and testing there.
bool BoxCollides(const AABB& boxToTest, AABB& outBoxIntersected) const;
private:
@@ -47,11 +47,10 @@ private:
//WTODO: Do -derived class from AABB- struct containing AABB, with a bool Tested, falsify at
//start of Collision test, set on check, don't check if set already. Solves duplicate boxes in tree.
//Store indices in the struct, pointing to grand ancestor list of boxes, need the same AABB not copies to save Tested.
//WTODO: Boxes collide with themselves? Fix somehow, maybe float epsilon stuff.
std::vector<AABB> m_StaticObjects;
std::vector<AABB> m_DynamicObjects;
AABB m_Box;
bool m_UpdatedOnce;
unsigned int m_BoxID;
glm::vec3 m_PrevPos;
+34 -21
View File
@@ -21,6 +21,16 @@ bool isFirstLower(const ChildInfo& first, const ChildInfo& second)
return first.Distance < second.Distance;
}
bool isSameBoxProbably(const AABB& first, const AABB& second)
{
const float EPS = 0.0001f;
const auto& ma = first.MaxCorner();
const auto& mi = first.MinCorner();
return (std::abs(ma.x - mi.x) < EPS) &&
(std::abs(ma.z - mi.z) < EPS) &&
(std::abs(ma.y - mi.y) < EPS);
}
}
OctTree::OctTree()
@@ -131,16 +141,18 @@ bool OctTree::BoxCollides(const AABB& boxToTest, AABB& outBoxIntersected) const
return true;
}
} else {
std::vector<std::vector<AABB>> objVectors = {
m_StaticObjects,
m_DynamicObjects
};
for (const auto& objVector : objVectors) {
for (const auto& obj : objVector) {
if (Collision::AABBVsAABB(boxToTest, obj)) {
outBoxIntersected = obj;
return true;
}
for (const auto& obj : m_StaticObjects) {
if (Collision::AABBVsAABB(boxToTest, obj)) {
outBoxIntersected = obj;
return true;
}
}
for (const auto& obj : m_DynamicObjects) {
//If there is a collision and it is not testing against itself.
if (!isSameBoxProbably(boxToTest, obj) &&
Collision::AABBVsAABB(boxToTest, obj)) {
outBoxIntersected = obj;
return true;
}
}
}
@@ -170,17 +182,18 @@ bool OctTree::RayCollides(const Ray& ray, Output& data) const
//Check against boxes in the node.
float minDist = INFINITY;
bool intersected = false;
std::vector<std::vector<AABB>> objVectors = {
m_StaticObjects,
m_DynamicObjects
};
for (const auto& objVector : objVectors) {
for (const auto& obj : objVector) {
float dist;
if (Collision::RayVsAABB(ray, obj, dist)) {
minDist = std::min(dist, minDist);
intersected = true;
}
for (const auto& obj : m_StaticObjects) {
float dist;
if (Collision::RayVsAABB(ray, obj, dist)) {
minDist = std::min(dist, minDist);
intersected = true;
}
}
for (const auto& obj : m_DynamicObjects) {
float dist;
if (Collision::RayVsAABB(ray, obj, dist)) {
minDist = std::min(dist, minDist);
intersected = true;
}
}
+20
View File
@@ -16,5 +16,25 @@ BOOST_AUTO_TEST_CASE(octTreeTest2)
}
BOOST_AUTO_TEST_CASE(octSameRegionTest)
{
glm::vec3 mini = glm::vec3(-1, -1, -1);
glm::vec3 maxi = glm::vec3(1, 1, 1);
OctTree tree(AABB(mini, maxi), 2);
AABB firstQuadrant(mini, 0.8f*mini);
tree.AddStaticObject(firstQuadrant);
AABB testBox(0.9f*mini, 0.8f*mini);
std::vector<AABB> region;
tree.BoxesInSameRegion(testBox, region);
BOOST_REQUIRE(region.size() == 1);
AABB& box = region[0];
BOOST_CHECK_CLOSE_FRACTION(box.Center().x, firstQuadrant.Center().x, 0.00001f);
BOOST_CHECK_CLOSE_FRACTION(box.Center().y, firstQuadrant.Center().y, 0.00001f);
BOOST_CHECK_CLOSE_FRACTION(box.Center().z, firstQuadrant.Center().z, 0.00001f);
BOOST_CHECK_CLOSE_FRACTION(box.HalfSize().x, firstQuadrant.HalfSize().x, 0.00001f);
BOOST_CHECK_CLOSE_FRACTION(box.HalfSize().y, firstQuadrant.HalfSize().y, 0.00001f);
BOOST_CHECK_CLOSE_FRACTION(box.HalfSize().z, firstQuadrant.HalfSize().z, 0.00001f);
}
BOOST_AUTO_TEST_SUITE_END()