/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield * * This library is open source and may be redistributed and/or modified under * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or * (at your option) any later version. The full license is in LICENSE file * included with this distribution, and on the openscenegraph.org website. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * OpenSceneGraph Public License for more details. */ #include #include #include #include using namespace osg; using namespace osgTerrain; Terrain::Terrain(): _sampleRatio(1.0), _verticalScale(1.0), _blendingPolicy(TerrainTile::INHERIT), _equalizeBoundaries(false) { setNumChildrenRequiringUpdateTraversal(1); } Terrain::Terrain(const Terrain& ts, const osg::CopyOp& copyop): osg::CoordinateSystemNode(ts,copyop), _sampleRatio(ts._sampleRatio), _verticalScale(ts._verticalScale), _blendingPolicy(ts._blendingPolicy), _equalizeBoundaries(ts._equalizeBoundaries), _terrainTechnique(ts._terrainTechnique) { setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()+1); } Terrain::~Terrain() { OpenThreads::ScopedLock lock(_mutex); for(TerrainTileSet::iterator itr = _terrainTileSet.begin(); itr != _terrainTileSet.end(); ++itr) { const_cast(*itr)->_terrain = 0; } _terrainTileSet.clear(); _terrainTileMap.clear(); } void Terrain::setSampleRatio(float ratio) { if (_sampleRatio == ratio) return; _sampleRatio = ratio; dirtyRegisteredTiles(); } void Terrain::setVerticalScale(float scale) { if (_verticalScale == scale) return; _verticalScale = scale; dirtyRegisteredTiles(); } void Terrain::setEqualizeBoundaries(bool equalizeBoundaries) { if(_equalizeBoundaries == equalizeBoundaries) return; _equalizeBoundaries = equalizeBoundaries; dirtyRegisteredTiles(); } void Terrain::setBlendingPolicy(TerrainTile::BlendingPolicy policy) { if (_blendingPolicy == policy) return; _blendingPolicy = policy; dirtyRegisteredTiles(); } void Terrain::traverse(osg::NodeVisitor& nv) { if (nv.getVisitorType()==osg::NodeVisitor::UPDATE_VISITOR) { // need to check if any TerrainTechniques need to have their update called on them. osgUtil::UpdateVisitor* uv = dynamic_cast(&nv); if (uv) { typedef std::list< osg::ref_ptr > TerrainTileList; TerrainTileList tiles; { OpenThreads::ScopedLock lock(_mutex); std::copy(_updateTerrainTileSet.begin(), _updateTerrainTileSet.end(), std::back_inserter(tiles)); _updateTerrainTileSet.clear(); } for(TerrainTileList::iterator itr = tiles.begin(); itr != tiles.end(); ++itr) { TerrainTile* tile = itr->get(); tile->traverse(nv); } } } Group::traverse(nv); } void Terrain::updateTerrainTileOnNextFrame(TerrainTile* terrainTile) { OpenThreads::ScopedLock lock(_mutex); _updateTerrainTileSet.insert(terrainTile); } TerrainTile* Terrain::getTile(const TileID& tileID) { OpenThreads::ScopedLock lock(_mutex); // OSG_NOTICE<<"Terrain::getTile("<second; } const TerrainTile* Terrain::getTile(const TileID& tileID) const { OpenThreads::ScopedLock lock(_mutex); TerrainTileMap::const_iterator itr = _terrainTileMap.find(tileID); if (itr == _terrainTileMap.end()) return 0; return itr->second; } void Terrain::dirtyRegisteredTiles(int dirtyMask) { OpenThreads::ScopedLock lock(_mutex); for(TerrainTileSet::iterator itr = _terrainTileSet.begin(); itr != _terrainTileSet.end(); ++itr) { (const_cast(*itr))->setDirtyMask(dirtyMask); } } static unsigned int s_maxNumTiles = 0; void Terrain::registerTerrainTile(TerrainTile* tile) { if (!tile) return; OpenThreads::ScopedLock lock(_mutex); if (tile->getTileID().valid()) { _terrainTileMap[tile->getTileID()] = tile; } _terrainTileSet.insert(tile); if (_terrainTileSet.size() > s_maxNumTiles) s_maxNumTiles = _terrainTileSet.size(); // OSG_NOTICE<<"Terrain::registerTerrainTile "<getTileID().level<<", "<getTileID().x<<", "<getTileID().y<<")"< lock(_mutex); if (tile->getTileID().valid()) { _terrainTileMap.erase(tile->getTileID()); } _terrainTileSet.erase(tile); _updateTerrainTileSet.erase(tile); // OSG_NOTICE<<"Terrain::unregisterTerrainTile "<