Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Texture.cpp
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Texture.cpp	(revision 3214)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Texture.cpp	(revision 3261)
@@ -54,5 +54,6 @@
 		mImage = malloc(GetByteSize());
 
-		Debug << "successfully loaded texture " << filename << " w " << mWidth << " h " << mHeight << endl;
+		Debug << "loaded texture " << filename << " w " << mWidth << " h " << mHeight << endl;
+		//cout  << "loaded texture " << filename << " w " << mWidth << " h " << mHeight << endl;
 
 		ilCopyPixels(0, 0, 0, mWidth, mHeight, 1, IL_RGBA, IL_UNSIGNED_BYTE, mImage);
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ObjExporter.h
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ObjExporter.h	(revision 3261)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ObjExporter.h	(revision 3261)
@@ -0,0 +1,29 @@
+#ifndef __OBJEXPORTER_H
+#define __OBJEXPORTER_H
+
+#include "common.h"
+#include "Bvh.h"
+#include <map>
+
+
+namespace CHCDemoEngine
+{
+
+/** Class for exporting bvh to Jiris format
+*/
+class ObjExporter
+{
+public:
+
+	bool Export(const std::string &filename, Bvh *bvh);
+
+
+public:
+
+	int WriteGeometry(Geometry *geom, std::ofstream &ostream);
+};
+
+
+}
+
+#endif
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ObjExporter.cpp
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ObjExporter.cpp	(revision 3261)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ObjExporter.cpp	(revision 3261)
@@ -0,0 +1,100 @@
+#include "ObjExporter.h"
+#include "SceneEntity.h"
+#include "Shape.h"
+#include "Geometry.h"
+
+
+using namespace std;
+
+// MAGIC of all bin exports
+#ifndef MAGIC 
+#define MAGIC 0x827923
+#endif
+
+#define BVH_VERSION 2.1
+
+namespace CHCDemoEngine
+{
+
+static int currentIdx = 0;
+
+
+int ObjExporter::WriteGeometry(Geometry *geom, ofstream &ostream)
+{
+	int numVertices;
+	Vector3 *vertices = geom->GetVertices(numVertices);
+
+	//cout << "vtx: " << numVertices << endl;
+	for (int i = 0; i < numVertices; ++ i)
+	{
+		Vector3 v = vertices[i];
+		ostream << "v " << v.x << " " << v.y << " " << v.z << endl;
+	}
+
+	return numVertices;
+}
+
+
+bool ObjExporter::Export(const string &filename, Bvh *bvh)
+{
+	 cout << "Exporting obj to file '" << filename.c_str() << "'" << endl;
+  
+	 ofstream ostream(filename.c_str());
+
+	 if (!ostream.is_open()) 
+	 {
+		 cerr << "Error: Cannot open file " << filename.c_str() << " for writing" << endl;
+		 return false;
+	 }
+
+	 int numVertices = 0;
+
+	 BvhLeafContainer nodes;
+	 bvh->CollectLeaves(bvh->GetStaticRoot(), nodes);
+
+	 cout << "writing " << nodes.size() << " objects ..." << endl; 
+
+	 BvhLeafContainer::const_iterator it, it_end = nodes.end();
+
+	 int j = 0;
+	 const int t = 1000;
+
+	 for (it = nodes.begin(); it != it_end; ++ it, ++ j)
+	 {
+		 if  ((j % t) == (t - 1))
+			 cout << j + 1 << endl;
+
+		 BvhNode *node = *it;
+
+		 int geometrySize;
+		 SceneEntity **entities = bvh->GetGeometry(node, geometrySize);
+
+		 for (int i = 0; i < geometrySize; ++ i)
+		 {
+			 ShapeContainer::iterator sit, send;
+
+			 entities[i]->GetLODLevel(0, sit, send);
+
+			 for (; sit != send; ++ sit)
+			 {
+				 Geometry *geom = (*sit)->GetGeometry();
+				 numVertices += WriteGeometry(geom, ostream);
+			 }
+		 }
+	 }
+
+	 cout << "finished" << endl;
+	 cout << "writing " << numVertices << " indices ..." << endl;
+
+	 for (int i = 0; i < numVertices; i += 3)
+	 {
+		 ostream << "f " << i << " " << i + 1 << " " << i + 2 << endl;
+	 }
+
+	 cout << "successfully exported obj" << endl;
+	
+	 return true;
+}
+
+
+}
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Texture.h
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Texture.h	(revision 3214)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Texture.h	(revision 3261)
@@ -22,5 +22,5 @@
 
 
-	/** Constructor loading texture from file
+	/** Constructor loading a texture from a file
 	*/
 	Texture(const std::string &filename);
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ResourceManager.cpp
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ResourceManager.cpp	(revision 3260)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ResourceManager.cpp	(revision 3261)
@@ -383,6 +383,6 @@
 	}
 
-	//const bool delGeometry = true;
-	const bool delGeometry = false;
+	const bool delGeometry = true;
+	//const bool delGeometry = false;
 	return new Geometry(vertices, normals, texcoords, vertexCount, delGeometry, NULL);//tangents);
 }
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp	(revision 3260)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp	(revision 3261)
@@ -587,13 +587,29 @@
 	//LoadModel("sibenik.dem", dynamicObjects);
 
+	LoadModel("procedural_pompeii_area6_hires/pompeii.dem", dynamicObjects);
+
+	AxisAlignedBox3 box;
+	box.Initialize();
+
+	const Vector3 offs(.0f, 3000.0f, 180);
+	//const Vector3 sceneCenter(470.398f, 240.364f, 180.3);
+	Matrix4x4 moffs = TranslationMatrix(offs);
+
+	for (size_t i = 0; i < dynamicObjects.size(); ++ i)
+	{
+		dynamicObjects[i]->GetTransform()->SetMatrix(moffs);
+		box.Include(dynamicObjects[i]->GetWorldBoundingBox());
+	}
+
+	cout << "pompeii bb:\n" << box << endl;
+
 #if 0
-	LoadModel("hbuddha.dem", dynamicObjects);
-
-	buddha = dynamicObjects.back();
-	
 	const Vector3 sceneCenter(470.398f, 240.364f, 181.7f);
 	//const Vector3 sceneCenter(470.398f, 240.364f, 180.3);
-	
 	Matrix4x4 transl = TranslationMatrix(sceneCenter);
+	
+	LoadModel("hbuddha.dem", dynamicObjects);
+
+	buddha = dynamicObjects.back();
 	buddha->GetTransform()->SetMatrix(transl);
 
@@ -646,6 +662,6 @@
 
 
-	ObjExporter().Export(model_path + "mycity.obj", bvh);
-	BvhExporter().Export(model_path + "mycity.bvh", bvh);
+	//ObjExporter().Export(model_path + "mycity.obj", bvh);
+	//BvhExporter().Export(model_path + "mycity.bvh", bvh);
 
 
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/BvhExporter.cpp
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/BvhExporter.cpp	(revision 3260)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/BvhExporter.cpp	(revision 3261)
@@ -78,5 +78,5 @@
 bool BvhExporter::Export(const string &filename, Bvh *bvh)
 {
-	 cout << "Info: Exporting to file '" << filename.c_str() << "'" << endl;
+	 cout << "Exporting bvh to file '" << filename.c_str() << "'" << endl;
   
 	 FILE *fw = fopen(filename.c_str(), "wb");
@@ -121,10 +121,14 @@
 	 }
 
+	 cout << "writing " << (int)triangles.size() << " triangle ids ..." << endl;
+
 	 // export sorted triangle IDs
-	 for (int i = 0; i < triangles.size(); ++i) 
+	 for (int i = 0; i < (int)triangles.size(); ++i) 
 	 {
 		 fwrite(&triangles[i], sizeof(int), 1, fw);
 	 }
 
+	 cout << "writing bvh nodes ..." << endl;
+	 
 	 SaveNode(bvh->GetStaticRoot(), fw);
 	 
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/MainApp.vcproj
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/MainApp.vcproj	(revision 3258)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/MainApp.vcproj	(revision 3261)
@@ -154,9 +154,10 @@
 				IgnoreAllDefaultLibraries="false"
 				IgnoreDefaultLibraryNames="LIBCMT"
-				GenerateDebugInformation="true"
+				GenerateDebugInformation="false"
 				SubSystem="1"
 				LargeAddressAware="2"
 				OptimizeReferences="2"
 				EnableCOMDATFolding="2"
+				OptimizeForWindows98="1"
 				TargetMachine="1"
 			/>
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/Converter/ObjConverter.cpp
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/Converter/ObjConverter.cpp	(revision 3260)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/Converter/ObjConverter.cpp	(revision 3261)
@@ -30,5 +30,4 @@
 	{
 		string s(pch);
-		//s += "\n",
 		triples.push_back(s);
 		
@@ -104,5 +103,4 @@
 			if (!normals.empty())
 			{
-				//if (dummy < 3) cout << nIndices[idx1] << " " << nIndices[idx2] << " " << nIndices[idx3] << endl;
 				faceNormals.push_back(normals[nIndices[idx1]]);
 				faceNormals.push_back(normals[nIndices[idx2]]);
@@ -140,11 +138,5 @@
 {
 	for (size_t i = 0; i < mGeometry.size(); ++ i)
-	{
-		delete [] mGeometry[i]->mVertices;
-		delete [] mGeometry[i]->mNormals;
-		delete [] mGeometry[i]->mTexcoords;
-
 		delete mGeometry[i];
-	}
 	
 	mGeometry.clear();
@@ -211,11 +203,5 @@
 	
 	for (size_t i = 0; i < mGeometry.size(); ++ i)
-	{
-		delete [] mGeometry[i]->mVertices;
-		delete [] mGeometry[i]->mNormals;
-		delete [] mGeometry[i]->mTexcoords;
-
 		delete mGeometry[i];
-	}
 	
 	mGeometry.clear();
@@ -306,4 +292,5 @@
 					++ mNumShapes;
 
+					if (!currentMat) cout << "here3" << endl;
 					LoadShape(faceVertices, faceNormals, faceTexcoords, currentMat);
 
@@ -323,5 +310,5 @@
 
 				currentMat = mMaterialTable[matName];
-				cout << "matname: " << matName << endl;
+				//cout << "matname: " << matName << endl;
 			}
 
@@ -538,4 +525,6 @@
 		Material *mat = (*it)->mMaterial;
 
+		if (!mat) cerr << "error: no material specified!!" << endl;
+
 		ofile.write(reinterpret_cast<char *>(&mat->texture), sizeof(int));
 
@@ -628,5 +617,4 @@
 		{
 			string s(pch);
-			//s += "\n",
 			strings.push_back(s);
 
@@ -634,8 +622,5 @@
 		}
 
-		cout << endl;
-
-		
-		if ((strings.size() == 2) && (strcmp(strings[0].c_str(),"newmtl") == 0))
+		if ((strings.size() == 2) && (strcmp(strings[0].c_str(), "newmtl") == 0))
 		{
 			currentMat = new Material();
@@ -643,5 +628,5 @@
 		}
 
-		if ((strings.size() == 2) && (strcmp(strings[0].c_str(),"map_Kd") == 0))
+		if ((strings.size() == 2) && (strcmp(strings[0].c_str(), "map_Kd") == 0))
 		{
 			TextureTable::const_iterator it = mTextureTable.find(strings[1]);
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/Converter/ObjConverter2.cpp
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/Converter/ObjConverter2.cpp	(revision 3261)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/Converter/ObjConverter2.cpp	(revision 3261)
@@ -0,0 +1,595 @@
+#include "ObjConverter2.h"
+#include "SimpleTri.h"
+#include "SimpleVec.h"
+#include "gzstream.h"
+#include <iostream>
+
+
+using namespace std;
+
+
+static void LoadIndices(char *str, 
+						const VertexArray &vertices, 
+						const VertexArray &normals, 
+						const vector<pair<float, float> > &texcoords,
+						VertexArray &faceVertices,
+						VertexArray &faceNormals,
+						vector<Texcoord> &faceTexcoords
+						)
+{
+	vector<string> triples;
+
+	char *next_token;
+
+	// extract the triples of the form v/t/n v/t/n ...
+	char *pch = strtok_s(str + 1, " ", &next_token);
+
+	while (pch)
+	{
+		string s(pch);
+		//s += "\n",
+		triples.push_back(s);
+		
+		pch = strtok_s(NULL, " ", &next_token);	  
+	}
+
+	vector<int> indices;
+	vector<int> nIndices;
+	vector<int> tIndices;
+
+	char seps[] = " /\t\n";
+
+	for (size_t i = 0; i < triples.size(); ++ i)
+	{
+		static int dummy = 0;
+
+		size_t found;
+		found = triples[i].find_first_of(seps);
+		size_t prevfound = 0;
+		// vertex, normal, texture indices
+		string str = triples[i].substr(prevfound, found);
+
+		int index = (int)strtol(str.c_str(), NULL, 10) - 1;
+
+		int tIndex = index;
+		int nIndex = index;	
+		
+		prevfound = found;
+		found = triples[i].find_first_of(seps, found + 1);  
+
+		if (found != string::npos)
+		{
+			str = triples[i].substr(prevfound, found);
+
+			int idx = (int)strtol(str.c_str(), NULL, 10) - 1;
+			if (idx > 0) tIndex = idx;
+		}
+
+		if ((found + 1) < triples[i].size())
+		{
+			str = triples[i].substr(found + 1);
+
+			int idx = (int)strtol(str.c_str(), NULL, 10) - 1;
+			if (idx > 0) nIndex = idx;
+		}
+
+		// store indices
+		if (index >= 0)
+		{
+			indices.push_back(index);
+			nIndices.push_back(nIndex);
+			tIndices.push_back(tIndex);
+		}
+
+		// new triangle found
+		if (indices.size() > 2)
+		{
+			// change orientation of faces?
+#if 1
+			int idx1 = 0;
+			int idx2 = (int)indices.size() - 2;
+			int idx3 = (int)indices.size() - 1;
+#else
+			int idx3 = 0;
+			int idx2 = (int)indices.size() - 2;
+			int idx1 = (int)indices.size() - 1;
+#endif
+			faceVertices.push_back(vertices[indices[idx1]]);
+			faceVertices.push_back(vertices[indices[idx2]]);
+			faceVertices.push_back(vertices[indices[idx3]]);
+
+
+			if (!normals.empty())
+			{
+				faceNormals.push_back(normals[nIndices[idx1]]);
+				faceNormals.push_back(normals[nIndices[idx2]]);
+				faceNormals.push_back(normals[nIndices[idx3]]);
+			}
+			else
+			{
+				// no face normals? => create normals
+				const SimpleTri tri(vertices[indices[idx1]],
+					                vertices[indices[idx2]], 
+									vertices[indices[idx3]]);
+				const SimpleVec n = tri.GetNormal();
+
+				faceNormals.push_back(n);
+				faceNormals.push_back(n);
+				faceNormals.push_back(n);
+			}
+
+			if (!texcoords.empty())
+			{
+				faceTexcoords.push_back(texcoords[tIndices[idx1]]);
+				faceTexcoords.push_back(texcoords[tIndices[idx2]]);
+				faceTexcoords.push_back(texcoords[tIndices[idx3]]);
+			}
+		}
+	}
+}
+
+
+ObjConverter2::ObjConverter2()
+{}
+
+
+ObjConverter2::~ObjConverter2()
+{
+	for (size_t i = 0; i < mGeometry.size(); ++ i)
+		delete mGeometry[i];
+	
+	mGeometry.clear();
+}
+
+
+void ObjConverter2::LoadShape(const VertexArray &faceVertices,
+							  const VertexArray &faceNormals,
+							  const vector<Texcoord> &faceTexcoords,
+							  Material *mat)
+{
+	int numElements = (int)faceVertices.size();
+	Geometry *geom = new Geometry();
+
+	// convert the triangles to geometry
+	geom->mVertices = new SimpleVec[numElements];
+	geom->mNormals = new SimpleVec[numElements];
+	geom->mTexcoords = new Texcoord[numElements];
+
+	geom->mVertexCount = numElements;
+	geom->mTexcoordCount = (int)faceTexcoords.size();
+
+	geom->mMaterial = mat;
+
+	cout << "creating new geometry with " << numElements << " vertices" << endl;
+
+	for (int i = 0; i < numElements; ++ i)
+	{
+#if 1
+		// convert to our camera system: change y and z
+		geom->mVertices[i].x = faceVertices[i].x;
+		geom->mVertices[i].y = -faceVertices[i].z;
+		geom->mVertices[i].z = faceVertices[i].y;
+	
+		geom->mNormals[i].x = faceNormals[i].x;
+		geom->mNormals[i].y = -faceNormals[i].z;
+		geom->mNormals[i].z = faceNormals[i].y;
+
+#else
+		geom->mVertices[i].x = faceVertices[i].x;
+		geom->mVertices[i].y = faceVertices[i].y;
+		geom->mVertices[i].z = faceVertices[i].z;
+	
+		geom->mNormals[i].x = faceNormals[i].x;
+		geom->mNormals[i].y = faceNormals[i].y;
+		geom->mNormals[i].z = faceNormals[i].z;
+
+#endif
+
+		if (i < geom->mTexcoordCount)
+		{
+			geom->mTexcoords[i].first = faceTexcoords[i].first;
+			geom->mTexcoords[i].second = faceTexcoords[i].second;
+		}
+	}
+
+	mGeometry.push_back(geom);
+}
+
+
+bool ObjConverter2::Convert(const string &filename,
+							const std::string &outputFilename)
+{
+	mNumShapes = 0;
+	
+	for (size_t i = 0; i < mGeometry.size(); ++ i)
+		delete mGeometry[i];
+	
+	mGeometry.clear();
+
+	if (!ReadFile(filename))
+	{
+		cerr << "could not read file" << endl;
+		return false;
+	}
+
+	if (!WriteFile(outputFilename))
+	{
+		cerr << "could not write file" << endl;
+		return false;
+	}
+
+
+	return true;
+}
+
+
+bool ObjConverter2::Convert2(const vector<string> &filenames,
+							 const std::string &outputFilename)
+{
+	mNumShapes = 0;
+
+	vector<string>::const_iterator it, it_end = filenames.end();
+
+	for (it = filenames.begin(); it != it_end; ++ it)
+	{
+		cout << "\n==================\n loading file " << *it << endl;
+
+		if (!ReadFile(*it))
+		{
+			cerr << "could not read file " << *it << endl;
+			return false;
+		}
+	}
+
+	if (!WriteFile(outputFilename))
+	{
+		cerr << "could not write file" << endl;
+		return false;
+	}
+
+	return true;
+}
+
+
+
+bool ObjConverter2::ReadFile(const string &filename) 
+{
+	FILE *file;
+
+	if ((file = fopen(filename.c_str(), "r")) == NULL)
+	{	
+		return false;
+	}
+	
+	Material *currentMat = NULL;
+	VertexArray faceVertices; 
+	VertexArray faceNormals;
+	vector<Texcoord> faceTexcoords;
+
+	VertexArray vertices; 
+	VertexArray normals;
+	vector<Texcoord> texcoords;
+
+	vector<int> indices;
+
+	int line = 0;
+	const int len = 10000;
+	char str[len];
+
+	while (fgets(str, len, file) != NULL)
+	{
+		switch (str[0])
+		{
+		case 'v': // vertex or normal
+			{
+				// still an object to load
+				if (!faceVertices.empty())
+				{
+					++ mNumShapes;
+
+					//if (!currentMat){ cerr << "no mat!!" << endl; std::cin.get(); }
+					LoadShape(faceVertices, faceNormals, faceTexcoords, currentMat);
+
+					faceVertices.clear();
+					faceNormals.clear();
+					faceTexcoords.clear();
+
+					currentMat = NULL;
+				}
+
+				float x, y, z;
+
+				switch (str[1]) 
+				{
+				case 'n' :
+					sscanf(str + 2, "%f %f %f", &x, &y, &z);
+					normals.push_back(SimpleVec(x, y, z));
+					break;
+				case 't':
+					sscanf(str + 2, "%f %f", &x, &y);
+					texcoords.push_back(pair<float, float>(x, y));
+					break;
+				default:
+					sscanf(str + 1, "%f %f %f", &x, &y, &z);
+					//const float scale = 5e-3f;
+					const float scale = 5.0f;
+					vertices.push_back(SimpleVec(x * scale, y * scale, z* scale));
+				}
+				break;
+			}
+		case 'f': 
+			{
+				//////////
+				//-- indices in the current line
+
+				LoadIndices(str, 
+					        vertices, normals, texcoords, 
+					        faceVertices, faceNormals, faceTexcoords);
+
+				break;
+			}   // end face
+		/*case 'g': // load a new shape
+			{
+				if (!faceVertices.empty())
+				{
+					++ mNumShapes;
+
+					LoadShape(faceVertices, faceNormals, faceTexcoords, currentMat);
+
+					faceVertices.clear();
+					faceNormals.clear();
+					faceTexcoords.clear();
+
+					currentMat = NULL;
+				}
+			}
+			break;*/
+		case 'u': // usemtl => material
+			{
+				string matName(str + 7);
+				// throw away linebreak character
+				matName.resize(matName.size() - 1);
+
+				currentMat = mMaterialTable[matName];
+				//cout << "matname: " << matName << endl;
+				//cout << "currentMat: " << currentMat << endl;
+			}
+			break;
+		case 'm': // material library
+			{
+				string matLibName(model_path + string(str + 7));
+				// throw away linebreak character
+				matLibName.resize(matLibName.size() - 1);
+				
+				cout << "loading mat library " << matLibName << endl;
+
+				// load the materials
+				if (!LoadMaterials(matLibName))
+				{
+					cerr << "loading material library failed" << endl;
+					exit(0);
+				}
+			}
+
+		default:
+			// throw away line
+			break;
+		}
+
+		++ line;
+	}
+
+	// convert the rest of the vertives
+	if (!faceVertices.empty())
+	{
+		++ mNumShapes;
+
+		LoadShape(faceVertices, faceNormals, faceTexcoords, currentMat);
+
+		faceVertices.clear();
+		faceNormals.clear();
+		faceTexcoords.clear();
+	}
+
+	fclose(file);
+	
+	return true;
+}
+
+
+void ObjConverter2::WriteGeometry(ogzstream &str, Geometry *geom)
+{
+	int vertexCount = geom->mVertexCount;
+	str.write(reinterpret_cast<char *>(&vertexCount), sizeof(int));
+  
+	str.write(reinterpret_cast<char *>(geom->mVertices), sizeof(SimpleVec) * vertexCount);
+	str.write(reinterpret_cast<char *>(geom->mNormals), sizeof(SimpleVec) * vertexCount);
+
+	int texCoordCount = geom->mTexcoordCount;
+	str.write(reinterpret_cast<char *>(&texCoordCount), sizeof(int));
+
+	if (texCoordCount)
+		str.write(reinterpret_cast<char *>(geom->mTexcoords), sizeof(float) * texCoordCount * 2);
+}
+
+
+bool ObjConverter2::WriteFile(const string &filename)
+{
+	ogzstream ofile(filename.c_str());
+	if (!ofile.is_open()) return false;
+	
+
+	/////////
+	//-- write textures
+
+	int textureCount = (int)mTextures.size();
+
+	ofile.write(reinterpret_cast<char *>(&textureCount), sizeof(int));
+
+	TextureArray::const_iterator tit, tit_end = mTextures.end();
+	
+	for (tit = mTextures.begin(); tit != tit_end; ++ tit)
+	{
+		const string texName = (*tit);
+
+		int texnameSize = (int)texName.length() + 1;
+		ofile.write(reinterpret_cast<char *>(&texnameSize), sizeof(int));
+
+		ofile.write(texName.c_str(), sizeof(char) * texnameSize);
+
+		int boundS = 1, boundT = 1;
+
+		ofile.write(reinterpret_cast<char *>(&boundS), sizeof(int));
+		ofile.write(reinterpret_cast<char *>(&boundT), sizeof(int));
+	}
+
+
+	///////////
+	//-- write shapes
+
+	ofile.write(reinterpret_cast<char *>(&mNumShapes), sizeof(int));
+
+	vector<Geometry *>::const_iterator it, it_end = mGeometry.end();
+
+	for (it = mGeometry.begin(); it != it_end; ++ it)
+	{
+		WriteGeometry(ofile, *it);
+
+		
+		/////////
+		//-- material
+
+		Material *mat = (*it)->mMaterial;
+
+		if (!mat) cerr << "error: no material specified!!" << endl;
+
+		ofile.write(reinterpret_cast<char *>(&mat->texture), sizeof(int));
+
+		bool alphaTestEnabled = false;
+		bool cullFaceEnabled = true;
+		//bool cullFaceEnabled = false;
+		
+		ofile.write(reinterpret_cast<char *>(&alphaTestEnabled), sizeof(bool));
+		ofile.write(reinterpret_cast<char *>(&cullFaceEnabled), sizeof(bool));
+
+		// material
+		bool hasMaterial = true;
+		ofile.write(reinterpret_cast<char *>(&hasMaterial), sizeof(bool));
+	
+		SimpleVec ambient, diffuse, spec, emm;
+
+		ambient.x = ambient.y = ambient.z = 0.2f;
+		//diffuse.x = diffuse.y = diffuse.z = 1.0f;
+		diffuse.x = mat->rgb[0]; diffuse.y =mat->rgb[1]; diffuse.z = mat->rgb[2];
+		spec.x = spec.y = spec.z = .0f;
+		emm = spec;
+
+		// only write rgb part of the material
+		ofile.write(reinterpret_cast<char *>(&ambient), sizeof(SimpleVec));
+		ofile.write(reinterpret_cast<char *>(&diffuse), sizeof(SimpleVec));
+		ofile.write(reinterpret_cast<char *>(&spec), sizeof(SimpleVec));
+		ofile.write(reinterpret_cast<char *>(&emm), sizeof(SimpleVec));
+	}
+
+
+	int entityCount = 1;
+	ofile.write(reinterpret_cast<char *>(&entityCount), sizeof(int));
+
+
+	//////////
+	//-- write single scene entity
+
+	// no transformation
+	bool hasTrafo = false;
+	ofile.write(reinterpret_cast<char *>(&hasTrafo), sizeof(bool));
+
+	// a dummy lod
+	int numLODs = 1;
+	ofile.write(reinterpret_cast<char *>(&numLODs), sizeof(int));
+
+	float dist = 0;
+	ofile.write(reinterpret_cast<char *>(&dist), sizeof(float));
+
+	ofile.write(reinterpret_cast<char *>(&mNumShapes), sizeof(int));
+
+	// all shapes belong to this scene entity
+	for (int i = 0; i < mNumShapes; ++ i)
+	{
+		int shapeId = i;
+		ofile.write(reinterpret_cast<char *>(&shapeId), sizeof(int));
+	}
+
+	return true;
+}
+
+
+bool ObjConverter2::LoadMaterials(const std::string &matFileName)
+{
+	FILE *file;
+
+	if ((file = fopen(matFileName.c_str(), "r")) == NULL) return false;
+	
+	int line = 0;
+	const int len = 10000;
+	char str[len];
+
+	Material *currentMat = NULL;
+
+
+	while (fgets(str, len, file) != NULL)
+	{
+		//sscanf(str + 1, "%f %f %f", &x, &y, &z);
+		vector<string> strings;
+
+		char *next_token;
+
+		// extract the triples of the form v/t/n v/t/n ...
+		char *pch = strtok_s(str, " \n", &next_token);
+
+		while (pch)
+		{
+			string s(pch);
+			strings.push_back(s);
+
+			pch = strtok_s(NULL, " \n", &next_token);	 
+		}
+		
+		if ((strings.size() == 2) && (strcmp(strings[0].c_str(),"newmtl") == 0))
+		{
+			currentMat = new Material();
+			mMaterialTable[strings[1].c_str()] = currentMat;
+		}
+
+		if ((strings.size() == 2) && 
+			((strcmp(strings[0].c_str(),"map_Kd") == 0) || (strcmp(strings[0].c_str(),"map_Ka") == 0)))
+		{
+			TextureTable::const_iterator it = mTextureTable.find(strings[1]);
+
+			int id;
+
+			if (it == mTextureTable.end()) // parameter not found
+			{
+				mTextures.push_back(strings[1]);
+				id = (int)mTextures.size();
+				mTextureTable[strings[1]] = id;
+			}
+			else
+			{
+				id = (*it).second;
+			}
+
+			currentMat->texture = id;
+		}
+
+		if ((strings.size() == 4) && (strcmp(strings[0].c_str(),"Kd") == 0))
+		{
+			currentMat->rgb[0] = (float)atof(strings[1].c_str());
+			currentMat->rgb[1] = (float)atof(strings[2].c_str());
+			currentMat->rgb[2] = (float)atof(strings[3].c_str());
+		}
+
+		++ line;
+	}
+
+	return true;
+}
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/Converter/main.cpp
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/Converter/main.cpp	(revision 3247)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/Converter/main.cpp	(revision 3261)
@@ -1,3 +1,3 @@
-#include "ObjConverter.h"
+#include "ObjConverter2.h"
 #include <iostream>
 #include <time.h>
@@ -5,5 +5,4 @@
 using namespace std;
 
-static string model_path("data/city/model/");
 
 int main(int argc, char* argv[])
@@ -11,8 +10,8 @@
 	int returnCode = 0;
 
-	ObjConverter converter;
+	ObjConverter2 converter;
 
 	cout << "converting obj to dem format" << endl;
-	
+#if 0	
 	if (!converter.LoadMaterials(model_path + argv[3]))
 	{
@@ -30,7 +29,30 @@
 		exit(0);
 	}
+#else
+	
+	//const int numFiles = 879;
+	const int numFiles = 100;
+
+	vector<string> filenames;
+	const string base(model_path + argv[1]);
+
+	for (int i = 0; i < numFiles; ++ i)
+	{
+		char filename[100];
+		sprintf(filename, "%s%s%d%s", base.c_str(), ".b", i, ".obj");
+		filenames.push_back(filename);
+	}
+
+	if (!converter.Convert2(filenames, model_path + argv[2]))
+	{
+		cerr << "conversion failed" << endl;
+
+		std::cin.get();
+		exit(0);
+	}
+#endif
 
 	cout << "conversion successful" << endl;
-	cout << "press any key" << std::cin.get();
+	//cout << "press any key" << std::cin.get();
 
 	return 0;
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/Converter/ObjConverter.h
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/Converter/ObjConverter.h	(revision 3247)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/Converter/ObjConverter.h	(revision 3261)
@@ -15,4 +15,7 @@
 
 class Geometry;
+
+static std::string model_path("data/city/model/");
+
 
 typedef std::vector<SimpleVec> VertexArray;
@@ -37,5 +40,5 @@
 	             // const std::string textureFilename) const;
 
-	bool LoadMaterials(const std::string &matFileName);
+	bool LoadMaterials(const std::string &mtlFilename);
 
 	~ObjConverter();
@@ -45,4 +48,20 @@
 	struct Geometry
 	{
+		Geometry(): 
+	    mVertices(NULL),
+		mNormals(NULL),
+		mTexcoords(NULL), 
+		mMaterial(NULL), 
+		mVertexCount(0), 
+		mTexcoordCount(0)
+		{}
+
+		~Geometry()
+		{
+			delete [] mVertices;
+			delete [] mNormals;
+			delete [] mTexcoords;
+		}
+
 		SimpleVec *mVertices;
 		SimpleVec *mNormals;
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/Converter/ObjConverter2.h
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/Converter/ObjConverter2.h	(revision 3261)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/Converter/ObjConverter2.h	(revision 3261)
@@ -0,0 +1,101 @@
+#ifndef _OBJCONVERTER2_H
+#define _OBJCONVERTER2_H
+
+#include "SimpleVec.h"
+#include <string>
+#include <vector>
+#include <map>
+
+
+struct Material
+{
+	float rgb[3];
+	int texture;
+};
+
+class Geometry;
+
+static std::string model_path("data/city/model/procedural_pompeii_area6_hires/");
+
+
+typedef std::vector<SimpleVec> VertexArray;
+typedef std::pair<float, float> Texcoord;
+typedef std::map<std::string, Material *> MaterialTable;
+typedef std::map<std::string, int> TextureTable;
+
+typedef std::vector<std::string> TextureArray;
+
+class ogzstream;
+
+/** Converts obj format into objects readable by our format
+*/
+class ObjConverter2
+{
+public:
+
+	ObjConverter2();
+
+	bool Convert(const std::string &inputFilename, 
+		         const std::string &outputFilename);
+	
+	bool Convert2(const std::vector<std::string> &filenames, 
+		          const std::string &outputFilename);
+
+	bool LoadMaterials(const std::string &mtlFilename);
+
+	~ObjConverter2();
+
+protected:
+
+	struct Geometry
+	{
+		Geometry(): 
+	    mVertices(NULL),
+		mNormals(NULL),
+		mTexcoords(NULL), 
+		mMaterial(NULL), 
+		mVertexCount(0), 
+		mTexcoordCount(0)
+		{}
+
+		~Geometry()
+		{
+			delete [] mVertices;
+			delete [] mNormals;
+			delete [] mTexcoords;
+		}
+
+		SimpleVec *mVertices;
+		SimpleVec *mNormals;
+		Texcoord *mTexcoords;
+		Material *mMaterial;
+
+		int mVertexCount;
+		int mTexcoordCount;
+	};
+
+typedef std::vector<Geometry *> GeometryArray;
+
+	void LoadShape(const VertexArray &faceVertices,
+		           const VertexArray &faceNormals,
+				   const std::vector<Texcoord> &faceTexcoords, 
+				   Material *mat);
+
+	void WriteGeometry(ogzstream &str, Geometry *geom);
+
+	bool ReadFile(const std::string &inputFilename);
+	bool WriteFile(const std::string &outputFilename);
+
+
+	MaterialTable mMaterialTable;
+	TextureTable mTextureTable;
+	
+	TextureArray mTextures;
+	GeometryArray mGeometry;
+
+	int mNumShapes;
+};
+
+
+
+#endif
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/Converter.vcproj
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/Converter.vcproj	(revision 3258)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/Converter.vcproj	(revision 3261)
@@ -69,4 +69,5 @@
 				GenerateDebugInformation="true"
 				SubSystem="1"
+				LargeAddressAware="2"
 				TargetMachine="1"
 			/>
@@ -122,7 +123,16 @@
 				Name="VCCLCompilerTool"
 				AdditionalOptions=" /D &quot;_CRT_SECURE_NO_WARNINGS&quot;"
+				Optimization="3"
+				InlineFunctionExpansion="2"
+				EnableIntrinsicFunctions="true"
+				FavorSizeOrSpeed="1"
+				OmitFramePointers="true"
+				EnableFiberSafeOptimizations="true"
 				AdditionalIncludeDirectories="libs\Zlib\include"
 				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+				StringPooling="true"
 				RuntimeLibrary="2"
+				EnableEnhancedInstructionSet="2"
+				RuntimeTypeInfo="false"
 				UsePrecompiledHeader="0"
 				WarningLevel="3"
@@ -145,6 +155,7 @@
 				AdditionalLibraryDirectories="libs\Zlib\lib"
 				IgnoreDefaultLibraryNames="libCMT"
-				GenerateDebugInformation="true"
+				GenerateDebugInformation="false"
 				SubSystem="1"
+				LargeAddressAware="2"
 				OptimizeReferences="2"
 				EnableCOMDATFolding="2"
@@ -198,4 +209,8 @@
 			</File>
 			<File
+				RelativePath=".\Converter\ObjConverter2.cpp"
+				>
+			</File>
+			<File
 				RelativePath=".\Converter\SimpleTri.cpp"
 				>
@@ -220,4 +235,8 @@
 			</File>
 			<File
+				RelativePath=".\Converter\ObjConverter2.h"
+				>
+			</File>
+			<File
 				RelativePath=".\Converter\SimpleTri.h"
 				>
