mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-03-13 17:09:05 -05:00
Merged master in
This commit is contained in:
Submodule apps/OpenSpace/ext/sgct updated: f8659e216d...15c2a977e1
@@ -865,11 +865,11 @@ void setSgctDelegateFunctions() {
|
||||
currentWindow->viewports().front()->nonLinearProjection()
|
||||
) != nullptr;
|
||||
};
|
||||
sgctDelegate.takeScreenshot = [](bool applyWarping) {
|
||||
sgctDelegate.takeScreenshot = [](bool applyWarping, std::vector<int> windowIds) {
|
||||
ZoneScoped
|
||||
|
||||
Settings::instance().setCaptureFromBackBuffer(applyWarping);
|
||||
Engine::instance().takeScreenshot();
|
||||
Engine::instance().takeScreenshot(std::move(windowIds));
|
||||
return Engine::instance().screenShotNumber();
|
||||
};
|
||||
sgctDelegate.swapBuffer = []() {
|
||||
|
||||
@@ -7,28 +7,46 @@ local path = asset.syncedResource({
|
||||
Version = 1
|
||||
})
|
||||
|
||||
local layer = {
|
||||
Identifier = "ERA5_Land_HighRes_Monthly_2M_Temperature_Temporal",
|
||||
Name = "ERA5 Land HighRes Monthly 2M Temperature (Temporal)",
|
||||
local layer_prototype = {
|
||||
Identifier = "ERA5_Land_HighRes_Monthly_2M_Temperature_Temporal_prototype",
|
||||
Name = "ERA5 Land HighRes Monthly 2M Temperature (Temporal) [Prototype]",
|
||||
Type = "TemporalTileLayer",
|
||||
FilePath =
|
||||
"<OpenSpaceTemporalGDALDataset>" ..
|
||||
"<OpenSpaceTimeStart>1981-01-01</OpenSpaceTimeStart>" ..
|
||||
"<OpenSpaceTimeEnd>1990-10-01</OpenSpaceTimeEnd>" ..
|
||||
"<OpenSpaceTimeResolution>1M</OpenSpaceTimeResolution>" ..
|
||||
"<OpenSpaceTimeIdFormat>YYYY-MM-DD</OpenSpaceTimeIdFormat>" ..
|
||||
"<OpenSpaceTransferFunction>" .. path .. "rainbow.png</OpenSpaceTransferFunction>" ..
|
||||
"<OpenSpaceTimeInterpolation>linear</OpenSpaceTimeInterpolation>" ..
|
||||
"<FilePath>" .. path .. "${OpenSpaceTimeId}-land.png</FilePath>" ..
|
||||
"</OpenSpaceTemporalGDALDataset>",
|
||||
Mode = "Prototyped",
|
||||
Prototyped = {
|
||||
Time = {
|
||||
Start = "1981-01-01",
|
||||
End = "1990-10-01"
|
||||
},
|
||||
TemporalResolution = "1M",
|
||||
TimeFormat = "YYYY-MM-DD",
|
||||
Prototype = path .. "${OpenSpaceTimeId}-land.png"
|
||||
},
|
||||
Interpolation = true,
|
||||
Colormap = path .. "rainbow.png",
|
||||
Description = [[ Temporal coverage: 01 Jan 1981 - 31 Dec 2020.]]
|
||||
}
|
||||
|
||||
local layer_folder = {
|
||||
Identifier = "ERA5_Land_HighRes_Monthly_2M_Temperature_Temporal_folder",
|
||||
Name = "ERA5 Land HighRes Monthly 2M Temperature (Temporal) [Folder]",
|
||||
Type = "TemporalTileLayer",
|
||||
Mode = "Folder",
|
||||
Folder = {
|
||||
Folder = "C:/Development/sync/http/earth_textures_climate/1",
|
||||
Format = "%Y-%m-%d-land.png"
|
||||
},
|
||||
Interpolation = true,
|
||||
Colormap = path .. "rainbow.png",
|
||||
Description = [[ Temporal coverage: 01 Jan 1981 - 31 Dec 2020.]]
|
||||
}
|
||||
|
||||
asset.onInitialize(function ()
|
||||
openspace.globebrowsing.addLayer(globeIdentifier, "ColorLayers", layer)
|
||||
openspace.globebrowsing.addLayer(globeIdentifier, "ColorLayers", layer_prototype)
|
||||
openspace.globebrowsing.addLayer(globeIdentifier, "ColorLayers", layer_folder)
|
||||
end)
|
||||
|
||||
asset.export("layer", layer)
|
||||
asset.export("layer", layer_prototype)
|
||||
|
||||
asset.meta = {
|
||||
Name = "Climate Earth Layers",
|
||||
Version = "1.0",
|
||||
|
||||
@@ -4,14 +4,20 @@ local layer = {
|
||||
Identifier = "AMSR2_GCOM_W1_Sea_Ice_Concentration_Temporal",
|
||||
Name = "AMSR2 GCOM W1 Sea Ice Concentration (Temporal)",
|
||||
Type = "TemporalTileLayer",
|
||||
FilePath = openspace.globebrowsing.createTemporalGibsGdalXml(
|
||||
"AMSRU2_Sea_Ice_Concentration_12km",
|
||||
"2012-05-08",
|
||||
"Yesterday",
|
||||
"1d",
|
||||
"2km",
|
||||
"png"
|
||||
),
|
||||
Mode = "Prototyped",
|
||||
Prototyped = {
|
||||
Time = {
|
||||
Start = "2012-05-08",
|
||||
End = "Yesterday"
|
||||
},
|
||||
TemporalResolution = "1d",
|
||||
TimeFormat = "YYYY-MM-DD",
|
||||
Prototype = openspace.globebrowsing.createTemporalGibsGdalXml(
|
||||
"AMSRU2_Sea_Ice_Concentration_12km",
|
||||
"2km",
|
||||
"png"
|
||||
)
|
||||
},
|
||||
Description = [[ Temporal coverage: 02 July 2012 - Present. The Advanced Microwave
|
||||
Scanning Radiometer-E/Advanced Microwave Scanning Radiometer-2 (AMSR-E/AMSR2)
|
||||
unified "Sea Ice Concentration (12 km)" layer displays the percent of sea ice
|
||||
|
||||
@@ -4,14 +4,20 @@ local layer = {
|
||||
Identifier = "Aqua_Modis_Temporal",
|
||||
Name = "Aqua Modis (Temporal)",
|
||||
Type = "TemporalTileLayer",
|
||||
FilePath = openspace.globebrowsing.createTemporalGibsGdalXml(
|
||||
"MODIS_Aqua_CorrectedReflectance_TrueColor",
|
||||
"2002-07-04",
|
||||
"Yesterday",
|
||||
"1d",
|
||||
"250m",
|
||||
"jpg"
|
||||
),
|
||||
Mode = "Prototyped",
|
||||
Prototyped = {
|
||||
Time = {
|
||||
Start = "2002-07-04",
|
||||
End = "Yesterday"
|
||||
},
|
||||
TemporalResolution = "1d",
|
||||
TimeFormat = "YYYY-MM-DD",
|
||||
Prototype = openspace.globebrowsing.createTemporalGibsGdalXml(
|
||||
"MODIS_Aqua_CorrectedReflectance_TrueColor",
|
||||
"250m",
|
||||
"jpg"
|
||||
)
|
||||
},
|
||||
Description = [[ Temporal coverage: 03 July 2002 - Present. True Color: Red = Band 1,
|
||||
Green = Band 4, Blue = Band 3. These images are called true-color or natural color
|
||||
because this combination of wavelengths is similar to what the human eye would see.
|
||||
|
||||
@@ -13,14 +13,20 @@ local layer = {
|
||||
Identifier = "Temporal_VIIRS_SNPP",
|
||||
Name = "Temporal VIIRS SNPP",
|
||||
Type = "TemporalTileLayer",
|
||||
FilePath = openspace.globebrowsing.createTemporalGibsGdalXml(
|
||||
"VIIRS_SNPP_CorrectedReflectance_TrueColor",
|
||||
"2015-11-24",
|
||||
"Today",
|
||||
"1d",
|
||||
"250m",
|
||||
"jpg"
|
||||
),
|
||||
Mode = "Prototyped",
|
||||
Prototyped = {
|
||||
Time = {
|
||||
Start = "2015-11-24",
|
||||
End = "Today"
|
||||
},
|
||||
TemporalResolution = "1d",
|
||||
TimeFormat = "YYYY-MM-DD",
|
||||
Prototype = openspace.globebrowsing.createTemporalGibsGdalXml(
|
||||
"VIIRS_SNPP_CorrectedReflectance_TrueColor",
|
||||
"250m",
|
||||
"jpg"
|
||||
)
|
||||
},
|
||||
PadTiles = false
|
||||
}
|
||||
},
|
||||
|
||||
@@ -4,14 +4,20 @@ local layer = {
|
||||
Identifier = "GHRSST_L4_G1SST_Sea_Surface_Temperature_Temporal",
|
||||
Name = "GHRSST L4 G1SST Sea Surface Temperature (Temporal)",
|
||||
Type = "TemporalTileLayer",
|
||||
FilePath = openspace.globebrowsing.createTemporalGibsGdalXml(
|
||||
"GHRSST_L4_G1SST_Sea_Surface_Temperature",
|
||||
"2010-06-21",
|
||||
"2019-12-08",
|
||||
"1d",
|
||||
"1km",
|
||||
"png"
|
||||
),
|
||||
Mode = "Prototyped",
|
||||
Prototyped = {
|
||||
Time = {
|
||||
Start = "2010-06-21",
|
||||
End = "2019-12-08"
|
||||
},
|
||||
TemporalResolution = "1d",
|
||||
TimeFormat = "YYYY-MM-DD",
|
||||
Prototype = openspace.globebrowsing.createTemporalGibsGdalXml(
|
||||
"GHRSST_L4_G1SST_Sea_Surface_Temperature",
|
||||
"1km",
|
||||
"png"
|
||||
)
|
||||
},
|
||||
Description = [[ Temporal coverage: 21 June 2010 - 08 December 2019. The imagery
|
||||
resolution is 1 km, and the temporal resolution is daily.]],
|
||||
Author = "NASA EOSDIS Global Imagery Browse Services"
|
||||
|
||||
@@ -4,14 +4,20 @@ local layer = {
|
||||
Identifier = "GHRSST_L4_MUR_Sea_Surface_Temperature_Temporal",
|
||||
Name = "GHRSST L4 MUR Sea Surface Temperature (Temporal)",
|
||||
Type = "TemporalTileLayer",
|
||||
FilePath = openspace.globebrowsing.createTemporalGibsGdalXml(
|
||||
"GHRSST_L4_MUR_Sea_Surface_Temperature",
|
||||
"2002-06-01",
|
||||
"Yesterday",
|
||||
"1d",
|
||||
"1km",
|
||||
"png"
|
||||
),
|
||||
Mode = "Prototyped",
|
||||
Prototyped = {
|
||||
Time = {
|
||||
Start = "2002-06-01",
|
||||
End = "Yesterday"
|
||||
},
|
||||
TemporalResolution = "1d",
|
||||
TimeFormat = "YYYY-MM-DD",
|
||||
Prototype = openspace.globebrowsing.createTemporalGibsGdalXml(
|
||||
"GHRSST_L4_MUR_Sea_Surface_Temperature",
|
||||
"1km",
|
||||
"png"
|
||||
)
|
||||
},
|
||||
Description = [[ Temporal coverage: 01 June 2002 - Present. The imagery resolution
|
||||
is 1 km, and the temporal resolution is daily.]]
|
||||
}
|
||||
|
||||
@@ -4,14 +4,20 @@ local layer = {
|
||||
Identifier = "MODIS_Terra_Chlorophyll_A_Temporal",
|
||||
Name = "MODIS Terra Chlorophyll A (Temporal)",
|
||||
Type = "TemporalTileLayer",
|
||||
FilePath = openspace.globebrowsing.createTemporalGibsGdalXml(
|
||||
Mode = "Prototyped",
|
||||
Prototyped = {
|
||||
Time = {
|
||||
Start = "2013-07-02",
|
||||
End = "Yesterday"
|
||||
},
|
||||
TemporalResolution = "1d",
|
||||
TimeFormat = "YYYY-MM-DD",
|
||||
Prototype = openspace.globebrowsing.createTemporalGibsGdalXml(
|
||||
"MODIS_Terra_Chlorophyll_A",
|
||||
"2013-07-02",
|
||||
"Yesterday",
|
||||
"1d",
|
||||
"1km",
|
||||
"png"
|
||||
),
|
||||
)
|
||||
},
|
||||
Description = [[ Temporal coverage: 02 July 2013 - Present. The imagery resolution
|
||||
is 1 km, and the temporal resolution is daily.]]
|
||||
}
|
||||
|
||||
@@ -4,14 +4,20 @@ local layer = {
|
||||
Identifier = "Terra_Modis_Temporal",
|
||||
Name = "Terra Modis (Temporal)",
|
||||
Type = "TemporalTileLayer",
|
||||
FilePath = openspace.globebrowsing.createTemporalGibsGdalXml(
|
||||
"MODIS_Terra_CorrectedReflectance_TrueColor",
|
||||
"2000-02-24",
|
||||
"Yesterday",
|
||||
"1d",
|
||||
"250m",
|
||||
"jpg"
|
||||
),
|
||||
Mode = "Prototyped",
|
||||
Prototyped = {
|
||||
Time = {
|
||||
Start = "2000-02-24",
|
||||
End = "Yesterday"
|
||||
},
|
||||
TemporalResolution = "1d",
|
||||
TimeFormat = "YYYY-MM-DD",
|
||||
Prototype = openspace.globebrowsing.createTemporalGibsGdalXml(
|
||||
"MODIS_Terra_CorrectedReflectance_TrueColor",
|
||||
"250m",
|
||||
"jpg"
|
||||
)
|
||||
},
|
||||
Description = [[ Temporal coverage: 02 July 2013 - Present. The imagery resolution
|
||||
is 1 km, and the temporal resolution is daily.]]
|
||||
}
|
||||
|
||||
@@ -4,14 +4,20 @@ local layer = {
|
||||
Identifier = "VIIRS_SNPP_Temporal",
|
||||
Name = "VIIRS SNPP (Temporal)",
|
||||
Type = "TemporalTileLayer",
|
||||
FilePath = openspace.globebrowsing.createTemporalGibsGdalXml(
|
||||
"VIIRS_SNPP_CorrectedReflectance_TrueColor",
|
||||
"2015-11-24",
|
||||
"Yesterday",
|
||||
"1d",
|
||||
"250m",
|
||||
"jpg"
|
||||
),
|
||||
Mode = "Prototyped",
|
||||
Prototyped = {
|
||||
Time = {
|
||||
Start = "2015-11-24",
|
||||
End = "Yesterday"
|
||||
},
|
||||
TemporalResolution = "1d",
|
||||
TimeFormat = "YYYY-MM-DD",
|
||||
Prototype = openspace.globebrowsing.createTemporalGibsGdalXml(
|
||||
"VIIRS_SNPP_CorrectedReflectance_TrueColor",
|
||||
"250m",
|
||||
"jpg"
|
||||
)
|
||||
},
|
||||
Description = [[ Temporal coverage: 11 November 2015 - Present. The imagery resolution
|
||||
is 0.25 km, and the temporal resolution is daily.]]
|
||||
}
|
||||
|
||||
@@ -4,14 +4,20 @@ local layer = {
|
||||
Identifier = "Earth_at_Night_Temporal",
|
||||
Name = "Earth at Night (Temporal)",
|
||||
Type = "TemporalTileLayer",
|
||||
FilePath = openspace.globebrowsing.createTemporalGibsGdalXml(
|
||||
"VIIRS_SNPP_DayNightBand_ENCC",
|
||||
"2012-05-08",
|
||||
"Yesterday",
|
||||
"1d",
|
||||
"500m",
|
||||
"png"
|
||||
),
|
||||
Mode = "Prototyped",
|
||||
Prototyped = {
|
||||
Time = {
|
||||
Start = "2012-05-08",
|
||||
End = "Yesterday"
|
||||
},
|
||||
TemporalResolution = "1d",
|
||||
TimeFormat = "YYYY-MM-DD",
|
||||
Prototype = openspace.globebrowsing.createTemporalGibsGdalXml(
|
||||
"VIIRS_SNPP_DayNightBand_ENCC",
|
||||
"500m",
|
||||
"png"
|
||||
)
|
||||
},
|
||||
Description = [[ The VIIRS Nighttime Imagery (Day/Night Band, Enhanced Near Constant
|
||||
Contrast) layer shows the Earth's surface and atmosphere using a sensor designed
|
||||
to capture low-light emission sources, under varying illumination conditions. It
|
||||
|
||||
@@ -20,7 +20,7 @@ asset.require("./layers/colorlayers/hirisels")
|
||||
-- Height layers
|
||||
asset.require("./layers/heightlayers/mola_sweden")
|
||||
asset.require("./layers/heightlayers/mola_utah")
|
||||
local heightLayer = asset.require("./layers/heightlayers/mdem200m")
|
||||
local heightLayer = asset.require("./layers/heightlayers/MDEM200M")
|
||||
asset.require("./layers/heightlayers/hirisels")
|
||||
|
||||
-- Overlays
|
||||
|
||||
@@ -3,7 +3,7 @@ asset.require("./static_server")
|
||||
local guiCustomization = asset.require("customization/gui")
|
||||
|
||||
-- Select which commit hashes to use for the frontend and backend
|
||||
local frontendHash = "4fe18eea379c8493dbcb2cea6798d09a85819912"
|
||||
local frontendHash = "7e513ba86b0bb989b72f22712ebf0bb5a626ba06"
|
||||
local dataProvider = "data.openspaceproject.com/files/webgui"
|
||||
|
||||
local frontend = asset.syncedResource({
|
||||
|
||||
Submodule ext/ghoul updated: 0edf5e2588...a94d2561aa
@@ -76,7 +76,8 @@ struct WindowDelegate {
|
||||
|
||||
bool (*isFisheyeRendering)() = []() { return false; };
|
||||
|
||||
unsigned int (*takeScreenshot)(bool applyWarping) = [](bool) { return 0u; };
|
||||
unsigned int (*takeScreenshot)(bool applyWarping, std::vector<int> windowIds) =
|
||||
[](bool, std::vector<int>) { return 0u; };
|
||||
|
||||
void (*swapBuffer)() = []() {};
|
||||
|
||||
|
||||
@@ -148,6 +148,7 @@ private:
|
||||
// Reset camera direction to the aim node.
|
||||
properties::TriggerProperty _retargetAim;
|
||||
|
||||
properties::BoolProperty _followAnchorNodeRotation;
|
||||
properties::FloatProperty _followAnchorNodeRotationDistance;
|
||||
properties::FloatProperty _minimumAllowedDistance;
|
||||
|
||||
|
||||
@@ -81,6 +81,8 @@ public:
|
||||
static scripting::LuaLibrary luaLibrary();
|
||||
|
||||
private:
|
||||
void handlePathEnd();
|
||||
|
||||
/**
|
||||
* Populate list of nodes that are relevant for collision checks, etc
|
||||
*/
|
||||
@@ -90,6 +92,7 @@ private:
|
||||
|
||||
std::unique_ptr<Path> _currentPath = nullptr;
|
||||
bool _isPlaying = false;
|
||||
bool _startSimulationTimeOnFinish = false;
|
||||
|
||||
properties::OptionProperty _defaultPathType;
|
||||
properties::BoolProperty _includeRoll;
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <openspace/properties/propertyowner.h>
|
||||
|
||||
#include <openspace/properties/optionproperty.h>
|
||||
#include <openspace/properties/list/intlistproperty.h>
|
||||
#include <openspace/properties/scalar/boolproperty.h>
|
||||
#include <openspace/properties/scalar/intproperty.h>
|
||||
#include <openspace/properties/scalar/floatproperty.h>
|
||||
@@ -177,6 +178,7 @@ private:
|
||||
properties::BoolProperty _showVersionInfo;
|
||||
properties::BoolProperty _showCameraInfo;
|
||||
|
||||
properties::IntListProperty _screenshotWindowIds;
|
||||
properties::BoolProperty _applyWarping;
|
||||
properties::BoolProperty _screenshotUseDate;
|
||||
properties::BoolProperty _showFrameInformation;
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
#include <ghoul/glm.h>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <modules/galaxy/rendering/renderablegalaxy.h>
|
||||
#include <modules/galaxy/tasks/milkywayconversiontask.h>
|
||||
#include <modules/galaxy/tasks/milkywaypointsconversiontask.h>
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/rendering/renderable.h>
|
||||
#include <openspace/util/factorymanager.h>
|
||||
#include <ghoul/misc/assert.h>
|
||||
@@ -47,4 +48,10 @@ void GalaxyModule::internalInitialize(const ghoul::Dictionary&) {
|
||||
fTask->registerClass<MilkywayPointsConversionTask>("MilkywayPointsConversionTask");
|
||||
}
|
||||
|
||||
std::vector<documentation::Documentation> GalaxyModule::documentations() const {
|
||||
return {
|
||||
RenderableGalaxy::Documentation()
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -35,6 +35,8 @@ public:
|
||||
|
||||
GalaxyModule();
|
||||
|
||||
std::vector<documentation::Documentation> documentations() const override;
|
||||
|
||||
private:
|
||||
void internalInitialize(const ghoul::Dictionary&) override;
|
||||
};
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
namespace {
|
||||
constexpr int8_t CurrentCacheVersion = 1;
|
||||
|
||||
constexpr const char* _loggerCat = "Renderable Galaxy";
|
||||
constexpr const char* _loggerCat = "RenderableGalaxy";
|
||||
|
||||
enum StarRenderingMethod {
|
||||
Points,
|
||||
@@ -125,8 +125,7 @@ namespace {
|
||||
{
|
||||
"Downscale",
|
||||
"Downscale Factor Volume Rendering",
|
||||
"This value set the downscaling factor"
|
||||
" when rendering the current volume."
|
||||
"This value sets the downscaling factor when rendering the current volume."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo NumberOfRayCastingStepsInfo =
|
||||
@@ -229,6 +228,10 @@ namespace {
|
||||
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation RenderableGalaxy::Documentation() {
|
||||
return codegen::doc<Parameters>("galaxy_renderablegalaxy");
|
||||
}
|
||||
|
||||
RenderableGalaxy::RenderableGalaxy(const ghoul::Dictionary& dictionary)
|
||||
: Renderable(dictionary)
|
||||
, _volumeRenderingEnabled(VolumeRenderingEnabledInfo, true)
|
||||
|
||||
@@ -54,6 +54,8 @@ public:
|
||||
void render(const RenderData& data, RendererTasks& tasks) override;
|
||||
void update(const UpdateData& data) override;
|
||||
|
||||
static documentation::Documentation Documentation();
|
||||
|
||||
private:
|
||||
void renderPoints(const RenderData& data);
|
||||
void renderBillboards(const RenderData& data);
|
||||
|
||||
@@ -57,9 +57,18 @@ set(HEADER_FILES
|
||||
src/skirtedgrid.h
|
||||
src/tileindex.h
|
||||
src/tileloadjob.h
|
||||
src/tileprovider.h
|
||||
src/tiletextureinitdata.h
|
||||
src/timequantizer.h
|
||||
src/tileprovider/defaulttileprovider.h
|
||||
src/tileprovider/imagesequencetileprovider.h
|
||||
src/tileprovider/singleimagetileprovider.h
|
||||
src/tileprovider/sizereferencetileprovider.h
|
||||
src/tileprovider/temporaltileprovider.h
|
||||
src/tileprovider/texttileprovider.h
|
||||
src/tileprovider/tileindextileprovider.h
|
||||
src/tileprovider/tileprovider.h
|
||||
src/tileprovider/tileproviderbyindex.h
|
||||
src/tileprovider/tileproviderbylevel.h
|
||||
)
|
||||
|
||||
set(SOURCE_FILES
|
||||
@@ -87,9 +96,18 @@ set(SOURCE_FILES
|
||||
src/skirtedgrid.cpp
|
||||
src/tileindex.cpp
|
||||
src/tileloadjob.cpp
|
||||
src/tileprovider.cpp
|
||||
src/tiletextureinitdata.cpp
|
||||
src/timequantizer.cpp
|
||||
src/tileprovider/defaulttileprovider.cpp
|
||||
src/tileprovider/imagesequencetileprovider.cpp
|
||||
src/tileprovider/singleimagetileprovider.cpp
|
||||
src/tileprovider/sizereferencetileprovider.cpp
|
||||
src/tileprovider/temporaltileprovider.cpp
|
||||
src/tileprovider/texttileprovider.cpp
|
||||
src/tileprovider/tileindextileprovider.cpp
|
||||
src/tileprovider/tileprovider.cpp
|
||||
src/tileprovider/tileproviderbyindex.cpp
|
||||
src/tileprovider/tileproviderbylevel.cpp
|
||||
)
|
||||
source_group("Source Files" FILES ${SOURCE_FILES})
|
||||
|
||||
|
||||
@@ -35,7 +35,15 @@
|
||||
#include <modules/globebrowsing/src/layeradjustment.h>
|
||||
#include <modules/globebrowsing/src/layermanager.h>
|
||||
#include <modules/globebrowsing/src/memoryawaretilecache.h>
|
||||
#include <modules/globebrowsing/src/tileprovider.h>
|
||||
#include <modules/globebrowsing/src/tileprovider/defaulttileprovider.h>
|
||||
#include <modules/globebrowsing/src/tileprovider/imagesequencetileprovider.h>
|
||||
#include <modules/globebrowsing/src/tileprovider/singleimagetileprovider.h>
|
||||
#include <modules/globebrowsing/src/tileprovider/sizereferencetileprovider.h>
|
||||
#include <modules/globebrowsing/src/tileprovider/temporaltileprovider.h>
|
||||
#include <modules/globebrowsing/src/tileprovider/tileindextileprovider.h>
|
||||
#include <modules/globebrowsing/src/tileprovider/tileprovider.h>
|
||||
#include <modules/globebrowsing/src/tileprovider/tileproviderbyindex.h>
|
||||
#include <modules/globebrowsing/src/tileprovider/tileproviderbylevel.h>
|
||||
#include <openspace/documentation/verifier.h>
|
||||
#include <openspace/engine/globalscallbacks.h>
|
||||
#include <openspace/navigation/navigationhandler.h>
|
||||
@@ -236,7 +244,7 @@ void GlobeBrowsingModule::internalInitialize(const ghoul::Dictionary& dict) {
|
||||
_tileCache = std::make_unique<cache::MemoryAwareTileCache>(_tileCacheSizeMB);
|
||||
addPropertySubOwner(_tileCache.get());
|
||||
|
||||
tileprovider::initializeDefaultTile();
|
||||
TileProvider::initializeDefaultTile();
|
||||
|
||||
// Convert from MB to Bytes
|
||||
GdalWrapper::create(
|
||||
@@ -249,10 +257,9 @@ void GlobeBrowsingModule::internalInitialize(const ghoul::Dictionary& dict) {
|
||||
global::callback::deinitializeGL->emplace_back([]() {
|
||||
ZoneScopedN("GlobeBrowsingModule")
|
||||
|
||||
tileprovider::deinitializeDefaultTile();
|
||||
TileProvider::deinitializeDefaultTile();
|
||||
});
|
||||
|
||||
|
||||
// Render
|
||||
global::callback::render->emplace_back([&]() {
|
||||
ZoneScopedN("GlobeBrowsingModule")
|
||||
@@ -279,46 +286,45 @@ void GlobeBrowsingModule::internalInitialize(const ghoul::Dictionary& dict) {
|
||||
ghoul_assert(fRotation, "Rotation factory was not created");
|
||||
fRotation->registerClass<globebrowsing::GlobeRotation>("GlobeRotation");
|
||||
|
||||
auto fTileProvider =
|
||||
std::make_unique<ghoul::TemplateFactory<tileprovider::TileProvider>>();
|
||||
auto fTileProvider = std::make_unique<ghoul::TemplateFactory<TileProvider>>();
|
||||
ghoul_assert(fTileProvider, "TileProvider factory was not created");
|
||||
|
||||
fTileProvider->registerClass<tileprovider::DefaultTileProvider>(
|
||||
fTileProvider->registerClass<DefaultTileProvider>(
|
||||
layergroupid::LAYER_TYPE_NAMES[static_cast<int>(
|
||||
layergroupid::TypeID::DefaultTileLayer
|
||||
)]
|
||||
);
|
||||
fTileProvider->registerClass<tileprovider::SingleImageProvider>(
|
||||
fTileProvider->registerClass<SingleImageProvider>(
|
||||
layergroupid::LAYER_TYPE_NAMES[static_cast<int>(
|
||||
layergroupid::TypeID::SingleImageTileLayer
|
||||
)]
|
||||
);
|
||||
fTileProvider->registerClass<tileprovider::ImageSequenceTileProvider>(
|
||||
fTileProvider->registerClass<ImageSequenceTileProvider>(
|
||||
layergroupid::LAYER_TYPE_NAMES[static_cast<int>(
|
||||
layergroupid::TypeID::ImageSequenceTileLayer
|
||||
)]
|
||||
);
|
||||
fTileProvider->registerClass<tileprovider::TemporalTileProvider>(
|
||||
fTileProvider->registerClass<TemporalTileProvider>(
|
||||
layergroupid::LAYER_TYPE_NAMES[static_cast<int>(
|
||||
layergroupid::TypeID::TemporalTileLayer
|
||||
)]
|
||||
);
|
||||
fTileProvider->registerClass<tileprovider::TileIndexTileProvider>(
|
||||
fTileProvider->registerClass<TileIndexTileProvider>(
|
||||
layergroupid::LAYER_TYPE_NAMES[static_cast<int>(
|
||||
layergroupid::TypeID::TileIndexTileLayer
|
||||
)]
|
||||
);
|
||||
fTileProvider->registerClass<tileprovider::SizeReferenceTileProvider>(
|
||||
fTileProvider->registerClass<SizeReferenceTileProvider>(
|
||||
layergroupid::LAYER_TYPE_NAMES[static_cast<int>(
|
||||
layergroupid::TypeID::SizeReferenceTileLayer
|
||||
)]
|
||||
);
|
||||
fTileProvider->registerClass<tileprovider::TileProviderByLevel>(
|
||||
fTileProvider->registerClass<TileProviderByLevel>(
|
||||
layergroupid::LAYER_TYPE_NAMES[static_cast<int>(
|
||||
layergroupid::TypeID::ByLevelTileLayer
|
||||
)]
|
||||
);
|
||||
fTileProvider->registerClass<tileprovider::TileProviderByIndex>(
|
||||
fTileProvider->registerClass<TileProviderByIndex>(
|
||||
layergroupid::LAYER_TYPE_NAMES[static_cast<int>(
|
||||
layergroupid::TypeID::ByIndexTileLayer
|
||||
)]
|
||||
@@ -376,12 +382,14 @@ scripting::LuaLibrary GlobeBrowsingModule::luaLibrary() const {
|
||||
"moveLayer",
|
||||
&globebrowsing::luascriptfunctions::moveLayer,
|
||||
"string, string, number, number",
|
||||
"Rearranges the order of a single layer in a scene graph node. The first "
|
||||
"parameter specifies the scene graph node, the second parameter specifies "
|
||||
"Rearranges the order of a single layer on a globe. The first parameter"
|
||||
"is the identifier of the globe, the second parameter specifies "
|
||||
"the name of the layer group, the third parameter is the original position "
|
||||
"of the layer that should be moved and the last parameter is the new "
|
||||
"position. The new position may be -1 to place the layer at the top or any "
|
||||
"large number bigger than the number of layers to place it at the bottom."
|
||||
"position in the list. The first position in the list has index 0, and the "
|
||||
"last position is given by the number of layers minus one. The new position "
|
||||
"may be -1 to place the layer at the top or any number bigger than the "
|
||||
"number of layers to place it at the bottom."
|
||||
},
|
||||
{
|
||||
"goToChunk",
|
||||
|
||||
@@ -169,7 +169,7 @@ int moveLayer(lua_State* L) {
|
||||
}
|
||||
|
||||
globebrowsing::LayerGroup& lg = globe->layerManager().layerGroup(group);
|
||||
lg.moveLayers(oldPosition, newPosition);
|
||||
lg.moveLayer(oldPosition, newPosition);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,30 +1,11 @@
|
||||
openspace.globebrowsing.documentation = {
|
||||
{
|
||||
Name = "createTemporalGibsGdalXml",
|
||||
Arguments = "string, string, string, string, string, string, [string]",
|
||||
Documentation =
|
||||
"Creates an XML configuration for a temporal GIBS dataset." ..
|
||||
"Arguments are: Name, Start date, end date, time resolution, time format," ..
|
||||
"resolution, file format. The last parameter is the temporal format and " ..
|
||||
"defaults to YYYY-MM-DD. For all specifications, see " ..
|
||||
"https://wiki.earthdata.nasa.gov/display/GIBS/GIBS+Available+Imagery+Products" ..
|
||||
"Usage:" ..
|
||||
"openspace.globebrowsing.addLayer(" ..
|
||||
"\"Earth\"," ..
|
||||
"\"ColorLayers\"," ..
|
||||
"{" ..
|
||||
"Type = \"TemporalTileLayer\"," ..
|
||||
"Name = \"MODIS_Terra_Chlorophyll_A\"," ..
|
||||
"FilePath = openspace.globebrowsing.createTemporalGibsGdalXml(" ..
|
||||
"\"MODIS_Terra_Chlorophyll_A\"," ..
|
||||
"\"2013-07-02\"," ..
|
||||
"\"Yesterday\"," ..
|
||||
"\"1d\"," ..
|
||||
"\"1km\"," ..
|
||||
"\"png\"" ..
|
||||
")" ..
|
||||
"}" ..
|
||||
")"
|
||||
Arguments = "string, string, string",
|
||||
Documentation = [[
|
||||
Creates an XML configuration for a temporal GIBS dataset to be used in
|
||||
a TemporalTileprovider
|
||||
]]
|
||||
},
|
||||
{
|
||||
Name = "createGibsGdalXml",
|
||||
@@ -40,7 +21,7 @@ openspace.globebrowsing.documentation = {
|
||||
"\"ColorLayers\"," ..
|
||||
"{" ..
|
||||
"Name = \"MODIS_Terra_Chlorophyll_A\"," ..
|
||||
"FilePath = openspace.globebrowsing.createTemporalGibsGdalXml(" ..
|
||||
"FilePath = openspace.globebrowsing.createGibsGdalXml(" ..
|
||||
"\"MODIS_Terra_Chlorophyll_A\"," ..
|
||||
"\"2013-07-02\"," ..
|
||||
"\"1km\"," ..
|
||||
@@ -111,21 +92,27 @@ openspace.globebrowsing.addGibsLayer = function(layer, resolution, format, start
|
||||
if endDate == 'Present' then
|
||||
endDate = ''
|
||||
end
|
||||
local xml = openspace.globebrowsing.createTemporalGibsGdalXml(layer, startDate, endDate, '1d', resolution, format)
|
||||
openspace.globebrowsing.addLayer('Earth', 'ColorLayers', { Identifier = layer, Type = "TemporalTileLayer", FilePath = xml })
|
||||
end
|
||||
|
||||
openspace.globebrowsing.createTemporalGibsGdalXml = function (layerName, startDate, endDate, timeResolution, resolution, format, temporalFormat)
|
||||
temporalFormat = temporalFormat or 'YYYY-MM-DD'
|
||||
local temporalTemplate =
|
||||
"<OpenSpaceTemporalGDALDataset>" ..
|
||||
"<OpenSpaceTimeStart>" .. startDate .. "</OpenSpaceTimeStart>" ..
|
||||
"<OpenSpaceTimeEnd>" .. endDate .. "</OpenSpaceTimeEnd>" ..
|
||||
"<OpenSpaceTimeResolution>" .. timeResolution .. "</OpenSpaceTimeResolution>" ..
|
||||
"<OpenSpaceTimeIdFormat>" .. temporalFormat .. "</OpenSpaceTimeIdFormat>" ..
|
||||
openspace.globebrowsing.createGibsGdalXml(layerName, "${OpenSpaceTimeId}", resolution, format) ..
|
||||
"</OpenSpaceTemporalGDALDataset>"
|
||||
return temporalTemplate
|
||||
local layer = {
|
||||
Identifier = layerName,
|
||||
Type = "TemporalTileLayer",
|
||||
Mode = "Prototyped",
|
||||
Prototyped = {
|
||||
Time = {
|
||||
Start = startDate,
|
||||
End = endDate
|
||||
},
|
||||
TemporalResolution = "1d",
|
||||
TimeFormat = "YYYY-MM-DD",
|
||||
Prototype = openspace.globebrowsing.createTemporalGibsGdalXml(layerName, resolution, format)
|
||||
}
|
||||
}
|
||||
|
||||
openspace.globebrowsing.addLayer(
|
||||
'Earth',
|
||||
'ColorLayers',
|
||||
layer
|
||||
)
|
||||
end
|
||||
|
||||
openspace.globebrowsing.createGibsGdalXml = function (layerName, date, resolution, format)
|
||||
@@ -196,6 +183,10 @@ openspace.globebrowsing.createGibsGdalXml = function (layerName, date, resolutio
|
||||
return gdalWmsTemplate
|
||||
end
|
||||
|
||||
openspace.globebrowsing.createTemporalGibsGdalXml = function (layerName, resolution, format)
|
||||
return openspace.globebrowsing.createGibsGdalXml(layerName, "${OpenSpaceTimeId}", resolution, format)
|
||||
end
|
||||
|
||||
openspace.globebrowsing.parseInfoFile = function (file)
|
||||
-- We are loading these values from an external info file and since we are switching
|
||||
-- to a strict Lua, we need to predefine these global variables
|
||||
|
||||
@@ -26,25 +26,23 @@
|
||||
|
||||
uniform sampler2D prevTexture;
|
||||
uniform sampler2D nextTexture;
|
||||
uniform sampler2D colormapTexture;
|
||||
uniform sampler1D colormapTexture;
|
||||
uniform float blendFactor;
|
||||
|
||||
in vec2 texCoord;
|
||||
|
||||
Fragment getFragment() {
|
||||
vec4 texel0 = texture2D(prevTexture, texCoord);
|
||||
vec4 texel1 = texture2D(nextTexture, texCoord);
|
||||
vec4 texel0 = texture(prevTexture, texCoord);
|
||||
vec4 texel1 = texture(nextTexture, texCoord);
|
||||
|
||||
vec4 mixedTexture = mix(texel0, texel1, blendFactor);
|
||||
|
||||
Fragment frag;
|
||||
if (mixedTexture.r > 0.999) {
|
||||
vec2 position = vec2(mixedTexture.r - 0.01, 0.5);
|
||||
frag.color = texture2D(colormapTexture, position);
|
||||
frag.color = texture(colormapTexture, mixedTexture.r - 0.01);
|
||||
}
|
||||
else {
|
||||
vec2 position = vec2(mixedTexture.r , 0.5);
|
||||
frag.color = texture2D(colormapTexture, position);
|
||||
frag.color = texture(colormapTexture, mixedTexture.r);
|
||||
}
|
||||
|
||||
frag.color.a = mixedTexture.a;
|
||||
|
||||
@@ -50,8 +50,6 @@ AsyncTileDataProvider::AsyncTileDataProvider(std::string name,
|
||||
performReset(ResetRawTileDataReader::No);
|
||||
}
|
||||
|
||||
AsyncTileDataProvider::~AsyncTileDataProvider() {} // NOLINT
|
||||
|
||||
const RawTileDataReader& AsyncTileDataProvider::rawTileDataReader() const {
|
||||
return *_rawTileDataReader;
|
||||
}
|
||||
|
||||
@@ -50,8 +50,6 @@ public:
|
||||
AsyncTileDataProvider(std::string name,
|
||||
std::unique_ptr<RawTileDataReader> rawTileDataReader);
|
||||
|
||||
~AsyncTileDataProvider();
|
||||
|
||||
/**
|
||||
* Creates a job which asynchronously loads a raw tile. This job is enqueued.
|
||||
*/
|
||||
|
||||
@@ -115,9 +115,8 @@ struct TileMetaData {
|
||||
class Tile {
|
||||
public:
|
||||
/**
|
||||
* Describe if this Tile is good for usage (OK) or otherwise
|
||||
* the reason why it is not.
|
||||
*/
|
||||
* Describe if this Tile is good for usage (OK) or otherwise the reason why it is not.
|
||||
*/
|
||||
enum class Status {
|
||||
/**
|
||||
* E.g when texture data is not currently in memory.
|
||||
@@ -168,7 +167,6 @@ struct ChunkTile {
|
||||
|
||||
|
||||
|
||||
//using ChunkTilePile = std::vector<ChunkTile>;
|
||||
// The ChunkTilePile either contains 1 or 3 ChunkTile, depending on if layer-blending is
|
||||
// enabled. If it is enabled, we need the two adjacent levels, if it is not enabled, only
|
||||
// the current layer is needed
|
||||
|
||||
@@ -286,13 +286,13 @@ Layer::Layer(layergroupid::GroupID id, const ghoul::Dictionary& layerDict,
|
||||
|
||||
_reset.onChange([&]() {
|
||||
if (_tileProvider) {
|
||||
tileprovider::reset(*_tileProvider);
|
||||
_tileProvider->reset();
|
||||
}
|
||||
});
|
||||
|
||||
_remove.onChange([&]() {
|
||||
if (_tileProvider) {
|
||||
tileprovider::reset(*_tileProvider);
|
||||
_tileProvider->reset();
|
||||
_parent.deleteLayer(identifier());
|
||||
}
|
||||
});
|
||||
@@ -360,13 +360,13 @@ void Layer::initialize() {
|
||||
ZoneScoped
|
||||
|
||||
if (_tileProvider) {
|
||||
tileprovider::initialize(*_tileProvider);
|
||||
_tileProvider->initialize();
|
||||
}
|
||||
}
|
||||
|
||||
void Layer::deinitialize() {
|
||||
if (_tileProvider) {
|
||||
tileprovider::deinitialize(*_tileProvider);
|
||||
_tileProvider->deinitialize();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -374,7 +374,7 @@ ChunkTilePile Layer::chunkTilePile(const TileIndex& tileIndex, int pileSize) con
|
||||
ZoneScoped
|
||||
|
||||
if (_tileProvider) {
|
||||
return tileprovider::chunkTilePile(*_tileProvider, tileIndex, pileSize);
|
||||
return _tileProvider->chunkTilePile(tileIndex, pileSize);
|
||||
}
|
||||
else {
|
||||
ChunkTilePile chunkTilePile;
|
||||
@@ -390,7 +390,7 @@ ChunkTilePile Layer::chunkTilePile(const TileIndex& tileIndex, int pileSize) con
|
||||
|
||||
Tile::Status Layer::tileStatus(const TileIndex& index) const {
|
||||
return _tileProvider ?
|
||||
tileprovider::tileStatus(*_tileProvider, index) :
|
||||
_tileProvider->tileStatus(index) :
|
||||
Tile::Status::Unavailable;
|
||||
}
|
||||
|
||||
@@ -404,7 +404,7 @@ layergroupid::BlendModeID Layer::blendMode() const {
|
||||
|
||||
TileDepthTransform Layer::depthTransform() const {
|
||||
return _tileProvider ?
|
||||
tileprovider::depthTransform(*_tileProvider) :
|
||||
_tileProvider->depthTransform() :
|
||||
TileDepthTransform{ 1.f, 0.f };
|
||||
}
|
||||
|
||||
@@ -416,7 +416,7 @@ bool Layer::enabled() const {
|
||||
return _enabled;
|
||||
}
|
||||
|
||||
tileprovider::TileProvider* Layer::tileProvider() const {
|
||||
TileProvider* Layer::tileProvider() const {
|
||||
return _tileProvider.get();
|
||||
}
|
||||
|
||||
@@ -440,7 +440,7 @@ void Layer::update() {
|
||||
ZoneScoped
|
||||
|
||||
if (_tileProvider) {
|
||||
tileprovider::update(*_tileProvider);
|
||||
_tileProvider->update();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -483,7 +483,7 @@ void Layer::initializeBasedOnType(layergroupid::TypeID id, ghoul::Dictionary ini
|
||||
std::string name = initDict.value<std::string>(KeyName);
|
||||
LDEBUG("Initializing tile provider for layer: '" + name + "'");
|
||||
}
|
||||
_tileProvider = tileprovider::createFromDictionary(id, std::move(initDict));
|
||||
_tileProvider = TileProvider::createFromDictionary(id, std::move(initDict));
|
||||
break;
|
||||
}
|
||||
case layergroupid::TypeID::SolidColor: {
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#include <modules/globebrowsing/src/basictypes.h>
|
||||
#include <modules/globebrowsing/src/layeradjustment.h>
|
||||
#include <modules/globebrowsing/src/layerrendersettings.h>
|
||||
#include <modules/globebrowsing/src/tileprovider.h>
|
||||
#include <modules/globebrowsing/src/tileprovider/tileprovider.h>
|
||||
#include <openspace/properties/optionproperty.h>
|
||||
#include <openspace/properties/scalar/boolproperty.h>
|
||||
|
||||
@@ -40,8 +40,7 @@ namespace openspace::globebrowsing {
|
||||
|
||||
struct LayerGroup;
|
||||
struct TileIndex;
|
||||
|
||||
namespace tileprovider { struct TileProvider; }
|
||||
struct TileProvider;
|
||||
|
||||
class Layer : public properties::PropertyOwner {
|
||||
public:
|
||||
@@ -59,7 +58,7 @@ public:
|
||||
TileDepthTransform depthTransform() const;
|
||||
void setEnabled(bool enabled);
|
||||
bool enabled() const;
|
||||
tileprovider::TileProvider* tileProvider() const;
|
||||
TileProvider* tileProvider() const;
|
||||
glm::vec3 solidColor() const;
|
||||
const LayerRenderSettings& renderSettings() const;
|
||||
const LayerAdjustment& layerAdjustment() const;
|
||||
@@ -89,7 +88,7 @@ private:
|
||||
properties::StringProperty _guiDescription;
|
||||
|
||||
layergroupid::TypeID _type;
|
||||
std::unique_ptr<tileprovider::TileProvider> _tileProvider;
|
||||
std::unique_ptr<TileProvider> _tileProvider;
|
||||
properties::Vec3Property _solidColor;
|
||||
LayerRenderSettings _renderSettings;
|
||||
LayerAdjustment _layerAdjustment;
|
||||
|
||||
@@ -74,7 +74,7 @@ documentation::Documentation LayerAdjustment::Documentation() {
|
||||
}
|
||||
|
||||
LayerAdjustment::LayerAdjustment()
|
||||
: properties::PropertyOwner({ "adjustment" })
|
||||
: properties::PropertyOwner({ "Adjustment" })
|
||||
, _chromaKeyColor(ChromaKeyColorInfo, glm::vec3(0.f), glm::vec3(0.f), glm::vec3(1.f))
|
||||
, _chromaKeyTolerance(ChromaKeyToleranceInfo, 0.f, 0.f, 1.f)
|
||||
, _typeOption(TypeInfo, properties::OptionProperty::DisplayType::Dropdown)
|
||||
|
||||
@@ -36,8 +36,6 @@ namespace openspace::documentation { struct Documentation; }
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
namespace tileprovider { struct TileProvider; }
|
||||
|
||||
class LayerAdjustment : public properties::PropertyOwner {
|
||||
public:
|
||||
LayerAdjustment();
|
||||
|
||||
@@ -212,16 +212,9 @@ void LayerGroup::deleteLayer(const std::string& layerName) {
|
||||
LERROR("Could not find layer " + layerName);
|
||||
}
|
||||
|
||||
void LayerGroup::moveLayers(int oldPosition, int newPosition) {
|
||||
void LayerGroup::moveLayer(int oldPosition, int newPosition) {
|
||||
oldPosition = std::max(0, oldPosition);
|
||||
newPosition = std::min(newPosition, static_cast<int>(_layers.size()));
|
||||
|
||||
// We need to adjust the new position as we first delete the old position, if this
|
||||
// position is before the new position we have reduced the size of the vector by 1 and
|
||||
// need to adapt where we want to put the value in
|
||||
if (oldPosition < newPosition) {
|
||||
newPosition -= 1;
|
||||
}
|
||||
newPosition = std::min(newPosition, static_cast<int>(_layers.size() - 1));
|
||||
|
||||
// There are two synchronous vectors that we have to update here. The _layers vector
|
||||
// is used to determine the order while rendering, the _subowners is the order in
|
||||
|
||||
@@ -33,8 +33,7 @@
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
class Layer;
|
||||
|
||||
namespace tileprovider { struct TileProvider; }
|
||||
struct TileProvider;
|
||||
|
||||
/**
|
||||
* Convenience class for dealing with multiple <code>Layer</code>s.
|
||||
@@ -52,7 +51,7 @@ struct LayerGroup : public properties::PropertyOwner {
|
||||
|
||||
Layer* addLayer(const ghoul::Dictionary& layerDict);
|
||||
void deleteLayer(const std::string& layerName);
|
||||
void moveLayers(int oldPosition, int newPosition);
|
||||
void moveLayer(int oldPosition, int newPosition);
|
||||
|
||||
/// @returns const vector of all layers
|
||||
std::vector<Layer*> layers() const;
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
#include <modules/globebrowsing/src/layer.h>
|
||||
#include <modules/globebrowsing/src/layergroup.h>
|
||||
#include <modules/globebrowsing/src/tileprovider.h>
|
||||
#include <modules/globebrowsing/src/tileprovider/tileprovider.h>
|
||||
#include <modules/globebrowsing/src/tiletextureinitdata.h>
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/documentation/verifier.h>
|
||||
@@ -155,7 +155,7 @@ void LayerManager::reset(bool includeDisabled) {
|
||||
for (std::unique_ptr<LayerGroup>& layerGroup : _layerGroups) {
|
||||
for (Layer* layer : layerGroup->layers()) {
|
||||
if ((layer->enabled() || includeDisabled) && layer->tileProvider()) {
|
||||
tileprovider::reset(*layer->tileProvider());
|
||||
layer->tileProvider()->reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#include <modules/globebrowsing/src/layer.h>
|
||||
#include <modules/globebrowsing/src/layergroup.h>
|
||||
#include <modules/globebrowsing/src/renderableglobe.h>
|
||||
#include <modules/globebrowsing/src/tileprovider.h>
|
||||
#include <modules/globebrowsing/src/tileprovider/tileprovider.h>
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/documentation/verifier.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
@@ -322,7 +322,7 @@ ChunkTileVector tilesAndSettingsUnsorted(const LayerGroup& layerGroup,
|
||||
for (Layer* layer : layerGroup.activeLayers()) {
|
||||
if (layer->tileProvider()) {
|
||||
tilesAndSettings.emplace_back(
|
||||
tileprovider::chunkTile(*layer->tileProvider(), tileIndex),
|
||||
layer->tileProvider()->chunkTile(tileIndex),
|
||||
&layer->renderSettings()
|
||||
);
|
||||
}
|
||||
@@ -403,7 +403,7 @@ bool colorAvailableForChunk(const Chunk& chunk, const LayerManager& lm) {
|
||||
|
||||
for (Layer* lyr : colorLayers.activeLayers()) {
|
||||
if (lyr->tileProvider()) {
|
||||
ChunkTile t = tileprovider::chunkTile(*lyr->tileProvider(), chunk.tileIndex);
|
||||
ChunkTile t = lyr->tileProvider()->chunkTile(chunk.tileIndex);
|
||||
if (t.tile.status == Tile::Status::Unavailable) {
|
||||
return false;
|
||||
}
|
||||
@@ -1886,16 +1886,15 @@ float RenderableGlobe::getHeight(const glm::dvec3& position) const {
|
||||
_layerManager.layerGroup(layergroupid::GroupID::HeightLayers).activeLayers();
|
||||
|
||||
for (Layer* layer : heightMapLayers) {
|
||||
tileprovider::TileProvider* tileProvider = layer->tileProvider();
|
||||
TileProvider* tileProvider = layer->tileProvider();
|
||||
if (!tileProvider) {
|
||||
continue;
|
||||
}
|
||||
// Transform the uv coordinates to the current tile texture
|
||||
const ChunkTile chunkTile = tileprovider::chunkTile(*tileProvider, tileIndex);
|
||||
const ChunkTile chunkTile = tileProvider->chunkTile(tileIndex);
|
||||
const Tile& tile = chunkTile.tile;
|
||||
const TileUvTransform& uvTransform = chunkTile.uvTransform;
|
||||
const TileDepthTransform& depthTransform =
|
||||
tileprovider::depthTransform(*tileProvider);
|
||||
const TileDepthTransform& depthTransform = tileProvider->depthTransform();
|
||||
if (tile.status != Tile::Status::OK) {
|
||||
return 0;
|
||||
}
|
||||
@@ -1953,10 +1952,10 @@ float RenderableGlobe::getHeight(const glm::dvec3& position) const {
|
||||
std::isnan(sample11);
|
||||
|
||||
const bool anySampleIsNoData =
|
||||
sample00 == tileprovider::noDataValueAsFloat(*tileProvider) ||
|
||||
sample01 == tileprovider::noDataValueAsFloat(*tileProvider) ||
|
||||
sample10 == tileprovider::noDataValueAsFloat(*tileProvider) ||
|
||||
sample11 == tileprovider::noDataValueAsFloat(*tileProvider);
|
||||
sample00 == tileProvider->noDataValueAsFloat() ||
|
||||
sample01 == tileProvider->noDataValueAsFloat() ||
|
||||
sample10 == tileProvider->noDataValueAsFloat() ||
|
||||
sample11 == tileProvider->noDataValueAsFloat();
|
||||
|
||||
if (anySampleIsNaN || anySampleIsNoData) {
|
||||
continue;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,292 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2022 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_GLOBEBROWSING___TILE_PROVIDER___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___TILE_PROVIDER___H__
|
||||
|
||||
#include <openspace/properties/propertyowner.h>
|
||||
|
||||
#include <modules/globebrowsing/src/basictypes.h>
|
||||
#include <modules/globebrowsing/src/ellipsoid.h>
|
||||
#include <modules/globebrowsing/src/layergroupid.h>
|
||||
#include <modules/globebrowsing/src/tileindex.h>
|
||||
#include <modules/globebrowsing/src/tiletextureinitdata.h>
|
||||
#include <modules/globebrowsing/src/timequantizer.h>
|
||||
#include <openspace/properties/stringproperty.h>
|
||||
#include <openspace/properties/scalar/boolproperty.h>
|
||||
#include <openspace/properties/scalar/intproperty.h>
|
||||
#include <unordered_map>
|
||||
#include <ghoul/opengl/programobject.h>
|
||||
|
||||
struct CPLXMLNode;
|
||||
|
||||
namespace ghoul::fontrendering {
|
||||
class Font;
|
||||
class FontRenderer;
|
||||
} // namespace ghoul::fontrendering
|
||||
|
||||
namespace openspace { class PixelBuffer; }
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
class AsyncTileDataProvider;
|
||||
struct RawTile;
|
||||
struct TileIndex;
|
||||
namespace cache { class MemoryAwareTileCache; }
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
namespace openspace::globebrowsing::tileprovider {
|
||||
|
||||
enum class Type {
|
||||
DefaultTileProvider = 0,
|
||||
SingleImageTileProvider,
|
||||
ImageSequenceTileProvider,
|
||||
SizeReferenceTileProvider,
|
||||
TemporalTileProvider,
|
||||
TileIndexTileProvider,
|
||||
ByIndexTileProvider,
|
||||
ByLevelTileProvider,
|
||||
InterpolateTileProvider
|
||||
};
|
||||
|
||||
|
||||
struct TileProvider : public properties::PropertyOwner {
|
||||
static unsigned int NumTileProviders;
|
||||
|
||||
Type type;
|
||||
|
||||
TileProvider();
|
||||
virtual ~TileProvider() = default;
|
||||
|
||||
std::string name;
|
||||
|
||||
uint16_t uniqueIdentifier = 0;
|
||||
bool isInitialized = false;
|
||||
};
|
||||
|
||||
struct DefaultTileProvider : public TileProvider {
|
||||
DefaultTileProvider(const ghoul::Dictionary& dictionary);
|
||||
|
||||
std::unique_ptr<AsyncTileDataProvider> asyncTextureDataProvider;
|
||||
|
||||
cache::MemoryAwareTileCache* tileCache = nullptr;
|
||||
|
||||
properties::StringProperty filePath;
|
||||
properties::IntProperty tilePixelSize;
|
||||
layergroupid::GroupID layerGroupID = layergroupid::GroupID::Unknown;
|
||||
bool performPreProcessing = false;
|
||||
bool padTiles = true;
|
||||
};
|
||||
|
||||
struct SingleImageProvider : public TileProvider {
|
||||
SingleImageProvider(const ghoul::Dictionary& dictionary);
|
||||
|
||||
std::unique_ptr<ghoul::opengl::Texture> tileTexture;
|
||||
Tile tile;
|
||||
|
||||
properties::StringProperty filePath;
|
||||
};
|
||||
|
||||
struct InterpolateTileProvider : public TileProvider {
|
||||
InterpolateTileProvider(const ghoul::Dictionary&);
|
||||
virtual ~InterpolateTileProvider();
|
||||
|
||||
Tile calculateTile(const TileIndex&);
|
||||
TileProvider* before = nullptr;
|
||||
TileProvider* t1 = nullptr;
|
||||
TileProvider* t2 = nullptr;
|
||||
TileProvider* future = nullptr;
|
||||
float factor = 1.f;
|
||||
GLuint vaoQuad = 0;
|
||||
GLuint vboQuad = 0;
|
||||
GLuint fbo = 0;
|
||||
std::string colormap;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> shaderProgram;
|
||||
std::unique_ptr<SingleImageProvider> singleImageProvider;
|
||||
cache::MemoryAwareTileCache* tileCache = nullptr;
|
||||
};
|
||||
|
||||
struct TextTileProvider : public TileProvider {
|
||||
TextTileProvider(TileTextureInitData initData, size_t fontSize = 48);
|
||||
|
||||
const TileTextureInitData initData;
|
||||
|
||||
std::unique_ptr<ghoul::fontrendering::FontRenderer> fontRenderer;
|
||||
std::shared_ptr<ghoul::fontrendering::Font> font;
|
||||
size_t fontSize = 0;
|
||||
|
||||
std::string text;
|
||||
glm::vec2 textPosition = glm::vec2(0.f);
|
||||
glm::vec4 textColor = glm::vec4(0.f);
|
||||
|
||||
GLuint fbo = 0;
|
||||
|
||||
cache::MemoryAwareTileCache* tileCache;
|
||||
};
|
||||
|
||||
struct SizeReferenceTileProvider : public TextTileProvider {
|
||||
SizeReferenceTileProvider(const ghoul::Dictionary& dictionary);
|
||||
|
||||
Ellipsoid ellipsoid;
|
||||
};
|
||||
|
||||
struct TileIndexTileProvider : public TextTileProvider {
|
||||
TileIndexTileProvider(const ghoul::Dictionary& dictionary);
|
||||
};
|
||||
|
||||
struct TileProviderByIndex : public TileProvider {
|
||||
TileProviderByIndex(const ghoul::Dictionary& dictionary);
|
||||
|
||||
std::unordered_map<
|
||||
TileIndex::TileHashKey, std::unique_ptr<TileProvider>
|
||||
> tileProviderMap;
|
||||
std::unique_ptr<TileProvider> defaultTileProvider;
|
||||
};
|
||||
|
||||
struct TileProviderByLevel : public TileProvider {
|
||||
TileProviderByLevel(const ghoul::Dictionary& dictionary);
|
||||
|
||||
std::vector<int> providerIndices;
|
||||
std::vector<std::unique_ptr<TileProvider>> levelTileProviders;
|
||||
};
|
||||
|
||||
|
||||
struct ImageSequenceTileProvider : public TileProvider {
|
||||
ImageSequenceTileProvider(const ghoul::Dictionary& dictionary);
|
||||
|
||||
std::unique_ptr<DefaultTileProvider> currentTileProvider = nullptr;
|
||||
|
||||
properties::IntProperty index;
|
||||
properties::StringProperty currentImage;
|
||||
properties::StringProperty folderPath;
|
||||
|
||||
ghoul::Dictionary initDict;
|
||||
bool isImageDirty = true;
|
||||
std::vector<std::filesystem::path> imagePaths;
|
||||
};
|
||||
|
||||
/**
|
||||
* Provide <code>Tile</code>s from web map services that have temporal resolution.
|
||||
*
|
||||
* TemporalTileProviders are instantiated using a ghoul::Dictionary,
|
||||
* and must define a filepath to a Openspace Temporal dataset description file.
|
||||
* This is an xml-file that defines the same meta data as the GDAL wms description
|
||||
* (http://www.gdal.org/frmt_wms.html), but augmented with some
|
||||
* extra tags describing the temporal properties of the dataset. See
|
||||
* <code>TemporalTileProvider::TemporalXMLTags</code>
|
||||
*
|
||||
*/
|
||||
struct TemporalTileProvider : public TileProvider {
|
||||
enum class TimeFormatType {
|
||||
YYYY_MM_DD = 0,
|
||||
YYYYMMDD_hhmmss,
|
||||
YYYYMMDD_hhmm,
|
||||
YYYY_MM_DDThhColonmmColonssZ,
|
||||
YYYY_MM_DDThh_mm_ssZ
|
||||
};
|
||||
|
||||
using TimeKey = std::string;
|
||||
|
||||
TemporalTileProvider(const ghoul::Dictionary& dictionary);
|
||||
|
||||
ghoul::Dictionary initDict;
|
||||
properties::StringProperty filePath;
|
||||
properties::BoolProperty useFixedTime;
|
||||
properties::StringProperty fixedTime;
|
||||
std::string gdalXmlTemplate;
|
||||
|
||||
std::unordered_map<TimeKey, std::unique_ptr<TileProvider>> tileProviderMap;
|
||||
|
||||
bool interpolation = false;
|
||||
|
||||
TileProvider* currentTileProvider = nullptr;
|
||||
double startTimeJ2000;
|
||||
double endTimeJ2000;
|
||||
TimeFormatType timeFormat;
|
||||
TimeQuantizer timeQuantizer;
|
||||
std::string colormap;
|
||||
|
||||
std::string myResolution;
|
||||
std::unique_ptr<InterpolateTileProvider> interpolateTileProvider;
|
||||
};
|
||||
|
||||
|
||||
|
||||
void initializeDefaultTile();
|
||||
void deinitializeDefaultTile();
|
||||
|
||||
std::unique_ptr<TileProvider> createFromDictionary(layergroupid::TypeID layerTypeID,
|
||||
const ghoul::Dictionary& dictionary);
|
||||
|
||||
bool initialize(TileProvider& tp);
|
||||
bool deinitialize(TileProvider& tp);
|
||||
|
||||
Tile tile(TileProvider& tp, const TileIndex& tileIndex);
|
||||
|
||||
ChunkTile chunkTile(TileProvider& tp, TileIndex tileIndex, int parents = 0,
|
||||
int maxParents = 1337);
|
||||
|
||||
ChunkTilePile chunkTilePile(TileProvider& tp, TileIndex tileIndex, int pileSize);
|
||||
|
||||
/**
|
||||
* Returns the status of a <code>Tile</code>. The <code>Tile::Status</code>
|
||||
* corresponds the <code>Tile</code> that would be returned
|
||||
* if the function <code>tile</code> would be invoked with the same
|
||||
* <code>TileIndex</code> argument at this point in time.
|
||||
*/
|
||||
Tile::Status tileStatus(TileProvider& tp, const TileIndex& index);
|
||||
|
||||
/**
|
||||
* Get the associated depth transform for this TileProvider.
|
||||
* This is necessary for TileProviders serving height map
|
||||
* data, in order to correcly map pixel values to meters.
|
||||
*/
|
||||
TileDepthTransform depthTransform(TileProvider& tp);
|
||||
|
||||
/**
|
||||
* This method should be called once per frame. Here, TileProviders
|
||||
* are given the opportunity to update their internal state.
|
||||
*/
|
||||
void update(TileProvider& tp);
|
||||
|
||||
/**
|
||||
* Provides a uniform way of all TileProviders to reload or
|
||||
* restore all of its internal state. This is mainly useful
|
||||
* for debugging purposes.
|
||||
*/
|
||||
void reset(TileProvider& tp);
|
||||
|
||||
/**
|
||||
* \returns The maximum level as defined by <code>TileIndex</code>
|
||||
* that this TileProvider is able provide.
|
||||
*/
|
||||
int maxLevel(TileProvider& tp);
|
||||
|
||||
/**
|
||||
* \returns the no data value for the dataset. Default is the minimum float avalue.
|
||||
*/
|
||||
float noDataValueAsFloat(TileProvider& tp);
|
||||
|
||||
} // namespace openspace::globebrowsing::tileprovider
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___TILE_PROVIDER___H__
|
||||
204
modules/globebrowsing/src/tileprovider/defaulttileprovider.cpp
Normal file
204
modules/globebrowsing/src/tileprovider/defaulttileprovider.cpp
Normal file
@@ -0,0 +1,204 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2022 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/globebrowsing/src/tileprovider/defaulttileprovider.h>
|
||||
|
||||
#include <modules/globebrowsing/globebrowsingmodule.h>
|
||||
#include <modules/globebrowsing/src/memoryawaretilecache.h>
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
#include <optional>
|
||||
|
||||
namespace {
|
||||
constexpr openspace::properties::Property::PropertyInfo FilePathInfo = {
|
||||
"FilePath",
|
||||
"File Path",
|
||||
"The path of the GDAL file or the image file that is to be used in this tile "
|
||||
"provider."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo TilePixelSizeInfo = {
|
||||
"TilePixelSize",
|
||||
"Tile Pixel Size",
|
||||
"This value is the preferred size (in pixels) for each tile. Choosing the right "
|
||||
"value is a tradeoff between more efficiency (larger images) and better quality "
|
||||
"(smaller images). The tile pixel size has to be smaller than the size of the "
|
||||
"complete image if a single image is used."
|
||||
};
|
||||
|
||||
struct [[codegen::Dictionary(DefaultTileProvider)]] Parameters {
|
||||
// User-facing name of this tile provider
|
||||
std::optional<std::string> name;
|
||||
|
||||
// The path to the file that is loaded by GDAL to produce tiles. Since GDAL
|
||||
// supports it, this can also be the textual representation of the contents of a
|
||||
// loading file
|
||||
std::string filePath;
|
||||
|
||||
// The layer into which this tile provider is loaded
|
||||
int layerGroupID;
|
||||
|
||||
// [[codegen::verbatim(TilePixelSizeInfo.description)]]
|
||||
std::optional<int> tilePixelSize;
|
||||
|
||||
// Determines whether the tiles should have a padding zone around it, making the
|
||||
// interpolation between tiles more pleasant
|
||||
std::optional<bool> padTiles;
|
||||
|
||||
// Determines if the tiles should be preprocessed before uploading to the GPU
|
||||
std::optional<bool> performPreProcessing;
|
||||
|
||||
};
|
||||
#include "defaulttileprovider_codegen.cpp"
|
||||
} // namespace
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
DefaultTileProvider::DefaultTileProvider(const ghoul::Dictionary& dictionary)
|
||||
: _filePath(FilePathInfo, "")
|
||||
, _tilePixelSize(TilePixelSizeInfo, 32, 32, 2048)
|
||||
{
|
||||
ZoneScoped
|
||||
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
name = p.name.value_or("Name unspecified");
|
||||
std::string _loggerCat = "DefaultTileProvider (" + name + ")";
|
||||
|
||||
// 1. Get required Keys
|
||||
_filePath = p.filePath;
|
||||
|
||||
_layerGroupID = layergroupid::GroupID(p.layerGroupID);
|
||||
|
||||
// 2. Initialize default values for any optional Keys
|
||||
// getValue does not work for integers
|
||||
int pixelSize = p.tilePixelSize.value_or(0);
|
||||
_padTiles = p.padTiles.value_or(_padTiles);
|
||||
|
||||
// Only preprocess height layers by default
|
||||
switch (_layerGroupID) {
|
||||
case layergroupid::GroupID::HeightLayers: _performPreProcessing = true; break;
|
||||
default: _performPreProcessing = false; break;
|
||||
}
|
||||
|
||||
_performPreProcessing = p.performPreProcessing.value_or(_performPreProcessing);
|
||||
|
||||
TileTextureInitData initData(
|
||||
tileTextureInitData(_layerGroupID, _padTiles, pixelSize)
|
||||
);
|
||||
_tilePixelSize = initData.dimensions.x;
|
||||
initAsyncTileDataReader(initData);
|
||||
|
||||
addProperty(_filePath);
|
||||
addProperty(_tilePixelSize);
|
||||
}
|
||||
|
||||
void DefaultTileProvider::initAsyncTileDataReader(TileTextureInitData initData) {
|
||||
ZoneScoped
|
||||
|
||||
_asyncTextureDataProvider = std::make_unique<AsyncTileDataProvider>(
|
||||
name,
|
||||
std::make_unique<RawTileDataReader>(
|
||||
_filePath,
|
||||
initData,
|
||||
RawTileDataReader::PerformPreprocessing(_performPreProcessing)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
Tile DefaultTileProvider::tile(const TileIndex& tileIndex) {
|
||||
ZoneScoped
|
||||
|
||||
ghoul_assert(_asyncTextureDataProvider, "No data provider");
|
||||
if (tileIndex.level > maxLevel()) {
|
||||
return Tile{ nullptr, std::nullopt, Tile::Status::OutOfRange };
|
||||
}
|
||||
const cache::ProviderTileKey key = { tileIndex, uniqueIdentifier };
|
||||
cache::MemoryAwareTileCache* tileCache =
|
||||
global::moduleEngine->module<GlobeBrowsingModule>()->tileCache();
|
||||
Tile tile = tileCache->get(key);
|
||||
if (!tile.texture) {
|
||||
_asyncTextureDataProvider->enqueueTileIO(tileIndex);
|
||||
}
|
||||
|
||||
return tile;
|
||||
}
|
||||
|
||||
Tile::Status DefaultTileProvider::tileStatus(const TileIndex& index) {
|
||||
ghoul_assert(_asyncTextureDataProvider, "No data provider");
|
||||
const RawTileDataReader& reader = _asyncTextureDataProvider->rawTileDataReader();
|
||||
|
||||
if (index.level > reader.maxChunkLevel()) {
|
||||
return Tile::Status::OutOfRange;
|
||||
}
|
||||
|
||||
const cache::ProviderTileKey key = { index, uniqueIdentifier };
|
||||
cache::MemoryAwareTileCache* tileCache =
|
||||
global::moduleEngine->module<GlobeBrowsingModule>()->tileCache();
|
||||
return tileCache->get(key).status;
|
||||
}
|
||||
|
||||
TileDepthTransform DefaultTileProvider::depthTransform() {
|
||||
ghoul_assert(_asyncTextureDataProvider, "No data provider");
|
||||
return _asyncTextureDataProvider->rawTileDataReader().depthTransform();
|
||||
}
|
||||
|
||||
void DefaultTileProvider::update() {
|
||||
ghoul_assert(_asyncTextureDataProvider, "No data provider");
|
||||
_asyncTextureDataProvider->update();
|
||||
|
||||
std::optional<RawTile> tile = _asyncTextureDataProvider->popFinishedRawTile();
|
||||
if (tile) {
|
||||
const cache::ProviderTileKey key = { tile->tileIndex, uniqueIdentifier };
|
||||
cache::MemoryAwareTileCache* tileCache =
|
||||
global::moduleEngine->module<GlobeBrowsingModule>()->tileCache();
|
||||
ghoul_assert(!tileCache->exist(key), "Tile must not be existing in cache");
|
||||
tileCache->createTileAndPut(key, std::move(*tile));
|
||||
}
|
||||
|
||||
if (_asyncTextureDataProvider->shouldBeDeleted()) {
|
||||
initAsyncTileDataReader(
|
||||
tileTextureInitData(_layerGroupID, _padTiles, _tilePixelSize)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void DefaultTileProvider::reset() {
|
||||
global::moduleEngine->module<GlobeBrowsingModule>()->tileCache()->clear();
|
||||
ghoul_assert(_asyncTextureDataProvider, "No data provider");
|
||||
_asyncTextureDataProvider->prepareToBeDeleted();
|
||||
}
|
||||
|
||||
int DefaultTileProvider::maxLevel() {
|
||||
ghoul_assert(_asyncTextureDataProvider, "No data provider");
|
||||
return _asyncTextureDataProvider->rawTileDataReader().maxChunkLevel();
|
||||
}
|
||||
|
||||
float DefaultTileProvider::noDataValueAsFloat() {
|
||||
ghoul_assert(_asyncTextureDataProvider, "No data provider");
|
||||
return _asyncTextureDataProvider->noDataValueAsFloat();
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
61
modules/globebrowsing/src/tileprovider/defaulttileprovider.h
Normal file
61
modules/globebrowsing/src/tileprovider/defaulttileprovider.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2022 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__DEFAULTTILEPROVIDER___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__DEFAULTTILEPROVIDER___H__
|
||||
|
||||
#include <modules/globebrowsing/src/tileprovider/tileprovider.h>
|
||||
|
||||
#include <modules/globebrowsing/src/asynctiledataprovider.h>
|
||||
#include <memory>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
class DefaultTileProvider : public TileProvider {
|
||||
public:
|
||||
DefaultTileProvider(const ghoul::Dictionary& dictionary);
|
||||
|
||||
Tile tile(const TileIndex& tileIndex) override final;
|
||||
Tile::Status tileStatus(const TileIndex& index) override final;
|
||||
TileDepthTransform depthTransform() override final;
|
||||
void update() override final;
|
||||
void reset() override final;
|
||||
int maxLevel() override final;
|
||||
float noDataValueAsFloat() override final;
|
||||
|
||||
private:
|
||||
void initAsyncTileDataReader(TileTextureInitData initData);
|
||||
|
||||
properties::StringProperty _filePath;
|
||||
properties::IntProperty _tilePixelSize;
|
||||
|
||||
std::unique_ptr<AsyncTileDataProvider> _asyncTextureDataProvider;
|
||||
layergroupid::GroupID _layerGroupID = layergroupid::GroupID::Unknown;
|
||||
bool _performPreProcessing = false;
|
||||
bool _padTiles = true;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__DEFAULTTILEPROVIDER___H__
|
||||
@@ -0,0 +1,158 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2022 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/globebrowsing/src/tileprovider/imagesequencetileprovider.h>
|
||||
|
||||
#include <modules/globebrowsing/src/tileprovider/defaulttileprovider.h>
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <optional>
|
||||
|
||||
namespace {
|
||||
constexpr openspace::properties::Property::PropertyInfo IndexInfo = {
|
||||
"Index",
|
||||
"Index",
|
||||
"The index into the list of images that is used to pick the currently displayed "
|
||||
"image"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo CurrentImageInfo = {
|
||||
"CurrentImage",
|
||||
"Current Image",
|
||||
"The read-only value of the currently selected image"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo FolderPathInfo = {
|
||||
"FolderPath",
|
||||
"Folder Path",
|
||||
"The path that is used to look for images for this image provider. The path must "
|
||||
"point to an existing folder that contains images"
|
||||
};
|
||||
|
||||
struct [[codegen::Dictionary(ImageSequenceTileProvider)]] Parameters {
|
||||
// [[codegen::verbatim(IndexInfo.description)]]
|
||||
std::optional<int> index;
|
||||
|
||||
// [[codegen::verbatim(FolderPathInfo.description)]]
|
||||
std::filesystem::path folderPath [[codegen::directory()]];
|
||||
};
|
||||
#include "imagesequencetileprovider_codegen.cpp"
|
||||
} // namespace
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
ImageSequenceTileProvider::ImageSequenceTileProvider(const ghoul::Dictionary& dictionary)
|
||||
: _index(IndexInfo, 0)
|
||||
, _currentImage(CurrentImageInfo)
|
||||
, _folderPath(FolderPathInfo)
|
||||
, _initDict(dictionary)
|
||||
{
|
||||
ZoneScoped
|
||||
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
_index = p.index.value_or(_index);
|
||||
_index.setMinValue(0);
|
||||
_index.onChange([this]() { _isImageDirty = true; });
|
||||
addProperty(_index);
|
||||
|
||||
_currentImage.setReadOnly(true);
|
||||
addProperty(_currentImage);
|
||||
|
||||
_folderPath = p.folderPath.string();
|
||||
addProperty(_folderPath);
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
Tile ImageSequenceTileProvider::tile(const TileIndex& tileIndex) {
|
||||
ZoneScoped
|
||||
|
||||
return _currentTileProvider ? _currentTileProvider->tile(tileIndex) : Tile();
|
||||
}
|
||||
|
||||
Tile::Status ImageSequenceTileProvider::tileStatus(const TileIndex& index) {
|
||||
return _currentTileProvider ?
|
||||
_currentTileProvider->tileStatus(index) :
|
||||
Tile::Status::Unavailable;
|
||||
}
|
||||
|
||||
TileDepthTransform ImageSequenceTileProvider::depthTransform() {
|
||||
if (_currentTileProvider) {
|
||||
return _currentTileProvider->depthTransform();
|
||||
}
|
||||
else {
|
||||
return { 1.f, 0.f };
|
||||
}
|
||||
}
|
||||
|
||||
void ImageSequenceTileProvider::update() {
|
||||
if (_isImageDirty && !_imagePaths.empty() &&
|
||||
_index >= 0 && _index < _imagePaths.size())
|
||||
{
|
||||
if (_currentTileProvider) {
|
||||
_currentTileProvider->deinitialize();
|
||||
}
|
||||
|
||||
std::string p = _imagePaths[_index].string();
|
||||
_currentImage = p;
|
||||
_initDict.setValue("FilePath", p);
|
||||
_currentTileProvider = std::make_unique<DefaultTileProvider>(_initDict);
|
||||
_currentTileProvider->initialize();
|
||||
_isImageDirty = false;
|
||||
}
|
||||
|
||||
if (_currentTileProvider) {
|
||||
_currentTileProvider->update();
|
||||
}
|
||||
}
|
||||
|
||||
void ImageSequenceTileProvider::reset() {
|
||||
namespace fs = std::filesystem;
|
||||
std::string path = _folderPath;
|
||||
_imagePaths.clear();
|
||||
for (const fs::directory_entry& p : fs::directory_iterator(path)) {
|
||||
if (p.is_regular_file()) {
|
||||
_imagePaths.push_back(p.path());
|
||||
}
|
||||
}
|
||||
|
||||
_index = 0;
|
||||
_index.setMaxValue(static_cast<int>(_imagePaths.size() - 1));
|
||||
|
||||
if (_currentTileProvider) {
|
||||
_currentTileProvider->reset();
|
||||
}
|
||||
}
|
||||
|
||||
int ImageSequenceTileProvider::maxLevel() {
|
||||
return _currentTileProvider ? _currentTileProvider->maxLevel() : 0;
|
||||
}
|
||||
|
||||
float ImageSequenceTileProvider::noDataValueAsFloat() {
|
||||
return _currentTileProvider ?
|
||||
_currentTileProvider->noDataValueAsFloat() :
|
||||
std::numeric_limits<float>::min();
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
@@ -0,0 +1,60 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2022 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__IMAGESEQUENCETILEPROVIDER___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__IMAGESEQUENCETILEPROVIDER___H__
|
||||
|
||||
#include <modules/globebrowsing/src/tileprovider/tileprovider.h>
|
||||
|
||||
#include <modules/globebrowsing/src/tileprovider/defaulttileprovider.h>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
class ImageSequenceTileProvider : public TileProvider {
|
||||
public:
|
||||
ImageSequenceTileProvider(const ghoul::Dictionary& dictionary);
|
||||
|
||||
Tile tile(const TileIndex& tileIndex) override final;
|
||||
Tile::Status tileStatus(const TileIndex& index) override final;
|
||||
TileDepthTransform depthTransform() override final;
|
||||
void update() override final;
|
||||
void reset() override final;
|
||||
int maxLevel() override final;
|
||||
float noDataValueAsFloat() override final;
|
||||
|
||||
private:
|
||||
std::unique_ptr<DefaultTileProvider> _currentTileProvider = nullptr;
|
||||
|
||||
properties::IntProperty _index;
|
||||
properties::StringProperty _currentImage;
|
||||
properties::StringProperty _folderPath;
|
||||
|
||||
ghoul::Dictionary _initDict;
|
||||
bool _isImageDirty = true;
|
||||
std::vector<std::filesystem::path> _imagePaths;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__IMAGESEQUENCETILEPROVIDER___H__
|
||||
@@ -0,0 +1,100 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2022 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/globebrowsing/src/tileprovider/singleimagetileprovider.h>
|
||||
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <ghoul/io/texture/texturereader.h>
|
||||
|
||||
namespace {
|
||||
constexpr openspace::properties::Property::PropertyInfo FilePathInfo = {
|
||||
"FilePath",
|
||||
"File Path",
|
||||
"The file path that is used for this image provider. The file must point to an "
|
||||
"image that is then loaded and used for all tiles."
|
||||
};
|
||||
|
||||
struct [[codegen::Dictionary(SingleImageProvider)]] Parameters {
|
||||
// [[codegen::verbatim(FilePathInfo.description)]]
|
||||
std::string filePath;
|
||||
};
|
||||
#include "singleimagetileprovider_codegen.cpp"
|
||||
} // namespace
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
SingleImageProvider::SingleImageProvider(const ghoul::Dictionary& dictionary)
|
||||
: _filePath(FilePathInfo)
|
||||
{
|
||||
ZoneScoped
|
||||
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
_filePath = p.filePath;
|
||||
addProperty(_filePath);
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
Tile SingleImageProvider::tile(const TileIndex&) {
|
||||
ZoneScoped
|
||||
return _tile;
|
||||
}
|
||||
|
||||
Tile::Status SingleImageProvider::tileStatus(const TileIndex&) {
|
||||
return _tile.status;
|
||||
}
|
||||
|
||||
TileDepthTransform SingleImageProvider::depthTransform() {
|
||||
return { 0.f, 1.f };
|
||||
}
|
||||
|
||||
void SingleImageProvider::update() {}
|
||||
|
||||
void SingleImageProvider::reset() {
|
||||
if (_filePath.value().empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
_tileTexture = ghoul::io::TextureReader::ref().loadTexture(_filePath, 2);
|
||||
if (!_tileTexture) {
|
||||
throw ghoul::RuntimeError(
|
||||
fmt::format("Unable to load texture '{}'", _filePath.value())
|
||||
);
|
||||
}
|
||||
|
||||
_tileTexture->uploadTexture();
|
||||
_tileTexture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap);
|
||||
_tile = Tile{ _tileTexture.get(), std::nullopt, Tile::Status::OK };
|
||||
}
|
||||
|
||||
int SingleImageProvider::maxLevel() {
|
||||
return 1337; // unlimited
|
||||
}
|
||||
|
||||
float SingleImageProvider::noDataValueAsFloat() {
|
||||
return std::numeric_limits<float>::min();
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
@@ -0,0 +1,53 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2022 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__SINGLEIMAGETILEPROVIDER___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__SINGLEIMAGETILEPROVIDER___H__
|
||||
|
||||
#include <modules/globebrowsing/src/tileprovider/tileprovider.h>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
class SingleImageProvider : public TileProvider {
|
||||
public:
|
||||
SingleImageProvider(const ghoul::Dictionary& dictionary);
|
||||
|
||||
Tile tile(const TileIndex& tileIndex) override final;
|
||||
Tile::Status tileStatus(const TileIndex& index) override final;
|
||||
TileDepthTransform depthTransform() override final;
|
||||
void update() override final;
|
||||
void reset() override final;
|
||||
int maxLevel() override final;
|
||||
float noDataValueAsFloat() override final;
|
||||
|
||||
private:
|
||||
properties::StringProperty _filePath;
|
||||
|
||||
std::unique_ptr<ghoul::opengl::Texture> _tileTexture;
|
||||
Tile _tile;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__SINGLEIMAGETILEPROVIDER___H__
|
||||
@@ -0,0 +1,121 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2022 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/globebrowsing/src/tileprovider/sizereferencetileprovider.h>
|
||||
|
||||
#include <modules/globebrowsing/src/geodeticpatch.h>
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <ghoul/font/fontmanager.h>
|
||||
#include <optional>
|
||||
#include <variant>
|
||||
|
||||
namespace {
|
||||
struct [[codegen::Dictionary(SizeReferenceTileProvider)]] Parameters {
|
||||
std::optional<std::variant<glm::dvec3, double>> radii;
|
||||
};
|
||||
#include "sizereferencetileprovider_codegen.cpp"
|
||||
} // namespace
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
SizeReferenceTileProvider::SizeReferenceTileProvider(const ghoul::Dictionary& dictionary)
|
||||
: TextTileProvider(tileTextureInitData(layergroupid::GroupID::ColorLayers, false))
|
||||
{
|
||||
ZoneScoped
|
||||
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
font = global::fontManager->font("Mono", static_cast<float>(fontSize));
|
||||
|
||||
if (p.radii.has_value()) {
|
||||
if (std::holds_alternative<glm::dvec3>(*p.radii)) {
|
||||
_ellipsoid = std::get<glm::dvec3>(*p.radii);
|
||||
}
|
||||
else {
|
||||
const double r = std::get<double>(*p.radii);
|
||||
_ellipsoid = glm::dvec3(r, r, r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Tile SizeReferenceTileProvider::tile(const TileIndex& tileIndex) {
|
||||
ZoneScoped
|
||||
|
||||
const GeodeticPatch patch(tileIndex);
|
||||
const bool aboveEquator = patch.isNorthern();
|
||||
const double lat = aboveEquator ? patch.minLat() : patch.maxLat();
|
||||
const double lon1 = patch.minLon();
|
||||
const double lon2 = patch.maxLon();
|
||||
int l = static_cast<int>(_ellipsoid.longitudalDistance(lat, lon1, lon2));
|
||||
|
||||
const bool useKm = l > 9999;
|
||||
if (useKm) {
|
||||
l /= 1000;
|
||||
}
|
||||
l = static_cast<int>(std::round(l));
|
||||
if (useKm) {
|
||||
l *= 1000;
|
||||
}
|
||||
double tileLongitudalLength = l;
|
||||
|
||||
const char* unit;
|
||||
if (tileLongitudalLength > 9999) {
|
||||
tileLongitudalLength *= 0.001;
|
||||
unit = "km";
|
||||
}
|
||||
else {
|
||||
unit = "m";
|
||||
}
|
||||
|
||||
std::string text = fmt::format(" {:.0f} {:s}", tileLongitudalLength, unit);
|
||||
glm::vec2 textPosition = {
|
||||
0.f,
|
||||
aboveEquator ?
|
||||
fontSize / 2.f :
|
||||
initData.dimensions.y - 3.f * fontSize / 2.f
|
||||
};
|
||||
|
||||
return TextTileProvider::renderTile(tileIndex, text, textPosition, glm::vec4(1.f));
|
||||
}
|
||||
|
||||
Tile::Status SizeReferenceTileProvider::tileStatus(const TileIndex& index) {
|
||||
return Tile::Status::OK;
|
||||
}
|
||||
|
||||
TileDepthTransform SizeReferenceTileProvider::depthTransform() {
|
||||
return { 0.f, 1.f };
|
||||
}
|
||||
|
||||
void SizeReferenceTileProvider::update() {}
|
||||
|
||||
int SizeReferenceTileProvider::maxLevel() {
|
||||
return 1337; // unlimited
|
||||
}
|
||||
|
||||
float SizeReferenceTileProvider::noDataValueAsFloat() {
|
||||
return std::numeric_limits<float>::min();
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
@@ -0,0 +1,49 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2022 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__SIZEREFERENCETILEPROVIDER___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__SIZEREFERENCETILEPROVIDER___H__
|
||||
|
||||
#include <modules/globebrowsing/src/tileprovider/texttileprovider.h>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
class SizeReferenceTileProvider : public TextTileProvider {
|
||||
public:
|
||||
SizeReferenceTileProvider(const ghoul::Dictionary& dictionary);
|
||||
|
||||
Tile tile(const TileIndex& tileIndex) override final;
|
||||
Tile::Status tileStatus(const TileIndex& index) override final;
|
||||
TileDepthTransform depthTransform() override final;
|
||||
void update() override final;
|
||||
int maxLevel() override final;
|
||||
float noDataValueAsFloat() override final;
|
||||
|
||||
private:
|
||||
Ellipsoid _ellipsoid;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__SIZEREFERENCETILEPROVIDER___H__
|
||||
822
modules/globebrowsing/src/tileprovider/temporaltileprovider.cpp
Normal file
822
modules/globebrowsing/src/tileprovider/temporaltileprovider.cpp
Normal file
@@ -0,0 +1,822 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2022 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/globebrowsing/src/tileprovider/temporaltileprovider.h>
|
||||
|
||||
#include <modules/globebrowsing/globebrowsingmodule.h>
|
||||
#include <modules/globebrowsing/src/memoryawaretilecache.h>
|
||||
#include <modules/globebrowsing/src/tileprovider/defaulttileprovider.h>
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/util/memorymanager.h>
|
||||
#include <openspace/util/spicemanager.h>
|
||||
#include <openspace/util/timemanager.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/io/texture/texturereader.h>
|
||||
#include <ghoul/opengl/openglstatecache.h>
|
||||
#include <ghoul/opengl/textureunit.h>
|
||||
#include <ctime>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
namespace {
|
||||
constexpr const char* KeyBasePath = "BasePath";
|
||||
|
||||
constexpr const char* TimePlaceholder = "${OpenSpaceTimeId}";
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo FilePathInfo = {
|
||||
"FilePath",
|
||||
"File Path",
|
||||
"This is the path to the XML configuration file that describes the temporal tile "
|
||||
"information."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo UseFixedTimeInfo = {
|
||||
"UseFixedTime",
|
||||
"Use Fixed Time",
|
||||
"If this value is enabled, the time-varying timevarying dataset will always use "
|
||||
"the time that is specified in the 'FixedTime' property, rather than using the "
|
||||
"actual time from OpenSpace"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo FixedTimeInfo = {
|
||||
"FixedTime",
|
||||
"Fixed Time",
|
||||
"If the 'UseFixedTime' is enabled, this time will be used instead of the actual "
|
||||
"time taken from OpenSpace for the displayed tiles."
|
||||
};
|
||||
|
||||
struct [[codegen::Dictionary(TemporalTileProvider)]] Parameters {
|
||||
// [[codegen::verbatim(UseFixedTimeInfo.description)]]
|
||||
std::optional<bool> useFixedTime;
|
||||
|
||||
// [[codegen::verbatim(FixedTimeInfo.description)]]
|
||||
std::optional<std::string> fixedTime;
|
||||
|
||||
enum class Mode {
|
||||
Prototyped,
|
||||
Folder
|
||||
};
|
||||
// The mode that his temporal tile provider operates in. In the `Prototyped` mode,
|
||||
// a given start and end time, temporal resolution, and perscriptive time format
|
||||
// is used to generate the information used by GDAL to access the data. In the
|
||||
// `folder` method, a folder and a time format is provided and each file in the
|
||||
// folder is scanned using the time format instead
|
||||
Mode mode;
|
||||
|
||||
struct Prototyped {
|
||||
struct Time {
|
||||
// The (inclusive) starting time of the temporal image range
|
||||
std::string start;
|
||||
// The (inclusive) ending time of the temporal image range
|
||||
std::string end;
|
||||
};
|
||||
// The starting and ending times for the range of values
|
||||
Time time;
|
||||
|
||||
// The temporal resolution between each image
|
||||
std::string temporalResolution;
|
||||
|
||||
// The specification of the date format that is used in the tile provider. The
|
||||
// time format must be specified in a manner appropriate for the SPICE
|
||||
// function `timout_c`.
|
||||
// https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/timout_c.html
|
||||
std::string timeFormat;
|
||||
|
||||
// The text that will be used as the prototype to generate the data to load
|
||||
// the image layer. Any occurance of `${OpenSpaceTimeId}` in this prototype
|
||||
// is replaced with the current date according to the remaining information
|
||||
// such as the resolution and the format and the resulting text is used to
|
||||
// load the corresponding images
|
||||
std::string prototype;
|
||||
|
||||
};
|
||||
std::optional<Prototyped> prototyped;
|
||||
|
||||
struct Folder {
|
||||
// The folder that is parsed for files. Every file in the provided directory
|
||||
// is checked against the provided format and added if it adheres to said
|
||||
// format
|
||||
std::filesystem::path folder [[codegen::directory()]];
|
||||
|
||||
// The format of files that is pared in the provided folder. The format string
|
||||
// has to be compatible to the C++ function get_time.
|
||||
// https://en.cppreference.com/w/cpp/io/manip/get_time
|
||||
std::string format;
|
||||
};
|
||||
std::optional<Folder> folder;
|
||||
|
||||
// Determines whether this tile provider should interpolate between two adjacent
|
||||
// layers
|
||||
std::optional<bool> interpolation;
|
||||
|
||||
// If provided, the tile provider will use this color map to convert a greyscale
|
||||
// image to color
|
||||
std::optional<std::string> colormap;
|
||||
};
|
||||
#include "temporaltileprovider_codegen.cpp"
|
||||
|
||||
std::string_view timeStringify(const std::string& format, const openspace::Time& t) {
|
||||
ZoneScoped
|
||||
|
||||
constexpr const int BufferSize = 64;
|
||||
ghoul_assert(format.size() < BufferSize, "Format string too long");
|
||||
|
||||
using namespace openspace;
|
||||
|
||||
char FormatBuf[BufferSize];
|
||||
std::memset(FormatBuf, '\0', BufferSize);
|
||||
std::memcpy(FormatBuf, format.c_str(), format.size());
|
||||
|
||||
char* OutBuf = reinterpret_cast<char*>(
|
||||
global::memoryManager->TemporaryMemory.allocate(BufferSize)
|
||||
);
|
||||
std::memset(OutBuf, '\0', BufferSize);
|
||||
|
||||
const double time = t.j2000Seconds();
|
||||
SpiceManager::ref().dateFromEphemerisTime(time, OutBuf, BufferSize, FormatBuf);
|
||||
return std::string_view(OutBuf, format.size());
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
TemporalTileProvider::TemporalTileProvider(const ghoul::Dictionary& dictionary)
|
||||
: _initDict(dictionary)
|
||||
, _useFixedTime(UseFixedTimeInfo, false)
|
||||
, _fixedTime(FixedTimeInfo)
|
||||
{
|
||||
ZoneScoped
|
||||
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
// Make sure that the user provided the data that they requested. The mode parameter
|
||||
// is a required one and these two if statements tie the table requirement to the mode
|
||||
if (p.mode == Parameters::Mode::Folder && !p.folder.has_value()) {
|
||||
throw ghoul::RuntimeError(
|
||||
"When selecting the `Folder` mode, a `Folder` table must be specified"
|
||||
);
|
||||
}
|
||||
if (p.mode == Parameters::Mode::Prototyped && !p.prototyped.has_value()) {
|
||||
throw ghoul::RuntimeError(
|
||||
"When selecting the `Prototyped` mode, a `Prototyped` table must be specified"
|
||||
);
|
||||
}
|
||||
|
||||
_useFixedTime = p.useFixedTime.value_or(_useFixedTime);
|
||||
_useFixedTime.onChange([this]() { _fixedTimeDirty = true; });
|
||||
addProperty(_useFixedTime);
|
||||
|
||||
_fixedTime = p.fixedTime.value_or(_fixedTime);
|
||||
_fixedTime.onChange([this]() { _fixedTimeDirty = true; });
|
||||
addProperty(_fixedTime);
|
||||
|
||||
_colormap = p.colormap.value_or(_colormap);
|
||||
|
||||
if (p.prototyped.has_value()) {
|
||||
_mode = Mode::Prototype;
|
||||
|
||||
Time start = Time(p.prototyped->time.start);
|
||||
Time end = Time::now();
|
||||
_prototyped.startTimeJ2000 = start.j2000Seconds();
|
||||
_prototyped.endTimeJ2000 = Time(p.prototyped->time.end).j2000Seconds();
|
||||
if (p.prototyped->time.end == "Yesterday") {
|
||||
end.advanceTime(-60.0 * 60.0 * 24.0); // Go back one day
|
||||
}
|
||||
else if (p.prototyped->time.end != "Today") {
|
||||
end.setTime(p.prototyped->time.end);
|
||||
}
|
||||
|
||||
try {
|
||||
_prototyped.timeQuantizer.setStartEndRange(
|
||||
std::string(start.ISO8601()),
|
||||
std::string(end.ISO8601())
|
||||
);
|
||||
_prototyped.timeQuantizer.setResolution(p.prototyped->temporalResolution);
|
||||
_prototyped.temporalResolution = p.prototyped->temporalResolution;
|
||||
}
|
||||
catch (const ghoul::RuntimeError& e) {
|
||||
throw ghoul::RuntimeError(fmt::format(
|
||||
"Could not create time quantizer for Temporal GDAL dataset. {}", e.message
|
||||
));
|
||||
}
|
||||
|
||||
if (p.prototyped->timeFormat.size() >= 64) {
|
||||
throw ghoul::RuntimeError(fmt::format(
|
||||
"Time format string '{}' too large. Maximum length of 64 is allowed",
|
||||
p.prototyped->timeFormat
|
||||
));
|
||||
}
|
||||
_prototyped.timeFormat = p.prototyped->timeFormat;
|
||||
_prototyped.prototype = p.prototyped->prototype;
|
||||
}
|
||||
|
||||
if (p.folder.has_value()) {
|
||||
_mode = Mode::Folder;
|
||||
|
||||
_folder.folder = p.folder->folder;
|
||||
_folder.format = p.folder->format;
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
for (const fs::directory_entry& path : fs::directory_iterator(_folder.folder)) {
|
||||
if (!path.is_regular_file()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string file = path.path().filename().string();
|
||||
std::istringstream ss(file);
|
||||
|
||||
std::tm tm = {};
|
||||
ss >> std::get_time(&tm, p.folder->format.c_str());
|
||||
if (!ss.fail()) {
|
||||
std::string date = fmt::format(
|
||||
"{}-{}-{} {}:{}:{}",
|
||||
tm.tm_year + 1900,
|
||||
tm.tm_mon + 1,
|
||||
tm.tm_mday,
|
||||
tm.tm_hour,
|
||||
tm.tm_min,
|
||||
tm.tm_sec
|
||||
);
|
||||
|
||||
double et = SpiceManager::ref().ephemerisTimeFromDate(date);
|
||||
_folder.files.push_back({ et, path.path().string() });
|
||||
}
|
||||
}
|
||||
|
||||
using K = double;
|
||||
using V = std::string;
|
||||
std::sort(
|
||||
_folder.files.begin(),
|
||||
_folder.files.end(),
|
||||
[](const std::pair<K, V>& lhs, const std::pair<K, V>& rhs) {
|
||||
return lhs.first < rhs.first;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
_isInterpolating = p.interpolation.value_or(_isInterpolating);
|
||||
if (_isInterpolating) {
|
||||
_interpolateTileProvider = std::make_unique<InterpolateTileProvider>(dictionary);
|
||||
_interpolateTileProvider->initialize();
|
||||
_interpolateTileProvider->colormap =
|
||||
ghoul::io::TextureReader::ref().loadTexture(_colormap, 1);
|
||||
_interpolateTileProvider->colormap->uploadTexture();
|
||||
_interpolateTileProvider->colormap->setFilter(
|
||||
ghoul::opengl::Texture::FilterMode::AnisotropicMipMap
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Tile TemporalTileProvider::tile(const TileIndex& tileIndex) {
|
||||
ZoneScoped
|
||||
if (!_currentTileProvider) {
|
||||
update();
|
||||
}
|
||||
|
||||
return _currentTileProvider->tile(tileIndex);
|
||||
}
|
||||
|
||||
Tile::Status TemporalTileProvider::tileStatus(const TileIndex& index) {
|
||||
if (!_currentTileProvider) {
|
||||
update();
|
||||
}
|
||||
|
||||
return _currentTileProvider->tileStatus(index);
|
||||
}
|
||||
|
||||
TileDepthTransform TemporalTileProvider::depthTransform() {
|
||||
if (!_currentTileProvider) {
|
||||
update();
|
||||
}
|
||||
|
||||
return _currentTileProvider->depthTransform();
|
||||
}
|
||||
|
||||
void TemporalTileProvider::update() {
|
||||
TileProvider* newCurr = nullptr;
|
||||
try {
|
||||
if (_useFixedTime && !_fixedTime.value().empty()) {
|
||||
if (_fixedTimeDirty) {
|
||||
std::string fixedTime = _fixedTime.value();
|
||||
double et = SpiceManager::ref().ephemerisTimeFromDate(fixedTime);
|
||||
newCurr = retrieveTileProvider(Time(et));
|
||||
_fixedTimeDirty = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
newCurr = tileProvider(global::timeManager->time());
|
||||
}
|
||||
}
|
||||
catch (const ghoul::RuntimeError& e) {
|
||||
LERRORC("TemporalTileProvider", e.message);
|
||||
}
|
||||
|
||||
if (newCurr) {
|
||||
_currentTileProvider = newCurr;
|
||||
}
|
||||
if (_currentTileProvider) {
|
||||
_currentTileProvider->update();
|
||||
}
|
||||
}
|
||||
|
||||
void TemporalTileProvider::reset() {
|
||||
for (std::pair<const double, DefaultTileProvider>& it : _tileProviderMap) {
|
||||
it.second.reset();
|
||||
}
|
||||
}
|
||||
|
||||
int TemporalTileProvider::maxLevel() {
|
||||
if (!_currentTileProvider) {
|
||||
update();
|
||||
}
|
||||
return _currentTileProvider->maxLevel();
|
||||
}
|
||||
|
||||
float TemporalTileProvider::noDataValueAsFloat() {
|
||||
return std::numeric_limits<float>::min();
|
||||
}
|
||||
|
||||
DefaultTileProvider TemporalTileProvider::createTileProvider(
|
||||
std::string_view timekey) const
|
||||
{
|
||||
ZoneScoped
|
||||
|
||||
std::string value;
|
||||
switch (_mode) {
|
||||
case Mode::Prototype: {
|
||||
static const std::vector<std::string> IgnoredTokens = {
|
||||
// From: http://www.gdal.org/frmt_wms.html
|
||||
"${x}", "${y}", "${z}", "${version}" "${format}", "${layer}"
|
||||
};
|
||||
|
||||
value = _prototyped.prototype;
|
||||
while (true) {
|
||||
const size_t pos = value.find(TimePlaceholder);
|
||||
|
||||
if (pos == std::string::npos) {
|
||||
break;
|
||||
}
|
||||
|
||||
const size_t numChars = std::string_view(TimePlaceholder).size();
|
||||
value = value.replace(pos, numChars, timekey);
|
||||
}
|
||||
|
||||
value = FileSys.expandPathTokens(std::move(value), IgnoredTokens).string();
|
||||
break;
|
||||
}
|
||||
case Mode::Folder: {
|
||||
value = std::string(timekey);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ghoul::Dictionary dict = _initDict;
|
||||
dict.setValue("FilePath", value);
|
||||
return DefaultTileProvider(dict);
|
||||
}
|
||||
|
||||
DefaultTileProvider* TemporalTileProvider::retrieveTileProvider(const Time& t) {
|
||||
ZoneScoped
|
||||
|
||||
const double time = t.j2000Seconds();
|
||||
if (const auto it = _tileProviderMap.find(time); it != _tileProviderMap.end()) {
|
||||
return &it->second;
|
||||
}
|
||||
|
||||
std::string_view timeStr = [this, time]() {
|
||||
switch (_mode) {
|
||||
case Mode::Prototype:
|
||||
return timeStringify(_prototyped.timeFormat, Time(time));
|
||||
case Mode::Folder: {
|
||||
// Yes this will have to be done twice since we do the check previously
|
||||
// but it is only happening when the images change, so I think that should
|
||||
// be fine
|
||||
auto it = std::lower_bound(
|
||||
_folder.files.cbegin(),
|
||||
_folder.files.cend(),
|
||||
time,
|
||||
[](const std::pair<double, std::string>& p, double time) {
|
||||
return p.first < time;
|
||||
}
|
||||
);
|
||||
return std::string_view(it->second);
|
||||
}
|
||||
default: throw ghoul::MissingCaseException();
|
||||
};
|
||||
}();
|
||||
|
||||
DefaultTileProvider tileProvider = createTileProvider(timeStr);
|
||||
tileProvider.initialize();
|
||||
|
||||
auto it = _tileProviderMap.insert({ time, std::move(tileProvider) });
|
||||
return &it.first->second;
|
||||
}
|
||||
|
||||
template <>
|
||||
TileProvider*
|
||||
TemporalTileProvider::tileProvider<TemporalTileProvider::Mode::Folder, false>(
|
||||
const Time& time)
|
||||
{
|
||||
// Find the most current image that matches the current time. We can't pass the `time`
|
||||
// variable into the retrieveTileProvider function as it would generate a new
|
||||
// non-existing TileProvider for every new frame
|
||||
using It = std::vector<std::pair<double, std::string>>::const_iterator;
|
||||
It it = std::lower_bound(
|
||||
_folder.files.begin(),
|
||||
_folder.files.end(),
|
||||
time.j2000Seconds(),
|
||||
[](const std::pair<double, std::string>& p, double t) {
|
||||
return p.first < t;
|
||||
}
|
||||
);
|
||||
|
||||
if (it != _folder.files.begin()) {
|
||||
it -= 1;
|
||||
}
|
||||
|
||||
double t = it->first;
|
||||
return retrieveTileProvider(Time(t));
|
||||
}
|
||||
|
||||
template <>
|
||||
TileProvider*
|
||||
TemporalTileProvider::tileProvider<TemporalTileProvider::Mode::Folder, true>(
|
||||
const Time& time)
|
||||
{
|
||||
using It = std::vector<std::pair<double, std::string>>::const_iterator;
|
||||
It next = std::lower_bound(
|
||||
_folder.files.begin(),
|
||||
_folder.files.end(),
|
||||
time.j2000Seconds(),
|
||||
[](const std::pair<double, std::string>& p, double t) {
|
||||
return p.first < t;
|
||||
}
|
||||
);
|
||||
|
||||
It curr = next != _folder.files.begin() ? next - 1 : next;
|
||||
It nextNext = next != _folder.files.end() ? next + 1 : curr;
|
||||
It prev = curr != _folder.files.begin() ? curr - 1 : curr;
|
||||
|
||||
_interpolateTileProvider->t1 = retrieveTileProvider(Time(curr->first));
|
||||
_interpolateTileProvider->t2 = retrieveTileProvider(Time(next->first));
|
||||
_interpolateTileProvider->future = retrieveTileProvider(Time(nextNext->first));
|
||||
_interpolateTileProvider->before = retrieveTileProvider(Time(prev->first));
|
||||
|
||||
_interpolateTileProvider->factor = static_cast<float>(
|
||||
(time.j2000Seconds() - curr->first) /
|
||||
(next->first - curr->first)
|
||||
);
|
||||
|
||||
if (_interpolateTileProvider->factor > 1.f) {
|
||||
_interpolateTileProvider->factor = 1.f;
|
||||
}
|
||||
|
||||
return _interpolateTileProvider.get();
|
||||
}
|
||||
|
||||
template <>
|
||||
TileProvider*
|
||||
TemporalTileProvider::tileProvider<TemporalTileProvider::Mode::Prototype, false>(
|
||||
const Time& time)
|
||||
{
|
||||
Time tCopy(time);
|
||||
if (_prototyped.timeQuantizer.quantize(tCopy, true)) {
|
||||
return retrieveTileProvider(tCopy);
|
||||
}
|
||||
else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
TileProvider*
|
||||
TemporalTileProvider::tileProvider<TemporalTileProvider::Mode::Prototype, true>(
|
||||
const Time& time)
|
||||
{
|
||||
Time tCopy(time);
|
||||
if (!_prototyped.timeQuantizer.quantize(tCopy, true)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Time nextTile = tCopy;
|
||||
Time nextNextTile = tCopy;
|
||||
Time prevTile = tCopy;
|
||||
Time secondToLast = Time(_prototyped.endTimeJ2000);
|
||||
Time secondToFirst = Time(_prototyped.startTimeJ2000);
|
||||
|
||||
_interpolateTileProvider->t1 = retrieveTileProvider(tCopy);
|
||||
|
||||
// if the images are for each hour
|
||||
if (_prototyped.temporalResolution == "1h") {
|
||||
constexpr const int Hour = 60 * 60;
|
||||
// the second tile to interpolate between
|
||||
nextTile.advanceTime(Hour);
|
||||
// the tile after the second tile
|
||||
nextNextTile.advanceTime(2 * Hour);
|
||||
// the tile before the first tile
|
||||
prevTile.advanceTime(-Hour + 1);
|
||||
// to make sure that an image outside the dataset is not searched for both
|
||||
// ends of the dataset are calculated
|
||||
secondToLast.advanceTime(-Hour);
|
||||
secondToFirst.advanceTime(Hour);
|
||||
}
|
||||
// if the images are for each month
|
||||
if (_prototyped.temporalResolution == "1M") {
|
||||
constexpr const int Day = 24 * 60 * 60;
|
||||
|
||||
// the second tile to interpolate between
|
||||
nextTile.advanceTime(32 * Day);
|
||||
// the tile after the second tile
|
||||
nextNextTile.advanceTime(64 * Day);
|
||||
// the tile before the first tile
|
||||
prevTile.advanceTime(-2 * Day);
|
||||
// to make sure that an image outside the dataset is not searched for both
|
||||
// ends of the dataset are calculated
|
||||
secondToLast.advanceTime(-2 * Day);
|
||||
secondToFirst.advanceTime(32 * Day);
|
||||
|
||||
// since months vary in length the time is set to the first of each month
|
||||
auto setToFirstOfMonth = [](Time& t) {
|
||||
std::string timeString = std::string(t.ISO8601());
|
||||
timeString[8] = '0';
|
||||
timeString[9] = '1';
|
||||
t.setTime(timeString);
|
||||
};
|
||||
|
||||
setToFirstOfMonth(nextTile);
|
||||
setToFirstOfMonth(nextNextTile);
|
||||
setToFirstOfMonth(prevTile);
|
||||
setToFirstOfMonth(secondToLast);
|
||||
setToFirstOfMonth(secondToFirst);
|
||||
}
|
||||
|
||||
// the necessary tile providers are loaded if they exist within the timespan
|
||||
if (secondToLast.j2000Seconds() > time.j2000Seconds() &&
|
||||
secondToFirst.j2000Seconds() < time.j2000Seconds())
|
||||
{
|
||||
_interpolateTileProvider->t2 = retrieveTileProvider(nextTile);
|
||||
_interpolateTileProvider->future = retrieveTileProvider(nextNextTile);
|
||||
_interpolateTileProvider->before = retrieveTileProvider(prevTile);
|
||||
}
|
||||
else if (secondToLast.j2000Seconds() < time.j2000Seconds() &&
|
||||
_prototyped.endTimeJ2000 > time.j2000Seconds())
|
||||
{
|
||||
_interpolateTileProvider->t2 = retrieveTileProvider(nextTile);
|
||||
_interpolateTileProvider->future = retrieveTileProvider(tCopy);
|
||||
_interpolateTileProvider->before = retrieveTileProvider(prevTile);
|
||||
}
|
||||
else if (secondToFirst.j2000Seconds() > time.j2000Seconds() &&
|
||||
_prototyped.startTimeJ2000 < time.j2000Seconds())
|
||||
{
|
||||
_interpolateTileProvider->t2 = retrieveTileProvider(nextTile);
|
||||
_interpolateTileProvider->future = retrieveTileProvider(nextNextTile);
|
||||
_interpolateTileProvider->before = retrieveTileProvider(tCopy);
|
||||
}
|
||||
else {
|
||||
_interpolateTileProvider->t2 = retrieveTileProvider(tCopy);
|
||||
_interpolateTileProvider->future = retrieveTileProvider(tCopy);
|
||||
_interpolateTileProvider->before = retrieveTileProvider(tCopy);
|
||||
}
|
||||
_interpolateTileProvider->factor = static_cast<float>(
|
||||
(time.j2000Seconds() - tCopy.j2000Seconds()) /
|
||||
(nextTile.j2000Seconds() - tCopy.j2000Seconds())
|
||||
);
|
||||
|
||||
if (_interpolateTileProvider->factor > 1.f) {
|
||||
_interpolateTileProvider->factor = 1.f;
|
||||
}
|
||||
return _interpolateTileProvider.get();
|
||||
}
|
||||
|
||||
TileProvider* TemporalTileProvider::tileProvider(const Time& time) {
|
||||
if (_isInterpolating) {
|
||||
switch (_mode) {
|
||||
case Mode::Folder:
|
||||
return tileProvider<Mode::Folder, true>(time);
|
||||
case Mode::Prototype:
|
||||
return tileProvider<Mode::Prototype, true>(time);
|
||||
default: throw ghoul::MissingCaseException();
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch (_mode) {
|
||||
case Mode::Folder:
|
||||
return tileProvider<Mode::Folder, false>(time);
|
||||
case Mode::Prototype:
|
||||
return tileProvider<Mode::Prototype, false>(time);
|
||||
default: throw ghoul::MissingCaseException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TemporalTileProvider::InterpolateTileProvider::InterpolateTileProvider(
|
||||
const ghoul::Dictionary&)
|
||||
{
|
||||
ZoneScoped
|
||||
|
||||
glGenFramebuffers(1, &fbo);
|
||||
glGenVertexArrays(1, &vaoQuad);
|
||||
glGenBuffers(1, &vboQuad);
|
||||
glBindVertexArray(vaoQuad);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vboQuad);
|
||||
// Quad for fullscreen with vertex (xy) and texture coordinates (uv)
|
||||
const GLfloat vertexData[] = {
|
||||
// x y u v
|
||||
-1.f, -1.f, 0.f, 0.f,
|
||||
1.f, 1.f, 1.f, 1.f,
|
||||
-1.f, 1.f, 0.f, 1.f,
|
||||
-1.f, -1.f, 0.f, 0.f,
|
||||
1.f, -1.f, 1.f, 0.f,
|
||||
1.f, 1.f, 1.f, 1.f
|
||||
};
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW);
|
||||
// vertex coordinates at location 0
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), nullptr);
|
||||
glEnableVertexAttribArray(0);
|
||||
// texture coords at location 1
|
||||
glVertexAttribPointer(
|
||||
1,
|
||||
2,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
4 * sizeof(GLfloat),
|
||||
reinterpret_cast<void*>(2 * sizeof(GLfloat))
|
||||
);
|
||||
glEnableVertexAttribArray(1);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
shaderProgram = global::renderEngine->buildRenderProgram(
|
||||
"InterpolatingProgram",
|
||||
absPath("${MODULE_GLOBEBROWSING}/shaders/interpolate_vs.glsl"),
|
||||
absPath("${MODULE_GLOBEBROWSING}/shaders/interpolate_fs.glsl")
|
||||
);
|
||||
}
|
||||
|
||||
TemporalTileProvider::InterpolateTileProvider::~InterpolateTileProvider() {
|
||||
glDeleteFramebuffers(1, &fbo);
|
||||
glDeleteBuffers(1, &vboQuad);
|
||||
glDeleteVertexArrays(1, &vaoQuad);
|
||||
}
|
||||
|
||||
Tile TemporalTileProvider::InterpolateTileProvider::tile(const TileIndex& tileIndex) {
|
||||
ZoneScoped
|
||||
TracyGpuZone("tile");
|
||||
|
||||
// prev and next are the two tiles to interpolate between
|
||||
Tile prev = t1->tile(tileIndex);
|
||||
Tile next = t2->tile(tileIndex);
|
||||
// the tile before and the tile after the interpolation interval are loaded so the
|
||||
// interpolation goes smoother
|
||||
Tile prevprev = before->tile(tileIndex);
|
||||
Tile nextnext = future->tile(tileIndex);
|
||||
cache::ProviderTileKey key = { tileIndex, uniqueIdentifier };
|
||||
|
||||
if (!prev.texture || !next.texture) {
|
||||
return Tile{ nullptr, std::nullopt, Tile::Status::Unavailable };
|
||||
}
|
||||
|
||||
// The data for initializing the texture
|
||||
TileTextureInitData initData(
|
||||
prev.texture->dimensions().x,
|
||||
prev.texture->dimensions().y,
|
||||
prev.texture->dataType(),
|
||||
prev.texture->format(),
|
||||
TileTextureInitData::PadTiles::No,
|
||||
TileTextureInitData::ShouldAllocateDataOnCPU::No
|
||||
);
|
||||
|
||||
// Check if a tile exists for the given key in the tileCache
|
||||
// Initializing the tile that will contian the interpolated texture
|
||||
Tile ourTile;
|
||||
// The texture that will contain the interpolated image
|
||||
ghoul::opengl::Texture* writeTexture;
|
||||
cache::MemoryAwareTileCache* tileCache =
|
||||
global::moduleEngine->module<GlobeBrowsingModule>()->tileCache();
|
||||
if (tileCache->exist(key)) {
|
||||
ourTile = tileCache->get(key);
|
||||
writeTexture = ourTile.texture;
|
||||
}
|
||||
else {
|
||||
// Create a texture with the initialization data
|
||||
writeTexture = tileCache->texture(initData);
|
||||
ourTile = Tile{ writeTexture, std::nullopt, Tile::Status::OK };
|
||||
tileCache->put(key, initData.hashKey, ourTile);
|
||||
}
|
||||
|
||||
// Saves current state
|
||||
GLint currentFBO;
|
||||
GLint viewport[4];
|
||||
glGetIntegerv(GL_FRAMEBUFFER_BINDING, ¤tFBO);
|
||||
global::renderEngine->openglStateCache().viewport(viewport);
|
||||
// Bind render texture to FBO
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, *writeTexture, 0);
|
||||
glDisable(GL_BLEND);
|
||||
GLenum textureBuffers[1] = { GL_COLOR_ATTACHMENT0 };
|
||||
glDrawBuffers(1, textureBuffers);
|
||||
|
||||
// Setup our own viewport settings
|
||||
GLsizei w = static_cast<GLsizei>(writeTexture->width());
|
||||
GLsizei h = static_cast<GLsizei>(writeTexture->height());
|
||||
glViewport(0, 0, w, h);
|
||||
glClearColor(0.f, 0.f, 0.f, 0.f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
GLint id;
|
||||
glGetIntegerv(GL_CURRENT_PROGRAM, &id);
|
||||
// Activate shader and bind uniforms
|
||||
shaderProgram->activate();
|
||||
shaderProgram->setUniform("blendFactor", factor);
|
||||
|
||||
// The texture that will give the color for the interpolated texture
|
||||
ghoul::opengl::TextureUnit colormapUnit;
|
||||
colormapUnit.activate();
|
||||
colormap->bind();
|
||||
shaderProgram->setUniform("colormapTexture", colormapUnit);
|
||||
|
||||
ghoul::opengl::TextureUnit prevUnit;
|
||||
prevUnit.activate();
|
||||
prev.texture->bind();
|
||||
shaderProgram->setUniform("prevTexture", prevUnit);
|
||||
|
||||
ghoul::opengl::TextureUnit nextUnit;
|
||||
nextUnit.activate();
|
||||
next.texture->bind();
|
||||
shaderProgram->setUniform("nextTexture", nextUnit);
|
||||
|
||||
// Render to the texture
|
||||
glBindVertexArray(vaoQuad);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6); // 2 triangles
|
||||
// Deactivate shader program (when rendering is completed)
|
||||
shaderProgram->deactivate();
|
||||
glUseProgram(id);
|
||||
// Restores system state
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, currentFBO);
|
||||
glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
|
||||
// Restores OpenGL Rendering State
|
||||
global::renderEngine->openglStateCache().resetColorState();
|
||||
global::renderEngine->openglStateCache().resetBlendState();
|
||||
global::renderEngine->openglStateCache().resetDepthState();
|
||||
global::renderEngine->openglStateCache().resetPolygonAndClippingState();
|
||||
global::renderEngine->openglStateCache().resetViewportState();
|
||||
|
||||
return ourTile;
|
||||
}
|
||||
|
||||
Tile::Status TemporalTileProvider::InterpolateTileProvider::tileStatus(
|
||||
const TileIndex& index)
|
||||
{
|
||||
return std::min(t1->tileStatus(index), t2->tileStatus(index));
|
||||
}
|
||||
|
||||
TileDepthTransform TemporalTileProvider::InterpolateTileProvider::depthTransform() {
|
||||
return t1->depthTransform();
|
||||
}
|
||||
|
||||
void TemporalTileProvider::InterpolateTileProvider::update() {
|
||||
t1->update();
|
||||
t2->update();
|
||||
before->update();
|
||||
future->update();
|
||||
}
|
||||
|
||||
void TemporalTileProvider::InterpolateTileProvider::reset() {
|
||||
t1->reset();
|
||||
t2->reset();
|
||||
before->reset();
|
||||
future->reset();
|
||||
}
|
||||
|
||||
int TemporalTileProvider::InterpolateTileProvider::maxLevel() {
|
||||
return glm::min(t1->maxLevel(), t2->maxLevel());
|
||||
}
|
||||
|
||||
float TemporalTileProvider::InterpolateTileProvider::noDataValueAsFloat() {
|
||||
return std::numeric_limits<float>::min();
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
130
modules/globebrowsing/src/tileprovider/temporaltileprovider.h
Normal file
130
modules/globebrowsing/src/tileprovider/temporaltileprovider.h
Normal file
@@ -0,0 +1,130 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2022 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__TEMPORALTILEPROVIDER___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__TEMPORALTILEPROVIDER___H__
|
||||
|
||||
#include <modules/globebrowsing/src/tileprovider/tileprovider.h>
|
||||
|
||||
#include <modules/globebrowsing/src/tileprovider/defaulttileprovider.h>
|
||||
#include <modules/globebrowsing/src/tileprovider/singleimagetileprovider.h>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
/**
|
||||
* Provide <code>Tile</code>s from web map services that have temporal resolution.
|
||||
*
|
||||
* TemporalTileProviders are instantiated using a ghoul::Dictionary, and must define a
|
||||
* filepath to a Openspace Temporal dataset description file. This is an xml-file that
|
||||
* defines the same meta data as the GDAL wms description
|
||||
* (http://www.gdal.org/frmt_wms.html), but augmented with some extra tags describing the
|
||||
* temporal properties of the dataset. See
|
||||
* <code>TemporalTileProvider::TemporalXMLTags</code>
|
||||
*/
|
||||
class TemporalTileProvider : public TileProvider {
|
||||
public:
|
||||
TemporalTileProvider(const ghoul::Dictionary& dictionary);
|
||||
|
||||
Tile tile(const TileIndex& tileIndex) override final;
|
||||
Tile::Status tileStatus(const TileIndex& index) override final;
|
||||
TileDepthTransform depthTransform() override final;
|
||||
void update() override final;
|
||||
void reset() override final;
|
||||
int maxLevel() override final;
|
||||
float noDataValueAsFloat() override final;
|
||||
|
||||
private:
|
||||
enum class Mode {
|
||||
Prototype,
|
||||
Folder
|
||||
};
|
||||
|
||||
struct InterpolateTileProvider : public TileProvider {
|
||||
InterpolateTileProvider(const ghoul::Dictionary&);
|
||||
virtual ~InterpolateTileProvider();
|
||||
|
||||
Tile tile(const TileIndex& tileIndex) override final;
|
||||
Tile::Status tileStatus(const TileIndex& index) override final;
|
||||
TileDepthTransform depthTransform() override final;
|
||||
void update() override final;
|
||||
void reset() override final;
|
||||
int maxLevel() override final;
|
||||
float noDataValueAsFloat() override final;
|
||||
|
||||
TileProvider* before = nullptr;
|
||||
TileProvider* t1 = nullptr;
|
||||
TileProvider* t2 = nullptr;
|
||||
TileProvider* future = nullptr;
|
||||
float factor = 1.f;
|
||||
GLuint vaoQuad = 0;
|
||||
GLuint vboQuad = 0;
|
||||
GLuint fbo = 0;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> shaderProgram;
|
||||
std::unique_ptr<ghoul::opengl::Texture> colormap;
|
||||
};
|
||||
|
||||
DefaultTileProvider createTileProvider(std::string_view timekey) const;
|
||||
DefaultTileProvider* retrieveTileProvider(const Time& t);
|
||||
|
||||
template <Mode mode, bool interpolation>
|
||||
TileProvider* tileProvider(const Time& time);
|
||||
|
||||
TileProvider* tileProvider(const Time& time);
|
||||
|
||||
Mode _mode;
|
||||
|
||||
struct {
|
||||
double startTimeJ2000 = 0.0;
|
||||
double endTimeJ2000 = 0.0;
|
||||
|
||||
std::string temporalResolution;
|
||||
std::string timeFormat;
|
||||
TimeQuantizer timeQuantizer;
|
||||
std::string prototype;
|
||||
} _prototyped;
|
||||
|
||||
struct {
|
||||
std::filesystem::path folder;
|
||||
std::string format;
|
||||
|
||||
std::vector<std::pair<double, std::string>> files;
|
||||
} _folder;
|
||||
|
||||
ghoul::Dictionary _initDict;
|
||||
properties::BoolProperty _useFixedTime;
|
||||
properties::StringProperty _fixedTime;
|
||||
bool _fixedTimeDirty = true;
|
||||
|
||||
TileProvider* _currentTileProvider = nullptr;
|
||||
std::unordered_map<double, DefaultTileProvider> _tileProviderMap;
|
||||
|
||||
bool _isInterpolating = false;
|
||||
|
||||
std::string _colormap;
|
||||
std::unique_ptr<InterpolateTileProvider> _interpolateTileProvider;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__TEMPORALTILEPROVIDER___H__
|
||||
109
modules/globebrowsing/src/tileprovider/texttileprovider.cpp
Normal file
109
modules/globebrowsing/src/tileprovider/texttileprovider.cpp
Normal file
@@ -0,0 +1,109 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2022 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/globebrowsing/src/tileprovider/texttileprovider.h>
|
||||
|
||||
#include <modules/globebrowsing/globebrowsingmodule.h>
|
||||
#include <modules/globebrowsing/src/memoryawaretilecache.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <ghoul/font/fontmanager.h>
|
||||
#include <ghoul/font/fontrenderer.h>
|
||||
#include <ghoul/opengl/openglstatecache.h>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
TextTileProvider::TextTileProvider(TileTextureInitData initData_, size_t fontSize_)
|
||||
: initData(std::move(initData_))
|
||||
, fontSize(fontSize_)
|
||||
{
|
||||
ZoneScoped
|
||||
|
||||
tileCache = global::moduleEngine->module<GlobeBrowsingModule>()->tileCache();
|
||||
}
|
||||
|
||||
TextTileProvider::~TextTileProvider() {}
|
||||
|
||||
void TextTileProvider::internalInitialize() {
|
||||
ZoneScoped
|
||||
|
||||
font = global::fontManager->font("Mono", static_cast<float>(fontSize));
|
||||
fontRenderer = ghoul::fontrendering::FontRenderer::createDefault();
|
||||
fontRenderer->setFramebufferSize(glm::vec2(initData.dimensions));
|
||||
glGenFramebuffers(1, &fbo);
|
||||
}
|
||||
|
||||
void TextTileProvider::internalDeinitialize() {
|
||||
glDeleteFramebuffers(1, &fbo);
|
||||
}
|
||||
|
||||
Tile TextTileProvider::renderTile(const TileIndex& tileIndex, const std::string& text,
|
||||
const glm::vec2& position, const glm::vec4& color)
|
||||
{
|
||||
ZoneScoped
|
||||
TracyGpuZone("tile")
|
||||
|
||||
cache::ProviderTileKey key = { tileIndex, uniqueIdentifier };
|
||||
Tile tile = tileCache->get(key);
|
||||
if (!tile.texture) {
|
||||
ghoul::opengl::Texture* texture = tileCache->texture(initData);
|
||||
|
||||
// Keep track of defaultFBO and viewport to be able to reset state when done
|
||||
GLint defaultFBO = global::renderEngine->openglStateCache().defaultFramebuffer();
|
||||
|
||||
// Render to texture
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
glFramebufferTexture2D(
|
||||
GL_FRAMEBUFFER,
|
||||
GL_COLOR_ATTACHMENT0,
|
||||
GL_TEXTURE_2D,
|
||||
*texture,
|
||||
0
|
||||
);
|
||||
|
||||
GLsizei w = static_cast<GLsizei>(texture->width());
|
||||
GLsizei h = static_cast<GLsizei>(texture->height());
|
||||
glViewport(0, 0, w, h);
|
||||
glClearColor(0.f, 0.f, 0.f, 0.f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
fontRenderer->render(*font, position, text, color);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO);
|
||||
global::renderEngine->openglStateCache().resetViewportState();
|
||||
|
||||
tile = Tile{ texture, std::nullopt, Tile::Status::OK };
|
||||
tileCache->put(key, initData.hashKey, tile);
|
||||
}
|
||||
return tile;
|
||||
}
|
||||
|
||||
void TextTileProvider::reset() {
|
||||
ZoneScoped
|
||||
|
||||
tileCache->clear();
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
60
modules/globebrowsing/src/tileprovider/texttileprovider.h
Normal file
60
modules/globebrowsing/src/tileprovider/texttileprovider.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2022 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__TEXTTILEPROVIDER___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__TEXTTILEPROVIDER___H__
|
||||
|
||||
#include <modules/globebrowsing/src/tileprovider/tileprovider.h>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
class TextTileProvider : public TileProvider {
|
||||
public:
|
||||
TextTileProvider(TileTextureInitData initData, size_t fontSize = 48);
|
||||
virtual ~TextTileProvider();
|
||||
|
||||
void reset() override;
|
||||
|
||||
protected:
|
||||
Tile renderTile(const TileIndex& tileIndex, const std::string& text,
|
||||
const glm::vec2& position, const glm::vec4& color);
|
||||
|
||||
const TileTextureInitData initData;
|
||||
|
||||
std::unique_ptr<ghoul::fontrendering::FontRenderer> fontRenderer;
|
||||
std::shared_ptr<ghoul::fontrendering::Font> font;
|
||||
size_t fontSize = 0;
|
||||
|
||||
GLuint fbo = 0;
|
||||
|
||||
cache::MemoryAwareTileCache* tileCache;
|
||||
|
||||
private:
|
||||
void internalInitialize() override final;
|
||||
void internalDeinitialize() override final;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__TEXTTILEPROVIDER___H__
|
||||
@@ -0,0 +1,65 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2022 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/globebrowsing/src/tileprovider/tileindextileprovider.h>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
TileIndexTileProvider::TileIndexTileProvider(const ghoul::Dictionary&)
|
||||
: TextTileProvider(tileTextureInitData(layergroupid::GroupID::ColorLayers, false))
|
||||
{}
|
||||
|
||||
Tile TileIndexTileProvider::tile(const TileIndex& tileIndex) {
|
||||
ZoneScoped
|
||||
std::string text = fmt::format(
|
||||
"level: {}\nx: {}\ny: {}", tileIndex.level, tileIndex.x, tileIndex.y
|
||||
);
|
||||
glm::vec2 textPosition = glm::vec2(
|
||||
initData.dimensions.x / 4 -
|
||||
(initData.dimensions.x / 32) * log10(1 << tileIndex.level),
|
||||
initData.dimensions.y / 2 + fontSize
|
||||
);
|
||||
|
||||
return TextTileProvider::renderTile(tileIndex, text, textPosition, glm::vec4(1.f));
|
||||
}
|
||||
|
||||
Tile::Status TileIndexTileProvider::tileStatus(const TileIndex&) {
|
||||
return Tile::Status::OK;
|
||||
}
|
||||
|
||||
TileDepthTransform TileIndexTileProvider::depthTransform() {
|
||||
return { 0.f, 1.f };
|
||||
}
|
||||
|
||||
void TileIndexTileProvider::update() {}
|
||||
|
||||
int TileIndexTileProvider::maxLevel() {
|
||||
return 1337; // unlimited
|
||||
}
|
||||
|
||||
float TileIndexTileProvider::noDataValueAsFloat() {
|
||||
return std::numeric_limits<float>::min();
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
@@ -22,14 +22,25 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include "catch2/catch.hpp"
|
||||
#ifndef __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__TILEINDEXTILEPROVIDER___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__TILEINDEXTILEPROVIDER___H__
|
||||
|
||||
#include <modules/globebrowsing/src/tileprovider.h>
|
||||
#include <openspace/util/time.h>
|
||||
#include <glm/glm.hpp>
|
||||
#include <modules/globebrowsing/src/tileprovider/texttileprovider.h>
|
||||
|
||||
namespace {
|
||||
constexpr const char* fileName = "data/scene/debugglobe/map_service_configs/"
|
||||
"VIIRS_SNPP_CorrectedReflectance_TrueColor_temporal.xml";
|
||||
} // namespace
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
class TileIndexTileProvider : public TextTileProvider {
|
||||
public:
|
||||
TileIndexTileProvider(const ghoul::Dictionary& dictionary);
|
||||
|
||||
Tile tile(const TileIndex& tileIndex) override final;
|
||||
Tile::Status tileStatus(const TileIndex& index) override final;
|
||||
TileDepthTransform depthTransform() override final;
|
||||
void update() override final;
|
||||
int maxLevel() override final;
|
||||
float noDataValueAsFloat() override final;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__TILEINDEXTILEPROVIDER___H__
|
||||
238
modules/globebrowsing/src/tileprovider/tileprovider.cpp
Normal file
238
modules/globebrowsing/src/tileprovider/tileprovider.cpp
Normal file
@@ -0,0 +1,238 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2022 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/globebrowsing/src/tileprovider/tileprovider.h>
|
||||
|
||||
#include <modules/globebrowsing/globebrowsingmodule.h>
|
||||
#include <modules/globebrowsing/src/asynctiledataprovider.h>
|
||||
#include <modules/globebrowsing/src/geodeticpatch.h>
|
||||
#include <modules/globebrowsing/src/layermanager.h>
|
||||
#include <modules/globebrowsing/src/memoryawaretilecache.h>
|
||||
#include <modules/globebrowsing/src/rawtiledatareader.h>
|
||||
#include <modules/globebrowsing/src/tileprovider/defaulttileprovider.h>
|
||||
#include <modules/globebrowsing/src/tileprovider/imagesequencetileprovider.h>
|
||||
#include <modules/globebrowsing/src/tileprovider/singleimagetileprovider.h>
|
||||
#include <modules/globebrowsing/src/tileprovider/sizereferencetileprovider.h>
|
||||
#include <modules/globebrowsing/src/tileprovider/temporaltileprovider.h>
|
||||
#include <modules/globebrowsing/src/tileprovider/tileindextileprovider.h>
|
||||
#include <modules/globebrowsing/src/tileprovider/tileproviderbyindex.h>
|
||||
#include <modules/globebrowsing/src/tileprovider/tileproviderbylevel.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/util/factorymanager.h>
|
||||
#include <openspace/util/memorymanager.h>
|
||||
#include <openspace/util/spicemanager.h>
|
||||
#include <openspace/util/timemanager.h>
|
||||
#include <ghoul/filesystem/file.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/font/fontmanager.h>
|
||||
#include <ghoul/font/fontrenderer.h>
|
||||
#include <ghoul/io/texture/texturereader.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/misc/profiling.h>
|
||||
#include <ghoul/opengl/openglstatecache.h>
|
||||
#include <ghoul/opengl/textureunit.h>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include "cpl_minixml.h"
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
namespace {
|
||||
|
||||
std::unique_ptr<ghoul::opengl::Texture> DefaultTileTexture;
|
||||
Tile DefaultTile = Tile { nullptr, std::nullopt, Tile::Status::Unavailable };
|
||||
|
||||
constexpr const char* KeyFilePath = "FilePath";
|
||||
|
||||
} // namespace
|
||||
|
||||
unsigned int TileProvider::NumTileProviders = 0;
|
||||
|
||||
std::unique_ptr<TileProvider> TileProvider::createFromDictionary(
|
||||
layergroupid::TypeID layerTypeID,
|
||||
const ghoul::Dictionary& dictionary)
|
||||
{
|
||||
ZoneScoped
|
||||
|
||||
const char* type = layergroupid::LAYER_TYPE_NAMES[static_cast<int>(layerTypeID)];
|
||||
auto factory = FactoryManager::ref().factory<TileProvider>();
|
||||
TileProvider* result = factory->create(type, dictionary);
|
||||
return std::unique_ptr<TileProvider>(result);
|
||||
}
|
||||
|
||||
void TileProvider::initializeDefaultTile() {
|
||||
ZoneScoped
|
||||
|
||||
ghoul_assert(!DefaultTile.texture, "Default tile should not have been created");
|
||||
using namespace ghoul::opengl;
|
||||
|
||||
// Create pixel data
|
||||
TileTextureInitData initData(
|
||||
8,
|
||||
8,
|
||||
GL_UNSIGNED_BYTE,
|
||||
Texture::Format::RGBA,
|
||||
TileTextureInitData::PadTiles::No,
|
||||
TileTextureInitData::ShouldAllocateDataOnCPU::Yes
|
||||
);
|
||||
char* pixels = new char[initData.totalNumBytes];
|
||||
memset(pixels, 0, initData.totalNumBytes * sizeof(char));
|
||||
|
||||
// Create ghoul texture
|
||||
DefaultTileTexture = std::make_unique<Texture>(initData.dimensions, GL_TEXTURE_2D);
|
||||
DefaultTileTexture->setDataOwnership(Texture::TakeOwnership::Yes);
|
||||
DefaultTileTexture->setPixelData(pixels);
|
||||
DefaultTileTexture->uploadTexture();
|
||||
DefaultTileTexture->setFilter(ghoul::opengl::Texture::FilterMode::LinearMipMap);
|
||||
|
||||
// Create tile
|
||||
DefaultTile = Tile{ DefaultTileTexture.get(), std::nullopt, Tile::Status::OK };
|
||||
}
|
||||
|
||||
void TileProvider::deinitializeDefaultTile() {
|
||||
DefaultTileTexture = nullptr;
|
||||
}
|
||||
|
||||
TileProvider::TileProvider() : properties::PropertyOwner({ "TileProvider" }) {}
|
||||
|
||||
void TileProvider::initialize() {
|
||||
ZoneScoped
|
||||
|
||||
ghoul_assert(!isInitialized, "TileProvider can only be initialized once.");
|
||||
|
||||
if (TileProvider::NumTileProviders >
|
||||
static_cast<unsigned int>(std::numeric_limits<uint16_t>::max()) - 1)
|
||||
{
|
||||
LERRORC(
|
||||
"TileProvider",
|
||||
"Number of tile providers exceeds 65535. Something will break soon"
|
||||
);
|
||||
TileProvider::NumTileProviders = 0;
|
||||
}
|
||||
uniqueIdentifier = static_cast<uint16_t>(TileProvider::NumTileProviders++);
|
||||
if (TileProvider::NumTileProviders == std::numeric_limits<unsigned int>::max()) {
|
||||
--TileProvider::NumTileProviders;
|
||||
return;
|
||||
}
|
||||
|
||||
internalInitialize();
|
||||
isInitialized = true;
|
||||
}
|
||||
|
||||
void TileProvider::deinitialize() {
|
||||
ZoneScoped
|
||||
|
||||
internalDeinitialize();
|
||||
}
|
||||
|
||||
void TileProvider::internalInitialize() {}
|
||||
void TileProvider::internalDeinitialize() {}
|
||||
|
||||
ChunkTile TileProvider::chunkTile(TileIndex tileIndex, int parents, int maxParents) {
|
||||
ZoneScoped
|
||||
|
||||
ghoul_assert(isInitialized, "TileProvider was not initialized.");
|
||||
|
||||
auto ascendToParent = [](TileIndex& ti, TileUvTransform& uv) {
|
||||
uv.uvOffset *= 0.5;
|
||||
uv.uvScale *= 0.5;
|
||||
|
||||
uv.uvOffset += ti.positionRelativeParent();
|
||||
|
||||
ti.x /= 2;
|
||||
ti.y /= 2;
|
||||
ti.level--;
|
||||
};
|
||||
|
||||
TileUvTransform uvTransform = { glm::vec2(0.f, 0.f), glm::vec2(1.f, 1.f) };
|
||||
|
||||
// Step 1. Traverse 0 or more parents up the chunkTree as requested by the caller
|
||||
for (int i = 0; i < parents && tileIndex.level > 1; i++) {
|
||||
ascendToParent(tileIndex, uvTransform);
|
||||
}
|
||||
maxParents -= parents;
|
||||
|
||||
// Step 2. Traverse 0 or more parents up the chunkTree to make sure we're inside
|
||||
// the range of defined data.
|
||||
int maximumLevel = maxLevel();
|
||||
while (tileIndex.level > maximumLevel) {
|
||||
ascendToParent(tileIndex, uvTransform);
|
||||
maxParents--;
|
||||
}
|
||||
if (maxParents < 0) {
|
||||
return ChunkTile { Tile(), uvTransform, TileDepthTransform() };
|
||||
}
|
||||
|
||||
// Step 3. Traverse 0 or more parents up the chunkTree until we find a chunk that
|
||||
// has a loaded tile ready to use.
|
||||
while (tileIndex.level > 1) {
|
||||
Tile t = tile(tileIndex);
|
||||
if (t.status != Tile::Status::OK) {
|
||||
if (--maxParents < 0) {
|
||||
return ChunkTile { Tile(), uvTransform, TileDepthTransform() };
|
||||
}
|
||||
ascendToParent(tileIndex, uvTransform);
|
||||
}
|
||||
else {
|
||||
return ChunkTile { std::move(t), uvTransform, TileDepthTransform() };
|
||||
}
|
||||
}
|
||||
|
||||
return ChunkTile { Tile(), uvTransform, TileDepthTransform() };
|
||||
}
|
||||
|
||||
ChunkTilePile TileProvider::chunkTilePile(TileIndex tileIndex, int pileSize) {
|
||||
ZoneScoped
|
||||
|
||||
ghoul_assert(isInitialized, "TileProvider was not initialized.");
|
||||
ghoul_assert(pileSize >= 0, "pileSize must be positive");
|
||||
|
||||
ChunkTilePile chunkTilePile;
|
||||
std::fill(chunkTilePile.begin(), chunkTilePile.end(), std::nullopt);
|
||||
for (int i = 0; i < pileSize; ++i) {
|
||||
chunkTilePile[i] = chunkTile(tileIndex, i);
|
||||
if (chunkTilePile[i]->tile.status == Tile::Status::Unavailable) {
|
||||
if (i == 0) {
|
||||
// First iteration
|
||||
chunkTilePile[i]->tile = DefaultTile;
|
||||
chunkTilePile[i]->uvTransform.uvOffset = { 0.f, 0.f };
|
||||
chunkTilePile[i]->uvTransform.uvScale = { 1.f, 1.f };
|
||||
}
|
||||
else {
|
||||
// We are iterating through the array one-by-one, so we are guaranteed
|
||||
// that for tile 'i', tile 'i-1' already was initializated
|
||||
chunkTilePile[i]->tile = chunkTilePile[i - 1]->tile;
|
||||
chunkTilePile[i]->uvTransform.uvOffset =
|
||||
chunkTilePile[i - 1]->uvTransform.uvOffset;
|
||||
chunkTilePile[i]->uvTransform.uvScale =
|
||||
chunkTilePile[i - 1]->uvTransform.uvScale;
|
||||
}
|
||||
}
|
||||
}
|
||||
return chunkTilePile;
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
145
modules/globebrowsing/src/tileprovider/tileprovider.h
Normal file
145
modules/globebrowsing/src/tileprovider/tileprovider.h
Normal file
@@ -0,0 +1,145 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2022 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__TILEPROVIDER___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__TILEPROVIDER___H__
|
||||
|
||||
#include <openspace/properties/propertyowner.h>
|
||||
|
||||
#include <modules/globebrowsing/src/basictypes.h>
|
||||
#include <modules/globebrowsing/src/ellipsoid.h>
|
||||
#include <modules/globebrowsing/src/layergroupid.h>
|
||||
#include <modules/globebrowsing/src/tileindex.h>
|
||||
#include <modules/globebrowsing/src/tiletextureinitdata.h>
|
||||
#include <modules/globebrowsing/src/timequantizer.h>
|
||||
#include <openspace/properties/stringproperty.h>
|
||||
#include <openspace/properties/scalar/boolproperty.h>
|
||||
#include <openspace/properties/scalar/intproperty.h>
|
||||
#include <unordered_map>
|
||||
#include <ghoul/opengl/programobject.h>
|
||||
|
||||
struct CPLXMLNode;
|
||||
|
||||
namespace ghoul::fontrendering {
|
||||
class Font;
|
||||
class FontRenderer;
|
||||
} // namespace ghoul::fontrendering
|
||||
|
||||
namespace openspace { class PixelBuffer; }
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
class AsyncTileDataProvider;
|
||||
struct RawTile;
|
||||
struct TileIndex;
|
||||
namespace cache { class MemoryAwareTileCache; }
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
enum class Type {
|
||||
DefaultTileProvider = 0,
|
||||
SingleImageTileProvider,
|
||||
ImageSequenceTileProvider,
|
||||
SizeReferenceTileProvider,
|
||||
TemporalTileProvider,
|
||||
TileIndexTileProvider,
|
||||
ByIndexTileProvider,
|
||||
ByLevelTileProvider,
|
||||
InterpolateTileProvider
|
||||
};
|
||||
|
||||
|
||||
struct TileProvider : public properties::PropertyOwner {
|
||||
static unsigned int NumTileProviders;
|
||||
|
||||
static std::unique_ptr<TileProvider> createFromDictionary(
|
||||
layergroupid::TypeID layerTypeID, const ghoul::Dictionary& dictionary);
|
||||
|
||||
static void initializeDefaultTile();
|
||||
static void deinitializeDefaultTile();
|
||||
|
||||
TileProvider();
|
||||
virtual ~TileProvider() = default;
|
||||
|
||||
void initialize();
|
||||
void deinitialize();
|
||||
|
||||
virtual Tile tile(const TileIndex& tileIndex) = 0;
|
||||
|
||||
/**
|
||||
* Returns the status of a <code>Tile</code>. The <code>Tile::Status</code>
|
||||
* corresponds the <code>Tile</code> that would be returned if the function
|
||||
* <code>tile</code> would be invoked with the same <code>TileIndex</code> argument at
|
||||
* this point in time.
|
||||
*/
|
||||
virtual Tile::Status tileStatus(const TileIndex& index) = 0;
|
||||
|
||||
/**
|
||||
* Get the associated depth transform for this TileProvider. This is necessary for
|
||||
* TileProviders serving height map data, in order to correcly map pixel values to
|
||||
* meters.
|
||||
*/
|
||||
virtual TileDepthTransform depthTransform() = 0;
|
||||
|
||||
/**
|
||||
* This method should be called once per frame. Here, TileProviders are given the
|
||||
* opportunity to update their internal state.
|
||||
*/
|
||||
virtual void update() = 0;
|
||||
|
||||
/**
|
||||
* Provides a uniform way of all TileProviders to reload or restore all of its
|
||||
* internal state. This is mainly useful for debugging purposes.
|
||||
*/
|
||||
virtual void reset() = 0;
|
||||
|
||||
/**
|
||||
* \return The maximum level as defined by <code>TileIndex</code> that this
|
||||
* TileProvider is able provide.
|
||||
*/
|
||||
virtual int maxLevel() = 0;
|
||||
|
||||
/**
|
||||
* \return the no data value for the dataset. Default is the minimum float value.
|
||||
*/
|
||||
virtual float noDataValueAsFloat() = 0;
|
||||
|
||||
|
||||
ChunkTile chunkTile(TileIndex tileIndex, int parents = 0, int maxParents = 1337);
|
||||
ChunkTilePile chunkTilePile(TileIndex tileIndex, int pileSize);
|
||||
|
||||
|
||||
std::string name;
|
||||
|
||||
uint16_t uniqueIdentifier = 0;
|
||||
bool isInitialized = false;
|
||||
|
||||
private:
|
||||
virtual void internalInitialize();
|
||||
virtual void internalDeinitialize();
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__TILEPROVIDER___H__
|
||||
140
modules/globebrowsing/src/tileprovider/tileproviderbyindex.cpp
Normal file
140
modules/globebrowsing/src/tileprovider/tileproviderbyindex.cpp
Normal file
@@ -0,0 +1,140 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2022 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/globebrowsing/src/tileprovider/tileproviderbyindex.h>
|
||||
|
||||
#include <openspace/documentation/documentation.h>
|
||||
|
||||
namespace {
|
||||
constexpr const char* KeyDefaultProvider = "DefaultProvider";
|
||||
constexpr const char* KeyProviders = "IndexTileProviders";
|
||||
constexpr const char* KeyTileIndex = "TileIndex";
|
||||
constexpr const char* KeyTileProvider = "TileProvider";
|
||||
|
||||
struct [[codegen::Dictionary(TileProviderByIndex)]] Parameters {
|
||||
ghoul::Dictionary defaultProvider;
|
||||
|
||||
struct IndexProvider {
|
||||
struct Index {
|
||||
int x [[codegen::greaterequal(0)]];
|
||||
int y [[codegen::greaterequal(0)]];
|
||||
int level [[codegen::inrange(0, 255)]];
|
||||
};
|
||||
Index tileIndex;
|
||||
ghoul::Dictionary tileProvider;
|
||||
};
|
||||
std::vector<IndexProvider> indexTileProviders;
|
||||
};
|
||||
#include "tileproviderbyindex_codegen.cpp"
|
||||
} // namespace
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
TileProviderByIndex::TileProviderByIndex(const ghoul::Dictionary& dictionary) {
|
||||
ZoneScoped
|
||||
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
layergroupid::TypeID typeID = layergroupid::TypeID::DefaultTileLayer;
|
||||
if (p.defaultProvider.hasValue<std::string>("Type")) {
|
||||
std::string type = p.defaultProvider.value<std::string>("Type");
|
||||
typeID = ghoul::from_string<layergroupid::TypeID>(type);
|
||||
|
||||
if (typeID == layergroupid::TypeID::Unknown) {
|
||||
throw ghoul::RuntimeError("Unknown layer type: " + type);
|
||||
}
|
||||
}
|
||||
|
||||
_defaultTileProvider = createFromDictionary(typeID, p.defaultProvider);
|
||||
|
||||
for (const Parameters::IndexProvider& ip : p.indexTileProviders) {
|
||||
const TileIndex tileIndex(
|
||||
ip.tileIndex.x,
|
||||
ip.tileIndex.y,
|
||||
static_cast<uint8_t>(ip.tileIndex.level)
|
||||
);
|
||||
|
||||
layergroupid::TypeID providerTypeID = layergroupid::TypeID::DefaultTileLayer;
|
||||
if (ip.tileProvider.hasValue<std::string>("Type")) {
|
||||
std::string type = ip.tileProvider.value<std::string>("Type");
|
||||
providerTypeID = ghoul::from_string<layergroupid::TypeID>(type);
|
||||
|
||||
if (providerTypeID == layergroupid::TypeID::Unknown) {
|
||||
throw ghoul::RuntimeError("Unknown layer type: " + type);
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<TileProvider> stp = createFromDictionary(
|
||||
providerTypeID,
|
||||
ip.tileProvider
|
||||
);
|
||||
TileIndex::TileHashKey key = tileIndex.hashKey();
|
||||
_providers.insert(std::make_pair(key, std::move(stp)));
|
||||
}
|
||||
}
|
||||
|
||||
Tile TileProviderByIndex::tile(const TileIndex& tileIndex) {
|
||||
ZoneScoped
|
||||
const auto it = _providers.find(tileIndex.hashKey());
|
||||
const bool hasProvider = it != _providers.end();
|
||||
return hasProvider ? it->second->tile(tileIndex) : Tile();
|
||||
}
|
||||
|
||||
Tile::Status TileProviderByIndex::tileStatus(const TileIndex& index) {
|
||||
const auto it = _providers.find(index.hashKey());
|
||||
const bool hasProvider = it != _providers.end();
|
||||
return hasProvider ? it->second->tileStatus(index) : Tile::Status::Unavailable;
|
||||
}
|
||||
|
||||
TileDepthTransform TileProviderByIndex::depthTransform() {
|
||||
return _defaultTileProvider->depthTransform();
|
||||
}
|
||||
|
||||
void TileProviderByIndex::update() {
|
||||
using K = TileIndex::TileHashKey;
|
||||
using V = std::unique_ptr<TileProvider>;
|
||||
for (std::pair<const K, V>& it : _providers) {
|
||||
it.second->update();
|
||||
}
|
||||
_defaultTileProvider->update();
|
||||
}
|
||||
|
||||
void TileProviderByIndex::reset() {
|
||||
using K = TileIndex::TileHashKey;
|
||||
using V = std::unique_ptr<TileProvider>;
|
||||
for (std::pair<const K, V>& it : _providers) {
|
||||
it.second->reset();
|
||||
}
|
||||
_defaultTileProvider->reset();
|
||||
}
|
||||
|
||||
int TileProviderByIndex::maxLevel() {
|
||||
return _defaultTileProvider->maxLevel();
|
||||
}
|
||||
|
||||
float TileProviderByIndex::noDataValueAsFloat() {
|
||||
return std::numeric_limits<float>::min();
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
51
modules/globebrowsing/src/tileprovider/tileproviderbyindex.h
Normal file
51
modules/globebrowsing/src/tileprovider/tileproviderbyindex.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2022 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__TILEPROVIDERBYINDEX___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__TILEPROVIDERBYINDEX___H__
|
||||
|
||||
#include <modules/globebrowsing/src/tileprovider/tileprovider.h>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
class TileProviderByIndex : public TileProvider {
|
||||
public:
|
||||
TileProviderByIndex(const ghoul::Dictionary& dictionary);
|
||||
|
||||
Tile tile(const TileIndex& tileIndex) override final;
|
||||
Tile::Status tileStatus(const TileIndex& index) override final;
|
||||
TileDepthTransform depthTransform() override final;
|
||||
void update() override final;
|
||||
void reset() override final;
|
||||
int maxLevel() override final;
|
||||
float noDataValueAsFloat() override final;
|
||||
|
||||
private:
|
||||
std::unordered_map<TileIndex::TileHashKey, std::unique_ptr<TileProvider>> _providers;
|
||||
std::unique_ptr<TileProvider> _defaultTileProvider;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__TILEPROVIDERBYINDEX___H__
|
||||
161
modules/globebrowsing/src/tileprovider/tileproviderbylevel.cpp
Normal file
161
modules/globebrowsing/src/tileprovider/tileproviderbylevel.cpp
Normal file
@@ -0,0 +1,161 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2022 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <modules/globebrowsing/src/tileprovider/tileproviderbylevel.h>
|
||||
|
||||
#include <openspace/documentation/documentation.h>
|
||||
|
||||
namespace {
|
||||
struct [[codegen::Dictionary(TileProviderByLevel)]] Parameters {
|
||||
int layerGroupID;
|
||||
|
||||
struct Providers {
|
||||
int maxLevel [[codegen::greaterequal(0)]];
|
||||
ghoul::Dictionary tileProvider;
|
||||
};
|
||||
std::vector<Providers> levelTileProviders;
|
||||
};
|
||||
#include "tileproviderbylevel_codegen.cpp"
|
||||
} // namespace
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
TileProviderByLevel::TileProviderByLevel(const ghoul::Dictionary& dictionary) {
|
||||
ZoneScoped
|
||||
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
layergroupid::GroupID layerGroup = static_cast<layergroupid::GroupID>(p.layerGroupID);
|
||||
|
||||
for (Parameters::Providers p : p.levelTileProviders) {
|
||||
p.tileProvider.setValue("LayerGroupID", static_cast<int>(layerGroup));
|
||||
|
||||
layergroupid::TypeID typeID = layergroupid::TypeID::DefaultTileLayer;
|
||||
if (p.tileProvider.hasValue<std::string>("Type")) {
|
||||
std::string type = p.tileProvider.value<std::string>("Type");
|
||||
typeID = ghoul::from_string<layergroupid::TypeID>(type);
|
||||
|
||||
if (typeID == layergroupid::TypeID::Unknown) {
|
||||
throw ghoul::RuntimeError("Unknown layer type: " + type);
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<TileProvider> tp = createFromDictionary(typeID, p.tileProvider);
|
||||
|
||||
std::string provId = p.tileProvider.value<std::string>("Identifier");
|
||||
tp->setIdentifier(provId);
|
||||
std::string providerName = p.tileProvider.value<std::string>("Name");
|
||||
tp->setGuiName(providerName);
|
||||
addPropertySubOwner(tp.get());
|
||||
|
||||
_levelTileProviders.push_back(std::move(tp));
|
||||
|
||||
// Ensure we can represent the max level
|
||||
if (static_cast<int>(_providerIndices.size()) < p.maxLevel) {
|
||||
_providerIndices.resize(p.maxLevel + 1, -1);
|
||||
}
|
||||
|
||||
// map this level to the tile provider index
|
||||
_providerIndices[p.maxLevel] = static_cast<int>(_levelTileProviders.size()) - 1;
|
||||
}
|
||||
|
||||
// Fill in the gaps (value -1 ) in provider indices, from back to end
|
||||
for (int i = static_cast<int>(_providerIndices.size()) - 2; i >= 0; --i) {
|
||||
if (_providerIndices[i] == -1) {
|
||||
_providerIndices[i] = _providerIndices[i + 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TileProviderByLevel::internalInitialize() {
|
||||
for (const std::unique_ptr<TileProvider>& prov : _levelTileProviders) {
|
||||
prov->initialize();
|
||||
}
|
||||
}
|
||||
|
||||
void TileProviderByLevel::internalDeinitialize() {
|
||||
for (const std::unique_ptr<TileProvider>& prov : _levelTileProviders) {
|
||||
prov->deinitialize();
|
||||
}
|
||||
}
|
||||
|
||||
Tile TileProviderByLevel::tile(const TileIndex& tileIndex) {
|
||||
ZoneScoped
|
||||
|
||||
TileProvider* provider = levelProvider(tileIndex.level);
|
||||
if (provider) {
|
||||
return provider->tile(tileIndex);
|
||||
}
|
||||
else {
|
||||
return Tile();
|
||||
}
|
||||
}
|
||||
|
||||
Tile::Status TileProviderByLevel::tileStatus(const TileIndex& index) {
|
||||
TileProvider* provider = levelProvider(index.level);
|
||||
return provider ? provider->tileStatus(index) : Tile::Status::Unavailable;
|
||||
}
|
||||
|
||||
TileProvider* TileProviderByLevel::levelProvider(int level) const {
|
||||
ZoneScoped
|
||||
|
||||
if (!_levelTileProviders.empty()) {
|
||||
int clampedLevel = glm::clamp(
|
||||
level,
|
||||
0,
|
||||
static_cast<int>(_providerIndices.size() - 1)
|
||||
);
|
||||
int idx = _providerIndices[clampedLevel];
|
||||
return _levelTileProviders[idx].get();
|
||||
}
|
||||
else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
TileDepthTransform TileProviderByLevel::depthTransform() {
|
||||
return { 0.f, 1.f };
|
||||
}
|
||||
|
||||
void TileProviderByLevel::update() {
|
||||
for (const std::unique_ptr<TileProvider>& provider : _levelTileProviders) {
|
||||
provider->update();
|
||||
}
|
||||
}
|
||||
|
||||
void TileProviderByLevel::reset() {
|
||||
for (const std::unique_ptr<TileProvider>& provider : _levelTileProviders) {
|
||||
provider->reset();
|
||||
}
|
||||
}
|
||||
|
||||
int TileProviderByLevel::maxLevel() {
|
||||
return static_cast<int>(_providerIndices.size() - 1);
|
||||
}
|
||||
|
||||
float TileProviderByLevel::noDataValueAsFloat() {
|
||||
return std::numeric_limits<float>::min();
|
||||
}
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
55
modules/globebrowsing/src/tileprovider/tileproviderbylevel.h
Normal file
55
modules/globebrowsing/src/tileprovider/tileproviderbylevel.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2022 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__TILEPROVIDERBYLEVEL___H__
|
||||
#define __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__TILEPROVIDERBYLEVEL___H__
|
||||
|
||||
#include <modules/globebrowsing/src/tileprovider/tileprovider.h>
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
class TileProviderByLevel : public TileProvider {
|
||||
public:
|
||||
TileProviderByLevel(const ghoul::Dictionary& dictionary);
|
||||
|
||||
Tile tile(const TileIndex& tileIndex) override final;
|
||||
Tile::Status tileStatus(const TileIndex& index) override final;
|
||||
TileDepthTransform depthTransform() override final;
|
||||
void update() override final;
|
||||
void reset() override final;
|
||||
int maxLevel() override final;
|
||||
float noDataValueAsFloat() override final;
|
||||
|
||||
private:
|
||||
std::vector<int> _providerIndices;
|
||||
std::vector<std::unique_ptr<TileProvider>> _levelTileProviders;
|
||||
|
||||
void internalInitialize() override final;
|
||||
void internalDeinitialize() override final;
|
||||
TileProvider* levelProvider(int level) const;
|
||||
};
|
||||
|
||||
} // namespace openspace::globebrowsing
|
||||
|
||||
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___TILEPROVIDER__TILEPROVIDERBYLEVEL___H__
|
||||
@@ -73,7 +73,7 @@ namespace {
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation RenderableCrawlingLine::Documentation() {
|
||||
return codegen::doc<Parameters>("newhorizons_renderable_crawlingline");
|
||||
return codegen::doc<Parameters>("spacecraftinstruments_renderablecrawlingline");
|
||||
}
|
||||
|
||||
RenderableCrawlingLine::RenderableCrawlingLine(const ghoul::Dictionary& dictionary)
|
||||
|
||||
@@ -196,7 +196,7 @@ namespace {
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation RenderableFov::Documentation() {
|
||||
return codegen::doc<Parameters>("newhorizons_renderable_fieldofview");
|
||||
return codegen::doc<Parameters>("spacecraftinstruments_renderablefieldofview");
|
||||
}
|
||||
|
||||
RenderableFov::RenderableFov(const ghoul::Dictionary& dictionary)
|
||||
|
||||
@@ -90,7 +90,7 @@ namespace {
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation RenderableModelProjection::Documentation() {
|
||||
return codegen::doc<Parameters>("newhorizons_renderable_modelprojection");
|
||||
return codegen::doc<Parameters>("spacecraftinstruments_renderablemodelprojection");
|
||||
}
|
||||
|
||||
RenderableModelProjection::RenderableModelProjection(const ghoul::Dictionary& dictionary)
|
||||
|
||||
@@ -45,6 +45,7 @@ namespace {
|
||||
constexpr const char* _loggerCat = "RenderablePlaneProjection";
|
||||
constexpr const char* GalacticFrame = "GALACTIC";
|
||||
|
||||
// @TODO (emmbr 2022-01-20) Add documentation
|
||||
struct [[codegen::Dictionary(RenderablePlaneProjection)]] Parameters {
|
||||
std::optional<std::string> spacecraft;
|
||||
std::optional<std::string> instrument;
|
||||
@@ -58,6 +59,10 @@ namespace {
|
||||
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation RenderablePlaneProjection::Documentation() {
|
||||
return codegen::doc<Parameters>("spacecraftinstruments_renderableorbitdisc");
|
||||
}
|
||||
|
||||
RenderablePlaneProjection::RenderablePlaneProjection(const ghoul::Dictionary& dict)
|
||||
: Renderable(dict)
|
||||
{
|
||||
|
||||
@@ -56,6 +56,8 @@ public:
|
||||
void render(const RenderData& data, RendererTasks& rendererTask) override;
|
||||
void update(const UpdateData& data) override;
|
||||
|
||||
static documentation::Documentation Documentation();
|
||||
|
||||
private:
|
||||
void loadTexture();
|
||||
void updatePlane(const Image& img, double currentTime);
|
||||
|
||||
@@ -162,7 +162,7 @@ namespace {
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation RenderablePlanetProjection::Documentation() {
|
||||
return codegen::doc<Parameters>("newhorizons_renderable_planetprojection");
|
||||
return codegen::doc<Parameters>("spacecraftinstruments_renderableplanetprojection");
|
||||
}
|
||||
|
||||
RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary& dict)
|
||||
|
||||
@@ -143,7 +143,7 @@ namespace {
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation RenderableShadowCylinder::Documentation() {
|
||||
return codegen::doc<Parameters>("newhorizons_renderable_shadowcylinder");
|
||||
return codegen::doc<Parameters>("spacecraftinstruments_renderableshadowcylinder");
|
||||
}
|
||||
|
||||
RenderableShadowCylinder::RenderableShadowCylinder(const ghoul::Dictionary& dictionary)
|
||||
|
||||
@@ -61,12 +61,12 @@ void SpacecraftInstrumentsModule::internalInitialize(const ghoul::Dictionary&) {
|
||||
auto fRenderable = FactoryManager::ref().factory<Renderable>();
|
||||
ghoul_assert(fRenderable, "No renderable factory existed");
|
||||
|
||||
fRenderable->registerClass<RenderableShadowCylinder>("RenderableShadowCylinder");
|
||||
fRenderable->registerClass<RenderableCrawlingLine>("RenderableCrawlingLine");
|
||||
fRenderable->registerClass<RenderableFov>("RenderableFov");
|
||||
fRenderable->registerClass<RenderableModelProjection>("RenderableModelProjection");
|
||||
fRenderable->registerClass<RenderablePlaneProjection>("RenderablePlaneProjection");
|
||||
fRenderable->registerClass<RenderablePlanetProjection>("RenderablePlanetProjection");
|
||||
fRenderable->registerClass<RenderableModelProjection>("RenderableModelProjection");
|
||||
fRenderable->registerClass<RenderableShadowCylinder>("RenderableShadowCylinder");
|
||||
|
||||
auto fDecoder = FactoryManager::ref().factory<Decoder>();
|
||||
fDecoder->registerClass<InstrumentDecoder>("Instrument");
|
||||
@@ -85,9 +85,12 @@ std::vector<documentation::Documentation>
|
||||
SpacecraftInstrumentsModule::documentations() const
|
||||
{
|
||||
return {
|
||||
RenderableCrawlingLine::Documentation(),
|
||||
RenderableFov::Documentation(),
|
||||
RenderableModelProjection::Documentation(),
|
||||
RenderablePlaneProjection::Documentation(),
|
||||
RenderablePlanetProjection::Documentation(),
|
||||
RenderableShadowCylinder::Documentation(),
|
||||
ProjectionComponent::Documentation()
|
||||
};
|
||||
}
|
||||
|
||||
@@ -162,7 +162,7 @@ namespace {
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation ProjectionComponent::Documentation() {
|
||||
return codegen::doc<Parameters>("newhorizons_projectioncomponent");
|
||||
return codegen::doc<Parameters>("spacecraftinstruments_projectioncomponent");
|
||||
}
|
||||
|
||||
ProjectionComponent::ProjectionComponent()
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
|
||||
namespace {
|
||||
constexpr const char* _loggerCat = "Renderable ToyVolume";
|
||||
constexpr const char* _loggerCat = "RenderableToyVolume";
|
||||
constexpr openspace::properties::Property::PropertyInfo SizeInfo = {
|
||||
"Size",
|
||||
"Size",
|
||||
|
||||
@@ -134,24 +134,33 @@ namespace {
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo FollowAnchorNodeInfo = {
|
||||
"FollowAnchorNodeRotation",
|
||||
"Follow Anchor Node Rotation",
|
||||
"If true, the camera will rotate with the current achor node if within a "
|
||||
"certain distance from it. When this happens, the object will appear fixed in "
|
||||
"relation to the camera. The distance at which the change happens is controlled "
|
||||
"through another property."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo
|
||||
FollowAnchorNodeDistanceInfo = {
|
||||
"FollowAnchorNodeRotationDistance",
|
||||
"Follow anchor node rotation distance",
|
||||
"Follow Anchor Node Rotation Distance",
|
||||
"A factor used to determine the distance at which the camera starts rotating "
|
||||
"with the anchor node. When this happends, a the object will appear fixed in "
|
||||
"relation to the camera. The actual distance will be computed by multiplying "
|
||||
"with the anchor node. The actual distance will be computed by multiplying "
|
||||
"this factor with the approximate radius of the node."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo MinimumDistanceInfo = {
|
||||
"MinimumAllowedDistance",
|
||||
"Minimum allowed distance",
|
||||
"Minimum Allowed Distance",
|
||||
"Limits how close the camera can get to an object. The distance is given in "
|
||||
"meters above the surface."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo VelocityZoomControlInfo = {
|
||||
"VelocityZoomControl",
|
||||
"Velocity zoom control",
|
||||
"Velocity Zoom Control",
|
||||
"Controls the velocity of the camera motion when zooming in to the focus node "
|
||||
"on a linear flight. The higher the value the faster the camera will move "
|
||||
"towards the focus."
|
||||
@@ -180,7 +189,7 @@ namespace {
|
||||
constexpr openspace::properties::Property::PropertyInfo
|
||||
StereoInterpolationTimeInfo = {
|
||||
"StereoInterpolationTime",
|
||||
"Stereo interpolation time",
|
||||
"Stereo Interpolation Time",
|
||||
"The time to interpolate to a new stereoscopic depth "
|
||||
"when the anchor node is changed, in seconds."
|
||||
};
|
||||
@@ -188,7 +197,7 @@ namespace {
|
||||
constexpr openspace::properties::Property::PropertyInfo
|
||||
RetargetInterpolationTimeInfo = {
|
||||
"RetargetAnchorInterpolationTime",
|
||||
"Retarget interpolation time",
|
||||
"Retarget Interpolation Time",
|
||||
"The time to interpolate the camera rotation "
|
||||
"when the anchor or aim node is changed, in seconds."
|
||||
};
|
||||
@@ -196,13 +205,13 @@ namespace {
|
||||
constexpr openspace::properties::Property::PropertyInfo
|
||||
FollowRotationInterpTimeInfo = {
|
||||
"FollowRotationInterpolationTime",
|
||||
"Follow rotation interpolation time",
|
||||
"Follow Rotation Interpolation Time",
|
||||
"The interpolation time when toggling following focus node rotation."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo InvertMouseButtons = {
|
||||
"InvertMouseButtons",
|
||||
"Invert left and right mouse buttons",
|
||||
"Invert Left and Right Mouse Buttons",
|
||||
"If this value is 'false', the left mouse button causes the camera to rotate "
|
||||
"around the object and the right mouse button causes the zooming motion. If this "
|
||||
"value is 'true', these two functionalities are reversed."
|
||||
@@ -229,7 +238,7 @@ namespace {
|
||||
constexpr openspace::properties::Property::PropertyInfo
|
||||
StereoscopicDepthOfFocusSurfaceInfo = {
|
||||
"StereoscopicDepthOfFocusSurface",
|
||||
"Stereoscopic depth of the surface in focus",
|
||||
"Stereoscopic Depth of the Surface in Focus",
|
||||
"Set the stereoscopically perceived distance (in meters) to the closest "
|
||||
"point out of the surface of the anchor and the center of the aim node. "
|
||||
"Only used if UseAdaptiveStereoscopicDepthInfo is set to true."
|
||||
@@ -331,7 +340,8 @@ OrbitalNavigator::OrbitalNavigator()
|
||||
, _aim(AimInfo)
|
||||
, _retargetAnchor(RetargetAnchorInfo)
|
||||
, _retargetAim(RetargetAimInfo)
|
||||
, _followAnchorNodeRotationDistance(FollowAnchorNodeInfo, 5.f, 0.f, 20.f)
|
||||
, _followAnchorNodeRotation(FollowAnchorNodeInfo, true)
|
||||
, _followAnchorNodeRotationDistance(FollowAnchorNodeDistanceInfo, 5.f, 0.f, 20.f)
|
||||
, _minimumAllowedDistance(MinimumDistanceInfo, 10.0f, 0.0f, 10000.f)
|
||||
, _mouseSensitivity(MouseSensitivityInfo, 15.f, 1.f, 50.f)
|
||||
, _joystickSensitivity(JoystickSensitivityInfo, 10.f, 1.0f, 50.f)
|
||||
@@ -491,6 +501,7 @@ OrbitalNavigator::OrbitalNavigator()
|
||||
addProperty(_aim);
|
||||
addProperty(_retargetAnchor);
|
||||
addProperty(_retargetAim);
|
||||
addProperty(_followAnchorNodeRotation);
|
||||
addProperty(_followAnchorNodeRotationDistance);
|
||||
addProperty(_minimumAllowedDistance);
|
||||
|
||||
@@ -954,7 +965,7 @@ void OrbitalNavigator::setRetargetInterpolationTime(float durationInSeconds) {
|
||||
|
||||
bool OrbitalNavigator::shouldFollowAnchorRotation(const glm::dvec3& cameraPosition) const
|
||||
{
|
||||
if (!_anchorNode) {
|
||||
if (!_anchorNode || !_followAnchorNodeRotation) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -466,7 +466,6 @@ Path createPathFromDictionary(const ghoul::Dictionary& dictionary, Path::Type ty
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
LERROR(fmt::format("Uknown camera path target type: {}", p.targetType));
|
||||
throw ghoul::MissingCaseException();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,7 +200,7 @@ void PathNavigator::updateCamera(double deltaTime) {
|
||||
|
||||
if (_currentPath->hasReachedEnd()) {
|
||||
LINFO("Reached end of path");
|
||||
_isPlaying = false;
|
||||
handlePathEnd();
|
||||
|
||||
if (_applyIdleBehaviorOnFinish) {
|
||||
constexpr const char* ApplyIdleBehaviorScript =
|
||||
@@ -263,10 +263,16 @@ void PathNavigator::startPath() {
|
||||
return;
|
||||
}
|
||||
|
||||
//OBS! Until we can handle simulation time: early out if not paused
|
||||
// Always pause the simulation time when flying, to aovid problem with objects
|
||||
// moving. However, keep track of whether the time was running before the path
|
||||
// was started, so we can reset it on finish
|
||||
if (!global::timeManager->isPaused()) {
|
||||
LERROR("Simulation time must be paused to run a camera path");
|
||||
return;
|
||||
global::timeManager->setPause(true);
|
||||
_startSimulationTimeOnFinish = true;
|
||||
LINFO(
|
||||
"Pausing time simulation during path traversal. "
|
||||
"Will unpause once the camera path is finished"
|
||||
);
|
||||
}
|
||||
|
||||
LINFO("Starting path");
|
||||
@@ -280,9 +286,7 @@ void PathNavigator::abortPath() {
|
||||
LWARNING("No camera path is playing");
|
||||
return;
|
||||
}
|
||||
_isPlaying = false;
|
||||
clearPath(); // TODO: instead of clearing this could be handled better
|
||||
|
||||
handlePathEnd();
|
||||
LINFO("Aborted camera path");
|
||||
}
|
||||
|
||||
@@ -329,6 +333,16 @@ const std::vector<SceneGraphNode*>& PathNavigator::relevantNodes() {
|
||||
return _relevantNodes;
|
||||
}
|
||||
|
||||
void PathNavigator::handlePathEnd() {
|
||||
_isPlaying = false;
|
||||
|
||||
if (_startSimulationTimeOnFinish) {
|
||||
global::timeManager->setPause(false);
|
||||
}
|
||||
_startSimulationTimeOnFinish = false;
|
||||
clearPath();
|
||||
}
|
||||
|
||||
void PathNavigator::findRelevantNodes() {
|
||||
const std::vector<SceneGraphNode*>& allNodes =
|
||||
global::renderEngine->scene()->allSceneGraphNodes();
|
||||
@@ -413,8 +427,8 @@ scripting::LuaLibrary PathNavigator::luaLibrary() {
|
||||
"Stops a path, if one is being played"
|
||||
},
|
||||
{
|
||||
"goTo",
|
||||
&luascriptfunctions::goTo,
|
||||
"flyTo",
|
||||
&luascriptfunctions::flyTo,
|
||||
"string [, bool, double]",
|
||||
"Move the camera to the node with the specified identifier. The optional "
|
||||
"double specifies the duration of the motion. If the optional bool is "
|
||||
@@ -422,8 +436,8 @@ scripting::LuaLibrary PathNavigator::luaLibrary() {
|
||||
"node. Either of the optional parameters can be left out."
|
||||
},
|
||||
{
|
||||
"goToHeight",
|
||||
&luascriptfunctions::goToHeight,
|
||||
"flyToHeight",
|
||||
&luascriptfunctions::flyToHeight,
|
||||
"string, double [, bool, double]",
|
||||
"Move the camera to the node with the specified identifier. The second "
|
||||
"argument is the desired target height above the target node's bounding "
|
||||
@@ -433,8 +447,8 @@ scripting::LuaLibrary PathNavigator::luaLibrary() {
|
||||
"parameters can be left out."
|
||||
},
|
||||
{
|
||||
"goToNavigationState",
|
||||
&luascriptfunctions::goToNavigationState,
|
||||
"flyToNavigationState",
|
||||
&luascriptfunctions::flyToNavigationState,
|
||||
"table, [double]",
|
||||
"Create a path to the navigation state described by the input table. "
|
||||
"The optional double specifies the target duration of the motion. Note "
|
||||
@@ -445,7 +459,7 @@ scripting::LuaLibrary PathNavigator::luaLibrary() {
|
||||
"createPath",
|
||||
&luascriptfunctions::createPath,
|
||||
"table",
|
||||
"Create the path as described by the lua table input argument"
|
||||
"Create a camera path as described by the lua table input argument"
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
@@ -68,8 +68,8 @@ int stopPath(lua_State* L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int goTo(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, { 1, 3 }, "lua::goTo");
|
||||
int flyTo(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, { 1, 3 }, "lua::flyTo");
|
||||
auto [nodeIdentifier, useUpFromTargetOrDuration, duration] = ghoul::lua::values<
|
||||
std::string, std::optional<std::variant<bool, double>>, std::optional<double>
|
||||
>(L);
|
||||
@@ -120,8 +120,8 @@ int goTo(lua_State* L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int goToHeight(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, { 2, 4 }, "lua::goToHeight");
|
||||
int flyToHeight(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, { 2, 4 }, "lua::flyToHeight");
|
||||
auto [nodeIdentifier, height, useUpFromTargetOrDuration, duration] =
|
||||
ghoul::lua::values<
|
||||
std::string, double, std::optional<std::variant<bool, double>>,
|
||||
@@ -169,8 +169,8 @@ int goToHeight(lua_State* L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int goToNavigationState(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, { 1, 2 }, "lua::goToNavigationState");
|
||||
int flyToNavigationState(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, { 1, 2 }, "lua::flyToNavigationState");
|
||||
auto [navigationState, duration] =
|
||||
ghoul::lua::values<ghoul::Dictionary, std::optional<double>>(L);
|
||||
|
||||
@@ -182,7 +182,7 @@ int goToNavigationState(lua_State* L) {
|
||||
);
|
||||
}
|
||||
catch (documentation::SpecificationError& e) {
|
||||
LERRORC("goToNavigationState", ghoul::to_string(e.result));
|
||||
LERRORC("flyToNavigationState", ghoul::to_string(e.result));
|
||||
return ghoul::lua::luaError(
|
||||
L, fmt::format("Unable to create a path: {}", e.what())
|
||||
);
|
||||
|
||||
@@ -130,6 +130,14 @@ namespace {
|
||||
"shown on the screen"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo ScreenshotWindowIdsInfo = {
|
||||
"ScreenshotWindowId",
|
||||
"Screenshow Window Ids",
|
||||
"The list of window identifiers whose screenshot will be taken the next time "
|
||||
"anyone triggers a screenshot. If this list is empty (the default), all windows "
|
||||
"will have their screenshot taken. Id's that do not exist are silently ignored."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo ApplyWarpingInfo = {
|
||||
"ApplyWarpingScreenshot",
|
||||
"Apply Warping to Screenshots",
|
||||
@@ -277,6 +285,7 @@ RenderEngine::RenderEngine()
|
||||
, _verticalLogOffset(VerticalLogOffsetInfo, 0.f, 0.f, 1.f)
|
||||
, _showVersionInfo(ShowVersionInfo, true)
|
||||
, _showCameraInfo(ShowCameraInfo, true)
|
||||
, _screenshotWindowIds(ScreenshotWindowIdsInfo)
|
||||
, _applyWarping(ApplyWarpingInfo, false)
|
||||
, _screenshotUseDate(ScreenshotUseDateInfo, false)
|
||||
, _showFrameInformation(ShowFrameNumberInfo, false)
|
||||
@@ -342,6 +351,7 @@ RenderEngine::RenderEngine()
|
||||
addProperty(_value);
|
||||
|
||||
addProperty(_globalBlackOutFactor);
|
||||
addProperty(_screenshotWindowIds);
|
||||
addProperty(_applyWarping);
|
||||
|
||||
_screenshotUseDate.onChange([this]() {
|
||||
@@ -1046,7 +1056,10 @@ void RenderEngine::takeScreenshot() {
|
||||
std::filesystem::create_directories(absPath("${SCREENSHOTS}"));
|
||||
}
|
||||
|
||||
_latestScreenshotNumber = global::windowDelegate->takeScreenshot(_applyWarping);
|
||||
_latestScreenshotNumber = global::windowDelegate->takeScreenshot(
|
||||
_applyWarping,
|
||||
_screenshotWindowIds
|
||||
);
|
||||
}
|
||||
|
||||
unsigned int RenderEngine::latestScreenshotNumber() const {
|
||||
|
||||
Submodule support/coding/codegen updated: 4bb5b66dae...425a0a224e
@@ -40,7 +40,6 @@ add_executable(
|
||||
test_rawvolumeio.cpp
|
||||
test_scriptscheduler.cpp
|
||||
test_spicemanager.cpp
|
||||
test_temporaltileprovider.cpp
|
||||
test_timequantizer.cpp
|
||||
test_timeline.cpp
|
||||
|
||||
|
||||
Reference in New Issue
Block a user