|
|
@@ -1,5 +1,7 @@
|
|
|
#include "anki/scene/Octree.h"
|
|
|
#include "anki/util/Exception.h"
|
|
|
+#include "anki/core/Logger.h"
|
|
|
+#include "anki/core/Globals.h"
|
|
|
#include "anki/collision/CollisionAlgorithmsMatrix.h"
|
|
|
|
|
|
|
|
|
@@ -7,99 +9,118 @@ namespace anki {
|
|
|
|
|
|
|
|
|
//==============================================================================
|
|
|
-Octree::Octree(const Aabb& aabb, uchar maxDepth_)
|
|
|
-: maxDepth(maxDepth_)
|
|
|
+Octree::Octree(const Aabb& aabb, uchar maxDepth_, float looseness_)
|
|
|
+: maxDepth(maxDepth_ < 1 ? 1 : maxDepth_),
|
|
|
+ looseness(looseness_)
|
|
|
{
|
|
|
- if(maxDepth < 1)
|
|
|
- {
|
|
|
- maxDepth = 1;
|
|
|
- }
|
|
|
-
|
|
|
// Create root
|
|
|
- root = new OctreeNode();
|
|
|
- root->aabb = aabb;
|
|
|
-
|
|
|
- // Create children
|
|
|
- //createSubTree(maxDepth, *root);
|
|
|
+ root = new OctreeNode(aabb, NULL);
|
|
|
+ nodes.push_back(root);
|
|
|
}
|
|
|
|
|
|
|
|
|
//==============================================================================
|
|
|
-OctreeNode& Octree::place(const Aabb& aabb)
|
|
|
+OctreeNode* Octree::place(const Aabb& aabb)
|
|
|
{
|
|
|
- // Run the recursive
|
|
|
- return place(aabb, 0, *root);
|
|
|
+ if(CollisionAlgorithmsMatrix::collide(aabb, root->getAabb()))
|
|
|
+ {
|
|
|
+ // Run the recursive
|
|
|
+ return place(aabb, 0, *root);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
|
|
|
//==============================================================================
|
|
|
-OctreeNode& Octree::place(const Aabb& aabb, uint depth, OctreeNode& node)
|
|
|
+OctreeNode* Octree::place(const Aabb& aabb, uint depth, OctreeNode& node)
|
|
|
{
|
|
|
if(depth >= maxDepth)
|
|
|
{
|
|
|
- return node;
|
|
|
+ return &node;
|
|
|
}
|
|
|
|
|
|
- uint count = 0;
|
|
|
- uint last = 0;
|
|
|
- for(uint i = 0; i < 8; ++i)
|
|
|
+
|
|
|
+ for(uint i = 0; i < 2; ++i)
|
|
|
{
|
|
|
- if(CollisionAlgorithmsMatrix::collide(aabb, node.children[i].aabb))
|
|
|
+ for(uint j = 0; j < 2; ++j)
|
|
|
{
|
|
|
- last = i;
|
|
|
- ++count;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- ASSERT(count != 0);
|
|
|
+ for(uint k = 0; k < 2; ++k)
|
|
|
+ {
|
|
|
+ uint id = i * 4 + j * 2 + k;
|
|
|
+
|
|
|
+ Aabb childAabb;
|
|
|
+ if(node.getChildren()[id] != NULL)
|
|
|
+ {
|
|
|
+ childAabb = node.getChildren()[id]->getAabb();
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ calcAabb(i, j, k, node.getAabb(), childAabb);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // If aabb its completely inside the target
|
|
|
+ if(aabb.getMax() <= childAabb.getMax() &&
|
|
|
+ aabb.getMin() >= childAabb.getMin())
|
|
|
+ {
|
|
|
+ // Create new node if needed
|
|
|
+ if(node.getChildren()[id] == NULL)
|
|
|
+ {
|
|
|
+ OctreeNode* newNode = new OctreeNode(childAabb, &node);
|
|
|
+ node.addChild(id, *newNode);
|
|
|
+ nodes.push_back(newNode);
|
|
|
+ }
|
|
|
+
|
|
|
+ return place(aabb, depth + 1, *node.getChildren()[id]);
|
|
|
+ }
|
|
|
+ } // k
|
|
|
+ } // j
|
|
|
+ } // i
|
|
|
|
|
|
- if(count == 1)
|
|
|
- {
|
|
|
- return place(aabb, depth + 1, node.children[last]);
|
|
|
- }
|
|
|
+ return &node;
|
|
|
}
|
|
|
|
|
|
|
|
|
//==============================================================================
|
|
|
-/*void Octree::createSubTree(uint rdepth, OctreeNode& parent)
|
|
|
+void Octree::calcAabb(uint i, uint j, uint k, const Aabb& paabb,
|
|
|
+ Aabb& out) const
|
|
|
{
|
|
|
- if(rdepth == 0)
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- const Aabb& paabb = parent.getAabb();
|
|
|
const Vec3& min = paabb.getMin();
|
|
|
const Vec3& max = paabb.getMax();
|
|
|
-
|
|
|
Vec3 d = (max - min) / 2.0;
|
|
|
|
|
|
- // Create children
|
|
|
- for(uint i = 0; i < 2; ++i)
|
|
|
- {
|
|
|
- for(uint j = 0; j < 2; ++j)
|
|
|
- {
|
|
|
- for(uint k = 0; k < 2; ++k)
|
|
|
- {
|
|
|
- Vec3 omin;
|
|
|
- omin.x() = min.x() + d.x() * i;
|
|
|
- omin.y() = min.y() + d.y() * j;
|
|
|
- omin.z() = min.z() + d.z() * k;
|
|
|
+ Vec3 omin;
|
|
|
+ omin.x() = min.x() + d.x() * i;
|
|
|
+ omin.y() = min.y() + d.y() * j;
|
|
|
+ omin.z() = min.z() + d.z() * k;
|
|
|
|
|
|
- Vec3 omax = omin + d;
|
|
|
+ Vec3 omax = omin + d;
|
|
|
|
|
|
- OctreeNode* node = new OctreeNode();
|
|
|
- node->parent = &parent;
|
|
|
- node->aabb = Aabb(omin, omax);
|
|
|
+ // Scale the AABB with looseness
|
|
|
+ float tmp0 = (1.0 + looseness) / 2.0;
|
|
|
+ float tmp1 = (1.0 - looseness) / 2.0;
|
|
|
+ Vec3 nomin = tmp0 * omin + tmp1 * omax;
|
|
|
+ Vec3 nomax = tmp0 * omax + tmp1 * omin;
|
|
|
|
|
|
- parent.children[i * 4 + j * 2 + k] = node;
|
|
|
- nodes.push_back(node);
|
|
|
+ // Crop to fit the parent's AABB
|
|
|
+ for(uint n = 0; n < 3; ++n)
|
|
|
+ {
|
|
|
+ if(nomin[n] < min[n])
|
|
|
+ {
|
|
|
+ nomin[n] = min[n];
|
|
|
+ }
|
|
|
|
|
|
- createSubTree(rdepth - 1, *node);
|
|
|
- } // k
|
|
|
- } // j
|
|
|
- } // i
|
|
|
-}*/
|
|
|
+ if(nomax[n] > max[n])
|
|
|
+ {
|
|
|
+ nomax[n] = max[n];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ out = Aabb(nomin, nomax);
|
|
|
+}
|
|
|
|
|
|
|
|
|
} // end namespace
|