Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Matrix4x4.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Matrix4x4.h	(revision 2913)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Matrix4x4.h	(revision 2915)
@@ -111,4 +111,7 @@
 	friend Matrix4x4 GetFittingProjectionMatrix(const AxisAlignedBox3 &box);
 
+	//output is initialized with the same result as glFrustum
+	friend Matrix4x4 GetFrustum(float left, float right, float bottom, float top, float near, float far);
+
 	// Overloaded output operator.
 	friend std::ostream& operator<< (std::ostream &s, const Matrix4x4 &M);
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ShadowMapping.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ShadowMapping.h	(revision 2913)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ShadowMapping.h	(revision 2915)
@@ -63,6 +63,6 @@
 	*/
 	Polyhedron *CalcClippedFrustum(const AxisAlignedBox3 &box) const;
-
-
+	
+	bool CalcLightProjectionLispSM(Matrix4x4 &lightProj);
 	bool CalcLightProjection(Matrix4x4 &lightProj);
 
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ShadowMapping.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ShadowMapping.cpp	(revision 2914)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ShadowMapping.cpp	(revision 2915)
@@ -144,6 +144,4 @@
 	VertexArray::const_iterator it, it_end = vertices.end();
 
-	//cout << "=================" << endl;
-
 	for (it = vertices.begin(); it != it_end; ++ it)
 	{
@@ -155,5 +153,4 @@
 		v -= Magnitude(mSceneBox.Diagonal()) * lightDir;
 
-		//cout << "pt: " << v << endl;
 		SimpleRay ray(v, lightDir);
 
@@ -163,9 +160,5 @@
 		{
 			Vector3 newpt = ray.Extrap(tNear);
-			Vector3 newpt2 = ray.Extrap(tFar);
-
-			frustumPoints.push_back(newpt);
-
-			//if (newpt.z < 220) cout << "ipt: " << newpt << " " << *it << endl;
+			frustumPoints.push_back(newpt);			
 		}
 	}
@@ -173,7 +166,10 @@
 
 
-bool ShadowMap::CalcLightProjection(Matrix4x4 &lightProj)
-{
-	DEL_PTR(polyhedron);
+bool ShadowMap::CalcLightProjectionLispSM(Matrix4x4 &lightProj)
+{
+	Matrix4x4 lispMtx = IdentityMatrix();
+
+	const float dotProd = DotProd(mCamera->GetDirection(), mShadowCam->GetDirection());
+	const float sinGamma = sqrt(1.0f - dotProd * dotProd);
 
 
@@ -181,4 +177,5 @@
 	//-- First step: calc frustum clipped by scene box
 
+	DEL_PTR(polyhedron);
 	polyhedron = CalcClippedFrustum(mSceneBox);
 
@@ -200,10 +197,4 @@
 	Matrix4x4 lightView;
 	mShadowCam->GetModelViewMatrix(lightView);
-
-	//Matrix4x4 inverseCamView;
-	//mCamera->GetModelViewMatrix(inverseCamView);
-	//Invert(inverseCamView);
-
-	//Matrix4x4 m = inverseCamView * lightView;
 
 	VertexArray::const_iterator it, it_end = frustumPoints.end();
@@ -212,31 +203,116 @@
 	{
 		Vector3 pt = *it;
-
-		//pt = inverseCamView * pt;
 		pt = lightView * pt;
-		//v = m * v;
 
 		extremalPoints.Include(pt);
-		//cout << "pt: " << pt << endl;
+	}
+
+
+	///////////////
+	//-- We apply the lispsm algorithm in order to calculate an optimal light projection matrix
+
+	// use lispsm formulas
+	const float fac = 1.0f / sinGamma;
+	
+	const float z_n = fac * mCamera->GetNear();
+
+	// light space y size
+	const float d = fabs(extremalPoints.Max()[1] - extremalPoints.Min()[1]); 
+
+	const float z_f = z_n + d * sinGamma;
+
+	// this is the famous n parameter
+	const float n = (z_n + sqrt(z_f * z_n)) /sinGamma;
+	const float f = n + d;
+
+	const Vector3 nearPt = mShadowCam->GetNear() * mShadowCam->GetDirection() + mShadowCam->GetPosition();
+
+	//get the coordinates of the near camera point in light space
+	const Vector3 lsNear = lightView * nearPt;
+
+	//c start has the x and y coordinate of e, the z coord of B.min()
+	const Vector3 startPt = Vector3(lsNear.x, lsNear.y, extremalPoints.Max().z);
+
+	// the new projection center
+	Vector3	projCenter = startPt - Vector3(0, 0, 1) * n;
+
+	//construct a translation that moves to the projection center
+	const Matrix4x4 projectionCenter = TranslationMatrix(-projCenter);
+
+	lightProj = IdentityMatrix();
+
+	//one possibility for a simple perspective transformation matrix
+	//with the two parameters n(near) and f(far) in y direction
+	
+	// a = (f+n)/(f-n); b = -2*f*n/(f-n);
+	// [ 1 0 0 0]
+	// [ 0 a 0 b]
+	// [ 0 0 1 0]
+	// [ 0 1 0 0]
+
+	lightProj.x[1][1] = (f + n) / (f - n);		 
+	lightProj.x[1][3] = 1.0f;
+
+	lightProj.x[3][1] = -2.0f * f * n / (f - n);		
+	lightProj.x[3][3] = 0.0f;				
+
+	cout << "here4\n" << lightProj << endl;
+
+	// transform into OpenGL right handed system
+	Matrix4x4 scale = ScaleMatrix(1.0f, 1.0f, -1.0f);
+
+	lightProj = projectionCenter * scale * lightProj;
+
+	Vector3 pmax = extremalPoints.Max();
+	Vector3 pmin = extremalPoints.Min();
+
+	cout << "min: " << lightProj * pmin << endl;
+	cout << "max: " << lightProj * pmax << endl;
+	
+
+	return true;
+}
+
+
+bool ShadowMap::CalcLightProjection(Matrix4x4 &lightProj)
+{
+	DEL_PTR(polyhedron);
+
+
+	///////////////////
+	//-- First step: calc frustum clipped by scene box
+
+	polyhedron = CalcClippedFrustum(mSceneBox);
+
+	if (!polyhedron) return false; // something is wrong
+
+	// include the part of the light volume that "sees" the frustum
+	// we only require frustum vertices
+
+	VertexArray frustumPoints;
+	IncludeLightVolume(*polyhedron, frustumPoints, mShadowCam->GetDirection(), mSceneBox);
+
+
+	///////////////
+	//-- transform points from world view to light view and calculate extremal points
+
+	AxisAlignedBox3 extremalPoints;
+	extremalPoints.Initialize();
+
+	Matrix4x4 lightView;
+	mShadowCam->GetModelViewMatrix(lightView);
+
+	VertexArray::const_iterator it, it_end = frustumPoints.end();
+		
+	for (it = frustumPoints.begin(); it != it_end; ++ it)
+	{
+		Vector3 pt = *it;
+		pt = lightView * pt;
+
+		extremalPoints.Include(pt);
 	}
 
 	// focus projection matrix on the extremal points
 	lightProj = GetFittingProjectionMatrix(extremalPoints);
-
-	/*Vector3 pmax = extremalPoints.Max();
-	Vector3 pmin = extremalPoints.Min();
-
-	cout << "min: " << lightProj * pmin << endl;
-	cout << "max: " << lightProj * pmax << endl;
-	
-	for (it = frustumPoints.begin(); it != it_end; ++ it)
-	{
-		Vector3 pt = *it;
-		
-		pt = lightView * pt;
-		pt = lightProj * pt;
-
-		cout << "pt: " << pt << endl;
-	}*/
 
 	return true;
@@ -283,6 +359,4 @@
 
 	Polyhedron *p = new Polyhedron(polygons);
-	//return p;
-	
 	Polyhedron *clippedPolyhedron = box.CalcIntersection(*p);
 	
@@ -348,5 +422,6 @@
 	mShadowCam->GetModelViewMatrix(lightView);
 
-	CalcLightProjection(lightProj);
+	//CalcLightProjection(lightProj);
+	CalcLightProjectionLispSM(lightProj);
 
 	glMatrixMode(GL_PROJECTION);
@@ -354,5 +429,5 @@
 	glLoadMatrixf((float *)lightProj.x);
 
-	//cout << "new:\n" << lightProj << endl;
+	cout << "new:\n" << lightProj << endl;
 
 	glMatrixMode(GL_MODELVIEW);
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Matrix4x4.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Matrix4x4.cpp	(revision 2913)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Matrix4x4.cpp	(revision 2915)
@@ -676,26 +676,58 @@
 
 	m.x[0][0] = -2.0f / (box.Max()[0] - box.Min()[0]);
+	m.x[0][1] = .0f;
+	m.x[0][2] = .0f;
+	m.x[0][3] = .0f;
+
 	m.x[1][0] = .0f;
+	m.x[1][1] = -2.0f / (box.Max()[1] - box.Min()[1]);
+	m.x[1][2] = .0f;
+	m.x[1][3] = .0f;
+
 	m.x[2][0] = .0f;
+	m.x[2][1] = .0f;
+	m.x[2][2] = -2.0f / (box.Max()[2] - box.Min()[2]);
+	m.x[2][3] = .0f;
+
 	m.x[3][0] = (box.Max()[0] + box.Min()[0]) / (box.Max()[0] - box.Min()[0]);
-
+	m.x[3][1] = (box.Max()[1] + box.Min()[1]) / (box.Max()[1] - box.Min()[1]);
+	m.x[3][2] = (box.Max()[2] + box.Min()[2]) / (box.Max()[2] - box.Min()[2]);
+	m.x[3][3] = 1.0f;
+
+	return m;
+}
+
+
+//output is initialized with the same result as glFrustum
+Matrix4x4 GetFrustum(float left, float right, float bottom, float top, float near, float far)
+{
+	Matrix4x4 m;
+
+	const float xDif = 1.0f / (right - left);
+	const float yDif = 1.0f / (top - bottom);
+	const float zDif = 1.0f / (near - far);
+
+	m.x[0][0] = 2.0f * near * xDif;
 	m.x[0][1] = .0f;
-	m.x[1][1] = -2.0f / (box.Max()[1] - box.Min()[1]);
-	m.x[2][1] = .0f;
-	m.x[3][1] = (box.Max()[1] + box.Min()[1]) / (box.Max()[1] - box.Min()[1]);
-
 	m.x[0][2] = .0f;
+	m.x[0][3] = .0f;
+
+	m.x[1][0] = .0f;
+	m.x[1][1] = 2.0f * near * yDif;
 	m.x[1][2] = .0f;
-	m.x[2][2] = -2.0f / (box.Max()[2] - box.Min()[2]);
-	m.x[3][2] = (box.Max()[2] + box.Min()[2]) / (box.Max()[2] - box.Min()[2]);
-
-	m.x[0][3] = .0f;
 	m.x[1][3] = .0f;
-	m.x[2][3] = .0f;
-	m.x[3][3] = 1.0f;
-
-	return m;
-}
-
-
-}
+
+	m.x[2][0] = (right + left) * xDif;
+	m.x[2][1] = (top + bottom)* yDif;
+	m.x[2][2] = (far + near) * zDif;
+	m.x[2][3] = -1.0f;
+
+	m.x[3][0] = .0f;
+	m.x[3][1] = .0f;
+	m.x[3][2] = 2.0f * near * far * zDif;
+	m.x[3][3] = .0f;
+}
+
+
+
+}
