Index: trunk/VUT/work/TestCullingTerrain/TerrainFrameListener.cpp
===================================================================
--- trunk/VUT/work/TestCullingTerrain/TerrainFrameListener.cpp	(revision 187)
+++ trunk/VUT/work/TestCullingTerrain/TerrainFrameListener.cpp	(revision 254)
@@ -70,5 +70,6 @@
 // output file for object positions / orientations
 const char* objects_out_filename = "objects.out";
-
+	
+std::ofstream video_out("video.lst");
 
 //-----------------------------------------------------------------------
@@ -117,5 +118,5 @@
 mShowVisualization(false),
 mCullCamera(false),
-mRecord(false),
+mRecordFrames(false),
 mShowShadows(false),
 mShowHelp(false),
@@ -134,5 +135,10 @@
 mDeleteObjects(false),
 mUseItemBuffer(false),
-mItemBufferMode(GtpVisibility::QueryManager::PATCH_VISIBILITY)
+mItemBufferMode(GtpVisibility::QueryManager::PATCH_VISIBILITY),
+mRecordVideo(false),
+mPureRenderTimeFps(0.0),
+mNumVideoFrames(0),
+mDemoFps(0),
+mUseDemoFps(false)
 {
 	//mInputDevice = PlatformManager::getSingleton().createInputReader();
@@ -159,6 +165,6 @@
 
 	initVisStatsOverlay(); // visibility stats overlay
-	initHelpOverlay(); // help overlay
-	initQueryOverlay(); // visibility query stats overlay
+	initHelpOverlay();     // help overlay
+	initQueryOverlay();    // visibility query stats overlay
 
 	// show stats overlays
@@ -179,4 +185,8 @@
 	setObjectType(mCurrentObjectType);
 
+	// initialise timer
+	mTimer = Root::getSingleton().getTimer();
+	mTimeFrameEnded = mTimeFrameStarted = mTimer->getMilliseconds();
+	
 	// reset statistics
 	resetStats();
@@ -356,5 +366,5 @@
 	{	return false;	}*/
 
-	// --- set parameters for visualization
+	//-- set parameters for visualization
 	if (mShowVisualization)
 	{
@@ -362,5 +372,5 @@
 		mSceneMgr->setOption("ShowOctree", &mShowVisualization);
 		
-		// ---- setup visualization camera
+		//-- setup visualization camera
 
 		mVizCamera->setPosition(0, 0, 0);
@@ -380,4 +390,10 @@
 		mVizCamera->moveRelative(Vector3(0, 800, 0));
 	}
+	else
+	{
+		// frame start time
+		mTimeFrameStarted = mTimer->getMilliseconds();
+		//Ogre::LogManager::getSingleton().logMessage("Frame started");
+	}
 
 	//-- set application state
@@ -385,11 +401,14 @@
 	{
 	case REPLAY:
+		/// set the current camera data to loaded frame information 
 		setCurrentFrameInfo(evt.timeSinceLastFrame);
+		// HACK to produce demo
+		addFrameInfo(mSavedFrameInfo, mCamNode, evt.timeSinceLastFrame);
 		break;
 	case WALKTHROUGH:
-		//-- if we are recording camera status per frame
-		if (mRecord)
+		//-- recording the camera settings per frame
+		if (mRecordFrames)
 		{
-			addFrameInfo(mCamNode, evt.timeSinceLastFrame);
+			addFrameInfo(mFrameInfo, mCamNode, evt.timeSinceLastFrame);
 			// print recording message
 			mWindow->setDebugText("Recording frame " + 
@@ -573,10 +592,23 @@
 		return false;
 
+	// timer end time
+	if (!mShowVisualization)
+	{
+		mTimeFrameEnded = mTimer->getMilliseconds();
+		//Ogre::LogManager::getSingleton().logMessage("Frame ended");
+	}
+
     updateStats();
 
+	if (mRecordVideo) // record current frame
+	{
+		//Ogre::LogManager::getSingleton().logMessage("taking video frame");
+		takeVideoFrame(video_out);
+		//Ogre::LogManager::getSingleton().logMessage("finished");
+	}
 	//-- IMPORTANT: must be set, otherwise terrain is not rendered correctly
 	mSceneMgr->endFrame();
 
-	if (mTimeDelay <= 0) // approx. one second
+	if (mTimeDelay <= 0) // simulates approx. one second
 		mTimeDelay = 1.0;
 
@@ -603,5 +635,23 @@
 		ofstr << StringConverter::toString((*it).position) << " " 
 			  << StringConverter::toString((*it).orientation) << " "
-			  << StringConverter::toString((*it).timeElapsed) << "\n";
+			  << StringConverter::toString((*it).timeElapsed) << " "
+			  << StringConverter::toString((*it).fps) << "\n";
+	}
+	ofstr.close();
+}
+// quick hack
+void TerrainFrameListener::writeNewFrameInfo()
+{
+	std::ofstream ofstr("newframe.out");
+	
+	std::vector<frame_info>::const_iterator it, it_end;
+
+	it_end = mSavedFrameInfo.end();
+	for (it = mSavedFrameInfo.begin(); it < it_end; ++it)
+	{
+		ofstr << StringConverter::toString((*it).position) << " " 
+			  << StringConverter::toString((*it).orientation) << " "
+			  << StringConverter::toString((*it).timeElapsed) << " "
+			  << StringConverter::toString((*it).fps) << "\n";
 	}
 	ofstr.close();
@@ -621,7 +671,7 @@
 	{
 		ifstr.getline(line, 256);
-		sscanf(line, "%f %f %f %f %f %f %f %f", &info.position.x, &info.position.y, &info.position.z,
+		sscanf(line, "%f %f %f %f %f %f %f %f %f", &info.position.x, &info.position.y, &info.position.z,
 			   &info.orientation.w, &info.orientation.x, &info.orientation.y, &info.orientation.z,
-			   &info.timeElapsed);
+			   &info.timeElapsed, &info.fps);
 		
 		mFrameInfo.push_back(info);
@@ -636,12 +686,19 @@
 {
 	mCurrentFrame = 0;
+	int lastState = mAppState;
+
+	// transition to the next state
+	mAppState = (mAppState + 1) % STATE_NUM;
 
 	// if last state was replay state
-	if (mAppState == REPLAY)
-	{
-		// reset debug text and write frame info to file
+	if (lastState == REPLAY)
+	{
+        // reset debug text
 		mWindow->setDebugText("");
-		writeFrames();
-		
+				
+		// hack for producing demo
+		writeNewFrameInfo();
+		mSavedFrameInfo.clear();
+
 		float avgFps = (float)mAvgFps / (float)mFrameCount;
 
@@ -659,19 +716,16 @@
 	}
 	
-	//-- set the next státe
-	mAppState = (mAppState + 1) % STATE_NUM;
-
 	// replay recorded walkthrough
 	if (mAppState == REPLAY)
 	{
 		// no recording during replay
-		mRecord = false;
-
-		// load recorded walkthrough
+		mRecordFrames = false; mWindow->setDebugText("");
+
+		// load recorded walkthrough from disk
 		if (mFrameInfo.size() == 0)
 		{
 			loadFrames();
 		}
-
+		
 		// if there are no recorded frames => set next state
 		if (mFrameInfo.size() == 0) 
@@ -679,5 +733,5 @@
 			nextAppState();
 		}
-		else
+		else // replay
 		{
 			mWindow->setDebugText("Replay");
@@ -699,11 +753,16 @@
 void TerrainFrameListener::toggleRecord()
 {
-	mRecord = !mRecord;
-
-	// clear previous camera path
-	if (mRecord)
+	mRecordFrames = !mRecordFrames;
+
+	if (mRecordFrames) 
+	{
+		// starting new recording => clear old frame info
 		mFrameInfo.clear();
+	}
 	else
+	{
+		writeFrames(); // write frame info to file
 		mWindow->setDebugText("");
+	}
 }
 //-----------------------------------------------------------------------
@@ -711,6 +770,10 @@
 {
 	mVisibilityThreshold += incr; 
-	if(mVisibilityThreshold < 0) mVisibilityThreshold = 0;
-	
+
+	if (mVisibilityThreshold < 0)
+	{
+		mVisibilityThreshold = 0;
+	}
+
 	char str[100]; sprintf(str,": %d", mVisibilityThreshold);
 
@@ -722,6 +785,10 @@
 {
 	mAssumedVisibility += incr; 
-	if(mAssumedVisibility < 0) mAssumedVisibility = 0;
-	
+
+	if (mAssumedVisibility < 0) 
+	{	
+		mAssumedVisibility = 0;
+	}
+
 	char str[100]; sprintf(str,": %d", mAssumedVisibility);
 
@@ -739,5 +806,5 @@
 {
 	mCurrentAlgorithm = (mCurrentAlgorithm + 1) % 
-		(GtpVisibility::VisibilityEnvironment::NUM_CULLING_MANAGERS - 1);
+		GtpVisibility::VisibilityEnvironment::NUM_CULLING_MANAGERS;
 	setAlgorithm(mCurrentAlgorithm);
 }
@@ -745,5 +812,5 @@
 void TerrainFrameListener::setObjectType(int objectType)
 {
-	if (mCurrentObjectType >= 3)
+	if (mCurrentObjectType >= 3) // TODO: define a constant
 		mCurrentObjectType = 0;
 
@@ -779,11 +846,26 @@
 	static String trisString = "Triangle Count: ";
 
+	int currentFps = mWindow->getStatistics().lastFPS;
+	
+	if (mUseDemoFps)
+		currentFps = mDemoFps;
+#if 0
+	// HACK: take pure rendering time, only measures the render call
+	long pureRenderTime = mTimeFrameEnded - mTimeFrameStarted;
+
+	if (pureRenderTime)
+	{
+		mPureRenderTimeFps = 1000.0 / (float) pureRenderTime;
+	}
+	currentFps = mPureRenderRenderTimeFps;
+	//std::stringstream d; d << "Pure render time fps: " << mPureRenderTimeFps << "\n";
+	//Ogre::LogManager::getSingleton().logMessage(d.str());
+#endif
+	
 	// HACK: compute average fps ourselfs, because ogre avg. fps is wrong
 	// TODO: update only once per second
-	mAvgFps += mWindow->getStatistics().lastFPS;
-	++ mFrameCount;
-	
-	float avgFps = (float)mAvgFps / (float)mFrameCount;
-    
+	mAvgFps += currentFps;
+	float avgFps = (float)mAvgFps / (float)(mFrameCount++);
+   
 	// update stats when necessary
     try 
@@ -796,11 +878,14 @@
 		const RenderTarget::FrameStats& stats = mWindow->getStatistics();
 
-		//guiAvg->setCaption(avgFps + StringConverter::toString(stats.avgFPS));
-		if (mTimeDelay < 0) // only update once per second
+		// HACK: take newly computed avg. fps instead of Ogre avg fps and update only once per second
+		if (mTimeDelay < 0) 
 		{		
 			guiAvg->setCaption(avgFpsString + StringConverter::toString(avgFps) + " ms");
+			//guiCurr->setCaption(currFpsString + StringConverter::toString(currentFps));
 		}
-
-		guiCurr->setCaption(currFpsString + StringConverter::toString(stats.lastFPS));
+		//guiAvg->setCaption(avgFps + StringConverter::toString(stats.avgFPS));
+		guiCurr->setCaption(currFpsString + StringConverter::toString(currentFps));
+		
+
 		guiBest->setCaption(bestFpsString + StringConverter::toString(stats.bestFPS)
 			+" "+StringConverter::toString(stats.bestFrameTime) + " ms");
@@ -1039,5 +1124,6 @@
 		break;
 	case KC_F2:
-		toggleShowStats();
+		mStatsOn = !mStatsOn;
+		showStats(mStatsOn);
 		break;
 	case KC_F3:
@@ -1063,4 +1149,8 @@
 		mUseAnimation = !mUseAnimation;
 		break;
+
+	case KC_F10:
+		mRecordVideo = !mRecordVideo;
+			
 	case KC_F11:
 		takeScreenshot();
@@ -1081,4 +1171,7 @@
 	case KC_DELETE:
 		mDeleteObjects = true;
+		break;
+	case KC_M: // hack
+		mUseDemoFps = !mUseDemoFps;
 		break;
 	//KEY_PRESSED(KC_F3, 0.3, writeFrames());
@@ -1110,12 +1203,14 @@
 }
 //-----------------------------------------------------------------------
-void TerrainFrameListener::addFrameInfo(SceneNode *camNode, Real timeElapsed)
+void TerrainFrameListener::addFrameInfo(FrameInfoContainer &frameInfos, SceneNode *camNode, Real timeElapsed)
 {
 	frame_info info;
+
 	info.orientation = mCamNode->getOrientation();
 	info.position = mCamNode->getPosition();
 	info.timeElapsed = timeElapsed;
-
-	mFrameInfo.push_back(info);
+	info.fps = mWindow->getStatistics().lastFPS;
+
+	frameInfos.push_back(info);
 }
 //-----------------------------------------------------------------------
@@ -1124,5 +1219,5 @@
 	//-- find current frame relative to elapsed frame time		
 	mReplayTimeElapsed -= timeElapsed;
-
+	
 	while ((mReplayTimeElapsed <= 0) && (mCurrentFrame < (int)mFrameInfo.size() - 1))
 	{
@@ -1130,5 +1225,7 @@
 	}
 
-	frame_info new_frame = mFrameInfo[mCurrentFrame];
+
+	// TODO: crashes here if recording / replaying on the same time!!
+	frame_info new_frame = mFrameInfo[mCurrentFrame]; 
 	frame_info old_frame = mFrameInfo[mCurrentFrame - 1];
 		
@@ -1143,11 +1240,16 @@
 	Vector3 camPos = old_frame.position + factor 
 		* (new_frame.position - old_frame.position);
+
+	// interpolate the orientation
 	Quaternion camOrienation = Quaternion::Slerp(factor, old_frame.orientation, 
 		new_frame.orientation, true);
 
+	// HACK: interpolate fps
+	mDemoFps = old_frame.fps + factor * (new_frame.fps -old_frame.fps);
+
 	mCamNode->setPosition(camPos);
 	mCamNode->setOrientation(camOrienation);
 	
-	// stop replay after a full walkthrough
+	// stop replaying after one full walkthrough
 	if (mCurrentFrame == (int)mFrameInfo.size() - 1)
 	{
@@ -1249,10 +1351,22 @@
 }
 //-----------------------------------------------------------------------
+void TerrainFrameListener::takeVideoFrame(std::ofstream &ofstr)
+{
+	char name[50];
+
+	sprintf(name, "frame_%05d.tga", ++mNumVideoFrames);
+    mWindow->writeContentsToFile(name);
+    //mWindow->setDebugText(String("Wrote ") + name);
+
+	ofstr << name << "\n";
+}
+//-----------------------------------------------------------------------
 void TerrainFrameListener::takeScreenshot()
 {
-	char tmp[20];
-	sprintf(tmp, "screenshot_%d.png", ++mNumScreenShots);
-    mWindow->writeContentsToFile(tmp);
-    mWindow->setDebugText(String("Wrote ") + tmp);
+	char name[50];
+
+	sprintf(name, "screenshot_%05d.png", ++mNumScreenShots);
+    mWindow->writeContentsToFile(name);
+    //mWindow->setDebugText(String("Wrote ") + name);
 }
 //-----------------------------------------------------------------------
@@ -1283,11 +1397,5 @@
 	}
 }
-//-----------------------------------------------------------------------
-void TerrainFrameListener::toggleShowStats()
-{
-	mStatsOn = !mStatsOn;
-
-	showStats(mStatsOn);
-}
+
 //-----------------------------------------------------------------------
 void TerrainFrameListener::toggleShowHelp()
@@ -1336,6 +1444,8 @@
 	initHelpOverlayElement("Recorded", top); top += vert_space;
 	initHelpOverlayElement("Animation", top); top += vert_space;
+	initHelpOverlayElement("Video", top); top += vert_space;
 	initHelpOverlayElement("Screenshots", top); top += vert_space;
 	initHelpOverlayElement("WriteOut", top); top += vert_space;
+
 
 	top +=vert_space;
Index: trunk/VUT/work/TestCullingTerrain/TestCullingTerrainApplication.cpp
===================================================================
--- trunk/VUT/work/TestCullingTerrain/TestCullingTerrainApplication.cpp	(revision 187)
+++ trunk/VUT/work/TestCullingTerrain/TestCullingTerrainApplication.cpp	(revision 254)
@@ -305,5 +305,5 @@
 	{
 		// the objects are generated randomly distributed over the terrain
-		generateScene(900, 0);
+		generateScene(900, 0); // create soldiers, trees, ninjas
 		generateScene(500, 1);
 		generateScene(100, 2);
Index: trunk/VUT/work/TestCullingTerrain/TerrainFrameListener.h
===================================================================
--- trunk/VUT/work/TestCullingTerrain/TerrainFrameListener.h	(revision 187)
+++ trunk/VUT/work/TestCullingTerrain/TerrainFrameListener.h	(revision 254)
@@ -20,4 +20,5 @@
 
 
+
 /** Frame listener specialised for terrains.
 */
@@ -75,5 +76,8 @@
 	   Quaternion orientation;
 	   Real timeElapsed;
+	   Real fps;
    } frame_info;
+
+   typedef std::vector<frame_info> FrameInfoContainer;
 
    enum  {WALKTHROUGH, REPLAY, STATE_NUM};
@@ -85,5 +89,5 @@
    void zoomVizCamera(int zoom);
 	
-   void addFrameInfo(SceneNode *camNode, Real timeElapsed);
+   void addFrameInfo(FrameInfoContainer &frameInfos, SceneNode *camNode, Real timeElapsed);
    void setCurrentFrameInfo(Real timeElapsed);
 
@@ -95,21 +99,33 @@
    void loadFrames();
 
-  
-    // Constructor takes a RenderWindow because it uses that to determine input context
-    //ExampleFrameListener(RenderWindow* win, Camera* cam, bool useBufferedInputKeys = false, bool useBufferedInputMouse = false)
+	// quick hack
+	void writeNewFrameInfo();
     
     bool processUnbufferedKeyInput(const FrameEvent& evt);
     bool processUnbufferedMouseInput(const FrameEvent& evt);
 
+	/** Shows the frame / algorithm statistics.
+	*/ 
     void showStats(bool show);
 
+	/** Updates frame statistics and the frame statistics display.
+	*/
 	void updateStats();
 
+	/** Toggles wether help screen is shown or not.
+	*/
 	void toggleShowHelp();
-	void toggleShowStats();
-
+	
+	/** Toggles wether shadows are shown or not.
+	*/
 	void toggleShowShadows();
 	void toggleDisplayCameraDetails();
+	/** Takes screenshot of the current scene.
+	*/
 	void takeScreenshot();
+	/** Takes one video frame.
+	*/
+	void takeVideoFrame(std::ofstream &ofstr);
+
 	void nextSceneDetailLevel();
 	void nextFilter();
@@ -120,7 +136,15 @@
 	void changeAssumedVisibility(int incr);
 	void setTestGeometryForVisibleLeaves(bool testGeometryForVisibleLeaves);
+	/** Shows octree hierarchy of the scene.
+	*/
 	void toggleShowOctree();
+	/** Toggles wether we use the initial depth pass.
+	*/
 	void toggleUseDepthPass();
+	/** Toggles wether the visualization is shown.
+	*/
 	void toggleShowViz();
+	/** Toggles wether the frames are recorded.
+	*/
 	void toggleRecord();
 
@@ -134,4 +158,6 @@
 	void applyVisibilityQuery(bool fromPoint, bool relativeVisibility, bool useItemBuffer);
 
+	/** Shows result from visibility queries.
+	*/
 	void toggleShowQueryStats();
 
@@ -168,15 +194,19 @@
 	int mVisibilityThreshold;
 	int mAssumedVisibility;
-	// the current frame number
+	/// the current frame number
 	int mCurrentFrame;
-	// the current application state
+	/// the current application state
 	int mAppState;
-	// The number of objects on the screen
+	/// The number of objects on the screen
 	int mObjectCount;            
-	// visualization mode
+	/// visualization mode
 	int mNodeVizMode;
-
-	SceneNode *mCurrentObject;    // the newly created object
-
+	/// number of video frames
+	int mNumVideoFrames;
+	/// the newly created object
+	SceneNode *mCurrentObject;    
+/// HACK
+float mDemoFps;
+bool mUseDemoFps;
 	OverlayElement *mAlgorithmInfo;
 	OverlayElement *mThresholdInfo;
@@ -214,5 +244,5 @@
 	bool mShowVisualization;
 	bool mCullCamera;
-	bool mRecord;
+	bool mRecordFrames;
 	bool mShowShadows;
 	bool mVisualizeCulledNodes;
@@ -232,7 +262,9 @@
 	SceneNode *mCamNode;
 	
-	//std::deque<Vector3> mWalkList;   // The list of points we are walking to
-	std::vector<frame_info> mFrameInfo;
-		
+	/// Per frame data stored for a walkthrough
+	FrameInfoContainer mFrameInfo;
+	/// HACK: for demo
+	FrameInfoContainer mSavedFrameInfo;
+	
 	Real mReplayTimeElapsed;
 	//EventProcessor* mEventProcessor;
@@ -282,5 +314,10 @@
 
 	bool mDeleteObjects;
-
+	bool mRecordVideo;
+
+	Timer *mTimer;
+	long mTimeFrameEnded;
+	long mTimeFrameStarted;
+	float mPureRenderTimeFps;
 	TestCullingTerrainApplication *mApplication;
 };
Index: trunk/VUT/work/TestCullingTerrain/TestCullingTerrainApplication.h
===================================================================
--- trunk/VUT/work/TestCullingTerrain/TestCullingTerrainApplication.h	(revision 183)
+++ trunk/VUT/work/TestCullingTerrain/TestCullingTerrainApplication.h	(revision 254)
@@ -157,5 +157,4 @@
 	Vector3 mTerrainMaxPos;
 
-
 private:
 	void chooseSceneManager(void);
Index: trunk/VUT/work/TestCulling/TestCullingApplication.cpp
===================================================================
--- trunk/VUT/work/TestCulling/TestCullingApplication.cpp	(revision 160)
+++ trunk/VUT/work/TestCulling/TestCullingApplication.cpp	(revision 254)
@@ -20,7 +20,7 @@
 
 
-/***********************************************/
-/* TestCullingApplication implementation       */
-/***********************************************/
+/***************************************************/
+/*     TestCullingApplication implementation       */
+/***************************************************/
 
 //-----------------------------------------------------------------------
Index: trunk/VUT/work/TestCulling/TestCullingApplication.h
===================================================================
--- trunk/VUT/work/TestCulling/TestCullingApplication.h	(revision 160)
+++ trunk/VUT/work/TestCulling/TestCullingApplication.h	(revision 254)
@@ -17,5 +17,5 @@
 }
 
-String mCurrentAlgorithmCaptions[GtpVisibility::VisibilityEnvironment::NUM_CULLING_MANAGERS] = 
+String mCurrentAlgorithmCaptions[] = 
 {
     "View Frustum Culling", 
Index: trunk/VUT/work/iv/IVFrameListener.cpp
===================================================================
--- trunk/VUT/work/iv/IVFrameListener.cpp	(revision 187)
+++ trunk/VUT/work/iv/IVFrameListener.cpp	(revision 254)
@@ -66,5 +66,5 @@
 mShowVisualization(false),
 mCullCamera(false),
-mRecord(false),
+mRecordFrames(false),
 mShowShadows(false),
 mShowHelp(false),
@@ -288,5 +288,5 @@
 	case WALKTHROUGH:
 		//-- if we are recording camera status per frame
-		if (mRecord)
+		if (mRecordFrames)
 		{
 			addFrameInfo(mCamNode, evt.timeSinceLastFrame);
@@ -442,5 +442,5 @@
 	{
 		// no recording during replay
-		mRecord = false;
+		mRecordFrames = false;
 
 		// load recorded walkthrough
@@ -475,8 +475,8 @@
 void IVFrameListener::toggleRecord()
 {
-	mRecord = !mRecord;
+	mRecordFrames = !mRecordFrames;
 
 	// clear previous camera path
-	if (mRecord)
+	if (mRecordFrames)
 		mFrameInfo.clear();
 	else
@@ -834,5 +834,5 @@
 	info.position = mCamNode->getPosition();
 	info.timeElapsed = timeElapsed;
-
+	
 	mFrameInfo.push_back(info);
 }
Index: trunk/VUT/work/iv/IVFrameListener.h
===================================================================
--- trunk/VUT/work/iv/IVFrameListener.h	(revision 187)
+++ trunk/VUT/work/iv/IVFrameListener.h	(revision 254)
@@ -182,5 +182,5 @@
 	bool mShowVisualization;
 	bool mCullCamera;
-	bool mRecord;
+	bool mRecordFrames;
 	bool mShowShadows;
 	bool mVisualizeCulledNodes;
