diff --git a/src/blackmisc/simulation/interpolationhints.h b/src/blackmisc/simulation/interpolationhints.h index a29aeffc5..51eb6cc36 100644 --- a/src/blackmisc/simulation/interpolationhints.h +++ b/src/blackmisc/simulation/interpolationhints.h @@ -19,6 +19,8 @@ namespace BlackMisc { + namespace Aviation { class CAircraftSituation; } + namespace Simulation { //! Hints for interpolator such as ground elevation @@ -73,6 +75,15 @@ namespace BlackMisc //! Set aircraft parts void setAircraftParts(const BlackMisc::Aviation::CAircraftParts &parts) { m_hasParts = true; m_aircraftParts = parts; } + //! Function object that can obtain ground elevation + using ElevationProvider = std::function; + + //! Function object that can obtain ground elevation + const ElevationProvider &getElevationProvider() const { return m_elevationProvider; } + + //! Set function object that can obtain ground elevation + void setElevationProvider(const ElevationProvider &ep) { m_elevationProvider = ep; } + //! \copydoc BlackMisc::Mixin::Index::propertyByIndex CVariant propertyByIndex(const BlackMisc::CPropertyIndex &index) const; @@ -91,6 +102,7 @@ namespace BlackMisc BlackMisc::PhysicalQuantities::CLength m_cgAboveGround { 0, nullptr }; //!< center of gravity above ground bool m_hasParts = false; //!< Has valid aircraft parts? BlackMisc::Aviation::CAircraftParts m_aircraftParts; //!< Aircraft parts + ElevationProvider m_elevationProvider; //!< Provider of ground elevation (lazy computation) BLACK_METACLASS( CInterpolationHints, @@ -99,6 +111,7 @@ namespace BlackMisc BLACK_METAMEMBER(cgAboveGround), BLACK_METAMEMBER(hasParts), BLACK_METAMEMBER(aircraftParts) + // elevationProvider not included ); }; } // namespace diff --git a/src/blackmisc/simulation/interpolatorlinear.cpp b/src/blackmisc/simulation/interpolatorlinear.cpp index 729fb0a3a..2fc9c3d62 100644 --- a/src/blackmisc/simulation/interpolatorlinear.cpp +++ b/src/blackmisc/simulation/interpolatorlinear.cpp @@ -143,6 +143,22 @@ namespace BlackMisc + oldAlt, oldAlt.getReferenceDatum())); + // Interpolate between altitude and ground elevation, with proportions weighted according to interpolated onGround flag + if (hints.hasAircraftParts()) + { + const double groundFactor = hints.getAircraftParts().isOnGroundInterpolated(); + if (groundFactor > 0.0) + { + const auto &groundElevation = hints.getElevationProvider(); + if (groundElevation) + { + currentSituation.setAltitude(CAltitude(currentSituation.getAltitude() * (1.0 - groundFactor) + + groundElevation(currentSituation) * groundFactor, + oldAlt.getReferenceDatum())); + } + } + } + if (!setup.isForcingFullInterpolation() && !hints.isVtolAircraft() && newVec == oldVec && oldAlt == newAlt) { // stop interpolation here, does not work for VTOL aircraft. We need a flag for VTOL aircraft