Index: trunk/VUT/GtpVisibility/include/VisibilityInfo.h
===================================================================
--- trunk/VUT/GtpVisibility/include/VisibilityInfo.h	(revision 316)
+++ trunk/VUT/GtpVisibility/include/VisibilityInfo.h	(revision 318)
@@ -30,5 +30,6 @@
 	void SetProjectedPixels(int vis);
 	
-	/** Computes ratio of visible to projected pixels. */
+	/** Computes ratio of visible to projected pixels. 
+	*/
 	float ComputeRelativeVisibility();
 
@@ -39,4 +40,14 @@
 	*/
 	void AddVisibility(const int visiblePixels, const int projectedPixels);
+
+	bool operator<(const VisibilityInfo<T> &b) const 
+	{
+		return mSource < b.mSource;
+	}
+
+	bool operator==(const VisibilityInfo<T> &b) const 
+	{
+		return mSource == b.mSource;
+	}
 
 protected:
Index: trunk/VUT/work/ogre_changes/Plugins/OctreeSceneManager/src/OgreOctreeSceneManager.cpp
===================================================================
--- trunk/VUT/work/ogre_changes/Plugins/OctreeSceneManager/src/OgreOctreeSceneManager.cpp	(revision 316)
+++ trunk/VUT/work/ogre_changes/Plugins/OctreeSceneManager/src/OgreOctreeSceneManager.cpp	(revision 318)
@@ -1034,5 +1034,5 @@
 
 #ifdef GTP_VISIBILITY_MODIFIED_OGRE
-	mNumOctreeNodes = 1;
+	mNumOctants = 1;
 #endif // GTP_VISIBILITY_MODIFIED_OGRE
 
Index: trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env	(revision 313)
+++ trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env	(revision 318)
@@ -63,10 +63,10 @@
 	hierarchyType bspTree
 	height 7.0
-	maxViewCells 20
+	maxViewCells 0
 	#hierarchyType kdTree
 	#hierarchyType sceneDependent
 	filename ../data/atlanta/atlanta_viewcells_large.x3d
 #	filename ../data/vienna/viewcells-25-sel.x3d
-#	filename ../data/vienna/viewcells-25.x3d
+	filename ../data/vienna/viewcells-25.x3d
 #	filename ../data/vienna/viewcells-large-sel.x3d
 }
Index: trunk/VUT/GtpVisibilityPreprocessor/src/X3dParser.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/X3dParser.cpp	(revision 312)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/X3dParser.cpp	(revision 318)
@@ -484,5 +484,5 @@
 				ptr = endptr;
 				
-				float y = strtod(ptr, &endptr);
+				float y = (float)strtod(ptr, &endptr);
 
 				
@@ -491,5 +491,5 @@
 				ptr = endptr;
 
-				float z = strtod(ptr, &endptr);
+				float z = (float)strtod(ptr, &endptr);
 
 				if (ptr == endptr)
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h	(revision 313)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h	(revision 318)
@@ -8,5 +8,4 @@
 class ViewCell;
 class Plane3;
-//class Mesh;
 class BspTree;  
 class BspInterior;
@@ -14,11 +13,4 @@
 class AxisAlignedBox3;
 class Ray;
-
-//namespace GtpVisibilityPreprocessor {
-
-/** Container storing a soup of polygons used during BSP tree construction
-*/
-typedef vector<Polygon3 *> PolygonContainer;
-typedef vector<Ray *> RayContainer;
 
 struct BspRayTraversalData 
@@ -179,6 +171,7 @@
 	void SetupChildLinks(BspNode *b, BspNode *f);
 
-	/** Splits polygons.
-		@param polys the polygons to be split
+	/** Splits polygons with respect to the split plane.
+		@param polys the polygons to be split. the polygons are consumed and
+			   distributed to the containers frontPolys, backPolys, coincident.
 		@param frontPolys returns the polygons in the front of the split plane
 		@param backPolys returns the polygons in the back of the split plane
@@ -187,9 +180,9 @@
 		@param storePolys if the polygons should be stored in the node
 	*/
-	void SplitPolygons(PolygonContainer *polys, 
-					   PolygonContainer *frontPolys, 
-					   PolygonContainer *backPolys, 
-					   PolygonContainer *coincident, 
-					   int &splits, 
+	void SplitPolygons(PolygonContainer &polys, 
+					   PolygonContainer &frontPolys, 
+					   PolygonContainer &backPolys, 
+					   PolygonContainer &coincident,
+					   int &splits,
 					   bool storePolys = false);
 
@@ -261,10 +254,26 @@
 		/// the view cell associated with this subdivsion
 		ViewCell *mViewCell;
-		/// if the node is an inside or outside node with respect to the parent plane
-		//bool mIsInside;
-		BspTraversalData() {}
+		/// rays piercing this node
+		RayContainer *mRays;
+
+		BspTraversalData():
+		mNode(NULL),
+		mPolygons(NULL),
+		mDepth(0),
+		mViewCell(NULL),
+		mRays(NULL)
+		{}
 		
-		BspTraversalData(BspNode *node, PolygonContainer *polys, const int depth, ViewCell *viewCell): 
-		mNode(node), mPolygons(polys), mDepth(depth), mViewCell(viewCell) {}
+		BspTraversalData(BspNode *node, 
+						 PolygonContainer *polys, 
+						 const int depth, 
+						 ViewCell *viewCell,
+						 RayContainer *rays = NULL): 
+		mNode(node), 
+		mPolygons(polys), 
+		mDepth(depth), 
+		mViewCell(viewCell),
+		mRays(rays)
+		{}
     };
 
@@ -364,7 +373,10 @@
 
 	/** Evaluates the contribution of the candidate split plane.
+		@note the polygons can be reordered in the process.
 		@returns the cost of the candidate split plane
 	*/
-	float EvalSplitPlane(PolygonContainer &polys, const Plane3 &candidatePlane);
+	float EvalSplitPlane(PolygonContainer &polys, 
+						 const Plane3 &candidatePlane,
+						 const RayContainer &rays);
 
 	/** Evaluates tree stats in the BSP tree leafs.
@@ -382,6 +394,10 @@
 		@param leaf the leaf to be split
 		@param polys the polygon list on which the split decition is based
-	*/
-	Plane3 SelectPlane(BspLeaf *leaf, PolygonContainer &polys);
+		@param rays ray container on which selection may be based
+		Returns the split plane
+	*/
+	Plane3 SelectPlane(BspLeaf *leaf, 
+					   PolygonContainer &polys,
+					   const RayContainer &ray);
 
 	/** Filters next view cell down the tree and inserts it into the appropriate leaves
@@ -401,11 +417,13 @@
 		@param backPolys returns the polygons in the back of the split plane
 		@param coincident returns the polygons coincident to the split plane
+		@param rays ray container used to guide the split process
 		@returns the root of the subdivision
 	*/
 	BspInterior *SubdivideNode(BspLeaf *leaf, 
-						 	   PolygonContainer *polys, 
-							   PolygonContainer *frontPolys, 
-							   PolygonContainer *backPolys, 
-							   PolygonContainer *coincident);
+						 	   PolygonContainer &polys, 
+							   PolygonContainer &frontPolys,
+							   PolygonContainer &backPolys, 
+							   PolygonContainer &coincident,
+							   const RayContainer &rays);
 
 	/** Filters polygons down the tree.
@@ -418,22 +436,32 @@
 						PolygonContainer *frontPolys, PolygonContainer *backPolys);
 
-	/** Selects the split plane in order to get a balanced tree.
+	/** Selects the split plane in order to construct a tree with
+		certain characteristics (e.g., balanced tree, least splits, 
+		2.5d aligned)
 		@param polygons container of polygons
+		@param rays bundle of rays on which the split can be based
 		@param maxTests the maximal number of candidate tests
 	*/
-	Plane3 SelectPlaneHeuristics(PolygonContainer &polys, const int maxTests);
-
-	/** Extracts the meshes of the objects and copies them into the mesh. 
+	Plane3 SelectPlaneHeuristics(PolygonContainer &polys, 
+								 const RayContainer &rays,
+								 const int maxTests);
+
+	/** Extracts the meshes of the objects and adds them to polygons. 
 		Adds object aabb to the aabb of the tree.
 		@param maxPolys the maximal number of objects to be stored as polygons
 		@returns the number of polygons
 	*/
-	int Copy2PolygonSoup(const ObjectContainer &objects, PolygonContainer &polys, int maxObjects = 0);
-	/** Extracts the meshes of the view cells and copies them into the mesh. 
+	int AddToPolygonSoup(const ObjectContainer &objects, 
+						 PolygonContainer &polys, 
+						 int maxObjects = 0);
+
+	/** Extracts the meshes of the view cells and and adds them to polygons.
 		Adds view cell aabb to the aabb of the tree.
 		@param maxPolys the maximal number of objects to be stored as polygons
 		@returns the number of polygons
 	*/
-	int Copy2PolygonSoup(const ViewCellContainer &viewCells, PolygonContainer &polys, int maxObjects = 0);
+	int AddToPolygonSoup(const ViewCellContainer &viewCells, 
+						 PolygonContainer &polys, 
+						 int maxObjects = 0);
 
 	/** Extract polygons of this mesh and add to polygon container.
@@ -491,4 +519,15 @@
 							 vector<SortableEntry> &splitCandidates) const;
 
+	/** Splits the rays into front and back rays according to split plane
+		@param rays contains the rays to be split. The rays are 
+			   distributed to front and back rays.
+		@param frontRays returns rays on the front side of the plane
+		@param backRays returns rays on the back side of the plane
+	*/
+	void BspTree::SplitRays(const Plane3 plane,
+							RayContainer &rays, 
+							RayContainer &frontRays, 
+							RayContainer &backRays);
+
 	/// Pointer to the root of the tree
 	BspNode *mRoot;
Index: trunk/VUT/GtpVisibilityPreprocessor/src/AxisAlignedBox3.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/AxisAlignedBox3.h	(revision 312)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/AxisAlignedBox3.h	(revision 318)
@@ -305,8 +305,8 @@
   void GetEdge(const int edge, int  &aIdx, int &bIdx) const;
 
-  /** Bounds plane with box. Returns polygon resulting from the bounded
-	  plane.
+  /** Computes cross section of plane with box (i.e., bounds box). 
+	  @returns the cross section
   */
-  Polygon3 *BoundPlane(const Plane3 &plane);
+  Polygon3 *CrossSection(const Plane3 &plane);
 
 #define __EXTENT_HACK
@@ -360,7 +360,4 @@
   static const int fsvertices[27][9];
 
-  // table storing the complementary edges of each edge
-  //static const int complEdgeTbl[12][3];
-
   // input and output operator with stream
   friend ostream& operator<<(ostream &s, const AxisAlignedBox3 &A);
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Vector3.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Vector3.h	(revision 176)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Vector3.h	(revision 318)
@@ -299,4 +299,24 @@
 }
 
+// angle between two vectors with respect to a surface normal in the
+// range [0 .. 2 * pi]
+inline float
+Angle(const Vector3 &A, const Vector3 &B, const Vector3 &norm)
+{
+	Vector3 cross = CrossProd(A, B);
+
+	float signedAngle;
+
+	if (DotProd(cross, norm) > 0)
+		signedAngle = atan2(-Magnitude(CrossProd(A, B)), DotProd(A, B));
+	else
+		signedAngle = atan2(Magnitude(CrossProd(A, B)), DotProd(A, B));
+
+	if (signedAngle < 0)
+		return 2 * PI + signedAngle;
+
+	return signedAngle;
+}
+
 inline Vector3
 Vector3::operator+() const
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp	(revision 313)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp	(revision 318)
@@ -149,8 +149,8 @@
 }
 
-void BspInterior::SplitPolygons(PolygonContainer *polys, 
-								PolygonContainer *frontPolys, 
-								PolygonContainer *backPolys, 
-								PolygonContainer *coincident,
+void BspInterior::SplitPolygons(PolygonContainer &polys, 
+								PolygonContainer &frontPolys, 
+								PolygonContainer &backPolys, 
+								PolygonContainer &coincident,
 								int &splits, 
 								bool storePolys)
@@ -160,8 +160,8 @@
 	Debug << "splitting polygons of node " << this << " with plane " << mPlane << endl;
 #endif
-	while (!polys->empty())
-	{
-		Polygon3 *poly = polys->back();
-		polys->pop_back();
+	while (!polys.empty())
+	{
+		Polygon3 *poly = polys.back();
+		polys.pop_back();
 
 		//Debug << "New polygon with plane: " << poly->GetSupportingPlane() << "\n";
@@ -179,13 +179,13 @@
 			case Polygon3::COINCIDENT:
 				//Debug << "coincident" << endl;	
-				coincident->push_back(poly);
+				coincident.push_back(poly);
 				break;			
 			case Polygon3::FRONT_SIDE:	
 				//Debug << "front" << endl;
-				frontPolys->push_back(poly);
+				frontPolys.push_back(poly);
 				break;
 			case Polygon3::BACK_SIDE:
 				//Debug << "back" << endl;
-				backPolys->push_back(poly);
+				backPolys.push_back(poly);
 				break;
 			case Polygon3::SPLIT:
@@ -200,10 +200,10 @@
 				// check if polygons still valid 
 				if (front_piece->Valid())
-					frontPolys->push_back(front_piece);
+					frontPolys.push_back(front_piece);
 				else
 					DEL_PTR(front_piece);
 				
 				if (back_piece->Valid())
-					backPolys->push_back(back_piece);
+					backPolys.push_back(back_piece);
 				else				
 					DEL_PTR(back_piece);
@@ -402,8 +402,8 @@
 		
 				// split viewcell polygons with respect to split plane
-				interior->SplitPolygons(tData.mPolygons, 
-										frontPolys, 
-										backPolys,
-										&coincident,
+				interior->SplitPolygons(*tData.mPolygons, 
+										*frontPolys, 
+										*backPolys,
+										coincident,
 										splits, 
 										mStoreSplitPolys);
@@ -475,5 +475,5 @@
 }
 
-int BspTree::Copy2PolygonSoup(const ViewCellContainer &viewCells, PolygonContainer &polys, int maxObjects)
+int BspTree::AddToPolygonSoup(const ViewCellContainer &viewCells, PolygonContainer &polys, int maxObjects)
 {
 	int limit = (maxObjects > 0) ? Min((int)viewCells.size(), maxObjects) : (int)viewCells.size();
@@ -491,5 +491,5 @@
 }
 
-int BspTree::Copy2PolygonSoup(const ObjectContainer &objects, PolygonContainer &polys, int maxObjects)
+int BspTree::AddToPolygonSoup(const ObjectContainer &objects, PolygonContainer &polys, int maxObjects)
 {
 	int limit = (maxObjects > 0) ? Min((int)objects.size(), maxObjects) : (int)objects.size();
@@ -531,5 +531,5 @@
  	// copy view cell meshes into one big polygon soup
 	PolygonContainer *polys = new PolygonContainer();
-	mStat.polys = Copy2PolygonSoup(viewCells, *polys);
+	mStat.polys = AddToPolygonSoup(viewCells, *polys);
 
 	// construct tree from viewcell polygons
@@ -546,5 +546,5 @@
 	
 	// copy mesh instance polygons into one big polygon soup
-	mStat.polys = Copy2PolygonSoup(objects, *polys);
+	mStat.polys = AddToPolygonSoup(objects, *polys);
 
 	// construct tree from polygon soup
@@ -607,7 +607,12 @@
 		leaf->SetViewCell(tData.mViewCell);
 		
+		//-- clean up
+
 		// remaining polygons are discarded or added to node
 		leaf->ProcessPolygons(tData.mPolygons, mStoreSplitPolys);
 		DEL_PTR(tData.mPolygons);
+
+        CLEAR_CONTAINER(*tData.mRays);
+		DEL_PTR(tData.mRays);
 
 		return leaf;
@@ -621,8 +626,9 @@
 	// create new interior node and two leaf nodes
 	BspInterior *interior = SubdivideNode(dynamic_cast<BspLeaf *>(tData.mNode),
-										  tData.mPolygons,
-										  frontPolys,
-										  backPolys, 
-										  &coincident);
+										  *tData.mPolygons,
+										  *frontPolys,
+										  *backPolys, 
+										  coincident,
+										  *tData.mRays);
 
 	ViewCell *frontViewCell = mRootCell;
@@ -648,11 +654,34 @@
 	interior->ProcessPolygons(&coincident, mStoreSplitPolys);
 
+	// split rays
+	RayContainer *frontRays = NULL;
+	RayContainer *backRays = NULL;
+
+	if (tData.mRays->size() > 0)
+	{
+		RayContainer *frontRays = new RayContainer();
+		RayContainer *backRays = new RayContainer();
+
+		Plane3 plane;
+		SplitRays(plane, *tData.mRays, *frontRays, *backRays);
+	}
+
 	// push the children on the stack
-	tStack.push(BspTraversalData(interior->GetBack(), backPolys, tData.mDepth + 1, backViewCell));
-	tStack.push(BspTraversalData(interior->GetFront(), frontPolys, tData.mDepth + 1, frontViewCell));
+	tStack.push(BspTraversalData(interior->GetBack(), 
+								 backPolys, 
+								 tData.mDepth + 1, 
+								 backViewCell, 
+								 backRays));
+
+	tStack.push(BspTraversalData(interior->GetFront(), 
+								 frontPolys, 
+								 tData.mDepth + 1, 
+								 frontViewCell, 
+								 frontRays));
 
 	// cleanup
 	DEL_PTR(tData.mNode);
 	DEL_PTR(tData.mPolygons);
+	DEL_PTR(tData.mRays);
 
 	return interior;
@@ -684,19 +713,18 @@
 			foundFront = true;
 		}
-		//if (foundFront) Debug << "front viewCell: " << *frontViewCell << endl;
-		//if (foundBack) Debug << "back viewCell: " << *backViewCell << endl;
 	}
 }
 
 BspInterior *BspTree::SubdivideNode(BspLeaf *leaf, 
-									PolygonContainer *polys, 
-									PolygonContainer *frontPolys,
-									PolygonContainer *backPolys, 
-									PolygonContainer *coincident)
+									PolygonContainer &polys, 
+									PolygonContainer &frontPolys,
+									PolygonContainer &backPolys, 
+									PolygonContainer &coincident,
+									const RayContainer &rays)
 {
 	mStat.nodes += 2;
 
 	// add the new nodes to the tree + select subdivision plane
-	BspInterior *interior = new BspInterior(SelectPlane(leaf, *polys)); 
+	BspInterior *interior = new BspInterior(SelectPlane(leaf, polys, rays)); 
 
 #ifdef _DEBUG
@@ -707,5 +735,10 @@
 	int splits = 0;
 	
-	interior->SplitPolygons(polys, frontPolys, backPolys, coincident, splits, mStoreSplitPolys);
+	interior->SplitPolygons(polys, 
+							frontPolys, 
+							backPolys, 
+							coincident, 
+							splits, 
+							mStoreSplitPolys);
 	
  	mStat.splits += splits;
@@ -829,5 +862,7 @@
 }
 
-Plane3 BspTree::SelectPlane(BspLeaf *leaf, PolygonContainer &polys)
+Plane3 BspTree::SelectPlane(BspLeaf *leaf, 
+							PolygonContainer &polys, 
+							const RayContainer &rays)
 {
 	if (polys.size() == 0)
@@ -882,8 +917,10 @@
 
 	// use heuristics to find appropriate plane
-	return SelectPlaneHeuristics(polys, sMaxCandidates);
-}
-
-Plane3 BspTree::SelectPlaneHeuristics(PolygonContainer &polys, int maxTests)
+	return SelectPlaneHeuristics(polys, rays, sMaxCandidates);
+}
+
+Plane3 BspTree::SelectPlaneHeuristics(PolygonContainer &polys,
+									  const RayContainer &rays,
+									  const int maxTests)
 {
 	float lowestCost = MAX_FLOAT;
@@ -901,5 +938,5 @@
 		
 		// evaluate current candidate
-		float candidateCost = EvalSplitPlane(polys, candidatePlane);
+		float candidateCost = EvalSplitPlane(polys, candidatePlane, rays);
 			
 		if (candidateCost < lowestCost)
@@ -928,5 +965,7 @@
 }
 
-float BspTree::EvalSplitPlane(PolygonContainer &polys, const Plane3 &candidatePlane)
+float BspTree::EvalSplitPlane(PolygonContainer &polys, 
+							  const Plane3 &candidatePlane, 
+							  const RayContainer &rays)
 {
 	float val = 0;
@@ -1318,3 +1357,14 @@
 	}
 }
+
+void BspTree::SplitRays(const Plane3 plane,
+						RayContainer &rays, 
+						RayContainer &frontRays, 
+						RayContainer &backRays)
+{
+	while (!rays.empty())
+	{
+		//TODO
+	}
+}
 //} // GtpVisibilityPreprocessor
Index: trunk/VUT/GtpVisibilityPreprocessor/src/main.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/main.cpp	(revision 315)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/main.cpp	(revision 318)
@@ -66,11 +66,12 @@
 		  m.mDiffuseColor = RgbColor(1, 0, 0);
 		  exporter->SetForcedMaterial(m);
-		  exporter->SetWireframe();
+		  exporter->SetWireframe();//exporter->SetFilled();
 		  exporter->ExportBspSplits(*p->mBspTree);
 
-		  m.mDiffuseColor = RgbColor(0, 1, 0);
-		  exporter->SetForcedMaterial(m);
+		  //m.mDiffuseColor = RgbColor(0, 1, 0);
+		  //exporter->SetForcedMaterial(m);
 		  exporter->SetFilled();
 
+		  exporter->ResetForcedMaterial();
 		  exporter->ExportViewCells(p->mViewCells);
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/X3dExporter.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/X3dExporter.cpp	(revision 316)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/X3dExporter.cpp	(revision 318)
@@ -249,10 +249,11 @@
 	VertexContainer::const_iterator vi;  
 	
-	for (vi = poly->mVertices.begin(); vi != poly->mVertices.end(); ++vi) 
-	{
-		stream << index ++ << " ";
-	}
+	for (int index = 0; index < (int)poly->mVertices.size(); ++ index) 
+		stream << index << " ";
+	
+	if (mWireframe) // final line to finish polygon
+		stream << "0 ";
+
 	stream << "-1" << endl;
-
 	stream << "\" >" << endl;
 	
@@ -278,5 +279,5 @@
 void X3dExporter::ExportPolygons(const PolygonContainer &polys)
 {
-	stream << "<Shape>" << endl;
+  	stream << "<Shape>" << endl;
 	stream << "<Appearance>" << endl;
   
@@ -319,8 +320,11 @@
 	{
 		Polygon3 *poly = *pit;
+		int startIdx = index;
 		for (vi = poly->mVertices.begin(); vi != poly->mVertices.end(); ++vi) 
 		{
 			stream << index ++ << " ";
 		}
+
+		stream << startIdx << " ";// finish line
 		stream << "-1" << endl;
 	}
@@ -329,5 +333,5 @@
 	
 	stream << "<Coordinate  point=\"" << endl;
-	for (pit = polys.begin(); pit != polys.end(); ++pit)
+	for (pit = polys.begin(); pit != polys.end(); ++ pit)
 	{
 		Polygon3 *poly = *pit;
@@ -657,5 +661,5 @@
 
 			// bounded plane is added to the polygons
-			Polygon3 *planePoly = tree.GetBoundingBox().BoundPlane(*interior->GetPlane());
+			Polygon3 *planePoly = tree.GetBoundingBox().CrossSection(*interior->GetPlane());
 		
 			// do all the splits with the previous planes
@@ -689,5 +693,5 @@
 			else
 			{
-				Debug << "polygon not valid: " << *planePoly << " size: " << (int)planePoly->mVertices.size() << endl;
+				//Debug << "polygon not valid: " << *planePoly << " size: " << (int)planePoly->mVertices.size() << endl;
 				DEL_PTR(planePoly);
 			}
@@ -720,5 +724,5 @@
 
 			// bounded plane is added to the polygons
-			polys.push_back(tree.GetBoundingBox().BoundPlane(*interior->GetPlane()));
+			polys.push_back(tree.GetBoundingBox().CrossSection(*interior->GetPlane()));
 		
 			// push the children on the stack
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Polygon3.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Polygon3.cpp	(revision 317)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Polygon3.cpp	(revision 318)
@@ -56,4 +56,5 @@
 	VertexContainer::const_iterator it;
 	
+	bool foundSplit = false;
 	// find line - plane intersections
 	for (it = mVertices.begin(); it != mVertices.end(); ++ it)
@@ -71,5 +72,5 @@
 			
 				// test if split point not too close to previous split point
-				if ((splitPts.size() == 0) || 
+				if (!foundSplit || 
 					(SqrDistance(splitPt, splitPts.back()) > SIDE_TOLERANCE_SQRD))
 				{
@@ -79,4 +80,5 @@
 					
 					splitPts.push_back(splitPt);
+					foundSplit = true;
 				}
 			}
@@ -91,5 +93,5 @@
 				// test if split point not too close to other split point
 					// test if split point not too close to previous split point
-				if ((splitPts.size() == 0) || 
+				if (!foundSplit || 
 					(SqrDistance(splitPt, splitPts.back()) > SIDE_TOLERANCE_SQRD))
 				{
@@ -99,4 +101,5 @@
 
 					splitPts.push_back(splitPt);
+					foundSplit = true;
 				}	
 			}
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Containers.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Containers.h	(revision 263)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Containers.h	(revision 318)
@@ -12,8 +12,13 @@
 class Intersectable;
 class Polygon3;
+class Ray;
 
-/** Container storing polygons used during BSP tree construction
+/** Container storing polygons used during BSP tree construction.
 */
 typedef vector<Polygon3 *> PolygonContainer;
+
+/** Container storing a bundle of rays.
+*/
+typedef vector<Ray *> RayContainer;
 
 /** Container for Mesh pointers primarily for the use within the kDTree and
Index: trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.cpp	(revision 316)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.cpp	(revision 318)
@@ -400,5 +400,7 @@
 				 << 100*passContributingSamples/(float)passSamples<<"%)" << " avgPVS="
 				 << pvsSize/(float)objects.size() << endl 
-				 << "avg ray contrib=" << passSampleContributions/(float)passContributingSamples << endl;
+				 << "avg ray contrib=" << 
+				 ((passContributingSamples > 0) ? passSampleContributions/(float)passContributingSamples : 0)
+				 << endl;
 		
 		
@@ -410,5 +412,7 @@
 			"#PContributingSamples\n"<<100*passContributingSamples/(float)passSamples<<endl <<
 			"#AvgPVS\n"<< pvsSize/(float)objects.size() << endl <<
-			"#AvgRayContrib\n" << passSampleContributions/(float)passContributingSamples << endl;
+			"#AvgRayContrib\n" << 
+			((passContributingSamples > 0) ? passSampleContributions/(float)passContributingSamples : 0)
+			<< endl;
 	}
   
Index: trunk/VUT/GtpVisibilityPreprocessor/src/AxisAlignedBox3.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/AxisAlignedBox3.cpp	(revision 313)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/AxisAlignedBox3.cpp	(revision 318)
@@ -1647,17 +1647,28 @@
 }
 
+struct VertexData
+{
+	Vector3 mVertex;
+	float mAngle;
+	
+	VertexData(Vector3 vtx, float angle): mVertex(vtx), mAngle(angle)
+	{}
+
+	bool operator<(const VertexData &b) const 
+	{
+		return mAngle < b.mAngle;
+	}
+};
+
 // TODO: use a table to avoid normal and distance computations
-Polygon3 *AxisAlignedBox3::BoundPlane(const Plane3 &plane)
-{
-	Vector3 ptA, ptB;
-	int sideA = 0, sideB = 0;
-
-	VertexContainer vertices;
-
+Polygon3 *AxisAlignedBox3::CrossSection(const Plane3 &plane)
+{
+	Polygon3 *planePoly = new Polygon3();
+	
 	int side[8];
-
-	bool onFrontSide, onBackSide = false;
-
+	bool onFrontSide = false, onBackSide = false;
+	
 	Vector3 vtx;
+	//-- compute classification of vertices
 	for (int i = 0; i < 8; ++i)
 	{
@@ -1669,118 +1680,68 @@
 			onBackSide = true;
 		else // vertex coincident => push_back
-			vertices.push_back(vtx);
+			planePoly->mVertices.push_back(vtx);
 	}
 
-	// does not intersect
-	if (!onFrontSide && !onBackSide)
-		return NULL;
-
-	for (int i = 0; i < 12; ++ i)
+	//-- find intersections
+	if (onFrontSide && onBackSide)
 	{
-		int aIdx, bIdx;
-		GetEdge(i, aIdx, bIdx);
-
-		ptA = GetVertex(aIdx);
-		ptB = GetVertex(bIdx);
-
-		int sideA = side[aIdx];
-		int sideB = side[bIdx];
-
-		if (((sideA > 0) && (sideB < 0)) || (sideA < 0) && (sideB > 0))
-			vertices.push_back(plane.FindIntersection(ptA, ptB));	
-	}
-
-	// illformed polygon => swap
-	// HACK: cannot work in abitrary cases
-	if (vertices.size() > 3)
-	{
-		for (int j = 0; j < (int)vertices.size() - 1; ++j)
+		Vector3 ptA, ptB;
+		for (int i = 0; i < 12; ++ i)
 		{
-			float minDist = 99999;
-			int minIdx = j;
-
-			for (int i = j + 1; i < vertices.size(); ++i)
-			{
-				float dist = SqrDistance(vertices[j], vertices[i]);
-				
-				if (dist < minDist)
-				{
-					minDist = dist;
-					minIdx = i;
-				}
-			}
-
-			Vector3 vtx = vertices[minIdx];
-			vertices[minIdx] = vertices[j + 1];
-			vertices[j + 1] = vtx;
+			int aIdx, bIdx;
+			GetEdge(i, aIdx, bIdx);
+
+			ptA = GetVertex(aIdx);
+			ptB = GetVertex(bIdx);
+
+			int sideA = side[aIdx];
+			int sideB = side[bIdx];
+
+			if (((sideA > 0) && (sideB < 0)) || (sideA < 0) && (sideB > 0))
+				planePoly->mVertices.push_back(plane.FindIntersection(ptA, ptB));	
 		}
 	}
 
-	Polygon3 *planePoly = new Polygon3();
-	
-	// wrong surface orientation?
-    Vector3 norm = Normalize(CrossProd(vertices[0] - vertices[1],
-									   vertices[2] - vertices[1]));
-
-	
-
-	if (DotProd(norm, plane.mNormal) > 0)
-		for (int i = 0; i < (int)vertices.size(); ++ i)
-			planePoly->mVertices.push_back(vertices[i]);
-	else
+	// order intersectioins	
+	if (planePoly->mVertices.size() > 3)
 	{
-		for (int i = (int)vertices.size() - 1; i >= 0; -- i)
-			planePoly->mVertices.push_back(vertices[i]);
+		Vector3 centerOfMass(0);
+
+		// compute center of mass
+		for (int i = 0; i < (int)planePoly->mVertices.size(); ++ i)
+			centerOfMass += planePoly->mVertices[i];
+		
+		centerOfMass /= (float)planePoly->mVertices.size();
+
+		vector<VertexData> vertexData;
+		
+		Vector3 refVec = Normalize(centerOfMass - planePoly->mVertices[0]);
+
+		// compute angle to reference point
+		for (int i = 1; i < (int)planePoly->mVertices.size(); ++ i)
+		{
+			float angle = 
+				Angle(refVec, centerOfMass - planePoly->mVertices[i], plane.mNormal);
+
+			vertexData.push_back(VertexData(planePoly->mVertices[i], angle));
+		}
+		
+		std::stable_sort(vertexData.begin(), vertexData.end());
+
+		// update vertices
+		for (int i = 1; i < (int)planePoly->mVertices.size(); ++ i)
+			planePoly->mVertices[i] = vertexData[i - 1].mVertex;
 	}
-
-	//Debug << *planePoly << "\narea: " << planePoly->GetArea() << endl;
+	else if (planePoly->mVertices.size() == 3)
+	{
+		// fix orientation if needed
+		if (DotProd(planePoly->GetNormal(), plane.mNormal) < 0)
+		{
+			Vector3 v = planePoly->mVertices[1];
+			planePoly->mVertices[1] = planePoly->mVertices[2];
+			planePoly->mVertices[2] = v;
+		}
+	}
 	
 	return planePoly;
 }
-/*
-const int AxisAlignedBox3::complEdgeTbl[12][3] =
-{
-	{3, 4, 5},
-	{3, 4, 5},
-	{3, 4, 5},
-	{0, 1, 2},
-	{0, 1, 2},
-	{0, 1, 2},
-	{9, 10, 11},
-	{8, 9, 10},
-	{7, 10, 11},
-	{6, 7, 11},
-	{6, 7, 8},
-	{6, 8, 9},
-};
-*/
-
-/*
-inline void addEdge(int idx, int ptAIdx, int ptBIdx)
-{
-	edgeTable[idx].push_back(edge(ptAIdx, ptBIdx));
-}
-int AxisAlignedBox3::CreateEdgeTable()
-{
-	//-- four vertices pattern 1 (3 + reflection)
-	int idx = getIdx(1) + getIdx(2) + getIdx(5) + getIdx(6); 
-	addEdge(idx, 1, 0); addEdge(idx, 3, 2); addEdge(idx, 7, 6; addEdge(idx, 4, 5);
-	int idx = 255 - idx;
-	addEdge(idx, 4, 5); addEdge(idx, 7, 6);  addEdge(idx, 3, 2); addEdge(idx, 1, 0); 
-
-	int idx = getIdx(0) + getIdx(1) + getIdx(2) + getIdx(3); 
-	addEdge(idx, 0, 4); addEdge(idx, 3, 7); addEdge(idx, 2, 6); addEdge(idx, 1, 5);
-	int idx = 255 - idx;
-	addEdge(idx, 1, 5); addEdge(idx, 2, 6); addEdge(idx, 3, 7); addEdge(idx, 0, 4); 
-
-	int idx = getIdx(2) + getIdx(6) + getIdx(7) + getIdx(3);
-	addEdge(idx, 0, 3); addEdge(idx, 4, 7); addEdge(idx, 5, 6); addEdge(idx, 1, 2);
-	int idx = 255 - idx;
-	addEdge(idx, 1, 2); addEdge(idx, 5, 6); addEdge(idx, 4, 7); addEdge(idx, 0, 3); 
-
-
-	//-- four vertices pattern 2 (12 + reflection
-	int idx = getIdx(0) + getIdx(4);
-	addEdge(idx, 0, 1); addEdge(idx, 0, 3); addEdge(idx, 4, 7; addEdge(idx, 4, 5);
-}
-*/
Index: trunk/VUT/Ogre/src/OgreOcclusionQueriesQueryManager.cpp
===================================================================
--- trunk/VUT/Ogre/src/OgreOcclusionQueriesQueryManager.cpp	(revision 316)
+++ trunk/VUT/Ogre/src/OgreOcclusionQueriesQueryManager.cpp	(revision 318)
@@ -7,30 +7,4 @@
 
 namespace Ogre {
-
-//-----------------------------------------------------------------------
-bool nodeinfo_eq(const GtpVisibility::NodeInfo &a, const GtpVisibility::NodeInfo &b)
-{
-	return a.GetSource() == b.GetSource();
-} 
-bool nodeinfo_lt(const GtpVisibility::NodeInfo &a, const GtpVisibility::NodeInfo &b)
-{
-	return a.GetSource() < b.GetSource();
-}
-bool meshinfo_eq(const GtpVisibility::MeshInfo &a, const GtpVisibility::MeshInfo &b)
-{
-	return a.GetSource() == b.GetSource();
-} 
-bool meshinfo_lt(const GtpVisibility::MeshInfo &a, const GtpVisibility::MeshInfo &b)
-{	
-	return a.GetSource() < b.GetSource();
-}
-bool patchinfo_eq(const GtpVisibility::PatchInfo &a, const GtpVisibility::PatchInfo &b)
-{
-	return a.GetSource() == b.GetSource();
-} 
-bool patchinfo_lt(const GtpVisibility::PatchInfo &a, const GtpVisibility::PatchInfo &b)
-{
-	return a.GetSource() < b.GetSource();
-}
 
 //----------------------------------------------------------------------- 
@@ -408,5 +382,5 @@
 					GtpVisibility::NodeInfoContainer *visibleNodes)
 {
-	sort(visibleNodes->begin(), visibleNodes->end(), nodeinfo_lt);
+	stable_sort(visibleNodes->begin(), visibleNodes->end()/*, nodeinfo_lt*/);
 
 	GtpVisibility::NodeInfoContainer::iterator visibleNodesIt,
@@ -429,5 +403,5 @@
 	
 	// physically delete duplicates
-	visibleNodes->erase(std::unique(visibleNodes->begin(), visibleNodes->end(), nodeinfo_eq),
+	visibleNodes->erase(std::unique(visibleNodes->begin(), visibleNodes->end()),
 						visibleNodes->end());
 }
@@ -436,5 +410,5 @@
 				GtpVisibility::MeshInfoContainer *visibleGeometry)
 {
-	sort(visibleGeometry->begin(), visibleGeometry->end(), meshinfo_lt);
+	stable_sort(visibleGeometry->begin(), visibleGeometry->end());
 	
 	GtpVisibility::MeshInfoContainer::iterator visibleGeomIt,
@@ -457,5 +431,5 @@
 
 	// physically delete duplicates
-	visibleGeometry->erase(std::unique(visibleGeometry->begin(), visibleGeometry->end(), meshinfo_eq), 
+	visibleGeometry->erase(std::unique(visibleGeometry->begin(), visibleGeometry->end()), 
 						   visibleGeometry->end());
 }
@@ -464,5 +438,5 @@
 				GtpVisibility::PatchInfoContainer *visiblePatches)
 {
-	sort(visiblePatches->begin(), visiblePatches->end(), patchinfo_lt);
+	stable_sort(visiblePatches->begin(), visiblePatches->end());
 	
 	GtpVisibility::PatchInfoContainer::iterator visiblePatchIt,
@@ -485,5 +459,5 @@
 
 	// physically delete duplicates
-	visiblePatches->erase(std::unique(visiblePatches->begin(), visiblePatches->end(), patchinfo_eq), 
+	visiblePatches->erase(std::unique(visiblePatches->begin(), visiblePatches->end()), 
 						  visiblePatches->end());
 }
