From b7525e446d19afaf599d0a648af8c46cc6505c5e Mon Sep 17 00:00:00 2001 From: Glenn Waldron Date: Fri, 20 Dec 2024 16:21:53 -0500 Subject: [PATCH] GeoTransform: fix a bug: terrain callback was not reinstalled after the terrain observer_ptr went null and a new terrain was found --- src/osgEarth/GeoTransform | 19 ++++++++----------- src/osgEarth/GeoTransform.cpp | 33 +++++++++++++++++++++++++-------- 2 files changed, 33 insertions(+), 19 deletions(-) diff --git a/src/osgEarth/GeoTransform b/src/osgEarth/GeoTransform index e2223b51c1..8fae2bc9b8 100644 --- a/src/osgEarth/GeoTransform +++ b/src/osgEarth/GeoTransform @@ -16,8 +16,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see */ -#ifndef OSGEARTH_GEO_TRANSFORM -#define OSGEARTH_GEO_TRANSFORM +#pragma once #include #include @@ -123,16 +122,14 @@ namespace osgEarth protected: virtual ~GeoTransform(); - GeoPoint _position; // Current position - osg::observer_ptr _terrain; // Terrain for relative height resolution - bool _terrainCallbackInstalled; // Whether the Terrain callback is in - bool _autoRecomputeHeights; // Whether to resolve relative position Z's - bool _findTerrainInUpdateTraversal; // True is we need _terrain but don't have it - bool _clampInUpdateTraversal; // Whether a terrain clamp is required - + GeoPoint _position; // Current position + osg::observer_ptr _terrain; // Terrain for relative height resolution + bool _terrainCallbackInstalled; // Whether the Terrain callback is in + bool _autoRecomputeHeights; // Whether to resolve relative position Z's + bool _findTerrainInUpdateTraversal; // True is we need _terrain but don't have it + bool _clampInUpdateTraversal; // Whether a terrain clamp is required osg::ref_ptr _computeMatrixCallback; + osg::ref_ptr> _terrainCallback; // Callback for terrain updates }; } // namespace osgEarth - -#endif // OSGEARTH_GEO_TRANSFORM diff --git a/src/osgEarth/GeoTransform.cpp b/src/osgEarth/GeoTransform.cpp index 4696c5f11a..cff28e75b8 100644 --- a/src/osgEarth/GeoTransform.cpp +++ b/src/osgEarth/GeoTransform.cpp @@ -27,16 +27,16 @@ using namespace osgEarth; GeoTransform::GeoTransform() : -_findTerrainInUpdateTraversal(false), -_terrainCallbackInstalled(false), -_autoRecomputeHeights(true), -_clampInUpdateTraversal(false) + _findTerrainInUpdateTraversal(false), + _terrainCallbackInstalled(false), + _autoRecomputeHeights(true), + _clampInUpdateTraversal(false) { - //nop + //nop } GeoTransform::GeoTransform(const GeoTransform& rhs, const osg::CopyOp& op) : -osg::MatrixTransform(rhs, op) + osg::MatrixTransform(rhs, op) { _position = rhs._position; _terrain = rhs._terrain.get(); @@ -58,9 +58,24 @@ GeoTransform::setTerrain(Terrain* terrain) if (terrain) { if (_terrain.valid()) + { + if (_terrainCallback.valid()) + { + _terrain->removeTerrainCallback(_terrainCallback.get()); + _terrainCallbackInstalled = false; + } _terrain->removeObserver(this); + } + _terrain = terrain; _terrain->addObserver(this); + + if (_terrainCallback.valid()) + { + _terrain->addTerrainCallback(_terrainCallback); + _terrainCallbackInstalled = true; + } + setPosition(_position); } } @@ -152,8 +167,10 @@ GeoTransform::setPosition(const GeoPoint& position) !_terrainCallbackInstalled && terrain.valid()) { - // The Adapter template auto-destructs, so we never need to remote it manually. - terrain->addTerrainCallback( new TerrainCallbackAdapter(this) ); + // The Adapter template auto-destructs, so we never need to remove it manually. + if (!_terrainCallback.valid()) + _terrainCallback = new TerrainCallbackAdapter(this); + terrain->addTerrainCallback(_terrainCallback); _terrainCallbackInstalled = true; }