Index: /GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoLodManager.h
===================================================================
--- /GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoLodManager.h	(revision 1069)
+++ /GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoLodManager.h	(revision 1071)
@@ -22,11 +22,10 @@
 	{
 	public:
-		lodobj_dist_node_t(LodObject *o):dist2cam(0.0f),lodobj(o),must_recalculate_distance(true){}
-		lodobj_dist_node_t(const lodobj_dist_node_t &c):dist2cam(c.dist2cam),lodobj(c.lodobj),must_recalculate_distance(c.must_recalculate_distance){}
-		lodobj_dist_node_t(void):dist2cam(0.0f),lodobj(NULL),must_recalculate_distance(true){}
+		lodobj_dist_node_t(LodObject *o):dist2cam(0.0f),lodobj(o){}
+		lodobj_dist_node_t(const lodobj_dist_node_t &c):dist2cam(c.dist2cam),lodobj(c.lodobj){}
+		lodobj_dist_node_t(void):dist2cam(0.0f),lodobj(NULL){}
 		float dist2cam;
 		LodObject *lodobj;
 		bool operator < (const lodobj_dist_node_t &o) const { return (dist2cam < o.dist2cam); }
-		bool must_recalculate_distance;
 	};
 
Index: /GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoLodManager.cpp
===================================================================
--- /GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoLodManager.cpp	(revision 1069)
+++ /GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoLodManager.cpp	(revision 1071)
@@ -18,6 +18,8 @@
 	{
 	public:
-		lodobj_idpos_node_t(LodObject *o):lodobj(o){}
+		lodobj_idpos_node_t(LodObject *o):lodobj(o),must_recalculate_distance(true),dist2cam(0.0f){}
 		LodObject *lodobj;
+		float dist2cam; // used to index the lodobj in the other map
+		bool must_recalculate_distance;
 		bool operator < (const lodobj_idpos_node_t &o) const { return (lodobj->GetUniqueID()<o.lodobj->GetUniqueID()); }
 	};
@@ -45,9 +47,34 @@
 	if (camera_changed)
 	{
-		// if the camera has changed, recalculate all lodobject distances to it
-		float random_dist = SelectRandomDistance();
-
+		// if the camera has changed, recalculate all lodobject distances to it		
+		lodobj_dists.clear();
+		for (std::map<Geometry::lodobj_idpos_node_t,Geometry::Vector3>::iterator it = lodobj_pos.begin(); it != lodobj_pos.end(); it++)
+		{
+			const lodobj_idpos_node_t & posnode = it->first;
+			const Vector3 & pos = it->second;
+			float newdist = CalculateDistToCamera(pos);
+			lodobj_dists[newdist] = lodobj_dist_node_t(posnode.lodobj);
+		}
 		camera_changed=false;
 	}
+	else
+	{
+		// if any of the objects changed its position, the distance must be recalculated
+		for (std::map<Geometry::lodobj_idpos_node_t,Geometry::Vector3>::iterator it = lodobj_pos.begin(); it != lodobj_pos.end(); it++)
+		{
+			const lodobj_idpos_node_t & posnode = it->first;
+			if (posnode.must_recalculate_distance)
+			{
+				const Vector3 & pos = it->second;
+				float newdist = CalculateDistToCamera(pos);
+				lodobj_dists[newdist] = lodobj_dist_node_t(posnode.lodobj);
+/*				lodobj_dists.erase(it);*/
+			}
+		}
+	}
+
+	// select a tree to change its LOD
+	float random_dist = SelectRandomDistance();
+	std::map<float,Geometry::lodobj_dist_node_t>::iterator nearest = lodobj_dists.upper_bound(random_dist);
 }
 
Index: /GTP/trunk/Lib/Geom/shared/GTGeometry/GTGeometry.vcproj
===================================================================
--- /GTP/trunk/Lib/Geom/shared/GTGeometry/GTGeometry.vcproj	(revision 1069)
+++ /GTP/trunk/Lib/Geom/shared/GTGeometry/GTGeometry.vcproj	(revision 1071)
@@ -317,7 +317,4 @@
 					RelativePath=".\src\libs\vmi\src\simplify.cpp">
 				</File>
-				<File
-					RelativePath=".\src\libs\vmi\src\WriteTGA.cpp">
-				</File>
 			</Filter>
 		</Filter>
@@ -436,4 +433,7 @@
 			<File
 				RelativePath=".\include\VertexData.h">
+			</File>
+			<File
+				RelativePath=".\src\libs\vmi\src\WriteTGA.cpp">
 			</File>
 			<Filter
Index: /GTP/trunk/Lib/Geom/shared/GeoTool/src/GeoMeshLoader.cpp
===================================================================
--- /GTP/trunk/Lib/Geom/shared/GeoTool/src/GeoMeshLoader.cpp	(revision 1070)
+++ /GTP/trunk/Lib/Geom/shared/GeoTool/src/GeoMeshLoader.cpp	(revision 1071)
@@ -1381,31 +1381,150 @@
 };
 
-
-class vertex_arranger_node
+class VertexArranger
 {
 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(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;
 };
 
@@ -1532,5 +1651,5 @@
 	// fill up the mesh structure with the loaded information
 
-	std::map<vertex_arranger_node,int> vertex_map;
+	VertexArranger vertex_arranger(mesh);
 		 
 	mesh->mSubMesh=new Geometry::SubMesh[mesh->mSubMeshCount];
@@ -1544,4 +1663,6 @@
 		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++)
@@ -1549,79 +1670,11 @@
 			const face_t & auxface = *it;
 
-			vertex_arranger_node v1(auxface.v1,auxface.n1,auxface.t1);
-			vertex_arranger_node v2(auxface.v2,auxface.n2,auxface.t2);
-			vertex_arranger_node v3(auxface.v3,auxface.n3,auxface.t3);
-
-			std::map<vertex_arranger_node,int>::iterator res;
-			res=vertex_map.find(v1);
-			if (res==vertex_map.end())
-			{
-				int val = vertex_map.size();
-				vertex_map[v1] = val;
-				submesh->mIndex[j*3+0] = val;
-			}
-			else
-				submesh->mIndex[j*3+0] = res->second;
-
-			res=vertex_map.find(v2);
-			if (res==vertex_map.end())
-			{
-				int val = vertex_map.size();
-				vertex_map[v2] = val;
-				submesh->mIndex[j*3+1] = val;
-			}
-			else
-				submesh->mIndex[j*3+1] = res->second;
-
-			res=vertex_map.find(v3);
-			if (res==vertex_map.end())
-			{
-				int val = vertex_map.size();
-				vertex_map[v3] = val;
-				submesh->mIndex[j*3+2] = val;
-			}
-			else
-				submesh->mIndex[j*3+2] = res->second;
+			vertex_arranger.AddFace(auxface.v1,auxface.v2,auxface.v3,
+									auxface.t1,auxface.t2,auxface.t3,
+									auxface.n1,auxface.n2,auxface.n3);
 		}			
 	}
 
-	mesh->mVertexBuffer=new Geometry::VertexBuffer;
-	mesh->mVertexBuffer->mVertexCount = vertex_map.size();
-	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 (found_texcoords)
-			mesh->mVertexBuffer->mTexCoords[j] = texcoords[ti];		
-	}
-
-	delete[] vertex_list;
-}
-
+	vertex_arranger.Arrange(vertices,normals,texcoords);
+}
+
