Panagiotis Christopoulos Charitos пре 13 година
родитељ
комит
9e92be1ba6

+ 19 - 14
include/anki/resource/Mesh.h

@@ -128,7 +128,7 @@ protected:
 	U32 vertsCount;
 	U32 vertsCount;
 	U32 indicesCount; ///< Indices count per level
 	U32 indicesCount; ///< Indices count per level
 	U32 texChannelsCount;
 	U32 texChannelsCount;
-	Bool weights;
+	Bool8 weights;
 	Obb visibilityShape;
 	Obb visibilityShape;
 
 
 	Vbo vbo;
 	Vbo vbo;
@@ -141,41 +141,41 @@ protected:
 };
 };
 
 
 /// A mesh that behaves as a mesh and as a collection of separate meshes
 /// A mesh that behaves as a mesh and as a collection of separate meshes
-class MultiMesh: public Mesh
+class BucketMesh: public Mesh
 {
 {
 	/// Default constructor. Do nothing
 	/// Default constructor. Do nothing
-	MultiMesh()
+	BucketMesh()
 	{}
 	{}
 
 
 	/// Load file
 	/// Load file
-	MultiMesh(const char* filename)
+	BucketMesh(const char* filename)
 	{
 	{
 		load(filename);
 		load(filename);
 	}
 	}
 	/// @}
 	/// @}
 
 
 	/// Does nothing
 	/// Does nothing
-	~MultiMesh()
+	~BucketMesh()
 	{}
 	{}
 
 
 	/// @name MeshBase implementers
 	/// @name MeshBase implementers
 	/// @{
 	/// @{
 	U32 getIndicesCountSub(U32 subMeshId, U32& offset) const
 	U32 getIndicesCountSub(U32 subMeshId, U32& offset) const
 	{
 	{
-		ANKI_ASSERT(subMeshId < subIndicesCount.size());
-		offset = subIndicesOffsets[subMeshId];
-		return subIndicesCount[subMeshId];
+		ANKI_ASSERT(subMeshId < subMeshes.size());
+		offset = subMeshes[subMeshId].indicesOffset;
+		return subMeshes[subMeshId].indicesCount;
 	}
 	}
 
 
 	const Obb& getBoundingShapeSub(U32 subMeshId) const
 	const Obb& getBoundingShapeSub(U32 subMeshId) const
 	{
 	{
-		ANKI_ASSERT(subMeshId < subVisibilityShapes.size());
-		return subVisibilityShapes[subMeshId];
+		ANKI_ASSERT(subMeshId < subMeshes.size());
+		return subMeshes[subMeshId].visibilityShape;
 	}
 	}
 
 
 	U32 getSubMeshesCount() const
 	U32 getSubMeshesCount() const
 	{
 	{
-		return subIndicesCount.size();
+		return subMeshes.size();
 	}
 	}
 	/// @}
 	/// @}
 
 
@@ -183,9 +183,14 @@ class MultiMesh: public Mesh
 	void load(const char* filename);
 	void load(const char* filename);
 
 
 private:
 private:
-	Vector<U32> subIndicesCount;
-	Vector<U32> subIndicesOffsets;
-	Vector<Obb> subVisibilityShapes;
+	struct SubMeshData
+	{
+		U32 indicesCount;
+		U32 indicesOffset; ///< In bytes
+		Obb visibilityShape;
+	};
+
+	Vector<SubMeshData> subMeshes;
 };
 };
 
 
 } // end namespace anki
 } // end namespace anki

+ 52 - 7
include/anki/resource/MeshLoader.h

@@ -63,6 +63,8 @@ public:
 		Vec3 normal;
 		Vec3 normal;
 	};
 	};
 
 
+	MeshLoader()
+	{}
 	MeshLoader(const char* filename)
 	MeshLoader(const char* filename)
 	{
 	{
 		load(filename);
 		load(filename);
@@ -87,7 +89,7 @@ public:
 		return vertTangents;
 		return vertTangents;
 	}
 	}
 
 
-	const Vector<Vec2>& getTexureCoordinates(const U32 channel) const
+	const Vector<Vec2>& getTextureCoordinates(const U32 channel) const
 	{
 	{
 		return texCoords;
 		return texCoords;
 	}
 	}
@@ -103,10 +105,57 @@ public:
 
 
 	const Vector<ushort>& getIndices() const
 	const Vector<ushort>& getIndices() const
 	{
 	{
-		return vertIndeces;
+		return vertIndices;
+	}
+	/// @}
+
+	/// @name BucketMesh methods
+	/// @{
+	void appendPositions(const Vector<Vec3>& positions)
+	{
+		vertCoords.insert(
+			vertCoords.end(), positions.begin(), positions.end());
+	}
+
+	void appendNormals(const Vector<Vec3>& normals)
+	{
+		vertNormals.insert(
+			vertNormals.end(), normals.begin(), normals.end());
+	}
+
+	void appendTangents(const Vector<Vec4>& tangents)
+	{
+		vertTangents.insert(
+			vertTangents.end(), tangents.begin(), tangents.end());
+	}
+
+	void appendTextureCoordinates(const Vector<Vec2>& coords, U32 channel)
+	{
+		ANKI_ASSERT(channel == 0 && "Currently only one channel is supported");
+		texCoords.insert(texCoords.end(), coords.begin(), coords.end());
+	}
+
+	void appendWeights(const Vector<VertexWeight>& weights)
+	{
+		vertWeights.insert(vertWeights.end(), weights.begin(), weights.end());
+	}
+
+	/// This will adjust the indices bias
+	void appendIndices(const Vector<U16>& indices)
+	{
+		U16 bias = vertCoords.size();
+
+		for(U16 index : indices)
+		{
+			vertIndices.push_back(bias + index);
+		}
 	}
 	}
 	/// @}
 	/// @}
 
 
+	/// Load the mesh data from a binary file
+	/// @exception Exception
+	void load(const char* filename);
+
 private:
 private:
 	/// @name Data
 	/// @name Data
 	/// @{
 	/// @{
@@ -118,13 +167,9 @@ private:
 	Vector<VertexWeight> vertWeights; ///< Optional
 	Vector<VertexWeight> vertWeights; ///< Optional
 	Vector<Triangle> tris; ///< Required
 	Vector<Triangle> tris; ///< Required
 	/// Generated. Used for vertex arrays & VBOs
 	/// Generated. Used for vertex arrays & VBOs
-	Vector<U16> vertIndeces;
+	Vector<U16> vertIndices;
 	/// @}
 	/// @}
 
 
-	/// Load the mesh data from a binary file
-	/// @exception Exception
-	void load(const char* filename);
-
 	void createFaceNormals();
 	void createFaceNormals();
 	void createVertNormals();
 	void createVertNormals();
 	void createAllNormals()
 	void createAllNormals()

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

@@ -4,7 +4,7 @@
 #include "anki/collision/Aabb.h"
 #include "anki/collision/Aabb.h"
 #include "anki/util/Array.h"
 #include "anki/util/Array.h"
 #include "anki/scene/Common.h"
 #include "anki/scene/Common.h"
-#include "anki/scene/VisibilityTestResults.h"
+#include "anki/scene/Visibility.h"
 #include <memory>
 #include <memory>
 
 
 namespace anki {
 namespace anki {

+ 22 - 0
include/anki/scene/Renderable.h

@@ -185,9 +185,31 @@ public:
 	{
 	{
 		return ubo;
 		return ubo;
 	}
 	}
+
+	U32 getSubMeshesCount() const
+	{
+		return subMeshVisible.size();
+	}
 	/// @}
 	/// @}
 
 
+	/// Set all sub meshes to not visible
+	void setAllSubMeshesNotVisible()
+	{
+		memset(&subMeshVisible[0], 0, 
+			sizeof(subMeshVisible.size()) * sizeof(Bool8));
+	}
+
+	/// Set the visibility of a single sub mesh
+	void setSubMeshVisible(U submeshId, Bool visible)
+	{
+		ANKI_ASSERT(submeshId < subMeshVisible.size());
+		subMeshVisible[submeshId] = visible;
+	}
+
 protected:
 protected:
+	/// Holds the visible submeshes in case of bucket meshes
+	SceneVector<Bool8> subMeshVisible;
+
 	/// The derived class needs to call that
 	/// The derived class needs to call that
 	void init(PropertyMap& pmap);
 	void init(PropertyMap& pmap);
 
 

+ 42 - 0
include/anki/scene/StaticGeometryNode.h

@@ -0,0 +1,42 @@
+#ifndef ANKI_SCENE_STATIC_GEOMETRY_NODE_H
+#define ANKI_SCENE_STATIC_GEOMETRY_NODE_H
+
+#include "anki/scene/Common.h"
+#include "anki/scene/Spatial.h"
+#include "anki/scene/Renderable.h"
+
+namespace anki {
+
+/// XXX
+class StaticGeometryPatchNode: public SceneNode, public Spatial
+{
+public:
+	/// @name Constructors/Destructor
+	/// @{
+	StaticGeometryPatchNode(
+		const char* name, Scene* scene); // Scene
+	/// @}
+
+	/// @name SceneNode virtuals
+	/// @{
+
+	/// Override SceneNode::getSpatial()
+	Spatial* getSpatial()
+	{
+		return this;
+	}
+	/// @}
+};
+
+/// XXX
+class StaticGeometryNode: public SceneNode, public Spatial, public Renderable
+{
+public:
+
+private:
+	SceneVector<StaticGeometryPatch*> patches;
+};
+
+} // end namespace anki
+
+#endif

+ 2 - 0
include/anki/scene/VisibilityTestResults.h → include/anki/scene/Visibility.h

@@ -40,6 +40,8 @@ struct VisibilityTestResults
 	{}
 	{}
 };
 };
 
 
+/// XXX
+
 /// @}
 /// @}
 
 
 } // end namespace anki
 } // end namespace anki

+ 92 - 16
src/resource/Mesh.cpp

@@ -14,21 +14,21 @@ namespace anki {
 //==============================================================================
 //==============================================================================
 void Mesh::load(const char* filename)
 void Mesh::load(const char* filename)
 {
 {
-	MeshLoader loader(filename);
+	try
+	{
+		MeshLoader loader(filename);
 
 
-	// Set the non-VBO members
-	vertsCount = loader.getPositions().size();
-	ANKI_ASSERT(vertsCount > 0);
+		// Set the non-VBO members
+		vertsCount = loader.getPositions().size();
+		ANKI_ASSERT(vertsCount > 0);
 
 
-	indicesCount = loader.getIndices().size();
-	ANKI_ASSERT(indicesCount > 0);
-	ANKI_ASSERT(indicesCount % 3 == 0 && "Expecting triangles");
+		indicesCount = loader.getIndices().size();
+		ANKI_ASSERT(indicesCount > 0);
+		ANKI_ASSERT(indicesCount % 3 == 0 && "Expecting triangles");
 
 
-	weights = loader.getWeights().size() > 1;
-	texChannelsCount = loader.getTextureChannelsCount();
+		weights = loader.getWeights().size() > 1;
+		texChannelsCount = loader.getTextureChannelsCount();
 
 
-	try
-	{
 		createVbos(loader);
 		createVbos(loader);
 
 
 		visibilityShape.set(loader.getPositions());
 		visibilityShape.set(loader.getPositions());
@@ -77,7 +77,7 @@ void Mesh::createVbos(const MeshLoader& loader)
 
 
 		for(U j = 0; j < texChannelsCount; j++)
 		for(U j = 0; j < texChannelsCount; j++)
 		{
 		{
-			memcpy(ptr, &loader.getTexureCoordinates(j)[i], sizeof(Vec2));
+			memcpy(ptr, &loader.getTextureCoordinates(j)[i], sizeof(Vec2));
 			ptr += sizeof(Vec2);
 			ptr += sizeof(Vec2);
 		}
 		}
 
 
@@ -194,11 +194,11 @@ void Mesh::getVboInfo(const VertexAttribute attrib, const Vbo*& v, U32& size,
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-// MultiMesh                                                                   =
+// BucketMesh                                                                  =
 //==============================================================================
 //==============================================================================
 
 
 //==============================================================================
 //==============================================================================
-void MultiMesh::load(const char* filename)
+void BucketMesh::load(const char* filename)
 {
 {
 	try
 	try
 	{
 	{
@@ -207,17 +207,93 @@ void MultiMesh::load(const char* filename)
 
 
 		XmlElement rootEl = doc.getChildElement("multiMesh");
 		XmlElement rootEl = doc.getChildElement("multiMesh");
 		XmlElement meshesEl = rootEl.getChildElement("meshes");
 		XmlElement meshesEl = rootEl.getChildElement("meshes");
-
 		XmlElement meshEl = meshesEl.getChildElement("mesh");
 		XmlElement meshEl = meshesEl.getChildElement("mesh");
 
 
+		vertsCount = 0;
+		indicesCount = 0;
+		U i = 0;
+
+		MeshLoader fullLoader;
+
 		do
 		do
 		{
 		{
+			std::string subMeshFilename = meshEl.getText();
+
+			// Load the submesh and if not the first load the append the 
+			// vertices to the fullMesh
+			MeshLoader* loader;
+			MeshLoader subLoader;
+			if(i != 0)
+			{
+				// Load
+				subLoader.load(subMeshFilename.c_str());
+				loader = &subLoader;
+
+				// Sanity checks
+				if(weights != (loader->getWeights().size() > 1))
+				{
+					throw ANKI_EXCEPTION("All sub meshes should have or not "
+						"have vertex weights");
+				}
+
+				if(texChannelsCount != loader->getTextureChannelsCount())
+				{
+					throw ANKI_EXCEPTION("All sub meshes should have the "
+						"same number of texture channels");
+				}
+
+				// Append
+				fullLoader.appendPositions(subLoader.getPositions());
+				fullLoader.appendNormals(subLoader.getNormals());
+				fullLoader.appendTangents(subLoader.getTangents());
+
+				for(U j = 0; j < texChannelsCount; j++)
+				{
+					fullLoader.appendTextureCoordinates(
+						subLoader.getTextureCoordinates(j), j);
+				}
+
+				if(weights)
+				{
+					fullLoader.appendWeights(subLoader.getWeights());
+				}
+			}
+			else
+			{
+				// Load
+				fullLoader.load(subMeshFilename.c_str());
+				loader = &fullLoader;
+
+				// Set properties
+				weights = loader->getWeights().size() > 1;
+				texChannelsCount = loader->getTextureChannelsCount();
+			}
+
+			// Push back the new submesh
+			SubMeshData submesh;
+
+			submesh.indicesCount = loader->getIndices().size();
+			submesh.indicesOffset = indicesCount * sizeof(U16);
+			submesh.visibilityShape.set(loader->getPositions());
+
+			subMeshes.push_back(submesh);
+
+			// Set the global numbers
+			vertsCount += loader->getPositions().size();
+			indicesCount += loader->getIndices().size();
+
+			// Move to next
 			meshesEl = meshesEl.getNextSiblingElement("mesh");
 			meshesEl = meshesEl.getNextSiblingElement("mesh");
+			++i;
 		} while(meshesEl);
 		} while(meshesEl);
+
+		// Create the bucket mesh
+		createVbos(fullLoader);
+		visibilityShape.set(fullLoader.getPositions());
 	}
 	}
 	catch(std::exception& e)
 	catch(std::exception& e)
 	{
 	{
-		throw ANKI_EXCEPTION("MultiMesh loading failed: " + filename) << e;
+		throw ANKI_EXCEPTION("BucketMesh loading failed: " + filename) << e;
 	}
 	}
 }
 }
 
 

+ 4 - 4
src/resource/MeshLoader.cpp

@@ -155,12 +155,12 @@ void MeshLoader::doPostLoad()
 //==============================================================================
 //==============================================================================
 void MeshLoader::createVertIndeces()
 void MeshLoader::createVertIndeces()
 {
 {
-	vertIndeces.resize(tris.size() * 3);
+	vertIndices.resize(tris.size() * 3);
 	for(uint i = 0; i < tris.size(); i++)
 	for(uint i = 0; i < tris.size(); i++)
 	{
 	{
-		vertIndeces[i * 3 + 0] = tris[i].vertIds[0];
-		vertIndeces[i * 3 + 1] = tris[i].vertIds[1];
-		vertIndeces[i * 3 + 2] = tris[i].vertIds[2];
+		vertIndices[i * 3 + 0] = tris[i].vertIds[0];
+		vertIndices[i * 3 + 1] = tris[i].vertIds[1];
+		vertIndices[i * 3 + 2] = tris[i].vertIds[2];
 	}
 	}
 }
 }
 
 

+ 1 - 1
src/scene/Renderable.cpp

@@ -78,7 +78,7 @@ RenderableVariable::~RenderableVariable()
 
 
 //==============================================================================
 //==============================================================================
 Renderable::Renderable(const SceneAllocator<U8>& alloc)
 Renderable::Renderable(const SceneAllocator<U8>& alloc)
-	:	vars(alloc)
+	: vars(alloc), subMeshVisible(alloc)
 {}
 {}
 
 
 //==============================================================================
 //==============================================================================

+ 1 - 1
src/scene/Sector.cpp

@@ -3,7 +3,7 @@
 #include "anki/scene/SceneNode.h"
 #include "anki/scene/SceneNode.h"
 #include "anki/scene/Renderable.h"
 #include "anki/scene/Renderable.h"
 #include "anki/scene/Light.h"
 #include "anki/scene/Light.h"
-#include "anki/scene/VisibilityTestResults.h"
+#include "anki/scene/Visibility.h"
 #include "anki/scene/Frustumable.h"
 #include "anki/scene/Frustumable.h"
 #include "anki/scene/Scene.h"
 #include "anki/scene/Scene.h"
 #include "anki/core/Logger.h"
 #include "anki/core/Logger.h"