diff --git a/include/osgTerrain/GeometryTechnique b/include/osgTerrain/GeometryTechnique index 859543c0f..c22cf5b6d 100644 --- a/include/osgTerrain/GeometryTechnique +++ b/include/osgTerrain/GeometryTechnique @@ -38,16 +38,7 @@ class OSGTERRAIN_EXPORT GeometryTechnique : public TerrainTechnique virtual Locator* computeMasterLocator(); - virtual osg::Vec3d computeCenterModel(Locator* masterLocator); - virtual void generateGeometry(Locator* masterLocator, const osg::Vec3d& centerModel); - - virtual void applyColorLayers(); - - virtual void applyTransparency(); - - virtual void smoothGeometry(); - virtual void update(osgUtil::UpdateVisitor* nv); virtual void cull(osgUtil::CullVisitor* nv); @@ -86,24 +77,32 @@ class OSGTERRAIN_EXPORT GeometryTechnique : public TerrainTechnique virtual ~GeometryTechnique(); - struct BufferData + class BufferData : public osg::Referenced { + public: + BufferData() {} + osg::ref_ptr _transform; osg::ref_ptr _geode; osg::ref_ptr _geometry; - }; - - unsigned int _currentReadOnlyBuffer; - unsigned int _currentWriteBuffer; - - BufferData _bufferData[2]; - - void swapBuffers(); - inline BufferData& getReadOnlyBuffer() { return _bufferData[_currentReadOnlyBuffer]; } - inline BufferData& getWriteBuffer() { return _bufferData[_currentWriteBuffer]; } - - + protected: + ~BufferData() {} + }; + + virtual osg::Vec3d computeCenterModel(BufferData& buffer, Locator* masterLocator); + + virtual void generateGeometry(BufferData& buffer, Locator* masterLocator, const osg::Vec3d& centerModel); + + virtual void applyColorLayers(BufferData& buffer); + + virtual void applyTransparency(BufferData& buffer); + + + OpenThreads::Mutex _writeBufferMutex; + osg::ref_ptr _currentBufferData; + osg::ref_ptr _newBufferData; + float _filterBias; osg::ref_ptr _filterBiasUniform; float _filterWidth; diff --git a/include/osgTerrain/Terrain b/include/osgTerrain/Terrain index abe6b3b53..ff3c91cd1 100644 --- a/include/osgTerrain/Terrain +++ b/include/osgTerrain/Terrain @@ -91,6 +91,9 @@ class OSGTERRAIN_EXPORT Terrain : public osg::Group /** Get the const TerrainTechnique protype*/ const TerrainTechnique* getTerrainTechniquePrototype() const { return _terrainTechnique.get(); } + /** Tell the Terrain node to call the terrainTile's TerrainTechnique on the next update traversal.*/ + void updateTerrainTileOnNextFrame(TerrainTile* terrainTile); + protected: virtual ~Terrain(); @@ -112,6 +115,7 @@ class OSGTERRAIN_EXPORT Terrain : public osg::Group mutable OpenThreads::Mutex _mutex; TerrainTileSet _terrainTileSet; TerrainTileMap _terrainTileMap; + TerrainTileSet _updateTerrainTileSet; osg::ref_ptr _terrainTechnique; }; diff --git a/include/osgTerrain/TerrainTechnique b/include/osgTerrain/TerrainTechnique index 1922cddbd..3dcd32b64 100644 --- a/include/osgTerrain/TerrainTechnique +++ b/include/osgTerrain/TerrainTechnique @@ -25,7 +25,31 @@ namespace osgTerrain { class TerrainTile; -class OSGTERRAIN_EXPORT TerrainTechnique : public osg::Object +class OSGTERRAIN_EXPORT TerrainNeighbours +{ + public: + + TerrainNeighbours(); + ~TerrainNeighbours(); + + void clear(); + void addNeighbour(TerrainTile* tile); + void removeNeighbour(TerrainTile* tile); + bool containsNeighbour(TerrainTile* tile) const; + + protected: + + TerrainNeighbours(const TerrainNeighbours& tn) {} + TerrainNeighbours& operator = (const TerrainNeighbours& rhs) { return *this; } + + typedef std::set Neighbours; + + mutable OpenThreads::Mutex _neighboursMutex; + Neighbours _neighbours; +}; + + +class OSGTERRAIN_EXPORT TerrainTechnique : public osg::Object, public osg::Observer { public: @@ -33,7 +57,7 @@ class OSGTERRAIN_EXPORT TerrainTechnique : public osg::Object /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ TerrainTechnique(const TerrainTechnique&,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); - + META_Object(osgTerrain, TerrainTechnique); TerrainTile* getTerrainTile() { return _terrainTile; } @@ -56,15 +80,26 @@ class OSGTERRAIN_EXPORT TerrainTechnique : public osg::Object * for all graphics contexts. */ virtual void releaseGLObjects(osg::State* = 0) const {} + void addNeighbour(TerrainTile* tile) { _neighbours.addNeighbour(tile); } + void removeNeighbour(TerrainTile* tile) { _neighbours.removeNeighbour(tile); } + + bool containsNeighbour(TerrainTile* tile) { return _neighbours.containsNeighbour(tile); } + TerrainNeighbours& getNeighbours() { return _neighbours; } + const TerrainNeighbours& getNeighbours() const { return _neighbours; } + protected: - - void setDirty(bool dirty); virtual ~TerrainTechnique(); - + + void setTerrainTile(TerrainTile* tile); + void setDirty(bool dirty); + friend class osgTerrain::TerrainTile; - TerrainTile* _terrainTile; + TerrainTile* _terrainTile; + + + TerrainNeighbours _neighbours; }; diff --git a/include/osgTerrain/TerrainTile b/include/osgTerrain/TerrainTile index 2ac187474..ab5e8ba87 100644 --- a/include/osgTerrain/TerrainTile +++ b/include/osgTerrain/TerrainTile @@ -69,7 +69,7 @@ class OSGTERRAIN_EXPORT TerrainTile : public osg::Group public: TerrainTile(); - + /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ TerrainTile(const TerrainTile&,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); @@ -172,11 +172,32 @@ class OSGTERRAIN_EXPORT TerrainTile : public osg::Group BlendingPolicy getBlendingPolicy() const { return _blendingPolicy; } + enum DirtyMask + { + NOT_DIRTY = 0, + IMAGERY_DIRTY = 1<<0, + ELEVATION_DIRTY = 1<<1, + LEFT_EDGE_DIRTY = 1<<2, + RIGHT_EDGE_DIRTY = 1<<3, + TOP_EDGE_DIRTY = 1<<4, + BOTTOM_EDGE_DIRTY = 1<<5, + EDGES_DIRTY = LEFT_EDGE_DIRTY | RIGHT_EDGE_DIRTY | TOP_EDGE_DIRTY | BOTTOM_EDGE_DIRTY, + ALL_DIRTY = IMAGERY_DIRTY | ELEVATION_DIRTY | EDGES_DIRTY + }; + /** Set the dirty flag on/off.*/ - void setDirty(bool dirty); + void setDirty(bool dirty) { setDirtyMask(dirty ? ALL_DIRTY : NOT_DIRTY); } + + /** return true if the any of the DirtyMask are set.*/ + int getDirty() const { return _dirtyMask!=NOT_DIRTY; } + + + /** Set the dirty flag on/off.*/ + void setDirtyMask(int dirtyMask); /** return true if the tile is dirty and needs to be updated,*/ - bool getDirty() const { return _dirty; } + int getDirtyMask() const { return _dirtyMask; } + /** Compute the bounding volume of the terrain by computing the union of the bounding volumes of all layers.*/ virtual osg::BoundingSphere computeBound() const; @@ -207,7 +228,7 @@ class OSGTERRAIN_EXPORT TerrainTile : public osg::Group Terrain* _terrain; - bool _dirty; + int _dirtyMask; bool _hasBeenTraversal; TileID _tileID; diff --git a/src/osgTerrain/GeometryTechnique.cpp b/src/osgTerrain/GeometryTechnique.cpp index 30bd8cd5e..238f2811c 100644 --- a/src/osgTerrain/GeometryTechnique.cpp +++ b/src/osgTerrain/GeometryTechnique.cpp @@ -15,7 +15,6 @@ #include #include -#include #include #include @@ -32,10 +31,7 @@ using namespace osgTerrain; #define NEW_COORD_CODE -GeometryTechnique::GeometryTechnique(): - _currentReadOnlyBuffer(1), - _currentWriteBuffer(0) - +GeometryTechnique::GeometryTechnique() { setFilterBias(0); setFilterWidth(0.1); @@ -44,9 +40,7 @@ GeometryTechnique::GeometryTechnique(): } GeometryTechnique::GeometryTechnique(const GeometryTechnique& gt,const osg::CopyOp& copyop): - TerrainTechnique(gt,copyop), - _currentReadOnlyBuffer(1), - _currentWriteBuffer(0) + TerrainTechnique(gt,copyop) { setFilterBias(gt._filterBias); setFilterWidth(gt._filterWidth); @@ -57,11 +51,6 @@ GeometryTechnique::~GeometryTechnique() { } -void GeometryTechnique::swapBuffers() -{ - std::swap(_currentReadOnlyBuffer,_currentWriteBuffer); -} - void GeometryTechnique::setFilterBias(float filterBias) { _filterBias = filterBias; @@ -112,23 +101,57 @@ void GeometryTechnique::init() if (!_terrainTile) return; - BufferData& buffer = getWriteBuffer(); + OpenThreads::ScopedLock lock(_writeBufferMutex); + + // take a temporary referecen + osg::ref_ptr tile = _terrainTile; + + if (_terrainTile->getDirtyMask()==0) return; + + osg::ref_ptr buffer = new BufferData; Locator* masterLocator = computeMasterLocator(); - osg::Vec3d centerModel = computeCenterModel(masterLocator); + osg::Vec3d centerModel = computeCenterModel(*buffer, masterLocator); - generateGeometry(masterLocator, centerModel); + if ((_terrainTile->getDirtyMask() & TerrainTile::IMAGERY_DIRTY)==0) + { + generateGeometry(*buffer, masterLocator, centerModel); - applyColorLayers(); + osg::ref_ptr read_buffer = _currentBufferData; - applyTransparency(); + osg::StateSet* stateset = read_buffer->_geode->getStateSet(); + if (stateset) + { + // OSG_NOTICE<<"Reusing StateSet"<_geode->setStateSet(stateset); + } + else + { + applyColorLayers(*buffer); + applyTransparency(*buffer); + } + } + else + { + generateGeometry(*buffer, masterLocator, centerModel); + applyColorLayers(*buffer); + applyTransparency(*buffer); + } - // smoothGeometry(); + if (buffer->_transform.valid()) buffer->_transform->setThreadSafeRefUnref(true); - if (buffer._transform.valid()) buffer._transform->setThreadSafeRefUnref(true); + if (!_currentBufferData) + { + _currentBufferData = buffer; + } + else + { + _newBufferData = buffer; + if (_terrainTile->getTerrain()) _terrainTile->getTerrain()->updateTerrainTileOnNextFrame(_terrainTile); + } - swapBuffers(); + _terrainTile->setDirtyMask(0); } Locator* GeometryTechnique::computeMasterLocator() @@ -149,12 +172,10 @@ Locator* GeometryTechnique::computeMasterLocator() return masterLocator; } -osg::Vec3d GeometryTechnique::computeCenterModel(Locator* masterLocator) +osg::Vec3d GeometryTechnique::computeCenterModel(BufferData& buffer, Locator* masterLocator) { if (!masterLocator) return osg::Vec3d(0.0,0.0,0.0); - BufferData& buffer = getWriteBuffer(); - osgTerrain::Layer* elevationLayer = _terrainTile->getElevationLayer(); osgTerrain::Layer* colorLayer = _terrainTile->getColorLayer(0); @@ -211,32 +232,460 @@ osg::Vec3d GeometryTechnique::computeCenterModel(Locator* masterLocator) return centerModel; } -void GeometryTechnique::generateGeometry(Locator* masterLocator, const osg::Vec3d& centerModel) +class VertexNormalGenerator { - BufferData& buffer = getWriteBuffer(); - + public: + + typedef std::vector Indices; + typedef std::pair< osg::ref_ptr, Locator* > TexCoordLocatorPair; + typedef std::map< Layer*, TexCoordLocatorPair > LayerToTexCoordMap; + + VertexNormalGenerator(Locator* masterLocator, const osg::Vec3d& centerModel, int numRows, int numColmns, float scaleHeight, bool createSkirt); + + void populateCenter(osgTerrain::Layer* elevationLayer, LayerToTexCoordMap& layerToTexCoordMap); + void populateLeftBoundary(osgTerrain::Layer* elevationLayer); + void populateRightBoundary(osgTerrain::Layer* elevationLayer); + void populateAboveBoundary(osgTerrain::Layer* elevationLayer); + void populateBelowBoundary(osgTerrain::Layer* elevationLayer); + + void computeNormals(); + + unsigned int capacity() const { return _vertices->capacity(); } + + inline void setVertex(int c, int r, const osg::Vec3& v, const osg::Vec3& n) + { + int& i = index(c,r); + if (i==0) + { + if (r<0 || r>=_numRows || c<0 || c>=_numColumns) + { + i = -(1+_boundaryVertices->size()); + _boundaryVertices->push_back(v); + // OSG_NOTICE<<"setVertex("<size() + 1; + _vertices->push_back(v); + _normals->push_back(n); + // OSG_NOTICE<<"setVertex("< _vertices; + osg::ref_ptr _normals; + osg::ref_ptr _elevations; + + osg::ref_ptr _boundaryVertices; + +}; + +VertexNormalGenerator::VertexNormalGenerator(Locator* masterLocator, const osg::Vec3d& centerModel, int numRows, int numColumns, float scaleHeight, bool createSkirt): + _masterLocator(masterLocator), + _centerModel(centerModel), + _numRows(numRows), + _numColumns(numColumns), + _scaleHeight(scaleHeight) +{ + int numVerticesInBody = numColumns*numRows; + int numVerticesInSkirt = createSkirt ? numColumns*2 + numRows*2 - 4 : 0; + int numVertices = numVerticesInBody+numVerticesInSkirt; + + _indices.resize((_numRows+2)*(_numRows+2),0); + + _vertices = new osg::Vec3Array; + _vertices->reserve(numVertices); + + _normals = new osg::Vec3Array; + _normals->reserve(numVertices); + + _elevations = new osg::FloatArray; + _elevations->reserve(numVertices); + + _boundaryVertices = new osg::Vec3Array; + _boundaryVertices->reserve(_numRows*2 + _numColumns*2 + 4); +} + +void VertexNormalGenerator::populateCenter(osgTerrain::Layer* elevationLayer, LayerToTexCoordMap& layerToTexCoordMap) +{ + // OSG_NOTICE<getNumRows()!=static_cast(_numRows)) || + (elevationLayer->getNumColumns()!=static_cast(_numColumns)) ); + + for(int j=0; j<_numRows; ++j) + { + for(int i=0; i<_numColumns; ++i) + { + osg::Vec3d ndc( ((double)i)/(double)(_numColumns-1), ((double)j)/(double)(_numRows-1), 0.0); + + bool validValue = true; + if (elevationLayer) + { + float value = 0.0f; + if (sampled) validValue = elevationLayer->getInterpolatedValidValue(ndc.x(), ndc.y(), value); + else validValue = elevationLayer->getValidValue(i,j,value); + ndc.z() = value*_scaleHeight; + } + + if (validValue) + { + osg::Vec3d model; + _masterLocator->convertLocalToModel(ndc, model); + + for(VertexNormalGenerator::LayerToTexCoordMap::iterator itr = layerToTexCoordMap.begin(); + itr != layerToTexCoordMap.end(); + ++itr) + { + osg::Vec2Array* texcoords = itr->second.first.get(); + Locator* colorLocator = itr->second.second; + if (colorLocator != _masterLocator) + { + osg::Vec3d color_ndc; + Locator::convertLocalCoordBetween(*_masterLocator, ndc, *colorLocator, color_ndc); + (*texcoords).push_back(osg::Vec2(color_ndc.x(), color_ndc.y())); + } + else + { + (*texcoords).push_back(osg::Vec2(ndc.x(), ndc.y())); + } + } + + if (_elevations.valid()) + { + (*_elevations).push_back(ndc.z()); + } + + // compute the local normal + osg::Vec3d ndc_one = ndc; ndc_one.z() += 1.0; + osg::Vec3d model_one; + _masterLocator->convertLocalToModel(ndc_one, model_one); + model_one = model_one - model; + model_one.normalize(); + + setVertex(i, j, osg::Vec3(model-_centerModel), model_one); + } + } + } +} + +void VertexNormalGenerator::populateLeftBoundary(osgTerrain::Layer* elevationLayer) +{ + // OSG_NOTICE<<" VertexNormalGenerator::populateLeftBoundary("<getNumRows()!=static_cast(_numRows)) || + (elevationLayer->getNumColumns()!=static_cast(_numColumns)) ); + + for(int j=0; j<_numRows; ++j) + { + for(int i=-1; i<=0; ++i) + { + osg::Vec3d ndc( ((double)i)/(double)(_numColumns-1), ((double)j)/(double)(_numRows-1), 0.0); + osg::Vec3d left_ndc( 1.0+ndc.x(), ndc.y(), 0.0); + + bool validValue = true; + if (elevationLayer) + { + float value = 0.0f; + if (sampled) validValue = elevationLayer->getInterpolatedValidValue(left_ndc.x(), left_ndc.y(), value); + else validValue = elevationLayer->getValidValue((_numColumns-1)+i,j,value); + ndc.z() = value*_scaleHeight; + + ndc.z() += 0.f; + } + + if (validValue) + { + osg::Vec3d model; + _masterLocator->convertLocalToModel(ndc, model); + + // compute the local normal + osg::Vec3d ndc_one = ndc; ndc_one.z() += 1.0; + osg::Vec3d model_one; + _masterLocator->convertLocalToModel(ndc_one, model_one); + model_one = model_one - model; + model_one.normalize(); + + setVertex(i, j, osg::Vec3(model-_centerModel), model_one); + // OSG_NOTICE<<" setVertex("<getNumRows()!=static_cast(_numRows)) || + (elevationLayer->getNumColumns()!=static_cast(_numColumns)) ); + + for(int j=0; j<_numRows; ++j) + { + for(int i=_numColumns-1; i<_numColumns+1; ++i) + { + osg::Vec3d ndc( ((double)i)/(double)(_numColumns-1), ((double)j)/(double)(_numRows-1), 0.0); + osg::Vec3d right_ndc(ndc.x()-1.0, ndc.y(), 0.0); + + bool validValue = true; + if (elevationLayer) + { + float value = 0.0f; + if (sampled) validValue = elevationLayer->getInterpolatedValidValue(right_ndc.x(), right_ndc.y(), value); + else validValue = elevationLayer->getValidValue(i-(_numColumns-1),j,value); + ndc.z() = value*_scaleHeight; + } + + if (validValue) + { + osg::Vec3d model; + _masterLocator->convertLocalToModel(ndc, model); + + // compute the local normal + osg::Vec3d ndc_one = ndc; ndc_one.z() += 1.0; + osg::Vec3d model_one; + _masterLocator->convertLocalToModel(ndc_one, model_one); + model_one = model_one - model; + model_one.normalize(); + + setVertex(i, j, osg::Vec3(model-_centerModel), model_one); + // OSG_NOTICE<<" setVertex("<getNumRows()!=static_cast(_numRows)) || + (elevationLayer->getNumColumns()!=static_cast(_numColumns)) ); + + for(int j=_numRows-1; j<_numRows+1; ++j) + { + for(int i=0; i<_numColumns; ++i) + { + osg::Vec3d ndc( ((double)i)/(double)(_numColumns-1), ((double)j)/(double)(_numRows-1), 0.0); + osg::Vec3d above_ndc( ndc.x(), ndc.y()-1.0, 0.0); + + bool validValue = true; + if (elevationLayer) + { + float value = 0.0f; + if (sampled) validValue = elevationLayer->getInterpolatedValidValue(above_ndc.x(), above_ndc.y(), value); + else validValue = elevationLayer->getValidValue(i,j-(_numRows-1),value); + ndc.z() = value*_scaleHeight; + } + + if (validValue) + { + osg::Vec3d model; + _masterLocator->convertLocalToModel(ndc, model); + + // compute the local normal + osg::Vec3d ndc_one = ndc; ndc_one.z() += 1.0; + osg::Vec3d model_one; + _masterLocator->convertLocalToModel(ndc_one, model_one); + model_one = model_one - model; + model_one.normalize(); + + setVertex(i, j, osg::Vec3(model-_centerModel), model_one); + // OSG_NOTICE<<" setVertex("<getNumRows()!=static_cast(_numRows)) || + (elevationLayer->getNumColumns()!=static_cast(_numColumns)) ); + + for(int j=-1; j<=0; ++j) + { + for(int i=0; i<_numColumns; ++i) + { + osg::Vec3d ndc( ((double)i)/(double)(_numColumns-1), ((double)j)/(double)(_numRows-1), 0.0); + osg::Vec3d below_ndc( ndc.x(), 1.0+ndc.y(), 0.0); + + bool validValue = true; + if (elevationLayer) + { + float value = 0.0f; + if (sampled) validValue = elevationLayer->getInterpolatedValidValue(below_ndc.x(), below_ndc.y(), value); + else validValue = elevationLayer->getValidValue(i,(_numRows-1)+j,value); + ndc.z() = value*_scaleHeight; + } + + if (validValue) + { + osg::Vec3d model; + _masterLocator->convertLocalToModel(ndc, model); + + // compute the local normal + osg::Vec3d ndc_one = ndc; ndc_one.z() += 1.0; + osg::Vec3d model_one; + _masterLocator->convertLocalToModel(ndc_one, model_one); + model_one = model_one - model; + model_one.normalize(); + + setVertex(i, j, osg::Vec3(model-_centerModel), model_one); + // OSG_NOTICE<<" setVertex("<=0) computeNormal(i, j, (*_normals)[vi]); + else OSG_NOTICE<<"Not computing normal, vi="<getTerrain(); osgTerrain::Layer* elevationLayer = _terrainTile->getElevationLayer(); + buffer._geode = new osg::Geode; if(buffer._transform.valid()) buffer._transform->addChild(buffer._geode.get()); - + buffer._geometry = new osg::Geometry; buffer._geode->addDrawable(buffer._geometry.get()); - + osg::Geometry* geometry = buffer._geometry.get(); unsigned int numRows = 20; unsigned int numColumns = 20; - + if (elevationLayer) { numColumns = elevationLayer->getNumColumns(); numRows = elevationLayer->getNumRows(); } - - float sampleRatio = _terrainTile->getTerrain() ? _terrainTile->getTerrain()->getSampleRatio() : 1.0f; - + + float sampleRatio = terrain ? terrain->getSampleRatio() : 1.0f; + double i_sampleFactor = 1.0; double j_sampleFactor = 1.0; @@ -270,37 +719,34 @@ void GeometryTechnique::generateGeometry(Locator* masterLocator, const osg::Vec3 } bool createSkirt = skirtHeight != 0.0f; - - unsigned int numVerticesInBody = numColumns*numRows; - unsigned int numVerticesInSkirt = createSkirt ? numColumns*2 + numRows*2 - 4 : 0; - unsigned int numVertices = numVerticesInBody+numVerticesInSkirt; + + + float scaleHeight = terrain ? terrain->getVerticalScale() : 1.0f; + + // construct the VertexNormalGenerator which will manage the generation and the vertices and normals + VertexNormalGenerator VNG(masterLocator, centerModel, numRows, numColumns, scaleHeight, createSkirt); + + unsigned int numVertices = VNG.capacity(); // allocate and assign vertices - osg::ref_ptr vertices = new osg::Vec3Array; - vertices->reserve(numVertices); - geometry->setVertexArray(vertices.get()); + geometry->setVertexArray(VNG._vertices.get()); // allocate and assign normals - osg::ref_ptr normals = new osg::Vec3Array; - if (normals.valid()) normals->reserve(numVertices); - geometry->setNormalArray(normals.get()); + geometry->setNormalArray(VNG._normals.get()); geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX); - - //float minHeight = 0.0; - float scaleHeight = _terrainTile->getTerrain() ? _terrainTile->getTerrain()->getVerticalScale() : 1.0f; // allocate and assign tex coords - typedef std::pair< osg::ref_ptr, Locator* > TexCoordLocatorPair; - typedef std::map< Layer*, TexCoordLocatorPair > LayerToTexCoordMap; + // typedef std::pair< osg::ref_ptr, Locator* > TexCoordLocatorPair; + // typedef std::map< Layer*, TexCoordLocatorPair > LayerToTexCoordMap; - LayerToTexCoordMap layerToTexCoordMap; + VertexNormalGenerator::LayerToTexCoordMap layerToTexCoordMap; for(unsigned int layerNum=0; layerNum<_terrainTile->getNumColorLayers(); ++layerNum) { osgTerrain::Layer* colorLayer = _terrainTile->getColorLayer(layerNum); if (colorLayer) { - LayerToTexCoordMap::iterator itr = layerToTexCoordMap.find(colorLayer); + VertexNormalGenerator::LayerToTexCoordMap::iterator itr = layerToTexCoordMap.find(colorLayer); if (itr!=layerToTexCoordMap.end()) { geometry->setTexCoordArray(layerNum, itr->second.first.get()); @@ -323,7 +769,7 @@ void GeometryTechnique::generateGeometry(Locator* masterLocator, const osg::Vec3 } } - TexCoordLocatorPair& tclp = layerToTexCoordMap[colorLayer]; + VertexNormalGenerator::TexCoordLocatorPair& tclp = layerToTexCoordMap[colorLayer]; tclp.first = new osg::Vec2Array; tclp.first->reserve(numVertices); tclp.second = locator ? locator : masterLocator; @@ -332,10 +778,6 @@ void GeometryTechnique::generateGeometry(Locator* masterLocator, const osg::Vec3 } } - osg::ref_ptr elevations = new osg::FloatArray; - if (elevations.valid()) elevations->reserve(numVertices); - - // allocate and assign color osg::ref_ptr colors = new osg::Vec4Array(1); (*colors)[0].set(1.0f,1.0f,1.0f,1.0f); @@ -343,131 +785,123 @@ void GeometryTechnique::generateGeometry(Locator* masterLocator, const osg::Vec3 geometry->setColorArray(colors.get()); geometry->setColorBinding(osg::Geometry::BIND_OVERALL); - - typedef std::vector Indices; - Indices indices(numVertices, -1); - + // // populate vertex and tex coord arrays - unsigned int i, j; - for(j=0; jgetTileID(); + + osg::ref_ptr left_tile = terrain->getTile(TileID(tileID.level, tileID.x-1, tileID.y)); + osg::ref_ptr right_tile = terrain->getTile(TileID(tileID.level, tileID.x+1, tileID.y)); + osg::ref_ptr top_tile = terrain->getTile(TileID(tileID.level, tileID.x, tileID.y+1)); + osg::ref_ptr bottom_tile = terrain->getTile(TileID(tileID.level, tileID.x, tileID.y-1)); + + VNG.populateLeftBoundary(left_tile.valid() ? left_tile->getElevationLayer() : 0); + VNG.populateRightBoundary(right_tile.valid() ? right_tile->getElevationLayer() : 0); + VNG.populateAboveBoundary(top_tile.valid() ? top_tile->getElevationLayer() : 0); + VNG.populateBelowBoundary(bottom_tile.valid() ? bottom_tile->getElevationLayer() : 0); + + _neighbours.clear(); + + bool updateNeighboursImmediately = true; + + if (left_tile.valid()) addNeighbour(left_tile.get()); + if (right_tile.valid()) addNeighbour(right_tile.get()); + if (top_tile.valid()) addNeighbour(top_tile.get()); + if (bottom_tile.valid()) addNeighbour(bottom_tile.get()); + + + if (left_tile.valid()) { - unsigned int iv = j*numColumns + i; - osg::Vec3d ndc( ((double)i)/(double)(numColumns-1), ((double)j)/(double)(numRows-1), 0.0); - - bool validValue = true; - if (elevationLayer) + if (!(left_tile->getTerrainTechnique()->containsNeighbour(_terrainTile))) { - float value = 0.0f; - if (sampleRatio==1.0) validValue = elevationLayer->getValidValue(i,j,value); - else validValue = elevationLayer->getInterpolatedValidValue(ndc.x(), ndc.y(), value); - ndc.z() = value*scaleHeight; - } - - if (validValue) - { - indices[iv] = vertices->size(); - - osg::Vec3d model; - masterLocator->convertLocalToModel(ndc, model); - - (*vertices).push_back(model - centerModel); - - for(LayerToTexCoordMap::iterator itr = layerToTexCoordMap.begin(); - itr != layerToTexCoordMap.end(); - ++itr) + left_tile->setDirtyMask(left_tile->getDirtyMask() | TerrainTile::LEFT_EDGE_DIRTY); + if (updateNeighboursImmediately) { - osg::Vec2Array* texcoords = itr->second.first.get(); - Locator* colorLocator = itr->second.second; - if (colorLocator != masterLocator) - { - osg::Vec3d color_ndc; - Locator::convertLocalCoordBetween(*masterLocator, ndc, *colorLocator, color_ndc); - (*texcoords).push_back(osg::Vec2(color_ndc.x(), color_ndc.y())); - } - else - { - (*texcoords).push_back(osg::Vec2(ndc.x(), ndc.y())); - } + left_tile->init(); } - - if (elevations.valid()) - { - (*elevations).push_back(ndc.z()); - } - - // compute the local normal - osg::Vec3d ndc_one = ndc; ndc_one.z() += 1.0; - osg::Vec3d model_one; - masterLocator->convertLocalToModel(ndc_one, model_one); - model_one = model_one - model; - model_one.normalize(); - (*normals).push_back(model_one); } - else + } + if (right_tile.valid()) + { + if (!(right_tile->getTerrainTechnique()->containsNeighbour(_terrainTile))) { - indices[iv] = -1; + right_tile->setDirtyMask(right_tile->getDirtyMask() | TerrainTile::RIGHT_EDGE_DIRTY); + if (updateNeighboursImmediately) right_tile->init(); + } + } + if (top_tile.valid()) + { + if (!(top_tile->getTerrainTechnique()->containsNeighbour(_terrainTile))) + { + top_tile->setDirtyMask(top_tile->getDirtyMask() | TerrainTile::TOP_EDGE_DIRTY); + if (updateNeighboursImmediately) top_tile->init(); + } + } + + if (bottom_tile) + { + if (!(bottom_tile->getTerrainTechnique()->containsNeighbour(_terrainTile))) + { + bottom_tile->setDirtyMask(bottom_tile->getDirtyMask() | TerrainTile::BOTTOM_EDGE_DIRTY); + if (updateNeighboursImmediately) bottom_tile->init(); } } } - // populate primitive sets -// bool optimizeOrientations = elevations!=0; - bool swapOrientation = !(masterLocator->orientationOpenGL()); + osg::ref_ptr skirtVectors = new osg::Vec3Array((*VNG._normals)); + VNG.computeNormals(); + // + // populate the primitive data + // + bool swapOrientation = !(masterLocator->orientationOpenGL()); bool smallTile = numVertices <= 16384; // OSG_NOTICE<<"smallTile = "< elements = smallTile ? static_cast(new osg::DrawElementsUShort(GL_TRIANGLES)) : static_cast(new osg::DrawElementsUInt(GL_TRIANGLES)); - + elements->reserveElements((numRows-1) * (numColumns-1) * 6); geometry->addPrimitiveSet(elements.get()); + + unsigned int i, j; for(j=0; j=0) ++numValid; if (i01>=0) ++numValid; if (i10>=0) ++numValid; if (i11>=0) ++numValid; - + if (numValid==4) { - float e00 = (*elevations)[i00]; - float e10 = (*elevations)[i10]; - float e01 = (*elevations)[i01]; - float e11 = (*elevations)[i11]; - - if (fabsf(e00-e11) dot_01_10) { elements->addElement(i01); elements->addElement(i00); @@ -495,23 +929,15 @@ void GeometryTechnique::generateGeometry(Locator* masterLocator, const osg::Vec3 if (i11>=0) elements->addElement(i11); if (i10>=0) elements->addElement(i10); } - } } - - osg::ref_ptr skirtVectors = new osg::Vec3Array((*normals)); - - if (elevationLayer) - { - smoothGeometry(); - - normals = dynamic_cast(geometry->getNormalArray()); - - if (!normals) createSkirt = false; - } + if (createSkirt) { + osg::ref_ptr vertices = VNG._vertices.get(); + osg::ref_ptr normals = VNG._normals.get(); + osg::ref_ptr skirtDrawElements = smallTile ? static_cast(new osg::DrawElementsUShort(GL_QUAD_STRIP)) : static_cast(new osg::DrawElementsUInt(GL_QUAD_STRIP)); @@ -521,7 +947,7 @@ void GeometryTechnique::generateGeometry(Locator* masterLocator, const osg::Vec3 r=0; for(c=0;c(numColumns);++c) { - int orig_i = indices[(r)*numColumns+c]; // index of original vertex of grid + int orig_i = VNG.vertex_index(c,r); if (orig_i>=0) { unsigned int new_i = vertices->size(); // index of new index of added skirt point @@ -529,7 +955,7 @@ void GeometryTechnique::generateGeometry(Locator* masterLocator, const osg::Vec3 (*vertices).push_back(new_v); if (normals.valid()) (*normals).push_back((*normals)[orig_i]); - for(LayerToTexCoordMap::iterator itr = layerToTexCoordMap.begin(); + for(VertexNormalGenerator::LayerToTexCoordMap::iterator itr = layerToTexCoordMap.begin(); itr != layerToTexCoordMap.end(); ++itr) { @@ -564,14 +990,14 @@ void GeometryTechnique::generateGeometry(Locator* masterLocator, const osg::Vec3 c=numColumns-1; for(r=0;r(numRows);++r) { - int orig_i = indices[(r)*numColumns+c]; // index of original vertex of grid + int orig_i = VNG.vertex_index(c,r); // index of original vertex of grid if (orig_i>=0) { unsigned int new_i = vertices->size(); // index of new index of added skirt point osg::Vec3 new_v = (*vertices)[orig_i] - ((*skirtVectors)[orig_i])*skirtHeight; (*vertices).push_back(new_v); if (normals.valid()) (*normals).push_back((*normals)[orig_i]); - for(LayerToTexCoordMap::iterator itr = layerToTexCoordMap.begin(); + for(VertexNormalGenerator::LayerToTexCoordMap::iterator itr = layerToTexCoordMap.begin(); itr != layerToTexCoordMap.end(); ++itr) { @@ -606,14 +1032,14 @@ void GeometryTechnique::generateGeometry(Locator* masterLocator, const osg::Vec3 r=numRows-1; for(c=numColumns-1;c>=0;--c) { - int orig_i = indices[(r)*numColumns+c]; // index of original vertex of grid + int orig_i = VNG.vertex_index(c,r); // index of original vertex of grid if (orig_i>=0) { unsigned int new_i = vertices->size(); // index of new index of added skirt point osg::Vec3 new_v = (*vertices)[orig_i] - ((*skirtVectors)[orig_i])*skirtHeight; (*vertices).push_back(new_v); if (normals.valid()) (*normals).push_back((*normals)[orig_i]); - for(LayerToTexCoordMap::iterator itr = layerToTexCoordMap.begin(); + for(VertexNormalGenerator::LayerToTexCoordMap::iterator itr = layerToTexCoordMap.begin(); itr != layerToTexCoordMap.end(); ++itr) { @@ -648,14 +1074,14 @@ void GeometryTechnique::generateGeometry(Locator* masterLocator, const osg::Vec3 c=0; for(r=numRows-1;r>=0;--r) { - int orig_i = indices[(r)*numColumns+c]; // index of original vertex of grid + int orig_i = VNG.vertex_index(c,r); // index of original vertex of grid if (orig_i>=0) { unsigned int new_i = vertices->size(); // index of new index of added skirt point osg::Vec3 new_v = (*vertices)[orig_i] - ((*skirtVectors)[orig_i])*skirtHeight; (*vertices).push_back(new_v); if (normals.valid()) (*normals).push_back((*normals)[orig_i]); - for(LayerToTexCoordMap::iterator itr = layerToTexCoordMap.begin(); + for(VertexNormalGenerator::LayerToTexCoordMap::iterator itr = layerToTexCoordMap.begin(); itr != layerToTexCoordMap.end(); ++itr) { @@ -722,10 +1148,8 @@ void GeometryTechnique::generateGeometry(Locator* masterLocator, const osg::Vec3 } } -void GeometryTechnique::applyColorLayers() +void GeometryTechnique::applyColorLayers(BufferData& buffer) { - BufferData& buffer = getWriteBuffer(); - typedef std::map LayerToTextureMap; LayerToTextureMap layerToTextureMap; @@ -816,7 +1240,7 @@ void GeometryTechnique::applyColorLayers() } } -void GeometryTechnique::applyTransparency() +void GeometryTechnique::applyTransparency(BufferData& buffer) { TerrainTile::BlendingPolicy blendingPolicy = _terrainTile->getBlendingPolicy(); if (blendingPolicy == TerrainTile::INHERIT && _terrainTile->getTerrain()) @@ -860,7 +1284,6 @@ void GeometryTechnique::applyTransparency() if (enableBlending) { - BufferData& buffer = getWriteBuffer(); osg::StateSet* stateset = buffer._geode->getOrCreateStateSet(); stateset->setMode(GL_BLEND, osg::StateAttribute::ON); stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); @@ -868,35 +1291,27 @@ void GeometryTechnique::applyTransparency() } -void GeometryTechnique::smoothGeometry() -{ - BufferData& buffer = getWriteBuffer(); - - if (buffer._geometry.valid()) - { - osgUtil::SmoothingVisitor smoother; - smoother.smooth(*buffer._geometry); - } -} - void GeometryTechnique::update(osgUtil::UpdateVisitor* uv) { if (_terrainTile) _terrainTile->osg::Group::traverse(*uv); + + if (_newBufferData.valid()) + { + _currentBufferData = _newBufferData; + _newBufferData = 0; + } } void GeometryTechnique::cull(osgUtil::CullVisitor* cv) { - BufferData& buffer = getReadOnlyBuffer(); - -#if 0 - if (buffer._terrainTile) buffer._terrainTile->osg::Group::traverse(*cv); -#else - if (buffer._transform.valid()) + if (_currentBufferData.valid()) { - buffer._transform->accept(*cv); + if (_currentBufferData->_transform.valid()) + { + _currentBufferData->_transform->accept(*cv); + } } -#endif } @@ -914,8 +1329,7 @@ void GeometryTechnique::traverse(osg::NodeVisitor& nv) { update(uv); return; - } - + } } else if (nv.getVisitorType()==osg::NodeVisitor::CULL_VISITOR) { @@ -934,8 +1348,10 @@ void GeometryTechnique::traverse(osg::NodeVisitor& nv) _terrainTile->init(); } - BufferData& buffer = getReadOnlyBuffer(); - if (buffer._transform.valid()) buffer._transform->accept(nv); + if (_currentBufferData.valid()) + { + if (_currentBufferData->_transform.valid()) _currentBufferData->_transform->accept(nv); + } } @@ -945,7 +1361,7 @@ void GeometryTechnique::cleanSceneGraph() void GeometryTechnique::releaseGLObjects(osg::State* state) const { - if (_bufferData[0]._transform.valid()) _bufferData[0]._transform->releaseGLObjects(state); - if (_bufferData[1]._transform.valid()) _bufferData[1]._transform->releaseGLObjects(state); + if (_currentBufferData.valid() && _currentBufferData->_transform.valid()) _currentBufferData->_transform->releaseGLObjects(state); + if (_newBufferData.valid() && _newBufferData->_transform.valid()) _newBufferData->_transform->releaseGLObjects(state); } diff --git a/src/osgTerrain/Terrain.cpp b/src/osgTerrain/Terrain.cpp index 79417bec6..24f2a8ca6 100644 --- a/src/osgTerrain/Terrain.cpp +++ b/src/osgTerrain/Terrain.cpp @@ -13,6 +13,7 @@ #include #include +#include #include @@ -24,6 +25,7 @@ Terrain::Terrain(): _verticalScale(1.0), _blendingPolicy(TerrainTile::INHERIT) { + setNumChildrenRequiringUpdateTraversal(1); _terrainTechnique = new GeometryTechnique; } @@ -34,6 +36,7 @@ Terrain::Terrain(const Terrain& ts, const osg::CopyOp& copyop): _blendingPolicy(ts._blendingPolicy), _terrainTechnique(ts._terrainTechnique) { + setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()+1); } @@ -54,13 +57,40 @@ Terrain::~Terrain() 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) + { + OpenThreads::ScopedLock lock(_mutex); + for(TerrainTileSet::iterator itr = _updateTerrainTileSet.begin(); + itr != _updateTerrainTileSet.end(); + ++itr) + { + TerrainTile* tile = *itr; + if (tile->getTerrainTechnique()) tile->getTerrainTechnique()->update(uv); + } + _updateTerrainTileSet.clear(); + } + } + 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("< lock(_mutex); - + if (tile->getTileID().valid()) { _terrainTileMap[tile->getTileID()] = tile; } - + _terrainTileSet.insert(tile); if (_terrainTileSet.size() > s_maxNumTiles) s_maxNumTiles = _terrainTileSet.size(); - // osg::notify(osg::NOTICE)<<"Terrain::registerTerrainTile "<getTileID().level<<", "<getTileID().x<<", "<getTileID().y<<")"<& TerrainTile::getTileLoadedCallbac TerrainTile::TerrainTile(): _terrain(0), - _dirty(false), + _dirtyMask(NOT_DIRTY), _hasBeenTraversal(false), _requiresNormals(true), _treatBoundariesToValidDataAsDefaultValue(false), @@ -70,7 +70,7 @@ TerrainTile::TerrainTile(): TerrainTile::TerrainTile(const TerrainTile& terrain,const osg::CopyOp& copyop): Group(terrain,copyop), _terrain(0), - _dirty(false), + _dirtyMask(NOT_DIRTY), _hasBeenTraversal(false), _elevationLayer(terrain._elevationLayer), _colorLayers(terrain._colorLayers), @@ -86,6 +86,11 @@ TerrainTile::TerrainTile(const TerrainTile& terrain,const osg::CopyOp& copyop): TerrainTile::~TerrainTile() { + if (_terrainTechnique.valid()) + { + _terrainTechnique->setTerrainTile(0); + } + if (_terrain) setTerrain(0); } @@ -134,9 +139,9 @@ void TerrainTile::traverse(osg::NodeVisitor& nv) } } } - + init(); - + _hasBeenTraversal = true; } @@ -162,7 +167,7 @@ void TerrainTile::traverse(osg::NodeVisitor& nv) void TerrainTile::init() { if (!_terrainTechnique) - { + { if (_terrain && _terrain->getTerrainTechniquePrototype()) { osg::ref_ptr object = _terrain->getTerrainTechniquePrototype()->clone(osg::CopyOp::DEEP_COPY_ALL); @@ -177,45 +182,47 @@ void TerrainTile::init() if (_terrainTechnique.valid() && getDirty()) { _terrainTechnique->init(); - - setDirty(false); - } + } } void TerrainTile::setTerrainTechnique(TerrainTechnique* terrainTechnique) { if (_terrainTechnique == terrainTechnique) return; - int dirtyDelta = _dirty ? -1 : 0; + int dirtyDelta = (_dirtyMask==NOT_DIRTY) ? 0 : -1; if (_terrainTechnique.valid()) { - _terrainTechnique->_terrainTile = 0; + _terrainTechnique->setTerrainTile(0); } _terrainTechnique = terrainTechnique; if (_terrainTechnique.valid()) { - _terrainTechnique->_terrainTile = this; + _terrainTechnique->setTerrainTile(this); ++dirtyDelta; } - if (dirtyDelta>0) setDirty(true); - else if (dirtyDelta<0) setDirty(false); + if (dirtyDelta>0) setDirtyMask(ALL_DIRTY); + else if (dirtyDelta<0) setDirtyMask(NOT_DIRTY); } -void TerrainTile::setDirty(bool dirty) +void TerrainTile::setDirtyMask(int dirtyMask) { - if (_dirty==dirty) return; + if (_dirtyMask==dirtyMask) return; - _dirty = dirty; + int dirtyDelta = (_dirtyMask==NOT_DIRTY) ? 0 : -1; - if (_dirty) + _dirtyMask = dirtyMask; + + if (_dirtyMask!=NOT_DIRTY) dirtyDelta += 1; + + if (dirtyDelta>0) { setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()+1); } - else if (getNumChildrenRequiringUpdateTraversal()>0) + else if (dirtyDelta<0 && getNumChildrenRequiringUpdateTraversal()>0) { setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()-1); } diff --git a/src/osgWrappers/introspection/osgTerrain/GeometryTechnique.cpp b/src/osgWrappers/introspection/osgTerrain/GeometryTechnique.cpp index 180ca99b1..096c8a255 100644 --- a/src/osgWrappers/introspection/osgTerrain/GeometryTechnique.cpp +++ b/src/osgWrappers/introspection/osgTerrain/GeometryTechnique.cpp @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -81,31 +80,6 @@ BEGIN_OBJECT_REFLECTOR(osgTerrain::GeometryTechnique) __Locator_P1__computeMasterLocator, "", ""); - I_Method1(osg::Vec3d, computeCenterModel, IN, osgTerrain::Locator *, masterLocator, - Properties::VIRTUAL, - __osg_Vec3d__computeCenterModel__Locator_P1, - "", - ""); - I_Method2(void, generateGeometry, IN, osgTerrain::Locator *, masterLocator, IN, const osg::Vec3d &, centerModel, - Properties::VIRTUAL, - __void__generateGeometry__Locator_P1__C5_osg_Vec3d_R1, - "", - ""); - I_Method0(void, applyColorLayers, - Properties::VIRTUAL, - __void__applyColorLayers, - "", - ""); - I_Method0(void, applyTransparency, - Properties::VIRTUAL, - __void__applyTransparency, - "", - ""); - I_Method0(void, smoothGeometry, - Properties::VIRTUAL, - __void__smoothGeometry, - "", - ""); I_Method1(void, update, IN, osgUtil::UpdateVisitor *, nv, Properties::VIRTUAL, __void__update__osgUtil_UpdateVisitor_P1, @@ -171,22 +145,28 @@ BEGIN_OBJECT_REFLECTOR(osgTerrain::GeometryTechnique) __void__releaseGLObjects__osg_State_P1, "If State is non-zero, this function releases any associated OpenGL objects for the specified graphics context. ", "Otherwise, releases OpenGL objects for all graphics contexts. "); - I_ProtectedMethod0(void, swapBuffers, - Properties::NON_VIRTUAL, + I_ProtectedMethod2(osg::Vec3d, computeCenterModel, IN, osg::BufferData &, buffer, IN, osgTerrain::Locator *, masterLocator, + Properties::VIRTUAL, Properties::NON_CONST, - __void__swapBuffers, + __osg_Vec3d__computeCenterModel__BufferData_R1__Locator_P1, "", ""); - I_ProtectedMethod0(osg::BufferData &, getReadOnlyBuffer, - Properties::NON_VIRTUAL, + I_ProtectedMethod3(void, generateGeometry, IN, osg::BufferData &, buffer, IN, osgTerrain::Locator *, masterLocator, IN, const osg::Vec3d &, centerModel, + Properties::VIRTUAL, Properties::NON_CONST, - __BufferData_R1__getReadOnlyBuffer, + __void__generateGeometry__BufferData_R1__Locator_P1__C5_osg_Vec3d_R1, "", ""); - I_ProtectedMethod0(osg::BufferData &, getWriteBuffer, - Properties::NON_VIRTUAL, + I_ProtectedMethod1(void, applyColorLayers, IN, osg::BufferData &, buffer, + Properties::VIRTUAL, Properties::NON_CONST, - __BufferData_R1__getWriteBuffer, + __void__applyColorLayers__BufferData_R1, + "", + ""); + I_ProtectedMethod1(void, applyTransparency, IN, osg::BufferData &, buffer, + Properties::VIRTUAL, + Properties::NON_CONST, + __void__applyTransparency__BufferData_R1, "", ""); I_SimpleProperty(float, FilterBias, diff --git a/src/osgWrappers/introspection/osgTerrain/Terrain.cpp b/src/osgWrappers/introspection/osgTerrain/Terrain.cpp index cb85d8ec9..aeb691d0a 100644 --- a/src/osgWrappers/introspection/osgTerrain/Terrain.cpp +++ b/src/osgWrappers/introspection/osgTerrain/Terrain.cpp @@ -125,6 +125,11 @@ BEGIN_OBJECT_REFLECTOR(osgTerrain::Terrain) __C5_TerrainTechnique_P1__getTerrainTechniquePrototype, "Get the const TerrainTechnique protype. ", ""); + I_Method1(void, updateTerrainTileOnNextFrame, IN, osgTerrain::TerrainTile *, terrainTile, + Properties::NON_VIRTUAL, + __void__updateTerrainTileOnNextFrame__TerrainTile_P1, + "Tell the Terrain node to call the terrainTile's TerrainTechnique on the next update traversal. ", + ""); I_ProtectedMethod0(void, dirtyRegisteredTiles, Properties::NON_VIRTUAL, Properties::NON_CONST, diff --git a/src/osgWrappers/introspection/osgTerrain/TerrainTechnique.cpp b/src/osgWrappers/introspection/osgTerrain/TerrainTechnique.cpp index 7bcbdf7a4..fe61cce27 100644 --- a/src/osgWrappers/introspection/osgTerrain/TerrainTechnique.cpp +++ b/src/osgWrappers/introspection/osgTerrain/TerrainTechnique.cpp @@ -27,9 +27,42 @@ #undef OUT #endif +BEGIN_VALUE_REFLECTOR(osgTerrain::TerrainNeighbours) + I_DeclaringFile("osgTerrain/TerrainTechnique"); + I_Constructor0(____TerrainNeighbours, + "", + ""); + I_Method0(void, clear, + Properties::NON_VIRTUAL, + __void__clear, + "", + ""); + I_Method1(void, addNeighbour, IN, osgTerrain::TerrainTile *, tile, + Properties::NON_VIRTUAL, + __void__addNeighbour__TerrainTile_P1, + "", + ""); + I_Method1(void, removeNeighbour, IN, osgTerrain::TerrainTile *, tile, + Properties::NON_VIRTUAL, + __void__removeNeighbour__TerrainTile_P1, + "", + ""); + I_Method1(bool, containsNeighbour, IN, osgTerrain::TerrainTile *, tile, + Properties::NON_VIRTUAL, + __bool__containsNeighbour__TerrainTile_P1, + "", + ""); + I_ProtectedConstructor1(IN, const osgTerrain::TerrainNeighbours &, tn, + Properties::NON_EXPLICIT, + ____TerrainNeighbours__C5_TerrainNeighbours_R1, + "", + ""); +END_REFLECTOR + BEGIN_OBJECT_REFLECTOR(osgTerrain::TerrainTechnique) I_DeclaringFile("osgTerrain/TerrainTechnique"); I_BaseType(osg::Object); + I_BaseType(osg::Observer); I_Constructor0(____TerrainTechnique, "", ""); @@ -102,12 +135,46 @@ BEGIN_OBJECT_REFLECTOR(osgTerrain::TerrainTechnique) __void__releaseGLObjects__osg_State_P1, "If State is non-zero, this function releases any associated OpenGL objects for the specified graphics context. ", "Otherwise, releases OpenGL objects for all graphics contexts. "); + I_Method1(void, addNeighbour, IN, osgTerrain::TerrainTile *, tile, + Properties::NON_VIRTUAL, + __void__addNeighbour__TerrainTile_P1, + "", + ""); + I_Method1(void, removeNeighbour, IN, osgTerrain::TerrainTile *, tile, + Properties::NON_VIRTUAL, + __void__removeNeighbour__TerrainTile_P1, + "", + ""); + I_Method1(bool, containsNeighbour, IN, osgTerrain::TerrainTile *, tile, + Properties::NON_VIRTUAL, + __bool__containsNeighbour__TerrainTile_P1, + "", + ""); + I_Method0(osgTerrain::TerrainNeighbours &, getNeighbours, + Properties::NON_VIRTUAL, + __TerrainNeighbours_R1__getNeighbours, + "", + ""); + I_Method0(const osgTerrain::TerrainNeighbours &, getNeighbours, + Properties::NON_VIRTUAL, + __C5_TerrainNeighbours_R1__getNeighbours, + "", + ""); + I_ProtectedMethod1(void, setTerrainTile, IN, osgTerrain::TerrainTile *, tile, + Properties::NON_VIRTUAL, + Properties::NON_CONST, + __void__setTerrainTile__TerrainTile_P1, + "", + ""); I_ProtectedMethod1(void, setDirty, IN, bool, dirty, Properties::NON_VIRTUAL, Properties::NON_CONST, __void__setDirty__bool, "", ""); + I_SimpleProperty(osgTerrain::TerrainNeighbours &, Neighbours, + __TerrainNeighbours_R1__getNeighbours, + 0); I_SimpleProperty(osgTerrain::TerrainTile *, TerrainTile, __TerrainTile_P1__getTerrainTile, 0); diff --git a/src/osgWrappers/introspection/osgTerrain/TerrainTile.cpp b/src/osgWrappers/introspection/osgTerrain/TerrainTile.cpp index 92bc322d4..6cf515730 100644 --- a/src/osgWrappers/introspection/osgTerrain/TerrainTile.cpp +++ b/src/osgWrappers/introspection/osgTerrain/TerrainTile.cpp @@ -38,6 +38,19 @@ BEGIN_ENUM_REFLECTOR(osgTerrain::TerrainTile::BlendingPolicy) I_EnumLabel(osgTerrain::TerrainTile::ENABLE_BLENDING_WHEN_ALPHA_PRESENT); END_REFLECTOR +BEGIN_ENUM_REFLECTOR(osgTerrain::TerrainTile::DirtyMask) + I_DeclaringFile("osgTerrain/TerrainTile"); + I_EnumLabel(osgTerrain::TerrainTile::NOT_DIRTY); + I_EnumLabel(osgTerrain::TerrainTile::IMAGERY_DIRTY); + I_EnumLabel(osgTerrain::TerrainTile::ELEVATION_DIRTY); + I_EnumLabel(osgTerrain::TerrainTile::LEFT_EDGE_DIRTY); + I_EnumLabel(osgTerrain::TerrainTile::RIGHT_EDGE_DIRTY); + I_EnumLabel(osgTerrain::TerrainTile::TOP_EDGE_DIRTY); + I_EnumLabel(osgTerrain::TerrainTile::BOTTOM_EDGE_DIRTY); + I_EnumLabel(osgTerrain::TerrainTile::EDGES_DIRTY); + I_EnumLabel(osgTerrain::TerrainTile::ALL_DIRTY); +END_REFLECTOR + BEGIN_OBJECT_REFLECTOR(osgTerrain::TerrainTile) I_DeclaringFile("osgTerrain/TerrainTile"); I_BaseType(osg::Group); @@ -213,9 +226,19 @@ BEGIN_OBJECT_REFLECTOR(osgTerrain::TerrainTile) __void__setDirty__bool, "Set the dirty flag on/off. ", ""); - I_Method0(bool, getDirty, + I_Method0(int, getDirty, Properties::NON_VIRTUAL, - __bool__getDirty, + __int__getDirty, + "return true if the any of the DirtyMask are set. ", + ""); + I_Method1(void, setDirtyMask, IN, int, dirtyMask, + Properties::NON_VIRTUAL, + __void__setDirtyMask__int, + "Set the dirty flag on/off. ", + ""); + I_Method0(int, getDirtyMask, + Properties::NON_VIRTUAL, + __int__getDirtyMask, "return true if the tile is dirty and needs to be updated, ", ""); I_Method0(osg::BoundingSphere, computeBound, @@ -247,8 +270,11 @@ BEGIN_OBJECT_REFLECTOR(osgTerrain::TerrainTile) 0, 0); I_SimpleProperty(bool, Dirty, - __bool__getDirty, + 0, __void__setDirty__bool); + I_SimpleProperty(int, DirtyMask, + __int__getDirtyMask, + __void__setDirtyMask__int); I_SimpleProperty(osgTerrain::Layer *, ElevationLayer, __Layer_P1__getElevationLayer, __void__setElevationLayer__Layer_P1);