Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SceneEntity.h
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SceneEntity.h	(revision 2865)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SceneEntity.h	(revision 2980)
@@ -27,4 +27,5 @@
 {
 	friend class RenderQueue;
+	friend class EntityMerger;
 
 public:
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Geometry.h
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Geometry.h	(revision 2953)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Geometry.h	(revision 2980)
@@ -12,9 +12,11 @@
 class RenderState;
 
-/** Represents drawable geometry consisting of triangles
+
+/** Represents drawable geometry consisting of triangles.
 */
 class Geometry
 {
-friend class ResourceManager;
+	friend class ResourceManager;
+	friend class EntityMerger;
 
 public:
@@ -27,5 +29,5 @@
 	Geometry(Vector3 *vertices, 
 		     Vector3 *normals, 
-			 float *texcoords, 
+			 Texcoord2 *texcoords, 
 			 int numVertices, 
 			 bool delData);
@@ -56,5 +58,5 @@
 	Vector3 *mNormals;
 
-	float *mTexCoords;
+	Texcoord2 *mTexCoords;
 
 	unsigned int mVboId;
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Geometry.cpp
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Geometry.cpp	(revision 2795)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Geometry.cpp	(revision 2980)
@@ -10,5 +10,5 @@
 Geometry::Geometry(Vector3 *vertices, 
 				   Vector3 *normals,
-				   float *texcoords,
+				   Texcoord2 *texcoords,
 				   int numVertices,
 				   bool delData):
@@ -62,6 +62,6 @@
 	if (mTexCoords)
 	{
-		for (int i = 0; i < mNumVertices * 2; ++ i)
-			data[mNumVertices * 6 + i] = mTexCoords[i];
+		for (int i = 0; i < mNumVertices; ++ i)
+			((Texcoord2 *)data)[mNumVertices * 3 + i] = mTexCoords[i];
 	}
 
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/EntityMerger.cpp
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/EntityMerger.cpp	(revision 2980)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/EntityMerger.cpp	(revision 2980)
@@ -0,0 +1,162 @@
+#include "EntityMerger.h"
+#include "Transform3.h"
+#include "SceneEntity.h"
+#include "Shape.h"
+#include "Geometry.h"
+
+
+using namespace std;
+
+
+namespace CHCDemoEngine 
+{
+
+EntityMerger::EntityMerger(SceneEntity *entity1, SceneEntity *entity2): 
+mEntity1(entity1), mEntity2(entity2)
+{}
+
+
+EntityMerger::~EntityMerger()
+{}
+
+
+SceneEntity *EntityMerger::Merge()
+{
+	Shape *shape1 = mEntity1->GetShape(0);
+	Shape *shape2 = mEntity2->GetShape(0);
+
+	SceneEntity *ent = new SceneEntity(new Transform3());
+
+	Shape *shape = MergeShapes(shape1, shape2, ent);
+	
+	LODLevel *lodLevel = new LODLevel(0);
+
+	lodLevel->AddShape(shape);
+	ent->AddLODLevel(lodLevel);
+
+	return ent;
+}
+
+
+Shape *EntityMerger::MergeShapes(Shape *shape1, Shape *shape2, SceneEntity *parent)
+{
+	Material *mat = shape1->GetMaterial();
+
+	Geometry *geom1 = shape1->GetGeometry();
+	Geometry *geom2 = shape2->GetGeometry();
+
+	Geometry *geom = MergeGeometry(geom1, geom2);
+
+	Shape *shape = new Shape(geom, mat, parent);
+
+	return shape;
+}
+
+
+Geometry *EntityMerger::MergeGeometry(Geometry *geom1, Geometry *geom2)
+{
+	const int size1 = geom1->GetNumTriangles() * 3;
+	const int size2 = geom2->GetNumTriangles() * 3;
+
+	const int size = size1 + size2;
+
+	Vector3 *vertices = new Vector3[size];
+	Vector3 *normals = new Vector3[size];
+
+	Texcoord2 *texcoords;
+	
+	if (geom1->mTexCoords && geom2->mTexCoords)
+		texcoords = new Texcoord2[size];
+	else
+		texcoords = NULL;
+
+	int i = 0;
+
+	for (; i < size1; ++ i)
+	{
+		vertices[i] = geom1->mVertices[i];
+		normals[i] = geom1->mNormals[i];
+
+		if (texcoords)
+			texcoords[i] = geom1->mTexCoords[i];
+	}
+
+	for (; i < size; ++ i)
+	{
+		int idx = i - size1;
+		vertices[i] = geom2->mVertices[idx];
+		normals[i] = geom2->mNormals[idx];
+		
+		if (texcoords) texcoords[i] = geom2->mTexCoords[idx];
+	}
+
+	Geometry *geom = new Geometry(vertices, normals, texcoords, size, true);
+
+	return geom;
+}
+
+
+Shape *EntityMerger::MergeShapes(const ShapeContainer &shapes, SceneEntity *parent)
+{
+	/*Material *mat = shape1->GetMaterial();
+
+	Geometry *geom1 = shape1->GetGeometry();
+	Geometry *geom2 = shape2->GetGeometry();
+
+	Geometry *geom = MergeGeometry(geometries);
+
+	Shape *shape = new Shape(geom, mat, parent);
+
+	return shape;*/
+	return NULL;
+}
+
+
+Geometry *EntityMerger::MergeGeometries(const GeometryContainer &geometries)
+{
+	int size = 0;
+	bool hasTexCoords = true;
+
+	for (size_t i = 0; i < geometries.size(); ++ i)
+	{
+		Geometry *geom = geometries[i];
+		size += geom->GetNumTriangles() * 3;
+
+		if (geom->mTexCoords)
+			hasTexCoords = false;
+	}
+
+	Vector3 *vertices = new Vector3[size];
+	Vector3 *normals = new Vector3[size];
+
+	Texcoord2 *texcoords;
+	
+	if (hasTexCoords)
+		texcoords = new Texcoord2[size];
+	else
+		texcoords = NULL;
+
+	int totalIdx = 0;
+
+	for (size_t i = 0; i < geometries.size(); ++ i)
+	{
+		Geometry *geom = geometries[i];
+
+		for (int j = 0; j < geom->GetNumTriangles() * 3; ++ j)
+		{
+			vertices[totalIdx + j] = geom->mVertices[j];
+			normals[totalIdx + j] = geom->mNormals[j];
+
+			if (hasTexCoords) texcoords[totalIdx + j] = geom->mTexCoords[j];
+		}
+
+		totalIdx += geom->GetNumTriangles() * 3; 
+	}
+
+
+	Geometry *geom = new Geometry(vertices, normals, texcoords, size, true);
+
+	return geom;
+}
+
+}
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ResourceManager.cpp
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ResourceManager.cpp	(revision 2963)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ResourceManager.cpp	(revision 2980)
@@ -192,5 +192,5 @@
 	Vector3 *vertices;
 	Vector3 *normals;
-	float *texcoords;
+	Texcoord2 *texcoords;
 
 
@@ -217,6 +217,6 @@
 	if (texCoordCount)
 	{
-		texcoords = new float[texCoordCount * 2];
-		str.read(reinterpret_cast<char *>(texcoords), sizeof(float) * texCoordCount * 2);
+		texcoords = new Texcoord2[texCoordCount];
+		str.read(reinterpret_cast<char *>(texcoords), sizeof(Texcoord2) * texCoordCount);
 	}
 	else
@@ -224,7 +224,7 @@
 		texcoords = NULL;
 	}
-	
-
-	return new Geometry(vertices, normals, texcoords, vertexCount, true);
+
+	// return new Geometry(vertices, normals, texcoords, vertexCount, true);
+	return new Geometry(vertices, normals, texcoords, vertexCount, false);
 }
 
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/EntityMerger.h
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/EntityMerger.h	(revision 2980)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/EntityMerger.h	(revision 2980)
@@ -0,0 +1,46 @@
+#ifndef __ENTITYMERGER_H
+#define __ENTITYMERGER_H
+
+#include "common.h"
+
+
+namespace CHCDemoEngine 
+{
+
+class Material;
+class Transform3;
+class SceneEntity;
+class Geometry;
+class Shape;
+
+
+/** Class representing a scene entity merger
+	It merges two scene entities and creates a new one
+*/
+class EntityMerger
+{
+public:
+	
+	/** Creates a scene entity.
+	*/
+	EntityMerger(SceneEntity *entity1, SceneEntity *entity2);
+	~EntityMerger();
+
+	SceneEntity *Merge();
+
+protected:
+
+	Geometry *MergeGeometry(Geometry *geom1, Geometry *geom2);
+	Shape *MergeShapes(Shape *shape1, Shape *shape2, SceneEntity *parent);
+
+	Geometry *MergeGeometries(const GeometryContainer &geometries);
+	Shape *MergeShapes(const ShapeContainer &shapes, SceneEntity *parent);
+
+
+	SceneEntity *mEntity1;
+	SceneEntity *mEntity2;
+};
+
+}
+
+#endif // __ENTITYMERGER_H
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp	(revision 2978)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp	(revision 2980)
@@ -40,4 +40,5 @@
 #include "SkyPreetham.h"
 #include "Texture.h"
+#include "EntityMerger.h"
 
 
@@ -58,4 +59,5 @@
 /// the renderable scene geometry
 SceneEntityContainer sceneEntities;
+SceneEntityContainer sceneEntities2;
 // traverses and renders the hierarchy
 RenderTraverser *traverser = NULL;
@@ -262,5 +264,4 @@
 
 
-
 /////////
 //-- cg stuff
@@ -449,6 +450,44 @@
 	}
 
-	
-	
+	SceneEntityContainer::const_iterator sit, sit_end = sceneEntities.end();
+
+	int merged = 0;
+	
+	SceneEntity *oldEnt = NULL;
+
+	cout << "merging entities .. " << endl;
+
+	for (sit = sceneEntities.begin(); sit < sit_end; ++ sit)
+	{
+		SceneEntity *newEnt = (*sit);
+
+		if (!newEnt->GetTransform()->IsIdentity())
+		{
+			sceneEntities2.push_back(newEnt);
+			continue;
+		}
+
+		if (oldEnt)
+		{
+			EntityMerger merger(newEnt, oldEnt);
+			SceneEntity *ent = merger.Merge();
+
+			sceneEntities2.push_back(ent);
+
+			oldEnt = NULL;
+
+			++ merged;
+		}
+		else
+		{
+			oldEnt = newEnt;
+		}
+	}
+
+	if (oldEnt && oldEnt->GetTransform()->IsIdentity())
+		sceneEntities2.push_back(oldEnt);
+
+	cout << "merged " << merged << " of " << (int)sceneEntities.size() << " entities " << endl;
+
 	// set far plane based on scene extent
 	farDist = 10.0f * Magnitude(bvh->GetBox().Diagonal());
@@ -611,4 +650,5 @@
 {
 	PrintGLerror("fbo start");
+
 	// this fbo basicly stores the scene information we get from standard rendering of a frame
 	// we store colors, normals, positions (for the ssao)
@@ -1096,18 +1136,24 @@
 	{
 		// actually render the scene geometry using the specified algorithm
-		traverser->RenderScene();
+		//traverser->RenderScene();
+
 	/*
 		state.Reset();
 		aeroplane->Render(&state);
-
-	SceneEntityContainer::const_iterator sit, sit_end = sceneEntities.end();
+*/
+
+#if 0
+		SceneEntityContainer::const_iterator sit, sit_end = sceneEntities.end();
 
 		for (sit = sceneEntities.begin(); sit != sit_end; ++ sit)
-		{
 			renderQueue->Enqueue(*sit);
-		}
-
+#else
+
+		SceneEntityContainer::const_iterator sit, sit_end = sceneEntities2.end();
+
+		for (sit = sceneEntities2.begin(); sit != sit_end; ++ sit)
+			renderQueue->Enqueue(*sit);
+#endif
 		renderQueue->Apply();
-		*/
 	}
 
@@ -1115,5 +1161,4 @@
 	/////////
 	//-- do the rest of the rendering
-
 	
 	// reset depth pass and render visible objects
@@ -1772,4 +1817,6 @@
 	DEL_PTR(fbo);
 	DEL_PTR(ssaoShader);
+
+	CLEAR_CONTAINER(sceneEntities2);
 
 	if (sCgMrtVertexProgram)
@@ -2085,5 +2132,6 @@
 	state.SetUseAlphaToCoverage(false);
 
-	// change CHC++ set of state variables (must be done for each change of camera because
+	// change CHC++ set of state variables 
+	// this must be done for each change of camera because
 	// otherwise the temporal coherency is broken
 	BvhNode::SetCurrentState(1);
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/common.h
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/common.h	(revision 2966)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/common.h	(revision 2980)
@@ -31,5 +31,5 @@
 class Polygon3;
 class Vector3;
-
+class Geometry;
 
 
@@ -492,4 +492,5 @@
 
 typedef std::vector<Shape *> ShapeContainer;
+typedef std::vector<Geometry *> GeometryContainer;
 typedef std::vector<LODLevel *> LODLevelContainer;
 typedef std::vector<Polygon3 *> PolygonContainer;
@@ -497,4 +498,6 @@
 typedef std::vector<Vector3> VertexArray;
 
+typedef std::pair<float, float> Texcoord2;
+
 
 static std::ofstream Debug("debug.log");
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/FriendlyCulling.vcproj
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/FriendlyCulling.vcproj	(revision 2975)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/FriendlyCulling.vcproj	(revision 2980)
@@ -609,4 +609,12 @@
 				</File>
 				<File
+					RelativePath=".\src\EntityMerger.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\src\EntityMerger.h"
+					>
+				</File>
+				<File
 					RelativePath=".\src\FrameBufferObject.cpp"
 					>
