Index: GTP/trunk/Lib/Vis/Preprocessing/src/GvsPreprocessor.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/GvsPreprocessor.cpp	(revision 2729)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/GvsPreprocessor.cpp	(revision 2730)
@@ -14,4 +14,7 @@
 #include "IntersectableWrapper.h"
 #include "Timer/PerfTimer.h"
+#include "Vector2.h"
+#include "RndGauss.h"
+
 
 
@@ -1326,13 +1329,9 @@
 	// export the preprocessed information to a file
 	if (0 && mExportVisibility)
-	{
 		ExportPreprocessedData(mVisibilityFileName);
-	}
 	
 	// compute the pixel error of this visibility solution
-	if (mEvaluatePixelError)
-	{
+	if (0 && mEvaluatePixelError)
 		ComputeRenderError();
-	}
 
 	return true;
@@ -1424,4 +1423,7 @@
 	mGvsStats.mGvsSamples = 0;
 
+	//renderer->mPvsStat.currentPass = 0;
+	mPass = 0;
+
 	int oldContribution = 0;
 	int passSamples = 0;
@@ -1507,4 +1509,8 @@
 			mGvsStats.mPassContribution = 0;
 			passSamples = 0;
+			
+			// compute the pixel error of this visibility solution
+			if (mEvaluatePixelError)
+				ComputeRenderError();
 		}
 	}
@@ -1627,7 +1633,7 @@
 	cout << "raw cast time          : " << rawCastTime << endl;
 
-	float randomRaysPerSec = mGvsStats.mRandomSamples / (1e6f * initialTime);
-	float gvsRaysPerSec = mGvsStats.mGvsSamples / (1e6f * gvsTime);
-	float rawRaysPerSec = mGvsStats.mPerViewCellSamples / (1e6f * rawCastTime);
+	double randomRaysPerSec = mGvsStats.mRandomSamples / (1e6 * initialTime);
+	double gvsRaysPerSec = mGvsStats.mGvsSamples / (1e6 * gvsTime);
+	double rawRaysPerSec = mGvsStats.mPerViewCellSamples / (1e6 * rawCastTime);
 
 	cout << "cast " << randomRaysPerSec << " M random rays/s: " << endl;
@@ -1804,3 +1810,90 @@
 }
 
-}
+
+void GvsPreprocessor::ComputeRenderError()
+{
+	// compute rendering error	
+	if (renderer && renderer->mPvsStatFrames) 
+	{
+		if (!mViewCellsManager->GetViewCellPointsList()->empty()) 
+		{
+			ViewCellPointsList *vcPoints = mViewCellsManager->GetViewCellPointsList();
+			ViewCellPointsList::const_iterator vit = vcPoints->begin(),	vit_end = vcPoints->end();
+
+			SimpleRayContainer viewPoints;
+
+			for (; vit != vit_end; ++ vit) 
+			{
+				ViewCellPoints *vp = *vit;
+				
+				SimpleRayContainer::const_iterator rit = vp->second.begin(), rit_end = vp->second.end();
+			
+				for (; rit!=rit_end; ++rit)
+				{
+					ViewCell *vc = mViewCellsManager->GetViewCell((*rit).mOrigin);
+					if (vc == mCurrentViewCell)
+						viewPoints.push_back(*rit);
+				}
+			}
+
+			renderer->mPvsErrorBuffer.clear();
+
+			if (viewPoints.size() != renderer->mPvsErrorBuffer.size()) 
+			{
+				renderer->mPvsErrorBuffer.resize(viewPoints.size());
+				renderer->ClearErrorBuffer();
+			}
+
+			cout << "evaluating list of " << viewPoints.size() << " pts" << endl;
+			renderer->EvalPvsStat(viewPoints);
+		} 
+		else
+		{
+			cout << "evaluating random points" << endl;
+			renderer->EvalPvsStat();
+		}
+
+		mStats <<
+			"#AvgPvsRenderError\n" <<renderer->mPvsStat.GetAvgError()<<endl<<
+			"#AvgPixelError\n" <<renderer->GetAvgPixelError()<<endl<<
+			"#MaxPixelError\n" <<renderer->GetMaxPixelError()<<endl<<
+			"#MaxPvsRenderError\n" <<renderer->mPvsStat.GetMaxError()<<endl<<
+			"#ErrorFreeFrames\n" <<renderer->mPvsStat.GetErrorFreeFrames()<<endl<<
+			"#AvgRenderPvs\n" <<renderer->mPvsStat.GetAvgPvs()<<endl;
+	}
+}
+
+
+SimpleRay GvsPreprocessor::GenerateJitteredSample(const SimpleRay &sray)
+{
+	// mutate the origin
+	Vector3 d = sray.mDirection;
+  
+	// Compute right handed coordinate system from direction
+	Vector3 U, V;
+	d.RightHandedBase(U, V);
+
+	float rr[2];
+
+	rr[0] = RandomValue(0, 1);
+	rr[1] = RandomValue(0, 1);
+
+	Vector2 vr2(rr[0], rr[1]);
+	Vector2 gaussvec2;
+
+	const float sigma = 0.2f;
+
+	GaussianOn2D(vr2, sigma, // input
+		         gaussvec2); // output
+	
+	Vector3 shift = gaussvec2.xx * U + gaussvec2.yy * V;
+	
+	d += shift;
+  
+	d.Normalize();
+
+	return SimpleRay(sray.mOrigin, d, SamplingStrategy::GVS, 1.0f);
+}
+
+
+}
