Index: /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/OBA/OBAOgreFrameListenerMode.h
===================================================================
--- /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/OBA/OBAOgreFrameListenerMode.h	(revision 721)
+++ /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/OBA/OBAOgreFrameListenerMode.h	(revision 751)
@@ -74,4 +74,6 @@
 
 	virtual void destroyScene(void);    // Optional to override this
+
+	unsigned int getHandle();
 };
 
Index: /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/LBBC/LBBCSampleConfigFile.h
===================================================================
--- /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/LBBC/LBBCSampleConfigFile.h	(revision 747)
+++ /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/LBBC/LBBCSampleConfigFile.h	(revision 751)
@@ -50,15 +50,27 @@
 	Ogre::String getEntityClustersFolder();
 
-	bool getEntityClustersMergedClusters();
-
 	bool getEntityClustersSplittedClusters();
 
-	Ogre::String getEntityClustersMergedMeshName();
+	bool getEntityClustersGroupedClusters();
+
+	bool getBillboardCloudDiffuseColorGroupedBillboardsTextureAtlasDebug();
+
+	bool getBillboardCloudDiffuseColorMergedBillboardsTextureAtlasDebug();
+
+	bool getBillboardCloudIndirectGroupedBillboardsTextureAtlasDebug();
+
+	bool getBillboardCloudIndirectMergedBillboardsTextureAtlasDebug();
+
+	Ogre::String getEntityClustersGroupedMeshName();
 
 	Ogre::String getEntityClustersSplittedMeshName();
 
-	Ogre::String getEntityClustersMergedMaterialName();
+	Ogre::String getEntityClustersGroupedMaterialName();
 
 	Ogre::String getEntityClustersSplittedMaterialName();
+
+	Ogre::String getEntityClustersGroupedTextureUnit0Name();
+
+	Ogre::String getEntityClustersSplittedTextureUnit0Name();
 
 	bool getBillboardCloudMergedBillboards();
@@ -94,4 +106,8 @@
 	Ogre::String getBillboardCloudMergedXMLName();
 
+	Ogre::String getBillboardCloudIndirectPointMeshName();
+
+	Ogre::String getBillboardCloudIndirectPointMaterialName();
+
 	unsigned int getBillboardCloudGroups();
 
@@ -102,5 +118,5 @@
 	Ogre::String getBillboardCloudDiffuseColorEntityTextureName();
 
-	Ogre::String getBillboardCloudDiffuseColorEntityTextureAtlasName();
+	Ogre::String getBillboardCloudDiffuseColorEntityTextureAtlasName();	
 
 	unsigned int getBillboardCloudDiffuseColorEntityTextureAtlasBitRange();
@@ -108,17 +124,17 @@
 	unsigned int getBillboardCloudDiffuseColorEntityTextureAtlasSize();
 
-	unsigned int getBillboardCloudDiffuseColorBillboardGroupTextureSize();
+	unsigned int getBillboardCloudDiffuseColorGroupedBillboardsTextureSize();
 
-	bool getBillboardCloudIndirectBillboardGroupTextureAtlasGeneration();
+	bool getBillboardCloudIndirectGroupedBillboardsTextureAtlasGeneration();
 
-	Ogre::String getBillboardCloudIndirectBillboardGroupTextureAtlasName();
+	Ogre::String getBillboardCloudIndirectGroupedBillboardsTextureAtlasName();
 
-	unsigned int getBillboardCloudIndirectBillboardGroupTextureAtlasBitRange();
+	unsigned int getBillboardCloudIndirectGroupedBillboardsTextureAtlasBitRange();
 
-	unsigned int getBillboardCloudIndirectBillboardGroupTextureAtlasSize();
+	unsigned int getBillboardCloudIndirectGroupedBillboardsTextureAtlasSize();
 
-	unsigned int getBillboardCloudIndirectBillboardGroupTextureSize();
+	unsigned int getBillboardCloudIndirectGroupedBillboardsTextureSize();
 
-	bool getBillboardCloudDiffuseColorBillboardGroupTextureAtlasGeneration();
+	bool getBillboardCloudDiffuseColorGroupedBillboardsTextureAtlasGeneration();
 
 	bool getBillboardCloudDiffuseColorMergedBillboardsTextureAtlasGeneration();
@@ -132,5 +148,5 @@
 	unsigned int getBillboardCloudDiffuseColorMergedBillboardsTextureSize();
 
-	unsigned int getBillboardCloudDiffuseColorBillboardGroupTextureAtlasSize();
+	unsigned int getBillboardCloudDiffuseColorGroupedBillboardsTextureAtlasSize();
 
 	unsigned int getBillboardCloudDiffuseColorEntityTextureAtlasNumSamples();
@@ -138,7 +154,11 @@
 	bool getBillboardCloudIndirectMergedBillboardsTextureAtlasGeneration();
 
+	Ogre::String getBillboardCloudDiffuseColorGroupedBillboardsTextureAtlasName();
+
 	Ogre::String getBillboardCloudIndirectMergedBillboardsTextureAtlasName();
 
 	unsigned int getBillboardCloudIndirectMergedBillboardsTextureAtlasBitRange();
+
+	unsigned int getBillboardCloudDiffuseColorGroupedBillboardsTextureAtlasBitRange();
 
 	unsigned int getBillboardCloudIndirectMergedBillboardsTextureAtlasSize();
Index: /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/LBBC/LBBCManager.h
===================================================================
--- /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/LBBC/LBBCManager.h	(revision 745)
+++ /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/LBBC/LBBCManager.h	(revision 751)
@@ -69,4 +69,5 @@
 	void loadBillboardCloudMergedXML();
 
+	void saveBillboardCloudIndirectSplittedPointMeshName();
 
   protected:
Index: /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/LBBC/LBBCLeafDistributionGenerator.h
===================================================================
--- /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/LBBC/LBBCLeafDistributionGenerator.h	(revision 721)
+++ /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/LBBC/LBBCLeafDistributionGenerator.h	(revision 751)
@@ -16,4 +16,6 @@
     virtual ~LeafDistributionGenerator();
 
+	void generateAverageLeafPosition(Leaf *leaf);
+
 	void generateAverageLeafNormal(Leaf *leaf);
 
Index: /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/LBBC/LBBCClusterViewMode.h
===================================================================
--- /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/LBBC/LBBCClusterViewMode.h	(revision 731)
+++ /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/LBBC/LBBCClusterViewMode.h	(revision 751)
@@ -13,4 +13,5 @@
 		  OBA::OgreFrameListenerMode(win, ogreFrameListenerModeHandle, useBufferedInputKeys, useBufferedInputMouse)
 		{
+			showDebugOverlay(false);
 		}
 
@@ -19,10 +20,30 @@
 		}
 
+		bool frameStarted(const Ogre::FrameEvent& evt, Ogre::InputReader *inputReader)
+		{
+			mWindow->getViewport(0)->setBackgroundColour(Ogre::ColourValue(0.0, 0.0, 0.0, 1.0));
+
+			return OgreFrameListenerMode::frameStarted(evt, inputReader);	
+		}
+
+		void setEntityClustersMeshName(Ogre::String entityClustersMeshName)
+		{
+			mEntityClustersMeshName = entityClustersMeshName;
+		}
+
 		virtual void createScene()
 		{
+			mWindow->getViewport(0)->setBackgroundColour(Ogre::ColourValue(0.0, 0.0, 0.0, 1.0));
+
 			Ogre::SceneNode* sNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
-			Ogre::Entity* emesh = mSceneMgr->createEntity("chestnutLeavesEntitySample.mesh", "chestnutLeavesEntitySample.mesh");		
-			sNode->attachObject(emesh);
+			//Ogre::Entity* eLeafClustersGrouped = mSceneMgr->createEntity(mEntityClustersMeshName, mEntityClustersMeshName);					
+			Ogre::Entity* eLeafClustersGrouped = mSceneMgr->createEntity("chestnutLeafClustersGrouped.mesh", "chestnutLeafClustersGrouped.mesh");								
+			sNode->attachObject(eLeafClustersGrouped);			
+			sNode->rotate(Ogre::Vector3::UNIT_X, Ogre::Radian(Ogre::Degree(-90.0)));
 		}
+	protected:
+		Ogre::String mEntityClustersMeshName;
+
+
 };
 
Index: /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/LBBC/LBBCEntityTextureAtlasViewMode.h
===================================================================
--- /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/LBBC/LBBCEntityTextureAtlasViewMode.h	(revision 745)
+++ /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/LBBC/LBBCEntityTextureAtlasViewMode.h	(revision 751)
@@ -40,6 +40,4 @@
 		virtual ~EntityTextureAtlasViewMode();		
 
-		unsigned int nextPowerOf2(unsigned int nPlanes);
-
 		virtual bool frameStarted(const Ogre::FrameEvent& evt, Ogre::InputReader *inputReader);
 
Index: /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/LBBC/LBBCBillboardViewMode.h
===================================================================
--- /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/LBBC/LBBCBillboardViewMode.h	(revision 731)
+++ /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/LBBC/LBBCBillboardViewMode.h	(revision 751)
@@ -13,4 +13,6 @@
 		  OBA::OgreFrameListenerMode(win, ogreFrameListenerModeHandle, useBufferedInputKeys, useBufferedInputMouse)
 		{
+			showDebugOverlay(false);
+			mReloadedTextures = false;
 		}
 
@@ -19,11 +21,47 @@
 		}
 
+		bool frameStarted(const Ogre::FrameEvent& evt, Ogre::InputReader *inputReader)
+		{
+			mWindow->getViewport(0)->setBackgroundColour(Ogre::ColourValue(0.0, 0.0, 0.0, 1.0));
+
+			//if (!mReloadedTextures)
+			//{
+			//	for (unsigned int iSubEntity = 0; iSubEntity < mBillboardCloudEntity->getNumSubEntities(); iSubEntity++)
+			//	{
+			//		Ogre::MaterialPtr materialPtr = Ogre::MaterialManager::getSingleton().getByName(mBillboardCloudEntity->getSubEntity(iSubEntity)->getMaterialName());
+			//		Ogre::LogManager::getSingleton().logMessage("Reloading texture:" + materialPtr->getTechnique(0)->getPass(0)->getTextureUnitState(0)->getTextureName());
+
+			//		Ogre::TexturePtr texturePtr = Ogre::TextureManager::getSingleton().getByName(materialPtr->getTechnique(0)->getPass(0)->getTextureUnitState(0)->getTextureName());
+			//		texturePtr->reload();
+			//		materialPtr->reload();
+			//	}
+			//	mReloadedTextures = true;
+			//}
+
+			return OgreFrameListenerMode::frameStarted(evt, inputReader);	
+		}
+
+		void setBillboardCloudMeshName(Ogre::String billboardCloudMeshName)
+		{
+			mBillboardCloudMeshName = billboardCloudMeshName;
+		}
+
 		virtual void createScene()
 		{
+			mWindow->getViewport(0)->setBackgroundColour(Ogre::ColourValue(0.0, 0.0, 0.0, 1.0));
+
 			Ogre::SceneNode* sNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
-			Ogre::Entity* emesh = mSceneMgr->createEntity("chestnutLeavesBillboardCloudMerged.mesh","chestnutLeavesBillboardCloudGrouped.mesh");		
-			sNode->attachObject(emesh);
+			//mBillboardCloudEntity = mSceneMgr->createEntity(mBillboardCloudMeshName, mBillboardCloudMeshName);		
+			mBillboardCloudEntity = mSceneMgr->createEntity("chestnutLeavesBillboardCloudGrouped.mesh", "chestnutLeavesBillboardCloudGrouped.mesh");		
+			sNode->attachObject(mBillboardCloudEntity);
+			sNode->rotate(Ogre::Vector3::UNIT_X, Ogre::Radian(Ogre::Degree(-90.0)));
 		}
 
+	protected:
+		Ogre::String mBillboardCloudMeshName;
+
+		Ogre::Entity *mBillboardCloudEntity;
+
+		bool mReloadedTextures;
 };
 
Index: /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/LBBC/LBBCBillboardCloudTextureViewMode.h
===================================================================
--- /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/LBBC/LBBCBillboardCloudTextureViewMode.h	(revision 747)
+++ /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/LBBC/LBBCBillboardCloudTextureViewMode.h	(revision 751)
@@ -22,11 +22,11 @@
 	unsigned int mSubEntityVisible;
 
-	Ogre::Entity *mEntity;
+	Ogre::Entity *mEntityClusters;
 
 public:
 	
-	void setEntity(Ogre::Entity *entity)
+	void setEntityClusters(Ogre::Entity *entity)
 	{
-		mEntity = entity;
+		mEntityClusters = entity;
 	}
 
@@ -50,8 +50,4 @@
 		if (mCurrentTexture < mNumTextures)
 		{
-			//calculateProjectionMatrix(unsigned int iSubEntity, Ogre::Camera *cam);
-			//initializeShaderParameters(unsigned int iSubEntity);
-			mTexture->getRectangle2D()->setVisible(false);
-			mTextureAtlas->getRectangle2D()->setVisible(false);
 		}
     }
@@ -76,5 +72,4 @@
 	void preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt)
     {
-		//configureTexture( unsigned int iSubEntity );
     }
 
@@ -90,7 +85,11 @@
 		unsigned int mFrame;
 
-		Ogre::SceneNode *mClusterizedEntitiesMergedSceneNode;
+		Ogre::SceneNode *mEntityClustersGroupedSceneNode;
 		
-		Ogre::Entity *mClusterizedEntities;
+		Ogre::SceneNode *mBillboardCloudSplittedSceneNode;
+
+		Ogre::Entity *mEntityClustersGrouped;
+
+		Ogre::Entity *mBillboardCloudSplitted;
 
 		ClusterTextureListener mClusterTextureListener;
@@ -120,9 +119,23 @@
 		Ogre::String mTextureAtlasFolder;
 
-		Ogre::String mEntityName;
+		Ogre::String mEntityClustersGroupedName;
+
+		Ogre::String mBillboardCloudSplittedName;
+
+		Ogre::Matrix4 mCustomProjMatrix;
+
+		Ogre::String mTextureName;
+
+		bool mDebugBillboardGeneration;
+
+		bool mDebugTextureAtlasGeneration;
+
+		unsigned int mCurrentBillboardGroup;
+
+		unsigned int mCurrentBillboard;
 
 	public:
 
-		BillboardCloudTextureViewMode(Ogre::RenderWindow* win, unsigned int ogreFrameListenerModeHandle, bool useBufferedInputKeys = false, bool useBufferedInputMouse = false);
+		BillboardCloudTextureViewMode(Ogre::RenderWindow* win, unsigned int ogreFrameListenerModeHandle, bool useBufferedInputKeys = false, bool useBufferedInputMouse = false);	
 
 		virtual ~BillboardCloudTextureViewMode();		
@@ -133,4 +146,22 @@
 
 		virtual void destroyScene();
+
+		void setBillboardCloudGroupedTextureAtlasDebug(bool debugTextureAtlasGeneration);
+
+		void setTextureName(Ogre::String textureName);
+
+		void configureBillboard();
+
+		void enableEntityClusterCustomOrthogonalCameraMaterial(unsigned int iEntityClusterGrouped);
+
+		void disableEntityClusterCustomOrthogonalCameraMaterial(unsigned int iEntityClusterGrouped);
+
+		void configureTexture();
+
+		void configureTextureAtlas();
+	
+		bool processUnbufferedKeyInput(const Ogre::FrameEvent& evt);
+
+		void saveTextureAtlas();
 		
 		void setTextureAtlasSize(unsigned int size);
@@ -138,5 +169,7 @@
 		void setTextureSize(unsigned int size);
 
-		void setEntityName(Ogre::String entityName);
+		void setEntityClustersGroupedName(Ogre::String entityClustersGrouped);
+
+		void setBillboardCloudSplittedName(Ogre::String billboardCloudSplittedName);
 
 		void setTextureAtlasName(Ogre::String textureAtlasName);
@@ -145,4 +178,15 @@
 
 		void setTextureAtlasBitRange(unsigned int bitRange);
+
+		void configureBillboardOrthogonalAlignedCamera(unsigned int iBillboard);
+
+		void initializeEntityClustersGrouped();
+
+		void initializeBillboardCloudSplitted();
+		
+		void generateTexture();
+
+		void generateTextureAtlas();
+
 };
 
Index: /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/BBC/BBCSubEntity.h
===================================================================
--- /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/BBC/BBCSubEntity.h	(revision 721)
+++ /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/BBC/BBCSubEntity.h	(revision 751)
@@ -130,6 +130,4 @@
 	void setMaterialName(Ogre::String value);
 
-	//void createUniqueVertices();
-
 	UniqueVertexList* getUniqueVertices();
 
Index: /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/BBC/BBCBillboardClusterData.h
===================================================================
--- /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/BBC/BBCBillboardClusterData.h	(revision 745)
+++ /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/BBC/BBCBillboardClusterData.h	(revision 751)
@@ -77,5 +77,5 @@
 	Ogre::Vector2 getBillboardUVMapMin(unsigned int iBillboardGroup);
 
-	void addBillboardUVMapMin(Ogre::Vector2 min);
+	void addBillboardUVMapMin(Ogre::Vector2 minVec);
 
 	void removeBillboardUVMapMin(unsigned int iBillboardGroup);
@@ -83,5 +83,5 @@
 	Ogre::Vector2 getBillboardUVMapMax(unsigned int iBillboardGroup);
 
-	void addBillboardUVMapMax(Ogre::Vector2 max);
+	void addBillboardUVMapMax(Ogre::Vector2 maxVec);
 
 	void removeBillboardUVMapMax(unsigned int iBillboardGroup);
Index: /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/BBC/BBCBillboardCloudGenerator.h
===================================================================
--- /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/BBC/BBCBillboardCloudGenerator.h	(revision 721)
+++ /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/BBC/BBCBillboardCloudGenerator.h	(revision 751)
@@ -2,5 +2,4 @@
 #define _BBCBILLBOARDCLOUDGENERATOR_H
 
-#include <BBCUtil.h>
 #include <BBCEntity.h>
 #include <BBCEntityDistribution.h>
Index: /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/BBC/BBCBillboardCloudUVMapper.h
===================================================================
--- /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/BBC/BBCBillboardCloudUVMapper.h	(revision 745)
+++ /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/BBC/BBCBillboardCloudUVMapper.h	(revision 751)
@@ -46,5 +46,5 @@
     void generateTextureAtlasTextureCoords(bool mergeBillboards, bool groupedBillboards = false, unsigned int numberGroups = 1);
 
-	void addTextureAtlasTextureCoords(bool mergeBillboards, bool groupedBillboards, unsigned int numGeneratedBillboardClouds, unsigned int iBillboardGroup, unsigned int iBillboard);
+	void addTextureAtlasTextureCoords(bool mergeBillboards, bool groupedBillboards, unsigned int numGeneratedBillboardClouds, unsigned int iBillboardGroup, unsigned int iBillboard, unsigned int iBillboardInGroup);
 
     void setBillboardCloud(BillboardCloud *billboardCloud);
Index: /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/BBC/BBCManager.h
===================================================================
--- /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/BBC/BBCManager.h	(revision 731)
+++ /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/BBC/BBCManager.h	(revision 751)
@@ -3,4 +3,5 @@
 
 #include <BBCPrerequisites.h>
+#include <BBCUtil.h>
 #include <BBCSingleton.h>
 
@@ -31,10 +32,4 @@
 	void shutdown(void);
 
-	Ogre::MeshSerializer* getMeshSerializer(void);
-
-	Ogre::XMLMeshSerializer* getXMLMeshSerializer(void);
-
-  protected:
-
 };
 
Index: /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/BBC/BBCUtil.h
===================================================================
--- /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/BBC/BBCUtil.h	(revision 700)
+++ /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/BBC/BBCUtil.h	(revision 751)
@@ -5,4 +5,36 @@
 
 namespace BBC {
+
+class _BBCExport Util
+{
+public:
+	static Ogre::String getBaseName(Ogre::String fileName)
+	{
+		Ogre::String baseName;
+		size_t pos = fileName.find_last_of(".");
+		baseName = fileName.substr(0, pos);
+		return baseName;
+	}
+
+	static Ogre::String getExtensionName(Ogre::String fileName)
+	{
+		Ogre::String ext;
+		size_t pos = fileName.find_last_of(".");
+		ext = fileName.substr(pos+1);
+		return ext;
+	}
+
+	static unsigned int nextPowerOf2(unsigned int nPlanes)
+	{
+		unsigned int depth = 1;
+		while (depth < nPlanes)
+		{
+			depth = depth << 1;
+		}
+		return depth;
+	}
+
+};
+
 /*
 extern "C" _BBCExport double fround(double n, unsigned d)
@@ -15,16 +47,4 @@
       return (int)floor(x + 0.5);
 }
-
-extern "C" _BBCExport unsigned int getUpperPowerOfTwo(unsigned int powerOfTwo)
-{
-	unsigned int icount = 0;
-	unsigned int depth = 1;
-	while (icount < powerOfTwo)
-	{
-		depth = depth << 1;
-		icount++;
-	}
-	return depth;
-}
 */
 }
Index: /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/IMG/IMGUtil.h
===================================================================
--- /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/IMG/IMGUtil.h	(revision 751)
+++ /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/IMG/IMGUtil.h	(revision 751)
@@ -0,0 +1,52 @@
+#ifndef _IMGUTIL_H
+#define _IMGUTIL_H
+
+#include <IMGPrerequisites.h>
+
+namespace IMG {
+
+class _IMGExport Util
+{
+public:
+	static Ogre::String getBaseName(Ogre::String fileName)
+	{
+		Ogre::String baseName;
+		size_t pos = fileName.find_last_of(".");
+		baseName = fileName.substr(0, pos);
+		return baseName;
+	}
+
+	static Ogre::String getExtensionName(Ogre::String fileName)
+	{
+		Ogre::String ext;
+		size_t pos = fileName.find_last_of(".");
+		ext = fileName.substr(pos+1);
+		return ext;
+	}
+
+	static unsigned int nextPowerOf2(unsigned int nPlanes)
+	{
+		unsigned int depth = 1;
+		while (depth < nPlanes)
+		{
+			depth = depth << 1;
+		}
+		return depth;
+	}
+
+};
+
+/*
+extern "C" _BBCExport double fround(double n, unsigned d)
+{ 
+	return floor(n * pow((double)10.,(int) d) + .5) / pow((double)10.,(int) d);
+}
+
+extern "C" _BBCExport int iround(double x)
+{
+      return (int)floor(x + 0.5);
+}
+*/
+}
+
+#endif
Index: /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/IMG/IMGTexture.h
===================================================================
--- /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/IMG/IMGTexture.h	(revision 745)
+++ /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/IMG/IMGTexture.h	(revision 751)
@@ -55,5 +55,7 @@
 	 void setRenderTargetListener(Ogre::RenderTargetListener *renderTargetListener);
 
-	 virtual void create(Ogre::String fileName, unsigned int width, unsigned int height, Ogre::PixelFormat pixelFormat, Ogre::Camera *camera);
+	 virtual void debug();
+
+	 virtual void create(Ogre::String fileName, unsigned int width, unsigned int height, Ogre::PixelFormat pixelFormat, Ogre::Camera *camera, Ogre::ColourValue backgroundColour);
 
 	 Ogre::ColourValue getAvgColour();
Index: /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/IMG/IMGTextureAtlas.h
===================================================================
--- /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/IMG/IMGTextureAtlas.h	(revision 745)
+++ /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/IMG/IMGTextureAtlas.h	(revision 751)
@@ -3,4 +3,5 @@
 
 #include <IMGPrerequisites.h>
+#include <IMGUtil.h>
 #include <IMGTexture.h>
 
@@ -51,5 +52,5 @@
 	void debug();
 
-	void create(Ogre::String fileName, unsigned int width, unsigned int height, Ogre::PixelFormat pixelFormat, Ogre::Camera *camera);
+	void create(Ogre::String fileName, unsigned int width, unsigned int height, Ogre::PixelFormat pixelFormat, Ogre::Camera *camera, Ogre::ColourValue backgroundColour);
 
 	void update();
Index: /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/scripts/IBRBillboardCloudTreeGenerator.vcproj
===================================================================
--- /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/scripts/IBRBillboardCloudTreeGenerator.vcproj	(revision 745)
+++ /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/scripts/IBRBillboardCloudTreeGenerator.vcproj	(revision 751)
@@ -30,4 +30,5 @@
 				BufferSecurityCheck="TRUE"
 				EnableFunctionLevelLinking="TRUE"
+				DisableLanguageExtensions="FALSE"
 				UsePrecompiledHeader="0"
 				WarningLevel="3"
@@ -83,4 +84,5 @@
 				PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
 				RuntimeLibrary="2"
+				DisableLanguageExtensions="FALSE"
 				UsePrecompiledHeader="0"
 				WarningLevel="3"
Index: /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/scripts/IBRBillboardCloudTreeGeneratorCommandLine.vcproj
===================================================================
--- /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/scripts/IBRBillboardCloudTreeGeneratorCommandLine.vcproj	(revision 731)
+++ /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/scripts/IBRBillboardCloudTreeGeneratorCommandLine.vcproj	(revision 751)
@@ -25,4 +25,5 @@
 				BasicRuntimeChecks="3"
 				RuntimeLibrary="1"
+				DisableLanguageExtensions="FALSE"
 				UsePrecompiledHeader="0"
 				WarningLevel="3"
@@ -73,4 +74,5 @@
 				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
 				RuntimeLibrary="0"
+				DisableLanguageExtensions="FALSE"
 				UsePrecompiledHeader="0"
 				WarningLevel="3"
Index: /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/OBAOgreFrameListener.cpp
===================================================================
--- /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/OBAOgreFrameListener.cpp	(revision 731)
+++ /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/OBAOgreFrameListener.cpp	(revision 751)
@@ -156,6 +156,5 @@
 	mDefaultOgreFrameListenerMode = getFrameListenerMode(iOgreFrameListenerMode);
 	Ogre::Root::getSingleton()._setCurrentSceneManager(mDefaultOgreFrameListenerMode->getSceneManager());
-	mWindow->removeAllViewports();
-	mWindow->addViewport(mDefaultOgreFrameListenerMode->getCamera());
+	mWindow->getViewport(0)->setCamera(mDefaultOgreFrameListenerMode->getCamera());	
 }
 
Index: /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCEntityTextureAtlasViewMode.cpp
===================================================================
--- /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCEntityTextureAtlasViewMode.cpp	(revision 747)
+++ /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCEntityTextureAtlasViewMode.cpp	(revision 751)
@@ -10,5 +10,5 @@
 	mTextureAtlasGenerated = false;
 	mFrame = 0;
-	mDebugOverlay->setScale(0.0, 0.0);
+	showDebugOverlay(false);
 }
 
@@ -49,17 +49,16 @@
 }
 
-unsigned int EntityTextureAtlasViewMode::nextPowerOf2(unsigned int nPlanes)
-{
-	unsigned int depth = 1;
-	while (depth < nPlanes)
-	{
-		depth = depth << 1;
-	}
-	return depth;
-}
-
 bool EntityTextureAtlasViewMode::frameStarted(const Ogre::FrameEvent& evt, Ogre::InputReader *inputReader)
 {
+	mWindow->getViewport(0)->setBackgroundColour(Ogre::ColourValue(1.0, 1.0, 1.0, 1.0));
+
 	if (mFrame == 1)
+	{
+		mTextureAtlas->getTextureAtlasSceneNode()->setVisible(false);
+		mTextureAtlas->update();
+		mTextureAtlas->getTextureAtlasSceneNode()->setVisible(true);
+	}
+	
+	if (mFrame == 2)
 	{
 		if (!mTextureAtlasGenerated)
@@ -93,4 +92,9 @@
 void EntityTextureAtlasViewMode::createScene()
 {
+	IMG::TexturePtr texturePtr ( new IMG::Texture() );
+	texturePtr->bind(mTextureName);
+	Ogre::ColourValue avgColour = texturePtr->getAvgColour();
+	mWindow->getViewport(0)->setBackgroundColour(Ogre::ColourValue(1.0, 1.0, 1.0, 1.0)); 
+
 	mTextureAtlasNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
 	mTextureAtlas = IMG::TextureAtlasPtr( new IMG::TextureAtlas() );
@@ -109,5 +113,5 @@
 	}
 
-	mTextureAtlas->create(mTextureAtlasName, mTextureAtlasSize, mTextureAtlasSize, mSrcPixelFormat, mCamera);
+	mTextureAtlas->create(mTextureAtlasName, mTextureAtlasSize, mTextureAtlasSize, mSrcPixelFormat, mCamera, avgColour);
 	mTextureAtlas->setTextureAtlasSceneNode(mTextureAtlasNode);
 
@@ -116,14 +120,15 @@
 	unsigned int irow = 1;
 	unsigned int icol = 1;
-	unsigned int nrow = Ogre::Math::Sqrt(nextPowerOf2(numSubTextures));
+	unsigned int nrow = Ogre::Math::Sqrt(BBC::Util::nextPowerOf2(numSubTextures));
 	Ogre::Real step = 2.0 / nrow;
 	Ogre::Real degreeStep = 360.0 / numSubTextures;
 	Ogre::Real degree = 0.0;
 
-	IMG::TexturePtr texturePtr ( new IMG::Texture() );
-	texturePtr->bind(mTextureName);
 	Ogre::MaterialPtr materialPtr = Ogre::MaterialManager::getSingleton().create("TextureAtlas" + Ogre::StringConverter::toString(numSubTextures), Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);		
-	materialPtr->getTechnique(0)->getPass(0)->setDiffuse( 1.0, 1.0, 1.0, 0.0);
-	materialPtr->getTechnique(0)->getPass(0)->setAmbient( texturePtr->getAvgColour() );
+	materialPtr->getTechnique(0)->getPass(0)->setAlphaRejectSettings(Ogre::CMPF_GREATER_EQUAL, 10);
+	materialPtr->getTechnique(0)->getPass(0)->createTextureUnitState("transparent.png");
+	materialPtr->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureFiltering(Ogre::FO_NONE, Ogre::FO_NONE, Ogre::FO_NONE);			
+	materialPtr->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);
+	materialPtr->getTechnique(0)->getPass(0)->setLightingEnabled(false);
 	mTextureAtlas->setMaterial(materialPtr.getPointer());	
 	mTextureAtlas->setCorners(-1.0, 1.0, 1.0, -1.0);	
@@ -133,12 +138,12 @@
 		IMG::TexturePtr texturePtr = IMG::TexturePtr( new IMG::Texture() );
 		Ogre::MaterialPtr materialPtr = Ogre::MaterialManager::getSingleton().create("TextureAtlas" + Ogre::StringConverter::toString(iSubTexture), Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);		
-		materialPtr->getTechnique(0)->getPass(0)->setAmbient(maxTexCoords[0], maxTexCoords[1], 1.0 );
-		materialPtr->getTechnique(0)->getPass(0)->setDiffuse( 1.0, 1.0, 1.0, 1.0);
+		materialPtr->getTechnique(0)->getPass(0)->setAmbient(Ogre::Math::RangeRandom(1.0, 0.0), 1.0, 0.0);
+		materialPtr->getTechnique(0)->getPass(0)->setDiffuse(1.0, 1.0, 1.0, 1.0);
+		//materialPtr->getTechnique(0)->getPass(0)->setLightingEnabled(false);
 		materialPtr->getTechnique(0)->getPass(0)->setAlphaRejectSettings(Ogre::CMPF_GREATER_EQUAL, 10);
 		materialPtr->getTechnique(0)->getPass(0)->createTextureUnitState(mTextureName, 0);
 		materialPtr->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureFiltering(Ogre::FO_NONE, Ogre::FO_NONE, Ogre::FO_NONE);
 		materialPtr->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);
-		materialPtr->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureRotate(Ogre::Radian(Ogre::Degree(degree)));
-		materialPtr->getTechnique(0)->getPass(0)->setLightingEnabled(false);
+		materialPtr->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureRotate(Ogre::Radian(Ogre::Degree(degree)));		
 		
 		texturePtr->setMaterial(materialPtr.getPointer());
Index: /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCKMeansClusterGenerator.cpp
===================================================================
--- /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCKMeansClusterGenerator.cpp	(revision 721)
+++ /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCKMeansClusterGenerator.cpp	(revision 751)
@@ -74,97 +74,106 @@
 void KMeansClusterGenerator::recomputeBillboard(BBC::BillboardPtr billboard)
 {
-	Ogre::Matrix3 nmii = Ogre::Matrix3::ZERO;
-	Ogre::Matrix3 nmiiSum = Ogre::Matrix3::ZERO;
-	Ogre::Matrix3 miiSum = Ogre::Matrix3::ZERO;
-	Ogre::Matrix3 mii = Ogre::Matrix3::ZERO;	
-	Ogre::Matrix3 mijSum = Ogre::Matrix3::ZERO;
-	Ogre::Matrix3 mij = Ogre::Matrix3::ZERO; 
-	Ogre::Vector3 lastY = Ogre::Vector3::ZERO;
-	Ogre::Vector3 piSum = Ogre::Vector3::ZERO;
-	Ogre::Vector3 normSum = Ogre::Vector3::ZERO;
-
 	BillboardKMeansClusterData *billboardClusterData = (BillboardKMeansClusterData*)billboard->getBillboardClusterData().get();			
 	BBC::EntityClusterPtr entityCluster = billboardClusterData->getEntityCluster();
 
-	for (unsigned int iLeaf = 0; iLeaf < entityCluster->getNumEntitiesClusterData(); iLeaf++)
-	{
-		Leaf* leaf = (Leaf*)entityCluster->getEntityClusterData(iLeaf)->getEntity().get();
-		Ogre::Vector3 pi = leaf->getPosition();	
-		Ogre::Vector3 norm2 = leaf->getLeafNormal();	
-		piSum = piSum + pi * (1.0 / (float)entityCluster->getNumEntitiesClusterData());
+	if (entityCluster->getNumEntitiesClusterData() > 1)
+	{
+		Ogre::Matrix3 nmii = Ogre::Matrix3::ZERO;
+		Ogre::Matrix3 nmiiSum = Ogre::Matrix3::ZERO;
+		Ogre::Matrix3 miiSum = Ogre::Matrix3::ZERO;
+		Ogre::Matrix3 mii = Ogre::Matrix3::ZERO;	
+		Ogre::Matrix3 mijSum = Ogre::Matrix3::ZERO;
+		Ogre::Matrix3 mij = Ogre::Matrix3::ZERO; 
+		Ogre::Vector3 lastY = Ogre::Vector3::ZERO;
+		Ogre::Vector3 piSum = Ogre::Vector3::ZERO;
+		Ogre::Vector3 normSum = Ogre::Vector3::ZERO;
+
+		for (unsigned int iLeaf = 0; iLeaf < entityCluster->getNumEntitiesClusterData(); iLeaf++)
+		{
+			Leaf* leaf = (Leaf*)entityCluster->getEntityClusterData(iLeaf)->getEntity().get();
+			Ogre::Vector3 pi = leaf->getPosition();	
+			Ogre::Vector3 norm2 = leaf->getLeafNormal();	
+			piSum = piSum + pi * (1.0 / (float)entityCluster->getNumEntitiesClusterData());
+				
+			mii[0][0] = pi.x * pi.x;
+			mii[0][1] = pi.x * pi.y;
+			mii[0][2] = pi.x * pi.z;
+			mii[1][0] = pi.y * pi.x;
+			mii[1][1] = pi.y * pi.y;
+			mii[1][2] = pi.y * pi.z;
+			mii[2][0] = pi.z * pi.x;
+			mii[2][1] = pi.z * pi.y;
+			mii[2][2] = pi.z * pi.z;	
+			nmii[0][0] = norm2.x * norm2.x;
+			nmii[0][1] = norm2.x * norm2.y;
+			nmii[0][2] = norm2.x * norm2.z;
+			nmii[1][0] = norm2.y * norm2.x;
+			nmii[1][1] = norm2.y * norm2.y;
+			nmii[1][2] = norm2.y * norm2.z;
+			nmii[2][0] = norm2.z * norm2.x;
+			nmii[2][1] = norm2.z * norm2.y;
+			nmii[2][2] = norm2.z * norm2.z;	
 			
-		mii[0][0] = pi.x * pi.x;
-		mii[0][1] = pi.x * pi.y;
-		mii[0][2] = pi.x * pi.z;
-		mii[1][0] = pi.y * pi.x;
-		mii[1][1] = pi.y * pi.y;
-		mii[1][2] = pi.y * pi.z;
-		mii[2][0] = pi.z * pi.x;
-		mii[2][1] = pi.z * pi.y;
-		mii[2][2] = pi.z * pi.z;	
-		nmii[0][0] = norm2.x * norm2.x;
-		nmii[0][1] = norm2.x * norm2.y;
-		nmii[0][2] = norm2.x * norm2.z;
-		nmii[1][0] = norm2.y * norm2.x;
-		nmii[1][1] = norm2.y * norm2.y;
-		nmii[1][2] = norm2.y * norm2.z;
-		nmii[2][0] = norm2.z * norm2.x;
-		nmii[2][1] = norm2.z * norm2.y;
-		nmii[2][2] = norm2.z * norm2.z;	
+			nmiiSum = nmiiSum + ( nmii * (1.0 / (float)entityCluster->getNumEntitiesClusterData()));
+
+			miiSum = miiSum + ( mii * (1.0 / (float)entityCluster->getNumEntitiesClusterData()));
+
+			// Generate the initial value for the iterative method as the average...
+			Ogre::Vector3 norm = leaf->getLeafNormal();
+			lastY = lastY + norm;
+
+			// Generate the sum normal of all the leaves associated to the plane...
+			normSum = normSum + norm;
+		}
 		
-		nmiiSum = nmiiSum + ( nmii * (1.0 / (float)entityCluster->getNumEntitiesClusterData()));
-
-		miiSum = miiSum + ( mii * (1.0 / (float)entityCluster->getNumEntitiesClusterData()));
-
-		// Generate the initial value for the iterative method as the average...
-		Ogre::Vector3 norm = leaf->getLeafNormal();
-		lastY = lastY + norm;
-
-		// Generate the sum normal of all the leaves associated to the plane...
-		normSum = normSum + norm;
-	}
-	
-	mijSum[0][0] = piSum.x * piSum.x;
-	mijSum[0][1] = piSum.x * piSum.y;
-	mijSum[0][2] = piSum.x * piSum.z;
-	mijSum[1][0] = piSum.y * piSum.x;
-	mijSum[1][1] = piSum.y * piSum.y;
-	mijSum[1][2] = piSum.y * piSum.z;
-	mijSum[2][0] = piSum.z * piSum.x;
-	mijSum[2][1] = piSum.z * piSum.y;
-	mijSum[2][2] = piSum.z * piSum.z;	
-
-	Ogre::Matrix3 mA = miiSum - mijSum;
-	mA = mA - (mAlpha * nmiiSum);
-	mA = mA.Inverse();
-
-	lastY.normalise();
-	normSum.normalise();
-
-	// Apply the iterative approach
-	Ogre::Vector3 currY;
-	currY = mA * lastY;
-	currY.normalise();
-
-	for(unsigned int icount = 0; icount < 100; icount++)
-	{
-		lastY = currY;
+		mijSum[0][0] = piSum.x * piSum.x;
+		mijSum[0][1] = piSum.x * piSum.y;
+		mijSum[0][2] = piSum.x * piSum.z;
+		mijSum[1][0] = piSum.y * piSum.x;
+		mijSum[1][1] = piSum.y * piSum.y;
+		mijSum[1][2] = piSum.y * piSum.z;
+		mijSum[2][0] = piSum.z * piSum.x;
+		mijSum[2][1] = piSum.z * piSum.y;
+		mijSum[2][2] = piSum.z * piSum.z;	
+
+		Ogre::Matrix3 mA = miiSum - mijSum;
+		mA = mA - (mAlpha * nmiiSum);
+		mA = mA.Inverse();
+
+		lastY.normalise();
+		normSum.normalise();
+
+		// Apply the iterative approach
+		Ogre::Vector3 currY;
 		currY = mA * lastY;
 		currY.normalise();
-	}
-
-	// Generate the d parameter...
-	float sumD = 0;
-	for (unsigned int iLeaf = 0; iLeaf < entityCluster->getNumEntitiesClusterData(); iLeaf++)
-	{
-		Leaf* leaf = (Leaf*)entityCluster->getEntityClusterData(iLeaf)->getEntity().get();
-		Ogre::Vector3 pi = leaf->getPosition();	
-		sumD = sumD + pi.dotProduct(currY);
-	}
-
-	sumD = - sumD / (float)entityCluster->getNumEntitiesClusterData();
-
-	billboardClusterData->setNormal(currY);
-	billboardClusterData->setD(sumD);
+
+		for(unsigned int icount = 0; icount < 100; icount++)
+		{
+			lastY = currY;
+			currY = mA * lastY;
+			currY.normalise();
+		}
+
+		// Generate the d parameter...
+		float sumD = 0;
+		for (unsigned int iLeaf = 0; iLeaf < entityCluster->getNumEntitiesClusterData(); iLeaf++)
+		{
+			Leaf* leaf = (Leaf*)entityCluster->getEntityClusterData(iLeaf)->getEntity().get();
+			Ogre::Vector3 pi = leaf->getPosition();	
+			sumD = sumD + pi.dotProduct(currY);
+		}
+
+		sumD = - sumD / (float)entityCluster->getNumEntitiesClusterData();
+
+		billboardClusterData->setNormal(currY);
+		billboardClusterData->setD(sumD);
+	}
+	else if (entityCluster->getNumEntitiesClusterData() == 1)
+	{
+		Leaf* leaf = (Leaf*)entityCluster->getEntityClusterData(0)->getEntity().get();
+		billboardClusterData->setNormal(leaf->getLeafNormal());
+		billboardClusterData->setD(leaf->getLeafD());
+	}
 }
 
Index: /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/IBRBillboardCloudTreeApplication.cpp
===================================================================
--- /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/IBRBillboardCloudTreeApplication.cpp	(revision 747)
+++ /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/IBRBillboardCloudTreeApplication.cpp	(revision 751)
@@ -59,5 +59,6 @@
 		//mLBBCManager->loadSampleConfigFile(mOpts.cfg);
 		mLBBCManager->initialize();
-		mLBBCManager->loadBillboardCloudMergedXML();
+		//mLBBCManager->loadBillboardCloudMergedXML();
+		mLBBCManager->loadBillboardCloudGroupedXML();
 		this->go();	
 		for (unsigned int iFrameListenerMode = 0; iFrameListenerMode < mFrameListener->getNumFrameListenerModes(); iFrameListenerMode++)
@@ -147,40 +148,4 @@
 
 	{
-		LBBC::BillboardCloudTextureViewMode *anotherFrameListenerMode;
-		anotherFrameListenerMode = new LBBC::BillboardCloudTextureViewMode(mWindow,mFrameListener->getNumFrameListenerModes());
-		anotherFrameListenerMode->chooseSceneManager();
-		anotherFrameListenerMode->createCamera();
-		anotherFrameListenerMode->createViewports();
-		anotherFrameListenerMode->setTextureAtlasSize(mSampleConfigFile->getBillboardCloudDiffuseColorMergedBillboardsTextureAtlasSize());
-		anotherFrameListenerMode->setTextureSize(mSampleConfigFile->getBillboardCloudDiffuseColorMergedBillboardsTextureSize());
-		anotherFrameListenerMode->setTextureAtlasBitRange(mSampleConfigFile->getBillboardCloudDiffuseColorMergedBillboardsTextureAtlasBitRange());
-		anotherFrameListenerMode->setTextureAtlasName(mSampleConfigFile->getBillboardCloudDiffuseColorMergedBillboardsTextureAtlasName());
-		anotherFrameListenerMode->setTextureAtlasFolder(mSampleConfigFile->getBillboardCloudFolder());
-		anotherFrameListenerMode->setEntityName(mSampleConfigFile->getEntityClustersMergedMeshName());
-		anotherFrameListenerMode->createScene();
-		mFrameListener->addFrameListenerMode(anotherFrameListenerMode);
-	}
-
-	{
-		LBBC::ClusterViewMode *anotherFrameListenerMode;
-		anotherFrameListenerMode = new LBBC::ClusterViewMode(mWindow,mFrameListener->getNumFrameListenerModes());
-		anotherFrameListenerMode->chooseSceneManager();
-		anotherFrameListenerMode->createCamera();
-		anotherFrameListenerMode->createViewports();
-		anotherFrameListenerMode->createScene();
-		mFrameListener->addFrameListenerMode(anotherFrameListenerMode);
-	}
-
-	{
-		LBBC::BillboardViewMode *anotherFrameListenerMode;
-		anotherFrameListenerMode = new LBBC::BillboardViewMode(mWindow,mFrameListener->getNumFrameListenerModes());
-		anotherFrameListenerMode->chooseSceneManager();
-		anotherFrameListenerMode->createCamera();
-		anotherFrameListenerMode->createViewports();
-		anotherFrameListenerMode->createScene();
-		mFrameListener->addFrameListenerMode(anotherFrameListenerMode);
-	}
-
-	{
 		LBBC::EntityTextureAtlasViewMode *textureAtlasFrameListenerMode;
 		textureAtlasFrameListenerMode = new LBBC::EntityTextureAtlasViewMode(mWindow,mFrameListener->getNumFrameListenerModes());
@@ -199,4 +164,46 @@
 	}
 
+	{
+		LBBC::BillboardCloudTextureViewMode *anotherFrameListenerMode;
+		anotherFrameListenerMode = new LBBC::BillboardCloudTextureViewMode(mWindow,mFrameListener->getNumFrameListenerModes());
+		anotherFrameListenerMode->chooseSceneManager();
+		anotherFrameListenerMode->createCamera();
+		anotherFrameListenerMode->createViewports();
+		anotherFrameListenerMode->setTextureAtlasSize(mSampleConfigFile->getBillboardCloudDiffuseColorGroupedBillboardsTextureAtlasSize());
+		anotherFrameListenerMode->setTextureSize(mSampleConfigFile->getBillboardCloudDiffuseColorGroupedBillboardsTextureSize());
+		anotherFrameListenerMode->setTextureAtlasBitRange(mSampleConfigFile->getBillboardCloudDiffuseColorGroupedBillboardsTextureAtlasBitRange());
+		anotherFrameListenerMode->setTextureAtlasName(mSampleConfigFile->getBillboardCloudDiffuseColorGroupedBillboardsTextureAtlasName());
+		anotherFrameListenerMode->setTextureName(mSampleConfigFile->getBillboardCloudDiffuseColorEntityTextureName());
+		anotherFrameListenerMode->setTextureAtlasFolder(mSampleConfigFile->getBillboardCloudFolder());
+		anotherFrameListenerMode->setEntityClustersGroupedName(mSampleConfigFile->getEntityClustersGroupedMeshName());
+		//anotherFrameListenerMode->setBillboardCloudSplittedName(mSampleConfigFile->getBillboardCloudSplittedMeshName());
+		anotherFrameListenerMode->setBillboardCloudSplittedName(mSampleConfigFile->getBillboardCloudIndirectPointMeshName());
+		anotherFrameListenerMode->setBillboardCloudGroupedTextureAtlasDebug(mSampleConfigFile->getBillboardCloudDiffuseColorGroupedBillboardsTextureAtlasDebug());
+		anotherFrameListenerMode->createScene();
+		mFrameListener->addFrameListenerMode(anotherFrameListenerMode);
+	}
+
+	{
+		LBBC::BillboardViewMode *anotherFrameListenerMode;
+		anotherFrameListenerMode = new LBBC::BillboardViewMode(mWindow,mFrameListener->getNumFrameListenerModes());
+		anotherFrameListenerMode->chooseSceneManager();
+		anotherFrameListenerMode->createCamera();
+		anotherFrameListenerMode->createViewports();
+		//anotherFrameListenerMode->setBillboardCloudMeshName(mSampleConfigFile->getBillboardCloudGroupedMeshName());
+		anotherFrameListenerMode->createScene();
+		mFrameListener->addFrameListenerMode(anotherFrameListenerMode);
+	}
+
+	{
+		LBBC::ClusterViewMode *anotherFrameListenerMode;
+		anotherFrameListenerMode = new LBBC::ClusterViewMode(mWindow,mFrameListener->getNumFrameListenerModes());
+		anotherFrameListenerMode->chooseSceneManager();
+		anotherFrameListenerMode->createCamera();
+		anotherFrameListenerMode->createViewports();
+		//anotherFrameListenerMode->setEntityClustersMeshName(mSampleConfigFile->getEntityClustersGroupedMeshName());
+		anotherFrameListenerMode->createScene();
+		mFrameListener->addFrameListenerMode(anotherFrameListenerMode);
+	}
+
 	mFrameListener->removeFrameListenerMode(0);
 	mFrameListener->setEnabledFrameListenerMode(0);
Index: /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCBillboardCloudTextureViewMode.cpp
===================================================================
--- /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCBillboardCloudTextureViewMode.cpp	(revision 747)
+++ /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCBillboardCloudTextureViewMode.cpp	(revision 751)
@@ -10,5 +10,9 @@
 {	
 	mFrame = 0;
-	mDebugOverlay->setScale(0.0, 0.0);
+	mCurrentBillboardGroup = 0;
+	mCurrentBillboard = 0;
+	showDebugOverlay(false);
+	mDebugBillboardGeneration = false;
+	mDebugTextureAtlasGeneration = false;
 }
 
@@ -18,72 +22,263 @@
 }
 
+
+void BillboardCloudTextureViewMode::setBillboardCloudGroupedTextureAtlasDebug(bool debugTextureAtlasGeneration)
+{
+	mDebugTextureAtlasGeneration = debugTextureAtlasGeneration;
+}
+
+void BillboardCloudTextureViewMode::configureBillboardOrthogonalAlignedCamera(unsigned int iBillboard)
+{
+	BBC::BillboardPtr billboardPtr = ((LBBC::LBBCManager*)LBBC::LBBCManager::getSingletonPtr())->getLeaves()->getBillboardCloud()->getBillboard(iBillboard);
+	Ogre::Vector3 vTopLeft = billboardPtr->getBillboardClusterData()->getQuadTopLeftCorner();
+	Ogre::Vector3 vTopRight = billboardPtr->getBillboardClusterData()->getQuadTopRightCorner();
+	Ogre::Vector3 vBottomLeft = billboardPtr->getBillboardClusterData()->getQuadBottomLeftCorner();
+	Ogre::Vector3 vBottomRight = billboardPtr->getBillboardClusterData()->getQuadBottomRightCorner();
+
+	Ogre::Vector3 vMidPoint = vTopLeft.midPoint(vBottomRight);
+	Ogre::Vector3 vWidth(vTopRight - vTopLeft);
+	Ogre::Vector3 vHeight(vBottomLeft - vTopLeft);
+
+	Ogre::Real w = vWidth.length();
+	Ogre::Real h = vHeight.length();
+	Ogre::Real aspect = w / h;
+	Ogre::Radian fovy = Ogre::Radian(Ogre::Degree(90.0));
+	Ogre::Real nearPlane =	h / Ogre::Math::Tan(fovy/2.0,false);
+	Ogre::Real farPlane = 100000;
+
+	Ogre::Vector3 vUp = vTopLeft - vBottomLeft;
+	vUp.normalise();
+
+	Ogre::Vector3 vI(vTopRight-vTopLeft);
+	vI.normalise();
+
+	Ogre::Vector3 vJ(vBottomLeft-vTopLeft);
+	vJ.normalise();
+
+	Ogre::Vector3 vDir = -vI.crossProduct(vJ);
+	vDir.normalise();
+
+	Ogre::Vector3 vRight = vDir.crossProduct(vUp);
+	vRight.normalise();	
+
+	Ogre::Quaternion qOrientation(vRight, vUp, -vDir);
+	
+	mCamera->setNearClipDistance(nearPlane);
+	mCamera->setOrientation(qOrientation);
+	mCamera->setPosition(vMidPoint - (vDir * (nearPlane*nearPlane)));
+
+	Ogre::Radian thetaY (fovy / 2.0f);
+	Ogre::Real tanThetaY = Ogre::Math::Tan(thetaY);
+
+	Ogre::Real tanThetaX = tanThetaY * aspect;
+
+	Ogre::Real half_w,half_h;
+	half_w = w / 2.0;
+	half_h = h / 2.0;
+
+	Ogre::Real iw = 1.0 / half_w;
+	Ogre::Real ih = 1.0 / half_h;
+	Ogre::Real q;
+	if (farPlane == 0)
+	{
+		q = 0;
+	}
+	else
+	{
+		q = 2.0 / (farPlane - nearPlane);
+	}
+	mCustomProjMatrix = Ogre::Matrix4::ZERO;
+	mCustomProjMatrix[0][0] = iw;
+	mCustomProjMatrix[1][1] = ih;
+	mCustomProjMatrix[2][2] = -q;
+	mCustomProjMatrix[2][3] = - (farPlane + nearPlane)/(farPlane - nearPlane);
+	mCustomProjMatrix[3][3] = 1;	
+}
+
+void BillboardCloudTextureViewMode::saveTextureAtlas()
+{
+	if (mBitRange == 32)
+	{
+		mDestPixelFormat = Ogre::PF_FLOAT32_RGBA;
+	}
+	else if (mBitRange == 16)
+	{
+		mDestPixelFormat = Ogre::PF_FLOAT16_RGBA;
+	}
+	else  // mBitRange == 8
+	{
+		mDestPixelFormat = Ogre::PF_BYTE_RGBA;
+	}
+
+	Ogre::String textureAtlasFileName = BBC::Util::getBaseName(mTextureAtlasName) + Ogre::StringConverter::toString(mCurrentBillboardGroup) + "." + BBC::Util::getExtensionName(mTextureAtlasName);
+	mTextureAtlas->save(mTextureAtlasFolder, textureAtlasFileName, mDestPixelFormat);
+}
+
+void BillboardCloudTextureViewMode::disableEntityClusterCustomOrthogonalCameraMaterial(unsigned int iEntityClusterGrouped)
+{
+	mEntityClustersGrouped->getSubEntity(iEntityClusterGrouped)->getMaterial()->getTechnique(0)->getPass(0)->setVertexProgram("");
+	mEntityClustersGrouped->getSubEntity(iEntityClusterGrouped)->getMaterial()->getTechnique(0)->getPass(0)->setFragmentProgram("");
+	mEntityClustersGrouped->getSubEntity(iEntityClusterGrouped)->getMaterial()->reload();
+}
+
+void BillboardCloudTextureViewMode::enableEntityClusterCustomOrthogonalCameraMaterial(unsigned int iEntityClusterGrouped)
+{
+	mEntityClustersGrouped->getSubEntity(iEntityClusterGrouped)->getMaterial()->getTechnique(0)->getPass(0)->setVertexProgram("diffuseTextureVP");
+	mEntityClustersGrouped->getSubEntity(iEntityClusterGrouped)->getMaterial()->getTechnique(0)->getPass(0)->setFragmentProgram("diffuseTextureFP");
+
+	Ogre::GpuProgramParametersSharedPtr vertParams;
+	Ogre::GpuProgramParametersSharedPtr fragParams;
+	vertParams = mEntityClustersGrouped->getSubEntity(iEntityClusterGrouped)->getMaterial()->getTechnique(0)->getPass(0)->getVertexProgramParameters();
+	fragParams = mEntityClustersGrouped->getSubEntity(iEntityClusterGrouped)->getMaterial()->getTechnique(0)->getPass(0)->getFragmentProgramParameters();
+
+	vertParams->setNamedConstant("projectionmatrix", mCamera->getProjectionMatrixWithRSDepth());
+	vertParams->setNamedAutoConstant("worldmatrix", Ogre::GpuProgramParameters::ACT_WORLD_MATRIX);
+	vertParams->setNamedAutoConstant("viewmatrix", Ogre::GpuProgramParameters::ACT_VIEW_MATRIX);
+	mEntityClustersGrouped->getSubEntity(iEntityClusterGrouped)->getMaterial()->reload();
+}
+
+void BillboardCloudTextureViewMode::configureTexture()
+{
+	mTextureAtlas->getRectangle2D()->setVisible(false);
+	mEntityClustersGrouped->getSubEntity((mCurrentTexture-1) % mEntityClustersGrouped->getNumSubEntities())->setVisible(false);
+	mEntityClustersGrouped->getSubEntity(mCurrentTexture % mEntityClustersGrouped->getNumSubEntities())->setVisible(true);
+
+	configureBillboardOrthogonalAlignedCamera(mCurrentTexture % mBillboardCloudSplitted->getNumSubEntities());
+	mCamera->setCustomProjectionMatrix(true,mCustomProjMatrix);
+
+	if (mDebugTextureAtlasGeneration)
+	{
+		mClusterTexture->getMaterial()->getTechnique(0)->getPass(0)->setAmbient(Ogre::Math::RangeRandom(0.0,1.0), Ogre::Math::RangeRandom(0.0,1.0), Ogre::Math::RangeRandom(0.0,1.0));
+		mClusterTexture->getMaterial()->getTechnique(0)->getPass(0)->setDiffuse(Ogre::Math::RangeRandom(0.0,1.0), Ogre::Math::RangeRandom(0.0,1.0), Ogre::Math::RangeRandom(0.0,1.0), 1.0);
+	}
+}
+
+void BillboardCloudTextureViewMode::generateTexture()
+{
+	configureTexture();
+
+	enableEntityClusterCustomOrthogonalCameraMaterial(mCurrentTexture % mEntityClustersGrouped->getNumSubEntities());
+	
+	mClusterTexture->update();		
+
+	disableEntityClusterCustomOrthogonalCameraMaterial(mCurrentTexture % mEntityClustersGrouped->getNumSubEntities());
+}
+
+void BillboardCloudTextureViewMode::initializeEntityClustersGrouped()
+{
+	if (mFrame == 1)
+	{
+		for (unsigned int iSubEntity = 0; iSubEntity < mEntityClustersGrouped->getNumSubEntities(); iSubEntity++)
+		{
+			mEntityClustersGrouped->getSubEntity(iSubEntity)->setVisible(false);
+		}
+	}
+}
+
+void BillboardCloudTextureViewMode::initializeBillboardCloudSplitted()
+{
+	if (mFrame == 1)
+	{
+		for (unsigned int iSubEntity = 0; iSubEntity < mBillboardCloudSplitted->getNumSubEntities(); iSubEntity++)
+		{
+			mBillboardCloudSplitted->getSubEntity(iSubEntity)->setVisible(false);
+		}
+	}
+}
+
+bool BillboardCloudTextureViewMode::processUnbufferedKeyInput(const Ogre::FrameEvent& evt)
+{
+	if (mInputDevice->isKeyDown(Ogre::KC_SPACE))
+    {
+        mCurrentTexture++;
+    }
+
+	return OgreFrameListenerMode::processUnbufferedKeyInput(evt);
+}
+
+void BillboardCloudTextureViewMode::configureTextureAtlas()
+{
+	mEntityClustersGrouped->getSubEntity(mCurrentTexture % mEntityClustersGrouped->getNumSubEntities())->setVisible(false);
+
+	mClusterTexture->getRectangle2D()->setVisible(true);
+	mTextureAtlas->getRectangle2D()->setVisible(true);
+
+ 	Ogre::Vector2 uvMapMax = ((LBBC::LBBCManager*)LBBC::LBBCManager::getSingletonPtr())->getLeaves()->getBillboardCloud()->getBillboard(mCurrentTexture % mEntityClustersGrouped->getNumSubEntities())->getBillboardClusterData()->getBillboardUVMapMax(0);
+	Ogre::Vector2 uvMapMin = ((LBBC::LBBCManager*)LBBC::LBBCManager::getSingletonPtr())->getLeaves()->getBillboardCloud()->getBillboard(mCurrentTexture % mEntityClustersGrouped->getNumSubEntities())->getBillboardClusterData()->getBillboardUVMapMin(0);
+
+	mClusterTexture->setCorners(uvMapMin[0], uvMapMax[1], uvMapMax[0], uvMapMin[1]);
+}
+
+void BillboardCloudTextureViewMode::generateTextureAtlas()
+{	
+	configureTextureAtlas();
+
+	mTextureAtlas->update();		
+	//mTextureAtlas->debug();
+	
+	mClusterTexture->getRectangle2D()->setVisible(false);
+}
+
 bool BillboardCloudTextureViewMode::frameStarted(const Ogre::FrameEvent& evt, Ogre::InputReader *inputReader)
 {
-	if (mFrame == 1)
-	{
-		for (unsigned int iSubEntity = 0; iSubEntity < mClusterizedEntities->getNumSubEntities(); iSubEntity++)
+	initializeEntityClustersGrouped();
+    initializeBillboardCloudSplitted();
+
+	if (mFrame > 1)
+	{		
+		if (!mDebugBillboardGeneration)
 		{
-			mClusterizedEntities->getSubEntity(iSubEntity)->setVisible(false);
+			mWindow->getViewport(0)->setBackgroundColour(Ogre::ColourValue(1.0, 1.0, 1.0, 1.0));
+
+			if (mCurrentTexture < mNumTextures)
+			{
+				generateTexture();
+
+				generateTextureAtlas();
+
+				mCurrentTexture++;
+				mCurrentBillboard++;
+
+				unsigned int numBillboardsCurrentGroups = ((LBBC::LBBCManager*)LBBC::LBBCManager::getSingletonPtr())->getLeaves()->getBillboardCloud()->getBillboardGroup(mCurrentBillboardGroup)->getNumBillboards();
+
+				if (mCurrentBillboard == numBillboardsCurrentGroups)
+				{
+					saveTextureAtlas();
+					
+					unsigned int numBillboardGroups = ((LBBC::LBBCManager*)LBBC::LBBCManager::getSingletonPtr())->getLeaves()->getBillboardCloud()->getNumBillboardGroups();
+
+					if (mCurrentBillboardGroup < numBillboardGroups)
+					{
+						mCurrentBillboard = 0;
+						mCurrentBillboardGroup++;						
+
+						mTextureAtlas->getRectangle2D()->setVisible(false);
+						mTextureAtlas->update();
+						//mTextureAtlas->debug();
+					}
+				}
+			}
+
+			if (mCurrentTexture == mNumTextures)
+			{				
+				mDebugBillboardGeneration = true;
+
+				mWindow->getViewport(0)->setBackgroundColour(Ogre::ColourValue(0.0, 0.0, 0.0, 1.0)); 
+
+				mTextureAtlas->getRectangle2D()->setVisible(false);
+
+				mCurrentTexture = 0;
+			}
 		}
-	}
-	
-	if (mFrame > 1)
-	{
-		mClusterizedEntities->getSubEntity((mCurrentTexture-1) % mClusterizedEntities->getNumSubEntities())->setVisible(false);
-	}
-
-	if (mFrame == 1)
-	{
-		mTextureAtlas->update();
-	}
-
-	if (mFrame > 1)
-	{
-		mClusterizedEntities->getSubEntity(mCurrentTexture % mClusterizedEntities->getNumSubEntities())->setVisible(true);
-		mClusterTextureListener.setSubEntityVisible(mCurrentTexture% mClusterizedEntities->getNumSubEntities());
-		mClusterTexture->update();
-
-		//if (mCurrentTexture <= mNumTextures)
+		else
 		{
-			mClusterizedEntities->getSubEntity(mCurrentTexture)->setVisible(false);
-			mClusterTexture->getMaterial()->getTechnique(0)->getPass(0)->setAmbient( Ogre::Math::RangeRandom(0.0,1.0), Ogre::Math::RangeRandom(0.0,1.0), Ogre::Math::RangeRandom(0.0,1.0) );
-			mClusterTexture->getRectangle2D()->setVisible(true);
-			mTextureAtlas->getRectangle2D()->setVisible(true);
- 			Ogre::Vector2 uvMapMax = ((LBBC::LBBCManager*)LBBC::LBBCManager::getSingletonPtr())->getLeaves()->getBillboardCloud()->getBillboard(mCurrentTexture)->getBillboardClusterData()->getBillboardUVMapMax(0);
-			Ogre::Vector2 uvMapMin = ((LBBC::LBBCManager*)LBBC::LBBCManager::getSingletonPtr())->getLeaves()->getBillboardCloud()->getBillboard(mCurrentTexture)->getBillboardClusterData()->getBillboardUVMapMin(0);
-			mClusterTexture->setCorners(uvMapMin[0], uvMapMax[1], uvMapMax[0], uvMapMin[1]);
-			mClusterTexture->getMaterial()->getTechnique(0)->getPass(0)->setAmbient(uvMapMax[0], uvMapMax[1], 0.0);
-			mTextureAtlas->update();		
-			//mTextureAtlas->debug();
-			mClusterTexture->getRectangle2D()->setVisible(false);
-			
-			Ogre::LogManager::getSingleton().logMessage("Billboard(" + Ogre::StringConverter::toString(mCurrentTexture) + ") uvMapMin(" + Ogre::StringConverter::toString(uvMapMin[0]) + "," +
-				Ogre::StringConverter::toString(uvMapMin[1]) + ") uvMapMax(" + Ogre::StringConverter::toString(uvMapMax[0]) + "," +
-				Ogre::StringConverter::toString(uvMapMax[1]) + ")");
-			Ogre::LogManager::getSingleton().logMessage(
-				"USize(" + Ogre::StringConverter::toString(Ogre::Math::Abs(uvMapMax[0]-uvMapMin[0])) +
-				"," + Ogre::StringConverter::toString(Ogre::Math::Abs(uvMapMax[1]-uvMapMin[1])) + ")");
-
-			mCurrentTexture++;
-
-			if (mCurrentTexture == mNumTextures)
-			{
-				if (mBitRange == 32)
-				{
-					mDestPixelFormat = Ogre::PF_FLOAT32_RGBA;
-				}
-				else if (mBitRange == 16)
-				{
-					mDestPixelFormat = Ogre::PF_FLOAT16_RGBA;
-				}
-				else  // mBitRange == 8
-				{
-					mDestPixelFormat = Ogre::PF_BYTE_RGBA;
-				}
-				mTextureAtlas->save(mTextureAtlasFolder, mTextureAtlasName, mDestPixelFormat);
-			}
+			mWindow->getViewport(0)->setBackgroundColour(Ogre::ColourValue(0.0, 0.0, 0.0, 1.0)); 
+
+			configureBillboard();
+
+			configureTexture();
 
 			mCurrentTexture = mCurrentTexture % mNumTextures;
-		}		
+		}
 	}
 
@@ -93,4 +288,10 @@
 }
 
+void BillboardCloudTextureViewMode::configureBillboard()
+{
+	mBillboardCloudSplitted->getSubEntity((mCurrentTexture-1) % mEntityClustersGrouped->getNumSubEntities())->setVisible(false);
+	mBillboardCloudSplitted->getSubEntity(mCurrentTexture % mEntityClustersGrouped->getNumSubEntities())->setVisible(true);
+}
+
 void BillboardCloudTextureViewMode::setTextureAtlasSize(unsigned int size)
 {
@@ -98,7 +299,12 @@
 }
 
-void BillboardCloudTextureViewMode::setEntityName(Ogre::String entityName)
-{
-	mEntityName = entityName;
+void BillboardCloudTextureViewMode::setEntityClustersGroupedName(Ogre::String entityClustersGroupedName)
+{
+	mEntityClustersGroupedName = entityClustersGroupedName;
+}
+
+void BillboardCloudTextureViewMode::setBillboardCloudSplittedName(Ogre::String billboardCloudSplittedName)
+{
+	mBillboardCloudSplittedName = billboardCloudSplittedName;
 }
 
@@ -123,4 +329,9 @@
 }
 
+void BillboardCloudTextureViewMode::setTextureName(Ogre::String textureName)
+{
+	mTextureName = textureName;
+}
+
 void BillboardCloudTextureViewMode::createScene()
 {
@@ -139,50 +350,56 @@
 
 	LBBC::Leaves *mLeaves = ((LBBC::LBBCManager*)LBBC::LBBCManager::getSingletonPtr())->getLeaves();
-	Ogre::LogManager::getSingleton().logMessage("Num.Billboards:" + Ogre::StringConverter::toString(mLeaves->getBillboardCloud()->getNumBillboards()));
-	Ogre::LogManager::getSingleton().logMessage("Num.BillboardGroups:" + Ogre::StringConverter::toString(mLeaves->getBillboardCloud()->getNumBillboardGroups()));
 	Ogre::Vector2 uvMapMax = mLeaves->getBillboardCloud()->getBillboard(0)->getBillboardClusterData()->getBillboardUVMapMax(0);
 	Ogre::Vector2 uvMapMin = mLeaves->getBillboardCloud()->getBillboard(0)->getBillboardClusterData()->getBillboardUVMapMin(0);
-	Ogre::LogManager::getSingleton().logMessage("BillboardUVMapMax:" + Ogre::StringConverter::toString( Ogre::Vector3(uvMapMax[0], uvMapMax[1], 0.0) ));
-	Ogre::LogManager::getSingleton().logMessage("BillboardUVMapMin:" + Ogre::StringConverter::toString( Ogre::Vector3(uvMapMin[0], uvMapMin[1], 0.0) ));
-
-	mClusterizedEntitiesMergedSceneNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
-	Ogre::LogManager::getSingleton().logMessage("Mesh:" + mEntityName);
-	std::cin.get();
-
-	mClusterizedEntities = mSceneMgr->createEntity(mEntityName, mEntityName);
-	//mClusterizedEntities = mSceneMgr->createEntity("mapleLeavesClusterizedEntitiesMerged.mesh", "mapleLeavesClusterizedEntitiesMerged.mesh");
-    mClusterizedEntitiesMergedSceneNode->attachObject(mClusterizedEntities);
+
+	IMG::TexturePtr texturePtr ( new IMG::Texture() );
+	texturePtr->bind(mTextureName);
+	Ogre::ColourValue avgColour = texturePtr->getAvgColour();
+	mWindow->getViewport(0)->setBackgroundColour(Ogre::ColourValue(1.0, 1.0, 1.0, 1.0)); 
+
+	mEntityClustersGroupedSceneNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
+	mBillboardCloudSplittedSceneNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
+
+	mEntityClustersGrouped = mSceneMgr->createEntity(mEntityClustersGroupedName, mEntityClustersGroupedName);
+    mEntityClustersGroupedSceneNode->attachObject(mEntityClustersGrouped);
+
+	mBillboardCloudSplitted = mSceneMgr->createEntity(mBillboardCloudSplittedName, mBillboardCloudSplittedName);
+    mBillboardCloudSplittedSceneNode->attachObject(mBillboardCloudSplitted);
 
 	mTextureAtlas = IMG::TextureAtlasPtr( new IMG::TextureAtlas() );
-	mTextureAtlas->create("TextureAtlas", mTextureAtlasSize, mTextureAtlasSize, mSrcPixelFormat, mCamera);
+	mTextureAtlas->create("TextureAtlas", mTextureAtlasSize, mTextureAtlasSize, mSrcPixelFormat, mCamera, avgColour);
 	mTextureAtlas->setRenderTargetListener(&mTextureAtlasListener);
-	mTextureAtlas->setTextureAtlasSceneNode(mClusterizedEntitiesMergedSceneNode);
+	mTextureAtlas->setTextureAtlasSceneNode(mEntityClustersGroupedSceneNode);
 	Ogre::MaterialPtr materialPtr1 = Ogre::MaterialManager::getSingleton().create("textureAtlasMaterial", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);		
-	materialPtr1->getTechnique(0)->getPass(0)->setDiffuse( 1.0, 1.0, 1.0, 1.0);
 	materialPtr1->getTechnique(0)->getPass(0)->setAlphaRejectSettings(Ogre::CMPF_GREATER_EQUAL, 10);
 	materialPtr1->getTechnique(0)->getPass(0)->createTextureUnitState("transparent.png");
 	materialPtr1->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureFiltering(Ogre::FO_NONE, Ogre::FO_NONE, Ogre::FO_NONE);			
 	materialPtr1->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);
+	materialPtr1->getTechnique(0)->getPass(0)->setLightingEnabled(false);
 	mTextureAtlas->setMaterial(materialPtr1.getPointer());
 	mTextureAtlas->setCorners(-1.0, 1.0, 1.0, -1.0);	
 
 	mClusterTexture = IMG::TexturePtr( new IMG::Texture() );
-	mClusterTexture->create("clusterTexture", mTextureSize, mTextureSize, mSrcPixelFormat, mCamera);
+	mClusterTexture->create("clusterTexture", mTextureSize, mTextureSize, mSrcPixelFormat, mCamera, avgColour);
 	mClusterTexture->setRenderTargetListener(&mClusterTextureListener);
-	Ogre::MaterialPtr materialPtr = Ogre::MaterialManager::getSingleton().create("textureMaterial", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);		
-	materialPtr->getTechnique(0)->getPass(0)->setAmbient( 1.0, Ogre::Math::RangeRandom(0.5,1.0), 1.0 );
-	materialPtr->getTechnique(0)->getPass(0)->setDiffuse( 1.0, 1.0, 1.0, 1.0 );
-	//materialPtr->getTechnique(0)->getPass(0)->setAlphaRejectSettings(Ogre::CMPF_GREATER_EQUAL, 10);
-	//materialPtr->getTechnique(0)->getPass(0)->createTextureUnitState("clusterTexture", 0);
+	Ogre::MaterialPtr materialPtr = Ogre::MaterialManager::getSingleton().create("textureMaterial", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);			
+	if (!mDebugTextureAtlasGeneration)
+	{
+		materialPtr->getTechnique(0)->getPass(0)->setAlphaRejectSettings(Ogre::CMPF_GREATER_EQUAL, 10);
+		materialPtr->getTechnique(0)->getPass(0)->createTextureUnitState("clusterTexture", 0);
+		materialPtr->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureFiltering(Ogre::FO_NONE, Ogre::FO_NONE, Ogre::FO_NONE);			
+		materialPtr->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);		
+		materialPtr->getTechnique(0)->getPass(0)->setLightingEnabled(false);
+	}
 	mClusterTexture->setMaterial(materialPtr.getPointer());
 
 	mTextureAtlas->addTexture(mClusterTexture);
 	
-	mClusterTextureListener.setNumTextures(mClusterizedEntities->getNumSubEntities());
+	mClusterTextureListener.setNumTextures(mEntityClustersGrouped->getNumSubEntities());
 	mClusterTextureListener.setTextureAtlas(mTextureAtlas);
 	mClusterTextureListener.setTexture(mClusterTexture);
-	mClusterTextureListener.setEntity(mClusterizedEntities);
-
-	mNumTextures = mClusterizedEntities->getNumSubEntities();
+	mClusterTextureListener.setEntityClusters(mEntityClustersGrouped);
+
+	mNumTextures = mEntityClustersGrouped->getNumSubEntities();
 	mCurrentTexture = 0;
 }
Index: /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/IMGTexture.cpp
===================================================================
--- /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/IMGTexture.cpp	(revision 745)
+++ /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/IMGTexture.cpp	(revision 751)
@@ -29,4 +29,33 @@
 	//	delete mMaterial;
 	//}
+}
+
+void Texture::debug()
+{
+	unsigned char* pBufferBox = new unsigned char[mTexture->getBuffer(0, 0)->getSizeInBytes()];
+
+    // Read pixels	
+	Ogre::PixelBox pBox(mWidth, mHeight, 1, mPixelFormat, pBufferBox);
+
+	mTexture->getBuffer(0, 0)->blitToMemory(pBox);
+
+	if (mPixelFormat == Ogre::PF_FLOAT32_RGBA)
+	{
+		imdebug("rgba w=%d h=%d %p b=32f",pBox.getWidth(), pBox.getHeight(), pBox.data);
+	}
+
+	if (mPixelFormat == Ogre::PF_A8R8G8B8)
+	{
+		//unsigned char* pBufferDest = new unsigned char[pBox.getWidth()*pBox.getHeight()*4];	
+		unsigned char* pBufferDest = new unsigned char[pBox.getWidth()*pBox.getHeight()*4];	
+		Ogre::PixelBox pDest(mWidth, mHeight, 1, Ogre::PF_BYTE_RGBA, pBufferDest);
+		Ogre::PixelUtil::bulkPixelConversion(pBox.data, mPixelFormat, pDest.data, Ogre::PF_BYTE_RGBA, pBox.getWidth()*pBox.getHeight());
+		
+		imdebug("rgba w=%d h=%d %p ", pDest.getWidth(), pDest.getHeight(), pDest.data);
+		
+		delete [] pBufferDest;
+	}
+
+	delete [] pBufferBox;
 }
 
@@ -191,5 +220,5 @@
 }
 
-void Texture::create(Ogre::String fileName, unsigned int width, unsigned int height, Ogre::PixelFormat pixelFormat, Ogre::Camera *camera)
+void Texture::create(Ogre::String fileName, unsigned int width, unsigned int height, Ogre::PixelFormat pixelFormat, Ogre::Camera *camera, Ogre::ColourValue backgroundColour)
 {
 	mCamera = camera;
@@ -203,5 +232,5 @@
 	Ogre::Viewport *v = rt->addViewport(mCamera);
 	v->setClearEveryFrame(true);
-	v->setBackgroundColour(Ogre::ColourValue(1.0f, 1.0f, 1.0f, 0.0f));
+	v->setBackgroundColour(backgroundColour);
 	v->setOverlaysEnabled(false);
 	v->setDimensions(0,0,1.0,1.0);	
Index: /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCLeafDistributionGenerator.cpp
===================================================================
--- /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCLeafDistributionGenerator.cpp	(revision 721)
+++ /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCLeafDistributionGenerator.cpp	(revision 751)
@@ -186,5 +186,5 @@
 	{
 		Leaf *leaf = (Leaf*) mEntityDistribution->getEntity(ileaf).get();
-		leaf->setPosition(leaf->getSubEntity(0)->getUniqueVertex(0).position);
+		generateAverageLeafPosition(leaf);
         generateAverageLeafNormal(leaf);
 		leaf->setLeafD(-leaf->getLeafNormal().dotProduct(leaf->getPosition()));
@@ -283,3 +283,15 @@
 }
 
-}
+void LeafDistributionGenerator::generateAverageLeafPosition(Leaf *leaf)
+{
+	Ogre::Vector3 aVPosition(0,0,0);
+	for (unsigned int iN = 0; iN < leaf->getSubEntity(0)->getNumVertices(); iN++)
+	{
+		aVPosition = aVPosition + leaf->getSubEntity(0)->getPosition(iN);
+	}
+	aVPosition = aVPosition / leaf->getSubEntity(0)->getNumVertices();
+
+	leaf->setPosition(aVPosition);
+}
+
+}
Index: /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/OBAOgreFrameListenerMode.cpp
===================================================================
--- /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/OBAOgreFrameListenerMode.cpp	(revision 721)
+++ /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/OBAOgreFrameListenerMode.cpp	(revision 751)
@@ -381,8 +381,8 @@
 
     // Position it at 500 in Z direction
-    mCamera->setPosition(Ogre::Vector3(0,0,500));
+    mCamera->setPosition(Ogre::Vector3(0.0, 0.0, 500.0));
     // Look back along -Z
-    mCamera->lookAt(Ogre::Vector3(0,0,-300));
-    mCamera->setNearClipDistance(5);
+    mCamera->lookAt(Ogre::Vector3(0.0, 0.0, -300.0));
+    mCamera->setNearClipDistance(5.0);
 }
 
@@ -390,10 +390,17 @@
 {
     // Create one viewport, entire window
-	Ogre::Viewport* vp = mWindow->addViewport(mCamera,mOgreFrameListenerModeHandle);
-    vp->setBackgroundColour(Ogre::ColourValue(0,0,0));
-
-    // Alter the camera aspect ratio to match the viewport
-    mCamera->setAspectRatio(
-        Ogre::Real(vp->getActualWidth()) / Ogre::Real(vp->getActualHeight()));
+	if (mWindow->getNumViewports() == 0)
+	{
+		Ogre::Viewport* vp = mWindow->addViewport(mCamera,mOgreFrameListenerModeHandle);
+		vp->setBackgroundColour(Ogre::ColourValue(0.0, 0.0, 0.0));
+	}
+	// Alter the camera aspect ratio to match the viewport
+	mCamera->setAspectRatio(
+		Ogre::Real(mWindow->getViewport(0)->getActualWidth()) / Ogre::Real(mWindow->getViewport(0)->getActualHeight()));
+}
+
+unsigned int OgreFrameListenerMode::getHandle()
+{
+	return mOgreFrameListenerModeHandle;
 }
 
Index: /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/BBCBillboardCloudUVMapper.cpp
===================================================================
--- /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/BBCBillboardCloudUVMapper.cpp	(revision 745)
+++ /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/BBCBillboardCloudUVMapper.cpp	(revision 751)
@@ -118,12 +118,6 @@
 }
 
-void BillboardCloudUVMapper::addTextureAtlasTextureCoords(bool mergeBillboards, bool groupedBillboards, unsigned int numGeneratedBillboardClouds, unsigned int iBillboardGroup, unsigned int iBillboard)
-{
-	unsigned int iUniqueVertex = 0;
-
-	Ogre::LogManager::getSingleton().logMessage("iBBC:" + Ogre::StringConverter::toString(numGeneratedBillboardClouds) + "-" + "iBBCG:" + Ogre::StringConverter::toString(iBillboardGroup));
-
-	Ogre::LogManager::getSingleton().logMessage("SizeCLList:" + Ogre::StringConverter::toString(getClusterList(iBillboardGroup)->getSize()) + " -- numBBC:" + Ogre::StringConverter::toString(numGeneratedBillboardClouds));
-
+void BillboardCloudUVMapper::addTextureAtlasTextureCoords(bool mergeBillboards, bool groupedBillboards, unsigned int numGeneratedBillboards, unsigned int iBillboardGroup, unsigned int iBillboard, unsigned int iBillboardInGroup)
+{
 	IMG::Cluster *cluster = getClusterList(iBillboardGroup)->get(getClusterList(iBillboardGroup)->getSize()-1);		
 	IMG::Box2d *box = cluster->getBspNodeBound();
@@ -131,7 +125,4 @@
 	Ogre::Vector2 min = box->getMinimum();
 
-	Ogre::LogManager::getSingleton().logMessage("max:" + Ogre::StringConverter::toString(Ogre::Vector3(max[0], max[1], 0.0)) );
-	Ogre::LogManager::getSingleton().logMessage("min:" + Ogre::StringConverter::toString(Ogre::Vector3(min[0], min[1], 0.0)) );
-
 	Ogre::Vector2 umax;
 	umax[0] = (max[0] / mTextureAtlasWidth);
@@ -145,44 +136,43 @@
 	umax = umax * 2.0 - 1.0;
 
-	Ogre::LogManager::getSingleton().logMessage("Umax:" + Ogre::StringConverter::toString(Ogre::Vector3(umax[0], umax[1], 0.0)) );
-	Ogre::LogManager::getSingleton().logMessage("Umin:" + Ogre::StringConverter::toString(Ogre::Vector3(umin[0], umin[1], 0.0)) );
-	
+	mBillboardCloud->getBillboard(iBillboard)->getBillboardClusterData()->addBillboardUVMapMax(umax);
 	mBillboardCloud->getBillboard(iBillboard)->getBillboardClusterData()->addBillboardUVMapMin(umin);
-	mBillboardCloud->getBillboard(iBillboard)->getBillboardClusterData()->addBillboardUVMapMax(umax);
-
-	Ogre::LogManager::getSingleton().logMessage("Max:" + Ogre::StringConverter::toString(Ogre::Vector3(max[0],max[1],0)) + 
-		"\tMin:" + Ogre::StringConverter::toString(Ogre::Vector3(min[0],min[1],0)) + 
-		"\tSize(" + Ogre::StringConverter::toString(max[0]-min[0]) +
-		"," + Ogre::StringConverter::toString(max[1]-min[1]) + ")");
-
-	Ogre::LogManager::getSingleton().logMessage(
-		"UMax:" + Ogre::StringConverter::toString(Ogre::Vector3(umax[0], umax[1],0)) + 
-		"\tUMin:" + Ogre::StringConverter::toString(Ogre::Vector3(umin[0], umin[1],0)) + 
-		"\tUSize(" + Ogre::StringConverter::toString(umax[0]-umin[0]) +
-		"," + Ogre::StringConverter::toString(umax[1]-umin[1]) + ")");
-
-	std::cin.get();
-
-
-	SubEntityPtr subEntity;												
+
+	//Ogre::LogManager::getSingleton().logMessage("Max:" + Ogre::StringConverter::toString(Ogre::Vector3(max[0],max[1],0)) + 
+	//	"\tMin:" + Ogre::StringConverter::toString(Ogre::Vector3(min[0],min[1],0)) + 
+	//	"\tSize(" + Ogre::StringConverter::toString(max[0]-min[0]) +
+	//	"," + Ogre::StringConverter::toString(max[1]-min[1]) + ")");
+
+	//Ogre::LogManager::getSingleton().logMessage(
+	//	"UMax:" + Ogre::StringConverter::toString(Ogre::Vector3(umax[0], umax[1],0)) + 
+	//	"\tUMin:" + Ogre::StringConverter::toString(Ogre::Vector3(umin[0], umin[1],0)) + 
+	//	"\tUSize(" + Ogre::StringConverter::toString(umax[0]-umin[0]) +
+	//	"," + Ogre::StringConverter::toString(umax[1]-umin[1]) + ")");
 	
 	Ogre::Vector2 texCoords01,texCoords02,texCoords03,texCoords04;
-	texCoords01[0] = min[0] / mTextureAtlasWidth;
-	texCoords01[1] = min[1] / mTextureAtlasHeight;
-
-	texCoords02[0] = max[0] / mTextureAtlasWidth;
-	texCoords02[1] = min[1] / mTextureAtlasHeight;
-
-	texCoords03[0] = max[0] / mTextureAtlasWidth;
-	texCoords03[1] = max[1] / mTextureAtlasHeight;
-
-	texCoords04[0] = min[0] / mTextureAtlasWidth;
-	texCoords04[1] = max[1] / mTextureAtlasHeight;
+
+	texCoords02[0] = min[0] / mTextureAtlasWidth;
+	texCoords02[1] = 1.0 - (min[1] / mTextureAtlasHeight);
+
+	texCoords01[0] = max[0] / mTextureAtlasWidth;
+	texCoords01[1] = 1.0 - (min[1] / mTextureAtlasHeight);
+
+	texCoords04[0] = max[0] / mTextureAtlasWidth;
+	texCoords04[1] = 1.0 - (max[1] / mTextureAtlasHeight);
+
+	texCoords03[0] = min[0] / mTextureAtlasWidth;
+	texCoords03[1] = 1.0 - (max[1] / mTextureAtlasHeight);
 	
 	if (groupedBillboards)
 	{
-		Ogre::LogManager::getSingleton().logMessage("DontMerge");
-		subEntity = mBillboardCloud->getEntity()->getSubEntity(iBillboardGroup);				
-		
+		SubEntityPtr subEntity;												
+
+		unsigned int iUniqueVertex = 0;
+
+		subEntity = mBillboardCloud->getEntity()->getSubEntity(numGeneratedBillboards);				
+
+		subEntity->addTextureCoordSet(2);
+		subEntity->enableVertexColours(true);
+
 		// Face A
 		//(0,0,0);
@@ -216,53 +206,12 @@
 		subEntity->setVertexColour(iUniqueVertex+4, subEntityColour05.getAsRGBA());
 		subEntity->setVertexColour(iUniqueVertex+5, subEntityColour06.getAsRGBA());
-
-		iUniqueVertex = iUniqueVertex + 6;
 	}
 	else
 	{
-		if (!mergeBillboards)
-		{
-			Ogre::LogManager::getSingleton().logMessage("DontMerge");
-
-			subEntity = mBillboardCloud->getEntity()->getSubEntity(numGeneratedBillboardClouds);
-			subEntity->addTextureCoordSet(2);
-			subEntity->enableVertexColours(true);
-			// Face A
-			//(0,0,0);
-			//(1,0,0);
-			//(1,1,0);
-
-			subEntity->setTexCoord(0, subEntity->getNumTexCoordSets()-1, Ogre::Vector3(texCoords01[0],texCoords01[1], 0));
-			subEntity->setTexCoord(1, subEntity->getNumTexCoordSets()-1, Ogre::Vector3(texCoords02[0],texCoords02[1], 0));
-			subEntity->setTexCoord(2, subEntity->getNumTexCoordSets()-1, Ogre::Vector3(texCoords03[0],texCoords03[1], 0));
-
-			Ogre::ColourValue subEntityColour01 = Ogre::ColourValue(0, texCoords01[0],texCoords01[1]);
-			Ogre::ColourValue subEntityColour02 = Ogre::ColourValue(0, texCoords02[0],texCoords02[1]);
-			Ogre::ColourValue subEntityColour03 = Ogre::ColourValue(0, texCoords03[0],texCoords03[1]);
-
-			subEntity->setVertexColour(0, subEntityColour01.getAsRGBA());
-			subEntity->setVertexColour(1, subEntityColour02.getAsRGBA());
-			subEntity->setVertexColour(2, subEntityColour03.getAsRGBA());
-
-			// Face B
-			//(1,1,0);
-			//(0,1,0);
-			//(0,0,0);
-			subEntity->setTexCoord(3, subEntity->getNumTexCoordSets()-1, Ogre::Vector3(texCoords03[0],texCoords03[1],0));
-			subEntity->setTexCoord(4, subEntity->getNumTexCoordSets()-1, Ogre::Vector3(texCoords04[0],texCoords04[1],0));
-			subEntity->setTexCoord(5, subEntity->getNumTexCoordSets()-1, Ogre::Vector3(texCoords01[0],texCoords01[1],0));
-
-			Ogre::ColourValue subEntityColour04 = Ogre::ColourValue(0, texCoords03[0],texCoords03[1]);
-			Ogre::ColourValue subEntityColour05 = Ogre::ColourValue(0, texCoords04[0],texCoords04[1]);
-			Ogre::ColourValue subEntityColour06 = Ogre::ColourValue(0, texCoords01[0],texCoords01[1]);
-
-			subEntity->setVertexColour(3, subEntityColour04.getAsRGBA());
-			subEntity->setVertexColour(4, subEntityColour05.getAsRGBA());
-			subEntity->setVertexColour(5, subEntityColour06.getAsRGBA());
-
-		}
-		else
-		{
-			Ogre::LogManager::getSingleton().logMessage("Merge");
+		if (mergeBillboards)
+		{
+			SubEntityPtr subEntity;	
+
+			unsigned int iUniqueVertex = numGeneratedBillboards * 6;
 
 			subEntity = mBillboardCloud->getEntity()->getSubEntity(0);				
@@ -300,7 +249,5 @@
 			subEntity->setVertexColour(iUniqueVertex+5, subEntityColour06.getAsRGBA());
 
-			iUniqueVertex = iUniqueVertex + 6;
-		}
-		Ogre::LogManager::getSingleton().logMessage("EndAdd");
+		}
 	}
 }
@@ -310,10 +257,8 @@
 	IMG::NodeBspPtr nodeDest;
 	IMG::Cluster cluster;
-	Ogre::LogManager::getSingleton().logMessage("w:" + Ogre::StringConverter::toString(mTextureWidth));
-	Ogre::LogManager::getSingleton().logMessage("h:" + Ogre::StringConverter::toString(mTextureHeight));
+
 	nodeDest = getBsp(iBillboardGroup)->insert(mTextureWidth,mTextureHeight,iBillboard);
 	
 	cluster.setBspNodeBound(nodeDest->getBound());
-	//cluster.finish();
 	getClusterList(iBillboardGroup)->insert(&cluster);	
 }
@@ -323,5 +268,5 @@
 	unsigned int numBillboardGroups;
 	bool enabledTextureCoordSet = false;
-	unsigned int numGeneratedBillboardClouds = 0;
+	unsigned int numGeneratedBillboards = 0;
 
 	for (unsigned int iBillboard = 0; iBillboard < mBillboardCloud->getNumBillboards(); iBillboard++)
@@ -342,15 +287,5 @@
 				}
 			}
-			else
-			{
-				if (groupedBillboards)
-				{
-					SubEntityPtr subEntity = mBillboardCloud->getEntity()->getSubEntity(numGeneratedBillboardClouds);	
-					subEntity->addTextureCoordSet(2);
-					subEntity->enableVertexColours(true);
-				}
-			}
-
-			numGeneratedBillboardClouds++;
+			numGeneratedBillboards++;
 		}
 	}
@@ -373,7 +308,7 @@
 	
 	unsigned int iBillboardsInGroup = 0;
-	unsigned int numberBillboardsEachGroup = numGeneratedBillboardClouds / numGroups;
-	unsigned int numberBillboardsAddedFirstGroup = numGeneratedBillboardClouds % numGroups;
-	numGeneratedBillboardClouds = 0;
+	unsigned int numberBillboardsEachGroup = numGeneratedBillboards / numGroups;
+	unsigned int numberBillboardsAddedFirstGroup = numGeneratedBillboards % numGroups;
+	numGeneratedBillboards = 0;
 	unsigned int iBillboardGroup;
 	for (iBillboardGroup = 0; iBillboardGroup < numBillboardGroups; iBillboardGroup++)
@@ -388,5 +323,4 @@
 		addBsp(bsp);
 		addClusterList(clusterList);
-
 	}
 
@@ -400,17 +334,13 @@
 		if (billboardClusterData != NULL)
 		{
-			Ogre::LogManager::getSingleton().logMessage("billboardData");
+			BillboardPtr billboard = mBillboardCloud->getBillboard(iBillboard);		
 			EntityClusterPtr entityCluster = billboardClusterData->getEntityCluster();
+
 			if (entityCluster->getNumEntitiesClusterData() > 0)
 			{			
-				Ogre::LogManager::getSingleton().logMessage("entityCluster");
-				
 				if ((iBillboardGroup == 0) && (iBillboardsInGroup < (numberBillboardsEachGroup + numberBillboardsAddedFirstGroup)))
 				{
-					Ogre::LogManager::getSingleton().logMessage("\nA");
-					Ogre::LogManager::getSingleton().logMessage("IG:" + Ogre::StringConverter::toString(iBillboardsInGroup) + " SizeCLList(" + Ogre::StringConverter::toString(iBillboardGroup) + "):" + Ogre::StringConverter::toString(getClusterList(iBillboardGroup)->getSize()) + " -- numBBC:" + Ogre::StringConverter::toString(numGeneratedBillboardClouds));
-
 					addTextureInBsp(iBillboardGroup, iBillboard);
-					addTextureAtlasTextureCoords(mergeBillboards, groupedBillboards, numGeneratedBillboardClouds, iBillboardGroup, iBillboard);
+					addTextureAtlasTextureCoords(mergeBillboards, groupedBillboards, numGeneratedBillboards, iBillboardGroup, iBillboard, iBillboardsInGroup);
 					iBillboardsInGroup++;
 				}
@@ -419,9 +349,6 @@
 					if ((iBillboardGroup > 0) && (iBillboardsInGroup < numberBillboardsEachGroup))
 					{
-						Ogre::LogManager::getSingleton().logMessage("\nB");
-						Ogre::LogManager::getSingleton().logMessage("IG:" + Ogre::StringConverter::toString(iBillboardsInGroup) + " SizeCLList(" + Ogre::StringConverter::toString(iBillboardGroup) + "):" + Ogre::StringConverter::toString(getClusterList(iBillboardGroup)->getSize()) + " -- numBBC:" + Ogre::StringConverter::toString(numGeneratedBillboardClouds));
-
 						addTextureInBsp(iBillboardGroup, iBillboard);
-						addTextureAtlasTextureCoords(mergeBillboards, groupedBillboards, numGeneratedBillboardClouds, iBillboardGroup, iBillboard);
+						addTextureAtlasTextureCoords(mergeBillboards, groupedBillboards, numGeneratedBillboards, iBillboardGroup, iBillboard, iBillboardsInGroup);
 						iBillboardsInGroup++;
 					}
@@ -431,18 +358,14 @@
 						iBillboardsInGroup = 0;
 
-						Ogre::LogManager::getSingleton().logMessage("\nC IG:" + Ogre::StringConverter::toString(iBillboardsInGroup-1) + " SizeCLList(" + Ogre::StringConverter::toString(iBillboardGroup-1) + "):" + Ogre::StringConverter::toString(getClusterList(iBillboardGroup-1)->getSize()));
-						Ogre::LogManager::getSingleton().logMessage("IG:" + Ogre::StringConverter::toString(iBillboardsInGroup) + " SizeCLList(" + Ogre::StringConverter::toString(iBillboardGroup) + "):" + Ogre::StringConverter::toString(getClusterList(iBillboardGroup)->getSize()) + " -- numBBC:" + Ogre::StringConverter::toString(numGeneratedBillboardClouds));
-
 						addTextureInBsp(iBillboardGroup, iBillboard);
-						addTextureAtlasTextureCoords(mergeBillboards, groupedBillboards, numGeneratedBillboardClouds, iBillboardGroup, iBillboard);
+						addTextureAtlasTextureCoords(mergeBillboards, groupedBillboards, numGeneratedBillboards, iBillboardGroup, iBillboard, iBillboardsInGroup);
 						iBillboardsInGroup++;
 					}
 				}
 
-				numGeneratedBillboardClouds++;
+				numGeneratedBillboards++;
 			}
 		}
 	}	
-	//mBsp.Print();
 }
 
Index: /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCBillboardKMeansClusterData.cpp
===================================================================
--- /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCBillboardKMeansClusterData.cpp	(revision 745)
+++ /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCBillboardKMeansClusterData.cpp	(revision 751)
@@ -181,14 +181,26 @@
 	if (iBillboardGroup >= 0)
 	{		
+		//uvMapMin = billboardNode->ToElement()->InsertEndChild(TiXmlElement("uvMapMin"))->ToElement();
+		//Ogre::String sUvMapMinX = Ogre::StringConverter::toString(this->getBillboardUVMapMin(iBillboardGroup).x);
+		//uvMapMin->ToElement()->SetAttribute("x",sUvMapMinX.c_str());
+		//Ogre::String sUvMapMinY = Ogre::StringConverter::toString(this->getBillboardUVMapMin(iBillboardGroup).y);
+		//uvMapMin->ToElement()->SetAttribute("y",sUvMapMinY.c_str());
+
+		//uvMapMax = billboardNode->ToElement()->InsertEndChild(TiXmlElement("uvMapMax"))->ToElement();
+		//Ogre::String suvMapMaxX = Ogre::StringConverter::toString(this->getBillboardUVMapMax(iBillboardGroup).x);
+		//uvMapMax->ToElement()->SetAttribute("x",suvMapMaxX.c_str());
+		//Ogre::String suvMapMaxY = Ogre::StringConverter::toString(this->getBillboardUVMapMax(iBillboardGroup).y);
+		//uvMapMax->ToElement()->SetAttribute("y",suvMapMaxY.c_str());
+
 		uvMapMin = billboardNode->ToElement()->InsertEndChild(TiXmlElement("uvMapMin"))->ToElement();
-		Ogre::String sUvMapMinX = Ogre::StringConverter::toString(this->getBillboardUVMapMin(iBillboardGroup).x);
+		Ogre::String sUvMapMinX = Ogre::StringConverter::toString(this->getBillboardUVMapMin(0).x);
 		uvMapMin->ToElement()->SetAttribute("x",sUvMapMinX.c_str());
-		Ogre::String sUvMapMinY = Ogre::StringConverter::toString(this->getBillboardUVMapMin(iBillboardGroup).y);
+		Ogre::String sUvMapMinY = Ogre::StringConverter::toString(this->getBillboardUVMapMin(0).y);
 		uvMapMin->ToElement()->SetAttribute("y",sUvMapMinY.c_str());
 
 		uvMapMax = billboardNode->ToElement()->InsertEndChild(TiXmlElement("uvMapMax"))->ToElement();
-		Ogre::String suvMapMaxX = Ogre::StringConverter::toString(this->getBillboardUVMapMax(iBillboardGroup).x);
+		Ogre::String suvMapMaxX = Ogre::StringConverter::toString(this->getBillboardUVMapMax(0).x);
 		uvMapMax->ToElement()->SetAttribute("x",suvMapMaxX.c_str());
-		Ogre::String suvMapMaxY = Ogre::StringConverter::toString(this->getBillboardUVMapMax(iBillboardGroup).y);
+		Ogre::String suvMapMaxY = Ogre::StringConverter::toString(this->getBillboardUVMapMax(0).y);
 		uvMapMax->ToElement()->SetAttribute("y",suvMapMaxY.c_str());
 	}
@@ -209,6 +221,5 @@
 
 void BillboardKMeansClusterData::generateBillboardBoundingQuad() 
-{
-	
+{	
 	Ogre::Vector3 normal = getNormal();
 	Ogre::Vector3 planePosition;
@@ -333,4 +344,18 @@
 		}		
 	}
+	
+	for (unsigned int iLeaf = 0; iLeaf < entityCluster->getNumEntitiesClusterData(); iLeaf++)
+	{
+		LeafKMeansClusterData *leafKMeansClusterData = (LeafKMeansClusterData*)entityCluster->getEntityClusterData(iLeaf).get();
+		Leaf *leaf = (Leaf*)leafKMeansClusterData->getEntity().get();		
+
+		Ogre::Vector3 position = leaf->getPosition();
+		Ogre::Vector4 projPointP1d4 =  Ogre::Vector4(position.x,position.y,position.z,1.0f) * invMCoordPlane * constCoord * coordPlane;
+		
+		// The point projected in the plane
+		Ogre::Vector3 projPointP1(projPointP1d4.x,projPointP1d4.y,projPointP1d4.z);
+
+		leaf->setPosition(projPointP1);
+	}
 
 	Ogre::Vector3 aP;
Index: /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/IMGCluster.cpp
===================================================================
--- /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/IMGCluster.cpp	(revision 731)
+++ /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/IMGCluster.cpp	(revision 751)
@@ -110,10 +110,10 @@
 void Cluster::print() 
 {
-	Ogre::LogManager::getSingleton().logMessage("\n\nCluster: " + Ogre::StringConverter::toString(id) + ", axisproj: " + Ogre::StringConverter::toString(axisproj)  + ", order: " + Ogre::StringConverter::toString(order));
+	//Ogre::LogManager::getSingleton().logMessage("\n\nCluster: " + Ogre::StringConverter::toString(id) + ", axisproj: " + Ogre::StringConverter::toString(axisproj)  + ", order: " + Ogre::StringConverter::toString(order));
 	
 	plane.print();
-	Ogre::LogManager::getSingleton().logMessage("\nOrigin (" + Ogre::StringConverter::toString(lumel_origin) + ")");
-	Ogre::LogManager::getSingleton().logMessage("Inc U (" + Ogre::StringConverter::toString(lumel_x_axis) + ")");
-	Ogre::LogManager::getSingleton().logMessage("Inc V (" + Ogre::StringConverter::toString(lumel_y_axis.z) + ")");
+	//Ogre::LogManager::getSingleton().logMessage("\nOrigin (" + Ogre::StringConverter::toString(lumel_origin) + ")");
+	//Ogre::LogManager::getSingleton().logMessage("Inc U (" + Ogre::StringConverter::toString(lumel_x_axis) + ")");
+	//Ogre::LogManager::getSingleton().logMessage("Inc V (" + Ogre::StringConverter::toString(lumel_y_axis.z) + ")");
 	
 	bound.print();
@@ -121,5 +121,5 @@
 	bspnodebound.print();
 	
-	Ogre::LogManager::getSingleton().logMessage("Printant els vertexs: ");
+	//Ogre::LogManager::getSingleton().logMessage("Printant els vertexs: ");
 }
 
@@ -145,5 +145,5 @@
 void Cluster::finish() 
 {
-	Ogre::LogManager::getSingleton().logMessage("\nCluster::Finish()");
+	//Ogre::LogManager::getSingleton().logMessage("\nCluster::Finish()");
 	Plane3 *plane = getPlane();
 	Ogre::Vector3 normal = *plane->getNormal();
@@ -157,7 +157,7 @@
 	bool type = true;
 
-	Ogre::LogManager::getSingleton().logMessage("\tCreant cluster 2d");
+	//Ogre::LogManager::getSingleton().logMessage("\tCreant cluster 2d");
 	axisproj = cluster2d.create2d (this, 0, true);	
-	Ogre::LogManager::getSingleton().logMessage("\t Imprimint el que hi al del cluster");
+	//Ogre::LogManager::getSingleton().logMessage("\t Imprimint el que hi al del cluster");
 		
 	std::vector<Ogre::Vector2> vector2;
@@ -172,10 +172,10 @@
 	max = bound.getMaximum();
 	
-	Ogre::LogManager::getSingleton().logMessage("Caixa Englobant del cluster 2d");
+	//Ogre::LogManager::getSingleton().logMessage("Caixa Englobant del cluster 2d");
 	bound.print();
 
 	Ogre::Vector3 aux (-9999,-9999,-9999);
 
-	Ogre::LogManager::getSingleton().logMessage("Axisproj:" + Ogre::StringConverter::toString(axisproj));
+	//Ogre::LogManager::getSingleton().logMessage("Axisproj:" + Ogre::StringConverter::toString(axisproj));
 }
 
Index: /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/BBCManager.cpp
===================================================================
--- /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/BBCManager.cpp	(revision 731)
+++ /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/BBCManager.cpp	(revision 751)
@@ -22,4 +22,5 @@
 BBCManager::~BBCManager() 
 {
+
 }
 
Index: /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/IMGTextureAtlas.cpp
===================================================================
--- /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/IMGTextureAtlas.cpp	(revision 747)
+++ /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/IMGTextureAtlas.cpp	(revision 751)
@@ -87,5 +87,5 @@
 }
 
-void TextureAtlas::create(Ogre::String fileName, unsigned int width, unsigned int height, Ogre::PixelFormat pixelFormat, Ogre::Camera *camera)
+void TextureAtlas::create(Ogre::String fileName, unsigned int width, unsigned int height, Ogre::PixelFormat pixelFormat, Ogre::Camera *camera, Ogre::ColourValue backgroundColour)
 {
 	mCamera = camera;
@@ -101,5 +101,5 @@
 		Ogre::Viewport *v = rt->addViewport(mCamera);
 		v->setClearEveryFrame(true);
-		v->setBackgroundColour(Ogre::ColourValue(1.0f, 1.0f, 1.0f, 0.0f));
+		v->setBackgroundColour(backgroundColour);
 		v->setOverlaysEnabled(false);
 		v->setDimensions(0,0,1.0,1.0);	
@@ -113,5 +113,5 @@
 		Ogre::Viewport *v = rt->addViewport(mCamera);
 		v->setClearEveryFrame(true);
-		v->setBackgroundColour(Ogre::ColourValue(1.0f, 1.0f, 1.0f, 0.0f));
+		v->setBackgroundColour(backgroundColour);
 		v->setOverlaysEnabled(false);
 		v->setDimensions(0,0,1.0,1.0);	
Index: /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/BBCBillboardCloud.cpp
===================================================================
--- /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/BBCBillboardCloud.cpp	(revision 745)
+++ /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/BBCBillboardCloud.cpp	(revision 751)
@@ -237,64 +237,70 @@
 			unsigned int billboardHandle = billboardGroup->getBillboardHandle(iBillboard);
 			BillboardPtr billboard = this->getBillboard(billboardHandle);
-			EntityClusterPtr entityCluster = billboard->getBillboardClusterData()->getEntityCluster();
-
-			if (entityCluster->getNumEntitiesClusterData() > 0)
-			{
-				subEntity = mEntity->getSubEntity(numGeneratedBillboardClouds);
-
-				while (subEntityGroup->getNumTexCoordSets() < subEntity->getNumTexCoordSets())
+
+			BillboardClusterData *billboardClusterData = billboard->getBillboardClusterData().get();
+
+			if (billboardClusterData != NULL)
+			{				
+				EntityClusterPtr entityCluster = billboardClusterData->getEntityCluster();
+
+				if (entityCluster->getNumEntitiesClusterData() > 0)
 				{
-					subEntityGroup->addTextureCoordSet(subEntity->getTexCoordDimensions(subEntityGroup->getNumTexCoordSets()));
+					subEntity = mEntity->getSubEntity(numGeneratedBillboardClouds);
+
+					while (subEntityGroup->getNumTexCoordSets() < subEntity->getNumTexCoordSets())
+					{
+						subEntityGroup->addTextureCoordSet(subEntity->getTexCoordDimensions(subEntityGroup->getNumTexCoordSets()));
+					}
+
+					unsigned int offset = subEntityGroup->getNumFaces() * 3;
+					Ogre::Vector3 indicesA = Ogre::Vector3(offset, offset + 1, offset + 2);
+					subEntityGroup->addFaceVerticesIDs(indicesA);
+					offset = subEntityGroup->getNumFaces()*3;
+					Ogre::Vector3 indicesB = Ogre::Vector3(offset, offset + 1, offset + 2);
+					subEntityGroup->addFaceVerticesIDs(indicesB);
+
+					UniqueVertex vFaceA1,vFaceA2,vFaceA3;
+					// Face A of the billboard quad
+					vFaceA1.position = billboard->getBillboardClusterData()->getQuadTopLeftCorner();
+					vFaceA1.normal = billboard->getBillboardClusterData()->getNormal();
+
+					vFaceA2.position = billboard->getBillboardClusterData()->getQuadTopRightCorner();
+					vFaceA2.normal = billboard->getBillboardClusterData()->getNormal();
+					
+					vFaceA3.position = billboard->getBillboardClusterData()->getQuadBottomRightCorner();
+					vFaceA3.normal = billboard->getBillboardClusterData()->getNormal();
+					
+					// Face B of the billboard quad
+					UniqueVertex vFaceB1,vFaceB2,vFaceB3;
+					vFaceB1.position = billboard->getBillboardClusterData()->getQuadBottomRightCorner();
+					vFaceB1.normal = billboard->getBillboardClusterData()->getNormal();
+					
+					vFaceB2.position = billboard->getBillboardClusterData()->getQuadBottomLeftCorner();
+					vFaceB2.normal = billboard->getBillboardClusterData()->getNormal();
+					
+					vFaceB3.position = billboard->getBillboardClusterData()->getQuadTopLeftCorner();
+					vFaceB3.normal = billboard->getBillboardClusterData()->getNormal();
+					
+					Ogre::LogManager::getSingleton().logMessage("BBCG-SubEntity(" + Ogre::StringConverter::toString(numGeneratedBillboardClouds) + ") - Num.Tex.Coord.Sets:"+ Ogre::StringConverter::toString(subEntity->getNumTexCoordSets()));
+
+					for (unsigned int iTexCoordSet = 0; iTexCoordSet < subEntityGroup->getNumTexCoordSets(); iTexCoordSet++)
+					{					
+						vFaceA1.uv[iTexCoordSet] = subEntity->getUniqueVertex(0).uv[iTexCoordSet];
+						vFaceA2.uv[iTexCoordSet] = subEntity->getUniqueVertex(1).uv[iTexCoordSet];
+						vFaceA3.uv[iTexCoordSet] = subEntity->getUniqueVertex(2).uv[iTexCoordSet];
+						vFaceB1.uv[iTexCoordSet] = subEntity->getUniqueVertex(3).uv[iTexCoordSet];
+						vFaceB2.uv[iTexCoordSet] = subEntity->getUniqueVertex(4).uv[iTexCoordSet];
+						vFaceB3.uv[iTexCoordSet] = subEntity->getUniqueVertex(5).uv[iTexCoordSet];
+					}
+
+					subEntityGroup->addUniqueVertex(vFaceA1);
+					subEntityGroup->addUniqueVertex(vFaceA2);
+					subEntityGroup->addUniqueVertex(vFaceA3);
+					subEntityGroup->addUniqueVertex(vFaceB1);
+					subEntityGroup->addUniqueVertex(vFaceB2);
+					subEntityGroup->addUniqueVertex(vFaceB3);
+
+					numGeneratedBillboardClouds++;
 				}
-
-				unsigned int offset = subEntityGroup->getNumFaces() * 3;
-				Ogre::Vector3 indicesA = Ogre::Vector3(offset, offset + 1, offset + 2);
-				subEntityGroup->addFaceVerticesIDs(indicesA);
-				offset = subEntityGroup->getNumFaces()*3;
-				Ogre::Vector3 indicesB = Ogre::Vector3(offset, offset + 1, offset + 2);
-				subEntityGroup->addFaceVerticesIDs(indicesB);
-
-				UniqueVertex vFaceA1,vFaceA2,vFaceA3;
-				// Face A of the billboard quad
-				vFaceA1.position = billboard->getBillboardClusterData()->getQuadTopLeftCorner();
-				vFaceA1.normal = billboard->getBillboardClusterData()->getNormal();
-
-				vFaceA2.position = billboard->getBillboardClusterData()->getQuadTopRightCorner();
-				vFaceA2.normal = billboard->getBillboardClusterData()->getNormal();
-				
-				vFaceA3.position = billboard->getBillboardClusterData()->getQuadBottomRightCorner();
-				vFaceA3.normal = billboard->getBillboardClusterData()->getNormal();
-				
-				// Face B of the billboard quad
-				UniqueVertex vFaceB1,vFaceB2,vFaceB3;
-				vFaceB1.position = billboard->getBillboardClusterData()->getQuadBottomRightCorner();
-				vFaceB1.normal = billboard->getBillboardClusterData()->getNormal();
-				
-				vFaceB2.position = billboard->getBillboardClusterData()->getQuadBottomLeftCorner();
-				vFaceB2.normal = billboard->getBillboardClusterData()->getNormal();
-				
-				vFaceB3.position = billboard->getBillboardClusterData()->getQuadTopLeftCorner();
-				vFaceB3.normal = billboard->getBillboardClusterData()->getNormal();
-				
-				Ogre::LogManager::getSingleton().logMessage("BBCG-SubEntity(" + Ogre::StringConverter::toString(numGeneratedBillboardClouds) + ") - Num.Tex.Coord.Sets:"+ Ogre::StringConverter::toString(subEntity->getNumTexCoordSets()));
-
-				for (unsigned int iTexCoordSet = 0; iTexCoordSet < subEntityGroup->getNumTexCoordSets(); iTexCoordSet++)
-				{					
-					vFaceA1.uv[iTexCoordSet] = subEntity->getUniqueVertex(0).uv[iTexCoordSet];
-					vFaceA2.uv[iTexCoordSet] = subEntity->getUniqueVertex(1).uv[iTexCoordSet];
-					vFaceA3.uv[iTexCoordSet] = subEntity->getUniqueVertex(2).uv[iTexCoordSet];
-					vFaceB1.uv[iTexCoordSet] = subEntity->getUniqueVertex(3).uv[iTexCoordSet];
-					vFaceB2.uv[iTexCoordSet] = subEntity->getUniqueVertex(4).uv[iTexCoordSet];
-					vFaceB3.uv[iTexCoordSet] = subEntity->getUniqueVertex(5).uv[iTexCoordSet];
-				}
-
-				subEntityGroup->addUniqueVertex(vFaceA1);
-				subEntityGroup->addUniqueVertex(vFaceA2);
-				subEntityGroup->addUniqueVertex(vFaceA3);
-				subEntityGroup->addUniqueVertex(vFaceB1);
-				subEntityGroup->addUniqueVertex(vFaceB2);
-				subEntityGroup->addUniqueVertex(vFaceB3);
-
-				numGeneratedBillboardClouds++;
 			}
 		}
Index: /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCSampleConfigFile.cpp
===================================================================
--- /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCSampleConfigFile.cpp	(revision 747)
+++ /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCSampleConfigFile.cpp	(revision 751)
@@ -102,7 +102,7 @@
 }
 
-bool SampleConfigFile::getEntityClustersMergedClusters()
-{
-	return Ogre::StringConverter::parseBool(getSetting("Entity Clusters Merged Clusters"));
+bool SampleConfigFile::getEntityClustersGroupedClusters()
+{
+	return Ogre::StringConverter::parseBool(getSetting("Entity Clusters Grouped Clusters"));
 }
 
@@ -132,4 +132,14 @@
 }
 
+Ogre::String SampleConfigFile::getBillboardCloudIndirectPointMeshName()
+{
+	return getSetting("Billboard Cloud Indirect Point Mesh Name");
+}
+
+Ogre::String SampleConfigFile::getBillboardCloudIndirectPointMaterialName()
+{
+	return getSetting("Billboard Cloud Indirect Point Material Name");
+}
+
 Ogre::String SampleConfigFile::getEntityClustersFolder()
 {
@@ -137,7 +147,7 @@
 }
 
-Ogre::String SampleConfigFile::getEntityClustersMergedMeshName()
-{
-	return getSetting("Entity Clusters Merged Mesh Name");
+Ogre::String SampleConfigFile::getEntityClustersGroupedMeshName()
+{
+	return getSetting("Entity Clusters Grouped Mesh Name");
 }
 
@@ -147,7 +157,7 @@
 }
 
-Ogre::String SampleConfigFile::getEntityClustersMergedMaterialName()
-{
-	return getSetting("Entity Clusters Merged Material Name");
+Ogre::String SampleConfigFile::getEntityClustersGroupedMaterialName()
+{
+	return getSetting("Entity Clusters Grouped Material Name");
 }
 
@@ -192,4 +202,14 @@
 }
 
+Ogre::String SampleConfigFile::getEntityClustersGroupedTextureUnit0Name()
+{
+	return getSetting("Entity Clusters Grouped Texture Unit 0 Name");
+}
+
+Ogre::String SampleConfigFile::getEntityClustersSplittedTextureUnit0Name()
+{
+	return getSetting("Entity Clusters Splitted Texture Unit 0 Name");
+}
+
 Ogre::String SampleConfigFile::getBillboardCloudMergedTextureUnit0Name()
 {
@@ -207,7 +227,7 @@
 }
 
-Ogre::String SampleConfigFile::getBillboardCloudIndirectBillboardGroupTextureAtlasName()
-{
-	return getSetting("Billboard Cloud Indirect Billboard Group Texture Atlas Name");
+Ogre::String SampleConfigFile::getBillboardCloudIndirectGroupedBillboardsTextureAtlasName()
+{
+	return getSetting("Billboard Cloud Indirect Grouped Billboards Texture Atlas Name");
 }
 
@@ -217,7 +237,7 @@
 }
 
-unsigned int SampleConfigFile::getBillboardCloudDiffuseColorBillboardGroupTextureSize()
-{
-	return Ogre::StringConverter::parseInt(getSetting("Billboard Cloud Diffuse Color Billboard Group Texture Size"));
+unsigned int SampleConfigFile::getBillboardCloudDiffuseColorGroupedBillboardsTextureSize()
+{
+	return Ogre::StringConverter::parseInt(getSetting("Billboard Cloud Diffuse Color Grouped Billboards Texture Size"));
 }
 
@@ -227,32 +247,57 @@
 }
 
-unsigned int SampleConfigFile::getBillboardCloudIndirectBillboardGroupTextureAtlasBitRange()
-{
-	return Ogre::StringConverter::parseInt(getSetting("Billboard Cloud Indirect Billboard Group Texture Atlas Bit Range"));
-}
-
-unsigned int SampleConfigFile::getBillboardCloudIndirectBillboardGroupTextureAtlasSize()
-{
-	return Ogre::StringConverter::parseInt(getSetting("Billboard Cloud Indirect Billboard Group Texture Atlas Size"));
-}
-
-unsigned int SampleConfigFile::getBillboardCloudIndirectBillboardGroupTextureSize()
-{
-	return Ogre::StringConverter::parseInt(getSetting("Billboard Cloud Indirect Billboard Group Texture Size"));
-}
-
-unsigned int SampleConfigFile::getBillboardCloudDiffuseColorBillboardGroupTextureAtlasSize()
-{
-	return Ogre::StringConverter::parseInt(getSetting("Billboard Cloud Diffuse Color Billboard Group Texture Atlas Size"));
-}
-
-bool SampleConfigFile::getBillboardCloudDiffuseColorBillboardGroupTextureAtlasGeneration()
-{
-	return Ogre::StringConverter::parseBool(getSetting("Billboard Cloud Diffuse Color Billboard Group Texture Atlas Generation"));
-}
-
-bool SampleConfigFile::getBillboardCloudIndirectBillboardGroupTextureAtlasGeneration()
-{
-	return Ogre::StringConverter::parseBool(getSetting("Billboard Cloud Indirect Billboard Group Texture Atlas Generation"));
+unsigned int SampleConfigFile::getBillboardCloudDiffuseColorGroupedBillboardsTextureAtlasBitRange()
+{
+	return Ogre::StringConverter::parseInt(getSetting("Billboard Cloud Diffuse Color Grouped Billboards Texture Atlas Bit Range"));
+}
+
+unsigned int SampleConfigFile::getBillboardCloudIndirectGroupedBillboardsTextureAtlasBitRange()
+{
+	return Ogre::StringConverter::parseInt(getSetting("Billboard Cloud Indirect Grouped Billboards Texture Atlas Bit Range"));
+}
+
+unsigned int SampleConfigFile::getBillboardCloudIndirectGroupedBillboardsTextureAtlasSize()
+{
+	return Ogre::StringConverter::parseInt(getSetting("Billboard Cloud Indirect Grouped Billboards Texture Atlas Size"));
+}
+
+unsigned int SampleConfigFile::getBillboardCloudIndirectGroupedBillboardsTextureSize()
+{
+	return Ogre::StringConverter::parseInt(getSetting("Billboard Cloud Indirect Grouped Billboards Texture Size"));
+}
+
+unsigned int SampleConfigFile::getBillboardCloudDiffuseColorGroupedBillboardsTextureAtlasSize()
+{
+	return Ogre::StringConverter::parseInt(getSetting("Billboard Cloud Diffuse Color Grouped Billboards Texture Atlas Size"));
+}
+
+bool SampleConfigFile::getBillboardCloudDiffuseColorGroupedBillboardsTextureAtlasDebug()
+{
+	return Ogre::StringConverter::parseBool(getSetting("Billboard Cloud Diffuse Color Grouped Billboards Texture Atlas Debug"));
+}
+
+bool SampleConfigFile::getBillboardCloudDiffuseColorMergedBillboardsTextureAtlasDebug()
+{
+	return Ogre::StringConverter::parseBool(getSetting("Billboard Cloud Diffuse Color Merged Billboards Texture Atlas Debug"));
+}
+
+bool SampleConfigFile::getBillboardCloudIndirectGroupedBillboardsTextureAtlasDebug()
+{
+	return Ogre::StringConverter::parseBool(getSetting("Billboard Cloud Indirect Grouped Billboards Texture Atlas Debug"));
+}
+
+bool SampleConfigFile::getBillboardCloudIndirectMergedBillboardsTextureAtlasDebug()
+{
+	return Ogre::StringConverter::parseBool(getSetting("Billboard Cloud Indirect Merged Billboards Texture Atlas Debug"));
+}
+
+bool SampleConfigFile::getBillboardCloudDiffuseColorGroupedBillboardsTextureAtlasGeneration()
+{
+	return Ogre::StringConverter::parseBool(getSetting("Billboard Cloud Diffuse Color Grouped Billboards Texture Atlas Generation"));
+}
+
+bool SampleConfigFile::getBillboardCloudIndirectGroupedBillboardsTextureAtlasGeneration()
+{
+	return Ogre::StringConverter::parseBool(getSetting("Billboard Cloud Indirect Grouped Billboards Texture Atlas Generation"));
 }
 
@@ -272,4 +317,9 @@
 }
 
+Ogre::String SampleConfigFile::getBillboardCloudDiffuseColorGroupedBillboardsTextureAtlasName()
+{
+	return getSetting("Billboard Cloud Diffuse Color Grouped Billboards Texture Atlas Name");
+}
+
 Ogre::String SampleConfigFile::getBillboardCloudDiffuseColorEntityTextureAtlasName()
 {
Index: /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/BBCSubEntity.cpp
===================================================================
--- /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/BBCSubEntity.cpp	(revision 721)
+++ /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/BBCSubEntity.cpp	(revision 751)
@@ -167,21 +167,4 @@
 	return &mUniqueVertexList;
 }
-
-/*
-void SubEntity::createUniqueVertices()
-{
-	for (unsigned int i = 0; i < getNumVertices(); i++)
-	{
-		UniqueVertex uniqueVertex;
-		uniqueVertex.position = getVertex(i);
-		uniqueVertex.normal = getNormal(i);
-		for (unsigned int j = 0; j < getNumTexCoordSets(); j++)
-		{
-			uniqueVertex.uv[j] = getTexCoord(j,i);
-		}
-		
-	}
-}
-*/
 
 void SubEntity::addUniqueVertex(UniqueVertex uniqueVertex)
Index: /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/BBCBillboardClusterData.cpp
===================================================================
--- /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/BBCBillboardClusterData.cpp	(revision 745)
+++ /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/BBCBillboardClusterData.cpp	(revision 751)
@@ -6,4 +6,5 @@
 BillboardClusterData::BillboardClusterData(): references(0) // initialize references to 0 
 {
+
 }
 
@@ -134,7 +135,7 @@
 }
 
-void BillboardClusterData::addBillboardUVMapMin(Ogre::Vector2 min)
+void BillboardClusterData::addBillboardUVMapMin(Ogre::Vector2 minVec)
 {
-	mGroupedBillboardUVMapMinList.push_back(min);
+	mGroupedBillboardUVMapMinList.push_back(minVec);
 }
 
@@ -149,7 +150,7 @@
 }
 
-void BillboardClusterData::addBillboardUVMapMax(Ogre::Vector2 max)
+void BillboardClusterData::addBillboardUVMapMax(Ogre::Vector2 maxVec)
 {
-	mGroupedBillboardUVMapMaxList.push_back(max);
+	mGroupedBillboardUVMapMaxList.push_back(maxVec);
 }
 
Index: /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCKMeansClusterSerializer.cpp
===================================================================
--- /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCKMeansClusterSerializer.cpp	(revision 745)
+++ /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCKMeansClusterSerializer.cpp	(revision 751)
@@ -17,8 +17,7 @@
 	unsigned int numBillboardGroups = Ogre::StringConverter::parseInt(billboardGroupsNode->ToElement()->Attribute("count"));
 	
-	for (unsigned int iBillboardGroup = 0; iBillboardGroup < numBillboardGroups; iBillboardGroup++)
+	unsigned int iBillboardGroup = 0;
+	for (TiXmlNode *billboardGroupNode = billboardGroupsNode->FirstChild("billboardGroup"); billboardGroupNode; billboardGroupNode = billboardGroupNode->NextSibling() )
 	{
-		TiXmlNode *billboardGroupNode = billboardGroupsNode->FirstChild("billboardGroup");
-
 		unsigned int numBillboards = Ogre::StringConverter::parseInt(billboardGroupNode->ToElement()->Attribute("count"));
 
@@ -49,4 +48,5 @@
 			}
 		}
+		iBillboardGroup++;
 	}
 }
Index: /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCManager.cpp
===================================================================
--- /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCManager.cpp	(revision 747)
+++ /GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCManager.cpp	(revision 751)
@@ -138,7 +138,7 @@
 		mOgreMeshSerializer->setEntity(entity);
 		mOgreMeshSerializer->exportMesh(mSampleConfigFile->getEntityClustersFolder() +
-			mSampleConfigFile->getEntityClustersMergedMeshName(), false, false);
-		
-		OBA::OgreBase::getSingleton().getMeshSerializer()->exportMesh((Ogre::Mesh*)entity->getMesh().get(), mSampleConfigFile->getEntityDistributionFolder() + mSampleConfigFile->getEntityClustersMergedMeshName());
+			mSampleConfigFile->getEntityClustersGroupedMeshName(), false, false);
+		
+		OBA::OgreBase::getSingleton().getMeshSerializer()->exportMesh((Ogre::Mesh*)entity->getMesh().get(), mSampleConfigFile->getEntityDistributionFolder() + mSampleConfigFile->getEntityClustersGroupedMeshName());
 		//OBA::OgreBase::getSingleton().getXMLMeshSerializer()->exportMesh(entity->getMesh(), mSampleConfigFile->getEntityClustersFolder() + mSampleConfigFile->getEntitiesMeshPrefixName() + "Merged.mesh" + ".xml");				
 	}
@@ -205,5 +205,5 @@
 	{
 		BBC::SubEntityPtr subEntity = mLeaves->getBillboardCloud()->getEntity()->getSubEntity(iSubEntity);
-		subEntity->setMaterialName(mSampleConfigFile->getBillboardCloudGroupedMaterialName());
+		subEntity->setMaterialName(mSampleConfigFile->getBillboardCloudGroupedMaterialName() + Ogre::StringConverter::toString(iSubEntity));
 	}
 	mOgreMeshSerializer->setEntity(mLeaves->getBillboardCloud()->getEntity());
@@ -233,5 +233,5 @@
 
 	OBA::OgreBase::getSingleton().getMeshSerializer()->exportMesh(mLeaves->getBillboardCloud()->getEntity()->getMesh()->get(), mSampleConfigFile->getBillboardCloudFolder() + mSampleConfigFile->getBillboardCloudSplittedMeshName());
-	OBA::OgreBase::getSingleton().getXMLMeshSerializer()->exportMesh(mLeaves->getBillboardCloud()->getEntity()->getMesh()->get(), mSampleConfigFile->getBillboardCloudFolder() + mSampleConfigFile->getBillboardCloudSplittedMeshName() + ".xml");
+	//OBA::OgreBase::getSingleton().getXMLMeshSerializer()->exportMesh(mLeaves->getBillboardCloud()->getEntity()->getMesh()->get(), mSampleConfigFile->getBillboardCloudFolder() + mSampleConfigFile->getBillboardCloudSplittedMeshName() + ".xml");
 }
 
@@ -241,5 +241,5 @@
 	{
 		BBC::SubEntityPtr subEntity = mLeaves->getBillboardCloud()->getEntity()->getSubEntity(iSubEntity);
-		subEntity->setMaterialName(mSampleConfigFile->getBillboardCloudGroupedMaterialName());
+		subEntity->setMaterialName(mSampleConfigFile->getBillboardCloudMergedMaterialName());
 	}
 	mOgreMeshSerializer->setEntity(mLeaves->getBillboardCloud()->getEntity());
@@ -346,5 +346,5 @@
 	numSerializedBillboards = 0;
 
-	if (mSampleConfigFile->getEntityClustersMergedClusters())
+	if (mSampleConfigFile->getEntityClustersGroupedClusters())
 	{
 		BBC::EntityPtr entity;
@@ -359,5 +359,5 @@
 			{			
 				BBC::EntityPtr entityClusterized = entityCluster->getEntity();
-				entityClusterized->getSubEntity(0)->setMaterialName(mSampleConfigFile->getEntityClustersMergedMaterialName());
+				entityClusterized->getSubEntity(0)->setMaterialName(mSampleConfigFile->getEntityClustersGroupedMaterialName());
 				BBC::SubEntityPtr subEntity = entityClusterized->getSubEntity(0);
 
@@ -383,7 +383,7 @@
 		mOgreMeshSerializer->setEntity(entity);
 		mOgreMeshSerializer->exportMesh(mSampleConfigFile->getEntityClustersFolder() +
-			mSampleConfigFile->getEntityClustersMergedMeshName(), false, false);
-		
-		OBA::OgreBase::getSingleton().getMeshSerializer()->exportMesh(entity->getMesh()->get(), mSampleConfigFile->getEntityClustersFolder() + mSampleConfigFile->getEntityClustersMergedMeshName());
+			mSampleConfigFile->getEntityClustersGroupedMeshName(), false, false);
+		
+		OBA::OgreBase::getSingleton().getMeshSerializer()->exportMesh(entity->getMesh()->get(), mSampleConfigFile->getEntityClustersFolder() + mSampleConfigFile->getEntityClustersGroupedMeshName());
 		//OBA::OgreBase::getSingleton().getXMLMeshSerializer()->exportMesh(entity->getMesh(), mSampleConfigFile->getEntityClustersFolder() + mSampleConfigFile->getEntityClustersMeshPrefixName() + "Merged.mesh" + ".xml");
 	}
@@ -408,5 +408,5 @@
 		mSampleConfigFile->getEntitySampleMeshName(), false, false);
 	OBA::OgreBase::getSingleton().getMeshSerializer()->exportMesh(entityLeaf->getMesh()->get(), mSampleConfigFile->getEntityDistributionFolder() + mSampleConfigFile->getEntitySampleMeshName());
-	OBA::OgreBase::getSingleton().getXMLMeshSerializer()->exportMesh(entityLeaf->getMesh()->get(), mSampleConfigFile->getEntityDistributionFolder() + mSampleConfigFile->getEntitySampleMeshName() + ".xml");	
+	//OBA::OgreBase::getSingleton().getXMLMeshSerializer()->exportMesh(entityLeaf->getMesh()->get(), mSampleConfigFile->getEntityDistributionFolder() + mSampleConfigFile->getEntitySampleMeshName() + ".xml");	
 }
 
@@ -419,5 +419,4 @@
 void LBBCManager::generateBillboardCloud()
 {
-
 	if (mSampleConfigFile->getBillboardCloudGroupedBillboards())
 	{				
@@ -425,19 +424,16 @@
 		mLeaves->getBillboardCloud()->initializeBillboardCloudGroups(mSampleConfigFile->getBillboardCloudGroups());
 		
-		if (mSampleConfigFile->getBillboardCloudDiffuseColorBillboardGroupTextureAtlasGeneration())
-		{
-			mBillboardCloudUVMapper->shutdown();
-			mBillboardCloudUVMapper->setBillboardCloud(mLeaves->getBillboardCloud());
-			mBillboardCloudUVMapper->setTextureWidth(mSampleConfigFile->getBillboardCloudDiffuseColorBillboardGroupTextureSize());
-			mBillboardCloudUVMapper->setTextureHeight(mSampleConfigFile->getBillboardCloudDiffuseColorBillboardGroupTextureSize());
-			mBillboardCloudUVMapper->setTextureAtlasWidth(mSampleConfigFile->getBillboardCloudDiffuseColorBillboardGroupTextureAtlasSize());
-			mBillboardCloudUVMapper->setTextureAtlasHeight(mSampleConfigFile->getBillboardCloudDiffuseColorBillboardGroupTextureAtlasSize());
-			mBillboardCloudUVMapper->initialize();			
-			mBillboardCloudUVMapper->generateTextureAtlasTextureCoords(false, mSampleConfigFile->getBillboardCloudGroupedBillboards(), mSampleConfigFile->getBillboardCloudGroups()); 
-			
-			mLeaves->getBillboardCloud()->generateBillboardCloudGroups();
-			//saveBillboardCloudGrouped();
-			//saveBillboardCloudGroupedXML();
-		}
+		mBillboardCloudUVMapper->shutdown();
+		mBillboardCloudUVMapper->setBillboardCloud(mLeaves->getBillboardCloud());
+		mBillboardCloudUVMapper->setTextureWidth(mSampleConfigFile->getBillboardCloudDiffuseColorGroupedBillboardsTextureSize());
+		mBillboardCloudUVMapper->setTextureHeight(mSampleConfigFile->getBillboardCloudDiffuseColorGroupedBillboardsTextureSize());
+		mBillboardCloudUVMapper->setTextureAtlasWidth(mSampleConfigFile->getBillboardCloudDiffuseColorGroupedBillboardsTextureAtlasSize());
+		mBillboardCloudUVMapper->setTextureAtlasHeight(mSampleConfigFile->getBillboardCloudDiffuseColorGroupedBillboardsTextureAtlasSize());
+		mBillboardCloudUVMapper->initialize();			
+		mBillboardCloudUVMapper->generateTextureAtlasTextureCoords(false, mSampleConfigFile->getBillboardCloudGroupedBillboards(), mSampleConfigFile->getBillboardCloudGroups()); 
+		
+		mLeaves->getBillboardCloud()->generateBillboardCloudGroups();
+		saveBillboardCloudGrouped();
+		saveBillboardCloudGroupedXML();		
 	}
 
@@ -448,19 +444,16 @@
 		mLeaves->getBillboardCloud()->initializeBillboardCloudGroups(1);
 
-		if (mSampleConfigFile->getBillboardCloudDiffuseColorMergedBillboardsTextureAtlasGeneration())
-		{
-			mBillboardCloudUVMapper->shutdown();
-			mBillboardCloudUVMapper->setBillboardCloud(mLeaves->getBillboardCloud());
-			mBillboardCloudUVMapper->setTextureWidth(mSampleConfigFile->getBillboardCloudDiffuseColorMergedBillboardsTextureSize());
-			mBillboardCloudUVMapper->setTextureHeight(mSampleConfigFile->getBillboardCloudDiffuseColorMergedBillboardsTextureSize());
-			mBillboardCloudUVMapper->setTextureAtlasWidth(mSampleConfigFile->getBillboardCloudDiffuseColorMergedBillboardsTextureAtlasSize());
-			mBillboardCloudUVMapper->setTextureAtlasHeight(mSampleConfigFile->getBillboardCloudDiffuseColorMergedBillboardsTextureAtlasSize());
-			mBillboardCloudUVMapper->initialize();
-			mBillboardCloudUVMapper->generateTextureAtlasTextureCoords(false, mSampleConfigFile->getBillboardCloudGroupedBillboards(), 1); 
-
-			mLeaves->getBillboardCloud()->generateBillboardCloudGroups();
-			saveBillboardCloudMerged();
-			saveBillboardCloudMergedXML();
-		}
+		mBillboardCloudUVMapper->shutdown();
+		mBillboardCloudUVMapper->setBillboardCloud(mLeaves->getBillboardCloud());
+		mBillboardCloudUVMapper->setTextureWidth(mSampleConfigFile->getBillboardCloudDiffuseColorMergedBillboardsTextureSize());
+		mBillboardCloudUVMapper->setTextureHeight(mSampleConfigFile->getBillboardCloudDiffuseColorMergedBillboardsTextureSize());
+		mBillboardCloudUVMapper->setTextureAtlasWidth(mSampleConfigFile->getBillboardCloudDiffuseColorMergedBillboardsTextureAtlasSize());
+		mBillboardCloudUVMapper->setTextureAtlasHeight(mSampleConfigFile->getBillboardCloudDiffuseColorMergedBillboardsTextureAtlasSize());
+		mBillboardCloudUVMapper->initialize();
+		mBillboardCloudUVMapper->generateTextureAtlasTextureCoords(false, mSampleConfigFile->getBillboardCloudGroupedBillboards(), 1); 
+
+		mLeaves->getBillboardCloud()->generateBillboardCloudGroups();
+		saveBillboardCloudMerged();
+		saveBillboardCloudMergedXML();
 	}
 
@@ -482,4 +475,72 @@
 		saveBillboardCloudXML();
 	}
+
+	saveBillboardCloudIndirectSplittedPointMeshName();
+}
+
+void LBBCManager::saveBillboardCloudIndirectSplittedPointMeshName()
+{
+	BBC::EntityPtr entity;
+	unsigned int numSubEntities = 0;
+
+	entity = BBC::EntityPtr(new BBC::Entity());
+	entity->removeSubEntity(0);
+	
+	for (unsigned int iBillboard = 0; iBillboard < getLeaves()->getBillboardCloud()->getNumBillboards(); iBillboard++)
+	{
+		BBC::BillboardPtr billboard = getLeaves()->getBillboardCloud()->getBillboard(iBillboard);		
+		BBC::EntityClusterPtr entityCluster = billboard->getBillboardClusterData()->getEntityCluster();
+
+		if (entityCluster->getNumEntitiesClusterData() > 0)
+		{					
+			entity->createSubEntity();
+			entity->getSubEntity(numSubEntities)->setMaterialName(mSampleConfigFile->getBillboardCloudIndirectPointMaterialName());
+			entity->getSubEntity(numSubEntities)->enableNormals(false);
+			entity->getSubEntity(numSubEntities)->enableTextureCoords(false);
+			entity->getSubEntity(numSubEntities)->enableVertexColours(true);
+
+			for (unsigned int iLeaf = 0; iLeaf < entityCluster->getNumEntitiesClusterData(); iLeaf++)
+			{
+				BBC::UniqueVertex vertex;
+
+				LeafKMeansClusterData *leafKMeansClusterData = (LeafKMeansClusterData*)entityCluster->getEntityClusterData(iLeaf).get();
+				Leaf *leaf = (Leaf*)leafKMeansClusterData->getEntity().get();
+				vertex.position = leaf->getPosition();
+				vertex.colour = Ogre::ColourValue(Ogre::Math::RangeRandom(0.0, 1.0), Ogre::Math::RangeRandom(0.0, 1.0), Ogre::Math::RangeRandom(0.0, 1.0), 1.0).getAsRGBA(); 
+				entity->getSubEntity(numSubEntities)->addUniqueVertex(vertex);
+			}
+
+			unsigned int iVertexFace = 0;
+			Ogre::Vector3 faceVertexIndices = Ogre::Vector3::ZERO;
+
+			for (unsigned int iVertex = 0; iVertex < entity->getSubEntity(numSubEntities)->getNumVertices(); iVertex++)
+			{
+				faceVertexIndices[iVertexFace] = iVertex;
+				iVertexFace++;
+				
+				if ((iVertex + 1) != entity->getSubEntity(numSubEntities)->getNumVertices())
+				{
+					if (iVertexFace == 3)
+					{
+						entity->getSubEntity(numSubEntities)->addFaceVerticesIDs(faceVertexIndices);
+						iVertexFace = 0;
+						faceVertexIndices = Ogre::Vector3::ZERO;
+					}
+				}
+				else
+				{
+					entity->getSubEntity(numSubEntities)->addFaceVerticesIDs(faceVertexIndices);
+				}				
+			}
+
+			numSubEntities++;
+		}
+	}
+	
+	mOgreMeshSerializer->setEntity(entity);
+	mOgreMeshSerializer->exportMesh(mSampleConfigFile->getBillboardCloudFolder() + mSampleConfigFile->getBillboardCloudIndirectPointMeshName(), false, false);
+	OBA::OgreBase::getSingleton().getMeshSerializer()->exportMesh(entity->getMesh()->get(), mSampleConfigFile->getEntityDistributionFolder() + mSampleConfigFile->getBillboardCloudIndirectPointMeshName());
+	OBA::OgreBase::getSingleton().getXMLMeshSerializer()->exportMesh(entity->getMesh()->get(), mSampleConfigFile->getEntityDistributionFolder() + mSampleConfigFile->getBillboardCloudIndirectPointMeshName() + ".xml");	
+
 }
 
