From 851ccb0ca756cc4af982c4ed4d4e6efc371059d5 Mon Sep 17 00:00:00 2001 From: Nathaniel MacArthur-Warner Date: Wed, 23 Dec 2020 11:37:38 -0800 Subject: [PATCH 1/8] Fix creation of composite orthophotos in case where aspect ratio of input photos doesn't match tile --- simgear/scene/util/OrthophotoManager.cxx | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/simgear/scene/util/OrthophotoManager.cxx b/simgear/scene/util/OrthophotoManager.cxx index 65ad02d3..55507cbe 100644 --- a/simgear/scene/util/OrthophotoManager.cxx +++ b/simgear/scene/util/OrthophotoManager.cxx @@ -263,10 +263,11 @@ namespace simgear { const OrthophotoRef& some_orthophoto = orthophotos[0]; const ImageRef& some_image = some_orthophoto->_texture->getImage(); const OrthophotoBounds& some_bbox = some_orthophoto->getBbox(); - const double degs_to_pixels = some_image->s() / some_bbox.getWidth(); + const double degs_to_pixels_x = some_image->s() / some_bbox.getWidth(); + const double degs_to_pixels_y = some_image->t() / some_bbox.getHeight(); - const int total_width = degs_to_pixels * _bbox.getWidth(); - const int total_height = degs_to_pixels * _bbox.getHeight(); + const int total_width = degs_to_pixels_x * _bbox.getWidth(); + const int total_height = degs_to_pixels_y * _bbox.getHeight(); const int depth = some_image->r(); GLenum pixel_format = some_image->getPixelFormat(); @@ -279,10 +280,10 @@ namespace simgear { for (const auto& orthophoto : orthophotos) { const OrthophotoBounds& bounds = orthophoto->getBbox(); - const int width = degs_to_pixels * bounds.getWidth(); - const int height = degs_to_pixels * bounds.getHeight(); - const int s_offset = degs_to_pixels * _bbox.getLonOffset(bounds); - const int t_offset = degs_to_pixels * _bbox.getLatOffset(bounds); + const int width = degs_to_pixels_x * bounds.getWidth(); + const int height = degs_to_pixels_y * bounds.getHeight(); + const int s_offset = degs_to_pixels_x * _bbox.getLonOffset(bounds); + const int t_offset = degs_to_pixels_y * _bbox.getLatOffset(bounds); // Make a deep copy of the orthophoto's image so that we don't modify the original when scaling ImageRef sub_image = new osg::Image(*orthophoto->_texture->getImage(), osg::CopyOp::DEEP_COPY_ALL); From 0e7cf378a4497e0d3bec9680f858ea241174f615 Mon Sep 17 00:00:00 2001 From: Nathaniel MacArthur-Warner Date: Wed, 23 Dec 2020 14:07:34 -0800 Subject: [PATCH 2/8] Indent fix --- simgear/scene/util/OrthophotoManager.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/simgear/scene/util/OrthophotoManager.cxx b/simgear/scene/util/OrthophotoManager.cxx index 55507cbe..617138e5 100644 --- a/simgear/scene/util/OrthophotoManager.cxx +++ b/simgear/scene/util/OrthophotoManager.cxx @@ -264,7 +264,7 @@ namespace simgear { const ImageRef& some_image = some_orthophoto->_texture->getImage(); const OrthophotoBounds& some_bbox = some_orthophoto->getBbox(); const double degs_to_pixels_x = some_image->s() / some_bbox.getWidth(); - const double degs_to_pixels_y = some_image->t() / some_bbox.getHeight(); + const double degs_to_pixels_y = some_image->t() / some_bbox.getHeight(); const int total_width = degs_to_pixels_x * _bbox.getWidth(); const int total_height = degs_to_pixels_y * _bbox.getHeight(); From 6ed37c880adff20302be8d209fba1ac6faf72ce7 Mon Sep 17 00:00:00 2001 From: Nathaniel MacArthur-Warner Date: Wed, 23 Dec 2020 17:32:31 -0800 Subject: [PATCH 3/8] When creating composite orthophoto, only scale sub images when necessary --- simgear/scene/util/OrthophotoManager.cxx | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/simgear/scene/util/OrthophotoManager.cxx b/simgear/scene/util/OrthophotoManager.cxx index 617138e5..9dca6ac2 100644 --- a/simgear/scene/util/OrthophotoManager.cxx +++ b/simgear/scene/util/OrthophotoManager.cxx @@ -18,6 +18,7 @@ // Boston, MA 02110-1301, USA. #include "OrthophotoManager.hxx" +#include namespace simgear { @@ -285,16 +286,20 @@ namespace simgear { const int s_offset = degs_to_pixels_x * _bbox.getLonOffset(bounds); const int t_offset = degs_to_pixels_y * _bbox.getLatOffset(bounds); - // Make a deep copy of the orthophoto's image so that we don't modify the original when scaling - ImageRef sub_image = new osg::Image(*orthophoto->_texture->getImage(), osg::CopyOp::DEEP_COPY_ALL); + ImageRef sub_image = orthophoto->_texture->getImage(); if (sub_image->getPixelFormat() != pixel_format) { SG_LOG(SG_OSG, SG_ALERT, "Pixel format mismatch. Not creating part of composite orthophoto."); continue; } - sub_image->scaleImage(width, height, depth); - + if (sub_image->s() != width || sub_image->t() != height) { + SG_LOG(SG_OSG, SG_WARN, "Orthophoto resolution mismatch. Automatic scaling will be performed."); + // Make a deep copy of the orthophoto's image so that we don't modify the original when scaling + sub_image = new osg::Image(*sub_image, osg::CopyOp::DEEP_COPY_ALL); + sub_image->scaleImage(width, height, depth); + } + composite_image->copySubImage(s_offset, t_offset, 0, sub_image); } From a56d1718de98561145aedee5a00e942ca0677429 Mon Sep 17 00:00:00 2001 From: Nathaniel MacArthur-Warner Date: Wed, 23 Dec 2020 22:38:03 -0800 Subject: [PATCH 4/8] Check for and scale down oversize composite orthophotos --- simgear/scene/util/OrthophotoManager.cxx | 25 ++++++++++++++++++++++++ simgear/scene/util/OrthophotoManager.hxx | 3 ++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/simgear/scene/util/OrthophotoManager.cxx b/simgear/scene/util/OrthophotoManager.cxx index 9dca6ac2..4363349c 100644 --- a/simgear/scene/util/OrthophotoManager.cxx +++ b/simgear/scene/util/OrthophotoManager.cxx @@ -18,6 +18,7 @@ // Boston, MA 02110-1301, USA. #include "OrthophotoManager.hxx" +#include "SGSceneFeatures.hxx" #include namespace simgear { @@ -303,6 +304,30 @@ namespace simgear { composite_image->copySubImage(s_offset, t_offset, 0, sub_image); } + int max_texture_size = SGSceneFeatures::instance()->getMaxTextureSize(); + int new_width = total_width; + int new_height = total_height; + if (new_width > max_texture_size) { + int factor = new_width / max_texture_size; + new_width /= factor; + new_height /= factor; + } + if (new_height > max_texture_size) { + int factor = new_height / max_texture_size; + new_width /= factor; + new_height /= factor; + } + if (total_width != new_width || total_height != new_height) { + SG_LOG(SG_OSG, SG_INFO, "Composite orthophoto exceeds the maximum texture size of your GPU. Automatic scaling will be performed."); + ImageRef scaled_image; + bool success = ImageUtils::resizeImage(composite_image, new_width, new_height, scaled_image); + if (success) { + composite_image = scaled_image; + } else { + SG_LOG(SG_OSG, SG_ALERT, "Failed to scale composite orthophoto."); + } + } + _texture = textureFromImage(composite_image); } diff --git a/simgear/scene/util/OrthophotoManager.hxx b/simgear/scene/util/OrthophotoManager.hxx index ba2cc880..f53730f7 100644 --- a/simgear/scene/util/OrthophotoManager.hxx +++ b/simgear/scene/util/OrthophotoManager.hxx @@ -36,6 +36,7 @@ #include #include "SGSceneFeatures.hxx" #include "OsgSingleton.hxx" +#include "SGImageUtils.hxx" namespace simgear { @@ -108,4 +109,4 @@ namespace simgear { }; } -#endif \ No newline at end of file +#endif From 3fc6df203c2ae9449a87f5777f1896019a36c467 Mon Sep 17 00:00:00 2001 From: Nathaniel MacArthur-Warner Date: Wed, 23 Dec 2020 23:39:39 -0800 Subject: [PATCH 5/8] Attempt to convert subimage on pixel format mismatch, provide more helpful logs --- simgear/scene/util/OrthophotoManager.cxx | 33 ++++++++++++++++-------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/simgear/scene/util/OrthophotoManager.cxx b/simgear/scene/util/OrthophotoManager.cxx index 4363349c..aeac6448 100644 --- a/simgear/scene/util/OrthophotoManager.cxx +++ b/simgear/scene/util/OrthophotoManager.cxx @@ -289,19 +289,30 @@ namespace simgear { ImageRef sub_image = orthophoto->_texture->getImage(); - if (sub_image->getPixelFormat() != pixel_format) { - SG_LOG(SG_OSG, SG_ALERT, "Pixel format mismatch. Not creating part of composite orthophoto."); - continue; - } - if (sub_image->s() != width || sub_image->t() != height) { - SG_LOG(SG_OSG, SG_WARN, "Orthophoto resolution mismatch. Automatic scaling will be performed."); - // Make a deep copy of the orthophoto's image so that we don't modify the original when scaling - sub_image = new osg::Image(*sub_image, osg::CopyOp::DEEP_COPY_ALL); - sub_image->scaleImage(width, height, depth); + SG_LOG(SG_OSG, SG_INFO, "Orthophoto resolution mismatch. Automatic scaling will be performed."); + ImageRef scaled_image; + bool success = ImageUtils::resizeImage(sub_image, width, height, scaled_image); + if (success) { + sub_image = scaled_image; + } else { + SG_LOG(SG_OSG, SG_ALERT, "Failed to scale part of composite orthophoto. The image on the airport may be distorted."); + } } - composite_image->copySubImage(s_offset, t_offset, 0, sub_image); + if (sub_image->getPixelFormat() != pixel_format || sub_image->getDataType() != data_type) { + SG_LOG(SG_OSG, SG_INFO, "Pixel format or data type mismatch. Attempting to convert component of composite orthophoto."); + if (ImageUtils::canConvert(sub_image, pixel_format, data_type)) { + sub_image = ImageUtils::convert(sub_image, pixel_format, data_type); + } else { + SG_LOG(SG_OSG, SG_ALERT, "Failed to convert component of composite orthophoto. Part of the image on the airport may be missing."); + } + } + + bool success = ImageUtils::copyAsSubImage(sub_image, composite_image, s_offset, t_offset); + if (!success) { + SG_LOG(SG_OSG, SG_ALERT, "Failed to copy part of composite orthophoto. Part of the image on the aiport may be missing."); + } } int max_texture_size = SGSceneFeatures::instance()->getMaxTextureSize(); @@ -324,7 +335,7 @@ namespace simgear { if (success) { composite_image = scaled_image; } else { - SG_LOG(SG_OSG, SG_ALERT, "Failed to scale composite orthophoto."); + SG_LOG(SG_OSG, SG_ALERT, "Failed to scale composite orthophoto. You may encounter errors due to the oversize texture."); } } From 7dc8a86524d0050c24626a3d81fe8eec6e122d04 Mon Sep 17 00:00:00 2001 From: Nathaniel MacArthur-Warner Date: Thu, 24 Dec 2020 12:26:30 -0800 Subject: [PATCH 6/8] Warn when loading uncompressed DDS files since it causes problems on some systems --- simgear/scene/util/OrthophotoManager.cxx | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/simgear/scene/util/OrthophotoManager.cxx b/simgear/scene/util/OrthophotoManager.cxx index aeac6448..28b1c3ca 100644 --- a/simgear/scene/util/OrthophotoManager.cxx +++ b/simgear/scene/util/OrthophotoManager.cxx @@ -231,25 +231,26 @@ namespace simgear { dds_path.concat(".dds"); if (dds_path.exists()) { ImageRef image = osgDB::readRefImageFile(dds_path.str()); - if (!image) { - return nullptr; + if (image) { + if (!image->isCompressed()) { + SG_LOG(SG_OSG, SG_WARN, "Loading uncompressed DDS orthophoto. This is known to cause problems on some systems."); + } + const Texture2DRef texture = textureFromImage(image); + const OrthophotoBounds bbox = OrthophotoBounds::fromBucket(bucket); + return new Orthophoto(texture, bbox); } - const Texture2DRef texture = textureFromImage(image); - const OrthophotoBounds bbox = OrthophotoBounds::fromBucket(bucket); - return new Orthophoto(texture, bbox); } SGPath png_path = path; png_path.concat(".png"); if (png_path.exists()) { ImageRef image = osgDB::readRefImageFile(png_path.str()); - if (!image) { - return nullptr; + if (image) { + image->flipVertical(); + const Texture2DRef texture = textureFromImage(image); + const OrthophotoBounds bbox = OrthophotoBounds::fromBucket(bucket); + return new Orthophoto(texture, bbox); } - image->flipVertical(); - const Texture2DRef texture = textureFromImage(image); - const OrthophotoBounds bbox = OrthophotoBounds::fromBucket(bucket); - return new Orthophoto(texture, bbox); } } From 7572d8f6eefff74cbe098dea906189ca8b8d3e2f Mon Sep 17 00:00:00 2001 From: Nathaniel MacArthur-Warner Date: Thu, 24 Dec 2020 14:43:14 -0800 Subject: [PATCH 7/8] Another logging improvement --- simgear/scene/util/OrthophotoManager.cxx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/simgear/scene/util/OrthophotoManager.cxx b/simgear/scene/util/OrthophotoManager.cxx index 28b1c3ca..3f6ed639 100644 --- a/simgear/scene/util/OrthophotoManager.cxx +++ b/simgear/scene/util/OrthophotoManager.cxx @@ -238,6 +238,8 @@ namespace simgear { const Texture2DRef texture = textureFromImage(image); const OrthophotoBounds bbox = OrthophotoBounds::fromBucket(bucket); return new Orthophoto(texture, bbox); + } else { + SG_LOG(SG_OSG, SG_ALERT, "Failed to load orthophoto with path " << dds_path); } } @@ -250,6 +252,8 @@ namespace simgear { const Texture2DRef texture = textureFromImage(image); const OrthophotoBounds bbox = OrthophotoBounds::fromBucket(bucket); return new Orthophoto(texture, bbox); + } else { + SG_LOG(SG_OSG, SG_ALERT, "Failed to load orthophoto with path " << png_path); } } } From 1960a1b2648d9f1a18b6f4661d39d090d775609f Mon Sep 17 00:00:00 2001 From: Nathaniel MacArthur-Warner Date: Thu, 24 Dec 2020 14:55:34 -0800 Subject: [PATCH 8/8] Get rid of duplicate log --- simgear/scene/util/OrthophotoManager.cxx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/simgear/scene/util/OrthophotoManager.cxx b/simgear/scene/util/OrthophotoManager.cxx index 3f6ed639..28b1c3ca 100644 --- a/simgear/scene/util/OrthophotoManager.cxx +++ b/simgear/scene/util/OrthophotoManager.cxx @@ -238,8 +238,6 @@ namespace simgear { const Texture2DRef texture = textureFromImage(image); const OrthophotoBounds bbox = OrthophotoBounds::fromBucket(bucket); return new Orthophoto(texture, bbox); - } else { - SG_LOG(SG_OSG, SG_ALERT, "Failed to load orthophoto with path " << dds_path); } } @@ -252,8 +250,6 @@ namespace simgear { const Texture2DRef texture = textureFromImage(image); const OrthophotoBounds bbox = OrthophotoBounds::fromBucket(bucket); return new Orthophoto(texture, bbox); - } else { - SG_LOG(SG_OSG, SG_ALERT, "Failed to load orthophoto with path " << png_path); } } }