forked from teamnwah/openmw-tes3coop
Preload terrain
This commit is contained in:
parent
98848c752a
commit
0865cea211
13 changed files with 152 additions and 66 deletions
|
@ -258,16 +258,21 @@ namespace MWRender
|
|||
return mResourceSystem;
|
||||
}
|
||||
|
||||
SceneUtil::WorkQueue *RenderingManager::getWorkQueue()
|
||||
SceneUtil::WorkQueue* RenderingManager::getWorkQueue()
|
||||
{
|
||||
return mWorkQueue.get();
|
||||
}
|
||||
|
||||
SceneUtil::UnrefQueue *RenderingManager::getUnrefQueue()
|
||||
SceneUtil::UnrefQueue* RenderingManager::getUnrefQueue()
|
||||
{
|
||||
return mUnrefQueue.get();
|
||||
}
|
||||
|
||||
Terrain::World* RenderingManager::getTerrain()
|
||||
{
|
||||
return mTerrain.get();
|
||||
}
|
||||
|
||||
void RenderingManager::preloadCommonAssets()
|
||||
{
|
||||
osg::ref_ptr<PreloadCommonAssetsWorkItem> workItem (new PreloadCommonAssetsWorkItem(mResourceSystem));
|
||||
|
@ -279,12 +284,6 @@ namespace MWRender
|
|||
mWorkQueue->addWorkItem(workItem);
|
||||
}
|
||||
|
||||
void RenderingManager::clearCache()
|
||||
{
|
||||
if (mTerrain.get())
|
||||
mTerrain->clearCache();
|
||||
}
|
||||
|
||||
double RenderingManager::getReferenceTime() const
|
||||
{
|
||||
return mViewer->getFrameStamp()->getReferenceTime();
|
||||
|
@ -838,7 +837,7 @@ namespace MWRender
|
|||
void RenderingManager::updateTextureFiltering()
|
||||
{
|
||||
if (mTerrain.get())
|
||||
mTerrain->clearCache();
|
||||
mTerrain->updateCache();
|
||||
|
||||
mResourceSystem->getSceneManager()->setFilterSettings(
|
||||
Settings::Manager::getString("texture mag filter", "General"),
|
||||
|
|
|
@ -73,11 +73,10 @@ namespace MWRender
|
|||
|
||||
SceneUtil::WorkQueue* getWorkQueue();
|
||||
SceneUtil::UnrefQueue* getUnrefQueue();
|
||||
Terrain::World* getTerrain();
|
||||
|
||||
void preloadCommonAssets();
|
||||
|
||||
void clearCache();
|
||||
|
||||
double getReferenceTime() const;
|
||||
|
||||
osg::Group* getLightRoot();
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <components/resource/keyframemanager.hpp>
|
||||
#include <components/misc/resourcehelpers.hpp>
|
||||
#include <components/nifosg/nifloader.hpp>
|
||||
#include <components/terrain/world.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/world.hpp"
|
||||
|
@ -44,10 +45,14 @@ namespace MWWorld
|
|||
{
|
||||
public:
|
||||
/// Constructor to be called from the main thread.
|
||||
PreloadItem(MWWorld::CellStore* cell, Resource::SceneManager* sceneManager, Resource::BulletShapeManager* bulletShapeManager, Resource::KeyframeManager* keyframeManager)
|
||||
: mSceneManager(sceneManager)
|
||||
PreloadItem(MWWorld::CellStore* cell, Resource::SceneManager* sceneManager, Resource::BulletShapeManager* bulletShapeManager, Resource::KeyframeManager* keyframeManager, Terrain::World* terrain)
|
||||
: mIsExterior(cell->getCell()->isExterior())
|
||||
, mX(cell->getCell()->getGridX())
|
||||
, mY(cell->getCell()->getGridY())
|
||||
, mSceneManager(sceneManager)
|
||||
, mBulletShapeManager(bulletShapeManager)
|
||||
, mKeyframeManager(keyframeManager)
|
||||
, mTerrain(terrain)
|
||||
{
|
||||
osg::Timer timer;
|
||||
ListModelsVisitor visitor (mMeshes);
|
||||
|
@ -86,8 +91,8 @@ namespace MWWorld
|
|||
|
||||
//std::cout << "preloading " << mesh << std::endl;
|
||||
|
||||
mPreloadedNodes.push_back(mSceneManager->cacheInstance(mesh));
|
||||
mPreloadedShapes.push_back(mBulletShapeManager->cacheInstance(mesh));
|
||||
mPreloadedObjects.push_back(mSceneManager->cacheInstance(mesh));
|
||||
mPreloadedObjects.push_back(mBulletShapeManager->cacheInstance(mesh));
|
||||
|
||||
size_t slashpos = mesh.find_last_of("/\\");
|
||||
if (slashpos != std::string::npos && slashpos != mesh.size()-1)
|
||||
|
@ -99,7 +104,7 @@ namespace MWWorld
|
|||
if(kfname.size() > 4 && kfname.compare(kfname.size()-4, 4, ".nif") == 0)
|
||||
{
|
||||
kfname.replace(kfname.size()-4, 4, ".kf");
|
||||
mPreloadedKeyframes.push_back(mKeyframeManager->get(kfname));
|
||||
mPreloadedObjects.push_back(mKeyframeManager->get(kfname));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -111,29 +116,44 @@ namespace MWWorld
|
|||
// error will be shown when visiting the cell
|
||||
}
|
||||
}
|
||||
std::cout << "preloaded " << mPreloadedNodes.size() << " nodes in " << preloadTimer.time_m() << std::endl;
|
||||
|
||||
if (mIsExterior)
|
||||
{
|
||||
try
|
||||
{
|
||||
mPreloadedObjects.push_back(mTerrain->cacheCell(mX, mY));
|
||||
}
|
||||
catch(std::exception& e)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "preloaded " << mPreloadedObjects.size() << " objects in " << preloadTimer.time_m() << std::endl;
|
||||
}
|
||||
|
||||
private:
|
||||
typedef std::vector<std::string> MeshList;
|
||||
bool mIsExterior;
|
||||
int mX;
|
||||
int mY;
|
||||
MeshList mMeshes;
|
||||
Resource::SceneManager* mSceneManager;
|
||||
Resource::BulletShapeManager* mBulletShapeManager;
|
||||
Resource::KeyframeManager* mKeyframeManager;
|
||||
Terrain::World* mTerrain;
|
||||
|
||||
// keep a ref to the loaded object to make sure it stays loaded as long as this cell is in the preloaded state
|
||||
std::vector<osg::ref_ptr<const osg::Node> > mPreloadedNodes;
|
||||
std::vector<osg::ref_ptr<const Resource::BulletShapeInstance> > mPreloadedShapes;
|
||||
std::vector<osg::ref_ptr<const NifOsg::KeyframeHolder> > mPreloadedKeyframes;
|
||||
// keep a ref to the loaded objects to make sure it stays loaded as long as this cell is in the preloaded state
|
||||
std::vector<osg::ref_ptr<const osg::Object> > mPreloadedObjects;
|
||||
};
|
||||
|
||||
/// Worker thread item: update the resource system's cache, effectively deleting unused entries.
|
||||
class UpdateCacheItem : public SceneUtil::WorkItem
|
||||
{
|
||||
public:
|
||||
UpdateCacheItem(Resource::ResourceSystem* resourceSystem, double referenceTime)
|
||||
UpdateCacheItem(Resource::ResourceSystem* resourceSystem, Terrain::World* terrain, double referenceTime)
|
||||
: mReferenceTime(referenceTime)
|
||||
, mResourceSystem(resourceSystem)
|
||||
, mTerrain(terrain)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -141,17 +161,21 @@ namespace MWWorld
|
|||
{
|
||||
osg::Timer timer;
|
||||
mResourceSystem->updateCache(mReferenceTime);
|
||||
|
||||
mTerrain->updateCache();
|
||||
std::cout << "cleared cache in " << timer.time_m() << std::endl;
|
||||
}
|
||||
|
||||
private:
|
||||
double mReferenceTime;
|
||||
Resource::ResourceSystem* mResourceSystem;
|
||||
Terrain::World* mTerrain;
|
||||
};
|
||||
|
||||
CellPreloader::CellPreloader(Resource::ResourceSystem* resourceSystem, Resource::BulletShapeManager* bulletShapeManager)
|
||||
CellPreloader::CellPreloader(Resource::ResourceSystem* resourceSystem, Resource::BulletShapeManager* bulletShapeManager, Terrain::World* terrain)
|
||||
: mResourceSystem(resourceSystem)
|
||||
, mBulletShapeManager(bulletShapeManager)
|
||||
, mTerrain(terrain)
|
||||
, mExpiryDelay(0.0)
|
||||
{
|
||||
}
|
||||
|
@ -177,7 +201,7 @@ namespace MWWorld
|
|||
return;
|
||||
}
|
||||
|
||||
osg::ref_ptr<PreloadItem> item (new PreloadItem(cell, mResourceSystem->getSceneManager(), mBulletShapeManager, mResourceSystem->getKeyframeManager()));
|
||||
osg::ref_ptr<PreloadItem> item (new PreloadItem(cell, mResourceSystem->getSceneManager(), mBulletShapeManager, mResourceSystem->getKeyframeManager(), mTerrain));
|
||||
mWorkQueue->addWorkItem(item);
|
||||
|
||||
mPreloadCells[cell] = PreloadEntry(timestamp, item);
|
||||
|
@ -201,7 +225,7 @@ namespace MWWorld
|
|||
}
|
||||
|
||||
// the resource cache is cleared from the worker thread so that we're not holding up the main thread with delete operations
|
||||
mWorkQueue->addWorkItem(new UpdateCacheItem(mResourceSystem, timestamp));
|
||||
mWorkQueue->addWorkItem(new UpdateCacheItem(mResourceSystem, mTerrain, timestamp));
|
||||
}
|
||||
|
||||
void CellPreloader::setExpiryDelay(double expiryDelay)
|
||||
|
|
|
@ -11,6 +11,11 @@ namespace Resource
|
|||
class BulletShapeManager;
|
||||
}
|
||||
|
||||
namespace Terrain
|
||||
{
|
||||
class World;
|
||||
}
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
class CellStore;
|
||||
|
@ -18,7 +23,7 @@ namespace MWWorld
|
|||
class CellPreloader
|
||||
{
|
||||
public:
|
||||
CellPreloader(Resource::ResourceSystem* resourceSystem, Resource::BulletShapeManager* bulletShapeManager);
|
||||
CellPreloader(Resource::ResourceSystem* resourceSystem, Resource::BulletShapeManager* bulletShapeManager, Terrain::World* terrain);
|
||||
|
||||
/// Ask a background thread to preload rendering meshes and collision shapes for objects in this cell.
|
||||
/// @note The cell itself must be in State_Loaded or State_Preloaded.
|
||||
|
@ -37,6 +42,7 @@ namespace MWWorld
|
|||
private:
|
||||
Resource::ResourceSystem* mResourceSystem;
|
||||
Resource::BulletShapeManager* mBulletShapeManager;
|
||||
Terrain::World* mTerrain;
|
||||
osg::ref_ptr<SceneUtil::WorkQueue> mWorkQueue;
|
||||
double mExpiryDelay;
|
||||
|
||||
|
|
|
@ -416,7 +416,6 @@ namespace MWWorld
|
|||
mCellChanged = true;
|
||||
|
||||
mPreloader->updateCache(mRendering.getReferenceTime());
|
||||
mRendering.clearCache();
|
||||
|
||||
std::cout << "changeCellGrid took " << timer.time_m() << std::endl;
|
||||
}
|
||||
|
@ -463,7 +462,7 @@ namespace MWWorld
|
|||
, mPreloadDoors(Settings::Manager::getBool("preload doors", "Cells"))
|
||||
, mPreloadFastTravel(Settings::Manager::getBool("preload fast travel", "Cells"))
|
||||
{
|
||||
mPreloader.reset(new CellPreloader(rendering.getResourceSystem(), physics->getShapeManager()));
|
||||
mPreloader.reset(new CellPreloader(rendering.getResourceSystem(), physics->getShapeManager(), rendering.getTerrain()));
|
||||
mPreloader->setWorkQueue(mRendering.getWorkQueue());
|
||||
|
||||
mPhysics->setUnrefQueue(rendering.getUnrefQueue());
|
||||
|
@ -549,7 +548,6 @@ namespace MWWorld
|
|||
MWBase::Environment::get().getWindowManager()->changeCell(mCurrentCell);
|
||||
|
||||
mPreloader->updateCache(mRendering.getReferenceTime());
|
||||
mRendering.clearCache();
|
||||
|
||||
std::cout << "change to interior took " << timer.time_m() << std::endl;
|
||||
}
|
||||
|
|
|
@ -19,11 +19,6 @@ namespace Resource
|
|||
mCache->removeExpiredObjectsInCache(referenceTime - mExpiryDelay);
|
||||
}
|
||||
|
||||
void ResourceManager::clearCache()
|
||||
{
|
||||
mCache->clear();
|
||||
}
|
||||
|
||||
void ResourceManager::setExpiryDelay(double expiryDelay)
|
||||
{
|
||||
mExpiryDelay = expiryDelay;
|
||||
|
|
|
@ -22,9 +22,6 @@ namespace Resource
|
|||
/// Clear cache entries that have not been referenced for longer than expiryDelay.
|
||||
virtual void updateCache(double referenceTime);
|
||||
|
||||
/// Clear all cache entries regardless of having external references.
|
||||
virtual void clearCache();
|
||||
|
||||
/// How long to keep objects in cache after no longer being referenced.
|
||||
void setExpiryDelay (double expiryDelay);
|
||||
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
#include <cassert>
|
||||
|
||||
#include <OpenThreads/ScopedLock>
|
||||
|
||||
#include <osg/PrimitiveSet>
|
||||
|
||||
#include "defs.hpp"
|
||||
|
@ -178,6 +180,7 @@ namespace Terrain
|
|||
|
||||
osg::ref_ptr<osg::Vec2Array> BufferCache::getUVBuffer()
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mUvBufferMutex);
|
||||
if (mUvBufferMap.find(mNumVerts) != mUvBufferMap.end())
|
||||
{
|
||||
return mUvBufferMap[mNumVerts];
|
||||
|
@ -206,6 +209,7 @@ namespace Terrain
|
|||
|
||||
osg::ref_ptr<osg::DrawElements> BufferCache::getIndexBuffer(unsigned int flags)
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mIndexBufferMutex);
|
||||
unsigned int verts = mNumVerts;
|
||||
|
||||
if (mIndexBufferMap.find(flags) != mIndexBufferMap.end())
|
||||
|
|
|
@ -17,8 +17,10 @@ namespace Terrain
|
|||
|
||||
/// @param flags first 4*4 bits are LOD deltas on each edge, respectively (4 bits each)
|
||||
/// next 4 bits are LOD level of the index buffer (LOD 0 = don't omit any vertices)
|
||||
/// @note Thread safe.
|
||||
osg::ref_ptr<osg::DrawElements> getIndexBuffer (unsigned int flags);
|
||||
|
||||
/// @note Thread safe.
|
||||
osg::ref_ptr<osg::Vec2Array> getUVBuffer();
|
||||
|
||||
// TODO: add releaseGLObjects() for our vertex/element buffer objects
|
||||
|
@ -27,8 +29,10 @@ namespace Terrain
|
|||
// Index buffers are shared across terrain batches where possible. There is one index buffer for each
|
||||
// combination of LOD deltas and index buffer LOD we may need.
|
||||
std::map<int, osg::ref_ptr<osg::DrawElements> > mIndexBufferMap;
|
||||
OpenThreads::Mutex mIndexBufferMutex;
|
||||
|
||||
std::map<int, osg::ref_ptr<osg::Vec2Array> > mUvBufferMap;
|
||||
OpenThreads::Mutex mUvBufferMutex;
|
||||
|
||||
unsigned int mNumVerts;
|
||||
};
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
#include <memory>
|
||||
|
||||
#include <OpenThreads/ScopedLock>
|
||||
|
||||
#include <components/resource/resourcesystem.hpp>
|
||||
#include <components/resource/imagemanager.hpp>
|
||||
#include <components/resource/scenemanager.hpp>
|
||||
|
@ -50,9 +52,9 @@ namespace Terrain
|
|||
TerrainGrid::TerrainGrid(osg::Group* parent, Resource::ResourceSystem* resourceSystem, osgUtil::IncrementalCompileOperation* ico, Storage* storage, int nodeMask, SceneUtil::UnrefQueue* unrefQueue)
|
||||
: Terrain::World(parent, resourceSystem, ico, storage, nodeMask)
|
||||
, mNumSplits(4)
|
||||
, mCache((storage->getCellVertices()-1)/static_cast<float>(mNumSplits) + 1)
|
||||
, mUnrefQueue(unrefQueue)
|
||||
{
|
||||
mCache = BufferCache((storage->getCellVertices()-1)/static_cast<float>(mNumSplits) + 1);
|
||||
}
|
||||
|
||||
TerrainGrid::~TerrainGrid()
|
||||
|
@ -63,6 +65,21 @@ TerrainGrid::~TerrainGrid()
|
|||
}
|
||||
}
|
||||
|
||||
osg::ref_ptr<osg::Node> TerrainGrid::cacheCell(int x, int y)
|
||||
{
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mGridCacheMutex);
|
||||
Grid::iterator found = mGridCache.find(std::make_pair(x,y));
|
||||
if (found != mGridCache.end())
|
||||
return found->second;
|
||||
}
|
||||
osg::ref_ptr<osg::Node> node = buildTerrain(NULL, 1.f, osg::Vec2f(x+0.5, y+0.5));
|
||||
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mGridCacheMutex);
|
||||
mGridCache.insert(std::make_pair(std::make_pair(x,y), node));
|
||||
return node;
|
||||
}
|
||||
|
||||
osg::ref_ptr<osg::Node> TerrainGrid::buildTerrain (osg::Group* parent, float chunkSize, const osg::Vec2f& chunkCenter)
|
||||
{
|
||||
if (chunkSize * mNumSplits > 1.f)
|
||||
|
@ -131,19 +148,22 @@ osg::ref_ptr<osg::Node> TerrainGrid::buildTerrain (osg::Group* parent, float chu
|
|||
unsigned int dummyTextureCounter = 0;
|
||||
|
||||
std::vector<osg::ref_ptr<osg::Texture2D> > layerTextures;
|
||||
for (std::vector<LayerInfo>::const_iterator it = layerList.begin(); it != layerList.end(); ++it)
|
||||
{
|
||||
osg::ref_ptr<osg::Texture2D> texture = mTextureCache[it->mDiffuseMap];
|
||||
if (!texture)
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mTextureCacheMutex);
|
||||
for (std::vector<LayerInfo>::const_iterator it = layerList.begin(); it != layerList.end(); ++it)
|
||||
{
|
||||
texture = new osg::Texture2D(mResourceSystem->getImageManager()->getImage(it->mDiffuseMap));
|
||||
texture->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT);
|
||||
texture->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT);
|
||||
mResourceSystem->getSceneManager()->applyFilterSettings(texture);
|
||||
mTextureCache[it->mDiffuseMap] = texture;
|
||||
osg::ref_ptr<osg::Texture2D> texture = mTextureCache[it->mDiffuseMap];
|
||||
if (!texture)
|
||||
{
|
||||
texture = new osg::Texture2D(mResourceSystem->getImageManager()->getImage(it->mDiffuseMap));
|
||||
texture->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT);
|
||||
texture->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT);
|
||||
mResourceSystem->getSceneManager()->applyFilterSettings(texture);
|
||||
mTextureCache[it->mDiffuseMap] = texture;
|
||||
}
|
||||
layerTextures.push_back(texture);
|
||||
textureCompileDummy->getOrCreateStateSet()->setTextureAttributeAndModes(dummyTextureCounter++, layerTextures.back());
|
||||
}
|
||||
layerTextures.push_back(texture);
|
||||
textureCompileDummy->getOrCreateStateSet()->setTextureAttributeAndModes(dummyTextureCounter++, layerTextures.back());
|
||||
}
|
||||
|
||||
std::vector<osg::ref_ptr<osg::Texture2D> > blendmapTextures;
|
||||
|
@ -196,11 +216,27 @@ void TerrainGrid::loadCell(int x, int y)
|
|||
if (mGrid.find(std::make_pair(x, y)) != mGrid.end())
|
||||
return; // already loaded
|
||||
|
||||
osg::Vec2f center(x+0.5f, y+0.5f);
|
||||
// try to get it from the cache
|
||||
osg::ref_ptr<osg::Node> terrainNode;
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mGridCacheMutex);
|
||||
Grid::const_iterator found = mGridCache.find(std::make_pair(x,y));
|
||||
if (found != mGridCache.end())
|
||||
{
|
||||
terrainNode = found->second;
|
||||
if (!terrainNode)
|
||||
return; // no terrain defined
|
||||
}
|
||||
}
|
||||
|
||||
osg::ref_ptr<osg::Node> terrainNode = buildTerrain(NULL, 1.f, center);
|
||||
// didn't find in cache, build it
|
||||
if (!terrainNode)
|
||||
return; // no terrain defined
|
||||
{
|
||||
osg::Vec2f center(x+0.5f, y+0.5f);
|
||||
terrainNode = buildTerrain(NULL, 1.f, center);
|
||||
if (!terrainNode)
|
||||
return; // no terrain defined
|
||||
}
|
||||
|
||||
mTerrainRoot->addChild(terrainNode);
|
||||
|
||||
|
@ -213,7 +249,7 @@ void TerrainGrid::unloadCell(int x, int y)
|
|||
if (it == mGrid.end())
|
||||
return;
|
||||
|
||||
osg::Node* terrainNode = it->second;
|
||||
osg::ref_ptr<osg::Node> terrainNode = it->second;
|
||||
mTerrainRoot->removeChild(terrainNode);
|
||||
|
||||
if (mUnrefQueue.get())
|
||||
|
@ -222,18 +258,28 @@ void TerrainGrid::unloadCell(int x, int y)
|
|||
mGrid.erase(it);
|
||||
}
|
||||
|
||||
void TerrainGrid::clearCache()
|
||||
void TerrainGrid::updateCache()
|
||||
{
|
||||
for (TextureCache::iterator it = mTextureCache.begin(); it != mTextureCache.end();)
|
||||
{
|
||||
if (it->second->referenceCount() <= 1)
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mTextureCacheMutex);
|
||||
for (TextureCache::iterator it = mTextureCache.begin(); it != mTextureCache.end();)
|
||||
{
|
||||
if (mUnrefQueue.get())
|
||||
mUnrefQueue->push(it->second);
|
||||
mTextureCache.erase(it++);
|
||||
if (it->second->referenceCount() <= 1)
|
||||
mTextureCache.erase(it++);
|
||||
else
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mGridCacheMutex);
|
||||
for (Grid::iterator it = mGridCache.begin(); it != mGridCache.end();)
|
||||
{
|
||||
if (it->second->referenceCount() <= 1)
|
||||
mGridCache.erase(it++);
|
||||
else
|
||||
++it;
|
||||
}
|
||||
else
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,11 +21,20 @@ namespace Terrain
|
|||
TerrainGrid(osg::Group* parent, Resource::ResourceSystem* resourceSystem, osgUtil::IncrementalCompileOperation* ico, Storage* storage, int nodeMask, SceneUtil::UnrefQueue* unrefQueue = NULL);
|
||||
~TerrainGrid();
|
||||
|
||||
/// Load a terrain cell and store it in cache for later use.
|
||||
/// @note The returned ref_ptr should be kept by the caller to ensure that the terrain stays in cache for as long as needed.
|
||||
/// @note Thread safe.
|
||||
virtual osg::ref_ptr<osg::Node> cacheCell(int x, int y);
|
||||
|
||||
/// @note Not thread safe.
|
||||
virtual void loadCell(int x, int y);
|
||||
|
||||
/// @note Not thread safe.
|
||||
virtual void unloadCell(int x, int y);
|
||||
|
||||
/// Clear cached textures that are no longer referenced
|
||||
void clearCache();
|
||||
/// Clear cached objects that are no longer referenced
|
||||
/// @note Thread safe.
|
||||
void updateCache();
|
||||
|
||||
private:
|
||||
osg::ref_ptr<osg::Node> buildTerrain (osg::Group* parent, float chunkSize, const osg::Vec2f& chunkCenter);
|
||||
|
@ -35,10 +44,16 @@ namespace Terrain
|
|||
|
||||
typedef std::map<std::string, osg::ref_ptr<osg::Texture2D> > TextureCache;
|
||||
TextureCache mTextureCache;
|
||||
OpenThreads::Mutex mTextureCacheMutex;
|
||||
|
||||
typedef std::map<std::pair<int, int>, osg::ref_ptr<osg::Node> > Grid;
|
||||
Grid mGrid;
|
||||
|
||||
Grid mGridCache;
|
||||
OpenThreads::Mutex mGridCacheMutex;
|
||||
|
||||
BufferCache mCache;
|
||||
|
||||
osg::ref_ptr<SceneUtil::UnrefQueue> mUnrefQueue;
|
||||
};
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@ namespace Terrain
|
|||
World::World(osg::Group* parent, Resource::ResourceSystem* resourceSystem, osgUtil::IncrementalCompileOperation* ico,
|
||||
Storage* storage, int nodeMask)
|
||||
: mStorage(storage)
|
||||
, mCache(storage->getCellVertices())
|
||||
, mParent(parent)
|
||||
, mResourceSystem(resourceSystem)
|
||||
, mIncrementalCompileOperation(ico)
|
||||
|
|
|
@ -39,10 +39,12 @@ namespace Terrain
|
|||
Storage* storage, int nodeMask);
|
||||
virtual ~World();
|
||||
|
||||
virtual void clearCache() {}
|
||||
virtual void updateCache() {}
|
||||
|
||||
float getHeightAt (const osg::Vec3f& worldPos);
|
||||
|
||||
virtual osg::ref_ptr<osg::Node> cacheCell(int x, int y) {return NULL;}
|
||||
|
||||
// This is only a hint and may be ignored by the implementation.
|
||||
virtual void loadCell(int x, int y) {}
|
||||
virtual void unloadCell(int x, int y) {}
|
||||
|
@ -52,8 +54,6 @@ namespace Terrain
|
|||
protected:
|
||||
Storage* mStorage;
|
||||
|
||||
BufferCache mCache;
|
||||
|
||||
osg::ref_ptr<osg::Group> mParent;
|
||||
osg::ref_ptr<osg::Group> mTerrainRoot;
|
||||
|
||||
|
|
Loading…
Reference in a new issue