Index: GTP/trunk/App/Demos/Geom/Demo_LodManager/main.cpp
===================================================================
--- GTP/trunk/App/Demos/Geom/Demo_LodManager/main.cpp	(revision 1802)
+++ GTP/trunk/App/Demos/Geom/Demo_LodManager/main.cpp	(revision 1802)
@@ -0,0 +1,548 @@
+/*	==========================================================================
+ *	(C) 2006 Universitat Jaume I
+ *	==========================================================================
+ *	PROYECT:	GAME TOOLS
+ *	==========================================================================*/
+/**	CONTENT:	
+	*
+	*
+	*	@file	main.cpp
+/** COMMENTS:
+	* Model must be in "media/models" folder.
+	* Lod file must be in "media/GT" folder.
+/*===========================================================================*/
+#include "ExampleApplication.h"
+#include "GeoLodManager.h"
+#include "GeoMeshLoader.h"
+#include "audiere.h"
+
+
+// Distance values
+#define dist_min 2000
+#define dist_max 4000
+
+// Model name
+//#define model_name "dwarf2"
+
+
+//Global variables
+Geometry::LodManager* lodManager = NULL;
+Geometry::Mesh  *the_lodstrips_mesh = NULL, 
+				*the_lodtree_mesh = NULL;
+Geometry::GeoMeshLoader *lodstrips_meshloader = NULL,
+						*lodtree_meshloader = NULL;
+Ogre::SceneManager *sceneManager = NULL;
+Ogre::Entity *orig_lodstrips_entity = NULL,
+			 *orig_lodtree_entity = NULL;
+
+		audiere::AudioDevicePtr device(audiere::OpenDevice());
+		audiere::OutputStreamPtr song(OpenSound(device,"../../musica.mp3",false));
+
+
+MaterialPtr *mat;
+
+ColourValue color=ColourValue::Red;
+
+Camera* theCam;
+Entity* pPlaneEnt;
+
+char HelpString[]="(F1) Quit this Help\n"
+			"This demo shows an example of the LODManager in action. Every model in the scene\n"
+			"has its own LodStrips object associated that manages its level of detail.\n"
+			"Since the scene is highly populated, changing the LOD of every object independently\n"
+			"would make the performance to fall.\n"
+			"The LodManager makes efficient LOD computations by reusing previously calculated LODs.\n"
+			"The level of detail of the objects depends on the distance to the camera. When the\n"
+			"camera goes away from them, the level of detail decreases, and when the camera gets\n"
+			"closer to them increases to restore the original geometry of the model.\n"
+			"(F4) LODManager ON\n"
+			"(F3) LODManager OFF\n\n"
+			"IMPORTANT: to notice performance improvements the user must move the camera, since the\n"
+			"LOD in only re-calculated when the camera position changes.";
+
+char NoHelpString[]="\n\n\n\n\n\n\n\n\n\n\n\n\n(F1) Help\n";
+
+OverlayElement* mLOD;
+OverlayElement* mInfo;
+OverlayElement* mInfo2;
+OverlayElement* mHelp;
+
+//Ogre::OverlayElement *mInfo, *mInfo2;
+
+// framerate test
+std::vector<float> framerates;
+const unsigned int msDelay = 1000;
+
+class CustomIndexData : public Geometry::IndexData
+{
+private:
+	Ogre::Mesh *targetMesh;
+	Ogre::HardwareIndexBufferSharedPtr ibuf;
+	unsigned long* pIdx;
+	Ogre::HardwareIndexBufferSharedPtr *orig_indexbuff;
+
+public:
+	CustomIndexData(Ogre::Mesh *ogremesh):Geometry::IndexData(){
+		targetMesh=ogremesh;
+		pIdx=NULL;
+		orig_indexbuff=new Ogre::HardwareIndexBufferSharedPtr[targetMesh->getNumSubMeshes()];
+		for (int i=0; i<targetMesh->getNumSubMeshes(); i++)
+		{
+			Ogre::RenderOperation mRenderOp;
+			targetMesh->getSubMesh(i)->_getRenderOperation(mRenderOp,0);
+			orig_indexbuff[i] = mRenderOp.indexData->indexBuffer;
+		}
+	}
+	virtual ~CustomIndexData(void){
+		delete[] orig_indexbuff;
+	}
+
+	virtual void Begin(unsigned int submeshid, unsigned int indexcount){
+		Ogre::RenderOperation mRenderOp;	
+		targetMesh->getSubMesh(submeshid)->_getRenderOperation(mRenderOp,0);
+
+		// restore the original index data to modify it
+		mRenderOp.indexData->indexBuffer = orig_indexbuff[submeshid];
+
+		ibuf = mRenderOp.indexData->indexBuffer;
+		mRenderOp.indexData->indexCount = indexcount;
+		pIdx = static_cast<unsigned long*>(ibuf->lock(Ogre::HardwareBuffer::HBL_NORMAL));
+	}
+
+	virtual void SetIndex(unsigned int i, unsigned int index){
+		pIdx[i] = index;
+	}
+	virtual void End(){
+		ibuf->unlock();
+	}
+	virtual void BorrowIndexData(const Geometry::IndexData *idata){
+		CustomIndexData *custom_data = (CustomIndexData*)idata;
+		for (int i=0; i<targetMesh->getNumSubMeshes(); i++)
+		{
+			Ogre::RenderOperation mRenderOp, mRenderOpParam;
+
+			targetMesh->getSubMesh(i)->_getRenderOperation(mRenderOp,0);			
+			custom_data->targetMesh->getSubMesh(i)->_getRenderOperation(mRenderOpParam,0);
+
+			mRenderOp.indexData->indexBuffer = mRenderOpParam.indexData->indexBuffer;
+			mRenderOp.indexData->indexCount  = mRenderOpParam.indexData->indexCount;
+		}
+	}
+};
+
+void AddNewLodStripsObj(void)
+{
+	const int troop_width = 30;
+	static int iname = 0;
+	int i = iname%troop_width;
+	int j = iname/troop_width;	
+
+	char newObjName[16]="";
+	sprintf(newObjName,"model_%d",iname);
+	char newMeshName[16]="";
+	sprintf(newMeshName,"mesh_%d",iname);
+	iname++;
+
+	Ogre::Mesh *ogreMesh = orig_lodstrips_entity->getMesh()->clone(newMeshName).getPointer();
+	Entity *entity = sceneManager->createEntity(newObjName,newMeshName);
+	entity->setNormaliseNormals(true);
+
+	Ogre::SceneNode * auxnode = sceneManager->getRootSceneNode()->createChildSceneNode();
+	auxnode->attachObject(entity);
+	auxnode->rotate(Ogre::Vector3(0,1,0),Ogre::Degree(180.0f),Ogre::Node::TS_WORLD);
+	auxnode->scale(30.0f,30.0f,30.0f);
+	float randomsepx = (float)((rand()%18)-9);
+	float randomsepy = (float)((rand()%12)-6);
+	auxnode->translate(i*120.0f+randomsepx,0.0f,-j*120.0f-randomsepx);
+//	auxnode->translate(0,0,-500.0f);
+
+	Geometry::LodStripsLibrary *myStrips = new Geometry::LodStripsLibrary(
+							lodstrips_meshloader->GetLodStripsData(),
+							the_lodstrips_mesh,
+							new CustomIndexData(ogreMesh));
+
+	entity->setMaterialName("LODStripsDemo/Ogro");
+
+	// add the object to the manager
+	Ogre::Vector3 opos = auxnode->getPosition();
+	lodManager->AddLodObj("ogre",myStrips,Geometry::Vector3(opos.x,opos.y,opos.z));				
+}
+
+
+void AddNewLodTreeObj(void)
+{
+	const int troop_width = 10;
+	static int iname = 0;
+	int i = iname%troop_width;
+	int j = iname/troop_width;	
+
+	char newObjName[16]="";
+	sprintf(newObjName,"tree_%d",iname);
+	char newMeshName[16]="";
+	sprintf(newMeshName,"tree_%d",iname);
+	iname++;
+
+	Ogre::Mesh *ogreMesh = orig_lodtree_entity->getMesh()->clone(newMeshName).getPointer();
+	Entity *entity = sceneManager->createEntity(newObjName,newMeshName);
+	entity->setNormaliseNormals(true);
+
+	Ogre::SceneNode * auxnode = sceneManager->getRootSceneNode()->createChildSceneNode();
+	auxnode->attachObject(entity);
+	auxnode->scale(11.0f,11.0f,11.0f);
+	auxnode->rotate(Ogre::Vector3(0,0,1),Ogre::Degree(rand()%360));
+	auxnode->rotate(Ogre::Vector3(1,0,0),Ogre::Radian(-3.14159f*0.5f),Ogre::Node::TS_WORLD);
+	float randomsepx = (float)((rand()%18)-9);
+	float randomsepy = (float)((rand()%12)-6);
+	auxnode->translate(i*60.0f+randomsepx,-1.0f,-j*60.0f-randomsepx);
+	auxnode->translate(300,0,-500.0f);
+
+	Geometry::LodTreeLibrary *myTree = new Geometry::LodTreeLibrary(
+							lodtree_meshloader->GetLodStripsData(),
+							lodtree_meshloader->GetTreeSimpSeq(),
+							the_lodtree_mesh,
+							new CustomIndexData(ogreMesh));
+
+	// load the right material for each part of the tree
+	for (int submesh=0; submesh < ogreMesh->getNumSubMeshes(); submesh++)
+	{
+		bool istrunk = myTree->GetLeavesSubMesh()!=submesh;
+		if (istrunk)
+			entity->getSubEntity(submesh)->setMaterialName("Examples/Populifolia/trunk");
+		else
+			entity->getSubEntity(submesh)->setMaterialName("Examples/Populifolia/leaf");
+	}
+
+
+	// add the object to the manager
+	Ogre::Vector3 opos = auxnode->getPosition();
+	lodManager->AddLodObj("tree",myTree,Geometry::Vector3(opos.x,opos.y,opos.z));				
+}
+
+
+
+class LodManagerFrameListener : public ExampleFrameListener
+{
+	int manage;
+
+public:
+
+    LodManagerFrameListener(RenderWindow* win, Camera* cam)
+        : ExampleFrameListener(win, cam, false, false)
+    {
+		manage=1;
+	}
+
+	bool frameStarted(const FrameEvent& evt)
+    {
+		Vector3 dist; 
+		int distance=0,inc2=0;
+
+		// test
+		static float timeLeft = 0;
+		
+		const RenderTarget::FrameStats& stats = mWindow->getStatistics();
+
+		static bool rec_stats = false;
+
+		if (mInputDevice->isKeyDown(Ogre::KC_J))
+			rec_stats=true;
+
+		if (rec_stats)
+		{
+			if (timeLeft <= 0.0f)
+			{
+				framerates.push_back(stats.lastFPS);
+				timeLeft = msDelay;
+			}
+			timeLeft -= evt.timeSinceLastFrame * 1000.0f;	
+		}
+
+		// Move upto 80 units/second
+		Real MoveFactor = 180.0 * evt.timeSinceLastFrame;
+
+		// Copy the current state of the input devices
+		mInputDevice->capture();
+
+		// 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;
+		
+		lodManager->UpdateLOD(stats.lastFPS,90);
+
+		bool cam_moved=false;
+
+		if (mInputDevice->isKeyDown(Ogre::KC_F3))
+		{
+			lodManager->always_calculate_lod = true;
+			cam_moved = true;
+		}
+		if (mInputDevice->isKeyDown(Ogre::KC_F4))
+		{
+			lodManager->always_calculate_lod = false;
+			cam_moved = true;
+		}
+
+		//if (mInputDevice->isKeyDown(Ogre::KC_F7))
+		//{
+		//	lodManager->force_highest_lod = true;
+		//	cam_moved = true;
+		//}
+
+		//if (mInputDevice->isKeyDown(Ogre::KC_F8))
+		//{
+		//	lodManager->force_highest_lod = false;
+		//	cam_moved = true;
+		//}
+
+		// Move the cam
+		if(mInputDevice->isKeyDown(Ogre::KC_UP))
+		{
+		  mTranslateVector.z = -mMoveScale;
+		  cam_moved=true;
+		}
+
+		if(mInputDevice->isKeyDown(Ogre::KC_DOWN))
+		{
+		  mTranslateVector.z = mMoveScale;
+		  cam_moved=true;
+		}
+
+		// Instead of moving the ship left and right, rotate it using yaw()
+		if(mInputDevice->isKeyDown(Ogre::KC_LEFT))
+		{
+		  mCamera->yaw(mRotScale);
+		  cam_moved=true;
+		}
+
+		if(mInputDevice->isKeyDown(Ogre::KC_RIGHT))
+		{
+		  mCamera->yaw(-mRotScale);
+		  cam_moved=true;
+		}
+
+		if(mInputDevice->isKeyDown(Ogre::KC_ESCAPE))
+		{
+			delete lodManager;
+			delete [] mat;
+			FILE *f=fopen("fps.txt","wt");
+			unsigned int ms = 0;
+			for (std::vector<float>::iterator it = framerates.begin(); it != framerates.end(); it++, ms++)
+				fprintf(f,"%u %f\n",ms,*it);
+			fclose(f);
+		    return false;
+		}
+
+		static bool newpush = true;
+		if (!mInputDevice->isKeyDown(Ogre::KC_F1))
+			newpush = true;
+
+		static bool showing_help = false;
+		if (mInputDevice->isKeyDown(Ogre::KC_F1) && newpush)
+		{
+			newpush = false;
+			if (showing_help = !showing_help)
+                mHelp->setCaption(HelpString);
+			else
+                mHelp->setCaption(NoHelpString);
+		}
+
+        if( mInputDevice->getMouseButton( 1 ) )
+        {
+            mTranslateVector.x += mInputDevice->getMouseRelativeX() * 0.13;
+            mTranslateVector.y -= mInputDevice->getMouseRelativeY() * 0.13;
+			cam_moved=true;
+        }
+        else
+        {
+            mRotX = Degree(-mInputDevice->getMouseRelativeX() * 0.13);
+            mRotY = Degree(-mInputDevice->getMouseRelativeY() * 0.13);
+        }
+
+		char cadena[256];
+       
+		if ( lodManager->always_calculate_lod )		
+			sprintf(cadena,"\n\nLOD Manager:  OFF\nTriangle Count: %d\n",stats.triangleCount);
+		else
+			sprintf(cadena,"\n\nLOD Manager:  ON\nTriangle Count: %d\n",stats.triangleCount);
+
+		mInfo->setCaption(cadena);
+		mWindow->getStatistics();
+
+		sprintf(cadena,"Current FPS: %f\n",stats.lastFPS);
+		mInfo2->setCaption(cadena);
+
+
+		mCamera->yaw(mRotX);
+        mCamera->pitch(mRotY);
+        mCamera->moveRelative(mTranslateVector);
+
+		if (cam_moved)
+			lodManager->UpdateCamera(Geometry::Vector3(mCamera->getPosition().x,mCamera->getPosition().y,mCamera->getPosition().z));
+
+		return true;
+    }
+};
+
+class LodManagerApplication : public ExampleApplication
+{
+public:
+    LodManagerApplication() {}
+
+    ~LodManagerApplication() {}
+protected:
+    
+    // Just override the mandatory create scene method
+    void createScene(void)
+    {
+		mat = new MaterialPtr[1];
+
+		theCam = mCamera;
+        theCam->setPosition(1900,200,800);
+        // Set ambient light
+		sceneManager = mSceneMgr;
+        mSceneMgr->setAmbientLight(ColourValue(0.2, 0.2, 0.2));
+
+		//SHADOWS
+		//mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_MODULATIVE);
+		//mSceneMgr->setShadowTextureSettings(2048,1);
+		//mSceneMgr->setShadowFarDistance(2048);
+		//mSceneMgr->setShadowColour(ColourValue(0.5, 0.5, 0.5));
+
+        // Create a point light
+        Light* l = mSceneMgr->createLight("MainLight");
+        l->setType(Light::LT_DIRECTIONAL);
+        l->setDirection(-0.5,-1.0,-1.0);
+
+        
+        mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox");
+
+        // My node to which all objects will be attached
+        SceneNode* myRootNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
+
+        // Define a floor plane mesh
+		Plane plane( Vector3::UNIT_Y, 0 );
+
+		MeshManager::getSingleton().createPlane("ground",
+			ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane,
+			40000,40000,6,6,true,1,200,200,Vector3::UNIT_Z);
+
+		Entity* groundEntity = mSceneMgr->createEntity( "GroundEntity", "ground" );
+		mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(groundEntity);
+		
+		groundEntity->setMaterialName("SnowTerrain");
+		groundEntity->setCastShadows(false);       
+
+
+		lodManager = new Geometry::LodManager(dist_min,dist_max,Geometry::Vector3(theCam->getPosition().x,theCam->getPosition().y,theCam->getPosition().z),100);
+		lodManager->UpdateCamera(Geometry::Vector3(	theCam->getPosition().x,
+													theCam->getPosition().y,
+													theCam->getPosition().z ));
+
+		// load the LodStrips info from the object /////////////////////////////////////////////////////////////////
+		lodstrips_meshloader=new Geometry::GeoMeshLoader;
+		the_lodstrips_mesh = lodstrips_meshloader->load("../../../OgreStuff/media/GT/ogrolod.mesh");
+
+		if (!lodstrips_meshloader->GetLodStripsData())
+            OGRE_EXCEPT(1, "The loaded mesh does not contain any LOD info","LOD Demo");
+
+		orig_lodstrips_entity = mSceneMgr->createEntity("orig_lods", "../../../OgreStuff/media/GT/ogrolod.mesh");
+
+
+		// load the LodTree info from the object //////////////////////////////////////////////////////////////////
+/*		lodtree_meshloader=new Geometry::GeoMeshLoader;
+		the_lodtree_mesh = lodtree_meshloader->load("../../../OgreStuff/media/GT/ML11.mesh");
+
+		if (!lodtree_meshloader->GetLodStripsData())
+            OGRE_EXCEPT(1, "The loaded mesh does not contain LODStrips info","LOD Demo");
+		if (!lodtree_meshloader->GetTreeSimpSeq())
+            OGRE_EXCEPT(1, "The loaded mesh does not contain LODTree info","LOD Demo");
+
+		orig_lodtree_entity = mSceneMgr->createEntity("orig_lodt", "../../../OgreStuff/media/GT/ML11.mesh");*/
+
+
+		// Add objects to the LodManager!
+
+/*		for (int i=0; i<25; i++)
+			AddNewLodTreeObj();*/
+		//audiere::AudioDevicePtr device(audiere::OpenDevice());
+		//audiere::OutputStreamPtr song(OpenSound(device,"../../musica.mp3",false));
+		song->setVolume(0.5f);
+		song->setRepeat(true);
+		song->play(); 
+
+		for (int i=0; i<1000; i++)
+			AddNewLodStripsObj();
+		
+
+        // show overlay
+        Overlay* pOver = OverlayManager::getSingleton().getByName("Demo_LodStrips/Overlay");    
+        mInfo = OverlayManager::getSingleton().getOverlayElement("Demo_LodStrips/Info_1");
+		mInfo2 = OverlayManager::getSingleton().getOverlayElement("Demo_LodStrips/Info_2");
+        mHelp = OverlayManager::getSingleton().getOverlayElement("Demo_LodStrips/Help");
+		mHelp->setCaption(NoHelpString);
+		pOver->show();
+//		pOver->hide();
+
+    }
+
+    void createFrameListener(void)
+    {
+        mFrameListener= new LodManagerFrameListener(mWindow, mCamera);
+        mFrameListener->showDebugOverlay(false);
+        mRoot->addFrameListener(mFrameListener);
+    }
+
+};
+
+
+
+#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
+#define WIN32_LEAN_AND_MEAN
+#include "windows.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
+INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
+#else
+int main(int argc, char **argv)
+#endif
+{
+    // Create application object
+    LodManagerApplication app;
+
+    try {
+        app.go();
+    } catch( Exception& e ) {
+#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
+        MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
+#else
+        std::cerr << "An exception has occured: " << e.getFullDescription();
+#endif
+    }
+
+
+    return 0;
+}
+
+#ifdef __cplusplus
+}
+#endif
Index: GTP/trunk/App/Demos/Geom/main.cpp
===================================================================
--- GTP/trunk/App/Demos/Geom/main.cpp	(revision 1791)
+++ 	(revision )
@@ -1,548 +1,0 @@
-/*	==========================================================================
- *	(C) 2006 Universitat Jaume I
- *	==========================================================================
- *	PROYECT:	GAME TOOLS
- *	==========================================================================*/
-/**	CONTENT:	
-	*
-	*
-	*	@file	main.cpp
-/** COMMENTS:
-	* Model must be in "media/models" folder.
-	* Lod file must be in "media/GT" folder.
-/*===========================================================================*/
-#include "ExampleApplication.h"
-#include "GeoLodManager.h"
-#include "GeoMeshLoader.h"
-#include "audiere.h"
-
-
-// Distance values
-#define dist_min 2000
-#define dist_max 4000
-
-// Model name
-//#define model_name "dwarf2"
-
-
-//Global variables
-Geometry::LodManager* lodManager = NULL;
-Geometry::Mesh  *the_lodstrips_mesh = NULL, 
-				*the_lodtree_mesh = NULL;
-Geometry::GeoMeshLoader *lodstrips_meshloader = NULL,
-						*lodtree_meshloader = NULL;
-Ogre::SceneManager *sceneManager = NULL;
-Ogre::Entity *orig_lodstrips_entity = NULL,
-			 *orig_lodtree_entity = NULL;
-
-		audiere::AudioDevicePtr device(audiere::OpenDevice());
-		audiere::OutputStreamPtr song(OpenSound(device,"../../musica.mp3",false));
-
-
-MaterialPtr *mat;
-
-ColourValue color=ColourValue::Red;
-
-Camera* theCam;
-Entity* pPlaneEnt;
-
-char HelpString[]="(F1) Quit this Help\n"
-			"This demo shows an example of the LODManager in action. Every model in the scene\n"
-			"has its own LodStrips object associated that manages its level of detail.\n"
-			"Since the scene is highly populated, changing the LOD of every object independently\n"
-			"would make the performance to fall.\n"
-			"The LodManager makes efficient LOD computations by reusing previously calculated LODs.\n"
-			"The level of detail of the objects depends on the distance to the camera. When the\n"
-			"camera goes away from them, the level of detail decreases, and when the camera gets\n"
-			"closer to them increases to restore the original geometry of the model.\n"
-			"(F4) LODManager ON\n"
-			"(F3) LODManager OFF\n\n"
-			"IMPORTANT: to notice performance improvements the user must move the camera, since the\n"
-			"LOD in only re-calculated when the camera position changes.";
-
-char NoHelpString[]="\n\n\n\n\n\n\n\n\n\n\n\n\n(F1) Help\n";
-
-OverlayElement* mLOD;
-OverlayElement* mInfo;
-OverlayElement* mInfo2;
-OverlayElement* mHelp;
-
-//Ogre::OverlayElement *mInfo, *mInfo2;
-
-// framerate test
-std::vector<float> framerates;
-const unsigned int msDelay = 1000;
-
-class CustomIndexData : public Geometry::IndexData
-{
-private:
-	Ogre::Mesh *targetMesh;
-	Ogre::HardwareIndexBufferSharedPtr ibuf;
-	unsigned long* pIdx;
-	Ogre::HardwareIndexBufferSharedPtr *orig_indexbuff;
-
-public:
-	CustomIndexData(Ogre::Mesh *ogremesh):Geometry::IndexData(){
-		targetMesh=ogremesh;
-		pIdx=NULL;
-		orig_indexbuff=new Ogre::HardwareIndexBufferSharedPtr[targetMesh->getNumSubMeshes()];
-		for (int i=0; i<targetMesh->getNumSubMeshes(); i++)
-		{
-			Ogre::RenderOperation mRenderOp;
-			targetMesh->getSubMesh(i)->_getRenderOperation(mRenderOp,0);
-			orig_indexbuff[i] = mRenderOp.indexData->indexBuffer;
-		}
-	}
-	virtual ~CustomIndexData(void){
-		delete[] orig_indexbuff;
-	}
-
-	virtual void Begin(unsigned int submeshid, unsigned int indexcount){
-		Ogre::RenderOperation mRenderOp;	
-		targetMesh->getSubMesh(submeshid)->_getRenderOperation(mRenderOp,0);
-
-		// restore the original index data to modify it
-		mRenderOp.indexData->indexBuffer = orig_indexbuff[submeshid];
-
-		ibuf = mRenderOp.indexData->indexBuffer;
-		mRenderOp.indexData->indexCount = indexcount;
-		pIdx = static_cast<unsigned long*>(ibuf->lock(Ogre::HardwareBuffer::HBL_NORMAL));
-	}
-
-	virtual void SetIndex(unsigned int i, unsigned int index){
-		pIdx[i] = index;
-	}
-	virtual void End(){
-		ibuf->unlock();
-	}
-	virtual void BorrowIndexData(const Geometry::IndexData *idata){
-		CustomIndexData *custom_data = (CustomIndexData*)idata;
-		for (int i=0; i<targetMesh->getNumSubMeshes(); i++)
-		{
-			Ogre::RenderOperation mRenderOp, mRenderOpParam;
-
-			targetMesh->getSubMesh(i)->_getRenderOperation(mRenderOp,0);			
-			custom_data->targetMesh->getSubMesh(i)->_getRenderOperation(mRenderOpParam,0);
-
-			mRenderOp.indexData->indexBuffer = mRenderOpParam.indexData->indexBuffer;
-			mRenderOp.indexData->indexCount  = mRenderOpParam.indexData->indexCount;
-		}
-	}
-};
-
-void AddNewLodStripsObj(void)
-{
-	const int troop_width = 30;
-	static int iname = 0;
-	int i = iname%troop_width;
-	int j = iname/troop_width;	
-
-	char newObjName[16]="";
-	sprintf(newObjName,"model_%d",iname);
-	char newMeshName[16]="";
-	sprintf(newMeshName,"mesh_%d",iname);
-	iname++;
-
-	Ogre::Mesh *ogreMesh = orig_lodstrips_entity->getMesh()->clone(newMeshName).getPointer();
-	Entity *entity = sceneManager->createEntity(newObjName,newMeshName);
-	entity->setNormaliseNormals(true);
-
-	Ogre::SceneNode * auxnode = sceneManager->getRootSceneNode()->createChildSceneNode();
-	auxnode->attachObject(entity);
-	auxnode->rotate(Ogre::Vector3(0,1,0),Ogre::Degree(180.0f),Ogre::Node::TS_WORLD);
-	auxnode->scale(30.0f,30.0f,30.0f);
-	float randomsepx = (float)((rand()%18)-9);
-	float randomsepy = (float)((rand()%12)-6);
-	auxnode->translate(i*120.0f+randomsepx,0.0f,-j*120.0f-randomsepx);
-//	auxnode->translate(0,0,-500.0f);
-
-	Geometry::LodStripsLibrary *myStrips = new Geometry::LodStripsLibrary(
-							lodstrips_meshloader->GetLodStripsData(),
-							the_lodstrips_mesh,
-							new CustomIndexData(ogreMesh));
-
-	entity->setMaterialName("LODStripsDemo/Ogro");
-
-	// add the object to the manager
-	Ogre::Vector3 opos = auxnode->getPosition();
-	lodManager->AddLodObj("ogre",myStrips,Geometry::Vector3(opos.x,opos.y,opos.z));				
-}
-
-
-void AddNewLodTreeObj(void)
-{
-	const int troop_width = 10;
-	static int iname = 0;
-	int i = iname%troop_width;
-	int j = iname/troop_width;	
-
-	char newObjName[16]="";
-	sprintf(newObjName,"tree_%d",iname);
-	char newMeshName[16]="";
-	sprintf(newMeshName,"tree_%d",iname);
-	iname++;
-
-	Ogre::Mesh *ogreMesh = orig_lodtree_entity->getMesh()->clone(newMeshName).getPointer();
-	Entity *entity = sceneManager->createEntity(newObjName,newMeshName);
-	entity->setNormaliseNormals(true);
-
-	Ogre::SceneNode * auxnode = sceneManager->getRootSceneNode()->createChildSceneNode();
-	auxnode->attachObject(entity);
-	auxnode->scale(11.0f,11.0f,11.0f);
-	auxnode->rotate(Ogre::Vector3(0,0,1),Ogre::Degree(rand()%360));
-	auxnode->rotate(Ogre::Vector3(1,0,0),Ogre::Radian(-3.14159f*0.5f),Ogre::Node::TS_WORLD);
-	float randomsepx = (float)((rand()%18)-9);
-	float randomsepy = (float)((rand()%12)-6);
-	auxnode->translate(i*60.0f+randomsepx,-1.0f,-j*60.0f-randomsepx);
-	auxnode->translate(300,0,-500.0f);
-
-	Geometry::LodTreeLibrary *myTree = new Geometry::LodTreeLibrary(
-							lodtree_meshloader->GetLodStripsData(),
-							lodtree_meshloader->GetTreeSimpSeq(),
-							the_lodtree_mesh,
-							new CustomIndexData(ogreMesh));
-
-	// load the right material for each part of the tree
-	for (int submesh=0; submesh < ogreMesh->getNumSubMeshes(); submesh++)
-	{
-		bool istrunk = myTree->GetLeavesSubMesh()!=submesh;
-		if (istrunk)
-			entity->getSubEntity(submesh)->setMaterialName("Examples/Populifolia/trunk");
-		else
-			entity->getSubEntity(submesh)->setMaterialName("Examples/Populifolia/leaf");
-	}
-
-
-	// add the object to the manager
-	Ogre::Vector3 opos = auxnode->getPosition();
-	lodManager->AddLodObj("tree",myTree,Geometry::Vector3(opos.x,opos.y,opos.z));				
-}
-
-
-
-class LodManagerFrameListener : public ExampleFrameListener
-{
-	int manage;
-
-public:
-
-    LodManagerFrameListener(RenderWindow* win, Camera* cam)
-        : ExampleFrameListener(win, cam, false, false)
-    {
-		manage=1;
-	}
-
-	bool frameStarted(const FrameEvent& evt)
-    {
-		Vector3 dist; 
-		int distance=0,inc2=0;
-
-		// test
-		static float timeLeft = 0;
-		
-		const RenderTarget::FrameStats& stats = mWindow->getStatistics();
-
-		static bool rec_stats = false;
-
-		if (mInputDevice->isKeyDown(Ogre::KC_J))
-			rec_stats=true;
-
-		if (rec_stats)
-		{
-			if (timeLeft <= 0.0f)
-			{
-				framerates.push_back(stats.lastFPS);
-				timeLeft = msDelay;
-			}
-			timeLeft -= evt.timeSinceLastFrame * 1000.0f;	
-		}
-
-		// Move upto 80 units/second
-		Real MoveFactor = 180.0 * evt.timeSinceLastFrame;
-
-		// Copy the current state of the input devices
-		mInputDevice->capture();
-
-		// 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;
-		
-		lodManager->UpdateLOD(stats.lastFPS,90);
-
-		bool cam_moved=false;
-
-		if (mInputDevice->isKeyDown(Ogre::KC_F3))
-		{
-			lodManager->always_calculate_lod = true;
-			cam_moved = true;
-		}
-		if (mInputDevice->isKeyDown(Ogre::KC_F4))
-		{
-			lodManager->always_calculate_lod = false;
-			cam_moved = true;
-		}
-
-		//if (mInputDevice->isKeyDown(Ogre::KC_F7))
-		//{
-		//	lodManager->force_highest_lod = true;
-		//	cam_moved = true;
-		//}
-
-		//if (mInputDevice->isKeyDown(Ogre::KC_F8))
-		//{
-		//	lodManager->force_highest_lod = false;
-		//	cam_moved = true;
-		//}
-
-		// Move the cam
-		if(mInputDevice->isKeyDown(Ogre::KC_UP))
-		{
-		  mTranslateVector.z = -mMoveScale;
-		  cam_moved=true;
-		}
-
-		if(mInputDevice->isKeyDown(Ogre::KC_DOWN))
-		{
-		  mTranslateVector.z = mMoveScale;
-		  cam_moved=true;
-		}
-
-		// Instead of moving the ship left and right, rotate it using yaw()
-		if(mInputDevice->isKeyDown(Ogre::KC_LEFT))
-		{
-		  mCamera->yaw(mRotScale);
-		  cam_moved=true;
-		}
-
-		if(mInputDevice->isKeyDown(Ogre::KC_RIGHT))
-		{
-		  mCamera->yaw(-mRotScale);
-		  cam_moved=true;
-		}
-
-		if(mInputDevice->isKeyDown(Ogre::KC_ESCAPE))
-		{
-			delete lodManager;
-			delete [] mat;
-			FILE *f=fopen("fps.txt","wt");
-			unsigned int ms = 0;
-			for (std::vector<float>::iterator it = framerates.begin(); it != framerates.end(); it++, ms++)
-				fprintf(f,"%u %f\n",ms,*it);
-			fclose(f);
-		    return false;
-		}
-
-		static bool newpush = true;
-		if (!mInputDevice->isKeyDown(Ogre::KC_F1))
-			newpush = true;
-
-		static bool showing_help = false;
-		if (mInputDevice->isKeyDown(Ogre::KC_F1) && newpush)
-		{
-			newpush = false;
-			if (showing_help = !showing_help)
-                mHelp->setCaption(HelpString);
-			else
-                mHelp->setCaption(NoHelpString);
-		}
-
-        if( mInputDevice->getMouseButton( 1 ) )
-        {
-            mTranslateVector.x += mInputDevice->getMouseRelativeX() * 0.13;
-            mTranslateVector.y -= mInputDevice->getMouseRelativeY() * 0.13;
-			cam_moved=true;
-        }
-        else
-        {
-            mRotX = Degree(-mInputDevice->getMouseRelativeX() * 0.13);
-            mRotY = Degree(-mInputDevice->getMouseRelativeY() * 0.13);
-        }
-
-		char cadena[256];
-       
-		if ( lodManager->always_calculate_lod )		
-			sprintf(cadena,"\n\nLOD Manager:  OFF\nTriangle Count: %d\n",stats.triangleCount);
-		else
-			sprintf(cadena,"\n\nLOD Manager:  ON\nTriangle Count: %d\n",stats.triangleCount);
-
-		mInfo->setCaption(cadena);
-		mWindow->getStatistics();
-
-		sprintf(cadena,"Current FPS: %f\n",stats.lastFPS);
-		mInfo2->setCaption(cadena);
-
-
-		mCamera->yaw(mRotX);
-        mCamera->pitch(mRotY);
-        mCamera->moveRelative(mTranslateVector);
-
-		if (cam_moved)
-			lodManager->UpdateCamera(Geometry::Vector3(mCamera->getPosition().x,mCamera->getPosition().y,mCamera->getPosition().z));
-
-		return true;
-    }
-};
-
-class LodManagerApplication : public ExampleApplication
-{
-public:
-    LodManagerApplication() {}
-
-    ~LodManagerApplication() {}
-protected:
-    
-    // Just override the mandatory create scene method
-    void createScene(void)
-    {
-		mat = new MaterialPtr[1];
-
-		theCam = mCamera;
-        theCam->setPosition(1900,200,800);
-        // Set ambient light
-		sceneManager = mSceneMgr;
-        mSceneMgr->setAmbientLight(ColourValue(0.2, 0.2, 0.2));
-
-		//SHADOWS
-		//mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_MODULATIVE);
-		//mSceneMgr->setShadowTextureSettings(2048,1);
-		//mSceneMgr->setShadowFarDistance(2048);
-		//mSceneMgr->setShadowColour(ColourValue(0.5, 0.5, 0.5));
-
-        // Create a point light
-        Light* l = mSceneMgr->createLight("MainLight");
-        l->setType(Light::LT_DIRECTIONAL);
-        l->setDirection(-0.5,-1.0,-1.0);
-
-        
-        mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox");
-
-        // My node to which all objects will be attached
-        SceneNode* myRootNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
-
-        // Define a floor plane mesh
-		Plane plane( Vector3::UNIT_Y, 0 );
-
-		MeshManager::getSingleton().createPlane("ground",
-			ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane,
-			40000,40000,6,6,true,1,200,200,Vector3::UNIT_Z);
-
-		Entity* groundEntity = mSceneMgr->createEntity( "GroundEntity", "ground" );
-		mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(groundEntity);
-		
-		groundEntity->setMaterialName("SnowTerrain");
-		groundEntity->setCastShadows(false);       
-
-
-		lodManager = new Geometry::LodManager(dist_min,dist_max,Geometry::Vector3(theCam->getPosition().x,theCam->getPosition().y,theCam->getPosition().z),100);
-		lodManager->UpdateCamera(Geometry::Vector3(	theCam->getPosition().x,
-													theCam->getPosition().y,
-													theCam->getPosition().z ));
-
-		// load the LodStrips info from the object /////////////////////////////////////////////////////////////////
-		lodstrips_meshloader=new Geometry::GeoMeshLoader;
-		the_lodstrips_mesh = lodstrips_meshloader->load("../../../OgreStuff/media/GT/ogrolod.mesh");
-
-		if (!lodstrips_meshloader->GetLodStripsData())
-            OGRE_EXCEPT(1, "The loaded mesh does not contain any LOD info","LOD Demo");
-
-		orig_lodstrips_entity = mSceneMgr->createEntity("orig_lods", "../../../OgreStuff/media/GT/ogrolod.mesh");
-
-
-		// load the LodTree info from the object //////////////////////////////////////////////////////////////////
-/*		lodtree_meshloader=new Geometry::GeoMeshLoader;
-		the_lodtree_mesh = lodtree_meshloader->load("../../../OgreStuff/media/GT/ML11.mesh");
-
-		if (!lodtree_meshloader->GetLodStripsData())
-            OGRE_EXCEPT(1, "The loaded mesh does not contain LODStrips info","LOD Demo");
-		if (!lodtree_meshloader->GetTreeSimpSeq())
-            OGRE_EXCEPT(1, "The loaded mesh does not contain LODTree info","LOD Demo");
-
-		orig_lodtree_entity = mSceneMgr->createEntity("orig_lodt", "../../../OgreStuff/media/GT/ML11.mesh");*/
-
-
-		// Add objects to the LodManager!
-
-/*		for (int i=0; i<25; i++)
-			AddNewLodTreeObj();*/
-		//audiere::AudioDevicePtr device(audiere::OpenDevice());
-		//audiere::OutputStreamPtr song(OpenSound(device,"../../musica.mp3",false));
-		song->setVolume(0.5f);
-		song->setRepeat(true);
-		song->play(); 
-
-		for (int i=0; i<1000; i++)
-			AddNewLodStripsObj();
-		
-
-        // show overlay
-        Overlay* pOver = OverlayManager::getSingleton().getByName("Demo_LodStrips/Overlay");    
-        mInfo = OverlayManager::getSingleton().getOverlayElement("Demo_LodStrips/Info_1");
-		mInfo2 = OverlayManager::getSingleton().getOverlayElement("Demo_LodStrips/Info_2");
-        mHelp = OverlayManager::getSingleton().getOverlayElement("Demo_LodStrips/Help");
-		mHelp->setCaption(NoHelpString);
-		pOver->show();
-//		pOver->hide();
-
-    }
-
-    void createFrameListener(void)
-    {
-        mFrameListener= new LodManagerFrameListener(mWindow, mCamera);
-        mFrameListener->showDebugOverlay(false);
-        mRoot->addFrameListener(mFrameListener);
-    }
-
-};
-
-
-
-#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
-#define WIN32_LEAN_AND_MEAN
-#include "windows.h"
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
-INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
-#else
-int main(int argc, char **argv)
-#endif
-{
-    // Create application object
-    LodManagerApplication app;
-
-    try {
-        app.go();
-    } catch( Exception& e ) {
-#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
-        MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
-#else
-        std::cerr << "An exception has occured: " << e.getFullDescription();
-#endif
-    }
-
-
-    return 0;
-}
-
-#ifdef __cplusplus
-}
-#endif
