Panagiotis Christopoulos Charitos 12 years ago
parent
commit
a8c2a3b470
4 changed files with 155 additions and 118 deletions
  1. 5 2
      src/util/Memory.cpp
  2. 19 16
      tools/scene/Common.h
  3. 41 69
      tools/scene/Main.cpp
  4. 90 31
      tools/scene/Model.cpp

+ 5 - 2
src/util/Memory.cpp

@@ -83,7 +83,7 @@ void* StackMemoryPool::allocate(PtrSize size_) throw()
 	PtrSize size = 
 	PtrSize size = 
 		getAlignedRoundUp(alignmentBytes, size_ + headerSize);
 		getAlignedRoundUp(alignmentBytes, size_ + headerSize);
 
 
-	ANKI_ASSERT(size < std::numeric_limits<U32>::max() && "Too big allocation");
+	ANKI_ASSERT(size < MAX_U32 && "Too big allocation");
 
 
 	U8* out = top.fetch_add(size);
 	U8* out = top.fetch_add(size);
 
 
@@ -123,11 +123,14 @@ Bool StackMemoryPool::free(void* ptr) throw()
 	U8* realptr = (U8*)ptr - headerSize;
 	U8* realptr = (U8*)ptr - headerSize;
 
 
 	// realptr should be inside the pool's preallocated memory
 	// realptr should be inside the pool's preallocated memory
-	ANKI_ASSERT(realptr >= memory && realptr < memory + memsize);
+	ANKI_ASSERT(realptr >= memory);
 
 
 	// Get block size
 	// Get block size
 	U32 size = ((MemoryBlockHeader*)realptr)->size;
 	U32 size = ((MemoryBlockHeader*)realptr)->size;
 
 
+	// Check if the size is ok
+	ANKI_ASSERT(realptr + size <= memory + memsize);
+
 	// Atomic stuff
 	// Atomic stuff
 	U8* expected = realptr + size;
 	U8* expected = realptr + size;
 	U8* desired = realptr;
 	U8* desired = realptr;

+ 19 - 16
tools/scene/Common.h

@@ -9,6 +9,7 @@
 #include <string>
 #include <string>
 #include <vector>
 #include <vector>
 #include <fstream>
 #include <fstream>
+#include <unordered_map>
 
 
 //==============================================================================
 //==============================================================================
 // Log and errors
 // Log and errors
@@ -33,18 +34,18 @@ extern const char* XML_HEADER;
 const uint32_t INVALID_INDEX = 0xFFFFFFFF;
 const uint32_t INVALID_INDEX = 0xFFFFFFFF;
 
 
 /// Thin mesh wrapper
 /// Thin mesh wrapper
-struct Mesh
+struct Model
 {
 {
-	uint32_t index = INVALID_INDEX; ///< Mesh index in the scene
-	std::vector<aiMatrix4x4> transforms;
+	uint32_t meshIndex = INVALID_INDEX; ///< Mesh index in the scene
 	uint32_t mtlIndex = INVALID_INDEX;
 	uint32_t mtlIndex = INVALID_INDEX;
+	bool instanced = false;
 };
 };
 
 
-/// Thin material wrapper
-struct Material
+/// Scene node
+struct Node
 {
 {
-	uint32_t index = INVALID_INDEX;
-	std::vector<uint32_t> meshIndices;
+	uint32_t modelIndex; ///< Index inside Exporter::models
+	std::vector<aiMatrix4x4> transforms;
 };
 };
 
 
 const uint32_t MAX_BONES_PER_VERTEX = 4;
 const uint32_t MAX_BONES_PER_VERTEX = 4;
@@ -69,8 +70,8 @@ struct Exporter
 	aiScene* scene = nullptr;
 	aiScene* scene = nullptr;
 	Assimp::Importer* importer;
 	Assimp::Importer* importer;
 
 
-	std::vector<Mesh> meshes;
-	std::vector<Material> materials;
+	std::vector<Model> models;
+	std::vector<Node> nodes;
 };
 };
 
 
 /// Replace all @a from substrings in @a str to @a to
 /// Replace all @a from substrings in @a str to @a to
@@ -98,21 +99,23 @@ extern void exportAnimation(
 extern void exportMesh(
 extern void exportMesh(
 	const Exporter& exporter,
 	const Exporter& exporter,
 	const aiMesh& mesh, 
 	const aiMesh& mesh, 
-	const std::string* name,
 	const aiMatrix4x4* transform);
 	const aiMatrix4x4* transform);
 
 
 /// Export a skeleton
 /// Export a skeleton
-extern void exportSkeleton(const Exporter& exporter, const aiMesh& mesh);
-
-/// Helper function
-extern std::string getMaterialName(const aiMaterial& mtl);
+extern void exportSkeleton(
+	const Exporter& exporter, 
+	const aiMesh& mesh);
 
 
 /// Export material
 /// Export material
 extern void exportMaterial(
 extern void exportMaterial(
 	const Exporter& exporter, 
 	const Exporter& exporter, 
 	const aiMaterial& mtl, 
 	const aiMaterial& mtl, 
-	bool instanced,
-	const std::string* name);
+	bool instanced);
+
+/// Export model
+extern void exportModel(
+	const Exporter& exporter, 
+	const Model& model);
 
 
 /// Write light to the scene file
 /// Write light to the scene file
 extern void exportLight(
 extern void exportLight(

+ 41 - 69
tools/scene/Main.cpp

@@ -113,67 +113,55 @@ error:
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-static void exportModel(
-	const aiScene& scene, 
-	const aiNode& node)
+static void visitNode(Exporter& exporter, const aiNode* ainode)
 {
 {
-	if(node.mNumMeshes == 0)
+	if(ainode == nullptr)
 	{
 	{
 		return;
 		return;
 	}
 	}
 
 
-	std::string name = node.mName.C_Str();
+	assert(ainode->mNumMeshes > 0);
 
 
-	LOGI("Exporting model %s\n", name.c_str());
-
-	std::fstream file;
-	file.open(config.outDir + name + ".ankimdl", std::ios::out);
-
-	file << xmlHeader << '\n';
-	file << "<model>\n";
-	file << "\t<modelPatches>\n";
-
-	for(uint32_t i = 0; i < node.mNumMeshes; i++)
+	// For every mesh of this node
+	for(unsigned i = 0; i < ainode->mNumMeshes; i++)
 	{
 	{
-		uint32_t meshIndex = node.mMeshes[i];
-		const aiMesh& mesh = *scene.mMeshes[meshIndex];
-	
-		// start
-		file << "\t\t<modelPatch>\n";
+		unsigned meshIndex = ainode->mMeshes[i];
+		unsigned mtlIndex =  scene.mMeshes[meshIndex]->mMaterialIndex;
 
 
-		// Write mesh
-		file << "\t\t\t<mesh>" << config.rpath 
-			<< mesh.mName.C_Str() << ".ankimesh</mesh>\n";
+		// Find if there is another node with the same model
+		std::vector<Node>::iterator it;
+		for(it = exporter.nodes.begin(); it != exporter.nodes.end(); it++)
+		{
+			const Node& node = *it;
+			const Model& model = exporter.models[node.modelIndex];
 
 
-		// Write material
-		const aiMaterial& mtl = *scene.mMaterials[mesh.mMaterialIndex];
-		aiString mtlname;
-		mtl.Get(AI_MATKEY_NAME, mtlname);
+			if(model.meshIndex == meshIndex && model.mtlIndex = mtlIndex)
+			{
+				break;
+			}
+		}
 
 
-		file << "\t\t\t<material>" << config.rpath 
-			<< mtlname.C_Str() << ".ankimtl</material>\n";
+		if(it != exporter.node.end())
+		{
+			// A node with the same model exists. It's instanced
 
 
-		// end
-		file << "\t\t</modelPatch>\n";
-	}
+			Node& node = *it;
+			Model& model = exporter.models[tmpnode.modelIndex];
 
 
-	file << "\t</modelPatches>\n";
-	file << "</model>\n";
-}
-
-//==============================================================================
-static void visitNode(const aiNode* node, const aiScene& scene)
-{
-	if(node == nullptr)
-	{
-		return;
-	}
+			assert(node.transforms.size() > 0);
+			node.transforms.push_back(node.mTransformation);
+			
+			model.instanced = true;
+			break;
+		}
 
 
-	// For every mesh of this node
-	for(uint32_t i = 0; i < node->mNumMeshes; i++)
-	{
-		uint32_t meshIndex = node->mMeshes[i];
-		const aiMesh& mesh = *scene.mMeshes[meshIndex];
+		// Search if model exists
+		std::vector<Model>::iterator it2;
+		for(it2 = exporter.models.begin(); it2 != exporter.models.end(); it2++)
+		{
+			Model& model = *it;
+			if(model.meshIndex == )
+		}
 
 
 		// Is material set?
 		// Is material set?
 		if(config.meshes[meshIndex].mtlIndex == INVALID_INDEX)
 		if(config.meshes[meshIndex].mtlIndex == INVALID_INDEX)
@@ -201,40 +189,24 @@ static void visitNode(const aiNode* node, const aiScene& scene)
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-static void exportScene(const aiScene& scene)
+static void exportScene(const Exporter& exporter)
 {
 {
-	LOGI("Exporting scene to %s\n", config.outDir.c_str());
+	LOGI("Exporting scene to %s\n", exporter.outDir.c_str());
 
 
 	//
 	//
 	// Open scene file
 	// Open scene file
 	//
 	//
 	std::ofstream file;
 	std::ofstream file;
-	file.open(config.outDir + "master.ankiscene");
+	file.open(exporter.outDir + "master.ankiscene");
 
 
-	file << xmlHeader << "\n"
-		<< "<scene>\n";
+	file << XML_HEADER << "\n<scene>\n";
 
 
 	//
 	//
 	// Get all the data
 	// Get all the data
 	//
 	//
 
 
-	config.meshes.resize(scene.mNumMeshes);
-	config.materials.resize(scene.mNumMaterials);
-
-	int i = 0;
-	for(Mesh& mesh : config.meshes)
-	{
-		mesh.index = i++;
-	}
-	i = 0;
-	for(Material& mtl : config.materials)
-	{
-		mtl.index = i++;
-	}
-
 	const aiNode* node = scene.mRootNode;
 	const aiNode* node = scene.mRootNode;
-
-	visitNode(node, scene);
+	visitNode(exporter, node);
 
 
 #if 0
 #if 0
 	//
 	//

+ 90 - 31
tools/scene/Model.cpp

@@ -1,14 +1,66 @@
 #include "Common.h"
 #include "Common.h"
 #include <cassert>
 #include <cassert>
 
 
+//==============================================================================
+static const aiMesh& getMesh(const Exporter& exporter, unsigned index)
+{
+	assert(index < exporter.scene->mNumMeshes);
+	return *exporter.scene->mMeshes[index];
+}
+
+//==============================================================================
+static const aiMaterial& getMaterial(const Exporter& exporter, unsigned index)
+{
+	assert(index < exporter.scene->mNumMaterials);
+	return *exporter.scene->mMaterials[index];
+}
+
+//==============================================================================
+static std::string getMeshName(const aiMesh& mesh)
+{
+	return std::string(mesh.mName.C_Str());
+}
+
+//==============================================================================
+static std::string getMaterialName(const aiMaterial& mtl, bool instanced)
+{
+	aiString ainame;
+	std::string name;
+	if(mtl.Get(AI_MATKEY_NAME, ainame) == AI_SUCCESS)
+	{
+		name = ainame.C_Str();
+
+		if(instanced)
+		{
+			name += "_inst";
+		}
+	}
+	else
+	{
+		ERROR("Material's name is missing\n");
+	}
+
+	return name;
+}
+
+//==============================================================================
+static std::string getModelName(const Exporter& exporter, const Model& model)
+{
+	std::string name = 
+		getMeshName(getMesh(exporter, model.meshIndex)) + "_"
+		+ getMaterialName(getMaterial(exporter, model.mtlIndex), 
+			model.instanced);
+
+	return name;
+}
+
 //==============================================================================
 //==============================================================================
 void exportMesh(
 void exportMesh(
 	const Exporter& exporter,
 	const Exporter& exporter,
 	const aiMesh& mesh, 
 	const aiMesh& mesh, 
-	const std::string* name_,
 	const aiMatrix4x4* transform)
 	const aiMatrix4x4* transform)
 {
 {
-	std::string name = (name_) ? *name_ : mesh.mName.C_Str();
+	std::string name = getMeshName(mesh);
 	std::fstream file;
 	std::fstream file;
 	LOGI("Exporting mesh %s\n", name.c_str());
 	LOGI("Exporting mesh %s\n", name.c_str());
 
 
@@ -202,43 +254,16 @@ void exportSkeleton(const Exporter& exporter, const aiMesh& mesh)
 	file << "</skeleton>\n";
 	file << "</skeleton>\n";
 }
 }
 
 
-//==============================================================================
-std::string getMaterialName(const aiMaterial& mtl)
-{
-	aiString ainame;
-	std::string name;
-	if(mtl.Get(AI_MATKEY_NAME, ainame) == AI_SUCCESS)
-	{
-		name = ainame.C_Str();
-	}
-	else
-	{
-		ERROR("Material's name is missing\n");
-	}
-
-	return name;
-}
-
 //==============================================================================
 //==============================================================================
 void exportMaterial(
 void exportMaterial(
 	const Exporter& exporter, 
 	const Exporter& exporter, 
 	const aiMaterial& mtl, 
 	const aiMaterial& mtl, 
-	bool instanced,
-	const std::string* name_)
+	bool instanced)
 {
 {
 	std::string diffTex;
 	std::string diffTex;
 	std::string normTex;
 	std::string normTex;
 
 
-	std::string name;
-	if(name_)
-	{
-		name = *name_;
-	}
-	else
-	{
-		name = getMaterialName(mtl);
-	}
-
+	std::string name = getMaterialName(mtl, instanced);
 	LOGI("Exporting material %s\n", name.c_str());
 	LOGI("Exporting material %s\n", name.c_str());
 
 
 	// Diffuse texture
 	// Diffuse texture
@@ -298,3 +323,37 @@ void exportMaterial(
 
 
 	file << str;
 	file << str;
 }
 }
+
+//==============================================================================
+void exportModel(const Exporter& exporter, const Model& model)
+{
+	std::string name = getModelName(exporter, model);
+	LOGI("Exporting model %s\n", name.c_str());
+
+	std::fstream file;
+	file.open(exporter.outDir + name + ".ankimdl", std::ios::out);
+
+	file << XML_HEADER << '\n';
+	file << "<model>\n";
+	file << "\t<modelPatches>\n";
+	
+	// start
+	file << "\t\t<modelPatch>\n";
+
+	// Write mesh
+	file << "\t\t\t<mesh>" << exporter.rpath 
+		<< getMeshName(getMesh(exporter, model.meshIndex)) 
+		<< ".ankimesh</mesh>\n";
+
+	// Write material
+	file << "\t\t\t<material>" << exporter.rpath 
+		<< getMaterialName(getMaterial(exporter, model.mtlIndex),
+			model.instanced) 
+		<< ".ankimtl</material>\n";
+
+	// end
+	file << "\t\t</modelPatch>\n";
+
+	file << "\t</modelPatches>\n";
+	file << "</model>\n";
+}