Index: /trunk/VUT/GtpVisibilityPreprocessor/src/Makefile
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/Makefile	(revision 401)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/Makefile	(revision 427)
@@ -1,5 +1,5 @@
 #############################################################################
 # Makefile for building: preprocessor
-# Generated by qmake (1.07a) (Qt 3.3.2) on: Wed Nov 09 22:44:25 2005
+# Generated by qmake (1.07a) (Qt 3.3.2) on: Tue Nov 22 12:10:40 2005
 # Project:  preprocessor.pro
 # Template: app
@@ -74,5 +74,8 @@
 		VssRay.cpp \
 		VssTree.cpp \
-		VssPreprocessor.cpp
+		VssPreprocessor.cpp \
+		RenderSimulator.cpp \
+		VspKdTree.cpp \
+		RayInfo.cpp
 OBJECTS =	Preprocessor.obj \
 		SamplingPreprocessor.obj \
@@ -107,5 +110,8 @@
 		VssRay.obj \
 		VssTree.obj \
-		VssPreprocessor.obj
+		VssPreprocessor.obj \
+		RenderSimulator.obj \
+		VspKdTree.obj \
+		RayInfo.obj
 FORMS =	
 UICDECLS =	
@@ -202,4 +208,7 @@
 	-$(DEL_FILE) VssTree.obj
 	-$(DEL_FILE) VssPreprocessor.obj
+	-$(DEL_FILE) RenderSimulator.obj
+	-$(DEL_FILE) VspKdTree.obj
+	-$(DEL_FILE) RayInfo.obj
 
 
@@ -220,21 +229,25 @@
 		ViewCell.h \
 		Environment.h \
-		Containers.h \
-		AxisAlignedBox3.h \
-		Rectangle3.h \
-		Matrix4x4.h \
-		Vector3.h \
-		Plane3.h \
-		common.h \
-		Material.h \
-		VssRay.h \
+		RenderSimulator.h \
+		Containers.h \
+		AxisAlignedBox3.h \
+		Rectangle3.h \
+		Matrix4x4.h \
+		Vector3.h \
+		Plane3.h \
+		common.h \
+		Material.h \
+		VssRay.h \
+		Ray.h \
 		Parser.h \
 		Mesh.h \
 		KdTree.h \
 		ViewCellBsp.h \
-		Intersectable.h \
-		Pvs.h \
-		Ray.h \
-		Polygon3.h \
+		VspKdTree.h \
+		Intersectable.h \
+		Pvs.h \
+		Polygon3.h \
+		Statistics.h \
+		RayInfo.h \
 		
 
@@ -248,4 +261,5 @@
 		Polygon3.h \
 		ViewCell.h \
+		RenderSimulator.h \
 		Containers.h \
 		AxisAlignedBox3.h \
@@ -258,10 +272,13 @@
 		Pvs.h \
 		Preprocessor.h \
-		Mesh.h \
-		ViewCellBsp.h \
-		Intersectable.h \
-		Material.h \
-		Exporter.h \
-		VssRay.h \
+		VssRay.h \
+		Mesh.h \
+		ViewCellBsp.h \
+		VspKdTree.h \
+		Intersectable.h \
+		Material.h \
+		Statistics.h \
+		RayInfo.h \
+		Exporter.h \
 		
 
@@ -274,15 +291,19 @@
 		ViewCellBsp.h \
 		ViewCell.h \
-		Intersectable.h \
-		Plane3.h \
-		Matrix4x4.h \
-		AxisAlignedBox3.h \
-		Material.h \
-		Pvs.h \
-		Rectangle3.h \
-		Vector3.h \
-		common.h \
-		Ray.h \
-		Polygon3.h \
+		VspKdTree.h \
+		Intersectable.h \
+		Plane3.h \
+		Matrix4x4.h \
+		AxisAlignedBox3.h \
+		Material.h \
+		Pvs.h \
+		Rectangle3.h \
+		Vector3.h \
+		common.h \
+		Ray.h \
+		Polygon3.h \
+		Statistics.h \
+		VssRay.h \
+		RayInfo.h \
 		
 
@@ -347,15 +368,18 @@
 		Polygon3.h \
 		VssRay.h \
-		Containers.h \
-		AxisAlignedBox3.h \
-		Rectangle3.h \
-		Matrix4x4.h \
-		Vector3.h \
-		Plane3.h \
-		Exporter.h \
-		Material.h \
-		Intersectable.h \
-		Pvs.h \
-		Ray.h \
+		VspKdTree.h \
+		Containers.h \
+		AxisAlignedBox3.h \
+		Rectangle3.h \
+		Matrix4x4.h \
+		Vector3.h \
+		Plane3.h \
+		Exporter.h \
+		Material.h \
+		Ray.h \
+		Intersectable.h \
+		Pvs.h \
+		Statistics.h \
+		RayInfo.h \
 		
 
@@ -374,4 +398,5 @@
 		VssRay.h \
 		Material.h \
+		Ray.h \
 		Pvs.h \
 		
@@ -434,20 +459,23 @@
 		SceneGraph.h \
 		Preprocessor.h \
-		Containers.h \
-		Mesh.h \
-		KdTree.h \
-		ViewCellBsp.h \
-		Intersectable.h \
-		Plane3.h \
-		Matrix4x4.h \
-		AxisAlignedBox3.h \
-		Material.h \
-		Pvs.h \
-		Rectangle3.h \
-		Vector3.h \
-		common.h \
-		Ray.h \
-		Polygon3.h \
-		VssRay.h \
+		VssRay.h \
+		Containers.h \
+		Mesh.h \
+		KdTree.h \
+		ViewCellBsp.h \
+		VspKdTree.h \
+		Intersectable.h \
+		Plane3.h \
+		Matrix4x4.h \
+		AxisAlignedBox3.h \
+		Material.h \
+		Pvs.h \
+		Rectangle3.h \
+		Vector3.h \
+		common.h \
+		Ray.h \
+		Polygon3.h \
+		Statistics.h \
+		RayInfo.h \
 		
 
@@ -476,5 +504,7 @@
 		Material.h \
 		Vector3.h \
-		common.h \
+		Ray.h \
+		common.h \
+		Matrix4x4.h \
 		
 
@@ -595,4 +625,5 @@
 		Vector3.h \
 		common.h \
+		Statistics.h \
 		
 
@@ -628,4 +659,5 @@
 		Vector3.h \
 		Containers.h \
+		Statistics.h \
 		Intersectable.h \
 		Matrix4x4.h \
@@ -644,7 +676,8 @@
 		AxisAlignedBox3.h \
 		Vector3.h \
-		common.h \
-		Rectangle3.h \
-		Matrix4x4.h \
+		Ray.h \
+		common.h \
+		Matrix4x4.h \
+		Rectangle3.h \
 		Plane3.h \
 		
@@ -660,6 +693,6 @@
 		Vector3.h \
 		common.h \
-		Rectangle3.h \
-		Matrix4x4.h \
+		Matrix4x4.h \
+		Rectangle3.h \
 		Plane3.h \
 		Pvs.h \
@@ -689,8 +722,57 @@
 		Mesh.h \
 		ViewCellBsp.h \
-		Intersectable.h \
-		Material.h \
-		Exporter.h \
-		Statistics.h \
+		VspKdTree.h \
+		Intersectable.h \
+		Material.h \
+		Statistics.h \
+		RayInfo.h \
+		Exporter.h \
+		
+
+RenderSimulator.obj: RenderSimulator.cpp  \
+		RenderSimulator.h \
+		KdTree.h \
+		ViewCellBsp.h \
+		ViewCell.h \
+		common.h \
+		Statistics.h \
+		Containers.h \
+		AxisAlignedBox3.h \
+		Ray.h \
+		Pvs.h \
+		Rectangle3.h \
+		Matrix4x4.h \
+		Vector3.h \
+		Plane3.h \
+		Mesh.h \
+		Polygon3.h \
+		Intersectable.h \
+		Material.h \
+		
+
+VspKdTree.obj: VspKdTree.cpp  \
+		VspKdTree.h \
+		Environment.h \
+		VssRay.h \
+		Intersectable.h \
+		Ray.h \
+		RayInfo.h \
+		AxisAlignedBox3.h \
+		Statistics.h \
+		Vector3.h \
+		common.h \
+		Matrix4x4.h \
+		Rectangle3.h \
+		Plane3.h \
+		Pvs.h \
+		
+
+RayInfo.obj: RayInfo.cpp  \
+		RayInfo.h \
+		Ray.h \
+		VssRay.h \
+		Matrix4x4.h \
+		Vector3.h \
+		common.h \
 		
 
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/VssTree.h
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/VssTree.h	(revision 403)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/VssTree.h	(revision 427)
@@ -60,5 +60,6 @@
 	// max depth nodes
   int minSizeNodes;
-	
+  int maxCostRatioNodes;
+
   // max number of rays per node
   int maxRayRefs;
@@ -91,4 +92,5 @@
 		maxRayContribNodes = 0;
 		minSizeNodes = 0;
+		maxCostRatioNodes = 0;
   }
 
@@ -140,5 +142,5 @@
 public:
 
-#define USE_FIXEDPOINT_T 1
+#define USE_FIXEDPOINT_T 0
 
 struct RayInfo
@@ -159,6 +161,6 @@
 #if USE_FIXEDPOINT_T
 #define FIXEDPOINT_ONE 0x7FFE
-												//			  mMaxT(0xFFFF)
-																			mMaxT(FIXEDPOINT_ONE)
+										 //			  mMaxT(0xFFFF)
+										 mMaxT(FIXEDPOINT_ONE)
 #else
 		mMaxT(1.0f)
@@ -167,7 +169,7 @@
 	
 	RayInfo(VssRay *r,
-										const float _min,
-										const float _max
-										):mRay(r) {
+					const float _min,
+					const float _max
+					):mRay(r) {
 		SetMinT(_min);
 		SetMaxT(_max);
@@ -175,7 +177,7 @@
 	
 	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);
 	}
@@ -187,4 +189,28 @@
 		SetMinT(_min);
 	}
+
+	enum {
+				SOURCE_RAY = 0,
+				TERMINATION_RAY,
+				PASSING_RAY,
+				CONTAINED_RAY
+	};
+	
+	int GetRayClass() const {
+		
+		bool startsBefore = GetMinT() > 0.0f;
+		bool terminatesAfter = GetMaxT() < 1.0f;
+		
+		if (startsBefore && terminatesAfter)
+			return PASSING_RAY;
+
+		if (!startsBefore && !terminatesAfter)
+			return CONTAINED_RAY;
+		
+		if (!startsBefore)
+			return SOURCE_RAY;
+		
+		return TERMINATION_RAY;
+	}
 	
 	friend bool operator<(const RayInfo &a, const RayInfo &b) {
@@ -224,5 +250,5 @@
 
 
-  int ComputeRayIntersection(const float axis,
+  int ComputeRayIntersection(const int axis,
 														 const float position,
 														 float &t
@@ -433,4 +459,25 @@
 	}
 
+	// comparator for the 
+	struct less_contribution : public
+	binary_function<const VssTreeLeaf *, const VssTreeLeaf *, bool> {
+		
+		bool operator()(const VssTreeLeaf * a, const VssTreeLeaf *b) {
+			return a->GetAvgRayContribution() < b->GetAvgRayContribution();
+		}
+	};
+
+	struct greater_contribution : public
+	binary_function<const VssTreeLeaf *, const VssTreeLeaf *, bool> {
+		
+		bool operator()(const VssTreeLeaf * a, const VssTreeLeaf *b) {
+			return a->GetAvgRayContribution() > b->GetAvgRayContribution();
+		}
+	};
+	
+	friend bool GreaterContribution(const VssTreeLeaf * a, const VssTreeLeaf *b) {
+		return a->GetAvgRayContribution() > b->GetAvgRayContribution();
+	}
+	
 };
 
@@ -762,6 +809,5 @@
   VssTreeNode *
   SubdivideLeaf(
-								VssTreeLeaf *leaf,
-								const float SAThreshold
+								VssTreeLeaf *leaf
 								);
 
@@ -772,7 +818,9 @@
 						);
 
-  void
-  AddRay(VssRay *ray);
-	
+	//  void
+	//  AddRay(VssRay *ray);
+	void
+	AddRay(VssTreeNode::RayInfo &info);
+
   void
   TraverseInternalNode(
@@ -803,7 +851,28 @@
 							 SimpleRayContainer &rays);
 
+	int
+	GenerateRays(const int numberOfRays,
+							 const int numberOfLeaves,
+							 SimpleRayContainer &rays);
+		
 	float
 	GetAvgPvsSize();
 
+	int
+	UpdateSubdivision();
+
+	bool
+	TerminationCriteriaSatisfied(VssTreeLeaf *leaf);
+
+	void
+	CollectLeaves(vector<VssTreeLeaf *> &leaves);
+
+	bool
+	ClipRay(
+					VssTreeNode::RayInfo &rayInfo,
+					const AxisAlignedBox3 &box
+					);
+
+	
 };
 
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/Environment.cpp
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/Environment.cpp	(revision 426)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/Environment.cpp	(revision 427)
@@ -1160,5 +1160,10 @@
 								 "1000000");
 	
-  RegisterOption("VssPreprocessor.samplesPerPass",
+  RegisterOption("VssPreprocessor.vssSamplesPerPass",
+								 optInt,
+								 "-vss_samples_per_pass=",
+								 "1000");
+
+	  RegisterOption("VssPreprocessor.samplesPerPass",
 								 optInt,
 								 "-samples_per_pass=",
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/VssTree.cpp
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/VssTree.cpp	(revision 403)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/VssTree.cpp	(revision 427)
@@ -184,4 +184,7 @@
 	app << "#N_PMAXRAYCONTRIBLEAVES  ( Percentage of leaves with maximal ray contribution )\n"<<
     maxRayContribNodes*100/(double)Leaves()<<endl;
+
+	app << "#N_PMAXCOSTRATIOLEAVES  ( Percentage of leaves with max cost ratio )\n"<<
+    maxCostRatioNodes*100/(double)Leaves()<<endl;
 
   app << "#N_ADDED_RAYREFS  (Number of dynamically added ray references )\n"<<
@@ -230,4 +233,30 @@
 }
 
+bool
+VssTree::ClipRay(
+								 VssTreeNode::RayInfo &rayInfo,
+								 const AxisAlignedBox3 &box
+								 )
+{
+	float tmin, tmax;
+	static Ray ray;
+	ray.Init(rayInfo.mRay->GetOrigin(), rayInfo.mRay->GetDir(), Ray::LINE_SEGMENT);
+	box.ComputeMinMaxT(ray, &tmin, &tmax);
+	if (tmin >= tmax)
+		return false;
+	
+	if (tmin > 0.0f)
+		rayInfo.SetMinT(tmin);
+
+	if (tmax < 1.0f)
+		rayInfo.SetMaxT(tmax);
+	
+	//  	vssRay->SetupEndPoints(
+	//  												 origin,
+	//  												 termination
+	//  												 );
+	return true;
+}
+
 
 void
@@ -256,6 +285,11 @@
       ri != rays.end();
       ri++) {
-    leaf->AddRay(VssTreeNode::RayInfo(*ri));
-
+
+		VssTreeNode::RayInfo info(*ri);
+		if (forcedBoundingBox)
+			if (!ClipRay(info, *forcedBoundingBox))
+				continue;
+		leaf->AddRay(info);
+		
     bbox.Include((*ri)->GetOrigin());
     bbox.Include((*ri)->GetTermination());
@@ -271,7 +305,7 @@
 	
 	
-	if ( forcedBoundingBox )
+	if ( forcedBoundingBox ) 
 		bbox = *forcedBoundingBox;
-
+	
 	cout<<"Bbox = "<<bbox<<endl;
 	cout<<"Dirr Bbox = "<<dirBBox<<endl;
@@ -296,4 +330,62 @@
 }
 
+int
+VssTree::UpdateSubdivision()
+{
+	priority_queue<TraversalData> tStack;
+  //  stack<TraversalData> tStack;
+  
+	tStack.push(TraversalData(root, bbox, 0));
+	
+  AxisAlignedBox3 backBox;
+  AxisAlignedBox3 frontBox;
+
+	maxMemory = maxTotalMemory;
+	int subdivided = 0;
+	int lastMem = 0;
+  while (!tStack.empty()) {
+		
+		float mem = GetMemUsage();
+		
+		if ( lastMem/10 != ((int)mem)/10) {
+			cout<<mem<<" MB"<<endl;
+		}
+		lastMem = (int)mem;
+		
+		if (  mem > maxMemory ) {
+      // count statistics on unprocessed leafs
+      while (!tStack.empty()) {
+				//				EvaluateLeafStats(tStack.top());
+				tStack.pop();
+      }
+      break;
+    }
+    
+    TraversalData data = tStack.top();
+    tStack.pop();
+
+		if (data.node->IsLeaf()) {
+			VssTreeNode *node = SubdivideNode((VssTreeLeaf *) data.node,
+																				data.bbox,
+																				backBox,
+																				frontBox
+																				);
+			if (!node->IsLeaf()) {
+				subdivided++;
+				VssTreeInterior *interior = (VssTreeInterior *) node;
+				// push the children on the stack
+				tStack.push(TraversalData(interior->back, backBox, data.depth+1));
+				tStack.push(TraversalData(interior->front, frontBox, data.depth+1));
+			} else {
+				//      EvaluateLeafStats(data);
+			}
+		} else {
+			VssTreeInterior *interior = (VssTreeInterior *) data.node;
+			tStack.push(TraversalData(interior->back, GetBBox(interior->back), data.depth+1));
+			tStack.push(TraversalData(interior->front, GetBBox(interior->front), data.depth+1));
+		}
+  }
+	return subdivided;
+}
 
 
@@ -403,4 +495,5 @@
 	if (costRatio > termMaxCostRatio) {
 		//		cout<<"Too big cost ratio "<<costRatio<<endl;
+		stat.maxCostRatioNodes++;
 		return -1;
 	}
@@ -436,10 +529,10 @@
 	pvsBack = 0;
 
-	float newCost;
 
 	Intersectable::NewMail(3);
-	
+	bool costImportance = true;
 	// eval pvs size
 	int pvsSize = leaf->GetPvsSize();
+	float ratio;
 
 	Intersectable::NewMail(3);
@@ -464,5 +557,5 @@
 				AddObject2Pvs((*ri).mRay->mTerminationObject, side, pvsBack, pvsFront);
       }
-		
+
 		AxisAlignedBox3 box = GetBBox(leaf);
 		
@@ -471,8 +564,29 @@
 		float sizeBox = maxBox - minBox;
 		
-		//		float sum = raysBack*(position - minBox) + raysFront*(maxBox - position);
-		float sum = pvsBack*(position - minBox) + pvsFront*(maxBox - position);
-
-		newCost = ct_div_ci + sum/sizeBox;
+		if (!costImportance) {
+			
+			//		float sum = raysBack*(position - minBox) + raysFront*(maxBox - position);
+			float sum = pvsBack*(position - minBox) + pvsFront*(maxBox - position);
+			float newCost = ct_div_ci + sum/sizeBox;
+			float oldCost = pvsSize;
+			ratio = newCost/oldCost;
+		} else {
+			// importance based cost
+#if 0
+			float newContrib =
+				((position - minBox)*sqr(pvsBack/(raysBack + Limits::Small)) +
+				 (maxBox - position)*sqr(pvsFront/(raysFront + Limits::Small)))/sizeBox;
+
+			//			float newContrib =
+			//				sqr(pvsBack/(raysBack + Limits::Small)) +
+			//				sqr(pvsFront/(raysFront + Limits::Small));
+			float oldContrib = sqr(leaf->GetAvgRayContribution());
+			ratio = oldContrib/newContrib;
+#else
+			float newCost = raysBack*pvsBack  + raysFront*pvsFront;
+			float oldCost = leaf->rays.size()*pvsSize;
+			ratio = newCost/oldCost;
+#endif
+		}
 		
   } else {
@@ -499,5 +613,5 @@
 				//				(*ri).mRay->mSide = side;
 				AddObject2Pvs((*ri).mRay->mTerminationObject, side, pvsBack, pvsFront);
-
+				
       }
 		
@@ -507,17 +621,33 @@
 		float maxBox = box.Max(axis-3);
 		float sizeBox = maxBox - minBox;
-		
-		//		float sum = raysBack*(position - minBox) + raysFront*(maxBox - position);
-		float sum =
-			pvsBack*(position - minBox) +
-			pvsFront*(maxBox - position);
-		//		float sum = pvsBack + pvsFront;
-		newCost = ct_div_ci + sum/sizeBox;
-  }
-
+
+		if (!costImportance) {
+			
+			float directionalPenalty = 1.0f;
+			float sum =
+				(pvsBack*(position - minBox) +
+				 pvsFront*(maxBox - position))*directionalPenalty;
+			float newCost = ct_div_ci + sum/sizeBox;
+			float oldCost = pvsSize;
+			ratio = newCost/oldCost;
+		} else {
+#if 0
+			float directionalPenalty = 0.7f;
+			// importance based cost
+			float newContrib =
+				directionalPenalty*((position - minBox)*sqr(pvsBack/(raysBack + Limits::Small)) +
+														(maxBox - position)*sqr(pvsFront/(raysFront + Limits::Small)))/sizeBox;
+			float oldContrib = sqr(leaf->GetAvgRayContribution());
+			ratio = oldContrib/newContrib;
+#else
+			float newCost = raysBack*pvsBack  + raysFront*pvsFront;
+			float oldCost = leaf->rays.size()*pvsSize;
+			ratio = newCost/oldCost;
+#endif
+		}
+	}
 	//	cout<<axis<<" "<<pvsSize<<" "<<pvsBack<<" "<<pvsFront<<endl;
 	//  float oldCost = leaf->rays.size();
-	float oldCost = pvsSize;
-  float ratio = newCost/oldCost;
+
 	//	cout<<"ratio="<<ratio<<endl;
 	return ratio;
@@ -534,5 +664,5 @@
 															int &pvsFront
 															)
-{
+	{
 	int nRaysBack[6], nRaysFront[6];
 	int nPvsBack[6], nPvsFront[6];
@@ -547,7 +677,11 @@
 	int dAxis = dBox.Size().DrivingAxis() + 3;
 
-	bool onlyDrivingAxis = true; 
-
-	for (axis = 0; axis < 6; axis++) {
+	bool onlyDrivingAxis = false; 
+
+	float dirSplitBoxSize = 0.01f;
+	bool allowDirSplit = Magnitude(sBox.Size())*dirSplitBoxSize < Magnitude(bbox.Size());
+		
+
+	for (axis = 0; axis < 5; axis++) {
 		if (!onlyDrivingAxis || axis == sAxis || axis == dAxis) {
 			if (axis < 3)
@@ -765,4 +899,13 @@
 }
 
+bool
+VssTree::TerminationCriteriaSatisfied(VssTreeLeaf *leaf)
+{
+	return ( (leaf->GetPvsSize() < termMinPvs) ||
+					(leaf->rays.size() < termMinRays) ||
+					//			 (leaf->GetAvgRayContribution() > termMaxRayContribution ) ||
+					(leaf->depth >= termMaxDepth) ||
+					SqrMagnitude(GetBBox(leaf).Size()) <= termMinSize );
+}
 
 
@@ -776,10 +919,5 @@
 {
   
-  if ( (leaf->GetPvsSize() < termMinPvs) ||
-			 (leaf->rays.size() < termMinRays) ||
-			 //			 (leaf->GetAvgRayContribution() > termMaxRayContribution ) ||
-       (leaf->depth >= termMaxDepth) ||
-			 SqrMagnitude(box.Size()) <= termMinSize ) {
-
+	if (TerminationCriteriaSatisfied(leaf)) {
 #if 0
 		if (leaf->depth >= termMaxDepth) {
@@ -802,5 +940,6 @@
   // select subdivision axis
   int axis = SelectPlane( leaf, box, position, raysBack, raysFront, pvsBack, pvsFront);
-
+	//	cout<<axis<<" ";
+	
 	//	cout<<"rays back="<<raysBack<<" rays front="<<raysFront<<" pvs back="<<pvsBack<<" pvs front="<<
 	//		pvsFront<<endl;
@@ -966,10 +1105,9 @@
 VssTreeNode *
 VssTree::SubdivideLeaf(
-											 VssTreeLeaf *leaf,
-											 const float sizeThreshold
+											 VssTreeLeaf *leaf
 											 )
 {
   VssTreeNode *node = leaf;
-
+	
   AxisAlignedBox3 leafBBox = GetBBox(leaf);
 
@@ -978,8 +1116,5 @@
 	
   // check if we should perform a dynamic subdivision of the leaf
-  if (
-			//      leaf->rays.size() > (unsigned)termMinCost &&
-			(leaf->GetPvsSize() >= termMinPvs) &&
-      SqrMagnitude(leafBBox.Size()) > sizeThreshold) {
+	if (!TerminationCriteriaSatisfied(leaf)) {
     
 		// memory check and realese...
@@ -998,4 +1133,5 @@
 										);
   }
+	
   return node;
 }
@@ -1036,8 +1172,8 @@
       ri != add.end();
       ri++) {
-    AddRay(*ri);
-  }
-  
-
+		VssTreeNode::RayInfo info(*ri);
+		if (ClipRay(info, bbox))
+			AddRay(info);
+  }
 }
 
@@ -1128,10 +1264,10 @@
 
 void
-VssTree::AddRay(VssRay *ray)
+VssTree::AddRay(VssTreeNode::RayInfo &info)
 {
 
   stack<RayTraversalData> tstack;
   
-  tstack.push(RayTraversalData(root, VssTreeNode::RayInfo(ray)));
+  tstack.push(RayTraversalData(root, info));
   
   RayTraversalData data;
@@ -1461,4 +1597,69 @@
 }
 
+void
+VssTree::CollectLeaves(vector<VssTreeLeaf *> &leaves)
+{
+	stack<VssTreeNode *> tstack;
+  tstack.push(root);
+	
+  while (!tstack.empty()) {
+    VssTreeNode *node = tstack.top();
+    tstack.pop();
+		
+    if (node->IsLeaf()) {
+			VssTreeLeaf *leaf = (VssTreeLeaf *)node;
+			leaves.push_back(leaf);
+		} else {
+			VssTreeInterior *in = (VssTreeInterior *)node;
+			// both nodes for directional splits
+			tstack.push(in->front);
+			tstack.push(in->back);
+		}
+	}
+}
+
+int
+VssTree::GenerateRays(const int numberOfRays,
+											const int numberOfLeaves,
+											SimpleRayContainer &rays)
+{
+
+	vector<VssTreeLeaf *> leaves;
+	
+	CollectLeaves(leaves);
+	
+	sort(leaves.begin(),
+			 leaves.end(),
+			 GreaterContribution);
+			 
+
+	float sumContrib = 0.0;
+	int i;
+	for (i=0; i < numberOfLeaves; i++) {
+		float c = leaves[i]->GetAvgRayContribution();
+		sumContrib += c;
+		//		cout<<"ray contrib "<<i<<" : "<<c<<endl;
+	}
+
+	float avgContrib = sumContrib/numberOfLeaves;
+	float ratioPerLeaf = numberOfRays/(avgContrib*numberOfLeaves);
+	
+	for (i=0; i < numberOfLeaves; i++) {
+		VssTreeLeaf *leaf = leaves[i];
+		float c = leaf->GetAvgRayContribution();
+		int num = (c*ratioPerLeaf + 0.5);
+		//			cout<<num<<" ";
+		
+		for (int i=0; i < num; i++) {
+			Vector3 origin = GetBBox(leaf).GetRandomPoint();
+			Vector3 dirVector = GetDirBBox(leaf).GetRandomPoint();
+			Vector3 direction = Vector3(sin(dirVector.x), sin(dirVector.y), cos(dirVector.x));
+			//cout<<"dir vector.x="<<dirVector.x<<"direction'.x="<<atan2(direction.x, direction.y)<<endl;
+			rays.push_back(SimpleRay(origin, direction));
+		}
+	}
+	return rays.size();
+}
+
 
 float
@@ -1491,2 +1692,4 @@
 	return sumPvs/(float)leaves;
 }
+
+	
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/VssRay.h
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/VssRay.h	(revision 426)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/VssRay.h	(revision 427)
@@ -163,5 +163,13 @@
     mTermination += translation;
   }
-	
+
+	void SetupEndPoints(const Vector3 &origin,
+											const Vector3 &termination)
+	{
+		mOrigin = origin;
+		mTermination = termination;
+		Precompute();
+	}
+											
   bool HasPosDir(const int axis) const { return mFlags & (1<<axis); }
 
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/VssPreprocessor.cpp
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/VssPreprocessor.cpp	(revision 403)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/VssPreprocessor.cpp	(revision 427)
@@ -10,4 +10,9 @@
 #include "VssTree.h"
 
+
+bool useViewSpaceBox = true;
+bool use2dSampling = false;
+bool useViewspacePlane = false;
+
 VssPreprocessor::VssPreprocessor():
 	mPass(0),
@@ -18,4 +23,5 @@
   environment->GetIntValue("VssPreprocessor.initialSamples", mInitialSamples);
   environment->GetIntValue("VssPreprocessor.vssSamples", mVssSamples);
+  environment->GetIntValue("VssPreprocessor.vssSamplesPerPass", mVssSamplesPerPass);
 	environment->GetBoolValue("VssPreprocessor.useImportanceSampling", mUseImportanceSampling);
 	
@@ -49,4 +55,9 @@
 	static Ray ray;
 	AxisAlignedBox3 box = mKdTree->GetBox();
+
+	AxisAlignedBox3 sbox = box;
+	sbox.Enlarge(Vector3(-Limits::Small));
+	if (!sbox.IsInside(viewPoint))
+		return 0;
 	
 	SetupRay(ray, viewPoint, direction);
@@ -145,44 +156,161 @@
 
 Vector3
-VssPreprocessor::GetDirection(const Vector3 &viewpoint)
-{
-	int i = RandomValue(0, mObjects.size()-1);
-	Intersectable *object = mObjects[i];
-	Vector3 point, normal;
-	object->GetRandomSurfacePoint(point, normal);
+VssPreprocessor::GetDirection(const Vector3 &viewpoint,
+															AxisAlignedBox3 *viewSpaceBox
+															)
+{
+	Vector3 point;
+	if (!use2dSampling) {
+		Vector3 normal;
+		int i = RandomValue(0, mObjects.size()-1);
+		Intersectable *object = mObjects[i];
+		object->GetRandomSurfacePoint(point, normal);
+	} else {
+		AxisAlignedBox3 box;
+		
+		if (viewSpaceBox)
+			box =*viewSpaceBox;
+		else 
+			box = mKdTree->GetBox();
+		
+		point = box.GetRandomPoint();
+		point.y = viewpoint.y;
+	}
+	
 	return point - viewpoint;
 }
 
 int
-VssPreprocessor::RandomizedImportanceSampling(VssTree *vssTree,
-																							const int desiredSamples)
-{
-	float minRayContribution;
-	float maxRayContribution;
-	float avgRayContribution;
-
-	vssTree->GetRayContributionStatistics(minRayContribution,
-																				maxRayContribution,
-																				avgRayContribution);
-
-	cout<<
-		"#MIN_RAY_CONTRIB\n"<<minRayContribution<<endl<<
-		"#MAX_RAY_CONTRIB\n"<<maxRayContribution<<endl<<
-		"#AVG_RAY_CONTRIB\n"<<avgRayContribution<<endl;
-	
-	float p = desiredSamples/(float)(avgRayContribution*vssTree->stat.Leaves());
-	SimpleRayContainer rays;
-	int num = vssTree->GenerateRays(p, rays);
+VssPreprocessor::GenerateImportanceRays(VssTree *vssTree,
+																				const int desiredSamples,
+																				SimpleRayContainer &rays
+																				)
+{
+	int num;
+	if (0) {
+		float minRayContribution;
+		float maxRayContribution;
+		float avgRayContribution;
+		
+		vssTree->GetRayContributionStatistics(minRayContribution,
+																					maxRayContribution,
+																					avgRayContribution);
+		
+		cout<<
+			"#MIN_RAY_CONTRIB\n"<<minRayContribution<<endl<<
+			"#MAX_RAY_CONTRIB\n"<<maxRayContribution<<endl<<
+			"#AVG_RAY_CONTRIB\n"<<avgRayContribution<<endl;
+		
+		float p = desiredSamples/(float)(avgRayContribution*vssTree->stat.Leaves());
+		num = vssTree->GenerateRays(p, rays);
+	} else {
+		int leaves = vssTree->stat.Leaves()/2;
+		num = vssTree->GenerateRays(desiredSamples, leaves, rays);
+	}
+	
 	cout<<"Generated "<<num<<" rays."<<endl;
 	
-	VssRayContainer  vssRays;
-	
-	for (int i=0; i < rays.size(); i++)
-		CastRay(rays[i].mOrigin, rays[i].mDirection, vssRays);
-
-	vssTree->AddRays(vssRays);
 	return num;
 }
 
+
+bool
+VssPreprocessor::ExportRays(const char *filename,
+														const VssRayContainer &vssRays,
+														const int number
+														)
+{
+	cout<<"Exporting vss rays..."<<endl<<flush;
+	
+	float prob = number/(float)vssRays.size();
+
+
+	Exporter *exporter = NULL;
+	exporter = Exporter::GetExporter(filename);
+	//	exporter->SetWireframe();
+	//	exporter->ExportKdTree(*mKdTree);
+	exporter->SetFilled();
+	exporter->ExportScene(mSceneGraph->mRoot);
+	exporter->SetWireframe();
+
+	if (mViewSpaceBox) {
+		exporter->SetForcedMaterial(RgbColor(1,0,0));
+		exporter->ExportBox(*mViewSpaceBox);
+		exporter->ResetForcedMaterial();
+	}
+	
+	VssRayContainer rays;	for (int i=0; i < vssRays.size(); i++)
+		if (RandomValue(0,1) < prob)
+			rays.push_back(vssRays[i]);
+
+	exporter->ExportRays(rays, RgbColor(1, 0, 0));
+	
+	delete exporter;
+
+	cout<<"done."<<endl<<flush;
+
+	return true;
+}
+
+
+bool
+VssPreprocessor::ExportVssTreeLeaf(char *filename,
+																	 VssTree *tree,
+																	 VssTreeLeaf *leaf)
+{
+	Exporter *exporter = NULL;
+	exporter = Exporter::GetExporter(filename);
+	exporter->SetWireframe();
+	exporter->ExportKdTree(*mKdTree);
+	
+	if (mViewSpaceBox) {
+		exporter->SetForcedMaterial(RgbColor(1,0,0));
+		exporter->ExportBox(*mViewSpaceBox);
+		exporter->ResetForcedMaterial();
+	}
+	
+	exporter->SetForcedMaterial(RgbColor(0,0,1));
+	exporter->ExportBox(tree->GetBBox(leaf));
+	exporter->ResetForcedMaterial();
+	
+	VssRayContainer rays[4];
+	for (int i=0; i < leaf->rays.size(); i++) {
+		int k = leaf->rays[i].GetRayClass();
+		rays[k].push_back(leaf->rays[i].mRay);
+	}
+	
+	// SOURCE RAY
+	exporter->ExportRays(rays[0], RgbColor(1, 0, 0));
+	// TERMINATION RAY
+	exporter->ExportRays(rays[1], RgbColor(1, 1, 1));
+	// PASSING_RAY
+	exporter->ExportRays(rays[2], RgbColor(1, 1, 0));
+	// CONTAINED_RAY
+	exporter->ExportRays(rays[3], RgbColor(0, 0, 1));
+
+	delete exporter;
+	return true;
+}
+
+void
+VssPreprocessor::ExportVssTreeLeaves(VssTree *tree, const int number)
+{
+	vector<VssTreeLeaf *> leaves;
+	tree->CollectLeaves(leaves);
+
+	int num = 0;
+	int i;
+	float p = number / (float)leaves.size();
+	for (i=0; i < leaves.size(); i++) {
+		if (RandomValue(0,1) < p) {
+			char filename[64];
+			sprintf(filename, "vss-leaf-%04d.x3d", num);
+			ExportVssTreeLeaf(filename, tree, leaves[i]);
+			num++;
+		}
+		if (num >= number)
+			break;
+	}
+}
 
 bool
@@ -196,20 +324,30 @@
   int totalSamples = 0;
 
-	AxisAlignedBox3 *viewSpaceBox = NULL;
-
-	AxisAlignedBox3 box = mKdTree->GetBox();
-
-	
-	if (1)
-		box.Enlarge(box.Size()*-Vector3(0.45, 0.45, 0.45));
-	else {
+
+	AxisAlignedBox3 *box = new AxisAlignedBox3(mKdTree->GetBox());
+
+	if (!useViewspacePlane) {
+		float size = 0.01f;
+		float s = 0.5f - size;
+		float olds = Magnitude(box->Size());
+		box->Enlarge(box->Size()*Vector3(-s));
+		Vector3 translation = Vector3(-olds*0.1f, 0, 0);
+		box->SetMin(box->Min() + translation);
+		box->SetMax(box->Max() + translation);
+	} else {
+		
 		// sample city like heights
-		box.SetMin(1, box.Min(1) + box.Size(1)*0.1);
-		box.SetMax(1, box.Min(1) + box.Size(1)*0.2);
-	}
-	
-	bool useViewSpaceBox = false;
+		box->SetMin(1, box->Min(1) + box->Size(1)*0.1);
+		box->SetMax(1, box->Min(1) + box->Size(1)*0.2);
+	}
+
+	if (use2dSampling)
+		box->SetMax(1, box->Min(1));
+	
 	if (useViewSpaceBox)
-		viewSpaceBox = &box;
+		mViewSpaceBox = box;
+	else
+		mViewSpaceBox = NULL;
+		
 
 	VssTree *vssTree = NULL;
@@ -223,9 +361,9 @@
 		int sampleContributions;
 		
-		
-		for (int k=0; k < mSamplesPerPass; k++) {
+		int s = Min(mSamplesPerPass, mInitialSamples);
+		for (int k=0; k < s; k++) {
 			
-			Vector3 viewpoint = GetViewpoint(viewSpaceBox);
-			Vector3 direction = GetDirection(viewpoint);
+			Vector3 viewpoint = GetViewpoint(mViewSpaceBox);
+			Vector3 direction = GetDirection(viewpoint, mViewSpaceBox);
 			
 			sampleContributions = CastRay(viewpoint, direction, mVssRays);
@@ -271,29 +409,14 @@
 	cout << "#totalRayStackSize=" << mVssRays.size() << endl <<flush;
 
-	cout<<"Exporting vss rays..."<<endl<<flush;
-	
-	int exportRays = 10000;
-
-	if (exportRays) {
-		float prob = exportRays/(float)mVssRays.size();
-		
-		Exporter *exporter = NULL;
-		exporter = Exporter::GetExporter("vss-rays.x3d");
-		exporter->SetWireframe();
-		exporter->ExportKdTree(*mKdTree);
-		if (viewSpaceBox) {
-			exporter->SetForcedMaterial(RgbColor(1,0,0));
-			exporter->ExportBox(*viewSpaceBox);
-			exporter->ResetForcedMaterial();
-		}
-		VssRayContainer rays;
-		for (int i=0; i < mVssRays.size(); i++)
-			if (RandomValue(0,1) < prob)
-				rays.push_back(mVssRays[i]);
-		exporter->ExportRays(rays, RgbColor(1, 0, 0));
-
-		delete exporter;
-	}
-	cout<<"done."<<endl<<flush;
+	
+	//	int numExportRays = 10000;
+
+	int numExportRays = 0;
+
+	if (numExportRays) {
+		char filename[64];
+		sprintf(filename, "vss-rays-initial.x3d");
+		ExportRays(filename, mVssRays, numExportRays);
+	}
 
 
@@ -302,28 +425,58 @@
 	vssTree = new VssTree;
 	
-	vssTree->Construct(mVssRays, viewSpaceBox);
+	vssTree->Construct(mVssRays, mViewSpaceBox);
 
 	cout<<"VssTree root PVS size = "<<vssTree->GetRootPvsSize()<<endl;
 
+	ExportVssTreeLeaves(vssTree, 10);
 	
 	int samples = 0;
+	int pass = 0;
 	while (1) {
-		int num = mSamplesPerPass;
+		int num = mVssSamplesPerPass;
+		SimpleRayContainer rays;
+		VssRayContainer vssRays;
+		
 		if (!mUseImportanceSampling) {
-			VssRayContainer vssRays;
 			for (int j=0; j < num; j++) {
-				Vector3 viewpoint = GetViewpoint(viewSpaceBox);
-				Vector3 direction = GetDirection(viewpoint);
-				CastRay(viewpoint, direction, vssRays);
+				Vector3 viewpoint = GetViewpoint(mViewSpaceBox);
+				Vector3 direction = GetDirection(viewpoint, mViewSpaceBox);
+				rays.push_back(SimpleRay(viewpoint, direction));
 			}
-			vssTree->AddRays(vssRays);
 		} else {
-			num = RandomizedImportanceSampling(vssTree, num);
-		}
+			num = GenerateImportanceRays(vssTree, num, rays);
+		}
+		
+		
+		for (int i=0; i < rays.size(); i++)
+			CastRay(rays[i].mOrigin, rays[i].mDirection, vssRays);
+		
+		vssTree->AddRays(vssRays);
+		
+		if (1) {
+			int subdivided = vssTree->UpdateSubdivision();
+			cout<<"subdivided leafs = "<<subdivided<<endl;
+		}
+		
+		if (numExportRays) {
+			char filename[64];
+			if (mUseImportanceSampling)
+				sprintf(filename, "vss-rays-i%04d.x3d", pass);
+			else
+				sprintf(filename, "vss-rays-%04d.x3d", pass);
+			
+			ExportRays(filename, vssRays, numExportRays);
+		}
+
+		
 		samples+=num;
 		float pvs = vssTree->GetAvgPvsSize();
+		cout<<"*****************************\n";
 		cout<<samples<<" avgPVS ="<<pvs<<endl;
+		cout<<"VssTree root PVS size = "<<vssTree->GetRootPvsSize()<<endl;
+		cout<<"*****************************\n";
 		if (samples >= mVssSamples)
 			break;
+		pass++;
 	}
 
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/X3dExporter.cpp
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/X3dExporter.cpp	(revision 426)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/X3dExporter.cpp	(revision 427)
@@ -86,5 +86,5 @@
   stream<<"<Shape>"<<endl;
   stream<<"<Appearance>"<<endl;
-  stream<<"<Material ambientColor=\""<<color.r<<" "<<color.g<<" "<<color.b<<
+  stream<<"<Material diffuseColor=\""<<color.r<<" "<<color.g<<" "<<color.b<<
     "\" />"<<endl;
   stream<<"</Appearance>"<<endl;
@@ -135,5 +135,5 @@
   stream<<"<Shape>"<<endl;
   stream<<"<Appearance>"<<endl;
-  stream<<"<Material ambientColor=\""<<color.r<<" "<<color.g<<" "<<color.b<<
+  stream<<"<Material diffuseColor=\""<<color.r<<" "<<color.g<<" "<<color.b<<
     "\" />"<<endl;
   stream<<"</Appearance>"<<endl;
@@ -347,5 +347,5 @@
 
   if (mWireframe)
-    stream<<"<IndexedLineSet ccw=\"TRUE\" coordIndex=\""<<endl;
+    stream<<"<IndexedLineSet coordIndex=\""<<endl;
   else
     stream<<"<IndexedFaceSet ccw=\"TRUE\" coordIndex=\""<<endl;
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/default.env
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/default.env	(revision 410)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/default.env	(revision 427)
@@ -13,7 +13,7 @@
 #;../data/vienna/vienna-plane.x3d
 # filename ../data/vienna/viewcells-25-sel.x3d
-# filename ../data/atlanta/atlanta2.x3d
+filename ../data/atlanta/atlanta2.x3d
 # filename ../data/soda/soda.dat
-filename ../data/soda/soda5.dat
+# filename ../data/soda/soda5.dat
 }
 
@@ -25,6 +25,7 @@
 VssPreprocessor {
 	samplesPerPass  100000
-	initialSamples 200000
+	initialSamples 2000000
 	vssSamples 1000000
+	vssSamplesPerPass 100000
 	useImportanceSampling true
 }
@@ -34,12 +35,12 @@
 
 	maxDepth 	40
-	minPvs		1
-	minRays		50
-	minSize		0.00001
-	maxCostRatio	0.95
+	minPvs		3
+	minRays		100
+	minSize		0.001
+  maxCostRatio	0.98
 	maxRayContribution 0.05
 	
-	maxTotalMemory	400
-	maxStaticMemory	20
+	maxTotalMemory	200
+	maxStaticMemory	50
 
 	splitType regular
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/preprocessor.pro
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/preprocessor.pro	(revision 382)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/preprocessor.pro	(revision 427)
@@ -38,4 +38,5 @@
 Exporter.cpp Camera.cpp X3dParser.cpp MeshKdTree.cpp Pvs.cpp \
 MutualVisibility.cpp Triangle3.cpp Rectangle3.cpp Plane3.cpp Polygon3.cpp \
-ViewCell.cpp ViewCellBsp.cpp Halton.cpp VssRay.cpp VssTree.cpp VssPreprocessor.cpp
+ViewCell.cpp ViewCellBsp.cpp Halton.cpp VssRay.cpp VssTree.cpp VssPreprocessor.cpp \
+RenderSimulator.cpp VspKdTree.cpp RayInfo.cpp
 
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/VssPreprocessor.h
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/VssPreprocessor.h	(revision 403)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/VssPreprocessor.h	(revision 427)
@@ -8,4 +8,5 @@
 #include "VssRay.h"
 class VssTree;
+class VssTreeLeaf;
 
 /** Sampling based visibility preprocessing. The implementation is based on heuristical
@@ -15,7 +16,10 @@
 	int mPass;
   int mSamplesPerPass;
+  int mVssSamplesPerPass;
   int mInitialSamples;
   int mVssSamples;
 	bool mUseImportanceSampling;
+
+	AxisAlignedBox3 *mViewSpaceBox;
 
 	ofstream mStats;
@@ -35,5 +39,7 @@
 
 	Vector3
-	GetDirection(const Vector3 &viewpoint);
+	GetDirection(const Vector3 &viewpoint,
+							 AxisAlignedBox3 *viewSpaceBox
+							 );
 	
   void
@@ -57,7 +63,27 @@
 	virtual bool BuildBspTree() { return false; }
 
+
+	bool
+	ExportRays(const char *filename,
+						 const VssRayContainer &vssRays,
+						 const int number
+						 );
+
 	int
-	RandomizedImportanceSampling(VssTree *vssTree, const int desiredSamples);
+	GenerateImportanceRays(VssTree *vssTree,
+												 const int desiredSamples,
+												 SimpleRayContainer &rays
+												 );
 
+
+	bool
+	ExportVssTreeLeaf(char *filename,
+										VssTree *tree,
+										VssTreeLeaf *leaf);
+
+	void
+	ExportVssTreeLeaves(VssTree *tree, const int number);
+	
+	
 };
 
