From 8929717c9f53d66f45ba224deed308830ca2b791 Mon Sep 17 00:00:00 2001
From: Anakin <Battlefrontler@t-online.de>
Date: Sun, 13 Nov 2016 12:15:33 +0100
Subject: [PATCH] handle clustered models

---
 MshViewer/Header/Object.h             |  18 ++--
 MshViewer/Source/Object.cpp           |  48 +++++----
 MshViewer/Source/OpenGlController.cpp | 147 +++++++++++++++-----------
 MshViewer/main.cpp                    |   2 +-
 README.md                             |  10 +-
 Release/Msh/cluster.msh               | Bin 0 -> 2484 bytes
 6 files changed, 127 insertions(+), 98 deletions(-)
 create mode 100644 Release/Msh/cluster.msh

diff --git a/MshViewer/Header/Object.h b/MshViewer/Header/Object.h
index 36b8c8b..c4157ea 100644
--- a/MshViewer/Header/Object.h
+++ b/MshViewer/Header/Object.h
@@ -20,17 +20,21 @@ struct ChunkHeader {
 	std::streampos position;
 };
 
+struct Segment {
+	std::string texture			= "";
+	float* vertex				= nullptr;
+	float* uv					= nullptr;
+	std::uint32_t* mesh			= nullptr;
+	std::uint32_t meshSize		= 0;
+};
+
 struct Modl {
 	std::string name			= "";
 	std::string parent			= "";
 	Mtyp type					= null;
 	std::int32_t renderFlags	= -1;
 	glm::mat4 m4x4Translation	= glm::mat4(1.0f);
-	std::string texture			= "";
-	float* vertex				= nullptr;
-	float* uv					= nullptr;
-	std::uint32_t* mesh			= nullptr;
-	std::uint32_t meshSize		= 0;
+	std::vector<Segment*> segmLst;
 };
 
 
@@ -55,8 +59,8 @@ private:
 	void analyseGeomChunks(Modl* dataDestination, std::list<ChunkHeader*> &chunkList);
 	void analyseSegmChunks(Modl* dataDestination, std::list<ChunkHeader*> &chunkList);
 	void analyseClthChunks(Modl* dataDestination, std::list<ChunkHeader*> &chunkList);
-	void readVertex(Modl* dataDestination, std::streampos position);
-	void readUV(Modl* dataDestination, std::streampos position);
+	void readVertex(Segment* dataDestination, std::streampos position);
+	void readUV(Segment* dataDestination, std::streampos position);
 	
 
 public:
diff --git a/MshViewer/Source/Object.cpp b/MshViewer/Source/Object.cpp
index ed468bb..330d007 100644
--- a/MshViewer/Source/Object.cpp
+++ b/MshViewer/Source/Object.cpp
@@ -369,6 +369,8 @@ void Object::analyseGeomChunks(Modl * dataDestination, std::list<ChunkHeader*>&
 
 void Object::analyseSegmChunks(Modl * dataDestination, std::list<ChunkHeader*>& chunkList)
 {
+	Segment* tempData = new Segment;
+
 	for (std::list<ChunkHeader*>::iterator it = chunkList.begin(); it != chunkList.end(); it++)
 	{
 		/*if (!strcmp("SHDW", (*it)->name))
@@ -396,16 +398,16 @@ void Object::analyseSegmChunks(Modl * dataDestination, std::list<ChunkHeader*>&
 			if (vTextures.size() <= tempIndex)
 			{
 				std::cout << "warning texture index <" << tempIndex << "> unknown" << std::endl;
-				dataDestination->texture = "";
+				tempData->texture = "";
 				continue;
 			}
-			dataDestination->texture = vTextures[tempIndex];
+			tempData->texture = vTextures[tempIndex];
 			continue;
 		}
 
 		if (!strcmp("POSL", (*it)->name))
 		{
-			readVertex(dataDestination, (*it)->position);
+			readVertex(tempData, (*it)->position);
 			continue;
 		}
 
@@ -420,7 +422,7 @@ void Object::analyseSegmChunks(Modl * dataDestination, std::list<ChunkHeader*>&
 
 		if (!strcmp("UV0L", (*it)->name))
 		{
-			readUV(dataDestination, (*it)->position);
+			readUV(tempData, (*it)->position);
 			continue;
 		}
 
@@ -429,11 +431,11 @@ void Object::analyseSegmChunks(Modl * dataDestination, std::list<ChunkHeader*>&
 			fsMesh.seekg((*it)->position);
 
 			fsMesh.seekg((*it)->position);
-			fsMesh.read(reinterpret_cast<char*>(&dataDestination->meshSize), sizeof(dataDestination->meshSize));
+			fsMesh.read(reinterpret_cast<char*>(&tempData->meshSize), sizeof(tempData->meshSize));
 
-			dataDestination->mesh = new std::uint32_t[dataDestination->meshSize];
+			tempData->mesh = new std::uint32_t[tempData->meshSize];
 
-			for (unsigned int i = 0; i < dataDestination->meshSize; i += 3)
+			for (unsigned int i = 0; i < tempData->meshSize; i += 3)
 			{
 				std::uint16_t tempValue[3];
 				fsMesh.read(reinterpret_cast<char*>(&tempValue[0]), sizeof(std::uint16_t));
@@ -446,18 +448,21 @@ void Object::analyseSegmChunks(Modl * dataDestination, std::list<ChunkHeader*>&
 				tempValue[0] = (std::uint16_t(tempValue[0] << 1) >> 1);
 				tempValue[1] = (std::uint16_t(tempValue[1] << 1) >> 1);
 
-				dataDestination->mesh[i] = (std::uint32_t)tempValue[0];
-				dataDestination->mesh[i + 1] = (std::uint32_t)tempValue[1];
-				dataDestination->mesh[i + 2] = (std::uint32_t)tempValue[2];
+				tempData->mesh[i] = (std::uint32_t)tempValue[0];
+				tempData->mesh[i + 1] = (std::uint32_t)tempValue[1];
+				tempData->mesh[i + 2] = (std::uint32_t)tempValue[2];
 			}
 
 			continue;
 		}
 	}
+	dataDestination->segmLst.push_back(tempData);
 }
 
 void Object::analyseClthChunks(Modl * dataDestination, std::list<ChunkHeader*>& chunkList)
 {
+	Segment* tempData = new Segment;
+
 	for (std::list<ChunkHeader*>::iterator it = chunkList.begin(); it != chunkList.end(); it++)
 	{
 		if (!strcmp("CTEX", (*it)->name))
@@ -466,42 +471,43 @@ void Object::analyseClthChunks(Modl * dataDestination, std::list<ChunkHeader*>&
 			char* buffer = new char[(*it)->size];
 			*buffer = { 0 };
 			fsMesh.read(buffer, (*it)->size);
-			dataDestination->texture = buffer;
+			tempData->texture = buffer;
 			delete buffer;
 			continue;
 		}
 
 		if (!strcmp("CPOS", (*it)->name))
 		{
-			readVertex(dataDestination, (*it)->position);
+			readVertex(tempData, (*it)->position);
 			continue;
 		}
 
 		if (!strcmp("CUV0", (*it)->name))
 		{
-			readUV(dataDestination, (*it)->position);
+			readUV(tempData, (*it)->position);
 			continue;
 		}
 
 		if (!strcmp("CMSH", (*it)->name))
 		{
 			fsMesh.seekg((*it)->position);
-			fsMesh.read(reinterpret_cast<char*>(&dataDestination->meshSize), sizeof(dataDestination->meshSize));
+			fsMesh.read(reinterpret_cast<char*>(&tempData->meshSize), sizeof(tempData->meshSize));
 
-			dataDestination->mesh = new std::uint32_t[dataDestination->meshSize * 3];
+			tempData->mesh = new std::uint32_t[tempData->meshSize * 3];
 
-			for (unsigned int i = 0; i < dataDestination->meshSize; i += 3)
+			for (unsigned int i = 0; i < tempData->meshSize; i += 3)
 			{
-				fsMesh.read(reinterpret_cast<char*>(&dataDestination->mesh[i]), sizeof(std::uint32_t));
-				fsMesh.read(reinterpret_cast<char*>(&dataDestination->mesh[i + 1]), sizeof(std::uint32_t));
-				fsMesh.read(reinterpret_cast<char*>(&dataDestination->mesh[i + 2]), sizeof(std::uint32_t));
+				fsMesh.read(reinterpret_cast<char*>(&tempData->mesh[i]), sizeof(std::uint32_t));
+				fsMesh.read(reinterpret_cast<char*>(&tempData->mesh[i + 1]), sizeof(std::uint32_t));
+				fsMesh.read(reinterpret_cast<char*>(&tempData->mesh[i + 2]), sizeof(std::uint32_t));
 			}
 			continue;
 		}
 	}
+	dataDestination->segmLst.push_back(tempData);
 }
 
-void Object::readVertex(Modl* dataDestination, std::streampos position)
+void Object::readVertex(Segment* dataDestination, std::streampos position)
 {
 	std::uint32_t tempSize;
 	fsMesh.seekg(position);
@@ -513,7 +519,7 @@ void Object::readVertex(Modl* dataDestination, std::streampos position)
 		fsMesh.read(reinterpret_cast<char*>(&dataDestination->vertex[i]), sizeof(float));
 }
 
-void Object::readUV(Modl* dataDestination, std::streampos position)
+void Object::readUV(Segment* dataDestination, std::streampos position)
 {
 	std::uint32_t tempSize;
 	fsMesh.seekg(position);
diff --git a/MshViewer/Source/OpenGlController.cpp b/MshViewer/Source/OpenGlController.cpp
index b752a11..11da94a 100644
--- a/MshViewer/Source/OpenGlController.cpp
+++ b/MshViewer/Source/OpenGlController.cpp
@@ -114,9 +114,17 @@ void OpenGLController::deleteVectors()
 		Modl* cursor = vModels.back();
 		vModels.pop_back();
 
-		delete cursor->uv;
-		delete cursor->mesh;
-		delete cursor->vertex;
+		while (!cursor->segmLst.empty())
+		{
+			Segment* segmCuror = cursor->segmLst.back();
+			cursor->segmLst.pop_back();
+
+			delete segmCuror->uv;
+			delete segmCuror->mesh;
+			delete segmCuror->vertex;
+			delete segmCuror;
+		}
+		
 		delete cursor;
 	}
 
@@ -294,29 +302,36 @@ void OpenGLController::updateScene()
 	glUniform1i(gluiSamplerID, 0);
 
 	int instanceOffset(0);
+	int textureIndex(0);
 
 	for (unsigned int modelIndex = 0; modelIndex < vModels.size(); modelIndex++)
 	{
-		// give texture to the shader
-		glTexImage2D(GL_TEXTURE_2D,
-			0,
-			vTextures[modelIndex]->alpha ? GL_RGBA : GL_RGB,
-			vTextures[modelIndex]->width,
-			vTextures[modelIndex]->height,
-			0,
-			vTextures[modelIndex]->alpha ? GL_BGRA : GL_BGR,
-			GL_UNSIGNED_BYTE,
-			vTextures[modelIndex]->data->data()
-		);
-
-		glGenerateMipmap(GL_TEXTURE_2D);
-
-		// give the MVP to the shader
-		glUniformMatrix4fv(gluiMatrixID, 1, GL_FALSE, &getMVPMatrix(modelIndex)[0][0]);
-
-		glDrawArrays(GL_TRIANGLES, instanceOffset, vModels[modelIndex]->meshSize);
-
-		instanceOffset += vModels[modelIndex]->meshSize;
+		for (auto& segIt : vModels[modelIndex]->segmLst)
+		{
+			// give texture to the shader
+			glTexImage2D(
+				GL_TEXTURE_2D,
+				0,
+				vTextures[textureIndex]->alpha ? GL_RGBA : GL_RGB,
+				vTextures[textureIndex]->width,
+				vTextures[textureIndex]->height,
+				0,
+				vTextures[textureIndex]->alpha ? GL_BGRA : GL_BGR,
+				GL_UNSIGNED_BYTE,
+				vTextures[textureIndex]->data->data()
+			);
+
+			glGenerateMipmap(GL_TEXTURE_2D);
+
+			// give the MVP to the shader
+			glUniformMatrix4fv(gluiMatrixID, 1, GL_FALSE, &getMVPMatrix(modelIndex)[0][0]);
+
+			glDrawArrays(GL_TRIANGLES, instanceOffset, segIt->meshSize);
+
+			// recalulate counter
+			instanceOffset += segIt->meshSize;
+			textureIndex++;
+		}
 	}
 
 	glfwSwapBuffers(pWindow);
@@ -343,27 +358,30 @@ void OpenGLController::loadMsh(const char * path)
 	// collect vertex data of all models
 	std::vector<Vertex> tempBufferData;
 
-	for (auto& it : vModels)
+	for (auto& modIt : vModels)
 	{
-		for (unsigned int i = 0; i < it->meshSize; i++)
+		for (auto& segIt : modIt->segmLst)
 		{
-			Vertex tempVertex;
-			tempVertex.position[0] = (GLfloat)it->vertex[it->mesh[i] * 3];
-			tempVertex.position[1] = (GLfloat)it->vertex[it->mesh[i] * 3 + 1];
-			tempVertex.position[2] = (GLfloat)it->vertex[it->mesh[i] * 3 + 2];
-
-			if (it->uv == NULL)
-			{
-				tempVertex.uv[0] = 1.0;
-				tempVertex.uv[1] = 1.0;
-			}
-			else
+			for (unsigned int i = 0; i < segIt->meshSize; i++)
 			{
-				tempVertex.uv[0] = (GLfloat)it->uv[it->mesh[i] * 2];
-				tempVertex.uv[1] = (GLfloat)it->uv[it->mesh[i] * 2 + 1];
+				Vertex tempVertex;
+				tempVertex.position[0] = (GLfloat)segIt->vertex[segIt->mesh[i] * 3];
+				tempVertex.position[1] = (GLfloat)segIt->vertex[segIt->mesh[i] * 3 + 1];
+				tempVertex.position[2] = (GLfloat)segIt->vertex[segIt->mesh[i] * 3 + 2];
+
+				if (segIt->uv == NULL)
+				{
+					tempVertex.uv[0] = 1.0;
+					tempVertex.uv[1] = 1.0;
+				}
+				else
+				{
+					tempVertex.uv[0] = (GLfloat)segIt->uv[segIt->mesh[i] * 2];
+					tempVertex.uv[1] = (GLfloat)segIt->uv[segIt->mesh[i] * 2 + 1];
+				}
+
+				tempBufferData.push_back(tempVertex);
 			}
-
-			tempBufferData.push_back(tempVertex);
 		}
 	}
 
@@ -379,35 +397,38 @@ void OpenGLController::loadMsh(const char * path)
 
 
 	// get textures
-	for (auto& it : vModels)
+	for (auto& modIt : vModels)
 	{
-		textureData* tempData = new textureData;
-		try
+		for (auto& segIt : modIt->segmLst)
 		{
-			if (it->texture == "")
-				throw std::invalid_argument("no texture name");
+			textureData* tempData = new textureData;
+			try
+			{
+				if (segIt->texture == "")
+					throw std::invalid_argument("no texture name");
 
-			std::string tempPath = path;
+				std::string tempPath = path;
 
-			while (tempPath.back() != '/' && tempPath.back() != '\\')
-				tempPath.pop_back();
+				while (tempPath.back() != '/' && tempPath.back() != '\\')
+					tempPath.pop_back();
 
-			TextureTGA tempTex(std::string(tempPath + it->texture).c_str());
+				TextureTGA tempTex(std::string(tempPath + segIt->texture).c_str());
 
-			tempData->alpha = tempTex.hasAlpha();
-			tempData->width = tempTex.getWidth();
-			tempData->height = tempTex.getHeight();
-			tempData->data = new std::vector<std::uint8_t>(tempTex.getData());
-		}
-		catch (std::invalid_argument e)
-		{
-			GLubyte solidColor[4] = { 0, 0, 255, 255 };
-			tempData->alpha = true;
-			tempData->width = 1;
-			tempData->height = 1;
-			tempData->data = new std::vector<std::uint8_t>({ 0, 0, 255, 255 });
-		}
+				tempData->alpha = tempTex.hasAlpha();
+				tempData->width = tempTex.getWidth();
+				tempData->height = tempTex.getHeight();
+				tempData->data = new std::vector<std::uint8_t>(tempTex.getData());
+			}
+			catch (std::invalid_argument e)
+			{
+				GLubyte solidColor[4] = { 0, 0, 255, 255 };
+				tempData->alpha = true;
+				tempData->width = 1;
+				tempData->height = 1;
+				tempData->data = new std::vector<std::uint8_t>({ 0, 0, 255, 255 });
+			}
 
-		vTextures.push_back(tempData);
+			vTextures.push_back(tempData);
+		}
 	}
 }
diff --git a/MshViewer/main.cpp b/MshViewer/main.cpp
index c23d154..4a166c9 100644
--- a/MshViewer/main.cpp
+++ b/MshViewer/main.cpp
@@ -17,7 +17,7 @@ int main(int argc, char** argv)
 	else
 		scene = OpenGLController::getInstance();
 
-	scene->loadMsh("..\\Release\\Msh\\structured.msh");
+	scene->loadMsh("..\\Release\\Msh\\cluster.msh");
 
 	do {
 		scene->updateScene();
diff --git a/README.md b/README.md
index 78a4fb7..f8cb589 100644
--- a/README.md
+++ b/README.md
@@ -13,11 +13,11 @@ Feel free to use my code the way you like. But remember i used some public libra
 licence, too.
 
 ### To Do
-- crashing sometimes - no idea why,
+- cluster seam to use wrong textures
+- cloth testing
+- colisions are displayed (dont touch hiden things)
 - bones are not triangulated,
 - nulls are not triangulated,
-- crash when loading trooper,
-- display cloth testing
 - integrate into a software:
 -> gui open file ( + drag and drop),
 -> list all msh under a directory,
@@ -25,6 +25,4 @@ licence, too.
 -> display colisions,
 -> lights,
 -> handle render flags,
-- draw more then one model,
-- use different textures for one or multiple models,
-- take a look at destruction
+
diff --git a/Release/Msh/cluster.msh b/Release/Msh/cluster.msh
new file mode 100644
index 0000000000000000000000000000000000000000..c073ae3c2d02cfcc9d6348f9f979e72c89fae64f
GIT binary patch
literal 2484
zcmeZpbqQL-$-v+n>|r#AlYt@F)6Xr1fq}u#(brXkfq@}7IW;deKFT%3wW1)us3a96
z=N9DX%frCHz{tSB0OB(+d~kGf@{iDAKnD%>s3Hvx3=9x_ee+!hU&j!i2TTkMYzzzx
zzK$U-2~c|l;P(0^mZTPCCgvD2xHyJ5nlLah7#kbg!!QE_$b3{hYvxQl7>3AuI5~y{
zIk7+;0<xzBY7fW{FdIN-Q_GH!2m=?8A4*ayN=l1Tjg5lzO41V{eyqS^H^^z!v>Oy}
zhDH_@hDH`nMTw<(5ZiIvZ^XbrweSV`9m#(8qS90p`>}<+F_rBHg+0{&LHQ*R-{XpR
zL)zKxUX)l0w%pg>#m9k-fx$N<G60kgLD<*NB?3f)@(?JmaWF72B$p<og3^MUk9#mk
z4#W-#a`e*xF;LPvSO7|Z(m#~Rz`)?{>hF7nm4Shr{21)&?)w6g7d>J22lxm3I503U
zu!5~<H~`JRFdCkpk;IYZVC(~aLB2@lfDA)+H&%87B>#fcf-po)XqbTysGI@0r{`gU
zz0~2Uc13dH_75!ktwDSc4dR2uL3|J$91;`&N)w=RhM|G6fr){+fw6&w0o}h$3=9ld
z{0s8~vR~1~V0;h_!VZ}JMfd^4!sa&y1_lg2Bl}n4@KigHe->EwTZ8-w;)7@qA0!Uq
zgJ@#?3kpLt|APDoaz6-z*vJ@N48{l1Xz>e)D?I)Lc@<VSp!gZtzo2-0VKc)H6py_R
zMeRX+5Dnsk#6f%zO{{;JamO#n4=}&N*dQ8)L2@uQn8p#m`yqY?kqtz#k^TG3W`-Ro
zK6@UDg3~pK4~kC^A0!UqgJ@#?3(CW2@e6i40|Pi8gV-Q{fiR2>qG1>&4(6l!mpH$H
zLIHvi>XH2m@)syRLH+{8BZv>8L41%nh!3KP^)IL_#p7R?e_%AoUm!LJgV-n-)xRKL
xApF3<Ks+1SzuIfoTL0efVLgez*8XozjXj7DqCtF+IEW9TarxKT$Iu7l5&#0Z{tW;C

literal 0
HcmV?d00001

-- 
GitLab