Index: /GTP/trunk/App/Demos/Vis/KdTreeDemo/OGRE/include/TestKdTreeAppListener.h
===================================================================
--- /GTP/trunk/App/Demos/Vis/KdTreeDemo/OGRE/include/TestKdTreeAppListener.h	(revision 1204)
+++ /GTP/trunk/App/Demos/Vis/KdTreeDemo/OGRE/include/TestKdTreeAppListener.h	(revision 1205)
@@ -94,4 +94,5 @@
 		}
 
+		String mSceneManager;
 		String mDemoInfileName;
 		String mDemoOutfileName;
@@ -105,4 +106,5 @@
 		Real mKI;
 		String mRenderMethod;
+		String mComment;
 	};
 
@@ -233,4 +235,7 @@
 	void togglePlayback();
 
+	/** write FPS stats to log file (csv) **/
+	void saveLog();
+
 	void saveFrameInfo(Real elapsedTime);
 
Index: /GTP/trunk/App/Demos/Vis/KdTreeDemo/OGRE/src/TestKdTree.cpp
===================================================================
--- /GTP/trunk/App/Demos/Vis/KdTreeDemo/OGRE/src/TestKdTree.cpp	(revision 1204)
+++ /GTP/trunk/App/Demos/Vis/KdTreeDemo/OGRE/src/TestKdTree.cpp	(revision 1205)
@@ -33,5 +33,6 @@
 				.addOpt("","kt", ARGUMENT_REQUIRED)
 				.addOpt("","ki", ARGUMENT_REQUIRED)
-				.addOpt("r","rendermethod", ARGUMENT_REQUIRED);
+				.addOpt("r","rendermode", ARGUMENT_REQUIRED)
+				.addOpt("s","scenemgr", ARGUMENT_REQUIRED);
 
 
@@ -78,4 +79,17 @@
 			}
 
+			if (cmdparser.getOpt("s",tmp))
+			{
+				if (tmp == "KDT" || tmp == "OCT" || tmp == "OCM" || tmp == "GEN")
+				{
+					options.mSceneManager = tmp;
+				}
+				else
+				{
+					MessageBox(NULL, ("Invalid argument for option --scenemgr: " + tmp).c_str(), "Error", MB_OK | MB_ICONERROR );
+					return -1;
+				}
+			}
+
 		}
 		catch (std::string s)
@@ -177,6 +191,6 @@
 
 	// set default demo output name to avoid SNAFUs
-	if (mOptions.mDemoOutfileName.empty())
-		mOptions.mDemoOutfileName = "demo.bin";
+	//if (mOptions.mDemoOutfileName.empty())
+	//	mOptions.mDemoOutfileName = "demo.bin";
 
 	if (mOptions.mDemoLogfileName.empty())
@@ -184,6 +198,31 @@
 
 	// set default demo logfile name to avoid SNAFUs
-	if (mOptions.mDemoLogfileName.empty())
-		mOptions.mDemoLogfileName = "demo.csv";
+	//if (mOptions.mDemoLogfileName.empty())
+	//	mOptions.mDemoLogfileName = "demo.csv";
+
+	// override scene manager set in config file
+	if (!mOptions.mSceneManager.empty())
+	{
+		if (mOptions.mSceneManager == "KDT")
+			mSelectedSceneManager = "KdTreeSceneManager";
+		else if (mOptions.mSceneManager == "OCT")
+			mSelectedSceneManager = "OctreeSceneManager";
+		else if (mOptions.mSceneManager == "OCM")
+			mSelectedSceneManager = "OcclusionCullingSceneManager";
+		else if (mOptions.mSceneManager == "GEN")
+			mSelectedSceneManager = "DefaultSceneManager";
+	}
+	// the other way round for log
+	else
+	{
+		if (mSelectedSceneManager == "KdTreeSceneManager")
+			mOptions.mSceneManager = "KDT";
+		else if (mSelectedSceneManager == "OctreeSceneManager")
+			mOptions.mSceneManager = "OCT";
+		else if (mSelectedSceneManager == "OcclusionCullingSceneManager")
+			mOptions.mSceneManager = "OCM";
+		else if (mSelectedSceneManager == "DefaultSceneManager")
+			mOptions.mSceneManager = "GEN";
+	}
 
 	ExampleApplication::setupResources();
Index: /GTP/trunk/App/Demos/Vis/KdTreeDemo/OGRE/src/TestKdTreeAppListener.cpp
===================================================================
--- /GTP/trunk/App/Demos/Vis/KdTreeDemo/OGRE/src/TestKdTreeAppListener.cpp	(revision 1204)
+++ /GTP/trunk/App/Demos/Vis/KdTreeDemo/OGRE/src/TestKdTreeAppListener.cpp	(revision 1205)
@@ -4,4 +4,5 @@
 #include <OgrePanelOverlayElement.h>
 #include "TestKdTreeAppListener.h"
+#include <windows.h>
 
 void KdTreeAppListener::updateStats(void)
@@ -1023,28 +1024,5 @@
 			if (mOptions.mDemoMode)
 			{
-				// write FPS log
-				Real minFPS = Math::POS_INFINITY, maxFPS = 0.0, avgFPS = 0.0;
-				std::ofstream demolog(mOptions.mDemoLogfileName.c_str());
-				if (demolog)
-				{
-					for (std::list<Real>::iterator it = mDemoFPS.begin(); it != mDemoFPS.end(); it ++)
-					{
-						demolog << (int)*it << "\n";
-
-						if (*it < minFPS)
-							minFPS = *it;
-
-						if (*it > maxFPS)
-							maxFPS = *it;
-
-						avgFPS += *it;
-					}
-
-					avgFPS /= mDemoFPS.size();
-
-					demolog << "\n" << (int)minFPS << "\n" << (int)avgFPS << "\n" << (int)maxFPS << "\n";
-
-					demolog.close();
-				}
+				saveLog();
 				return false;
 			}
@@ -1242,24 +1220,27 @@
 	// open file
 	std::ofstream dest(filename.c_str());
-	if (!dest)
-	{
-		LogManager::getSingleton().logMessage("Failed to open file for saving demo: " + filename);
-		return;
-	}
-
-	FrameList::iterator it = framelist.begin();
-	FrameList::iterator end = framelist.end();
-
-	// dump values
-	while (it != end)
-	{
-		dest << 
-			StringConverter::toString(it->mPosition) << " " << 
-			StringConverter::toString(it->mOrientation) << " " << 
-			StringConverter::toString(it->mElapsedTime) << "\n";
-		++ it;
-	}
-
-	dest.close();
+	if (dest.is_open())
+	{
+		FrameList::iterator it = framelist.begin();
+		FrameList::iterator end = framelist.end();
+
+		// dump values
+		while (it != end)
+		{
+			dest << 
+				StringConverter::toString(it->mPosition) << " " << 
+				StringConverter::toString(it->mOrientation) << " " << 
+				StringConverter::toString(it->mElapsedTime) << "\n";
+			++ it;
+		}
+
+		dest.close();
+	}
+	else
+	{
+		LogManager::getSingleton().logMessage("##Error##: Failed to open file for saving demo: " + filename);
+	}
+
+
 }
 
@@ -1269,30 +1250,31 @@
 	std::ofstream dest(filename.c_str(), std::ios_base::out | std::ios_base::binary);
 
-	if (!dest)
-	{
-		LogManager::getSingleton().logMessage("Failed to open file for saving demo: " + filename);
-		return;
-	}
-
-	FrameList::iterator it = framelist.begin();
-	FrameList::iterator end = framelist.end();
-
-	int size = sizeof(Real);
-
-	// dump values
-	while (it != end)
-	{
-		dest.write((char *)&it->mPosition.x, size);
-		dest.write((char *)&it->mPosition.y, size);
-		dest.write((char *)&it->mPosition.z, size);
-		dest.write((char *)&it->mOrientation.w, size);
-		dest.write((char *)&it->mOrientation.x, size);
-		dest.write((char *)&it->mOrientation.y, size);
-		dest.write((char *)&it->mOrientation.z, size);
-		dest.write((char *)&it->mElapsedTime, size);
-		++ it;
-	}
-
-	dest.close();
+	if (dest.is_open())
+	{
+		FrameList::iterator it = framelist.begin();
+		FrameList::iterator end = framelist.end();
+
+		int size = sizeof(Real);
+
+		// dump values
+		while (it != end)
+		{
+			dest.write((char *)&it->mPosition.x, size);
+			dest.write((char *)&it->mPosition.y, size);
+			dest.write((char *)&it->mPosition.z, size);
+			dest.write((char *)&it->mOrientation.w, size);
+			dest.write((char *)&it->mOrientation.x, size);
+			dest.write((char *)&it->mOrientation.y, size);
+			dest.write((char *)&it->mOrientation.z, size);
+			dest.write((char *)&it->mElapsedTime, size);
+			++ it;
+		}
+
+		dest.close();
+	}
+	else
+	{
+		LogManager::getSingleton().logMessage("##Error##: Failed to open file for saving demo: " + filename);
+	}
 }
 
@@ -1315,37 +1297,38 @@
 	// open file
 	std::ifstream src(filename.c_str());
-	if (!src)
-	{
-		LogManager::getSingleton().logMessage("Failed to open file for reading demo: " + filename);
-		return;
-	}
-
-	// clear the list
-	framelist.clear();
-
-	Vector3 pos;
-	Quaternion or;
-	Real time;
-
-	while (!src.eof())
-	{
-		src >> pos.x;	
-		src >> pos.y;	
-		src >> pos.z;
-
-		src >> or.w;
-		src >> or.x;
-		src >> or.y;
-		src >> or.z;
-
-		src >> time;
-
-		framelist.push_back(FrameInfo(pos, or, time));
-	}
-
-	// HACK pop last frame, was doubled while reading
-	framelist.pop_back();
-
-	src.close();
+	if (src.is_open())
+	{
+		// clear the list
+		framelist.clear();
+
+		Vector3 pos;
+		Quaternion or;
+		Real time;
+
+		while (!src.eof())
+		{
+			src >> pos.x;	
+			src >> pos.y;	
+			src >> pos.z;
+
+			src >> or.w;
+			src >> or.x;
+			src >> or.y;
+			src >> or.z;
+
+			src >> time;
+
+			framelist.push_back(FrameInfo(pos, or, time));
+		}
+
+		// HACK pop last frame, was doubled while reading
+		framelist.pop_back();
+
+		src.close();
+	}
+	else
+	{
+		LogManager::getSingleton().logMessage("##Error##: Failed to open file for reading demo: " + filename);
+	}
 }
 
@@ -1355,37 +1338,133 @@
 	// open file
 	std::ifstream src(filename.c_str(), std::ios_base::out | std::ios_base::binary);
-	if (!src)
-	{
-		LogManager::getSingleton().logMessage("Failed to open file for reading demo: " + filename);
-		return;
-	}
-
-	// clear the list
-	framelist.clear();
-
-	int size = sizeof(Real);
-
-	Vector3 pos;
-	Quaternion or;
-	Real time;
-
-	while (!src.eof())
-	{
-		src.read((char *)&pos.x, size);
-		src.read((char *)&pos.y, size);
-		src.read((char *)&pos.z, size);
-		src.read((char *)&or.w, size);
-		src.read((char *)&or.x, size);
-		src.read((char *)&or.y, size);
-		src.read((char *)&or.z, size);
-		src.read((char *)&time, size);
-
-		framelist.push_back(FrameInfo(pos, or, time));
-	}
-
-	// HACK pop last frame, was doubled while reading
-	framelist.pop_back();
-
-	src.close();
+	if (src.is_open())
+	{
+		// clear the list
+		framelist.clear();
+
+		int size = sizeof(Real);
+
+		Vector3 pos;
+		Quaternion or;
+		Real time;
+
+		while (!src.eof())
+		{
+			src.read((char *)&pos.x, size);
+			src.read((char *)&pos.y, size);
+			src.read((char *)&pos.z, size);
+			src.read((char *)&or.w, size);
+			src.read((char *)&or.x, size);
+			src.read((char *)&or.y, size);
+			src.read((char *)&or.z, size);
+			src.read((char *)&time, size);
+
+			framelist.push_back(FrameInfo(pos, or, time));
+		}
+
+		// HACK pop last frame, was doubled while reading
+		framelist.pop_back();
+
+		src.close();
+	}
+	else
+	{
+		LogManager::getSingleton().logMessage("##Error##: Failed to open file for reading demo: " + filename);
+	}
+}
+
+//-----------------------------------------------------------------------------
+void KdTreeAppListener::saveLog()
+{
+	// field separator and record separator
+	static const String fs = ",", rs ="\n", ds = ":";
+	// stats
+	Real minFPS = Math::POS_INFINITY, maxFPS = 0.0, avgFPS = 0.0;
+	String demofile;
+	
+	// check if logfile exists
+	std::ifstream logread(mOptions.mDemoLogfileName.c_str());
+	if (logread.is_open())
+	{
+		// read first item, it's the name of the demo
+		// if matches, OK, otherwise do something
+		logread >> demofile;
+		if (!StringUtil::startsWith(demofile, mOptions.mDemoInfileName))
+		{
+			LogManager::getSingleton().logMessage(
+				"##Error##: Saved demo stats do not match the current demo: " +
+				demofile + " != " + mOptions.mDemoInfileName);
+			logread.close();
+			return;
+		}
+	}
+	// otherwise write header
+	else
+	{
+		std::ofstream logheader(mOptions.mDemoLogfileName.c_str());
+		if (logheader.is_open())
+		{
+			// demo title
+			logheader << mOptions.mDemoInfileName << fs;
+			// seconds
+			for (size_t i = 0; i < mDemoFPS.size(); i ++)
+			{
+				logheader << (i+1) << fs;
+			}
+			// minFPS, avgFPS, maxFPS, comment, record separator
+			logheader << "min FPS" << fs << "avg FPS" << fs << "max FPS" << fs << "Comment" << rs;
+			logheader.close();
+		}
+		else
+		{
+			LogManager::getSingleton().logMessage(
+				"##Error##: Failed to write log demo header to " +
+				mOptions.mDemoLogfileName);
+			return;
+
+		}
+	}
+
+	// append current stats
+	std::ofstream logwrite(mOptions.mDemoLogfileName.c_str(), std::ios_base::app);
+	if (logwrite.is_open())
+	{
+		// demo settings
+		logwrite << mOptions.mSceneManager;
+		if (mOptions.mSceneManager == "KDT")
+		{
+			logwrite << ds << mOptions.mRenderMethod << ds << mOptions.mMaxDepth << ds 
+				<< mOptions.mKT << ds << mOptions.mKI;
+		}
+		//else if (mOptions.mSceneManager == "OCM" && mOptions.mRenderMethod != "INT")
+		//{
+		//	logwrite << ds << mOptions.mRenderMethod;
+		//}
+		logwrite << fs;
+		// per second stats
+		for (std::list<Real>::iterator it = mDemoFPS.begin(); it != mDemoFPS.end(); it ++)
+		{
+			if (*it < minFPS)
+				minFPS = *it;
+
+			if (*it > maxFPS)
+				maxFPS = *it;
+
+			avgFPS += *it;
+
+			logwrite << (int)(*it) << fs;
+
+		}
+		avgFPS /= mDemoFPS.size();
+		// minFPS, avgFPS, maxFPS, comment, record separator
+		logwrite << (int)minFPS << fs << (int)avgFPS << fs << (int)maxFPS << fs << mOptions.mComment << rs;
+		logwrite.close();
+	}
+	else
+	{
+		LogManager::getSingleton().logMessage(
+			"##Error##: Failed to write demo log to " +
+			mOptions.mDemoLogfileName);
+	}
 }
 
