Index: trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env	(revision 410)
+++ trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env	(revision 411)
@@ -67,4 +67,5 @@
 ViewCells {
 	#hierarchy kdTree
+	hierarchy vspTree
 	hierarchy bspTree
 	# hierarchy sceneDependent
@@ -201,10 +202,16 @@
 	epsilon		1e-6
 
-	maxDepth 	40
-	minPvs		1
-	minRays		50
-	minSize		0.00001
-	maxCostRatio	0.95
-	maxRayContribution 0.05
+	Construction {
+		samples 100000
+	}
+	
+	Termination {
+		maxDepth 	40
+		minPvs		1
+		minRays		50
+		minSize		0.00001
+		maxCostRatio	0.95
+		maxRayContribution 0.05
+	}
 	
 	maxTotalMemory	400
@@ -212,10 +219,6 @@
 
 	splitType regular
-#	splitType heuristics
 
 	numberOfEndPointDomains	10000
 	ct_div_ci	0.0
-	randomize	false
-
-	refDirBoxMaxSize	0.1
-}
+}
Index: trunk/VUT/GtpVisibilityPreprocessor/src/VspKdTree.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/VspKdTree.cpp	(revision 410)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/VspKdTree.cpp	(revision 411)
@@ -608,5 +608,5 @@
 	
 	float sum = rr*sizeBox;
-	float minSum = 1e20;
+	float minSum = 1e20f;
 	
 	Intersectable::NewMail();
@@ -706,5 +706,5 @@
 	splitCandidates->clear();
   
-	int requestedSize = 2*(node->rays.size());
+	int requestedSize = 2 * (int)(node->rays.size());
 	// creates a sorted split candidates array
 	if (splitCandidates->capacity() > 500000 &&
@@ -756,5 +756,5 @@
 
 	if ((int)(leaf->rays.size()) > stat.maxRayRefs)
-		stat.maxRayRefs = leaf->rays.size();
+		stat.maxRayRefs = (int)leaf->rays.size();
 }
 
@@ -899,5 +899,5 @@
 	
 	// update stats
-	stat.rayRefs -= leaf->rays.size();
+	stat.rayRefs -= (int)leaf->rays.size();
 	stat.rayRefs += raysBack + raysFront;
 
@@ -1057,5 +1057,5 @@
 				if (removeAllScheduledRays) 
 				{
-					int tail = leaf->rays.size() - 1;
+					int tail = (int)leaf->rays.size() - 1;
 
 					for (int i=0; i < (int)(leaf->rays.size()); ++ i) 
@@ -1435,5 +1435,5 @@
 			VspKdTreeLeaf *leaf = (VspKdTreeLeaf *)node;
 			float c = leaf->GetAvgRayContribution();
-			int num = (c*ratioPerLeaf + 0.5);
+			int num = (int)(c*ratioPerLeaf + 0.5);
 			//			cout<<num<<" ";
 
@@ -1457,5 +1457,5 @@
 	}
 
-	return rays.size();
+	return (int)rays.size();
 }
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/RenderSimulator.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/RenderSimulator.h	(revision 409)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/RenderSimulator.h	(revision 411)
@@ -30,5 +30,8 @@
 {
 public:
-	BspViewCellRenderSimulator(float objRenderCost, float vcOverhead, float moveSpeed, BspTree *bspTree);
+	BspViewCellRenderSimulator(float objRenderCost, 
+							   float vcOverhead, 
+							   float moveSpeed, 
+							   BspTree *bspTree);
 
 	Real SimulateRendering();
@@ -47,5 +50,8 @@
 {
 public:
-	KdViewCellRenderSimulator(float objRenderCost, float vcOverhead, float moveSpeed, KdTree *kdTree);
+	KdViewCellRenderSimulator(float objRenderCost, 
+							  float vcOverhead, 
+							  float moveSpeed, 
+							  KdTree *kdTree);
 	Real SimulateRendering();
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h	(revision 409)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h	(revision 411)
@@ -244,4 +244,5 @@
 	*/
 	BspInterior(const Plane3 &plane);
+	~BspInterior();
 	/** @return false since it is an interior node 
 	*/
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Environment.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Environment.cpp	(revision 409)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Environment.cpp	(revision 411)
@@ -1336,31 +1336,88 @@
 
 
-	RegisterOption("VspKdTree.maxDepth", optInt, "kd_depth=", "12");
-  RegisterOption("VspKdTree.minPvs", optInt, "kd_minpvs=", "1");
-  RegisterOption("VspKdTree.minRays", optInt, "kd_minrays=", "10");
-	RegisterOption("VspKdTree.maxCostRatio", optFloat, "maxcost=", "0.95");
-	RegisterOption("VspKdTree.maxRayContribution", optFloat, "maxraycontrib=", "0.5");
-
-	RegisterOption("VspKdTree.epsilon", optFloat, "kd_eps=", "1e-6");
-  RegisterOption("VspKdTree.ct_div_ci", optFloat, "kd_ctdivci=", "1.0");
-  RegisterOption("VspKdTree.randomize", optBool, "randomize", "false");
-  RegisterOption("VspKdTree.splitType", optString, "split=", "queries");
-  RegisterOption("VspKdTree.numberOfEndPointDomains", optInt, "endpoints=", "10000");
-
-  RegisterOption("VspKdTree.minSize", optFloat, "minsize=", "0.001");
-
-  RegisterOption("VspKdTree.maxTotalMemory", optFloat, "mem=", "60.0");
-  RegisterOption("VspKdTree.maxStaticMemory", optFloat, "statmem=", "8.0");
-
-  RegisterOption("VspKdTree.queryType", optString, "qtype=", "static");
-
-  RegisterOption("VspKdTree.queryPosWeight", optFloat, "qposweight=", "0.0");
-  RegisterOption("VspKdTree.useRefDirSplits", optBool, "refdir", "false");
-  RegisterOption("VspKdTree.refDirAngle", optFloat, "refangle=", "10");
-  RegisterOption("VspKdTree.refDirBoxMaxSize", optFloat, "refboxsize=", "0.1");
-  RegisterOption("VspKdTree.accessTimeThreshold", optInt, "accesstime=", "1000");
-  RegisterOption("VspKdTree.minCollapseDepth", optInt, "colldepth=", "4");
-
-  	RegisterOption("VssTree.maxDepth", optInt, "kd_depth=", "12");
+  RegisterOption("VspKdTree.Construction.Samples",
+		 optInt,
+		 "-vsp_construction_samples=",
+		 "100000");
+
+  RegisterOption("VspKdTree.Termination.maxDepth", 
+		optInt, 
+		"vsp_depth=", "30");
+
+  RegisterOption("VspKdTree.Termination.minPvs", 
+	  optInt, 
+	  "vsp_minpvs=", 
+	  "1");
+
+  RegisterOption("VspKdTree.Termination.minRays", 
+	  optInt, 
+	  "vsp_minrays=", 
+	  "10");
+
+  RegisterOption("VspKdTree.maxCostRatio", 
+	  optFloat, 
+	  "vsp_maxcost=", 
+	  "0.95");
+
+  RegisterOption("VspKdTree.maxRayContribution", 
+	  optFloat, 
+	  "vsp_max_ray_contrib=", 
+	  "0.5");
+
+  RegisterOption("VspKdTree.epsilon", 
+	  optFloat, 
+	  "kd_eps=", 
+	  "1e-6");
+
+  RegisterOption("VspKdTree.ct_div_ci", 
+	  optFloat, 
+	  "vsp_ctdivci=", "1.0");
+  
+  RegisterOption("VspKdTree.splitType", 
+	  optString, 
+	  "split=", 
+	  "queries");
+
+  RegisterOption("VspKdTree.numberOfEndPointDomains", 
+	  optInt, 
+	  "endpoints=", 
+	  "10000");
+
+  RegisterOption("VspKdTree.minSize", 
+	  optFloat, 
+	  "minsize=", 
+	  "0.001");
+
+  RegisterOption("VspKdTree.maxTotalMemory", 
+	  optFloat, 
+	  "vsp_max_total_mem=", 
+	  "60.0");
+
+  RegisterOption("VspKdTree.maxStaticMemory", 
+	  optFloat, 
+	  "vsp_max_static_mem=", 
+	  "8.0");
+
+  RegisterOption("VspKdTree.queryType", 
+	  optString, 
+	  "qtype=", 
+	  "static");
+
+  RegisterOption("VspKdTree.queryPosWeight", 
+		optFloat, 
+		"qposweight=", 
+		"0.0");
+  
+  RegisterOption("VspKdTree.accessTimeThreshold", 
+	  optInt, 
+	  "accesstime=", 
+	  "1000");
+
+  RegisterOption("VspKdTree.minCollapseDepth", 
+	  optInt, 
+	  "vsp_min_colldepth=", 
+	  "4");
+  
+  RegisterOption("VssTree.maxDepth", optInt, "kd_depth=", "12");
   RegisterOption("VssTree.minPvs", optInt, "kd_minpvs=", "1");
   RegisterOption("VssTree.minRays", optInt, "kd_minrays=", "10");
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp	(revision 410)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp	(revision 411)
@@ -113,4 +113,10 @@
 mPlane(plane), mFront(NULL), mBack(NULL)
 {}
+
+BspInterior::~BspInterior() 
+{ 
+	DEL_PTR(mFront); 
+	DEL_PTR(mBack);
+}
 
 bool BspInterior::IsLeaf() const
@@ -375,25 +381,5 @@
 BspTree::~BspTree()
 {
-	std::stack<BspNode *> tStack;
-
-	tStack.push(mRoot);
-
-	while (!tStack.empty())
-	{
-		BspNode *node = tStack.top();
-
-	    tStack.pop();
-	
-		if (!node->IsLeaf())
-		{
-			BspInterior *interior = dynamic_cast<BspInterior *>(node);
-
-			// push the children on the stack (there are always two children)
-			tStack.push(interior->GetBack());
-			tStack.push(interior->GetFront());
-		}
-
-		DEL_PTR(node);
-	}
+	DEL_PTR(mRoot);
 }
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.h	(revision 372)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.h	(revision 411)
@@ -35,6 +35,6 @@
 	*/
 	static void DeriveViewCells(const ObjectContainer &objects, 
-															ViewCellContainer &viewCells, 
-															const int maxViewCells);
+								ViewCellContainer &viewCells, 
+								const int maxViewCells);
 
 	
@@ -62,5 +62,5 @@
 
 	/// view cells types
-	enum HierarchyType {BSP, KD};
+	enum HierarchyType {BSP, KD, VSP};
 
 	/** Generates view cells of type specified by view cells type.
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.cpp	(revision 410)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.cpp	(revision 411)
@@ -62,4 +62,8 @@
 	{
 		ViewCell::sHierarchy = ViewCell::KD;
+	}
+	else if (strcmp(viewCellsStr, "vspTree") == 0)
+	{
+		ViewCell::sHierarchy = ViewCell::VSP;
 	}
 	else if (strcmp(viewCellsStr, "sceneDependent") == 0)
Index: trunk/VUT/GtpVisibilityPreprocessor/src/VssRay.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/VssRay.h	(revision 410)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/VssRay.h	(revision 411)
@@ -61,7 +61,14 @@
   }
 	
-	VccRay(const Ray &ray):
-  VccRay(ray.GetLoc(), ray.Extrap(ray.intersections[0].mT),  ray.intersections[0].mObject, ray.sourceObject.mObject)
-  {}
+	VssRay(const Ray &ray)
+		:mOrigin(ray.GetLoc()), 
+		mTermination(ray.Extrap(ray.intersections[0].mT)),
+		mOriginObject(ray.sourceObject.mObject),
+		mTerminationObject(ray.intersections[0].mObject),
+		mRefCount(0),
+		mFlags(0),
+		mMailbox(-1)
+	{}
+
   void Precompute() {
     mFlags = 0;
Index: trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.h	(revision 409)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.h	(revision 411)
@@ -6,5 +6,5 @@
 
 #include "Preprocessor.h"
-
+#include "VssRay.h"
 
 /** Sampling based visibility preprocessing. The implementation is based on heuristical
@@ -14,22 +14,10 @@
 		
   SamplingPreprocessor();
-
   ~SamplingPreprocessor();
 
   virtual bool ComputeVisibility();
 
+
 protected:
-	int mPass;
-
-  int mSamplesPerPass;
-  int mTotalSamples;
-  int mKdPvsDepth;
-  ofstream mStats;
-  ObjectContainer mObjects;
-  RayContainer mSampleRays;
-  int mBspConstructionSamples;
-  int mPostProcessSamples;
-  int mVisualizationSamples;
-
   void
   SetupRay(Ray &ray, 
@@ -81,4 +69,10 @@
 							 int &sampleContributions);
 
+	void ProcessVspViewCells(const Ray &ray,
+							 Intersectable *object,
+							 const int faceIndex,
+							 int &contributingSamples,
+							 int &sampleContributions);
+
 	/** Adds objects samples to bsp view cells.
 	*/
@@ -98,4 +92,21 @@
 	*/
 	int PostprocessViewCells(const RayContainer &rays);
+
+protected:
+	int mPass;
+	int mSamplesPerPass;
+	int mTotalSamples;
+	int mKdPvsDepth;
+	ofstream mStats;
+	ObjectContainer mObjects;
+
+	RayContainer mSampleRays;
+	VssRayContainer mVspSampleRays;
+	int mBspConstructionSamples;
+	int mVspConstructionSamples;
+
+    int mPostProcessSamples;
+	int mVisualizationSamples;
+
 };
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.h	(revision 409)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.h	(revision 411)
@@ -9,4 +9,5 @@
 #include "ViewCellBsp.h"
 #include "ViewCell.h"
+#include "VspKdTree.h"
 
 class RenderSimulator;
@@ -119,4 +120,9 @@
 
   RenderSimulator *mRenderSimulator;
+
+  /** Kd tree inducing a coarse partition of view space that are the building
+	  blocks for view cells.
+  */
+  VspKdTree *mVspKdTree;
 };
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/VspKdTree.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/VspKdTree.h	(revision 410)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/VspKdTree.h	(revision 411)
@@ -104,29 +104,4 @@
 
 
-// --------------------------------------------------------------
-// For sorting rays
-// --------------------------------------------------------------
-struct  SortableEntry
-{
-  enum EType {
-    ERayMin,
-    ERayMax
-  };
-
-  int type;
-  float value;
-  void *data;
-  
-  SortableEntry() {}
-  SortableEntry(const int t, const float v, void *d):type(t),
-																										 value(v),
-																										 data(d) {}
-	
-  friend bool operator<(const SortableEntry &a, const SortableEntry &b) {
-    return a.value < b.value;
-  }
-};
-
-
 class VspKdTreeInterior;
 
@@ -158,6 +133,6 @@
 #if USE_FIXEDPOINT_T
 #define FIXEDPOINT_ONE 0x7FFE
-												//			  mMaxT(0xFFFF)
-																			mMaxT(FIXEDPOINT_ONE)
+	// mMaxT(0xFFFF)
+		mMaxT(FIXEDPOINT_ONE)
 #else
 		mMaxT(1.0f)
@@ -166,7 +141,8 @@
 	
 	RayInfo(VssRay *r,
-										const float _min,
-										const float _max
-										):mRay(r) {
+			const float _min,
+			const float _max
+			):mRay(r) 
+	{
 		SetMinT(_min);
 		SetMaxT(_max);
@@ -174,14 +150,15 @@
 	
 	RayInfo(VssRay *r,
-										const short _min,
-										const float _max
-										):mRay(r), mMinT(_min) {
+			const short _min,
+			const float _max):mRay(r), mMinT(_min) 
+	{
 		SetMaxT(_max);
 	}
 	
 	RayInfo(VssRay *r,
-										const float _min,
-										const short _max
-										):mRay(r), mMaxT(_max) {
+			const float _min,
+			const short _max):
+	mRay(r), mMaxT(_max) 
+	{
 		SetMinT(_min);
 	}
@@ -223,23 +200,20 @@
 
 
-  int ComputeRayIntersection(const float axis,
-														 const float position,
-														 float &t
-														 ) const {
-		
+	int ComputeRayIntersection(const int axis, const float position, float &t) const 
+	{		
 		// intersect the ray with the plane
-    float denom = mRay->GetDir(axis);
+		float denom = mRay->GetDir(axis);
     
-    if (fabs(denom) < 1e-20)
-      //if (denom == 0.0f)
-      return (mRay->GetOrigin(axis) > position) ? 1 : -1;
+		if (fabs(denom) < 1e-20)
+			//if (denom == 0.0f)
+			return (mRay->GetOrigin(axis) > position) ? 1 : -1;
     
-    t = (position - mRay->GetOrigin(axis))/denom;
-
-    if (t < GetMinT())
-      return (denom > 0) ? 1 : -1;
-
-    if (t > GetMaxT())
-      return (denom > 0) ? -1 : 1;
+		t = (position - mRay->GetOrigin(axis))/denom;
+
+		if (t < GetMinT())
+			return (denom > 0) ? 1 : -1;
+
+		if (t > GetMaxT())
+			return (denom > 0) ? -1 : 1;
 
 		return 0;
@@ -250,7 +224,7 @@
 
 
-	typedef vector<RayInfo> RayInfoContainer;
-	
-  enum { EInterior, ELeaf };
+typedef vector<RayInfo> RayInfoContainer;
+
+enum {EInterior, ELeaf};
 
   /////////////////////////////////
@@ -294,6 +268,5 @@
 // KD-tree node - interior node
 // --------------------------------------------------------------
-class VspKdTreeInterior :
-  public VspKdTreeNode
+class VspKdTreeInterior: public VspKdTreeNode
 {
 public:
@@ -340,30 +313,27 @@
   virtual int Type() const  { return EInterior; }
   
-  virtual ~VspKdTreeInterior() {
-    if (back)
-      delete back;
-    if (front)
-      delete front;
-  }
-  
-  virtual void Print(ostream &s) const {
-    if (axis == 0)
-      s<<"x ";
-    else
-      if (axis == 1)
-	s<<"y ";
-      else
-	s<<"z ";
-    s<<position<<" ";
-    back->Print(s);
-    front->Print(s);
-  }
-
-  
-	
-  int ComputeRayIntersection(const RayInfo &rayData,
-														 float &t
-														 ) {
-		return rayData.ComputeRayIntersection(axis, position, t);
+  virtual ~VspKdTreeInterior()
+  {
+	  DEL_PTR(back);
+	  DEL_PTR(front);
+  }
+  
+  virtual void Print(ostream &s) const 
+  {
+	  if (axis == 0)
+		  s << "x ";
+	  else
+		  if (axis == 1)
+			  s << "y ";
+		  else
+			  s << "z ";
+	  s << position << " ";
+	  back->Print(s);
+	  front->Print(s);
+  }
+	
+  int ComputeRayIntersection(const RayInfo &rayData, float &t) 
+  {
+	  return rayData.ComputeRayIntersection(axis, position, t);
   }
 
@@ -465,4 +435,31 @@
 class VspKdTree
 {
+	// --------------------------------------------------------------
+	// For sorting rays
+	// -------------------------------------------------------------
+	struct SortableEntry
+	{
+		enum EType 
+		{
+			ERayMin,
+			ERayMax
+		};
+
+		int type;
+		float value;
+		void *data;
+  
+		SortableEntry() {}
+		SortableEntry(const int t, const float v, void *d):type(t),
+					  value(v), data(d) 
+		{
+		}
+		
+		friend bool operator<(const SortableEntry &a, const SortableEntry &b) 
+		{
+			return a.value < b.value;
+		}
+	};
+
 	struct TraversalData
 	{  
Index: trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.cpp	(revision 410)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.cpp	(revision 411)
@@ -9,5 +9,5 @@
 #include "RenderSimulator.h"
 
-SamplingPreprocessor::SamplingPreprocessor(): mPass(0), mSampleRays(NULL)
+SamplingPreprocessor::SamplingPreprocessor(): mPass(0)
 {
   // this should increase coherence of the samples
@@ -15,4 +15,6 @@
   environment->GetIntValue("Sampling.totalSamples", mTotalSamples);
   environment->GetIntValue("BspTree.Construction.samples", mBspConstructionSamples);
+  environment->GetIntValue("VspTree.Construction.samples", mVspConstructionSamples);
+
   environment->GetIntValue("ViewCells.PostProcessing.samples", mPostProcessSamples);
   environment->GetIntValue("BspTree.Visualization.samples", mVisualizationSamples);
@@ -25,4 +27,5 @@
 {
 	CLEAR_CONTAINER(mSampleRays);
+	CLEAR_CONTAINER(mVspSampleRays);
 }
 
@@ -198,15 +201,14 @@
 		}
 	}
-	else
-		{
-			if (ray.kdLeaves.size()) {
-				Intersectable *terminator =
-					ray.intersections.size() ? ray.intersections[0].mObject: NULL;
-
-				sampleContributions += AddNodeSamples(ray,
-																							object,
-																							terminator);
-			}
-		}
+	else {
+		if (ray.kdLeaves.size()) {
+			Intersectable *terminator =
+				ray.intersections.size() ? ray.intersections[0].mObject: NULL;
+
+			sampleContributions += AddNodeSamples(ray,
+																						object,
+																						terminator);
+		}
+	}
 	
 	return sampleContributions;
@@ -482,12 +484,12 @@
 						//mVspKdTree->Construct(mSampleRays, mBoundingBox);
 					}
-					/*else if (ViewCell::sHierarchy == ViewCell::VSPKD)
+					else if (ViewCell::sHierarchy == ViewCell::VSP)
 					{
-						ProcessVspKdViewCells(ray,
-											  reverseSample ? NULL : object,
-											  faceIndex,
-											  passContributingSamples,
-											  passSampleContributions);
-					}*/
+						ProcessVspViewCells(ray,
+											reverseSample ? NULL : object,
+											faceIndex,
+											passContributingSamples,
+											passSampleContributions);
+					}
 				}
 			} else {
@@ -709,4 +711,47 @@
 }
 
+
+void SamplingPreprocessor::ProcessVspViewCells(const Ray &ray,
+                                               Intersectable *object,
+											   const int faceIndex,
+											   int &contributingSamples,
+											   int &sampleContributions)
+{
+	// save rays for bsp tree construction
+	if (!mVspKdTree)
+	{
+		if ((int)mVspSampleRays.size() < mVspConstructionSamples)
+		{
+			MeshInstance *mi = dynamic_cast<MeshInstance *>(object);
+			
+			VssRay *sRay = new VssRay(ray);
+			mVspSampleRays.push_back(sRay);
+		
+			// also add origin to sample
+			sRay->mOriginObject = object;
+		}
+		else
+		{
+			// construct VSP tree using the collected samples
+			cout << "building VSP tree from " << (int)mVspSampleRays.size() << " samples " << endl;
+			mVspKdTree->Construct(mVspSampleRays);
+		
+			// add contributions of saved samples to PVS
+			//contributingSamples += mBspTree->GetStat().contributingSamples;
+			//sampleContributions += mBspTree->GetStat().sampleContributions;
+
+			// throw away samples because BSP leaves not stored in order 
+			// Need ordered rays for post processing => collect new rays
+			//CLEAR_CONTAINER(mVspSampleRays);
+		}
+	}
+	// save rays for post processing
+	/*else if (((int)mVspSampleRays.size() < mPostProcessSamples) ||
+			 ((int)mVspSampleRays.size() < mVisualizationSamples))
+	{
+		mVspSampleRays.push_back(new Ray(ray));
+	}*/
+}
+
 void SamplingPreprocessor::ProcessBspViewCells(const Ray &ray,
                                                Intersectable *object,
