Index: trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env	(revision 530)
+++ trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env	(revision 532)
@@ -9,5 +9,5 @@
 #	filename vienna.x3d
 #	filename ../data/vienna/vienna-simple.x3d
-	filename ../data/vienna/vienna-buildings.x3d
+#	filename ../data/vienna/vienna-buildings.x3d
 #filename ../data/vienna/vienna-buildings.x3d;../data/vienna/vienna-roofs.x3d
 #;../data/vienna/vienna-plane.x3d
@@ -15,5 +15,5 @@
 #	filename ../data/atlanta/atlanta2.x3d
 #	filename ../data/soda/soda.dat
-#	filename ../data/soda/soda5.dat
+	filename ../data/soda/soda5.dat
 }
 
@@ -21,5 +21,5 @@
 	# stored sample rays
 	samplesFilename rays.out
-	useGlRenderer false
+	useGlRenderer true
 #	type sampling
 	type vss
@@ -29,6 +29,6 @@
 VssPreprocessor {
 	samplesPerPass  100000
-	initialSamples 300000
-	vssSamples 2000000
+	initialSamples 200000
+	vssSamples 3000000
 	vssSamplesPerPass 100000
 	useImportanceSampling true
@@ -36,4 +36,5 @@
 	storeInitialSamples false
 	useViewSpaceBox false
+	testBeamSampling true
 }
 
@@ -183,5 +184,5 @@
 	maxPvsRatio 0.1
 		
-	delayedConstruction true
+	delayedConstruction false
 		
 		
@@ -257,5 +258,5 @@
 VspBspTree {
 	Construction {
-		samples 900000
+		samples 100000
 		epsilon 0.005
 		randomize false
Index: trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.h	(revision 520)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.h	(revision 532)
@@ -22,4 +22,6 @@
 class ViewCellsManager;
 class BspMergeCandidate;
+class Beam;
+
 struct BspRay;
 
@@ -286,4 +288,13 @@
 	bool Export(ofstream &stream);
 
+	/** Casts beam, i.e. a 5D frustum of rays, into tree.
+		Tests conservative using the bounding box of the nodes.
+		@returns number of view cells it intersected
+	*/
+	int CastBeam(Beam &beam);
+
+	void CollectViewCells(BspNode *root, 
+						  ViewCellContainer &viewCells,
+						  bool onlyUnmailed = false) const;
 protected:
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h	(revision 508)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h	(revision 532)
@@ -44,5 +44,5 @@
 					   const float epsilon) const;
 
-	/** Computes bounding box of the node.
+	/** Computes bounding box of the geometry.
 	*/
 	void ComputeBoundingBox(AxisAlignedBox3 &box);
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.h	(revision 527)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.h	(revision 532)
@@ -25,4 +25,5 @@
 class ViewCellsStatistics;
 class Exporter;
+class Beam;
 
 struct BspRay;
@@ -246,4 +247,8 @@
 	virtual bool ExportViewCells(const string filename);
 
+	/** Casts beam to collect view cells.
+	*/
+	virtual int CastBeam(Beam &beam);
+
 protected:
 
@@ -566,4 +571,6 @@
 	bool ExportViewCells(const string filename);
 
+	int CastBeam(Beam &beam);
+
 protected:
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.cpp	(revision 517)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.cpp	(revision 532)
@@ -16,5 +16,5 @@
 #include "ViewCellBsp.h"
 #include "ViewCellsManager.h"
-
+#include "Beam.h"
 
 //-- static members
@@ -1464,5 +1464,15 @@
 }
 
+
 void VspBspTree::CollectViewCells(ViewCellContainer &viewCells) const
+{
+	ViewCell::NewMail();
+	CollectViewCells(mRoot, viewCells, true);
+}
+
+
+void VspBspTree::CollectViewCells(BspNode *root, 
+								  ViewCellContainer &viewCells,
+								  bool onlyUnmailed) const
 {
 	stack<BspNode *> nodeStack;
@@ -1472,6 +1482,4 @@
 
 	nodeStack.push(mRoot);
-
-	ViewCell::NewMail();
 	
 	while (!nodeStack.empty()) 
@@ -1486,5 +1494,5 @@
 				ViewCell *viewCell = dynamic_cast<BspLeaf *>(node)->GetViewCell();
 			
-				if (!viewCell->Mailed()) 
+				if (!onlyUnmailed || !viewCell->Mailed()) 
 				{
 					viewCell->Mail();
@@ -2146,4 +2154,71 @@
 		}
 	}
+}
+
+
+typedef pair<BspNode *, BspNodeGeometry *> bspNodePair;
+
+int VspBspTree::CastBeam(Beam &beam)
+{
+    stack<bspNodePair> nodeStack;
+	BspNodeGeometry *rgeom = new BspNodeGeometry();
+	ConstructGeometry(mRoot, *rgeom);
+
+	nodeStack.push(bspNodePair(mRoot, rgeom));
+  
+	ViewCell::NewMail();
+
+	while (!nodeStack.empty()) 
+	{
+		BspNode *node = nodeStack.top().first;
+		BspNodeGeometry *geom = nodeStack.top().second;
+		nodeStack.pop();
+		
+		AxisAlignedBox3 box;
+		geom->ComputeBoundingBox(box);
+
+		int side = beam.ComputeIntersection(box);
+		
+		switch (side) 
+		{
+		case -1:
+			CollectViewCells(node, beam.mViewCells, true);
+			break;
+		case 0:
+			if (node->IsLeaf())
+			{
+				BspLeaf *leaf = dynamic_cast<BspLeaf *>(leaf);
+				if (!leaf->GetViewCell()->Mailed() && leaf->TreeValid())
+					beam.mViewCells.push_back(leaf->GetViewCell());
+			}
+			else 
+			{
+				BspInterior *interior = dynamic_cast<BspInterior *>(node);
+				BspNode *first = interior->GetBack();
+				BspNode *second = interior->GetFront();
+                
+				// decide on the order of the nodes
+				if (DotProd(beam.mPlanes[0].mNormal, 
+					interior->GetPlane().mNormal) > 0)
+				{
+					swap(first, second);
+				}
+
+				BspNodeGeometry *leftGeom = new BspNodeGeometry();
+				BspNodeGeometry *rightGeom = new BspNodeGeometry();
+
+				ConstructGeometry(first, *leftGeom);
+				ConstructGeometry(second, *rightGeom);
+
+				nodeStack.push(bspNodePair(first, leftGeom));
+				nodeStack.push(bspNodePair(second, rightGeom));
+			}
+			break;
+			// default: cull
+		}
+		DEL_PTR(geom);
+	}
+
+	return beam.mViewCells.size();
 }
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Environment.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Environment.cpp	(revision 517)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Environment.cpp	(revision 532)
@@ -1155,4 +1155,6 @@
 				 "100000");
   
+  RegisterOption("VssPreprocessor.testBeamSampling", optBool, "beam_sampling", "false");
+
   RegisterOption("VssPreprocessor.vssSamples",
 				 optInt,
@@ -1574,5 +1576,6 @@
 	RegisterOption("VssTree.queryType", optString, "qtype=", "static");
 
-
+	
+	
 	RegisterOption("VssTree.queryPosWeight", optFloat, "qposweight=", "0.0");
 	RegisterOption("VssTree.useRefDirSplits", optBool, "refdir", "false");
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Beam.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Beam.h	(revision 531)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Beam.h	(revision 532)
@@ -56,5 +56,5 @@
   
 public:			
-  enum {STORE_KD_NODES=1, STORE_OBJECTS=2, VALID=4};
+  enum {STORE_KD_NODES=1, STORE_OBJECTS=2, STORE_VIEW_CELLS, VALID=8};
   int mFlags;
   
@@ -90,5 +90,5 @@
   bool SetValid() { return mFlags |= VALID; }
 
-  Beam():mFlags(STORE_KD_NODES+STORE_OBJECTS), mKdNodes(0), mObjects(0)
+  Beam():mFlags(STORE_KD_NODES+STORE_OBJECTS), mKdNodes(0), mObjects(0), mViewCells(0)
   {
   }
Index: trunk/VUT/GtpVisibilityPreprocessor/src/KdTree.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/KdTree.cpp	(revision 512)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/KdTree.cpp	(revision 532)
@@ -1005,4 +1005,15 @@
   }
 
+  if (beam.mFlags & Beam::STORE_OBJECTS)
+  {
+	  vector<KdNode *>::const_iterator it, it_end = beam.mKdNodes.end();
+
+	  Intersectable::NewMail();
+	  for (it = beam.mKdNodes.begin(); it != it_end; ++ it)
+	  {
+		  CollectObjects(*it, beam.mObjects);
+	  }
+  }
+
   return beam.mKdNodes.size();
 }
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.cpp	(revision 520)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.cpp	(revision 532)
@@ -256,5 +256,5 @@
 	}
 	if (mUseGlRenderer)
-	  renderer = new GlRendererBuffer(1024, 768, mSceneGraph, mViewCellsManager);
+	  renderer = new GlRendererBuffer(1024, 768, mSceneGraph, mViewCellsManager, mKdTree);
 	
 	return true;
Index: trunk/VUT/GtpVisibilityPreprocessor/src/dual_depth.cg
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/dual_depth.cg	(revision 530)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/dual_depth.cg	(revision 532)
@@ -12,6 +12,5 @@
 };
 
-pixel dual_depth(fragment IN,
-		 	     const uniform sampler2D depthMap)
+pixel main(fragment IN, const uniform sampler2D depthMap)
 {
 	pixel OUT;
Index: trunk/VUT/GtpVisibilityPreprocessor/src/VssPreprocessor.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/VssPreprocessor.cpp	(revision 531)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/VssPreprocessor.cpp	(revision 532)
@@ -32,4 +32,6 @@
   environment->GetBoolValue("VssPreprocessor.storeInitialSamples", mStoreInitialSamples);
   environment->GetBoolValue("VssPreprocessor.useViewSpaceBox", mUseViewSpaceBox);
+  environment->GetBoolValue("VssPreprocessor.testBeamSampling", mTestBeamSampling);
+
   useViewspacePlane = mUseViewSpaceBox; //hack
 
@@ -349,7 +351,6 @@
 
 
-void VssPreprocessor::TestBeamCasting(VssTree *tree)
-{
-
+void VssPreprocessor::TestBeamCasting(VssTree *tree, ViewCellsManager *vm)
+{
 	vector<VssTreeLeaf *> leaves;
 	tree->CollectLeaves(leaves);
@@ -363,5 +364,14 @@
 		AxisAlignedBox3 dirBox =tree->GetDirBBox(leaf);
 		AxisAlignedBox3 box = tree->GetBBox(leaf);
+		
 		beam.Construct(dirBox, box);
+
+		// collect kd leaves and view cells
+		mKdTree->CastBeam(beam);
+		vm->CastBeam(beam);
+
+		Debug << "found " << beam.mViewCells.size() << " view cells and " 
+			  << beam.mKdNodes.size() << " kd nodes" << endl;
+
 		Intersectable *sourceObj = mObjects[5];
 		BeamSampleStatistics stats;
@@ -371,7 +381,5 @@
 										  stats);
 
-		Debug << "beam statistics: " << stats << endl;
-
-
+		Debug << "beam statistics: " << stats << endl << endl;
 	}
 
@@ -581,4 +589,7 @@
   int pass = 0;
 
+  if (mTestBeamSampling)
+	  TestBeamCasting(vssTree, mViewCellsManager);
+
   // cast view cell samples
   while (1) {
Index: trunk/VUT/GtpVisibilityPreprocessor/src/main.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/main.cpp	(revision 496)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/main.cpp	(revision 532)
@@ -94,5 +94,5 @@
   if (p->mUseGlRenderer) {
 	
-	rendererWidget = new GlRendererWidget(p->mSceneGraph, p->mViewCellsManager);
+	  rendererWidget = new GlRendererWidget(p->mSceneGraph, p->mViewCellsManager, p->mKdTree);
 	//  renderer->resize(640, 480);
 	rendererWidget->resize(640, 480);
Index: trunk/VUT/GtpVisibilityPreprocessor/src/GlRenderer.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/GlRenderer.h	(revision 531)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/GlRenderer.h	(revision 532)
@@ -18,4 +18,5 @@
 class Material;
 class Beam;
+class KdTree;
 
 class BeamSampleStatistics;
@@ -66,9 +67,12 @@
   bool mWireFrame;
 
+  KdTree *mKdTree;
+
   QWaitCondition mRenderingFinished;
   
   
   GlRenderer(SceneGraph *sceneGraph,
-			 ViewCellsManager *viewcells);
+			 ViewCellsManager *viewcells,
+			 KdTree *tree);
   
   ~GlRenderer();
@@ -103,17 +107,11 @@
 class GlRendererBuffer : public QGLPixelBuffer, public GlRenderer
 {
-
 public:
-  int mPvsStatFrames;
-  vector<float> mPvsErrorBuffer;
-  
-  PvsRenderStatistics mPvsStat;
-
-
-  GlRendererBuffer(const int w,
-				   const int h,
-				   SceneGraph *sceneGraph,
-				   ViewCellsManager *viewcells):
-	QGLPixelBuffer(QSize(w, h)), GlRenderer(sceneGraph, viewcells) {
+	GlRendererBuffer(const int w,
+					 const int h,
+					 SceneGraph *sceneGraph,
+					 ViewCellsManager *viewcells,
+					 KdTree *tree):
+	QGLPixelBuffer(QSize(w, h)), GlRenderer(sceneGraph, viewcells, tree) {
 
 	mPvsStatFrames = 10000;
@@ -125,5 +123,5 @@
 	doneCurrent();
 
-  }
+	}
   
   void
@@ -154,4 +152,9 @@
 							   );
 
+   PvsRenderStatistics mPvsStat;
+   
+   int mPvsStatFrames;
+   vector<float> mPvsErrorBuffer;
+
 private:
 	static void GenQueries(const int numQueries);
@@ -175,7 +178,8 @@
   GlRendererWidget(SceneGraph *sceneGraph,
 				   ViewCellsManager *viewcells,
+				   KdTree *tree,
 				   QWidget * parent = 0, const QGLWidget * shareWidget = 0, Qt::WFlags f = 0
 				   ):
-	GlRenderer(sceneGraph, viewcells), QGLWidget(parent, shareWidget, f)
+	GlRenderer(sceneGraph, viewcells, tree), QGLWidget(parent, shareWidget, f)
   {
 	mTopView = false;
@@ -204,5 +208,4 @@
   virtual int GetWidth() const { return width(); }
   virtual int GetHeight() const { return height(); }
-
 };
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/VssPreprocessor.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/VssPreprocessor.h	(revision 531)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/VssPreprocessor.h	(revision 532)
@@ -105,5 +105,7 @@
   void CastRay(const BspTree &tree, const VssRay & vssRay);
 
-  void TestBeamCasting(VssTree *tree);
+  void TestBeamCasting(VssTree *tre, ViewCellsManager *vm);
+
+  bool mTestBeamSampling;
 };
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.cpp	(revision 527)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.cpp	(revision 532)
@@ -12,4 +12,7 @@
 #include "VspBspTree.h"
 #include "ViewCellsParser.h"
+#include "Beam.h"
+
+
 
 
@@ -311,4 +314,9 @@
 }
 
+
+int ViewCellsManager::CastBeam(Beam &beam)
+{
+	return 0;
+}
 
 ViewCellContainer &ViewCellsManager::GetViewCells()
@@ -2431,2 +2439,8 @@
 	return true;
 }
+
+
+int VspBspViewCellsManager::CastBeam(Beam &beam)
+{
+	return 0;
+}
Index: trunk/VUT/GtpVisibilityPreprocessor/src/GlRenderer.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/GlRenderer.cpp	(revision 530)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/GlRenderer.cpp	(revision 532)
@@ -6,4 +6,5 @@
 #include "Viewcell.h"
 #include "Beam.h"
+#include "KdTree.h"
 
 #include <GL/glext.h>
@@ -30,6 +31,8 @@
 
 GlRenderer::GlRenderer(SceneGraph *sceneGraph,
-					   ViewCellsManager *viewCellsManager):
-  Renderer(sceneGraph, viewCellsManager)
+					   ViewCellsManager *viewCellsManager,
+					   KdTree *tree):
+  Renderer(sceneGraph, viewCellsManager),
+  mKdTree(tree)
 {
   mSceneGraph->CollectObjects(&mObjects);
@@ -43,4 +46,6 @@
 GlRenderer::~GlRenderer()
 {
+	cgDestroyProgram(sCgFragmentProgram);
+	cgDestroyContext(sCgContext);
 }
 
@@ -152,11 +157,31 @@
   sCgContext = cgCreateContext();
 
-  sCgFragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT);
+  if (cgGLIsProfileSupported(CG_PROFILE_ARBFP1))
+	  sCgFragmentProfile = CG_PROFILE_ARBFP1;
+  else {
+	  // try FP30
+	  if (cgGLIsProfileSupported(CG_PROFILE_FP30))
+            sCgFragmentProfile = CG_PROFILE_FP30;
+	  else {
+		  fprintf(stderr, "Neither arbfp1 or fp30 fragment profiles supported on this system.\n");
+		  exit(1);
+	  }
+  }
 
   sCgFragmentProgram = cgCreateProgramFromFile(sCgContext, 		
 											   CG_SOURCE, "../src/dual_depth.cg",
 											   sCgFragmentProfile,
-											   "dual_depth", 
+											   NULL, 
 											   NULL);
+
+  if (!cgIsProgramCompiled(sCgFragmentProgram))
+	  cgCompileProgram(sCgFragmentProgram);
+
+  cgGLLoadProgram(sCgFragmentProgram);
+  cgGLBindProgram(sCgFragmentProgram);
+ // Debug << "LAST LISTING----" << cgGetLastListing(sCgContext) << "----\n";
+
+  Debug << "---- PROGRAM BEGIN ----\n" << 
+	  cgGetProgramString(sCgFragmentProgram, CG_COMPILED_PROGRAM) << "---- PROGRAM END ----\n";
 }
 
@@ -683,4 +708,15 @@
 	//     this beam is fast - the same hold for step 3)
 
+	if (beam.mFlags & !Beam::STORE_OBJECTS)
+	{
+		vector<KdNode *>::const_iterator it, it_end = beam.mKdNodes.end();
+
+		Intersectable::NewMail();
+		for (it = beam.mKdNodes.begin(); it != it_end; ++ it)
+		{
+			mKdTree->CollectObjects(*it, beam.mObjects);
+		}
+	}
+
 	// list of objects intersected by the frustum
 #if 0
@@ -704,4 +740,8 @@
 #endif
 
+	// remove objects again
+	if (beam.mFlags & !Beam::STORE_OBJECTS)
+		beam.mObjects.clear();
+
 	// bind ray origin depth buffer
 	glBindTexture(GL_TEXTURE_2D, depthMap);
@@ -719,7 +759,6 @@
 	//    stencil buffer bit at step 3)
 	glStencilFunc(GL_EQUAL, 0x1, 0x1);
-
-	// compare with second depth buffer: done in pixel shader
-	cgGLBindProgram(sCgFragmentProgram);
+ 
+	//cgGLBindProgram(sCgFragmentProgram);
 	cgGLEnableProfile(sCgFragmentProfile);
 
