Răsfoiți Sursa

Visibility tests

Panagiotis Christopoulos Charitos 13 ani în urmă
părinte
comite
7ab90610fe

+ 22 - 13
include/anki/scene/Octree.h

@@ -9,6 +9,8 @@
 namespace anki {
 
 class Spatial;
+class Frustumable;
+class SceneNode;
 
 /// Octree node
 class OctreeNode
@@ -39,17 +41,17 @@ public:
 		return aabb;
 	}
 
-	Vector<Spatial*>::iterator getSpatialsBegin()
+	Vector<SceneNode*>::iterator getSceneNodesBegin()
 	{
-		return spatials.begin();
+		return sceneNodes.begin();
 	}
-	Vector<Spatial*>::iterator getSpatialsEnd()
+	Vector<SceneNode*>::iterator getSceneNodesEnd()
 	{
-		return spatials.end();
+		return sceneNodes.end();
 	}
-	uint32_t getSpatialsCount() const
+	uint32_t getSceneNodesCount() const
 	{
-		return spatials.size();
+		return sceneNodes.size();
 	}
 	/// @}
 
@@ -68,7 +70,7 @@ private:
 	ChildrenContainer children;
 	OctreeNode* parent;
 	Aabb aabb; ///< Including AABB
-	Vector<Spatial*> spatials;
+	Vector<SceneNode*> sceneNodes;
 };
 
 /// Octree
@@ -94,13 +96,11 @@ public:
 	}
 	/// @}
 
-	void placeSpatial(Spatial* sp);
+	/// Place a spatial in the tree
+	void placeSceneNode(SceneNode* sn);
 
-	/// Place an AABB inside the tree. The algorithm is pretty simple, find the
-	/// node that completely includes the aabb. If found then go deeper into
-	/// the node's children. The aabb will not be in more than one nodes. Also,
-	/// if it is ourside the tree then return nullptr
-	OctreeNode* place(const Aabb& aabb);
+	/// Fill the fr with visible data
+	void doVisibilityTests(Frustumable& fr);
 
 private:
 	uint32_t maxDepth;
@@ -109,6 +109,15 @@ private:
 
 	OctreeNode* place(const Aabb& aabb, uint depth, OctreeNode& node);
 
+	/// Place an AABB inside the tree. The algorithm is pretty simple, find the
+	/// node that completely includes the aabb. If found then go deeper into
+	/// the node's children. The aabb will not be in more than one nodes. Also,
+	/// if it is ourside the tree then return nullptr
+	OctreeNode* place(const Aabb& aabb);
+
+	/// Recursive method
+	void doVisibilityTestsRec(Frustumable& fr, OctreeNode& node);
+
 	void createChildren(OctreeNode& parent);
 
 	/// Calculate the AABB of a child given the parent's AABB and its

+ 2 - 2
include/anki/scene/Sector.h

@@ -5,7 +5,7 @@
 
 namespace anki {
 
-class Spatial;
+class SceneNode;
 
 /// A sector
 class Sector
@@ -24,7 +24,7 @@ public:
 		return octree;
 	}
 
-	bool placeSpatial(Spatial* sp);
+	bool placeSceneNode(SceneNode* sp);
 
 private:
 	Octree octree;

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

@@ -20,6 +20,7 @@ class Light;
 class VisibilityInfo
 {
 	friend class VisibilityTester;
+	friend class Octree;
 
 public:
 	typedef Vector<Renderable*> Renderables;

+ 1 - 1
src/renderer/Drawer.cpp

@@ -481,7 +481,7 @@ void SceneDebugDrawer::draw(const OctreeNode& octnode, uint32_t depth,
 	const Octree& octree) const
 {
 	// Draw if it has spatials
-	if(octnode.getSpatialsCount() != 0)
+	if(octnode.getSceneNodesCount() != 0)
 	{
 		//Vec3 color = Vec3(1.0 - float(depth) / float(octree.getMaxDepth()));
 		Vec3 color(1.0);

+ 62 - 8
src/scene/Octree.cpp

@@ -1,5 +1,7 @@
 #include "anki/scene/Octree.h"
 #include "anki/scene/Spatial.h"
+#include "anki/scene/Frustumable.h"
+#include "anki/scene/Light.h"
 #include "anki/util/Exception.h"
 #include "anki/core/Logger.h"
 #include "anki/collision/CollisionAlgorithmsMatrix.h"
@@ -13,13 +15,14 @@ Octree::Octree(const Aabb& aabb, uint8_t maxDepth_, float looseness_)
 {}
 
 //==============================================================================
-void Octree::placeSpatial(Spatial* sp)
+void Octree::placeSceneNode(SceneNode* sn)
 {
+	Spatial* sp = sn->getSpatial();
+	ANKI_ASSERT(sp != nullptr);
 	OctreeNode* toBePlacedNode = place(sp->getAabb());
 
 	if(toBePlacedNode == nullptr)
 	{
-		ANKI_LOGI("Outside the whole tree");
 		// Outside the whole tree
 		return;
 	}
@@ -28,7 +31,6 @@ void Octree::placeSpatial(Spatial* sp)
 
 	if(crntNode == toBePlacedNode)
 	{
-		ANKI_LOGI("Don't place in the same");
 		// Don't place in the same
 		return;
 	}
@@ -36,15 +38,16 @@ void Octree::placeSpatial(Spatial* sp)
 	// Remove from current node
 	if(crntNode)
 	{
-		Vector<Spatial*>::iterator it =
-			std::find(crntNode->spatials.begin(), crntNode->spatials.end(), sp);
+		Vector<SceneNode*>::iterator it =
+			std::find(crntNode->sceneNodes.begin(),
+			crntNode->sceneNodes.end(), sn);
 
-		ANKI_ASSERT(it != crntNode->spatials.end());
-		crntNode->spatials.erase(it);
+		ANKI_ASSERT(it != crntNode->sceneNodes.end());
+		crntNode->sceneNodes.erase(it);
 	}
 
 	// Add to new one node
-	toBePlacedNode->spatials.push_back(sp);
+	toBePlacedNode->sceneNodes.push_back(sn);
 	sp->setOctreeNode(toBePlacedNode);
 }
 
@@ -152,4 +155,55 @@ void Octree::calcAabb(uint32_t i, uint32_t j, uint32_t k, const Aabb& paabb,
 	out = Aabb(nomin, nomax);
 }
 
+//==============================================================================
+void Octree::doVisibilityTests(Frustumable& fr)
+{
+	fr.getVisibilityInfo().renderables.clear();
+	fr.getVisibilityInfo().lights.clear();
+
+	doVisibilityTestsRec(fr, root);
+}
+
+//==============================================================================
+void Octree::doVisibilityTestsRec(Frustumable& fr, OctreeNode& node)
+{
+	VisibilityInfo& vinfo = fr.getVisibilityInfo();
+
+	for(SceneNode* sn : node.sceneNodes)
+	{
+		Spatial* sp = sn->getSpatial();
+		ANKI_ASSERT(sp);
+
+		if(!fr.insideFrustum(*sp))
+		{
+			continue;
+		}
+
+		Renderable* r = sn->getRenderable();
+		if(r)
+		{
+			vinfo.renderables.push_back(r);
+		}
+
+		Light* l = sn->getLight();
+		if(l)
+		{
+			vinfo.lights.push_back(l);
+
+			if(l->getShadowEnabled() && sn->getFrustumable() != nullptr)
+			{
+				//testLight(*l, scene);
+			}
+		}
+	}
+
+	for(uint32_t i = 0; i < 8; ++i)
+	{
+		if(node.children[i].get() != nullptr)
+		{
+			doVisibilityTestsRec(fr, *node.children[i]);
+		}
+	}
+}
+
 } // end namespace anki

+ 1 - 1
src/scene/Scene.cpp

@@ -52,7 +52,7 @@ void Scene::update(float prevUpdateTime, float crntTime)
 		{
 			for(Sector* sector : sectors)
 			{
-				if(sector->placeSpatial(sp))
+				if(sector->placeSceneNode(n))
 				{
 					ANKI_LOGI("Placing: " << n->getName());
 					continue;

+ 3 - 3
src/scene/Sector.cpp

@@ -5,17 +5,17 @@
 namespace anki {
 
 //==============================================================================
-bool Sector::placeSpatial(Spatial* sp)
+bool Sector::placeSceneNode(SceneNode* sn)
 {
 	// XXX Optimize
 
-	if(!CollisionAlgorithmsMatrix::collide(sp->getAabb(),
+	if(!CollisionAlgorithmsMatrix::collide(sn->getSpatial()->getAabb(),
 		octree.getRoot().getAabb()))
 	{
 		return false;
 	}
 
-	octree.placeSpatial(sp);
+	octree.placeSceneNode(sn);
 	return true;
 }