Browse Source

Add the ability to get the dir light and the skybox. Optimize iteration times of BlockArray

Panagiotis Christopoulos Charitos 2 years ago
parent
commit
a8bb12a5f0

+ 19 - 0
AnKi/Scene/Components/LightComponent.cpp

@@ -31,6 +31,11 @@ LightComponent::~LightComponent()
 {
 {
 	deleteArray(SceneMemoryPool::getSingleton(), m_frustums, m_frustumCount);
 	deleteArray(SceneMemoryPool::getSingleton(), m_frustums, m_frustumCount);
 	m_spatial.removeFromOctree(SceneGraph::getSingleton().getOctree());
 	m_spatial.removeFromOctree(SceneGraph::getSingleton().getOctree());
+
+	if(m_type == LightComponentType::kDirectional)
+	{
+		SceneGraph::getSingleton().removeDirectionalLight(this);
+	}
 }
 }
 
 
 void LightComponent::setLightComponentType(LightComponentType type)
 void LightComponent::setLightComponentType(LightComponentType type)
@@ -50,6 +55,20 @@ void LightComponent::setLightComponentType(LightComponentType type)
 		m_spatial.setUpdatesOctreeBounds(true);
 		m_spatial.setUpdatesOctreeBounds(true);
 	}
 	}
 
 
+	if(m_typeChanged)
+	{
+		if(type == LightComponentType::kDirectional)
+		{
+			// Now it's directional, inform the scene
+			SceneGraph::getSingleton().addDirectionalLight(this);
+		}
+		else if(m_type == LightComponentType::kDirectional)
+		{
+			// It was directional, inform the scene
+			SceneGraph::getSingleton().removeDirectionalLight(this);
+		}
+	}
+
 	m_type = type;
 	m_type = type;
 }
 }
 
 

+ 1 - 0
AnKi/Scene/Components/LightComponent.h

@@ -53,6 +53,7 @@ public:
 	void setDiffuseColor(const Vec4& x)
 	void setDiffuseColor(const Vec4& x)
 	{
 	{
 		m_diffColor = x;
 		m_diffColor = x;
+		m_shapeUpdated = true;
 	}
 	}
 
 
 	void setRadius(F32 x)
 	void setRadius(F32 x)

+ 3 - 0
AnKi/Scene/Components/SkyboxComponent.cpp

@@ -18,11 +18,14 @@ SkyboxComponent::SkyboxComponent(SceneNode* node)
 {
 {
 	m_spatial.setAlwaysVisible(true);
 	m_spatial.setAlwaysVisible(true);
 	m_spatial.setUpdatesOctreeBounds(false);
 	m_spatial.setUpdatesOctreeBounds(false);
+
+	SceneGraph::getSingleton().addSkybox(this);
 }
 }
 
 
 SkyboxComponent::~SkyboxComponent()
 SkyboxComponent::~SkyboxComponent()
 {
 {
 	m_spatial.removeFromOctree(SceneGraph::getSingleton().getOctree());
 	m_spatial.removeFromOctree(SceneGraph::getSingleton().getOctree());
+	SceneGraph::getSingleton().removeSkybox(this);
 }
 }
 
 
 void SkyboxComponent::loadImageResource(CString filename)
 void SkyboxComponent::loadImageResource(CString filename)

+ 7 - 0
AnKi/Scene/SceneGraph.cpp

@@ -387,4 +387,11 @@ Error SceneGraph::updateNodes(UpdateSceneNodesCtx& ctx)
 	return err;
 	return err;
 }
 }
 
 
+LightComponent* SceneGraph::getDirectionalLight() const
+{
+	LightComponent* out = (m_dirLights.getSize()) ? m_dirLights[0] : nullptr;
+	ANKI_ASSERT(out->getLightComponentType() == LightComponentType::kDirectional);
+	return out;
+}
+
 } // end namespace anki
 } // end namespace anki

+ 44 - 0
AnKi/Scene/SceneGraph.h

@@ -161,6 +161,47 @@ public:
 		return m_componentArrays;
 		return m_componentArrays;
 	}
 	}
 
 
+	void addDirectionalLight(LightComponent* comp)
+	{
+		ANKI_ASSERT(m_dirLights.find(comp) == m_dirLights.getEnd());
+		m_dirLights.emplaceBack(comp);
+		if(m_dirLights.getSize() > 1)
+		{
+			ANKI_SCENE_LOGW("More than one directional lights detected");
+		}
+	}
+
+	void removeDirectionalLight(LightComponent* comp)
+	{
+		auto it = m_dirLights.find(comp);
+		ANKI_ASSERT(it != m_dirLights.getEnd());
+		m_dirLights.erase(it);
+	}
+
+	LightComponent* getDirectionalLight() const;
+
+	void addSkybox(SkyboxComponent* comp)
+	{
+		ANKI_ASSERT(m_skyboxes.find(comp) == m_skyboxes.getEnd());
+		m_skyboxes.emplaceBack(comp);
+		if(m_skyboxes.getSize() > 1)
+		{
+			ANKI_SCENE_LOGW("More than one skyboxes detected");
+		}
+	}
+
+	void removeSkybox(SkyboxComponent* comp)
+	{
+		auto it = m_skyboxes.find(comp);
+		ANKI_ASSERT(it != m_skyboxes.getEnd());
+		m_skyboxes.erase(it);
+	}
+
+	SkyboxComponent* getSkybox() const
+	{
+		return (m_skyboxes.getSize()) ? m_skyboxes[0] : nullptr;
+	}
+
 private:
 private:
 	class UpdateSceneNodesCtx;
 	class UpdateSceneNodesCtx;
 
 
@@ -196,6 +237,9 @@ private:
 
 
 	SceneComponentArrays m_componentArrays;
 	SceneComponentArrays m_componentArrays;
 
 
+	SceneDynamicArray<LightComponent*> m_dirLights;
+	SceneDynamicArray<SkyboxComponent*> m_skyboxes;
+
 	SceneGraph();
 	SceneGraph();
 
 
 	~SceneGraph();
 	~SceneGraph();

+ 8 - 16
AnKi/Util/BlockArray.inl.h

@@ -173,25 +173,17 @@ BlockArray<T, TMemoryPool, TConfig>& BlockArray<T, TMemoryPool, TConfig>::operat
 template<typename T, typename TMemoryPool, typename TConfig>
 template<typename T, typename TMemoryPool, typename TConfig>
 U32 BlockArray<T, TMemoryPool, TConfig>::getNextElementIndex(U32 crnt) const
 U32 BlockArray<T, TMemoryPool, TConfig>::getNextElementIndex(U32 crnt) const
 {
 {
-	ANKI_ASSERT(crnt < kMaxU32);
-	const U32 localIdx = crnt % kElementCountPerBlock;
-	U32 blockIdx = crnt / kElementCountPerBlock;
-	ANKI_ASSERT(blockIdx < m_blockMetadatas.getSize());
-
-	Mask mask = m_blockMetadatas[blockIdx].m_elementsInUseMask;
-	mask.unsetNLeastSignificantBits(localIdx + 1);
-	U32 locIdx;
-	if((locIdx = mask.getLeastSignificantBit()) != kMaxU32)
-	{
-		return blockIdx * kElementCountPerBlock + locIdx;
-	}
+	ANKI_ASSERT(crnt < m_endIndex);
 
 
-	++blockIdx;
-	for(; blockIdx < m_blockMetadatas.getSize(); ++blockIdx)
+	++crnt;
+	for(; crnt < m_endIndex; ++crnt)
 	{
 	{
-		if((locIdx = m_blockMetadatas[blockIdx].m_elementsInUseMask.getLeastSignificantBit()) != kMaxU32)
+		const U32 localIdx = crnt % kElementCountPerBlock;
+		const U32 blockIdx = crnt / kElementCountPerBlock;
+
+		if(m_blockMetadatas[blockIdx].m_elementsInUseMask.get(localIdx))
 		{
 		{
-			return blockIdx * kElementCountPerBlock + locIdx;
+			return crnt;
 		}
 		}
 	}
 	}
 
 

+ 15 - 0
AnKi/Util/DynamicArray.h

@@ -280,6 +280,21 @@ public:
 	/// Resizes the storage but DOESN'T CONSTRUCT ANY ELEMENTS. It only moves or destroys.
 	/// Resizes the storage but DOESN'T CONSTRUCT ANY ELEMENTS. It only moves or destroys.
 	void resizeStorage(Size newSize);
 	void resizeStorage(Size newSize);
 
 
+	/// Search the array until you find the 1st value.
+	Iterator find(const Value& what)
+	{
+		Value* it = m_data;
+		Value* end = m_data + m_size;
+		for(; it != end; ++it)
+		{
+			if(*it == what)
+			{
+				return it;
+			}
+		}
+		return end;
+	}
+
 	TMemoryPool& getMemoryPool()
 	TMemoryPool& getMemoryPool()
 	{
 	{
 		return m_pool;
 		return m_pool;