#include "terraingrid.hpp" #include #include #include #include #include "texturemanager.hpp" #include "chunkmanager.hpp" namespace Terrain { TerrainGrid::TerrainGrid(osg::Group* parent, Resource::ResourceSystem* resourceSystem, osgUtil::IncrementalCompileOperation* ico, Storage* storage, int nodeMask, Shader::ShaderManager* shaderManager, SceneUtil::UnrefQueue* unrefQueue) : Terrain::World(parent, resourceSystem, ico, storage, nodeMask) , mNumSplits(4) , mUnrefQueue(unrefQueue) , mShaderManager(shaderManager) { osg::ref_ptr material (new osg::Material); material->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE); mTerrainRoot->getOrCreateStateSet()->setAttributeAndModes(material, osg::StateAttribute::ON); mChunkManager->setShaderManager(mShaderManager); } TerrainGrid::~TerrainGrid() { while (!mGrid.empty()) { unloadCell(mGrid.begin()->first.first, mGrid.begin()->first.second); } } osg::ref_ptr TerrainGrid::cacheCell(int x, int y) { osg::Vec2f center(x+0.5f, y+0.5f); return buildTerrain(NULL, 1.f, center); } osg::ref_ptr TerrainGrid::buildTerrain (osg::Group* parent, float chunkSize, const osg::Vec2f& chunkCenter) { if (chunkSize * mNumSplits > 1.f) { // keep splitting osg::ref_ptr group (new osg::Group); if (parent) parent->addChild(group); float newChunkSize = chunkSize/2.f; buildTerrain(group, newChunkSize, chunkCenter + osg::Vec2f(newChunkSize/2.f, newChunkSize/2.f)); buildTerrain(group, newChunkSize, chunkCenter + osg::Vec2f(newChunkSize/2.f, -newChunkSize/2.f)); buildTerrain(group, newChunkSize, chunkCenter + osg::Vec2f(-newChunkSize/2.f, newChunkSize/2.f)); buildTerrain(group, newChunkSize, chunkCenter + osg::Vec2f(-newChunkSize/2.f, -newChunkSize/2.f)); return group; } else { osg::ref_ptr node = mChunkManager->getChunk(chunkSize, chunkCenter); if (!node) return NULL; if (parent) parent->addChild(node); return node; } } 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); osg::ref_ptr terrainNode = buildTerrain(NULL, 1.f, center); if (!terrainNode) return; // no terrain defined mTerrainRoot->addChild(terrainNode); mGrid[std::make_pair(x,y)] = terrainNode; } void TerrainGrid::unloadCell(int x, int y) { Grid::iterator it = mGrid.find(std::make_pair(x,y)); if (it == mGrid.end()) return; osg::ref_ptr terrainNode = it->second; mTerrainRoot->removeChild(terrainNode); if (mUnrefQueue.get()) mUnrefQueue->push(terrainNode); mGrid.erase(it); } void TerrainGrid::updateTextureFiltering() { mTextureManager->updateTextureFiltering(); } }