Index: /GTP/trunk/App/Demos/Vis/HillyTerrain/OGRE/TestCullingTerrain.vcproj
===================================================================
--- /GTP/trunk/App/Demos/Vis/HillyTerrain/OGRE/TestCullingTerrain.vcproj	(revision 2121)
+++ /GTP/trunk/App/Demos/Vis/HillyTerrain/OGRE/TestCullingTerrain.vcproj	(revision 2123)
@@ -22,5 +22,5 @@
 				Optimization="0"
 				AdditionalIncludeDirectories="&quot;$(OGRE_PATH)\Dependencies\include&quot;;&quot;$(OGRE_PATH)\OgreMain\include&quot;;&quot;$(OGRE_PATH)\Samples\Common\include&quot;;&quot;$(OGRE_PATH)\Dependencies\include\CEGUI&quot;;&quot;$(OGRE_PATH)\PlugIns\OctreeSceneManager\include&quot;;&quot;$(OGRE_ADDONS_PATH)\dotsceneoctree\PlugIns\DotSceneManager\include&quot;;&quot;$(OGRE_PATH)\Samples\Common\CEGUIRenderer\include&quot;;..\..\GtpVisibility\include;..\..\Ogre\include;..\include;..\..\..\..\..\Lib\Vis\OnlineCullingCHC\include;..\..\..\..\..\Lib\Vis\OnlineCullingCHC\OGRE\include;..\..\..\..\..\Lib\Vis\OnlineCullingCHC\IVReader\include"
-				PreprocessorDefinitions="_WINDOWS;_STLP_USE_DYNAMIC_LIB;OGRE_LIBRARY_IMPORTS;_DEBUG;WIN32;_STLP_DEBUG;PLUGIN_TERRAIN_IMPORTS;GTP_VISIBILITY_MODIFIED_OGRE"
+				PreprocessorDefinitions="_WINDOWS;_STLP_USE_DYNAMIC_LIB;OGRE_LIBRARY_IMPORTS;_DEBUG;WIN32;_STLP_DEBUG;GTP_VISIBILITY_MODIFIED_OGRE"
 				MinimalRebuild="TRUE"
 				BasicRuntimeChecks="3"
@@ -35,8 +35,8 @@
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="Plugin_OctreeSceneManager.lib Plugin_VisibilitySceneManager.lib GtpVisibility.lib Preprocessor.lib OGREMain_d.LIB CEGUIBase_d.lib OgreGUIRenderer_d.lib zdll.lib zziplibd.lib"
+				AdditionalDependencies="Plugin_OctreeSceneManager.lib Plugin_VisibilitySceneManager.lib GtpVisibility.lib Preprocessor.lib OGREMain_d.LIB CEGUIBase_d.lib OgreGUIRenderer_d.lib zdll.lib zziplibd.lib IVReader.lib"
 				OutputFile="$(OGRE_PATH)/Samples/Common/bin/Debug/TestCullingTerrain.exe"
 				LinkIncremental="1"
-				AdditionalLibraryDirectories="&quot;$(OGRE_PATH)\Dependencies\Lib\$(ConfigurationName)&quot;;&quot;$(OGRE_PATH)\OgreMain\Lib\$(ConfigurationName)&quot;;&quot;$(OGRE_PATH)\PlugIns\OctreeSceneManager\bin\$(ConfigurationName)&quot;;&quot;$(OGRE_PATH)\Samples\Common\CEGUIRenderer\lib&quot;;&quot;..\..\..\..\..\Lib\Vis\OnlineCullingCHC\OGRE\lib\$(ConfigurationName)&quot;;&quot;..\..\..\..\..\Lib\Vis\OnlineCullingCHC\lib\$(ConfigurationName)&quot;;&quot;..\..\..\..\..\Lib\Vis\Preprocessing\lib\$(ConfigurationName)&quot;"
+				AdditionalLibraryDirectories="&quot;$(OGRE_PATH)\Dependencies\Lib\$(ConfigurationName)&quot;;&quot;$(OGRE_PATH)\OgreMain\Lib\$(ConfigurationName)&quot;;&quot;$(OGRE_PATH)\PlugIns\OctreeSceneManager\bin\$(ConfigurationName)&quot;;&quot;$(OGRE_PATH)\Samples\Common\CEGUIRenderer\lib&quot;;&quot;..\..\..\..\..\Lib\Vis\OnlineCullingCHC\OGRE\lib\$(ConfigurationName)&quot;;&quot;..\..\..\..\..\Lib\Vis\OnlineCullingCHC\lib\$(ConfigurationName)&quot;;&quot;..\..\..\..\..\Lib\Vis\Preprocessing\lib\$(ConfigurationName)&quot;;&quot;..\..\..\..\..\Lib\Vis\OnlineCullingCHC\IVReader\lib\$(ConfigurationName)&quot;"
 				GenerateDebugInformation="TRUE"
 				ProgramDatabaseFile="$(OutDir)/TestCullingTerrain.pdb"
@@ -78,9 +78,10 @@
 				EnableIntrinsicFunctions="TRUE"
 				FavorSizeOrSpeed="1"
+				OmitFramePointers="TRUE"
 				EnableFiberSafeOptimizations="TRUE"
 				OptimizeForProcessor="0"
 				OptimizeForWindowsApplication="TRUE"
 				AdditionalIncludeDirectories="&quot;$(OGRE_PATH)\Dependencies\include&quot;;&quot;$(OGRE_PATH)\OgreMain\include&quot;;&quot;$(OGRE_PATH)\Samples\Common\include&quot;;&quot;$(OGRE_PATH)\Dependencies\include\CEGUI&quot;;&quot;$(OGRE_PATH)\PlugIns\OctreeSceneManager\include&quot;;&quot;$(OGRE_PATH)\Samples\Common\CEGUIRenderer\include&quot;;..\..\Ogre\include;..\..\..\..\..\Lib\Vis\OnlineCullingCHC\include;..\include;..\..\..\..\..\Lib\Vis\OnlineCullingCHC\OGRE\include;..\..\..\..\..\Lib\Vis\OnlineCullingCHC\IVReader\include"
-				PreprocessorDefinitions="_WINDOWS;_STLP_USE_DYNAMIC_LIB;OGRE_LIBRARY_IMPORTS;_RELEASE;WIN32;_STLP_RELEASE;GTP_VISIBILITY_MODIFIED_OGRE;GAMETOOLS_ILLUMINATION_MODULE1;USE_VERBOSE_PVS"
+				PreprocessorDefinitions="_WINDOWS;_STLP_USE_DYNAMIC_LIB;OGRE_LIBRARY_IMPORTS;_RELEASE;WIN32;_STLP_RELEASE;GTP_VISIBILITY_MODIFIED_OGRE;GAMETOOLS_ILLUMINATION_MODULE"
 				RuntimeLibrary="2"
 				RuntimeTypeInfo="TRUE"
Index: /GTP/trunk/App/Demos/Vis/HillyTerrain/OGRE/TestCullingTerrainApplication.cpp
===================================================================
--- /GTP/trunk/App/Demos/Vis/HillyTerrain/OGRE/TestCullingTerrainApplication.cpp	(revision 2121)
+++ /GTP/trunk/App/Demos/Vis/HillyTerrain/OGRE/TestCullingTerrainApplication.cpp	(revision 2123)
@@ -282,8 +282,7 @@
 	*	because then the camera is displayed correctly in the visualization
 	*/
-	//Vector3 viewPoint(707, 5000, 528);
+	// hack: vienna view point
 	Vector3 viewPoint(830, 300, -540);
-	std::stringstream d; d << "here3: " << viewPoint;
-	Ogre::LogManager::getSingleton().logMessage(d.str());
+	
 	mCamNode = mSceneMgr->getRootSceneNode()->
 		createChildSceneNode("CamNode1", viewPoint);
@@ -454,10 +453,6 @@
 {
 	/////////
-	//-- load scene
+	//-- load parameters & scene
 	loadConfig("terrainCulling.cfg");
-	
-	if (0 && !LoadScene(mFilename))
-	   	LogManager::getSingleton().logMessage("error loading scene");
-	
 	
 	/////////////////////////////////////
@@ -502,7 +497,15 @@
 		mSceneMgr->setWorldGeometry(terrain_cfg);
 
+		// was terrain loaded?
 		mSceneMgr->getOption("ShowTerrain", &msShowHillyTerrain); 
 	}
 	
+	// hack view point for terrain
+	if (msShowHillyTerrain)
+	{
+		Vector3 viewPoint(707, 5000, 528);
+		mCamNode->setPosition(viewPoint);
+	}
+
 	////// 
 	//-- CEGUI setup
Index: /GTP/trunk/Lib/Vis/OnlineCullingCHC/IVReader/src/IVReader.vcproj
===================================================================
--- /GTP/trunk/Lib/Vis/OnlineCullingCHC/IVReader/src/IVReader.vcproj	(revision 2122)
+++ /GTP/trunk/Lib/Vis/OnlineCullingCHC/IVReader/src/IVReader.vcproj	(revision 2123)
@@ -24,5 +24,5 @@
 				MinimalRebuild="TRUE"
 				BasicRuntimeChecks="3"
-				RuntimeLibrary="1"
+				RuntimeLibrary="3"
 				UsePrecompiledHeader="0"
 				WarningLevel="3"
@@ -73,5 +73,5 @@
 				Name="VCCLCompilerTool"
 				AdditionalIncludeDirectories="&quot;$(OGRE_PATH)\Dependencies\include\CEGUI&quot;;&quot;$(OGRE_PATH)\Samples\Common\CEGUIRenderer\include&quot;;&quot;$(OGRE_PATH)\OgreMain\include&quot;;&quot;$(OGRE_PATH)\Dependencies\include&quot;;&quot;$(OGRE_PATH)\Samples\Common\include&quot;;..\include"
-				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;IVREADER_EXPORTS;GTP_VISIBILITY_MODIFIED_OGRE;GAMETOOLS_ILLUMINATION_MODULE1;USE_VERBOSE_PVS"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;IVREADER_EXPORTS;GTP_VISIBILITY_MODIFIED_OGRE;GAMETOOLS_ILLUMINATION_MODULE"
 				RuntimeLibrary="2"
 				UsePrecompiledHeader="0"
Index: /GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgreOcclusionCullingSceneManager.h
===================================================================
--- /GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgreOcclusionCullingSceneManager.h	(revision 2119)
+++ /GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgreOcclusionCullingSceneManager.h	(revision 2123)
@@ -14,4 +14,11 @@
 #include "ViewCellsManager.h"
 
+
+namespace GtpVisibilityPreprocessor {
+class Intersectable;
+}
+
+class ObjReader;
+
 namespace Ogre {
 
@@ -24,5 +31,6 @@
 {
 public:
-	OcclusionCullingSceneManager(const String& name, GtpVisibility::VisibilityManager *visManager);
+	OcclusionCullingSceneManager(const String& name, 
+								 GtpVisibility::VisibilityManager *visManager);
 	~OcclusionCullingSceneManager();
 
@@ -70,12 +78,15 @@
 	*/
 	bool validatePassForRendering(Pass* pass);
+
 #ifdef ITEM_BUFFER
 	void RenderItemBuffer(RenderPriorityGroup* pGroup);
 	void RenderSingleObjectForItemBuffer(Renderable *rend, Pass *pass);
 #endif // ITEM_BUFFER
+
 	void _renderQueueGroupObjects(RenderQueueGroup* pGroup,
-		QueuedRenderableCollection::OrganisationMode om);
-
-	/** Override from SceneManager so that sub entities can be assigned an id for item buffer.
+								  QueuedRenderableCollection::OrganisationMode om);
+
+	/** Override from SceneManager so that sub entities can be assigned 
+		an id for item buffer.
 	*/
 	Entity* createEntity(const String& entityName, const String& meshName);
@@ -93,8 +104,10 @@
 	void endFrame();
 
-	void renderAdditiveStencilShadowedQueueGroupObjects(RenderQueueGroup* pGroup,
-		QueuedRenderableCollection::OrganisationMode om);
-	void renderModulativeStencilShadowedQueueGroupObjects(RenderQueueGroup* pGroup,
-		QueuedRenderableCollection::OrganisationMode om);
+	void renderAdditiveStencilShadowedQueueGroupObjects(
+				RenderQueueGroup* pGroup,
+				QueuedRenderableCollection::OrganisationMode om);
+	void renderModulativeStencilShadowedQueueGroupObjects(
+				RenderQueueGroup* pGroup,
+				QueuedRenderableCollection::OrganisationMode om);
 	
 	/** Override standard function so octree boxes are always of equal side length.
@@ -113,4 +126,10 @@
 protected:
 	
+	void MailPvsObjects();
+	void RenderPvsEntry(GtpVisibilityPreprocessor::Intersectable *obj);
+	void SetObjectVisible(GtpVisibilityPreprocessor::Intersectable *entry, 
+						  const bool visible);
+	void ShowViewCellsGeometry();
+
 	/** Creates material for depth pass, e.g., a pass that only fills the depth buffer. 
 	*/
@@ -254,4 +273,6 @@
 
 	bool mShowTerrain;
+
+	ObjReader *mObjReader;
 };
 
Index: /GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgreBoundingBoxConverter.h
===================================================================
--- /GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgreBoundingBoxConverter.h	(revision 2115)
+++ /GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgreBoundingBoxConverter.h	(revision 2123)
@@ -217,5 +217,6 @@
 
 			// we are only interested in scene entities
-			if (mo->getMovableType() != "Entity")
+			if ((mo->getMovableType() != "Entity") &&
+				(mo->getMovableType() != "ManualObject"))
 				continue;
 			
@@ -237,4 +238,34 @@
 }
 
+static void AddToObjects(EntityContainer *entites, 
+						 GtpVisibilityPreprocessor::ObjectContainer &objects,
+						 const int id)
+{
+	// TODO: can actually just put single objects into pvs with same id, 
+	// this can be sorted out later!!
+#if 0
+	EntityContainer::const_iterator eit, eit_end = entryObjects.end();
+
+	for (eit = entryObjects.begin(); eit != eit_end; ++ eit)
+	{
+		Entity *ent = *eit;
+
+        // warning: multiple ids possible
+		OgreMeshInstance *omi = new OgreMeshInstance(ent);
+		omi->SetId(id);
+		objects.push_back(omi);
+	}
+
+	delete entryObjects;
+
+#else
+
+	EngineIntersectable *entry = new EngineIntersectable(entites);
+
+	entry->SetId(id);
+	objects.push_back(entry);
+#endif
+}
+
 #if USE_KD_PVS
 //-------------------------------------------------------------------------
@@ -255,30 +286,10 @@
 			OgreTypeConverter::ConvertToOgre(pbox);
 		
-		EntityContainer entryObjects;
+		EntityContainer *entryObjects = new EntityContainer();
 
 		// find all objects that intersect the bounding box
-		FindIntersectingObjects(box, entryObjects);
-
-		// TODO: can actually just put single objects into pvs with same id, 
-		// this can be sorted out later!!
-#if 1
-		EntityContainer::const_iterator eit, eit_end = entryObjects.end();
-
-		for (eit = entryObjects.begin(); eit != eit_end; ++ eit)
-		{
-			Entity *ent = *eit;
-
-            // warning: multiple ids possible
-			OgreMeshInstance *omi = new OgreMeshInstance(ent);
-			omi->SetId(id);
-			objects.push_back(omi);
-		}
-#else
-		EngineIntersectable *entry = 
-			new EngineIntersectable(entryObjects);
-
-		entry->SetId(id);
-		objects.push_back(entry);
-#endif
+		FindIntersectingObjects(box, *entryObjects);
+
+		AddToObjects(entryObjects, objects, id);
 	}
 
Index: /GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreKdTreeSceneManager.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreKdTreeSceneManager.cpp	(revision 2115)
+++ /GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreKdTreeSceneManager.cpp	(revision 2123)
@@ -1355,9 +1355,9 @@
 	while (pit.HasMoreEntries())
 	{		
-		GtpVisibilityPreprocessor::ObjectPvsEntry entry = pit.Next();
-
-		if (entry.mObject)
-		{
-			OgreMeshInstance *omi = static_cast<OgreMeshInstance *>(entry.mObject);
+		GtpVisibilityPreprocessor::Intersectable *entry = pit.Next();
+
+		if (entry)
+		{
+			OgreMeshInstance *omi = static_cast<OgreMeshInstance *>(entry);
 			omi->GetEntity()->setVisible(load);
 		}
Index: /GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreBvHierarchySceneManager.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreBvHierarchySceneManager.cpp	(revision 2115)
+++ /GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreBvHierarchySceneManager.cpp	(revision 2123)
@@ -1354,9 +1354,9 @@
 	while (pit.HasMoreEntries())
 	{		
-		GtpVisibilityPreprocessor::ObjectPvsEntry entry = pit.Next();
-
-		if (entry.mObject)
-		{
-			OgreMeshInstance *omi = static_cast<OgreMeshInstance *>(entry.mObject);
+		GtpVisibilityPreprocessor::Intersectable *entry = pit.Next();
+
+		if (entry)
+		{
+			OgreMeshInstance *omi = static_cast<OgreMeshInstance *>(entry);
 			omi->GetEntity()->setVisible(load);
 		}
Index: /GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/Plugin_VisibilitySceneManager.vcproj
===================================================================
--- /GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/Plugin_VisibilitySceneManager.vcproj	(revision 2122)
+++ /GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/Plugin_VisibilitySceneManager.vcproj	(revision 2123)
@@ -20,5 +20,5 @@
 				Name="VCCLCompilerTool"
 				Optimization="0"
-				AdditionalIncludeDirectories="&quot;$(OGRE_PATH)\PlugIns\OctreeSceneManager\include&quot;;&quot;$(OGRE_PATH)\Samples\Common\include&quot;;&quot;$(OGRE_PATH)\Dependencies\include\CEGUI&quot;;&quot;$(OGRE_PATH)\Samples\Common\CEGUIRenderer\include&quot;;&quot;$(OGRE_PATH)\OgreMain\include&quot;;&quot;$(OGRE_PATH)\Dependencies\include&quot;;..\include;..\..\..\OnlineCullingCHC\include;..\..\..\Preprocessing\src"
+				AdditionalIncludeDirectories="&quot;$(OGRE_PATH)\PlugIns\OctreeSceneManager\include&quot;;&quot;$(OGRE_PATH)\Samples\Common\include&quot;;&quot;$(OGRE_PATH)\Dependencies\include\CEGUI&quot;;&quot;$(OGRE_PATH)\Samples\Common\CEGUIRenderer\include&quot;;&quot;$(OGRE_PATH)\OgreMain\include&quot;;&quot;$(OGRE_PATH)\Dependencies\include&quot;;..\include;..\..\..\OnlineCullingCHC\include;..\..\..\Preprocessing\src;..\..\..\..\..\Lib\Vis\OnlineCullingCHC\IVReader\include;..\..\..\..\..\Lib\Vis\OnlineCullingCHC\ObjReader\include"
 				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;PLUGIN_KD_TERRAIN_EXPORTS;GTP_VISIBILITY_MODIFIED_OGRE"
 				MinimalRebuild="TRUE"
@@ -36,10 +36,10 @@
 				Name="VCLinkerTool"
 				IgnoreImportLibrary="TRUE"
-				AdditionalDependencies="OgreMain_d.lib CEGUIBase_d.lib OgreGUIRenderer_d.lib Plugin_OctreeSceneManager.lib GtpVisibility.lib zdll.lib zziplibd.lib Preprocessor.lib devil.lib glut32.lib xerces-c_2D.lib OpenGL32.Lib glu32.lib cg.lib cgGL.lib glew32.lib"
+				AdditionalDependencies="OgreMain_d.lib CEGUIBase_d.lib OgreGUIRenderer_d.lib Plugin_OctreeSceneManager.lib GtpVisibility.lib zdll.lib zziplibd.lib Preprocessor.lib devil.lib glut32.lib xerces-c_2D.lib OpenGL32.Lib glu32.lib cg.lib cgGL.lib glew32.lib IVReader.lib ObjReader.lib"
 				OutputFile="$(OutDir)/Plugin_VisibilitySceneManager.dll"
 				Version="0.99"
 				LinkIncremental="1"
 				SuppressStartupBanner="TRUE"
-				AdditionalLibraryDirectories="&quot;$(OGRE_PATH)\OgreMain\lib\$(ConfigurationName)&quot;;&quot;$(OGRE_PATH)\Dependencies\lib\$(ConfigurationName)&quot;;&quot;$(OGRE_PATH)\PlugIns\OctreeSceneManager\bin\$(ConfigurationName)&quot;;&quot;$(OGRE_PATH)\Samples\Common\CEGUIRenderer\lib&quot;;&quot;..\lib\$(ConfigurationName)&quot;;&quot;..\..\lib\$(ConfigurationName)&quot;;&quot;..\..\..\Preprocessing\lib\$(ConfigurationName)&quot;;..\..\..\Preprocessing\src\GL;..\..\..\..\..\..\..\NonGTP\Xerces\xercesc\lib;&quot;$(CG_LIB_PATH)&quot;"
+				AdditionalLibraryDirectories="&quot;$(OGRE_PATH)\OgreMain\lib\$(ConfigurationName)&quot;;&quot;$(OGRE_PATH)\Dependencies\lib\$(ConfigurationName)&quot;;&quot;$(OGRE_PATH)\PlugIns\OctreeSceneManager\bin\$(ConfigurationName)&quot;;&quot;$(OGRE_PATH)\Samples\Common\CEGUIRenderer\lib&quot;;&quot;..\lib\$(ConfigurationName)&quot;;&quot;..\..\lib\$(ConfigurationName)&quot;;&quot;..\..\..\Preprocessing\lib\$(ConfigurationName)&quot;;..\..\..\Preprocessing\src\GL;..\..\..\..\..\..\..\NonGTP\Xerces\xercesc\lib;&quot;$(CG_LIB_PATH)&quot;;&quot;..\..\..\..\..\Lib\Vis\OnlineCullingCHC\ObjReader\lib\$(ConfigurationName)&quot;;&quot;..\..\..\..\..\Lib\Vis\OnlineCullingCHC\IVReader\lib\$(ConfigurationName)&quot;"
 				ModuleDefinitionFile="..\misc\OgreVisibilitySceneManager.def"
 				GenerateDebugInformation="TRUE"
@@ -87,8 +87,8 @@
 				OmitFramePointers="TRUE"
 				EnableFiberSafeOptimizations="TRUE"
-				OptimizeForProcessor="3"
+				OptimizeForProcessor="0"
 				OptimizeForWindowsApplication="TRUE"
-				AdditionalIncludeDirectories="&quot;$(OGRE_PATH)\PlugIns\OctreeSceneManager\include&quot;;&quot;$(OGRE_PATH)\Samples\Common\include&quot;;&quot;$(OGRE_PATH)\Dependencies\include\CEGUI&quot;;&quot;$(OGRE_PATH)\Samples\Common\CEGUIRenderer\include&quot;;&quot;$(OGRE_PATH)\OgreMain\include&quot;;&quot;$(OGRE_PATH)\Dependencies\include&quot;;..\include;..\..\..\OnlineCullingCHC\include;..\..\..\Preprocessing\src;..\..\..\..\..\Lib\Vis\OnlineCullingCHC\IVReader\include;..\..\..\Preprocessing\src\Timer;..\..\..\..\..\Lib\Vis\OnlineCullingCHC\ObjReader\include"
-				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;PLUGIN_KD_TERRAIN_EXPORTS;GTP_VISIBILITY_MODIFIED_OGRE;GAMETOOLS_ILLUMINATION_MODULE1;USE_VERBOSE_PVS"
+				AdditionalIncludeDirectories="&quot;$(OGRE_PATH)\PlugIns\OctreeSceneManager\include&quot;;&quot;$(OGRE_PATH)\Samples\Common\include&quot;;&quot;$(OGRE_PATH)\Dependencies\include\CEGUI&quot;;&quot;$(OGRE_PATH)\Samples\Common\CEGUIRenderer\include&quot;;&quot;$(OGRE_PATH)\OgreMain\include&quot;;&quot;$(OGRE_PATH)\Dependencies\include&quot;;..\include;..\..\..\OnlineCullingCHC\include;..\..\..\Preprocessing\src;..\..\..\Preprocessing\src\Timer;..\..\..\..\..\Lib\Vis\OnlineCullingCHC\IVReader\include;..\..\..\..\..\Lib\Vis\OnlineCullingCHC\ObjReader\include"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;PLUGIN_KD_TERRAIN_EXPORTS;GTP_VISIBILITY_MODIFIED_OGRE;GAMETOOLS_ILLUMINATION_MODULE"
 				StringPooling="TRUE"
 				RuntimeLibrary="2"
Index: /GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreOcclusionCullingSceneManager.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreOcclusionCullingSceneManager.cpp	(revision 2122)
+++ /GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreOcclusionCullingSceneManager.cpp	(revision 2123)
@@ -78,4 +78,6 @@
 	// TODO: set maxdepth to reasonable value
 	mMaxDepth = 50;
+
+	mObjReader = new ObjReader(this);
 }
 //-----------------------------------------------------------------------
@@ -107,4 +109,6 @@
 	CLEAR_CONTAINER(mObjects);
 	OGRE_DELETE(mCurrentViewCell);
+
+	OGRE_DELETE(mObjReader);
 }
 //-----------------------------------------------------------------------
@@ -379,4 +383,123 @@
 	selectPageSource(pageSourceName, optlist);
 }
+
+
+void OcclusionCullingSceneManager::MailPvsObjects()
+{
+	GtpVisibilityPreprocessor::ObjectPvsIterator pit = 
+			mCurrentViewCell->GetPvs().GetIterator();
+
+	while (pit.HasMoreEntries())
+	{		
+		GtpVisibilityPreprocessor::Intersectable *obj = pit.Next();
+
+		if (obj->Type() != 
+			GtpVisibilityPreprocessor::Intersectable::ENGINE_INTERSECTABLE)
+			continue;
+			
+		EngineIntersectable *oi = static_cast<EngineIntersectable *>(obj);
+
+		EntityContainer *entries = oi->GetItem();
+		EntityContainer::const_iterator eit, eit_end = entries->end();
+
+		for (eit = entries->begin(); eit != eit_end; ++ eit)
+		{
+			(*eit)->setUserAny(Any((int)0));
+		}
+	}
+}
+//-----------------------------------------------------------------------
+void OcclusionCullingSceneManager::ShowViewCellsGeometry()
+{/*
+	// show only current view cell
+	if (!mShowViewCells)
+	{
+		const int id = mCurrentViewCell->GetId();
+
+		MovableMap::iterator fit = mViewCellsGeometry.find(id);
+
+		if ((fit != mViewCellsGeometry.end()) && (*fit).second)
+			(*fit).second->_updateRenderQueue(getRenderQueue());
+	}
+	else
+	{
+		MovableMap::const_iterator mit, mit_end = mViewCellsGeometry.end();
+
+		for (mit = mViewCellsGeometry.begin(); mit != mit_end; ++ mit)
+		{
+			if ((*mit).second)
+				(*mit).second->_updateRenderQueue(getRenderQueue());
+		}	
+	}*/
+}
+
+
+void OcclusionCullingSceneManager::RenderPvsEntry(GtpVisibilityPreprocessor::Intersectable *obj)
+{
+	switch (obj->Type())
+	{	
+		case GtpVisibilityPreprocessor::Intersectable::OGRE_MESH_INSTANCE:
+			{
+				OgreMeshInstance *omi = static_cast<OgreMeshInstance *>(obj);
+				omi->GetEntity()->_updateRenderQueue(getRenderQueue());
+			}
+			break;
+
+		case GtpVisibilityPreprocessor::Intersectable::ENGINE_INTERSECTABLE:
+			{
+				EngineIntersectable *oi = static_cast<EngineIntersectable *>(obj);
+
+				EntityContainer *entries = oi->GetItem();
+				EntityContainer::const_iterator eit, eit_end = entries->end();
+
+				for (eit = entries->begin(); eit != eit_end; ++ eit)
+				{
+					Entity *ent = *eit;
+					// mailing hack
+					Any newAny = ent->getUserAny();
+					int flt = any_cast<int>(newAny);
+
+					if (any_cast<int>(newAny) == 0)
+					{
+						ent->setUserAny(Any((int)1));
+						ent->_updateRenderQueue(getRenderQueue());
+					}
+				}
+			}
+			break;
+		default:
+			break;
+	}	
+}
+//-----------------------------------------------------------------------
+void OcclusionCullingSceneManager::SetObjectVisible(GtpVisibilityPreprocessor::Intersectable *entry, 
+													const bool visible)
+{
+	switch (entry->Type())
+	{
+	case GtpVisibilityPreprocessor::Intersectable::OGRE_MESH_INSTANCE:
+		{
+			OgreMeshInstance *omi = static_cast<OgreMeshInstance *>(entry);
+			omi->GetEntity()->setVisible(visible);
+			//GtpVisibilityPreprocessor::Debug << "assigned id " << omi->GetId() << endl;
+		}
+		break;
+	case GtpVisibilityPreprocessor::Intersectable::ENGINE_INTERSECTABLE:
+		{
+			EngineIntersectable *oi = static_cast<EngineIntersectable *>(entry);
+
+			EntityContainer *entries = oi->GetItem();
+			EntityContainer::const_iterator eit, eit_end = entries->end();
+			for (eit = entries->begin(); eit != eit_end; ++ eit)
+			{
+				Entity *ent = *eit;
+				ent->setVisible(visible);
+			}
+		}
+		break;
+	default:
+		break;
+	}
+}
 //-----------------------------------------------------------------------
 void OcclusionCullingSceneManager::PrepareVisualization(Camera *cam)
@@ -404,46 +527,26 @@
 
 	// show current view cell geometry
-    if (mCurrentViewCell && mCurrentViewCell->GetMesh())
-	{/*
+    if (mCurrentViewCell)// && mCurrentViewCell->GetMesh())
+	{
 		//const bool showSingleViewCell = true;
 		if (mViewCellsGeometryLoaded)
 		{
-			if (!mShowViewCells)
-			{
-				const int id = mCurrentViewCell->GetId();
-
-				MovableMap::iterator fit = mViewCellsGeometry.find(id);
-
-				if ((fit != mViewCellsGeometry.end()) && (*fit).second)
-					(*fit).second->_updateRenderQueue(getRenderQueue());
-			}
-			else
-			{
-				MovableMap::const_iterator mit, mit_end = mViewCellsGeometry.end();
-
-				for (mit = mViewCellsGeometry.begin(); mit != mit_end; ++ mit)
-				{
-					if ((*mit).second)
-						(*mit).second->_updateRenderQueue(getRenderQueue());
-				}	
-			}
-		}
-		*/
+			ShowViewCellsGeometry();
+		}
+		
 		//////////
 		//-- set PVS of view cell visible
 
-		GtpVisibilityPreprocessor::ObjectPvsIterator pit = mCurrentViewCell->GetPvs().GetIterator();
+		GtpVisibilityPreprocessor::ObjectPvsIterator pit = 
+			mCurrentViewCell->GetPvs().GetIterator();
+
+		MailPvsObjects();
 
 		while (pit.HasMoreEntries())
-		{		
-			GtpVisibilityPreprocessor::ObjectPvsEntry entry = pit.Next();
-			GtpVisibilityPreprocessor::Intersectable *obj = entry.mObject;
-
-			OgreMeshInstance *omi = static_cast<OgreMeshInstance *>(obj);
-			omi->GetEntity()->_updateRenderQueue(getRenderQueue());
-		}
-		
-	}
-/*
+		{
+			RenderPvsEntry(pit.Next());
+		}	
+	}
+#if 0
    if (mRenderNodesForViz || mRenderNodesContentForViz)
 	{
@@ -479,5 +582,6 @@
 			}
 		}
-	}*/
+	}
+#endif
 }
 //-----------------------------------------------------------------------
@@ -601,8 +705,8 @@
 {
 	// $$matt temp: Remove this!!
-	if (1) 
+	if (0) 
 	{
 		getDestinationRenderSystem()->_setCullingMode(CULL_NONE);
-		LogManager::getSingleton().logMessage("warning: culling mode");
+		//LogManager::getSingleton().logMessage("warning: culling mode");
 	}
 
@@ -1367,7 +1471,5 @@
 		GtpVisibilityPreprocessor::Intersectable *entry = *it;
 
-		OgreMeshInstance *omi = static_cast<OgreMeshInstance *>(entry);
-		omi->GetEntity()->setVisible(visible);
-		//GtpVisibilityPreprocessor::Debug << "assigned id " << omi->GetId() << endl;
+		SetObjectVisible(entry, visible);
 	}
 }
@@ -1421,6 +1523,4 @@
 	}
 		
-	GtpVisibilityPreprocessor::ObjectPvsIterator pit = vc->GetPvs().GetIterator();
-
 	////////////
 	//-- set PVS of view cell to visible
@@ -1429,14 +1529,14 @@
 	//LogManager::getSingleton().logMessage(d.str());
 
+	GtpVisibilityPreprocessor::ObjectPvsIterator pit = vc->GetPvs().GetIterator();
+
 	while (pit.HasMoreEntries())
 	{		
-		GtpVisibilityPreprocessor::ObjectPvsEntry entry = pit.Next();
-		GtpVisibilityPreprocessor::Intersectable *obj = entry.mObject;
+		GtpVisibilityPreprocessor::Intersectable *obj = pit.Next();
 
 		// no associated geometry found
 		if (!obj) continue;
 	
-		OgreMeshInstance *omi = static_cast<OgreMeshInstance *>(obj);
-		omi->GetEntity()->setVisible(load);
+		SetObjectVisible(obj, load);
 	}
 }
@@ -1706,10 +1806,8 @@
 												SceneNode *root)
 {
-	ObjReader objReader(this);
-
 	Timer *timer = PlatformManager::getSingleton().createTimer();
 	timer->reset();
 
-	if (!objReader.LoadFile(filename.c_str(), viewCellsFile, root))
+	if (!mObjReader->LoadFile(filename.c_str(), viewCellsFile, root))
 	{
 		PlatformManager::getSingleton().destroyTimer(timer);
Index: /GTP/trunk/Lib/Vis/OnlineCullingCHC/ObjReader/include/ObjManualMeshLoader.h
===================================================================
--- /GTP/trunk/Lib/Vis/OnlineCullingCHC/ObjReader/include/ObjManualMeshLoader.h	(revision 2111)
+++ /GTP/trunk/Lib/Vis/OnlineCullingCHC/ObjReader/include/ObjManualMeshLoader.h	(revision 2123)
@@ -2,22 +2,21 @@
 #define __ObjManualMeshLoader_H__
 
+#include "Ogre.h"
 
-#include "Ogre.h"
-#include "ObjMeshData.h"
-
+namespace  GtpVisibilityPreprocessor {
+class BvhLeaf;
+}
 
 class __declspec(dllexport) ObjManualMeshLoader: public Ogre::ManualResourceLoader
 {
-	public:
-		ObjManualMeshLoader();
-		ObjManualMeshLoader(ObjMeshData *mData);
-		~ObjManualMeshLoader(); 
+public:
+	ObjManualMeshLoader(GtpVisibilityPreprocessor::BvhLeaf *obj);
+	~ObjManualMeshLoader(); 
 
-		void loadResource(Ogre::Resource *resource);
+	void loadResource(Ogre::Resource *resource);
 
-		Ogre::AxisAlignedBox *getBoundingBox();
-	private:
-		ObjMeshData *data;
+protected:
 
+	GtpVisibilityPreprocessor::BvhLeaf *mObject;
 };
 
Index: /GTP/trunk/Lib/Vis/OnlineCullingCHC/ObjReader/include/ObjReader.h
===================================================================
--- /GTP/trunk/Lib/Vis/OnlineCullingCHC/ObjReader/include/ObjReader.h	(revision 2122)
+++ /GTP/trunk/Lib/Vis/OnlineCullingCHC/ObjReader/include/ObjReader.h	(revision 2123)
@@ -7,4 +7,7 @@
 #include "Containers.h"
 
+namespace  GtpVisibilityPreprocessor {
+class Intersectable;
+}
 
 class __declspec(dllexport) ObjReader
@@ -14,8 +17,10 @@
 	~ObjReader();
 
-	bool LoadFile(const string &sceneName, 
-				  const string &visibilitySolution,
+	bool LoadFile(const std::string &sceneName, 
+				  const std::string &visibilitySolution,
 				  Ogre::SceneNode *root);
-	
+	void dummy();
+	Ogre::Entity * dummy2(const std::string &name,
+				GtpVisibilityPreprocessor::Intersectable *object);
 	Ogre::Entity *CreateEntity(const std::string &name,
 							   GtpVisibilityPreprocessor::Intersectable *object);
@@ -25,4 +30,5 @@
 
 	Ogre::SceneManager *mSceneManager;
+	GtpVisibilityPreprocessor::ObjectContainer mPvsObjects;
 };
 
Index: /GTP/trunk/Lib/Vis/OnlineCullingCHC/ObjReader/src/ObjReader.vcproj
===================================================================
--- /GTP/trunk/Lib/Vis/OnlineCullingCHC/ObjReader/src/ObjReader.vcproj	(revision 2122)
+++ /GTP/trunk/Lib/Vis/OnlineCullingCHC/ObjReader/src/ObjReader.vcproj	(revision 2123)
@@ -20,21 +20,21 @@
 				Name="VCCLCompilerTool"
 				Optimization="0"
-				AdditionalIncludeDirectories="&quot;$(OGRE_PATH)\Dependencies\include\CEGUI&quot;;&quot;$(OGRE_PATH)\Samples\Common\CEGUIRenderer\include&quot;;&quot;$(OGRE_PATH)\OgreMain\include&quot;;&quot;$(OGRE_PATH)\Dependencies\include&quot;;&quot;$(OGRE_PATH)\Samples\Common\include&quot;;..\include"
+				AdditionalIncludeDirectories="&quot;$(OGRE_PATH)\Dependencies\include\CEGUI&quot;;&quot;$(OGRE_PATH)\Samples\Common\CEGUIRenderer\include&quot;;&quot;$(OGRE_PATH)\OgreMain\include&quot;;&quot;$(OGRE_PATH)\Dependencies\include&quot;;&quot;$(OGRE_PATH)\Samples\Common\include&quot;;..\include;..\..\..\Preprocessing\src"
 				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;OBJREADER_EXPORTS;GTP_VISIBILITY_MODIFIED_OGRE"
 				MinimalRebuild="TRUE"
 				BasicRuntimeChecks="3"
-				RuntimeLibrary="1"
-				UsePrecompiledHeader="0"
-				WarningLevel="3"
-				Detect64BitPortabilityProblems="TRUE"
-				DebugInformationFormat="3"/>
-			<Tool
-				Name="VCCustomBuildTool"/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="OgreMain_d.lib CEGUIBase_d.lib OgreGUIRenderer_d.lib"
-				OutputFile="$(OutDir)/ObjReader.dll"
-				LinkIncremental="1"
-				AdditionalLibraryDirectories="&quot;$(OGRE_PATH)\OgreMain\lib\$(ConfigurationName)&quot;;&quot;$(OGRE_PATH)\Samples\Common\CEGUIRenderer\lib&quot;;&quot;..\..\GtpVisibility\lib\$(ConfigurationName)&quot;;&quot;..\..\lib\$(ConfigurationName)&quot;;&quot;..\lib\$(ConfigurationName)&quot;;&quot;$(OGRE_PATH)\Dependencies\lib\$(ConfigurationName)&quot;"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="OgreMain_d.lib CEGUIBase_d.lib OgreGUIRenderer_d.lib Preprocessor.lib xerces-c_2.lib zdll.lib zziplibd.lib"
+				OutputFile="$(OutDir)/ObjReader.dll"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="&quot;$(OGRE_PATH)\OgreMain\lib\$(ConfigurationName)&quot;;&quot;$(OGRE_PATH)\Samples\Common\CEGUIRenderer\lib&quot;;&quot;..\..\GtpVisibility\lib\$(ConfigurationName)&quot;;&quot;..\..\lib\$(ConfigurationName)&quot;;&quot;..\lib\$(ConfigurationName)&quot;;&quot;$(OGRE_PATH)\Dependencies\lib\$(ConfigurationName)&quot;;&quot;..\..\..\Preprocessing\lib\$(ConfigurationName)&quot;;..\..\..\..\..\..\..\NonGTP\Xerces\xercesc\lib"
 				GenerateDebugInformation="TRUE"
 				ProgramDatabaseFile="$(OutDir)/$(ProjectName).pdb"
@@ -73,5 +73,5 @@
 				Name="VCCLCompilerTool"
 				AdditionalIncludeDirectories="&quot;$(OGRE_PATH)\OgreMain\include&quot;;&quot;$(OGRE_PATH)\Dependencies\include&quot;;&quot;$(OGRE_PATH)\Samples\Common\include&quot;;..\include;..\..\..\Preprocessing\src"
-				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;OBJREADER_EXPORTS;GTP_VISIBILITY_MODIFIED_OGRE;GAMETOOLS_ILLUMINATION_MODULE1;USE_VERBOSE_PVS"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;OBJREADER_EXPORTS;GTP_VISIBILITY_MODIFIED_OGRE;GAMETOOLS_ILLUMINATION_MODULE"
 				RuntimeLibrary="2"
 				UsePrecompiledHeader="0"
@@ -339,14 +339,20 @@
 			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
 			<File
+				RelativePath=".\ObjManualMeshLoader.cpp">
+			</File>
+			<File
 				RelativePath="..\src\ObjReader.cpp">
 			</File>
-			<Filter
-				Name="Header Files"
-				Filter="h;hpp;hxx;hm;inl;inc;xsd"
-				UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
-				<File
-					RelativePath="..\include\ObjReader.h">
-				</File>
-			</Filter>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+			<File
+				RelativePath="..\include\ObjManualMeshLoader.h">
+			</File>
+			<File
+				RelativePath="..\include\ObjReader.h">
+			</File>
 		</Filter>
 	</Files>
Index: /GTP/trunk/Lib/Vis/OnlineCullingCHC/ObjReader/src/ObjManualMeshLoader.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/OnlineCullingCHC/ObjReader/src/ObjManualMeshLoader.cpp	(revision 2111)
+++ /GTP/trunk/Lib/Vis/OnlineCullingCHC/ObjReader/src/ObjManualMeshLoader.cpp	(revision 2123)
@@ -1,13 +1,12 @@
 #include "ObjManualMeshLoader.h"
-#include "ObjReader.h"
+#include "Triangle3.h"
+#include "IntersectableWrapper.h"
+#include "BvHierarchy.h"
+#include "OgreLogManager.h"
 
-ObjManualMeshLoader::ObjManualMeshLoader()
-{
-	data = NULL;
-}
+#define USE_HBL_DISCARD 1
 
-
-ObjManualMeshLoader::ObjManualMeshLoader(ObjMeshData *mData):
-data(mData)
+ObjManualMeshLoader::ObjManualMeshLoader(GtpVisibilityPreprocessor::BvhLeaf *obj):
+mObject(obj)
 {
 }
@@ -16,15 +15,4 @@
 ObjManualMeshLoader::~ObjManualMeshLoader()
 {
-	if (data != NULL)
-	{
-		data->collapse();
-		delete data;
-	}
-}
-
-
-Ogre::AxisAlignedBox *ObjManualMeshLoader::getBoundingBox()
-{
-	return data->boundingBox;
 }
 
@@ -33,89 +21,109 @@
 {
 	using namespace Ogre;
-	Mesh *pMesh = (Mesh *) resource;
 
+	Mesh *mesh = (Mesh *) resource;
+	SubMesh* submesh = mesh->createSubMesh();
 
-	Vector3 translation = data->boundingBox->getCenter();
+	const int triCount = (int)mObject->mObjects.size();
+	const int vertexCount = triCount * 3;
 
-	bool nOk = ((data->normals != NULL) && (data->ncnt > 0));
-	bool tOk = ((data->texCoords != NULL) && (data->tcnt > 0));
-	
-	pMesh->sharedVertexData = new VertexData(); 
+	// We must create the vertex data, indicating how many vertices there will be
+	submesh->useSharedVertices = false;
+	submesh->vertexData = new VertexData();
+	submesh->vertexData->vertexStart = 0;
+	submesh->vertexData->vertexCount = vertexCount;
 
-	VertexDeclaration* vertexDecl = pMesh->sharedVertexData->vertexDeclaration; 
+	static const unsigned short source = 0;
+	size_t offset = 0;
 
-	size_t currOffset = 0; 
-	vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_POSITION); 
-	currOffset += VertexElement::getTypeSize(VET_FLOAT3); 
-	if (nOk)
+	// We must now declare what the vertex data contains
+	VertexDeclaration* declaration = submesh->vertexData->vertexDeclaration;
+
+	offset += declaration->addElement(source, offset, VET_FLOAT3, VES_POSITION).getSize();
+	offset += declaration->addElement(source, offset, VET_FLOAT3, VES_NORMAL).getSize();
+	//offset += declaration->addElement(source, offset, VET_FLOAT2,VES_TEXTURE_COORDINATES).getSize();
+
+	HardwareVertexBufferSharedPtr vbuffer = HardwareBufferManager::getSingleton().
+		createVertexBuffer(declaration->getVertexSize(source),
+						   submesh->vertexData->vertexCount,
+						   HardwareBuffer::HBU_STATIC_WRITE_ONLY);
+
+    // we get access to the buffer to fill it.  During so we record the bounding box.
+	AxisAlignedBox aabox;
+
+	submesh->vertexData->vertexBufferBinding->setBinding(source, vbuffer);
+#if USE_HBL_DISCARD
+	float* vdata = static_cast<float*>(vbuffer->lock(HardwareBuffer::HBL_DISCARD));
+#else
+	float* vdata = static_cast<float *>(vbuffer->lock(HardwareBuffer::HBL_NORMAL));
+#endif
+
+	GtpVisibilityPreprocessor::ObjectContainer::
+		const_iterator oit, oit_end = mObject->mObjects.end();
+
+	for (oit = mObject->mObjects.begin(); oit != oit_end; ++ oit)
 	{
-		vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_NORMAL); 
-		currOffset += VertexElement::getTypeSize(VET_FLOAT3); 
-	}
-    if (tOk)
-	{
-		vertexDecl->addElement(0, currOffset, VET_FLOAT2, VES_TEXTURE_COORDINATES); 
-		currOffset += VertexElement::getTypeSize(VET_FLOAT2); 
-	}
+		GtpVisibilityPreprocessor::TriangleIntersectable *tObj = 
+			static_cast<GtpVisibilityPreprocessor::TriangleIntersectable *>(*oit);
+		
+		const GtpVisibilityPreprocessor::Triangle3 tri = tObj->GetItem();
+		const GtpVisibilityPreprocessor::Vector3 n = tri.GetNormal();
 
-	pMesh->sharedVertexData->vertexCount = data->vcnt/3; 
-	HardwareVertexBufferSharedPtr vbuf = 
-		HardwareBufferManager::getSingleton(). 
-		createVertexBuffer(vertexDecl->getVertexSize(0), pMesh->sharedVertexData->vertexCount, 
-			HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); 
+		for (int i = 0; i < 3; ++ i)
+		{
+			Vector3 vtx(tri.mVertices[i].x, tri.mVertices[i].y, tri.mVertices[i].z);
+		
+			*(vdata ++) = vtx.x;
+			*(vdata ++) = vtx.y;
+			*(vdata ++) = vtx.z;
 
-	VertexBufferBinding* binding = pMesh->sharedVertexData->vertexBufferBinding; 
-	binding->setBinding(0, vbuf); 
+			*(vdata ++) = n.x;
+			*(vdata ++) = n.y;
+			*(vdata ++) = n.z;
 
-	Real* pVertices = static_cast<Real*>(vbuf->lock(HardwareBuffer::HBL_DISCARD)); 
-
-	int offset = 0, size = 3;
-	if (nOk) size += 3;
-	if (tOk) size += 2;
-	for (int i=0; i<data->vcnt/3; i++) 
-	{
-		pVertices[i*size]   = data->vertices[i*3]   - translation.x;
-		pVertices[i*size+1] = data->vertices[i*3+1] - translation.y;
-		pVertices[i*size+2] = data->vertices[i*3+2] - translation.z;
-
-		offset = 3;
-		if (nOk)
-		{
-			pVertices[i*size+offset] = data->normals[i*3];	 offset++;
-			pVertices[i*size+offset] = data->normals[i*3+1]; offset++;
-			pVertices[i*size+offset] = data->normals[i*3+2]; offset++;
-		}
-		if (tOk)
-		{
-			pVertices[i*size+offset] = data->texCoords[i*2];   offset++;
-			pVertices[i*size+offset] = -data->texCoords[i*2+1]; offset++;
+			aabox.merge(vtx);
 		}
 	}
 
-	vbuf->unlock(); 
+	vbuffer->unlock();
+
+#if 0
+	RenderOperation rop;
+	submesh->_getRenderOperation(rop);
+	rop.useIndexes = false;
+#endif
+	//////
+	//-- Creates the index data
+    
+	const int indexCount = vertexCount;
+	submesh->indexData->indexStart = 0;
+	submesh->operationType = RenderOperation::OT_TRIANGLE_LIST;
+
+	// we use an index for every vertex
+	submesh->indexData->indexCount = indexCount;
+	submesh->indexData->indexBuffer =
+	    HardwareBufferManager::getSingleton().
+			createIndexBuffer(HardwareIndexBuffer::IT_16BIT,
+							  submesh->indexData->indexCount,
+							  HardwareBuffer::HBU_STATIC_WRITE_ONLY);
+
+#if USE_HBL_DISCARD
+	uint16* idata = static_cast<uint16 *>(submesh->indexData->indexBuffer->lock(HardwareBuffer::HBL_DISCARD));
+#else
+	uint16* idata = static_cast<uint16 *>(submesh->indexData->indexBuffer->lock(HardwareBuffer::HBL_NORMAL));
+#endif
+	for (int j = 0; j < indexCount; ++ j)
+    {
+		idata[j] = j;
+    }
+    
+	submesh->indexData->indexBuffer->unlock();
+	submesh->setMaterialName("BaseWhite"); 
+
+	// indicate the bounding box
+	mesh->_setBounds(aabox); 
+	mesh->_setBoundingSphereRadius((aabox.getMaximum() - aabox.getMinimum()).length() / 2.0); 
+}
 
 
-	SubMesh *pSub = pMesh->createSubMesh(); 
-	pSub->operationType = RenderOperation::OT_TRIANGLE_LIST; //;data->roType;
-	pSub->useSharedVertices = true; 
 
-	pSub->indexData->indexCount = data->icnt; 
-	pSub->indexData->indexBuffer = HardwareBufferManager::getSingleton(). 
-		createIndexBuffer(HardwareIndexBuffer::IT_16BIT, 
-			pSub->indexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); 
-
-	HardwareIndexBufferSharedPtr ibuf = pSub->indexData->indexBuffer; 
-	unsigned short* pIndices = static_cast<unsigned short*>(ibuf->lock(HardwareBuffer::HBL_DISCARD)); 
-
-	for (i = 0; i < data->icnt; i++) pIndices[i] = data->indices[i];
-	
-	ibuf->unlock(); 
-		
-	AxisAlignedBox bb(data->boundingBox->getMinimum() - translation, data->boundingBox->getMaximum() - translation);
-	//AxisAlignedBox bb(data->boundingBox->getMinimum(), data->boundingBox->getMaximum());
-	pMesh->_setBounds(bb); 
-	Real radius = data->boundingBox->getMinimum().length();
-	if (data->boundingBox->getMaximum().length() > radius) radius = data->boundingBox->getMaximum().length();
-	pMesh->_setBoundingSphereRadius(radius); 
-
-}
Index: /GTP/trunk/Lib/Vis/OnlineCullingCHC/ObjReader/src/ObjReader.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/OnlineCullingCHC/ObjReader/src/ObjReader.cpp	(revision 2122)
+++ /GTP/trunk/Lib/Vis/OnlineCullingCHC/ObjReader/src/ObjReader.cpp	(revision 2123)
@@ -8,4 +8,5 @@
 #include "PreprocessorFactory.h"
 #include "OgreLogManager.h"
+#include "ObjManualMeshLoader.h"
 
 
@@ -17,5 +18,7 @@
 
 ObjReader::~ObjReader()
-{}
+{
+	CLEAR_CONTAINER(mPvsObjects);
+}
 
 
@@ -31,7 +34,6 @@
 	// hack
 	preprocessor->mLoadMeshes = false;
-	GtpVisibilityPreprocessor::ObjectContainer pvsObjects;
 
-	Ogre::LogManager::getSingleton().logMessage("loading obj scene!!");
+	Ogre::LogManager::getSingleton().logMessage("loading obj scene");
 
 	if (preprocessor->LoadScene(sceneName))
@@ -39,5 +41,5 @@
 		Ogre::LogManager::getSingleton().logMessage("scene loaded, loading objects");
 		// form objects from the scene triangles
-		if (!preprocessor->LoadObjects(visibilitySolution, pvsObjects, preprocessor->mObjects))
+		if (!preprocessor->LoadObjects(visibilitySolution, mPvsObjects, preprocessor->mObjects))
 		{
 			Ogre::LogManager::getSingleton().logMessage("objects cannot be loaded");
@@ -52,17 +54,25 @@
 
 	std::stringstream d; 
-	d << "successfully loaded " << pvsObjects.size() << " objects from " << preprocessor->mObjects.size() << " preprocessor objects";
+	d << "successfully loaded " << mPvsObjects.size() << " objects from " << preprocessor->mObjects.size() << " preprocessor objects";
 
 	Ogre::LogManager::getSingleton().logMessage(d.str());
 
-	GtpVisibilityPreprocessor::ObjectContainer::const_iterator oit, oit_end = pvsObjects.end();
+	GtpVisibilityPreprocessor::ObjectContainer::const_iterator oit, oit_end = mPvsObjects.end();
 
 	int i = 0;
-	for (oit = pvsObjects.begin(); oit != oit_end; ++ oit, ++ i)
+	for (oit = mPvsObjects.begin(); oit != oit_end; ++ oit, ++ i)
 	{
-		Ogre::LogManager::getSingleton().logMessage("r");
+		if (i % 5000 == 4999)
+		{
+			d << i << " objects created" << endl;
+		}
+	
 		const Ogre::String entname = "Object" + Ogre::StringConverter::toString(i);
 
-		Ogre::ManualObject *ent = CreateEntity(entname, *oit);
+#if 0
+		Ogre::ManualObject *ent = CreateManualObject(entname, *oit);
+#else
+		Ogre::Entity *ent = CreateEntity(entname, *oit);
+#endif
 
 		const Ogre::String nodeName = entname + "Node";
@@ -70,6 +80,6 @@
 		node->attachObject(ent);
 
-		if (i > 100)
-			break;
+		// problems for too many objects (= vbo)?
+		//if (i > 30000)break;
 	}
 
@@ -89,14 +99,19 @@
 	std::string entityName = name + "Entity";
 
-GtpVisibilityPreprocessor::BvhLeaf *bvhObj = 
+	GtpVisibilityPreprocessor::BvhLeaf *bvhObj = 
 		static_cast<GtpVisibilityPreprocessor::BvhLeaf *>(object);
+
 	const int vertexCount = (int)bvhObj->mObjects.size() * 3;
 
 	ManualObject* manual = mSceneManager->createManualObject(entityName);
-	manual->begin("BaseWhiteNoLighting", RenderOperation::OT_LINE_STRIP);
+	manual->begin("BaseWhite", RenderOperation::OT_TRIANGLE_LIST);
 	
+	const float red = GtpVisibilityPreprocessor::Random(1.0f);
+	const float green = GtpVisibilityPreprocessor::Random(1.0f);
+	const float blue = GtpVisibilityPreprocessor::Random(1.0f);
+
 	// create vertices
-	
-	GtpVisibilityPreprocessor::ObjectContainer::const_iterator oit, oit_end = bvhObj->mObjects.end();
+	GtpVisibilityPreprocessor::ObjectContainer::const_iterator oit, 
+		oit_end = bvhObj->mObjects.end();
 	
 	for (oit = bvhObj->mObjects.begin(); oit != oit_end; ++ oit)
@@ -110,13 +125,19 @@
 		{
 			const GtpVisibilityPreprocessor::Vector3 vtx = tri.mVertices[i];
+			const GtpVisibilityPreprocessor::Vector3 n = tri.GetNormal();
+
 			manual->position(vtx.x, vtx.y, vtx.z);
-			manual->colour(1.0f, 0.0f, 0.0f);
+			manual->normal(n.x, n.y, n.z);
+			//manual->colour(red, green, blue);
 		}
 	}
 
+	if (0)
 	for (int i = 0; i < vertexCount; ++ i)
 	{
 		manual->index(i);
 	}
+
+	manual->end();
 
 	return manual;
@@ -137,108 +158,13 @@
 	std::string entityName = name + "Entity";
 
-	MeshPtr mesh = MeshManager::getSingleton().createManual(meshName, "Custom");
-	SubMesh* submesh = mesh->createSubMesh();
+	ObjManualMeshLoader *loader = new ObjManualMeshLoader(bvhObj);
 
-	const int vertexCount = (int)bvhObj->mObjects.size() * 3;
-
-	// We must create the vertex data, indicating how many vertices there will be
-	submesh->useSharedVertices = false;
-	submesh->vertexData = new VertexData();
-	submesh->vertexData->vertexStart = 0;
-	submesh->vertexData->vertexCount = vertexCount;
-
-	std::stringstream d; d << "objects: " << bvhObj->mObjects.size() << " vtx: " << submesh->vertexData->vertexCount << endl;
-	Ogre::LogManager::getSingleton().logMessage(d.str());
-
-	static const unsigned short source = 0;
-	size_t offset = 0;
-
-	VertexDeclaration* declaration = HardwareBufferManager::getSingleton().createVertexDeclaration();
-
-	offset += declaration->addElement(source, offset, VET_FLOAT3, VES_POSITION).getSize();
-	//offset += declaration->addElement(source, offset, VET_FLOAT3,VES_NORMAL).getSize();
-	//offset += declaration->addElement(source, offset, VET_FLOAT2,VES_TEXTURE_COORDINATES).getSize();
-
-
-	int numVertices = 0;
-
-	HardwareVertexBufferSharedPtr vbuffer = HardwareBufferManager::getSingleton().
-		createVertexBuffer(declaration->getVertexSize(source),
-						   submesh->vertexData->vertexCount,
-						   HardwareBuffer::HBU_STATIC_WRITE_ONLY);
-
-    // No we get access to the buffer to fill it.  During so we record the bounding box.
-	AxisAlignedBox aabox;
-
-	float* vdata = static_cast<float*>(vbuffer->lock(HardwareBuffer::HBL_DISCARD));
-
-	GtpVisibilityPreprocessor::ObjectContainer::const_iterator oit, oit_end = bvhObj->mObjects.end();
-
-	for (oit = bvhObj->mObjects.begin(); oit != oit_end; ++ oit)
-	{
-		GtpVisibilityPreprocessor::TriangleIntersectable *tObj = 
-			static_cast<GtpVisibilityPreprocessor::TriangleIntersectable *>(*oit);
-		
-		GtpVisibilityPreprocessor::Triangle3 tri = tObj->GetItem();
-
-		for (int i = 0; i < 3; ++ i)
-		{
-			Vector3 vtx = Vector3(tri.mVertices[i]);
-
-			*vdata ++ = vtx.x;
-			*vdata ++ = vtx.y;
-			*vdata ++ = vtx.z;
-
-			//std::stringstream d; d << vtx;
-			//Ogre::LogManager::getSingleton().logMessage(d.str());
-			aabox.merge(vtx);
-		}
-	}
-	//Ogre::LogManager::getSingleton().logMessage("***");
-	vbuffer->unlock();
-	
-	/*Ogre::RenderOperation rop;
-	submesh->_getRenderOperation(rop);
-	rop.useIndexes = false;
-*/
-	//////
-	//-- Creates the index data
-
-    submesh->vertexData->vertexBufferBinding->setBinding(source, vbuffer);
-
-	submesh->indexData->indexStart = 0;
-	// we use an index for every vertex
-	submesh->indexData->indexCount = vertexCount;
-	submesh->indexData->indexBuffer =
-	    HardwareBufferManager::getSingleton().
-			createIndexBuffer(HardwareIndexBuffer::IT_16BIT,
-							  submesh->indexData->indexCount,
-							  HardwareBuffer::HBU_STATIC_WRITE_ONLY);
-	submesh->operationType = RenderOperation::OT_LINE_STRIP;
-	//uint16* idata = static_cast<uint16*>(submesh->indexData->indexBuffer->lock(HardwareBuffer::HBL_DISCARD));
-    unsigned short* idata = static_cast<unsigned short*>(submesh->indexData->indexBuffer->lock(HardwareBuffer::HBL_DISCARD));
-
-	for (int j = 0; j < vertexCount; ++ j)
-    {
-		*idata = j;
-		++ idata;
-    }
-    
-	submesh->indexData->indexBuffer->unlock();
-
-	submesh->setMaterialName("BaseWhiteNoLighting"); 
-
-	// We must indicate the bounding box
-	mesh->_setBounds(aabox); 
-	mesh->_setBoundingSphereRadius((aabox.getMaximum() - aabox.getMinimum()).length() / 2.0); 
-	mesh->load();
-	mesh->touch();
+	Mesh* pMesh = MeshManager::getSingleton().createManual(meshName, "ObjGroup", loader).getPointer(); 
+	pMesh->load(); 
 
 	// Create an entity with the mesh
 	entity = mSceneManager->createEntity(entityName, meshName);
 
-	//entity->setRenderQueueGroup(Ogre::RENDER_QUEUE_MAIN);
+	return entity;
+}
 
-	return entity;
-#endif
-}
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/Mutation.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/Mutation.cpp	(revision 2105)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/Mutation.cpp	(revision 2123)
@@ -51,5 +51,5 @@
   cerr<<"Muattion update..."<<endl;
   cerr<<"rays = "<<mRays.size()<<endl;
-  if (mRays.size()) {
+  if ((int)mRays.size()) {
 	cerr<<"Oversampling factors = "<<
 	  GetEntry(0).mMutations<<" "<<
@@ -59,10 +59,10 @@
 	  GetEntry(4).mMutations<<" "<<
 	  GetEntry(5).mMutations<<" ... "<<
-	  GetEntry(mRays.size()-6).mMutations<<" "<<
-	  GetEntry(mRays.size()-5).mMutations<<" "<<
-	  GetEntry(mRays.size()-4).mMutations<<" "<<
-	  GetEntry(mRays.size()-3).mMutations<<" "<<
-	  GetEntry(mRays.size()-2).mMutations<<" "<<
-	  GetEntry(mRays.size()-1).mMutations<<endl;
+	  GetEntry((int)mRays.size()-6).mMutations<<" "<<
+	  GetEntry((int)mRays.size()-5).mMutations<<" "<<
+	  GetEntry((int)mRays.size()-4).mMutations<<" "<<
+	  GetEntry((int)mRays.size()-3).mMutations<<" "<<
+	  GetEntry((int)mRays.size()-2).mMutations<<" "<<
+	  GetEntry((int)mRays.size()-1).mMutations<<endl;
   }
   int contributingRays = 0;
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/ObjectPvs.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/ObjectPvs.h	(revision 2120)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/ObjectPvs.h	(revision 2123)
@@ -23,7 +23,5 @@
 		but the individual contributions of the entries are summed up.
 	*/
-	float EvalPvsCost() const {	
-		//temp matt 
-		return 1.0f; }
+	float EvalPvsCost() const;
 
 	friend ostream &operator<<(ostream &s, const ObjectPvs &p) 
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsParser.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsParser.h	(revision 2114)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsParser.h	(revision 2123)
@@ -11,4 +11,5 @@
 class BoundingBoxConverter;
 class Environment;
+
 
 class ViewCellsParser: public Parser
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h	(revision 2117)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h	(revision 2123)
@@ -7,5 +7,5 @@
 #include "Containers.h"
 #include "ViewCell.h"
-//#include "ViewCellBsp.h"
+
 
 namespace GtpVisibilityPreprocessor {
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/ObjectPvs.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/ObjectPvs.cpp	(revision 2123)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/ObjectPvs.cpp	(revision 2123)
@@ -0,0 +1,170 @@
+#include <iostream>
+#include <stack>
+#include "ObjectPvs.h"
+#include "Intersectable.h"
+#include "IntersectableWrapper.h"
+#include "KdTree.h"
+#include "common.h"
+#include "BvHierarchy.h"
+
+
+namespace GtpVisibilityPreprocessor {
+
+
+/** the pvs is the number of different objects in the node leaves
+	We eliminate already accounted kd nodes and objects using mailboxing. 
+*/
+static int EvalKdNodeContribution(KdIntersectable *kdobj)
+{
+	int pvs = 0;
+	stack<KdNode *> tStack;
+
+	tStack.push(kdobj->GetItem());
+
+	while (!tStack.empty())
+	{
+		KdNode *node = tStack.top();
+		tStack.pop();
+
+		// already processed node (=> objects already in pvs)?
+		if (!node->Mailed())
+		{
+			node->Mail();
+
+			if (node->IsLeaf())
+			{
+				KdLeaf *leaf = static_cast<KdLeaf *>(node);
+                       
+				// add #objects exclusivly in this node
+				pvs += (int)(leaf->mObjects.size() - leaf->mMultipleObjects.size());
+
+				// Objects already accounted for can only be found among those
+				// which are referenced in more than one leaf
+				ObjectContainer::const_iterator oit, oit_end = leaf->mMultipleObjects.end();
+						
+				for (oit = leaf->mMultipleObjects.begin(); oit != oit_end; ++ oit)
+				{
+					Intersectable *object = *oit;						
+                            
+					if (!object->Mailed())
+					{
+						object->Mail();
+						++ pvs;
+					}
+				}
+			}
+			else // traverse tree
+			{
+				KdInterior *interior = static_cast<KdInterior *>(node);
+
+				tStack.push(interior->mFront);
+				tStack.push(interior->mBack);
+			}
+		}
+	}
+
+	return pvs;
+}
+
+
+/** Returns the the number of new (unmailed) objects in the leaves of the node.
+	We eliminate already accounted bvh nodes and objects using mailboxing. 
+*/
+static float EvalBvhNodeContribution(BvhNode *bvhObj)
+{
+	BvhNode *node;
+
+	// hack for choosing which node to account for
+	if (bvhObj->IsLeaf())
+		node = static_cast<BvhLeaf *>(bvhObj)->GetActiveNode();
+	else
+		node = bvhObj;
+
+	// early exit
+	if (node->IsLeaf())	
+	{	
+		BvhLeaf *leaf = static_cast<BvhLeaf *>(node);
+		// objects already accounted for
+		if (leaf->Mailed())
+			return 0;
+
+		leaf->Mail();
+		return BvHierarchy::EvalAbsCost(leaf->mObjects);
+	}			 
+
+	// compute leaf pvs
+	float pvs = 0;
+	stack<BvhNode *> tStack;
+	tStack.push(node);
+
+	while (!tStack.empty())
+	{
+		node = tStack.top();
+		tStack.pop();
+
+		// already processed node (=> objects already in pvs)?
+		if (!node->Mailed())
+		{
+			node->Mail();
+
+			if (node->IsLeaf())
+			{
+				BvhLeaf *leaf = static_cast<BvhLeaf *>(node);
+
+				// add #objects exclusivly in this node
+				pvs += BvHierarchy::EvalAbsCost(leaf->mObjects);
+			}
+			else // traverse tree
+			{
+				BvhInterior *interior = static_cast<BvhInterior *>(node);
+
+				tStack.push(interior->GetFront());
+				tStack.push(interior->GetBack());
+			}
+		}
+	}
+
+	return pvs;
+}
+
+
+float ObjectPvs::EvalPvsCost() const
+{
+	float pvs = 0;
+
+	Intersectable::NewMail();
+	KdLeaf::NewMail();
+
+	ObjectPvsIterator pit = GetIterator();
+
+	while (pit.HasMoreEntries())
+	{		
+		Intersectable *obj = pit.Next();
+
+		switch (obj->Type())
+		{
+			case Intersectable::KD_INTERSECTABLE:
+				{
+					// found kd node
+					KdIntersectable *kdObj = static_cast<KdIntersectable *>(obj);
+					pvs += EvalKdNodeContribution(kdObj);	
+					break;
+				}
+			case Intersectable::BVH_INTERSECTABLE:
+				{
+					BvhNode *bvhObj = static_cast<BvhNode *>(obj);
+					pvs += EvalBvhNodeContribution(bvhObj);
+					break;
+				}
+			default:
+				// hack: should use assigned cost here
+				++ pvs;
+				
+				break;
+		}
+	}
+
+	return pvs;
+}
+
+}
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/HashPvs.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/HashPvs.h	(revision 2117)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/HashPvs.h	(revision 2123)
@@ -20,5 +20,5 @@
    {
       bucket_size = 4,
-      min_buckets = 80
+      min_buckets = 8
    };
 
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.vcproj
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.vcproj	(revision 2120)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.vcproj	(revision 2123)
@@ -72,5 +72,5 @@
 				OptimizeForWindowsApplication="TRUE"
 				AdditionalIncludeDirectories="..\include;..\src;..\..\..\..\..\..\NonGTP\Devil\include;..\..\..\..\..\..\NonGTP\Zlib\include;..\..\..\..\..\..\NonGTP\Xerces;..\..\..\..\..\..\NonGTP\Boost;Timer"
-				PreprocessorDefinitions="WIN32;NDEBUG;_LIB;USE_VERBOSE_PVS"
+				PreprocessorDefinitions="WIN32;NDEBUG;_LIB;"
 				ExceptionHandling="TRUE"
 				RuntimeLibrary="2"
@@ -383,4 +383,7 @@
 			</File>
 			<File
+				RelativePath=".\BitVectorPvs.cpp">
+			</File>
+			<File
 				RelativePath=".\BitVectorPvs.h">
 			</File>
@@ -582,4 +585,7 @@
 			<File
 				RelativePath="..\src\MutualVisibility.h">
+			</File>
+			<File
+				RelativePath=".\ObjectPvs.cpp">
 			</File>
 			<File
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/BitVectorPvs.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/BitVectorPvs.cpp	(revision 2123)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/BitVectorPvs.cpp	(revision 2123)
@@ -0,0 +1,7 @@
+#include "BitVectorPvs.h"
+
+
+namespace GtpVisibilityPreprocessor {
+
+
+}
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 2122)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 2123)
@@ -1050,4 +1050,8 @@
 												   preprocessorObjects, 
 												   bconverter);
+
+	//Debug << " view cells parsed in "
+	//	  << TimeDiff(startTime, GetTime()) * 1e-3f << " secs" << endl;
+	
 
 	if (!success)
@@ -3687,4 +3691,6 @@
 	vector<ObjectPvs>::iterator oit = pvsList.begin();
 
+	PvsData pvsData;
+
 	for (vit = interior->mChildren.begin(); vit != vit_end; ++ vit, ++ oit)
 	{
@@ -3694,7 +3700,5 @@
 		while (pit.HasMoreEntries())
 		{		
-			ObjectPvsEntry entry = pit.Next();
-
-			Intersectable *intersect = entry.mObject;
+			Intersectable *intersect = pit.Next(pvsData);
 
 			if (!intersect->Mailed())
@@ -3702,5 +3706,5 @@
 				intersect->Mail();
 
-				pvs.AddSampleDirty(intersect, entry.mData.mSumPdf);
+				pvs.AddSampleDirty(intersect, pvsData.mSumPdf);
 			}
 		}
@@ -4179,9 +4183,7 @@
 			while (pit.HasMoreEntries())
 			{		
-				ObjectPvsEntry entry = pit.Next();
+				Intersectable *intersect = pit.Next();
 
                 // output PVS of view cell
-				Intersectable *intersect = entry.mObject;
-				
 				if (!intersect->Mailed())
 				{
@@ -4684,8 +4686,7 @@
 			while (pit.HasMoreEntries())
 			{		
-				ObjectPvsEntry entry = pit.Next();
-				
 				//-- output PVS of view cell
-				Intersectable *intersect = entry.mObject;
+				Intersectable *intersect = pit.Next();
+
 				if (!intersect->Mailed())
 				{
@@ -5501,6 +5502,5 @@
 			while (pit.HasMoreEntries())
 			{
-				ObjectPvsEntry entry = pit.Next();		
-				Intersectable *intersect = entry.mObject;
+				Intersectable *intersect = pit.Next();		
 				
 				if (!intersect->Mailed())
@@ -6283,7 +6283,7 @@
 		while (pit.HasMoreEntries())
 		{		
-			ObjectPvsEntry entry = pit.Next();
+			Intersectable *obj = pit.Next();
 				
-			BvhNode *node = static_cast<BvhNode *>(entry.mObject);
+			BvhNode *node = static_cast<BvhNode *>(obj);
 			
 			// hack!!
@@ -6496,8 +6496,6 @@
 			while (pit.HasMoreEntries())
 			{		
-				ObjectPvsEntry entry = pit.Next();
+				Intersectable *intersect = pit.Next();
 				
-				Intersectable *intersect = entry.mObject;
-
 				if (!intersect->Mailed())
 				{
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/common.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/common.h	(revision 1757)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/common.h	(revision 2123)
@@ -330,5 +330,5 @@
 long GetTime();
 long GetRealTime();
-Real TimeDiff(long t1,long t2);
+Real TimeDiff(long t1, long t2);
 char *TimeString();
 
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.cpp	(revision 2116)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.cpp	(revision 2123)
@@ -3387,6 +3387,5 @@
 		while (oit.HasMoreEntries())
 		{
-			const ObjectPvsEntry &entry = oit.Next();
-			BvhNode *obj = static_cast<BvhNode *>(entry.mObject);
+			BvhNode *obj = static_cast<BvhNode *>(oit.Next());
 
 			if (!obj->IsRoot())
@@ -3411,11 +3410,11 @@
 			}
 		}
-		
+
+		PvsData pvsData;
 		oit = leaf->GetViewCell()->GetPvs().GetIterator();
 
 		while (oit.HasMoreEntries())
 		{
-			const ObjectPvsEntry &entry = oit.Next();
-			BvhNode *obj = static_cast<BvhNode *>(entry.mObject);
+			BvhNode *obj = static_cast<BvhNode *>(oit.Next(pvsData));
 
 			if (!obj->IsRoot())
@@ -3426,5 +3425,5 @@
 				if (!parent->Mailed(1))
 				{
-					newPvs.AddSampleDirty(obj, entry.mData.mSumPdf);
+					newPvs.AddSampleDirty(obj, pvsData.mSumPdf);
 				}
 			}
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/ObjParser.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/ObjParser.cpp	(revision 2119)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/ObjParser.cpp	(revision 2123)
@@ -203,5 +203,4 @@
 	if (SqrMagnitude(cross_a_b) <= 0.000001 * FLT_EPSILON * FLT_EPSILON) 
 	{
-		cout << "x";
 		// v0, v1 & v2 lies on a line (area == 0)
 		return false;
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/common.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/common.cpp	(revision 2001)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/common.cpp	(revision 2123)
@@ -153,9 +153,9 @@
 // return time diff. in ms
 Real
-TimeDiff(long time1,long time2) // in ms
-{
-  //  const Real clk=1.0e-3f; // ticks per second
+TimeDiff(long time1, long time2) // in ms
+{
+  const Real clk=1.0e-3f; // ticks per second
   // $$ tmp store time in ms
-  const Real clk=1.0f; // ticks per second
+  //const Real clk=1.0f; // ticks per second
   long t=time2-time1;
   
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsParserXerces.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsParserXerces.h	(revision 2116)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsParserXerces.h	(revision 2123)
@@ -8,5 +8,6 @@
 #include "Mesh.h"
 #include "BoundingBoxConverter.h"
-
+#include "PerfTimer.h"
+#include <hash_map>
 
 namespace GtpVisibilityPreprocessor {
@@ -30,4 +31,28 @@
 class BspNode;
 
+/*
+struct pvs_hash_compare
+{
+   enum
+   {
+      bucket_size = 4,
+      min_buckets = 8
+   };
+
+   size_t operator()(Intersectable *a) const
+   {
+	   size_t h = (size_t)(a->GetId());// % 2000;
+	   return h;
+   }
+
+   bool operator()(int a, int b) const
+   {
+      return a < b;
+   }
+};*/
+
+
+typedef stdext::hash_map<int, Intersectable *> pvs_hash;
+
 
 class ViewCellsParseHandlers: public HandlerBase
@@ -132,10 +157,17 @@
   int nObjects;
   
-  
+  PerfTimer mBoxTimer;
+  PerfTimer mPvsTimer;
+  PerfTimer mObjectTimer;
+
+  pvs_hash mHashPvs;
+
   ////////////////////////////////
 
 
   // Handlers for X3D
-  
+
+  void CreateHashVector();
+
   void StartBspLeaf(AttributeList& attributes);
   void StartBspInterior(AttributeList& attributes);
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/ObjectsParser.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/ObjectsParser.cpp	(revision 2119)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/ObjectsParser.cpp	(revision 2123)
@@ -85,10 +85,4 @@
   , mIsObjectSpaceHierarchy(false)
 {
-	// sort objects so we can search in them
-	//if (!is_sorted(mPvsObjects.begin(), mPvsObjects.end(), ilt))
-		sort(mPvsObjects.begin(), mPvsObjects.end(), ilt);
-Debug << "here333";
-	//if (!is_sorted(mPreprocessorObjects.begin(), mPreprocessorObjects.end(), ilt))
-		//sort(mPreprocessorObjects.begin(), mPreprocessorObjects.end(), ilt);
 }
 
@@ -257,4 +251,9 @@
 	{
 		const int objId = *it;	
+
+#if 0
+		// assume there is is no id missing
+		objects.push_back(mPreprocessorObjects[objId]);
+#else
 		dummyInst.SetId(objId);
 
@@ -268,11 +267,6 @@
 		{
 			objects.push_back(*oit);
-			Debug << "x";
-		}
-		else
-		{
-			Debug << "y";
-			//cerr << "StartBvhLeafObjects error: object with id " << objId << " does not exist" << endl;
-		}
+		}
+#endif
 	}
 }
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsParser.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsParser.cpp	(revision 2119)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsParser.cpp	(revision 2123)
@@ -68,4 +68,6 @@
 // hack for loading bvh nodes
 #define PVS_HACK 0
+#define USE_HASH_COMPARE 1
+
 
 inline static bool ilt(Intersectable *obj1, Intersectable *obj2)
@@ -103,12 +105,4 @@
   , nObjects(0)
 {
-	// q: can we assume that the objects are sorted?
-	
-	// sort objects so we can search in them
-	//if (!is_sorted(mPvsObjects.begin(), mPvsObjects.end(), ilt))
-		sort(mPvsObjects.begin(), mPvsObjects.end(), ilt);
-
-	//if (!is_sorted(mPreprocessorObjects.begin(), mPreprocessorObjects.end(), ilt))
-	//	sort(mPreprocessorObjects.begin(), mPreprocessorObjects.end(), ilt);
 }
 
@@ -119,4 +113,26 @@
 
 
+void ViewCellsParseHandlers::CreateHashVector()
+{
+	ObjectContainer::const_iterator oit, oit_end = mPvsObjects.end();
+
+	for (oit = mPvsObjects.begin(); oit != oit_end; ++ oit)
+	{
+		mHashPvs[(*oit)->GetId()] = (*oit);
+	}
+	//Debug<<"\nhsize: " << mHashPvs.size() << endl;
+}
+/*
+void ViewCellsParseHandlers::CreateHashVector2()
+{
+	ObjectContainer::const_iterator oit, oit_end = mPvsObjects.end();
+
+	for (oit = mPvsObjects.begin(); oit != oit_end; ++ oit)
+	{
+		mHashPvs[(*oit)->GetId()] = (*oit);
+	}
+	Debug<<"\nhsize: " << mHashPvs.size() << endl;
+}
+*/
 // ---------------------------------------------------------------------------
 //  StdInParseHandlers: Implementation of the SAX DocumentHandler interface
@@ -133,22 +149,26 @@
 		EndBoundingBoxes();
 	}
-
-	if (element == "ViewCells")
+	else if (element == "ViewCells")
 	{	
 		EndViewCells();
-	}
-
-	if (element == "ObjectSpaceHierarchy")
+		Debug << "view cell hierarchy parsed" << endl;
+	}
+	else if (element == "ObjectSpaceHierarchy")
 	{
 		EndObjectSpaceHierarchy();
-	}
-
-	// finished, create view cells manager
-	if (element == "VisibilitySolution")
+		Debug << "object space hierarchy parsed" << endl;
+		mObjectTimer.Exit();
+	}
+	// finished paring, create view cells manager
+	else if (element == "VisibilitySolution")
 	{
 		CreateViewCellsManager();
-	}
-
-	if (element == "Interior")
+
+		Debug << "pvs time: " << mPvsTimer.TotalTime() << endl;
+		Debug << "object time: " << mObjectTimer.TotalTime() << endl;
+		Debug << "box time: " << mBoxTimer.TotalTime() << endl;
+
+	}
+	else if (element == "Interior")
 	{
 		switch (mCurrentState)
@@ -289,4 +309,6 @@
 	const long startTime = GetTime();
 	
+	mBoxTimer.Entry();
+
 	if (mBoundingBoxConverter)
 	{
@@ -296,6 +318,25 @@
 	}
 
+	if (USE_HASH_COMPARE)
+	{
+		CreateHashVector();
+	}
+	else
+	{
+		sort(mPvsObjects.begin(), mPvsObjects.end(), ilt);
+
+		/*ObjectContainer::const_iterator oit, oit_end = mPvsObjects.end();
+        
+		int id = 0;
+		for (oit = mPvsObjects.begin(); oit != oit_end; ++ oit, ++ id)
+		{
+			if ((*oit)->GetId() != id)
+				Debug << "error" << endl;
+		}*/
+	}
+
 	Debug << "\nconverted bounding boxes to objects in "
-		  << TimeDiff(startTime, GetTime()) * 1e-3 << " secs" << endl;
+		  << TimeDiff(startTime, GetTime()) * 1e-6 << " secs" << endl;
+	mBoxTimer.Exit();
 }
 
@@ -412,13 +453,15 @@
 	if (element == "Interior") 
 	{
-		//cout << "[";
 		StartViewCell(attributes, false);
+		return;
 	}
 
 	if (element == "Leaf") 
 	{
-		//cout << "l";
 		StartViewCell(attributes, true);
-	}
+		return;
+	}
+
+	Debug << "StartViewCellHierarchyElement: should not come here: " << element << endl;
 }
 
@@ -440,7 +483,6 @@
 		mViewCellsTree = new ViewCellsTree();
 	}
-
 	// decides about the view cell hierarchy
-	if (element == "ViewSpaceHierarchy")
+	else if (element == "ViewSpaceHierarchy")
 	{		
 		Debug << "\nparsing view space hierarchy" << endl;
@@ -450,7 +492,6 @@
 		StartViewSpaceHierarchy(attributes);
 	}
-
 	// decides about the view cell hierarchy
-	if (element == "ObjectSpaceHierarchy")
+	else if (element == "ObjectSpaceHierarchy")
 	{
 		cout  << "\nparsing object space hierarchy" << endl;
@@ -458,33 +499,37 @@
 
 		mCurrentState = PARSE_OBJECTSPACE_HIERARCHY;
+		mObjectTimer.Entry();
 		StartObjectSpaceHierarchy(attributes);
 	}
-	
 	// decides the used view cell hierarchy
-	if (element == "BoundingBox")
+	else if (element == "BoundingBox")
 	{
 		StartBoundingBox(attributes);
 	}
-
-	// parse view space hierarchy
-	switch (mCurrentState)
-	{
-	case PARSE_VIEWSPACE_HIERARCHY:
-		if ((++ nViewCells % 1000) == 0)
-			cout << "\r" << nViewCells << " view cells parsed\r";
+	else
+	{
+		// parse view space hierarchy
+		switch (mCurrentState)
+		{
+		case PARSE_VIEWSPACE_HIERARCHY:
+			if ((++ nViewCells % 1000) == 0)
+			{
+				cout << "\r" << nViewCells << " view cells parsed\r";
+				Debug << nViewCells << " view cells parsed" << endl;
+			}
+			StartViewSpaceHierarchyElement(element, attributes);
+			break;
+		case PARSE_OBJECTSPACE_HIERARCHY:
+			if ((++ nObjects % 1000) == 0)
+				cout <<"\r" << nObjects << " objects parsed\r";
 		
-		StartViewSpaceHierarchyElement(element, attributes);
-		break;
-	case PARSE_OBJECTSPACE_HIERARCHY:
-		if ((++ nObjects % 1000) == 0)
-			cout <<"\r" << nObjects << " objects parsed\r";
-		
-		StartObjectSpaceHierarchyElement(element, attributes);
-		break;
-	case PARSE_VIEWCELLS:
-		StartViewCellHierarchyElement(element, attributes);
-		break;
-	default:
-		break;
+			StartObjectSpaceHierarchyElement(element, attributes);
+			break;
+		case PARSE_VIEWCELLS:
+			StartViewCellHierarchyElement(element, attributes);
+			break;
+		default:
+			break;
+		}
 	}
 	
@@ -509,5 +554,8 @@
 	}
 
-#if 1
+	Intersectable::NewMail();
+
+	mPvsTimer.Entry();
+
 	// TODO: 
 	// 1) find objects and add them to pvs
@@ -522,31 +570,14 @@
 	{
 		const int objId = *it;	
-		dummyInst.SetId(objId);
-
-		// equal indeces possible!
-		result = equal_range(mPvsObjects.begin(), 
-							 mPvsObjects.end(), 
-							 (Intersectable *)&dummyInst, 
-							 ilt);	
-
-		ObjectContainer::const_iterator eit = result.first;
-
-		for (; eit != result.second; ++ eit)
-		{
-			pvs.AddSample(*eit, 1.0f);
-		}
-	}
-
+	
+#if USE_HASH_COMPARE
+		pvs_hash::iterator oit = mHashPvs.find(objId);
+
+		if ((oit != mHashPvs.end()) && ((*oit).second->GetId() == objId))
+		{
+			pvs.AddSample((*oit).second, 1.0f);
+		}
 #else
-
-	// TODO: 
-	// 1) find objects and add them to pvs
-	// 2) get view cell with specified id
-	MeshInstance dummyInst(NULL);
-
-	vector<int>::const_iterator it, it_end = objIndices.end();
-	for (it = objIndices.begin(); it != it_end; ++ it)
-	{
-		const int objId = *it;	
+#if 0
 		dummyInst.SetId(objId);
 
@@ -558,16 +589,13 @@
 		if ((oit != mPvsObjects.end()) && ((*oit)->GetId() == objId))
 		{
-			// $$JB we should store a float a per object which corresponds
-			// to sumof pdfs, i.e. its relative visibility
-			// temporarily set to 1.0f
 			pvs.AddSample(*oit, 1.0f);
 		}
-		else
-		{
-			Debug << "x";
-			//Debug << "StartViewCellPvs error: object with id " << objId << " does not exist" << endl;
-		}
-	}
+#else
+		pvs.AddSample(mPvsObjects[objId], 1.0f);
 #endif
+#endif
+	}
+	
+	mPvsTimer.Exit();
 }
 
@@ -814,5 +842,4 @@
 {
 	ViewCell *viewCell = NULL;
-	
 	const int len = attributes.getLength();
 	float mergeCost;
@@ -841,6 +868,6 @@
 			viewCell->SetId(id);
 
-			if (mCurrentViewCell) // replace front or (if not NULL) back child
-			{	
+			if (mCurrentViewCell) 
+			{	// replace front or (if not NULL) back child
 				ViewCellInterior *interior = 
 					static_cast<ViewCellInterior *>(mCurrentViewCell);
@@ -862,8 +889,7 @@
 			const char *ptr = attrValue.LocalForm();
 
-			// note: id must come before pvs! 
+			// hack: assume that view cell id comes before pvs
 			// otherwise view cell is undefined
 
-			// hack: assume that view cell comes before pvs
 			StartViewCellPvs(viewCell->GetPvs(), ptr); 
 			//StartViewCellPvs(pvs, ptr);
@@ -915,6 +941,4 @@
 		for (vit = mViewCells.begin(); vit != vit_end; ++ vit, ++ i)
 		{
-			//if ((i % 1000) == 0)
-			//	Debug << "\n exchanged " << i << " boxes" << endl;
 			ViewCell *vc = (*vit);
 
@@ -1302,9 +1326,7 @@
 		{
 			objects.push_back(*oit);
-			Debug << "x";
 		}
 		else
 		{
-			Debug << "y";
 			//cerr << "StartBvhLeafObjects error: object with id " << objId << " does not exist" << endl;
 		}
@@ -1483,5 +1505,4 @@
 	}
 
-	cout<<"parsed - will delete the parser"<<endl<<flush;
 	//
 	//  Delete the parser itself.  Must be done prior to calling Terminate, below.
Index: /GTP/trunk/Lib/Vis/GtpVisibility.sln
===================================================================
--- /GTP/trunk/Lib/Vis/GtpVisibility.sln	(revision 2110)
+++ /GTP/trunk/Lib/Vis/GtpVisibility.sln	(revision 2123)
@@ -16,4 +16,6 @@
 		{101A7691-74F3-48B4-96A3-CF35578F5900} = {101A7691-74F3-48B4-96A3-CF35578F5900}
 		{EABCE292-D598-4600-A1C9-2591E7D62FDA} = {EABCE292-D598-4600-A1C9-2591E7D62FDA}
+		{7319E499-473D-4CE5-9983-725D6E68A55D} = {7319E499-473D-4CE5-9983-725D6E68A55D}
+		{7319E499-473D-4CE5-9983-725D6E68A55D} = {7319E499-473D-4CE5-9983-725D6E68A55D}
 	EndProjectSection
 EndProject
@@ -465,6 +467,6 @@
 		{7319E499-473D-4CE5-9983-725D6E68A55D}.Release Internal.ActiveCfg = Release Internal|Win32
 		{7319E499-473D-4CE5-9983-725D6E68A55D}.Release Internal.Build.0 = Release Internal|Win32
-		{7319E499-473D-4CE5-9983-725D6E68A55D}.Release Static.ActiveCfg = Release Internal|Win32
-		{7319E499-473D-4CE5-9983-725D6E68A55D}.Release Static.Build.0 = Release Internal|Win32
+		{7319E499-473D-4CE5-9983-725D6E68A55D}.Release Static.ActiveCfg = Release|Win32
+		{7319E499-473D-4CE5-9983-725D6E68A55D}.Release Static.Build.0 = Release|Win32
 		{7319E499-473D-4CE5-9983-725D6E68A55D}.Release_Internal.ActiveCfg = Release_Internal|Win32
 		{7319E499-473D-4CE5-9983-725D6E68A55D}.Release_Internal.Build.0 = Release_Internal|Win32
