Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaderenv.h
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaderenv.h	(revision 3360)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaderenv.h	(revision 3361)
@@ -14,5 +14,5 @@
 //#define NUM_SAMPLES 24
 #define NUM_SAMPLES 32
-//#define NUM_SAMPLES 8
+//#define NUM_SAMPLES 48
 
 //#define MIN_SAMPLES 48
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/ssao.cg
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/ssao.cg	(revision 3355)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/ssao.cg	(revision 3361)
@@ -308,4 +308,7 @@
 }
 
+//#define TRYOUT
+
+#ifdef TRYOUT
 
 /** The ssao shader returning the an intensity value between 0 and 1.
@@ -399,5 +402,5 @@
 		// check if the samples have been valid in the last frame
 		// only mark sample as invalid if in the last / current frame
-		// they possibly have any influence on the ao
+		// they possibly have any influence on the AO
 
 		const float changeFactor = sampleColor.y;
@@ -412,5 +415,5 @@
 		const float partlyResetThres = 1.0f;
 
-		const float tooFarAway = step(0.5f, lengthToSample - changeFactor);
+		const float tooFarAway = step(.5f, lengthToSample - changeFactor);
 		if (0)//pixelValid <= partlyResetThres)
 			validSamples = max(validSamples, pixelValid * (1.0f - tooFarAway) * step(-0.1f, cosAngle));
@@ -451,4 +454,157 @@
 }
 
+#else
+
+float3 ssao(fragment IN,
+			sampler2D colors,
+			sampler2D noiseTex,
+			sampler2D samples,
+			float3 normal,
+			float3 centerPosition,
+			float radius,
+			float3 bl,
+			float3 br,
+			float3 tl,
+			float3 tr, 
+			float3 viewDir,
+			float convergence,
+			float sampleIntensity,
+			bool isMovingObject,
+			float oldIdx,
+			sampler2D attribsTex
+			)
+{
+	float total_ao = .0f;
+	float validSamples = .0f;
+	float numSamples = .0f;
+
+	float3 diffVec = tex2Dlod(attribsTex, float4(IN.texCoord, 0, 0)).xyz;
+
+	for (int i = 0; i < NUM_SAMPLES; ++ i) 
+	{
+		float2 offset;
+
+		const float2 ssaoOffset = 
+			tex2Dlod(samples, float4((0.5f + i + oldIdx) / NUM_PRECOMPUTED_SAMPLES, .5f, .0f, .0f)).xy;
+
+
+		////////////////////
+		//-- add random noise: reflect around random normal vector 
+		//-- (affects performance for some reason!)
+
+		if (convergence < SSAO_CONVERGENCE_THRESHOLD)
+		{
+			float2 mynoise = tex2Dlod(noiseTex, float4(IN.texCoord * 4.0f, 0, 0)).xy;
+			//offset = myreflect(samples[i], mynoise);
+			//offset = myrotate(samples[i], mynoise.x);
+			offset = myrotate(ssaoOffset, mynoise.x);
+		}
+		else
+		{
+			offset = ssaoOffset;
+		}
+
+
+		// weight with projected coordinate to reach similar kernel size for near and far
+		const float2 texcoord = IN.texCoord.xy + offset * radius;
+
+		const float4 sampleColor = tex2Dlod(colors, float4(texcoord, .0f, .0f));
+		const float3 samplePos = ReconstructSamplePos(sampleColor.w, texcoord, bl, br, tl, tr);
+		
+		
+
+		////////////////
+		//-- compute contribution of sample using the direction and angle
+
+		float3 dirSample = samplePos - centerPosition;
+
+		const float minDist = 1e-6f;
+		const float eps = 1e-3f;
+
+		const float lengthToSample = length(dirSample);
+		const float sampleWeight = 1.0f / max(lengthToSample, eps);
+
+		dirSample /= max(length(dirSample), minDist); // normalize
+
+		// angle between current normal and direction to sample controls AO intensity.
+		const float cosAngle = dot(dirSample, normal);
+
+		//const float aoContrib = sampleIntensity / sqrLen;
+		const float aoContrib = sampleIntensity * sampleWeight;
+		//const float aoContrib = (1.0f > lengthToSample) ? occlusionPower(9e-2f, DISTANCE_SCALE + lengthToSample): .0f;
+
+		total_ao += max(cosAngle, .0f) * aoContrib;
+
+		++ numSamples;
+
+
+#ifdef PERFORMANCE_TEST
+		// check if the samples have been valid in the last frame
+		// only mark sample as invalid if in the last / current frame
+		// they possibly have any influence on the ao
+
+		//const float pixelValid = sampleColor.x;
+		//const float pixelValid = length(sampleDiffVec - diffVec) < 1e-3f ? .0f : 10.0f;
+		//float pixelValid = max(sampleColor.x, length(sampleDiffVec - diffVec) < 1e-3f ? .0f : 10.0f);
+		float pixelValid = sampleColor.x;
+
+		if (pixelValid < 1)
+		{
+			const float3 sampleDiffVec = tex2Dlod(attribsTex, float4(texcoord, .0f, .0f)).xyz;
+			pixelValid = length(sampleDiffVec - diffVec) < 1e-3f ? .0f : 10.0f;
+		}
+
+		// hack:
+		// we check if the sample could have been near enough to the current pixel 
+		// or if the angle is small enough
+		// to have any influence in the current or last frame
+
+#if 1
+		const float changeFactor = sampleColor.y;
+		const float partlyResetThres = 1.0f;
+
+		if (0)//pixelValid <= partlyResetThres)
+		{
+			const float tooFarAway = step(0.5f, lengthToSample - changeFactor);
+			validSamples = max(validSamples, pixelValid * (1.0f - tooFarAway) * step(-0.1f, cosAngle));
+		}
+		else
+		{
+			validSamples = max(validSamples, pixelValid);
+		}
+#endif
+
+#ifdef USE_GTX
+		// we can bail out early and use a minimal #samples)
+		// if some conditions are met as long as the hardware supports it
+		if (numSamples >= MIN_SAMPLES)
+		{
+			//break;
+			// if the pixel belongs to a static object and all the samples stay valid in the current frame
+			if (!isMovingObject && (validSamples < 1.0f) && (convergence > NUM_SAMPLES)) break;
+			// if the pixel belongs to a dynamic object but the #accumulated samples for this pixel is sufficiently high 
+			// (=> there was no discontinuity recently)
+			//else if (isMovingObject && (convergence > SSAO_CONVERGENCE_THRESHOLD)) break;
+			else if (isMovingObject && (convergence > NUM_SAMPLES * 5)) break;
+		}
+#endif
+
+#endif // PERFORMANCE_TEST
+	}
+
+	// "normalize" ao contribution
+	total_ao /= numSamples;
+
+#if 1
+	// if surface normal perpenticular to view dir, approx. half of the samples will not count
+	// => compensate for this (on the other hand, projected sampling area could be larger!)
+	const float viewCorrection = 1.0f + VIEW_CORRECTION_SCALE * max(dot(viewDir, normal), 0.0f);
+	total_ao *= viewCorrection;
+#endif
+
+	//return float3(total_ao, validSamples, numSamples);
+	return float3(min(1.0f, total_ao), validSamples, numSamples);
+}
+#endif
 
 
@@ -501,5 +657,4 @@
 	
 #ifdef PERFORMANCE_TEST	
-//#if 0
 	float3 diffVec = tex2Dlod(attribsTex, float4(IN.texCoord, 0, 0)).xyz;
 
@@ -530,8 +685,8 @@
 	const float3 diffVec = float3(.0f);
 	const bool isMovingObject = false;
-	const float oldSsao = 0;
-	
-	float oldWeight = 0;
-	float oldIdx    = 0;
+	const float oldSsao = .0f;
+	
+	float oldWeight = .0f;
+	float oldIdx    = .0f;
 	
 #endif
@@ -544,13 +699,23 @@
 		if (1)
 		{
+#ifdef TRYOUT
 			ao = ssao(IN, colors, noiseTex, samples, normal, eyeSpacePos.xyz, 
 				      radiusMult, bl, br, tl, tr, normalize(viewDir),
 					  oldWeight, sampleIntensity, isMovingObject, oldIdx);
+#else
+
+			  ao = ssao(IN, colors, noiseTex, samples,
+				      normal, eyeSpacePos.xyz, radiusMult, bl, 
+					  br, tl, tr, normalize(viewDir), 
+					  oldWeight, sampleIntensity, isMovingObject, oldIdx,
+					  attribsTex);
+#endif				  
 		}
 		else
 		{
-			ao = ssao2(IN, colors, noiseTex, samples, normal, eyeSpacePos.xyz, radiusMult, 
+			/*ao = ssao2(IN, colors, noiseTex, samples, normal, eyeSpacePos.xyz, radiusMult, 
 			           bl, br, tl, tr, normalize(viewDir), oldWeight, sampleIntensity, 
 					   isMovingObject, normals, oldIdx);
+					   */
 		}
 	}
@@ -575,5 +740,5 @@
 	
 	// don't check for moving objects, otherwise almost no coherence
-	if (!isMovingObject)
+	if (1)//!isMovingObject)
 	{
 		if (ao.y > completelyResetThres) 
@@ -584,5 +749,6 @@
 		else if (ao.y > partlyResetThres)
 		{
-			oldWeight = min(oldWeight, 4.0f * newWeight);
+			const float factor = 4.0f;
+			oldWeight = min(oldWeight, factor * newWeight);
 			//oldWeight = .0f; 
 			//oldIdx    = .0f;
@@ -594,6 +760,8 @@
 	//-- blend ao between old and new samples (and avoid division by zero)
 
-	OUT.illum_col.x = (ao.x * newWeight + oldSsao * oldWeight);
+	OUT.illum_col.x = ao.x * newWeight + oldSsao * oldWeight;
 	OUT.illum_col.x /= (newWeight + oldWeight);
+	//OUT.illum_col.x = clamp(OUT.illum_col.x, 0, 1);
+	//OUT.illum_col.x = ao.y;
 
 	// the new weight for the next frame
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/combineSsaoSep.cg
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/combineSsaoSep.cg	(revision 3356)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/combineSsaoSep.cg	(revision 3361)
@@ -248,7 +248,9 @@
 	}
 
+	//OUT.illum_col.xyz = float3(ao.x * 1e1f, col.yz);
+
 	//OUT.illum_col.xyz = float3(ao.w * 5e-1f, 0, 0);
 	//OUT.illum_col.xyz = float3(ao.z * 1e-3f);
-	//OUT.illum_col.xyz = float3(ao.y * 1e-3f);x
+	//OUT.illum_col.xyz = float3(ao.y * 1e-3f);
 	//OUT.illum_col.xyz = ao.xyz;
 
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/deferred.cg
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/deferred.cg	(revision 3360)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/shaders/deferred.cg	(revision 3361)
@@ -40,5 +40,5 @@
 
 	// hack: prevent to shade the sky
-#if 1
+#if 0
 	if (color.w > DEPTH_THRESHOLD)
 	{
@@ -250,7 +250,7 @@
 
 	// compute position from old frame for dynamic objects + translational portion
-	//const float3 translatedPos = difVec - oldEyePos + worldPos.xyz;
+	const float3 translatedPos = difVec - oldEyePos + worldPos.xyz;
 	// don't use difVec here: want to detect if the actual pixel has changed => ssao changed
-	const float3 translatedPos = -oldEyePos + worldPos.xyz;
+	//const float3 translatedPos = -oldEyePos + worldPos.xyz;
 
 
@@ -293,5 +293,5 @@
 	// means that we only use slight temporal coherence over some frames
 	// so that there is no noticeable drag
-	const float pixelCouldBeValid = 2.0f;
+	const float pixelCouldBeValid = 4.0f;
 	// this pixel information has to be discarded in order to not create artifacts
 	const float pixelIsNotValid = 100.0f;
@@ -306,9 +306,11 @@
 	}
 	else if ( // check if changed from dynamic to not dynamic object
-   	         ((oldDynamic && !newDynamic) || (!oldDynamic && newDynamic) ||
+   	         (
+			  (oldDynamic && !newDynamic) || (!oldDynamic && newDynamic) ||
 			 (
 			  (oldEyeSpaceDepth < DEPTH_THRESHOLD) && (projectedEyeSpaceDepth < DEPTH_THRESHOLD) &&
 			  (oldDynamic || newDynamic) &&  // check if we have a dynamic object 
-			  (depthDif > MIN_DEPTH_DIFF)))) // and there is a depth discontinuity
+			  (depthDif > MIN_DEPTH_DIFF)))
+			  ) // and there is a depth discontinuity
 	{	
 		isPixelValid = pixelCouldBeValid;
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp	(revision 3360)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp	(revision 3361)
@@ -149,9 +149,6 @@
 
 bool useSkylightForIllum = true;
-
 bool showFPS = true;
-
 static int globalVisibleId = 0;
-
 PerfTimer applicationTimer;
 
@@ -203,5 +200,5 @@
 // ssao parameters
 float ssaoKernelRadius = 1e-8f;
-float ssaoSampleIntensity = 0.2f;
+float ssaoSampleIntensity = .2f;
 float ssaoFilterRadius = 3.0f;
 float ssaoTempCohFactor = 255.0;
@@ -647,7 +644,7 @@
 	
 	// for buddha (lowres)
-	/*positions.push_back(Vector3(6.07307, 8.20723, 6.62));
+	positions.push_back(Vector3(6.07307, 8.20723, 6.62));
 	positions.push_back(Vector3(-17.1935, 11.1687, 8.8781));
-	positions.push_back(Vector3(1.50032, 31.1943, 19.1f));*/
+	positions.push_back(Vector3(1.50032, 31.1943, 19.1f));
 
 	// for happy buddha
@@ -658,5 +655,5 @@
 	// for dragon
 	//positions.push_back(Vector3(6.07307, 8.20723, 5.0f));
-	positions.push_back(Vector3(0, 0, -0.8));
+	//positions.push_back(Vector3(0, 0, -0.8));
 
 #endif
@@ -666,6 +663,6 @@
 	
 	//LoadModel("hbuddha.dem", dynamicObjects);
-	LoadModel("horse.dem", dynamicObjects);
-	//LoadModel("happy.dem", dynamicObjects);
+	//LoadModel("horse.dem", dynamicObjects);
+	LoadModel("happy.dem", dynamicObjects);
 	//LoadModel("dragon.dem", dynamicObjects);
 	//LoadModel("torus.dem", dynamicObjects);
@@ -681,4 +678,5 @@
 	}
 
+	/*
 	const float rotAngle = M_PI / 2.0f;
 	const Matrix4x4 rotMatrix = RotationXMatrix(rotAngle);
@@ -689,13 +687,14 @@
 	dynamicObjects[0]->GetTransform()->MultMatrix(scaleMatrix);
 
-	//dynamicObjects[1]->GetTransform()->MultMatrix(rotMatrix);
-	//dynamicObjects[1]->GetTransform()->MultMatrix(scaleMatrix);
-
-	//dynamicObjects[2]->GetTransform()->MultMatrix(rotMatrix);
-	//dynamicObjects[2]->GetTransform()->MultMatrix(scaleMatrix);
+	dynamicObjects[1]->GetTransform()->MultMatrix(rotMatrix);
+	dynamicObjects[1]->GetTransform()->MultMatrix(scaleMatrix);
+
+	dynamicObjects[2]->GetTransform()->MultMatrix(rotMatrix);
+	dynamicObjects[2]->GetTransform()->MultMatrix(scaleMatrix);
 
 	cout << "dynamic objects: " << (int)dynamicObjects.size() << endl;
-
+	*/
 	CreateAnimation(positions[0]);
+
 #endif
 
@@ -827,4 +826,5 @@
 	// buffer holding the difference vector to the old frame
 	fbo->AddColorBuffer(ColorBufferObject::RGB_FLOAT_16, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_LINEAR);
+	//fbo->AddColorBuffer(ColorBufferObject::RGB_UBYTE, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_LINEAR);
 	// another color buffer
 	fbo->AddColorBuffer(ColorBufferObject::RGBA_FLOAT_32, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_LINEAR, ColorBufferObject::FILTER_NEAREST);
@@ -1172,5 +1172,5 @@
 		dynamicObjects[i]->GetTransform()->InitFrame();
 
-	if (0)//buddha)
+	if (buddha)
 	{
 		Matrix4x4 oldTrafo = buddha->GetTransform()->GetMatrix();
@@ -1194,11 +1194,11 @@
 #endif
 
-#if 0
+#if 1
 		/////////////////////////
 		//-- update animations
 
 		//const float rotAngle = M_PI * 1e-3f;
-		//const float rotAngle = 0.3f * M_PI / 180.0f;
-		const float rotAngle = 0.6f * M_PI / 180.0f;
+		const float rotAngle = 0.3f * M_PI / 180.0f;
+		//const float rotAngle = 0.6f * M_PI / 180.0f;
 
 		Matrix4x4 rotMatrix = RotationZMatrix(rotAngle);
@@ -1206,10 +1206,8 @@
 		dynamicObjects[1]->GetTransform()->MultMatrix(rotMatrix);
 
+		// hack: second buddha
 		const float rotAngle2 = 0.0033f * M_PI;
-
 		Matrix4x4 rotMatrix2 = RotationZMatrix(rotAngle);
-		// hack: second buddha
 		//dynamicObjects[3]->GetTransform()->MultMatrix(rotMatrix2);
-
 
 		//const float moveSpeed = 5e-3f;
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredRenderer.cpp
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredRenderer.cpp	(revision 3360)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredRenderer.cpp	(revision 3361)
@@ -407,5 +407,5 @@
 		cout << "using half resolution ssao" << endl;
 	}
-
+#if 1
 
 	/////////
@@ -467,5 +467,5 @@
 
 	PrepareLenseFlare();
-
+#endif
 	InitCg();
 }
@@ -660,5 +660,5 @@
 	*/
 
-	if (mShadingMethod != 0)
+	if (mShadingMethod != DEFAULT)
 	{
 		PrepareSsao(fbo); // downsample fbo buffers
@@ -966,4 +966,5 @@
 	GLuint colorsTex = fbo->GetColorBuffer(colorBufferIdx)->GetTexture();
 	GLuint normalsTex = fbo->GetColorBuffer(1)->GetTexture();
+	//GLuint aoTex = fbo->GetColorBuffer(1)->GetTexture();
 	GLuint aoTex = mTempFbo->GetColorBuffer(1)->GetTexture();
 
@@ -1103,4 +1104,5 @@
 	GLuint colorsTex = fbo->GetColorBuffer(colorBufferIdx)->GetTexture();
 	GLuint normalsTex = fbo->GetColorBuffer(1)->GetTexture();
+	//GLuint ssaoTex = fbo->GetColorBuffer(1)->GetTexture();
 	GLuint ssaoTex = mTempFbo->GetColorBuffer(0)->GetTexture();
 	
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/MainApp.vcproj
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/MainApp.vcproj	(revision 3342)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/MainApp.vcproj	(revision 3361)
@@ -156,5 +156,5 @@
 				IgnoreAllDefaultLibraries="false"
 				IgnoreDefaultLibraryNames="LIBCMT"
-				GenerateDebugInformation="false"
+				GenerateDebugInformation="true"
 				SubSystem="1"
 				LargeAddressAware="2"
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/Converter/main.cpp
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/Converter/main.cpp	(revision 3360)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/Converter/main.cpp	(revision 3361)
@@ -1,4 +1,4 @@
-#include "ObjConverter.h"
-//#include "PlyConverter.h"
+//#include "ObjConverter.h"
+#include "PlyConverter.h"
 #include <iostream>
 #include <time.h>
@@ -12,6 +12,6 @@
 
 	//ObjConverter2 converter;
-	ObjConverter converter;
-	//PlyConverter converter;
+	//ObjConverter converter;
+	PlyConverter converter;
 
 	cout << "converting obj to dem format" << endl;
Index: /GTP/trunk/App/Demos/Vis/FriendlyCulling/Converter/PlyConverter.cpp
===================================================================
--- /GTP/trunk/App/Demos/Vis/FriendlyCulling/Converter/PlyConverter.cpp	(revision 3359)
+++ /GTP/trunk/App/Demos/Vis/FriendlyCulling/Converter/PlyConverter.cpp	(revision 3361)
@@ -44,5 +44,12 @@
 		for (size_t j = 0; j < face.indices.size(); ++ j)
 		{
-			geom->mVertices.push_back(vertices[faces[i].indices[j]]);
+			SimpleVec h = vertices[faces[i].indices[j]];
+			SimpleVec v;
+			
+			v.x = h.x * 14;
+			v.y = h.z * 14;
+			v.z = h.y * 14;
+	
+			geom->mVertices.push_back(v);
 
 			/*if (!normals.empty())
@@ -69,7 +76,7 @@
 
 		// no face normals? => create normals
-		const SimpleTri tri(geom->mVertices[idx],
+		const SimpleTri tri(geom->mVertices[idx + 2],
 			                geom->mVertices[idx + 1], 
-							geom->mVertices[idx + 2]);
+							geom->mVertices[idx + 0]);
 
 		const SimpleVec n = tri.GetNormal();
