Commits

Xiangquan Xiao committed d5d8042

gsoc12-terrain: Move LoadDataRequest to LodManager

Comments (0)

Files changed (8)

Components/Terrain/include/OgreTerrain.h

 		bool canHandleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ);
 		/// WorkQueue::RequestHandler override
 		WorkQueue::Response* handleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ);
-		WorkQueue::Response* handleRequestDerivedData(const WorkQueue::Request* req, const WorkQueue* srcQ);
-		WorkQueue::Response* handleRequestLoadData(const WorkQueue::Request* req, const WorkQueue* srcQ);
 		/// WorkQueue::ResponseHandler override
 		bool canHandleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ);
 		/// WorkQueue::ResponseHandler override
 		void handleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ);
-		void handleResponseDerivedData(const WorkQueue::Response* res, const WorkQueue* srcQ);
-		void handleResponseLoadData(const WorkQueue::Response* res, const WorkQueue* srcQ);
 
 		static const uint16 WORKQUEUE_DERIVED_DATA_REQUEST;
-		static const uint16 WORKQUEUE_LOAD_DATA_REQUEST;
 
 
 		/// Utility method, get the first LOD Level at which this vertex is no longer included
 
 		size_t getPositionBufVertexSize() const;
 		size_t getDeltaBufVertexSize() const;
-
-		struct LoadRequest
-		{
-			Terrain* terrain;
-			String filename;
-			uint16 lodLevel;
-			bool readDone;
-			bool synchronous;
-			_OgreTerrainExport friend std::ostream& operator<<(std::ostream& o, const LoadRequest& r)
-			{ return o; }
-		};
-
+
 		bool mIsPrepared;	/// Is Terrain prepared?
 		TerrainLodManager mLodManager;
 		TerrainAutoUpdateLod* mAutoUpdateLod;
 			Each chunk's payload is compressed using deflate() as well.
 		  */
 		void writeGeometryData(float* data, StreamSerialiser& stream);
+
+	public:
+
 		/** Read separated geometry data from file into allocated memory
 		  @param filename A file to read from
 		  @param lodLevel Which LOD level to load
 		*/
 		bool loadLodLevel(uint lodLevel);
 
-	public:
-
 		/** Removes highest LOD level loaded
 		  @param deleteData Delete *ALL* geometry data afterwards
 		  @param onlyLast Remove LOD level only if it is lowest one in its associated vertex data range
 		/// Decrease Terrain's LOD level by 1
 		void decreaseLodLevel();
 
-		int getHighestLodStored() { return mLodManager.mHighestLodPrepared; };
+		int getHighestLodPrepared() { return mLodManager.mHighestLodPrepared; };
 		int getHighestLodLoaded() { return mLodManager.mHighestLodLoaded; };
 		int getTargetLodLevel() { return mLodManager.mTargetLodLevel; };
 

Components/Terrain/include/OgreTerrainGroup.h

 		@param x, y The coordinates of the terrain slot relative to the centre slot (signed).
 		@param synchronous Whether we should force this to happen entirely in the
 			primary thread (default false, operations are threaded if possible)
-		@remarks This method is used primarily for paging as it could run Terrain::prepare() and
-			Terrain::increaseLodLevel() in a sequence asynchronously.
 		*/
 		virtual void loadTerrain(long x, long y, bool synchronous = false);
 		

Components/Terrain/include/OgreTerrainLodManager.h

 
 namespace Ogre
 {
+	class Terrain;
 	/** \addtogroup Optional Components
 	*  @{
 	*/
 	class _OgreTerrainExport TerrainLodManager : public WorkQueue::RequestHandler, public WorkQueue::ResponseHandler
 	{
 	public:
-        TerrainLodManager();
+        TerrainLodManager(Terrain* t);
         ~TerrainLodManager();
 
 		static const uint16 WORKQUEUE_LOAD_DATA_REQUEST;
         virtual WorkQueue::Response* handleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ);
         virtual void handleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ);
 
+        uint16 getWorkQueueChannel()
+        {
+        	return mWorkQueueChannel;
+        }
+
 	public:
+		struct LoadRequest
+		{
+			Terrain* terrain;
+			String filename;
+			uint16 lodLevel;
+			bool readDone;
+			bool synchronous;
+			_OgreTerrainExport friend std::ostream& operator<<(std::ostream& o, const LoadRequest& r)
+			{ return o; }
+		};
+
 		/** Separate geometry data by LOD level
 		@param data A geometry data to separate i.e. mHeightData/mDeltaData
 		@returns Allocated array filled with separated geometry data
 		  */
 		static float* separateData(float* data, uint16 patchSize, uint16 numLodLevels);
 
-//    private:
-		uint16 mWorkQueueChannel;
 
 		int mHighestLodPrepared;  /// Highest LOD level stored in memory i.e. mHeightData/mDeltaData
 		int mHighestLodLoaded;  /// Highest LOD level loaded in GPU
 		int mTargetLodLevel;    /// Which LOD level is demanded
-		bool mIsPrepared;	/// Is Terrain prepared?
+		bool mIsPrepared;	/// Is Terrain prepared?
 		bool mIncreaseLodLevelInProgress;  /// Is increaseLodLevel() running?
+	private:
+		uint16 mWorkQueueChannel;
+		Terrain* terrain;
 	};
 	/** @} */
 	/** @} */

Components/Terrain/src/OgreTerrain.cpp

 	// since 129^2 is the greatest power we can address in 16-bit index
 	const uint16 Terrain::TERRAIN_MAX_BATCH_SIZE = 129; 
 	const uint16 Terrain::WORKQUEUE_DERIVED_DATA_REQUEST = 1;
-	const uint16 Terrain::WORKQUEUE_LOAD_DATA_REQUEST = 2;
 	const size_t Terrain::LOD_MORPH_CUSTOM_PARAM = 1001;
 	const uint8 Terrain::DERIVED_DATA_DELTAS = 1;
 	const uint8 Terrain::DERIVED_DATA_NORMALS = 2;
 		, mIsPrepared(false)
 		, mAutoUpdateLod(0)
 		, mCustomTextureAllocator(0)
-		, mLodManager()
+		, mLodManager(this)
 
 	{
 		mRootNode = sm->getRootSceneNode()->createChildSceneNode();
 		uint treeStart, treeEnd;
 		getVertexDataRange(lodLevel, &treeStart, &treeEnd);
 
-		mQuadTree->load(treeStart, treeEnd);		
+		mQuadTree->load(treeStart, treeEnd);
 
 		return true;
 	}
 	//---------------------------------------------------------------------
 	bool Terrain::canHandleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ)
 	{
-		if (req->getType() == WORKQUEUE_DERIVED_DATA_REQUEST)
-		{
-			DerivedDataRequest ddr = any_cast<DerivedDataRequest>(req->getData());
-			// only deal with own requests
-			// we do this because if we delete a terrain we want any pending tasks to be discarded
-			if (ddr.terrain != this)
-				return false;
-		}
-
-		if (req->getType() == WORKQUEUE_LOAD_DATA_REQUEST)
-		{
-			LoadRequest lreq = any_cast<LoadRequest>(req->getData());
-			// only deal with own requests
-			// we do this because if we delete a terrain we want any pending tasks to be discarded
-			if (lreq.terrain != this)
-				return false;
-		}
-
-		return RequestHandler::canHandleRequest(req, srcQ);
+		DerivedDataRequest ddr = any_cast<DerivedDataRequest>(req->getData());
+		// only deal with own requests
+		// we do this because if we delete a terrain we want any pending tasks to be discarded
+		if (ddr.terrain != this)
+			return false;
+		else
+			return RequestHandler::canHandleRequest(req, srcQ);
 
 	}
 	//---------------------------------------------------------------------
 	bool Terrain::canHandleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ)
 	{
-		if (res->getRequest()->getType() == WORKQUEUE_DERIVED_DATA_REQUEST)
-		{
-			DerivedDataRequest ddr = any_cast<DerivedDataRequest>(res->getRequest()->getData());
-			// only deal with own requests
-			// we do this because if we delete a terrain we want any pending tasks to be discarded
-			if (ddr.terrain != this)
-				return false;
-		}
-
-		if (res->getRequest()->getType() == WORKQUEUE_LOAD_DATA_REQUEST)
-		{
-			LoadRequest lreq = any_cast<LoadRequest>(res->getRequest()->getData());
-			// only deal with own requests
-			// we do this because if we delete a terrain we want any pending tasks to be discarded
-			if (lreq.terrain != this)
-				return false;
-		}
-
-		return true;
+		DerivedDataRequest ddreq = any_cast<DerivedDataRequest>(res->getRequest()->getData());
+		// only deal with own requests
+		// we do this because if we delete a terrain we want any pending tasks to be discarded
+		if (ddreq.terrain != this)
+			return false;
+		else
+			return true;
+
 	}
 	//---------------------------------------------------------------------
 	WorkQueue::Response* Terrain::handleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ)
 	{
-		if (req->getType() == WORKQUEUE_DERIVED_DATA_REQUEST)
-			return handleRequestDerivedData(req, srcQ);
-		else // if (req->getType() == WORKQUEUE_LOAD_DATA_REQUEST)
-			return handleRequestLoadData(req, srcQ);
-	}
-
-	WorkQueue::Response* Terrain::handleRequestLoadData(const WorkQueue::Request* req, const WorkQueue* srcQ)
-	{
-		LoadRequest lreq = any_cast<LoadRequest>(req->getData());
-
-		assert(mIsPrepared && "Terrain instance should have been constructed in the main thread");
-		WorkQueue::Response* response = 0;
-		float *mTempGeometryData = NULL;
-		try
-		{
-			if (!lreq.readDone)
-				// read data from file into temporary height & delta buffer
-				mTempGeometryData = readGeometryData(lreq.filename, lreq.lodLevel);
-			else
-				// create CPU vertex data
-				prepareLodLevel(lreq.lodLevel, false);							
-
-			if (mTempGeometryData)
-				response = OGRE_NEW WorkQueue::Response(req, true, Any(mTempGeometryData));
-			else response = OGRE_NEW WorkQueue::Response(req, true, Any());
-		}
-		catch (Exception& e)
-		{
-			// oops
-			response = OGRE_NEW WorkQueue::Response(req, false, Any(),
-				e.getFullDescription());
-		}
-
-		return response;
-	}
-	//---------------------------------------------------------------------
-	WorkQueue::Response* Terrain::handleRequestDerivedData(const WorkQueue::Request* req, const WorkQueue* srcQ)
-	{
 		// Background thread (maybe)
 
 		DerivedDataRequest ddr = any_cast<DerivedDataRequest>(req->getData());
 	//---------------------------------------------------------------------
 	void Terrain::handleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ)
 	{
-		if (res->getRequest()->getType() == WORKQUEUE_DERIVED_DATA_REQUEST)
-			handleResponseDerivedData(res, srcQ);
-		else // if (req->getType() == WORKQUEUE_LOAD_DATA_REQUEST)
-			handleResponseLoadData(res, srcQ);
-	}
-	void Terrain::handleResponseDerivedData(const WorkQueue::Response* res, const WorkQueue* srcQ)
-	{
 		// Main thread
 
 		DerivedDataResponse ddres = any_cast<DerivedDataResponse>(res->getData());
 			if (mCompositeMapRequired)
 				updateCompositeMap();
 		}
-	}
-		void Terrain::handleResponseLoadData(const WorkQueue::Response* res, const WorkQueue* srcQ)
-		{
-		// No response data, just request
-		LoadRequest lreq = any_cast<LoadRequest>(res->getRequest()->getData());		
-
-		if (res->succeeded())			
-		{
-			// cancel load if LOD level was removed meanwhile
-			if (mLodManager.mTargetLodLevel > lreq.lodLevel)
-			{
-				mLodManager.mIncreaseLodLevelInProgress = false;
-				return ;
-			}
-
-			if (!lreq.readDone)
-			{
-				float *mTempGeometryData = any_cast<float*>(res->getData());
-				assert(mTempGeometryData && "Temporary height/delta data can't be NULL");
-
-				// copy height & delta data into terrain's buffers
-				fillLodData(lreq.lodLevel, mTempGeometryData);
-
-				OGRE_FREE(mTempGeometryData, MEMCATEGORY_GEOMETRY);
-				mTempGeometryData = NULL;
-
-				lreq.readDone = true;
-
-				// create CPU vertex data in background thread
-				Root::getSingleton().getWorkQueue()->addRequest(
-				mWorkQueueChannel, WORKQUEUE_LOAD_DATA_REQUEST,
-					Any(lreq), 0, lreq.synchronous);
-
-				return ;
-			}
-			else
-			{
-				// create GPU data
-				loadLodLevel(lreq.lodLevel);
-
-				mLodManager.mHighestLodLoaded = lreq.lodLevel;
-
-				if (mLodManager.mTargetLodLevel < mLodManager.mHighestLodLoaded)
-				{
-					lreq.lodLevel--;
-					lreq.readDone = false;
-
-					if (mLodManager.mHighestLodPrepared != -1 && mLodManager.mTargetLodLevel >= mLodManager.mHighestLodPrepared)
-						lreq.readDone = true;
-
-					Root::getSingleton().getWorkQueue()->addRequest(
-						mWorkQueueChannel, WORKQUEUE_LOAD_DATA_REQUEST,
-						Any(lreq), 0, lreq.synchronous);
-				}
-				else mLodManager.mIncreaseLodLevelInProgress = false;
-			}
-		}
-		else
-		{
-			// oh dear
-			LogManager::getSingleton().stream(LML_CRITICAL) <<
-				"We failed to prepare the terrain with the error '" << res->getMessages() << "'";
-			// free mem ?
-		}
 
 	}
 	//---------------------------------------------------------------------
 		{
 			mLodManager.mIncreaseLodLevelInProgress = true;
 
-			LoadRequest req;
+			TerrainLodManager::LoadRequest req;
 			req.terrain = this;
 			req.lodLevel = mLodManager.mTargetLodLevel;
 			req.filename = filename;
 				req.readDone = true;
 
 			Root::getSingleton().getWorkQueue()->addRequest(
-				mWorkQueueChannel, WORKQUEUE_LOAD_DATA_REQUEST,
+				mLodManager.getWorkQueueChannel(), TerrainLodManager::WORKQUEUE_LOAD_DATA_REQUEST,
 				Any(req), 0, synchronous);
 		}
 	}

Components/Terrain/src/OgreTerrainGroup.cpp

 	//---------------------------------------------------------------------
 	void TerrainGroup::loadTerrainImpl(TerrainSlot* slot, bool synchronous)
 	{
-		slot->load = true;
-		slot->synchronous = synchronous;
+		slot->load = true;
+		slot->synchronous = synchronous;
+		if (slot->isPrepared || slot->prepareInProgress)
+			return ;
 
-		prepare(slot->x, slot->y, synchronous);
-	}
-	//---------------------------------------------------------------------
-	void TerrainGroup::prepare(long x, long y, bool synchronous /* = false */)
-	{
-		TerrainSlot* slot = getTerrainSlot(x, y, false);
-		if (slot)
+		// if not allocated
+		if (!slot->instance && 
+			(!slot->def.filename.empty() || slot->def.importData))
 		{
-			if (slot->isPrepared || slot->prepareInProgress)
-				return ;	
-
-			// if not allocated
-			TerrainSlot* slot = getTerrainSlot(x, y, false);
-			if (!slot->instance && (!slot->def.filename.empty() || slot->def.importData))
-			{
-				// Allocate in main thread so no race conditions
-				slot->instance = OGRE_NEW Terrain(mSceneManager);
-				slot->instance->setResourceGroup(mResourceGroup);
-				// Use shared pool of buffers
-				slot->instance->setGpuBufferAllocator(&mBufferAllocator);
-				slot->instance->setTextureAllocator(&mTextureAllocator);
-			}
-
-			slot->prepareInProgress = true;
+			// Allocate in main thread so no race conditions
+			slot->instance = OGRE_NEW Terrain(mSceneManager);
+			slot->instance->setResourceGroup(mResourceGroup);
+			// Use shared pool of buffers
+			slot->instance->setGpuBufferAllocator(&mBufferAllocator);
+			slot->instance->setTextureAllocator(&mTextureAllocator);
+		}
+
+			slot->prepareInProgress = true;
 
 			LoadRequest req;
 			req.slot = slot;
 			Root::getSingleton().getWorkQueue()->addRequest(
 				mWorkQueueChannel, WORKQUEUE_LOAD_REQUEST, 
 				Any(req), 0, synchronous);
-		}
 	}
 	//---------------------------------------------------------------------
 	void TerrainGroup::increaseLodLevel(long x, long y, bool synchronous /* = false */)
 		TerrainSlot* slot = getTerrainSlot(x, y, false);
 		if (slot)
 		{
-			// terrain not prepared yet
-			if (!slot->isPrepared)
-				return ;
-
+			// terrain not prepared yet
+			if (!slot->isPrepared)
+				return ;
+
 			slot->instance->increaseLodLevel(slot->def.filename, synchronous);
-			slot->isLoaded = true;
+			slot->isLoaded = true;
 		}
 	}
 	void TerrainGroup::decreaseLodLevel(long x, long y)
 				return ;
 
 			slot->instance->decreaseLodLevel();
-
-			//if (slot->instance->getHighestLodLoaded() == -1 || slot->instance->getTargetLodLevel() == -1)
-			//slot->isLoaded = false;
 		}
 	}
 	//---------------------------------------------------------------------
 		if (slot)
 		{
 			slot->freeInstance();
-			slot->isPrepared = false;
-			slot->prepareInProgress = false;
-			slot->isLoaded = false;
-			LogManager::getSingleton().stream() << "unloaded terrain (" << x << "," << y << ")";
+			slot->isPrepared = false;
+			slot->prepareInProgress = false;
+			slot->isLoaded = false;
+			LogManager::getSingleton().stream() << "unloaded terrain (" << x << "," << y << ")";
 		}
 
 
 			Terrain* terrain = slot->instance;
 			if (terrain)
 			{
-				slot->isPrepared = true;
-				slot->prepareInProgress = false;
-
+				slot->isPrepared = true;
+				slot->prepareInProgress = false;
+
 				if (slot->def.filename.empty())
 				{
 					// image imported data
 					terrain->load();
 				}
-				else if (slot->load)
+				else if (slot->load)
 				{
-					terrain->increaseLodLevel(slot->def.filename, slot->synchronous);
-					slot->isLoaded = true;
+					terrain->increaseLodLevel(slot->def.filename, slot->synchronous);
+					slot->isLoaded = true;
 				}
 
 				// do final load now we've prepared in the background

Components/Terrain/src/OgreTerrainLodManager.cpp

 #include "OgreTerrainLodManager.h"
 #include "OgreStreamSerialiser.h"
 #include "OgreRoot.h"
+#include "OgreTerrain.h"
 
 namespace Ogre
 {
-	const uint16 TerrainLodManager::WORKQUEUE_LOAD_DATA_REQUEST = 2;
-	TerrainLodManager::TerrainLodManager()
+	const uint16 TerrainLodManager::WORKQUEUE_LOAD_DATA_REQUEST = 1;
+
+	TerrainLodManager::TerrainLodManager(Terrain* t)
 		: mHighestLodPrepared(-1)
 		, mHighestLodLoaded(-1)
 		, mTargetLodLevel(-1)
 		, mIncreaseLodLevelInProgress(false)
+		, terrain(t)
 	{
 		WorkQueue* wq = Root::getSingleton().getWorkQueue();
 		mWorkQueueChannel = wq->getChannel("Ogre/TerrainLodManager");
 
     bool TerrainLodManager::canHandleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ)
     {
+		if (req->getType() == WORKQUEUE_LOAD_DATA_REQUEST)
+		{
+			LoadRequest lreq = any_cast<LoadRequest>(req->getData());
+			// only deal with own requests
+			// we do this because if we delete a terrain we want any pending tasks to be discarded
+			if (lreq.terrain != terrain)
+				return false;
+		}
+
 		return RequestHandler::canHandleRequest(req, srcQ);
     }
 
 	bool TerrainLodManager::canHandleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ)
 	{
+		if (res->getRequest()->getType() == WORKQUEUE_LOAD_DATA_REQUEST)
+		{
+			LoadRequest lreq = any_cast<LoadRequest>(res->getRequest()->getData());
+			// only deal with own requests
+			// we do this because if we delete a terrain we want any pending tasks to be discarded
+			if (lreq.terrain != terrain)
+				return false;
+		}
+
 		return true;
 	}
 
     WorkQueue::Response* TerrainLodManager::handleRequest(const WorkQueue::Request* req, const WorkQueue* srcQ)
 	{
-    	WorkQueue::Response* response = OGRE_NEW WorkQueue::Response(req, true, Any());
+		LoadRequest lreq = any_cast<LoadRequest>(req->getData());
+
+		WorkQueue::Response* response = 0;
+		float *mTempGeometryData = NULL;
+		try
+		{
+			if (!lreq.readDone)
+				// read data from file into temporary height & delta buffer
+				mTempGeometryData = terrain->readGeometryData(lreq.filename, lreq.lodLevel);
+			else
+				// create CPU vertex data
+				terrain->prepareLodLevel(lreq.lodLevel, false);
+
+			if (mTempGeometryData)
+				response = OGRE_NEW WorkQueue::Response(req, true, Any(mTempGeometryData));
+			else response = OGRE_NEW WorkQueue::Response(req, true, Any());
+		}
+		catch (Exception& e)
+		{
+			// oops
+			response = OGRE_NEW WorkQueue::Response(req, false, Any(),
+				e.getFullDescription());
+		}
 
 		return response;
+
 	}
 
     void TerrainLodManager::handleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ)
 	{
+		// No response data, just request
+		LoadRequest lreq = any_cast<LoadRequest>(res->getRequest()->getData());
+
+		if (res->succeeded())
+		{
+			// cancel load if LOD level was removed meanwhile
+			if (mTargetLodLevel > lreq.lodLevel)
+			{
+				mIncreaseLodLevelInProgress = false;
+				return ;
+			}
+
+			if (!lreq.readDone)
+			{
+				float *mTempGeometryData = any_cast<float*>(res->getData());
+				assert(mTempGeometryData && "Temporary height/delta data can't be NULL");
+
+				// copy height & delta data into terrain's buffers
+				terrain->fillLodData(lreq.lodLevel, mTempGeometryData);
+
+				OGRE_FREE(mTempGeometryData, MEMCATEGORY_GEOMETRY);
+				mTempGeometryData = NULL;
+
+				lreq.readDone = true;
+
+				// create CPU vertex data in background thread
+				Root::getSingleton().getWorkQueue()->addRequest(
+				mWorkQueueChannel, WORKQUEUE_LOAD_DATA_REQUEST,
+					Any(lreq), 0, lreq.synchronous);
+
+				return ;
+			}
+			else
+			{
+				// create GPU data
+				terrain->loadLodLevel(lreq.lodLevel);
+
+				mHighestLodLoaded = lreq.lodLevel;
+
+				if (mTargetLodLevel < mHighestLodLoaded)
+				{
+					lreq.lodLevel--;
+					lreq.readDone = false;
+
+					if (mHighestLodPrepared != -1 && mTargetLodLevel >= mHighestLodPrepared)
+						lreq.readDone = true;
+
+					Root::getSingleton().getWorkQueue()->addRequest(
+						mWorkQueueChannel, WORKQUEUE_LOAD_DATA_REQUEST,
+						Any(lreq), 0, lreq.synchronous);
+				}
+				else
+					mIncreaseLodLevelInProgress = false;
+			}
+		}
+		else
+		{
+			// oh dear
+			LogManager::getSingleton().stream(LML_CRITICAL) <<
+				"We failed to prepare the terrain with the error '" << res->getMessages() << "'";
+			// free mem ?
+		}
 	}
 
     // data are reorganized from lowest lod level(mNumLodLevels-1) to highest(0)
-	float* TerrainLodManager::separateData(float* data, uint16 patchSize, uint16 numLodLevels )
+	float* TerrainLodManager::separateData(float* data, uint16 batchSize, uint16 numLodLevels )
 	{
-		float* ret = OGRE_ALLOC_T(float, patchSize*patchSize, MEMCATEGORY_GENERAL);
+		float* ret = OGRE_ALLOC_T(float, batchSize*batchSize, MEMCATEGORY_GENERAL);
 
 		unsigned int ptr = 0;
 		unsigned int inc, prev;
 			inc = 1 << lvl;
 			prev = 1 << (lvl + 1);
 
-			for (uint16 y = 0; y < patchSize; y += inc)
+			for (uint16 y = 0; y < batchSize; y += inc)
 			{
-				for (uint16 x = 0; x < patchSize-1; x += inc)
+				for (uint16 x = 0; x < batchSize-1; x += inc)
 				{
 					if ((lvl == numLodLevels - 1) || ((x % prev != 0) || (y % prev != 0)))
-						ret[ptr++] = *(data + y * patchSize + x);
+						ret[ptr++] = *(data + y * batchSize + x);
 				}
 				if ((lvl == numLodLevels -1) || (y % prev) != 0)
-				ret[ptr++] = *(data + y * patchSize + patchSize - 1);
+				ret[ptr++] = *(data + y * batchSize + batchSize - 1);
 
-				if (y+inc > patchSize)
+				if (y+inc > batchSize)
 					break;
 			}
 		}

Samples/Terrain/include/Terrain.h

 			TERRAIN_PAGE_MIN_X, TERRAIN_PAGE_MIN_Y, 
 			TERRAIN_PAGE_MAX_X, TERRAIN_PAGE_MAX_Y);
 #else
-		// sync load since we want everything in place when we start
 		for (long x = TERRAIN_PAGE_MIN_X; x <= TERRAIN_PAGE_MAX_X; ++x)
 			for (long y = TERRAIN_PAGE_MIN_Y; y <= TERRAIN_PAGE_MAX_Y; ++y)
-			{
 				defineTerrain(x, y, blankTerrain);
-				mTerrainGroup->prepare(x,y,true);
+		// sync load since we want everything in place when we start
+		mTerrainGroup->loadAllTerrains(true);
+		for (long x = TERRAIN_PAGE_MIN_X; x <= TERRAIN_PAGE_MAX_X; ++x)
+			for (long y = TERRAIN_PAGE_MIN_Y; y <= TERRAIN_PAGE_MAX_Y; ++y)
 				for (int i = mTerrainGroup->getTerrain(x,y)->getNumLodLevels(); i > 0; i--)
 				    mTerrainGroup->increaseLodLevel(x,y,true);
-			}
 #endif
 
 		if (mTerrainsImported)

Samples/TerrainPaging/include/TerrainPaging.h

 				OverlayElement *l = OverlayManager::getSingleton().createOverlayElement("TextArea", lName);
 				l->setCaption(StringConverter::toString(t->getTargetLodLevel())+"/"+
 					  StringConverter::toString(t->getHighestLodLoaded())+"/"+
-					  StringConverter::toString(t->getHighestLodStored()));
+					  StringConverter::toString(t->getHighestLodPrepared()));
 				l->setPosition(x, y);
 				l->setDimensions(0.1, 0.1);  // centre text in label and its position
 				l->setParameter("font_name", "StarWars");