Index: /GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoLodStripsLibrary.h
===================================================================
--- /GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoLodStripsLibrary.h	(revision 1078)
+++ /GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoLodStripsLibrary.h	(revision 1083)
@@ -133,5 +133,5 @@
 
 			//	Loads Mesh.
-			void	LoadStripMesh(const LodStripsLibraryData &, Mesh *geomesh);
+			void	LoadStripMesh(const LodStripsLibraryData *, Mesh *geomesh);
 
 			Geometry::CREATEINDEXDATAFUNC create_index_data_func;
@@ -139,4 +139,6 @@
 			//	Strips vector.
 			SmallIntVector	*mStrips;
+			int *indices_x_submesh;
+			int *offsets_x_submesh;
 
 			void UpdateDataRetrievalInterface(void);			
@@ -149,5 +151,5 @@
 			 * 	including the multiresolution object.
 			*/
-			LodStripsLibrary(const LodStripsLibraryData &, Mesh *geomesh, CREATEINDEXDATAFUNC idfun=NULL);
+			LodStripsLibrary(const LodStripsLibraryData *, Mesh *geomesh, CREATEINDEXDATAFUNC idfun=NULL);
 
 			/// Destructor.
@@ -173,5 +175,6 @@
 			uint32	MinVertices();
 
-			int *indices_x_submesh;
+			uint32 GetValidIndexCount(int submeshid) const { return indices_x_submesh[submeshid]; }
+			uint32 GetValidOffset(int submeshid) const { return offsets_x_submesh[submeshid]; }
 	};
 }
Index: /GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoLodTreeLibrary.h
===================================================================
--- /GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoLodTreeLibrary.h	(revision 1078)
+++ /GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoLodTreeLibrary.h	(revision 1083)
@@ -22,6 +22,6 @@
 /*		LodTreeLibrary( const LodTreeLibrary &);
 		LodTreeLibrary(LodTreeLibrary*);*/
-		LodTreeLibrary(	const LodStripsLibraryData &,
-						const TreeSimplificationSequence &,
+		LodTreeLibrary(	const LodStripsLibraryData *,
+						const TreeSimplificationSequence *,
 						Geometry::Mesh *treeGeoMesh,
 						uint32 leafSubMeshID
@@ -57,4 +57,6 @@
 /*		const VertexData* Get_Trunk_VertexData(void) const;*/
 		const IndexData* CurrentLOD_Trunk_Indices(void) const;
+		uint32 GetValidTrunkIndexCount(int isubmesh) const { return trunk->GetValidIndexCount(isubmesh); }
+		uint32 GetValidTrunkOffset(int isubmesh) const { return trunk->GetValidOffset(isubmesh); }
 
 //		uint32 Get_Foliage_VertexCount(void) const;
@@ -64,13 +66,7 @@
 		const VertexData* Get_Foliage_VertexData(void) const;
 
-//		Geometry::IndexData *trunk_all_indices;
-//		unsigned int *indices_offsets;
-
-//		const Geometry::SmallIntVector & GetStrip(uint32 istrip) const { return trunk->mStrips[istrip]; }
-		Geometry::LodStripsLibrary *trunk;
-
 	private:
 		Foliage *foliage;
-
+		Geometry::LodStripsLibrary *trunk;
 	};
 }
Index: /GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoMeshLoader.h
===================================================================
--- /GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoMeshLoader.h	(revision 1083)
+++ /GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoMeshLoader.h	(revision 1083)
@@ -0,0 +1,218 @@
+/*	==========================================================================
+ *	(C) 2005 Universitat Jaume I
+ *	==========================================================================
+ *	PROYECT:	GAME TOOLS
+ *	==========================================================================
+ *	CONTENT:	
+ *
+ *
+ *	@file	GeoMeshLoader.h
+ *===========================================================================*/
+#ifndef __GEO_MESH_LOADER__
+#define __GEO_MESH_LOADER__
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string>
+#include <vector>
+#include <memory.h>
+#include <time.h>
+#include <iostream>
+#include <iomanip>
+#include "GeoBase.h"
+#include "GeoMesh.h"
+#include "GeoLodStripsLibrary.h"
+#include "GeoLodTreeLibrary.h"
+
+namespace Geometry 
+{
+	const	unsigned	short	CHUNK_OVERHEAD_SIZE	= sizeof(unsigned short)
+																							+
+																							sizeof(unsigned long);
+
+	const unsigned	short M_HEADER											= 0x1000;
+	const unsigned	short M_MESH												= 0x3000;
+	const unsigned	short M_SUBMESH											= 0x4000; 
+	const unsigned	short M_SUBMESH_OPERATION						= 0x4010;
+	const unsigned	short M_SUBMESH_BONE_ASSIGNMENT			= 0x4100;
+	const unsigned	short M_GEOMETRY										= 0x5000;
+	const unsigned	short M_GEOMETRY_VERTEX_DECLARATION = 0x5100;
+	const unsigned	short M_GEOMETRY_VERTEX_ELEMENT			= 0x5110;
+	const unsigned	short M_GEOMETRY_VERTEX_BUFFER			= 0x5200;
+	const unsigned	short M_GEOMETRY_VERTEX_BUFFER_DATA = 0x5210;
+	const unsigned	short M_MESH_SKELETON_LINK					= 0x6000;
+	const unsigned	short M_MESH_BONE_ASSIGNMENT				= 0x7000;
+	const unsigned	short M_MESH_LOD										=	0x8000;
+	const unsigned	short M_MESH_LOD_USAGE							=	0x8100;
+	const unsigned	short M_MESH_LOD_MANUAL							=	0x8110;
+	const unsigned	short M_MESH_LOD_GENERATED					=	0x8120;
+	const unsigned	short M_MESH_BOUNDS									=	0x9000;
+	const unsigned	short M_SUBMESH_NAME_TABLE					=	0xA000;
+	const unsigned	short	M_SUBMESH_NAME_TABLE_ELEMENT	=	0xA100;
+	const unsigned	short M_EDGE_LISTS									=	0xB000;
+	const unsigned	short M_EDGE_LIST_LOD								=	0xB100;
+	const unsigned	short M_EDGE_GROUP									= 0xB110;
+	const	unsigned	short	SUBMESH_COUNT									=	0;
+	const	unsigned	short	GEOMESH_BUILD									=	1;
+	
+	enum VertexElementType
+	{
+		VET_FLOAT1,
+		VET_FLOAT2,
+		VET_FLOAT3,
+		VET_FLOAT4,
+		VET_COLOUR,
+		VET_SHORT1,
+		VET_SHORT2,
+		VET_SHORT3,
+		VET_SHORT4,
+		VET_UBYTE4
+	};
+
+	enum VertexElementSemantic
+	{
+		/// Position, 3 reals per vertex
+		VES_POSITION = 1,
+		/// Blending weights
+		VES_BLEND_WEIGHTS = 2,
+		/// Blending indices
+		VES_BLEND_INDICES = 3,
+		/// Normal, 3 reals per vertex
+		VES_NORMAL = 4,
+		/// Diffuse colours
+		VES_DIFFUSE = 5,
+		/// Specular colours
+		VES_SPECULAR = 6,
+		/// Texture coordinates
+		VES_TEXTURE_COORDINATES = 7,
+		/// Binormal (Y axis if normal is Z)
+		VES_BINORMAL = 8,
+		/// Tangent (X axis if normal is Z)
+		VES_TANGENT = 9
+	};
+
+	/*
+	//	Bounding Box data.
+	struct	GeometryBounds
+	{
+		float	minx;
+		float	miny;
+		float	minz;
+		float	maxx;
+		float	maxy;
+		float	maxz;
+		float	radius;
+	};
+	*/
+	
+	/// Mesh class interface
+	class GeoMeshLoader
+	{
+		private:
+			
+			Mesh		*geoMesh;
+			size_t		mFileSize;
+			unsigned	int		numVertices;
+			unsigned	long	long_actual;
+			size_t		currentSubMesh;
+			bool		mError;
+
+			struct GeometryElement
+			{
+				unsigned short offset;
+				unsigned short semantic;
+				unsigned short type;
+				unsigned short index;
+			};
+
+			struct GT
+			{
+				unsigned short source; //bindIndex
+				std::vector <GeometryElement> list;
+			};
+
+			std::vector <GT> list;
+
+			//	Jump a chunk.
+			void jumpChunk(FILE	*f);
+
+			//	Read a chunk.
+			unsigned short readChunk(FILE	*f);
+
+			//	Read geometry vertex element.
+			void readGeometryVertexElement(FILE	*f, Mesh	*geoMesh);
+
+			//	Read geometry vertex declaration.
+			void readGeometryVertexDeclaration(FILE	*f, Mesh	*geoMesh);
+
+			//	Read geometry vertex buffer.
+			void readGeometryVertexBuffer(FILE		*f,
+																		Mesh		*geoMesh,
+																		int 		option);
+
+			//	Read geometry.
+			void readGeometry(FILE	*f, Mesh	*geoMesh, int option);
+
+			//	Read a submesh operation.
+			void readSubMeshOperation(FILE	*f, Mesh	*geoMesh, int option);
+
+			//	Read a submesh.
+			void readSubMesh(FILE	*f, Mesh	*geoMesh, int option);
+
+			//	Read skeleton name.
+			void readSkeletonLink(FILE	*f, Mesh	*geoMesh, int option);
+
+			//	Read bone assignment.
+			void readMeshBoneAssignment(FILE	*f, Mesh	*geoMesh, int option);
+
+			//	Read bone assignment.
+			void readSubMeshBoneAssignment(FILE	*f, SubMesh	*geoSubMesh, int option);
+
+			//	Read a mesh lod information.
+			void readMeshLodInfo(FILE	*f, Mesh	*geoMesh);
+
+			//	Read a submesh name table.
+			void readSubMeshNameTable(FILE	*f, Mesh	*geoMesh);
+
+			//	Read a mesh file.
+			void readMesh(FILE	*f, Mesh	*geoMesh, int option);
+
+			//	Read bounding box settings.
+			void	readMeshBounds(FILE	*f, Mesh	*geoMesh,	int	option);
+
+			//	Writes the strips list.
+			SubMesh* GeoMeshLoader::BuildStripsGeoSubMesh(SubMesh	*geoSubMesh);
+
+			//	Remove degenerate triangles of a submesh given.
+			SubMesh	*	removeDegenerateTriangles(SubMesh	*geoSubMesh);
+			
+			//	Sets coods between -1 and 1.
+			void	normalizeModel(Mesh	*geoMesh);
+
+			// Imports an OBJ object
+			void importOBJ(FILE *f, Mesh *geoMesh);
+
+			Geometry::LodStripsLibraryData *lodstripsdata;
+			Geometry::TreeSimplificationSequence *treesimpseq;
+
+		public:
+
+			//	Constructor.
+			GeoMeshLoader();
+
+			//	Destroyer.
+			~GeoMeshLoader();
+
+			//	Loads a Mesh file.
+			Mesh* load(char	*fileNameMesh);
+
+			//	Get the size in bytes of the file.
+			size_t	getFileSize();
+
+			// if the loaded .mesh file doesn't contain LOD data this will return NULL
+			const Geometry::LodStripsLibraryData * GetLodStripsData(void) const { return lodstripsdata; }
+			const Geometry::TreeSimplificationSequence * GetTreeSimpSeq(void) const { return treesimpseq; }
+	};
+}
+#endif
+
Index: /GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoMeshSaver.h
===================================================================
--- /GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoMeshSaver.h	(revision 1083)
+++ /GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoMeshSaver.h	(revision 1083)
@@ -0,0 +1,124 @@
+/*	==========================================================================
+ *	(C) 2005 Universitat Jaume I
+ *	==========================================================================
+ *	PROYECT:	GAME TOOLS
+ *	========================================================================*/
+/*	CONTENT:	
+ *
+ *
+ *	@file	GeoMeshSaver.h
+ *	========================================================================*/
+
+#ifndef	__GEO_MESH_SAVER__
+#define	__GEO_MESH_SAVER__
+
+#include	<GeoMeshLoader.h>
+
+namespace Geometry 
+{
+	//	Saves a Mesh.
+	class	GeoMeshSaver
+	{
+		private:
+			//	The mesh to write.
+			Mesh	*mGeoMesh;
+			
+			//	Mesh Bounds.
+			//GeometryBounds	mMeshBounds;
+			
+			//	Write in the file.
+			Serializer	*mSerializer;
+
+			//	Flag that indicate if the mesh 
+			//	is skeletally animated or not.
+			bool	mSkeletallyAnimated;
+			
+			//	Write the main mesh.
+			void	writeMesh(Mesh	*geoMesh);
+
+			//	Write a submesh.
+			void	writeSubMesh(SubMesh	*geoSubMesh);
+
+			// Operation type
+			void	writeSubMeshOperation(const	SubMesh	*geoSubMesh);
+			
+			//	Write geometry.
+			void	writeGeometry(VertexBuffer	*vertexBuffer);
+
+			//	Write Mesh Bounds.
+			void	writeMeshBounds(Mesh	*geoMesh);
+			
+			//	Calculate the mesh size in bytes.
+			size_t	calcMeshSize(const Mesh	*geoMesh);
+
+			//	Calculate the size in bytes for the submesh.
+			size_t	calcSubMeshSize(const SubMesh	*geoSubMesh);
+
+			//	Calculate the geometry size in bytes.
+			size_t	calcGeometrySize(const VertexBuffer* vertexBuffer);
+
+			//	Calculate the skeleton link size in bytes.
+			size_t	calcSkeletonLinkSize(const Mesh	*geoMesh);
+
+			//	Write the file header.
+			void	writeFileHeader(void);
+
+			//	Write a header chunk given.
+			void	writeChunkHeader(	unsigned short	id,
+															unsigned long		count);
+
+			//	Write integers into the file.
+			void	writeInts(unsigned long	id,
+											unsigned long	size);
+
+			//	Write shorts into the file
+			void	writeShorts(unsigned short	id,
+												unsigned long		count);
+
+			//	Write float into the file.
+			void	writeFloats(float						id,
+												unsigned long		count);
+
+			//	Write a string into the file.
+			void	writeString(const	String	&string);
+
+			//	Write booleans into the file.
+			void	writeBools(	const bool id,
+												unsigned	long		count);
+
+			//	Write skeleton name.
+			void	writeSkeletonLink(const	String	&string);
+
+			void	writeMeshBoneAssignment(const VertexBoneAssignment& assign);
+
+			void	writeSubMeshBoneAssignment(const VertexBoneAssignment& assign);
+
+			//	unnormalize geometry model.
+			void	unnormalizeModel(Mesh	*geoMesh);
+			
+		public:
+
+			//	Constructors.
+			GeoMeshSaver();
+
+			//	Destroyer.
+			~GeoMeshSaver();
+
+			//	Sets the material of the mesh.
+			void	setMaterialName(String	materialName);
+
+			//	Gets the material of the mesh.
+			String	getMaterialName();
+			
+			//	Saves a Mesh into a file.
+			int	save(Mesh	*geoMesh,	const	char	*fileNameMesh);
+
+			// temporal members used to tweak the lodtree leaf submesh
+			int leavesSubMesh;
+			VertexBuffer *leavesVB;
+			Index *indices;
+			int numindices;
+	};
+}
+#endif
+
Index: /GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoLodStripsLibrary.cpp
===================================================================
--- /GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoLodStripsLibrary.cpp	(revision 1078)
+++ /GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoLodStripsLibrary.cpp	(revision 1083)
@@ -17,5 +17,5 @@
 //	Constructors.
 //-----------------------------------------------------------------------------
-LodStripsLibrary::LodStripsLibrary(const LodStripsLibraryData &lodstripsdata, Mesh *geomesh, CREATEINDEXDATAFUNC idfun)
+LodStripsLibrary::LodStripsLibrary(const LodStripsLibraryData *lodstripsdata, Mesh *geomesh, CREATEINDEXDATAFUNC idfun)
 :create_index_data_func(idfun?idfun:DefaultIndexDataCreator)
 {
@@ -33,4 +33,5 @@
 	dataRetrievalInterface=NULL;
 	indices_x_submesh = NULL;
+	offsets_x_submesh = NULL;
 	
 	//	Loads the Level Of Detail file.
@@ -58,4 +59,6 @@
 	if (indices_x_submesh)
 		delete[] indices_x_submesh;
+	if (offsets_x_submesh)
+		delete[] offsets_x_submesh;
 }
 
@@ -430,5 +433,5 @@
 //	LoadStripMesh
 //-----------------------------------------------------------------------------
-void LodStripsLibrary::LoadStripMesh(const LodStripsLibraryData &lodstripsdata, Mesh *geomesh)
+void LodStripsLibrary::LoadStripMesh(const LodStripsLibraryData *lodstripsdata, Mesh *geomesh)
 {
 	FILE															*fp;
@@ -451,4 +454,5 @@
 	//	For each one of the submeshes.
 	indices_x_submesh = new int[geomesh->mSubMeshCount];
+	offsets_x_submesh = new int[geomesh->mSubMeshCount];
 	for (unsigned int submesh	=	0; submesh < geomesh->mSubMeshCount; submesh++)
 	{
@@ -492,4 +496,9 @@
 			i	= 0;
 			indices_x_submesh[submesh] = 0;
+			if (submesh==0)
+				offsets_x_submesh[submesh] = 0;
+			else
+				offsets_x_submesh[submesh] = indices_x_submesh[submesh-1];
+
 			//	For each index of the strip.
 			for (index = indexBegin; index < indexEnd; index++)
@@ -498,5 +507,5 @@
 				indices_x_submesh[submesh]++;
 				i++;
-			}
+			}			
 		}
 	}
@@ -559,8 +568,8 @@
 		fclose(fp);*/
 
-	mFileVertices = lodstripsdata.mFileVertices;
-	mFileChangesLOD = lodstripsdata.mFileChangesLOD;
-	mData = lodstripsdata.mData;
-	p_changes = lodstripsdata.p_changes;
+	mFileVertices = lodstripsdata->mFileVertices;
+	mFileChangesLOD = lodstripsdata->mFileChangesLOD;
+	mData = lodstripsdata->mData;
+	p_changes = lodstripsdata->p_changes;
 		
 		
@@ -602,4 +611,9 @@
 		{
 			indices_x_submesh[target_submesh] = counter;
+			if (target_submesh==0)
+				offsets_x_submesh[target_submesh] = 0;
+			else
+				offsets_x_submesh[target_submesh] = indices_x_submesh[target_submesh-1] + offsets_x_submesh[target_submesh-1];
+
 			counter = 0;
 			strip_count = 0;
@@ -617,4 +631,9 @@
 	{
 		indices_x_submesh[target_submesh] = counter;
+		if (target_submesh==0)
+			offsets_x_submesh[target_submesh] = 0;
+		else
+			offsets_x_submesh[target_submesh] = indices_x_submesh[target_submesh-1] + offsets_x_submesh[target_submesh-1];
+
 		counter = 0;
 		strip_count = 0;
Index: /GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/leaves/foliage.cpp
===================================================================
--- /GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/leaves/foliage.cpp	(revision 1078)
+++ /GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/leaves/foliage.cpp	(revision 1083)
@@ -10,5 +10,5 @@
 // Parameters --> None
 //--------------------------------------------------------------------------------------------------------------------------------
-Foliage::Foliage(const Geometry::SubMesh *leavesSubMesh, const Geometry::TreeSimplificationSequence & simpSeq, Geometry::CREATEVERTEXDATAFUNC vdfun, Geometry::CREATEINDEXDATAFUNC idfun): 
+Foliage::Foliage(const Geometry::SubMesh *leavesSubMesh, const Geometry::TreeSimplificationSequence * simpSeq, Geometry::CREATEVERTEXDATAFUNC vdfun, Geometry::CREATEINDEXDATAFUNC idfun): 
 Acth(NULL),
 create_vertex_data_func(vdfun==NULL?Geometry::DefaultVertexDataCreator:vdfun),
@@ -304,10 +304,10 @@
 
 /// returns the number of total leafs
-bool Foliage::ReadSimpSeq(const Geometry::TreeSimplificationSequence & simpSeq)
+bool Foliage::ReadSimpSeq(const Geometry::TreeSimplificationSequence * simpSeq)
 {
 	int tn, tv1,tv2, e=0;
 
 	tn = leafCount;
-	for (std::vector<Geometry::TreeSimplificationSequence::Step>::const_iterator it = simpSeq.mSteps.begin(); it != simpSeq.mSteps.end(); it++)
+	for (std::vector<Geometry::TreeSimplificationSequence::Step>::const_iterator it = simpSeq->mSteps.begin(); it != simpSeq->mSteps.end(); it++)
 	{
 		Leaves[tn].vertsLeaf[0] = it->mNewQuad[0];
Index: /GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/leaves/foliage.h
===================================================================
--- /GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/leaves/foliage.h	(revision 1078)
+++ /GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/leaves/foliage.h	(revision 1083)
@@ -27,5 +27,5 @@
 		int active_leaf_count;
 
-		Foliage (const Geometry::SubMesh *, const Geometry::TreeSimplificationSequence &, Geometry::CREATEVERTEXDATAFUNC vdfun=NULL, Geometry::CREATEINDEXDATAFUNC idfun=NULL);
+		Foliage (const Geometry::SubMesh *, const Geometry::TreeSimplificationSequence *, Geometry::CREATEVERTEXDATAFUNC vdfun=NULL, Geometry::CREATEINDEXDATAFUNC idfun=NULL);
 		Foliage (const Foliage *);
 		virtual ~Foliage (void); // Destructor
@@ -57,5 +57,5 @@
 		void ReadLeafs(const Geometry::SubMesh *);
 		void ReadVertices(const Geometry::SubMesh *);
-		bool ReadSimpSeq(const Geometry::TreeSimplificationSequence &); /// returns true when successful
+		bool ReadSimpSeq(const Geometry::TreeSimplificationSequence *); /// returns true when successful
 		void FillRoot(void);
 
Index: /GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoLodTreeLibrary.cpp
===================================================================
--- /GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoLodTreeLibrary.cpp	(revision 1078)
+++ /GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoLodTreeLibrary.cpp	(revision 1083)
@@ -5,6 +5,6 @@
 using namespace Geometry;
 
-Geometry::LodTreeLibrary::LodTreeLibrary(const LodStripsLibraryData &lodstripsdata,
-										 const TreeSimplificationSequence &simpseq,
+Geometry::LodTreeLibrary::LodTreeLibrary(const LodStripsLibraryData *lodstripsdata,
+										 const TreeSimplificationSequence *simpseq,
 										 Geometry::Mesh *treeGeoMesh,
 										 uint32 leafSubMeshID/*
Index: /GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoMeshLoader.cpp
===================================================================
--- /GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoMeshLoader.cpp	(revision 1083)
+++ /GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoMeshLoader.cpp	(revision 1083)
@@ -0,0 +1,1771 @@
+/*==========================================================================
+ *	(C) 2005 Universitat Jaume I
+ *==========================================================================
+ *	PROYECT:	GAME TOOLS
+ *==========================================================================*/
+/*	CONTENT:	
+ *
+ *
+ *	@file	GeoMeshLoader.cpp
+ *==========================================================================*/
+
+#include	"GeoMeshLoader.h"
+#include	<algorithm>
+#include	<cctype>
+#include	<map>
+
+using namespace Geometry;
+using	namespace	std;
+
+//---------------------------------------------------------------------------
+//	Jump a chunk.
+//---------------------------------------------------------------------------
+void GeoMeshLoader::jumpChunk(FILE	*f)
+{
+	fseek(f,-(long)CHUNK_OVERHEAD_SIZE,1);
+
+	//	Return to the begin of the chunk.
+	fseek(f,long_actual,SEEK_CUR);
+}
+
+//---------------------------------------------------------------------------
+//	Read a chunk.
+//---------------------------------------------------------------------------
+unsigned short GeoMeshLoader::readChunk(FILE	*f)
+{
+	unsigned	short	id;
+
+	fread(&id,sizeof(unsigned short),1,f);
+	fread(&long_actual,sizeof(unsigned long),1,f);
+									
+	return id;
+}
+
+//---------------------------------------------------------------------------
+//	Read geometry vertex element.
+//---------------------------------------------------------------------------
+void GeoMeshLoader::readGeometryVertexElement(FILE	*f, Mesh	*geoMesh)
+{
+	unsigned	short		source;
+	GeometryElement		aux;
+	int								i;
+	bool							found;
+	VertexElementType	vType;
+
+	i						=	0;
+	found	=	false;
+
+	//		VertexElementSemantic vSemantic;
+	// unsigned short source;  	// buffer bind source
+	fread(&source,sizeof(unsigned short),1,f);
+
+	// unsigned short type;    	// VertexElementType
+	fread(&aux.type,sizeof(unsigned short),1,f);
+
+	vType	=	static_cast<VertexElementType>(aux.type);
+
+	// unsigned short semantic; // VertexElementSemantic
+	fread(&aux.semantic,sizeof(unsigned short),1,f);
+
+	//	vSemantic = static_cast<VertexElementSemantic>(tmp);
+	//	unsigned short offset;	// start offset in buffer in bytes
+	fread(&aux.offset,sizeof(unsigned short),1,f);
+
+	// unsigned short index;	// index of the semantic
+	/*
+	VES_POSITION  Position, 3 reals per vertex.  
+	VES_BLEND_WEIGHTS  Blending weights.  
+	VES_BLEND_INDICES  Blending indices.  
+	VES_NORMAL  Normal, 3 reals per vertex.  
+	VES_DIFFUSE  Diffuse colours.  
+	VES_SPECULAR  Specular colours.  
+	VES_TEXTURE_COORDINATES  Texture coordinates.  
+	VES_BINORMAL  Binormal (Y axis if normal is Z).  
+	VES_TANGENT  Tangent (X axis if normal is Z).  
+	*/
+	fread(&aux.index,sizeof(unsigned short),1,f);
+
+	while ((i < list.size()) && (!found))
+	{
+		if (list[i].source==source)
+		{
+			found	=	true;
+		}
+		else
+		{
+			i++;
+		}
+	}
+
+	if (found)
+	{
+		list[i].list.push_back(aux);
+	}
+	else
+	{
+		GT	aux2;
+		
+		aux2.source	=	source;
+		aux2.list.push_back(aux);
+		list.push_back(aux2);
+	}
+}
+
+//---------------------------------------------------------------------------
+//	Read geometry vertex declaration.
+//---------------------------------------------------------------------------
+void GeoMeshLoader::readGeometryVertexDeclaration(FILE	*f, Mesh	*geoMesh)
+{
+	unsigned short chunkID;
+  // Find optional geometry chunks
+  if (!feof(f))
+  {
+    chunkID	=	readChunk(f);
+
+    while(!feof(f) && (chunkID == M_GEOMETRY_VERTEX_ELEMENT ))
+    {
+      switch (chunkID)
+      {
+				case M_GEOMETRY_VERTEX_ELEMENT:
+
+					//	Debug.
+					cout	<<	"		M_GEOMETRY_VERTEX_ELEMENT"
+								<<	endl;
+					
+          readGeometryVertexElement(f, geoMesh);
+
+          break;
+      }
+
+      // Get next chunk
+      if (!feof(f))
+      {
+				chunkID = readChunk(f);
+      }
+    }//	End while.
+
+    if (!feof(f))
+    {
+			// Backpedal back to start of non-submesh chunk
+			fseek(f,-(long)CHUNK_OVERHEAD_SIZE,1);
+    }
+
+  }//	End if (!feof(f))
+}//	End readGeometryVertexDeclaration.
+
+//---------------------------------------------------------------------------
+//	Read geometry vertex buffer.
+//---------------------------------------------------------------------------
+void GeoMeshLoader::readGeometryVertexBuffer(FILE	*f, Mesh	*geoMesh, int option)
+{
+	unsigned	short	bindIndex;
+	unsigned	short	vertexSize;
+	unsigned	short	headerID;
+	int							i;
+	float						aux;
+	int							k;
+	bool						found;
+	float						x,y,z;
+	SubMesh					*geoSubMesh;
+	VertexBuffer		*vertex_buffer;
+
+	i						=	0;
+	k						=	0;
+	found	=	false;
+	
+	if (option == GEOMESH_BUILD)
+	{
+		//	If is the main mesh.
+		if (currentSubMesh == -1)
+		{
+			vertex_buffer	=	geoMesh->mVertexBuffer;
+		}
+		//	If is a submesh.
+		else
+		{
+			//	Gets the current submesh
+			geoSubMesh		=	&geoMesh->mSubMesh[currentSubMesh];
+			vertex_buffer	=	geoSubMesh->mVertexBuffer;
+		}
+	}
+	
+	// Index to bind this buffer to
+	fread(&bindIndex,sizeof(unsigned short),1,f);
+
+	// Per-vertex size, must agree with declaration at this index
+	fread(&vertexSize,sizeof(unsigned short),1,f);
+
+	// Check for vertex data header
+	headerID	=	readChunk(f);
+
+	if (headerID != M_GEOMETRY_VERTEX_BUFFER_DATA)
+	{
+		cout	<<	"Can't find vertex buffer data area"
+					<<	endl;
+	}
+	else
+	{
+		//	Debug.
+		cout	<<	"		M_GEOMETRY_VERTEX_BUFFER_DATA"
+					<<	endl;
+	}
+
+	while ((i<list.size())&&(!found))
+	{
+		if (list[i].source	==	bindIndex)
+		{
+			found	=	true;
+		}
+		else
+		{
+			i++;
+		}
+	}
+
+	if (found)
+	{
+		for (k	=	0;	k < numVertices;	k++)
+		{
+			//	For each element in this source.
+			for(int j	=	0;	j < list[i].list.size();	j++)
+			{
+				//	Positions.
+				if (list[i].list[j].semantic == 1)
+				{
+					fread(&x,sizeof(float),1,f);
+					fread(&y,sizeof(float),1,f);
+					fread(&z,sizeof(float),1,f);
+
+					if (option == GEOMESH_BUILD)
+					{
+						vertex_buffer->mVertexInfo		|=	VERTEX_POSITION;
+						vertex_buffer->mPosition[k].x	=		x;
+						vertex_buffer->mPosition[k].y	=		y;
+						vertex_buffer->mPosition[k].z	=		z;
+					}
+				}
+				//	If are not vertices.
+				else 
+				{
+					if (list[i].list[j].type == 2)
+					{
+						fread(&x,sizeof(float),1,f);
+						fread(&y,sizeof(float),1,f);
+						fread(&z,sizeof(float),1,f);
+
+						if (option == GEOMESH_BUILD)
+						{
+							vertex_buffer->mVertexInfo	|=	VERTEX_NORMAL;
+							vertex_buffer->mNormal[k].x	=		x;
+							vertex_buffer->mNormal[k].y	=		y;
+							vertex_buffer->mNormal[k].z	=		z;
+						}
+					}
+					if (list[i].list[j].type == 1)
+					{
+						fread(&x,sizeof(float),1,f);
+						fread(&y,sizeof(float),1,f);
+						
+						if (option == GEOMESH_BUILD)
+						{
+							vertex_buffer->mVertexInfo			|=	VERTEX_TEXCOORDS;
+							vertex_buffer->mTexCoords[k].x	=		x;
+							vertex_buffer->mTexCoords[k].y	=		y;
+						}
+					}
+				}
+			}
+		}
+	}
+	else
+	{
+		//	Debug.
+		cout	<<	"Error: Source not found."
+					<<	endl;
+
+		//	Error.
+		mError	=	true;
+	}
+
+}
+
+//---------------------------------------------------------------------------
+//	Read Geometry.
+//---------------------------------------------------------------------------
+void GeoMeshLoader::readGeometry(FILE	*f, Mesh	*geoMesh, int option)
+{
+	SubMesh				*geoSubMesh;
+	VertexBuffer	*vertex_buffer;
+	
+	fread(&numVertices,sizeof(unsigned int),1,f);
+
+	if (option == GEOMESH_BUILD)
+	{
+		if (currentSubMesh == -1)
+		{
+			//	Get the current vertex buffer.
+			vertex_buffer	=	geoMesh->mVertexBuffer;
+		}
+		else
+		{
+			//	Get the current submesh.
+			geoSubMesh		=	&geoMesh->mSubMesh[currentSubMesh];
+
+			//	Create the VertexBuffer of the submesh.
+			geoSubMesh->mVertexBuffer	=	new VertexBuffer();
+
+			//	Get the current vertex buffer.
+			vertex_buffer	=	geoSubMesh->mVertexBuffer;
+		}
+
+		//	Initialize the VertexBuffer of the current submesh.
+		vertex_buffer->mVertexCount	=	numVertices;
+
+		//	Initialize the position array.
+		vertex_buffer->mPosition	=	new Vector3[numVertices];
+
+		//	Initialize the normal array.
+		vertex_buffer->mNormal		=	new Vector3[numVertices];
+
+		//	Initialize the texture coords array.
+		vertex_buffer->mTexCoords	=	new Vector2[numVertices];
+	}
+
+	// Find optional geometry chunks
+	if (!feof(f))
+	{
+		unsigned short chunkID = readChunk(f);
+	
+		while(!feof(f) && 
+					(chunkID == M_GEOMETRY_VERTEX_DECLARATION || 
+					chunkID == M_GEOMETRY_VERTEX_BUFFER ))
+		{
+			switch (chunkID)
+			{
+				case M_GEOMETRY_VERTEX_DECLARATION:
+
+					//	Debug.
+					cout	<<	"		M_GEOMETRY_VERTEX_DECLARATION"
+								<<	endl;
+					
+					readGeometryVertexDeclaration(f, geoMesh);
+					
+					break;
+					
+				case M_GEOMETRY_VERTEX_BUFFER:
+					
+					//	Debug.
+					cout	<<	"		M_GEOMETRY_VERTEX_BUFFER"
+								<<	endl;
+					
+					readGeometryVertexBuffer(f, geoMesh,option);
+					
+					break;
+			}
+		
+			// Get next chunk.
+			if (!feof(f))
+			{
+				chunkID = readChunk(f);
+			}
+		}
+
+		if (!feof(f))
+		{
+			// Backpedal back to start of non-submesh chunk.
+			fseek(f,-(long)CHUNK_OVERHEAD_SIZE,1);
+		}
+	}
+}
+
+//---------------------------------------------------------------------------
+//	Read a submesh operation.
+//---------------------------------------------------------------------------
+void GeoMeshLoader::readSubMeshOperation(	FILE	*f,
+																					Mesh	*geoMesh,
+																					int 	option)
+{
+	unsigned	short	opType;
+	
+	fread(&opType,sizeof(unsigned short),1,f);
+
+	if (option == GEOMESH_BUILD)
+	{
+		if (opType == 5)
+		{
+			geoMesh->mSubMesh[currentSubMesh].mType	=	GEO_TRIANGLE_STRIPS;
+		}
+		else
+		{
+			geoMesh->mSubMesh[currentSubMesh].mType	=	GEO_TRIANGLE_LIST;
+		}
+	}
+}
+
+//---------------------------------------------------------------------------
+//	Read a submesh.
+//---------------------------------------------------------------------------
+void GeoMeshLoader::readSubMesh(FILE	*f, Mesh	*geoMesh, int option)
+{
+	SubMesh					*geoSubMesh;
+	unsigned	short	chunkID;
+	char						materialName[255];
+	bool						useSharedVertices;
+	unsigned	int		numIndices;
+	bool						idx32bit;
+
+	switch	(option)
+	{
+		case	SUBMESH_COUNT:
+			geoMesh->mSubMeshCount++;
+			break;
+		case	GEOMESH_BUILD:
+
+			//	Initialize the new subMesh.
+			geoSubMesh	=	&geoMesh->mSubMesh[currentSubMesh];
+	}
+	
+	list.clear();
+
+	//	Gets material name.
+	fgets(materialName,255,f);
+	materialName[strlen(materialName) - 1]	=	'\0';
+
+	fread(&useSharedVertices,sizeof(bool),1,f);
+	
+	if (option	==	GEOMESH_BUILD)
+	{
+		//	Obtain the material name.
+		strcpy(geoSubMesh->mMaterialName,materialName);
+		
+		//	Obtain the flag of vertex shared.
+		geoSubMesh->mSharedVertexBuffer	=	useSharedVertices;
+		
+		if (useSharedVertices)
+		{
+			//	The VB of the submesh points to the VB of the mesh.
+			geoSubMesh->mVertexBuffer	=	geoMesh->mVertexBuffer;
+		}
+	}
+
+	fread(&numIndices,sizeof(unsigned int),1,f);
+	fread(&idx32bit,sizeof(bool),1,f);
+	
+	if (option == GEOMESH_BUILD)
+	{
+			//	Sets the index count of the submesh.
+			geoSubMesh->mIndexCount	=	numIndices;
+	
+			//	Create the index arrar for this submesh.
+			geoSubMesh->mIndex	=	new Index[numIndices];
+	}
+	
+
+	if (idx32bit)
+	{
+		unsigned int aux;
+
+		for (int i = 0; i < numIndices; i++)
+		{
+			fread(&aux,sizeof(unsigned int),1,f);
+
+			if (option == GEOMESH_BUILD)
+			{
+					geoSubMesh->mIndex[i]	=	aux;
+			}
+		}
+	}
+	else
+	{
+		unsigned short aux;
+
+		for (int i = 0; i < numIndices; i++)
+		{
+			fread(&aux,sizeof(unsigned short),1,f);
+			
+			if (option == GEOMESH_BUILD)
+			{
+				geoSubMesh->mIndex[i]	=	aux;
+			}
+		}
+	}
+
+  // M_GEOMETRY chunk 
+	// (Optional: present only if useSharedVertices = false)
+  if (!useSharedVertices)
+	{
+		chunkID = readChunk(f);
+		
+		if (chunkID != M_GEOMETRY)
+		{
+			//	Debug.
+			cout	<<	"Error: Missing mesh geometry."
+						<<	endl;
+
+			//	Error.
+			mError	=	true;
+		}
+		
+		readGeometry(f, geoMesh, option);
+	}
+
+	// Find all bone assignments (if present) 
+	if (!feof(f))
+	{
+		chunkID = readChunk(f);
+		while(!feof(f) &&
+					(chunkID == M_SUBMESH_BONE_ASSIGNMENT ||
+					chunkID == M_SUBMESH_OPERATION))
+		{
+			switch(chunkID)
+			{
+				case M_SUBMESH_OPERATION:
+								
+					//	Debug.
+					cout	<<	"		M_SUBMESH_OPERATION"
+								<<	endl;
+
+					readSubMeshOperation(f, geoMesh, option);
+					
+					break;
+					
+				case M_SUBMESH_BONE_ASSIGNMENT:
+					
+					//	Debug.
+					//cout	<<	"		M_SUBMESH_BONE_ASSIGNMENT"
+					//			<<	endl;
+					
+					if (option	==	GEOMESH_BUILD)
+					{
+						readSubMeshBoneAssignment(f, geoSubMesh, option);
+					}
+					else
+					{
+						jumpChunk(f);
+					}
+					
+					break;
+			}
+
+			if (!feof(f))
+			{
+				chunkID	=	readChunk(f);
+			}
+
+		}
+		if (!feof(f))
+		{
+			// Backpedal back to start of chunk.
+			fseek(f,-(long)CHUNK_OVERHEAD_SIZE,1);
+		}
+	}
+
+}
+
+//---------------------------------------------------------------------------
+//	Read a mesh lod information.
+//---------------------------------------------------------------------------
+void GeoMeshLoader::readMeshLodInfo(FILE	*f, Mesh	*geoMesh)
+{
+	unsigned	short	chunkID;
+	unsigned	short	i;
+	unsigned	short	aux;
+	bool						aux2;
+
+  // unsigned short numLevels;
+	fread(&aux,sizeof(unsigned short),1,f);
+	// bool manual;
+	// (true for manual alternate meshes, false for generated)
+	fread(&aux2,sizeof(bool),1,f);
+
+	// Loop from 1 rather than 0 (full detail index is not in file)
+	for (i = 1; i < aux; ++i)
+	{
+		chunkID = readChunk(f);
+		if (chunkID != M_MESH_LOD_USAGE)
+		{
+			//	Debug.
+			cout	<<	"Error: Missing M_MESH_LOD_USAGE chunk"
+						<<	endl;
+		}
+		else
+		{
+			cout	<<	"		M_MESH_LOD_USAGE"
+						<<	endl;
+		}
+		
+		jumpChunk(f);
+
+	}
+}
+
+//---------------------------------------------------------------------------
+//	Read a submesh name table.
+//---------------------------------------------------------------------------
+void GeoMeshLoader::readSubMeshNameTable(FILE	*f, Mesh	*geoMesh)
+{
+		unsigned	short	chunkID;
+		unsigned	short	subMeshIndex;
+		char						string[255];
+
+		if (!feof(f))
+		{
+			chunkID	=	readChunk(f);
+			
+			while	(!feof(f) && (chunkID == M_SUBMESH_NAME_TABLE_ELEMENT ))
+			{
+				//	Debug.
+				cout	<<	"		M_SUBMESH_NAME_TABLE_ELEMENT"
+							<<	endl;
+				
+				// Read in the index of the submesh.
+				fread(&subMeshIndex,sizeof(unsigned short),1,f);
+				
+				// Read in the String and map it to its index.
+				fgets(string,255,f);
+
+				// If we're not end of file get the next chunk ID.
+				if (!feof(f))
+				{
+					chunkID = readChunk(f);
+				}
+			}
+			if (!feof(f))
+			{
+				// Backpedal back to start of chunk.
+				fseek(f,-(long)CHUNK_OVERHEAD_SIZE,1);
+			}
+		}
+}
+
+//---------------------------------------------------------------------------
+//	Read a mesh file.
+//---------------------------------------------------------------------------
+
+#include "GeoLodStripsLibrary.h"
+#include "GeoLodStripsConstructor.h"
+
+void GeoMeshLoader::readMesh(FILE	*f, Mesh	*geoMesh, int option)
+{
+	unsigned	short	chunkID;
+	bool						nada;
+
+	//	Create the VertexBuffer of the mesh.
+	geoMesh->mVertexBuffer	=	new	VertexBuffer();
+	geoMesh->mVertexBuffer->mVertexCount	=	0;
+
+	//La vacio antes de leer el mesh
+	list.clear();
+
+	// bool skeletallyAnimated
+	fread(&nada,sizeof(bool),1,f);
+
+  // Find all subchunks 
+	if (!feof(f))
+	{
+		chunkID	=	readChunk(f);
+
+		while(!feof(f) &&
+				(chunkID == M_GEOMETRY ||
+				 chunkID == M_SUBMESH ||
+				 chunkID == M_MESH_SKELETON_LINK ||
+				 chunkID == M_MESH_BONE_ASSIGNMENT ||
+				 chunkID == M_MESH_LOD ||
+				 chunkID == M_MESH_BOUNDS ||
+				 chunkID == M_SUBMESH_NAME_TABLE ||
+				 chunkID == M_EDGE_LISTS ||
+				 chunkID == 0xabcd || 
+				 chunkID == 0xdcba))
+		{
+			switch(chunkID)
+			{
+				case 0xabcd:
+					cout << "LODSTRIPS_Chunk" << endl;
+					lodstripsdata = new Geometry::LodStripsLibraryData;
+
+					int				aux,v,c;
+					LODRegisterType	lod_register;
+					LODData			dataaux;
+					int				tam;
+
+					fread(&tam, sizeof(int), 1, f);
+					lodstripsdata->mFileVertices.clear();
+					for (v=0; v<tam; v++)
+					{
+						fread(&aux, sizeof(int), 1, f);
+						lodstripsdata->mFileVertices.push_back(aux);
+					}
+
+					lodstripsdata->mFileChangesLOD.clear();
+					fread(&tam, sizeof(int), 1, f);
+					for (c=0; c<tam; c++)
+					{
+						fread(&dataaux, sizeof(LODData), 1, f);
+						lod_register.strip= dataaux.strip;
+						lod_register.position= dataaux.nP;
+						lod_register.vertexRepetition= dataaux.nL1;
+						lod_register.edgeRepetition= dataaux.nL2;
+						//lod_register.obligatory=false;
+						//lod_register.obligatory= dataaux.obligatory;
+
+						lodstripsdata->mFileChangesLOD.push_back(lod_register);
+					}
+					
+					lodstripsdata->mData.clear();
+					fread(&tam, sizeof(int), 1, f);
+					for (int b=0; b<tam; b++)
+					{
+						fread(&aux, sizeof(int), 1, f);
+						lodstripsdata->mData.push_back(aux);
+					}
+
+					lodstripsdata->p_changes.clear();
+					fread(&tam, sizeof(int), 1, f);
+					for (int p=0; p<tam; p++)
+					{
+						fread(&aux, sizeof(int), 1, f);
+						lodstripsdata->p_changes.push_back(aux);
+					}					
+
+					break;
+
+				case 0xdcba:
+					cout << "LODTREES_Chunk" << endl;
+					treesimpseq = new Geometry::TreeSimplificationSequence;
+
+					int size;
+					fread(&size, sizeof(int), 1, f);
+					treesimpseq->mSteps.clear();
+					for (int i=0; i<size; i++)
+					{
+						Geometry::TreeSimplificationSequence::Step auxstep;
+						fread(&auxstep.mV0,sizeof(int),1,f);
+						fread(&auxstep.mV1,sizeof(int),1,f);
+						fread(&auxstep.mT0,sizeof(int),1,f);
+						fread(&auxstep.mT1,sizeof(int),1,f);
+						fread(auxstep.mNewQuad,sizeof(int),4,f);
+						treesimpseq->mSteps.push_back(auxstep);
+					}
+
+					break;
+
+
+				case M_GEOMETRY:
+
+					//	Debug.
+					cout	<<	"		M_GEOMETRY"
+								<<	endl;
+
+					readGeometry(f, geoMesh, option);
+					break;
+
+				case M_SUBMESH:
+
+					//	Debug.
+					cout	<<	"		M_SUBMESH"
+								<<	endl;
+
+					if (option == GEOMESH_BUILD)
+					{
+						//	Increments the current submesh.
+						currentSubMesh++;
+					}
+
+					readSubMesh(f, geoMesh, option);
+
+					break;
+
+				case M_MESH_SKELETON_LINK:
+
+					//	Debug.
+					cout	<<	"		M_MESH_SKELETON_LINK  "
+								<<	endl;
+								
+
+					readSkeletonLink(f, geoMesh, option);
+
+					break;
+
+				case M_MESH_BONE_ASSIGNMENT:
+
+					//	Debug.
+					//cout	<<	"		M_MESH_BONE_ASSIGNMENT  "
+					//			<<	endl;
+
+					readMeshBoneAssignment(f, geoMesh, option);
+
+					break;
+
+				case M_MESH_LOD:
+
+					//	Debug.
+					cout	<<	"		M_MESH_LOD"
+								<<	endl;
+					
+					readMeshLodInfo(f, geoMesh);
+					break;
+
+				case M_MESH_BOUNDS:
+
+					//	Debug.
+					cout	<<	"		M_MESH_BOUNDS "
+								<<	endl;
+
+					//jumpChunk(f);
+					readMeshBounds(f, geoMesh, option);
+					break;
+
+				case M_SUBMESH_NAME_TABLE:
+
+					//	Debug.
+					cout	<<	"		M_SUBMESH_NAME_TABLE "
+								<<	endl;
+
+					readSubMeshNameTable(f,	geoMesh);
+					break;
+
+				case M_EDGE_LISTS:
+
+					//	Debug.
+					cout	<<	"		M_EDGE_LISTS "
+								<<	endl;
+
+					jumpChunk(f);
+					break;
+			}
+
+			if (!feof(f))
+			{
+				chunkID	=	readChunk(f);
+			}
+
+		}
+
+		if (!feof(f))
+		{
+			// Backpedal back to start of chunk
+			fseek(f,-(long)CHUNK_OVERHEAD_SIZE,1);
+
+			//	Debug.
+			cout	<<	"Error: Reading failure."
+						<<	endl;
+
+			//	Error.
+			mError	=	true;
+		}
+	}
+
+}
+
+
+//---------------------------------------------------------------------------
+//	Allocate memory to the array of strips
+//---------------------------------------------------------------------------
+SubMesh* GeoMeshLoader::BuildStripsGeoSubMesh(SubMesh* geoSubMesh)
+{
+	bool		head_found;
+	bool		tail_found;
+	int			strip_count;
+	int			tailIndex;
+	size_t	tail;
+
+
+	head_found							=	false;
+	tail_found							=	false;
+	geoSubMesh->mStripCount	=	1;
+
+	//	Foreachone of the indices.
+	//	Obtains the number of triangle strips.
+	for (int i = 0; i < (geoSubMesh->mIndexCount - 1); i++)
+	{
+		if (geoSubMesh->mIndex[i] == geoSubMesh->mIndex[i+1])
+		{
+			if (head_found)
+			{
+				tail_found	=	true;
+			}
+			else
+			{
+				head_found	=	true;
+			}
+
+			//	Jump one index.
+			i++;
+		}
+		else
+		{
+			//	Increments the number of triangle strips.
+			if (tail_found)
+			{
+				geoSubMesh->mStripCount++;
+			}
+
+			head_found	=	false;
+			tail_found	=	false;
+		}
+	}
+
+	geoSubMesh->mStrip		=	(Index**) malloc(	sizeof(Index*)
+			*
+			geoSubMesh->mStripCount);
+
+	//	Number of strips. Initially there is one triangle strip.
+	strip_count	=	1;
+
+	head_found						=	false;
+	tail_found						=	false;
+
+	//	Initialize the fist triangle strip.
+	geoSubMesh->mStrip[0]	=	&geoSubMesh->mIndex[0];
+
+	//	Foreachone of the indices.
+	//	Assigns the beginning of the triangle strips.
+	for(int i = 0;i < (geoSubMesh->mIndexCount - 1); i++)
+	{
+		if(geoSubMesh->mIndex[i] == geoSubMesh->mIndex[i+1])
+		{
+			if(head_found)
+			{
+				if (!tail_found)
+				{
+					tailIndex		=	i;
+				}
+
+				tail_found	=	true;
+			}
+			else
+			{
+				head_found	=	true;
+			}
+
+			//	Jump one index.
+			i++;
+		}
+		else
+		{
+			//	Increments the number of triangle strips.
+			if(tail_found)
+			{
+				geoSubMesh->mStrip[strip_count++]	=	&geoSubMesh->mIndex[tailIndex];
+			}
+
+			head_found	=	false;
+			tail_found	=	false;
+		}
+	}
+
+	//	Remove degenerate triangles of a submesh given.
+	//geoSubMesh	=	removeDegenerateTriangles(geoSubMesh);
+
+	return	geoSubMesh;
+}
+
+//---------------------------------------------------------------------------
+//	Remove degenerate triangles of a submesh given.
+//---------------------------------------------------------------------------
+SubMesh	*	GeoMeshLoader::removeDegenerateTriangles(SubMesh	*geoSubMesh)
+{
+	Index		*indices;
+	Index		*index;
+	Index		*indexBegin;
+	Index		*indexEnd;
+	Index		*new_strip_starts;
+	size_t	new_index_count;
+	size_t	current_index;
+
+	//	Stores the new starts of strips.
+	new_strip_starts	=	new	Index[geoSubMesh->mStripCount];
+	
+	//	Calculate the new index count.
+	new_index_count	=	geoSubMesh->mIndexCount	
+		-
+		(2 * geoSubMesh->mStripCount)
+		+
+		2;
+
+	//	Auxiliar index array.
+	indices	=	new	Index[new_index_count];
+
+	//	Initialize the current index.
+	current_index	=	0;
+	
+	//	For each one of the strips.
+	for (int strip = 0; strip < geoSubMesh->mStripCount; strip++)
+	{
+		//	Stars of strip without degenerate triangles.
+		new_strip_starts[strip]	=	current_index;
+		
+		//	First index of the strip.
+		indexBegin	=	geoSubMesh->mStrip[strip];
+
+		//	If is the final strip
+		if (strip	== (geoSubMesh->mStripCount - 1))
+		{
+			//	The end of the index array.
+			indexEnd	= &geoSubMesh->mIndex[geoSubMesh->mIndexCount];
+		}
+		else
+		{
+			//	The beginning of the next strip.
+			indexEnd	= geoSubMesh->mStrip[strip + 1];
+		}
+
+		int i;
+		i	= 0;
+
+		//	If is not the first strip.
+		if (strip != 0)
+		{
+			indexBegin++;
+		}
+
+		//	If is not the last strip.
+		if (strip	!= (geoSubMesh->mStripCount - 1))
+		{
+			indexEnd--;
+		}
+
+		//	For each index of the strip.
+		for (index = indexBegin; index < indexEnd; index++)
+		{
+			indices[current_index++]	=	indexBegin[i];
+
+			//	Increments i.
+			i++;
+		}
+
+	}
+
+	//	Free Index memory.
+	delete	[]geoSubMesh->mIndex;
+
+	//	Update index count.
+	geoSubMesh->mIndexCount	=	new_index_count;
+
+	geoSubMesh->mIndex	=	new	Index[new_index_count];
+
+	//	Store new index array without degenerate triangles.
+	for (size_t	i	=	0;	i	<	geoSubMesh->mIndexCount; i++)
+	{
+		geoSubMesh->mIndex[i]	=	indices[i];
+	}
+
+	//	Free auxiliar index array;
+	delete	[]indices;
+
+	//	Update start of the strip.
+	for (int	strip	=	0; strip < geoSubMesh->mStripCount; strip++)
+	{
+		geoSubMesh->mStrip[strip]	=	&geoSubMesh->mIndex[new_strip_starts[strip]];
+	}
+
+	//	Free auxiliar strip starts.
+	delete	[]new_strip_starts;
+	
+	return	geoSubMesh;
+}
+
+//---------------------------------------------------------------------------
+//	Loads a mesh.
+//---------------------------------------------------------------------------
+Mesh* GeoMeshLoader::load(char	*nameFileMesh) 
+{
+	unsigned	short	uno;
+	unsigned	short	chunkID;
+	char		version[255];
+	char		kk;
+	FILE		*pFile;
+	SubMesh		*geosubmesh;
+
+	//	Debug.
+	cout	<<	"---------------------------------"
+				<<	endl
+				<<	"\t LOAD MESH"
+				<<	endl
+				<<	"---------------------------------"
+				<<	endl;
+
+	// retrieve the extension of the file
+	std::string fileExt;
+	std::string completeFileName(nameFileMesh);
+	for (std::string::reverse_iterator it = completeFileName.rbegin(); it!=completeFileName.rend(); it++)
+		if (*it=='.')
+			break;
+		else
+			fileExt += *it;
+
+	std::transform(fileExt.begin(), fileExt.end(), fileExt.begin(), std::toupper);
+	reverse(fileExt.begin(),fileExt.end());
+	
+	geoMesh	=	NULL;
+	if (lodstripsdata)
+		delete lodstripsdata;
+	lodstripsdata=NULL;
+
+	if (treesimpseq)
+		delete treesimpseq;
+	treesimpseq=NULL;
+
+	//	Open the mesh file.
+	pFile	=	fopen(nameFileMesh, "rb");
+
+	if (pFile)
+	{
+		//	Initialize the current submesh;
+		currentSubMesh	=	-1;
+
+		//	Initialize the return value.
+		geoMesh	=	new	Mesh();
+
+		if (fileExt==std::string("OBJ"))
+		{
+			mError	=	false;
+			importOBJ(pFile,geoMesh);
+		}
+		else
+		{
+			//	Count the submeshes
+			//	and next build the geomesh.
+			for (int option = 0; option < 2;option++)
+			{
+				//	Initialize Error.
+				mError	=	false;
+		
+				fread(&uno,sizeof(unsigned short),1,pFile);
+
+				if (uno != M_HEADER)
+				{
+					//	Debug.
+					cout	<<	"Error: Header not found."
+						<<	endl;
+
+					//	Error.
+					mError	=	true;
+				}
+
+				// Read version.
+				fgets(version,255,pFile);
+
+				cout	<<	version	<<	endl;
+
+				if (strcmp(version,"[MeshSerializer_v1.30]\n"))
+				{
+					//	Debug.
+					cout	<<	"Error: Wrong mesh version."
+						<<	endl
+						<<	"Only version 1.3 or older allowed."
+						<<	endl;
+
+					//	Error.
+					mError	=	true;
+				}
+
+				while(!feof(pFile))
+				{
+					chunkID = readChunk(pFile);
+
+					switch (chunkID)
+					{
+						case M_MESH:
+							readMesh(pFile, geoMesh, option);
+							break;
+					}
+				}
+
+				//	Create the submesh array.
+				if (option == SUBMESH_COUNT)
+				{
+					geoMesh->mSubMesh	= new SubMesh[geoMesh->mSubMeshCount];
+				}
+
+				//	Move the curso to the begining of the file.
+				fseek(pFile,0,SEEK_SET);
+			}
+
+			//	Goes to the end of the file.
+			fseek(pFile,0,SEEK_END);
+
+			//	Gets the size of the file.
+			mFileSize	=	ftell(pFile);
+		}
+
+		// Close the mesh file.
+		fclose(pFile);
+
+		//	If no error.
+		if (!mError)
+		{
+			for (int submesh = 0;	submesh < geoMesh->mSubMeshCount; submesh++)
+			{
+				//	Gets the actual submesh.
+				geosubmesh	=	&geoMesh->mSubMesh[submesh];
+
+				if (geosubmesh->mType == Geometry::GEO_TRIANGLE_STRIPS)
+				{
+					//	Fill the strips list.
+					geosubmesh	=	BuildStripsGeoSubMesh(geosubmesh);
+				}
+			}
+
+			//	Sets coods between -1 and 1.
+			normalizeModel(geoMesh);
+		}
+	}
+	else
+	{
+		//	Debug.
+		cout	<<	"Error: File not found."
+					<<	endl;
+
+		//	File not found.
+		mError	=	true;
+	}
+
+	//	If an error happens.
+	if (mError)
+	{
+		delete	geoMesh;
+		
+		geoMesh	=	NULL;
+	}
+	
+	return	geoMesh;
+}
+
+//---------------------------------------------------------------------------
+//	Sets coords between -1 and 1.
+//---------------------------------------------------------------------------
+void	GeoMeshLoader::normalizeModel(Mesh	*geoMesh)
+{
+	unsigned	int	i;
+	float					maxx, minx, maxy, miny, maxz, minz;
+	float					cx, cy, cz, w, h, d, max;
+	float					scale;
+	VertexBuffer	*vertex_buffer;
+
+	//	Gets vertex buffer.
+	vertex_buffer	=	geoMesh->mSubMesh[0].mVertexBuffer;
+	
+	//	Get the max/mins.
+	maxx = minx = vertex_buffer->mPosition[0].x;
+	maxy = miny = vertex_buffer->mPosition[0].y;
+	maxz = minz = vertex_buffer->mPosition[0].z;
+	
+	//	For each submesh.
+	for (int submesh = 0; submesh < geoMesh->mSubMeshCount; submesh++)
+	{
+		//	Gets the actual submesh.
+		vertex_buffer	=	geoMesh->mSubMesh[submesh].mVertexBuffer;
+
+		//	For each index of the strip.
+		for (int i = 0; i < vertex_buffer->mVertexCount; i++)
+		{
+			if (maxx < vertex_buffer->mPosition[i].x)
+			{
+				maxx = vertex_buffer->mPosition[i].x;
+			}
+
+			if (minx > vertex_buffer->mPosition[i].x)
+			{
+				minx = vertex_buffer->mPosition[i].x;
+			}
+
+			if (maxy < vertex_buffer->mPosition[i].y)
+			{
+				maxy = vertex_buffer->mPosition[i].y;
+			}
+
+			if (miny > vertex_buffer->mPosition[i].y)
+			{
+				miny = vertex_buffer->mPosition[i].y;
+			}
+
+			if (maxz < vertex_buffer->mPosition[i].z)
+			{
+				maxz = vertex_buffer->mPosition[i].z;
+			}
+
+			if (minz > vertex_buffer->mPosition[i].z)
+			{
+				minz = vertex_buffer->mPosition[i].z;
+			}
+		}
+
+		//	If is a shared vertex Buffer.
+		if (geoMesh->mSubMesh[submesh].mSharedVertexBuffer)
+		{
+			break;
+		}
+	}
+	
+	//	Calculate model width, height, and depth.
+	w = fabs(maxx) + fabs(minx);
+	h = fabs(maxy) + fabs(miny);
+	d = fabs(maxz) + fabs(minz);
+
+	//	Calculate center of the model.
+	cx = (maxx + minx) / 2.0;
+	cy = (maxy + miny) / 2.0;
+	cz = (maxz + minz) / 2.0;
+
+
+	//	Calculate max dimension.
+	if (w > h)
+	{
+		max	=	w;
+	}
+	else
+	{
+		max	=	h;
+	}
+
+	if (d > max)
+	{
+		max	=	d;
+	}
+	
+	//	Calculate unitizing scale factor.
+	scale = 1.0 / max;
+
+	geoMesh->mMeshBounds.scaleFactor		=	scale;
+
+	//	Translate around center then scale.
+	//	For each submesh.
+	for (int submesh = 0; submesh < geoMesh->mSubMeshCount; submesh++)
+	{
+		//	Gets the actual submesh.
+		vertex_buffer	=	geoMesh->mSubMesh[submesh].mVertexBuffer;
+
+		//	For each index of the strip.
+		for (int i = 0; i < vertex_buffer->mVertexCount; i++)
+		{
+			vertex_buffer->mPosition[i].x -= cx;
+			vertex_buffer->mPosition[i].y -= cy;
+			vertex_buffer->mPosition[i].z -= cz;
+			vertex_buffer->mPosition[i].x *= scale;
+			vertex_buffer->mPosition[i].y *= scale;
+			vertex_buffer->mPosition[i].z *= scale;
+		}
+
+		//	If is a shared vertex Buffer.
+		if (geoMesh->mSubMesh[submesh].mSharedVertexBuffer)
+		{
+			break;
+		}
+	}
+
+}
+
+//---------------------------------------------------------------------------
+//	Get the size in bytes of the file.
+//---------------------------------------------------------------------------
+size_t	GeoMeshLoader::getFileSize()
+{
+	return	mFileSize;
+}
+
+//---------------------------------------------------------------------------
+//	Constructor
+//---------------------------------------------------------------------------
+GeoMeshLoader::GeoMeshLoader()
+{
+	geoMesh			=	NULL;
+	mFileSize		=	0;
+	lodstripsdata	=	NULL;
+	treesimpseq		=	NULL;
+}
+
+//---------------------------------------------------------------------------
+//	Destroyer.
+//---------------------------------------------------------------------------
+GeoMeshLoader::~GeoMeshLoader()
+{
+	if (geoMesh)
+		delete	geoMesh;
+	if (lodstripsdata)
+		delete lodstripsdata;
+	if (treesimpseq)
+		delete treesimpseq;
+}
+
+//---------------------------------------------------------------------------
+//	Read bones of the submesh.
+//---------------------------------------------------------------------------
+void GeoMeshLoader::readSubMeshBoneAssignment(FILE* f, SubMesh* geoSubMesh,int option)
+{
+	if (option == GEOMESH_BUILD)
+	{
+		VertexBoneAssignment assign;
+
+		// unsigned int vertexIndex;
+		fread(&(assign.vertexIndex),sizeof(unsigned int),1,f);
+		// unsigned short boneIndex;
+		fread(&(assign.boneIndex),sizeof(unsigned short),1,f);
+		// float weight
+		fread(&(assign.weight),sizeof(float),1,f);
+
+		geoSubMesh->mBones.push_back(assign);
+	}
+}
+
+//---------------------------------------------------------------------------
+//	Read bones of the main mesh.
+//---------------------------------------------------------------------------
+void GeoMeshLoader::readMeshBoneAssignment(FILE* f, Mesh* geoMesh,int option)
+{
+	if (option == GEOMESH_BUILD)
+	{
+		VertexBoneAssignment assign;
+
+		// unsigned int vertexIndex;
+		fread(&(assign.vertexIndex),sizeof(unsigned int),1,f);
+		// unsigned short boneIndex;
+		fread(&(assign.boneIndex),sizeof(unsigned short),1,f);
+		// float weight
+		fread(&(assign.weight),sizeof(float),1,f);
+
+
+		geoMesh->mBones.push_back(assign);
+	}
+}
+
+//---------------------------------------------------------------------------
+//	Read skeleton link.
+//---------------------------------------------------------------------------
+void GeoMeshLoader::readSkeletonLink(FILE* f, Mesh* geoMesh,int option)
+{
+	if (option == GEOMESH_BUILD)
+	{
+		fgets(geoMesh->mSkeletonName,255,f);
+		
+		geoMesh->hasSkeleton	=	true;
+
+		//	Debug.
+		cout	<<	"Skeleton Name: "
+					<<	geoMesh->mSkeletonName
+					<<	endl;
+	}
+}
+
+//---------------------------------------------------------------------------
+//	Read bounding box settings.
+//---------------------------------------------------------------------------
+void	GeoMeshLoader::readMeshBounds(FILE	*f, Mesh	*geoMesh,	int	option)
+{
+	if (option == GEOMESH_BUILD)
+	{
+		fread(&(geoMesh->mMeshBounds.minX),sizeof(float),1,f);
+		fread(&(geoMesh->mMeshBounds.minY),sizeof(float),1,f);
+		fread(&(geoMesh->mMeshBounds.minZ),sizeof(float),1,f);
+		fread(&(geoMesh->mMeshBounds.maxX),sizeof(float),1,f);
+		fread(&(geoMesh->mMeshBounds.maxY),sizeof(float),1,f);
+		fread(&(geoMesh->mMeshBounds.maxZ),sizeof(float),1,f);
+		fread(&(geoMesh->mMeshBounds.radius),sizeof(float),1,f);
+	}
+}
+
+struct face_t
+{
+	int v1,v2,v3;
+	int t1,t2,t3;
+	int n1,n2,n3;
+};
+
+class VertexArranger
+{
+public:
+	VertexArranger(Geometry::Mesh *m){
+		mesh=m;
+		current_submesh=0;
+		current_tris=new int[m->mSubMeshCount];
+		for (int i=0; i<m->mSubMeshCount; i++)
+			current_tris[i] = 0;
+	}
+	~VertexArranger(void){
+		delete[] current_tris;
+	}
+
+	void AddFace(int v1, int v2, int v3, int t1, int t2, int t3, int n1, int n2, int n3){
+		Geometry::SubMesh *submesh = mesh->mSubMesh + current_submesh;
+
+		vertex_arranger_node vertex1(v1,n1,t1);
+		vertex_arranger_node vertex2(v2,n2,t2);
+		vertex_arranger_node vertex3(v3,n3,t3);
+		
+		int j = current_tris[current_submesh];
+
+		std::map<vertex_arranger_node,int>::iterator res;
+		res=vertex_map.find(vertex1);
+		if (res==vertex_map.end())
+		{
+			int val = vertex_map.size();
+			vertex_map[vertex1] = val;
+			submesh->mIndex[j*3+0] = val;
+		}
+		else
+			submesh->mIndex[j*3+0] = res->second;
+
+		res=vertex_map.find(vertex2);
+		if (res==vertex_map.end())
+		{
+			int val = vertex_map.size();
+			vertex_map[vertex2] = val;
+			submesh->mIndex[j*3+1] = val;
+		}
+		else
+			submesh->mIndex[j*3+1] = res->second;
+
+		res=vertex_map.find(vertex3);
+		if (res==vertex_map.end())
+		{
+			int val = vertex_map.size();
+			vertex_map[vertex3] = val;
+			submesh->mIndex[j*3+2] = val;
+		}
+		else
+			submesh->mIndex[j*3+2] = res->second;
+
+		current_tris[current_submesh] ++;
+	}
+
+	int GetVertexCount(void) const { return vertex_map.size(); }
+
+	void SetCurrentSubMesh(int i){ current_submesh = i; }
+	
+	class vertex_arranger_node
+	{
+	public:
+		int v, n, t;
+
+		vertex_arranger_node(void){
+			v=n=t=-1;
+		}
+		vertex_arranger_node(int iv, int in=-1, int it=-1){
+			v=iv;
+			n=in;
+			t=it;
+		}
+
+		bool operator<(const vertex_arranger_node &vu) const {
+			if (v<vu.v) return true;
+			if (v>vu.v) return false;
+			if (n<vu.n) return true;
+			if (n>vu.n) return false;
+			if (t<vu.t) return true;
+			if (t>vu.t) return false;
+			return false;
+		}
+		bool operator==(const vertex_arranger_node &vu) const {
+			return (v==vu.v && v==vu.v && n==vu.n && n==vu.n && t==vu.t && t==vu.t);
+		}	
+	};
+
+/*	VertexArranger::vertex_arranger_node *GetVertexInfo(void) const {
+		vertex_arranger_node * vertex_list = new vertex_arranger_node[GetVertexCount()];
+		for (std::map<vertex_arranger_node,int>::const_iterator it=vertex_map.begin(); it!=vertex_map.end(); it++)
+			vertex_list[it->second] = it->first;
+		return vertex_list;
+	}
+
+	const std::vector<int> GetIndexInfo(void) const { return indices; }*/
+
+	void Arrange( const std::vector<Geometry::Vector3> & vertices, 
+				  const std::vector<Geometry::Vector3> & normals,
+				  const std::vector<Geometry::Vector2> & texcoords){
+
+		mesh->mVertexBuffer=new Geometry::VertexBuffer;
+		mesh->mVertexBuffer->mVertexCount = GetVertexCount();
+		mesh->mVertexBuffer->mPosition = new Geometry::Vector3[mesh->mVertexBuffer->mVertexCount];
+		mesh->mVertexBuffer->mTexCoords = texcoords.empty()?NULL:new Geometry::Vector2[mesh->mVertexBuffer->mVertexCount];
+		mesh->mVertexBuffer->mNormal = normals.empty()?NULL:new Geometry::Vector3[mesh->mVertexBuffer->mVertexCount];
+		mesh->mVertexBuffer->mVertexInfo = Geometry::VERTEX_POSITION | (texcoords.empty()?0:Geometry::VERTEX_TEXCOORDS) | (normals.empty()?0:Geometry::VERTEX_NORMAL);
+
+		// sort the calculated vertices
+		
+		vertex_arranger_node * vertex_list = new vertex_arranger_node[mesh->mVertexBuffer->mVertexCount];
+		for (std::map<vertex_arranger_node,int>::iterator it=vertex_map.begin(); it!=vertex_map.end(); it++)
+			vertex_list[it->second] = it->first;
+
+		for (int i=0; i<mesh->mSubMeshCount; i++)
+			mesh->mSubMesh[i].mVertexBuffer = mesh->mVertexBuffer;
+		
+		for (int j=0; j<mesh->mVertexBuffer->mVertexCount; j++)
+		{		
+			int vi = vertex_list[j].v;
+			int ti = vertex_list[j].t;
+			int ni = vertex_list[j].n;
+
+			Geometry::Vector3 auxpos(vertices[vi]);
+			if (auxpos.x < mesh->mMeshBounds.minX) mesh->mMeshBounds.minX = auxpos.x;
+			if (auxpos.y < mesh->mMeshBounds.minY) mesh->mMeshBounds.minY = auxpos.y;
+			if (auxpos.z < mesh->mMeshBounds.minZ) mesh->mMeshBounds.minZ = auxpos.z;
+			if (auxpos.x > mesh->mMeshBounds.maxX) mesh->mMeshBounds.maxX = auxpos.x;
+			if (auxpos.y > mesh->mMeshBounds.maxY) mesh->mMeshBounds.maxY = auxpos.y;
+			if (auxpos.z > mesh->mMeshBounds.maxZ) mesh->mMeshBounds.maxZ = auxpos.z;
+
+			mesh->mVertexBuffer->mPosition[j] = auxpos;
+			mesh->mVertexBuffer->mNormal[j] = normals[ni];
+			if (texcoords.empty()==false)
+				mesh->mVertexBuffer->mTexCoords[j] = texcoords[ti];		
+		}
+
+		delete[] vertex_list;
+	}
+
+//private:
+	std::map<vertex_arranger_node,int> vertex_map;
+	Geometry::Mesh *mesh;
+	int current_submesh;
+	int *current_tris;
+};
+
+
+void	GeoMeshLoader::importOBJ(FILE *f, Mesh *mesh)
+{
+	mesh->hasSkeleton=false;
+	mesh->mSubMeshCount=0;
+
+	std::vector<Geometry::Vector3> vertices;
+	std::vector<Geometry::Vector3> normals;
+	std::vector<Geometry::Vector2> texcoords;
+	std::vector<std::vector<face_t> > faces;
+	std::vector<face_t> current_faces;
+
+	mesh->mMeshBounds.maxX = -99999999.9f;
+	mesh->mMeshBounds.maxY = -99999999.9f;
+	mesh->mMeshBounds.maxZ = -99999999.9f;
+	mesh->mMeshBounds.minX =  99999999.9f;
+	mesh->mMeshBounds.minY =  99999999.9f;
+	mesh->mMeshBounds.minZ =  99999999.9f;
+	mesh->mMeshBounds.radius = 1.0f;
+	mesh->mMeshBounds.scaleFactor = 1.0f;
+
+	char line[256]="";
+	while(!feof(f))
+	{
+		fgets(line,256,f);
+		if (line[0]=='v' && line[1]==' ')
+		{
+			Geometry::Vector3 v3;
+			sscanf(line+2,"%f %f %f",&v3.x,&v3.y,&v3.z);
+			vertices.push_back(v3);
+		}
+		else if (line[0]=='v' && line[1]=='t')
+		{
+			Geometry::Vector2 v2;
+			sscanf(line+2,"%f %f",&v2.x,&v2.y);
+			texcoords.push_back(v2);
+		}
+		else if (line[0]=='v' && line[1]=='n')
+		{
+			Geometry::Vector3 v3;
+			sscanf(line+2,"%f %f %f",&v3.x,&v3.y,&v3.z);
+			normals.push_back(v3);
+		}
+		else if (line[0]=='f')
+		{
+			face_t auxface;
+			auxface.n1=auxface.n2=auxface.n3=auxface.t1=auxface.t2=auxface.t3=auxface.v1=auxface.v2=auxface.v3=0;
+			int n = sscanf(line+2,"%d/%d/%d %d/%d/%d %d/%d/%d", &auxface.v1,&auxface.t1,&auxface.n1, 
+									  						    &auxface.v2,&auxface.t2,&auxface.n2, 
+																&auxface.v3,&auxface.t3,&auxface.n3);
+			if (n<9)
+			{
+				auxface.n1=auxface.n2=auxface.n3=auxface.t1=auxface.t2=auxface.t3=auxface.v1=auxface.v2=auxface.v3=0;
+				n = sscanf(line+2,"%d//%d %d//%d %d//%d", &auxface.v1,&auxface.n1, 
+														  &auxface.v2,&auxface.n2, 
+														  &auxface.v3,&auxface.n3);
+				if (n<6)
+				{
+					auxface.n1=auxface.n2=auxface.n3=auxface.t1=auxface.t2=auxface.t3=auxface.v1=auxface.v2=auxface.v3=0;
+					n = sscanf(line+2,"%d/%d %d/%d %d/%d", &auxface.v1,&auxface.t1,
+														   &auxface.v2,&auxface.t2, 
+														   &auxface.v3,&auxface.t3);
+					if (n<6)
+					{
+						auxface.n1=auxface.n2=auxface.n3=auxface.t1=auxface.t2=auxface.t3=auxface.v1=auxface.v2=auxface.v3=0;
+						n = sscanf(line+2,"%d %d %d", &auxface.v1,&auxface.v2,&auxface.v3);
+					}
+				}
+			}
+
+			auxface.v1=abs(auxface.v1); auxface.v2=abs(auxface.v2); auxface.v3=abs(auxface.v3);
+			auxface.t1=abs(auxface.t1); auxface.t2=abs(auxface.t2); auxface.t3=abs(auxface.t3);
+			auxface.n1=abs(auxface.n1); auxface.n2=abs(auxface.n2); auxface.n3=abs(auxface.n3);
+			auxface.v1--; auxface.v2--; auxface.v3--;
+			auxface.t1--; auxface.t2--; auxface.t3--;
+			auxface.n1--; auxface.n2--; auxface.n3--;
+			current_faces.push_back(auxface);
+		}
+		else if (line[0]=='g')
+		{
+			if (current_faces.size()>0)
+				faces.push_back(current_faces);
+			current_faces.clear();
+		}
+	}
+
+	if (current_faces.size()>0)
+		faces.push_back(current_faces);
+	current_faces.clear();
+
+	mesh->mSubMeshCount = faces.size();
+	bool found_texcoords=!texcoords.empty();
+
+	if (normals.empty())
+	{
+		// calculate face normals
+		for (int i=0, inormal=0; i<mesh->mSubMeshCount; i++)
+		{
+			Geometry::SubMesh *submesh = mesh->mSubMesh+i;
+			 std::vector<face_t> & vecfaces = faces[i];
+			int j=0;
+			for (std::vector<face_t>::iterator it=vecfaces.begin(); it!=vecfaces.end(); it++,j++,inormal++)
+			{
+				face_t & auxface = *it;
+				auxface.n1 = inormal;
+				auxface.n2 = inormal;
+				auxface.n3 = inormal;
+				Geometry::Vector3 v1,v2,v3,v31,v21,nor;
+				v1 = vertices[auxface.v1];
+				v2 = vertices[auxface.v2];
+				v3 = vertices[auxface.v3];
+				v31 = v3 - v1;
+				v21 = v2 - v1;
+				nor = v21.crossProduct(v31);
+				nor.normalise();
+				normals.push_back(nor);
+			}			
+		}
+	}
+
+	// fill up the mesh structure with the loaded information
+
+	VertexArranger vertex_arranger(mesh);
+		 
+	mesh->mSubMesh=new Geometry::SubMesh[mesh->mSubMeshCount];
+	for (int i=0; i<mesh->mSubMeshCount; i++)
+	{
+		Geometry::SubMesh *submesh = mesh->mSubMesh+i;
+		int j=0;
+		const std::vector<face_t> & vecfaces = faces[i];
+		std::vector<Geometry::Index> aux_indices;
+		submesh->mSharedVertexBuffer = true;
+		submesh->mIndexCount = vecfaces.size()*3;
+		submesh->mIndex=new Geometry::Index[submesh->mIndexCount];
+
+		vertex_arranger.SetCurrentSubMesh(i);
+		
+		for (std::vector<face_t>::const_iterator it=vecfaces.begin(); it!=vecfaces.end(); it++,j++)
+		{
+			const face_t & auxface = *it;
+
+			vertex_arranger.AddFace(auxface.v1,auxface.v2,auxface.v3,
+									auxface.t1,auxface.t2,auxface.t3,
+									auxface.n1,auxface.n2,auxface.n3);
+		}			
+	}
+
+	vertex_arranger.Arrange(vertices,normals,texcoords);
+}
+
Index: /GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoMeshSaver.cpp
===================================================================
--- /GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoMeshSaver.cpp	(revision 1083)
+++ /GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoMeshSaver.cpp	(revision 1083)
@@ -0,0 +1,846 @@
+/*==========================================================================
+ *	(C) 2005 Universitat Jaume I
+ *==========================================================================
+ *	PROYECT:	GAME TOOLS
+ *==========================================================================*/
+/*	CONTENT:	
+ *
+ *
+ *	@file	GeoMeshSaver.cpp
+ *==========================================================================*/
+#include	<GeoMeshSaver.h>
+
+using	namespace	Geometry;
+using	namespace	std;
+
+//---------------------------------------------------------------------------
+//		Public:
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+//	Constructors.
+//---------------------------------------------------------------------------
+GeoMeshSaver::GeoMeshSaver()
+{
+	leavesSubMesh	=	-1;
+	leavesVB			=	NULL;
+	numindices		=	0;
+	indices				=	NULL;
+}
+
+//---------------------------------------------------------------------------
+//	Destroyer.
+//---------------------------------------------------------------------------
+GeoMeshSaver::~GeoMeshSaver()
+{
+	delete	mGeoMesh;
+}
+
+//---------------------------------------------------------------------------
+//	Saves a Mesh into a file.
+//---------------------------------------------------------------------------
+int	GeoMeshSaver::save(Mesh	*geoMesh,	const	char	*fileNameMesh)
+{
+	int			size;
+	String	name(fileNameMesh);
+
+	mGeoMesh	=	new Mesh();
+
+	//	Set the mesh.
+	*mGeoMesh	=	*geoMesh;
+
+	//	Debug.
+	cout	<<	endl
+				<<	endl
+				<<	"-----------------------------------"
+				<<	endl
+				<<	"\t SAVE MESH"
+				<<	endl
+				<<	"-----------------------------------"
+				<<	endl
+				<<	endl;
+
+	//	Unnormalize geometry model.
+	unnormalizeModel(mGeoMesh);
+
+	if (leavesSubMesh>-1 && leavesVB)
+	{
+		Vector3 bmax(geoMesh->mMeshBounds.maxX,geoMesh->mMeshBounds.maxY,geoMesh->mMeshBounds.maxZ);
+		Vector3 bmin(geoMesh->mMeshBounds.minX,geoMesh->mMeshBounds.minY,geoMesh->mMeshBounds.minZ);
+		Vector3 center = (bmax+bmin)*0.5f;
+		float scale = geoMesh->mMeshBounds.scaleFactor;
+		
+		mGeoMesh->mSubMesh[leavesSubMesh].mSharedVertexBuffer=false;
+		mGeoMesh->mSubMesh[leavesSubMesh].mStripCount=0;
+		mGeoMesh->mSubMesh[leavesSubMesh].mIndexCount=numindices;
+		int icount = mGeoMesh->mSubMesh[leavesSubMesh].mIndexCount;
+		mGeoMesh->mSubMesh[leavesSubMesh].mIndex=new Index[icount];
+		for (int i=0; i<icount; i++)
+			mGeoMesh->mSubMesh[leavesSubMesh].mIndex[i]=indices[i];
+
+		mGeoMesh->mSubMesh[leavesSubMesh].mType=GEO_TRIANGLE_LIST;
+		mGeoMesh->mSubMesh[leavesSubMesh].mVertexBuffer=new VertexBuffer();
+		mGeoMesh->mSubMesh[leavesSubMesh].mVertexBuffer->mVertexInfo=VERTEX_POSITION;
+		mGeoMesh->mSubMesh[leavesSubMesh].mVertexBuffer->mVertexCount=leavesVB->mVertexCount;;
+		int vcount = mGeoMesh->mSubMesh[leavesSubMesh].mVertexBuffer->mVertexCount;
+		mGeoMesh->mSubMesh[leavesSubMesh].mVertexBuffer->mPosition=new Vector3[vcount];
+		mGeoMesh->mSubMesh[leavesSubMesh].mVertexBuffer->mNormal=new Vector3[vcount];
+		mGeoMesh->mSubMesh[leavesSubMesh].mVertexBuffer->mTexCoords=new Vector2[vcount];
+		for (int i=0; i<vcount; i++)
+		{
+			mGeoMesh->mSubMesh[leavesSubMesh].mVertexBuffer->mPosition[i].x = leavesVB->mPosition[i].x / scale + center.x;
+			mGeoMesh->mSubMesh[leavesSubMesh].mVertexBuffer->mPosition[i].y = leavesVB->mPosition[i].y / scale + center.y;
+			mGeoMesh->mSubMesh[leavesSubMesh].mVertexBuffer->mPosition[i].z = leavesVB->mPosition[i].z / scale + center.z;
+			mGeoMesh->mSubMesh[leavesSubMesh].mVertexBuffer->mNormal[i].x = leavesVB->mNormal[i].x;
+			mGeoMesh->mSubMesh[leavesSubMesh].mVertexBuffer->mNormal[i].y = leavesVB->mNormal[i].y;
+			mGeoMesh->mSubMesh[leavesSubMesh].mVertexBuffer->mNormal[i].z = leavesVB->mNormal[i].z;
+			mGeoMesh->mSubMesh[leavesSubMesh].mVertexBuffer->mTexCoords[i].x = leavesVB->mTexCoords[i].x;
+			mGeoMesh->mSubMesh[leavesSubMesh].mVertexBuffer->mTexCoords[i].y = leavesVB->mTexCoords[i].y;
+		}
+	}
+
+	//	Open the file.
+	mSerializer	=	new	Serializer(name,Serializer::WRITE);
+
+	//	Write the file header.
+	writeFileHeader();
+
+	//	Write the mesh data.
+	writeMesh(mGeoMesh);
+
+	size	=	mSerializer->GetSize();
+	
+	//	Close the file.
+	delete	mSerializer;
+	
+	//	Return the number of bytes written.
+	return	size;
+}
+
+//------------------------------------------
+//		Private:
+//------------------------------------------
+
+//	Write the main mesh.
+void	GeoMeshSaver::writeMesh(Mesh	*geoMesh)
+{
+	// Header
+	writeChunkHeader(M_MESH, calcMeshSize(geoMesh));
+
+	//	Debug.
+	cout	<<	"		M_MESH"
+				<<	endl;
+
+	//	Write the skeletally animated flag.
+	writeBools(geoMesh->hasSkeleton,1);
+	
+	//	Write shared geometry.
+	if (geoMesh->mVertexBuffer->mVertexCount > 0)
+	{
+		writeGeometry(geoMesh->mVertexBuffer);
+	}
+
+	//	Write submeshes.
+	for (int i = 0;	i < geoMesh->mSubMeshCount;	i++)
+	{
+		writeSubMesh(&geoMesh->mSubMesh[i]);
+	}
+
+	// Write skeleton info if required
+	if (geoMesh->hasSkeleton)
+	{
+		// Write skeleton link
+		writeSkeletonLink(geoMesh->mSkeletonName);
+
+		// Write bone assignments
+		if (!geoMesh->mBones.empty())
+		{
+
+			for (int i = 0; i< geoMesh->mBones.size(); i++)
+			{
+				writeMeshBoneAssignment(geoMesh->mBones[i]);
+			}
+
+		}
+	}
+
+	//	Write the mesh bounds.
+	writeMeshBounds(geoMesh);
+
+	/*
+	// Write LOD data if any
+	if (pMesh->getNumLodLevels() > 1)
+	{
+	LogManager::getSingleton().logMessage("Exporting LOD information....");
+	writeLodInfo(pMesh);
+	LogManager::getSingleton().logMessage("LOD information exported.");
+
+	}
+	// Write bounds information
+	LogManager::getSingleton().logMessage("Exporting bounds information....");
+	writeBoundsInfo(pMesh);
+	LogManager::getSingleton().logMessage("Bounds information exported.");
+
+	// Write submesh name table
+	LogManager::getSingleton().logMessage("Exporting submesh name table...");
+	writeSubMeshNameTable(pMesh);
+	LogManager::getSingleton().logMessage("Submesh name table exported.");
+
+	// Write edge lists
+	if (pMesh->isEdgeListBuilt())
+	{
+	LogManager::getSingleton().logMessage("Exporting edge lists...");
+	writeEdgeList(pMesh);
+	LogManager::getSingleton().logMessage("Edge lists exported");
+	}
+	*/
+}//	End write mesh.
+
+//	Write a submesh.
+void	GeoMeshSaver::writeSubMesh(SubMesh	*geoSubMesh)
+{
+	bool						idx32bit;
+	unsigned	long	indexCount;
+	Index						*index;
+	Index						*indexBegin;
+	Index						*indexEnd;
+
+	// Header.
+	writeChunkHeader(M_SUBMESH, calcSubMeshSize(geoSubMesh));
+
+	//	Debug.
+	cout	<<	"		M_SUBMESH"
+				<<	endl;
+
+	// Material Name.
+	strcat(geoSubMesh->mMaterialName,"\n");
+	mSerializer->WriteData(geoSubMesh->mMaterialName);
+
+	// bool useSharedVertices
+	writeBools(geoSubMesh->mSharedVertexBuffer, 1);
+
+	indexCount	=	geoSubMesh->mIndexCount;
+	
+	/*
+	//	If the submesh is in triangle strips.
+	if (geoSubMesh->mType == GEO_TRIANGLE_STRIPS)
+	{
+		indexCount	+=	(2 * geoSubMesh->mStripCount)
+										-
+										2;
+	}
+	*/
+	
+	//	Write index count.
+	writeInts(indexCount, 1);
+
+	// bool indexes32Bit
+	idx32bit	=	true;
+	writeBools(idx32bit, 1);
+
+	/*
+	//	If the submesh is in triangle strips.
+	if (geoSubMesh->mType == GEO_TRIANGLE_STRIPS)
+	{
+		//	For each one of the strips.
+		for (int strip = 0; strip < geoSubMesh->mStripCount; strip++)
+		{
+			//	First index of the strip.
+			indexBegin	=	geoSubMesh->mStrip[strip];
+
+			//	If is the final strip
+			if (strip	== (geoSubMesh->mStripCount - 1))
+			{
+				//	The end of the index array.
+				indexEnd	= &geoSubMesh->mIndex[geoSubMesh->mIndexCount];
+			}
+			else
+			{
+				//	The beginning of the next strip.
+				indexEnd	= geoSubMesh->mStrip[strip + 1];
+			}
+
+			int i;
+			i	= 0;
+
+			//	Degenerate.
+			if (strip != 0)
+			{
+				writeInts(indexBegin[i], 1);
+			}
+			
+			//	For each index of the strip.
+			for (index = indexBegin; index < indexEnd; index++)
+			{
+				writeInts(indexBegin[i], 1);
+				
+				//	Increments i.
+				i++;
+			}
+
+			//	Degenerate.
+			if (strip	!= (geoSubMesh->mStripCount - 1))
+			{
+				writeInts(indexBegin[i - 1], 1);
+			}
+		}
+	}
+	//	If the submesh is in triangle list.
+	else
+	{
+	*/
+		//	Write the index array.
+		for (int i = 0; i < geoSubMesh->mIndexCount; i++)
+		{
+			writeInts(geoSubMesh->mIndex[i], 1);
+		}
+	//}
+
+	// M_GEOMETRY stream (Optional: present only if useSharedVertices = false)
+	if (!geoSubMesh->mSharedVertexBuffer)
+	{
+		writeGeometry(geoSubMesh->mVertexBuffer);
+	}
+
+	// Operation type
+	writeSubMeshOperation(geoSubMesh);
+
+	// Bone assignments.
+	if (!geoSubMesh->mBones.empty())
+	{
+		for (int i = 0; i < geoSubMesh->mBones.size(); i++)
+		{
+			writeSubMeshBoneAssignment(geoSubMesh->mBones[i]);
+		}
+	}
+}
+
+//	Write the submesh operation chunk and data.
+void GeoMeshSaver::writeSubMeshOperation(const	SubMesh	*geoSubMesh)
+{
+	unsigned 	short opType;
+	unsigned	long	size;
+
+	size	=	CHUNK_OVERHEAD_SIZE	+	sizeof(unsigned	short);
+	
+	// Header
+	writeChunkHeader(M_SUBMESH_OPERATION, size);
+
+	//	Debug.
+	cout	<<	"		M_SUBMESH_OPERATION"
+				<<	endl;
+
+	//	If the mesh is in triangle strips.
+	if (geoSubMesh->mType	==	GEO_TRIANGLE_STRIPS)
+	{
+		opType	=	5;
+	}
+	//	If the mesh is in triangle list.
+	else
+	{
+		opType	=	4;
+	}
+	
+	writeShorts(opType, 1);
+}
+
+//	Write geometry.
+void	GeoMeshSaver::writeGeometry(VertexBuffer	*vertexBuffer)
+{
+	unsigned	short	element;
+	unsigned	long	size;
+	unsigned	short	buffer_count;
+
+	buffer_count	=	3;
+	
+	//	Calculate the size in bytes of the geometry chunk.
+	size	=	calcGeometrySize(vertexBuffer);
+		
+	//	Header.
+	//
+	//	Write the M_GEOMETRY header.
+	writeChunkHeader(M_GEOMETRY, size);
+
+	//	Debug.
+	cout	<<	"		M_GEOMETRY"
+				<<	endl;
+
+	writeInts(vertexBuffer->mVertexCount,1);
+
+	//	Vertex declaration.
+	//	Calculate the size of vertex declaration.
+	size	=	CHUNK_OVERHEAD_SIZE
+					+
+					buffer_count
+					*
+					(CHUNK_OVERHEAD_SIZE	+	(sizeof(unsigned short)	*	5));
+
+	//	Write the vertex declaration header.
+	writeChunkHeader(	M_GEOMETRY_VERTEX_DECLARATION,size);
+
+	//	Debug.
+	cout	<<	"		M_GEOMETRY_VERTEX_DECLARATION"
+				<<	endl;
+
+	//	Obtain the size of the vertex element chunk.
+	size	=	CHUNK_OVERHEAD_SIZE	+	(sizeof(unsigned short)	*	5);
+
+	//	Positions.
+	//	Write the vertex element header for position.
+	writeChunkHeader(	M_GEOMETRY_VERTEX_ELEMENT,size);
+
+	//	Debug.
+	cout	<<	"		M_GEOMETRY_VERTEX_ELEMENT"
+				<<	endl;
+
+	element	=	0;
+	writeShorts(element,1);
+
+	element	=	VET_FLOAT3;
+	writeShorts(element,1);
+	
+	element	=	VES_POSITION;
+	writeShorts(element,1);
+	
+	element	=	0;
+	writeShorts(element,1);
+	
+	element	=	0;
+	writeShorts(element,1);
+
+	//	Normals.
+	//	Write the vertex element header for position.
+	writeChunkHeader(	M_GEOMETRY_VERTEX_ELEMENT,size);
+	
+	//	Debug.
+	cout	<<	"		M_GEOMETRY_VERTEX_ELEMENT"
+				<<	endl;
+
+	element	=	1;
+	writeShorts(element,1);
+	
+	element	=	VET_FLOAT3;
+	writeShorts(element,1);
+	
+	element	=	VES_NORMAL;
+	writeShorts(element,1);
+	
+	element	=	0;
+	writeShorts(element,1);
+	
+	element	=	0;
+	writeShorts(element,1);
+
+	//	Textures.
+	//	Write the vertex element header for position.
+	writeChunkHeader(M_GEOMETRY_VERTEX_ELEMENT,size);
+	
+	//	Debug.
+	cout	<<	"		M_GEOMETRY_VERTEX_ELEMENT"
+				<<	endl;
+
+	element	=	2;
+	writeShorts(element,1);
+	
+	element	=	VET_FLOAT2;
+	writeShorts(element,1);
+	
+	element	=	VES_TEXTURE_COORDINATES;
+	writeShorts(element,1);
+	
+	element	=	0;
+	writeShorts(element,1);
+	
+	element	=	0;
+	writeShorts(element,1);
+
+	//	Obtain the size for vertex buffer header for positons.
+	size	=	(2	*	CHUNK_OVERHEAD_SIZE)	+	(2	*	sizeof(unsigned short));
+
+	//	Write the vertex buffer header for positions.
+	writeChunkHeader(M_GEOMETRY_VERTEX_BUFFER,	size);
+
+	//	Debug.
+	cout	<<	"		M_GEOMETRY_VERTEX_BUFFER"
+				<<	endl;
+
+	element	=	0;
+	writeShorts(element,1);
+	
+	element	=	12;
+	writeShorts(element,1);
+
+	//	Obtain the size for the vertex buffer data header for positions.
+	size	=	CHUNK_OVERHEAD_SIZE
+					+
+					((sizeof(float)	*	3)	*	vertexBuffer->mVertexCount);
+
+	//	Write the vertex buffer data header for positions.
+	writeChunkHeader(M_GEOMETRY_VERTEX_BUFFER_DATA,	size);
+
+	//	Debug.
+	cout	<<	"		M_GEOMETRY_VERTEX_BUFFER_DATA"
+				<<	endl;
+
+	//	Write all the positions coords.
+	mSerializer->WriteArray(vertexBuffer->mPosition,
+													vertexBuffer->mVertexCount);
+
+	//	Obtain the size for vertex buffer header for normals.
+	size	=	(2	*	CHUNK_OVERHEAD_SIZE)	+	(2	*	sizeof(unsigned short));
+
+	//	Write the vertex buffer header.
+	writeChunkHeader(	M_GEOMETRY_VERTEX_BUFFER,	size);
+
+	//	Debug.
+	cout	<<	"		M_GEOMETRY_VERTEX_BUFFER"
+				<<	endl;
+
+	element	=	1;
+	writeShorts(element,1);
+	
+	element	=	12;
+	writeShorts(element,1);
+
+	//	Obtain the size for the vertex buffer data header for normals.
+	size	=	CHUNK_OVERHEAD_SIZE
+					+
+					((sizeof(float)	*	3)	*	vertexBuffer->mVertexCount);
+
+	//	Write the vertex buffer data header for normals.
+	writeChunkHeader(M_GEOMETRY_VERTEX_BUFFER_DATA,	size);
+
+	//	Debug.
+	cout	<<	"		M_GEOMETRY_VERTEX_BUFFER_DATA"
+				<<	endl;
+
+	//	Write all the normals coords.
+	mSerializer->WriteArray(vertexBuffer->mNormal,
+													vertexBuffer->mVertexCount);
+
+	//	Obtain the size for vertex buffer header for textures.
+	size	=	(2	*	CHUNK_OVERHEAD_SIZE)	+	(2	*	sizeof(unsigned short));
+
+	//	Write the vertex buffer header for textures.
+	writeChunkHeader(M_GEOMETRY_VERTEX_BUFFER,	size);
+
+	//	Debug.
+	cout	<<	"		M_GEOMETRY_VERTEX_BUFFER"
+				<<	endl;
+
+	element	=	2;
+	writeShorts(element,1);
+	
+	element	=	8;
+	writeShorts(element,1);
+
+	//	Obtain the size for the vertex buffer data header for textures.
+	size	=	CHUNK_OVERHEAD_SIZE
+					+
+					((sizeof(float)	*	2)	*	vertexBuffer->mVertexCount);
+
+	//	Write the vertex buffer data header for textures.
+	writeChunkHeader(M_GEOMETRY_VERTEX_BUFFER_DATA,	size);
+
+	//	Debug.
+	cout	<<	"		M_GEOMETRY_VERTEX_BUFFER_DATA"
+				<<	endl;
+
+	//	Write all the texture coords.
+	mSerializer->WriteArray(vertexBuffer->mTexCoords,
+													vertexBuffer->mVertexCount);
+}
+
+//	Write Mesh Bounds.
+void	GeoMeshSaver::writeMeshBounds(Mesh	*geoMesh)
+{
+	size_t	size;
+
+	size	=	CHUNK_OVERHEAD_SIZE
+					+
+					(sizeof(float)	*	7);
+
+	writeChunkHeader(M_MESH_BOUNDS,	size);
+
+	//	Debug.
+	cout	<<	"		M_MESH_BOUNDS"
+				<<	endl;
+
+	writeFloats(geoMesh->mMeshBounds.minX,1);
+	writeFloats(geoMesh->mMeshBounds.minY,1);
+	writeFloats(geoMesh->mMeshBounds.minZ,1);
+	writeFloats(geoMesh->mMeshBounds.maxX,1);
+	writeFloats(geoMesh->mMeshBounds.maxY,1);
+	writeFloats(geoMesh->mMeshBounds.maxZ,1);
+	writeFloats(geoMesh->mMeshBounds.radius,1);
+}
+
+//	Calculate the mesh size in bytes.
+size_t GeoMeshSaver::calcMeshSize(const Mesh	*geoMesh)
+{
+	size_t size = CHUNK_OVERHEAD_SIZE;
+
+	// Number of shared vertices
+	size += sizeof(uint32);
+
+	// Geometry
+	if (geoMesh->mVertexBuffer->mVertexCount > 0)
+	{
+		size += calcGeometrySize(geoMesh->mVertexBuffer);
+	}
+
+	// Submeshes
+	for (unsigned short i = 0; i < geoMesh->mSubMeshCount; ++i)
+	{
+		size += calcSubMeshSize(&geoMesh->mSubMesh[i]);
+	}
+
+	//	Mesh Bounds size added.
+	size	+=	CHUNK_OVERHEAD_SIZE
+						+
+						(sizeof(float)	*	7);
+
+	// Skeleton link
+	if (geoMesh->hasSkeleton)
+	{
+		size +=	calcSkeletonLinkSize(geoMesh);
+	}
+
+	/*
+	// Submesh name table
+	size += calcSubMeshNameTableSize(geoMesh);
+
+	// Edge list
+	if (geoMesh->isEdgeListBuilt())
+	{
+		size += calcEdgeListSize(geoMesh);
+	}
+	*/
+	
+	return size;
+}
+
+//	Calc the size in bytes for the submesh.
+size_t GeoMeshSaver::calcSubMeshSize(const SubMesh	*geoSubMesh)
+{
+	size_t size = CHUNK_OVERHEAD_SIZE;
+
+	// Material name
+	size += strlen(geoSubMesh->mMaterialName);
+
+	// bool useSharedVertices
+	size += sizeof(bool);
+	// unsigned int indexCount
+	size += sizeof(unsigned int);
+	// bool indexes32bit
+	size += sizeof(bool);
+
+	// unsigned int* faceVertexIndices 
+	size += sizeof(unsigned int) * geoSubMesh->mIndexCount;
+
+	// Geometry
+	if (!geoSubMesh->mSharedVertexBuffer)
+	{
+		size += calcGeometrySize(geoSubMesh->mVertexBuffer);
+	}
+
+	return size;
+}
+
+//	Calculate the geometry size in bytes.
+size_t GeoMeshSaver::calcGeometrySize(const VertexBuffer* vertexBuffer)
+{
+	unsigned	long		size;
+	unsigned	long		buffer_count;
+
+	//	and another for normals.
+	buffer_count	=	3;
+
+	//	Calculate the size of the Geometry chunk.
+	size	=	CHUNK_OVERHEAD_SIZE	+	sizeof(unsigned int);
+	size	=	size
+					+
+					CHUNK_OVERHEAD_SIZE
+					+
+					buffer_count
+					*
+					(CHUNK_OVERHEAD_SIZE	+	(sizeof(unsigned short)	*	5));
+	size	=	size
+					+
+					buffer_count
+					*
+					(	(CHUNK_OVERHEAD_SIZE		*	2)
+						+
+						(sizeof(unsigned short)	*	2)
+						+
+						vertexBuffer->mVertexCount
+					);
+
+	return size;
+}
+
+//	Calculate the skeleton link size in bytes.
+size_t	GeoMeshSaver::calcSkeletonLinkSize(const Mesh	*geoMesh)
+{
+	size_t	size	=		CHUNK_OVERHEAD_SIZE;
+	size 					+=	strlen(geoMesh->mSkeletonName);
+
+	//	Debug.
+	cout	<<	"Length Skeleton Link: "
+				<<	strlen(geoMesh->mSkeletonName)
+				<<	endl;
+
+	return	size;
+}
+
+//	Write the file header.
+void GeoMeshSaver::writeFileHeader(void)
+{
+	String	mesh_version("[MeshSerializer_v1.30]\n");
+	
+	writeShorts(M_HEADER, 1);
+
+	writeString(mesh_version);
+
+}
+
+//	Write a header chunk given.
+void GeoMeshSaver::writeChunkHeader(unsigned short	id,
+																		unsigned long		size)
+{
+	mSerializer->WriteData(&id,sizeof(unsigned short),1);
+	mSerializer->WriteData(&size,sizeof(unsigned long),1);
+}
+
+//	Write integers into the file.
+void	GeoMeshSaver::writeInts(unsigned long	id,
+															unsigned long	count)
+{
+	mSerializer->WriteData(&id,sizeof(id),count);
+}
+
+//	Write shorts into the file
+void	GeoMeshSaver::writeShorts(unsigned short	id,
+																unsigned long		count)
+{
+	mSerializer->WriteData(&id,sizeof(id),count);
+}
+
+//	Write float into the file.
+void	GeoMeshSaver::writeFloats(float						id,
+																unsigned long		count)
+{
+	mSerializer->WriteData(&id,sizeof(id),count);
+}
+
+//	Write a string into the file.
+void GeoMeshSaver::writeString(const	String	&string)
+{
+	mSerializer->WriteData(string);
+}
+
+//	Write booleans into the file.
+void	GeoMeshSaver::writeBools(	const bool id,
+																unsigned	long		count)
+{
+	mSerializer->WriteData(&id,sizeof(bool),count);
+}
+
+void GeoMeshSaver::writeSkeletonLink(const String& skelName)
+{	
+	writeChunkHeader(M_MESH_SKELETON_LINK, calcSkeletonLinkSize(mGeoMesh));
+
+	//	Debug.
+	cout	<<	"		M_MESH_SKELETON_LINK"
+				<<	endl;
+
+    writeString(skelName);
+}
+
+void GeoMeshSaver::writeMeshBoneAssignment(const VertexBoneAssignment& assign)
+{
+	size_t size = CHUNK_OVERHEAD_SIZE + sizeof(unsigned int) + sizeof(unsigned short)+ sizeof(float);
+
+	writeChunkHeader(M_MESH_BONE_ASSIGNMENT, size);
+
+	// unsigned int vertexIndex;
+	writeInts(assign.vertexIndex, 1);
+	// unsigned short boneIndex;
+	writeShorts(assign.boneIndex, 1);
+	// float weight;
+	writeFloats(assign.weight, 1);
+}
+
+void GeoMeshSaver::writeSubMeshBoneAssignment(const VertexBoneAssignment& assign)
+{
+	size_t size = CHUNK_OVERHEAD_SIZE + sizeof(unsigned int) + sizeof(unsigned short)+ sizeof(float);
+
+	writeChunkHeader(M_SUBMESH_BONE_ASSIGNMENT, size);
+
+	// unsigned int vertexIndex;
+	writeInts(assign.vertexIndex, 1);
+	// unsigned short boneIndex;
+	writeShorts(assign.boneIndex, 1);
+	// float weight;
+	writeFloats(assign.weight, 1);
+}
+
+//	unnormalize geometry model.
+void	GeoMeshSaver::unnormalizeModel(Mesh	*geoMesh)
+{
+	float	maxx;
+	float	maxy;
+	float	maxz;
+	float	minx;
+	float	miny;
+	float	minz;
+	float	cx;
+	float	cy;
+	float	cz;
+	float	scale;
+	
+	VertexBuffer	*vertex_buffer;
+
+	maxx	=	geoMesh->mMeshBounds.maxX;
+	maxy	=	geoMesh->mMeshBounds.maxY;
+	maxz	=	geoMesh->mMeshBounds.maxZ;
+	minx	=	geoMesh->mMeshBounds.minX;
+	miny	=	geoMesh->mMeshBounds.minY;
+	minz	=	geoMesh->mMeshBounds.minZ;
+	scale	=	geoMesh->mMeshBounds.scaleFactor;
+	
+	//	Calculate center of the model.
+	cx = (maxx + minx) / 2.0;
+	cy = (maxy + miny) / 2.0;
+	cz = (maxz + minz) / 2.0;
+
+	//	Translate around center then scale.
+	//	For each submesh.
+
+	bool sharedScaled=false;
+
+	for (int submesh = 0; submesh < geoMesh->mSubMeshCount; submesh++)
+	{
+		//	Gets the actual submesh.
+		vertex_buffer	=	geoMesh->mSubMesh[submesh].mVertexBuffer;
+
+		if (geoMesh->mSubMesh[submesh].mSharedVertexBuffer && sharedScaled)
+			continue;
+			
+		//	For each index of the strip.
+		for (int i = 0; i < vertex_buffer->mVertexCount; i++)
+		{
+			vertex_buffer->mPosition[i].x /= scale;
+			vertex_buffer->mPosition[i].y /= scale;
+			vertex_buffer->mPosition[i].z /= scale;
+			vertex_buffer->mPosition[i].x += cx;
+			vertex_buffer->mPosition[i].y += cy;
+			vertex_buffer->mPosition[i].z += cz;
+		}
+
+		//	If is a shared vertex Buffer.
+		if (geoMesh->mSubMesh[submesh].mSharedVertexBuffer)
+			sharedScaled=true;
+	}
+}
+
Index: /GTP/trunk/Lib/Geom/shared/GTGeometry/GTGeometry.vcproj
===================================================================
--- /GTP/trunk/Lib/Geom/shared/GTGeometry/GTGeometry.vcproj	(revision 1071)
+++ /GTP/trunk/Lib/Geom/shared/GTGeometry/GTGeometry.vcproj	(revision 1083)
@@ -130,4 +130,10 @@
 			</File>
 			<File
+				RelativePath=".\src\GeoMeshLoader.cpp">
+			</File>
+			<File
+				RelativePath=".\src\GeoMeshSaver.cpp">
+			</File>
+			<File
 				RelativePath=".\src\GeoMeshSimplifier.cpp">
 			</File>
@@ -370,4 +376,10 @@
 			<File
 				RelativePath=".\include\GeoMesh.h">
+			</File>
+			<File
+				RelativePath=".\include\GeoMeshLoader.h">
+			</File>
+			<File
+				RelativePath=".\include\GeoMeshSaver.h">
 			</File>
 			<File
Index: /GTP/trunk/Lib/Geom/shared/GeoTool/include/GeoMeshViewUI.h
===================================================================
--- /GTP/trunk/Lib/Geom/shared/GeoTool/include/GeoMeshViewUI.h	(revision 1078)
+++ /GTP/trunk/Lib/Geom/shared/GeoTool/include/GeoMeshViewUI.h	(revision 1083)
@@ -372,7 +372,7 @@
 
 	//	Initialize the lodstripslibrary for visualization.
-	void	setLodStripsLibrary(const Geometry::LodStripsLibraryData &, Mesh	*geomesh);
+	void	setLodStripsLibrary(const Geometry::LodStripsLibraryData *, Mesh	*geomesh);
 	//	Initialize the lodtreelibrary for visualization.
-	void	setLodTreesLibrary(const Geometry::LodStripsLibraryData &, const Geometry::TreeSimplificationSequence &, Mesh	*geomesh, uint32 ileafSubMesh);
+	void	setLodTreesLibrary(const Geometry::LodStripsLibraryData *, const Geometry::TreeSimplificationSequence *, Mesh	*geomesh, uint32 ileafSubMesh);
 
 	// Indentify the mesh of leaves.
Index: P/trunk/Lib/Geom/shared/GeoTool/include/GeoMeshLoader.h
===================================================================
--- /GTP/trunk/Lib/Geom/shared/GeoTool/include/GeoMeshLoader.h	(revision 1078)
+++ 	(revision )
@@ -1,214 +1,0 @@
-/*	==========================================================================
- *	(C) 2005 Universitat Jaume I
- *	==========================================================================
- *	PROYECT:	GAME TOOLS
- *	==========================================================================
- *	CONTENT:	
- *
- *
- *	@file	GeoMeshLoader.h
- *===========================================================================*/
-#ifndef __GEO_MESH_LOADER__
-#define __GEO_MESH_LOADER__
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string>
-#include <vector>
-#include <memory.h>
-#include <time.h>
-#include <iostream>
-#include <iomanip>
-#include "GeoBase.h"
-#include "GeoMesh.h"
-#include "GeoLodStripsLibrary.h"
-#include "GeoLodTreeLibrary.h"
-
-namespace Geometry 
-{
-	const	unsigned	short	CHUNK_OVERHEAD_SIZE	= sizeof(unsigned short)
-																							+
-																							sizeof(unsigned long);
-
-	const unsigned	short M_HEADER											= 0x1000;
-	const unsigned	short M_MESH												= 0x3000;
-	const unsigned	short M_SUBMESH											= 0x4000; 
-	const unsigned	short M_SUBMESH_OPERATION						= 0x4010;
-	const unsigned	short M_SUBMESH_BONE_ASSIGNMENT			= 0x4100;
-	const unsigned	short M_GEOMETRY										= 0x5000;
-	const unsigned	short M_GEOMETRY_VERTEX_DECLARATION = 0x5100;
-	const unsigned	short M_GEOMETRY_VERTEX_ELEMENT			= 0x5110;
-	const unsigned	short M_GEOMETRY_VERTEX_BUFFER			= 0x5200;
-	const unsigned	short M_GEOMETRY_VERTEX_BUFFER_DATA = 0x5210;
-	const unsigned	short M_MESH_SKELETON_LINK					= 0x6000;
-	const unsigned	short M_MESH_BONE_ASSIGNMENT				= 0x7000;
-	const unsigned	short M_MESH_LOD										=	0x8000;
-	const unsigned	short M_MESH_LOD_USAGE							=	0x8100;
-	const unsigned	short M_MESH_LOD_MANUAL							=	0x8110;
-	const unsigned	short M_MESH_LOD_GENERATED					=	0x8120;
-	const unsigned	short M_MESH_BOUNDS									=	0x9000;
-	const unsigned	short M_SUBMESH_NAME_TABLE					=	0xA000;
-	const unsigned	short	M_SUBMESH_NAME_TABLE_ELEMENT	=	0xA100;
-	const unsigned	short M_EDGE_LISTS									=	0xB000;
-	const unsigned	short M_EDGE_LIST_LOD								=	0xB100;
-	const unsigned	short M_EDGE_GROUP									= 0xB110;
-	const	unsigned	short	SUBMESH_COUNT									=	0;
-	const	unsigned	short	GEOMESH_BUILD									=	1;
-	
-	enum VertexElementType
-	{
-		VET_FLOAT1,
-		VET_FLOAT2,
-		VET_FLOAT3,
-		VET_FLOAT4,
-		VET_COLOUR,
-		VET_SHORT1,
-		VET_SHORT2,
-		VET_SHORT3,
-		VET_SHORT4,
-		VET_UBYTE4
-	};
-
-	enum VertexElementSemantic
-	{
-		/// Position, 3 reals per vertex
-		VES_POSITION = 1,
-		/// Blending weights
-		VES_BLEND_WEIGHTS = 2,
-		/// Blending indices
-		VES_BLEND_INDICES = 3,
-		/// Normal, 3 reals per vertex
-		VES_NORMAL = 4,
-		/// Diffuse colours
-		VES_DIFFUSE = 5,
-		/// Specular colours
-		VES_SPECULAR = 6,
-		/// Texture coordinates
-		VES_TEXTURE_COORDINATES = 7,
-		/// Binormal (Y axis if normal is Z)
-		VES_BINORMAL = 8,
-		/// Tangent (X axis if normal is Z)
-		VES_TANGENT = 9
-	};
-
-	/*
-	//	Bounding Box data.
-	struct	GeometryBounds
-	{
-		float	minx;
-		float	miny;
-		float	minz;
-		float	maxx;
-		float	maxy;
-		float	maxz;
-		float	radius;
-	};
-	*/
-	
-	/// Mesh class interface
-	class GeoMeshLoader
-	{
-		private:
-			
-			Mesh						*geoMesh;
-			size_t					mFileSize;
-			unsigned	int		numVertices;
-			unsigned	long	long_actual;
-			size_t					currentSubMesh;
-			bool						mError;
-
-			struct GeometryElement
-			{
-				unsigned short offset;
-				unsigned short semantic;
-				unsigned short type;
-				unsigned short index;
-			};
-
-			struct GT
-			{
-				unsigned short source; //bindIndex
-				std::vector <GeometryElement> list;
-			};
-
-			std::vector <GT> list;
-
-			//	Jump a chunk.
-			void jumpChunk(FILE	*f);
-
-			//	Read a chunk.
-			unsigned short readChunk(FILE	*f);
-
-			//	Read geometry vertex element.
-			void readGeometryVertexElement(FILE	*f, Mesh	*geoMesh);
-
-			//	Read geometry vertex declaration.
-			void readGeometryVertexDeclaration(FILE	*f, Mesh	*geoMesh);
-
-			//	Read geometry vertex buffer.
-			void readGeometryVertexBuffer(FILE		*f,
-																		Mesh		*geoMesh,
-																		int 		option);
-
-			//	Read geometry.
-			void readGeometry(FILE	*f, Mesh	*geoMesh, int option);
-
-			//	Read a submesh operation.
-			void readSubMeshOperation(FILE	*f, Mesh	*geoMesh, int option);
-
-			//	Read a submesh.
-			void readSubMesh(FILE	*f, Mesh	*geoMesh, int option);
-
-			//	Read skeleton name.
-			void readSkeletonLink(FILE	*f, Mesh	*geoMesh, int option);
-
-			//	Read bone assignment.
-			void readMeshBoneAssignment(FILE	*f, Mesh	*geoMesh, int option);
-
-			//	Read bone assignment.
-			void readSubMeshBoneAssignment(FILE	*f, SubMesh	*geoSubMesh, int option);
-
-			//	Read a mesh lod information.
-			void readMeshLodInfo(FILE	*f, Mesh	*geoMesh);
-
-			//	Read a submesh name table.
-			void readSubMeshNameTable(FILE	*f, Mesh	*geoMesh);
-
-			//	Read a mesh file.
-			void readMesh(FILE	*f, Mesh	*geoMesh, int option);
-
-			//	Read bounding box settings.
-			void	readMeshBounds(FILE	*f, Mesh	*geoMesh,	int	option);
-
-			//	Writes the strips list.
-			SubMesh* GeoMeshLoader::BuildStripsGeoSubMesh(SubMesh	*geoSubMesh);
-
-			//	Remove degenerate triangles of a submesh given.
-			SubMesh	*	removeDegenerateTriangles(SubMesh	*geoSubMesh);
-			
-			//	Sets coods between -1 and 1.
-			void	normalizeModel(Mesh	*geoMesh);
-
-			// Imports an OBJ object
-			void importOBJ(FILE *f, Mesh *geoMesh);
-
-		public:
-
-			//	Constructor.
-			GeoMeshLoader();
-
-			//	Destroyer.
-			~GeoMeshLoader();
-
-			//	Loads a Mesh file.
-			Mesh* load(char	*fileNameMesh);
-
-			//	Get the size in bytes of the file.
-			size_t	getFileSize();
-
-			Geometry::LodStripsLibraryData lodstripsdata;
-			Geometry::TreeSimplificationSequence treesimpseq;
-	};
-}
-#endif
-
Index: P/trunk/Lib/Geom/shared/GeoTool/include/GeoMeshSaver.h
===================================================================
--- /GTP/trunk/Lib/Geom/shared/GeoTool/include/GeoMeshSaver.h	(revision 1017)
+++ 	(revision )
@@ -1,124 +1,0 @@
-/*	==========================================================================
- *	(C) 2005 Universitat Jaume I
- *	==========================================================================
- *	PROYECT:	GAME TOOLS
- *	========================================================================*/
-/*	CONTENT:	
- *
- *
- *	@file	GeoMeshSaver.h
- *	========================================================================*/
-
-#ifndef	__GEO_MESH_SAVER__
-#define	__GEO_MESH_SAVER__
-
-#include	<GeoMeshLoader.h>
-
-namespace Geometry 
-{
-	//	Saves a Mesh.
-	class	GeoMeshSaver
-	{
-		private:
-			//	The mesh to write.
-			Mesh	*mGeoMesh;
-			
-			//	Mesh Bounds.
-			//GeometryBounds	mMeshBounds;
-			
-			//	Write in the file.
-			Serializer	*mSerializer;
-
-			//	Flag that indicate if the mesh 
-			//	is skeletally animated or not.
-			bool	mSkeletallyAnimated;
-			
-			//	Write the main mesh.
-			void	writeMesh(Mesh	*geoMesh);
-
-			//	Write a submesh.
-			void	writeSubMesh(SubMesh	*geoSubMesh);
-
-			// Operation type
-			void	writeSubMeshOperation(const	SubMesh	*geoSubMesh);
-			
-			//	Write geometry.
-			void	writeGeometry(VertexBuffer	*vertexBuffer);
-
-			//	Write Mesh Bounds.
-			void	writeMeshBounds(Mesh	*geoMesh);
-			
-			//	Calculate the mesh size in bytes.
-			size_t	calcMeshSize(const Mesh	*geoMesh);
-
-			//	Calculate the size in bytes for the submesh.
-			size_t	calcSubMeshSize(const SubMesh	*geoSubMesh);
-
-			//	Calculate the geometry size in bytes.
-			size_t	calcGeometrySize(const VertexBuffer* vertexBuffer);
-
-			//	Calculate the skeleton link size in bytes.
-			size_t	calcSkeletonLinkSize(const Mesh	*geoMesh);
-
-			//	Write the file header.
-			void	writeFileHeader(void);
-
-			//	Write a header chunk given.
-			void	writeChunkHeader(	unsigned short	id,
-															unsigned long		count);
-
-			//	Write integers into the file.
-			void	writeInts(unsigned long	id,
-											unsigned long	size);
-
-			//	Write shorts into the file
-			void	writeShorts(unsigned short	id,
-												unsigned long		count);
-
-			//	Write float into the file.
-			void	writeFloats(float						id,
-												unsigned long		count);
-
-			//	Write a string into the file.
-			void	writeString(const	String	&string);
-
-			//	Write booleans into the file.
-			void	writeBools(	const bool id,
-												unsigned	long		count);
-
-			//	Write skeleton name.
-			void	writeSkeletonLink(const	String	&string);
-
-			void	writeMeshBoneAssignment(const VertexBoneAssignment& assign);
-
-			void	writeSubMeshBoneAssignment(const VertexBoneAssignment& assign);
-
-			//	unnormalize geometry model.
-			void	unnormalizeModel(Mesh	*geoMesh);
-			
-		public:
-
-			//	Constructors.
-			GeoMeshSaver();
-
-			//	Destroyer.
-			~GeoMeshSaver();
-
-			//	Sets the material of the mesh.
-			void	setMaterialName(String	materialName);
-
-			//	Gets the material of the mesh.
-			String	getMaterialName();
-			
-			//	Saves a Mesh into a file.
-			int	save(Mesh	*geoMesh,	const	char	*fileNameMesh);
-
-			// temporal members used to tweak the lodtree leaf submesh
-			int leavesSubMesh;
-			VertexBuffer *leavesVB;
-			Index *indices;
-			int numindices;
-	};
-}
-#endif
-
Index: /GTP/trunk/Lib/Geom/shared/GeoTool/src/GeoMeshViewUI.cpp
===================================================================
--- /GTP/trunk/Lib/Geom/shared/GeoTool/src/GeoMeshViewUI.cpp	(revision 1078)
+++ /GTP/trunk/Lib/Geom/shared/GeoTool/src/GeoMeshViewUI.cpp	(revision 1083)
@@ -795,7 +795,4 @@
 inline void GeoMeshViewUI::cb_menuLodStripsVisualize_i(fltk::Item*, void*)
 {
-	fltk::FileChooser *fcho;
-	const	char				*lod_file;
-	
 	//	Sets menus application state to NONE.
 	mApplicationState	=	NONE;
@@ -811,36 +808,28 @@
 	if (mGeoMesh != NULL)
 	{
-/*		fcho	=	new fltk::FileChooser("",
-				"*.lod",
-				fltk::FileChooser::CREATE,
-				"Open Lod file");
-
-		fcho->exec();
-
-		//	If a file was selected.
-		if (fcho->value())
-		{*/
+		if (geoMeshLoader->GetLodStripsData())
+		{
 			//	Build lod strips library.
-			setLodStripsLibrary(geoMeshLoader->lodstripsdata, mGeoMesh);
+			setLodStripsLibrary(geoMeshLoader->GetLodStripsData(), mGeoMesh);
 
 			//	Sets the aplication mode.
 			mApplicationState	=	VISUALIZE_LODSTRIPS;
-	/*	}
-
-		//	Free memory.
-		delete	fcho;*/
-
-		//	Hide the right panel.
-		hideRightPanel();
-
-		//	Show title.
-		mProcessTitle->label("Visualize LodStrips");
-
-		//	Show the Visulize LodStrips panel.
-		showLodStripSlider();
-
-		//	Repaint the window.
-		mMainWindow->redraw();
-
+		
+			//	Hide the right panel.
+			hideRightPanel();
+
+			//	Show title.
+			mProcessTitle->label("Visualize LodStrips");
+
+			//	Show the Visulize LodStrips panel.
+			showLodStripSlider();
+
+			//	Repaint the window.
+			mMainWindow->redraw();
+		}
+		else
+		{
+			fltk::alert("The loaded mesh does not contain LOD information.\nNothing will be done.");
+		}
 	}
 }
@@ -848,7 +837,4 @@
 inline void GeoMeshViewUI::cb_menuLodTreesVisualize_i(fltk::Item*, void*)
 {
-	fltk::FileChooser *fcho;
-	const	char				*lod_file;
-
 	//	Sets menus application state to NONE.
 	mApplicationState	=	NONE;
@@ -861,64 +847,26 @@
 	openMeshFile();
 
-	/*if (geoMeshView->getLeavesSubmesh()==-1)
-		{
-		fltk::alert("No se ha seleccionado el submesh de hojas!");
-		return;
-		}*/
-
 	//	If an object is loaded.
 	if (mGeoMesh != NULL)
 	{
-		// POR AHORA SE SELECCIONA EL PRIMER SUBMESH QUE NO ES STRIPS COMO HOJAS
-		int leafsSubMeshID = -1;
-
-		for (int i=0; i<mGeoMesh->mSubMeshCount; i++)
+		if (geoMeshLoader->GetTreeSimpSeq() && geoMeshLoader->GetLodStripsData())
 		{
-			if (mGeoMesh->mSubMesh[i].mType==GEO_TRIANGLE_LIST)
+			// select the first triangle-list submesh as leaves submesh
+			int leafsSubMeshID = -1;
+
+			for (int i=0; i<mGeoMesh->mSubMeshCount; i++)
 			{
-				leafsSubMeshID=i;
-				break;
+				if (mGeoMesh->mSubMesh[i].mType==GEO_TRIANGLE_LIST)
+				{
+					leafsSubMeshID=i;
+					break;
+				}
 			}
-		}
-
-		//	If an object is loaded.
-/*		if (mGeoMesh != NULL)
-		{
-			fcho	=	new fltk::FileChooser("",
-					"*.mesh",
-					fltk::FileChooser::CREATE,
-					"Open Lod file");
-
-			fcho->exec();
-
-			//	If a file was selected.
-			if (fcho->value())
-			{
-				//	Build lod strips library.
-
-				std::string lodstripFile(fcho->value());
-				delete fcho;
-				fcho	=	new fltk::FileChooser("",
-						"*.leafseq",
-						fltk::FileChooser::CREATE,
-						"Open LeafSeq file");
-
-				fcho->exec();
-
-				if (fcho->value())
-				{
-					std::string leafseqFile(fcho->value());*/
-
-					//setLodTreesLibrary(lodstripFile, leafseqFile, mGeoMesh, leafsSubMeshID);
-					setLodTreesLibrary(geoMeshLoader->lodstripsdata, geoMeshLoader->treesimpseq, mGeoMesh, leafsSubMeshID);
-
-					//	Sets the aplication mode.
-					mApplicationState	=	VISUALIZE_LODTREES;
-/*				}
-			}
-
-			//	Free memory.
-			delete	fcho;
-*/
+
+			setLodTreesLibrary(geoMeshLoader->GetLodStripsData(), geoMeshLoader->GetTreeSimpSeq(), mGeoMesh, leafsSubMeshID);
+
+			//	Sets the aplication mode.
+			mApplicationState	=	VISUALIZE_LODTREES;
+
 			//	Hide the right panel.
 			hideRightPanel();
@@ -933,5 +881,7 @@
 			//	Repaint the window.
 			mMainWindow->redraw();
-/*		}*/
+		}
+		else
+			fltk::alert("The loaded mesh does not contain LOD information.\nNothing will be done.");
 	}
 }
@@ -2367,5 +2317,5 @@
 //	Initialize the lodstripslibrary for visualization.
 //---------------------------------------------------------------------------
-void	GeoMeshViewUI::setLodStripsLibrary(const Geometry::LodStripsLibraryData &loddata, Mesh	*geomesh)
+void	GeoMeshViewUI::setLodStripsLibrary(const Geometry::LodStripsLibraryData *loddata, Mesh	*geomesh)
 {
 	//	If there is no lod strips object.
@@ -2392,11 +2342,9 @@
 //	Initialize the lodTreelibrary for visualization.
 //---------------------------------------------------------------------------
-void	GeoMeshViewUI::setLodTreesLibrary(const LodStripsLibraryData &lodstripsdata, const TreeSimplificationSequence &treesimpseq, Mesh *geomesh, uint32 ileafSubMesh)
+void	GeoMeshViewUI::setLodTreesLibrary(const LodStripsLibraryData *lodstripsdata, const TreeSimplificationSequence *treesimpseq, Mesh *geomesh, uint32 ileafSubMesh)
 {
 	//	If there is no lod strips object.
 	if (lodTreeLib)
-	{
 		delete	lodTreeLib;
-	}
 
 	//	New lod strips object.
Index: /GTP/trunk/Lib/Geom/shared/GeoTool/src/GeoMeshView.cpp
===================================================================
--- /GTP/trunk/Lib/Geom/shared/GeoTool/src/GeoMeshView.cpp	(revision 1078)
+++ /GTP/trunk/Lib/Geom/shared/GeoTool/src/GeoMeshView.cpp	(revision 1083)
@@ -892,6 +892,4 @@
 	current_strip = 0;
 
-	int begin_index = 0;
-
 	//	For each submesh.
 	for (int submesh = 0; submesh < geoMesh->mSubMeshCount; submesh++)
@@ -968,10 +966,10 @@
 		}*/
 
-		int indices_to_render = lodStripsLib->indices_x_submesh[submesh];
-
+		int indices_to_render = lodStripsLib->GetValidIndexCount(submesh);
+		int offset = lodStripsLib->GetValidOffset(submesh);
 
 		glBegin(GL_TRIANGLE_STRIP);
 		//for (int index = 0; index < lodStripsLib->dataRetrievalInterface->GetNumValidIndices(); index ++)
-		for (int index = begin_index; index < indices_to_render+begin_index; index ++)
+		for (int index = offset; index < indices_to_render+offset; index ++)
 		{
 			position = lodStripsLib->dataRetrievalInterface->GetIndex(index);
@@ -1007,5 +1005,4 @@
 		}
 		glEnd();
-		begin_index += indices_to_render;
 
 	}
@@ -1032,7 +1029,4 @@
 
 	// DRAW THE TRUNK AS A LODSTRIP OBJECT
-
-	int begin_index = 0;
-
 	//	For each submesh.
 	for (int submesh = 0; submesh < geoMesh->mSubMeshCount; submesh++)
@@ -1112,8 +1106,10 @@
 		}*/
 	
-		int indices_to_render = lodTreeLib->trunk->indices_x_submesh[submesh];
+//		int indices_to_render = lodTreeLib->trunk->GetValidIndexCount(submesh);
+		int indices_to_render = lodTreeLib->GetValidTrunkIndexCount(submesh);
+		int begin_index = lodTreeLib->GetValidTrunkOffset(submesh);
         		
 		glBegin(GL_TRIANGLE_STRIP);
-		for (int index = begin_index; index < lodTreeLib->trunk->indices_x_submesh[submesh]; index ++)
+		for (int index = begin_index; index < indices_to_render+begin_index; index ++)
 		{
 			position = lodTreeLib->CurrentLOD_Trunk_Indices()->GetIndex(index);
@@ -1149,6 +1145,4 @@
 		}
 		glEnd();
-		begin_index += indices_to_render;
-
 	}
 
Index: P/trunk/Lib/Geom/shared/GeoTool/src/GeoMeshLoader.cpp
===================================================================
--- /GTP/trunk/Lib/Geom/shared/GeoTool/src/GeoMeshLoader.cpp	(revision 1078)
+++ 	(revision )
@@ -1,1753 +1,0 @@
-/*==========================================================================
- *	(C) 2005 Universitat Jaume I
- *==========================================================================
- *	PROYECT:	GAME TOOLS
- *==========================================================================*/
-/*	CONTENT:	
- *
- *
- *	@file	GeoMeshLoader.cpp
- *==========================================================================*/
-
-#include	"GeoMeshLoader.h"
-#include	<algorithm>
-#include	<cctype>
-#include	<map>
-
-using namespace Geometry;
-using	namespace	std;
-
-//---------------------------------------------------------------------------
-//	Jump a chunk.
-//---------------------------------------------------------------------------
-void GeoMeshLoader::jumpChunk(FILE	*f)
-{
-	fseek(f,-(long)CHUNK_OVERHEAD_SIZE,1);
-
-	//	Return to the begin of the chunk.
-	fseek(f,long_actual,SEEK_CUR);
-}
-
-//---------------------------------------------------------------------------
-//	Read a chunk.
-//---------------------------------------------------------------------------
-unsigned short GeoMeshLoader::readChunk(FILE	*f)
-{
-	unsigned	short	id;
-
-	fread(&id,sizeof(unsigned short),1,f);
-	fread(&long_actual,sizeof(unsigned long),1,f);
-									
-	return id;
-}
-
-//---------------------------------------------------------------------------
-//	Read geometry vertex element.
-//---------------------------------------------------------------------------
-void GeoMeshLoader::readGeometryVertexElement(FILE	*f, Mesh	*geoMesh)
-{
-	unsigned	short		source;
-	GeometryElement		aux;
-	int								i;
-	bool							found;
-	VertexElementType	vType;
-
-	i						=	0;
-	found	=	false;
-
-	//		VertexElementSemantic vSemantic;
-	// unsigned short source;  	// buffer bind source
-	fread(&source,sizeof(unsigned short),1,f);
-
-	// unsigned short type;    	// VertexElementType
-	fread(&aux.type,sizeof(unsigned short),1,f);
-
-	vType	=	static_cast<VertexElementType>(aux.type);
-
-	// unsigned short semantic; // VertexElementSemantic
-	fread(&aux.semantic,sizeof(unsigned short),1,f);
-
-	//	vSemantic = static_cast<VertexElementSemantic>(tmp);
-	//	unsigned short offset;	// start offset in buffer in bytes
-	fread(&aux.offset,sizeof(unsigned short),1,f);
-
-	// unsigned short index;	// index of the semantic
-	/*
-	VES_POSITION  Position, 3 reals per vertex.  
-	VES_BLEND_WEIGHTS  Blending weights.  
-	VES_BLEND_INDICES  Blending indices.  
-	VES_NORMAL  Normal, 3 reals per vertex.  
-	VES_DIFFUSE  Diffuse colours.  
-	VES_SPECULAR  Specular colours.  
-	VES_TEXTURE_COORDINATES  Texture coordinates.  
-	VES_BINORMAL  Binormal (Y axis if normal is Z).  
-	VES_TANGENT  Tangent (X axis if normal is Z).  
-	*/
-	fread(&aux.index,sizeof(unsigned short),1,f);
-
-	while ((i < list.size()) && (!found))
-	{
-		if (list[i].source==source)
-		{
-			found	=	true;
-		}
-		else
-		{
-			i++;
-		}
-	}
-
-	if (found)
-	{
-		list[i].list.push_back(aux);
-	}
-	else
-	{
-		GT	aux2;
-		
-		aux2.source	=	source;
-		aux2.list.push_back(aux);
-		list.push_back(aux2);
-	}
-}
-
-//---------------------------------------------------------------------------
-//	Read geometry vertex declaration.
-//---------------------------------------------------------------------------
-void GeoMeshLoader::readGeometryVertexDeclaration(FILE	*f, Mesh	*geoMesh)
-{
-	unsigned short chunkID;
-  // Find optional geometry chunks
-  if (!feof(f))
-  {
-    chunkID	=	readChunk(f);
-
-    while(!feof(f) && (chunkID == M_GEOMETRY_VERTEX_ELEMENT ))
-    {
-      switch (chunkID)
-      {
-				case M_GEOMETRY_VERTEX_ELEMENT:
-
-					//	Debug.
-					cout	<<	"		M_GEOMETRY_VERTEX_ELEMENT"
-								<<	endl;
-					
-          readGeometryVertexElement(f, geoMesh);
-
-          break;
-      }
-
-      // Get next chunk
-      if (!feof(f))
-      {
-				chunkID = readChunk(f);
-      }
-    }//	End while.
-
-    if (!feof(f))
-    {
-			// Backpedal back to start of non-submesh chunk
-			fseek(f,-(long)CHUNK_OVERHEAD_SIZE,1);
-    }
-
-  }//	End if (!feof(f))
-}//	End readGeometryVertexDeclaration.
-
-//---------------------------------------------------------------------------
-//	Read geometry vertex buffer.
-//---------------------------------------------------------------------------
-void GeoMeshLoader::readGeometryVertexBuffer(FILE	*f, Mesh	*geoMesh, int option)
-{
-	unsigned	short	bindIndex;
-	unsigned	short	vertexSize;
-	unsigned	short	headerID;
-	int							i;
-	float						aux;
-	int							k;
-	bool						found;
-	float						x,y,z;
-	SubMesh					*geoSubMesh;
-	VertexBuffer		*vertex_buffer;
-
-	i						=	0;
-	k						=	0;
-	found	=	false;
-	
-	if (option == GEOMESH_BUILD)
-	{
-		//	If is the main mesh.
-		if (currentSubMesh == -1)
-		{
-			vertex_buffer	=	geoMesh->mVertexBuffer;
-		}
-		//	If is a submesh.
-		else
-		{
-			//	Gets the current submesh
-			geoSubMesh		=	&geoMesh->mSubMesh[currentSubMesh];
-			vertex_buffer	=	geoSubMesh->mVertexBuffer;
-		}
-	}
-	
-	// Index to bind this buffer to
-	fread(&bindIndex,sizeof(unsigned short),1,f);
-
-	// Per-vertex size, must agree with declaration at this index
-	fread(&vertexSize,sizeof(unsigned short),1,f);
-
-	// Check for vertex data header
-	headerID	=	readChunk(f);
-
-	if (headerID != M_GEOMETRY_VERTEX_BUFFER_DATA)
-	{
-		cout	<<	"Can't find vertex buffer data area"
-					<<	endl;
-	}
-	else
-	{
-		//	Debug.
-		cout	<<	"		M_GEOMETRY_VERTEX_BUFFER_DATA"
-					<<	endl;
-	}
-
-	while ((i<list.size())&&(!found))
-	{
-		if (list[i].source	==	bindIndex)
-		{
-			found	=	true;
-		}
-		else
-		{
-			i++;
-		}
-	}
-
-	if (found)
-	{
-		for (k	=	0;	k < numVertices;	k++)
-		{
-			//	For each element in this source.
-			for(int j	=	0;	j < list[i].list.size();	j++)
-			{
-				//	Positions.
-				if (list[i].list[j].semantic == 1)
-				{
-					fread(&x,sizeof(float),1,f);
-					fread(&y,sizeof(float),1,f);
-					fread(&z,sizeof(float),1,f);
-
-					if (option == GEOMESH_BUILD)
-					{
-						vertex_buffer->mVertexInfo		|=	VERTEX_POSITION;
-						vertex_buffer->mPosition[k].x	=		x;
-						vertex_buffer->mPosition[k].y	=		y;
-						vertex_buffer->mPosition[k].z	=		z;
-					}
-				}
-				//	If are not vertices.
-				else 
-				{
-					if (list[i].list[j].type == 2)
-					{
-						fread(&x,sizeof(float),1,f);
-						fread(&y,sizeof(float),1,f);
-						fread(&z,sizeof(float),1,f);
-
-						if (option == GEOMESH_BUILD)
-						{
-							vertex_buffer->mVertexInfo	|=	VERTEX_NORMAL;
-							vertex_buffer->mNormal[k].x	=		x;
-							vertex_buffer->mNormal[k].y	=		y;
-							vertex_buffer->mNormal[k].z	=		z;
-						}
-					}
-					if (list[i].list[j].type == 1)
-					{
-						fread(&x,sizeof(float),1,f);
-						fread(&y,sizeof(float),1,f);
-						
-						if (option == GEOMESH_BUILD)
-						{
-							vertex_buffer->mVertexInfo			|=	VERTEX_TEXCOORDS;
-							vertex_buffer->mTexCoords[k].x	=		x;
-							vertex_buffer->mTexCoords[k].y	=		y;
-						}
-					}
-				}
-			}
-		}
-	}
-	else
-	{
-		//	Debug.
-		cout	<<	"Error: Source not found."
-					<<	endl;
-
-		//	Error.
-		mError	=	true;
-	}
-
-}
-
-//---------------------------------------------------------------------------
-//	Read Geometry.
-//---------------------------------------------------------------------------
-void GeoMeshLoader::readGeometry(FILE	*f, Mesh	*geoMesh, int option)
-{
-	SubMesh				*geoSubMesh;
-	VertexBuffer	*vertex_buffer;
-	
-	fread(&numVertices,sizeof(unsigned int),1,f);
-
-	if (option == GEOMESH_BUILD)
-	{
-		if (currentSubMesh == -1)
-		{
-			//	Get the current vertex buffer.
-			vertex_buffer	=	geoMesh->mVertexBuffer;
-		}
-		else
-		{
-			//	Get the current submesh.
-			geoSubMesh		=	&geoMesh->mSubMesh[currentSubMesh];
-
-			//	Create the VertexBuffer of the submesh.
-			geoSubMesh->mVertexBuffer	=	new VertexBuffer();
-
-			//	Get the current vertex buffer.
-			vertex_buffer	=	geoSubMesh->mVertexBuffer;
-		}
-
-		//	Initialize the VertexBuffer of the current submesh.
-		vertex_buffer->mVertexCount	=	numVertices;
-
-		//	Initialize the position array.
-		vertex_buffer->mPosition	=	new Vector3[numVertices];
-
-		//	Initialize the normal array.
-		vertex_buffer->mNormal		=	new Vector3[numVertices];
-
-		//	Initialize the texture coords array.
-		vertex_buffer->mTexCoords	=	new Vector2[numVertices];
-	}
-
-	// Find optional geometry chunks
-	if (!feof(f))
-	{
-		unsigned short chunkID = readChunk(f);
-	
-		while(!feof(f) && 
-					(chunkID == M_GEOMETRY_VERTEX_DECLARATION || 
-					chunkID == M_GEOMETRY_VERTEX_BUFFER ))
-		{
-			switch (chunkID)
-			{
-				case M_GEOMETRY_VERTEX_DECLARATION:
-
-					//	Debug.
-					cout	<<	"		M_GEOMETRY_VERTEX_DECLARATION"
-								<<	endl;
-					
-					readGeometryVertexDeclaration(f, geoMesh);
-					
-					break;
-					
-				case M_GEOMETRY_VERTEX_BUFFER:
-					
-					//	Debug.
-					cout	<<	"		M_GEOMETRY_VERTEX_BUFFER"
-								<<	endl;
-					
-					readGeometryVertexBuffer(f, geoMesh,option);
-					
-					break;
-			}
-		
-			// Get next chunk.
-			if (!feof(f))
-			{
-				chunkID = readChunk(f);
-			}
-		}
-
-		if (!feof(f))
-		{
-			// Backpedal back to start of non-submesh chunk.
-			fseek(f,-(long)CHUNK_OVERHEAD_SIZE,1);
-		}
-	}
-}
-
-//---------------------------------------------------------------------------
-//	Read a submesh operation.
-//---------------------------------------------------------------------------
-void GeoMeshLoader::readSubMeshOperation(	FILE	*f,
-																					Mesh	*geoMesh,
-																					int 	option)
-{
-	unsigned	short	opType;
-	
-	fread(&opType,sizeof(unsigned short),1,f);
-
-	if (option == GEOMESH_BUILD)
-	{
-		if (opType == 5)
-		{
-			geoMesh->mSubMesh[currentSubMesh].mType	=	GEO_TRIANGLE_STRIPS;
-		}
-		else
-		{
-			geoMesh->mSubMesh[currentSubMesh].mType	=	GEO_TRIANGLE_LIST;
-		}
-	}
-}
-
-//---------------------------------------------------------------------------
-//	Read a submesh.
-//---------------------------------------------------------------------------
-void GeoMeshLoader::readSubMesh(FILE	*f, Mesh	*geoMesh, int option)
-{
-	SubMesh					*geoSubMesh;
-	unsigned	short	chunkID;
-	char						materialName[255];
-	bool						useSharedVertices;
-	unsigned	int		numIndices;
-	bool						idx32bit;
-
-	switch	(option)
-	{
-		case	SUBMESH_COUNT:
-			geoMesh->mSubMeshCount++;
-			break;
-		case	GEOMESH_BUILD:
-
-			//	Initialize the new subMesh.
-			geoSubMesh	=	&geoMesh->mSubMesh[currentSubMesh];
-	}
-	
-	list.clear();
-
-	//	Gets material name.
-	fgets(materialName,255,f);
-	materialName[strlen(materialName) - 1]	=	'\0';
-
-	fread(&useSharedVertices,sizeof(bool),1,f);
-	
-	if (option	==	GEOMESH_BUILD)
-	{
-		//	Obtain the material name.
-		strcpy(geoSubMesh->mMaterialName,materialName);
-		
-		//	Obtain the flag of vertex shared.
-		geoSubMesh->mSharedVertexBuffer	=	useSharedVertices;
-		
-		if (useSharedVertices)
-		{
-			//	The VB of the submesh points to the VB of the mesh.
-			geoSubMesh->mVertexBuffer	=	geoMesh->mVertexBuffer;
-		}
-	}
-
-	fread(&numIndices,sizeof(unsigned int),1,f);
-	fread(&idx32bit,sizeof(bool),1,f);
-	
-	if (option == GEOMESH_BUILD)
-	{
-			//	Sets the index count of the submesh.
-			geoSubMesh->mIndexCount	=	numIndices;
-	
-			//	Create the index arrar for this submesh.
-			geoSubMesh->mIndex	=	new Index[numIndices];
-	}
-	
-
-	if (idx32bit)
-	{
-		unsigned int aux;
-
-		for (int i = 0; i < numIndices; i++)
-		{
-			fread(&aux,sizeof(unsigned int),1,f);
-
-			if (option == GEOMESH_BUILD)
-			{
-					geoSubMesh->mIndex[i]	=	aux;
-			}
-		}
-	}
-	else
-	{
-		unsigned short aux;
-
-		for (int i = 0; i < numIndices; i++)
-		{
-			fread(&aux,sizeof(unsigned short),1,f);
-			
-			if (option == GEOMESH_BUILD)
-			{
-				geoSubMesh->mIndex[i]	=	aux;
-			}
-		}
-	}
-
-  // M_GEOMETRY chunk 
-	// (Optional: present only if useSharedVertices = false)
-  if (!useSharedVertices)
-	{
-		chunkID = readChunk(f);
-		
-		if (chunkID != M_GEOMETRY)
-		{
-			//	Debug.
-			cout	<<	"Error: Missing mesh geometry."
-						<<	endl;
-
-			//	Error.
-			mError	=	true;
-		}
-		
-		readGeometry(f, geoMesh, option);
-	}
-
-	// Find all bone assignments (if present) 
-	if (!feof(f))
-	{
-		chunkID = readChunk(f);
-		while(!feof(f) &&
-					(chunkID == M_SUBMESH_BONE_ASSIGNMENT ||
-					chunkID == M_SUBMESH_OPERATION))
-		{
-			switch(chunkID)
-			{
-				case M_SUBMESH_OPERATION:
-								
-					//	Debug.
-					cout	<<	"		M_SUBMESH_OPERATION"
-								<<	endl;
-
-					readSubMeshOperation(f, geoMesh, option);
-					
-					break;
-					
-				case M_SUBMESH_BONE_ASSIGNMENT:
-					
-					//	Debug.
-					//cout	<<	"		M_SUBMESH_BONE_ASSIGNMENT"
-					//			<<	endl;
-					
-					if (option	==	GEOMESH_BUILD)
-					{
-						readSubMeshBoneAssignment(f, geoSubMesh, option);
-					}
-					else
-					{
-						jumpChunk(f);
-					}
-					
-					break;
-			}
-
-			if (!feof(f))
-			{
-				chunkID	=	readChunk(f);
-			}
-
-		}
-		if (!feof(f))
-		{
-			// Backpedal back to start of chunk.
-			fseek(f,-(long)CHUNK_OVERHEAD_SIZE,1);
-		}
-	}
-
-}
-
-//---------------------------------------------------------------------------
-//	Read a mesh lod information.
-//---------------------------------------------------------------------------
-void GeoMeshLoader::readMeshLodInfo(FILE	*f, Mesh	*geoMesh)
-{
-	unsigned	short	chunkID;
-	unsigned	short	i;
-	unsigned	short	aux;
-	bool						aux2;
-
-  // unsigned short numLevels;
-	fread(&aux,sizeof(unsigned short),1,f);
-	// bool manual;
-	// (true for manual alternate meshes, false for generated)
-	fread(&aux2,sizeof(bool),1,f);
-
-	// Loop from 1 rather than 0 (full detail index is not in file)
-	for (i = 1; i < aux; ++i)
-	{
-		chunkID = readChunk(f);
-		if (chunkID != M_MESH_LOD_USAGE)
-		{
-			//	Debug.
-			cout	<<	"Error: Missing M_MESH_LOD_USAGE chunk"
-						<<	endl;
-		}
-		else
-		{
-			cout	<<	"		M_MESH_LOD_USAGE"
-						<<	endl;
-		}
-		
-		jumpChunk(f);
-
-	}
-}
-
-//---------------------------------------------------------------------------
-//	Read a submesh name table.
-//---------------------------------------------------------------------------
-void GeoMeshLoader::readSubMeshNameTable(FILE	*f, Mesh	*geoMesh)
-{
-		unsigned	short	chunkID;
-		unsigned	short	subMeshIndex;
-		char						string[255];
-
-		if (!feof(f))
-		{
-			chunkID	=	readChunk(f);
-			
-			while	(!feof(f) && (chunkID == M_SUBMESH_NAME_TABLE_ELEMENT ))
-			{
-				//	Debug.
-				cout	<<	"		M_SUBMESH_NAME_TABLE_ELEMENT"
-							<<	endl;
-				
-				// Read in the index of the submesh.
-				fread(&subMeshIndex,sizeof(unsigned short),1,f);
-				
-				// Read in the String and map it to its index.
-				fgets(string,255,f);
-
-				// If we're not end of file get the next chunk ID.
-				if (!feof(f))
-				{
-					chunkID = readChunk(f);
-				}
-			}
-			if (!feof(f))
-			{
-				// Backpedal back to start of chunk.
-				fseek(f,-(long)CHUNK_OVERHEAD_SIZE,1);
-			}
-		}
-}
-
-//---------------------------------------------------------------------------
-//	Read a mesh file.
-//---------------------------------------------------------------------------
-
-#include "GeoLodStripsLibrary.h"
-#include "GeoLodStripsConstructor.h"
-
-void GeoMeshLoader::readMesh(FILE	*f, Mesh	*geoMesh, int option)
-{
-	unsigned	short	chunkID;
-	bool						nada;
-
-	//	Create the VertexBuffer of the mesh.
-	geoMesh->mVertexBuffer	=	new	VertexBuffer();
-	geoMesh->mVertexBuffer->mVertexCount	=	0;
-
-	//La vacio antes de leer el mesh
-	list.clear();
-
-	// bool skeletallyAnimated
-	fread(&nada,sizeof(bool),1,f);
-
-  // Find all subchunks 
-	if (!feof(f))
-	{
-		chunkID	=	readChunk(f);
-
-		while(!feof(f) &&
-				(chunkID == M_GEOMETRY ||
-				 chunkID == M_SUBMESH ||
-				 chunkID == M_MESH_SKELETON_LINK ||
-				 chunkID == M_MESH_BONE_ASSIGNMENT ||
-				 chunkID == M_MESH_LOD ||
-				 chunkID == M_MESH_BOUNDS ||
-				 chunkID == M_SUBMESH_NAME_TABLE ||
-				 chunkID == M_EDGE_LISTS ||
-				 chunkID == 0xabcd || 
-				 chunkID == 0xdcba))
-		{
-			switch(chunkID)
-			{
-				case 0xabcd:
-					cout << "LODSTRIPS_Chunk" << endl;
-					int				aux,v,c;
-					LODRegisterType	lod_register;
-					LODData			dataaux;
-					int				tam;
-
-					fread(&tam, sizeof(int), 1, f);
-					lodstripsdata.mFileVertices.clear();
-					for (v=0; v<tam; v++)
-					{
-						fread(&aux, sizeof(int), 1, f);
-						lodstripsdata.mFileVertices.push_back(aux);
-					}
-
-					lodstripsdata.mFileChangesLOD.clear();
-					fread(&tam, sizeof(int), 1, f);
-					for (c=0; c<tam; c++)
-					{
-						fread(&dataaux, sizeof(LODData), 1, f);
-						lod_register.strip= dataaux.strip;
-						lod_register.position= dataaux.nP;
-						lod_register.vertexRepetition= dataaux.nL1;
-						lod_register.edgeRepetition= dataaux.nL2;
-						//lod_register.obligatory=false;
-						//lod_register.obligatory= dataaux.obligatory;
-
-						lodstripsdata.mFileChangesLOD.push_back(lod_register);
-					}
-					
-					lodstripsdata.mData.clear();
-					fread(&tam, sizeof(int), 1, f);
-					for (int b=0; b<tam; b++)
-					{
-						fread(&aux, sizeof(int), 1, f);
-						lodstripsdata.mData.push_back(aux);
-					}
-
-					lodstripsdata.p_changes.clear();
-					fread(&tam, sizeof(int), 1, f);
-					for (int p=0; p<tam; p++)
-					{
-						fread(&aux, sizeof(int), 1, f);
-						lodstripsdata.p_changes.push_back(aux);
-					}					
-
-					break;
-
-				case 0xdcba:
-					cout << "LODTREES_Chunk" << endl;
-					int size;
-					fread(&size, sizeof(int), 1, f);
-					treesimpseq.mSteps.clear();
-					for (int i=0; i<size; i++)
-					{
-						Geometry::TreeSimplificationSequence::Step auxstep;
-						fread(&auxstep.mV0,sizeof(int),1,f);
-						fread(&auxstep.mV1,sizeof(int),1,f);
-						fread(&auxstep.mT0,sizeof(int),1,f);
-						fread(&auxstep.mT1,sizeof(int),1,f);
-						fread(auxstep.mNewQuad,sizeof(int),4,f);
-						treesimpseq.mSteps.push_back(auxstep);
-					}
-
-					break;
-
-
-				case M_GEOMETRY:
-
-					//	Debug.
-					cout	<<	"		M_GEOMETRY"
-								<<	endl;
-
-					readGeometry(f, geoMesh, option);
-					break;
-
-				case M_SUBMESH:
-
-					//	Debug.
-					cout	<<	"		M_SUBMESH"
-								<<	endl;
-
-					if (option == GEOMESH_BUILD)
-					{
-						//	Increments the current submesh.
-						currentSubMesh++;
-					}
-
-					readSubMesh(f, geoMesh, option);
-
-					break;
-
-				case M_MESH_SKELETON_LINK:
-
-					//	Debug.
-					cout	<<	"		M_MESH_SKELETON_LINK  "
-								<<	endl;
-								
-
-					readSkeletonLink(f, geoMesh, option);
-
-					break;
-
-				case M_MESH_BONE_ASSIGNMENT:
-
-					//	Debug.
-					//cout	<<	"		M_MESH_BONE_ASSIGNMENT  "
-					//			<<	endl;
-
-					readMeshBoneAssignment(f, geoMesh, option);
-
-					break;
-
-				case M_MESH_LOD:
-
-					//	Debug.
-					cout	<<	"		M_MESH_LOD"
-								<<	endl;
-					
-					readMeshLodInfo(f, geoMesh);
-					break;
-
-				case M_MESH_BOUNDS:
-
-					//	Debug.
-					cout	<<	"		M_MESH_BOUNDS "
-								<<	endl;
-
-					//jumpChunk(f);
-					readMeshBounds(f, geoMesh, option);
-					break;
-
-				case M_SUBMESH_NAME_TABLE:
-
-					//	Debug.
-					cout	<<	"		M_SUBMESH_NAME_TABLE "
-								<<	endl;
-
-					readSubMeshNameTable(f,	geoMesh);
-					break;
-
-				case M_EDGE_LISTS:
-
-					//	Debug.
-					cout	<<	"		M_EDGE_LISTS "
-								<<	endl;
-
-					jumpChunk(f);
-					break;
-			}
-
-			if (!feof(f))
-			{
-				chunkID	=	readChunk(f);
-			}
-
-		}
-
-		if (!feof(f))
-		{
-			// Backpedal back to start of chunk
-			fseek(f,-(long)CHUNK_OVERHEAD_SIZE,1);
-
-			//	Debug.
-			cout	<<	"Error: Reading failure."
-						<<	endl;
-
-			//	Error.
-			mError	=	true;
-		}
-	}
-
-}
-
-
-//---------------------------------------------------------------------------
-//	Allocate memory to the array of strips
-//---------------------------------------------------------------------------
-SubMesh* GeoMeshLoader::BuildStripsGeoSubMesh(SubMesh* geoSubMesh)
-{
-	bool		head_found;
-	bool		tail_found;
-	int			strip_count;
-	int			tailIndex;
-	size_t	tail;
-
-
-	head_found							=	false;
-	tail_found							=	false;
-	geoSubMesh->mStripCount	=	1;
-
-	//	Foreachone of the indices.
-	//	Obtains the number of triangle strips.
-	for (int i = 0; i < (geoSubMesh->mIndexCount - 1); i++)
-	{
-		if (geoSubMesh->mIndex[i] == geoSubMesh->mIndex[i+1])
-		{
-			if (head_found)
-			{
-				tail_found	=	true;
-			}
-			else
-			{
-				head_found	=	true;
-			}
-
-			//	Jump one index.
-			i++;
-		}
-		else
-		{
-			//	Increments the number of triangle strips.
-			if (tail_found)
-			{
-				geoSubMesh->mStripCount++;
-			}
-
-			head_found	=	false;
-			tail_found	=	false;
-		}
-	}
-
-	geoSubMesh->mStrip		=	(Index**) malloc(	sizeof(Index*)
-			*
-			geoSubMesh->mStripCount);
-
-	//	Number of strips. Initially there is one triangle strip.
-	strip_count	=	1;
-
-	head_found						=	false;
-	tail_found						=	false;
-
-	//	Initialize the fist triangle strip.
-	geoSubMesh->mStrip[0]	=	&geoSubMesh->mIndex[0];
-
-	//	Foreachone of the indices.
-	//	Assigns the beginning of the triangle strips.
-	for(int i = 0;i < (geoSubMesh->mIndexCount - 1); i++)
-	{
-		if(geoSubMesh->mIndex[i] == geoSubMesh->mIndex[i+1])
-		{
-			if(head_found)
-			{
-				if (!tail_found)
-				{
-					tailIndex		=	i;
-				}
-
-				tail_found	=	true;
-			}
-			else
-			{
-				head_found	=	true;
-			}
-
-			//	Jump one index.
-			i++;
-		}
-		else
-		{
-			//	Increments the number of triangle strips.
-			if(tail_found)
-			{
-				geoSubMesh->mStrip[strip_count++]	=	&geoSubMesh->mIndex[tailIndex];
-			}
-
-			head_found	=	false;
-			tail_found	=	false;
-		}
-	}
-
-	//	Remove degenerate triangles of a submesh given.
-	//geoSubMesh	=	removeDegenerateTriangles(geoSubMesh);
-
-	return	geoSubMesh;
-}
-
-//---------------------------------------------------------------------------
-//	Remove degenerate triangles of a submesh given.
-//---------------------------------------------------------------------------
-SubMesh	*	GeoMeshLoader::removeDegenerateTriangles(SubMesh	*geoSubMesh)
-{
-	Index		*indices;
-	Index		*index;
-	Index		*indexBegin;
-	Index		*indexEnd;
-	Index		*new_strip_starts;
-	size_t	new_index_count;
-	size_t	current_index;
-
-	//	Stores the new starts of strips.
-	new_strip_starts	=	new	Index[geoSubMesh->mStripCount];
-	
-	//	Calculate the new index count.
-	new_index_count	=	geoSubMesh->mIndexCount	
-		-
-		(2 * geoSubMesh->mStripCount)
-		+
-		2;
-
-	//	Auxiliar index array.
-	indices	=	new	Index[new_index_count];
-
-	//	Initialize the current index.
-	current_index	=	0;
-	
-	//	For each one of the strips.
-	for (int strip = 0; strip < geoSubMesh->mStripCount; strip++)
-	{
-		//	Stars of strip without degenerate triangles.
-		new_strip_starts[strip]	=	current_index;
-		
-		//	First index of the strip.
-		indexBegin	=	geoSubMesh->mStrip[strip];
-
-		//	If is the final strip
-		if (strip	== (geoSubMesh->mStripCount - 1))
-		{
-			//	The end of the index array.
-			indexEnd	= &geoSubMesh->mIndex[geoSubMesh->mIndexCount];
-		}
-		else
-		{
-			//	The beginning of the next strip.
-			indexEnd	= geoSubMesh->mStrip[strip + 1];
-		}
-
-		int i;
-		i	= 0;
-
-		//	If is not the first strip.
-		if (strip != 0)
-		{
-			indexBegin++;
-		}
-
-		//	If is not the last strip.
-		if (strip	!= (geoSubMesh->mStripCount - 1))
-		{
-			indexEnd--;
-		}
-
-		//	For each index of the strip.
-		for (index = indexBegin; index < indexEnd; index++)
-		{
-			indices[current_index++]	=	indexBegin[i];
-
-			//	Increments i.
-			i++;
-		}
-
-	}
-
-	//	Free Index memory.
-	delete	[]geoSubMesh->mIndex;
-
-	//	Update index count.
-	geoSubMesh->mIndexCount	=	new_index_count;
-
-	geoSubMesh->mIndex	=	new	Index[new_index_count];
-
-	//	Store new index array without degenerate triangles.
-	for (size_t	i	=	0;	i	<	geoSubMesh->mIndexCount; i++)
-	{
-		geoSubMesh->mIndex[i]	=	indices[i];
-	}
-
-	//	Free auxiliar index array;
-	delete	[]indices;
-
-	//	Update start of the strip.
-	for (int	strip	=	0; strip < geoSubMesh->mStripCount; strip++)
-	{
-		geoSubMesh->mStrip[strip]	=	&geoSubMesh->mIndex[new_strip_starts[strip]];
-	}
-
-	//	Free auxiliar strip starts.
-	delete	[]new_strip_starts;
-	
-	return	geoSubMesh;
-}
-
-//---------------------------------------------------------------------------
-//	Loads a mesh.
-//---------------------------------------------------------------------------
-Mesh* GeoMeshLoader::load(char	*nameFileMesh) 
-{
-	unsigned	short	uno;
-	unsigned	short	chunkID;
-	char		version[255];
-	char		kk;
-	FILE		*pFile;
-	SubMesh		*geosubmesh;
-
-	//	Debug.
-	cout	<<	"---------------------------------"
-				<<	endl
-				<<	"\t LOAD MESH"
-				<<	endl
-				<<	"---------------------------------"
-				<<	endl;
-
-	// retrieve the extension of the file
-	std::string fileExt;
-	std::string completeFileName(nameFileMesh);
-	for (std::string::reverse_iterator it = completeFileName.rbegin(); it!=completeFileName.rend(); it++)
-		if (*it=='.')
-			break;
-		else
-			fileExt += *it;
-
-	std::transform(fileExt.begin(), fileExt.end(), fileExt.begin(), std::toupper);
-	reverse(fileExt.begin(),fileExt.end());
-	
-	geoMesh	=	NULL;
-
-	//	Open the mesh file.
-	pFile	=	fopen(nameFileMesh, "rb");
-
-	if (pFile)
-	{
-		//	Initialize the current submesh;
-		currentSubMesh	=	-1;
-
-		//	Initialize the return value.
-		geoMesh	=	new	Mesh();
-
-		if (fileExt==std::string("OBJ"))
-		{
-			mError	=	false;
-			importOBJ(pFile,geoMesh);
-		}
-		else
-		{
-			//	Count the submeshes
-			//	and next build the geomesh.
-			for (int option = 0; option < 2;option++)
-			{
-				//	Initialize Error.
-				mError	=	false;
-		
-				fread(&uno,sizeof(unsigned short),1,pFile);
-
-				if (uno != M_HEADER)
-				{
-					//	Debug.
-					cout	<<	"Error: Header not found."
-						<<	endl;
-
-					//	Error.
-					mError	=	true;
-				}
-
-				// Read version.
-				fgets(version,255,pFile);
-
-				cout	<<	version	<<	endl;
-
-				if (strcmp(version,"[MeshSerializer_v1.30]\n"))
-				{
-					//	Debug.
-					cout	<<	"Error: Wrong mesh version."
-						<<	endl
-						<<	"Only version 1.3 or older allowed."
-						<<	endl;
-
-					//	Error.
-					mError	=	true;
-				}
-
-				while(!feof(pFile))
-				{
-					chunkID = readChunk(pFile);
-
-					switch (chunkID)
-					{
-						case M_MESH:
-							readMesh(pFile, geoMesh, option);
-							break;
-					}
-				}
-
-				//	Create the submesh array.
-				if (option == SUBMESH_COUNT)
-				{
-					geoMesh->mSubMesh	= new SubMesh[geoMesh->mSubMeshCount];
-				}
-
-				//	Move the curso to the begining of the file.
-				fseek(pFile,0,SEEK_SET);
-			}
-
-			//	Goes to the end of the file.
-			fseek(pFile,0,SEEK_END);
-
-			//	Gets the size of the file.
-			mFileSize	=	ftell(pFile);
-		}
-
-		// Close the mesh file.
-		fclose(pFile);
-
-		//	If no error.
-		if (!mError)
-		{
-			for (int submesh = 0;	submesh < geoMesh->mSubMeshCount; submesh++)
-			{
-				//	Gets the actual submesh.
-				geosubmesh	=	&geoMesh->mSubMesh[submesh];
-
-				if (geosubmesh->mType == Geometry::GEO_TRIANGLE_STRIPS)
-				{
-					//	Fill the strips list.
-					geosubmesh	=	BuildStripsGeoSubMesh(geosubmesh);
-				}
-			}
-
-			//	Sets coods between -1 and 1.
-			normalizeModel(geoMesh);
-		}
-	}
-	else
-	{
-		//	Debug.
-		cout	<<	"Error: File not found."
-					<<	endl;
-
-		//	File not found.
-		mError	=	true;
-	}
-
-	//	If an error happens.
-	if (mError)
-	{
-		delete	geoMesh;
-		
-		geoMesh	=	NULL;
-	}
-	
-	return	geoMesh;
-}
-
-//---------------------------------------------------------------------------
-//	Sets coords between -1 and 1.
-//---------------------------------------------------------------------------
-void	GeoMeshLoader::normalizeModel(Mesh	*geoMesh)
-{
-	unsigned	int	i;
-	float					maxx, minx, maxy, miny, maxz, minz;
-	float					cx, cy, cz, w, h, d, max;
-	float					scale;
-	VertexBuffer	*vertex_buffer;
-
-	//	Gets vertex buffer.
-	vertex_buffer	=	geoMesh->mSubMesh[0].mVertexBuffer;
-	
-	//	Get the max/mins.
-	maxx = minx = vertex_buffer->mPosition[0].x;
-	maxy = miny = vertex_buffer->mPosition[0].y;
-	maxz = minz = vertex_buffer->mPosition[0].z;
-	
-	//	For each submesh.
-	for (int submesh = 0; submesh < geoMesh->mSubMeshCount; submesh++)
-	{
-		//	Gets the actual submesh.
-		vertex_buffer	=	geoMesh->mSubMesh[submesh].mVertexBuffer;
-
-		//	For each index of the strip.
-		for (int i = 0; i < vertex_buffer->mVertexCount; i++)
-		{
-			if (maxx < vertex_buffer->mPosition[i].x)
-			{
-				maxx = vertex_buffer->mPosition[i].x;
-			}
-
-			if (minx > vertex_buffer->mPosition[i].x)
-			{
-				minx = vertex_buffer->mPosition[i].x;
-			}
-
-			if (maxy < vertex_buffer->mPosition[i].y)
-			{
-				maxy = vertex_buffer->mPosition[i].y;
-			}
-
-			if (miny > vertex_buffer->mPosition[i].y)
-			{
-				miny = vertex_buffer->mPosition[i].y;
-			}
-
-			if (maxz < vertex_buffer->mPosition[i].z)
-			{
-				maxz = vertex_buffer->mPosition[i].z;
-			}
-
-			if (minz > vertex_buffer->mPosition[i].z)
-			{
-				minz = vertex_buffer->mPosition[i].z;
-			}
-		}
-
-		//	If is a shared vertex Buffer.
-		if (geoMesh->mSubMesh[submesh].mSharedVertexBuffer)
-		{
-			break;
-		}
-	}
-	
-	//	Calculate model width, height, and depth.
-	w = fabs(maxx) + fabs(minx);
-	h = fabs(maxy) + fabs(miny);
-	d = fabs(maxz) + fabs(minz);
-
-	//	Calculate center of the model.
-	cx = (maxx + minx) / 2.0;
-	cy = (maxy + miny) / 2.0;
-	cz = (maxz + minz) / 2.0;
-
-
-	//	Calculate max dimension.
-	if (w > h)
-	{
-		max	=	w;
-	}
-	else
-	{
-		max	=	h;
-	}
-
-	if (d > max)
-	{
-		max	=	d;
-	}
-	
-	//	Calculate unitizing scale factor.
-	scale = 1.0 / max;
-
-	geoMesh->mMeshBounds.scaleFactor		=	scale;
-
-	//	Translate around center then scale.
-	//	For each submesh.
-	for (int submesh = 0; submesh < geoMesh->mSubMeshCount; submesh++)
-	{
-		//	Gets the actual submesh.
-		vertex_buffer	=	geoMesh->mSubMesh[submesh].mVertexBuffer;
-
-		//	For each index of the strip.
-		for (int i = 0; i < vertex_buffer->mVertexCount; i++)
-		{
-			vertex_buffer->mPosition[i].x -= cx;
-			vertex_buffer->mPosition[i].y -= cy;
-			vertex_buffer->mPosition[i].z -= cz;
-			vertex_buffer->mPosition[i].x *= scale;
-			vertex_buffer->mPosition[i].y *= scale;
-			vertex_buffer->mPosition[i].z *= scale;
-		}
-
-		//	If is a shared vertex Buffer.
-		if (geoMesh->mSubMesh[submesh].mSharedVertexBuffer)
-		{
-			break;
-		}
-	}
-
-}
-
-//---------------------------------------------------------------------------
-//	Get the size in bytes of the file.
-//---------------------------------------------------------------------------
-size_t	GeoMeshLoader::getFileSize()
-{
-	return	mFileSize;
-}
-
-//---------------------------------------------------------------------------
-//	Constructor
-//---------------------------------------------------------------------------
-GeoMeshLoader::GeoMeshLoader()
-{
-	geoMesh			=	NULL;
-	mFileSize		=	0;
-}
-
-//---------------------------------------------------------------------------
-//	Destroyer.
-//---------------------------------------------------------------------------
-GeoMeshLoader::~GeoMeshLoader()
-{
-	delete	geoMesh;
-}
-
-//---------------------------------------------------------------------------
-//	Read bones of the submesh.
-//---------------------------------------------------------------------------
-void GeoMeshLoader::readSubMeshBoneAssignment(FILE* f, SubMesh* geoSubMesh,int option)
-{
-	if (option == GEOMESH_BUILD)
-	{
-		VertexBoneAssignment assign;
-
-		// unsigned int vertexIndex;
-		fread(&(assign.vertexIndex),sizeof(unsigned int),1,f);
-		// unsigned short boneIndex;
-		fread(&(assign.boneIndex),sizeof(unsigned short),1,f);
-		// float weight
-		fread(&(assign.weight),sizeof(float),1,f);
-
-		geoSubMesh->mBones.push_back(assign);
-	}
-}
-
-//---------------------------------------------------------------------------
-//	Read bones of the main mesh.
-//---------------------------------------------------------------------------
-void GeoMeshLoader::readMeshBoneAssignment(FILE* f, Mesh* geoMesh,int option)
-{
-	if (option == GEOMESH_BUILD)
-	{
-		VertexBoneAssignment assign;
-
-		// unsigned int vertexIndex;
-		fread(&(assign.vertexIndex),sizeof(unsigned int),1,f);
-		// unsigned short boneIndex;
-		fread(&(assign.boneIndex),sizeof(unsigned short),1,f);
-		// float weight
-		fread(&(assign.weight),sizeof(float),1,f);
-
-
-		geoMesh->mBones.push_back(assign);
-	}
-}
-
-//---------------------------------------------------------------------------
-//	Read skeleton link.
-//---------------------------------------------------------------------------
-void GeoMeshLoader::readSkeletonLink(FILE* f, Mesh* geoMesh,int option)
-{
-	if (option == GEOMESH_BUILD)
-	{
-		fgets(geoMesh->mSkeletonName,255,f);
-		
-		geoMesh->hasSkeleton	=	true;
-
-		//	Debug.
-		cout	<<	"Skeleton Name: "
-					<<	geoMesh->mSkeletonName
-					<<	endl;
-	}
-}
-
-//---------------------------------------------------------------------------
-//	Read bounding box settings.
-//---------------------------------------------------------------------------
-void	GeoMeshLoader::readMeshBounds(FILE	*f, Mesh	*geoMesh,	int	option)
-{
-	if (option == GEOMESH_BUILD)
-	{
-		fread(&(geoMesh->mMeshBounds.minX),sizeof(float),1,f);
-		fread(&(geoMesh->mMeshBounds.minY),sizeof(float),1,f);
-		fread(&(geoMesh->mMeshBounds.minZ),sizeof(float),1,f);
-		fread(&(geoMesh->mMeshBounds.maxX),sizeof(float),1,f);
-		fread(&(geoMesh->mMeshBounds.maxY),sizeof(float),1,f);
-		fread(&(geoMesh->mMeshBounds.maxZ),sizeof(float),1,f);
-		fread(&(geoMesh->mMeshBounds.radius),sizeof(float),1,f);
-	}
-}
-
-struct face_t
-{
-	int v1,v2,v3;
-	int t1,t2,t3;
-	int n1,n2,n3;
-};
-
-class VertexArranger
-{
-public:
-	VertexArranger(Geometry::Mesh *m){
-		mesh=m;
-		current_submesh=0;
-		current_tris=new int[m->mSubMeshCount];
-		for (int i=0; i<m->mSubMeshCount; i++)
-			current_tris[i] = 0;
-	}
-	~VertexArranger(void){
-		delete[] current_tris;
-	}
-
-	void AddFace(int v1, int v2, int v3, int t1, int t2, int t3, int n1, int n2, int n3){
-		Geometry::SubMesh *submesh = mesh->mSubMesh + current_submesh;
-
-		vertex_arranger_node vertex1(v1,n1,t1);
-		vertex_arranger_node vertex2(v2,n2,t2);
-		vertex_arranger_node vertex3(v3,n3,t3);
-		
-		int j = current_tris[current_submesh];
-
-		std::map<vertex_arranger_node,int>::iterator res;
-		res=vertex_map.find(vertex1);
-		if (res==vertex_map.end())
-		{
-			int val = vertex_map.size();
-			vertex_map[vertex1] = val;
-			submesh->mIndex[j*3+0] = val;
-		}
-		else
-			submesh->mIndex[j*3+0] = res->second;
-
-		res=vertex_map.find(vertex2);
-		if (res==vertex_map.end())
-		{
-			int val = vertex_map.size();
-			vertex_map[vertex2] = val;
-			submesh->mIndex[j*3+1] = val;
-		}
-		else
-			submesh->mIndex[j*3+1] = res->second;
-
-		res=vertex_map.find(vertex3);
-		if (res==vertex_map.end())
-		{
-			int val = vertex_map.size();
-			vertex_map[vertex3] = val;
-			submesh->mIndex[j*3+2] = val;
-		}
-		else
-			submesh->mIndex[j*3+2] = res->second;
-
-		current_tris[current_submesh] ++;
-	}
-
-	int GetVertexCount(void) const { return vertex_map.size(); }
-
-	void SetCurrentSubMesh(int i){ current_submesh = i; }
-	
-	class vertex_arranger_node
-	{
-	public:
-		int v, n, t;
-
-		vertex_arranger_node(void){
-			v=n=t=-1;
-		}
-		vertex_arranger_node(int iv, int in=-1, int it=-1){
-			v=iv;
-			n=in;
-			t=it;
-		}
-
-		bool operator<(const vertex_arranger_node &vu) const {
-			if (v<vu.v) return true;
-			if (v>vu.v) return false;
-			if (n<vu.n) return true;
-			if (n>vu.n) return false;
-			if (t<vu.t) return true;
-			if (t>vu.t) return false;
-			return false;
-		}
-		bool operator==(const vertex_arranger_node &vu) const {
-			return (v==vu.v && v==vu.v && n==vu.n && n==vu.n && t==vu.t && t==vu.t);
-		}	
-	};
-
-/*	VertexArranger::vertex_arranger_node *GetVertexInfo(void) const {
-		vertex_arranger_node * vertex_list = new vertex_arranger_node[GetVertexCount()];
-		for (std::map<vertex_arranger_node,int>::const_iterator it=vertex_map.begin(); it!=vertex_map.end(); it++)
-			vertex_list[it->second] = it->first;
-		return vertex_list;
-	}
-
-	const std::vector<int> GetIndexInfo(void) const { return indices; }*/
-
-	void Arrange( const std::vector<Geometry::Vector3> & vertices, 
-				  const std::vector<Geometry::Vector3> & normals,
-				  const std::vector<Geometry::Vector2> & texcoords){
-
-		mesh->mVertexBuffer=new Geometry::VertexBuffer;
-		mesh->mVertexBuffer->mVertexCount = GetVertexCount();
-		mesh->mVertexBuffer->mPosition = new Geometry::Vector3[mesh->mVertexBuffer->mVertexCount];
-		mesh->mVertexBuffer->mTexCoords = texcoords.empty()?NULL:new Geometry::Vector2[mesh->mVertexBuffer->mVertexCount];
-		mesh->mVertexBuffer->mNormal = normals.empty()?NULL:new Geometry::Vector3[mesh->mVertexBuffer->mVertexCount];
-		mesh->mVertexBuffer->mVertexInfo = Geometry::VERTEX_POSITION | (texcoords.empty()?0:Geometry::VERTEX_TEXCOORDS) | (normals.empty()?0:Geometry::VERTEX_NORMAL);
-
-		// sort the calculated vertices
-		
-		vertex_arranger_node * vertex_list = new vertex_arranger_node[mesh->mVertexBuffer->mVertexCount];
-		for (std::map<vertex_arranger_node,int>::iterator it=vertex_map.begin(); it!=vertex_map.end(); it++)
-			vertex_list[it->second] = it->first;
-
-		for (int i=0; i<mesh->mSubMeshCount; i++)
-			mesh->mSubMesh[i].mVertexBuffer = mesh->mVertexBuffer;
-		
-		for (int j=0; j<mesh->mVertexBuffer->mVertexCount; j++)
-		{		
-			int vi = vertex_list[j].v;
-			int ti = vertex_list[j].t;
-			int ni = vertex_list[j].n;
-
-			Geometry::Vector3 auxpos(vertices[vi]);
-			if (auxpos.x < mesh->mMeshBounds.minX) mesh->mMeshBounds.minX = auxpos.x;
-			if (auxpos.y < mesh->mMeshBounds.minY) mesh->mMeshBounds.minY = auxpos.y;
-			if (auxpos.z < mesh->mMeshBounds.minZ) mesh->mMeshBounds.minZ = auxpos.z;
-			if (auxpos.x > mesh->mMeshBounds.maxX) mesh->mMeshBounds.maxX = auxpos.x;
-			if (auxpos.y > mesh->mMeshBounds.maxY) mesh->mMeshBounds.maxY = auxpos.y;
-			if (auxpos.z > mesh->mMeshBounds.maxZ) mesh->mMeshBounds.maxZ = auxpos.z;
-
-			mesh->mVertexBuffer->mPosition[j] = auxpos;
-			mesh->mVertexBuffer->mNormal[j] = normals[ni];
-			if (texcoords.empty()==false)
-				mesh->mVertexBuffer->mTexCoords[j] = texcoords[ti];		
-		}
-
-		delete[] vertex_list;
-	}
-
-//private:
-	std::map<vertex_arranger_node,int> vertex_map;
-	Geometry::Mesh *mesh;
-	int current_submesh;
-	int *current_tris;
-};
-
-
-void	GeoMeshLoader::importOBJ(FILE *f, Mesh *mesh)
-{
-	mesh->hasSkeleton=false;
-	mesh->mSubMeshCount=0;
-
-	std::vector<Geometry::Vector3> vertices;
-	std::vector<Geometry::Vector3> normals;
-	std::vector<Geometry::Vector2> texcoords;
-	std::vector<std::vector<face_t> > faces;
-	std::vector<face_t> current_faces;
-
-	mesh->mMeshBounds.maxX = -99999999.9f;
-	mesh->mMeshBounds.maxY = -99999999.9f;
-	mesh->mMeshBounds.maxZ = -99999999.9f;
-	mesh->mMeshBounds.minX =  99999999.9f;
-	mesh->mMeshBounds.minY =  99999999.9f;
-	mesh->mMeshBounds.minZ =  99999999.9f;
-	mesh->mMeshBounds.radius = 1.0f;
-	mesh->mMeshBounds.scaleFactor = 1.0f;
-
-	char line[256]="";
-	while(!feof(f))
-	{
-		fgets(line,256,f);
-		if (line[0]=='v' && line[1]==' ')
-		{
-			Geometry::Vector3 v3;
-			sscanf(line+2,"%f %f %f",&v3.x,&v3.y,&v3.z);
-			vertices.push_back(v3);
-		}
-		else if (line[0]=='v' && line[1]=='t')
-		{
-			Geometry::Vector2 v2;
-			sscanf(line+2,"%f %f",&v2.x,&v2.y);
-			texcoords.push_back(v2);
-		}
-		else if (line[0]=='v' && line[1]=='n')
-		{
-			Geometry::Vector3 v3;
-			sscanf(line+2,"%f %f %f",&v3.x,&v3.y,&v3.z);
-			normals.push_back(v3);
-		}
-		else if (line[0]=='f')
-		{
-			face_t auxface;
-			auxface.n1=auxface.n2=auxface.n3=auxface.t1=auxface.t2=auxface.t3=auxface.v1=auxface.v2=auxface.v3=0;
-			int n = sscanf(line+2,"%d/%d/%d %d/%d/%d %d/%d/%d", &auxface.v1,&auxface.t1,&auxface.n1, 
-									  						    &auxface.v2,&auxface.t2,&auxface.n2, 
-																&auxface.v3,&auxface.t3,&auxface.n3);
-			if (n<9)
-			{
-				auxface.n1=auxface.n2=auxface.n3=auxface.t1=auxface.t2=auxface.t3=auxface.v1=auxface.v2=auxface.v3=0;
-				n = sscanf(line+2,"%d//%d %d//%d %d//%d", &auxface.v1,&auxface.n1, 
-														  &auxface.v2,&auxface.n2, 
-														  &auxface.v3,&auxface.n3);
-				if (n<6)
-				{
-					auxface.n1=auxface.n2=auxface.n3=auxface.t1=auxface.t2=auxface.t3=auxface.v1=auxface.v2=auxface.v3=0;
-					n = sscanf(line+2,"%d/%d %d/%d %d/%d", &auxface.v1,&auxface.t1,
-														   &auxface.v2,&auxface.t2, 
-														   &auxface.v3,&auxface.t3);
-					if (n<6)
-					{
-						auxface.n1=auxface.n2=auxface.n3=auxface.t1=auxface.t2=auxface.t3=auxface.v1=auxface.v2=auxface.v3=0;
-						n = sscanf(line+2,"%d %d %d", &auxface.v1,&auxface.v2,&auxface.v3);
-					}
-				}
-			}
-
-			auxface.v1=abs(auxface.v1); auxface.v2=abs(auxface.v2); auxface.v3=abs(auxface.v3);
-			auxface.t1=abs(auxface.t1); auxface.t2=abs(auxface.t2); auxface.t3=abs(auxface.t3);
-			auxface.n1=abs(auxface.n1); auxface.n2=abs(auxface.n2); auxface.n3=abs(auxface.n3);
-			auxface.v1--; auxface.v2--; auxface.v3--;
-			auxface.t1--; auxface.t2--; auxface.t3--;
-			auxface.n1--; auxface.n2--; auxface.n3--;
-			current_faces.push_back(auxface);
-		}
-		else if (line[0]=='g')
-		{
-			if (current_faces.size()>0)
-				faces.push_back(current_faces);
-			current_faces.clear();
-		}
-	}
-
-	if (current_faces.size()>0)
-		faces.push_back(current_faces);
-	current_faces.clear();
-
-	mesh->mSubMeshCount = faces.size();
-	bool found_texcoords=!texcoords.empty();
-
-	if (normals.empty())
-	{
-		// calculate face normals
-		for (int i=0, inormal=0; i<mesh->mSubMeshCount; i++)
-		{
-			Geometry::SubMesh *submesh = mesh->mSubMesh+i;
-			 std::vector<face_t> & vecfaces = faces[i];
-			int j=0;
-			for (std::vector<face_t>::iterator it=vecfaces.begin(); it!=vecfaces.end(); it++,j++,inormal++)
-			{
-				face_t & auxface = *it;
-				auxface.n1 = inormal;
-				auxface.n2 = inormal;
-				auxface.n3 = inormal;
-				Geometry::Vector3 v1,v2,v3,v31,v21,nor;
-				v1 = vertices[auxface.v1];
-				v2 = vertices[auxface.v2];
-				v3 = vertices[auxface.v3];
-				v31 = v3 - v1;
-				v21 = v2 - v1;
-				nor = v21.crossProduct(v31);
-				nor.normalise();
-				normals.push_back(nor);
-			}			
-		}
-	}
-
-	// fill up the mesh structure with the loaded information
-
-	VertexArranger vertex_arranger(mesh);
-		 
-	mesh->mSubMesh=new Geometry::SubMesh[mesh->mSubMeshCount];
-	for (int i=0; i<mesh->mSubMeshCount; i++)
-	{
-		Geometry::SubMesh *submesh = mesh->mSubMesh+i;
-		int j=0;
-		const std::vector<face_t> & vecfaces = faces[i];
-		std::vector<Geometry::Index> aux_indices;
-		submesh->mSharedVertexBuffer = true;
-		submesh->mIndexCount = vecfaces.size()*3;
-		submesh->mIndex=new Geometry::Index[submesh->mIndexCount];
-
-		vertex_arranger.SetCurrentSubMesh(i);
-		
-		for (std::vector<face_t>::const_iterator it=vecfaces.begin(); it!=vecfaces.end(); it++,j++)
-		{
-			const face_t & auxface = *it;
-
-			vertex_arranger.AddFace(auxface.v1,auxface.v2,auxface.v3,
-									auxface.t1,auxface.t2,auxface.t3,
-									auxface.n1,auxface.n2,auxface.n3);
-		}			
-	}
-
-	vertex_arranger.Arrange(vertices,normals,texcoords);
-}
-
Index: P/trunk/Lib/Geom/shared/GeoTool/src/GeoMeshSaver.cpp
===================================================================
--- /GTP/trunk/Lib/Geom/shared/GeoTool/src/GeoMeshSaver.cpp	(revision 1070)
+++ 	(revision )
@@ -1,846 +1,0 @@
-/*==========================================================================
- *	(C) 2005 Universitat Jaume I
- *==========================================================================
- *	PROYECT:	GAME TOOLS
- *==========================================================================*/
-/*	CONTENT:	
- *
- *
- *	@file	GeoMeshSaver.cpp
- *==========================================================================*/
-#include	<GeoMeshSaver.h>
-
-using	namespace	Geometry;
-using	namespace	std;
-
-//---------------------------------------------------------------------------
-//		Public:
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-//	Constructors.
-//---------------------------------------------------------------------------
-GeoMeshSaver::GeoMeshSaver()
-{
-	leavesSubMesh	=	-1;
-	leavesVB			=	NULL;
-	numindices		=	0;
-	indices				=	NULL;
-}
-
-//---------------------------------------------------------------------------
-//	Destroyer.
-//---------------------------------------------------------------------------
-GeoMeshSaver::~GeoMeshSaver()
-{
-	delete	mGeoMesh;
-}
-
-//---------------------------------------------------------------------------
-//	Saves a Mesh into a file.
-//---------------------------------------------------------------------------
-int	GeoMeshSaver::save(Mesh	*geoMesh,	const	char	*fileNameMesh)
-{
-	int			size;
-	String	name(fileNameMesh);
-
-	mGeoMesh	=	new Mesh();
-
-	//	Set the mesh.
-	*mGeoMesh	=	*geoMesh;
-
-	//	Debug.
-	cout	<<	endl
-				<<	endl
-				<<	"-----------------------------------"
-				<<	endl
-				<<	"\t SAVE MESH"
-				<<	endl
-				<<	"-----------------------------------"
-				<<	endl
-				<<	endl;
-
-	//	Unnormalize geometry model.
-	unnormalizeModel(mGeoMesh);
-
-	if (leavesSubMesh>-1 && leavesVB)
-	{
-		Vector3 bmax(geoMesh->mMeshBounds.maxX,geoMesh->mMeshBounds.maxY,geoMesh->mMeshBounds.maxZ);
-		Vector3 bmin(geoMesh->mMeshBounds.minX,geoMesh->mMeshBounds.minY,geoMesh->mMeshBounds.minZ);
-		Vector3 center = (bmax+bmin)*0.5f;
-		float scale = geoMesh->mMeshBounds.scaleFactor;
-		
-		mGeoMesh->mSubMesh[leavesSubMesh].mSharedVertexBuffer=false;
-		mGeoMesh->mSubMesh[leavesSubMesh].mStripCount=0;
-		mGeoMesh->mSubMesh[leavesSubMesh].mIndexCount=numindices;
-		int icount = mGeoMesh->mSubMesh[leavesSubMesh].mIndexCount;
-		mGeoMesh->mSubMesh[leavesSubMesh].mIndex=new Index[icount];
-		for (int i=0; i<icount; i++)
-			mGeoMesh->mSubMesh[leavesSubMesh].mIndex[i]=indices[i];
-
-		mGeoMesh->mSubMesh[leavesSubMesh].mType=GEO_TRIANGLE_LIST;
-		mGeoMesh->mSubMesh[leavesSubMesh].mVertexBuffer=new VertexBuffer();
-		mGeoMesh->mSubMesh[leavesSubMesh].mVertexBuffer->mVertexInfo=VERTEX_POSITION;
-		mGeoMesh->mSubMesh[leavesSubMesh].mVertexBuffer->mVertexCount=leavesVB->mVertexCount;;
-		int vcount = mGeoMesh->mSubMesh[leavesSubMesh].mVertexBuffer->mVertexCount;
-		mGeoMesh->mSubMesh[leavesSubMesh].mVertexBuffer->mPosition=new Vector3[vcount];
-		mGeoMesh->mSubMesh[leavesSubMesh].mVertexBuffer->mNormal=new Vector3[vcount];
-		mGeoMesh->mSubMesh[leavesSubMesh].mVertexBuffer->mTexCoords=new Vector2[vcount];
-		for (int i=0; i<vcount; i++)
-		{
-			mGeoMesh->mSubMesh[leavesSubMesh].mVertexBuffer->mPosition[i].x = leavesVB->mPosition[i].x / scale + center.x;
-			mGeoMesh->mSubMesh[leavesSubMesh].mVertexBuffer->mPosition[i].y = leavesVB->mPosition[i].y / scale + center.y;
-			mGeoMesh->mSubMesh[leavesSubMesh].mVertexBuffer->mPosition[i].z = leavesVB->mPosition[i].z / scale + center.z;
-			mGeoMesh->mSubMesh[leavesSubMesh].mVertexBuffer->mNormal[i].x = leavesVB->mNormal[i].x;
-			mGeoMesh->mSubMesh[leavesSubMesh].mVertexBuffer->mNormal[i].y = leavesVB->mNormal[i].y;
-			mGeoMesh->mSubMesh[leavesSubMesh].mVertexBuffer->mNormal[i].z = leavesVB->mNormal[i].z;
-			mGeoMesh->mSubMesh[leavesSubMesh].mVertexBuffer->mTexCoords[i].x = leavesVB->mTexCoords[i].x;
-			mGeoMesh->mSubMesh[leavesSubMesh].mVertexBuffer->mTexCoords[i].y = leavesVB->mTexCoords[i].y;
-		}
-	}
-
-	//	Open the file.
-	mSerializer	=	new	Serializer(name,Serializer::WRITE);
-
-	//	Write the file header.
-	writeFileHeader();
-
-	//	Write the mesh data.
-	writeMesh(mGeoMesh);
-
-	size	=	mSerializer->GetSize();
-	
-	//	Close the file.
-	delete	mSerializer;
-	
-	//	Return the number of bytes written.
-	return	size;
-}
-
-//------------------------------------------
-//		Private:
-//------------------------------------------
-
-//	Write the main mesh.
-void	GeoMeshSaver::writeMesh(Mesh	*geoMesh)
-{
-	// Header
-	writeChunkHeader(M_MESH, calcMeshSize(geoMesh));
-
-	//	Debug.
-	cout	<<	"		M_MESH"
-				<<	endl;
-
-	//	Write the skeletally animated flag.
-	writeBools(geoMesh->hasSkeleton,1);
-	
-	//	Write shared geometry.
-	if (geoMesh->mVertexBuffer->mVertexCount > 0)
-	{
-		writeGeometry(geoMesh->mVertexBuffer);
-	}
-
-	//	Write submeshes.
-	for (int i = 0;	i < geoMesh->mSubMeshCount;	i++)
-	{
-		writeSubMesh(&geoMesh->mSubMesh[i]);
-	}
-
-	// Write skeleton info if required
-	if (geoMesh->hasSkeleton)
-	{
-		// Write skeleton link
-		writeSkeletonLink(geoMesh->mSkeletonName);
-
-		// Write bone assignments
-		if (!geoMesh->mBones.empty())
-		{
-
-			for (int i = 0; i< geoMesh->mBones.size(); i++)
-			{
-				writeMeshBoneAssignment(geoMesh->mBones[i]);
-			}
-
-		}
-	}
-
-	//	Write the mesh bounds.
-	writeMeshBounds(geoMesh);
-
-	/*
-	// Write LOD data if any
-	if (pMesh->getNumLodLevels() > 1)
-	{
-	LogManager::getSingleton().logMessage("Exporting LOD information....");
-	writeLodInfo(pMesh);
-	LogManager::getSingleton().logMessage("LOD information exported.");
-
-	}
-	// Write bounds information
-	LogManager::getSingleton().logMessage("Exporting bounds information....");
-	writeBoundsInfo(pMesh);
-	LogManager::getSingleton().logMessage("Bounds information exported.");
-
-	// Write submesh name table
-	LogManager::getSingleton().logMessage("Exporting submesh name table...");
-	writeSubMeshNameTable(pMesh);
-	LogManager::getSingleton().logMessage("Submesh name table exported.");
-
-	// Write edge lists
-	if (pMesh->isEdgeListBuilt())
-	{
-	LogManager::getSingleton().logMessage("Exporting edge lists...");
-	writeEdgeList(pMesh);
-	LogManager::getSingleton().logMessage("Edge lists exported");
-	}
-	*/
-}//	End write mesh.
-
-//	Write a submesh.
-void	GeoMeshSaver::writeSubMesh(SubMesh	*geoSubMesh)
-{
-	bool						idx32bit;
-	unsigned	long	indexCount;
-	Index						*index;
-	Index						*indexBegin;
-	Index						*indexEnd;
-
-	// Header.
-	writeChunkHeader(M_SUBMESH, calcSubMeshSize(geoSubMesh));
-
-	//	Debug.
-	cout	<<	"		M_SUBMESH"
-				<<	endl;
-
-	// Material Name.
-	strcat(geoSubMesh->mMaterialName,"\n");
-	mSerializer->WriteData(geoSubMesh->mMaterialName);
-
-	// bool useSharedVertices
-	writeBools(geoSubMesh->mSharedVertexBuffer, 1);
-
-	indexCount	=	geoSubMesh->mIndexCount;
-	
-	/*
-	//	If the submesh is in triangle strips.
-	if (geoSubMesh->mType == GEO_TRIANGLE_STRIPS)
-	{
-		indexCount	+=	(2 * geoSubMesh->mStripCount)
-										-
-										2;
-	}
-	*/
-	
-	//	Write index count.
-	writeInts(indexCount, 1);
-
-	// bool indexes32Bit
-	idx32bit	=	true;
-	writeBools(idx32bit, 1);
-
-	/*
-	//	If the submesh is in triangle strips.
-	if (geoSubMesh->mType == GEO_TRIANGLE_STRIPS)
-	{
-		//	For each one of the strips.
-		for (int strip = 0; strip < geoSubMesh->mStripCount; strip++)
-		{
-			//	First index of the strip.
-			indexBegin	=	geoSubMesh->mStrip[strip];
-
-			//	If is the final strip
-			if (strip	== (geoSubMesh->mStripCount - 1))
-			{
-				//	The end of the index array.
-				indexEnd	= &geoSubMesh->mIndex[geoSubMesh->mIndexCount];
-			}
-			else
-			{
-				//	The beginning of the next strip.
-				indexEnd	= geoSubMesh->mStrip[strip + 1];
-			}
-
-			int i;
-			i	= 0;
-
-			//	Degenerate.
-			if (strip != 0)
-			{
-				writeInts(indexBegin[i], 1);
-			}
-			
-			//	For each index of the strip.
-			for (index = indexBegin; index < indexEnd; index++)
-			{
-				writeInts(indexBegin[i], 1);
-				
-				//	Increments i.
-				i++;
-			}
-
-			//	Degenerate.
-			if (strip	!= (geoSubMesh->mStripCount - 1))
-			{
-				writeInts(indexBegin[i - 1], 1);
-			}
-		}
-	}
-	//	If the submesh is in triangle list.
-	else
-	{
-	*/
-		//	Write the index array.
-		for (int i = 0; i < geoSubMesh->mIndexCount; i++)
-		{
-			writeInts(geoSubMesh->mIndex[i], 1);
-		}
-	//}
-
-	// M_GEOMETRY stream (Optional: present only if useSharedVertices = false)
-	if (!geoSubMesh->mSharedVertexBuffer)
-	{
-		writeGeometry(geoSubMesh->mVertexBuffer);
-	}
-
-	// Operation type
-	writeSubMeshOperation(geoSubMesh);
-
-	// Bone assignments.
-	if (!geoSubMesh->mBones.empty())
-	{
-		for (int i = 0; i < geoSubMesh->mBones.size(); i++)
-		{
-			writeSubMeshBoneAssignment(geoSubMesh->mBones[i]);
-		}
-	}
-}
-
-//	Write the submesh operation chunk and data.
-void GeoMeshSaver::writeSubMeshOperation(const	SubMesh	*geoSubMesh)
-{
-	unsigned 	short opType;
-	unsigned	long	size;
-
-	size	=	CHUNK_OVERHEAD_SIZE	+	sizeof(unsigned	short);
-	
-	// Header
-	writeChunkHeader(M_SUBMESH_OPERATION, size);
-
-	//	Debug.
-	cout	<<	"		M_SUBMESH_OPERATION"
-				<<	endl;
-
-	//	If the mesh is in triangle strips.
-	if (geoSubMesh->mType	==	GEO_TRIANGLE_STRIPS)
-	{
-		opType	=	5;
-	}
-	//	If the mesh is in triangle list.
-	else
-	{
-		opType	=	4;
-	}
-	
-	writeShorts(opType, 1);
-}
-
-//	Write geometry.
-void	GeoMeshSaver::writeGeometry(VertexBuffer	*vertexBuffer)
-{
-	unsigned	short	element;
-	unsigned	long	size;
-	unsigned	short	buffer_count;
-
-	buffer_count	=	3;
-	
-	//	Calculate the size in bytes of the geometry chunk.
-	size	=	calcGeometrySize(vertexBuffer);
-		
-	//	Header.
-	//
-	//	Write the M_GEOMETRY header.
-	writeChunkHeader(M_GEOMETRY, size);
-
-	//	Debug.
-	cout	<<	"		M_GEOMETRY"
-				<<	endl;
-
-	writeInts(vertexBuffer->mVertexCount,1);
-
-	//	Vertex declaration.
-	//	Calculate the size of vertex declaration.
-	size	=	CHUNK_OVERHEAD_SIZE
-					+
-					buffer_count
-					*
-					(CHUNK_OVERHEAD_SIZE	+	(sizeof(unsigned short)	*	5));
-
-	//	Write the vertex declaration header.
-	writeChunkHeader(	M_GEOMETRY_VERTEX_DECLARATION,size);
-
-	//	Debug.
-	cout	<<	"		M_GEOMETRY_VERTEX_DECLARATION"
-				<<	endl;
-
-	//	Obtain the size of the vertex element chunk.
-	size	=	CHUNK_OVERHEAD_SIZE	+	(sizeof(unsigned short)	*	5);
-
-	//	Positions.
-	//	Write the vertex element header for position.
-	writeChunkHeader(	M_GEOMETRY_VERTEX_ELEMENT,size);
-
-	//	Debug.
-	cout	<<	"		M_GEOMETRY_VERTEX_ELEMENT"
-				<<	endl;
-
-	element	=	0;
-	writeShorts(element,1);
-
-	element	=	VET_FLOAT3;
-	writeShorts(element,1);
-	
-	element	=	VES_POSITION;
-	writeShorts(element,1);
-	
-	element	=	0;
-	writeShorts(element,1);
-	
-	element	=	0;
-	writeShorts(element,1);
-
-	//	Normals.
-	//	Write the vertex element header for position.
-	writeChunkHeader(	M_GEOMETRY_VERTEX_ELEMENT,size);
-	
-	//	Debug.
-	cout	<<	"		M_GEOMETRY_VERTEX_ELEMENT"
-				<<	endl;
-
-	element	=	1;
-	writeShorts(element,1);
-	
-	element	=	VET_FLOAT3;
-	writeShorts(element,1);
-	
-	element	=	VES_NORMAL;
-	writeShorts(element,1);
-	
-	element	=	0;
-	writeShorts(element,1);
-	
-	element	=	0;
-	writeShorts(element,1);
-
-	//	Textures.
-	//	Write the vertex element header for position.
-	writeChunkHeader(M_GEOMETRY_VERTEX_ELEMENT,size);
-	
-	//	Debug.
-	cout	<<	"		M_GEOMETRY_VERTEX_ELEMENT"
-				<<	endl;
-
-	element	=	2;
-	writeShorts(element,1);
-	
-	element	=	VET_FLOAT2;
-	writeShorts(element,1);
-	
-	element	=	VES_TEXTURE_COORDINATES;
-	writeShorts(element,1);
-	
-	element	=	0;
-	writeShorts(element,1);
-	
-	element	=	0;
-	writeShorts(element,1);
-
-	//	Obtain the size for vertex buffer header for positons.
-	size	=	(2	*	CHUNK_OVERHEAD_SIZE)	+	(2	*	sizeof(unsigned short));
-
-	//	Write the vertex buffer header for positions.
-	writeChunkHeader(M_GEOMETRY_VERTEX_BUFFER,	size);
-
-	//	Debug.
-	cout	<<	"		M_GEOMETRY_VERTEX_BUFFER"
-				<<	endl;
-
-	element	=	0;
-	writeShorts(element,1);
-	
-	element	=	12;
-	writeShorts(element,1);
-
-	//	Obtain the size for the vertex buffer data header for positions.
-	size	=	CHUNK_OVERHEAD_SIZE
-					+
-					((sizeof(float)	*	3)	*	vertexBuffer->mVertexCount);
-
-	//	Write the vertex buffer data header for positions.
-	writeChunkHeader(M_GEOMETRY_VERTEX_BUFFER_DATA,	size);
-
-	//	Debug.
-	cout	<<	"		M_GEOMETRY_VERTEX_BUFFER_DATA"
-				<<	endl;
-
-	//	Write all the positions coords.
-	mSerializer->WriteArray(vertexBuffer->mPosition,
-													vertexBuffer->mVertexCount);
-
-	//	Obtain the size for vertex buffer header for normals.
-	size	=	(2	*	CHUNK_OVERHEAD_SIZE)	+	(2	*	sizeof(unsigned short));
-
-	//	Write the vertex buffer header.
-	writeChunkHeader(	M_GEOMETRY_VERTEX_BUFFER,	size);
-
-	//	Debug.
-	cout	<<	"		M_GEOMETRY_VERTEX_BUFFER"
-				<<	endl;
-
-	element	=	1;
-	writeShorts(element,1);
-	
-	element	=	12;
-	writeShorts(element,1);
-
-	//	Obtain the size for the vertex buffer data header for normals.
-	size	=	CHUNK_OVERHEAD_SIZE
-					+
-					((sizeof(float)	*	3)	*	vertexBuffer->mVertexCount);
-
-	//	Write the vertex buffer data header for normals.
-	writeChunkHeader(M_GEOMETRY_VERTEX_BUFFER_DATA,	size);
-
-	//	Debug.
-	cout	<<	"		M_GEOMETRY_VERTEX_BUFFER_DATA"
-				<<	endl;
-
-	//	Write all the normals coords.
-	mSerializer->WriteArray(vertexBuffer->mNormal,
-													vertexBuffer->mVertexCount);
-
-	//	Obtain the size for vertex buffer header for textures.
-	size	=	(2	*	CHUNK_OVERHEAD_SIZE)	+	(2	*	sizeof(unsigned short));
-
-	//	Write the vertex buffer header for textures.
-	writeChunkHeader(M_GEOMETRY_VERTEX_BUFFER,	size);
-
-	//	Debug.
-	cout	<<	"		M_GEOMETRY_VERTEX_BUFFER"
-				<<	endl;
-
-	element	=	2;
-	writeShorts(element,1);
-	
-	element	=	8;
-	writeShorts(element,1);
-
-	//	Obtain the size for the vertex buffer data header for textures.
-	size	=	CHUNK_OVERHEAD_SIZE
-					+
-					((sizeof(float)	*	2)	*	vertexBuffer->mVertexCount);
-
-	//	Write the vertex buffer data header for textures.
-	writeChunkHeader(M_GEOMETRY_VERTEX_BUFFER_DATA,	size);
-
-	//	Debug.
-	cout	<<	"		M_GEOMETRY_VERTEX_BUFFER_DATA"
-				<<	endl;
-
-	//	Write all the texture coords.
-	mSerializer->WriteArray(vertexBuffer->mTexCoords,
-													vertexBuffer->mVertexCount);
-}
-
-//	Write Mesh Bounds.
-void	GeoMeshSaver::writeMeshBounds(Mesh	*geoMesh)
-{
-	size_t	size;
-
-	size	=	CHUNK_OVERHEAD_SIZE
-					+
-					(sizeof(float)	*	7);
-
-	writeChunkHeader(M_MESH_BOUNDS,	size);
-
-	//	Debug.
-	cout	<<	"		M_MESH_BOUNDS"
-				<<	endl;
-
-	writeFloats(geoMesh->mMeshBounds.minX,1);
-	writeFloats(geoMesh->mMeshBounds.minY,1);
-	writeFloats(geoMesh->mMeshBounds.minZ,1);
-	writeFloats(geoMesh->mMeshBounds.maxX,1);
-	writeFloats(geoMesh->mMeshBounds.maxY,1);
-	writeFloats(geoMesh->mMeshBounds.maxZ,1);
-	writeFloats(geoMesh->mMeshBounds.radius,1);
-}
-
-//	Calculate the mesh size in bytes.
-size_t GeoMeshSaver::calcMeshSize(const Mesh	*geoMesh)
-{
-	size_t size = CHUNK_OVERHEAD_SIZE;
-
-	// Number of shared vertices
-	size += sizeof(uint32);
-
-	// Geometry
-	if (geoMesh->mVertexBuffer->mVertexCount > 0)
-	{
-		size += calcGeometrySize(geoMesh->mVertexBuffer);
-	}
-
-	// Submeshes
-	for (unsigned short i = 0; i < geoMesh->mSubMeshCount; ++i)
-	{
-		size += calcSubMeshSize(&geoMesh->mSubMesh[i]);
-	}
-
-	//	Mesh Bounds size added.
-	size	+=	CHUNK_OVERHEAD_SIZE
-						+
-						(sizeof(float)	*	7);
-
-	// Skeleton link
-	if (geoMesh->hasSkeleton)
-	{
-		size +=	calcSkeletonLinkSize(geoMesh);
-	}
-
-	/*
-	// Submesh name table
-	size += calcSubMeshNameTableSize(geoMesh);
-
-	// Edge list
-	if (geoMesh->isEdgeListBuilt())
-	{
-		size += calcEdgeListSize(geoMesh);
-	}
-	*/
-	
-	return size;
-}
-
-//	Calc the size in bytes for the submesh.
-size_t GeoMeshSaver::calcSubMeshSize(const SubMesh	*geoSubMesh)
-{
-	size_t size = CHUNK_OVERHEAD_SIZE;
-
-	// Material name
-	size += strlen(geoSubMesh->mMaterialName);
-
-	// bool useSharedVertices
-	size += sizeof(bool);
-	// unsigned int indexCount
-	size += sizeof(unsigned int);
-	// bool indexes32bit
-	size += sizeof(bool);
-
-	// unsigned int* faceVertexIndices 
-	size += sizeof(unsigned int) * geoSubMesh->mIndexCount;
-
-	// Geometry
-	if (!geoSubMesh->mSharedVertexBuffer)
-	{
-		size += calcGeometrySize(geoSubMesh->mVertexBuffer);
-	}
-
-	return size;
-}
-
-//	Calculate the geometry size in bytes.
-size_t GeoMeshSaver::calcGeometrySize(const VertexBuffer* vertexBuffer)
-{
-	unsigned	long		size;
-	unsigned	long		buffer_count;
-
-	//	and another for normals.
-	buffer_count	=	3;
-
-	//	Calculate the size of the Geometry chunk.
-	size	=	CHUNK_OVERHEAD_SIZE	+	sizeof(unsigned int);
-	size	=	size
-					+
-					CHUNK_OVERHEAD_SIZE
-					+
-					buffer_count
-					*
-					(CHUNK_OVERHEAD_SIZE	+	(sizeof(unsigned short)	*	5));
-	size	=	size
-					+
-					buffer_count
-					*
-					(	(CHUNK_OVERHEAD_SIZE		*	2)
-						+
-						(sizeof(unsigned short)	*	2)
-						+
-						vertexBuffer->mVertexCount
-					);
-
-	return size;
-}
-
-//	Calculate the skeleton link size in bytes.
-size_t	GeoMeshSaver::calcSkeletonLinkSize(const Mesh	*geoMesh)
-{
-	size_t	size	=		CHUNK_OVERHEAD_SIZE;
-	size 					+=	strlen(geoMesh->mSkeletonName);
-
-	//	Debug.
-	cout	<<	"Length Skeleton Link: "
-				<<	strlen(geoMesh->mSkeletonName)
-				<<	endl;
-
-	return	size;
-}
-
-//	Write the file header.
-void GeoMeshSaver::writeFileHeader(void)
-{
-	String	mesh_version("[MeshSerializer_v1.30]\n");
-	
-	writeShorts(M_HEADER, 1);
-
-	writeString(mesh_version);
-
-}
-
-//	Write a header chunk given.
-void GeoMeshSaver::writeChunkHeader(unsigned short	id,
-																		unsigned long		size)
-{
-	mSerializer->WriteData(&id,sizeof(unsigned short),1);
-	mSerializer->WriteData(&size,sizeof(unsigned long),1);
-}
-
-//	Write integers into the file.
-void	GeoMeshSaver::writeInts(unsigned long	id,
-															unsigned long	count)
-{
-	mSerializer->WriteData(&id,sizeof(id),count);
-}
-
-//	Write shorts into the file
-void	GeoMeshSaver::writeShorts(unsigned short	id,
-																unsigned long		count)
-{
-	mSerializer->WriteData(&id,sizeof(id),count);
-}
-
-//	Write float into the file.
-void	GeoMeshSaver::writeFloats(float						id,
-																unsigned long		count)
-{
-	mSerializer->WriteData(&id,sizeof(id),count);
-}
-
-//	Write a string into the file.
-void GeoMeshSaver::writeString(const	String	&string)
-{
-	mSerializer->WriteData(string);
-}
-
-//	Write booleans into the file.
-void	GeoMeshSaver::writeBools(	const bool id,
-																unsigned	long		count)
-{
-	mSerializer->WriteData(&id,sizeof(bool),count);
-}
-
-void GeoMeshSaver::writeSkeletonLink(const String& skelName)
-{	
-	writeChunkHeader(M_MESH_SKELETON_LINK, calcSkeletonLinkSize(mGeoMesh));
-
-	//	Debug.
-	cout	<<	"		M_MESH_SKELETON_LINK"
-				<<	endl;
-
-    writeString(skelName);
-}
-
-void GeoMeshSaver::writeMeshBoneAssignment(const VertexBoneAssignment& assign)
-{
-	size_t size = CHUNK_OVERHEAD_SIZE + sizeof(unsigned int) + sizeof(unsigned short)+ sizeof(float);
-
-	writeChunkHeader(M_MESH_BONE_ASSIGNMENT, size);
-
-	// unsigned int vertexIndex;
-	writeInts(assign.vertexIndex, 1);
-	// unsigned short boneIndex;
-	writeShorts(assign.boneIndex, 1);
-	// float weight;
-	writeFloats(assign.weight, 1);
-}
-
-void GeoMeshSaver::writeSubMeshBoneAssignment(const VertexBoneAssignment& assign)
-{
-	size_t size = CHUNK_OVERHEAD_SIZE + sizeof(unsigned int) + sizeof(unsigned short)+ sizeof(float);
-
-	writeChunkHeader(M_SUBMESH_BONE_ASSIGNMENT, size);
-
-	// unsigned int vertexIndex;
-	writeInts(assign.vertexIndex, 1);
-	// unsigned short boneIndex;
-	writeShorts(assign.boneIndex, 1);
-	// float weight;
-	writeFloats(assign.weight, 1);
-}
-
-//	unnormalize geometry model.
-void	GeoMeshSaver::unnormalizeModel(Mesh	*geoMesh)
-{
-	float	maxx;
-	float	maxy;
-	float	maxz;
-	float	minx;
-	float	miny;
-	float	minz;
-	float	cx;
-	float	cy;
-	float	cz;
-	float	scale;
-	
-	VertexBuffer	*vertex_buffer;
-
-	maxx	=	geoMesh->mMeshBounds.maxX;
-	maxy	=	geoMesh->mMeshBounds.maxY;
-	maxz	=	geoMesh->mMeshBounds.maxZ;
-	minx	=	geoMesh->mMeshBounds.minX;
-	miny	=	geoMesh->mMeshBounds.minY;
-	minz	=	geoMesh->mMeshBounds.minZ;
-	scale	=	geoMesh->mMeshBounds.scaleFactor;
-	
-	//	Calculate center of the model.
-	cx = (maxx + minx) / 2.0;
-	cy = (maxy + miny) / 2.0;
-	cz = (maxz + minz) / 2.0;
-
-	//	Translate around center then scale.
-	//	For each submesh.
-
-	bool sharedScaled=false;
-
-	for (int submesh = 0; submesh < geoMesh->mSubMeshCount; submesh++)
-	{
-		//	Gets the actual submesh.
-		vertex_buffer	=	geoMesh->mSubMesh[submesh].mVertexBuffer;
-
-		if (geoMesh->mSubMesh[submesh].mSharedVertexBuffer && sharedScaled)
-			continue;
-			
-		//	For each index of the strip.
-		for (int i = 0; i < vertex_buffer->mVertexCount; i++)
-		{
-			vertex_buffer->mPosition[i].x /= scale;
-			vertex_buffer->mPosition[i].y /= scale;
-			vertex_buffer->mPosition[i].z /= scale;
-			vertex_buffer->mPosition[i].x += cx;
-			vertex_buffer->mPosition[i].y += cy;
-			vertex_buffer->mPosition[i].z += cz;
-		}
-
-		//	If is a shared vertex Buffer.
-		if (geoMesh->mSubMesh[submesh].mSharedVertexBuffer)
-			sharedScaled=true;
-	}
-}
-
Index: /GTP/trunk/Lib/Geom/shared/GeoTool/GeoTool.vcproj
===================================================================
--- /GTP/trunk/Lib/Geom/shared/GeoTool/GeoTool.vcproj	(revision 1024)
+++ /GTP/trunk/Lib/Geom/shared/GeoTool/GeoTool.vcproj	(revision 1083)
@@ -141,10 +141,4 @@
 			</File>
 			<File
-				RelativePath=".\src\GeoMeshLoader.cpp">
-			</File>
-			<File
-				RelativePath=".\src\GeoMeshSaver.cpp">
-			</File>
-			<File
 				RelativePath=".\src\GeoMeshView.cpp">
 			</File>
@@ -165,10 +159,4 @@
 			<File
 				RelativePath=".\include\GeoMaterialLoader.h">
-			</File>
-			<File
-				RelativePath=".\include\GeoMeshLoader.h">
-			</File>
-			<File
-				RelativePath=".\include\GeoMeshSaver.h">
 			</File>
 			<File
