Index: GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/LBBC/LBBCSampleConfigFile.h
===================================================================
--- GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/LBBC/LBBCSampleConfigFile.h	(revision 731)
+++ GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/LBBC/LBBCSampleConfigFile.h	(revision 745)
@@ -52,5 +52,7 @@
 	Ogre::String getEntityClustersMeshPrefixName();
 
-	Ogre::String getEntityClustersMaterialPrefixName();
+	Ogre::String getEntityClustersMergedMaterialPrefixName();
+
+	Ogre::String getEntityClustersSplittedMaterialPrefixName();
 
 	bool getBillboardCloudMergedBillboards();
Index: GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/LBBC/LBBCManager.h
===================================================================
--- GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/LBBC/LBBCManager.h	(revision 731)
+++ GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/LBBC/LBBCManager.h	(revision 745)
@@ -21,9 +21,9 @@
     ~LBBCManager();
 
-	void runSampleConfigFile();
-
 	void loadSampleConfigFile(Ogre::String sampleConfigFile);
 
 	SampleConfigFile* getSampleConfigFile();
+
+	void initialize();
 
 	void setSampleConfigFile(SampleConfigFile *sampleConfigFile);
@@ -57,5 +57,16 @@
 	void saveBillboardCloudXML();
 
+	void saveBillboardCloudMergedXML();
+
+	void saveBillboardCloudGroupedXML();
+
 	Leaves* getLeaves();
+
+	void loadBillboardCloudXML();
+
+	void loadBillboardCloudGroupedXML();
+
+	void loadBillboardCloudMergedXML();
+
 
   protected:
Index: GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/LBBC/LBBCKMeansClusterSerializer.h
===================================================================
--- GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/LBBC/LBBCKMeansClusterSerializer.h	(revision 721)
+++ GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/LBBC/LBBCKMeansClusterSerializer.h	(revision 745)
@@ -15,6 +15,7 @@
     virtual ~KMeansClusterSerializer();
 
-	virtual void writeBillboardCloud(TiXmlDocument *document);
+	virtual void writeBillboardCloud(TiXmlDocument *document, bool groupedBillboards);
 
+	virtual void readBillboardCloud(TiXmlDocument *document, bool groupedBillboards);
 };
 
Index: GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/LBBC/LBBCKdTreeClusterSerializer.h
===================================================================
--- GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/LBBC/LBBCKdTreeClusterSerializer.h	(revision 721)
+++ GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/LBBC/LBBCKdTreeClusterSerializer.h	(revision 745)
@@ -12,5 +12,7 @@
     virtual ~KdTreeClusterSerializer();
 
-    void writeBillboardCloud(TiXmlDocument *document);
+    virtual void writeBillboardCloud(TiXmlDocument *document, bool groupedBillboards);
+
+	virtual void readBillboardCloud(TiXmlDocument *document, bool groupedBillboards);
 
 };
Index: GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/LBBC/LBBC.h
===================================================================
--- GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/LBBC/LBBC.h	(revision 731)
+++ GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/LBBC/LBBC.h	(revision 745)
@@ -10,3 +10,4 @@
 #include <LBBCClusterViewMode.h>
 #include <LBBCEntityTextureAtlasViewMode.h>
+#include <LBBCBillboardCloudTextureViewMode.h>
 #endif
Index: GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/LBBC/LBBCEntityTextureAtlasViewMode.h
===================================================================
--- GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/LBBC/LBBCEntityTextureAtlasViewMode.h	(revision 731)
+++ GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/LBBC/LBBCEntityTextureAtlasViewMode.h	(revision 745)
@@ -40,6 +40,4 @@
 		virtual ~EntityTextureAtlasViewMode();		
 
-		void setTextureAtlasFolder(Ogre::String textureAtlasFolder);
-
 		unsigned int nextPowerOf2(unsigned int nPlanes);
 
@@ -58,4 +56,6 @@
 		void setTextureAtlasName(Ogre::String textureAtlasName);
 
+		void setTextureAtlasFolder(Ogre::String textureAtlasFolder);
+
 		void setTextureAtlasSize(unsigned int size);
 };
Index: GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/LBBC/LBBCBillboardKMeansClusterData.h
===================================================================
--- GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/LBBC/LBBCBillboardKMeansClusterData.h	(revision 721)
+++ GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/LBBC/LBBCBillboardKMeansClusterData.h	(revision 745)
@@ -14,7 +14,7 @@
     virtual ~BillboardKMeansClusterData();
 
-	virtual void readBillboardClusterData(TiXmlNode *parentNode);
+	virtual void readBillboardClusterData(TiXmlNode *parentNode, int iBillboardGroup);
 
-	virtual void writeBillboardClusterData(TiXmlNode *parentNode);
+	virtual void writeBillboardClusterData(TiXmlNode *parentNode, int iBillboardGroup);
 
 	virtual void generateBillboardBoundingQuad();
Index: GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/LBBC/LBBCBillboardCloudTextureViewMode.h
===================================================================
--- GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/LBBC/LBBCBillboardCloudTextureViewMode.h	(revision 745)
+++ GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/LBBC/LBBCBillboardCloudTextureViewMode.h	(revision 745)
@@ -0,0 +1,151 @@
+#ifndef _LBBCBILLBOARDCLOUDTEXTUREVIEWMODE_H
+#define _LBBCBILLBOARDCLOUDTEXTUREVIEWMODE_H
+
+#include <LBBCPrerequisites.h>
+#include <LBBCManager.h>
+#include <IMG.h>
+#include <OBAOgreFrameListenerMode.h>
+
+namespace LBBC {
+
+class _BBCExport ClusterTextureListener : public Ogre::RenderTargetListener
+{
+protected:
+	IMG::TextureAtlasPtr mTextureAtlas;
+
+	IMG::TexturePtr mTexture;
+
+	unsigned int mNumTextures;
+
+	unsigned int mCurrentTexture;
+
+	unsigned int mSubEntityVisible;
+
+	Ogre::Entity *mEntity;
+
+public:
+	
+	void setEntity(Ogre::Entity *entity)
+	{
+		mEntity = entity;
+	}
+
+	void setSubEntityVisible(unsigned int iSubEntity)
+	{
+		mSubEntityVisible = iSubEntity;
+	}
+
+	void setTexture(IMG::TexturePtr texture)
+	{
+		mTexture = texture;
+	}
+
+	void setTextureAtlas(IMG::TextureAtlasPtr textureAtlas)
+	{
+		mTextureAtlas = textureAtlas;
+	}
+
+	void preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt)
+    {
+		if (mCurrentTexture < mNumTextures)
+		{
+			//calculateProjectionMatrix(unsigned int iSubEntity, Ogre::Camera *cam);
+			//initializeShaderParameters(unsigned int iSubEntity);
+			mTexture->getRectangle2D()->setVisible(false);
+			mTextureAtlas->getRectangle2D()->setVisible(false);
+		}
+    }
+
+	void postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt)
+    {   
+
+    }
+
+	void setNumTextures(unsigned int numTextures)
+	{
+		mNumTextures = numTextures;
+		mCurrentTexture = 0;
+	}
+
+
+};
+
+class _BBCExport TextureAtlasListener : public Ogre::RenderTargetListener
+{
+public:
+	void preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt)
+    {
+		//configureTexture( unsigned int iSubEntity );
+    }
+
+	void postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt)
+    {
+		
+    }
+};
+
+class _BBCExport BillboardCloudTextureViewMode : public OBA::OgreFrameListenerMode 
+{
+	protected:
+		unsigned int mFrame;
+
+		Ogre::SceneNode *mClusterizedEntitiesMergedSceneNode;
+		
+		Ogre::Entity *mClusterizedEntities;
+
+		ClusterTextureListener mClusterTextureListener;
+
+		TextureAtlasListener mTextureAtlasListener;
+
+		IMG::TexturePtr mClusterTexture;
+
+		IMG::TextureAtlasPtr mTextureAtlas;
+
+		unsigned int mNumTextures;
+
+		unsigned int mCurrentTexture;
+
+		unsigned int mTextureAtlasSize;
+
+		unsigned int mTextureSize;
+
+		Ogre::PixelFormat mTexturePixelFormat;
+
+		Ogre::String mEntityName;
+
+		unsigned int mBitRange;
+
+		Ogre::PixelFormat mSrcPixelFormat;
+
+		Ogre::PixelFormat mDestPixelFormat;
+
+		Ogre::String mTextureAtlasName;
+
+		Ogre::String mTextureAtlasFolder;
+
+	public:
+		BillboardCloudTextureViewMode(Ogre::RenderWindow* win, unsigned int ogreFrameListenerModeHandle, bool useBufferedInputKeys = false, bool useBufferedInputMouse = false);
+
+		virtual ~BillboardCloudTextureViewMode();		
+
+		virtual bool frameStarted(const Ogre::FrameEvent& evt, Ogre::InputReader *inputReader);
+
+		virtual void createScene();
+
+		virtual void destroyScene();
+		
+		void setTextureAtlasSize(unsigned int size);
+
+		void setTextureSize(unsigned int size);
+
+		void setEntityName(Ogre::String entityName);
+
+		void setTextureAtlasName(Ogre::String textureAtlasName);
+
+		void setTextureAtlasFolder(Ogre::String textureAtlasFolder);
+
+		void setTextureAtlasBitRange(unsigned int bitRange);
+};
+
+}
+#endif
Index: GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/BBC/BBCBillboardClusterData.h
===================================================================
--- GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/BBC/BBCBillboardClusterData.h	(revision 721)
+++ GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/BBC/BBCBillboardClusterData.h	(revision 745)
@@ -39,9 +39,11 @@
 	void setEntityCluster(EntityClusterPtr value);
 
-	virtual void readBillboardClusterData(TiXmlNode *parentNode);
+	virtual void readBillboardClusterData(TiXmlNode *parentNode, int iBillboardGroup);
 
-	virtual void writeBillboardClusterData(TiXmlNode *parentNode);
+	virtual void writeBillboardClusterData(TiXmlNode *parentNode, int iBillboardGroup);
 
 	virtual void generateBillboardBoundingQuad();
+
+	unsigned int getNumUVMapGroups();
 
 	Ogre::Vector3 getQuadTopLeftCorner();
@@ -53,4 +55,12 @@
 	Ogre::Vector3 getQuadBottomRightCorner();
 
+	void setQuadTopLeftCorner(Ogre::Vector3 topLeft);
+
+	void setQuadTopRightCorner(Ogre::Vector3 topRight);
+
+	void setQuadBottomLeftCorner(Ogre::Vector3 bottomLeft);
+
+	void setQuadBottomRightCorner(Ogre::Vector3 bottomRight);
+
 	Ogre::Vector3 getAxisX();
 
@@ -59,4 +69,21 @@
 	Ogre::Vector3 getAxisZ();
 
+	void setAxisX(Ogre::Vector3 axisX);
+
+	void setAxisY(Ogre::Vector3 axisY);
+
+	void setAxisZ(Ogre::Vector3 axisZ);
+
+	Ogre::Vector2 getBillboardUVMapMin(unsigned int iBillboardGroup);
+
+	void addBillboardUVMapMin(Ogre::Vector2 min);
+
+	void removeBillboardUVMapMin(unsigned int iBillboardGroup);
+
+	Ogre::Vector2 getBillboardUVMapMax(unsigned int iBillboardGroup);
+
+	void addBillboardUVMapMax(Ogre::Vector2 max);
+
+	void removeBillboardUVMapMax(unsigned int iBillboardGroup);
 
 
@@ -80,4 +107,8 @@
 
 	Ogre::Vector3 mNormal;
+
+	std::vector<Ogre::Vector2> mGroupedBillboardUVMapMinList;
+
+	std::vector<Ogre::Vector2> mGroupedBillboardUVMapMaxList;
 
 	float mD;
Index: GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/BBC/BBCBillboard.h
===================================================================
--- GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/BBC/BBCBillboard.h	(revision 721)
+++ GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/BBC/BBCBillboard.h	(revision 745)
@@ -31,5 +31,4 @@
   protected:
     unsigned int mBillboardHandle;
-
 
   public:
Index: GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/BBC/BBCBillboardCloudUVMapper.h
===================================================================
--- GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/BBC/BBCBillboardCloudUVMapper.h	(revision 721)
+++ GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/BBC/BBCBillboardCloudUVMapper.h	(revision 745)
@@ -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);
+	void addTextureAtlasTextureCoords(bool mergeBillboards, bool groupedBillboards, unsigned int numGeneratedBillboardClouds, unsigned int iBillboardGroup, unsigned int iBillboard);
 
     void setBillboardCloud(BillboardCloud *billboardCloud);
Index: GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/BBC/BBCBillboardGroup.h
===================================================================
--- GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/BBC/BBCBillboardGroup.h	(revision 721)
+++ GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/BBC/BBCBillboardGroup.h	(revision 745)
@@ -5,13 +5,4 @@
 
 namespace BBC {
-
-typedef struct
-{
-	unsigned int billboardHandle;
-	unsigned int width;
-	unsigned int height;
-	Ogre::Vector2 min;
-	Ogre::Vector2 max; 
-} BillboardGroupedInfo;
 
 // Forward declarations
Index: GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/BBC/BBCBillboardCloudSerializer.h
===================================================================
--- GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/BBC/BBCBillboardCloudSerializer.h	(revision 721)
+++ GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/BBC/BBCBillboardCloudSerializer.h	(revision 745)
@@ -30,5 +30,7 @@
 	BillboardCloud * getBillboardCloud();
 
-	virtual void writeBillboardCloud(TiXmlDocument *document);
+	virtual void writeBillboardCloud(TiXmlDocument *document, bool groupedBillboards);
+
+	virtual void readBillboardCloud(TiXmlDocument *document, bool groupedBillboards);
 
 };
Index: GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/BBC/BBC.h
===================================================================
--- GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/BBC/BBC.h	(revision 700)
+++ GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/BBC/BBC.h	(revision 745)
@@ -11,4 +11,6 @@
 #include <BBCBillboard.h>
 #include <BBCBillboardCloud.h>
+#include <BBCBillboardGroup.h>
+#include <BBCBillboardClusterData.h>
 #include <BBCBillboardCloudGenerator.h>
 #include <BBCEntityDistributionGenerator.h>
Index: GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/IMG/IMGTexture.h
===================================================================
--- GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/IMG/IMGTexture.h	(revision 731)
+++ GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/IMG/IMGTexture.h	(revision 745)
@@ -44,8 +44,16 @@
 	 bool mCalculatedAvgColour;
 
+	 Ogre::Camera *mCamera;
+
+	 Ogre::PixelFormat mPixelFormat;
+
   public:
      Texture();
 
      virtual ~Texture();
+
+	 void setRenderTargetListener(Ogre::RenderTargetListener *renderTargetListener);
+
+	 virtual void create(Ogre::String fileName, unsigned int width, unsigned int height, Ogre::PixelFormat pixelFormat, Ogre::Camera *camera);
 
 	 Ogre::ColourValue getAvgColour();
@@ -61,5 +69,5 @@
 	 virtual void save(Ogre::String folderName, Ogre::String filename);
 
-	 void rotate(Ogre::Real rRotation);
+	 virtual void update();
 
 	 void setCorners(Ogre::Real left, Ogre::Real top, Ogre::Real right, Ogre::Real bottom);
@@ -89,4 +97,8 @@
 	 void bind(Ogre::String textureName);
 
+	 void setCamera(Ogre::Camera *camera);
+
+	 void setFormat(Ogre::PixelFormat pixelFormat);
+
 };
 
Index: GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/IMG/IMGTextureAtlas.h
===================================================================
--- GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/IMG/IMGTextureAtlas.h	(revision 731)
+++ GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/include/IMG/IMGTextureAtlas.h	(revision 745)
@@ -25,9 +25,13 @@
 
   protected:
+	 enum CurrentTextureAtlas 
+	 {
+	     TEXTURE_ATLAS_PING,
+         TEXTURE_ATLAS_PONG
+     };
+
      Ogre::String mTextureAtlasName;
 
-	 Ogre::TexturePtr mTextureAtlas;
-
-	 Ogre::Camera *mCamera;
+	 Ogre::Texture *mTextureAtlasPong;
 	
 	 Ogre::SceneNode *mTextureAtlasSceneNode;
@@ -35,5 +39,7 @@
      std::vector<TexturePtr> mTextureList;
 
-	 Ogre::PixelFormat mPixelFormat;
+	 unsigned int mCurrentTextureAtlas;
+
+	 bool mFirstUpdate;
 
   public:
@@ -43,13 +49,11 @@
     virtual ~TextureAtlas();
 
-	unsigned int getReference();
-
-	void setFormat(Ogre::PixelFormat pixelFormat);
+	void debug();
 
 	void create(Ogre::String fileName, unsigned int width, unsigned int height, Ogre::PixelFormat pixelFormat, Ogre::Camera *camera);
 
-	void setCamera(Ogre::Camera *camera);
+	void update();
 
-	void update();
+	unsigned int getReference();
 
 	void setTextureAtlasSceneNode(Ogre::SceneNode *textureAtlasSceneNode);
Index: GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/scripts/IBRBillboardCloudTreeGenerator.vcproj
===================================================================
--- GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/scripts/IBRBillboardCloudTreeGenerator.vcproj	(revision 731)
+++ GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/scripts/IBRBillboardCloudTreeGenerator.vcproj	(revision 745)
@@ -162,7 +162,4 @@
 				</File>
 				<File
-					RelativePath="..\src\BBCBillboardCloudTextureGenerator.cpp">
-				</File>
-				<File
 					RelativePath="..\src\BBCBillboardCloudUVMapper.cpp">
 				</File>
@@ -213,4 +210,7 @@
 				Name="LBBC"
 				Filter="">
+				<File
+					RelativePath="..\src\LBBCBillboardCloudTextureViewMode.cpp">
+				</File>
 				<File
 					RelativePath="..\src\LBBCBillboardKdTreeClusterData.cpp">
@@ -353,7 +353,4 @@
 				</File>
 				<File
-					RelativePath="..\include\Bbc\BBCBillboardCloudTextureGenerator.h">
-				</File>
-				<File
 					RelativePath="..\include\Bbc\BBCBillboardCloudUVMapper.h">
 				</File>
@@ -415,4 +412,7 @@
 				<File
 					RelativePath="..\include\Lbbc\LBBC.h">
+				</File>
+				<File
+					RelativePath="..\include\Lbbc\LBBCBillboardCloudTextureViewMode.h">
 				</File>
 				<File
Index: GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCEntityTextureAtlasViewMode.cpp
===================================================================
--- GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCEntityTextureAtlasViewMode.cpp	(revision 731)
+++ GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCEntityTextureAtlasViewMode.cpp	(revision 745)
@@ -75,8 +75,10 @@
 			else  // mBitRange == 8
 			{
-				mDestPixelFormat = Ogre::PF_A8R8G8B8;
+				mDestPixelFormat = Ogre::PF_BYTE_RGBA;
 			}
 
 			mTextureAtlas->update();
+			mTextureAtlas->debug();			
+			std::cin.get();
 			mTextureAtlas->save(mTextureAtlasFolder, mTextureAtlasName, mDestPixelFormat);
 			mTextureAtlasGenerated = true;
@@ -122,8 +124,7 @@
 	IMG::TexturePtr texturePtr ( new IMG::Texture() );
 	texturePtr->bind(mTextureName);
-	Ogre::MaterialPtr materialPtr = Ogre::MaterialManager::getSingleton().create("TextureAtlas" + Ogre::StringConverter::toString(numSubTextures), "General");		
+	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)->setAmbient( texturePtr->getAvgColour() );
 	mTextureAtlas->setMaterial(materialPtr.getPointer());	
 	mTextureAtlas->setCorners(-1.0, 1.0, 1.0, -1.0);	
@@ -132,13 +133,12 @@
 	{				
 		IMG::TexturePtr texturePtr = IMG::TexturePtr( new IMG::Texture() );
-		Ogre::MaterialPtr materialPtr = Ogre::MaterialManager::getSingleton().create("TextureAtlas" + Ogre::StringConverter::toString(iSubTexture), "General");		
-		materialPtr->getTechnique(0)->getPass(0)->setAmbient( 1.0, Ogre::Math::RangeRandom(0.5,1.0), 1.0 );
+		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)->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)->getTextureUnitState(0)->setTextureFiltering(Ogre::FO_NONE, Ogre::FO_NONE, Ogre::FO_NONE);
 		materialPtr->getTechnique(0)->getPass(0)->setLightingEnabled(false);
 		
Index: GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/BBCBillboardCloudSerializer.cpp
===================================================================
--- GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/BBCBillboardCloudSerializer.cpp	(revision 699)
+++ GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/BBCBillboardCloudSerializer.cpp	(revision 745)
@@ -20,8 +20,13 @@
 }
 
-void BillboardCloudSerializer::writeBillboardCloud(TiXmlDocument *document)
+void BillboardCloudSerializer::writeBillboardCloud(TiXmlDocument *document, bool groupedBillboards)
 {
 	Ogre::LogManager::getSingleton().logMessage("BillboardCloudSerializer::writeBillboardCloud method not implemented.");
 }
 
+void BillboardCloudSerializer::readBillboardCloud(TiXmlDocument *document, bool groupedBillboards)
+{
+	Ogre::LogManager::getSingleton().logMessage("BillboardCloudSerializer::readBillboardCloud method not implemented.");
 }
+
+}
Index: GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/IBRBillboardCloudTreeApplication.cpp
===================================================================
--- GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/IBRBillboardCloudTreeApplication.cpp	(revision 731)
+++ GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/IBRBillboardCloudTreeApplication.cpp	(revision 745)
@@ -21,16 +21,42 @@
 		mSampleConfigFile = new LBBC::SampleConfigFile();
 		mSampleConfigFile->load(mOpts.cfg);
-
-		this->setup(false);
+		//this->setup(false);
+		//mLBBCManager = new LBBC::LBBCManager();	
+		//mLBBCManager->setSampleConfigFile(mSampleConfigFile);
+		////mLBBCManager->loadSampleConfigFile(mOpts.cfg);
+		//mLBBCManager->initialize();
+
+		//if (mSampleConfigFile->getEntityDistributionGeneration())
+		//{
+		//	mLBBCManager->generateEntityDistribution();
+		//}
+		//else
+		//{
+		//	mLBBCManager->loadEntityDistribution();
+		//}
+		//if (mSampleConfigFile->getEntitySampleMeshGeneration())
+		//{
+		//	mLBBCManager->saveSingleEntity();
+		//}
+		//if (mSampleConfigFile->getEntityClustersGeneration())
+		//{
+		//	mLBBCManager->generateEntityClusters();
+		//}
+		//if (mSampleConfigFile->getBillboardCloudGeneration())
+		//{
+		//	mLBBCManager->generateBillboardCloud();
+		//}
+
+		//mLBBCManager->shutdown();
+		//delete mLBBCManager;
+		//mOgreBase->shutdown();		
+		//delete mOgreBase;
+		//----------------------------------------------------------------------------
+		this->setup(true);
 		mLBBCManager = new LBBC::LBBCManager();	
 		mLBBCManager->setSampleConfigFile(mSampleConfigFile);	
 		//mLBBCManager->loadSampleConfigFile(mOpts.cfg);
-		mLBBCManager->runSampleConfigFile();	
-		mLBBCManager->shutdown();
-		delete mLBBCManager;
-		mOgreBase->shutdown();		
-		delete mOgreBase;
-		//----------------------------------------------------------------------------
-		this->setup(true);
+		mLBBCManager->initialize();
+		mLBBCManager->loadBillboardCloudMergedXML();
 		this->go();	
 		for (unsigned int iFrameListenerMode = 0; iFrameListenerMode < mFrameListener->getNumFrameListenerModes(); iFrameListenerMode++)
@@ -39,8 +65,9 @@
 		}
 		mRoot->shutdown();	
-		mWindow->destroy();		
+		mWindow->destroy();	
 		delete mRoot;
 		delete mSampleConfigFile;
 	}
+
 
 }
@@ -117,12 +144,28 @@
 
 	{
-		LBBC::ClusterViewMode *anotherFrameListenerMode;
-		anotherFrameListenerMode = new LBBC::ClusterViewMode(mWindow,mFrameListener->getNumFrameListenerModes());
+		LBBC::BillboardCloudTextureViewMode *anotherFrameListenerMode;
+		anotherFrameListenerMode = new LBBC::BillboardCloudTextureViewMode(mWindow,mFrameListener->getNumFrameListenerModes());
 		anotherFrameListenerMode->chooseSceneManager();
 		anotherFrameListenerMode->createCamera();
 		anotherFrameListenerMode->createViewports();
+		//anotherFrameListenerMode->setEntityName(Ogre::String(mSampleConfigFile->getEntityClustersMeshPrefixName() + "Merged.mesh"));
+		anotherFrameListenerMode->setTextureAtlasSize(mSampleConfigFile->getBillboardCloudDiffuseColorMergedBillboardsTextureAtlasSize());
+		anotherFrameListenerMode->setTextureSize(mSampleConfigFile->getBillboardCloudDiffuseColorMergedBillboardsTextureSize());
+		anotherFrameListenerMode->setTextureAtlasBitRange(mSampleConfigFile->getBillboardCloudDiffuseColorMergedBillboardsTextureAtlasBitRange());
+		anotherFrameListenerMode->setTextureAtlasName(mSampleConfigFile->getBillboardCloudDiffuseColorMergedBillboardsTextureAtlasPrefixName());
+		anotherFrameListenerMode->setTextureAtlasFolder(mSampleConfigFile->getBillboardCloudFolder());
 		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);
+	//}
 
 	//{
Index: GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCBillboardCloudTextureViewMode.cpp
===================================================================
--- GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCBillboardCloudTextureViewMode.cpp	(revision 745)
+++ GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCBillboardCloudTextureViewMode.cpp	(revision 745)
@@ -0,0 +1,194 @@
+
+#include "LBBCBillboardCloudTextureViewMode.h"
+#include "LBBCLeaves.h"
+#include "LBBCManager.h"
+
+namespace LBBC {
+
+BillboardCloudTextureViewMode::BillboardCloudTextureViewMode(Ogre::RenderWindow* win, unsigned int ogreFrameListenerModeHandle, bool useBufferedInputKeys, bool useBufferedInputMouse)
+:OBA::OgreFrameListenerMode(win, ogreFrameListenerModeHandle, useBufferedInputKeys, useBufferedInputMouse)
+{	
+	mFrame = 0;
+	mDebugOverlay->setScale(0.0, 0.0);
+}
+
+BillboardCloudTextureViewMode::~BillboardCloudTextureViewMode()
+{
+
+}
+
+bool BillboardCloudTextureViewMode::frameStarted(const Ogre::FrameEvent& evt, Ogre::InputReader *inputReader)
+{
+	if (mFrame == 1)
+	{
+		for (unsigned int iSubEntity = 0; iSubEntity < mClusterizedEntities->getNumSubEntities(); iSubEntity++)
+		{
+			mClusterizedEntities->getSubEntity(iSubEntity)->setVisible(false);
+		}
+	}
+	
+	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)
+		{
+			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);
+			}
+
+			mCurrentTexture = mCurrentTexture % mNumTextures;
+		}		
+	}
+
+	mFrame++;
+
+	return OgreFrameListenerMode::frameStarted(evt, inputReader);	
+}
+
+void BillboardCloudTextureViewMode::setTextureAtlasSize(unsigned int size)
+{
+	mTextureAtlasSize = size;
+}
+
+void BillboardCloudTextureViewMode::setTextureAtlasBitRange(unsigned int bitRange)
+{
+	mBitRange = bitRange;
+}
+
+void BillboardCloudTextureViewMode::setTextureSize(unsigned int size)
+{
+	mTextureSize = size;
+}
+
+void BillboardCloudTextureViewMode::setTextureAtlasFolder(Ogre::String textureAtlasFolder)
+{
+	mTextureAtlasFolder = textureAtlasFolder;
+}
+
+void BillboardCloudTextureViewMode::setTextureAtlasName(Ogre::String textureAtlasName)
+{
+	mTextureAtlasName = textureAtlasName;
+}
+
+void BillboardCloudTextureViewMode::setEntityName(Ogre::String entityName)
+{
+	mEntityName = entityName;
+}
+
+void BillboardCloudTextureViewMode::createScene()
+{
+	if (mBitRange == 32)
+	{
+		mSrcPixelFormat = Ogre::PF_FLOAT32_RGBA;
+	}
+	else if (mBitRange == 16)
+	{
+		mSrcPixelFormat = Ogre::PF_FLOAT16_RGBA;
+	}
+	else  // mBitRange == 8
+	{
+		mSrcPixelFormat = Ogre::PF_A8R8G8B8;
+	}
+
+	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();
+	//mClusterizedEntities = mSceneMgr->createEntity(mEntityName, mEntityName);
+	mClusterizedEntities = mSceneMgr->createEntity("mapleLeavesClusterizedEntitiesMerged.mesh", "mapleLeavesClusterizedEntitiesMerged.mesh");
+    mClusterizedEntitiesMergedSceneNode->attachObject(mClusterizedEntities);
+
+	mTextureAtlas = IMG::TextureAtlasPtr( new IMG::TextureAtlas() );
+	mTextureAtlas->create("TextureAtlas", mTextureAtlasSize, mTextureAtlasSize, mSrcPixelFormat, mCamera);
+	mTextureAtlas->setRenderTargetListener(&mTextureAtlasListener);
+	mTextureAtlas->setTextureAtlasSceneNode(mClusterizedEntitiesMergedSceneNode);
+	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->load();
+	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, mTexturePixelFormat, mCamera);
+	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);
+	mClusterTexture->setMaterial(materialPtr.getPointer());
+
+	mTextureAtlas->addTexture(mClusterTexture);
+	
+	mClusterTextureListener.setNumTextures(mClusterizedEntities->getNumSubEntities());
+	mClusterTextureListener.setTextureAtlas(mTextureAtlas);
+	mClusterTextureListener.setTexture(mClusterTexture);
+	mClusterTextureListener.setEntity(mClusterizedEntities);
+
+
+	mNumTextures = mClusterizedEntities->getNumSubEntities();
+	mCurrentTexture = 0;
+}
+
+void BillboardCloudTextureViewMode::destroyScene()
+{
+	
+}
+
+}
Index: GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/IMGTexture.cpp
===================================================================
--- GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/IMGTexture.cpp	(revision 731)
+++ GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/IMGTexture.cpp	(revision 745)
@@ -29,4 +29,9 @@
 	//	delete mMaterial;
 	//}
+}
+
+void Texture::setRenderTargetListener(Ogre::RenderTargetListener *renderTargetListener)
+{
+	mTexture->getBuffer(0, 0)->getRenderTarget()->addListener(renderTargetListener);
 }
 
@@ -140,7 +145,7 @@
 }
 
-void Texture::rotate(Ogre::Real rRotation)
-{
-	//mTexture->setTextureRotate( Degree( -rRotation ) );
+void Texture::update()
+{
+	mTexture->getBuffer(0, 0)->getRenderTarget()->update();
 }
 
@@ -186,3 +191,32 @@
 }
 
-}
+void Texture::create(Ogre::String fileName, unsigned int width, unsigned int height, Ogre::PixelFormat pixelFormat, Ogre::Camera *camera)
+{
+	mCamera = camera;
+	mWidth = width;
+	mHeight = height;
+	mPixelFormat = pixelFormat;
+	mTexture = Ogre::TextureManager::getSingleton().createManual(fileName, "General", Ogre::TEX_TYPE_2D, mWidth, mHeight, 0, mPixelFormat, Ogre::TU_RENDERTARGET).getPointer();
+	mTexture->getBuffer(0, 0)->getRenderTarget();
+	Ogre::RenderTexture *rt = mTexture->getBuffer()->getRenderTarget();
+	rt->setAutoUpdated(false);
+	Ogre::Viewport *v = rt->addViewport(mCamera);
+	v->setClearEveryFrame(true);
+	v->setBackgroundColour(Ogre::ColourValue(1.0f, 1.0f, 1.0f, 0.0f));
+	v->setOverlaysEnabled(false);
+	v->setDimensions(0,0,1.0,1.0);	
+	Ogre::Root::getSingleton().getRenderSystem()->clearFrameBuffer(Ogre::FBT_COLOUR, Ogre::ColourValue(1.0f,1.0f,1.0f,0.0f) );
+}
+
+void Texture::setCamera(Ogre::Camera *camera)
+{
+	mCamera = camera;
+}
+
+
+void Texture::setFormat(Ogre::PixelFormat pixelFormat)
+{
+	mPixelFormat = pixelFormat;
+}
+
+}
Index: GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/BBCBillboardCloudUVMapper.cpp
===================================================================
--- GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/BBCBillboardCloudUVMapper.cpp	(revision 731)
+++ GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/BBCBillboardCloudUVMapper.cpp	(revision 745)
@@ -118,5 +118,5 @@
 }
 
-void BillboardCloudUVMapper::addTextureAtlasTextureCoords(bool mergeBillboards, bool groupedBillboards, unsigned int numGeneratedBillboardClouds, unsigned int iBillboardGroup)
+void BillboardCloudUVMapper::addTextureAtlasTextureCoords(bool mergeBillboards, bool groupedBillboards, unsigned int numGeneratedBillboardClouds, unsigned int iBillboardGroup, unsigned int iBillboard)
 {
 	unsigned int iUniqueVertex = 0;
@@ -130,8 +130,38 @@
 	Ogre::Vector2 max = box->getMaximum();
 	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);
+	umax[1] = (max[1] / mTextureAtlasHeight);
+
+	Ogre::Vector2 umin;
+	umin[0] = (min[0] / mTextureAtlasWidth);
+	umin[1] = (min[1] / mTextureAtlasHeight);
+
+	umin = umin * 2.0 - 1.0;
+	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()->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;												
@@ -382,6 +412,5 @@
 
 					addTextureInBsp(iBillboardGroup, iBillboard);
-
-					addTextureAtlasTextureCoords(mergeBillboards, groupedBillboards, numGeneratedBillboardClouds, iBillboardGroup);
+					addTextureAtlasTextureCoords(mergeBillboards, groupedBillboards, numGeneratedBillboardClouds, iBillboardGroup, iBillboard);
 					iBillboardsInGroup++;
 				}
@@ -394,6 +423,5 @@
 
 						addTextureInBsp(iBillboardGroup, iBillboard);
-
-						addTextureAtlasTextureCoords(mergeBillboards, groupedBillboards, numGeneratedBillboardClouds, iBillboardGroup);
+						addTextureAtlasTextureCoords(mergeBillboards, groupedBillboards, numGeneratedBillboardClouds, iBillboardGroup, iBillboard);
 						iBillboardsInGroup++;
 					}
@@ -407,6 +435,5 @@
 
 						addTextureInBsp(iBillboardGroup, iBillboard);
-
-						addTextureAtlasTextureCoords(mergeBillboards, groupedBillboards, numGeneratedBillboardClouds, iBillboardGroup);
+						addTextureAtlasTextureCoords(mergeBillboards, groupedBillboards, numGeneratedBillboardClouds, iBillboardGroup, iBillboard);
 						iBillboardsInGroup++;
 					}
Index: GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCBillboardKMeansClusterData.cpp
===================================================================
--- GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCBillboardKMeansClusterData.cpp	(revision 731)
+++ GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCBillboardKMeansClusterData.cpp	(revision 745)
@@ -10,10 +10,79 @@
 }
 
-void BillboardKMeansClusterData::readBillboardClusterData(TiXmlNode *parentNode)
+void BillboardKMeansClusterData::readBillboardClusterData(TiXmlNode *billboardNode, int iBillboardGroup)
 {
-
-}
-
-void BillboardKMeansClusterData::writeBillboardClusterData(TiXmlNode *parentNode)
+	TiXmlNode *coord4dNode = billboardNode->FirstChild("coord4d");
+	Ogre::Vector3 normal;
+	normal[0] = Ogre::StringConverter::parseReal(coord4dNode->ToElement()->Attribute("nx"));
+	normal[1] = Ogre::StringConverter::parseReal(coord4dNode->ToElement()->Attribute("ny"));
+	normal[2] = Ogre::StringConverter::parseReal(coord4dNode->ToElement()->Attribute("nz"));
+	this->setNormal(normal);
+
+	TiXmlNode *topLeftNode = billboardNode->FirstChild("topLeft");	
+	Ogre::Vector3 topLeft;
+	topLeft[0] = Ogre::StringConverter::parseReal(topLeftNode->ToElement()->Attribute("x"));
+	topLeft[1] = Ogre::StringConverter::parseReal(topLeftNode->ToElement()->Attribute("y"));
+	topLeft[2] = Ogre::StringConverter::parseReal(topLeftNode->ToElement()->Attribute("z"));
+	this->setQuadTopLeftCorner(topLeft);
+
+	TiXmlNode *topRightNode = billboardNode->FirstChild("topRight");	
+	Ogre::Vector3 topRight;
+	topRight[0] = Ogre::StringConverter::parseReal(topRightNode->ToElement()->Attribute("x"));
+	topRight[1] = Ogre::StringConverter::parseReal(topRightNode->ToElement()->Attribute("y"));
+	topRight[2] = Ogre::StringConverter::parseReal(topRightNode->ToElement()->Attribute("z"));
+	this->setQuadTopRightCorner(topRight);
+
+	TiXmlNode *bottomRightNode = billboardNode->FirstChild("bottomRight");	
+	Ogre::Vector3 bottomRight;
+	bottomRight[0] = Ogre::StringConverter::parseReal(bottomRightNode->ToElement()->Attribute("x"));
+	bottomRight[1] = Ogre::StringConverter::parseReal(bottomRightNode->ToElement()->Attribute("y"));
+	bottomRight[2] = Ogre::StringConverter::parseReal(bottomRightNode->ToElement()->Attribute("z"));
+	this->setQuadBottomRightCorner(bottomRight);
+
+	TiXmlNode *bottomLeftNode = billboardNode->FirstChild("bottomLeft");	
+	Ogre::Vector3 bottomLeft;
+	bottomLeft[0] = Ogre::StringConverter::parseReal(bottomLeftNode->ToElement()->Attribute("x"));
+	bottomLeft[1] = Ogre::StringConverter::parseReal(bottomLeftNode->ToElement()->Attribute("y"));
+	bottomLeft[2] = Ogre::StringConverter::parseReal(bottomLeftNode->ToElement()->Attribute("z"));
+	this->setQuadBottomLeftCorner(bottomLeft);
+
+	TiXmlNode *axisXNode = billboardNode->FirstChild("axisX");	
+	Ogre::Vector3 axisX;
+	axisX[0] = Ogre::StringConverter::parseReal(axisXNode->ToElement()->Attribute("x"));
+	axisX[1] = Ogre::StringConverter::parseReal(axisXNode->ToElement()->Attribute("y"));
+	axisX[2] = Ogre::StringConverter::parseReal(axisXNode->ToElement()->Attribute("z"));
+	this->setAxisX(axisX);
+
+	TiXmlNode *axisYNode = billboardNode->FirstChild("axisY");	
+	Ogre::Vector3 axisY;
+	axisY[0] = Ogre::StringConverter::parseReal(axisYNode->ToElement()->Attribute("x"));
+	axisY[1] = Ogre::StringConverter::parseReal(axisYNode->ToElement()->Attribute("y"));
+	axisY[2] = Ogre::StringConverter::parseReal(axisYNode->ToElement()->Attribute("z"));
+	this->setAxisY(axisY);
+
+	TiXmlNode *axisZNode = billboardNode->FirstChild("axisZ");	
+	Ogre::Vector3 axisZ;
+	axisZ[0] = Ogre::StringConverter::parseReal(axisZNode->ToElement()->Attribute("x"));
+	axisZ[1] = Ogre::StringConverter::parseReal(axisZNode->ToElement()->Attribute("y"));
+	axisZ[2] = Ogre::StringConverter::parseReal(axisZNode->ToElement()->Attribute("z"));
+	this->setAxisZ(axisZ);
+
+	if (iBillboardGroup >= 0)
+	{
+		TiXmlNode *uvMapMinNode = billboardNode->FirstChild("uvMapMin");	
+		Ogre::Vector2 uvMapMin;
+		uvMapMin[0] = Ogre::StringConverter::parseReal(uvMapMinNode->ToElement()->Attribute("x"));
+		uvMapMin[1] = Ogre::StringConverter::parseReal(uvMapMinNode->ToElement()->Attribute("y"));
+		this->addBillboardUVMapMin(uvMapMin);
+
+		TiXmlNode *uvMapMaxNode = billboardNode->FirstChild("uvMapMax");	
+		Ogre::Vector2 uvMapMax;
+		uvMapMax[0] = Ogre::StringConverter::parseReal(uvMapMaxNode->ToElement()->Attribute("x"));
+		uvMapMax[1] = Ogre::StringConverter::parseReal(uvMapMaxNode->ToElement()->Attribute("y"));
+		this->addBillboardUVMapMax(uvMapMax);
+	}
+}
+
+void BillboardKMeansClusterData::writeBillboardClusterData(TiXmlNode *parentNode, int iBillboardGroup)
 {
 	BBC::EntityClusterPtr entityCluster = getEntityCluster();
@@ -32,4 +101,6 @@
 	TiXmlNode *billboardNode;
 	TiXmlNode *coord4dNode;
+	TiXmlNode *uvMapMin;
+	TiXmlNode *uvMapMax;
 	TiXmlNode *quadTopRightCornerNode;
 	TiXmlNode *quadTopLeftCornerNode;
@@ -107,4 +178,19 @@
 	Ogre::String sAZZ = Ogre::StringConverter::toString(getAxisZ().z);
 	axisZNode->ToElement()->SetAttribute("z",sAZZ.c_str());	
+
+	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());
+	}
 
 	leavesNode = billboardNode->ToElement()->InsertEndChild(TiXmlElement("leaves"))->ToElement();
Index: GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/IMGTextureAtlas.cpp
===================================================================
--- GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/IMGTextureAtlas.cpp	(revision 731)
+++ GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/IMGTextureAtlas.cpp	(revision 745)
@@ -8,4 +8,6 @@
 	mRectangle2D->setBoundingBox(Ogre::AxisAlignedBox(-100000.0 * Ogre::Vector3::UNIT_SCALE, 100000.0 * Ogre::Vector3::UNIT_SCALE));
 	mRectangle2D->setRenderQueueGroup(Ogre::RENDER_QUEUE_BACKGROUND);
+	mCurrentTextureAtlas = TEXTURE_ATLAS_PING;
+	mFirstUpdate = true;
 }
 
@@ -18,4 +20,32 @@
 {
 	return references;
+}
+
+void TextureAtlas::update()
+{
+	if (mCurrentTextureAtlas == TEXTURE_ATLAS_PING)
+	{
+		if (!mFirstUpdate)
+		{
+			mMaterial->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName(mTextureAtlasPong->getName());			
+			mMaterial->reload();
+			mTexture->getBuffer(0, 0)->getRenderTarget()->update();	
+		}				
+
+		if (mFirstUpdate)
+		{
+			mFirstUpdate = false;
+			mTexture->getBuffer(0, 0)->getRenderTarget()->update();
+		}
+	}
+	else
+	{
+		mMaterial->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName(mTexture->getName());
+		mMaterial->reload();
+		mTextureAtlasPong->getBuffer(0, 0)->getRenderTarget()->update();
+	}
+
+	mCurrentTextureAtlas++;
+	mCurrentTextureAtlas = mCurrentTextureAtlas % 2;
 }
 
@@ -57,4 +87,37 @@
 }
 
+void TextureAtlas::create(Ogre::String fileName, unsigned int width, unsigned int height, Ogre::PixelFormat pixelFormat, Ogre::Camera *camera)
+{
+	mCamera = camera;
+	mWidth = width;
+	mHeight = height;
+	mPixelFormat = pixelFormat;
+
+	{
+		mTexture = Ogre::TextureManager::getSingleton().createManual(fileName, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, mWidth, mHeight, 0, mPixelFormat, Ogre::TU_RENDERTARGET).getPointer();
+		mTexture->getBuffer(0, 0)->getRenderTarget();
+		Ogre::RenderTexture *rt = mTexture->getBuffer()->getRenderTarget();
+		rt->setAutoUpdated(false);
+		Ogre::Viewport *v = rt->addViewport(mCamera);
+		v->setClearEveryFrame(true);
+		v->setBackgroundColour(Ogre::ColourValue(1.0f, 1.0f, 1.0f, 0.0f));
+		v->setOverlaysEnabled(false);
+		v->setDimensions(0,0,1.0,1.0);	
+	}
+
+	{
+		mTextureAtlasPong = Ogre::TextureManager::getSingleton().createManual("PONG" + fileName, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, mWidth, mHeight, 0, mPixelFormat, Ogre::TU_RENDERTARGET).getPointer();
+		mTextureAtlasPong->getBuffer(0, 0)->getRenderTarget();
+		Ogre::RenderTexture *rt = mTextureAtlasPong->getBuffer()->getRenderTarget();
+		rt->setAutoUpdated(false);
+		Ogre::Viewport *v = rt->addViewport(mCamera);
+		v->setClearEveryFrame(true);
+		v->setBackgroundColour(Ogre::ColourValue(1.0f, 1.0f, 1.0f, 0.0f));
+		v->setOverlaysEnabled(false);
+		v->setDimensions(0,0,1.0,1.0);	
+	}
+	Ogre::Root::getSingleton().getRenderSystem()->clearFrameBuffer(Ogre::FBT_COLOUR, Ogre::ColourValue(1.0f,1.0f,1.0f,0.0f) );
+}
+
 Ogre::SceneNode* TextureAtlas::getTextureAtlasSceneNode()
 {
@@ -62,23 +125,63 @@
 }
 
-void TextureAtlas::setCamera(Ogre::Camera *camera)
-{
-	mCamera = camera;
-}
-
-void TextureAtlas::update()
-{
-	mTexture->getBuffer(0, 0)->getRenderTarget()->update();
+void TextureAtlas::debug()
+{
+	Ogre::Texture *texture;
+	if (mCurrentTextureAtlas == TEXTURE_ATLAS_PONG)
+	{
+		texture = mTexture;
+	}
+	else
+	{
+		texture = mTextureAtlasPong;
+	}
+
+	unsigned char* pBufferBox = new unsigned char[texture->getBuffer(0, 0)->getSizeInBytes()];
+
+    // Read pixels	
+	Ogre::PixelBox pBox(mWidth, mHeight, 1, mPixelFormat, pBufferBox);
+
+	texture->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;
 }
 
 void TextureAtlas::save(Ogre::String folderName, Ogre::String fileName, Ogre::PixelFormat pixelFormat)
 {	
-	unsigned char* pBufferBox = new unsigned char[mTexture->getBuffer(0, 0)->getSizeInBytes()];
-	unsigned char* pBufferDest = new unsigned char[mTexture->getBuffer(0, 0)->getSizeInBytes()];
+	Ogre::Texture *texture;
+
+	if (mCurrentTextureAtlas == TEXTURE_ATLAS_PONG)
+	{
+		texture = mTexture;
+	}
+	else
+	{
+		texture = mTextureAtlasPong;
+	}
+
+	unsigned char* pBufferBox = new unsigned char[texture->getBuffer(0, 0)->getSizeInBytes()];
+	unsigned char* pBufferDest = new unsigned char[texture->getBuffer(0, 0)->getSizeInBytes()];
 
     // Read pixels	
 	Ogre::PixelBox pBox(mWidth, mHeight, 1, mPixelFormat, pBufferBox);
 	Ogre::PixelBox pDest(mWidth, mHeight, 1, pixelFormat, pBufferDest);	
-	mTexture->getBuffer(0, 0)->blitToMemory(pBox);
+	texture->getBuffer(0, 0)->blitToMemory(pBox);
 	Ogre::PixelUtil::bulkPixelConversion(pBox.data,mPixelFormat,pDest.data,pixelFormat,pBox.getWidth()*pBox.getHeight());
 
@@ -97,5 +200,5 @@
 
 	// Wrap buffer in a chunk
-	Ogre::MemoryDataStreamPtr stream(new Ogre::MemoryDataStream(pBufferDest, mTexture->getBuffer(0, 0)->getSizeInBytes(), false));
+	Ogre::MemoryDataStreamPtr stream(new Ogre::MemoryDataStream(pBufferDest, texture->getBuffer(0, 0)->getSizeInBytes(), false));
 
     // Get codec 
@@ -124,26 +227,3 @@
 }
 
-void TextureAtlas::setFormat(Ogre::PixelFormat pixelFormat)
-{
-	mPixelFormat = pixelFormat;
-}
-
-void TextureAtlas::create(Ogre::String fileName, unsigned int width, unsigned int height, Ogre::PixelFormat pixelFormat, Ogre::Camera *camera)
-{
-	mCamera = camera;
-	mWidth = width;
-	mHeight = height;
-	mPixelFormat = pixelFormat;
-	mTexture = Ogre::TextureManager::getSingleton().createManual(fileName, "General", Ogre::TEX_TYPE_2D, mWidth, mHeight, 0, mPixelFormat, Ogre::TU_RENDERTARGET).getPointer();
-	mTexture->getBuffer(0, 0)->getRenderTarget();
-	Ogre::RenderTexture *rt = mTexture->getBuffer()->getRenderTarget();
-	rt->setAutoUpdated(false);
-	Ogre::Viewport *v = rt->addViewport(mCamera);
-	v->setClearEveryFrame(true);
-	v->setBackgroundColour(Ogre::ColourValue(1.0f, 1.0f, 1.0f, 0.0f));
-	v->setOverlaysEnabled(false);
-	v->setDimensions(0,0,1.0,1.0);	
-	Ogre::Root::getSingleton().getRenderSystem()->clearFrameBuffer(Ogre::FBT_COLOUR, Ogre::ColourValue(1.0f,1.0f,1.0f,0.0f) );
-}
-
-}
+}
Index: GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCLeafDistributionSerializer.cpp
===================================================================
--- GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCLeafDistributionSerializer.cpp	(revision 721)
+++ GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCLeafDistributionSerializer.cpp	(revision 745)
@@ -33,12 +33,12 @@
 
 	unsigned numEntities = Ogre::StringConverter::parseInt(leavesNode->ToElement()->Attribute("count"));
-	float dMin = Ogre::StringConverter::parseInt(leavesNode->ToElement()->Attribute("dMin"));
-	float dMax = Ogre::StringConverter::parseInt(leavesNode->ToElement()->Attribute("dMax"));
-	float nXMin = Ogre::StringConverter::parseInt(leavesNode->ToElement()->Attribute("nXMin"));
-	float nXMax = Ogre::StringConverter::parseInt(leavesNode->ToElement()->Attribute("nXMax"));
-	float nYMin = Ogre::StringConverter::parseInt(leavesNode->ToElement()->Attribute("nYMin"));
-	float nYMax = Ogre::StringConverter::parseInt(leavesNode->ToElement()->Attribute("nYMax"));
-	float nZMin = Ogre::StringConverter::parseInt(leavesNode->ToElement()->Attribute("nZMin"));
-	float nZMax = Ogre::StringConverter::parseInt(leavesNode->ToElement()->Attribute("nZMax"));
+	float dMin = Ogre::StringConverter::parseReal(leavesNode->ToElement()->Attribute("dMin"));
+	float dMax = Ogre::StringConverter::parseReal(leavesNode->ToElement()->Attribute("dMax"));
+	float nXMin = Ogre::StringConverter::parseReal(leavesNode->ToElement()->Attribute("nXMin"));
+	float nXMax = Ogre::StringConverter::parseReal(leavesNode->ToElement()->Attribute("nXMax"));
+	float nYMin = Ogre::StringConverter::parseReal(leavesNode->ToElement()->Attribute("nYMin"));
+	float nYMax = Ogre::StringConverter::parseReal(leavesNode->ToElement()->Attribute("nYMax"));
+	float nZMin = Ogre::StringConverter::parseReal(leavesNode->ToElement()->Attribute("nZMin"));
+	float nZMax = Ogre::StringConverter::parseReal(leavesNode->ToElement()->Attribute("nZMax"));
 
 	mLeafDistribution->setMinD(dMin);
Index: GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/BBCBillboardCloud.cpp
===================================================================
--- GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/BBCBillboardCloud.cpp	(revision 721)
+++ GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/BBCBillboardCloud.cpp	(revision 745)
@@ -136,5 +136,4 @@
 void BillboardCloud::initializeBillboardCloudGroups(unsigned int numberGroups)
 {
-
 	Ogre::LogManager::getSingleton().logMessage("Ini.Num.Billboard Groups:" + Ogre::StringConverter::toString(getNumBillboardGroups()));
 
@@ -164,4 +163,8 @@
 		if (entityCluster->getNumEntitiesClusterData() > 0)
 		{
+			for (unsigned int iBillboardGroup = 0; iBillboardGroup < billboard->getBillboardClusterData()->getNumUVMapGroups(); iBillboardGroup++)
+			{
+				billboard->getBillboardClusterData()->removeBillboardUVMapMax(iBillboardGroup);
+			}
 			numGeneratedBillboardClouds++;
 		}
Index: GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCSampleConfigFile.cpp
===================================================================
--- GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCSampleConfigFile.cpp	(revision 731)
+++ GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCSampleConfigFile.cpp	(revision 745)
@@ -132,7 +132,12 @@
 }
 
-Ogre::String SampleConfigFile::getEntityClustersMaterialPrefixName()
-{
-	return getSetting("Entity Clusters Material Prefix Name");
+Ogre::String SampleConfigFile::getEntityClustersMergedMaterialPrefixName()
+{
+	return getSetting("Entity Clusters Merged Material Prefix Name");
+}
+
+Ogre::String SampleConfigFile::getEntityClustersSplittedMaterialPrefixName()
+{
+	return getSetting("Entity Clusters Splitted Material Prefix Name");
 }
 
Index: GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/BBCBillboardClusterData.cpp
===================================================================
--- GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/BBCBillboardClusterData.cpp	(revision 721)
+++ GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/BBCBillboardClusterData.cpp	(revision 745)
@@ -10,4 +10,6 @@
 BillboardClusterData::~BillboardClusterData() 
 {
+	mGroupedBillboardUVMapMaxList.clear();
+	mGroupedBillboardUVMapMinList.clear();
 }
 
@@ -32,10 +34,10 @@
 }
 
-void BillboardClusterData::writeBillboardClusterData(TiXmlNode *parentNode)
+void BillboardClusterData::writeBillboardClusterData(TiXmlNode *parentNode, int iBillboardGroup)
 {
 	Ogre::LogManager::getSingleton().logMessage("writeBillboardClusterData method not implemented.");
 }
 
-void BillboardClusterData::readBillboardClusterData(TiXmlNode *parentNode)
+void BillboardClusterData::readBillboardClusterData(TiXmlNode *parentNode, int iBillboardGroup)
 {
 	Ogre::LogManager::getSingleton().logMessage("readBillboardClusterData method not implemented.");
@@ -77,4 +79,24 @@
 }
 
+void BillboardClusterData::setQuadTopLeftCorner(Ogre::Vector3 topLeft)
+{
+	mBillboardCorners[QUAD_TOP_LEFT] = topLeft;
+}
+
+void BillboardClusterData::setQuadTopRightCorner(Ogre::Vector3 topRight)
+{
+	mBillboardCorners[QUAD_TOP_RIGHT] = topRight;
+}
+
+void BillboardClusterData::setQuadBottomLeftCorner(Ogre::Vector3 bottomLeft)
+{
+	mBillboardCorners[QUAD_BOTTOM_LEFT] = bottomLeft;
+}
+
+void BillboardClusterData::setQuadBottomRightCorner(Ogre::Vector3 bottomRight)
+{
+	mBillboardCorners[QUAD_BOTTOM_RIGHT] = bottomRight;
+}
+
 Ogre::Vector3 BillboardClusterData::getAxisX()
 {
@@ -92,3 +114,60 @@
 }
 
+void BillboardClusterData::setAxisX(Ogre::Vector3 axisX)
+{
+	mAxisX = axisX;
 }
+
+void BillboardClusterData::setAxisY(Ogre::Vector3 axisY)
+{
+	mAxisY = axisY;
+}
+
+void BillboardClusterData::setAxisZ(Ogre::Vector3  axisZ)
+{
+	mAxisZ = axisZ;
+}
+
+Ogre::Vector2 BillboardClusterData::getBillboardUVMapMin(unsigned int iBillboardGroup)
+{
+	return mGroupedBillboardUVMapMinList[iBillboardGroup];
+}
+
+void BillboardClusterData::addBillboardUVMapMin(Ogre::Vector2 min)
+{
+	mGroupedBillboardUVMapMinList.push_back(min);
+}
+
+void BillboardClusterData::removeBillboardUVMapMin(unsigned int iBillboardGroup)
+{
+	mGroupedBillboardUVMapMinList.erase(mGroupedBillboardUVMapMinList.begin() + iBillboardGroup);
+}
+
+Ogre::Vector2 BillboardClusterData::getBillboardUVMapMax(unsigned int iBillboardGroup)
+{
+	return mGroupedBillboardUVMapMaxList[iBillboardGroup];
+}
+
+void BillboardClusterData::addBillboardUVMapMax(Ogre::Vector2 max)
+{
+	mGroupedBillboardUVMapMaxList.push_back(max);
+}
+
+void BillboardClusterData::removeBillboardUVMapMax(unsigned int iBillboardGroup)
+{
+	mGroupedBillboardUVMapMaxList.erase(mGroupedBillboardUVMapMaxList.begin() + iBillboardGroup);
+}
+
+unsigned int BillboardClusterData::getNumUVMapGroups()
+{
+	if (mGroupedBillboardUVMapMaxList.size() == mGroupedBillboardUVMapMinList.size())
+	{
+		return mGroupedBillboardUVMapMaxList.size();
+	}
+	else
+	{
+		return 0;
+	}
+}
+
+}
Index: GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCKMeansClusterSerializer.cpp
===================================================================
--- GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCKMeansClusterSerializer.cpp	(revision 721)
+++ GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCKMeansClusterSerializer.cpp	(revision 745)
@@ -10,27 +10,106 @@
 }
 
-void KMeansClusterSerializer::writeBillboardCloud(TiXmlDocument *document)
+void KMeansClusterSerializer::readBillboardCloud(TiXmlDocument *document, bool groupedBillboards)
+{
+	TiXmlNode *billboardCloudNode = document->FirstChild("billboardCloud");
+	TiXmlNode *billboardGroupsNode = billboardCloudNode->FirstChild("billboardGroups");
+
+	unsigned int numBillboardGroups = Ogre::StringConverter::parseInt(billboardGroupsNode->ToElement()->Attribute("count"));
+	
+	for (unsigned int iBillboardGroup = 0; iBillboardGroup < numBillboardGroups; iBillboardGroup++)
+	{
+		TiXmlNode *billboardGroupNode = billboardGroupsNode->FirstChild("billboardGroup");
+
+		unsigned int numBillboards = Ogre::StringConverter::parseInt(billboardGroupNode->ToElement()->Attribute("count"));
+
+		if (!groupedBillboards)
+		{
+			for (TiXmlNode *billboardNode = billboardGroupNode->FirstChild("billboard"); billboardNode; billboardNode = billboardNode->NextSibling() )
+			{
+				BBC::BillboardPtr billboard = BBC::BillboardPtr( new BBC::Billboard() );
+				BBC::BillboardClusterDataPtr billboardClusterData = BBC::BillboardClusterDataPtr( new BillboardKMeansClusterData() );
+				mBillboardCloud->addBillboard(billboard);
+				billboard->setBillboardClusterData(billboardClusterData);
+				billboard->getBillboardClusterData()->readBillboardClusterData(billboardNode, -1);
+			}
+		}
+		else
+		{
+			BBC::BillboardGroupPtr billboardGroup = BBC::BillboardGroupPtr( new BBC::BillboardGroup() );
+			mBillboardCloud->addBillboardGroup(billboardGroup);
+
+			for (TiXmlNode *billboardNode = billboardGroupNode->FirstChild("billboard"); billboardNode; billboardNode = billboardNode->NextSibling() )
+			{
+				BBC::BillboardPtr billboard = BBC::BillboardPtr( new BBC::Billboard() );
+				BBC::BillboardClusterDataPtr billboardClusterData = BBC::BillboardClusterDataPtr( new BillboardKMeansClusterData() );
+				mBillboardCloud->addBillboard(billboard);
+				billboard->setBillboardClusterData(billboardClusterData);
+				billboard->getBillboardClusterData()->readBillboardClusterData(billboardNode, iBillboardGroup);
+				billboardGroup->addBillboardHandle(billboard->getBillboardHandle());
+			}
+		}
+	}
+}
+
+void KMeansClusterSerializer::writeBillboardCloud(TiXmlDocument *document, bool groupedBillboards)
 {
 	TiXmlNode *billboardCloudNode = document->InsertEndChild(TiXmlElement("billboardCloud"))->ToElement();
 
-	unsigned int numSerializedBillboards = 0;
-	unsigned int numSerializedEntities = 0;
-	for (unsigned int iBillboard = 0; iBillboard < mBillboardCloud->getNumBillboards(); iBillboard++)
+	TiXmlNode *billboardGroupsNode = billboardCloudNode->InsertEndChild(TiXmlElement("billboardGroups"))->ToElement();	
+
+	if (!groupedBillboards)
 	{
-		BBC::BillboardPtr billboard = mBillboardCloud->getBillboard(iBillboard);
-		BBC::EntityClusterPtr entityCluster = billboard->getBillboardClusterData()->getEntityCluster();
+		billboardGroupsNode->ToElement()->SetAttribute("count",Ogre::StringConverter::toString(1));
+		TiXmlNode *billboardGroupNode = billboardGroupsNode->InsertEndChild(TiXmlElement("billboardGroup"))->ToElement();
 
-		// If the Billboard has Entities...
-		if (entityCluster->getNumEntitiesClusterData() > 0)
+		unsigned int numSerializedBillboards = 0;
+		unsigned int numSerializedEntities = 0;
+		for (unsigned int iBillboard = 0; iBillboard < mBillboardCloud->getNumBillboards(); iBillboard++)
 		{
-			BillboardKMeansClusterData *billboardKMeansClusterData = (BillboardKMeansClusterData*)billboard->getBillboardClusterData().get();
-			billboardKMeansClusterData->writeBillboardClusterData(billboardCloudNode);	
-			numSerializedBillboards++;
-			numSerializedEntities = numSerializedEntities + entityCluster->getNumEntitiesClusterData();
+			BBC::BillboardPtr billboard = mBillboardCloud->getBillboard(iBillboard);
+			BBC::EntityClusterPtr entityCluster = billboard->getBillboardClusterData()->getEntityCluster();
+
+			// If the Billboard has Entities...
+			if (entityCluster->getNumEntitiesClusterData() > 0)
+			{
+				BillboardKMeansClusterData *billboardKMeansClusterData = (BillboardKMeansClusterData*)billboard->getBillboardClusterData().get();
+				billboardKMeansClusterData->writeBillboardClusterData(billboardGroupNode, -1);	
+				numSerializedBillboards++;
+				numSerializedEntities = numSerializedEntities + entityCluster->getNumEntitiesClusterData();
+			}
 		}
+		billboardGroupNode->ToElement()->SetAttribute("count",Ogre::StringConverter::toString(numSerializedBillboards));
+		Ogre::LogManager::getSingleton().logMessage("Num.Serialized Billboards:" + Ogre::StringConverter::toString(numSerializedBillboards) + " with " + Ogre::StringConverter::toString(numSerializedEntities) + " Entities");
 	}
-	billboardCloudNode->ToElement()->SetAttribute("count",Ogre::StringConverter::toString(numSerializedBillboards));
-	
-	Ogre::LogManager::getSingleton().logMessage("Num.Serialized Billboards:" + Ogre::StringConverter::toString(numSerializedBillboards) + " with " + Ogre::StringConverter::toString(numSerializedEntities) + " Entities");
+	else
+	{
+		billboardGroupsNode->ToElement()->SetAttribute("count",Ogre::StringConverter::toString(mBillboardCloud->getNumBillboardGroups()));
+
+		unsigned int numSerializedBillboards = 0;
+		unsigned int numSerializedEntities = 0;
+
+		for (unsigned int iBillboardGroup = 0; iBillboardGroup < mBillboardCloud->getNumBillboardGroups(); iBillboardGroup++)
+		{
+			TiXmlNode *billboardGroupNode = billboardGroupsNode->InsertEndChild(TiXmlElement("billboardGroup"))->ToElement();
+
+			for (unsigned int iBillboard = 0; iBillboard < mBillboardCloud->getBillboardGroup(iBillboardGroup)->getNumBillboards(); iBillboard++)
+			{
+				BBC::BillboardPtr billboard = mBillboardCloud->getBillboard(mBillboardCloud->getBillboardGroup(iBillboardGroup)->getBillboardHandle(iBillboard));
+				BBC::EntityClusterPtr entityCluster = billboard->getBillboardClusterData()->getEntityCluster();
+
+				// If the Billboard has Entities...
+				if (entityCluster->getNumEntitiesClusterData() > 0)
+				{
+					BillboardKMeansClusterData *billboardKMeansClusterData = (BillboardKMeansClusterData*)billboard->getBillboardClusterData().get();
+					billboardKMeansClusterData->writeBillboardClusterData(billboardGroupNode, iBillboardGroup);	
+					numSerializedBillboards++;
+					numSerializedEntities = numSerializedEntities + entityCluster->getNumEntitiesClusterData();
+				}
+			}
+			billboardGroupNode->ToElement()->SetAttribute("count",Ogre::StringConverter::toString(mBillboardCloud->getBillboardGroup(iBillboardGroup)->getNumBillboards()));
+		}
+
+		Ogre::LogManager::getSingleton().logMessage("Num.Serialized Billboards:" + Ogre::StringConverter::toString(numSerializedBillboards) + " with " + Ogre::StringConverter::toString(numSerializedEntities) + " Entities");
+	}
 }
 
Index: GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCKdTreeClusterSerializer.cpp
===================================================================
--- GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCKdTreeClusterSerializer.cpp	(revision 721)
+++ GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCKdTreeClusterSerializer.cpp	(revision 745)
@@ -4,13 +4,19 @@
 namespace LBBC {
 
-KdTreeClusterSerializer::KdTreeClusterSerializer() {
+KdTreeClusterSerializer::KdTreeClusterSerializer() 
+{
 }
 
-KdTreeClusterSerializer::~KdTreeClusterSerializer() {
+KdTreeClusterSerializer::~KdTreeClusterSerializer() 
+{
 }
 
-void KdTreeClusterSerializer::writeBillboardCloud(TiXmlDocument *document) {
+void KdTreeClusterSerializer::writeBillboardCloud(TiXmlDocument *document, bool groupedBillboards) 
+{
 }
 
+void KdTreeClusterSerializer::readBillboardCloud(TiXmlDocument *document, bool groupedBillboards)
+{
+}
 
 }
Index: GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCManager.cpp
===================================================================
--- GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCManager.cpp	(revision 731)
+++ GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCManager.cpp	(revision 745)
@@ -69,8 +69,7 @@
 }
 
-void LBBCManager::runSampleConfigFile()
+void LBBCManager::initialize()
 {
 	mLeaves = new Leaves();
-	
 	BBC::EntityPtr entityLeaves(new BBC::Entity);
 	BBC::MeshPtr meshLeaves(new BBC::Mesh(this->loadMesh(mSampleConfigFile->getEntitiesFolder(), mSampleConfigFile->getEntitiesMeshPrefixName() + ".mesh")) );
@@ -78,29 +77,4 @@
 	mLeaves->setEntity(entityLeaves);
 	mLeaves->getEntity()->setMesh(meshLeaves);
-
-	if (mSampleConfigFile->getEntityDistributionGeneration())
-	{
-		generateEntityDistribution();
-	}
-	else
-	{
-		loadEntityDistribution();
-	}
-	
-	if (mSampleConfigFile->getEntitySampleMeshGeneration())
-	{
-		saveSingleEntity();
-	}
-
-	if (mSampleConfigFile->getEntityClustersGeneration())
-	{
-		generateEntityClusters();
-	}
-
-	if (mSampleConfigFile->getBillboardCloudGeneration())
-	{
-		generateBillboardCloud();
-	}	
-
 }
 
@@ -265,13 +239,4 @@
 void LBBCManager::saveBillboardCloudMerged()
 {	
-	//mLeaves->getBillboardCloud()->getEntity()->getSubEntity(0)->setMaterialName(mSampleConfigFile->getBillboardCloudMaterialPrefixName());
-	//mOgreMeshSerializer->setEntity(mLeaves->getBillboardCloud()->getEntity());
-	//mOgreMeshSerializer->exportMesh(mSampleConfigFile->getBillboardCloudFolder() +
-	//			mSampleConfigFile->getBillboardCloudMeshPrefixName() + "Merged.mesh", mSampleConfigFile->getBillboardCloudMergedBillboards(), false);
-	//OBA::OgreBase::getSingleton().getMeshSerializer()->exportMesh(mLeaves->getBillboardCloud()->getEntity()->getMesh(), 
-	//			mSampleConfigFile->getBillboardCloudFolder() + mSampleConfigFile->getBillboardCloudMeshPrefixName() + "Merged.mesh");
-	//OBA::OgreBase::getSingleton().getXMLMeshSerializer()->exportMesh(mLeaves->getBillboardCloud()->getEntity()->getMesh(), mSampleConfigFile->getBillboardCloudFolder() + mSampleConfigFile->getBillboardCloudMeshPrefixName() + "Merged.mesh.xml");
-	
-
 	for (unsigned int iSubEntity = 0; iSubEntity < mLeaves->getBillboardCloud()->getEntity()->getNumSubEntities(); iSubEntity++)
 	{
@@ -290,11 +255,60 @@
 void LBBCManager::saveBillboardCloudXML()
 {
-	//saveBillboardCloud()
 	TiXmlDocument *document2 = mBillboardCloudSerializer->create(
 									mSampleConfigFile->getBillboardCloudFolder() + 
 									mSampleConfigFile->getBillboardCloudXMLPrefixName() + ".xml");
 	mBillboardCloudSerializer->setBillboardCloud(mLeaves->getBillboardCloud());
-	mBillboardCloudSerializer->writeBillboardCloud(document2);	
+	mBillboardCloudSerializer->writeBillboardCloud(document2, false);	
 	mBillboardCloudSerializer->save();
+}
+
+void LBBCManager::saveBillboardCloudGroupedXML()
+{
+	TiXmlDocument *document2 = mBillboardCloudSerializer->create(
+									mSampleConfigFile->getBillboardCloudFolder() + 
+									mSampleConfigFile->getBillboardCloudXMLPrefixName() + "Grouped.xml");
+	mBillboardCloudSerializer->setBillboardCloud(mLeaves->getBillboardCloud());
+	mBillboardCloudSerializer->writeBillboardCloud(document2, true);	
+	mBillboardCloudSerializer->save();
+}
+
+void LBBCManager::saveBillboardCloudMergedXML()
+{
+	TiXmlDocument *document2 = mBillboardCloudSerializer->create(
+									mSampleConfigFile->getBillboardCloudFolder() + 
+									mSampleConfigFile->getBillboardCloudXMLPrefixName() + "Merged.xml");
+	mBillboardCloudSerializer->setBillboardCloud(mLeaves->getBillboardCloud());
+	mBillboardCloudSerializer->writeBillboardCloud(document2, true);	
+	mBillboardCloudSerializer->save();
+}
+
+void LBBCManager::loadBillboardCloudXML()
+{
+	TiXmlDocument *document = mBillboardCloudSerializer->load(
+									mSampleConfigFile->getBillboardCloudFolder() +
+									mSampleConfigFile->getBillboardCloudXMLPrefixName() + ".xml");
+
+	mBillboardCloudSerializer->setBillboardCloud(mLeaves->getBillboardCloud());
+	mBillboardCloudSerializer->readBillboardCloud(document, false);
+}
+
+void LBBCManager::loadBillboardCloudGroupedXML()
+{
+	TiXmlDocument *document = mBillboardCloudSerializer->load(
+									mSampleConfigFile->getBillboardCloudFolder() +
+									mSampleConfigFile->getBillboardCloudXMLPrefixName() + "Grouped.xml");
+	
+	mBillboardCloudSerializer->setBillboardCloud(mLeaves->getBillboardCloud());
+	mBillboardCloudSerializer->readBillboardCloud(document, true);
+}
+
+void LBBCManager::loadBillboardCloudMergedXML()
+{
+	TiXmlDocument *document = mBillboardCloudSerializer->load(
+									mSampleConfigFile->getBillboardCloudFolder() +
+									mSampleConfigFile->getBillboardCloudXMLPrefixName() + "Merged.xml");
+
+	mBillboardCloudSerializer->setBillboardCloud(mLeaves->getBillboardCloud());
+	mBillboardCloudSerializer->readBillboardCloud(document, true);
 }
 
@@ -316,5 +330,5 @@
 			{					
 				BBC::EntityPtr entityClusterized = entityCluster->getEntity();
-				entityClusterized->getSubEntity(0)->setMaterialName(mSampleConfigFile->getEntityClustersMaterialPrefixName());
+				entityClusterized->getSubEntity(0)->setMaterialName(mSampleConfigFile->getEntityClustersSplittedMaterialPrefixName());
 				mOgreMeshSerializer->setEntity(entityClusterized);
 				mOgreMeshSerializer->exportMesh(mSampleConfigFile->getEntityDistributionFolder() +
@@ -346,5 +360,5 @@
 			{			
 				BBC::EntityPtr entityClusterized = entityCluster->getEntity();
-				entityClusterized->getSubEntity(0)->setMaterialName(mSampleConfigFile->getEntityClustersMaterialPrefixName());
+				entityClusterized->getSubEntity(0)->setMaterialName(mSampleConfigFile->getEntityClustersMergedMaterialPrefixName());
 				BBC::SubEntityPtr subEntity = entityClusterized->getSubEntity(0);
 
@@ -367,5 +381,5 @@
 		
 		Ogre::LogManager::getSingleton().logMessage(" Mesh Generation --" + Ogre::StringConverter::toString(numSerializedBillboards));
-
+		
 		mOgreMeshSerializer->setEntity(entity);
 		mOgreMeshSerializer->exportMesh(mSampleConfigFile->getEntityClustersFolder() +
@@ -409,4 +423,27 @@
 void LBBCManager::generateBillboardCloud()
 {
+
+	if (mSampleConfigFile->getBillboardCloudGroupedBillboards())
+	{				
+		mLeaves->getBillboardCloud()->generateBillboardCloud(false);
+		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();
+		}
+	}
+
 	if (mSampleConfigFile->getBillboardCloudMergedBillboards())
 	{
@@ -424,34 +461,10 @@
 			mBillboardCloudUVMapper->setTextureAtlasHeight(mSampleConfigFile->getBillboardCloudDiffuseColorMergedBillboardsTextureAtlasSize());
 			mBillboardCloudUVMapper->initialize();
-
 			mBillboardCloudUVMapper->generateTextureAtlasTextureCoords(false, mSampleConfigFile->getBillboardCloudGroupedBillboards(), 1); 
+
+			mLeaves->getBillboardCloud()->generateBillboardCloudGroups();
+			saveBillboardCloudMerged();
+			saveBillboardCloudMergedXML();
 		}
-
-		mLeaves->getBillboardCloud()->generateBillboardCloudGroups();
-
-		saveBillboardCloudMerged();
-
-	}
-
-	if (mSampleConfigFile->getBillboardCloudGroupedBillboards())
-	{				
-		mLeaves->getBillboardCloud()->generateBillboardCloud(false);
-		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();
 	}
 
@@ -471,7 +484,6 @@
 		//}
 		saveBillboardCloudSplitted();
-	}
-
-	saveBillboardCloudXML();
+		saveBillboardCloudXML();
+	}
 }
 
