Index: trunk/VUT/GtpVisibilityPreprocessor/scripts/Preprocessor.vcproj
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/scripts/Preprocessor.vcproj	(revision 527)
+++ trunk/VUT/GtpVisibilityPreprocessor/scripts/Preprocessor.vcproj	(revision 544)
@@ -348,4 +348,10 @@
 			</File>
 			<File
+				RelativePath="..\src\Tetrahedron3.cpp">
+			</File>
+			<File
+				RelativePath="..\src\Tetrahedron3.h">
+			</File>
+			<File
 				RelativePath="..\src\Triangle3.cpp">
 			</File>
Index: trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env	(revision 543)
+++ trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env	(revision 544)
@@ -303,5 +303,5 @@
 		#maxAccRayLength	100
 		
-		maxViewCells		5001
+		maxViewCells		6001
 		
 		# used for pvs criterium
@@ -323,5 +323,5 @@
 	PostProcess {
 		maxCostRatio 0.001
-		minViewCells 1000
+		minViewCells 2000
 		useRaysForMerge true
 	}
Index: trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.h	(revision 542)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.h	(revision 544)
@@ -308,5 +308,5 @@
 		if not valid, sets regions invalid and deletes view cell.
 	*/
-	void CheckValidy();
+	void ValidateTree();
 
 protected:
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h	(revision 535)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h	(revision 544)
@@ -35,4 +35,6 @@
 	float GetArea() const;
 	
+	float GetVolume() const;
+
 	/** Computes new front and back geometry based on the old cell 
 		geometry and a new split plane
@@ -57,4 +59,7 @@
 	void AddToMesh(Mesh &mesh);
 
+	/** Computes mass center of bsp node geometry.
+	*/
+	Vector3 ComputeMassCenter() const;
 	/** The polygons the geometry consists of.
 	*/
Index: trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.cpp	(revision 543)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.cpp	(revision 544)
@@ -1606,6 +1606,5 @@
 
 
-
-void VspBspTree::CheckValidy()
+void VspBspTree::ValidateTree()
 {
 	stack<BspNode *> nodeStack;
@@ -1635,4 +1634,5 @@
 						BspLeaf *l = viewCell->mLeaves.back();
 						l->SetTreeValid(false);
+						++ mStat.invalidLeaves;
 						PropagateUpValidity(l);
 
@@ -2697,5 +2697,5 @@
 	startTime = GetTime();
 
-	int nViewCells = /*mergeStats.nodes*/ mStat.Leaves() - mStat.invalidLeaves;
+	int nViewCells = mStat.Leaves() - mStat.invalidLeaves;
 
 	//-- use priority queue to merge leaf pairs
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Tetrahedron3.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Tetrahedron3.cpp	(revision 544)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Tetrahedron3.cpp	(revision 544)
@@ -0,0 +1,27 @@
+#include "Tetrahedron3.h"
+
+
+float Tetrahedron3::GetArea() const
+{
+	float area = 0;
+	for (int i = 0; i < 4; ++ i)
+		area += GetTriangle(i).GetArea();
+
+	return area;
+}
+
+
+float Tetrahedron3::GetVolume() const
+{
+	const Vector3 a = mVertices[2] - mVertices[1];
+	const Vector3 b = mVertices[3] - mVertices[1];
+	const Vector3 c = mVertices[4] - mVertices[1];
+
+	return (1.0f / 6.0f) * fabs(DotProd(a, CrossProd(b, c)));
+}
+
+
+bool Tetrahedron3::Valid() const
+{
+	return true;
+}
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp	(revision 535)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp	(revision 544)
@@ -9,4 +9,5 @@
 #include "AxisAlignedBox3.h"
 #include "Triangle3.h"
+#include "Tetrahedron3.h"
 
 #include <stack>
@@ -2549,4 +2550,55 @@
 
 
+float BspNodeGeometry::GetVolume() const
+{
+	//-- compute volume using tetrahedralization of the geometry
+	//   and adding the volume of the single tetrahedrons
+	float volume = 0;
+	const float f = 1.0f / 6.0f;
+
+	PolygonContainer::const_iterator pit, pit_end = mPolys.end();
+
+	for (pit = mPolys.begin(); pit != pit_end; ++ pit)
+	{
+		Polygon3 *poly = *pit;
+		const Vector3 v = poly->mVertices[0];
+
+		for (int i = 1; i < (int)poly->mVertices.size() - 1; ++ i)
+		{
+			volume += f * (DotProd(v, 
+				CrossProd(poly->mVertices[i], poly->mVertices[i + 1])));
+		}
+	}
+
+	Debug << "volume: " << volume << endl;
+	return volume;
+}
+
+
+Vector3 BspNodeGeometry::ComputeMassCenter() const
+{
+	int n = 0;
+
+	Vector3 center(0,0,0);
+
+	PolygonContainer::const_iterator pit, pit_end = mPolys.end();
+
+	for (pit = mPolys.begin(); pit != pit_end; ++ pit)
+	{
+		Polygon3 *poly = *pit;
+		
+		VertexContainer::const_iterator vit, vit_end = poly->mVertices.end();
+
+		for(vit = poly->mVertices.begin(); vit != vit_end; ++ vit)
+		{
+			center += *vit;
+			++ n;
+		}
+	}
+
+	return center / (float)n;
+}
+
+
 void BspNodeGeometry::AddToMesh(Mesh &mesh)
 {
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Tetrahedron3.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Tetrahedron3.h	(revision 544)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Tetrahedron3.h	(revision 544)
@@ -0,0 +1,67 @@
+#ifndef __TETRAHEDRON3_H
+#define __TETRAHEDRON3_H
+
+#include "Triangle3.h"
+#include "Vector3.h"
+
+class Tetrahedron3 
+{
+public:
+  Vector3 mVertices[4];
+  
+  Tetrahedron3() {}
+  
+  Tetrahedron3(const Vector3 &a,
+			   const Vector3 &b,
+			   const Vector3 &c,
+			   const Vector3 &d) 
+  {
+	  Init(a, b, c, d);
+  }
+  
+  Tetrahedron3(const Triangle3 &t, const Vector3 &a)
+  {
+	  Init(t.mVertices[0], t.mVertices[1], t.mVertices[2], a);
+  }
+
+  void Init(const Vector3 &a,
+			const Vector3 &b,
+			const Vector3 &c,
+			const Vector3 &d) 
+  {
+	  mVertices[0] = a;
+	  mVertices[1] = b;
+	  mVertices[2] = c;
+	  mVertices[3] = c;
+  }
+
+  Triangle3 GetTriangle(const int i) const 
+  {
+	  switch(i)
+	  {
+	  case 0: 
+		  return Triangle3(mVertices[0],  mVertices[1], mVertices[2]);
+		  break;
+	  case 1:
+		  return Triangle3(mVertices[0],  mVertices[1], mVertices[3]);
+		  break;
+	  case 2:
+		  return Triangle3(mVertices[1],  mVertices[2], mVertices[3]);
+		  break;
+	  case 3:
+		  return Triangle3(mVertices[0],  mVertices[3], mVertices[2]);
+		  break;
+	  }
+	  return Triangle3();
+  }
+
+
+  float GetArea() const;
+  float GetVolume() const;
+  bool Valid() const;
+
+};
+
+
+#endif
+
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Triangle3.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Triangle3.h	(revision 191)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Triangle3.h	(revision 544)
@@ -37,4 +37,9 @@
 
   float GetSpatialAngle(const Vector3 &point) const;
+
+  float GetArea() const {
+	  Vector3 v1=mVertices[0]-mVertices[1], v2=mVertices[2]-mVertices[1];
+	  return 0.5f * Magnitude(CrossProd(v2, v1));
+  }
 };
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Polygon3.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Polygon3.cpp	(revision 538)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Polygon3.cpp	(revision 544)
@@ -120,6 +120,5 @@
 		v += CrossProd(mVertices[i], mVertices[i+1]);
     
-    //Debug << "area2: " << 0.5f * fabs(DotProd(GetNormal(), v)) << endl;  
-	return 0.5f * fabs(DotProd(GetNormal(), v));
+    return 0.5f * fabs(DotProd(GetNormal(), v));
 }
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.cpp	(revision 542)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.cpp	(revision 544)
@@ -2017,5 +2017,5 @@
 
 	// check if new view cells turned invalid
-	mVspBspTree->CheckValidy();
+	mVspBspTree->ValidateTree();
 	ResetViewCells();
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/GlRenderer.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/GlRenderer.cpp	(revision 542)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/GlRenderer.cpp	(revision 544)
@@ -582,13 +582,9 @@
 											   BeamSampleStatistics &stat)
 {
-	// create beam mesh if not already doen
-	//TODO: should this be done here?
-	
-	beam.CreateMesh(2.0f * Magnitude(mSceneGraph->GetBox().Diagonal()));
-
-	// TODO: should not be done every time here
+	// TODO: should be moved out of here (not to be done every time)
 	// only back faces are interesting for the depth pass
 	glShadeModel(GL_FLAT);
 	glDisable(GL_LIGHTING);
+
 	// needed to kill the fragments for the front buffer
 	glEnable(GL_ALPHA_TEST);
@@ -605,6 +601,7 @@
 	// 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....
-  //TODO: remove
+	// with a few viewpoints better sample the viewpoint space....
+
+	//TODO: comment in
 	//int viewPointSamples = sqrt((float)desiredSamples);
 	int viewPointSamples = max(desiredSamples / (GetWidth() * GetHeight()), 1);
@@ -640,4 +637,7 @@
 	// 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....
+
+	// disable alpha test again
+	glDisable(GL_ALPHA_TEST);
 }
 
@@ -650,20 +650,24 @@
 {
     // 1. setup the view port to match the desired samples
-	glViewport(0, 0, GetWidth(), GetHeight());
+	glViewport(0, 0, samples, samples);
 
 	// 2. setup the projection matrix and view matrix to match the viewpoint + beam.mDirBox
 	SetupProjectionForViewPoint(viewPoint, beam, sourceObject);
 
+
 	// 3. reset z-buffer to 0 and render the source object for the beam
 	//    with glCullFace(Enabled) and glFrontFace(GL_CW)
-	//    save result to depth map
-
-	// front depth buffer must bé initialised to 0
+	//    save result to the front depth map
+	//    the front depth map holds ray origins
+
+
+	// front depth buffer must be initialised to 0
 	float clearDepth;
+	
 	glGetFloatv(GL_DEPTH_CLEAR_VALUE, &clearDepth);
 	glClearDepth(0.0f);
-	
-
 	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+
+
 	//glFrontFace(GL_CW);
 	glEnable(GL_CULL_FACE);
@@ -676,4 +680,5 @@
 	glStencilFunc(GL_ALWAYS, 0x1, 0x1);
 	glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
+
 
 #if 0
@@ -694,49 +699,46 @@
 
 #endif	
+
+	 // copy contents of the front depth buffer into depth texture
+	glBindTexture(GL_TEXTURE_2D, frontDepthMap);	
+	glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, depthMapSize, depthMapSize);
+
+
 	// reset clear function
 	glClearDepth(clearDepth);
 
-	// copy contents of depth buffer into depth texture
-	// depth buffer holds ray origins
-	glBindTexture(GL_TEXTURE_2D, frontDepthMap);	
-	glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, depthMapSize, depthMapSize);
-
-
-#if 0
-	// only the samples which are inside the beam AND on the source object
-	// should be considered => only where stencil == 2
+	
+	
+	// 4. set up the termination depth buffer (= standard depth buffer)
+	//    only rays which have non-zero entry in the origin buffer are valid since
+	//    they realy start on the object surface (this is tagged by setting a
+	//    stencil buffer bit at step 3).
+	
+	glStencilFunc(GL_EQUAL, 0x1, 0x1);
+	glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
+
 	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-	glStencilFunc(GL_ALWAYS, 0x2, 0x2);
-	glStencilOp(GL_INCR, GL_INCR, GL_INCR);
-
-	// render back face of frustum beam
-	RenderMesh(beam.mMesh);
-#endif
-
-
-	// 4. set back to normal rendering and clear the ray termination depth buffer
-	//    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)
-
-	//glDisable(GL_STENCIL_TEST);
-	glEnable(GL_STENCIL_TEST);
-	glStencilFunc(GL_EQUAL, 0x1, 0x1);
-	//glStencilFunc(GL_EQUAL, 0x2, 0x2);
-	glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
-
-	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-	glColorMask(1, 1, 1, 1);
 	glDepthMask(1);
+
 	glEnable(GL_DEPTH_TEST);
-	//glDisable(GL_STENCIL_TEST);	
+		
 	glEnable(GL_CULL_FACE);
 	glCullFace(GL_BACK);
 
-
-	// 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)
-
+	// setup front depth buffer
+	glEnable(GL_TEXTURE_2D);
+	
+	// bind pixel shader implementing the front depth buffer functionality
+	cgGLBindProgram(sCgFragmentProgram);
+	cgGLEnableProfile(sCgFragmentProfile);
+
+
+	// 5. render all objects inside the beam 
+	//    we can use id based false color to read them back for gaining the pvs
+
+	glColorMask(1, 1, 1, 1);
+
+	
+	// if objects not stored in beam => extract objects
 	if (beam.mFlags & !Beam::STORE_OBJECTS)
 	{
@@ -750,5 +752,10 @@
 	}
 
-	// list of objects intersected by the frustum
+
+	//    (objects can be compiled to a gl list now so that subsequent rendering for
+	//    this beam is fast - the same hold for step 3)
+	//    Afterwards we have two depth buffers defining the ray origin and termination
+	
+
 #if 0
 	static int glObjList = -1; 
@@ -761,4 +768,5 @@
 		for (it = beam.mObjects.begin(); it != it_end; ++ it)
 		{
+			// render all objects except the source object
 			if (*it != sourceObject)
 				RenderIntersectable(*it);
@@ -767,4 +775,5 @@
 		glEndList();
 	}
+
 	glCallList(glObjList);
 #else
@@ -772,33 +781,27 @@
 	for (it = beam.mObjects.begin(); it != it_end; ++ it)
 	{	
+		// render all objects except the source object
 		if (*it != sourceObject)
 			RenderIntersectable(*it);
 	}
 #endif
-
-	
-    // 6. Now we have a two depth buffers defining the ray origin and termination
-
-	
-	// bind depth texture
-	glEnable(GL_TEXTURE_2D);
-	
-	// bind depth cull pixel shader
-	cgGLBindProgram(sCgFragmentProgram);
-	cgGLEnableProfile(sCgFragmentProfile);
-
-	// 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
+	
+   
+
+	// 6. 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
 
 	// create new queries if necessary
 	GenQueries((int)beam.mViewCells.size());
 
-	// now check whether any backfacing polygon would pass the depth test?
-	//matt: should check both back /front facing because of dual depth buffer
-	//and danger of cutting the near plane with front facing polys.
+	// check whether any backfacing polygon would pass the depth test?
+	// matt: should check both back /front facing because of dual depth buffer
+	// and danger of cutting the near plane with front facing polys.
+	
 	glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
 	glDepthMask(GL_FALSE);
 	glDisable(GL_CULL_FACE);
+
   
 	ViewCellContainer::const_iterator vit, vit_end = beam.mViewCells.end();
@@ -815,12 +818,16 @@
 	}
 
+
+
 	// at this point, if possible, go and do some other computation
+
+
+	
+	// 7. The number of visible pixels is the number of sample rays which see the source
+	//    object from the corresponding viewcell -> remember these values for later update
+	//   of the viewcell pvs - or update immediately?
 
 	queryIdx = 0;
 	unsigned int pixelCount;
-
-	// 8. The number of visible pixels is the number of sample rays which see the source
-	//    object from the corresponding viewcell -> remember these values for later update
-	//   of the viewcell pvs - or update immediately?
 
 	for (vit = beam.mViewCells.begin(); vit != vit_end; ++ vit)
@@ -835,5 +842,6 @@
 	
 
-	//  In general it is not neccessary to remember to extract all the rays cast. I hope it
+	// 8. Copmpute rendering statistics
+	// In general it is not neccessary to remember 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)
@@ -846,12 +854,23 @@
 	stat.pvsSize = ComputePvs(beam.mObjects, pvsObj);
 	
-	
+	// to gain ray source and termination
+	// copy contents of ray termination buffer into depth texture
+	// and compare with ray source buffer
 #if 0
-	// copy contents of back depth buffer into depth texture
-	// depth buffer holds ray origins
+	VssRayContainer rays;
+
 	glBindTexture(GL_TEXTURE_2D, backDepthMap);	
 	glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, depthMapSize, depthMapSize);
+
+	ComputeRays(Intersectable *sourceObj, rays);
+
 #endif
-	// reset state
+
+
+
+	//-- cleanup
+
+
+	// reset gl state
 	glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
 	glDepthMask(GL_TRUE);
@@ -861,5 +880,5 @@
 	glDisable(GL_TEXTURE_2D);
 
-	// remove objects again
+	// remove objects from beam
 	if (beam.mFlags & !Beam::STORE_OBJECTS)
 		beam.mObjects.clear();
