Procházet zdrojové kódy

Ocree and changing the Spatial a bit for the sectors placement

Panagiotis Christopoulos Charitos před 13 roky
rodič
revize
8811e7eae4

+ 10 - 0
include/anki/scene/Camera.h

@@ -91,6 +91,16 @@ public:
 	}
 	}
 	/// @}
 	/// @}
 
 
+	/// @name Spatial virtuals
+	/// @{
+
+	/// Override Spatial::getSpatialOrigin
+	const Vec3& getSpatialOrigin() const
+	{
+		return getWorldTransform().getOrigin();
+	}
+	/// @}
+
 	void lookAtPoint(const Vec3& point);
 	void lookAtPoint(const Vec3& point);
 
 
 protected:
 protected:

+ 10 - 0
include/anki/scene/Light.h

@@ -117,6 +117,16 @@ public:
 	}
 	}
 	/// @}
 	/// @}
 
 
+	/// @name Spatial virtuals
+	/// @{
+
+	/// Override Spatial::getSpatialOrigin
+	const Vec3& getSpatialOrigin() const
+	{
+		return getWorldTransform().getOrigin();
+	}
+	/// @}
+
 private:
 private:
 	LightType type;
 	LightType type;
 	Vec4 color = Vec4(1.0);
 	Vec4 color = Vec4(1.0);

+ 10 - 0
include/anki/scene/ModelNode.h

@@ -93,6 +93,16 @@ public:
 	}
 	}
 	/// @}
 	/// @}
 
 
+	/// @name Spatial virtuals
+	/// @{
+
+	/// Override Spatial::getSpatialOrigin
+	const Vec3& getSpatialOrigin() const
+	{
+		return getWorldTransform().getOrigin();
+	}
+	/// @}
+
 private:
 private:
 	Obb obb; ///< In world space
 	Obb obb; ///< In world space
 	const ModelPatch* modelPatch; ///< The resource
 	const ModelPatch* modelPatch; ///< The resource

+ 29 - 21
include/anki/scene/Octree.h

@@ -19,17 +19,18 @@ class OctreeNode
 	friend class Octree;
 	friend class Octree;
 
 
 public:
 public:
-	typedef Array<std::unique_ptr<OctreeNode>, 8> ChildrenContainer;
+	typedef Array<OctreeNode*, 8> ChildrenContainer;
 
 
-	OctreeNode(const Aabb& aabb_, OctreeNode* parent_)
-		: parent(parent_), aabb(aabb_)
-	{}
+	OctreeNode(const Aabb& aabb, OctreeNode* parent,
+		const SceneAllocator<U8>& alloc);
+
+	~OctreeNode();
 
 
 	/// @name Accessors
 	/// @name Accessors
 	/// @{
 	/// @{
 	const OctreeNode* getChild(U id) const
 	const OctreeNode* getChild(U id) const
 	{
 	{
-		return children[id].get();
+		return children[id];
 	}
 	}
 
 
 	const OctreeNode* getParent() const
 	const OctreeNode* getParent() const
@@ -42,17 +43,21 @@ public:
 		return aabb;
 		return aabb;
 	}
 	}
 
 
-	Vector<SceneNode*>::iterator getSceneNodesBegin()
+	SceneVector<SceneNode*>::iterator getSceneNodesBegin()
+	{
+		return sceneNodes.begin();
+	}
+	SceneVector<SceneNode*>::const_iterator getSceneNodesBegin() const
 	{
 	{
 		return sceneNodes.begin();
 		return sceneNodes.begin();
 	}
 	}
-	Vector<SceneNode*>::iterator getSceneNodesEnd()
+	SceneVector<SceneNode*>::iterator getSceneNodesEnd()
 	{
 	{
 		return sceneNodes.end();
 		return sceneNodes.end();
 	}
 	}
-	U getSceneNodesCount() const
+	SceneVector<SceneNode*>::const_iterator getSceneNodesEnd() const
 	{
 	{
-		return sceneNodes.size();
+		return sceneNodes.end();
 	}
 	}
 	/// @}
 	/// @}
 
 
@@ -61,21 +66,17 @@ public:
 		return parent == nullptr;
 		return parent == nullptr;
 	}
 	}
 
 
-	void addChild(U pos, OctreeNode* child)
-	{
-		child->parent = this;
-		children[pos].reset(child);
-	}
-
-	void addSceneNode(SceneNode* sn);
-
 	void removeSceneNode(SceneNode* sn);
 	void removeSceneNode(SceneNode* sn);
 
 
 private:
 private:
 	ChildrenContainer children;
 	ChildrenContainer children;
 	OctreeNode* parent;
 	OctreeNode* parent;
 	Aabb aabb; ///< Including AABB
 	Aabb aabb; ///< Including AABB
-	Vector<SceneNode*> sceneNodes;
+	SceneVector<SceneNode*> sceneNodes;
+
+	void addSceneNode(SceneNode* sn);
+
+	void addChild(U pos, OctreeNode* child);
 };
 };
 
 
 /// Octree
 /// Octree
@@ -85,6 +86,8 @@ public:
 	Octree(const SceneAllocator<U8>& alloc, const Aabb& aabb, U8 maxDepth, 
 	Octree(const SceneAllocator<U8>& alloc, const Aabb& aabb, U8 maxDepth, 
 		F32 looseness = 1.5);
 		F32 looseness = 1.5);
 
 
+	~Octree();
+
 	/// @name Accessors
 	/// @name Accessors
 	/// @{
 	/// @{
 	const OctreeNode& getRoot() const
 	const OctreeNode& getRoot() const
@@ -105,8 +108,10 @@ public:
 	/// Place a spatial in the tree
 	/// Place a spatial in the tree
 	void placeSceneNode(SceneNode* sn);
 	void placeSceneNode(SceneNode* sn);
 
 
-	/// Fill the fr with visible data
-	void doVisibilityTests(Frustumable& fr);
+	/// Do the visibility tests
+	void getVisible(const Frustumable& fr,
+		SceneVector<SceneNode*>* renderableNodes,
+		SceneVector<SceneNode*>* lightNodes);
 
 
 private:
 private:
 	SceneAllocator<U8> alloc;
 	SceneAllocator<U8> alloc;
@@ -123,7 +128,10 @@ private:
 	OctreeNode* place(const Aabb& aabb);
 	OctreeNode* place(const Aabb& aabb);
 
 
 	/// Recursive method
 	/// Recursive method
-	void doVisibilityTestsRec(Frustumable& fr, OctreeNode& node);
+	void doVisibilityTestsInternal(const Frustumable& fr,
+		SceneVector<SceneNode*>* renderableNodes,
+		SceneVector<SceneNode*>* lightNodes,
+		OctreeNode& node);
 
 
 	void createChildren(OctreeNode& parent);
 	void createChildren(OctreeNode& parent);
 
 

+ 10 - 0
include/anki/scene/ParticleEmitter.h

@@ -241,6 +241,16 @@ public:
 	void movableUpdate();
 	void movableUpdate();
 	/// @}
 	/// @}
 
 
+	/// @name Spatial virtuals
+	/// @{
+
+	/// Override Spatial::getSpatialOrigin
+	const Vec3& getSpatialOrigin() const
+	{
+		return getWorldTransform().getOrigin();
+	}
+	/// @}
+
 private:
 private:
 	ParticleEmitterResourcePointer particleEmitterResource;
 	ParticleEmitterResourcePointer particleEmitterResource;
 	std::unique_ptr<btCollisionShape> collShape = nullptr;
 	std::unique_ptr<btCollisionShape> collShape = nullptr;

+ 10 - 0
include/anki/scene/SkinNode.h

@@ -204,6 +204,16 @@ public:
 	}
 	}
 	/// @}
 	/// @}
 
 
+	/// @name Spatial virtuals
+	/// @{
+
+	/// Override Spatial::getSpatialOrigin
+	const Vec3& getSpatialOrigin() const
+	{
+		return getWorldTransform().getOrigin();
+	}
+	/// @}
+
 private:
 private:
 	std::unique_ptr<SkinModelPatch> skinModelPatch;
 	std::unique_ptr<SkinModelPatch> skinModelPatch;
 };
 };

+ 1 - 4
include/anki/scene/Spatial.h

@@ -71,10 +71,7 @@ public:
 		return timestamp;
 		return timestamp;
 	}
 	}
 
 
-	const Vec3& getSpatialOrigin() const
-	{
-		return origin;
-	}
+	virtual const Vec3& getSpatialOrigin() const = 0;
 	/// @}
 	/// @}
 
 
 	/// The derived class has to manually set when the collision shape got
 	/// The derived class has to manually set when the collision shape got

+ 4 - 1
src/renderer/DebugDrawer.cpp

@@ -523,8 +523,11 @@ void SceneDebugDrawer::draw(const Octree& octree) const
 void SceneDebugDrawer::draw(const OctreeNode& octnode, U32 depth,
 void SceneDebugDrawer::draw(const OctreeNode& octnode, U32 depth,
 	const Octree& octree) const
 	const Octree& octree) const
 {
 {
+	PtrSize nodesCount =
+		octnode.getSceneNodesEnd() - octnode.getSceneNodesBegin();
+
 	// Draw if it has spatials
 	// Draw if it has spatials
-	if(octnode.getSceneNodesCount() != 0)
+	if(nodesCount != 0)
 	{
 	{
 		//Vec3 color = Vec3(1.0 - F32(depth) / F32(octree.getMaxDepth()));
 		//Vec3 color = Vec3(1.0 - F32(depth) / F32(octree.getMaxDepth()));
 		Vec3 color(1.0);
 		Vec3 color(1.0);

+ 2 - 1
src/scene/Grid.cpp

@@ -60,7 +60,8 @@ Bool Grid::placeSceneNode(SceneNode* sn)
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-void getVisible(const Frustumable& /*cam*/, SceneVector<SceneNode*>& nodes)
+void Grid::getVisible(const Frustumable& cam,
+	SceneVector<SceneNode*>& nodes)
 {
 {
 	nodes.insert(nodes.end(), sceneNodes.begin(), sceneNodes.end());
 	nodes.insert(nodes.end(), sceneNodes.begin(), sceneNodes.end());
 }
 }

+ 90 - 48
src/scene/Octree.cpp

@@ -12,34 +12,62 @@ namespace anki {
 // OctreeNode                                                                  =
 // OctreeNode                                                                  =
 //==============================================================================
 //==============================================================================
 
 
+//==============================================================================
+OctreeNode::OctreeNode(const Aabb& aabb_, OctreeNode* parent_,
+	const SceneAllocator<U8>& alloc)
+	: parent(parent_), aabb(aabb_), sceneNodes(alloc)
+{
+	for(OctreeNode* child : children)
+	{
+		child = nullptr;
+	}
+}
+
+//==============================================================================
+OctreeNode::~OctreeNode()
+{
+	SceneAllocator<U8> alloc = sceneNodes.get_allocator();
+
+	for(OctreeNode* onode : children)
+	{
+		if(onode)
+		{
+			ANKI_DELETE(onode, alloc);
+		}
+	}
+}
+
 //==============================================================================
 //==============================================================================
 void OctreeNode::addSceneNode(SceneNode* sn)
 void OctreeNode::addSceneNode(SceneNode* sn)
 {
 {
 	ANKI_ASSERT(sn != nullptr);
 	ANKI_ASSERT(sn != nullptr);
 
 
 	Spatial* sp = sn->getSpatial();
 	Spatial* sp = sn->getSpatial();
+	ANKI_ASSERT(sp != nullptr);
+
 	if(this == sp->octreeNode)
 	if(this == sp->octreeNode)
 	{
 	{
-		// early exit
-		return;
+		// Nothing to do
 	}
 	}
-
-	// Remove from current node ...
-	if(sp->octreeNode != nullptr)
+	else
 	{
 	{
-		sp->octreeNode->removeSceneNode(sn);
-	}
+		// Remove from current node ...
+		if(sp->octreeNode != nullptr)
+		{
+			sp->octreeNode->removeSceneNode(sn);
+		}
 
 
-	// ... and add to a new
-	sceneNodes.push_back(sn);
-	sp->octreeNode = this;
+		// ... and add to a new
+		sceneNodes.push_back(sn);
+		sp->octreeNode = this;
+	}
 }
 }
 
 
 //==============================================================================
 //==============================================================================
 void OctreeNode::removeSceneNode(SceneNode* sn)
 void OctreeNode::removeSceneNode(SceneNode* sn)
 {
 {
 	ANKI_ASSERT(sn != nullptr);
 	ANKI_ASSERT(sn != nullptr);
-	Vector<SceneNode*>::iterator it =
+	SceneVector<SceneNode*>::iterator it =
 		std::find(sceneNodes.begin(), sceneNodes.end(), sn);
 		std::find(sceneNodes.begin(), sceneNodes.end(), sn);
 	ANKI_ASSERT(it != sceneNodes.end());
 	ANKI_ASSERT(it != sceneNodes.end());
 
 
@@ -47,6 +75,22 @@ void OctreeNode::removeSceneNode(SceneNode* sn)
 	sn->getSpatial()->octreeNode = nullptr;
 	sn->getSpatial()->octreeNode = nullptr;
 }
 }
 
 
+//==============================================================================
+void OctreeNode::addChild(U pos, OctreeNode* child)
+{
+	SceneAllocator<U8> alloc = sceneNodes.get_allocator();
+
+	child->parent = this;
+
+	if(children[pos])
+	{
+		OctreeNode* onode = children[pos];
+		ANKI_DELETE(onode, alloc);
+	}
+
+	children[pos] = child;
+}
+
 //==============================================================================
 //==============================================================================
 // Octree                                                                      =
 // Octree                                                                      =
 //==============================================================================
 //==============================================================================
@@ -54,10 +98,14 @@ void OctreeNode::removeSceneNode(SceneNode* sn)
 //==============================================================================
 //==============================================================================
 Octree::Octree(const SceneAllocator<U8>& alloc_, const Aabb& aabb, 
 Octree::Octree(const SceneAllocator<U8>& alloc_, const Aabb& aabb, 
 	U8 maxDepth_, F32 looseness_)
 	U8 maxDepth_, F32 looseness_)
-	:	alloc(alloc_), 
+	: alloc(alloc_),
 		maxDepth(maxDepth_ < 1 ? 1 : maxDepth_), 
 		maxDepth(maxDepth_ < 1 ? 1 : maxDepth_), 
 		looseness(looseness_),
 		looseness(looseness_),
-		root(aabb, nullptr)
+		root(aabb, nullptr, alloc)
+{}
+
+//==============================================================================
+Octree::~Octree()
 {}
 {}
 
 
 //==============================================================================
 //==============================================================================
@@ -67,13 +115,10 @@ void Octree::placeSceneNode(SceneNode* sn)
 	ANKI_ASSERT(sp != nullptr);
 	ANKI_ASSERT(sp != nullptr);
 	OctreeNode* toBePlacedNode = place(sp->getAabb());
 	OctreeNode* toBePlacedNode = place(sp->getAabb());
 
 
-	if(toBePlacedNode == nullptr)
+	if(toBePlacedNode != nullptr)
 	{
 	{
-		// Outside the whole tree
-		return;
+		toBePlacedNode->addSceneNode(sn);
 	}
 	}
-
-	toBePlacedNode->addSceneNode(sn);
 }
 }
 
 
 //==============================================================================
 //==============================================================================
@@ -110,7 +155,7 @@ OctreeNode* Octree::placeInternal(const Aabb& aabb, U depth, OctreeNode& node)
 				// Get the node's AABB. If there is no node then calculate the
 				// Get the node's AABB. If there is no node then calculate the
 				// AABB
 				// AABB
 				Aabb childAabb;
 				Aabb childAabb;
-				if(node.children[id].get() != nullptr)
+				if(node.children[id] != nullptr)
 				{
 				{
 					// There is a child
 					// There is a child
 					childAabb = node.children[id]->aabb;
 					childAabb = node.children[id]->aabb;
@@ -126,10 +171,13 @@ OctreeNode* Octree::placeInternal(const Aabb& aabb, U depth, OctreeNode& node)
 					aabb.getMin() >= childAabb.getMin())
 					aabb.getMin() >= childAabb.getMin())
 				{
 				{
 					// Go deeper
 					// Go deeper
-					if(node.children[id].get() == nullptr)
+					if(node.children[id] == nullptr)
 					{
 					{
 						// Create new node if needed
 						// Create new node if needed
-						OctreeNode* newNode = new OctreeNode(childAabb, &node);
+						OctreeNode* newNode =
+							ANKI_NEW(OctreeNode, alloc,
+							childAabb, &node, alloc);
+
 						node.addChild(id, newNode);
 						node.addChild(id, newNode);
 					}
 					}
 
 
@@ -180,52 +228,46 @@ void Octree::calcAabb(U i, U j, U k, const Aabb& paabb, Aabb& out) const
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-void Octree::doVisibilityTests(Frustumable& fr)
+void Octree::getVisible(const Frustumable& fr,
+	SceneVector<SceneNode*>* renderableNodes,
+	SceneVector<SceneNode*>* lightNodes)
 {
 {
-	fr.getVisibilityInfo().renderables.clear();
-	fr.getVisibilityInfo().lights.clear();
-
-	doVisibilityTestsRec(fr, root);
+	doVisibilityTestsInternal(fr, renderableNodes, lightNodes, root);
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-void Octree::doVisibilityTestsRec(Frustumable& fr, OctreeNode& node)
+void Octree::doVisibilityTestsInternal(const Frustumable& fr,
+	SceneVector<SceneNode*>* renderableNodes,
+	SceneVector<SceneNode*>* lightNodes,
+	OctreeNode& node)
 {
 {
-	VisibilityInfo& vinfo = fr.getVisibilityInfo();
-
 	for(SceneNode* sn : node.sceneNodes)
 	for(SceneNode* sn : node.sceneNodes)
 	{
 	{
 		Spatial* sp = sn->getSpatial();
 		Spatial* sp = sn->getSpatial();
 		ANKI_ASSERT(sp);
 		ANKI_ASSERT(sp);
 
 
-		if(!fr.insideFrustum(*sp))
-		{
-			continue;
-		}
-
-		Renderable* r = sn->getRenderable();
-		if(r)
+		if(fr.insideFrustum(*sp))
 		{
 		{
-			vinfo.renderables.push_back(sn);
-		}
-
-		Light* l = sn->getLight();
-		if(l)
-		{
-			vinfo.lights.push_back(sn);
+			Renderable* r = sn->getRenderable();
+			if(r != nullptr && renderableNodes != nullptr)
+			{
+				renderableNodes->push_back(sn);
+			}
 
 
-			if(l->getShadowEnabled() && sn->getFrustumable() != nullptr)
+			Light* l = sn->getLight();
+			if(l != nullptr && lightNodes != nullptr)
 			{
 			{
-				//testLight(*l, scene);
+				lightNodes->push_back(sn);
 			}
 			}
 		}
 		}
 	}
 	}
 
 
-	for(U i = 0; i < 8; ++i)
+	// Go to children
+	for(OctreeNode* onode : node.children)
 	{
 	{
-		if(node.children[i].get() != nullptr)
+		if(onode != nullptr)
 		{
 		{
-			doVisibilityTestsRec(fr, *node.children[i]);
+			doVisibilityTestsInternal(fr, renderableNodes, lightNodes, *onode);
 		}
 		}
 	}
 	}
 }
 }