Index: GTP-Internal/trunk/Lib/Vis/work/README_ONLINE.txt
===================================================================
--- GTP-Internal/trunk/Lib/Vis/work/README_ONLINE.txt	(revision 629)
+++ GTP-Internal/trunk/Lib/Vis/work/README_ONLINE.txt	(revision 629)
@@ -0,0 +1,46 @@
+How to install the Visibility Work Package
+
+
+1) Requirements: 
+   WindowsXP
+   Ogre 1.03 for vs 7.1
+   Ogre Dependencies
+   svn
+
+2) check out gametools repository
+   in the following it is assumed that your repository is located in D:\gametools (not required, just replace your path)
+
+   the current stable version is located in D:\gametools\branches\0.3
+
+2) add following environment variables:
+   OGRE_PATH: directory where ogre.sln is located
+
+3) copy VUT\work\ogre_changes into OGRE_PATH directory (only applies to version 1.03!!!!)
+
+4) Set configuration of Ogre soluation to release. add preprocessor flag GTP_VISIBILITY_MODIFIED_OGRE to following projects:
+   Plugin_OctreeSceneManager
+   RenderSystem_GL
+   RenderSystem_Direct9
+   RenderSystem_Direct7
+   OgreMain
+   GuiRenderer
+   
+   Also add the flag to the example projects you want to use
+
+5) Add following resources to OGRE_PATH\Samples\Common\bin\Release\resource.cfg:
+
+   FileSystem=D:\gametools\trunk\VUT\Ogre\resources\materials\scripts
+   FileSystem=D:\gametools\trunk\VUT\Ogre\resources\materials\textures
+   FileSystem=D:\gametools\trunk\VUT\Ogre\resources\models
+   FileSystem=D:\gametools\trunk\VUT\Ogre\resources\models\trees
+   FileSystem=D:\gametools\trunk\VUT\Ogre\resources\overlays
+   FileSystem=D:\gametools\trunk\VUT\Ogre\resources\media
+
+6) Add Plugin_VisibilitySceneManager to OGRE_PATH\Samples\Common\bin\Release\Plugins.cfg
+   and comment out OctreeSceneManager
+
+7) Copy D:\gametools\trunk\VUT\Ogre\resources\terrain.cfg into OGRE_PATH\Samples\Common\bin\Release
+
+8) open scripts\GtpVisibility.sln and compile all
+
+9) start TerrainExampleApplication for testing
Index: GTP-Internal/trunk/Lib/Vis/work/todo_occlusionculling.txt
===================================================================
--- GTP-Internal/trunk/Lib/Vis/work/todo_occlusionculling.txt	(revision 629)
+++ GTP-Internal/trunk/Lib/Vis/work/todo_occlusionculling.txt	(revision 629)
@@ -0,0 +1,29 @@
+1) write into ogre forum
+2) mode_render does not do any change
+3) scenenode::_rendervisibleobjects already uses frustum culling
+4) implement for bsp trees
+5) improve mouse control (strave)
+6) cull camera for testing
+7) error when near plane crosses bounding volume
+8) bounding box should be not two parts
+9) implement z-buffer pass
+10) nice scene for dotscenemanager + terrainscenemanager
+11) ask about ogre changes
+12) preprocess: do not always destroy occlusion queries
+13) prevent multiple rendering of objects, scene nodes and hierarchy nodes
+14) learn to create terrains (heightmaps)
+15) work with maya
+16) occlusion culling + transparent materials, shadows!!
+17) minimize code for new scenemanager (macros?)
+18) make more flexible: callbacks
+19) find out how rotations happen
+20) investigate time coherence options (i.e., query only every nth frame
+21) möllers acceleration for frustum culling
+22) update so less code has to be replicated in terrainscenetraverser
+23) implement frustum test where intersect by near plane is considered
+24) tell ogre-people about changes
+25) check glfinish error
+26) also disable frustum culling on mouse click
+27) better comments
+28) setrendermode: change!!!
+29) problems with coherent & geometry not in leave
Index: GTP-Internal/trunk/Lib/Vis/work/tools/replid
===================================================================
--- GTP-Internal/trunk/Lib/Vis/work/tools/replid	(revision 65)
+++ GTP-Internal/trunk/Lib/Vis/work/tools/replid	(revision 65)
@@ -0,0 +1,36 @@
+#!/bin/sh
+
+#$Id: replid,v 1.2 1999/11/06 21:23:19 bittner Exp $
+# Initially coding Jiri Bittner
+    
+if [ $# -lt 3 ]; then echo "Usage: replid strA strB file_list $1 $2"; fi
+
+STR1=$1
+STR2=$2
+
+shift
+shift
+FILES=`grep -l $STR1 $*`
+
+echo $FILES
+
+SEPARATORS='[^a-zA-Z0-9_\.]'
+BACKUPDIR="Backup"
+
+if [ ! -d $BACKUPDIR ]; then  mkdir $BACKUPDIR; fi
+
+for FILE in $FILES; do
+ echo "Replacing in $FILE"
+ cp $FILE $BACKUPDIR/$FILE
+ CMD='-e s/\('$SEPARATORS'\)'$STR1'\('$SEPARATORS'\)/\1'$STR2'\2/g -e  s/^'$STR1'\('$SEPARATORS'\)/'$STR2'\1/g  -e  s/\('$SEPARATORS'\)'$STR1'$/\1'$STR2'/g -e  s/^'$STR1'$/'$STR2'/g'
+# echo $CMD
+ sed $CMD < $BACKUPDIR/$FILE > $FILE.tmp
+ mv $FILE.tmp $FILE
+done
+
+
+
+
+
+
+
Index: GTP-Internal/trunk/Lib/Vis/work/tools/batch_replace
===================================================================
--- GTP-Internal/trunk/Lib/Vis/work/tools/batch_replace	(revision 65)
+++ GTP-Internal/trunk/Lib/Vis/work/tools/batch_replace	(revision 65)
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# $Id: brepl,v 1.2 1999/11/06 21:23:19 bittner Exp $
+# Script used to globaly replace identifiers in GOLEM on 6.11. 1999
+# Initially coding Jiri Bittner
+
+# some manual changed to the code were also neccesary
+# - stats.h members of classes CIntersections and CObjects (class name collisions)
+# - hfield.h member BoundingBox
+# - world.cpp environment strings (e.g. CBSP -> BSP)
+# ...
+
+    
+FILES=$*
+
+#replid  Vector3D Vector3 $FILES
+#replid  Visibility GtpVisibility $FILES
+#replid  SceneTraverser HierarchyInterface $FILES
+replid  Visibility GtpVisibilityPreprocessor $FILES
+
+
Index: GTP-Internal/trunk/Lib/Vis/work/IVReader/include/ivmanualmeshloader.h
===================================================================
--- GTP-Internal/trunk/Lib/Vis/work/IVReader/include/ivmanualmeshloader.h	(revision 193)
+++ GTP-Internal/trunk/Lib/Vis/work/IVReader/include/ivmanualmeshloader.h	(revision 193)
@@ -0,0 +1,24 @@
+#ifndef __IVManualMeshLoader_H__
+#define __IVManualMeshLoader_H__
+
+
+#include "Ogre.h"
+#include "ivmeshdata.h"
+
+
+class __declspec(dllexport) IVManualMeshLoader: public Ogre::ManualResourceLoader
+{
+	public:
+		IVManualMeshLoader();
+		IVManualMeshLoader(IVMeshData *mData);
+		~IVManualMeshLoader(); 
+
+		void loadResource(Ogre::Resource *resource);
+
+		Ogre::AxisAlignedBox *getBoundingBox();
+	private:
+		IVMeshData *data;
+
+};
+
+#endif
Index: GTP-Internal/trunk/Lib/Vis/work/IVReader/include/ivreader.h
===================================================================
--- GTP-Internal/trunk/Lib/Vis/work/IVReader/include/ivreader.h	(revision 187)
+++ GTP-Internal/trunk/Lib/Vis/work/IVReader/include/ivreader.h	(revision 187)
@@ -0,0 +1,130 @@
+#ifndef __mIVReader_H__
+#define __mIVReader_H__
+
+
+#include "ivnode.h"
+#include "ivmeshdata.h"
+#include "ivmanualmeshloader.h"
+#include "ogre.h"
+
+#define COMMENTCHAR '#'
+#define BLOCKSIZE 150
+#define BUFFERSIZE 256
+
+
+static const int validIVHeaderCnt = 2;
+
+static const char *validIVHeader[2] = {
+    { "#Inventor V2.1 ascii\n" },
+	{ "#VRML V1.0 ascii\n" },
+};
+
+
+enum IVTokenType
+{
+	IV_TOKEN_INVALID = -1,
+	IV_TOKEN_STRING = 0,
+	IV_TOKEN_INT = 1,
+	IV_TOKEN_REAL = 2,
+	IV_TOKEN_BRACEOPEN = 3,				// {
+	IV_TOKEN_BRACECLOSE = 4,			// }
+	IV_TOKEN_BRACKETOPEN = 5,			// [
+	IV_TOKEN_BRACKETCLOSE = 6,			// ]
+	IV_TOKEN_PARENTHESISOPEN = 7,		// (
+	IV_TOKEN_PARENTHESISCLOSE = 8,		// )
+	IV_TOKEN_DEF = 9,					// DEF
+	IV_TOKEN_USE = 10,					// USE
+};
+
+class __declspec(dllexport) IVMeshListNode
+{
+	public:
+		IVMeshListNode(std::string name, IVManualMeshLoader *loader);
+		~IVMeshListNode();
+
+		void attachNewNode(std::string name, IVManualMeshLoader *loader);
+
+		IVManualMeshLoader *getManualMeshLoader(std::string name);
+
+		IVMeshListNode *next;
+
+	private:
+		std::string name;
+		IVManualMeshLoader *loader;
+};
+
+class __declspec(dllexport) IVDefListNode
+{
+	public:
+		IVDefListNode(std::string name, IVNode *node);
+		~IVDefListNode();
+
+		void attachNewNode(std::string name, IVNode *node);
+
+		IVNode *getDef(std::string name);
+
+		IVDefListNode *next;
+
+	private:
+		std::string name;
+		IVNode *node;
+
+};
+
+class __declspec(dllexport) IVReader
+{
+	public:
+		IVReader();
+		~IVReader();
+
+		void setLog(Ogre::Log *IVLog = NULL);
+
+		bool loadFile(const char* filename);
+		void print();
+//		IVNode *getNode(const char* name);
+
+
+		void buildTree(Ogre::SceneManager *sceneMgr, Ogre::SceneNode *sceneNodeRoot);
+
+		void collapse();
+
+		static std::string intToStr(int num);
+		static std::string realToStr(Ogre::Real num);
+		
+		static Ogre::Log *IVLog;
+
+	private:
+		bool checkHeader(const char *string);
+		char buf[BUFFERSIZE];
+		int bufOffset;
+		bool getNextElement(char *token, IVTokenType *type);
+		void classify(char *token, IVTokenType *type);
+
+		bool isSpace(char c);
+		bool isNewline(char c);
+		bool eof;
+		bool isDigit(char c);
+		bool isHexDigit(char c);
+
+		IVNode *root;
+		FILE* infile;
+
+		static IVMeshListNode *meshList;
+		static void addMeshToList(std::string name, IVManualMeshLoader *loader);
+		
+		static int instanceCnt;
+
+		int treeCnt, nodeCnt, matCnt;
+		char *fileName;
+
+		Ogre::Entity *createEntity(Ogre::SceneManager* sceneMgr, std::string name, IVMeshData *mData, Ogre::Vector3 *translation = NULL);
+
+		void buildTree(Ogre::SceneManager *sceneMgr, Ogre::SceneNode *sceneNodeRoot, IVNode *mIVReaderoot, IVMeshData *mData = NULL, Ogre::Material *material = NULL);
+
+		IVDefListNode *defList;
+		void addDefToList(std::string name, IVNode *node);
+
+};
+
+
+#endif
Index: GTP-Internal/trunk/Lib/Vis/work/IVReader/include/ivnode.h
===================================================================
--- GTP-Internal/trunk/Lib/Vis/work/IVReader/include/ivnode.h	(revision 183)
+++ GTP-Internal/trunk/Lib/Vis/work/IVReader/include/ivnode.h	(revision 183)
@@ -0,0 +1,59 @@
+#ifndef __IVNode_H__
+#define __IVNode_H__
+
+
+#include <string.h>
+#include <Ogre.h>
+
+enum IVType
+{
+	IV_INVALID = -1,
+	IV_STRING = 0,
+	IV_INT = 1,
+	IV_REAL = 2
+};
+
+
+class IVField
+{
+public:
+	IVField();
+	~IVField();
+
+	char *name;
+	void *value;
+	IVType typ;
+	int cnt;
+	IVField *next;
+};
+
+class __declspec(dllexport) IVNode
+{
+	public:
+		IVNode();
+		IVNode(const char *s);
+		~IVNode();
+
+		void print(int ident=0);
+		void attachNode(IVNode *child);
+		void addField(const char *name, char *value);
+		void addField(const char *name, void *value, int cnt, IVType typ);
+
+		IVNode *getParent() { return parent; }
+		char *getName() { return name; }
+		IVNode *getNodeRecursive(const char *name);
+		IVNode *getNextChildNode(bool reset = false);
+		IVField *getField(const char *name);
+		void *getField(const char *name, IVType *typ, int *cnt);
+
+	private:
+		char *name;
+		IVField *fields;
+		IVNode *parent;
+		IVNode *children;
+		IVNode *next;
+
+		IVNode *actual;
+};
+
+#endif
Index: GTP-Internal/trunk/Lib/Vis/work/IVReader/include/ivmeshdata.h
===================================================================
--- GTP-Internal/trunk/Lib/Vis/work/IVReader/include/ivmeshdata.h	(revision 187)
+++ GTP-Internal/trunk/Lib/Vis/work/IVReader/include/ivmeshdata.h	(revision 187)
@@ -0,0 +1,43 @@
+#ifndef __IVMeshData_H__
+#define __IVMeshData_H__
+
+
+#include <Ogre.h>
+
+enum mIVReaderenderOperationType
+{
+	IV_ROT_INVALID = -1,
+	IV_ROT_TRIANGLE_STRIP = 1,
+	IV_ROT_TRIANGLE_LIST = 3,
+	IV_ROT_FACE_SET = 4,
+};
+
+class __declspec(dllexport) IVMeshData
+{
+	public:	
+		IVMeshData();
+		~IVMeshData();
+
+		IVMeshData *expand();
+
+		void collapse();
+		
+		Ogre::Real *vertices, *normals, *texCoords, *indices, *normalIndices, *texCoordIndices;
+		int vcnt, ncnt, tcnt, icnt, nicnt, ticnt;
+		mIVReaderenderOperationType roType;
+		Ogre::AxisAlignedBox *boundingBox;
+
+	private:
+		int getSeparatorCnt(Ogre::Real *data, int end);
+
+		Ogre::Real *expandTriangleStripIndices(Ogre::Real *indices, int icnt, int *icntOut);
+		Ogre::Real *expandFaceSetIndices(Ogre::Real *indices, int icnt, int *icntOut);
+
+		int getNextFaceSize(int start);
+
+		Ogre::AxisAlignedBox *calcBoundingBox();
+
+
+};
+
+#endif
Index: GTP-Internal/trunk/Lib/Vis/work/IVReader/scripts/IVReader.vcproj
===================================================================
--- GTP-Internal/trunk/Lib/Vis/work/IVReader/scripts/IVReader.vcproj	(revision 343)
+++ GTP-Internal/trunk/Lib/Vis/work/IVReader/scripts/IVReader.vcproj	(revision 343)
@@ -0,0 +1,154 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="IVReader"
+	ProjectGUID="{7319E499-473D-4CE5-9983-725D6E68A55D}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="Debug"
+			IntermediateDirectory="Debug"
+			ConfigurationType="2"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;IVREADER_EXPORTS"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="1"
+				UsePrecompiledHeader="3"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="4"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)/IVReader.dll"
+				LinkIncremental="2"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/IVReader.pdb"
+				SubSystem="2"
+				ImportLibrary="$(OutDir)/IVReader.lib"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="..\lib\$(ConfigurationName)"
+			IntermediateDirectory="..\obj\$(ConfigurationName)"
+			ConfigurationType="2"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="&quot;$(OGRE_PATH)\Dependencies\include\CEGUI&quot;;&quot;$(OGRE_PATH)\Samples\Common\CEGUIRenderer\include&quot;;&quot;$(OGRE_PATH)\OgreMain\include&quot;;&quot;$(OGRE_PATH)\Dependencies\include&quot;;&quot;$(OGRE_PATH)\Samples\Common\include&quot;;..\include"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;IVREADER_EXPORTS;GTP_VISIBILITY_MODIFIED_OGRE"
+				RuntimeLibrary="2"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="OgreMain.lib CEGUIBase.lib OgreGUIRenderer.lib"
+				OutputFile="$(OutDir)/IVReader.dll"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="&quot;$(OGRE_PATH)\OgreMain\lib\$(ConfigurationName)&quot;;&quot;$(OGRE_PATH)\Samples\Common\CEGUIRenderer\lib&quot;;&quot;..\..\GtpVisibility\lib\$(ConfigurationName)&quot;;&quot;..\..\lib\$(ConfigurationName)&quot;;&quot;..\lib\$(ConfigurationName)&quot;;&quot;$(OGRE_PATH)\Dependencies\lib\$(ConfigurationName)&quot;"
+				GenerateDebugInformation="TRUE"
+				SubSystem="2"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				ImportLibrary="$(OutDir)/IVReader.lib"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				CommandLine="copy $(OutDir)\$(TargetFileName) $(OGRE_PATH)\Samples\Common\bin\$(ConfigurationName)"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+			<File
+				RelativePath="..\src\ivmanualmeshloader.cpp">
+			</File>
+			<File
+				RelativePath="..\src\ivmeshdata.cpp">
+			</File>
+			<File
+				RelativePath="..\src\ivnode.cpp">
+			</File>
+			<File
+				RelativePath="..\src\ivreader.cpp">
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+			<File
+				RelativePath="..\include\ivmanualmeshloader.h">
+			</File>
+			<File
+				RelativePath="..\include\ivmeshdata.h">
+			</File>
+			<File
+				RelativePath="..\include\ivnode.h">
+			</File>
+			<File
+				RelativePath="..\include\ivreader.h">
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
Index: GTP-Internal/trunk/Lib/Vis/work/IVReader/src/ivmanualmeshloader.cpp
===================================================================
--- GTP-Internal/trunk/Lib/Vis/work/IVReader/src/ivmanualmeshloader.cpp	(revision 187)
+++ GTP-Internal/trunk/Lib/Vis/work/IVReader/src/ivmanualmeshloader.cpp	(revision 187)
@@ -0,0 +1,154 @@
+#include "ivmanualmeshloader.h"
+#include "ivreader.h"
+
+IVManualMeshLoader::IVManualMeshLoader()
+{
+	data = NULL;
+}
+
+
+IVManualMeshLoader::IVManualMeshLoader(IVMeshData *mData)
+{
+	data = mData;
+/*	data = new IVMeshData();
+	if ((mData->indices != NULL) && (mData->icnt > 0))
+	{
+		data->icnt = mData->icnt;
+		data->indices = new Ogre::Real[mData->icnt];
+		memcpy(data->indices, mData->indices, mData->icnt*sizeof(Ogre::Real));
+	}
+	if ((mData->vertices != NULL) && (mData->vcnt > 0))
+	{
+		data->vcnt = mData->vcnt;
+		data->vertices = new Ogre::Real[mData->vcnt];
+		memcpy(data->vertices, mData->vertices, mData->vcnt*sizeof(Ogre::Real));
+	}
+	if ((mData->normals != NULL) && (mData->vcnt > 0))
+	{
+		data->ncnt = mData->ncnt;
+		data->normals = new Ogre::Real[mData->ncnt];
+		memcpy(data->normals, mData->normals, mData->ncnt*sizeof(Ogre::Real));
+	}
+	if ((mData->texCoords != NULL) && (mData->tcnt > 0))
+	{
+		data->tcnt = mData->tcnt;
+		data->texCoords = new Ogre::Real[mData->tcnt];
+		memcpy(data->texCoords, mData->texCoords, mData->tcnt*sizeof(Ogre::Real));
+	}
+	*/
+}
+
+IVManualMeshLoader::~IVManualMeshLoader()
+{
+/*	if (data != NULL)
+	{
+		if (data->vertices != NULL)		delete [] data->vertices;
+		if (data->normals != NULL)		delete [] data->normals;
+		if (data->texCoords != NULL)	delete [] data->texCoords;
+		if (data->indices != NULL)		delete [] data->indices;
+		delete data;
+	}
+	*/
+	if (data != NULL)
+	{
+		data->collapse();
+		delete data;
+	}
+}
+
+
+Ogre::AxisAlignedBox *IVManualMeshLoader::getBoundingBox()
+{
+	return data->boundingBox;
+}
+
+void IVManualMeshLoader::loadResource(Ogre::Resource *resource)
+{
+	using namespace Ogre;
+	Mesh *pMesh = (Mesh *) resource;
+
+
+	Vector3 translation = data->boundingBox->getCenter();
+
+	bool nOk = ((data->normals != NULL) && (data->ncnt > 0));
+	bool tOk = ((data->texCoords != NULL) && (data->tcnt > 0));
+	
+	pMesh->sharedVertexData = new VertexData(); 
+
+	VertexDeclaration* vertexDecl = pMesh->sharedVertexData->vertexDeclaration; 
+
+	size_t currOffset = 0; 
+	vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_POSITION); 
+	currOffset += VertexElement::getTypeSize(VET_FLOAT3); 
+	if (nOk)
+	{
+		vertexDecl->addElement(0, currOffset, VET_FLOAT3, VES_NORMAL); 
+		currOffset += VertexElement::getTypeSize(VET_FLOAT3); 
+	}
+    if (tOk)
+	{
+		vertexDecl->addElement(0, currOffset, VET_FLOAT2, VES_TEXTURE_COORDINATES); 
+		currOffset += VertexElement::getTypeSize(VET_FLOAT2); 
+	}
+
+	pMesh->sharedVertexData->vertexCount = data->vcnt/3; 
+	HardwareVertexBufferSharedPtr vbuf = 
+		HardwareBufferManager::getSingleton(). 
+		createVertexBuffer(vertexDecl->getVertexSize(0), pMesh->sharedVertexData->vertexCount, 
+			HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); 
+
+	VertexBufferBinding* binding = pMesh->sharedVertexData->vertexBufferBinding; 
+	binding->setBinding(0, vbuf); 
+
+	Real* pVertices = static_cast<Real*>(vbuf->lock(HardwareBuffer::HBL_DISCARD)); 
+
+	int offset = 0, size = 3;
+	if (nOk) size += 3;
+	if (tOk) size += 2;
+	for (int i=0; i<data->vcnt/3; i++) 
+	{
+		pVertices[i*size]   = data->vertices[i*3]   - translation.x;
+		pVertices[i*size+1] = data->vertices[i*3+1] - translation.y;
+		pVertices[i*size+2] = data->vertices[i*3+2] - translation.z;
+
+		offset = 3;
+		if (nOk)
+		{
+			pVertices[i*size+offset] = data->normals[i*3];	 offset++;
+			pVertices[i*size+offset] = data->normals[i*3+1]; offset++;
+			pVertices[i*size+offset] = data->normals[i*3+2]; offset++;
+		}
+		if (tOk)
+		{
+			pVertices[i*size+offset] = data->texCoords[i*2];   offset++;
+			pVertices[i*size+offset] = -data->texCoords[i*2+1]; offset++;
+		}
+	}
+
+	vbuf->unlock(); 
+
+
+	SubMesh *pSub = pMesh->createSubMesh(); 
+	pSub->operationType = RenderOperation::OT_TRIANGLE_LIST; //;data->roType;
+	pSub->useSharedVertices = true; 
+
+	pSub->indexData->indexCount = data->icnt; 
+	pSub->indexData->indexBuffer = HardwareBufferManager::getSingleton(). 
+		createIndexBuffer(HardwareIndexBuffer::IT_16BIT, 
+			pSub->indexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); 
+
+	HardwareIndexBufferSharedPtr ibuf = pSub->indexData->indexBuffer; 
+	unsigned short* pIndices = static_cast<unsigned short*>(ibuf->lock(HardwareBuffer::HBL_DISCARD)); 
+
+	for (i = 0; i < data->icnt; i++) pIndices[i] = data->indices[i];
+	
+	ibuf->unlock(); 
+		
+	AxisAlignedBox bb(data->boundingBox->getMinimum() - translation, data->boundingBox->getMaximum() - translation);
+	pMesh->_setBounds(bb); 
+	Real radius = data->boundingBox->getMinimum().length();
+	if (data->boundingBox->getMaximum().length() > radius) radius = data->boundingBox->getMaximum().length();
+	pMesh->_setBoundingSphereRadius(radius); 
+
+}
+
Index: GTP-Internal/trunk/Lib/Vis/work/IVReader/src/ivreader.cpp
===================================================================
--- GTP-Internal/trunk/Lib/Vis/work/IVReader/src/ivreader.cpp	(revision 187)
+++ GTP-Internal/trunk/Lib/Vis/work/IVReader/src/ivreader.cpp	(revision 187)
@@ -0,0 +1,772 @@
+#include "IVReader.h"
+#include <string>
+#include <stdlib.h>
+#include <sstream>
+
+IVMeshListNode *IVReader::meshList = NULL;
+int IVReader::instanceCnt = 0;
+Ogre::Log *IVReader::IVLog = NULL;
+
+
+
+IVMeshListNode::IVMeshListNode(std::string name, IVManualMeshLoader *loader)
+{
+	this->name = name;
+	this->loader = loader;
+	next = NULL;
+}
+
+IVMeshListNode::~IVMeshListNode()
+{
+	if (loader != NULL) delete loader;
+}
+
+void IVMeshListNode::attachNewNode(std::string name, IVManualMeshLoader *loader)
+{
+	IVMeshListNode *help = this;
+
+	while (help->next != NULL) help = help->next;
+	help->next = new IVMeshListNode(name, loader);
+}
+
+IVManualMeshLoader *IVMeshListNode::getManualMeshLoader(std::string name)
+{
+	IVMeshListNode *help = this;
+	if (help->name == name) return help->loader;
+	while (help->next != NULL) 
+	{
+		help = help->next;
+		if (help->name == name) return help->loader;
+	}
+	return NULL;
+}
+
+IVDefListNode::IVDefListNode(std::string name, IVNode *node)
+{
+	this->name = name;
+	this->node = node;
+	next = NULL;
+}
+
+IVDefListNode::~IVDefListNode()
+{
+}
+
+void IVDefListNode::attachNewNode(std::string name, IVNode *node)
+{
+	IVDefListNode *help = this;
+
+	while (help->next != NULL) help = help->next;
+	help->next = new IVDefListNode(name, node);
+}
+
+IVNode *IVDefListNode::getDef(std::string name)
+{
+	IVDefListNode *help = this;
+	if (help->name == name) return help->node;
+	while (help->next != NULL) 
+	{
+		help = help->next;
+		if (help->name == name) return help->node;
+	}
+	return NULL;
+}
+
+IVReader::IVReader()
+{	
+	root = NULL; meshList = NULL; defList = NULL; fileName = NULL;
+	instanceCnt++;
+	IVLog = NULL;
+}
+
+IVReader::~IVReader()
+{
+	collapse();
+
+	instanceCnt--;
+	if (instanceCnt == 0) if (meshList != NULL) 
+	{	
+		IVMeshListNode *help = meshList, *delme = NULL;
+		while (help->next != NULL)
+		{
+			delme = help; help = help->next; delete delme;
+		}
+		delete help;
+	}
+}
+
+void IVReader::collapse()
+{
+	if (root != NULL) {	delete root; root = NULL; }
+	if (defList != NULL)
+	{	
+		IVDefListNode *help = defList, *delme = NULL;
+		while (help->next != NULL)
+		{
+			delme = help; help = help->next; delete delme;
+		}
+		delete help;
+		defList = NULL;
+	}
+	if (this->fileName != NULL) { delete [] this->fileName; this->fileName = NULL; }
+
+}
+
+void IVReader::setLog(Ogre::Log *IVLog)
+{
+	this->IVLog = IVLog;
+}
+
+std::string IVReader::intToStr(int num)
+{
+	std::ostringstream myStream; 
+	myStream << num;
+	myStream.flush();
+	
+	return(myStream.str());
+}
+
+std::string IVReader::realToStr(Ogre::Real num)
+{
+	std::ostringstream myStream; 
+	myStream << num;
+	myStream.flush();
+	
+	return(myStream.str());
+}
+
+bool IVReader::loadFile(const char* fileName)
+{
+	std::string message = "trying to load "; message = message + fileName + "...";
+	
+	if (IVLog != NULL) 
+		IVLog->logMessage(message);
+	
+	collapse();
+	this->fileName = new char[strlen(fileName)+1]; strcpy(this->fileName, fileName);
+	treeCnt = 0;
+
+    infile = fopen(fileName, "r"); root = NULL;
+
+	if (infile == NULL)
+	{
+		message = "! Error loading File "; message = message + fileName + " !";
+		if (IVLog != NULL) IVLog->logMessage(message);
+		return false;
+	}
+
+	if ((fgets(buf, BUFFERSIZE, infile) == NULL) && !feof(infile)) 
+	{
+		message = "! Error loading File "; message = message + fileName + " !";
+		if (IVLog != NULL) IVLog->logMessage(message);
+		fclose(infile);
+		return false;
+	}
+
+	if (!checkHeader(buf)) 
+	{
+		message = "! Invalid Header !";
+		if (IVLog != NULL) IVLog->logMessage(message);
+		fclose(infile);
+		return false;
+	}
+
+	IVTokenType tmptyp = IV_TOKEN_INVALID;
+	eof = false;	
+
+	bufOffset = 0;
+	char token[BUFFERSIZE] = "\0", oldtoken[BUFFERSIZE] = "\0", fieldtoken[BUFFERSIZE] = "\0";
+	int level = 0; 
+
+	while (getNextElement(token, &tmptyp)) 
+	{
+		if (tmptyp == IV_TOKEN_BRACEOPEN) 
+		{
+			root = new IVNode(oldtoken);
+			level++;
+			break;
+		}
+
+		strcpy(oldtoken, token);
+	}
+
+	IVNode *actualNode = root, *parent = root, *fieldNode = root, *newNode = NULL;
+	IVTokenType oldtmptyp = tmptyp;
+	bool textfield = false, realfield = false; IVType fieldtyp = IV_INVALID;
+	bool def = false; std::string defLabel;
+	Ogre::Real rblock[BLOCKSIZE]; 
+	float *rvalues;
+	int cnt = 0; int blockcnt = 0;
+	while (getNextElement(token, &tmptyp))
+	{
+		if ((tmptyp == IV_TOKEN_BRACKETOPEN)) 
+			if (!getNextElement(token, &tmptyp)) break;
+		if ((tmptyp == IV_TOKEN_INVALID)) 
+			if (!getNextElement(token, &tmptyp)) break;
+		if (tmptyp == IV_TOKEN_BRACEOPEN) 
+		{
+			actualNode = new IVNode(oldtoken); 
+			if (parent == NULL)
+			{
+				message = "Error loading file "; message = message + fileName + "! Invalid tree structure.";
+				if (IVLog != NULL) IVLog->logMessage(message);
+				fclose(infile);
+				return false;
+			}
+			parent->attachNode(actualNode);
+			parent = actualNode;
+			level++;
+
+			if (def)
+			{
+				addDefToList(defLabel, actualNode);
+				def = false;
+			}
+
+		} else
+		if (tmptyp == IV_TOKEN_BRACECLOSE) 
+		{
+			if (realfield)
+			{
+				if (blockcnt == 0) rvalues = (Ogre::Real *)malloc((cnt)*sizeof(Ogre::Real));
+				else rvalues = (Ogre::Real *)realloc(rvalues, (BLOCKSIZE*(blockcnt) + cnt)*sizeof(Ogre::Real));						
+				memcpy((void *)&rvalues[BLOCKSIZE*blockcnt], rblock, cnt*sizeof(Ogre::Real));
+				fieldNode->addField(fieldtoken, rvalues, BLOCKSIZE*blockcnt+cnt, fieldtyp);
+				realfield = false;
+//				free(rvalues);
+			}
+
+			if (level > 0)
+			{
+				actualNode = parent = actualNode->getParent();
+				level--;
+			}
+		} else
+		{
+			if (oldtmptyp == IV_TOKEN_DEF)
+			{
+				def = true; defLabel = ""; defLabel = defLabel + token;
+			} else
+			if (oldtmptyp == IV_TOKEN_USE)
+			{
+					newNode = new IVNode("USE"); 
+					if (parent == NULL)
+					{
+						message = "Error loading file "; message = message + fileName + "! Invalid tree structure.";
+						if (IVLog != NULL) IVLog->logMessage(message);
+						fclose(infile);
+						return false;
+					}
+					char *s = (char *)malloc(sizeof(char)*(strlen(token)+1));
+					memcpy(s, token, strlen(token));
+					s[strlen(token)] = '\0';
+					newNode->addField("label", s);
+					actualNode->attachNode(newNode);
+			} else
+			if (!def)
+			if (oldtmptyp == IV_TOKEN_STRING)
+			{
+				if (!textfield)
+				{
+					if (tmptyp == IV_TOKEN_STRING)
+					{
+/*						char *s = new char[strlen(token)+1];
+						strcpy(s, token);
+*/						
+						char *s = (char *)malloc(sizeof(char)*(strlen(token)+1));
+						memcpy(s, token, strlen(token));
+						s[strlen(token)] = '\0';
+						actualNode->addField(oldtoken, s);
+//						delete [] s;
+					}
+				}
+				if (!realfield)
+				{
+					if ((tmptyp == IV_TOKEN_REAL) || (tmptyp == IV_TOKEN_INT))
+					{	
+						cnt = 0; blockcnt = 0;
+						char *stopstring;						
+						rblock[0] = strtod(token, &stopstring);
+						cnt++;
+						strcpy(fieldtoken, oldtoken);
+						fieldNode = actualNode;
+					    if (tmptyp == IV_TOKEN_REAL) fieldtyp = IV_REAL;
+						if (tmptyp == IV_TOKEN_INT)	fieldtyp = IV_INT;
+						realfield = true;
+					}
+				}
+				textfield = !textfield;
+			}
+			else 
+			{
+				if (realfield)	
+				{
+					if ((tmptyp == IV_TOKEN_REAL) || (tmptyp == IV_TOKEN_INT))
+					{		
+						char *stopstring;
+						if (cnt >= BLOCKSIZE) 
+						{
+							if (blockcnt == 0) rvalues = (Ogre::Real *)malloc((BLOCKSIZE)*sizeof(Ogre::Real));
+							else rvalues = (Ogre::Real *)realloc(rvalues, (BLOCKSIZE*(blockcnt+1))*sizeof(Ogre::Real));
+							memcpy((void *)&rvalues[BLOCKSIZE*blockcnt], rblock, BLOCKSIZE*sizeof(Ogre::Real));
+							cnt = 0;
+							blockcnt++;
+							
+						}
+						rblock[cnt] = strtod(token, &stopstring);
+						cnt++;
+					    if (tmptyp == IV_TOKEN_REAL) fieldtyp = IV_REAL;
+					}
+					else
+					{
+						if (blockcnt == 0) rvalues = (Ogre::Real *)malloc((cnt)*sizeof(Ogre::Real));
+						else rvalues = (Ogre::Real *)realloc(rvalues, (BLOCKSIZE*(blockcnt) + cnt)*sizeof(Ogre::Real));						
+						memcpy((void *)&rvalues[BLOCKSIZE*blockcnt], rblock, cnt*sizeof(Ogre::Real));
+						fieldNode->addField(fieldtoken, rvalues, BLOCKSIZE*blockcnt+cnt, fieldtyp);
+						realfield = false;
+//						free(rvalues);
+					}
+				}
+				
+				textfield = false;
+			}
+		}
+
+
+		strcpy(oldtoken, token);
+		oldtmptyp = tmptyp;
+	}
+	message = ""; ; message = message + fileName + " loaded.";
+	if (IVLog != NULL) IVLog->logMessage(message);
+	fclose(infile);
+
+	return true;
+}
+
+void IVReader::print()
+{
+	if (root != NULL) root->print();
+}
+
+bool IVReader::checkHeader(const char *string)
+{
+	for (int i=0; i < validIVHeaderCnt; i++)
+		if (strcmp(validIVHeader[i], string) == 0) return true;
+	return false;
+}
+bool IVReader::isSpace(char c)
+{
+	if ((c==' ') || (c=='\t')) return true;
+	return false;
+}
+bool IVReader::isNewline(char c)
+{
+	if (c=='\n') return true;
+	return false;
+}
+bool IVReader::isDigit(char c)
+{
+	if ((c>=48) && (c<=57)) return true;
+	return false;
+}
+bool IVReader::isHexDigit(char c)
+{
+	if ( ((c>=48) && (c<=57)) || ((c>=65) && (c<=70)) || ((c>=97) && (c<=102)) ) return true;
+	return false;
+}
+
+
+bool IVReader::getNextElement(char *token, IVTokenType *type)
+{
+	if (eof) return false;
+	bool quoted = false;
+	while (isSpace(buf[bufOffset])) bufOffset++;
+	int i=0;
+	while ((!isSpace(buf[bufOffset])) || (quoted))
+	{
+		if (!quoted)
+		{
+			if (isNewline(buf[bufOffset]) || (buf[bufOffset] == COMMENTCHAR))
+			{
+				token[i] = '\0'; 
+				classify(token, type);
+				bufOffset = 0;
+				if (fgets(buf, BUFFERSIZE, infile) == NULL) 
+				{			
+					eof = true;
+				}
+				if (i==0) return getNextElement(token, type);
+				return true;
+			}
+			if ((buf[bufOffset] == ',') || (buf[bufOffset] == ']'))
+			{
+				token[i] = '\0';
+				bufOffset++;
+				classify(token, type);
+				return true;
+			}
+		
+			
+
+		} else if (isNewline(buf[bufOffset])) {	eof = true;	}
+
+		
+		token[i] = buf[bufOffset]; 
+		i++;
+		if (buf[bufOffset] == '"') 
+		{
+			quoted = !quoted; i--;
+		}
+		bufOffset++;
+
+		
+	}
+	token[i] = '\0';
+	classify(token, type);
+	return true;
+}
+
+void IVReader::classify(char *token, IVTokenType *type)
+{
+	bool isInt = true, isReal = true;
+	if (!isDigit(token[0]) && (token[0] != '-') && (token[0] != '+')) 
+	{
+		isInt = false; 
+		if (token[0] != '.') isReal = false; 
+	}
+	int i = 1;
+	while ((token[i] != '\0') && isReal)
+	{
+		if (isInt && (i!=2) && !isHexDigit(token[i])) 
+		{
+			isInt = false;
+		}
+		if (isInt && (i==2) && !isHexDigit(token[i]) && (token[i] != 'x') && (token[i] != 'X')) isInt = false;
+		if (isReal && (!isDigit(token[i])) && (token[i] != '.') && (token[i] != 'e') && (token[i] != 'E') && (token[i] != 'd') && (token[i] != 'D') && (token[i] != '-') && (token[i] != '+')) isReal = false;
+		i++;
+	}
+	if (isInt) *type = IV_TOKEN_INT; 
+	else if (isReal) *type = IV_TOKEN_REAL;
+	else *type = IV_TOKEN_STRING;
+
+	if (strcmp(token, "DEF") == 0) *type = IV_TOKEN_DEF;
+	if (strcmp(token, "USE") == 0) *type = IV_TOKEN_USE;
+
+	if (token[1] == '\0')
+	{
+		if (token[0] == '{') *type = IV_TOKEN_BRACEOPEN;
+		if (token[0] == '}') *type = IV_TOKEN_BRACECLOSE;
+		if (token[0] == '[') *type = IV_TOKEN_BRACKETOPEN;
+		if (token[0] == ']') *type = IV_TOKEN_BRACKETCLOSE;
+		if (token[0] == '(') *type = IV_TOKEN_PARENTHESISOPEN;
+		if (token[0] == ')') *type = IV_TOKEN_PARENTHESISCLOSE;
+	}
+	if (token[0] == '\0')
+	{
+		*type = IV_TOKEN_INVALID;
+	}
+
+}
+
+/*
+IVNode *IVReader::getNode(const char* name)
+{
+	return root->getNodeRecursive(name);
+}
+*/
+void IVReader::addMeshToList(std::string name, IVManualMeshLoader *loader)
+{	
+	if (meshList == NULL) 
+	{
+		meshList = new IVMeshListNode(name, loader);
+	}
+	else
+	{
+		meshList->attachNewNode(name, loader);
+	}
+}
+
+void IVReader::addDefToList(std::string name, IVNode *node)
+{	
+	if (defList == NULL) 
+	{
+		defList = new IVDefListNode(name, node);
+	}
+	else
+	{
+		defList->attachNewNode(name, node);
+	}
+}
+
+Ogre::Entity *IVReader::createEntity(Ogre::SceneManager* sceneMgr, std::string name, IVMeshData *mData, Ogre::Vector3 *translation)
+{
+	using namespace Ogre;
+
+	std::string meshName = name.substr(name.find('/',0), name.length()) + "/Mesh";
+	std::string entityName = name + "/Entity";
+
+	Mesh* pMesh = NULL;
+	if ((pMesh = (Mesh *) MeshManager::getSingleton().getByName(meshName).getPointer()) == NULL)
+	{
+
+		IVMeshData *data = mData->expand();
+
+		IVManualMeshLoader *loader	= new IVManualMeshLoader(data);
+
+		if (translation != NULL) *translation = data->boundingBox->getCenter();
+
+//		data->collapse();
+//		delete data;
+
+
+		addMeshToList(meshName, loader);
+
+		Mesh* pMesh = MeshManager::getSingleton().createManual(meshName, "IVGroup", loader).getPointer(); 
+
+		pMesh->load(); 
+		pMesh->touch();
+	}
+	else
+	{
+		if (translation != NULL)
+		{
+			*translation = meshList->getManualMeshLoader(meshName)->getBoundingBox()->getCenter();
+		}
+	}
+
+	Entity *pEntity = sceneMgr->createEntity(entityName, meshName);
+
+
+	return pEntity;
+}
+
+
+
+void IVReader::buildTree(Ogre::SceneManager* sceneMgr,  Ogre::SceneNode *sceneNodeRoot)
+{
+	using namespace Ogre;
+	if (root == NULL) return;
+
+	std::string s = intToStr(treeCnt) + "/" + fileName + "/Root";
+	SceneNode *actualSceneNode = sceneNodeRoot->createChildSceneNode(s);
+	s = "/"; s = s + fileName + "/RootMaterial";
+	
+	Material* pMaterial = NULL;
+	if ((pMaterial = (Material *) MaterialManager::getSingleton().getByName(s).getPointer()) == NULL)
+	{
+		pMaterial = (Material *)MaterialManager::getSingleton().create(s, "General").getPointer();
+	}
+	pMaterial->load();
+
+	nodeCnt = 1; matCnt = 1;
+	
+
+	buildTree(sceneMgr, actualSceneNode, root, NULL, pMaterial);	
+	treeCnt++; 
+
+
+	std::string message = "Tree of "; message = message + fileName + " built (" + intToStr(nodeCnt) + " Nodes)";
+	if (IVLog != NULL) IVLog->logMessage(message);
+
+}
+
+void IVReader::buildTree(Ogre::SceneManager* sceneMgr,  Ogre::SceneNode *sceneNodeRoot, IVNode *IVReaderoot, IVMeshData *mData, Ogre::Material *material)
+{
+	using namespace Ogre;
+
+	Material *newMaterial = NULL;
+
+	bool meshDataCreated = false;
+	if (mData == NULL)
+	{
+		mData = new IVMeshData();
+		meshDataCreated = true;
+	}
+
+	IVType t; int i;
+	
+	IVNode *help = IVReaderoot->getNextChildNode(true);
+	while (help != NULL)
+	{	
+		if (strcmp(help->getName(), "USE") == 0)
+		{
+			char *defLabel = (char *) help->getField("label", &t, &i);
+			if (t == IV_STRING) 
+			{
+				help = defList->getDef(defLabel);
+			}
+		}
+		if ((strcmp(help->getName(), "Separator") == 0) || (strcmp(help->getName(), "TransformSeparator") == 0)) 
+		{
+/*			std::string s = sceneNodeRoot->getName() + "/Sep" + intToStr(nodeCnt);
+			nodeCnt++;
+			SceneNode *actualSceneNode = sceneNodeRoot->createChildSceneNode(s);
+			buildTree(sceneMgr, actualSceneNode, help, mData, actualMaterial);
+*/
+			if (newMaterial == NULL) newMaterial = material;
+			buildTree(sceneMgr, sceneNodeRoot, help, mData, newMaterial);
+		}
+
+		if (strcmp(help->getName(), "Texture2") == 0)
+		{
+			char *textureFileName = (char *) help->getField("filename", &t, &i);
+			if (t == IV_STRING) 
+			{  
+				std::string s = sceneNodeRoot->getName().substr(sceneNodeRoot->getName().find('/',0), sceneNodeRoot->getName().length()) + "/Material" + intToStr(matCnt);
+				matCnt++;
+				if ((newMaterial = (Material *) MaterialManager::getSingleton().getByName(s).getPointer()) == NULL)
+				{
+					newMaterial = (Material *)MaterialManager::getSingleton().create(s, "General").getPointer();
+					newMaterial->getTechnique(0)->getPass(0)->createTextureUnitState(textureFileName);
+				}
+				newMaterial->load();
+				newMaterial->reload();
+			}
+		}
+// can be included
+		if (strcmp(help->getName(), "Material") == 0)
+		{
+			Real *ambientColor = (Real *) help->getField("ambientColor", &t, &i);
+			if ((i != 3) || (t != IV_REAL)) ambientColor = NULL;
+			Real *diffuseColor = (Real *) help->getField("diffuseColor", &t, &i);
+			if ((i != 3) || (t != IV_REAL)) diffuseColor = NULL;
+			Real *specularColor = (Real *) help->getField("specularColor", &t, &i);
+			if ((i != 3) || (t != IV_REAL)) specularColor = NULL;
+			Real *emissiveColor = (Real *) help->getField("emissiveColor", &t, &i);
+			if ((i != 3) || (t != IV_REAL)) emissiveColor = NULL;
+			Real *shininess = (Real *) help->getField("shininess", &t, &i);
+			if ((i != 1) || (t != IV_REAL)) shininess = NULL;
+			Real *transparency = (Real *) help->getField("transparency", &t, &i);
+			if ((i != 1) || (t != IV_REAL)) transparency = NULL;
+
+			if (newMaterial == NULL)
+			{
+				std::string s = sceneNodeRoot->getName().substr(sceneNodeRoot->getName().find('/',0), sceneNodeRoot->getName().length()) + "/Material" + intToStr(matCnt);
+				matCnt++;
+				if ((newMaterial = (Material *) MaterialManager::getSingleton().getByName(s).getPointer()) == NULL)
+				{
+					if (material == NULL) newMaterial = (Material *)MaterialManager::getSingleton().create(s, "General").getPointer();
+					else newMaterial = material->clone(s).getPointer();
+
+					Real alpha = 1.f;
+					if (transparency != NULL) alpha = 1.f - transparency[0];
+					if (ambientColor != NULL) newMaterial->setAmbient(ambientColor[0], ambientColor[1], ambientColor[2]);
+					if (diffuseColor != NULL) newMaterial->setDiffuse(diffuseColor[0], diffuseColor[1], diffuseColor[2], alpha);
+					if (specularColor != NULL) newMaterial->setSpecular(specularColor[0], specularColor[1], specularColor[2], alpha);
+					if (emissiveColor != NULL) newMaterial->setSelfIllumination(emissiveColor[0], emissiveColor[1], emissiveColor[2]);
+					if (shininess != NULL) newMaterial->setShininess(shininess[0]);
+					
+//					if (material->getTechnique(0)->getPass(0)->getNumTextureUnitStates() > 0)							
+//					{
+//						newMaterial->getTechnique(0)->getPass(0)->createTextureUnitState(material->getTechnique(0)->getPass(0)->getTextureUnitState(0)->getTextureName());
+//					}
+				}
+				newMaterial->load();
+				newMaterial->reload();
+			}
+			else
+			{
+				Real alpha = 1.f;
+				if (transparency != NULL) alpha = 1.f - transparency[0];
+				if (ambientColor != NULL) newMaterial->setAmbient(ambientColor[0], ambientColor[1], ambientColor[2]);
+				if (diffuseColor != NULL) newMaterial->setDiffuse(diffuseColor[0], diffuseColor[1], diffuseColor[2], alpha);
+				if (specularColor != NULL) newMaterial->setSpecular(specularColor[0], specularColor[1], specularColor[2], alpha);
+				if (emissiveColor != NULL) newMaterial->setSelfIllumination(emissiveColor[0], emissiveColor[1], emissiveColor[2]);
+				if (shininess != NULL) newMaterial->setShininess(shininess[0]);
+				newMaterial->load();
+			}
+		}
+
+		if (strcmp(help->getName(), "Coordinate3") == 0)
+		{
+			mData->vertices = (Real *) help->getField("point", &t, &mData->vcnt);
+			if ((t != IV_REAL) && (t != IV_INT)) mData->vertices = NULL;
+		}
+		if (strcmp(help->getName(), "Normal") == 0)
+		{
+			mData->normals = (Real *) help->getField("vector", &t, &mData->ncnt);
+			if ((t != IV_REAL) && (t != IV_INT)) mData->normals = NULL;
+		}
+		if (strcmp(help->getName(), "TextureCoordinate2") == 0)
+		{
+			mData->texCoords = (Real *) help->getField("point", &t, &mData->tcnt);
+			if ((t != IV_REAL) && (t != IV_INT)) mData->texCoords = NULL;
+		}
+
+		if (strcmp(help->getName(), "IndexedFaceSet") == 0)
+		{
+			std::string s = sceneNodeRoot->getName() + "/IFS" + intToStr(nodeCnt);
+			nodeCnt++;
+			SceneNode *triangleStripSceneNode = sceneNodeRoot->createChildSceneNode(s);
+
+			mData->indices = (Real *) help->getField("coordIndex", &t, &mData->icnt);
+			if (t != IV_INT) mData->indices = NULL;
+
+			mData->normalIndices = (Real *) help->getField("normalIndex", &t, &mData->nicnt);
+			if (t != IV_INT) mData->normalIndices = NULL;
+		
+			mData->texCoordIndices = (Real *) help->getField("textureCoordIndex", &t, &mData->ticnt);
+			if (t != IV_INT) mData->texCoordIndices = NULL;
+		
+
+			mData->roType = IV_ROT_FACE_SET;		
+	
+			Vector3 translation = Vector3(0,0,0);
+			Entity *pEntity = createEntity(sceneMgr, s, mData, &translation);
+			if (newMaterial == NULL) newMaterial = material;
+			if (newMaterial != NULL) pEntity->setMaterialName(newMaterial->getName());
+				
+			triangleStripSceneNode->attachObject(pEntity);
+			triangleStripSceneNode->translate(translation);		
+
+		}
+
+
+		if (strcmp(help->getName(), "IndexedTriangleStripSet") == 0)
+		{
+			std::string s = sceneNodeRoot->getName() + "/ITS" + intToStr(nodeCnt);
+			nodeCnt++;
+			SceneNode *triangleStripSceneNode = sceneNodeRoot->createChildSceneNode(s);
+		
+			mData->indices = (Real *) help->getField("coordIndex", &t, &mData->icnt);
+			if (t != IV_INT) mData->indices = NULL;
+
+			mData->normalIndices = (Real *) help->getField("normalIndex", &t, &mData->nicnt);
+			if (t != IV_INT) mData->normalIndices = NULL;
+
+			mData->texCoordIndices = (Real *) help->getField("textureCoordIndex", &t, &mData->ticnt);
+			if (t != IV_INT) mData->texCoordIndices = NULL;
+
+			IVNode *n = help->getNextChildNode(true);
+			while ((n != NULL) && (strcmp(help->getName(), "VertexProperty") == 0))
+			{
+				n = help->getNextChildNode();
+			}
+			if (n != NULL)
+			{
+				mData->vertices = (Real *) n->getField("vertex", &t, &mData->vcnt);
+				if ((t != IV_REAL) && (t != IV_INT)) mData->vertices = NULL;
+
+				mData->normals = (Real *) n->getField("normal", &t, &mData->ncnt);
+				if ((t != IV_REAL) && (t != IV_INT)) mData->normals = NULL;
+				mData->texCoords = (Real *) n->getField("texCoord", &t, &mData->tcnt);
+				if ((t != IV_REAL) && (t != IV_INT)) mData->texCoords = NULL;
+			}
+
+			mData->roType = IV_ROT_TRIANGLE_STRIP;		
+
+			Vector3 translation = Vector3(0,0,0);
+			Entity *pEntity = createEntity(sceneMgr, s, mData, &translation);
+			if (newMaterial == NULL) newMaterial = material;
+			if (newMaterial != NULL) pEntity->setMaterialName(newMaterial->getName());
+				
+			triangleStripSceneNode->attachObject(pEntity);
+			triangleStripSceneNode->translate(translation);		
+
+		}
+
+		help = IVReaderoot->getNextChildNode();
+	}
+	if (meshDataCreated) if (mData != NULL) delete mData;
+}
+
Index: GTP-Internal/trunk/Lib/Vis/work/IVReader/src/ivnode.cpp
===================================================================
--- GTP-Internal/trunk/Lib/Vis/work/IVReader/src/ivnode.cpp	(revision 187)
+++ GTP-Internal/trunk/Lib/Vis/work/IVReader/src/ivnode.cpp	(revision 187)
@@ -0,0 +1,211 @@
+#include "ivnode.h"
+#include "ivreader.h"
+
+IVField::IVField()
+{
+	next = NULL;
+	typ = IV_STRING;
+}
+IVField::~IVField()
+{
+	if (value != NULL) free(value);
+	if (name != NULL) delete [] name;
+//	if (next != NULL) delete next;
+}
+
+IVNode::IVNode()
+{
+	parent = children = next = actual = NULL; 
+	name = NULL;
+	fields = NULL;
+}
+
+IVNode::IVNode(const char *s)
+{
+	name = new char[strlen(s)+1];
+	strcpy(name, s);
+	parent = children = next = actual = NULL;
+	fields = NULL;	
+}
+
+IVNode::~IVNode()
+{
+	if (name != NULL) delete[] name;
+	if (fields != NULL) 
+	{
+		IVField *help = fields, *delme = NULL;
+		while (help->next != NULL)
+		{
+			delme = help; help = help->next; delete delme;
+		}
+		delete help;
+	}
+	if (children != NULL) 
+	{
+		IVNode *help = children, *delme = NULL;
+		while (help->next != NULL)
+		{
+			delme = help; help = help->next; delete delme;
+		}
+		delete help;
+	}
+//	if (next != NULL) delete next;
+}
+
+
+
+
+void IVNode::attachNode(IVNode *child)
+{
+	if (children == NULL) children = child;
+	else 
+	{
+		IVNode *help = children;
+		while (help->next != NULL) help = help->next;
+		help->next = child;
+	}
+	child->parent = this;
+}
+
+
+void IVNode::print(int ident)
+{
+	if (IVReader::IVLog != NULL)
+	{
+		std::string msg = ""; 
+
+//		for (int i=0; i < ident; i++) fprintf(stdout, " ");
+		for (int i=0; i < ident; i++) msg = msg + " ";
+//		fprintf(stdout, "%s:\n", name);
+		msg = msg + name + ":";
+		IVReader::IVLog->logMessage(msg);
+
+		IVField *help = fields;
+		while (help != NULL)
+		{
+//			for (int i=0; i < ident; i++) fprintf(stdout, " ");
+			msg = "";
+			for (int i=0; i < ident; i++) msg = msg + " ";
+			
+			if (help->typ == IV_STRING)
+			{
+//				fprintf(stdout, "- %s: %s\n", help->name, (char *)help->value);
+				msg = msg + "- " + help->name + ": " + (char *)help->value;
+				IVReader::IVLog->logMessage(msg);
+			}
+			if (help->typ == IV_INT)
+			{
+//				fprintf(stdout, "- %s (%d): ", help->name, help->cnt);
+				msg = msg + "- " + help->name + "(" + IVReader::intToStr(help->cnt) + "): ";
+//				for (int i=0; i < help->cnt; i++) fprintf(stdout, " %d", ((int *)help->value)[i]);
+				for (int i=0; i < help->cnt; i++) msg = msg + " " + IVReader::realToStr(((float *)help->value)[i]);
+//				fprintf(stdout, "\n");
+				IVReader::IVLog->logMessage(msg);
+			}
+			if (help->typ == IV_REAL)
+			{
+//				fprintf(stdout, "- %s (%d):\n", help->name, help->cnt);
+				msg = msg + "- " + help->name + "(" + IVReader::intToStr(help->cnt) + "): ";
+				for (int i=0; i < help->cnt; i++) 
+				{				
+//					fprintf(stdout, " %.3f", ((float *)help->value)[i]);
+					msg = msg + " " + IVReader::realToStr(((float *)help->value)[i]);
+//					if (i % 3 == 2) fprintf(stdout, "\n");
+					if (i % 3 == 2) msg = msg + "\n";
+				}
+//				fprintf(stdout, "\n");
+				IVReader::IVLog->logMessage(msg);
+			}
+			help = help->next;
+		}	
+		if (children != NULL) { children->print(ident+3); }
+		if (next != NULL) next->print(ident);
+	}
+}
+
+void IVNode::addField(const char *name, void *value, int cnt, IVType typ)
+{
+	IVField *newone = new IVField();
+	newone->name = new char[strlen(name)+1];
+	strcpy(newone->name, name);
+/*
+	if (typ == IV_STRING)
+	{
+		newone->value = new char[strlen((char *)value)+1];
+		strcpy((char *)newone->value, (char *)value);
+	} else
+	if ((typ == IV_INT) || (typ == IV_REAL))
+	{
+		newone->value = new Ogre::Real[cnt];
+		memcpy(newone->value, value, cnt*sizeof(Ogre::Real));
+	}
+*/
+	newone->value = value;
+	newone->typ = typ;
+	newone->cnt = cnt;
+	newone->next = NULL;
+
+	if (fields == NULL) fields = newone;
+	else
+	{
+		IVField *help = fields;
+		while (help->next != NULL) help = help->next;
+		help->next = newone;
+	}
+}
+
+
+void IVNode::addField(const char *name, char *value)
+{
+	addField(name, value, 1, IV_STRING);
+}
+
+
+IVNode *IVNode::getNodeRecursive(const char *name)
+{
+	if (strcmp(name, this->name) == 0) return this;
+	if (this->children != NULL)
+	{
+		IVNode *help = this->children->getNodeRecursive(name);
+		if (help != NULL) return help;
+	}
+	if (this->next != NULL) return this->next->getNodeRecursive(name); else return NULL;
+}
+
+
+IVNode *IVNode::getNextChildNode(bool reset)
+{
+	if (reset) actual = this->children;
+	else if (actual == NULL) actual = this->children; else actual = actual->next;
+	return actual;	
+}
+
+
+IVField *IVNode::getField(const char *name)
+{
+	IVField *help = fields;
+	while (help != NULL)
+	{
+		if (strcmp(name, help->name) == 0) return help;
+		help = help->next;
+	}
+	return NULL;
+}
+
+void *IVNode::getField(const char *name, IVType *typ, int *cnt)
+{
+	IVField *help = fields;
+	while (help != NULL)
+	{
+		if (strcmp(name, help->name) == 0) 
+		{
+			*typ = help->typ;
+			*cnt = help->cnt;
+			return help->value;
+		}
+		help = help->next;
+	}
+	*typ = IV_INVALID;
+	*cnt = 0;
+	return NULL;
+}
Index: GTP-Internal/trunk/Lib/Vis/work/IVReader/src/ivmeshdata.cpp
===================================================================
--- GTP-Internal/trunk/Lib/Vis/work/IVReader/src/ivmeshdata.cpp	(revision 187)
+++ GTP-Internal/trunk/Lib/Vis/work/IVReader/src/ivmeshdata.cpp	(revision 187)
@@ -0,0 +1,263 @@
+#include "ivmeshdata.h"
+#include "ivreader.h"
+
+
+IVMeshData::IVMeshData()
+{ 
+	vertices = normals = texCoords = indices = normalIndices = texCoordIndices = NULL; 
+	vcnt = ncnt = tcnt = icnt = nicnt = ticnt = 0;
+	roType = IV_ROT_INVALID;
+	boundingBox = NULL;
+}
+
+IVMeshData::~IVMeshData()
+{ 
+}
+
+void IVMeshData::collapse()
+{
+	if (indices != NULL)	delete [] indices;
+	if (vertices != NULL)	delete [] vertices;
+	if (normals != NULL)	delete [] normals;
+	if (texCoords != NULL)	delete [] texCoords;
+	if (normalIndices != NULL) delete [] normalIndices;
+	if (texCoordIndices != NULL) delete [] texCoordIndices;
+	if (boundingBox != NULL) delete boundingBox;
+	indices = vertices = normals = texCoords = normalIndices = texCoords = NULL;
+	boundingBox = NULL;
+}
+
+int IVMeshData::getSeparatorCnt(Ogre::Real *data, int end)
+{
+	int cnt = 0;
+	for (int i=0; i < end; i++) if (data[i] < 0.f) cnt++; 
+	return cnt;
+}
+
+Ogre::AxisAlignedBox *IVMeshData::calcBoundingBox()
+{
+	if ((vertices == NULL) || (vcnt <=0)) return new Ogre::AxisAlignedBox(0, 0, 0, 0, 0, 0);
+	Ogre::Real x, y, z, minX, minY, minZ, maxX, maxY, maxZ;
+	minX = minY = minZ = 999999;
+	maxX = maxY = maxZ = -999999;
+	for (int i=0; i<vcnt/3; i++) 
+	{
+		x = vertices[i*3];
+		if (minX > x) minX = x;	if (maxX < x) maxX = x;
+		y = vertices[i*3+1];
+		if (minY > y) minY = y;	if (maxY < y) maxY = y;
+		z = vertices[i*3+2];
+		if (minZ > z) minZ = z;	if (maxZ < z) maxZ = z;
+	}
+	return new Ogre::AxisAlignedBox(minX, minY, minZ, maxX, maxY, maxZ);
+
+}
+
+
+Ogre::Real *IVMeshData::expandTriangleStripIndices(Ogre::Real *indices, int icnt, int *icntOut)
+{
+	if (indices[icnt-1] >= 0.0)
+		*icntOut = (icnt+1 - 3*(getSeparatorCnt(indices, icnt)+1))*3;
+	else
+		*icntOut = (icnt - 3*getSeparatorCnt(indices, icnt))*3;
+if (*icntOut < 0)
+int hoppla = 1;
+	Ogre::Real *indOut = new Ogre::Real[*icntOut];
+
+	int triangleCnt = 0, tc = 0;
+	for (int i=2; i < icnt; i++)
+	{
+		if (indices[i] >= 0)
+		{
+			if (tc % 2 == 0)
+			{
+				indOut[triangleCnt*3]   = indices[i-2]; 
+				indOut[triangleCnt*3+1] = indices[i-1];
+				indOut[triangleCnt*3+2] = indices[i];
+			}
+			else
+			{
+				indOut[triangleCnt*3]   = indices[i]; 
+				indOut[triangleCnt*3+1] = indices[i-1];
+				indOut[triangleCnt*3+2] = indices[i-2];
+			}
+			triangleCnt++; tc++;
+		}
+		else
+		{
+			i += 2; tc = 0;
+		}
+	}
+	return indOut;
+}	
+
+int IVMeshData::getNextFaceSize(int start)
+{
+	for (int i=start; i < icnt; i++) 
+	{
+		if (indices[i] < 0.f) return i - start;
+	}
+	return icnt - start;
+}
+
+Ogre::Real *IVMeshData::expandFaceSetIndices(Ogre::Real *indices, int icnt, int *icntOut)
+{
+	if (indices[icnt-1] >= 0.0)
+		*icntOut = (icnt+1 - 3*(getSeparatorCnt(indices, icnt)+1))*3;
+	else
+		*icntOut = (icnt - 3*getSeparatorCnt(indices, icnt))*3;
+	Ogre::Real *indOut = new Ogre::Real[*icntOut];
+
+	int index = 0, size = 0;
+	for (int i=0; i < icnt; i++)
+	{
+		if ((size = getNextFaceSize(i)) < 3) break;
+		for (int j=0; j < size-2; j++)
+		{
+			indOut[index] = indices[i]; index++;
+			indOut[index] = indices[i+1+j]; index++;
+			indOut[index] = indices[i+2+j]; index++;
+		}
+		i = i + size; 
+	}
+	return indOut;
+}
+
+IVMeshData *IVMeshData::expand()
+{
+	using namespace Ogre;
+
+	IVMeshData *mDataOut = new IVMeshData();
+
+	mDataOut->boundingBox = calcBoundingBox();
+	if ((vertices == NULL) || (vcnt <= 0) || (indices == NULL) || (icnt <= 0))
+	{
+		if (IVReader::IVLog != NULL)
+		{
+			std::string message = "Expand-Error: ((vertices == NULL) || (vcnt <= 0) || (indices == NULL) || (icnt <= 0))";
+			IVReader::IVLog->logMessage(message);
+		}
+	
+		return mDataOut;
+	}
+	bool nOk, tOk, niOk, tiOk, nperv, tperv;
+	nOk = ((normals != NULL) && (ncnt > 0));
+	tOk = ((texCoords != NULL) && (tcnt > 0));
+	nperv = (ncnt == vcnt) && (nicnt != icnt);
+	tperv = (tcnt*3 == vcnt*2) && (ticnt != icnt);
+
+	if ((nOk && !nperv) || (tOk && !tperv)) 
+	{
+		niOk = ((normalIndices != NULL) && (nicnt == icnt));
+		tiOk = ((texCoordIndices != NULL) && (ticnt == icnt));
+
+		if (!nperv && nOk && !niOk) nOk = false;
+		if (!tperv && tOk && !tiOk) tOk = false;
+
+		int sepcnt = getSeparatorCnt(indices, icnt);
+		mDataOut->icnt = icnt;
+		mDataOut->vcnt = (icnt - sepcnt)*3;
+		mDataOut->vertices = new Real[mDataOut->vcnt];
+
+		if (nOk) 
+		{
+			mDataOut->ncnt = mDataOut->vcnt;
+			mDataOut->normals = new Real[mDataOut->ncnt];
+		}
+		if (tOk)
+		{
+			mDataOut->tcnt = (icnt - sepcnt)*2;
+			mDataOut->texCoords = new Real[mDataOut->tcnt];
+		}
+		mDataOut->indices = new Real[mDataOut->icnt];
+
+		int index = 0;
+		for (int i=0; i < icnt; i++)
+		{
+			if (indices[i] >= 0.f)
+			{
+				mDataOut->vertices[index*3]   = vertices[(int)indices[i]*3];
+				mDataOut->vertices[index*3+1] = vertices[(int)indices[i]*3+1];
+				mDataOut->vertices[index*3+2] = vertices[(int)indices[i]*3+2];
+
+				if (nOk)
+				{
+					if (nperv)
+					{
+						mDataOut->normals[index*3]   = normals[(int)indices[i]*3];
+						mDataOut->normals[index*3+1] = normals[(int)indices[i]*3+1];
+						mDataOut->normals[index*3+2] = normals[(int)indices[i]*3+2];
+					}
+					else
+					{
+						mDataOut->normals[index*3]   = normals[(int)normalIndices[i]*3];
+						mDataOut->normals[index*3+1] = normals[(int)normalIndices[i]*3+1];
+						mDataOut->normals[index*3+2] = normals[(int)normalIndices[i]*3+2];
+					}
+				}
+				if (tOk)
+				{
+					if (tperv)
+					{
+						mDataOut->texCoords[index*2]   = texCoords[(int)indices[i]*2];
+						mDataOut->texCoords[index*2+1] = texCoords[(int)indices[i]*2+1];
+					}
+					else
+					{
+						mDataOut->texCoords[index*2]   = texCoords[(int)texCoordIndices[i]*2];
+						mDataOut->texCoords[index*2+1] = texCoords[(int)texCoordIndices[i]*2+1];
+					}
+				}
+
+				mDataOut->indices[i] = index;
+				index++;
+			}
+			else mDataOut->indices[i] = indices[i];
+		}
+	}
+	else
+	{
+		mDataOut->icnt = icnt;
+		mDataOut->indices = new Real[mDataOut->icnt];
+		memcpy(mDataOut->indices, indices, mDataOut->icnt*sizeof(Real));
+
+		mDataOut->vcnt = vcnt;
+		mDataOut->vertices = new Real[mDataOut->vcnt];
+		memcpy(mDataOut->vertices, vertices, mDataOut->vcnt*sizeof(Real));
+
+		if (nOk)
+		{
+			mDataOut->ncnt = ncnt;
+			mDataOut->normals = new Real[mDataOut->ncnt];
+			memcpy(mDataOut->normals, normals, mDataOut->ncnt*sizeof(Real));
+		}
+		if (tOk)
+		{
+			mDataOut->tcnt = tcnt;
+			mDataOut->texCoords = new Real[mDataOut->tcnt];
+			memcpy(mDataOut->texCoords, texCoords, mDataOut->tcnt*sizeof(Real));
+		}
+
+	}
+
+	int icntNew = 0;
+	Real *indicesNew = NULL;
+	mDataOut->roType = roType;
+	if (mDataOut->roType == IV_ROT_TRIANGLE_STRIP)	
+	{	
+		indicesNew = expandTriangleStripIndices(mDataOut->indices, mDataOut->icnt, &icntNew);
+	}
+	else if (mDataOut->roType == IV_ROT_FACE_SET)
+	{
+		indicesNew = expandFaceSetIndices(mDataOut->indices, mDataOut->icnt, &icntNew);
+	}
+	else 
+	{
+		return mDataOut;
+	}
+	delete [] mDataOut->indices;
+	mDataOut->indices = indicesNew;
+	mDataOut->icnt = icntNew;
+
+	return mDataOut;
+}
Index: GTP-Internal/trunk/Lib/Vis/work/tinyxml/tinyxmlerror.cpp
===================================================================
--- GTP-Internal/trunk/Lib/Vis/work/tinyxml/tinyxmlerror.cpp	(revision 61)
+++ GTP-Internal/trunk/Lib/Vis/work/tinyxml/tinyxmlerror.cpp	(revision 61)
@@ -0,0 +1,50 @@
+/*
+www.sourceforge.net/projects/tinyxml
+Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com)
+
+This software is provided 'as-is', without any express or implied 
+warranty. In no event will the authors be held liable for any 
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any 
+purpose, including commercial applications, and to alter it and 
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must
+not claim that you wrote the original software. If you use this
+software in a product, an acknowledgment in the product documentation
+would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and
+must not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source
+distribution.
+*/
+
+#include "tinyxml.h"
+
+// The goal of the seperate error file is to make the first
+// step towards localization. tinyxml (currently) only supports
+// latin-1, but at least the error messages could now be translated.
+//
+// It also cleans up the code a bit.
+//
+
+const char* TiXmlBase::errorString[ TIXML_ERROR_STRING_COUNT ] =
+{
+	"No error",
+	"Error",
+	"Failed to open file",
+	"Memory allocation failed.",
+	"Error parsing Element.",
+	"Failed to read Element name",
+	"Error reading Element value.",
+	"Error reading Attributes.",
+	"Error: empty tag.",
+	"Error reading end tag.",
+	"Error parsing Unknown.",
+	"Error parsing Comment.",
+	"Error parsing Declaration.",
+	"Error document empty."
+};
Index: GTP-Internal/trunk/Lib/Vis/work/tinyxml/tinystr.h
===================================================================
--- GTP-Internal/trunk/Lib/Vis/work/tinyxml/tinystr.h	(revision 61)
+++ GTP-Internal/trunk/Lib/Vis/work/tinyxml/tinystr.h	(revision 61)
@@ -0,0 +1,228 @@
+/*
+www.sourceforge.net/projects/tinyxml
+Original file by Yves Berquin.
+
+This software is provided 'as-is', without any express or implied 
+warranty. In no event will the authors be held liable for any 
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any 
+purpose, including commercial applications, and to alter it and 
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must 
+not claim that you wrote the original software. If you use this 
+software in a product, an acknowledgment in the product documentation 
+would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and
+must not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source 
+distribution.
+*/
+
+#include "tinyxml.h"
+
+
+#ifndef TIXML_USE_STL
+
+#ifndef TIXML_STRING_INCLUDED
+#define TIXML_STRING_INCLUDED
+
+#pragma warning( disable : 4514 )
+
+#include <assert.h>
+
+/**
+   TiXmlString is an emulation of the std::string template.
+   Its purpose is to allow compiling TinyXML on compilers with no or poor STL support.
+   Only the member functions relevant to the TinyXML project have been implemented.
+   The buffer allocation is made by a simplistic power of 2 like mechanism : if we increase
+   a string and there's no more room, we allocate a buffer twice as big as we need.
+*/
+class TiXmlString
+{
+  public :
+    // TiXmlString constructor, based on a string
+    TiXmlString (const char * instring);
+
+    // TiXmlString empty constructor
+    TiXmlString ()
+    {
+        allocated = 0;
+        cstring = NULL;
+    }
+
+    // TiXmlString copy constructor
+    TiXmlString (const TiXmlString& copy);
+
+    // TiXmlString destructor
+    ~ TiXmlString ()
+    {
+        empty_it ();
+    }
+
+    // Convert a TiXmlString into a classical char *
+    const char * c_str () const
+    {
+        if (allocated)
+            return cstring;
+        return "";
+    }
+
+    // Return the length of a TiXmlString
+    unsigned length () const;
+
+    // TiXmlString = operator
+    void operator = (const char * content);
+
+    // = operator
+    void operator = (const TiXmlString & copy);
+
+    // += operator. Maps to append
+    TiXmlString& operator += (const char * suffix)
+    {
+        append (suffix);
+		return *this;
+    }
+
+    // += operator. Maps to append
+    TiXmlString& operator += (char single)
+    {
+        append (single);
+		return *this;
+    }
+
+    // += operator. Maps to append
+    TiXmlString& operator += (TiXmlString & suffix)
+    {
+        append (suffix);
+		return *this;
+    }
+    bool operator == (const TiXmlString & compare) const;
+    bool operator < (const TiXmlString & compare) const;
+    bool operator > (const TiXmlString & compare) const;
+
+    // Checks if a TiXmlString is empty
+    bool empty () const
+    {
+        return length () ? false : true;
+    }
+
+    // Checks if a TiXmlString contains only whitespace (same rules as isspace)
+	// Not actually used in tinyxml. Conflicts with a C macro, "isblank",
+	// which is a problem. Commenting out. -lee
+//    bool isblank () const;
+
+    // single char extraction
+    const char& at (unsigned index) const
+    {
+        assert( index < length ());
+        return cstring [index];
+    }
+
+    // find a char in a string. Return TiXmlString::notfound if not found
+    unsigned find (char lookup) const
+    {
+        return find (lookup, 0);
+    }
+
+    // find a char in a string from an offset. Return TiXmlString::notfound if not found
+    unsigned find (char tofind, unsigned offset) const;
+
+    /*	Function to reserve a big amount of data when we know we'll need it. Be aware that this
+		function clears the content of the TiXmlString if any exists.
+    */
+    void reserve (unsigned size)
+    {
+        empty_it ();
+        if (size)
+        {
+            allocated = size;
+            cstring = new char [size];
+            cstring [0] = 0;
+        }
+    }
+
+    // [] operator 
+    char& operator [] (unsigned index) const
+    {
+        assert( index < length ());
+        return cstring [index];
+    }
+
+    // Error value for find primitive 
+    enum {	notfound = 0xffffffff,
+            npos = notfound };
+
+    void append (const char *str, int len );
+
+  protected :
+
+    // The base string
+    char * cstring;
+    // Number of chars allocated
+    unsigned allocated;
+
+    // New size computation. It is simplistic right now : it returns twice the amount
+    // we need
+    unsigned assign_new_size (unsigned minimum_to_allocate)
+    {
+        return minimum_to_allocate * 2;
+    }
+
+    // Internal function that clears the content of a TiXmlString
+    void empty_it ()
+    {
+        if (cstring)
+            delete [] cstring;
+        cstring = NULL;
+        allocated = 0;
+    }
+
+    void append (const char *suffix );
+
+    // append function for another TiXmlString
+    void append (const TiXmlString & suffix)
+    {
+        append (suffix . c_str ());
+    }
+
+    // append for a single char. This could be improved a lot if needed
+    void append (char single)
+    {
+        char smallstr [2];
+        smallstr [0] = single;
+        smallstr [1] = 0;
+        append (smallstr);
+    }
+
+} ;
+
+/** 
+   TiXmlOutStream is an emulation of std::ostream. It is based on TiXmlString.
+   Only the operators that we need for TinyXML have been developped.
+*/
+class TiXmlOutStream : public TiXmlString
+{
+public :
+    TiXmlOutStream () : TiXmlString () {}
+
+    // TiXmlOutStream << operator. Maps to TiXmlString::append
+    TiXmlOutStream & operator << (const char * in)
+    {
+        append (in);
+        return (* this);
+    }
+
+    // TiXmlOutStream << operator. Maps to TiXmlString::append
+    TiXmlOutStream & operator << (const TiXmlString & in)
+    {
+        append (in . c_str ());
+        return (* this);
+    }
+} ;
+
+#endif	// TIXML_STRING_INCLUDED
+#endif	// TIXML_USE_STL
Index: GTP-Internal/trunk/Lib/Vis/work/tinyxml/tinyxmlparser.cpp
===================================================================
--- GTP-Internal/trunk/Lib/Vis/work/tinyxml/tinyxmlparser.cpp	(revision 61)
+++ GTP-Internal/trunk/Lib/Vis/work/tinyxml/tinyxmlparser.cpp	(revision 61)
@@ -0,0 +1,939 @@
+/*
+www.sourceforge.net/projects/tinyxml
+Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com)
+
+This software is provided 'as-is', without any express or implied 
+warranty. In no event will the authors be held liable for any 
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any 
+purpose, including commercial applications, and to alter it and 
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must 
+not claim that you wrote the original software. If you use this
+software in a product, an acknowledgment in the product documentation
+would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and 
+must not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source 
+distribution.
+*/
+
+#include "tinyxml.h"
+#include <ctype.h>
+
+//#define DEBUG_PARSER
+
+// Note tha "PutString" hardcodes the same list. This
+// is less flexible than it appears. Changing the entries
+// or order will break putstring.	
+TiXmlBase::Entity TiXmlBase::entity[ NUM_ENTITY ] = 
+{
+	{ "&amp;",  5, '&' },
+	{ "&lt;",   4, '<' },
+	{ "&gt;",   4, '>' },
+	{ "&quot;", 6, '\"' },
+	{ "&apos;", 6, '\'' }
+};
+
+
+const char* TiXmlBase::SkipWhiteSpace( const char* p )
+{
+	if ( !p || !*p )
+	{
+		return 0;
+	}
+	while ( p && *p )
+	{
+		if ( isspace( *p ) || *p == '\n' || *p =='\r' )		// Still using old rules for white space.
+			++p;
+		else
+			break;
+	}
+
+	return p;
+}
+
+#ifdef TIXML_USE_STL
+/*static*/ bool TiXmlBase::StreamWhiteSpace( TIXML_ISTREAM * in, TIXML_STRING * tag )
+{
+	for( ;; )
+	{
+		if ( !in->good() ) return false;
+
+		int c = in->peek();
+		if ( !IsWhiteSpace( c ) )
+			return true;
+		*tag += in->get();
+	}
+}
+
+/*static*/ bool TiXmlBase::StreamTo( TIXML_ISTREAM * in, int character, TIXML_STRING * tag )
+{
+	while ( in->good() )
+	{
+		int c = in->peek();
+		if ( c == character )
+			return true;
+
+		in->get();
+		*tag += c;
+	}
+	return false;
+}
+#endif
+
+const char* TiXmlBase::ReadName( const char* p, TIXML_STRING * name )
+{
+	*name = "";
+	assert( p );
+
+	// Names start with letters or underscores.
+	// After that, they can be letters, underscores, numbers,
+	// hyphens, or colons. (Colons are valid ony for namespaces,
+	// but tinyxml can't tell namespaces from names.)
+	if (    p && *p 
+		 && ( isalpha( (unsigned char) *p ) || *p == '_' ) )
+	{
+		while(		p && *p
+				&&	(		isalnum( (unsigned char ) *p ) 
+						 || *p == '_'
+						 || *p == '-'
+						 || *p == ':' ) )
+		{
+			(*name) += *p;
+			++p;
+		}
+		return p;
+	}
+	return 0;
+}
+
+const char* TiXmlBase::GetEntity( const char* p, char* value )
+{
+	// Presume an entity, and pull it out.
+    TIXML_STRING ent;
+	int i;
+
+	// Ignore the &#x entities.
+	if (    strncmp( "&#x", p, 3 ) == 0 
+	     && *(p+3) 
+		 && *(p+4) )
+	{
+		*value = 0;
+		
+		if ( isalpha( *(p+3) ) ) *value += ( tolower( *(p+3) ) - 'a' + 10 ) * 16;
+		else				     *value += ( *(p+3) - '0' ) * 16;
+
+		if ( isalpha( *(p+4) ) ) *value += ( tolower( *(p+4) ) - 'a' + 10 );
+		else				     *value += ( *(p+4) - '0' );
+
+		return p+6;
+	}
+
+	// Now try to match it.
+	for( i=0; i<NUM_ENTITY; ++i )
+	{
+		if ( strncmp( entity[i].str, p, entity[i].strLength ) == 0 )
+		{
+			assert( strlen( entity[i].str ) == entity[i].strLength );
+			*value = entity[i].chr;
+			return ( p + entity[i].strLength );
+		}
+	}
+
+	// So it wasn't an entity, its unrecognized, or something like that.
+	*value = *p;	// Don't put back the last one, since we return it!
+	return p+1;
+}
+
+
+bool TiXmlBase::StringEqual( const char* p,
+							 const char* tag,
+							 bool ignoreCase )
+{
+	assert( p );
+	if ( !p || !*p )
+	{
+		assert( 0 );
+		return false;
+	}
+
+    if ( tolower( *p ) == tolower( *tag ) )
+	{
+		const char* q = p;
+
+		if (ignoreCase)
+		{
+			while ( *q && *tag && *q == *tag )
+			{
+				++q;
+				++tag;
+			}
+
+			if ( *tag == 0 )		// Have we found the end of the tag, and everything equal?
+			{
+				return true;
+			}
+		}
+		else
+		{
+			while ( *q && *tag && tolower( *q ) == tolower( *tag ) )
+			{
+				++q;
+				++tag;
+			}
+
+			if ( *tag == 0 )
+			{
+				return true;
+			}
+		}
+	}
+	return false;
+}
+
+const char* TiXmlBase::ReadText(	const char* p, 
+									TIXML_STRING * text, 
+									bool trimWhiteSpace, 
+									const char* endTag, 
+									bool caseInsensitive )
+{
+    *text = "";
+	if (    !trimWhiteSpace			// certain tags always keep whitespace
+		 || !condenseWhiteSpace )	// if true, whitespace is always kept
+	{
+		// Keep all the white space.
+		while (	   p && *p
+				&& !StringEqual( p, endTag, caseInsensitive )
+			  )
+		{
+			char c;
+			p = GetChar( p, &c );
+            (* text) += c;
+		}
+	}
+	else
+	{
+		bool whitespace = false;
+
+		// Remove leading white space:
+		p = SkipWhiteSpace( p );
+		while (	   p && *p
+				&& !StringEqual( p, endTag, caseInsensitive ) )
+		{
+			if ( *p == '\r' || *p == '\n' )
+			{
+				whitespace = true;
+				++p;
+			}
+			else if ( isspace( *p ) )
+			{
+				whitespace = true;
+				++p;
+			}
+			else
+			{
+				// If we've found whitespace, add it before the
+				// new character. Any whitespace just becomes a space.
+				if ( whitespace )
+				{
+               (* text) += ' ';
+					whitespace = false;
+				}
+				char c;
+				p = GetChar( p, &c );
+            (* text) += c;
+			}
+		}
+	}
+	return p + strlen( endTag );
+}
+
+#ifdef TIXML_USE_STL
+
+void TiXmlDocument::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag )
+{
+	// The basic issue with a document is that we don't know what we're
+	// streaming. Read something presumed to be a tag (and hope), then
+	// identify it, and call the appropriate stream method on the tag.
+	//
+	// This "pre-streaming" will never read the closing ">" so the
+	// sub-tag can orient itself.
+
+	if ( !StreamTo( in, '<', tag ) ) 
+	{
+		SetError( TIXML_ERROR_PARSING_EMPTY );
+		return;
+	}
+
+	while ( in->good() )
+	{
+		size_t tagIndex = tag->length();
+		while ( in->good() && in->peek() != '>' )
+		{
+			int c = in->get();
+			(*tag) += (char) c;
+		}
+
+		if ( in->good() )
+		{
+			// We now have something we presume to be a node of 
+			// some sort. Identify it, and call the node to
+			// continue streaming.
+			TiXmlNode* node = Identify( tag->c_str() + tagIndex );
+
+			if ( node )
+			{
+				node->StreamIn( in, tag );
+				bool isElement = node->ToElement() != 0;
+				delete node;
+				node = 0;
+
+				// If this is the root element, we're done. Parsing will be
+				// done by the >> operator.
+				if ( isElement )
+				{
+					return;
+				}
+			}
+			else
+			{
+				SetError( TIXML_ERROR );
+				return;
+			}
+		}
+	}
+	// We should have returned sooner.
+	SetError( TIXML_ERROR );
+}
+
+#endif
+
+const char* TiXmlDocument::Parse( const char* p )
+{
+	// Parse away, at the document level. Since a document
+	// contains nothing but other tags, most of what happens
+	// here is skipping white space.
+	//
+	// In this variant (as opposed to stream and Parse) we
+	// read everything we can.
+
+
+	if ( !p || !*p )
+	{
+		SetError( TIXML_ERROR_DOCUMENT_EMPTY );
+		return false;
+	}
+
+    p = SkipWhiteSpace( p );
+	if ( !p )
+	{
+		SetError( TIXML_ERROR_DOCUMENT_EMPTY );
+		return false;
+	}
+
+	while ( p && *p )
+	{
+		TiXmlNode* node = Identify( p );
+		if ( node )
+		{
+			p = node->Parse( p );
+			LinkEndChild( node );
+		}
+		else
+		{
+			break;
+		}
+		p = SkipWhiteSpace( p );
+	}
+	// All is well.
+	return p;
+}
+
+
+TiXmlNode* TiXmlNode::Identify( const char* p )
+{
+	TiXmlNode* returnNode = 0;
+
+	p = SkipWhiteSpace( p );
+	if( !p || !*p || *p != '<' )
+	{
+		return 0;
+	}
+
+	TiXmlDocument* doc = GetDocument();
+	p = SkipWhiteSpace( p );
+
+	if ( !p || !*p )
+	{
+		return 0;
+	}
+
+	// What is this thing? 
+	// - Elements start with a letter or underscore, but xml is reserved.
+	// - Comments: <!--
+	// - Decleration: <?xml
+	// - Everthing else is unknown to tinyxml.
+	//
+
+	const char* xmlHeader = { "<?xml" };
+	const char* commentHeader = { "<!--" };
+
+	if ( StringEqual( p, xmlHeader, true ) )
+	{
+		#ifdef DEBUG_PARSER
+			TIXML_LOG( "XML parsing Declaration\n" );
+		#endif
+		returnNode = new TiXmlDeclaration();
+	}
+	else if (    isalpha( *(p+1) )
+			  || *(p+1) == '_' )
+	{
+		#ifdef DEBUG_PARSER
+			TIXML_LOG( "XML parsing Element\n" );
+		#endif
+		returnNode = new TiXmlElement( "" );
+	}
+	else if ( StringEqual( p, commentHeader, false ) )
+	{
+		#ifdef DEBUG_PARSER
+			TIXML_LOG( "XML parsing Comment\n" );
+		#endif
+		returnNode = new TiXmlComment();
+	}
+	else
+	{
+		#ifdef DEBUG_PARSER
+			TIXML_LOG( "XML parsing Unknown\n" );
+		#endif
+		returnNode = new TiXmlUnknown();
+	}
+
+	if ( returnNode )
+	{
+		// Set the parent, so it can report errors
+		returnNode->parent = this;
+		//p = returnNode->Parse( p );
+	}
+	else
+	{
+		if ( doc )
+			doc->SetError( TIXML_ERROR_OUT_OF_MEMORY );
+	}
+	return returnNode;
+}
+
+#ifdef TIXML_USE_STL
+
+void TiXmlElement::StreamIn (TIXML_ISTREAM * in, TIXML_STRING * tag)
+{
+	// We're called with some amount of pre-parsing. That is, some of "this"
+	// element is in "tag". Go ahead and stream to the closing ">"
+	while( in->good() )
+	{
+		int c = in->get();
+		(*tag) += (char) c ;
+		
+		if ( c == '>' )
+			break;
+	}
+
+	if ( tag->length() < 3 ) return;
+
+	// Okay...if we are a "/>" tag, then we're done. We've read a complete tag.
+	// If not, identify and stream.
+
+	if (    tag->at( tag->length() - 1 ) == '>' 
+		 && tag->at( tag->length() - 2 ) == '/' )
+	{
+		// All good!
+		return;
+	}
+	else if ( tag->at( tag->length() - 1 ) == '>' )
+	{
+		// There is more. Could be:
+		//		text
+		//		closing tag
+		//		another node.
+		for ( ;; )
+		{
+			StreamWhiteSpace( in, tag );
+
+			// Do we have text?
+			if ( in->peek() != '<' )
+			{
+				// Yep, text.
+				TiXmlText text( "" );
+				text.StreamIn( in, tag );
+
+				// What follows text is a closing tag or another node.
+				// Go around again and figure it out.
+				continue;
+			}
+
+			// We now have either a closing tag...or another node.
+			// We should be at a "<", regardless.
+			if ( !in->good() ) return;
+			assert( in->peek() == '<' );
+			size_t tagIndex = tag->length();
+
+			bool closingTag = false;
+			bool firstCharFound = false;
+
+			for( ;; )
+			{
+				if ( !in->good() )
+					return;
+
+				int c = in->peek();
+				
+				if ( c == '>' )
+					break;
+
+				*tag += c;
+				in->get();
+
+				if ( !firstCharFound && c != '<' && !IsWhiteSpace( c ) )
+				{
+					firstCharFound = true;
+					if ( c == '/' )
+						closingTag = true;
+				}
+			}
+			// If it was a closing tag, then read in the closing '>' to clean up the input stream.
+			// If it was not, the streaming will be done by the tag.
+			if ( closingTag )
+			{
+				int c = in->get();
+				assert( c == '>' );
+				*tag += c;
+
+				// We are done, once we've found our closing tag.
+				return;
+			}
+			else
+			{
+				// If not a closing tag, id it, and stream.
+				const char* tagloc = tag->c_str() + tagIndex;
+				TiXmlNode* node = Identify( tagloc );
+				if ( !node )
+					return;
+				node->StreamIn( in, tag );
+				delete node;
+				node = 0;
+
+				// No return: go around from the beginning: text, closing tag, or node.
+			}
+		}
+	}
+}
+#endif
+
+const char* TiXmlElement::Parse( const char* p )
+{
+	p = SkipWhiteSpace( p );
+	TiXmlDocument* document = GetDocument();
+
+	if ( !p || !*p || *p != '<' )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT );
+		return false;
+	}
+
+	p = SkipWhiteSpace( p+1 );
+
+	// Read the name.
+    p = ReadName( p, &value );
+	if ( !p || !*p )
+	{
+		if ( document )	document->SetError( TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME );
+		return false;
+	}
+
+    TIXML_STRING endTag ("</");
+	endTag += value;
+	endTag += ">";
+
+	// Check for and read attributes. Also look for an empty
+	// tag or an end tag.
+	while ( p && *p )
+	{
+		p = SkipWhiteSpace( p );
+		if ( !p || !*p )
+		{
+			if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES );
+			return 0;
+		}
+		if ( *p == '/' )
+		{
+			++p;
+			// Empty tag.
+			if ( *p  != '>' )
+			{
+				if ( document ) document->SetError( TIXML_ERROR_PARSING_EMPTY );		
+				return 0;
+			}
+			return (p+1);
+		}
+		else if ( *p == '>' )
+		{
+			// Done with attributes (if there were any.)
+			// Read the value -- which can include other
+			// elements -- read the end tag, and return.
+			++p;
+			p = ReadValue( p );		// Note this is an Element method, and will set the error if one happens.
+			if ( !p || !*p )
+				return 0;
+
+			// We should find the end tag now
+			if ( StringEqual( p, endTag.c_str(), false ) )
+			{
+				p += endTag.length();
+				return p;
+			}
+			else
+			{
+				if ( document ) document->SetError( TIXML_ERROR_READING_END_TAG );
+				return 0;
+			}
+		}
+		else
+		{
+			// Try to read an element:
+			TiXmlAttribute attrib;
+			attrib.SetDocument( document );
+			p = attrib.Parse( p );
+
+			if ( !p || !*p )
+			{
+				if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT );
+				return 0;
+			}
+			SetAttribute( attrib.Name(), attrib.Value() );
+		}
+	}
+	return p;
+}
+
+
+const char* TiXmlElement::ReadValue( const char* p )
+{
+	TiXmlDocument* document = GetDocument();
+
+	// Read in text and elements in any order.
+	p = SkipWhiteSpace( p );
+	while ( p && *p )
+	{
+		if ( *p != '<' )
+		{
+			// Take what we have, make a text element.
+			TiXmlText* textNode = new TiXmlText( "" );
+
+			if ( !textNode )
+			{
+				if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY );
+				    return 0;
+			}
+
+			p = textNode->Parse( p );
+
+			if ( !textNode->Blank() )
+				LinkEndChild( textNode );
+			else
+				delete textNode;
+		} 
+		else 
+		{
+			// We hit a '<'
+			// Have we hit a new element or an end tag?
+			if ( StringEqual( p, "</", false ) )
+			{
+				return p;
+			}
+			else
+			{
+				TiXmlNode* node = Identify( p );
+				if ( node )
+				{
+					p = node->Parse( p );
+					LinkEndChild( node );
+				}				
+				else
+				{
+					return 0;
+				}
+			}
+		}
+		p = SkipWhiteSpace( p );
+	}
+
+	if ( !p )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_READING_ELEMENT_VALUE );
+	}	
+	return p;
+}
+
+
+#ifdef TIXML_USE_STL
+void TiXmlUnknown::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag )
+{
+	while ( in->good() )
+	{
+		int c = in->get();	
+		(*tag) += c;
+
+		if ( c == '>' )
+		{
+			// All is well.
+			return;		
+		}
+	}
+}
+#endif
+
+
+const char* TiXmlUnknown::Parse( const char* p )
+{
+	TiXmlDocument* document = GetDocument();
+	p = SkipWhiteSpace( p );
+	if ( !p || !*p || *p != '<' )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_PARSING_UNKNOWN );
+		return 0;
+	}
+	++p;
+    value = "";
+
+	while ( p && *p && *p != '>' )
+	{
+		value += *p;
+		++p;
+	}
+
+	if ( !p )
+	{
+		if ( document )	document->SetError( TIXML_ERROR_PARSING_UNKNOWN );
+	}
+	if ( *p == '>' )
+		return p+1;
+	return p;
+}
+
+#ifdef TIXML_USE_STL
+void TiXmlComment::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag )
+{
+	while ( in->good() )
+	{
+		int c = in->get();	
+		(*tag) += c;
+
+		if ( c == '>' 
+			 && tag->at( tag->length() - 2 ) == '-'
+			 && tag->at( tag->length() - 3 ) == '-' )
+		{
+			// All is well.
+			return;		
+		}
+	}
+}
+#endif
+
+
+const char* TiXmlComment::Parse( const char* p )
+{
+	TiXmlDocument* document = GetDocument();
+	value = "";
+
+	p = SkipWhiteSpace( p );
+	const char* startTag = "<!--";
+	const char* endTag   = "-->";
+
+	if ( !StringEqual( p, startTag, false ) )
+	{
+		document->SetError( TIXML_ERROR_PARSING_COMMENT );
+		return 0;
+	}
+	p += strlen( startTag );
+	p = ReadText( p, &value, false, endTag, false );
+	return p;
+}
+
+
+const char* TiXmlAttribute::Parse( const char* p )
+{
+	p = SkipWhiteSpace( p );
+	if ( !p || !*p ) return 0;
+
+	// Read the name, the '=' and the value.
+	p = ReadName( p, &name );
+	if ( !p || !*p )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES );
+		return 0;
+	}
+	p = SkipWhiteSpace( p );
+	if ( !p || !*p || *p != '=' )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES );
+		return 0;
+	}
+
+	++p;	// skip '='
+	p = SkipWhiteSpace( p );
+	if ( !p || !*p )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES );
+		return 0;
+	}
+	
+	const char* end;
+
+	if ( *p == '\'' )
+	{
+		++p;
+		end = "\'";
+		p = ReadText( p, &value, false, end, false );
+	}
+	else if ( *p == '"' )
+	{
+		++p;
+		end = "\"";
+		p = ReadText( p, &value, false, end, false );
+	}
+	else
+	{
+		// All attribute values should be in single or double quotes.
+		// But this is such a common error that the parser will try
+		// its best, even without them.
+		value = "";
+		while (    p && *p										// existence
+				&& !isspace( *p ) && *p != '\n' && *p != '\r'	// whitespace
+				&& *p != '/' && *p != '>' )						// tag end
+		{
+			value += *p;
+			++p;
+		}
+	}
+	return p;
+}
+
+#ifdef TIXML_USE_STL
+void TiXmlText::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag )
+{
+	while ( in->good() )
+	{
+		int c = in->peek();	
+		if ( c == '<' )
+			return;
+
+		(*tag) += c;
+		in->get();
+	}
+}
+#endif
+
+const char* TiXmlText::Parse( const char* p )
+{
+	value = "";
+
+	//TiXmlDocument* doc = GetDocument();
+	bool ignoreWhite = true;
+//	if ( doc && !doc->IgnoreWhiteSpace() ) ignoreWhite = false;
+
+	const char* end = "<";
+	p = ReadText( p, &value, ignoreWhite, end, false );
+	if ( p )
+		return p-1;	// don't truncate the '<'
+	return 0;
+}
+
+#ifdef TIXML_USE_STL
+void TiXmlDeclaration::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag )
+{
+	while ( in->good() )
+	{
+		int c = in->get();
+		(*tag) += c;
+
+		if ( c == '>' )
+		{
+			// All is well.
+			return;
+		}
+	}
+}
+#endif
+
+const char* TiXmlDeclaration::Parse( const char* p )
+{
+	p = SkipWhiteSpace( p );
+	// Find the beginning, find the end, and look for
+	// the stuff in-between.
+	TiXmlDocument* document = GetDocument();
+	if ( !p || !*p || !StringEqual( p, "<?xml", true ) )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_PARSING_DECLARATION );
+		return 0;
+	}
+
+	p += 5;
+//	const char* start = p+5;
+//	const char* end  = strstr( start, "?>" );
+
+	version = "";
+	encoding = "";
+	standalone = "";
+
+	while ( p && *p )
+	{
+		if ( *p == '>' )
+		{
+			++p;
+			return p;
+		}
+
+		p = SkipWhiteSpace( p );
+		if ( StringEqual( p, "version", true ) )
+		{
+//			p += 7;
+			TiXmlAttribute attrib;
+			p = attrib.Parse( p );		
+			version = attrib.Value();
+		}
+		else if ( StringEqual( p, "encoding", true ) )
+		{
+//			p += 8;
+			TiXmlAttribute attrib;
+			p = attrib.Parse( p );		
+			encoding = attrib.Value();
+		}
+		else if ( StringEqual( p, "standalone", true ) )
+		{
+//			p += 10;
+			TiXmlAttribute attrib;
+			p = attrib.Parse( p );		
+			standalone = attrib.Value();
+		}
+		else
+		{
+			// Read over whatever it is.
+			while( p && *p && *p != '>' && !isspace( *p ) )
+				++p;
+		}
+	}
+	return 0;
+}
+
+bool TiXmlText::Blank() const
+{
+	for ( unsigned i=0; i<value.length(); i++ )
+		if ( !isspace( value[i] ) )
+			return false;
+	return true;
+}
+
Index: GTP-Internal/trunk/Lib/Vis/work/tinyxml/tinyxml.cpp
===================================================================
--- GTP-Internal/trunk/Lib/Vis/work/tinyxml/tinyxml.cpp	(revision 61)
+++ GTP-Internal/trunk/Lib/Vis/work/tinyxml/tinyxml.cpp	(revision 61)
@@ -0,0 +1,1108 @@
+/*
+www.sourceforge.net/projects/tinyxml
+Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com)
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any
+purpose, including commercial applications, and to alter it and
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must
+not claim that you wrote the original software. If you use this
+software in a product, an acknowledgment in the product documentation
+would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and
+must not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source
+distribution.
+*/
+
+#include <ctype.h>
+#include "tinyxml.h"
+
+bool TiXmlBase::condenseWhiteSpace = true;
+
+void TiXmlBase::PutString( const TIXML_STRING& str, TIXML_OSTREAM* stream )
+{
+	TIXML_STRING buffer;
+	PutString( str, &buffer );
+	(*stream) << buffer;
+}
+
+void TiXmlBase::PutString( const TIXML_STRING& str, TIXML_STRING* outString )
+{
+	int i=0;
+
+	while( i<(int)str.length() )
+	{
+		int c = str[i];
+
+		if (    c == '&' 
+		     && i < ( (int)str.length() - 2 )
+			 && str[i+1] == '#'
+			 && str[i+2] == 'x' )
+		{
+			// Hexadecimal character reference.
+			// Pass through unchanged.
+			// &#xA9;	-- copyright symbol, for example.
+			while ( i<(int)str.length() )
+			{
+				outString->append( str.c_str() + i, 1 );
+				++i;
+				if ( str[i] == ';' )
+					break;
+			}
+		}
+		else if ( c == '&' )
+		{
+			outString->append( entity[0].str, entity[0].strLength );
+			++i;
+		}
+		else if ( c == '<' )
+		{
+			outString->append( entity[1].str, entity[1].strLength );
+			++i;
+		}
+		else if ( c == '>' )
+		{
+			outString->append( entity[2].str, entity[2].strLength );
+			++i;
+		}
+		else if ( c == '\"' )
+		{
+			outString->append( entity[3].str, entity[3].strLength );
+			++i;
+		}
+		else if ( c == '\'' )
+		{
+			outString->append( entity[4].str, entity[4].strLength );
+			++i;
+		}
+		else if ( c < 32 || c > 126 )
+		{
+			// Easy pass at non-alpha/numeric/symbol
+			// 127 is the delete key. Below 32 is symbolic.
+			char buf[ 32 ];
+			sprintf( buf, "&#x%02X;", (unsigned) ( c & 0xff ) );
+			outString->append( buf, strlen( buf ) );
+			++i;
+		}
+		else
+		{
+			char realc = (char) c;
+			outString->append( &realc, 1 );
+			++i;
+		}
+	}
+}
+
+
+TiXmlNode::TiXmlNode( NodeType _type )
+{
+	parent = 0;
+	type = _type;
+	firstChild = 0;
+	lastChild = 0;
+	prev = 0;
+	next = 0;
+	userData = 0;
+}
+
+
+TiXmlNode::~TiXmlNode()
+{
+	TiXmlNode* node = firstChild;
+	TiXmlNode* temp = 0;
+
+	while ( node )
+	{
+		temp = node;
+		node = node->next;
+		delete temp;
+	}	
+}
+
+
+void TiXmlNode::Clear()
+{
+	TiXmlNode* node = firstChild;
+	TiXmlNode* temp = 0;
+
+	while ( node )
+	{
+		temp = node;
+		node = node->next;
+		delete temp;
+	}	
+
+	firstChild = 0;
+	lastChild = 0;
+}
+
+
+TiXmlNode* TiXmlNode::LinkEndChild( TiXmlNode* node )
+{
+	node->parent = this;
+
+	node->prev = lastChild;
+	node->next = 0;
+
+	if ( lastChild )
+		lastChild->next = node;
+	else
+		firstChild = node;			// it was an empty list.
+
+	lastChild = node;
+	return node;
+}
+
+
+TiXmlNode* TiXmlNode::InsertEndChild( const TiXmlNode& addThis )
+{
+	TiXmlNode* node = addThis.Clone();
+	if ( !node )
+		return 0;
+
+	return LinkEndChild( node );
+}
+
+
+TiXmlNode* TiXmlNode::InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis )
+{	
+	if ( !beforeThis || beforeThis->parent != this )
+		return 0;
+
+	TiXmlNode* node = addThis.Clone();
+	if ( !node )
+		return 0;
+	node->parent = this;
+
+	node->next = beforeThis;
+	node->prev = beforeThis->prev;
+	if ( beforeThis->prev )
+	{
+		beforeThis->prev->next = node;
+	}
+	else
+	{
+		assert( firstChild == beforeThis );
+		firstChild = node;
+	}
+	beforeThis->prev = node;
+	return node;
+}
+
+
+TiXmlNode* TiXmlNode::InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis )
+{
+	if ( !afterThis || afterThis->parent != this )
+		return 0;
+
+	TiXmlNode* node = addThis.Clone();
+	if ( !node )
+		return 0;
+	node->parent = this;
+
+	node->prev = afterThis;
+	node->next = afterThis->next;
+	if ( afterThis->next )
+	{
+		afterThis->next->prev = node;
+	}
+	else
+	{
+		assert( lastChild == afterThis );
+		lastChild = node;
+	}
+	afterThis->next = node;
+	return node;
+}
+
+
+TiXmlNode* TiXmlNode::ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis )
+{
+	if ( replaceThis->parent != this )
+		return 0;
+
+	TiXmlNode* node = withThis.Clone();
+	if ( !node )
+		return 0;
+
+	node->next = replaceThis->next;
+	node->prev = replaceThis->prev;
+
+	if ( replaceThis->next )
+		replaceThis->next->prev = node;
+	else
+		lastChild = node;
+
+	if ( replaceThis->prev )
+		replaceThis->prev->next = node;
+	else
+		firstChild = node;
+
+	delete replaceThis;
+	node->parent = this;
+	return node;
+}
+
+
+bool TiXmlNode::RemoveChild( TiXmlNode* removeThis )
+{
+	if ( removeThis->parent != this )
+	{	
+		assert( 0 );
+		return false;
+	}
+
+	if ( removeThis->next )
+		removeThis->next->prev = removeThis->prev;
+	else
+		lastChild = removeThis->prev;
+
+	if ( removeThis->prev )
+		removeThis->prev->next = removeThis->next;
+	else
+		firstChild = removeThis->next;
+
+	delete removeThis;
+	return true;
+}
+
+TiXmlNode* TiXmlNode::FirstChild( const char * value ) const
+{
+	TiXmlNode* node;
+	for ( node = firstChild; node; node = node->next )
+	{
+		if ( node->SValue() == TIXML_STRING( value ))
+			return node;
+	}
+	return 0;
+}
+
+TiXmlNode* TiXmlNode::LastChild( const char * value ) const
+{
+	TiXmlNode* node;
+	for ( node = lastChild; node; node = node->prev )
+	{
+		if ( node->SValue() == TIXML_STRING (value))
+			return node;
+	}
+	return 0;
+}
+
+TiXmlNode* TiXmlNode::IterateChildren( TiXmlNode* previous ) const
+{
+	if ( !previous )
+	{
+		return FirstChild();
+	}
+	else
+	{
+		assert( previous->parent == this );
+		return previous->NextSibling();
+	}
+}
+
+TiXmlNode* TiXmlNode::IterateChildren( const char * val, TiXmlNode* previous ) const
+{
+	if ( !previous )
+	{
+		return FirstChild( val );
+	}
+	else
+	{
+		assert( previous->parent == this );
+		return previous->NextSibling( val );
+	}
+}
+
+TiXmlNode* TiXmlNode::NextSibling( const char * value ) const
+{
+	TiXmlNode* node;
+	for ( node = next; node; node = node->next )
+	{
+		if ( node->SValue() == TIXML_STRING (value))
+			return node;
+	}
+	return 0;
+}
+
+
+TiXmlNode* TiXmlNode::PreviousSibling( const char * value ) const
+{
+	TiXmlNode* node;
+	for ( node = prev; node; node = node->prev )
+	{
+		if ( node->SValue() == TIXML_STRING (value))
+			return node;
+	}
+	return 0;
+}
+
+void TiXmlElement::RemoveAttribute( const char * name )
+{
+	TiXmlAttribute* node = attributeSet.Find( name );
+	if ( node )
+	{
+		attributeSet.Remove( node );
+		delete node;
+	}
+}
+
+TiXmlElement* TiXmlNode::FirstChildElement() const
+{
+	TiXmlNode* node;
+
+	for (	node = FirstChild();
+	node;
+	node = node->NextSibling() )
+	{
+		if ( node->ToElement() )
+			return node->ToElement();
+	}
+	return 0;
+}
+
+TiXmlElement* TiXmlNode::FirstChildElement( const char * value ) const
+{
+	TiXmlNode* node;
+
+	for (	node = FirstChild( value );
+	node;
+	node = node->NextSibling( value ) )
+	{
+		if ( node->ToElement() )
+			return node->ToElement();
+	}
+	return 0;
+}
+
+
+TiXmlElement* TiXmlNode::NextSiblingElement() const
+{
+	TiXmlNode* node;
+
+	for (	node = NextSibling();
+	node;
+	node = node->NextSibling() )
+	{
+		if ( node->ToElement() )
+			return node->ToElement();
+	}
+	return 0;
+}
+
+TiXmlElement* TiXmlNode::NextSiblingElement( const char * value ) const
+{
+	TiXmlNode* node;
+
+	for (	node = NextSibling( value );
+	node;
+	node = node->NextSibling( value ) )
+	{
+		if ( node->ToElement() )
+			return node->ToElement();
+	}
+	return 0;
+}
+
+
+
+TiXmlDocument* TiXmlNode::GetDocument() const
+{
+	const TiXmlNode* node;
+
+	for( node = this; node; node = node->parent )
+	{
+		if ( node->ToDocument() )
+			return node->ToDocument();
+	}
+	return 0;
+}
+
+
+TiXmlElement::TiXmlElement (const char * _value)
+: TiXmlNode( TiXmlNode::ELEMENT )
+{
+	firstChild = lastChild = 0;
+	value = _value;
+}
+
+TiXmlElement::~TiXmlElement()
+{
+	while( attributeSet.First() )
+	{
+		TiXmlAttribute* node = attributeSet.First();
+		attributeSet.Remove( node );
+		delete node;
+	}
+}
+
+// BEGIN OGRE CHANGES
+// USE STL ALONE
+#ifndef TIXML_USE_STL
+const char * TiXmlElement::Attribute( const char * name ) const
+{
+	TiXmlAttribute* node = attributeSet.Find( name );
+
+	if ( node )
+		return node->Value();
+
+	return 0;
+}
+
+
+const char * TiXmlElement::Attribute( const char * name, int* i ) const
+{
+	const char * s = Attribute( name );
+	if ( i )
+	{
+		if ( s )
+			*i = atoi( s );
+		else
+			*i = 0;
+	}
+	return s;
+}
+
+
+void TiXmlElement::SetAttribute( const char * name, int val )
+{	
+	char buf[64];
+	sprintf( buf, "%d", val );
+	SetAttribute( name, buf );
+}
+
+
+void TiXmlElement::SetAttribute( const char * name, const char * value )
+{
+	TiXmlAttribute* node = attributeSet.Find( name );
+	if ( node )
+	{
+		node->SetValue( value );
+		return;
+	}
+
+	TiXmlAttribute* attrib = new TiXmlAttribute( name, value );
+	if ( attrib )
+	{
+		attributeSet.Add( attrib );
+	}
+	else
+	{
+		TiXmlDocument* document = GetDocument();
+		if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY );
+	}
+}
+
+#endif
+
+#ifdef TIXML_USE_STL
+
+const char * TiXmlElement::Attribute( const std::string& name ) const
+{
+	TiXmlAttribute* node = attributeSet.Find( name.c_str() );
+
+	if ( node )
+		return node->Value();
+
+	return 0;
+}
+
+
+const char * TiXmlElement::Attribute( const std::string& name, int* i ) const
+{
+	const char * s = Attribute( name );
+	if ( i )
+	{
+		if ( s )
+			*i = atoi( s );
+		else
+			*i = 0;
+	}
+	return s;
+}
+
+
+void TiXmlElement::SetAttribute( const std::string& name, int val )
+{	
+	char buf[64];
+	sprintf( buf, "%d", val );
+	SetAttribute( name, buf );
+}
+
+
+void TiXmlElement::SetAttribute( const std::string& name, const std::string& value )
+{
+	TiXmlAttribute* node = attributeSet.Find( name.c_str() );
+	if ( node )
+	{
+		node->SetValue( value );
+		return;
+	}
+
+	TiXmlAttribute* attrib = new TiXmlAttribute( name, value );
+	if ( attrib )
+	{
+		attributeSet.Add( attrib );
+	}
+	else
+	{
+		TiXmlDocument* document = GetDocument();
+		if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY );
+	}
+}
+
+#endif
+// END OGRE CHANGES
+void TiXmlElement::Print( FILE* cfile, int depth ) const
+{
+	int i;
+	for ( i=0; i<depth; i++ )
+	{
+		fprintf( cfile, "    " );
+	}
+
+	fprintf( cfile, "<%s", value.c_str() );
+
+	TiXmlAttribute* attrib;
+	for ( attrib = attributeSet.First(); attrib; attrib = attrib->Next() )
+	{
+		fprintf( cfile, " " );
+		attrib->Print( cfile, depth );
+	}
+
+	// There are 3 different formatting approaches:
+	// 1) An element without children is printed as a <foo /> node
+	// 2) An element with only a text child is printed as <foo> text </foo>
+	// 3) An element with children is printed on multiple lines.
+	TiXmlNode* node;
+	if ( !firstChild )
+	{
+		fprintf( cfile, " />" );
+	}
+	else if ( firstChild == lastChild && firstChild->ToText() )
+	{
+		fprintf( cfile, ">" );
+		firstChild->Print( cfile, depth + 1 );
+		fprintf( cfile, "</%s>", value.c_str() );
+	}
+	else
+	{
+		fprintf( cfile, ">" );
+
+		for ( node = firstChild; node; node=node->NextSibling() )
+		{
+			if ( !node->ToText() )
+			{
+				fprintf( cfile, "\n" );
+			}
+			node->Print( cfile, depth+1 );
+		}
+		fprintf( cfile, "\n" );
+		for( i=0; i<depth; ++i )
+		fprintf( cfile, "    " );
+		fprintf( cfile, "</%s>", value.c_str() );
+	}
+}
+
+void TiXmlElement::StreamOut( TIXML_OSTREAM * stream ) const
+{
+	(*stream) << "<" << value;
+
+	TiXmlAttribute* attrib;
+	for ( attrib = attributeSet.First(); attrib; attrib = attrib->Next() )
+	{	
+		(*stream) << " ";
+		attrib->StreamOut( stream );
+	}
+
+	// If this node has children, give it a closing tag. Else
+	// make it an empty tag.
+	TiXmlNode* node;
+	if ( firstChild )
+	{ 		
+		(*stream) << ">";
+
+		for ( node = firstChild; node; node=node->NextSibling() )
+		{
+			node->StreamOut( stream );
+		}
+		(*stream) << "</" << value << ">";
+	}
+	else
+	{
+		(*stream) << " />";
+	}
+}
+
+TiXmlNode* TiXmlElement::Clone() const
+{
+	TiXmlElement* clone = new TiXmlElement( Value() );
+	if ( !clone )
+		return 0;
+
+	CopyToClone( clone );
+
+	// Clone the attributes, then clone the children.
+	TiXmlAttribute* attribute = 0;
+	for(	attribute = attributeSet.First();
+	attribute;
+	attribute = attribute->Next() )
+	{
+		clone->SetAttribute( attribute->Name(), attribute->Value() );
+	}
+
+	TiXmlNode* node = 0;
+	for ( node = firstChild; node; node = node->NextSibling() )
+	{
+		clone->LinkEndChild( node->Clone() );
+	}
+	return clone;
+}
+
+
+TiXmlDocument::TiXmlDocument() : TiXmlNode( TiXmlNode::DOCUMENT )
+{
+	error = false;
+	//	ignoreWhiteSpace = true;
+}
+
+TiXmlDocument::TiXmlDocument( const char * documentName ) : TiXmlNode( TiXmlNode::DOCUMENT )
+{
+	//	ignoreWhiteSpace = true;
+	value = documentName;
+	error = false;
+}
+
+bool TiXmlDocument::LoadFile()
+{
+	if ( LoadFile( value.c_str() ) )
+		return true;
+
+	return false;
+}
+
+
+bool TiXmlDocument::SaveFile() const
+{
+	if ( SaveFile( value.c_str() ) )
+		return true;
+
+	return false;
+}
+
+bool TiXmlDocument::LoadFile( const char* filename )
+{
+	// Delete the existing data:
+	Clear();
+
+	// There was a really terrifying little bug here. The code:
+	//		value = filename
+	// in the STL case, cause the assignment method of the std::string to
+	// be called. What is strange, is that the std::string had the same
+	// address as it's c_str() method, and so bad things happen. Looks
+	// like a bug in the Microsoft STL implementation.
+	// See STL_STRING_BUG above.
+	// Fixed with the StringToBuffer class.
+	value = filename;
+
+	FILE* file = fopen( value.c_str (), "r" );
+
+	if ( file )
+	{
+		// Get the file size, so we can pre-allocate the string. HUGE speed impact.
+		long length = 0;
+		fseek( file, 0, SEEK_END );
+		length = ftell( file );
+		fseek( file, 0, SEEK_SET );
+
+		// Strange case, but good to handle up front.
+		if ( length == 0 )
+		{
+			fclose( file );
+			return false;
+		}
+
+		// If we have a file, assume it is all one big XML file, and read it in.
+		// The document parser may decide the document ends sooner than the entire file, however.
+		TIXML_STRING data;
+		data.reserve( length );
+
+		const int BUF_SIZE = 2048;
+		char buf[BUF_SIZE];
+
+		while( fgets( buf, BUF_SIZE, file ) )
+		{
+			data += buf;
+		}
+		fclose( file );
+
+		Parse( data.c_str() );
+		if (  !Error() )
+		{
+			return true;
+		}
+	}
+	SetError( TIXML_ERROR_OPENING_FILE );
+	return false;
+}
+
+bool TiXmlDocument::SaveFile( const char * filename ) const
+{
+	// The old c stuff lives on...
+	FILE* fp = fopen( filename, "w" );
+	if ( fp )
+	{
+		Print( fp, 0 );
+		fclose( fp );
+		return true;
+	}
+	return false;
+}
+
+
+TiXmlNode* TiXmlDocument::Clone() const
+{
+	TiXmlDocument* clone = new TiXmlDocument();
+	if ( !clone )
+		return 0;
+
+	CopyToClone( clone );
+	clone->error = error;
+	clone->errorDesc = errorDesc.c_str ();
+
+	TiXmlNode* node = 0;
+	for ( node = firstChild; node; node = node->NextSibling() )
+	{
+		clone->LinkEndChild( node->Clone() );
+	}
+	return clone;
+}
+
+
+void TiXmlDocument::Print( FILE* cfile, int depth ) const
+{
+	TiXmlNode* node;
+	for ( node=FirstChild(); node; node=node->NextSibling() )
+	{
+		node->Print( cfile, depth );
+		fprintf( cfile, "\n" );
+	}
+}
+
+void TiXmlDocument::StreamOut( TIXML_OSTREAM * out ) const
+{
+	TiXmlNode* node;
+	for ( node=FirstChild(); node; node=node->NextSibling() )
+	{
+		node->StreamOut( out );
+
+		// Special rule for streams: stop after the root element.
+		// The stream in code will only read one element, so don't
+		// write more than one.
+		if ( node->ToElement() )
+			break;
+	}
+}
+
+TiXmlAttribute* TiXmlAttribute::Next() const
+{
+	// We are using knowledge of the sentinel. The sentinel
+	// have a value or name.
+	if ( next->value.empty() && next->name.empty() )
+		return 0;
+	return next;
+}
+
+
+TiXmlAttribute* TiXmlAttribute::Previous() const
+{
+	// We are using knowledge of the sentinel. The sentinel
+	// have a value or name.
+	if ( prev->value.empty() && prev->name.empty() )
+		return 0;
+	return prev;
+}
+
+
+void TiXmlAttribute::Print( FILE* cfile, int /*depth*/ ) const
+{
+	TIXML_STRING n, v;
+
+	PutString( Name(), &n );
+	PutString( Value(), &v );
+
+	if (value.find ('\"') == TIXML_STRING::npos)
+		fprintf (cfile, "%s=\"%s\"", n.c_str(), v.c_str() );
+	else
+		fprintf (cfile, "%s='%s'", n.c_str(), v.c_str() );
+}
+
+
+void TiXmlAttribute::StreamOut( TIXML_OSTREAM * stream ) const
+{
+	if (value.find( '\"' ) != TIXML_STRING::npos)
+	{
+		PutString( name, stream );
+		(*stream) << "=" << "'";
+		PutString( value, stream );
+		(*stream) << "'";
+	}
+	else
+	{
+		PutString( name, stream );
+		(*stream) << "=" << "\"";
+		PutString( value, stream );
+		(*stream) << "\"";
+	}
+}
+
+void TiXmlAttribute::SetIntValue( int value )
+{
+	char buf [64];
+	sprintf (buf, "%d", value);
+	SetValue (buf);
+}
+
+void TiXmlAttribute::SetDoubleValue( double value )
+{
+	char buf [64];
+	sprintf (buf, "%lf", value);
+	SetValue (buf);
+}
+
+const int TiXmlAttribute::IntValue() const
+{
+	return atoi (value.c_str ());
+}
+
+const double  TiXmlAttribute::DoubleValue() const
+{
+	return atof (value.c_str ());
+}
+
+void TiXmlComment::Print( FILE* cfile, int depth ) const
+{
+	for ( int i=0; i<depth; i++ )
+	{
+		fputs( "    ", cfile );
+	}
+	fprintf( cfile, "<!--%s-->", value.c_str() );
+}
+
+void TiXmlComment::StreamOut( TIXML_OSTREAM * stream ) const
+{
+	(*stream) << "<!--";
+	PutString( value, stream );
+	(*stream) << "-->";
+}
+
+TiXmlNode* TiXmlComment::Clone() const
+{
+	TiXmlComment* clone = new TiXmlComment();
+
+	if ( !clone )
+		return 0;
+
+	CopyToClone( clone );
+	return clone;
+}
+
+
+void TiXmlText::Print( FILE* cfile, int /*depth*/ ) const
+{
+	TIXML_STRING buffer;
+	PutString( value, &buffer );
+	fprintf( cfile, "%s", buffer.c_str() );
+}
+
+
+void TiXmlText::StreamOut( TIXML_OSTREAM * stream ) const
+{
+	PutString( value, stream );
+}
+
+
+TiXmlNode* TiXmlText::Clone() const
+{	
+	TiXmlText* clone = 0;
+	clone = new TiXmlText( "" );
+
+	if ( !clone )
+		return 0;
+
+	CopyToClone( clone );
+	return clone;
+}
+
+
+TiXmlDeclaration::TiXmlDeclaration( const char * _version,
+	const char * _encoding,
+	const char * _standalone )
+: TiXmlNode( TiXmlNode::DECLARATION )
+{
+	version = _version;
+	encoding = _encoding;
+	standalone = _standalone;
+}
+
+
+void TiXmlDeclaration::Print( FILE* cfile, int /*depth*/ ) const
+{
+	fprintf (cfile, "<?xml ");
+
+	if ( !version.empty() )
+		fprintf (cfile, "version=\"%s\" ", version.c_str ());
+	if ( !encoding.empty() )
+		fprintf (cfile, "encoding=\"%s\" ", encoding.c_str ());
+	if ( !standalone.empty() )
+		fprintf (cfile, "standalone=\"%s\" ", standalone.c_str ());
+	fprintf (cfile, "?>");
+}
+
+void TiXmlDeclaration::StreamOut( TIXML_OSTREAM * stream ) const
+{
+	(*stream) << "<?xml ";
+
+	if ( !version.empty() )
+	{
+		(*stream) << "version=\"";
+		PutString( version, stream );
+		(*stream) << "\" ";
+	}
+	if ( !encoding.empty() )
+	{
+		(*stream) << "encoding=\"";
+		PutString( encoding, stream );
+		(*stream ) << "\" ";
+	}
+	if ( !standalone.empty() )
+	{
+		(*stream) << "standalone=\"";
+		PutString( standalone, stream );
+		(*stream) << "\" ";
+	}
+	(*stream) << "?>";
+}
+
+TiXmlNode* TiXmlDeclaration::Clone() const
+{	
+	TiXmlDeclaration* clone = new TiXmlDeclaration();
+
+	if ( !clone )
+		return 0;
+
+	CopyToClone( clone );
+	clone->version = version;
+	clone->encoding = encoding;
+	clone->standalone = standalone;
+	return clone;
+}
+
+
+void TiXmlUnknown::Print( FILE* cfile, int depth ) const
+{
+	for ( int i=0; i<depth; i++ )
+		fprintf( cfile, "    " );
+	fprintf( cfile, "%s", value.c_str() );
+}
+
+void TiXmlUnknown::StreamOut( TIXML_OSTREAM * stream ) const
+{
+	(*stream) << "<" << value << ">";		// Don't use entities hear! It is unknown.
+}
+
+TiXmlNode* TiXmlUnknown::Clone() const
+{
+	TiXmlUnknown* clone = new TiXmlUnknown();
+
+	if ( !clone )
+		return 0;
+
+	CopyToClone( clone );
+	return clone;
+}
+
+
+TiXmlAttributeSet::TiXmlAttributeSet()
+{
+	sentinel.next = &sentinel;
+	sentinel.prev = &sentinel;
+}
+
+
+TiXmlAttributeSet::~TiXmlAttributeSet()
+{
+	assert( sentinel.next == &sentinel );
+	assert( sentinel.prev == &sentinel );
+}
+
+
+void TiXmlAttributeSet::Add( TiXmlAttribute* addMe )
+{
+	assert( !Find( addMe->Name() ) );	// Shouldn't be multiply adding to the set.
+
+	addMe->next = &sentinel;
+	addMe->prev = sentinel.prev;
+
+	sentinel.prev->next = addMe;
+	sentinel.prev      = addMe;
+}
+
+void TiXmlAttributeSet::Remove( TiXmlAttribute* removeMe )
+{
+	TiXmlAttribute* node;
+
+	for( node = sentinel.next; node != &sentinel; node = node->next )
+	{
+		if ( node == removeMe )
+		{
+			node->prev->next = node->next;
+			node->next->prev = node->prev;
+			node->next = 0;
+			node->prev = 0;
+			return;
+		}
+	}
+	assert( 0 );		// we tried to remove a non-linked attribute.
+}
+
+TiXmlAttribute*	TiXmlAttributeSet::Find( const char * name ) const
+{
+	TiXmlAttribute* node;
+
+	for( node = sentinel.next; node != &sentinel; node = node->next )
+	{
+		if ( node->name == name )
+			return node;
+	}
+	return 0;
+}
+
+
+#ifdef TIXML_USE_STL	
+TIXML_ISTREAM & operator >> (TIXML_ISTREAM & in, TiXmlNode & base)
+{
+	TIXML_STRING tag;
+	tag.reserve( 8 * 1000 );
+	base.StreamIn( &in, &tag );
+
+	base.Parse( tag.c_str() );
+	return in;
+}
+#endif
+
+
+TIXML_OSTREAM & operator<< (TIXML_OSTREAM & out, const TiXmlNode & base)
+{
+	base.StreamOut (& out);
+	return out;
+}
+
Index: GTP-Internal/trunk/Lib/Vis/work/tinyxml/tinyxml.h
===================================================================
--- GTP-Internal/trunk/Lib/Vis/work/tinyxml/tinyxml.h	(revision 61)
+++ GTP-Internal/trunk/Lib/Vis/work/tinyxml/tinyxml.h	(revision 61)
@@ -0,0 +1,956 @@
+/*
+www.sourceforge.net/projects/tinyxml
+Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com)
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any
+purpose, including commercial applications, and to alter it and
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must
+not claim that you wrote the original software. If you use this
+software in a product, an acknowledgment in the product documentation
+would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and
+must not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source
+distribution.
+*/
+
+
+#ifndef TINYXML_INCLUDED
+#define TINYXML_INCLUDED
+
+#ifdef _MSC_VER
+#pragma warning( disable : 4530 )
+#pragma warning( disable : 4786 )
+#endif
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+// Help out windows:
+#if defined( _DEBUG ) && !defined( DEBUG )
+#define DEBUG
+#endif
+
+#if defined( DEBUG ) && defined( _MSC_VER )
+#define NOMINMAX
+#include <windows.h>
+#define TIXML_LOG OutputDebugString
+#else
+#define TIXML_LOG printf
+#endif
+
+
+#ifdef TIXML_USE_STL
+	#include <string>
+    #include <iostream>
+	#define TIXML_STRING	std::string
+	#define TIXML_ISTREAM	std::istream
+	#define TIXML_OSTREAM	std::ostream
+#else
+	#include "tinystr.h"
+	#define TIXML_STRING	TiXmlString
+	#define TIXML_OSTREAM	TiXmlOutStream
+#endif
+
+class TiXmlDocument;
+class TiXmlElement;
+class TiXmlComment;
+class TiXmlUnknown;
+class TiXmlAttribute;
+class TiXmlText;
+class TiXmlDeclaration;
+
+
+/*  TiXmlBase is a base class for every class in TinyXml.
+	It does little except to establish that TinyXml classes
+	can be printed and provide some utility functions.
+
+	In XML, the document and elements can contain
+	other elements and other types of nodes.
+
+	@verbatim
+	A Document can contain:	Element	(container or leaf)
+							Comment (leaf)
+							Unknown (leaf)
+							Declaration( leaf )
+
+	An Element can contain:	Element (container or leaf)
+							Text	(leaf)
+							Attributes (not on tree)
+							Comment (leaf)
+							Unknown (leaf)
+
+	A Decleration contains: Attributes (not on tree)
+	@endverbatim
+*/
+class TiXmlBase
+{
+	friend class TiXmlNode;
+	friend class TiXmlElement;
+	friend class TiXmlDocument;
+
+public:
+	TiXmlBase()								{}
+	virtual ~TiXmlBase()					{}
+
+	/**	All TinyXml classes can print themselves to a filestream.
+		This is a formatted print, and will insert tabs and newlines.
+		
+		(For an unformatted stream, use the << operator.)
+	*/
+	virtual void Print( FILE* cfile, int depth ) const = 0;
+
+	/**	The world does not agree on whether white space should be kept or
+		not. In order to make everyone happy, these global, static functions
+		are provided to set whether or not TinyXml will condense all white space
+		into a single space or not. The default is to condense. Note changing these
+		values is not thread safe.
+	*/
+	static void SetCondenseWhiteSpace( bool condense )		{ condenseWhiteSpace = condense; }
+
+	/// Return the current white space setting.
+	static bool IsWhiteSpaceCondensed()						{ return condenseWhiteSpace; }
+
+protected:
+
+	static const char*	SkipWhiteSpace( const char* );
+	inline static bool	IsWhiteSpace( int c )		{ return ( isspace( c ) || c == '\n' || c == '\r' ); }
+
+	virtual void StreamOut (TIXML_OSTREAM *) const = 0;
+
+	#ifdef TIXML_USE_STL
+	    static bool	StreamWhiteSpace( TIXML_ISTREAM * in, TIXML_STRING * tag );
+	    static bool StreamTo( TIXML_ISTREAM * in, int character, TIXML_STRING * tag );
+	#endif
+
+	/*	Reads an XML name into the string provided. Returns
+		a pointer just past the last character of the name,
+		or 0 if the function has an error.
+	*/
+	static const char* ReadName( const char* p, TIXML_STRING* name );
+
+	/*	Reads text. Returns a pointer past the given end tag.
+		Wickedly complex options, but it keeps the (sensitive) code in one place.
+	*/
+	static const char* ReadText(	const char* in,				// where to start
+									TIXML_STRING* text,			// the string read
+									bool ignoreWhiteSpace,		// whether to keep the white space
+									const char* endTag,			// what ends this text
+									bool ignoreCase );			// whether to ignore case in the end tag
+	virtual const char* Parse( const char* p ) = 0;
+
+	// If an entity has been found, transform it into a character.
+	static const char* GetEntity( const char* in, char* value );
+
+	// Get a character, while interpreting entities.
+	inline static const char* GetChar( const char* p, char* value )
+	{
+		assert( p );
+		if ( *p == '&' )
+		{
+			return GetEntity( p, value );
+		}
+		else
+		{
+			*value = *p;
+			return p+1;
+		}
+	}
+
+	// Puts a string to a stream, expanding entities as it goes.
+	// Note this should not contian the '<', '>', etc, or they will be transformed into entities!
+	static void PutString( const TIXML_STRING& str, TIXML_OSTREAM* out );
+
+	static void PutString( const TIXML_STRING& str, TIXML_STRING* out );
+
+	// Return true if the next characters in the stream are any of the endTag sequences.
+	bool static StringEqual(	const char* p,
+								const char* endTag,
+								bool ignoreCase );
+
+
+	enum
+	{
+		TIXML_NO_ERROR = 0,
+		TIXML_ERROR,
+		TIXML_ERROR_OPENING_FILE,
+		TIXML_ERROR_OUT_OF_MEMORY,
+		TIXML_ERROR_PARSING_ELEMENT,
+		TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME,
+		TIXML_ERROR_READING_ELEMENT_VALUE,
+		TIXML_ERROR_READING_ATTRIBUTES,
+		TIXML_ERROR_PARSING_EMPTY,
+		TIXML_ERROR_READING_END_TAG,
+		TIXML_ERROR_PARSING_UNKNOWN,
+		TIXML_ERROR_PARSING_COMMENT,
+		TIXML_ERROR_PARSING_DECLARATION,
+		TIXML_ERROR_DOCUMENT_EMPTY,
+
+		TIXML_ERROR_STRING_COUNT
+	};
+	static const char* errorString[ TIXML_ERROR_STRING_COUNT ];
+
+private:
+	struct Entity
+	{
+		const char*     str;
+		unsigned int	strLength;
+		char		    chr;
+	};
+	enum
+	{
+		NUM_ENTITY = 5,
+		MAX_ENTITY_LENGTH = 6
+
+	};
+	static Entity entity[ NUM_ENTITY ];
+	static bool condenseWhiteSpace;
+};
+
+
+/*  The parent class for everything in the Document Object Model.
+	(Except for attributes, which are contained in elements.)
+	Nodes have siblings, a parent, and children. A node can be
+	in a document, or stand on its own. The type of a TiXmlNode
+	can be queried, and it can be cast to its more defined type.
+*/
+class TiXmlNode : public TiXmlBase
+{
+	friend class TiXmlDocument;
+	friend class TiXmlElement;
+
+public:
+	#ifdef TIXML_USE_STL	
+
+	    /** An input stream operator, for every class. Tolerant of newlines and
+		    formatting, but doesn't expect them.
+	    */
+	    friend std::istream& operator >> (std::istream& in, TiXmlNode& base);
+
+	    /** An output stream operator, for every class. Note that this outputs
+		    without any newlines or formatting, as opposed to Print(), which
+		    includes tabs and new lines.
+
+		    The operator<< and operator>> are not completely symmetric. Writing
+		    a node to a stream is very well defined. You'll get a nice stream
+		    of output, without any extra whitespace or newlines.
+		    
+		    But reading is not as well defined. (As it always is.) If you create
+		    a TiXmlElement (for example) and read that from an input stream,
+		    the text needs to define an element or junk will result. This is
+		    true of all input streams, but it's worth keeping in mind.
+
+		    A TiXmlDocument will read nodes until it reads a root element.
+	    */	
+	    friend std::ostream & operator<< (std::ostream& out, const TiXmlNode& base);
+
+	#else
+	    // Used internally, not part of the public API.
+	    friend TIXML_OSTREAM& operator<< (TIXML_OSTREAM& out, const TiXmlNode& base);
+	#endif
+
+	/** The types of XML nodes supported by TinyXml. (All the
+			unsupported types are picked up by UNKNOWN.)
+	*/
+	enum NodeType
+	{
+		DOCUMENT,
+		ELEMENT,
+		COMMENT,
+		UNKNOWN,
+		TEXT,
+		DECLARATION,
+		TYPECOUNT
+	};
+
+	virtual ~TiXmlNode();
+
+	/** The meaning of 'value' changes for the specific type of
+		TiXmlNode.
+		@verbatim
+		Document:	filename of the xml file
+		Element:	name of the element
+		Comment:	the comment text
+		Unknown:	the tag contents
+		Text:		the text string
+		@endverbatim
+
+		The subclasses will wrap this function.
+	*/
+	const char * Value () const { return value.c_str (); }
+
+	/** Changes the value of the node. Defined as:
+		@verbatim
+		Document:	filename of the xml file
+		Element:	name of the element
+		Comment:	the comment text
+		Unknown:	the tag contents
+		Text:		the text string
+		@endverbatim
+	*/
+	void SetValue (const char * _value) { value = _value;}
+
+    #ifdef TIXML_USE_STL
+	/// STL std::string form.
+	void SetValue( const std::string& value )    
+	{	  
+		SetValue( value.c_str() );    	
+	}	
+	#endif
+
+	/// Delete all the children of this node. Does not affect 'this'.
+	void Clear();
+
+	/// One step up the DOM.
+	TiXmlNode* Parent() const					{ return parent; }
+
+	TiXmlNode* FirstChild()	const	{ return firstChild; }		///< The first child of this node. Will be null if there are no children.
+	TiXmlNode* FirstChild( const char * value ) const;			///< The first child of this node with the matching 'value'. Will be null if none found.
+
+	TiXmlNode* LastChild() const	{ return lastChild; }		/// The last child of this node. Will be null if there are no children.
+	TiXmlNode* LastChild( const char * value ) const;			/// The last child of this node matching 'value'. Will be null if there are no children.
+
+    #ifdef TIXML_USE_STL
+	TiXmlNode* FirstChild( const std::string& value ) const	{	return FirstChild (value.c_str ());	}	///< STL std::string form.
+	TiXmlNode* LastChild( const std::string& value ) const	{	return LastChild (value.c_str ());	}	///< STL std::string form.
+	#endif
+
+	/** An alternate way to walk the children of a node.
+		One way to iterate over nodes is:
+		@verbatim
+			for( child = parent->FirstChild(); child; child = child->NextSibling() )
+		@endverbatim
+
+		IterateChildren does the same thing with the syntax:
+		@verbatim
+			child = 0;
+			while( child = parent->IterateChildren( child ) )
+		@endverbatim
+
+		IterateChildren takes the previous child as input and finds
+		the next one. If the previous child is null, it returns the
+		first. IterateChildren will return null when done.
+	*/
+	TiXmlNode* IterateChildren( TiXmlNode* previous ) const;
+
+	/// This flavor of IterateChildren searches for children with a particular 'value'
+	TiXmlNode* IterateChildren( const char * value, TiXmlNode* previous ) const;
+
+    #ifdef TIXML_USE_STL
+	TiXmlNode* IterateChildren( const std::string& value, TiXmlNode* previous ) const	{	return IterateChildren (value.c_str (), previous);	}	///< STL std::string form.
+	#endif
+
+	/** Add a new node related to this. Adds a child past the LastChild.
+		Returns a pointer to the new object or NULL if an error occured.
+	*/
+	TiXmlNode* InsertEndChild( const TiXmlNode& addThis );
+
+	/** Add a new node related to this. Adds a child before the specified child.
+		Returns a pointer to the new object or NULL if an error occured.
+	*/
+	TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis );
+
+	/** Add a new node related to this. Adds a child after the specified child.
+		Returns a pointer to the new object or NULL if an error occured.
+	*/
+	TiXmlNode* InsertAfterChild(  TiXmlNode* afterThis, const TiXmlNode& addThis );
+
+	/** Replace a child of this node.
+		Returns a pointer to the new object or NULL if an error occured.
+	*/
+	TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis );
+
+	/// Delete a child of this node.
+	bool RemoveChild( TiXmlNode* removeThis );
+
+	/// Navigate to a sibling node.
+	TiXmlNode* PreviousSibling() const			{ return prev; }
+
+	/// Navigate to a sibling node.
+	TiXmlNode* PreviousSibling( const char * ) const;
+
+    #ifdef TIXML_USE_STL
+	TiXmlNode* PreviousSibling( const std::string& value ) const	{	return PreviousSibling (value.c_str ());	}	///< STL std::string form.
+	TiXmlNode* NextSibling( const std::string& value) const	{	return NextSibling (value.c_str ());	}	///< STL std::string form.
+	#endif
+
+	/// Navigate to a sibling node.
+	TiXmlNode* NextSibling() const				{ return next; }
+
+	/// Navigate to a sibling node with the given 'value'.
+	TiXmlNode* NextSibling( const char * ) const;
+
+	/** Convenience function to get through elements.
+		Calls NextSibling and ToElement. Will skip all non-Element
+		nodes. Returns 0 if there is not another element.
+	*/
+	TiXmlElement* NextSiblingElement() const;
+
+	/** Convenience function to get through elements.
+		Calls NextSibling and ToElement. Will skip all non-Element
+		nodes. Returns 0 if there is not another element.
+	*/
+	TiXmlElement* NextSiblingElement( const char * ) const;
+
+    #ifdef TIXML_USE_STL
+	TiXmlElement* NextSiblingElement( const std::string& value) const	{	return NextSiblingElement (value.c_str ());	}	///< STL std::string form.
+	#endif
+
+	/// Convenience function to get through elements.
+	TiXmlElement* FirstChildElement()	const;
+
+	/// Convenience function to get through elements.
+	TiXmlElement* FirstChildElement( const char * value ) const;
+
+    #ifdef TIXML_USE_STL
+	TiXmlElement* FirstChildElement( const std::string& value ) const	{	return FirstChildElement (value.c_str ());	}	///< STL std::string form.
+	#endif
+
+	/// Query the type (as an enumerated value, above) of this node.
+	virtual int Type() const	{ return type; }
+
+	/** Return a pointer to the Document this node lives in.
+		Returns null if not in a document.
+	*/
+	TiXmlDocument* GetDocument() const;
+
+	/// Returns true if this node has no children.
+	bool NoChildren() const						{ return !firstChild; }
+
+	TiXmlDocument* ToDocument()	const		{ return ( this && type == DOCUMENT ) ? (TiXmlDocument*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
+	TiXmlElement*  ToElement() const		{ return ( this && type == ELEMENT  ) ? (TiXmlElement*)  this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
+	TiXmlComment*  ToComment() const		{ return ( this && type == COMMENT  ) ? (TiXmlComment*)  this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
+	TiXmlUnknown*  ToUnknown() const		{ return ( this && type == UNKNOWN  ) ? (TiXmlUnknown*)  this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
+	TiXmlText*	   ToText()    const		{ return ( this && type == TEXT     ) ? (TiXmlText*)     this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
+	TiXmlDeclaration* ToDeclaration() const	{ return ( this && type == DECLARATION ) ? (TiXmlDeclaration*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
+
+	virtual TiXmlNode* Clone() const = 0;
+
+	void  SetUserData( void* user )			{ userData = user; }
+	void* GetUserData()						{ return userData; }
+
+protected:
+	TiXmlNode( NodeType type );
+
+	#ifdef TIXML_USE_STL
+	    // The real work of the input operator.
+	    virtual void StreamIn( TIXML_ISTREAM* in, TIXML_STRING* tag ) = 0;
+	#endif
+
+	// The node is passed in by ownership. This object will delete it.
+	TiXmlNode* LinkEndChild( TiXmlNode* addThis );
+
+	// Figure out what is at *p, and parse it. Returns null if it is not an xml node.
+	TiXmlNode* Identify( const char* start );
+	void CopyToClone( TiXmlNode* target ) const	{ target->SetValue (value.c_str() );
+												  target->userData = userData; }
+
+	// Internal Value function returning a TIXML_STRING
+	TIXML_STRING SValue() const	{ return value ; }
+
+	TiXmlNode*		parent;
+	NodeType		type;
+
+	TiXmlNode*		firstChild;
+	TiXmlNode*		lastChild;
+
+	TIXML_STRING	value;
+
+	TiXmlNode*		prev;
+	TiXmlNode*		next;
+	void*			userData;
+};
+
+
+/*  An attribute is a name-value pair. Elements have an arbitrary
+	number of attributes, each with a unique name.
+
+	@note The attributes are not TiXmlNodes, since they are not
+		  part of the tinyXML document object model. There are other
+		  suggested ways to look at this problem.
+
+	@note Attributes have a parent
+*/
+class TiXmlAttribute : public TiXmlBase
+{
+	friend class TiXmlAttributeSet;
+
+public:
+	/// Construct an empty attribute.
+	TiXmlAttribute() : prev( 0 ), next( 0 )	{}
+
+	#ifdef TIXML_USE_STL
+	/// std::string constructor.
+	TiXmlAttribute( const std::string& _name, const std::string& _value )
+	{
+		name = _name;
+		value = _value;
+	}
+	#endif
+
+	/// Construct an attribute with a name and value.
+	TiXmlAttribute( const char * _name, const char * _value ): name( _name ), value( _value ), prev( 0 ), next( 0 ) {}
+	const char*		Name()  const		{ return name.c_str (); }		///< Return the name of this attribute.
+	const char*		Value() const		{ return value.c_str (); }		///< Return the value of this attribute.
+	const int       IntValue() const;									///< Return the value of this attribute, converted to an integer.
+	const double	DoubleValue() const;								///< Return the value of this attribute, converted to a double.
+
+	void SetName( const char* _name )	{ name = _name; }				///< Set the name of this attribute.
+	void SetValue( const char* _value )	{ value = _value; }				///< Set the value.
+
+	void SetIntValue( int value );										///< Set the value from an integer.
+	void SetDoubleValue( double value );								///< Set the value from a double.
+
+    #ifdef TIXML_USE_STL
+	/// STL std::string form.
+	void SetName( const std::string& _name )	
+	{	
+		SetName(_name.c_str() );	
+	}
+	/// STL std::string form.	
+	void SetValue( const std::string& _value )	
+	{	
+		SetValue( value.c_str() );	
+	}
+	#endif
+
+	/// Get the next sibling attribute in the DOM. Returns null at end.
+	TiXmlAttribute* Next() const;
+	/// Get the previous sibling attribute in the DOM. Returns null at beginning.
+	TiXmlAttribute* Previous() const;
+
+	bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; }
+	bool operator<( const TiXmlAttribute& rhs )	 const { return name < rhs.name; }
+	bool operator>( const TiXmlAttribute& rhs )  const { return name > rhs.name; }
+
+	/*	[internal use]
+		Attribtue parsing starts: first letter of the name
+						 returns: the next char after the value end quote
+	*/
+	virtual const char* Parse( const char* p );
+
+	// [internal use]
+	virtual void Print( FILE* cfile, int depth ) const;
+
+	virtual void StreamOut( TIXML_OSTREAM * out ) const;
+	// [internal use]
+	// Set the document pointer so the attribute can report errors.
+	void SetDocument( TiXmlDocument* doc )	{ document = doc; }
+
+private:
+	TiXmlDocument*	document;	// A pointer back to a document, for error reporting.
+	TIXML_STRING name;
+	TIXML_STRING value;
+	TiXmlAttribute*	prev;
+	TiXmlAttribute*	next;
+};
+
+
+/*	A class used to manage a group of attributes.
+	It is only used internally, both by the ELEMENT and the DECLARATION.
+	
+	The set can be changed transparent to the Element and Declaration
+	classes that use it, but NOT transparent to the Attribute
+	which has to implement a next() and previous() method. Which makes
+	it a bit problematic and prevents the use of STL.
+
+	This version is implemented with circular lists because:
+		- I like circular lists
+		- it demonstrates some independence from the (typical) doubly linked list.
+*/
+class TiXmlAttributeSet
+{
+public:
+	TiXmlAttributeSet();
+	~TiXmlAttributeSet();
+
+	void Add( TiXmlAttribute* attribute );
+	void Remove( TiXmlAttribute* attribute );
+
+	TiXmlAttribute* First() const	{ return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
+	TiXmlAttribute* Last()  const	{ return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
+	TiXmlAttribute*	Find( const char * name ) const;
+
+private:
+	TiXmlAttribute sentinel;
+};
+
+
+/*  The element is a container class. It has a value, the element name,
+	and can contain other elements, text, comments, and unknowns.
+	Elements also contain an arbitrary number of attributes.
+*/
+class TiXmlElement : public TiXmlNode
+{
+public:
+	/// Construct an element.
+	TiXmlElement (const char * in_value);
+
+	#ifdef TIXML_USE_STL
+	/// std::string constructor.
+	TiXmlElement( const std::string& _value ) : 	TiXmlNode( TiXmlNode::ELEMENT )
+	{
+		firstChild = lastChild = 0;
+		value = _value;
+	}
+	#endif
+
+	virtual ~TiXmlElement();
+
+// OGRE CHANGE 
+// Resolve ambiguity of std::string / const char* conversion of Ogre::String
+#ifndef TIXML_USE_STL
+// OGRE CHANGE
+	/** Given an attribute name, attribute returns the value
+		for the attribute of that name, or null if none exists.
+	*/
+	const char* Attribute( const char* name ) const;
+
+	/** Given an attribute name, attribute returns the value
+		for the attribute of that name, or null if none exists.
+		If the attribute exists and can be converted to an integer,
+		the integer value will be put in the return 'i', if 'i'
+		is non-null.
+	*/
+	const char* Attribute( const char* name, int* i ) const;
+
+	/** Sets an attribute of name to a given value. The attribute
+		will be created if it does not exist, or changed if it does.
+	*/
+	void SetAttribute( const char* name, const char * value );
+// OGRE CHANGE
+#endif
+// OGRE CHANGE
+    #ifdef TIXML_USE_STL
+	const char* Attribute( const std::string& name ) const;
+	const char* Attribute( const std::string& name, int* i ) const;
+
+	/// STL std::string form.
+	void SetAttribute( const std::string& name, const std::string& value );
+	///< STL std::string form.
+	void SetAttribute( const std::string& name, int value );
+	#endif
+
+	/** Sets an attribute of name to a given value. The attribute
+		will be created if it does not exist, or changed if it does.
+	*/
+	void SetAttribute( const char * name, int value );
+
+	/** Deletes an attribute with the given name.
+	*/
+	void RemoveAttribute( const char * name );
+    #ifdef TIXML_USE_STL
+	void RemoveAttribute( const std::string& name )	{	RemoveAttribute (name.c_str ());	}	///< STL std::string form.
+	#endif
+
+	TiXmlAttribute* FirstAttribute() const	{ return attributeSet.First(); }		///< Access the first attribute in this element.
+	TiXmlAttribute* LastAttribute()	const 	{ return attributeSet.Last(); }		///< Access the last attribute in this element.
+
+	// [internal use] Creates a new Element and returs it.
+	virtual TiXmlNode* Clone() const;
+	// [internal use]
+
+	virtual void Print( FILE* cfile, int depth ) const;
+
+protected:
+
+	// Used to be public [internal use]
+	#ifdef TIXML_USE_STL
+	    virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
+	#endif
+	virtual void StreamOut( TIXML_OSTREAM * out ) const;
+
+	/*	[internal use]
+		Attribtue parsing starts: next char past '<'
+						 returns: next char past '>'
+	*/
+	virtual const char* Parse( const char* p );
+
+	/*	[internal use]
+		Reads the "value" of the element -- another element, or text.
+		This should terminate with the current end tag.
+	*/
+	const char* ReadValue( const char* in );
+
+private:
+	TiXmlAttributeSet attributeSet;
+};
+
+
+/* 	An XML comment.
+*/
+class TiXmlComment : public TiXmlNode
+{
+public:
+	/// Constructs an empty comment.
+	TiXmlComment() : TiXmlNode( TiXmlNode::COMMENT ) {}
+	virtual ~TiXmlComment()	{}
+
+	// [internal use] Creates a new Element and returs it.
+	virtual TiXmlNode* Clone() const;
+	// [internal use]
+	virtual void Print( FILE* cfile, int depth ) const;
+protected:
+	// used to be public
+	#ifdef TIXML_USE_STL
+	    virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
+	#endif
+	virtual void StreamOut( TIXML_OSTREAM * out ) const;
+	/*	[internal use]
+		Attribtue parsing starts: at the ! of the !--
+						 returns: next char past '>'
+	*/
+	virtual const char* Parse( const char* p );
+};
+
+
+/*  XML text. Contained in an element.
+*/
+class TiXmlText : public TiXmlNode
+{
+	friend class TiXmlElement;
+public:
+	/// Constructor.
+	TiXmlText (const char * initValue) : TiXmlNode (TiXmlNode::TEXT)
+	{
+		SetValue( initValue );
+	}
+	virtual ~TiXmlText() {}
+
+	#ifdef TIXML_USE_STL
+	/// Constructor.
+	TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TEXT)
+	{
+		SetValue( initValue );
+	}
+	#endif
+
+protected :
+	// [internal use] Creates a new Element and returns it.
+	virtual TiXmlNode* Clone() const;
+	// [internal use]
+	virtual void Print( FILE* cfile, int depth ) const;
+	virtual void StreamOut ( TIXML_OSTREAM * out ) const;
+	// [internal use]
+	bool Blank() const;	// returns true if all white space and new lines
+	/*	[internal use]
+			Attribtue parsing starts: First char of the text
+							 returns: next char past '>'
+		*/
+	virtual const char* Parse( const char* p );
+	// [internal use]
+	#ifdef TIXML_USE_STL
+	    virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
+	#endif
+};
+
+
+/*  In correct XML the declaration is the first entry in the file.
+	@verbatim
+		<?xml version="1.0" standalone="yes"?>
+	@endverbatim
+
+	TinyXml will happily read or write files without a declaration,
+	however. There are 3 possible attributes to the declaration:
+	version, encoding, and standalone.
+
+	Note: In this version of the code, the attributes are
+	handled as special cases, not generic attributes, simply
+	because there can only be at most 3 and they are always the same.
+*/
+class TiXmlDeclaration : public TiXmlNode
+{
+public:
+	/// Construct an empty declaration.
+	TiXmlDeclaration()   : TiXmlNode( TiXmlNode::DECLARATION ) {}
+
+#ifdef TIXML_USE_STL
+	/// Constructor.
+	TiXmlDeclaration(
+						const std::string& _version,
+						const std::string& _encoding,
+						const std::string& _standalone )
+					: TiXmlNode( TiXmlNode::DECLARATION )
+	{
+		version = _version;
+		encoding = _encoding;
+		standalone = _standalone;
+	}
+#endif
+
+	/// Construct.
+	TiXmlDeclaration::TiXmlDeclaration( const char * _version,
+										const char * _encoding,
+										const char * _standalone );
+
+	virtual ~TiXmlDeclaration()	{}
+
+	/// Version. Will return empty if none was found.
+	const char * Version() const		{ return version.c_str (); }
+	/// Encoding. Will return empty if none was found.
+	const char * Encoding() const		{ return encoding.c_str (); }
+	/// Is this a standalone document?
+	const char * Standalone() const		{ return standalone.c_str (); }
+
+	// [internal use] Creates a new Element and returs it.
+	virtual TiXmlNode* Clone() const;
+	// [internal use]
+	virtual void Print( FILE* cfile, int depth ) const;
+
+protected:
+	// used to be public
+	#ifdef TIXML_USE_STL
+	    virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
+	#endif
+	virtual void StreamOut ( TIXML_OSTREAM * out) const;
+	//	[internal use]
+	//	Attribtue parsing starts: next char past '<'
+	//					 returns: next char past '>'
+
+	virtual const char* Parse( const char* p );
+
+private:
+	TIXML_STRING version;
+	TIXML_STRING encoding;
+	TIXML_STRING standalone;
+};
+
+
+/*  Any tag that tinyXml doesn't recognize is save as an
+	unknown. It is a tag of text, but should not be modified.
+	It will be written back to the XML, unchanged, when the file
+	is saved.
+*/
+class TiXmlUnknown : public TiXmlNode
+{
+public:
+	TiXmlUnknown() : TiXmlNode( TiXmlNode::UNKNOWN ) {}
+	virtual ~TiXmlUnknown() {}
+
+	// [internal use]
+	virtual TiXmlNode* Clone() const;
+	// [internal use]
+	virtual void Print( FILE* cfile, int depth ) const;
+protected:
+	// used to be public
+	#ifdef TIXML_USE_STL
+	    virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
+	#endif
+	virtual void StreamOut ( TIXML_OSTREAM * out ) const;
+	/*	[internal use]
+		Attribute parsing starts: First char of the text
+						 returns: next char past '>'
+	*/
+	virtual const char* Parse( const char* p );
+};
+
+
+/*  Always the top level node. A document binds together all the
+	XML pieces. It can be saved, loaded, and printed to the screen.
+	The 'value' of a document node is the xml file name.
+*/
+class TiXmlDocument : public TiXmlNode
+{
+public:
+	/// Create an empty document, that has no name.
+	TiXmlDocument();
+	/// Create a document with a name. The name of the document is also the filename of the xml.
+	TiXmlDocument( const char * documentName );
+
+	#ifdef TIXML_USE_STL
+	/// Constructor.
+	TiXmlDocument( const std::string& documentName ) :
+	    TiXmlNode( TiXmlNode::DOCUMENT )
+	{
+        value = documentName;
+		error = false;
+	}
+	#endif
+
+	virtual ~TiXmlDocument() {}
+
+	/** Load a file using the current document value.
+		Returns true if successful. Will delete any existing
+		document data before loading.
+	*/
+	bool LoadFile();
+	/// Save a file using the current document value. Returns true if successful.
+	bool SaveFile() const;
+	/// Load a file using the given filename. Returns true if successful.
+	bool LoadFile( const char * filename );
+	/// Save a file using the given filename. Returns true if successful.
+	bool SaveFile( const char * filename ) const;
+
+	#ifdef TIXML_USE_STL
+	bool LoadFile( const std::string& filename )			///< STL std::string version.
+	{
+		return ( LoadFile( filename.c_str() ));
+	}
+	bool SaveFile( const std::string& filename ) const		///< STL std::string version.
+	{
+		//StringToBuffer f( filename );
+		return ( SaveFile( filename.c_str() ));
+	}
+	#endif
+
+	/// Parse the given null terminated block of xml data.
+	virtual const char* Parse( const char* p );
+
+	/** Get the root element -- the only top level element -- of the document.
+		In well formed XML, there should only be one. TinyXml is tolerant of
+		multiple elements at the document level.
+	*/
+	TiXmlElement* RootElement() const		{ return FirstChildElement(); }
+
+	/// If, during parsing, a error occurs, Error will be set to true.
+	bool Error() const						{ return error; }
+
+	/// Contains a textual (english) description of the error if one occurs.
+	const char * ErrorDesc() const	{ return errorDesc.c_str (); }
+
+	/** Generally, you probably want the error string ( ErrorDesc() ). But if you
+			prefer the ErrorId, this function will fetch it.
+		*/
+	const int ErrorId()	const				{ return errorId; }
+
+	/// If you have handled the error, it can be reset with this call.
+	void ClearError()						{ error = false; errorId = 0; errorDesc = ""; }
+
+	/** Dump the document to standard out. */
+	void Print() const						{ Print( stdout, 0 ); }
+
+	// [internal use]
+	virtual void Print( FILE* cfile, int depth = 0 ) const;
+	// [internal use]
+	void SetError( int err ) {		assert( err > 0 && err < TIXML_ERROR_STRING_COUNT );
+		error   = true;
+		errorId = err;
+	errorDesc = errorString[ errorId ]; }
+
+protected :
+	virtual void StreamOut ( TIXML_OSTREAM * out) const;
+	// [internal use]
+	virtual TiXmlNode* Clone() const;
+	#ifdef TIXML_USE_STL
+	    virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
+	#endif
+
+private:
+	bool error;
+	int  errorId;
+	TIXML_STRING errorDesc;
+};
+
+#endif
+
Index: GTP-Internal/trunk/Lib/Vis/work/tinyxml/tinystr.cpp
===================================================================
--- GTP-Internal/trunk/Lib/Vis/work/tinyxml/tinystr.cpp	(revision 61)
+++ GTP-Internal/trunk/Lib/Vis/work/tinyxml/tinystr.cpp	(revision 61)
@@ -0,0 +1,265 @@
+/*
+www.sourceforge.net/projects/tinyxml
+Original file by Yves Berquin.
+
+This software is provided 'as-is', without any express or implied 
+warranty. In no event will the authors be held liable for any 
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any 
+purpose, including commercial applications, and to alter it and 
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must 
+not claim that you wrote the original software. If you use this 
+software in a product, an acknowledgment in the product documentation 
+would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and
+must not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source 
+distribution.
+*/
+
+#include "tinyxml.h"
+
+#ifndef TIXML_USE_STL
+
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "tinystr.h"
+
+// TiXmlString constructor, based on a C string
+TiXmlString::TiXmlString (const char* instring)
+{
+    unsigned newlen;
+    char * newstring;
+
+    if (!instring)
+    {
+        allocated = 0;
+        cstring = NULL;
+        return;
+    }
+    newlen = strlen (instring) + 1;
+    newstring = new char [newlen];
+    strcpy (newstring, instring);
+    allocated = newlen;
+    cstring = newstring;
+}
+
+// TiXmlString copy constructor
+TiXmlString::TiXmlString (const TiXmlString& copy)
+{
+    unsigned newlen;
+    char * newstring;
+
+	// Prevent copy to self!
+	if ( &copy == this )
+		return;
+
+    if (! copy . allocated)
+    {
+        allocated = 0;
+        cstring = NULL;
+        return;
+    }
+    newlen = strlen (copy . cstring) + 1;
+    newstring = new char [newlen];
+    strcpy (newstring, copy . cstring);
+    allocated = newlen;
+    cstring = newstring;
+}
+
+// TiXmlString = operator. Safe when assign own content
+void TiXmlString ::operator = (const char * content)
+{
+    unsigned newlen;
+    char * newstring;
+
+    if (! content)
+    {
+        empty_it ();
+        return;
+    }
+    newlen = strlen (content) + 1;
+    newstring = new char [newlen];
+    strcpy (newstring, content);
+    empty_it ();
+    allocated = newlen;
+    cstring = newstring;
+}
+
+// = operator. Safe when assign own content
+void TiXmlString ::operator = (const TiXmlString & copy)
+{
+    unsigned newlen;
+    char * newstring;
+
+    if (! copy . length ())
+    {
+        empty_it ();
+        return;
+    }
+    newlen = copy . length () + 1;
+    newstring = new char [newlen];
+    strcpy (newstring, copy . c_str ());
+    empty_it ();
+    allocated = newlen;
+    cstring = newstring;
+}
+
+
+//// Checks if a TiXmlString contains only whitespace (same rules as isspace)
+//bool TiXmlString::isblank () const
+//{
+//    char * lookup;
+//    for (lookup = cstring; * lookup; lookup++)
+//        if (! isspace (* lookup))
+//            return false;
+//    return true;
+//}
+
+// append a const char * to an existing TiXmlString
+void TiXmlString::append( const char* str, int len )
+{
+    char * new_string;
+    unsigned new_alloc, new_size;
+
+    new_size = length () + len + 1;
+    // check if we need to expand
+    if (new_size > allocated)
+    {
+        // compute new size
+        new_alloc = assign_new_size (new_size);
+
+        // allocate new buffer
+        new_string = new char [new_alloc];        
+        new_string [0] = 0;
+
+        // copy the previous allocated buffer into this one
+        if (allocated && cstring)
+            strcpy (new_string, cstring);
+
+        // append the suffix. It does exist, otherwize we wouldn't be expanding 
+        strncat (new_string, str, len);
+
+        // return previsously allocated buffer if any
+        if (allocated && cstring)
+            delete [] cstring;
+
+        // update member variables
+        cstring = new_string;
+        allocated = new_alloc;
+    }
+    else
+        // we know we can safely append the new string
+        strncat (cstring, str, len);
+}
+
+
+// append a const char * to an existing TiXmlString
+void TiXmlString::append( const char * suffix )
+{
+    char * new_string;
+    unsigned new_alloc, new_size;
+
+    new_size = length () + strlen (suffix) + 1;
+    // check if we need to expand
+    if (new_size > allocated)
+    {
+        // compute new size
+        new_alloc = assign_new_size (new_size);
+
+        // allocate new buffer
+        new_string = new char [new_alloc];        
+        new_string [0] = 0;
+
+        // copy the previous allocated buffer into this one
+        if (allocated && cstring)
+            strcpy (new_string, cstring);
+
+        // append the suffix. It does exist, otherwize we wouldn't be expanding 
+        strcat (new_string, suffix);
+
+        // return previsously allocated buffer if any
+        if (allocated && cstring)
+            delete [] cstring;
+
+        // update member variables
+        cstring = new_string;
+        allocated = new_alloc;
+    }
+    else
+        // we know we can safely append the new string
+        strcat (cstring, suffix);
+}
+
+// Check for TiXmlString equuivalence
+//bool TiXmlString::operator == (const TiXmlString & compare) const
+//{
+//    return (! strcmp (c_str (), compare . c_str ()));
+//}
+
+unsigned TiXmlString::length () const
+{
+    if (allocated)
+        return strlen (cstring);
+    return 0;
+}
+
+
+unsigned TiXmlString::find (char tofind, unsigned offset) const
+{
+    char * lookup;
+
+    if (offset >= length ())
+        return (unsigned) notfound;
+    for (lookup = cstring + offset; * lookup; lookup++)
+        if (* lookup == tofind)
+            return lookup - cstring;
+    return (unsigned) notfound;
+}
+
+
+bool TiXmlString::operator == (const TiXmlString & compare) const
+{
+	if ( allocated && compare.allocated )
+	{
+		assert( cstring );
+		assert( compare.cstring );
+		return ( strcmp( cstring, compare.cstring ) == 0 );
+ 	}
+	return false;
+}
+
+
+bool TiXmlString::operator < (const TiXmlString & compare) const
+{
+	if ( allocated && compare.allocated )
+	{
+		assert( cstring );
+		assert( compare.cstring );
+		return ( strcmp( cstring, compare.cstring ) > 0 );
+ 	}
+	return false;
+}
+
+
+bool TiXmlString::operator > (const TiXmlString & compare) const
+{
+	if ( allocated && compare.allocated )
+	{
+		assert( cstring );
+		assert( compare.cstring );
+		return ( strcmp( cstring, compare.cstring ) < 0 );
+ 	}
+	return false;
+}
+
+
+#endif	// TIXML_USE_STL
Index: GTP-Internal/trunk/Lib/Vis/work/iv/IVFrameListener.cpp
===================================================================
--- GTP-Internal/trunk/Lib/Vis/work/iv/IVFrameListener.cpp	(revision 417)
+++ GTP-Internal/trunk/Lib/Vis/work/iv/IVFrameListener.cpp	(revision 417)
@@ -0,0 +1,1219 @@
+#include <OgreNoMemoryMacros.h>
+#include <CEGUI/CEGUI.h>
+#include <../CEGUIRenderer/include/OgreCEGUIRenderer.h>
+#include <../CEGUIRenderer/include/OgreCEGUIResourceProvider.h>
+#include <../CEGUIRenderer/include/OgreCEGUITexture.h>
+#include <OgreMemoryMacros.h>
+#include "IVFrameListener.h"
+#include "OgreVisibilityOctreeSceneManager.h"
+#include "VisibilityInfo.h"
+#include "TestCullingIVApplication.h"
+
+
+//-- captions for overlays
+String IVFrameListener::msAlgorithmCaptions[] = 
+{
+	"Coherent Hierarchical Culling",
+	"View Frustum Culling", 
+	"Stop and Wait Culling"
+};
+
+
+// output file for frame info
+const char* frames_out_filename = "frame.out";
+// output file for object positions / orientations
+const char* objects_out_filename = "objects.out";
+
+
+//-----------------------------------------------------------------------
+IVFrameListener::IVFrameListener(RenderWindow* win, Camera* cam, 
+									   SceneManager *sceneManager, 
+									   CEGUI::Renderer *renderer,
+									   Camera *vizCamera,
+									   SceneNode *camNode,
+									   Light *sunLight,
+									   TestCullingIVApplication *app): 
+mCamera(cam),
+mWindow(win),
+mNumScreenShots(0),
+mTimeDelay(0),
+mSceneDetailIndex(0),
+mMoveScale(0.0f),
+mRotScale(0.0f),
+mTranslateVector(Vector3::ZERO),
+mAniso(1),
+mFiltering(TFO_BILINEAR), 
+mGUIRenderer(renderer), 
+mSceneMgr(sceneManager),
+mVisibilityThreshold(0),
+mAssumedVisibility(0),
+//mCurrentAlgorithm(GtpVisibility::VisibilityEnvironment::COHERENT_HIERARCHICAL_CULLING),
+//mCurrentAlgorithm(GtpVisibility::VisibilityEnvironment::STOP_AND_WAIT_CULLING),
+mCurrentAlgorithm(GtpVisibility::VisibilityEnvironment::FRUSTUM_CULLING),
+mNodeVizMode(NODEVIZ_NONE),
+mVizCameraHeight(Real(2500.0)),
+mCamNode(camNode),
+mAppState(WALKTHROUGH),
+mCurrentFrame(0),
+mReplayTimeElapsed(0),
+mRotateSpeed(72),
+mVizCamera(vizCamera),
+mStatsOn(true),
+mShutdownRequested(false), 
+mLMouseDown(false),
+mRMouseDown(false),
+mShowOctree(false),
+mUseDepthPass(false),
+mUseArbQueries(false),
+mTestGeometryForVisibleLeaves(false),
+mShowVisualization(false),
+mCullCamera(false),
+mRecordFrames(false),
+mShowShadows(false),
+mShowHelp(false),
+mDisplayCameraDetails(false),
+mVisualizeCulledNodes(false),
+mSunLight(sunLight),
+mShiftPressed(false),
+mShowQueryStats(false),
+mVisibilityManager(NULL),
+mDelayedQueriesIssued(0.0),
+mDelayedTraversedNodes(0.0),
+mApplication(app),
+mMoveSpeed(15),
+mAccumulatedTris(0),
+mAccumulatedFps(0)
+{
+	mRaySceneQuery = mSceneMgr->createRayQuery(
+        Ray(mCamNode->getPosition(), Vector3::NEGATIVE_UNIT_Y));
+
+	//mInputDevice = PlatformManager::getSingleton().createInputReader();
+	//mInputDevice->initialise(win, true, true);
+
+	mEventProcessor = new EventProcessor();
+	
+	mEventProcessor->initialise(win);
+	mEventProcessor->startProcessingEvents();
+	mEventProcessor->addMouseListener(this);
+	mEventProcessor->addMouseMotionListener(this);
+	mEventProcessor->addKeyListener(this);
+
+	mInputDevice = mEventProcessor->getInputReader();	
+
+	//-- overlays
+	mDebugOverlay = OverlayManager::getSingleton().getByName("Core/DebugOverlay");
+	mHelpOverlay = OverlayManager::getSingleton().getByName("Example/Visibility/HelpOverlay"); 
+	mQueryOverlay = OverlayManager::getSingleton().getByName("Example/Visibility/QueryOverlay"); 
+	mCullStatsOverlay = OverlayManager::getSingleton().getByName("Example/Visibility/CullStatsOverlay"); 
+
+	initVisStatsOverlay(); // visibility stats overlay
+	initHelpOverlay(); // help overlay
+	initQueryOverlay(); // visibility query stats overlay
+
+	// show stats overlays
+	showStats(true);
+	
+	// set culling algorithm type
+	setAlgorithm(mCurrentAlgorithm);
+
+	// set scene manager options
+	mSceneMgr->setOption("TestGeometryForVisibleLeaves", &mTestGeometryForVisibleLeaves);
+
+	// apply delayed rendering (i.e., transparents after hierarchical culling pass)
+	// only if optimization is not used 
+	bool delayRenderTransparents = !mTestGeometryForVisibleLeaves;
+
+	mSceneMgr->setOption("DelayRenderTransparents", &delayRenderTransparents);
+	mSceneMgr->setOption("UseDepthPass", &mUseDepthPass);
+	//mSceneMgr->setOption("UseArbQueries", &mUseArbQueries);
+
+	mSceneMgr->setOption("ShowOctree", &mShowOctree);
+	mSceneMgr->setOption("CullCamera", &mCullCamera);
+	mSceneMgr->setOption("PrepareVisualization", &mShowVisualization);
+
+	// reset statistics
+	resetStats();
+} 
+//-----------------------------------------------------------------------
+IVFrameListener::~IVFrameListener()
+{
+	OGRE_DELETE(mEventProcessor);
+	OGRE_DELETE(mRaySceneQuery);
+}
+//-----------------------------------------------------------------------
+void IVFrameListener::mouseMoved(MouseEvent *e)
+{
+	// Update CEGUI with the mouse motion
+    CEGUI::System::getSingleton().injectMouseMove(e->getRelX() * 
+		mGUIRenderer->getWidth(), e->getRelY() * mGUIRenderer->getHeight());
+}
+//-----------------------------------------------------------------------
+void IVFrameListener::mousePressed(MouseEvent* e)
+{
+     // Left mouse button down
+     if (e->getButtonID() & InputEvent::BUTTON0_MASK)
+     {
+		 CEGUI::MouseCursor::getSingleton().hide();
+		
+         mLMouseDown = true; 
+     }
+     // Right mouse button down
+     else if (e->getButtonID() & InputEvent::BUTTON1_MASK)
+     {
+         CEGUI::MouseCursor::getSingleton().hide();
+         mRMouseDown = true;
+     }
+}
+//-----------------------------------------------------------------------
+void IVFrameListener::mouseDragDropped(MouseEvent* e)
+{
+	// Left mouse button up
+    if (e->getButtonID() & InputEvent::BUTTON0_MASK)
+    {
+		CEGUI::MouseCursor::getSingleton().show();
+		
+	    mLMouseDown = false;
+    }
+    // Right mouse button up
+    else if (e->getButtonID() & InputEvent::BUTTON1_MASK)
+    {
+        CEGUI::MouseCursor::getSingleton().show();
+
+		mRMouseDown = false;
+    }
+}
+//-----------------------------------------------------------------------
+void IVFrameListener::mouseReleased(MouseEvent* e)
+{
+    // Left mouse button up
+    if (e->getButtonID() & InputEvent::BUTTON0_MASK)
+    {
+		CEGUI::MouseCursor::getSingleton().show();
+		
+	    mLMouseDown = false;
+    }
+    // Right mouse button up
+    else if (e->getButtonID() & InputEvent::BUTTON1_MASK)
+    {
+        CEGUI::MouseCursor::getSingleton().show(); 
+
+        mRMouseDown = false;
+    }
+} 
+//-----------------------------------------------------------------------
+void IVFrameListener::mouseDragged(MouseEvent *e)
+ {
+	 // If we are dragging the left mouse button.	 	 
+	 if (mLMouseDown)
+     {
+     }
+	 // If we are dragging the right mouse button.
+	 if (mRMouseDown)
+	 {
+		 mCamNode->yaw(-e->getRelX() * mRotateSpeed);
+		 mCamNode->pitch(-e->getRelY() * mRotateSpeed);
+	 }
+}
+//-----------------------------------------------------------------------
+bool IVFrameListener::frameStarted(const FrameEvent &evt)
+{
+	if (mWindow->isClosed())
+	{
+        return false;
+	}
+
+	if (mDisplayCameraDetails)  // Print camera details
+    {       
+        mWindow->setDebugText("P: " + StringConverter::toString(mCamera->getDerivedPosition()) + 
+			" " + "O: " + StringConverter::toString(mCamera->getDerivedOrientation()));
+    }
+
+	//-- setup what is needed for immediate mouse/key movement
+	if (mTimeDelay >= 0) 
+	{
+		mTimeDelay -= evt.timeSinceLastFrame;
+	}
+	
+	// If this is the first frame, pick a speed
+	if (evt.timeSinceLastFrame == 0)
+	{
+		mMoveScale = 1;
+		mRotScale = 0.1;
+	}
+	// Otherwise scale movement units by time passed since last frame
+	else
+	{
+		// Move about 100 units per second,
+		mMoveScale = mMoveSpeed * evt.timeSinceLastFrame;
+		// Take about 10 seconds for full rotation
+		mRotScale = mRotateSpeed * evt.timeSinceLastFrame;
+	}
+
+	mRotX = 0;
+	mRotY = 0;
+	mTranslateVector = Vector3::ZERO;
+
+	if (!processUnbufferedKeyInput(evt))
+	{
+		return false;
+	}
+	if (!processUnbufferedMouseInput(evt))
+	{	
+		return false;	
+	}
+
+	// --- set parameters for visualization
+	if (mShowVisualization)
+	{
+		// important for visualization => draw octree bounding boxes
+		mSceneMgr->setOption("ShowOctree", &mShowVisualization);
+		
+		// ---- setup visualization camera
+
+		mVizCamera->setPosition(0, 0, 0);
+		mVizCamera->setOrientation(Quaternion::IDENTITY);
+
+		Vector3 camPos = mCamNode->getPosition();
+		mVizCamera->setPosition(camPos.x, mVizCameraHeight, camPos.z);
+
+		// point down -Z axis
+		mVizCamera->pitch(Radian(Degree(270.0)));
+
+		// rotation arounnd X axis
+		mVizCamera->yaw(Math::ATan2(-mCamera->getDerivedDirection().x, 
+			-mCamera->getDerivedDirection().z));
+		
+		// move by a constant so view plane is on bottom of viewport
+		mVizCamera->moveRelative(Vector3(0, 800, 0));
+	}
+
+	//-- set application state
+	switch (mAppState)
+	{
+	case REPLAY:
+		setCurrentFrameInfo(evt.timeSinceLastFrame);
+		break;
+	case WALKTHROUGH:
+		//-- if we are recording camera status per frame
+		if (mRecordFrames)
+		{
+			addFrameInfo(mCamNode, evt.timeSinceLastFrame);
+			// print recording message
+			mWindow->setDebugText("Recording frame " + 
+				StringConverter::toString(mFrameInfo.size() - 1));
+		}	
+	
+		// move camera according to input
+		moveCamera();
+
+		// clamp camera so we always walk along the floor plane
+		Clamp2Floor();
+
+		break;
+
+	default:
+		break;
+	};	
+
+	return true;
+}
+
+bool IVFrameListener::processUnbufferedMouseInput(const FrameEvent& evt)
+{
+	/* Rotation factors, may not be used if the second mouse button is pressed. */
+
+    /* If the second mouse button is pressed, then the mouse movement results in 
+       sliding the camera, otherwise we rotate. */
+    if (mInputDevice->getMouseButton(1))
+    {
+		mTranslateVector.x += mInputDevice->getMouseRelativeX() * 0.13;
+		mTranslateVector.y -= mInputDevice->getMouseRelativeY() * 0.13;
+	}
+	else
+	{
+		mRotX = Degree(-mInputDevice->getMouseRelativeX() * 0.13);
+		mRotY = Degree(-mInputDevice->getMouseRelativeY() * 0.13);
+	}
+
+
+	return true;
+}
+//-----------------------------------------------------------------------
+bool IVFrameListener::Clamp2Floor()
+{
+	// clamp to floor plane
+	Ray updateRay;
+    updateRay.setOrigin(Vector3(mCamNode->getPosition().x, mCamNode->getPosition().y /*+ 2*/, 
+		mCamNode->getPosition().z));
+	//updateRay.setOrigin(Vector3(0, 100, -200));
+	updateRay.setDirection(Vector3::NEGATIVE_UNIT_Y);
+    mRaySceneQuery->setRay(updateRay);
+
+	RaySceneQueryResult& qryResult = mRaySceneQuery->execute();
+    
+	RaySceneQueryResult::iterator it = qryResult.begin();
+ 
+	while (it != qryResult.end() && it->movable)
+	{
+		if (it->movable->getName() != "PlayerCam")
+		{
+			mCamNode->setPosition(mCamNode->getPosition().x, 
+				it->movable->getWorldBoundingBox().getCenter().y + 2, 
+				mCamNode->getPosition().z);
+	
+			/*std::stringstream d;
+			d << "World: " << it->movable->getWorldBoundingBox().getCenter().y <<
+			", Object: " << it->movable->getBoundingBox().getCenter().y <<
+			", Camera: " << mCamera->getDerivedPosition();
+
+			LogManager::getSingleton().logMessage(d.str());*/
+
+			return true;
+		}
+		++ it;
+	}
+	return false;
+}
+//-----------------------------------------------------------------------
+bool IVFrameListener::frameEnded(const FrameEvent& evt)
+{
+	if (mShutdownRequested)
+		return false;
+
+    updateStats();
+
+	//-- IMPORTANT
+	mSceneMgr->endFrame();
+
+	if (mTimeDelay <= 0) // approx. one second
+		mTimeDelay = 1.0;
+
+	return true;
+}
+//-----------------------------------------------------------------------
+void IVFrameListener::moveCamera()
+{
+	// move node rather than camera so orientation is right in the visualization
+	mCamNode->yaw(mRotX);
+	mCamNode->pitch(mRotY);
+	mCamNode->translate(mCamNode->getLocalAxes(), mTranslateVector);
+}
+//-----------------------------------------------------------------------
+void IVFrameListener::writeFrames()
+{
+	std::ofstream ofstr(frames_out_filename);
+	
+	std::vector<frame_info>::const_iterator it, it_end;
+
+	it_end = mFrameInfo.end();
+	for (it = mFrameInfo.begin(); it < it_end; ++it)
+	{
+		ofstr << StringConverter::toString((*it).position) << " " 
+			  << StringConverter::toString((*it).orientation) << " "
+			  << StringConverter::toString((*it).timeElapsed) << "\n";
+	}
+	ofstr.close();
+}
+//-----------------------------------------------------------------------
+void IVFrameListener::loadFrames()
+{
+	std::ifstream ifstr(frames_out_filename);
+	char line[256];
+	frame_info info;
+
+	// reset current values
+	mFrameInfo.clear();
+	mCurrentFrame = 0;
+	
+	while (!ifstr.eof()) 
+	{
+		ifstr.getline(line, 256);
+		sscanf(line, "%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);
+		
+		mFrameInfo.push_back(info);
+	}
+	ifstr.close();
+}
+//-----------------------------------------------------------------------
+void IVFrameListener::nextAppState()
+{
+	mCurrentFrame = 0;
+
+	// if last state was replay state
+	if (mAppState == REPLAY)
+	{
+		// reset debug text and write frame info to file
+		mWindow->setDebugText("");
+		writeFrames();
+		
+		float avgFps = (float)mAccumulatedFps / (float)mFrameCount;
+		float avgTris = (float)mAccumulatedTris / (float)mFrameCount;
+
+		//-- write out stats for recorded walkthrough
+		std::stringstream d;
+	
+		d << "Algorithm: " << msAlgorithmCaptions[mCurrentAlgorithm] << "\n"
+		  //<< "avg. FPS: " << mWindow->getAverageFPS() << "\n"
+		  << "avg. FPS: " << avgFps << "\n"
+		  << "best FPS: " << mWindow->getBestFPS() << "\n"
+		  << "worst FPS: " << mWindow->getWorstFPS() << "\n"
+		  << "best frame time: " <<	mWindow->getBestFrameTime() << "\n"
+		  << "worst frame time: " << mWindow->getWorstFrameTime() << "\n"
+		  << "avg. #triangles: " << avgTris << " M\n"
+		  << "#frames: " << mFrameCount << "\n";
+
+		LogManager::getSingleton().logMessage(d.str());
+	}
+	
+	//-- set the next státe
+	mAppState = (mAppState + 1) % STATE_NUM;
+
+	// replay recorded walkthrough
+	if (mAppState == REPLAY)
+	{
+		// no recording during replay
+		mRecordFrames = false;
+
+		// load recorded walkthrough
+		if (mFrameInfo.size() == 0)
+		{
+			loadFrames();
+		}
+
+		// if there are no recorded frames => set next state
+		if (mFrameInfo.size() == 0) 
+		{
+			nextAppState();
+		}
+		else
+		{
+			mWindow->setDebugText("Replay");
+			
+			// reset, because we measure fps stats during walkthrough (warning: average fps broken)
+			mWindow->resetStatistics();
+			resetStats();
+
+			//-- initialise frame data
+			mReplayTimeElapsed = 0;
+
+			mCamNode->setPosition(mFrameInfo[0].position);
+			mCamNode->setOrientation(mFrameInfo[0].orientation);
+		}
+	}
+
+}
+//-----------------------------------------------------------------------
+void IVFrameListener::toggleRecord()
+{
+	mRecordFrames = !mRecordFrames;
+
+	// clear previous camera path
+	if (mRecordFrames)
+		mFrameInfo.clear();
+	else
+		mWindow->setDebugText("");
+}
+//-----------------------------------------------------------------------
+void IVFrameListener::changeThreshold(int incr)
+{
+	mVisibilityThreshold += incr; 
+	if(mVisibilityThreshold < 0) mVisibilityThreshold = 0;
+	
+	char str[100]; sprintf(str,": %d", mVisibilityThreshold);
+
+	mSceneMgr->setOption("Threshold", &mVisibilityThreshold); 
+	mThresholdInfo->setCaption(str);
+}
+//-----------------------------------------------------------------------
+void IVFrameListener::changeAssumedVisibility(int incr)
+{
+	mAssumedVisibility += incr; 
+	if(mAssumedVisibility < 0) mAssumedVisibility = 0;
+	
+	char str[100]; sprintf(str,": %d", mAssumedVisibility);
+
+	mSceneMgr->setOption("AssumedVisibility", &mAssumedVisibility); 
+	mAssumedVisibilityInfo->setCaption(str);
+}
+//-----------------------------------------------------------------------
+void IVFrameListener::zoomVizCamera(int zoom)
+{
+	mVizCameraHeight += zoom; 
+	if(mVizCameraHeight < 0) mVizCameraHeight = 0;
+}
+//-----------------------------------------------------------------------
+void IVFrameListener::nextAlgorithm()
+{
+	mCurrentAlgorithm = (mCurrentAlgorithm + 1) % 
+		GtpVisibility::VisibilityEnvironment::NUM_CULLING_MANAGERS;
+	setAlgorithm(mCurrentAlgorithm);
+}
+//-----------------------------------------------------------------------
+void IVFrameListener::setAlgorithm(int algorithm)
+{
+	mAlgorithmInfo->setCaption(": " + msAlgorithmCaptions[mCurrentAlgorithm]);
+	mSceneMgr->setOption("Algorithm", &mCurrentAlgorithm);
+}
+//-----------------------------------------------------------------------
+void IVFrameListener::resetStats()
+{
+	mAccumulatedFps = 0;
+	mAccumulatedTris = 0;
+	mFrameCount = 0;
+}
+//-----------------------------------------------------------------------
+void IVFrameListener::updateStats()
+{
+	unsigned int opt = 0;
+	char str[100];
+	
+	static String currFpsString = "Current FPS: ";
+	static String avgFpsString = "Average FPS: ";
+	static String bestFpsString = "Best FPS: ";
+	static String worstFpsString = "Worst FPS: ";
+	static String trisString = "Triangle Count: ";
+
+	// HACK: compute average fps ourselfs, because ogre avg. fps is wrong
+	// TODO: update only once per second
+	mAccumulatedFps += mWindow->getStatistics().lastFPS;
+	++ mFrameCount;
+	
+	float avgFps = (float)mAccumulatedFps / (float)mFrameCount;
+    
+	// update stats when necessary
+    try 
+	{
+		OverlayElement* guiAvg = OverlayManager::getSingleton().getOverlayElement("Core/AverageFps");
+		OverlayElement* guiCurr = OverlayManager::getSingleton().getOverlayElement("Core/CurrFps");
+		OverlayElement* guiBest = OverlayManager::getSingleton().getOverlayElement("Core/BestFps");
+		OverlayElement* guiWorst = OverlayManager::getSingleton().getOverlayElement("Core/WorstFps");
+
+		const RenderTarget::FrameStats& stats = mWindow->getStatistics();
+
+		//guiAvg->setCaption(avgFps + StringConverter::toString(stats.avgFPS));
+		if (mTimeDelay < 0) // only update once per second
+		{		
+			guiAvg->setCaption(avgFpsString + StringConverter::toString(avgFps) + " ms");
+		}
+		//std::stringstream d; d << "frame rate :" << stats.lastFPS;
+		//Ogre::LogManager::getSingleton().logMessage(d.str());
+
+		guiCurr->setCaption(currFpsString + StringConverter::toString(stats.lastFPS));
+		guiBest->setCaption(bestFpsString + StringConverter::toString(stats.bestFPS)
+			+" "+StringConverter::toString(stats.bestFrameTime) + " ms");
+		guiWorst->setCaption(worstFpsString + StringConverter::toString(stats.worstFPS)
+			+" "+StringConverter::toString(stats.worstFrameTime) + " ms");
+
+		OverlayElement* guiTris = OverlayManager::getSingleton().getOverlayElement("Core/NumTris");
+        guiTris->setCaption(trisString + StringConverter::toString(stats.triangleCount));
+
+		OverlayElement* guiDbg = OverlayManager::getSingleton().getOverlayElement("Core/DebugText");
+		guiDbg->setCaption(mWindow->getDebugText());
+
+		//-- culling stats
+		mSceneMgr->getOption("NumFrustumCulledNodes", &opt); sprintf(str,": %d", opt); 
+		mFrustumCulledNodesInfo->setCaption(str);
+
+		mSceneMgr->getOption("NumQueryCulledNodes", &opt); sprintf(str,": %d", opt); 
+		mQueryCulledNodesInfo->setCaption(str);
+	
+		mSceneMgr->getOption("NumHierarchyNodes", &opt); sprintf(str,": %d", opt); 
+		mHierarchyNodesInfo->setCaption(str);
+
+		mSceneMgr->getOption("NumRenderedNodes", &opt); sprintf(str,": %d", opt); 
+		mRenderedNodesInfo->setCaption(str);
+
+	//	sprintf(str,": %d", mTerrainContentGenerator->GetObjectCount()); 
+	//	mObjectsCountInfo->setCaption(str);
+
+		// take old value into account in order to create no sudden changes
+		mSceneMgr->getOption("NumQueriesIssued", &opt); 
+		mDelayedQueriesIssued = mDelayedQueriesIssued * 0.8 + (float)opt * 0.2;
+		sprintf(str,": %d", (int)mDelayedQueriesIssued); 
+		mQueriesIssuedInfo->setCaption(str);
+
+		mSceneMgr->getOption("NumTraversedNodes", &opt); 
+		mDelayedTraversedNodes = mDelayedTraversedNodes * 0.8 + (float)opt * 0.2;
+		sprintf(str,": %d", (int)mDelayedTraversedNodes); 
+		mTraversedNodesInfo->setCaption(str);
+
+	}
+	catch (...)
+	{
+		// ignore
+	}
+}
+//-----------------------------------------------------------------------
+void IVFrameListener::toggleTestGeometryForVisibleLeaves()
+{
+	mTestGeometryForVisibleLeaves = !mTestGeometryForVisibleLeaves;
+	mSceneMgr->setOption("TestGeometryForVisibleLeaves", &mTestGeometryForVisibleLeaves);
+	
+	/* disable optimization which tests geometry instead of aabb
+	 * for "delayed" rendering of transparents (i.e., render transparents after all the solids)
+	 * because otherwise visible transparents could be skipped
+	 */
+	bool delayedRendering = !mTestGeometryForVisibleLeaves;
+
+	mSceneMgr->setOption("DelayRenderTransparents", &delayedRendering);
+
+	if (mTestGeometryForVisibleLeaves)
+	{
+		mTestGeometryForVisibleLeavesInfo->setCaption(": true");
+	}
+	else
+	{
+		mTestGeometryForVisibleLeavesInfo->setCaption(": false");
+	}
+}
+//-----------------------------------------------------------------------
+void IVFrameListener::toggleShowOctree()
+{
+	mShowOctree = !mShowOctree;
+
+	mSceneMgr->setOption("ShowOctree", &mShowOctree);
+}
+//-----------------------------------------------------------------------
+void IVFrameListener::toggleUseArbQueries()
+{
+	mUseArbQueries = !mUseArbQueries;
+
+	mSceneMgr->setOption("UseArbQueries", &mUseArbQueries);
+	
+	if (mUseArbQueries)
+	{
+		mUseArbQueriesInfo->setCaption(": ARB");
+	}
+	else
+	{
+		mUseArbQueriesInfo->setCaption(": NV");
+	}
+}
+//-----------------------------------------------------------------------
+void IVFrameListener::toggleUseDepthPass()
+{
+	mUseDepthPass = !mUseDepthPass;
+
+	mSceneMgr->setOption("UseDepthPass", &mUseDepthPass);
+	
+	if (mUseDepthPass)
+	{
+		mUseDepthPassInfo->setCaption(": true");
+	}
+	else
+	{
+		mUseDepthPassInfo->setCaption(": false");
+	}
+}
+//-----------------------------------------------------------------------
+void IVFrameListener::toggleShowViz()
+{
+	mVisualizeCulledNodes = mShowVisualization = !mShowVisualization;
+	
+	// create viewport with priority VIZ_VIEWPORT_Z_ORDER: 
+	// will be rendered over standard viewport
+	if (mShowVisualization)
+	{	
+		Viewport *vizvp = mWindow->addViewport(mVizCamera, 
+			VIZ_VIEWPORT_Z_ORDER, 0.6, 0.6, 0.4, 0.4); 
+				
+		vizvp->setBackgroundColour(ColourValue(0.0, 0.3, 0.2, 1));
+
+		vizvp->setOverlaysEnabled(false);
+		// Alter the camera aspect ratio to match the viewport
+        mVizCamera->setAspectRatio(Real(vizvp->getActualWidth()) / 
+								   Real(vizvp->getActualHeight()));
+		
+		mSceneMgr->setOption("VisualizeCulledNodes", &mVisualizeCulledNodes);
+	}
+	else
+	{
+		// remove visualization viewport
+		mWindow->removeViewport(VIZ_VIEWPORT_Z_ORDER);
+
+		// octree bounding boxes are shown for visualization purpose, reset now
+		mSceneMgr->setOption("ShowOctree", &mShowOctree);
+	}
+}
+//-----------------------------------------------------------------------
+void IVFrameListener::toggleShowShadows()
+{
+	mShowShadows = !mShowShadows;
+
+	mSunLight->setCastShadows(mShowShadows);
+
+	if (mShowShadows)
+	{
+		mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_MODULATIVE);
+		//mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_MODULATIVE);
+		//mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_ADDITIVE);		
+	}
+	else
+	{
+		mSceneMgr->setShadowTechnique(SHADOWTYPE_NONE);
+	}
+
+}
+//-----------------------------------------------------------------------
+void IVFrameListener::nextNodeVizMode()
+{
+	mNodeVizMode = (mNodeVizMode + 1) % NODEVIZ_MODES_NUM;
+
+	bool renderNodesForViz = (mNodeVizMode == NODEVIZ_RENDER_NODES) || 
+		(mNodeVizMode == NODEVIZ_RENDER_NODES_AND_CONTENT);
+	bool renderNodesContentForViz = (mNodeVizMode == NODEVIZ_RENDER_NODES_AND_CONTENT);
+	//bool renderNodesContentForViz = mNodeVizMode == NODEVIZ_RENDER_GEOMETRY;
+
+	mSceneMgr->setOption("RenderNodesForViz", &renderNodesForViz);
+	mSceneMgr->setOption("RenderNodesContentForViz", &renderNodesContentForViz);
+}
+//-----------------------------------------------------------------------
+void IVFrameListener::keyPressed(KeyEvent* e)
+{
+	// hide exact visibility query overlay
+	if (mShowQueryStats)
+	{
+		mQueryOverlay->hide();
+		mShowQueryStats = false;
+	}
+
+	switch(e->getKey())
+	{
+	case KC_ESCAPE:
+		mShutdownRequested = true;
+		e->consume();
+		return;
+
+	case KC_SPACE:
+		nextAlgorithm();
+		break;
+	
+    case KC_F:
+		nextFilter();
+		break;
+	case KC_R:
+		nextSceneDetailLevel();
+		break;
+	case KC_P:
+		toggleDisplayCameraDetails();
+		break;
+	case KC_G:
+		toggleTestGeometryForVisibleLeaves();
+		break;
+	case KC_T:
+		toggleShowOctree();
+		break;
+	case KC_X:
+		toggleUseDepthPass();
+		break;
+	case KC_S:
+		toggleShowShadows();
+		break;
+	case KC_SUBTRACT:
+		changeThreshold(-10);
+		break;
+	case KC_ADD:
+		changeThreshold(10);
+		break;
+
+	//-- visualization
+	case KC_1:
+		toggleShowViz();
+		break;
+	case KC_2:
+		nextNodeVizMode();
+		break;
+
+	case KC_F1:
+		toggleShowHelp();
+		break;
+	case KC_F2:
+		toggleShowStats();
+		break;
+	case KC_F3:
+		nextAppState();
+		break;
+	case KC_F4:
+		toggleRecord();
+		break;
+
+	case KC_F11:
+		takeScreenshot();
+		break;
+
+	case KC_8:
+		changeAssumedVisibility(-1);
+		break;
+	case KC_9:
+		changeAssumedVisibility(1);
+		break;
+	case KC_LSHIFT:
+		mShiftPressed = true;
+		break;
+	case KC_A:
+		toggleUseArbQueries();
+		break;
+	default:
+		break;
+	}
+
+	CEGUI::System::getSingleton().injectKeyDown(e->getKey());
+	CEGUI::System::getSingleton().injectChar(e->getKeyChar());
+	e->consume();
+}
+//-----------------------------------------------------------------------
+void IVFrameListener::keyReleased(KeyEvent* e)
+{
+	if (e->getKey() == KC_LSHIFT)
+	{
+		mShiftPressed = false;
+	}
+	
+	CEGUI::System::getSingleton().injectKeyUp(e->getKey());
+	e->consume();
+}
+//-----------------------------------------------------------------------
+void IVFrameListener::keyClicked(KeyEvent* e) 
+{
+	// Do nothing
+	e->consume();
+}
+//-----------------------------------------------------------------------
+void IVFrameListener::addFrameInfo(SceneNode *camNode, Real timeElapsed)
+{
+	frame_info info;
+	info.orientation = mCamNode->getOrientation();
+	info.position = mCamNode->getPosition();
+	info.timeElapsed = timeElapsed;
+	
+	mFrameInfo.push_back(info);
+}
+//-----------------------------------------------------------------------
+void IVFrameListener::setCurrentFrameInfo(Real timeElapsed)
+{
+	//-- find current frame relative to elapsed frame time		
+	mReplayTimeElapsed -= timeElapsed;
+
+	while ((mReplayTimeElapsed <= 0) && (mCurrentFrame < (int)mFrameInfo.size() - 1))
+	{
+		mReplayTimeElapsed += mFrameInfo[mCurrentFrame ++].timeElapsed;
+	}
+
+	frame_info new_frame = mFrameInfo[mCurrentFrame];
+	frame_info old_frame = mFrameInfo[mCurrentFrame - 1];
+		
+	//-- interpolate frames
+	Real factor = 1;
+
+	if (old_frame.timeElapsed > 0)
+	{
+		factor = mReplayTimeElapsed / old_frame.timeElapsed;
+	}
+
+	Vector3 camPos = old_frame.position + factor 
+		* (new_frame.position - old_frame.position);
+	Quaternion camOrienation = Quaternion::Slerp(factor, old_frame.orientation, 
+		new_frame.orientation, true);
+
+	mCamNode->setPosition(camPos);
+	mCamNode->setOrientation(camOrienation);
+	
+	// stop replay after a full walkthrough
+	if (mCurrentFrame == (int)mFrameInfo.size() - 1)
+	{
+		nextAppState();
+	}
+}
+//-----------------------------------------------------------------------    
+bool IVFrameListener::processUnbufferedKeyInput(const FrameEvent& evt)
+{
+	bool cursorPressed = false;
+	
+	/* Move camera forward by keypress. */
+    if (mInputDevice->isKeyDown(KC_UP))
+	{
+		mTranslateVector.z = -mMoveScale;
+		cursorPressed = true;
+	}
+    /* Move camera backward by keypress. */
+    if (mInputDevice->isKeyDown(KC_DOWN))
+    {
+		mTranslateVector.z = mMoveScale;
+		cursorPressed = true;
+    }
+
+    if (mInputDevice->isKeyDown(KC_RIGHT))
+    {
+        //mCamNode->yaw(-mRotScale);
+		mRotX = -mRotScale;
+		cursorPressed = true;
+    }
+	
+    if (mInputDevice->isKeyDown(KC_LEFT))
+    {
+		mRotX = mRotScale;
+        //mCamNode->yaw(mRotScale);
+		cursorPressed = true;
+    }
+	// visualization camera
+	if (mInputDevice->isKeyDown(KC_3))
+	{
+		zoomVizCamera(50);
+	}
+	if (mInputDevice->isKeyDown(KC_4))
+	{
+		zoomVizCamera(-50);
+	}
+
+	// show the results
+	if (cursorPressed && mShowQueryStats)
+	{
+		mQueryOverlay->hide();
+		mShowQueryStats = false;
+	}
+
+    // Return true to continue rendering
+    return true;
+}
+//-----------------------------------------------------------------------
+void IVFrameListener::nextFilter()
+{
+	switch (mFiltering)
+	{
+	case TFO_BILINEAR:
+		mFiltering = TFO_TRILINEAR;
+		mAniso = 1;
+		break;
+	case TFO_TRILINEAR:
+		mFiltering = TFO_ANISOTROPIC;
+		mAniso = 8;
+		break;
+	case TFO_ANISOTROPIC:
+		mFiltering = TFO_BILINEAR;
+		mAniso = 1;
+		break;
+	default:
+		break;
+	}
+
+    MaterialManager::getSingleton().setDefaultTextureFiltering(mFiltering);
+    MaterialManager::getSingleton().setDefaultAnisotropy(mAniso);
+
+	// reload stats
+    showStats(mStatsOn);
+}
+//-----------------------------------------------------------------------
+void IVFrameListener::nextSceneDetailLevel()
+{
+	mSceneDetailIndex = (mSceneDetailIndex + 1) % 3;
+	switch (mSceneDetailIndex) 
+	{
+		case 0: 
+			mCamera->setDetailLevel(SDL_SOLID); 
+			break;
+		case 1: 
+			mCamera->setDetailLevel(SDL_WIREFRAME); 
+			break;
+		case 2: 
+			mCamera->setDetailLevel(SDL_POINTS); 
+			break;
+	}
+}
+//-----------------------------------------------------------------------
+void IVFrameListener::takeScreenshot()
+{
+	char tmp[20];
+	sprintf(tmp, "screenshot_%d.png", ++mNumScreenShots);
+    mWindow->writeContentsToFile(tmp);
+    mWindow->setDebugText(String("Wrote ") + tmp);
+}
+//-----------------------------------------------------------------------
+void IVFrameListener::toggleDisplayCameraDetails()
+{
+	mDisplayCameraDetails = !mDisplayCameraDetails;
+        
+    if (!mDisplayCameraDetails)
+	{
+		mWindow->setDebugText("");
+	}
+}
+//-----------------------------------------------------------------------
+void IVFrameListener::showStats(bool show)
+{
+	if (mDebugOverlay && mCullStatsOverlay)
+	{
+		if (show)
+		{
+			mDebugOverlay->show();
+			mCullStatsOverlay->show();
+		}
+		else
+		{
+			mDebugOverlay->hide();
+			mCullStatsOverlay->hide();
+		}
+	}
+}
+//-----------------------------------------------------------------------
+void IVFrameListener::toggleShowStats()
+{
+	mStatsOn = !mStatsOn;
+
+	showStats(mStatsOn);
+}
+//-----------------------------------------------------------------------
+void IVFrameListener::toggleShowHelp()
+{
+	mShowHelp = !mShowHelp;
+
+	if (mShowHelp)
+	{
+		mHelpOverlay->show();
+	}
+	else
+	{
+		mHelpOverlay->hide();
+	}
+}
+//-----------------------------------------------------------------------
+void IVFrameListener::initOverlayElement(OverlayElement **elInfo, String ext, 
+											  String name, int top, String caption)
+{
+	OverlayElement *el = 
+		OverlayManager::getSingleton().getOverlayElement(ext + name);
+
+	(*elInfo) = OverlayManager::getSingleton().getOverlayElement(ext + name + "Info");
+	(*elInfo)->setCaption(caption);
+
+	el->setTop(top);
+	(*elInfo)->setTop(top);
+}
+//-----------------------------------------------------------------------
+void IVFrameListener::initHelpOverlayElement(String name, int top)
+{
+	OverlayElement *el = OverlayManager::getSingleton().getOverlayElement(
+		"Example/Visibility/Help/" + name);
+
+	el->setTop(top);
+}
+//-----------------------------------------------------------------------
+void IVFrameListener::initHelpOverlay()
+{
+	const int vert_space = 15;
+	int top = 30;
+
+	initHelpOverlayElement("ShowHelp", top); top += vert_space;
+	initHelpOverlayElement("Stats", top); top += vert_space;
+	initHelpOverlayElement("AppState", top); top += vert_space;
+	initHelpOverlayElement("Recorded", top); top += vert_space;
+	initHelpOverlayElement("Animation", top); top += vert_space;
+	initHelpOverlayElement("Screenshots", top); top += vert_space;
+	initHelpOverlayElement("WriteOut", top); top += vert_space;
+
+	top +=vert_space;
+	initHelpOverlayElement("SceneDetail", top); top += vert_space;
+	initHelpOverlayElement("DisplayCameraDetails", top); top += vert_space;
+	initHelpOverlayElement("DisplayOctree", top); top += vert_space;
+	initHelpOverlayElement("UseShadows", top); top += vert_space;
+	initHelpOverlayElement("Filter", top); top += vert_space;
+
+	//-- visualization
+	top += vert_space;
+	initHelpOverlayElement("VizSection", top); top += vert_space;
+	initHelpOverlayElement("Viz", top); top += vert_space;
+	initHelpOverlayElement("NextVizMode", top); top += vert_space;
+	initHelpOverlayElement("ZoomViz", top); top += vert_space;
+
+
+	//-- visibility queries
+	top += vert_space;
+	initHelpOverlayElement("VisQuery", top); top += vert_space;
+	initHelpOverlayElement("FromCameraQuery", top); top += vert_space;
+	initHelpOverlayElement("FromPointQuery", top); top += vert_space;
+	initHelpOverlayElement("QueryType", top); top += vert_space;
+	initHelpOverlayElement("QueryTarget", top); top += vert_space;
+
+	//-- object generation
+	top += vert_space;
+	initHelpOverlayElement("SceneObjects", top); top += vert_space;
+	initHelpOverlayElement("GenerateObjects", top); top += vert_space;
+	initHelpOverlayElement("RemoveObjects", top); top += vert_space;
+	initHelpOverlayElement("DropObject", top); top += vert_space;
+
+	OverlayElement *helpPanel = OverlayManager::getSingleton().getOverlayElement(
+		"Example/Visibility/Help/HelpPanel");
+
+	helpPanel->setHeight(top + 10);
+}
+//-----------------------------------------------------------------------
+void IVFrameListener::initVisStatsOverlay()
+{
+	const int border_height = 10;
+	const int vert_space = 15;
+
+	//-- visibility culling stats overlay
+	int top = border_height;
+
+	String ext = "Example/Visibility/";
+	
+	initOverlayElement(&mAlgorithmInfo, ext, "Algorithm", top,
+		": " + msAlgorithmCaptions[mCurrentAlgorithm]); top += vert_space;
+
+	initOverlayElement(&mThresholdInfo, ext, "Threshold", top, ": 0"); top += vert_space;
+	initOverlayElement(&mTestGeometryForVisibleLeavesInfo, ext, 
+		"TestGeometryForVisibleLeaves", top, ": true"); top += vert_space;
+	initOverlayElement(&mUseDepthPassInfo, ext, "UseDepthPass", top, ": false"); top += vert_space;
+	initOverlayElement(&mAssumedVisibilityInfo, ext, "AssumedVisibility", top, ": 0"); top += vert_space;
+	initOverlayElement(&mCurrentObjectTypeInfo, ext, "CurrentObjectType", top, ": "); top += vert_space;
+	initOverlayElement(&mUseArbQueriesInfo, ext, "UseArbQueries", top, ": NV"); top += vert_space;
+	//initOverlayElement(&mHelpInfo, ext, "Help", top, ": "); top += vert_space;
+
+	OverlayElement *optionsPanel = OverlayManager::getSingleton().
+		getOverlayElement("Example/Visibility/VisibilityPanel");
+
+	optionsPanel->setHeight(top + border_height);
+
+	top = border_height;
+	//ext = "Example/Visibility/";
+	initOverlayElement(&mFrustumCulledNodesInfo, ext, "FrustumCulledNodes", top, ": 0"); top += vert_space;
+	initOverlayElement(&mQueryCulledNodesInfo, ext, "QueryCulledNodes", top, ": 0"); top += vert_space;
+	initOverlayElement(&mTraversedNodesInfo, ext, "TraversedNodes", top, ": 0"); top += vert_space;
+	initOverlayElement(&mHierarchyNodesInfo, ext, "HierarchyNodes", top, ": 0"); top += vert_space;
+	initOverlayElement(&mRenderedNodesInfo, ext, "RenderedNodes", top, ": 0"); top += vert_space;
+	initOverlayElement(&mObjectsCountInfo, ext, "ObjectsCount", top, ": 0"); top += vert_space;
+	initOverlayElement(&mQueriesIssuedInfo, ext, "QueriesIssued", top, ": 0"); top += vert_space;
+
+	OverlayElement *visPanel = OverlayManager::getSingleton().
+		getOverlayElement("Example/Visibility/VisibilityStatsPanel");
+
+	visPanel->setHeight(top + border_height);
+}
+//-----------------------------------------------------------------------
+void IVFrameListener::initQueryOverlay()
+{
+	const int border_height = 10;
+	const int vert_space = 15;
+
+	//-- visibility culling stats overlay
+	int top = border_height + 25;
+
+	String ext = "Example/Visibility/Query/";
+	    
+	initOverlayElement(&mQueryTypeInfo , ext, "QueryType", top,	": 0"); top += vert_space;
+	
+	initOverlayElement(&mQueryVisibleNodesInfo , ext, "VisibleNodes", top,	": 0"); top += vert_space;
+	initOverlayElement(&mQueryVisibleGeometryInfo , ext, "VisibleGeometry", top,	": 0"); top += vert_space;
+	initOverlayElement(&mQueryVisiblePatchInfo , ext, "VisiblePatches", top,	": 0"); top += vert_space;
+	
+	initOverlayElement(&mQueryNodeVisibilityInfo , ext, "NodeVisibility", top,	": 0"); top += vert_space;
+	initOverlayElement(&mQueryGeometryVisibilityInfo , ext, "GeometryVisibility", top,	": 0"); top += vert_space;
+	initOverlayElement(&mQueryPatchVisibilityInfo , ext, "PatchVisibility", top,	": 0"); top += vert_space;
+
+
+	OverlayElement *queryPanel = OverlayManager::getSingleton().
+		getOverlayElement("Example/Visibility/Query/QueryPanel");
+
+	queryPanel->setHeight(top + border_height);
+}
Index: GTP-Internal/trunk/Lib/Vis/work/iv/TestCullingIVApplication.cpp
===================================================================
--- GTP-Internal/trunk/Lib/Vis/work/iv/TestCullingIVApplication.cpp	(revision 370)
+++ GTP-Internal/trunk/Lib/Vis/work/iv/TestCullingIVApplication.cpp	(revision 370)
@@ -0,0 +1,318 @@
+#include <OgreNoMemoryMacros.h>
+#include <CEGUI/CEGUI.h>
+#include <../CEGUIRenderer/include/OgreCEGUIRenderer.h>
+#include <../CEGUIRenderer/include/OgreCEGUIResourceProvider.h>
+#include <../CEGUIRenderer/include/OgreCEGUITexture.h>
+#include <OgreMemoryMacros.h>
+
+#include <Ogre.h>
+
+//#include "OgreReferenceAppLayer.h"
+//#include "OgreRefAppWorld.h"
+#include "TestCullingIVApplication.h"
+#include "IVFrameListener.h"
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+
+/*********************************************************/
+/*        TestCullingIVApplication implementation        */
+/*********************************************************/
+
+//-----------------------------------------------------------------------
+TestCullingIVApplication::TestCullingIVApplication()
+{
+	mIVReader = new IVReader();
+}
+//-----------------------------------------------------------------------
+TestCullingIVApplication::~TestCullingIVApplication()
+{
+	OGRE_DELETE(mIVReader);
+}
+//-----------------------------------------------------------------------
+void TestCullingIVApplication::createCamera()
+{
+	// create the camera
+	mCamera = mSceneMgr->createCamera("PlayerCam");
+	// Look back along -Z
+    mCamera->lookAt(Vector3(0, 0, -300));
+	
+	/** set a nice viewpoint
+	*	we use a camera node here and apply all transformations on it instead
+	*	of applying all transformations directly to the camera
+	*	because then the camera is displayed correctly in the visualization
+	*/
+	mCamNode = mSceneMgr->getRootSceneNode()->
+		createChildSceneNode("CamNode1", Vector3(0, -100, -200));
+
+	mCamNode->attachObject(mCamera);
+	//mCamNode->lookAt(Vector3(0, 0, -300), Node::TS_WORLD); 
+	//mCamNode->setOrientation(Quaternion(-0.3486, 0.0122, 0.9365, 0.0329));
+
+	//-- create visualization camera
+	mVizCamera = mSceneMgr->createCamera("VizCam");
+	mVizCamera->setPosition(mCamNode->getPosition());
+
+	mVizCamera->setNearClipDistance(1);
+	mCamera->setNearClipDistance(1);
+
+	// infinite far plane?
+	if (mRoot->getRenderSystem()->getCapabilities()->hasCapability(RSC_INFINITE_FAR_PLANE))
+	{
+		mVizCamera->setFarClipDistance(0);
+		mCamera->setFarClipDistance(0);
+	}
+	else
+	{
+		 mVizCamera->setFarClipDistance(20000);
+		 mCamera->setFarClipDistance(20000);
+	}	
+}
+
+//-----------------------------------------------------------------------
+bool TestCullingIVApplication::setup()
+{
+	bool carryOn = ExampleApplication::setup();
+
+	if (carryOn)
+		createRenderTargetListener();
+
+	return carryOn;
+}
+//-----------------------------------------------------------------------
+void TestCullingIVApplication::createRenderTargetListener()
+{
+	mWindow->addListener(new VisualizationRenderTargetListener(mSceneMgr));
+}
+//-----------------------------------------------------------------------
+void TestCullingIVApplication::createScene()
+{
+	Real scale = 1;
+	mSceneMgr->setOption("NodeVizScale", &scale);
+	// HACK: change this to relative path
+	//String path = "E:/svn/gametools/trunk/VUT/Ogre/resources/";
+	String path = "D:/svn/trunk/VUT/Ogre/resources/";
+	
+	SceneNode *node1 = mSceneMgr->getRootSceneNode()->createChildSceneNode("Node1");
+	SceneNode *node2 = mSceneMgr->getRootSceneNode()->createChildSceneNode("Node2");
+	SceneNode *node3 = mSceneMgr->getRootSceneNode()->createChildSceneNode("Node3");
+	SceneNode *node4 = mSceneMgr->getRootSceneNode()->createChildSceneNode("Node4");
+	SceneNode *node5 = mSceneMgr->getRootSceneNode()->createChildSceneNode("Node5");
+	SceneNode *node6 = mSceneMgr->getRootSceneNode()->createChildSceneNode("Node6");
+	SceneNode *node7 = mSceneMgr->getRootSceneNode()->createChildSceneNode("Node7");
+	SceneNode *node8 = mSceneMgr->getRootSceneNode()->createChildSceneNode("Node8");
+	SceneNode *node9 = mSceneMgr->getRootSceneNode()->createChildSceneNode("Node9");
+
+
+	node1->translate(Vector3(-500, 0, 750));
+	node2->translate(Vector3(-400, 0, 750));
+	node3->scale(Vector3(100, 100 ,100));
+	node3->pitch(Radian(3 * Math::HALF_PI));
+	node4->translate(Vector3(-100, 0, 0));
+	node5->translate(Vector3(0, 300, 0));
+	
+	node6->scale(Vector3(100, 100 ,100));
+	node6->pitch(Radian(3 * Math::HALF_PI));
+	node6->roll(Radian(Math::HALF_PI));
+	node6->translate(Vector3(0, -100, 0));
+
+	node7->scale(Vector3(100, 100 ,100)); 
+	node7->pitch(Radian(3 * Math::HALF_PI));
+	node7->roll(Radian(Math::HALF_PI));
+	node7->translate(Vector3(100, 0, 0));
+	
+	node8->translate(Vector3(-300, -300, 0));
+
+	Log *log = LogManager::getSingleton().createLog("IVLog.log");
+	mIVReader->setLog(log);
+
+	/*if (mIVReader->loadFile("media\\house_test1.iv"))
+	{
+		mIVReader->buildTree(mSceneMgr, node1);
+		mIVReader->buildTree(mSceneMgr, node2);
+	}
+	if (mIVReader->loadFile("media\\anhk.wrl"))
+	{
+		mIVReader->buildTree(mSceneMgr, node3);
+	}
+	if (mIVReader->loadFile("media\\ant.wrl"))
+	{
+		mIVReader->buildTree(mSceneMgr, node4);
+	}
+	if (mIVReader->loadFile("media\\zepplin0.wrl"))
+	{
+		mIVReader->buildTree(mSceneMgr, node5);
+	}
+	if (mIVReader->loadFile("media\\warbird.wrl"))
+	{
+		mIVReader->buildTree(mSceneMgr, node6);
+	}
+	if (mIVReader->loadFile("media\\z_wing.wrl"))
+	{
+		mIVReader->buildTree(mSceneMgr, node7);
+	}*/
+
+	String fileName = path + "media\\city1500_flat_1.iv";
+	if (mIVReader->loadFile(fileName.c_str()))
+	{
+		mIVReader->buildTree(mSceneMgr, node8);
+	}
+
+	fileName = path + "media\\roofs_1500.iv";
+	if (mIVReader->loadFile(fileName.c_str()))
+	{
+		mIVReader->buildTree(mSceneMgr, node8);
+	}
+
+	fileName = path + "media\\CityRoads60.iv";
+	if (mIVReader->loadFile(fileName.c_str()))
+	{
+		mIVReader->buildTree(mSceneMgr, node8);
+	}
+
+	fileName = path + "media\\CityPlane60.iv";
+    if (mIVReader->loadFile(fileName.c_str()))
+	{
+		mIVReader->buildTree(mSceneMgr, node8);
+	}
+	
+	fileName = path + "media\\test.iv";
+	if (mIVReader->loadFile(fileName.c_str()))
+	{
+		mIVReader->buildTree(mSceneMgr, node9);
+	}
+
+	mIVReader->collapse();
+
+	
+	// Set ambient light
+	mAmbientLight = ColourValue(0.5 , 0.5, 0.5);
+	mSceneMgr->setAmbientLight(mAmbientLight);
+	
+	//-- create light
+	mSunLight = mSceneMgr->createLight("SunLight");
+	mSunLight->setType(Light::LT_DIRECTIONAL);
+	//mSunLight->setType(Light::LT_SPOTLIGHT);
+	//mSunLight->setSpotlightRange(Degree(30), Degree(50));
+
+    mSunLight->setPosition(707, 2000, 500);
+	mSunLight->setCastShadows(true);
+
+	// set light angle not too small over the surface, otherwise shadows textures will be broken
+	Vector3 dir(0.5, 1, 0.5);
+	dir.normalise();
+	mSunLight->setDirection(dir);
+	//mSunLight->setDirection(Vector3::NEGATIVE_UNIT_Y);
+	mSunLight->setDiffuseColour(1, 1, 1);
+	mSunLight->setSpecularColour(1, 1, 1);
+
+	// -- Fog
+	// NB it's VERY important to set this before calling setWorldGeometry 
+	// because the vertex program picked will be different
+	ColourValue fadeColour(0.93, 0.86, 0.76);
+	mWindow->getViewport(0)->setBackgroundColour(fadeColour);
+	//mSceneMgr->setFog( FOG_LINEAR, fadeColour, .001, 500, 1000);
+	
+	// Create a skybox
+	mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox", 5000, true);
+	
+	
+	//-- CEGUI setup
+	setupGui();
+
+	// Use 512x512 texture in GL since we can't go higher than the window res
+	mSceneMgr->setShadowTextureSettings(512, 2);
+
+	mSceneMgr->setShadowColour(ColourValue(0.5, 0.5, 0.5));
+}
+//-----------------------------------------------------------------------
+void TestCullingIVApplication::setupGui()
+{
+	 mGUIRenderer = new CEGUI::OgreCEGUIRenderer(mWindow, Ogre::RENDER_QUEUE_OVERLAY, 
+		 false, 3000, ST_EXTERIOR_CLOSE);
+     mGUISystem = new CEGUI::System(mGUIRenderer);
+
+	 // Mouse
+     CEGUI::SchemeManager::getSingleton().loadScheme((CEGUI::utf8*)"TaharezLook.scheme");
+     CEGUI::MouseCursor::getSingleton().setImage("TaharezLook", "MouseArrow");
+	 mGUISystem->setDefaultMouseCursor((CEGUI::utf8*)"TaharezLook", 
+									   (CEGUI::utf8*)"MouseArrow");
+
+	 CEGUI::MouseCursor::getSingleton().show();
+}
+//-----------------------------------------------------------------------
+void TestCullingIVApplication::createFrameListener()
+{
+	mIVFrameListener = new IVFrameListener(mWindow, mCamera, mSceneMgr, 
+		mGUIRenderer, mVizCamera, mCamNode, mSunLight, this);
+	
+	mRoot->addFrameListener(mIVFrameListener);
+}
+//-----------------------------------------------------------------------
+void TestCullingIVApplication::chooseSceneManager()
+{
+	mSceneMgr = mRoot->getSceneManager(ST_GENERIC);
+}
+
+
+
+/**************************************************************/
+/*      VisualizationRenderTargetListener implementation      */
+/**************************************************************/
+
+//-----------------------------------------------------------------------
+VisualizationRenderTargetListener::VisualizationRenderTargetListener(SceneManager *sceneMgr)
+:RenderTargetListener(), mSceneMgr(sceneMgr)
+{
+}
+//-----------------------------------------------------------------------
+void VisualizationRenderTargetListener::preViewportUpdate(const RenderTargetViewportEvent &evt)
+{
+	// visualization viewport
+	const bool showViz = evt.source->getZOrder() == VIZ_VIEWPORT_Z_ORDER;
+	const bool nShowViz = !showViz;
+
+	mSavedShadowTechnique = mSceneMgr->getShadowTechnique();
+	mSavedAmbientLight = mSceneMgr->getAmbientLight();
+
+	// -- ambient light must be full for visualization, shadows disabled
+    if (showViz)
+	{
+		mSceneMgr->setAmbientLight(ColourValue(1, 1, 1));
+		mSceneMgr->setShadowTechnique(SHADOWTYPE_NONE);
+	}
+	
+    mSceneMgr->setOption("PrepareVisualization", &showViz);
+	mSceneMgr->setOption("SkyBoxEnabled", &nShowViz);
+	//mSceneMgr->setOption("SkyPlaneEnabled", &showViz);
+	
+	RenderTargetListener::preViewportUpdate(evt);
+}
+//-----------------------------------------------------------------------
+void VisualizationRenderTargetListener::postRenderTargetUpdate(const RenderTargetEvent &evt)
+{
+	// reset values
+	mSceneMgr->setShadowTechnique(mSavedShadowTechnique);
+	mSceneMgr->setAmbientLight(mSavedAmbientLight);
+	
+	RenderTargetListener::postRenderTargetUpdate(evt);
+}
+//-----------------------------------------------------------------------
+INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
+{
+    // Create application object
+    TestCullingIVApplication app;
+
+	try 
+	{
+        app.go();
+    } 
+	catch( Ogre::Exception& e ) 
+	{
+        MessageBox( NULL, e.getFullDescription().c_str(), 
+			"An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
+    }	
+
+    return 0;
+}
Index: GTP-Internal/trunk/Lib/Vis/work/iv/Demo_IV.vcproj
===================================================================
--- GTP-Internal/trunk/Lib/Vis/work/iv/Demo_IV.vcproj	(revision 370)
+++ GTP-Internal/trunk/Lib/Vis/work/iv/Demo_IV.vcproj	(revision 370)
@@ -0,0 +1,183 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="Demo_IV"
+	ProjectGUID="{640481BA-D8FE-41ED-B2F2-9844A8CA1E40}"
+	SccProjectName=""
+	SccLocalPath="">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory=".\..\bin\$(ConfigurationName)"
+			IntermediateDirectory=".\..\obj\$(ConfigurationName)"
+			ConfigurationType="1"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\IVReader\include;&quot;$(OGRE_PATH)\Dependencies\include&quot;;&quot;$(OGRE_PATH)\OgreMain\include&quot;;&quot;$(OGRE_PATH)\Samples\Common\include&quot;;&quot;$(OGRE_PATH)\Dependencies\include\CEGUI&quot;;&quot;$(OGRE_PATH)\PlugIns\OctreeSceneManager\include&quot;;&quot;$(OGRE_PATH)\Samples\Common\CEGUIRenderer\include&quot;;..\..\Ogre\include;..\..\GtpVisibility\include;..\include"
+				PreprocessorDefinitions="NDEBUG;_WINDOWS;WIN32;GTP_VISIBILITY_MODIFIED_OGRE"
+				RuntimeLibrary="2"
+				UsePrecompiledHeader="0"
+				PrecompiledHeaderFile=""
+				AssemblerListingLocation=".\..\obj\Release/"
+				ObjectFile=".\..\obj\Release/"
+				ProgramDataBaseFileName=".\..\obj\Release/"
+				BrowseInformation="1"
+				BrowseInformationFile=".\..\obj\Release/"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				DebugInformationFormat="3"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				IgnoreImportLibrary="TRUE"
+				AdditionalDependencies="OGREMain.LIB CEGUIBase.lib OgreGUIRenderer.lib Plugin_OctreeSceneManager.lib Plugin_VisibilitySceneManager.lib IVReader.lib"
+				OutputFile="$(OGRE_PATH)/Samples/Common/bin/Release/Demo_IV.exe"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				AdditionalLibraryDirectories="&quot;$(OGRE_PATH)\OgreMain\Lib\$(ConfigurationName)&quot;;&quot;$(OGRE_PATH)\Samples\Common\CEGUIRenderer\lib&quot;;&quot;..\IVReader\Lib\$(ConfigurationName)&quot;;&quot;$(OGRE_PATH)\Dependencies\Lib\$(ConfigurationName)&quot;;&quot;$(OGRE_PATH)\PlugIns\OctreeSceneManager\bin\$(ConfigurationName)&quot;;&quot;..\..\Ogre\lib\$(ConfigurationName)&quot;"
+				ProgramDatabaseFile=".\..\bin\Release/Demo_IV.pdb"
+				SubSystem="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"
+				PreprocessorDefinitions="NDEBUG"
+				MkTypLibCompatible="TRUE"
+				SuppressStartupBanner="TRUE"
+				TargetEnvironment="1"
+				TypeLibraryName=".\..\bin\Release/Demo_IV.tlb"
+				HeaderFileName=""/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="2057"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory=".\..\bin\Debug"
+			IntermediateDirectory=".\..\obj\Debug"
+			ConfigurationType="1"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions="/Zm500 "
+				Optimization="0"
+				AdditionalIncludeDirectories="..\include;&quot;$(OGRE_PATH)\Samples\Common\include&quot;;&quot;$(OGRE_PATH)\OgreMain\include&quot;"
+				PreprocessorDefinitions="_WINDOWS;_DEBUG;WIN32;GTP_VISIBILITY_MODIFIED_OGRE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				PrecompiledHeaderFile=".\..\obj\Debug/Demo_IV.pch"
+				AssemblerListingLocation=".\..\obj\Debug/"
+				ObjectFile=".\..\obj\Debug/"
+				ProgramDataBaseFileName=".\..\obj\Debug/"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				DebugInformationFormat="4"
+				CompileAs="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				IgnoreImportLibrary="TRUE"
+				AdditionalDependencies="odbc32.lib odbccp32.lib OgreMain_d.lib"
+				OutputFile="$(OGRE_PATH)/Samples/Common/bin/Debug/Demo_IV.exe"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				AdditionalLibraryDirectories="&quot;$(OGRE_PATH)\OgreMain\Lib\$(ConfigurationName)&quot;"
+				IgnoreDefaultLibraryNames="LIBCMT"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\..\bin\Debug/Demo_IV.pdb"
+				SubSystem="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"
+				PreprocessorDefinitions="_DEBUG"
+				MkTypLibCompatible="TRUE"
+				SuppressStartupBanner="TRUE"
+				TargetEnvironment="1"
+				TypeLibraryName=".\..\bin\Debug/Demo_IV.tlb"
+				HeaderFileName=""/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="_DEBUG"
+				Culture="2057"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
+			<File
+				RelativePath=".\IVFrameListener.cpp">
+			</File>
+			<File
+				RelativePath=".\TestCullingIVApplication.cpp">
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl">
+			<File
+				RelativePath=".\IVFrameListener.h">
+			</File>
+			<File
+				RelativePath=".\TestCullingIVApplication.h">
+			</File>
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
+		</Filter>
+		<File
+			RelativePath=".\VTune\Demo_IV.vpj">
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
Index: GTP-Internal/trunk/Lib/Vis/work/iv/IVFrameListener.h
===================================================================
--- GTP-Internal/trunk/Lib/Vis/work/iv/IVFrameListener.h	(revision 343)
+++ GTP-Internal/trunk/Lib/Vis/work/iv/IVFrameListener.h	(revision 343)
@@ -0,0 +1,256 @@
+#ifndef _IVFrameListener_H__
+#define _IVFrameListener_H__
+
+#include "CEGUIForwardRefs.h"
+#include <Ogre.h>
+#include <OgreKeyEvent.h>
+#include <OgreEventListeners.h>
+#include <OgreStringConverter.h>
+#include <OgreException.h>
+#include "VisibilityEnvironment.h"
+#include "VisibilityManager.h"
+
+
+
+class TestCullingIVApplication;
+
+
+using namespace Ogre;
+
+
+/** Frame listener specialised for terrains.
+*/
+class IVFrameListener: public FrameListener, public MouseListener, 
+							public MouseMotionListener, public KeyListener
+{
+public:
+
+	IVFrameListener(RenderWindow* win, 
+						Camera* cam, 
+						SceneManager *sceneManager, 
+						CEGUI::Renderer *renderer, 
+						Camera *vizCamera,
+						SceneNode *camNode, 
+						Light *sunLight,
+						TestCullingIVApplication *app);
+
+	~IVFrameListener();
+
+
+	bool frameStarted(const FrameEvent& evt);
+	bool frameEnded(const FrameEvent& evt);
+   //bool processUnbufferedKeyInput(const FrameEvent& evt);
+    
+
+	/* MouseListener callbacks. */
+	virtual void mouseClicked(MouseEvent* e) { }
+	virtual void mouseEntered(MouseEvent* e) { }
+	virtual void mouseExited(MouseEvent* e)  { }
+
+	// This is when the mouse button goes DOWN.
+	void mousePressed(MouseEvent* e);
+
+	// This is when the mouse button is let UP.
+	void mouseReleased(MouseEvent* e);
+
+	/* MouseMotionListener callbacks */
+	void mouseMoved(MouseEvent *e);
+
+	// This is when the mouse is clicked, held and dragged.
+	void mouseDragged(MouseEvent *e);
+
+	void mouseDragDropped(MouseEvent *e);
+	void keyPressed(KeyEvent* e);
+
+	void keyReleased(KeyEvent* e);
+	void keyClicked(KeyEvent* e);
+
+	/** The information about camera position and orienation per frame.
+	*/
+	typedef struct
+	{
+		Vector3 position;
+		Quaternion orientation;
+		Real timeElapsed;
+	} frame_info;
+
+	enum  {WALKTHROUGH, REPLAY, STATE_NUM};
+
+	// visualization modes for scene nodes
+	enum {NODEVIZ_NONE, NODEVIZ_RENDER_NODES, NODEVIZ_RENDER_NODES_AND_CONTENT, NODEVIZ_MODES_NUM};
+	//enum {NODEVIZ_NONE, NODEVIZ_RENDER_GEOMETRY, NODEVIZ_MODES_NUM};
+
+	void zoomVizCamera(int zoom);
+
+	void addFrameInfo(SceneNode *camNode, Real timeElapsed);
+	void setCurrentFrameInfo(Real timeElapsed);
+
+	void setAlgorithm(int algorithm);
+
+	void moveCamera();
+
+	void writeFrames();
+	void loadFrames();
+
+	bool processUnbufferedKeyInput(const FrameEvent& evt);
+	bool processUnbufferedMouseInput(const FrameEvent& evt);
+
+	void showStats(bool show);
+
+	void updateStats();
+	void toggleShowHelp();
+	void toggleShowStats();
+
+	void toggleShowShadows();
+	void toggleDisplayCameraDetails();
+	void takeScreenshot();
+	void nextSceneDetailLevel();
+	void nextFilter();
+	void nextAlgorithm();
+	void nextNodeVizMode();
+	void nextAppState();
+	void changeThreshold(int incr);
+	void changeAssumedVisibility(int incr);
+	void toggleTestGeometryForVisibleLeaves();
+	void toggleShowOctree();
+	void toggleUseDepthPass();
+	void toggleUseArbQueries();
+	void toggleShowViz();
+	void toggleRecord();
+
+	bool Clamp2Floor();
+
+	static String msAlgorithmCaptions[];
+		
+	protected:
+
+	void initHelpOverlayElement(String name, int top);
+	void initOverlayElement(OverlayElement **elInfo, String ext, String name, 
+							int top, String caption);
+
+	//-- initialise overlays
+	void initHelpOverlay();
+	void initVisStatsOverlay();
+	void initQueryOverlay();
+
+	void resetStats();
+
+	SceneManager *mSceneMgr;           // A pointer to the scene manager
+
+	CEGUI::Renderer *mGUIRenderer;     // cegui renderer
+
+	int mCurrentAlgorithm;
+	int mVisibilityThreshold;
+	int mAssumedVisibility;
+	// the current frame number
+	int mCurrentFrame;
+	// the current application state
+	int mAppState;
+	// visualization mode
+	int mNodeVizMode;
+
+
+	OverlayElement *mAlgorithmInfo;
+	OverlayElement *mThresholdInfo;
+	OverlayElement *mAssumedVisibilityInfo;
+	OverlayElement *mFrustumCulledNodesInfo;
+	OverlayElement *mQueryCulledNodesInfo;
+	OverlayElement *mTraversedNodesInfo;
+	OverlayElement *mHierarchyNodesInfo;
+	OverlayElement *mTestGeometryForVisibleLeavesInfo;
+	OverlayElement *mUseDepthPassInfo;
+	OverlayElement *mUseArbQueriesInfo;
+	OverlayElement *mRenderedNodesInfo;
+	OverlayElement *mObjectsCountInfo;
+	OverlayElement *mQueriesIssuedInfo;
+	OverlayElement *mDelayedQueriesIssuedInfo;
+	OverlayElement *mDelayedTraversedNodesInfo;
+	OverlayElement *mCurrentObjectTypeInfo;
+
+	OverlayElement *mQueryTypeInfo;
+	OverlayElement *mQueryVisibleNodesInfo;
+	OverlayElement *mQueryVisibleGeometryInfo;
+	OverlayElement *mQueryVisiblePatchInfo;
+
+	OverlayElement *mQueryVisiblityInfo;
+	OverlayElement *mQueryNodeVisibilityInfo;
+	OverlayElement *mQueryGeometryVisibilityInfo;
+	OverlayElement *mQueryPatchVisibilityInfo;
+	//OverlayElement *mHelpInfo;
+	
+	bool mTestGeometryForVisibleLeaves;
+	bool mShowOctree;
+	bool mUseDepthPass;
+	bool mUseArbQueries;
+	bool mShowVisualization;
+	bool mCullCamera;
+	bool mRecordFrames;
+	bool mShowShadows;
+	bool mVisualizeCulledNodes;
+	bool mShowHelp;
+	bool mStatsOn;
+	bool mLMouseDown, mRMouseDown;     // True if the mouse buttons are down
+	bool mShutdownRequested;
+	bool mDisplayCameraDetails;
+	bool mUseItemBuffer;
+	bool mUseAnimation;
+
+	int mItemBufferMode;
+
+	Real mVizCameraHeight;
+
+	Camera *mVizCamera;
+	SceneNode *mCamNode;
+
+	std::vector<frame_info> mFrameInfo;
+		
+	Real mReplayTimeElapsed;
+	//EventProcessor* mEventProcessor;
+	InputReader* mInputDevice;
+	Camera* mCamera;
+
+	Vector3 mTranslateVector;
+	RenderWindow* mWindow;
+
+	unsigned int mNumScreenShots;
+	int mSceneDetailIndex;
+	int mAniso;
+
+	float mMoveScale;
+	Real mMoveSpeed;
+	Degree mRotScale;
+
+	// just to stop toggles flipping too fast
+	Real mTimeDelay;
+	Radian mRotX, mRotY;
+	TextureFilterOptions mFiltering;
+
+	Degree mRotateSpeed;
+
+	Overlay* mDebugOverlay;
+	Overlay* mHelpOverlay;
+	Overlay* mCullStatsOverlay;
+	Overlay* mQueryOverlay;
+
+	Light *mSunLight;
+	GtpVisibility::VisibilityManager *mVisibilityManager;
+	EventProcessor* mEventProcessor;
+
+	bool mShiftPressed;
+	bool mShowQueryStats;
+
+	unsigned long mAccumulatedFps;
+	unsigned long mAccumulatedTris;
+	unsigned long mFrameCount;
+
+	//bool mUseBufferedInputKeys, mUseBufferedInputMouse, mInputTypeSwitchingOn;
+	
+	float mDelayedQueriesIssued;
+	float mDelayedTraversedNodes;
+
+	TestCullingIVApplication *mApplication;
+	RaySceneQuery *mRaySceneQuery;
+};
+
+
+#endif //_IVFrameListener_H__
Index: GTP-Internal/trunk/Lib/Vis/work/iv/TestCullingIVApplication.h
===================================================================
--- GTP-Internal/trunk/Lib/Vis/work/iv/TestCullingIVApplication.h	(revision 187)
+++ GTP-Internal/trunk/Lib/Vis/work/iv/TestCullingIVApplication.h	(revision 187)
@@ -0,0 +1,78 @@
+#ifndef _TestCullingIVApplication_H__
+#define _TestCullingIVApplication_H__
+
+#include "CEGUIForwardRefs.h"
+#include <OgreRenderTargetListener.h>
+#include "ExampleApplication.h"
+
+#include "ivreader.h"
+#include "IVFrameListener.h"
+
+
+// z order index of visualizaion viewport
+#define VIZ_VIEWPORT_Z_ORDER 10
+
+
+/** Rendertarget listener which shows a visualization.
+*/
+class VisualizationRenderTargetListener: public RenderTargetListener
+{
+public:
+	VisualizationRenderTargetListener(SceneManager *sceneMgr);
+
+protected:
+	void preViewportUpdate (const RenderTargetViewportEvent &evt);
+	void postRenderTargetUpdate (const RenderTargetEvent &evt);
+
+	SceneManager *mSceneMgr;
+	
+	ShadowTechnique mSavedShadowTechnique;
+	ColourValue mSavedAmbientLight;
+};
+
+
+class TestCullingIVApplication: public ExampleApplication
+{
+public:
+	TestCullingIVApplication();
+	~TestCullingIVApplication();
+
+	/** Generates a scene using num entities of a type. 
+		@param num the number of objects
+		@parma objectType the type of objects
+	*/
+	void generateScene(int num, int objectType);
+
+
+protected:
+
+	//-- inherited from ExampleApplication
+	bool setup();
+	void createScene();
+	void createFrameListener();
+	void createCamera();
+	//void createViewports();
+	
+	virtual void createRenderTargetListener();
+
+	/** cegui setup 
+	*/
+	void setupGui();
+
+	CEGUI::OgreCEGUIRenderer *mGUIRenderer;
+	CEGUI::System *mGUISystem;
+
+	Camera *mVizCamera;
+	SceneNode *mCamNode;
+	Light *mSunLight;
+
+	ColourValue mAmbientLight;
+
+	IVReader *mIVReader;
+	IVFrameListener *mIVFrameListener;
+
+private:
+	void chooseSceneManager(void);
+};
+
+#endif // TestCullingIVApplication
Index: GTP-Internal/trunk/Lib/Vis/work/iv/Demo_IV.dsp
===================================================================
--- GTP-Internal/trunk/Lib/Vis/work/iv/Demo_IV.dsp	(revision 187)
+++ GTP-Internal/trunk/Lib/Vis/work/iv/Demo_IV.dsp	(revision 187)
@@ -0,0 +1,141 @@
+# Microsoft Developer Studio Project File - Name="Demo_IV" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** NICHT BEARBEITEN **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=Demo_IV - Win32 Debug
+!MESSAGE Dies ist kein gültiges Makefile. Zum Erstellen dieses Projekts mit NMAKE
+!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und führen Sie den Befehl
+!MESSAGE 
+!MESSAGE NMAKE /f "Demo_IV.mak".
+!MESSAGE 
+!MESSAGE Sie können beim Ausführen von NMAKE eine Konfiguration angeben
+!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel:
+!MESSAGE 
+!MESSAGE NMAKE /f "Demo_IV.mak" CFG="Demo_IV - Win32 Debug"
+!MESSAGE 
+!MESSAGE Für die Konfiguration stehen zur Auswahl:
+!MESSAGE 
+!MESSAGE "Demo_IV - Win32 Release" (basierend auf  "Win32 (x86) Application")
+!MESSAGE "Demo_IV - Win32 Debug" (basierend auf  "Win32 (x86) Application")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "Demo_IV - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "..\bin\Release"
+# PROP BASE Intermediate_Dir "..\obj\Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "..\bin\Release"
+# PROP Intermediate_Dir "..\obj\Release"
+# PROP Ignore_Export_Lib 1
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /Zi /Od /I "..\include" /I "..\..\Common\include" /I "..\..\..\OgreMain\include" /D "NDEBUG" /D "_MBCS" /D "_WINDOWS" /D "WIN32" /Fr /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x809 /d "NDEBUG"
+# ADD RSC /l 0x809 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib OgreMain.lib /nologo /subsystem:windows /machine:I386 /out:"../../Common/Bin/Release/Demo_IV.exe" /libpath:"..\..\..\OgreMain\lib\release"
+# SUBTRACT LINK32 /profile /debug
+
+!ELSEIF  "$(CFG)" == "Demo_IV - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "..\bin\Debug"
+# PROP BASE Intermediate_Dir "..\obj\Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "..\bin\Debug"
+# PROP Intermediate_Dir "..\obj\Debug"
+# PROP Ignore_Export_Lib 1
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\include" /I "..\..\Common\include" /I "..\..\..\OgreMain\include" /D "_MBCS" /D "_WINDOWS" /D "_DEBUG" /D "WIN32" /FD /GZ /Zm500 /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x809 /d "_DEBUG"
+# ADD RSC /l 0x809 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib OgreMain_d.lib /nologo /subsystem:windows /debug /machine:I386 /nodefaultlib:"LIBCMT" /out:"../../Common/Bin/Debug/Demo_IV.exe" /pdbtype:sept /libpath:"..\..\..\OgreMain\lib\debug"
+# SUBTRACT LINK32 /verbose
+
+!ENDIF 
+
+# Begin Target
+
+# Name "Demo_IV - Win32 Release"
+# Name "Demo_IV - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=..\src\IV.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\ivmanualmeshloader.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\ivmeshdata.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\ivnode.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\ivreader.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=..\src\ivmanualmeshloader.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\ivmeshdata.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\ivnode.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\src\ivreader.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
