diff --git a/MshViewer/Header/Object.h b/MshViewer/Header/Object.h
index 36b8c8bc88918e75c567fbda18083f09b175bb60..c4157ea05abcc41e0fd6753e57738239319c9619 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 ed468bb9fc8a50be38fa594202ba7a1a2cdcdd7e..330d007c7c59ea325576b4635e64f587ee28769d 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 b752a117b79aef54fc75ba535183f242391849b7..11da94ab4b4e57d219c0abf4859e95e499d095d0 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 c23d154d0993ab0c36051697779f9238d9b5c306..4a166c98951d5ded56ada2c80041f13c5e368bef 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 78a4fb7584d522b5da4d140a1cb5f7360a59049e..f8cb589a094b733a9b82ce7f8712ee3e2eac6715 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
Binary files /dev/null and b/Release/Msh/cluster.msh differ