float OsmAnd::AtlasMapRenderer_OpenGL::getReferenceTileSizeOnScreen( const MapRendererState& state ) { const auto& rasterMapProvider = state.rasterLayerProviders[static_cast<int>(RasterMapLayerId::BaseLayer)]; if(!rasterMapProvider) return static_cast<float>(DefaultReferenceTileSizeOnScreen) * setupOptions.displayDensityFactor; auto tileProvider = std::static_pointer_cast<IMapBitmapTileProvider>(rasterMapProvider); return tileProvider->getTileSize() * (setupOptions.displayDensityFactor / tileProvider->getTileDensity()); }
void OsmAnd::AtlasMapRenderer_BaseOpenGL::updateConfiguration() { BaseAtlasMapRenderer::updateConfiguration(); // Prepare values for projection matrix _aspectRatio = static_cast<float>(_activeConfig.viewport.width()); auto viewportHeight = _activeConfig.viewport.height(); if(viewportHeight > 0) _aspectRatio /= static_cast<float>(viewportHeight); _fovInRadians = qDegreesToRadians(_activeConfig.fieldOfView); _projectionPlaneHalfHeight = _zNear * _fovInRadians; _projectionPlaneHalfWidth = _projectionPlaneHalfHeight * _aspectRatio; // Setup projection with fake Z-far plane _mProjection = glm::frustum(-_projectionPlaneHalfWidth, _projectionPlaneHalfWidth, -_projectionPlaneHalfHeight, _projectionPlaneHalfHeight, _zNear, 1000.0f); // Calculate limits of camera distance to target and actual distance const auto& rasterMapProvider = _activeConfig.tileProviders[RasterMap]; auto tileProvider = static_cast<IMapBitmapTileProvider*>(rasterMapProvider.get()); const float screenTile = tileProvider->getTileSize() * (_activeConfig.displayDensityFactor / tileProvider->getTileDensity()); _nearDistanceFromCameraToTarget = Utilities_BaseOpenGL::calculateCameraDistance(_mProjection, _activeConfig.viewport, TileSide3D / 2.0f, screenTile / 2.0f, 1.5f); _baseDistanceFromCameraToTarget = Utilities_BaseOpenGL::calculateCameraDistance(_mProjection, _activeConfig.viewport, TileSide3D / 2.0f, screenTile / 2.0f, 1.0f); _farDistanceFromCameraToTarget = Utilities_BaseOpenGL::calculateCameraDistance(_mProjection, _activeConfig.viewport, TileSide3D / 2.0f, screenTile / 2.0f, 0.75f); // zoomFraction == [ 0.0 ... 0.5] scales tile [1.0x ... 1.5x] // zoomFraction == [-0.5 ...-0.0] scales tile [.75x ... 1.0x] if(_activeConfig.zoomFraction >= 0.0f) _distanceFromCameraToTarget = _baseDistanceFromCameraToTarget - (_baseDistanceFromCameraToTarget - _nearDistanceFromCameraToTarget) * (2.0f * _activeConfig.zoomFraction); else _distanceFromCameraToTarget = _baseDistanceFromCameraToTarget - (_farDistanceFromCameraToTarget - _baseDistanceFromCameraToTarget) * (2.0f * _activeConfig.zoomFraction); _groundDistanceFromCameraToTarget = _distanceFromCameraToTarget * qCos(qDegreesToRadians(_activeConfig.elevationAngle)); _tileScaleFactor = ((_activeConfig.zoomFraction >= 0.0f) ? (1.0f + _activeConfig.zoomFraction) : (1.0f + 0.5f * _activeConfig.zoomFraction)); _scaleToRetainProjectedSize = _distanceFromCameraToTarget / _baseDistanceFromCameraToTarget; // Recalculate projection with obtained value _zSkyplane = _activeConfig.fogDistance * _scaleToRetainProjectedSize + _distanceFromCameraToTarget; _zFar = glm::length(glm::vec3(_projectionPlaneHalfWidth * (_zSkyplane / _zNear), _projectionPlaneHalfHeight * (_zSkyplane / _zNear), _zSkyplane)); _mProjection = glm::frustum(-_projectionPlaneHalfWidth, _projectionPlaneHalfWidth, -_projectionPlaneHalfHeight, _projectionPlaneHalfHeight, _zNear, _zFar); _mProjectionInv = glm::inverse(_mProjection); // Setup camera _mDistance = glm::translate(0.0f, 0.0f, -_distanceFromCameraToTarget); _mElevation = glm::rotate(_activeConfig.elevationAngle, glm::vec3(1.0f, 0.0f, 0.0f)); _mAzimuth = glm::rotate(_activeConfig.azimuth, glm::vec3(0.0f, 1.0f, 0.0f)); _mView = _mDistance * _mElevation * _mAzimuth; // Get inverse camera _mDistanceInv = glm::translate(0.0f, 0.0f, _distanceFromCameraToTarget); _mElevationInv = glm::rotate(-_activeConfig.elevationAngle, glm::vec3(1.0f, 0.0f, 0.0f)); _mAzimuthInv = glm::rotate(-_activeConfig.azimuth, glm::vec3(0.0f, 1.0f, 0.0f)); _mViewInv = _mAzimuthInv * _mElevationInv * _mDistanceInv; // Correct fog distance _correctedFogDistance = _activeConfig.fogDistance * _scaleToRetainProjectedSize + (_distanceFromCameraToTarget - _groundDistanceFromCameraToTarget); // Calculate skyplane size float zSkyplaneK = _zSkyplane / _zNear; _skyplaneHalfSize.x = zSkyplaneK * _projectionPlaneHalfWidth; _skyplaneHalfSize.y = zSkyplaneK * _projectionPlaneHalfHeight; // Compute visible tileset computeVisibleTileset(); }