Browse Source

Sector and Octree

Panagiotis Christopoulos Charitos 13 years ago
parent
commit
78ffb1a151

+ 1 - 0
include/anki/scene/Common.h

@@ -3,6 +3,7 @@
 
 #include "anki/util/Allocator.h"
 #include "anki/util/Vector.h"
+#include "anki/util/StdTypes.h"
 
 namespace anki {
 

+ 6 - 5
include/anki/scene/Frustumable.h

@@ -11,6 +11,7 @@ namespace anki {
 // Forward
 class SectorGroup;
 class Sector;
+struct VisibilityTestResults;
 
 /// @addtogroup Scene
 /// @{
@@ -26,8 +27,8 @@ public:
 	/// @{
 
 	/// Pass the frustum here so we can avoid the virtuals
-	Frustumable(const SceneAllocator<U8>& alloc, Frustum* fr)
-		: frustum(fr), renderables(alloc), lights(alloc)
+	Frustumable(Frustum* fr)
+		: frustum(fr)
 	{}
 	/// @}
 
@@ -70,8 +71,8 @@ public:
 	/// Call this after the tests. Before it will point to junk
 	const VisibilityTestResults& getVisibilityTestResults() const
 	{
-		ANKI_ASSERT(visibles != nullptr);
-		return *visibles;
+		ANKI_ASSERT(visible != nullptr);
+		return *visible;
 	}
 
 	/// Get the origin for sorting and visibility tests
@@ -107,7 +108,7 @@ private:
 
 	/// Visibility stuff. It's per frame so the pointer is invalid on the next 
 	/// frame and before any visibility tests are run
-	VisibilityTestResults* visibles = nullptr;
+	VisibilityTestResults* visible = nullptr;
 };
 
 /// @}

+ 30 - 5
include/anki/scene/Octree.h

@@ -9,9 +9,11 @@
 
 namespace anki {
 
-class Spatial;
+// Forward
 class Frustumable;
 class SceneNode;
+class Octree;
+class Sector;
 
 /// Octree node
 class OctreeNode
@@ -68,6 +70,12 @@ public:
 
 	void removeSceneNode(SceneNode* sn);
 
+	/// @{
+	/// Will traverse to find the octree
+	const Octree& getOctree() const;
+	Octree& getOctree();
+	/// @}
+
 private:
 	ChildrenContainer children;
 	OctreeNode* parent;
@@ -79,12 +87,29 @@ private:
 	void addChild(U pos, OctreeNode* child);
 };
 
+/// Octree node
+class RootOctreeNode: public OctreeNode
+{
+	friend class OctreeNode;
+	friend class Octree;
+
+public:
+	RootOctreeNode(const Aabb& aabb, const SceneAllocator<U8>& alloc,
+		Octree* octree_)
+		: OctreeNode(aabb, nullptr, alloc), octree(octree_)
+	{
+		ANKI_ASSERT(octree != nullptr);
+	}
+
+private:
+	Octree* octree;
+};
+
 /// Octree
 class Octree
 {
 public:
-	Octree(const SceneAllocator<U8>& alloc, const Aabb& aabb, U8 maxDepth, 
-		F32 looseness = 1.5);
+	Octree(Sector* sector, const Aabb& aabb, U8 maxDepth, F32 looseness = 1.5);
 
 	~Octree();
 
@@ -114,10 +139,10 @@ public:
 		SceneVector<SceneNode*>* lightNodes);
 
 private:
-	SceneAllocator<U8> alloc;
+	Sector* sector;
 	U maxDepth;
 	F32 looseness;
-	OctreeNode root;
+	RootOctreeNode root;
 
 	OctreeNode* placeInternal(const Aabb& aabb, U depth, OctreeNode& node);
 

+ 28 - 4
include/anki/scene/Sector.h

@@ -10,6 +10,7 @@ namespace anki {
 class SceneNode;
 class Scene;
 class Sector;
+class SectorGroup;
 
 /// @addtogroup Scene
 /// @{
@@ -24,13 +25,13 @@ struct Portal
 };
 
 /// A sector. It consists of an octree and some portals
-struct Sector
+class Sector
 {
-	Octree octree;
-	SceneVector<Portal*> portals;
+	friend class SectorGroup;
 
+public:
 	/// Default constructor
-	Sector(const SceneAllocator<U8>& alloc, const Aabb& box);
+	Sector(SectorGroup* group, const Aabb& box);
 
 	/// Called when a node was moved or a change in shape happened
 	Bool placeSceneNode(SceneNode* sp);
@@ -39,6 +40,20 @@ struct Sector
 	{
 		return octree.getRoot().getAabb();
 	}
+
+	const SectorGroup& getSectorGroup() const
+	{
+		return *group;
+	}
+	SectorGroup& getSectorGroup()
+	{
+		return *group;
+	}
+
+private:
+	SectorGroup* group; ///< Know your father
+	Octree octree;
+	SceneVector<Portal*> portals;
 };
 
 /// Sector group. This is supposed to represent the whole scene
@@ -58,6 +73,15 @@ public:
 	/// Destructor
 	~SectorGroup();
 
+	const Scene& getScene() const
+	{
+		return *scene;
+	}
+	Scene& getScene()
+	{
+		return *scene;
+	}
+
 	/// Called when a node was moved or a change in shape happened. The node 
 	/// must be Spatial
 	void placeSceneNode(SceneNode* sp);

+ 1 - 1
include/anki/scene/VisibilityTestResults.h

@@ -20,7 +20,7 @@ struct VisibilityTestResults
 	Renderables renderables;
 	Lights lights;
 
-	VisibilityTestResults(const SceneVector<U8>& frameAlloc)
+	VisibilityTestResults(const SceneAllocator<U8>& frameAlloc)
 		: renderables(frameAlloc), lights(frameAlloc)
 	{}
 };

+ 1 - 1
src/scene/Camera.cpp

@@ -14,7 +14,7 @@ Camera::Camera(CameraType type_,
 	:	SceneNode(name, scene),
 		Movable(movableFlags, movParent, *this, getSceneAllocator()),
 		Spatial(this, frustum),
-		Frustumable(getSceneAllocator(), frustum),
+		Frustumable(frustum),
 		type(type_)
 {}
 

+ 1 - 1
src/scene/Light.cpp

@@ -48,7 +48,7 @@ PointLight::PointLight(const char* name, Scene* scene,
 SpotLight::SpotLight(const char* name, Scene* scene,
 	U32 movableFlags, Movable* movParent)
 	: 	Light(LT_SPOT, name, scene, movableFlags, movParent, &frustum),
-		Frustumable(getSceneAllocator(), &frustum)
+		Frustumable(&frustum)
 {
 	const F32 ang = toRad(45.0);
 	setOuterAngle(ang / 2.0);

+ 34 - 4
src/scene/Octree.cpp

@@ -2,6 +2,8 @@
 #include "anki/scene/Spatial.h"
 #include "anki/scene/Frustumable.h"
 #include "anki/scene/Light.h"
+#include "anki/scene/Sector.h"
+#include "anki/scene/Scene.h"
 #include "anki/util/Exception.h"
 #include "anki/core/Logger.h"
 
@@ -90,17 +92,42 @@ void OctreeNode::addChild(U pos, OctreeNode* child)
 	children[pos] = child;
 }
 
+//==============================================================================
+const Octree& OctreeNode::getOctree() const
+{
+	const OctreeNode* root = this;
+	while(root->parent != nullptr)
+	{
+		root = root->parent;
+	}
+
+	const RootOctreeNode* realRoot = static_cast<const RootOctreeNode*>(root);
+	return *(realRoot->octree);
+}
+
+//==============================================================================
+Octree& OctreeNode::getOctree()
+{
+	OctreeNode* root = this;
+	while(root->parent != nullptr)
+	{
+		root = root->parent;
+	}
+
+	RootOctreeNode* realRoot = static_cast<RootOctreeNode*>(root);
+	return *(realRoot->octree);
+}
+
 //==============================================================================
 // Octree                                                                      =
 //==============================================================================
 
 //==============================================================================
-Octree::Octree(const SceneAllocator<U8>& alloc_, const Aabb& aabb, 
-	U8 maxDepth_, F32 looseness_)
-	: alloc(alloc_),
+Octree::Octree(Sector* sector_, const Aabb& aabb, U8 maxDepth_, F32 looseness_)
+	: sector(sector_),
 		maxDepth(maxDepth_ < 1 ? 1 : maxDepth_), 
 		looseness(looseness_),
-		root(aabb, nullptr, alloc)
+		root(aabb, sector->getSectorGroup().getScene().getAllocator(), this)
 {}
 
 //==============================================================================
@@ -172,6 +199,9 @@ OctreeNode* Octree::placeInternal(const Aabb& aabb, U depth, OctreeNode& node)
 					// Go deeper
 					if(node.children[id] == nullptr)
 					{
+						SceneAllocator<U8> alloc =
+							sector->getSectorGroup().getScene().getAllocator();
+
 						// Create new node if needed
 						OctreeNode* newNode =
 							ANKI_NEW(OctreeNode, alloc,

+ 18 - 2
src/scene/Sector.cpp

@@ -1,6 +1,8 @@
 #include "anki/scene/Sector.h"
 #include "anki/scene/Spatial.h"
 #include "anki/scene/SceneNode.h"
+#include "anki/scene/VisibilityTestResults.h"
+#include "anki/scene/Frustumable.h"
 #include "anki/scene/Scene.h"
 #include "anki/core/Logger.h"
 
@@ -21,8 +23,9 @@ Portal::Portal()
 //==============================================================================
 
 //==============================================================================
-Sector::Sector(const SceneAllocator<U8>& alloc_, const Aabb& box)
-	: octree(alloc_, box, 3), portals(alloc_)
+Sector::Sector(SectorGroup* group_, const Aabb& box)
+	: group(group_), octree(this, box, 3),
+		portals(group->getScene().getAllocator())
 {}
 
 //==============================================================================
@@ -112,4 +115,17 @@ void SectorGroup::placeSceneNode(SceneNode* sn)
 	}
 }
 
+//==============================================================================
+void SectorGroup::doVisibilityTests(Frustumable& fr, VisibilityTest test)
+{
+	/// Create the visibility container
+	VisibilityTestResults* visible =
+		ANKI_NEW(VisibilityTestResults, scene->getFrameAllocator(),
+		scene->getFrameAllocator());
+
+	// Find the sectors
+
+	fr.visible = visible;
+}
+
 } // end namespace anki