Browse Source

More work on the octree

Panagiotis Christopoulos Charitos 7 years ago
parent
commit
780d912613
2 changed files with 79 additions and 20 deletions
  1. 64 12
      src/anki/scene/Octree.cpp
  2. 15 8
      src/anki/scene/Octree.h

+ 64 - 12
src/anki/scene/Octree.cpp

@@ -28,7 +28,7 @@ void Octree::place(const Aabb& volume, OctreeHandle* handle)
 	ANKI_ASSERT(handle);
 
 	// Remove the handle from the Octree...
-	// TOOD
+	// TODO
 
 	// .. and re-place it
 	placeRecursive(volume, handle, m_rootLeaf, m_sceneAabbMin, m_sceneAabbMax, 0);
@@ -53,7 +53,7 @@ void Octree::placeRecursive(
 
 		// Connect handle and leaf
 		handle->m_leafs.pushBack(newLeafNode(parent));
-		parent->m_handles.pushBack(newHandle(handle));
+		parent->m_handles.pushBack(newHandleNode(handle));
 
 		return;
 	}
@@ -110,32 +110,84 @@ void Octree::placeRecursive(
 		maskZ = LeafMask::ALL;
 	}
 
-	LeafMask maskUnion = maskX & maskY & maskZ;
+	const LeafMask maskUnion = maskX & maskY & maskZ;
 	ANKI_ASSERT(!!maskUnion && "Should be inside at least one leaf");
 
 	for(U i = 0; i < 8; ++i)
 	{
-		const LeafMask crntBit = LeafMask(1 << i);
+		const LeafMask crntBit = LeafMask(1u << i);
 
 		if(!!(maskUnion & crntBit))
 		{
 			// Inside the leaf, move deeper
 
-			// Compute AABB
-			Vec3 aabbMin, aabbMax;
-			if(!!(crntBit & LeafMask::RIGHT))
-			{
-				// TODO
-			}
-
+			// Create the leaf
 			if(parent->m_leafs[i] == nullptr)
 			{
 				parent->m_leafs[i] = newLeaf();
 			}
 
-			// TODO
+			// Compute AABB
+			Vec3 childAabbMin, childAabbMax;
+			computeChildAabb(crntBit, aabbMin, aabbMax, center, childAabbMin, childAabbMax);
+
+			// Move deeper
+			placeRecursive(volume, handle, parent->m_leafs[i], childAabbMin, childAabbMax, depth + 1);
 		}
 	}
 }
 
+void Octree::computeChildAabb(LeafMask child,
+	const Vec3& parentAabbMin,
+	const Vec3& parentAabbMax,
+	const Vec3& parentAabbCenter,
+	Vec3& childAabbMin,
+	Vec3& childAabbMax)
+{
+	ANKI_ASSERT(__builtin_popcount(U32(child)) == 1);
+
+	const Vec3& m = parentAabbMin;
+	const Vec3& M = parentAabbMax;
+	const Vec3& c = parentAabbCenter;
+
+	if(!!(child & LeafMask::RIGHT))
+	{
+		// Right
+		childAabbMin.x() = c.x();
+		childAabbMax.x() = M.x();
+	}
+	else
+	{
+		// Left
+		childAabbMin.x() = m.x();
+		childAabbMax.x() = c.x();
+	}
+
+	if(!!(child & LeafMask::TOP))
+	{
+		// Top
+		childAabbMin.y() = c.y();
+		childAabbMax.y() = M.y();
+	}
+	else
+	{
+		// Bottom
+		childAabbMin.y() = m.y();
+		childAabbMax.y() = c.y();
+	}
+
+	if(!!(child & LeafMask::FRONT))
+	{
+		// Front
+		childAabbMin.z() = c.z();
+		childAabbMax.z() = M.z();
+	}
+	else
+	{
+		// Back
+		childAabbMin.z() = m.z();
+		childAabbMax.z() = c.z();
+	}
+}
+
 } // end namespace anki

+ 15 - 8
src/anki/scene/Octree.h

@@ -51,22 +51,22 @@ public:
 
 private:
 	/// XXX
-	class Handle : public IntrusiveListEnabled<Handle>
+	class HandleNode : public IntrusiveListEnabled<HandleNode>
 	{
 	public:
 		OctreeHandle* m_handle = nullptr;
 	};
 
-	/// XXX
+	/// Octree leaf.
 	/// @warning Keept its size as small as possible.
 	class Leaf
 	{
 	public:
-		IntrusiveList<Handle> m_handles;
+		IntrusiveList<HandleNode> m_handles;
 		Array<Leaf*, 8> m_leafs = {};
 	};
 
-	/// XXX
+	/// Used so that OctreeHandle knows which leafs it belongs to.
 	class LeafNode : public IntrusiveListEnabled<LeafNode>
 	{
 	public:
@@ -103,7 +103,7 @@ private:
 
 	ObjectAllocatorSameType<Leaf, 256> m_leafAlloc;
 	ObjectAllocatorSameType<LeafNode, 128> m_leafNodeAlloc;
-	ObjectAllocatorSameType<Handle, 256> m_handleAlloc;
+	ObjectAllocatorSameType<HandleNode, 256> m_handleAlloc;
 
 	Leaf* m_rootLeaf = nullptr;
 
@@ -117,15 +117,15 @@ private:
 		m_leafAlloc.deleteInstance(m_alloc, leaf);
 	}
 
-	Handle* newHandle(OctreeHandle* handle)
+	HandleNode* newHandleNode(OctreeHandle* handle)
 	{
 		ANKI_ASSERT(handle);
-		Handle* out = m_handleAlloc.newInstance(m_alloc);
+		HandleNode* out = m_handleAlloc.newInstance(m_alloc);
 		out->m_handle = handle;
 		return out;
 	}
 
-	void releaseHandle(Handle* handle)
+	void releaseHandle(HandleNode* handle)
 	{
 		m_handleAlloc.deleteInstance(m_alloc, handle);
 	}
@@ -145,6 +145,13 @@ private:
 
 	void placeRecursive(
 		const Aabb& volume, OctreeHandle* handle, Leaf* parent, const Vec3& aabbMin, const Vec3& aabbMax, U32 depth);
+
+	void computeChildAabb(LeafMask child,
+		const Vec3& parentAabbMin,
+		const Vec3& parentAabbMax,
+		const Vec3& parentAabbCenter,
+		Vec3& childAabbMin,
+		Vec3& childAabbMax);
 };
 
 /// XXX