Index: trunk/VUT/GtpVisibilityPreprocessor/src/Beam.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Beam.cpp	(revision 506)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Beam.cpp	(revision 507)
@@ -40,4 +40,9 @@
 	}
   }
+
+  mBox = box;
+  mDirBox = dBox;
+  
+  SetValid();
 }
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/RssTree.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/RssTree.h	(revision 492)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/RssTree.h	(revision 507)
@@ -22,5 +22,5 @@
 #include "AxisAlignedBox3.h"
 #include "Halton.h"
-
+#include "beam.h"
 
 #define USE_KDNODE_VECTORS 1
@@ -419,4 +419,6 @@
   
   HaltonSequence halton;
+
+  Beam mBeam;
   
   RssTreeLeaf(RssTreeInterior *p,
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Makefile
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Makefile	(revision 505)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Makefile	(revision 507)
@@ -1,5 +1,5 @@
 #############################################################################
 # Makefile for building: preprocessor
-# Generated by qmake (2.00a) (Qt 4.1.0) on: pá 6. I 14:52:19 2006
+# Generated by qmake (2.00a) (Qt 4.1.0) on: so 7. I 10:49:27 2006
 # Project:  preprocessor.pro
 # Template: app
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Beam.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Beam.h	(revision 506)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Beam.h	(revision 507)
@@ -12,12 +12,11 @@
   
 public:			
-  enum {STORE_KD_NODES=1, STORE_OBJECTS=2};
+  enum {STORE_KD_NODES=1, STORE_OBJECTS=2, VALID=4};
   int mFlags;
   
   // list of nodes intersected by the frustum
   vector<KdNode *> mKdNodes;
-  // lits of objects intersected by the frum
+  // lits of objects intersected by the frustum
   vector<Intersectable *> mObjects;
-
 
   // spatial box
@@ -28,6 +27,9 @@
 
   vector<Plane3> mPlanes;
-  
-  Beam():mFlags(STORE_KD_NODES+STORE_OBJECTS)
+
+  bool IsValid() { return mFlags & VALID; }
+  bool SetValid() { return mFlags |= VALID; }
+
+  Beam():mFlags(STORE_KD_NODES+STORE_OBJECTS),mKdNodes(0), mObjects(0)
   {
   }
@@ -36,5 +38,5 @@
 				 const  AxisAlignedBox3 &dBox);
   
-
+  
   int
   ComputeIntersection(const  AxisAlignedBox3 &box);
Index: trunk/VUT/GtpVisibilityPreprocessor/src/KdTree.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/KdTree.cpp	(revision 505)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/KdTree.cpp	(revision 507)
@@ -941,8 +941,8 @@
 KdTree::GetRandomLeaf(const bool onlyUnmailed)
 {
-	stack<KdNode *> nodeStack;
+  stack<KdNode *> nodeStack;
   nodeStack.push(mRoot);
-
-	int mask = rand();
+  
+  int mask = rand();
 	
   while (!nodeStack.empty()) {
@@ -967,10 +967,42 @@
 
 int
-CastBeam(
-		 Beam &beam
-		 )
-{
-  
-
-  return 0;
-}
+KdTree::CastBeam(
+				 Beam &beam
+				 )
+{
+  stack<KdNode *> nodeStack;
+  nodeStack.push(mRoot);
+  
+  while (!nodeStack.empty()) {
+    KdNode *node = nodeStack.top();
+    nodeStack.pop();
+	
+	int side = beam.ComputeIntersection(GetBox(node));
+	switch (side) {
+	case -1:
+	  beam.mKdNodes.push_back(node);
+	  break;
+	case 0:
+	  if (node->IsLeaf())
+		beam.mKdNodes.push_back(node);
+	  else {
+		KdInterior *interior = (KdInterior *)node;
+		KdNode *first = interior->mBack;
+		KdNode *second = interior->mFront;
+		
+		if (interior->mAxis < 3) {
+		  // spatial split -> decide on the order of the nodes
+		  if (beam.mPlanes[0].mNormal[interior->mAxis] > 0)
+			swap(first, second);
+		}
+
+		nodeStack.push(first);
+		nodeStack.push(second);
+	  }
+	  break;
+	  // default: cull
+	}
+  }
+
+  return beam.mKdNodes.size();
+}
Index: trunk/VUT/GtpVisibilityPreprocessor/src/RssTree.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/RssTree.cpp	(revision 500)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/RssTree.cpp	(revision 507)
@@ -2003,4 +2003,5 @@
 	return;
   
+  
   int nrays = leaf->rays.size();
 
@@ -2008,4 +2009,5 @@
   AxisAlignedBox3 box = GetBBox(leaf);
   AxisAlignedBox3 dirBox = GetDirBBox(leaf);
+
 
   AxisAlignedBox3 sBox(box);
Index: trunk/VUT/GtpVisibilityPreprocessor/src/default.env
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/default.env	(revision 504)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/default.env	(revision 507)
@@ -15,5 +15,5 @@
 filename ../data/atlanta/atlanta2.x3d
 # filename ../data/soda/soda.dat
-# filename ../data/soda/soda5.dat
+filename ../data/soda/soda5.dat
 }
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/GlRenderer.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/GlRenderer.h	(revision 504)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/GlRenderer.h	(revision 507)
@@ -17,4 +17,5 @@
 class Intersectable;
 class Material;
+class Beam;
 
 struct PvsRenderStatistics {
@@ -129,9 +130,45 @@
   void
   ClearErrorBuffer();
-
   
 
   virtual int GetWidth() const { return width(); }
   virtual int GetHeight() const { return height(); }
+
+
+
+  // the values need for rss tree update computed already inside the glrendererbuffer
+  // not all of them need to be computed
+  struct BeamSampleStatistics {
+
+	enum {COMPUTE_PVS_SIZE, COMPUTE_RAY_CONTRIBUTIONS, COMPUTE_PVS_ENTROPY};
+	int flags;
+
+	BeamSampleStatistics():flags(COMPUTE_RAY_CONTRIBUTIONS) {}
+	
+	float pvsSize;
+	float rays;
+	float rayContributions;
+	float pvsEntropy;
+	float rayLengthEntropy;
+	float importance;
+	
+	float weightedRayContribution;
+  };
+  
+
+  void SampleBeamContributions(
+							   Intersectable *sourceObject,
+							   Beam &beam,
+							   const int samples,
+							   BeamSampleStatistics &stat
+							   );
+
+  void
+  SampleViewpointContributions(
+							   Intersectable *sourceObject,
+							   Beam &beam,
+							   const int desiredSamples,
+							   BeamSampleStatistics &stat
+							   );
 
 };
Index: trunk/VUT/GtpVisibilityPreprocessor/src/GlRenderer.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/GlRenderer.cpp	(revision 504)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/GlRenderer.cpp	(revision 507)
@@ -5,4 +5,5 @@
 #include "Pvs.h"
 #include "Viewcell.h"
+#include "Beam.cpp"
 
 #include <GL/glext.h>
@@ -529,2 +530,103 @@
   
 }
+
+
+void
+GlRendererBuffer::SampleBeamContributions(
+										  Intersectable *sourceObject,
+										  Beam &beam,
+										  const int desiredSamples,
+										  BeamSampleStatistics &stat
+										  )
+{
+  // assumes that the beam is constructed and contains kd-tree nodes
+  // and viewcells which it intersects
+
+
+  
+  
+  // Get the number of viewpoints to be sampled
+  // Now it is a sqrt but in general a wiser decision could be made.
+  // The less viewpoints the better for rendering performance, since less passes
+  // over the beam is needed.
+  // The viewpoints could actually be generated outside of the bounding box which
+  // would distribute the 'efective viewpoints' of the object surface and thus
+  // with a few viewpoints better sample the vipoint space....
+  
+  int viewPointSamples = sqrt((float)desiredSamples);
+
+  // the number of direction samples per pass is given by the number of viewpoints
+  int directionalSamples = desiredSamples/viewPointSamples;
+  int i;
+  for (i=0; i < viewPointSamples; i++) {
+	Vector3 viewPoint = beam.mBox.GetRandomPoint();
+	// perhaps the viewpoint should be shifted back a little bit so that it always lies
+	// inside the source object
+	// 'ideally' the viewpoints would be distributed on the soureObject surface, but this
+	// would require more complicated sampling (perhaps hierarchical rejection sampling of
+	// the object surface is an option here - only the mesh faces which are inside the box
+	// are considered as candidates) 
+	SampleViewpointContributions(
+								  sourceObject,
+								  beam,
+								  directionalSamples,
+								  stat
+								  );
+  }
+
+
+  // note:
+  // this routine would be called only if the number of desired samples is sufficiently
+  // large - for other rss tree cells the cpu based sampling is perhaps more efficient
+  // distributing the work between cpu and gpu would also allow us to place more sophisticated
+  // sample distributions (silhouette ones) using the cpu and the jittered once on the GPU
+  // in order that thios scheme is working well the gpu render buffer should run in a separate
+  // thread than the cpu sampler, which would not be such a big problem....
+}
+
+
+void
+GlRendererBuffer::SampleViewpointContributions(
+											   Intersectable *sourceObject,
+											   Beam &beam,
+											   const int desiredSamples,
+											   BeamSampleStatistics &stat
+											   )
+{
+  // 1. setup the view port to match the desired samples
+  // 2. setup the projection matrix and view matrix to match the viewpoint + beam.mDirBox
+  
+  // 3. reset z-buffer to 0 and render the source object for the beam using
+  //    glDepthFunc(GL_GREATER)
+  //    and glCullFace(Enabled) and glFrontFace(GL_CW)
+  //    remember the ray origin depth buffer somewhere?
+
+  // 4. set back to normal rendering and clear the ray termination depth buffer
+  // 5. render all objects inside the beam using id based false color
+  //    (objects can be compiled to a gl list now so that subsequent rendering for
+  //     this beam is fast - the same hold for step 3)
+
+
+  // 6. Now we have a two depth buffers defining the ray origin and termination
+  //    only rays which have non-zero entry in the origin buffer are valid since
+  //    they realy start on the object surface (this can also be tagged by setting a
+  //    stencil buffer bit at step 3)
+
+  // 7. Use occlusion queries for all viewcell meshes associated with the beam ->
+  // a fragment passes if the corresponding stencil fragment is set and its depth is
+  // between origin and termination buffer
+
+  // 8. The number of visible pixels is the number of sample rays which see the source
+  //    object from the corresponding viewcell -> rember these values for later update
+  //   of the viewcell pvs - or update immediatelly?
+
+  //  In general it is not neccessary to rember to extract all the rays cast. I hope it
+  // would be sufficient to gain only the intergral statistics about the new contributions
+  // and so the rss tree would actually store no new rays (only the initial ones)
+  // the subdivision of the tree would only be driven by the statistics (the glrender could
+  // evaluate the contribution entropy for example)
+  // However might be an option to extract/store only those the rays which made a contribution
+  // (new viewcell has been discovered) or relative contribution greater than a threashold...
+       
+  
+}
