diff --git a/data/assets/base.asset b/data/assets/base.asset
index 73e2db77ab..6ef26ab294 100644
--- a/data/assets/base.asset
+++ b/data/assets/base.asset
@@ -63,6 +63,22 @@ local Keybindings = {
GuiPath = "/Rendering",
Local = false
},
+ {
+ Key = "l",
+ Name = "Turn on labels",
+ Command = "openspace.setPropertyValue('{solarsystem_labels}.Renderable.Enabled', true)",
+ Documentation = "Turns on visibility for all solar system labels",
+ GuiPath = "/Rendering",
+ Local = false
+ },
+ {
+ Key = "Shift+l",
+ Name = "Turn off labels",
+ Command = "openspace.setPropertyValue('{solarsystem_labels}.Renderable.Enabled', false)",
+ Documentation = "Turns off visibility for all solar system labels",
+ GuiPath = "/Rendering",
+ Local = false
+ }
}
asset.onInitialize(function ()
diff --git a/data/assets/default.scene b/data/assets/default.scene
index 4cdd560715..ab9d0de977 100644
--- a/data/assets/default.scene
+++ b/data/assets/default.scene
@@ -9,9 +9,9 @@ asset.onInitialize(function ()
openspace.globebrowsing.goToGeo("Earth", 58.5877, 16.1924, 20000000)
- openspace.markInterestingNodes({ "Saturn", "Mars", "Moon", "Sun", "Saturn" })
+ openspace.markInterestingNodes({ "Earth", "Mars", "Moon", "Sun"})
end)
asset.onDeinitialize(function ()
- openspace.removeInterestingNodes({ "Earth", "Mars", "Moon", "Sun", "Saturn" })
+ openspace.removeInterestingNodes({ "Earth", "Mars", "Moon", "Sun" })
end)
diff --git a/data/assets/scene/milkyway/milkyway/volume.asset b/data/assets/scene/milkyway/milkyway/volume.asset
index f4ad4a9385..2ae420e931 100644
--- a/data/assets/scene/milkyway/milkyway/volume.asset
+++ b/data/assets/scene/milkyway/milkyway/volume.asset
@@ -21,7 +21,7 @@ local MilkyWayVolumeGalaxy = {
-- The center of the Milky Way is approximately 8 kiloparsec from the Sun.
-- The x-axis of galactic coordinates points from the sun towards the center
-- of the galaxy.
- Position = {8 * kiloparsec, 0, 0}
+ Position = { 8 * kiloparsec, 0, 0 }
}
},
Renderable = {
@@ -29,12 +29,13 @@ local MilkyWayVolumeGalaxy = {
StepSize = 0.01,
AbsorptionMultiply = 200,
EmissionMultiply = 250,
- Rotation = {3.1415926, 3.1248, 4.45741},
+ Rotation = { 3.1415926, 3.1248, 4.45741 },
Volume = {
Type = "Volume",
Filename = data .. "/MilkyWayRGBAVolume1024x1024x128.raw",
- Dimensions = {1024, 1024, 128},
- Size = {1.2E21, 1.2E21, 0.15E21}
+ Dimensions = { 1024, 1024, 128 },
+ Size = { 1.2E21, 1.2E21, 0.15E21 },
+ Downscale = 0.4,
},
Points = {
Type = "Points",
diff --git a/data/assets/scene/solarsystem/dwarf_planets/pluto/pluto.asset b/data/assets/scene/solarsystem/dwarf_planets/pluto/pluto.asset
index 8d2b891b4b..db18a54cc1 100644
--- a/data/assets/scene/solarsystem/dwarf_planets/pluto/pluto.asset
+++ b/data/assets/scene/solarsystem/dwarf_planets/pluto/pluto.asset
@@ -59,6 +59,24 @@ local Pluto = {
}
}
+local PlutoLabel = {
+ Identifier = "PlutoLabel",
+ Parent = Pluto.Identifier,
+ Renderable = {
+ Enabled = true,
+ Type = "RenderableLabels",
+ LabelText = "Pluto",
+ FontSize = 100.0,
+ LabelSize = 8.9,
+ LabelMaxSize = 100.0,
+ LabelMinSize = 1.0,
+ BlendMode = "Additive",
+ LabelOrientationOption = "Camera View Direction"
+ },
+ GUI = {
+ Name = "Pluto Label",
+ Path = "/Solar System/Dwarf Planets/Pluto"
+ }
+}
-
-assetHelper.registerSceneGraphNodesAndExport(asset, { Pluto })
+assetHelper.registerSceneGraphNodesAndExport(asset, { Pluto, PlutoLabel })
diff --git a/data/assets/scene/solarsystem/planets.asset b/data/assets/scene/solarsystem/planets.asset
index 8603643031..a631b33339 100644
--- a/data/assets/scene/solarsystem/planets.asset
+++ b/data/assets/scene/solarsystem/planets.asset
@@ -1,6 +1,7 @@
asset.request('./planets/mercury/mercury')
asset.request('./planets/venus/venus')
+asset.request('./planets/venus/atmosphere')
asset.request('./planets/earth/earth')
asset.request('./planets/earth/atmosphere')
diff --git a/data/assets/scene/solarsystem/planets/earth/earth.asset b/data/assets/scene/solarsystem/planets/earth/earth.asset
index 44150fd439..aab7c67f07 100644
--- a/data/assets/scene/solarsystem/planets/earth/earth.asset
+++ b/data/assets/scene/solarsystem/planets/earth/earth.asset
@@ -1,7 +1,7 @@
local transforms = asset.require('./transforms')
local assetHelper = asset.require('util/asset_helper')
local texturesPath = asset.require('./earth_textures').TexturesPath
-local labelsPath = asset.require('./earth_labels').LabelsPath
+local labelsPath = asset.require('./earth_globelabels').LabelsPath
asset.request('./trail')
@@ -263,11 +263,6 @@ local Earth = {
}
--Caster2 = { Name = "Independency Day Ship", Radius = 0.0, }
},
- -- Shadows = {
- -- Enabled = true,
- -- DistanceFraction = 70.0,
- -- DepthMapSize = {7680.0, 4320.0}
- -- },
Labels = {
Enable = false,
FileName = labelsPath .. "/Earth.labels",
@@ -292,6 +287,45 @@ local Earth = {
}
}
+local EarthLabel = {
+ Identifier = "EarthLabel",
+ Parent = Earth.Identifier,
+ -- Transform = {
+ -- Translation = {
+ -- Type = "SpiceTranslation",
+ -- Target = "EARTH",
+ -- Observer = "EARTH BARYCENTER"
+ -- },
+ -- -- Rotation = {
+ -- -- Type = "SpiceRotation",
+ -- -- SourceFrame = "IAU_MOON",
+ -- -- DestinationFrame = "GALACTIC"
+ -- -- }
+ -- },
+ Renderable = {
+ Enabled = false,
+ Type = "RenderableLabels",
+ LabelText = "Earth",
+ FontSize = 100.0,
+ LabelSize = 8.6,
+ LabelMaxSize = 100.0,
+ LabelMinSize = 1.0,
+ LabelOrientationOption = "Camera View Direction",
+ BlendMode = "Additive",
+ EnableFading = true,
+ FadeStartUnit = "au",
+ FadeStartDistance = 1.5,
+ FadeStartSpeed = 1.0,
+ FadeEndUnit = "au",
+ FadeEndDistance = 15.0,
+ FadeEndSpeed = 25.0
+ },
+ Tag = { "solarsystem_labels" },
+ GUI = {
+ Name = "Earth Label",
+ Path = "/Solar System/Planets/Earth"
+ }
+}
-assetHelper.registerSceneGraphNodesAndExport(asset, { Earth })
+assetHelper.registerSceneGraphNodesAndExport(asset, { Earth, EarthLabel })
diff --git a/data/assets/scene/solarsystem/planets/earth/earth_labels.asset b/data/assets/scene/solarsystem/planets/earth/earth_globelabels.asset
similarity index 100%
rename from data/assets/scene/solarsystem/planets/earth/earth_labels.asset
rename to data/assets/scene/solarsystem/planets/earth/earth_globelabels.asset
diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/satellites_shared.asset b/data/assets/scene/solarsystem/planets/earth/satellites/satellites_shared.asset
index 58b3e35ec4..e5fde6d30c 100644
--- a/data/assets/scene/solarsystem/planets/earth/satellites/satellites_shared.asset
+++ b/data/assets/scene/solarsystem/planets/earth/satellites/satellites_shared.asset
@@ -56,7 +56,7 @@ local registerSatelliteGroupObjects = function(containingAsset, group, tleFolder
Renderable = {
Type = "RenderableSatellites",
Path = file,
- Segments = 160,
+ Segments = 120,
Color = color,
Fade = 0.5
},
diff --git a/data/assets/scene/solarsystem/planets/jupiter/callisto/callisto.asset b/data/assets/scene/solarsystem/planets/jupiter/callisto/callisto.asset
index 1a31062cd1..d0b2496e52 100644
--- a/data/assets/scene/solarsystem/planets/jupiter/callisto/callisto.asset
+++ b/data/assets/scene/solarsystem/planets/jupiter/callisto/callisto.asset
@@ -3,7 +3,7 @@ local assetHelper = asset.require('util/asset_helper')
asset.require("spice/base")
asset.request('./trail')
local kernel = asset.require('../kernels').jup310
-local labelsPath = asset.require('../jupiter_labels').LabelsPath
+local labelsPath = asset.require('../jupiter_globelabels').LabelsPath
diff --git a/data/assets/scene/solarsystem/planets/jupiter/europa/europa.asset b/data/assets/scene/solarsystem/planets/jupiter/europa/europa.asset
index 9ee299ebf6..d5e455bb9f 100644
--- a/data/assets/scene/solarsystem/planets/jupiter/europa/europa.asset
+++ b/data/assets/scene/solarsystem/planets/jupiter/europa/europa.asset
@@ -3,7 +3,7 @@ local assetHelper = asset.require('util/asset_helper')
asset.require("spice/base")
asset.request('./trail')
local kernel = asset.require('../kernels').jup310
-local labelsPath = asset.require('../jupiter_labels').LabelsPath
+local labelsPath = asset.require('../jupiter_globelabels').LabelsPath
local map_service_configs = asset.localResource("map_service_configs")
diff --git a/data/assets/scene/solarsystem/planets/jupiter/ganymede/ganymede.asset b/data/assets/scene/solarsystem/planets/jupiter/ganymede/ganymede.asset
index 510484cebf..513136ef98 100644
--- a/data/assets/scene/solarsystem/planets/jupiter/ganymede/ganymede.asset
+++ b/data/assets/scene/solarsystem/planets/jupiter/ganymede/ganymede.asset
@@ -3,7 +3,7 @@ local assetHelper = asset.require('util/asset_helper')
asset.require("spice/base")
asset.request('./trail')
local kernel = asset.require('../kernels').jup310
-local labelsPath = asset.require('../jupiter_labels').LabelsPath
+local labelsPath = asset.require('../jupiter_globelabels').LabelsPath
diff --git a/data/assets/scene/solarsystem/planets/jupiter/io/io.asset b/data/assets/scene/solarsystem/planets/jupiter/io/io.asset
index ca10670c06..fb10f0b3a8 100644
--- a/data/assets/scene/solarsystem/planets/jupiter/io/io.asset
+++ b/data/assets/scene/solarsystem/planets/jupiter/io/io.asset
@@ -3,7 +3,7 @@ local assetHelper = asset.require('util/asset_helper')
asset.require("spice/base")
asset.request('./trail')
local kernel = asset.require('../kernels').jup310
-local labelsPath = asset.require('../jupiter_labels').LabelsPath
+local labelsPath = asset.require('../jupiter_globelabels').LabelsPath
diff --git a/data/assets/scene/solarsystem/planets/jupiter/jupiter.asset b/data/assets/scene/solarsystem/planets/jupiter/jupiter.asset
index 9333c339c1..071a9cad9f 100644
--- a/data/assets/scene/solarsystem/planets/jupiter/jupiter.asset
+++ b/data/assets/scene/solarsystem/planets/jupiter/jupiter.asset
@@ -42,6 +42,25 @@ local Jupiter = {
}
}
+local JupiterLabel = {
+ Identifier = "JupiterLabel",
+ Parent = Jupiter.Identifier,
+ Renderable = {
+ Enabled = false,
+ Type = "RenderableLabels",
+ LabelText = "Jupiter",
+ FontSize = 100.0,
+ LabelSize = 8.6,
+ LabelMaxSize = 100.0,
+ LabelMinSize = 1.0,
+ LabelOrientationOption = "Camera View Direction",
+ BlendMode = "Additive"
+ },
+ Tag = { "solarsystem_labels" },
+ GUI = {
+ Name = "Jupiter Label",
+ Path = "/Solar System/Planets/Jupiter"
+ }
+}
-
-assetHelper.registerSceneGraphNodesAndExport(asset, { Jupiter })
+assetHelper.registerSceneGraphNodesAndExport(asset, { Jupiter, JupiterLabel })
diff --git a/data/assets/scene/solarsystem/planets/jupiter/jupiter_labels.asset b/data/assets/scene/solarsystem/planets/jupiter/jupiter_globelabels.asset
similarity index 100%
rename from data/assets/scene/solarsystem/planets/jupiter/jupiter_labels.asset
rename to data/assets/scene/solarsystem/planets/jupiter/jupiter_globelabels.asset
diff --git a/data/assets/scene/solarsystem/planets/mars/mars.asset b/data/assets/scene/solarsystem/planets/mars/mars.asset
index 57ee23d861..ee4da17e7d 100644
--- a/data/assets/scene/solarsystem/planets/mars/mars.asset
+++ b/data/assets/scene/solarsystem/planets/mars/mars.asset
@@ -2,7 +2,7 @@ local transforms = asset.require('./transforms')
local assetHelper = asset.require('util/asset_helper')
asset.require("spice/base")
asset.request('./trail')
-local labelsPath = asset.require('./mars_labels').LabelsPath
+local labelsPath = asset.require('./mars_globelabels').LabelsPath
@@ -187,4 +187,31 @@ local Mars = {
}
}
-assetHelper.registerSceneGraphNodesAndExport(asset, { Mars })
+local MarsLabel = {
+ Identifier = "MarsLabel",
+ Parent = Mars.Identifier,
+ Renderable = {
+ Enabled = false,
+ Type = "RenderableLabels",
+ LabelText = "Mars",
+ FontSize = 100.0,
+ LabelSize = 8.5,
+ LabelMaxSize = 100.0,
+ LabelMinSize = 1.0,
+ LabelOrientationOption = "Camera View Direction",
+ BlendMode = "Additive",
+ TransformationMatrix = {
+ 1.0, 0.0, 0.0, -8.0E6,
+ 0.0, 1.0, 0.0, 0.0,
+ 0.0, 0.0, 1.0, 1.0E7,
+ 0.0, 0.0, 0.0, 1.0
+ },
+ },
+ Tag = { "solarsystem_labels" },
+ GUI = {
+ Name = "Mars Label",
+ Path = "/Solar System/Planets/Mars"
+ }
+}
+
+assetHelper.registerSceneGraphNodesAndExport(asset, { Mars, MarsLabel })
diff --git a/data/assets/scene/solarsystem/planets/mars/mars_labels.asset b/data/assets/scene/solarsystem/planets/mars/mars_globelabels.asset
similarity index 100%
rename from data/assets/scene/solarsystem/planets/mars/mars_labels.asset
rename to data/assets/scene/solarsystem/planets/mars/mars_globelabels.asset
diff --git a/data/assets/scene/solarsystem/planets/mercury/mercury.asset b/data/assets/scene/solarsystem/planets/mercury/mercury.asset
index d2bcf7c591..8eda6c5eb9 100644
--- a/data/assets/scene/solarsystem/planets/mercury/mercury.asset
+++ b/data/assets/scene/solarsystem/planets/mercury/mercury.asset
@@ -1,6 +1,6 @@
local assetHelper = asset.require('util/asset_helper')
local transforms = asset.require('./transforms')
-local labelsPath = asset.require('./mercury_labels').LabelsPath
+local labelsPath = asset.require('./mercury_globelabels').LabelsPath
asset.require("spice/base")
@@ -223,5 +223,25 @@ local Mercury = {
}
}
+local MercuryLabel = {
+ Identifier = "MercuryLabel",
+ Parent = Mercury.Identifier,
+ Renderable = {
+ Enabled = false,
+ Type = "RenderableLabels",
+ LabelText = "Mercury",
+ FontSize = 100.0,
+ LabelSize = 8.3,
+ LabelMaxSize = 100.0,
+ LabelMinSize = 1.0,
+ LabelOrientationOption = "Camera View Direction",
+ BlendMode = "Additive"
+ },
+ Tag = { "solarsystem_labels" },
+ GUI = {
+ Name = "Mercury Label",
+ Path = "/Solar System/Planets/Mercury"
+ }
+}
-assetHelper.registerSceneGraphNodesAndExport(asset, { Mercury })
+assetHelper.registerSceneGraphNodesAndExport(asset, { Mercury, MercuryLabel })
diff --git a/data/assets/scene/solarsystem/planets/mercury/mercury_labels.asset b/data/assets/scene/solarsystem/planets/mercury/mercury_globelabels.asset
similarity index 100%
rename from data/assets/scene/solarsystem/planets/mercury/mercury_labels.asset
rename to data/assets/scene/solarsystem/planets/mercury/mercury_globelabels.asset
diff --git a/data/assets/scene/solarsystem/planets/neptune/neptune.asset b/data/assets/scene/solarsystem/planets/neptune/neptune.asset
index 677395e8e5..326b2ef6c0 100644
--- a/data/assets/scene/solarsystem/planets/neptune/neptune.asset
+++ b/data/assets/scene/solarsystem/planets/neptune/neptune.asset
@@ -40,4 +40,25 @@ local Neptune = {
}
}
-assetHelper.registerSceneGraphNodesAndExport(asset, { Neptune })
+local NeptuneLabel = {
+ Identifier = "NeptuneLabel",
+ Parent = Neptune.Identifier,
+ Renderable = {
+ Enabled = false,
+ Type = "RenderableLabels",
+ LabelText = "Neptune",
+ FontSize = 100.0,
+ LabelSize = 8.8,
+ LabelMaxSize = 100.0,
+ LabelMinSize = 1.0,
+ LabelOrientationOption = "Camera View Direction",
+ BlendMode = "Additive"
+ },
+ Tag = { "solarsystem_labels" },
+ GUI = {
+ Name = "Neptune Label",
+ Path = "/Solar System/Planets/Neptune"
+ }
+}
+
+assetHelper.registerSceneGraphNodesAndExport(asset, { Neptune, NeptuneLabel })
diff --git a/data/assets/scene/solarsystem/planets/saturn/dione/dione.asset b/data/assets/scene/solarsystem/planets/saturn/dione/dione.asset
index 7cdd49b5cd..ded4b6ae73 100644
--- a/data/assets/scene/solarsystem/planets/saturn/dione/dione.asset
+++ b/data/assets/scene/solarsystem/planets/saturn/dione/dione.asset
@@ -2,7 +2,7 @@ local transforms = asset.require('../transforms')
local assetHelper = asset.require('util/asset_helper')
local kernel = asset.require('../kernels').sat375
asset.request('./trail')
-local labelsPath = asset.require('../saturn_labels').LabelsPath
+local labelsPath = asset.require('../saturn_globelabels').LabelsPath
diff --git a/data/assets/scene/solarsystem/planets/saturn/enceladus/enceladus.asset b/data/assets/scene/solarsystem/planets/saturn/enceladus/enceladus.asset
index 5fa01501ba..8a66735198 100644
--- a/data/assets/scene/solarsystem/planets/saturn/enceladus/enceladus.asset
+++ b/data/assets/scene/solarsystem/planets/saturn/enceladus/enceladus.asset
@@ -2,7 +2,7 @@ local transforms = asset.require('../transforms')
local assetHelper = asset.require('util/asset_helper')
local kernel = asset.require('../kernels').sat375
asset.request('./trail')
-local labelsPath = asset.require('../saturn_labels').LabelsPath
+local labelsPath = asset.require('../saturn_globelabels').LabelsPath
diff --git a/data/assets/scene/solarsystem/planets/saturn/iapetus/iapetus.asset b/data/assets/scene/solarsystem/planets/saturn/iapetus/iapetus.asset
index bab9c45056..892cc2c13e 100644
--- a/data/assets/scene/solarsystem/planets/saturn/iapetus/iapetus.asset
+++ b/data/assets/scene/solarsystem/planets/saturn/iapetus/iapetus.asset
@@ -2,7 +2,7 @@ local transforms = asset.require('../transforms')
local assetHelper = asset.require('util/asset_helper')
local kernel = asset.require('../kernels').sat375
asset.request('./trail')
-local labelsPath = asset.require('../saturn_labels').LabelsPath
+local labelsPath = asset.require('../saturn_globelabels').LabelsPath
diff --git a/data/assets/scene/solarsystem/planets/saturn/mimas/mimas.asset b/data/assets/scene/solarsystem/planets/saturn/mimas/mimas.asset
index 4dbedaad48..53d9b7da21 100644
--- a/data/assets/scene/solarsystem/planets/saturn/mimas/mimas.asset
+++ b/data/assets/scene/solarsystem/planets/saturn/mimas/mimas.asset
@@ -2,7 +2,7 @@ local transforms = asset.require('../transforms')
local assetHelper = asset.require('util/asset_helper')
local kernel = asset.require('../kernels').sat375
asset.request('./trail')
-local labelsPath = asset.require('../saturn_labels').LabelsPath
+local labelsPath = asset.require('../saturn_globelabels').LabelsPath
diff --git a/data/assets/scene/solarsystem/planets/saturn/rhea/rhea.asset b/data/assets/scene/solarsystem/planets/saturn/rhea/rhea.asset
index 0ab5688544..008663ecf5 100644
--- a/data/assets/scene/solarsystem/planets/saturn/rhea/rhea.asset
+++ b/data/assets/scene/solarsystem/planets/saturn/rhea/rhea.asset
@@ -2,7 +2,7 @@ local transforms = asset.require('../transforms')
local assetHelper = asset.require('util/asset_helper')
local kernel = asset.require('../kernels').sat375
asset.request('./trail')
-local labelsPath = asset.require('../saturn_labels').LabelsPath
+local labelsPath = asset.require('../saturn_globelabels').LabelsPath
diff --git a/data/assets/scene/solarsystem/planets/saturn/saturn.asset b/data/assets/scene/solarsystem/planets/saturn/saturn.asset
index 91bd69519c..aeef8db352 100644
--- a/data/assets/scene/solarsystem/planets/saturn/saturn.asset
+++ b/data/assets/scene/solarsystem/planets/saturn/saturn.asset
@@ -51,22 +51,25 @@ local Saturn = {
}
}
--- local SaturnRings = {
--- Identifier = "SaturnRings",
--- Parent = Saturn.Identifier,
--- Renderable = {
--- Type = "RenderableRings",
--- Texture = textures .. "/saturn_rings.png",
--- Size = 140445000,
--- Offset = { 74500 / 140445.100671159, 1.0 } -- min / max extend
--- },
--- GUI = {
--- Name = "Saturn Rings",
--- Path = "/Solar System/Planets/Saturn"
--- }
--- }
+local SaturnLabel = {
+ Identifier = "SaturnLabel",
+ Parent = Saturn.Identifier,
+ Renderable = {
+ Enabled = false,
+ Type = "RenderableLabels",
+ LabelText = "Saturn",
+ FontSize = 100.0,
+ LabelSize = 8.7,
+ LabelMaxSize = 100.0,
+ LabelMinSize = 1.0,
+ BlendMode = "Additive",
+ LabelOrientationOption = "Camera View Direction"
+ },
+ Tag = { "solarsystem_labels" },
+ GUI = {
+ Name = "Saturn Label",
+ Path = "/Solar System/Planets/Saturn"
+ }
+}
-
-
---assetHelper.registerSceneGraphNodesAndExport(asset, { Saturn, SaturnRings })
-assetHelper.registerSceneGraphNodesAndExport(asset, { Saturn })
+assetHelper.registerSceneGraphNodesAndExport(asset, { Saturn, SaturnLabel })
diff --git a/data/assets/scene/solarsystem/planets/saturn/saturn_labels.asset b/data/assets/scene/solarsystem/planets/saturn/saturn_globelabels.asset
similarity index 100%
rename from data/assets/scene/solarsystem/planets/saturn/saturn_labels.asset
rename to data/assets/scene/solarsystem/planets/saturn/saturn_globelabels.asset
diff --git a/data/assets/scene/solarsystem/planets/saturn/tethys/tethys.asset b/data/assets/scene/solarsystem/planets/saturn/tethys/tethys.asset
index 1979cf4d66..fea8618180 100644
--- a/data/assets/scene/solarsystem/planets/saturn/tethys/tethys.asset
+++ b/data/assets/scene/solarsystem/planets/saturn/tethys/tethys.asset
@@ -2,7 +2,7 @@ local transforms = asset.require('../transforms')
local assetHelper = asset.require('util/asset_helper')
local kernel = asset.require('../kernels').sat375
asset.request('./trail')
-local labelsPath = asset.require('../saturn_labels').LabelsPath
+local labelsPath = asset.require('../saturn_globelabels').LabelsPath
diff --git a/data/assets/scene/solarsystem/planets/saturn/titan/titan.asset b/data/assets/scene/solarsystem/planets/saturn/titan/titan.asset
index 0145308ed4..a086c9eecb 100644
--- a/data/assets/scene/solarsystem/planets/saturn/titan/titan.asset
+++ b/data/assets/scene/solarsystem/planets/saturn/titan/titan.asset
@@ -2,7 +2,7 @@ local transforms = asset.require('../transforms')
local assetHelper = asset.require('util/asset_helper')
local kernel = asset.require('../kernels').sat375
asset.request('./trail')
-local labelsPath = asset.require('../saturn_labels').LabelsPath
+local labelsPath = asset.require('../saturn_globelabels').LabelsPath
local map_service_configs = asset.localResource("map_service_configs")
diff --git a/data/assets/scene/solarsystem/planets/uranus/uranus.asset b/data/assets/scene/solarsystem/planets/uranus/uranus.asset
index 1bb29fa184..db3fb11848 100644
--- a/data/assets/scene/solarsystem/planets/uranus/uranus.asset
+++ b/data/assets/scene/solarsystem/planets/uranus/uranus.asset
@@ -42,6 +42,25 @@ local Uranus = {
}
}
+local UranusLabel = {
+ Identifier = "UranusLabel",
+ Parent = Uranus.Identifier,
+ Renderable = {
+ Enabled = false,
+ Type = "RenderableLabels",
+ LabelText = "Uranus",
+ FontSize = 100.0,
+ LabelSize = 8.7,
+ LabelMaxSize = 100.0,
+ LabelMinSize = 1.0,
+ LabelOrientationOption = "Camera View Direction",
+ BlendMode = "Additive"
+ },
+ Tag = { "solarsystem_labels" },
+ GUI = {
+ Name = "Neptune Label",
+ Path = "/Solar System/Planets/Uranus"
+ }
+}
-
-assetHelper.registerSceneGraphNodesAndExport(asset, { Uranus })
+assetHelper.registerSceneGraphNodesAndExport(asset, { Uranus, UranusLabel })
diff --git a/data/assets/scene/solarsystem/planets/venus/atmosphere.asset b/data/assets/scene/solarsystem/planets/venus/atmosphere.asset
new file mode 100644
index 0000000000..40a95cdc54
--- /dev/null
+++ b/data/assets/scene/solarsystem/planets/venus/atmosphere.asset
@@ -0,0 +1,66 @@
+local transforms = asset.require('./venus')
+local assetHelper = asset.require('util/asset_helper')
+
+
+
+local Atmosphere = {
+ Identifier = "VenusAtmosphere",
+ Parent = transforms.Venus.Identifier,
+ Renderable = {
+ Type = "RenderableAtmosphere",
+ Atmosphere = {
+ -- Atmosphere radius in Km
+ AtmosphereRadius = 6121.9,
+ PlanetRadius = 6051.9,
+ PlanetAverageGroundReflectance = 0.018,
+ GroundRadianceEmittion = 0.8,
+ SunIntensity = 11.47,
+ --MieScatteringExtinctionPropCoefficient = 0.23862,
+ Rayleigh = {
+ Coefficients = {
+ -- Wavelengths are given in 10^-9m
+ Wavelengths = { 680, 550, 440 },
+ -- Reflection coefficients are given in km^-1
+ Scattering = { 19.518E-3, 13.83E-3, 3.65E-3 }
+ -- In Rayleigh scattering, the coefficients of
+ -- absorption and scattering are the same.
+ },
+ -- Thichkness of atmosphere if its density were uniform, in Km
+ H_R = 6.7
+ },
+ -- Default
+ Mie = {
+ Coefficients = {
+ -- Reflection coefficients are given in km^-1
+ Scattering = { 53.61771e-3, 53.61771e-3, 53.61771e-3 },
+ -- Extinction coefficients are a fraction of the Scattering coefficients
+ Extinction = { 53.61771e-3/0.98979, 53.61771e-3/0.98979, 53.61771e-3/0.98979 }
+ },
+ -- Mie Height scale (atmosphere thickness for constant density) in Km
+ H_M = 9.8,
+ -- Mie Phase Function Value (G e [-1.0, 1.0].
+ -- If G = 1.0, Mie phase function = Rayleigh Phase Function)
+ G = 0.85
+ },
+ Image = {
+ ToneMapping = jToneMapping,
+ Exposure = 0.4,
+ Background = 1.8,
+ Gamma = 1.85
+ },
+ Debug = {
+ -- PreCalculatedTextureScale is a float from 1.0 to N, with N > 0.0 and N in Naturals (i.e., 1, 2, 3, 4, 5....)
+ PreCalculatedTextureScale = 1.0,
+ SaveCalculatedTextures = false
+ }
+ }
+ },
+ GUI = {
+ Name = "Venus Atmosphere",
+ Path = "/Solar System/Planets/Venus"
+ }
+}
+
+
+
+assetHelper.registerSceneGraphNodesAndExport(asset, { Atmosphere })
diff --git a/data/assets/scene/solarsystem/planets/venus/map_service_configs/Utah/MagellanDEM.wms b/data/assets/scene/solarsystem/planets/venus/map_service_configs/Utah/MagellanDEM.wms
new file mode 100644
index 0000000000..c8072a6e30
--- /dev/null
+++ b/data/assets/scene/solarsystem/planets/venus/map_service_configs/Utah/MagellanDEM.wms
@@ -0,0 +1,21 @@
+
+
+ http://openspace.sci.utah.edu/Venus/MagellanDEM/tile/${z}/${y}/${x}
+
+
+ -180.0
+ 90.0
+ 180.0
+ -90.0
+ 8192
+ 4096
+ 4
+ top
+
+ GEOGCS["GCS_Venus",DATUM["D_Venus",SPHEROID["Venus",6051000,0]],PRIMEM["Reference_Meridian",0],UNIT["Degree",0.0174532925199433]]
+ 256
+ 256
+ 1
+ 10
+ 5
+
diff --git a/data/assets/scene/solarsystem/planets/venus/map_service_configs/Utah/MagellanMosaic.wms b/data/assets/scene/solarsystem/planets/venus/map_service_configs/Utah/MagellanMosaic.wms
new file mode 100644
index 0000000000..084e231ea4
--- /dev/null
+++ b/data/assets/scene/solarsystem/planets/venus/map_service_configs/Utah/MagellanMosaic.wms
@@ -0,0 +1,21 @@
+
+
+ http://openspace.sci.utah.edu/Venus/MagellanMosaic/tile/${z}/${y}/${x}
+
+
+ -180.0
+ 84.0
+ 180.0
+ -80.0
+ 506928
+ 230948
+ 9
+ top
+
+ GEOGCS["GCS_Venus",DATUM["D_Venus",SPHEROID["Venus_localRadius",6051000,0]],PRIMEM["Reference_Meridian",0],UNIT["Degree",0.0174532925199433]]
+ 512
+ 512
+ 1
+ 10
+ 5
+
diff --git a/data/assets/scene/solarsystem/planets/venus/venus.asset b/data/assets/scene/solarsystem/planets/venus/venus.asset
index 0b7617dad2..c6b3bc516d 100644
--- a/data/assets/scene/solarsystem/planets/venus/venus.asset
+++ b/data/assets/scene/solarsystem/planets/venus/venus.asset
@@ -2,9 +2,9 @@ local assetHelper = asset.require('util/asset_helper')
local transforms = asset.require('./transforms')
asset.require("spice/base")
asset.request('./trail')
-local labelsPath = asset.require('./venus_labels').LabelsPath
-
+local labelsPath = asset.require('./venus_globelabels').LabelsPath
+local mapServiceConfigs = asset.localResource("map_service_configs")
local textures = asset.syncedResource({
Name = "Venus Textures",
@@ -13,6 +13,28 @@ local textures = asset.syncedResource({
Version = 1
})
+local color_layers = {
+ {
+ Identifier = "Texture",
+ FilePath = textures .. "/venus.jpg",
+ Enabled = true
+ },
+ {
+ Identifier = "Magellan_Mosaic_Utah",
+ Name = "Magellan Mosaic [Utah]",
+ FilePath = mapServiceConfigs .. "/Utah/MagellanMosaic.wms"
+ }
+}
+
+local height_layers = {
+ {
+ Identifier = "Magellan",
+ Name = "Magellan Elevation [Utah]",
+ FilePath = mapServiceConfigs .. "/Utah/MagellanDEM.wms",
+ TilePixelSize = 64
+ }
+}
+
local Venus = {
Identifier = "Venus",
Parent = transforms.VenusBarycenter.Identifier,
@@ -30,16 +52,12 @@ local Venus = {
},
Renderable = {
Type = "RenderableGlobe",
- Radii = { 6051900.0, 6051900.0, 6051800.0 },
+ --Radii = { 6051900.0, 6051900.0, 6051800.0 },
+ Radii = { 6051900.0, 6051900.0, 6051900.0 },
SegmentsPerPatch = 64,
Layers = {
- ColorLayers = {
- {
- Identifier = "Texture",
- FilePath = textures .. "/venus.jpg",
- Enabled = true
- }
- }
+ ColorLayers = color_layers,
+ HeightLayers = height_layers
},
Labels = {
Enable = false,
@@ -64,6 +82,26 @@ local Venus = {
}
}
+local VenusLabel = {
+ Identifier = "VenusLabel",
+ Parent = Venus.Identifier,
+ Renderable = {
+ Enabled = false,
+ Type = "RenderableLabels",
+ LabelText = "Venus",
+ FontSize = 100.0,
+ LabelSize = 8.4,
+ LabelMaxSize = 100.0,
+ LabelMinSize = 1.0,
+ LabelOrientationOption = "Camera View Direction",
+ BlendMode = "Additive"
+ },
+ Tag = { "solarsystem_labels" },
+ GUI = {
+ Name = "Venus Label",
+ Path = "/Solar System/Planets/Venus"
+ }
+}
-assetHelper.registerSceneGraphNodesAndExport(asset, { Venus })
+assetHelper.registerSceneGraphNodesAndExport(asset, { Venus, VenusLabel })
diff --git a/data/assets/scene/solarsystem/planets/venus/venus_labels.asset b/data/assets/scene/solarsystem/planets/venus/venus_globelabels.asset
similarity index 100%
rename from data/assets/scene/solarsystem/planets/venus/venus_labels.asset
rename to data/assets/scene/solarsystem/planets/venus/venus_globelabels.asset
diff --git a/data/assets/scene/solarsystem/sun/sun.asset b/data/assets/scene/solarsystem/sun/sun.asset
index cc887dc4d2..10c0ff4aec 100644
--- a/data/assets/scene/solarsystem/sun/sun.asset
+++ b/data/assets/scene/solarsystem/sun/sun.asset
@@ -27,4 +27,32 @@ local Sun = {
}
}
-assetHelper.registerSceneGraphNodesAndExport(asset, { Sun })
+local SunLabel = {
+ Identifier = "SunLabel",
+ Parent = Sun.Identifier,
+ Renderable = {
+ Enabled = false,
+ Type = "RenderableLabels",
+ LabelText = "Sun",
+ FontSize = 100.0,
+ LabelSize = 13.127,
+ LabelMaxSize = 100.0,
+ LabelMinSize = 1.0,
+ LabelOrientationOption = "Camera View Direction",
+ BlendMode = "Additive",
+ EnableFading = true,
+ FadeStartUnit = "Pm",
+ FadeStartDistance = 2.841,
+ FadeStartSpeed = 1.375,
+ FadeEndUnit = "pc",
+ FadeEndDistance = 1.326,
+ FadeEndSpeed = 1.0
+ },
+ Tag = { "solarsystem_labels" },
+ GUI = {
+ Name = "Sun Label",
+ Path = "/Solar System/Sun"
+ }
+}
+
+assetHelper.registerSceneGraphNodesAndExport(asset, { Sun, SunLabel })
diff --git a/include/openspace/rendering/framebufferrenderer.h b/include/openspace/rendering/framebufferrenderer.h
index a49568fe17..7dd048052f 100644
--- a/include/openspace/rendering/framebufferrenderer.h
+++ b/include/openspace/rendering/framebufferrenderer.h
@@ -70,6 +70,7 @@ public:
void updateDeferredcastData();
void updateHDRAndFiltering();
void updateFXAA();
+ void updateDownscaledVolume();
void setResolution(glm::ivec2 res) override;
void setHDRExposure(float hdrExposure) override;
@@ -110,6 +111,9 @@ private:
void resolveMSAA(float blackoutFactor);
void applyTMO(float blackoutFactor);
void applyFXAA();
+ void updateDownscaleTextures();
+ void updateExitVolumeTextures();
+ void writeDownscaledVolume();
std::map _raycastData;
RaycasterProgObjMap _exitPrograms;
@@ -122,10 +126,13 @@ private:
std::unique_ptr _hdrFilteringProgram;
std::unique_ptr _tmoProgram;
std::unique_ptr _fxaaProgram;
+ std::unique_ptr _downscaledVolumeProgram;
UniformCache(hdrFeedingTexture, blackoutFactor, hdrExposure, gamma,
Hue, Saturation, Value) _hdrUniformCache;
UniformCache(renderedTexture, inverseScreenSize) _fxaaUniformCache;
+ UniformCache(downscaledRenderedVolume, downscaledRenderedVolumeDepth)
+ _writeDownscaledVolumeUniformCache;
GLint _defaultFBO;
GLuint _screenQuad;
@@ -157,6 +164,13 @@ private:
GLuint fxaaTexture;
} _fxaaBuffers;
+ struct {
+ GLuint framebuffer;
+ GLuint colorTexture;
+ GLuint depthbuffer;
+ float currentDownscaleFactor = 1.f;
+ } _downscaleVolumeRendering;
+
unsigned int _pingPongIndex = 0u;
bool _dirtyDeferredcastData;
diff --git a/include/openspace/rendering/volumeraycaster.h b/include/openspace/rendering/volumeraycaster.h
index f8ed000553..aa1133606e 100644
--- a/include/openspace/rendering/volumeraycaster.h
+++ b/include/openspace/rendering/volumeraycaster.h
@@ -128,6 +128,25 @@ public:
* helper file) which should be a prefix to all symbols defined by the helper
*/
virtual std::string helperPath() const = 0;
+
+ void setMaxSteps(int nsteps);
+
+ int maxSteps() const;
+
+ void setDownscaleRender(float value);
+
+ float downscaleRender() const;
+
+private:
+ /**
+ * Maximum number of integration steps to be executed by the volume integrator.
+ */
+ int _rayCastMaxSteps = 1000;
+
+ /**
+ * Enable and set the downscale rendering of the volume. Used to improve performance.
+ */
+ float _downscaleRenderConst = 1.0f;
};
} // namespace openspace
diff --git a/modules/base/CMakeLists.txt b/modules/base/CMakeLists.txt
index 29379351a0..18a9c74159 100644
--- a/modules/base/CMakeLists.txt
+++ b/modules/base/CMakeLists.txt
@@ -41,6 +41,7 @@ set(HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/rendering/multimodelgeometry.h
${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderableboxgrid.h
${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablecartesianaxes.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablelabels.h
${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablemodel.h
${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablenodeline.h
${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderableplane.h
@@ -89,6 +90,7 @@ set(SOURCE_FILES
${CMAKE_CURRENT_SOURCE_DIR}/rendering/multimodelgeometry.cpp
${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderableboxgrid.cpp
${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablecartesianaxes.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablelabels.cpp
${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablemodel.cpp
${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablenodeline.cpp
${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderableplane.cpp
diff --git a/modules/base/basemodule.cpp b/modules/base/basemodule.cpp
index 3535e48522..1b6f3d8398 100644
--- a/modules/base/basemodule.cpp
+++ b/modules/base/basemodule.cpp
@@ -38,6 +38,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -123,6 +124,7 @@ void BaseModule::internalInitialize(const ghoul::Dictionary&) {
fRenderable->registerClass("RenderableBoxGrid");
fRenderable->registerClass("RenderableCartesianAxes");
+ fRenderable->registerClass("RenderableLabels");
fRenderable->registerClass("RenderableModel");
fRenderable->registerClass("RenderableNodeLine");
fRenderable->registerClass("RenderablePlaneImageLocal");
@@ -191,6 +193,7 @@ std::vector BaseModule::documentations() const {
DashboardItemVelocity::Documentation(),
RenderableBoxGrid::Documentation(),
+ RenderableLabels::Documentation(),
RenderableModel::Documentation(),
RenderableNodeLine::Documentation(),
RenderablePlane::Documentation(),
diff --git a/modules/base/rendering/renderablelabels.cpp b/modules/base/rendering/renderablelabels.cpp
new file mode 100644
index 0000000000..5c8bbd20ae
--- /dev/null
+++ b/modules/base/rendering/renderablelabels.cpp
@@ -0,0 +1,816 @@
+/*****************************************************************************************
+ * *
+ * OpenSpace *
+ * *
+ * Copyright (c) 2014-2019 *
+ * *
+ * 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
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace {
+ constexpr const char* _loggerCat = "base::RenderableLabels";
+
+ constexpr const char* MeterUnit = "m";
+ constexpr const char* KilometerUnit = "Km";
+ constexpr const char* MegameterUnit = "Mm";
+ constexpr const char* GigameterUnit = "Gm";
+ constexpr const char* AstronomicalUnit = "au";
+ constexpr const char* TerameterUnit = "Tm";
+ constexpr const char* PetameterUnit = "Pm";
+ constexpr const char* ParsecUnit = "pc";
+ constexpr const char* KiloparsecUnit = "Kpc";
+ constexpr const char* MegaparsecUnit = "Mpc";
+ constexpr const char* GigaparsecUnit = "Gpc";
+ constexpr const char* GigalightyearUnit = "Gly";
+
+ enum BlendMode {
+ BlendModeNormal = 0,
+ BlendModeAdditive
+ };
+
+ constexpr const int ViewDirection = 0;
+ constexpr const int NormalDirection = 1;
+
+ constexpr double PARSEC = 0.308567756E17;
+
+ constexpr openspace::properties::Property::PropertyInfo BlendModeInfo = {
+ "BlendMode",
+ "Blending Mode",
+ "This determines the blending mode that is applied to this plane."
+ };
+
+ constexpr openspace::properties::Property::PropertyInfo LabelColorInfo = {
+ "LabelColor",
+ "Label Color",
+ "The label color for the astronomical object."
+ };
+
+ constexpr openspace::properties::Property::PropertyInfo FontSizeInfo = {
+ "FontSize",
+ "Font Size",
+ "The font size for the astronomical object labels."
+ };
+
+ constexpr openspace::properties::Property::PropertyInfo LabelSizeInfo = {
+ "LabelSize",
+ "Label Size",
+ "The label size for the astronomical object labels."
+ };
+
+ constexpr openspace::properties::Property::PropertyInfo LabelTextInfo = {
+ "LabelText",
+ "Label Text",
+ "The text that will be displayed on screen."
+ };
+
+ constexpr openspace::properties::Property::PropertyInfo LabelMinSizeInfo = {
+ "LabelMinSize",
+ "Label Min Size",
+ "The minimal size (in pixels) of the labels for the astronomical "
+ "objects being rendered."
+ };
+
+ constexpr openspace::properties::Property::PropertyInfo LabelMaxSizeInfo = {
+ "LabelMaxSize",
+ "Label Max Size",
+ "The maximum size (in pixels) of the labels for the astronomical "
+ "objects being rendered."
+ };
+
+ constexpr openspace::properties::Property::PropertyInfo TransformationMatrixInfo = {
+ "TransformationMatrix",
+ "Transformation Matrix",
+ "Transformation matrix to be applied to each astronomical object."
+ };
+
+ constexpr openspace::properties::Property::PropertyInfo LabelOrientationOptionInfo = {
+ "LabelOrientationOption",
+ "Label Orientation Option",
+ "Label orientation rendering mode."
+ };
+
+ constexpr openspace::properties::Property::PropertyInfo EnableFadingEffectInfo = {
+ "EnableFading",
+ "Enable/Disable Fade-in effect",
+ "Enable/Disable the Fade-in effect."
+ };
+
+ constexpr openspace::properties::Property::PropertyInfo PixelSizeControlInfo = {
+ "EnablePixelSizeControl",
+ "Enable pixel size control.",
+ "Enable pixel size control for rectangular projections."
+ };
+
+ constexpr openspace::properties::Property::PropertyInfo FadeStartUnitOptionInfo = {
+ "FadeStartUnit",
+ "Fade-In/-Out Start Unit.",
+ "Unit for fade-in/-out starting position calculation."
+ };
+
+ constexpr openspace::properties::Property::PropertyInfo FadeEndUnitOptionInfo = {
+ "FadeEndUnit",
+ "Fade-In/-Out End Unit.",
+ "Unit for fade-in/-out ending position calculation."
+ };
+
+ constexpr openspace::properties::Property::PropertyInfo FadeStartDistInfo = {
+ "FadeStartDistance",
+ "Fade-In/-Out starting distance.",
+ "Fade-In/-Out starting distance."
+ };
+
+ constexpr openspace::properties::Property::PropertyInfo FadeEndDistInfo = {
+ "FadeEndDistance",
+ "Fade-In/-Out ending distance.",
+ "Fade-In/-Out ending distance."
+ };
+
+ constexpr openspace::properties::Property::PropertyInfo FadeStartSpeedInfo = {
+ "FadeStartSpeed",
+ "Fade-In/-Out starting speed.",
+ "Fade-In/-Out starting speed."
+ };
+
+ constexpr openspace::properties::Property::PropertyInfo FadeEndSpeedInfo = {
+ "FadeEndSpeed",
+ "Fade-In/-Out ending speed.",
+ "Fade-In/-Out ending speed."
+ };
+} // namespace
+
+namespace openspace {
+
+documentation::Documentation RenderableLabels::Documentation() {
+ using namespace documentation;
+ return {
+ "Renderable Labels",
+ "base_renderable_labels",
+ {
+ {
+ BlendModeInfo.identifier,
+ new StringInListVerifier({ "Normal", "Additive" }),
+ Optional::Yes,
+ BlendModeInfo.description, // + " The default value is 'Normal'.",
+ },
+ {
+ LabelOrientationOptionInfo.identifier,
+ new StringInListVerifier(
+ { "Camera View Direction", "Camera Position Normal" }
+ ),
+ Optional::Yes,
+ LabelOrientationOptionInfo.description,
+ },
+ {
+ LabelColorInfo.identifier,
+ new DoubleVector4Verifier,
+ Optional::Yes,
+ LabelColorInfo.description,
+ },
+ {
+ LabelColorInfo.identifier,
+ new DoubleVector4Verifier,
+ Optional::Yes,
+ LabelColorInfo.description,
+ },
+ {
+ LabelTextInfo.identifier,
+ new StringVerifier,
+ Optional::No,
+ LabelTextInfo.description
+ },
+ {
+ FontSizeInfo.identifier,
+ new DoubleVerifier,
+ Optional::Yes,
+ FontSizeInfo.description
+ },
+ {
+ LabelSizeInfo.identifier,
+ new DoubleVerifier,
+ Optional::Yes,
+ LabelSizeInfo.description
+ },
+ {
+ LabelMinSizeInfo.identifier,
+ new DoubleVerifier,
+ Optional::Yes,
+ LabelMinSizeInfo.description
+ },
+ {
+ LabelMaxSizeInfo.identifier,
+ new DoubleVerifier,
+ Optional::Yes,
+ LabelMaxSizeInfo.description
+ },
+ {
+ EnableFadingEffectInfo.identifier,
+ new BoolVerifier,
+ Optional::Yes,
+ EnableFadingEffectInfo.description
+ },
+ {
+ PixelSizeControlInfo.identifier,
+ new BoolVerifier,
+ Optional::Yes,
+ PixelSizeControlInfo.description
+ },
+ {
+ FadeStartUnitOptionInfo.identifier,
+ new StringInListVerifier(
+ { "m", "Km", "Mm", "Gm", "au", "Tm", "Pm", "pc", "Kpc", "Mpc",
+ "Gpc", "Gly"}
+ ),
+ Optional::Yes,
+ FadeStartUnitOptionInfo.description,
+ },
+ {
+ FadeEndUnitOptionInfo.identifier,
+ new StringInListVerifier(
+ {"m", "Km", "Mm", "Gm", "au", "Tm", "Pm", "pc", "Kpc", "Mpc",
+ "Gpc", "Gly"}
+ ),
+ Optional::Yes,
+ FadeEndUnitOptionInfo.description,
+ },
+ {
+ FadeStartDistInfo.identifier,
+ new DoubleVerifier,
+ Optional::Yes,
+ FadeStartDistInfo.description
+ },
+ {
+ FadeEndDistInfo.identifier,
+ new DoubleVerifier,
+ Optional::Yes,
+ FadeEndDistInfo.description
+ },
+ {
+ FadeStartSpeedInfo.identifier,
+ new DoubleVerifier,
+ Optional::Yes,
+ FadeStartSpeedInfo.description
+ },
+ {
+ FadeEndSpeedInfo.identifier,
+ new DoubleVerifier,
+ Optional::Yes,
+ FadeEndSpeedInfo.description
+ },
+ }
+ };
+}
+
+RenderableLabels::RenderableLabels(const ghoul::Dictionary& dictionary)
+ : Renderable(dictionary)
+ , _blendMode(BlendModeInfo, properties::OptionProperty::DisplayType::Dropdown)
+ , _labelColor(
+ LabelColorInfo,
+ glm::vec4(1.f, 1.f, 1.f, 1.f),
+ glm::vec4(0.f),
+ glm::vec4(1.f)
+ )
+ , _labelSize(LabelSizeInfo, 8.f, 0.5f, 30.f)
+ , _fontSize(FontSizeInfo, 50.f, 1.f, 100.f)
+ , _labelMinSize(LabelMinSizeInfo, 8.f, 0.5f, 24.f)
+ , _labelMaxSize(LabelMaxSizeInfo, 20.f, 0.5f, 100.f)
+ , _pixelSizeControl(PixelSizeControlInfo, false)
+ , _enableFadingEffect(EnableFadingEffectInfo, false)
+ , _labelText(LabelTextInfo)
+ , _fadeStartDistance(FadeStartDistInfo, 1.f, 0.f, 100.f)
+ , _fadeEndDistance(FadeEndDistInfo, 1.f, 0.f, 100.f)
+ , _fadeStartSpeed(FadeStartSpeedInfo, 1.f, 1.f, 100.f)
+ , _fadeEndSpeed(FadeEndSpeedInfo, 1.f, 1.f, 100.f)
+ , _labelOrientationOption(
+ LabelOrientationOptionInfo,
+ properties::OptionProperty::DisplayType::Dropdown
+ )
+ , _fadeStartUnitOption(
+ FadeStartUnitOptionInfo,
+ properties::OptionProperty::DisplayType::Dropdown
+ )
+ , _fadeEndUnitOption(
+ FadeEndUnitOptionInfo,
+ properties::OptionProperty::DisplayType::Dropdown
+ )
+{
+ documentation::testSpecificationAndThrow(
+ Documentation(),
+ dictionary,
+ "RenderableLabels"
+ );
+
+ registerUpdateRenderBinFromOpacity();
+
+ _blendMode.addOptions({
+ { BlendModeNormal, "Normal" },
+ { BlendModeAdditive, "Additive"}
+ });
+ _blendMode.onChange([&]() {
+ switch (_blendMode) {
+ case BlendModeNormal:
+ setRenderBinFromOpacity();
+ break;
+ case BlendModeAdditive:
+ setRenderBin(Renderable::RenderBin::Transparent);
+ break;
+ default:
+ throw ghoul::MissingCaseException();
+ }
+ });
+
+ if (dictionary.hasKey(BlendModeInfo.identifier)) {
+ const std::string v = dictionary.value(BlendModeInfo.identifier);
+ if (v == "Normal") {
+ _blendMode = BlendModeNormal;
+ }
+ else if (v == "Additive") {
+ _blendMode = BlendModeAdditive;
+ }
+ }
+
+ addProperty(_blendMode);
+
+ _labelOrientationOption.addOption(ViewDirection, "Camera View Direction");
+ _labelOrientationOption.addOption(NormalDirection, "Camera Position Normal");
+
+ _labelOrientationOption = NormalDirection;
+ if (dictionary.hasKeyAndValue(LabelOrientationOptionInfo.identifier)) {
+ const std::string o = dictionary.value(
+ LabelOrientationOptionInfo.identifier
+ );
+
+ if (o == "Camera View Direction") {
+ _labelOrientationOption = ViewDirection;
+ }
+ else if (o == "Camera Position Normal") {
+ _labelOrientationOption = NormalDirection;
+ }
+ }
+
+ if (dictionary.hasKey(LabelTextInfo.identifier)) {
+ _labelText = dictionary.value(LabelTextInfo.identifier);
+ }
+ addProperty(_labelText);
+
+ addProperty(_labelOrientationOption);
+
+ _labelColor.setViewOption(properties::Property::ViewOptions::Color);
+ if (dictionary.hasKey(LabelColorInfo.identifier)) {
+ _labelColor = dictionary.value(LabelColorInfo.identifier);
+ }
+ addProperty(_labelColor);
+
+ if (dictionary.hasKey(FontSizeInfo.identifier)) {
+ _fontSize = dictionary.value(FontSizeInfo.identifier);
+ }
+ _fontSize.onChange([&]() {
+ _font = global::fontManager.font(
+ "Mono",
+ _fontSize,
+ ghoul::fontrendering::FontManager::Outline::Yes,
+ ghoul::fontrendering::FontManager::LoadGlyphs::No
+ );
+ });
+ addProperty(_fontSize);
+
+ if (dictionary.hasKey(LabelSizeInfo.identifier)) {
+ _labelSize = dictionary.value(LabelSizeInfo.identifier);
+ }
+ addProperty(_labelSize);
+
+ if (dictionary.hasKey(LabelMinSizeInfo.identifier)) {
+ _labelMinSize = dictionary.value(LabelMinSizeInfo.identifier);
+ }
+ addProperty(_labelMinSize);
+
+ if (dictionary.hasKey(LabelMaxSizeInfo.identifier)) {
+ _labelMaxSize = dictionary.value(LabelMaxSizeInfo.identifier);
+ }
+ addProperty(_labelMaxSize);
+
+ if (dictionary.hasKey(TransformationMatrixInfo.identifier)) {
+ _transformationMatrix = dictionary.value(
+ TransformationMatrixInfo.identifier
+ );
+ }
+
+ if (dictionary.hasKey(PixelSizeControlInfo.identifier)) {
+ _pixelSizeControl = dictionary.value(PixelSizeControlInfo.identifier);
+ addProperty(_pixelSizeControl);
+ }
+
+ if (dictionary.hasKey(EnableFadingEffectInfo.identifier)) {
+ _enableFadingEffect = dictionary.value(EnableFadingEffectInfo.identifier);
+ }
+ addProperty(_enableFadingEffect);
+
+ if (dictionary.hasKey(FadeStartDistInfo.identifier)) {
+ _fadeStartDistance = dictionary.value(FadeStartDistInfo.identifier);
+ }
+
+ addProperty(_fadeStartDistance);
+
+ _fadeStartUnitOption.addOption(Meter, MeterUnit);
+ _fadeStartUnitOption.addOption(Kilometer, KilometerUnit);
+ _fadeStartUnitOption.addOption(Megameter, MegameterUnit);
+ _fadeStartUnitOption.addOption(Gigameter, GigameterUnit);
+ _fadeStartUnitOption.addOption(AU, AstronomicalUnit);
+ _fadeStartUnitOption.addOption(Terameter, TerameterUnit);
+ _fadeStartUnitOption.addOption(Petameter, PetameterUnit);
+ _fadeStartUnitOption.addOption(Parsec, ParsecUnit);
+ _fadeStartUnitOption.addOption(Kiloparsec, KiloparsecUnit);
+ _fadeStartUnitOption.addOption(Megaparsec, MegaparsecUnit);
+ _fadeStartUnitOption.addOption(Gigaparsec, GigaparsecUnit);
+ _fadeStartUnitOption.addOption(GigalightYears, GigalightyearUnit);
+
+ _fadeStartUnitOption = AU;
+
+ if (dictionary.hasKey(FadeStartUnitOptionInfo.identifier)) {
+ std::string unit = dictionary.value(
+ FadeStartUnitOptionInfo.identifier
+ );
+ if (unit == MeterUnit) {
+ _fadeStartUnitOption = Meter;
+ }
+ else if (unit == KilometerUnit) {
+ _fadeStartUnitOption = Kilometer;
+ }
+ else if (unit == MegameterUnit) {
+ _fadeStartUnitOption = Megameter;
+ }
+ else if (unit == GigameterUnit) {
+ _fadeStartUnitOption = Gigameter;
+ }
+ else if (unit == AstronomicalUnit) {
+ _fadeStartUnitOption = AU;
+ }
+ else if (unit == TerameterUnit) {
+ _fadeStartUnitOption = Terameter;
+ }
+ else if (unit == PetameterUnit) {
+ _fadeStartUnitOption = Petameter;
+ }
+ else if (unit == ParsecUnit) {
+ _fadeStartUnitOption = Parsec;
+ }
+ else if (unit == KiloparsecUnit) {
+ _fadeStartUnitOption = Kiloparsec;
+ }
+ else if (unit == MegaparsecUnit) {
+ _fadeStartUnitOption = Megaparsec;
+ }
+ else if (unit == GigaparsecUnit) {
+ _fadeStartUnitOption = Gigaparsec;
+ }
+ else if (unit == GigalightyearUnit) {
+ _fadeStartUnitOption = GigalightYears;
+ }
+ else {
+ LWARNING(
+ "No unit given for RenderableLabels. Using kilometer as units."
+ );
+ _fadeStartUnitOption = Kilometer;
+ }
+ }
+
+ addProperty(_fadeStartUnitOption);
+
+ if (dictionary.hasKey(FadeStartSpeedInfo.identifier)) {
+ _fadeStartSpeed = dictionary.value(FadeStartSpeedInfo.identifier);
+ }
+
+ addProperty(_fadeStartSpeed);
+
+ if (dictionary.hasKey(FadeEndDistInfo.identifier)) {
+ _fadeEndDistance = dictionary.value(FadeEndDistInfo.identifier);
+ }
+
+ addProperty(_fadeEndDistance);
+
+ _fadeEndUnitOption.addOption(Meter, MeterUnit);
+ _fadeEndUnitOption.addOption(Kilometer, KilometerUnit);
+ _fadeEndUnitOption.addOption(Megameter, MegameterUnit);
+ _fadeEndUnitOption.addOption(Gigameter, GigameterUnit);
+ _fadeEndUnitOption.addOption(AU, AstronomicalUnit);
+ _fadeEndUnitOption.addOption(Terameter, TerameterUnit);
+ _fadeEndUnitOption.addOption(Petameter, PetameterUnit);
+ _fadeEndUnitOption.addOption(Parsec, ParsecUnit);
+ _fadeEndUnitOption.addOption(Kiloparsec, KiloparsecUnit);
+ _fadeEndUnitOption.addOption(Megaparsec, MegaparsecUnit);
+ _fadeEndUnitOption.addOption(Gigaparsec, GigaparsecUnit);
+ _fadeEndUnitOption.addOption(GigalightYears, GigalightyearUnit);
+
+ _fadeEndUnitOption = AU;
+
+ if (dictionary.hasKey(FadeEndUnitOptionInfo.identifier)) {
+ std::string unit = dictionary.value(
+ FadeEndUnitOptionInfo.identifier
+ );
+ if (unit == MeterUnit) {
+ _fadeEndUnitOption = Meter;
+ }
+ else if (unit == KilometerUnit) {
+ _fadeEndUnitOption = Kilometer;
+ }
+ else if (unit == MegameterUnit) {
+ _fadeEndUnitOption = Megameter;
+ }
+ else if (unit == GigameterUnit) {
+ _fadeEndUnitOption = Gigameter;
+ }
+ else if (unit == AstronomicalUnit) {
+ _fadeEndUnitOption = AU;
+ }
+ else if (unit == TerameterUnit) {
+ _fadeEndUnitOption = Terameter;
+ }
+ else if (unit == PetameterUnit) {
+ _fadeEndUnitOption = Petameter;
+ }
+ else if (unit == ParsecUnit) {
+ _fadeEndUnitOption = Parsec;
+ }
+ else if (unit == KiloparsecUnit) {
+ _fadeEndUnitOption = Kiloparsec;
+ }
+ else if (unit == MegaparsecUnit) {
+ _fadeEndUnitOption = Megaparsec;
+ }
+ else if (unit == GigaparsecUnit) {
+ _fadeEndUnitOption = Gigaparsec;
+ }
+ else if (unit == GigalightyearUnit) {
+ _fadeEndUnitOption = GigalightYears;
+ }
+ else {
+ LWARNING(
+ "No unit given for RenderableLabels. Using kilometer as units."
+ );
+ _fadeEndUnitOption = Kilometer;
+ }
+ }
+
+ addProperty(_fadeEndUnitOption);
+
+ if (dictionary.hasKey(FadeEndSpeedInfo.identifier)) {
+ _fadeEndSpeed = dictionary.value(FadeEndSpeedInfo.identifier);
+ }
+
+ addProperty(_fadeEndSpeed);
+}
+
+bool RenderableLabels::isReady() const {
+ return true;
+}
+
+void RenderableLabels::initialize() {
+ bool success = true;// loadData();
+ if (!success) {
+ throw ghoul::RuntimeError("Error loading objects labels data.");
+ }
+
+ setRenderBin(Renderable::RenderBin::Transparent);
+}
+
+void RenderableLabels::initializeGL() {
+ if (_font == nullptr) {
+ //size_t _fontSize = 50;
+ _font = global::fontManager.font(
+ "Mono",
+ _fontSize,
+ ghoul::fontrendering::FontManager::Outline::Yes,
+ ghoul::fontrendering::FontManager::LoadGlyphs::No
+ );
+ }
+}
+
+void RenderableLabels::deinitializeGL() {}
+
+void RenderableLabels::render(const RenderData& data, RendererTasks&) {
+
+ //bool additiveBlending = (_blendMode == BlendModeAdditive);
+ //if (additiveBlending) {
+ glDepthMask(false);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+ //}
+
+ float fadeInVariable = 1.f;
+
+ if (_enableFadingEffect) {
+ float distanceNodeToCamera = glm::distance(
+ data.camera.positionVec3(),
+ data.modelTransform.translation
+ );
+ float sUnit = getUnit(_fadeStartUnitOption);
+ float eUnit = getUnit(_fadeEndUnitOption);
+ float startX = _fadeStartDistance * sUnit;
+ float endX = _fadeEndDistance * eUnit;
+ //fadeInVariable = changedPerlinSmoothStepFunc(distanceNodeToCamera, startX, endX);
+ fadeInVariable = linearSmoothStepFunc(
+ distanceNodeToCamera,
+ startX,
+ endX,
+ sUnit,
+ eUnit
+ );
+ }
+
+ glm::dmat4 modelMatrix(1.0);
+ glm::dmat4 modelViewMatrix = data.camera.combinedViewMatrix() * modelMatrix;
+ glm::dmat4 projectionMatrix = glm::dmat4(data.camera.projectionMatrix());
+
+ glm::dmat4 modelViewProjectionMatrix = projectionMatrix * modelViewMatrix;
+
+ glm::dvec3 cameraViewDirectionWorld = -data.camera.viewDirectionWorldSpace();
+ glm::dvec3 cameraUpDirectionWorld = data.camera.lookUpVectorWorldSpace();
+ glm::dvec3 orthoRight = glm::normalize(
+ glm::cross(cameraUpDirectionWorld, cameraViewDirectionWorld)
+ );
+ if (orthoRight == glm::dvec3(0.0)) {
+ glm::dvec3 otherVector(
+ cameraUpDirectionWorld.y,
+ cameraUpDirectionWorld.x,
+ cameraUpDirectionWorld.z
+ );
+ orthoRight = glm::normalize(glm::cross(otherVector, cameraViewDirectionWorld));
+ }
+ glm::dvec3 orthoUp = glm::normalize(glm::cross(cameraViewDirectionWorld, orthoRight));
+
+ renderLabels(data, modelViewProjectionMatrix, orthoRight, orthoUp, fadeInVariable);
+
+ //if (additiveBlending) {
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glDepthMask(true);
+ //}
+}
+
+void RenderableLabels::update(const UpdateData&) {
+}
+
+void RenderableLabels::setLabelText(const std::string & newText) {
+ _labelText = newText;
+}
+
+void RenderableLabels::renderLabels(const RenderData& data,
+ const glm::dmat4& modelViewProjectionMatrix,
+ const glm::dvec3& orthoRight,
+ const glm::dvec3& orthoUp, float fadeInVariable)
+{
+ glm::vec4 textColor = _labelColor;
+
+ textColor.a *= fadeInVariable;
+ textColor.a *= _opacity;
+
+ ghoul::fontrendering::FontRenderer::ProjectedLabelsInformation labelInfo;
+
+ labelInfo.orthoRight = orthoRight;
+ labelInfo.orthoUp = orthoUp;
+ labelInfo.minSize = static_cast(_labelMinSize);
+ labelInfo.maxSize = static_cast(_labelMaxSize);
+ labelInfo.cameraPos = data.camera.positionVec3();
+ labelInfo.cameraLookUp = data.camera.lookUpVectorWorldSpace();
+ labelInfo.renderType = _labelOrientationOption;
+ labelInfo.mvpMatrix = modelViewProjectionMatrix;
+ labelInfo.scale = powf(10.f, _labelSize);
+ labelInfo.enableDepth = true;
+ labelInfo.enableFalseDepth = false;
+
+ // We don't use spice rotation and scale
+ glm::vec3 transformedPos(
+ _transformationMatrix * glm::dvec4(data.modelTransform.translation, 1.0)
+ );
+
+ ghoul::fontrendering::FontRenderer::defaultProjectionRenderer().render(
+ *_font,
+ transformedPos,
+ _labelText,
+ textColor,
+ labelInfo
+ );
+}
+
+float RenderableLabels::changedPerlinSmoothStepFunc(float x, float startX,
+ float endX) const
+{
+ float f1 = 6.f * powf((x - startX), 5.f) - 15.f * powf((x - startX), 4.f) +
+ 10.f * powf((x - startX), 3.f);
+ float f2 = -6.f * powf((x - endX), 5.f) + 15.f * powf((x - endX), 4.f) -
+ 10.f * powf((x - endX), 3.f) + 1.f;
+ float f3 = 1.f;
+
+ if (x <= startX) {
+ return std::clamp(f1, 0.f, 1.f);
+ }
+ else if (x > startX && x < endX) {
+ return f3;
+ }
+ else if (x >= endX) {
+ return std::clamp(f2, 0.f, 1.f);
+ }
+}
+
+float RenderableLabels::linearSmoothStepFunc(float x, float startX, float endX,
+ float sUnit, float eUnit) const
+{
+ float sdiv = 1.f / (sUnit * _fadeStartSpeed);
+ float ediv = -1.f / (eUnit * _fadeEndSpeed);
+ float f1 = sdiv * (x - startX) + 1.f;
+ float f2 = ediv * (x - endX) + 1.f;
+ float f3 = 1.f;
+
+ if (x <= startX) {
+ return std::clamp(f1, 0.f, 1.f);
+ }
+ else if (x > startX && x < endX) {
+ return f3;
+ }
+ else if (x >= endX) {
+ return std::clamp(f2, 0.f, 1.f);
+ }
+}
+
+float RenderableLabels::getUnit(int unit) const {
+
+ float scale = 0.f;
+ switch (static_cast(unit)) {
+ case Meter:
+ scale = 1.f;
+ break;
+ case Kilometer:
+ scale = 1e3;
+ break;
+ case Megameter:
+ scale = 1e6;
+ break;
+ case Gigameter:
+ scale = 1e9;
+ break;
+ case AU:
+ scale = 149597870700.f;
+ break;
+ case Terameter:
+ scale = 1e12;
+ break;
+ case Petameter:
+ scale = 1e15;
+ break;
+ case Parsec:
+ scale = static_cast(PARSEC);
+ break;
+ case Kiloparsec:
+ scale = static_cast(1e3 * PARSEC);
+ break;
+ case Megaparsec:
+ scale = static_cast(1e6 * PARSEC);
+ break;
+ case Gigaparsec:
+ scale = static_cast(1e9 * PARSEC);
+ break;
+ case GigalightYears:
+ scale = static_cast(306391534.73091 * PARSEC);
+ break;
+ }
+
+ return scale;
+}
+
+} // namespace openspace
diff --git a/modules/base/rendering/renderablelabels.h b/modules/base/rendering/renderablelabels.h
new file mode 100644
index 0000000000..0f5bbf6f99
--- /dev/null
+++ b/modules/base/rendering/renderablelabels.h
@@ -0,0 +1,134 @@
+/*****************************************************************************************
+ * *
+ * OpenSpace *
+ * *
+ * Copyright (c) 2014-2019 *
+ * *
+ * 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_BASE___RENDERABLELABELS___H__
+#define __OPENSPACE_MODULE_BASE___RENDERABLELABELS___H__
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+namespace ghoul::filesystem { class File; }
+namespace ghoul::fontrendering { class Font; }
+namespace ghoul::opengl {
+ class ProgramObject;
+ class Texture;
+} // namespace ghoul::opengl
+
+namespace openspace {
+
+struct RenderData;
+struct UpdateData;
+
+namespace documentation { struct Documentation; }
+
+struct LinePoint;
+
+class RenderableLabels : public Renderable {
+public:
+ RenderableLabels(const ghoul::Dictionary& dictionary);
+
+ void initialize() override;
+ void initializeGL() override;
+ void deinitializeGL() override;
+
+ bool isReady() const override;
+
+ void render(const RenderData& data, RendererTasks& rendererTask) override;
+ void update(const UpdateData& data) override;
+
+ static documentation::Documentation Documentation();
+
+ void setLabelText(const std::string & newText);
+
+protected:
+ properties::OptionProperty _blendMode;
+
+private:
+ enum Unit {
+ Meter = 0,
+ Kilometer,
+ Megameter,
+ Gigameter,
+ AU,
+ Terameter,
+ Petameter,
+ Parsec,
+ Kiloparsec,
+ Megaparsec,
+ Gigaparsec,
+ GigalightYears
+ };
+
+ void renderLabels(const RenderData& data, const glm::dmat4& modelViewProjectionMatrix,
+ const glm::dvec3& orthoRight, const glm::dvec3& orthoUp, float fadeInVariable);
+
+ float changedPerlinSmoothStepFunc(float x, float startX, float endX) const;
+
+ float linearSmoothStepFunc(float x, float startX, float endX, float sUnit,
+ float eUnit) const;
+
+ float getUnit(int unit) const;
+
+ properties::Vec4Property _labelColor;
+ properties::FloatProperty _labelSize;
+ properties::FloatProperty _fontSize;
+ properties::FloatProperty _labelMinSize;
+ properties::FloatProperty _labelMaxSize;
+ properties::BoolProperty _pixelSizeControl;
+ properties::BoolProperty _enableFadingEffect;
+ properties::StringProperty _labelText;
+ properties::FloatProperty _fadeStartDistance;
+ properties::FloatProperty _fadeEndDistance;
+ properties::FloatProperty _fadeStartSpeed;
+ properties::FloatProperty _fadeEndSpeed;
+
+ properties::OptionProperty _labelOrientationOption;
+ properties::OptionProperty _fadeStartUnitOption;
+ properties::OptionProperty _fadeEndUnitOption;
+
+ std::shared_ptr _font;
+
+ std::string _speckFile;
+ std::string _colorMapFile;
+ std::string _labelFile;
+ std::string _colorOptionString;
+ std::string _datavarSizeOptionString;
+
+ // Data may require some type of transformation prior the spice transformation being
+ // applied.
+ glm::dmat4 _transformationMatrix = glm::dmat4(1.0);
+};
+
+} // namespace openspace
+
+#endif // __OPENSPACE_MODULE_BASE___RENDERABLELABELS___H__
diff --git a/modules/digitaluniverse/rendering/renderablebillboardscloud.cpp b/modules/digitaluniverse/rendering/renderablebillboardscloud.cpp
index da42b36210..40d332b2d6 100644
--- a/modules/digitaluniverse/rendering/renderablebillboardscloud.cpp
+++ b/modules/digitaluniverse/rendering/renderablebillboardscloud.cpp
@@ -42,7 +42,6 @@
#include
#include
#include
-#include
#include
#include
#include
diff --git a/modules/digitaluniverse/shaders/billboard_fs.glsl b/modules/digitaluniverse/shaders/billboard_fs.glsl
index 3ca590e5a5..d2859f1162 100644
--- a/modules/digitaluniverse/shaders/billboard_fs.glsl
+++ b/modules/digitaluniverse/shaders/billboard_fs.glsl
@@ -25,7 +25,7 @@
#include "fragment.glsl"
flat in vec4 gs_colorMap;
-in float vs_screenSpaceDepth;
+flat in float vs_screenSpaceDepth;
in vec2 texCoord;
in float ta;
diff --git a/modules/digitaluniverse/shaders/billboard_gs.glsl b/modules/digitaluniverse/shaders/billboard_gs.glsl
index cb955fbc33..4ee3047d28 100644
--- a/modules/digitaluniverse/shaders/billboard_gs.glsl
+++ b/modules/digitaluniverse/shaders/billboard_gs.glsl
@@ -55,7 +55,7 @@ flat in float dvarScaling[];
flat out vec4 gs_colorMap;
out vec2 texCoord;
-out float vs_screenSpaceDepth;
+flat out float vs_screenSpaceDepth;
out float ta;
const double PARSEC = 0.308567756e17LF;
@@ -171,17 +171,22 @@ void main() {
// Build primitive
- texCoord = corners[3];
- gl_Position = thirdPosition;
- EmitVertex();
+
texCoord = corners[0];
gl_Position = initialPosition;
EmitVertex();
- texCoord = corners[2];
- gl_Position = crossCorner;
- EmitVertex();
+
texCoord = corners[1];
gl_Position = secondPosition;
EmitVertex();
+
+ texCoord = corners[3];
+ gl_Position = thirdPosition;
+ EmitVertex();
+
+ texCoord = corners[2];
+ gl_Position = crossCorner;
+ EmitVertex();
+
EndPrimitive();
}
\ No newline at end of file
diff --git a/modules/galaxy/rendering/renderablegalaxy.cpp b/modules/galaxy/rendering/renderablegalaxy.cpp
index 1d88c2da23..71edb8d372 100644
--- a/modules/galaxy/rendering/renderablegalaxy.cpp
+++ b/modules/galaxy/rendering/renderablegalaxy.cpp
@@ -117,6 +117,19 @@ namespace {
"Enabled points",
"" // @TODO Missing documentation
};
+
+ constexpr openspace::properties::Property::PropertyInfo DownscaleVolumeRenderingInfo = {
+ "Downscale",
+ "Downscale Factor Volume Rendering",
+ "This value set the downscaling factor"
+ " when rendering the current volume."
+ };
+
+ constexpr openspace::properties::Property::PropertyInfo NumberOfRayCastingStepsInfo = {
+ "Steps",
+ "Number of RayCasting Steps",
+ "This value set the number of integration steps during the raycasting procedure."
+ };
} // namespace
namespace openspace {
@@ -135,6 +148,8 @@ namespace openspace {
, _enabledPointsRatio(EnabledPointsRatioInfo, 0.5f, 0.01f, 1.0f)
, _translation(TranslationInfo, glm::vec3(0.f), glm::vec3(0.f), glm::vec3(1.f))
, _rotation(RotationInfo, glm::vec3(0.f), glm::vec3(0.f), glm::vec3(6.28f))
+ , _downScaleVolumeRendering(DownscaleVolumeRenderingInfo, 1.f, 0.1f, 1.f)
+ , _numberOfRayCastingSteps(NumberOfRayCastingStepsInfo, 1000.f, 1.f, 1000.f)
{
dictionary.getValue("VolumeRenderingEnabled", _volumeRenderingEnabled);
dictionary.getValue("StarRenderingEnabled", _starRenderingEnabled);
@@ -224,6 +239,23 @@ namespace openspace {
LERROR("No volume dimensions specified.");
}
+ if (volumeDictionary.hasKey(NumberOfRayCastingStepsInfo.identifier)) {
+ _numberOfRayCastingSteps = static_cast(
+ volumeDictionary.value(NumberOfRayCastingStepsInfo.identifier)
+ );
+ }
+ else {
+ LINFO("Number of raycasting steps not specified. Using default value.");
+ }
+
+ _downScaleVolumeRendering.setVisibility(
+ openspace::properties::Property::Visibility::Developer
+ );
+ if (volumeDictionary.hasKey(DownscaleVolumeRenderingInfo.identifier)) {
+ _downScaleVolumeRendering =
+ volumeDictionary.value(DownscaleVolumeRenderingInfo.identifier);
+ }
+
if (!dictionary.hasKeyAndValue("Points")) {
LERROR("No points dictionary specified.");
}
@@ -307,6 +339,8 @@ void RenderableGalaxy::initializeGL() {
addProperty(_enabledPointsRatio);
addProperty(_translation);
addProperty(_rotation);
+ addProperty(_downScaleVolumeRendering);
+ addProperty(_numberOfRayCastingSteps);
// initialize points.
if (!_pointsFilename.empty()) {
@@ -470,6 +504,8 @@ void RenderableGalaxy::update(const UpdateData& data) {
volumeTransform[3] += translation;
_pointTransform[3] += translation;
+ _raycaster->setDownscaleRender(_downScaleVolumeRendering);
+ _raycaster->setMaxSteps(_numberOfRayCastingSteps);
_raycaster->setStepSize(_stepSize);
_raycaster->setAspect(_aspect);
_raycaster->setModelTransform(volumeTransform);
diff --git a/modules/galaxy/rendering/renderablegalaxy.h b/modules/galaxy/rendering/renderablegalaxy.h
index 0b49d848c4..d074bd848b 100644
--- a/modules/galaxy/rendering/renderablegalaxy.h
+++ b/modules/galaxy/rendering/renderablegalaxy.h
@@ -71,6 +71,8 @@ private:
properties::FloatProperty _enabledPointsRatio;
properties::Vec3Property _translation;
properties::Vec3Property _rotation;
+ properties::FloatProperty _downScaleVolumeRendering;
+ properties::FloatProperty _numberOfRayCastingSteps;
std::unique_ptr _pointSpreadFunctionTexture;
std::unique_ptr _pointSpreadFunctionFile;
diff --git a/modules/galaxy/shaders/galaxyraycast.glsl b/modules/galaxy/shaders/galaxyraycast.glsl
index a16188aa5d..dab687e3ca 100644
--- a/modules/galaxy/shaders/galaxyraycast.glsl
+++ b/modules/galaxy/shaders/galaxyraycast.glsl
@@ -29,17 +29,18 @@ uniform float absorptionMultiply#{id} = 50.0;
uniform float emissionMultiply#{id} = 1500.0;
uniform sampler3D galaxyTexture#{id};
-void sample#{id}(vec3 samplePos,
+void sample#{id}(
+ vec3 samplePos,
vec3 dir,
inout vec3 accumulatedColor,
inout vec3 accumulatedAlpha,
- inout float stepSize)
- {
+ inout float stepSize
+ ) {
vec3 aspect = aspect#{id};
stepSize = maxStepSize#{id} / length(dir / aspect);
//Early ray termination on black parts of the data
- vec3 normalizedPos = samplePos*2.0 - 1.0;
+ vec3 normalizedPos = samplePos * 2.f - 1.f;
if (normalizedPos.x * normalizedPos.x + normalizedPos.y * normalizedPos.y > 0.7) {
return;
}
@@ -51,12 +52,12 @@ void sample#{id}(vec3 samplePos,
sampledColor = sampledColor*sampledColor;
// Fudge for the dust "spreading"
- sampledColor.a = clamp(sampledColor.a, 0.0, 1.0);
- sampledColor.a = pow(sampledColor.a, 0.7);
+ sampledColor.a = clamp(sampledColor.a, 0.f, 1.f);
+ sampledColor.a = pow(sampledColor.a, 0.7f);
// Absorption probability
float scaledDensity = sampledColor.a * stepSize * absorptionMultiply#{id};
- vec3 alphaTint = vec3(0.3, 0.54, 0.85);
+ vec3 alphaTint = vec3(0.3f, 0.54f, 0.85f);
vec3 absorption = alphaTint * scaledDensity;
// Extinction
@@ -67,10 +68,10 @@ void sample#{id}(vec3 samplePos,
accumulatedColor.rgb +=
sampledColor.rgb * stepSize * emissionMultiply#{id} * opacityCoefficient#{id};
- vec3 oneMinusFrontAlpha = vec3(1.0) - accumulatedAlpha;
+ vec3 oneMinusFrontAlpha = vec3(1.f) - accumulatedAlpha;
accumulatedAlpha += oneMinusFrontAlpha * sampledColor.rgb * opacityCoefficient#{id};
}
float stepSize#{id}(vec3 samplePos, vec3 dir) {
- return maxStepSize#{id} * length(dir * 1.0 / aspect#{id});
+ return maxStepSize#{id} * length(dir * 1.f / aspect#{id});
}
diff --git a/modules/space/rendering/renderablesatellites.cpp b/modules/space/rendering/renderablesatellites.cpp
index 7453ff44f5..5476bf828f 100644
--- a/modules/space/rendering/renderablesatellites.cpp
+++ b/modules/space/rendering/renderablesatellites.cpp
@@ -66,13 +66,6 @@ namespace {
"method includes lines. If the rendering mode is set to Points, this value is "
"ignored."
};
- constexpr openspace::properties::Property::PropertyInfo FadeInfo = {
- "Fade",
- "Line fade",
- "The fading factor that is applied to the trail if the 'EnableFade' value is "
- "'true'. If it is 'false', this setting has no effect. The higher the number, "
- "the less fading is applied."
- };
constexpr openspace::properties::Property::PropertyInfo LineColorInfo = {
"Color",
"Color",
@@ -301,12 +294,6 @@ documentation::Documentation RenderableSatellites::Documentation() {
Optional::Yes,
LineWidthInfo.description
},
- {
- FadeInfo.identifier,
- new DoubleVerifier,
- Optional::Yes,
- FadeInfo.description
- },
{
LineColorInfo.identifier,
new DoubleVector3Verifier,
@@ -320,8 +307,7 @@ documentation::Documentation RenderableSatellites::Documentation() {
RenderableSatellites::RenderableSatellites(const ghoul::Dictionary& dictionary)
: Renderable(dictionary)
, _path(PathInfo)
- , _nSegments(SegmentsInfo)
- , _lineFade(FadeInfo)
+ , _nSegments(SegmentsInfo, 120, 4, 1024)
{
documentation::testSpecificationAndThrow(
@@ -332,16 +318,21 @@ RenderableSatellites::RenderableSatellites(const ghoul::Dictionary& dictionary)
_path = dictionary.value(PathInfo.identifier);
_nSegments = static_cast(dictionary.value(SegmentsInfo.identifier));
- _lineFade = static_cast(dictionary.value(FadeInfo.identifier));
if (dictionary.hasKeyAndValue(LineColorInfo.identifier)) {
_appearance.lineColor = dictionary.value(LineColorInfo.identifier);
}
+ auto reinitializeTrailBuffers = [this]() {
+ initializeGL();
+ };
+
+ _path.onChange(reinitializeTrailBuffers);
+ _nSegments.onChange(reinitializeTrailBuffers);
+
addPropertySubOwner(_appearance);
addProperty(_path);
addProperty(_nSegments);
- addProperty(_lineFade);
}
diff --git a/modules/space/rendering/renderablesatellites.h b/modules/space/rendering/renderablesatellites.h
index e052683cfc..b2bf0864a0 100644
--- a/modules/space/rendering/renderablesatellites.h
+++ b/modules/space/rendering/renderablesatellites.h
@@ -113,8 +113,6 @@ private:
properties::StringProperty _path;
properties::UIntProperty _nSegments;
- properties::DoubleProperty _lineFade;
-
RenderableTrail::Appearance _appearance;
glm::vec3 _position;
diff --git a/modules/space/shaders/star_ge.glsl b/modules/space/shaders/star_ge.glsl
index dcb36a5711..80ba2dd4f1 100644
--- a/modules/space/shaders/star_ge.glsl
+++ b/modules/space/shaders/star_ge.glsl
@@ -82,14 +82,6 @@ void main() {
vs_position = gl_in[0].gl_Position; // in object space
dvec4 dpos = modelMatrix * dvec4(vs_position);
- dvec4 clipTestPos = cameraViewProjectionMatrix * dpos;
- clipTestPos /= clipTestPos.w;
- if ((clipTestPos.x < -1.0 || clipTestPos.x > 1.0) ||
- (clipTestPos.y < -1.0 || clipTestPos.y > 1.0))
- {
- return;
- }
-
ge_bvLumAbsMagAppMag = vs_bvLumAbsMagAppMag[0];
ge_velocity = vs_velocity[0];
ge_speed = vs_speed[0];
@@ -156,96 +148,43 @@ void main() {
dvec3 scaledUp = dvec3(0.0);
vec4 bottomLeftVertex, bottomRightVertex, topLeftVertex, topRightVertex;
- // if (distanceToStarInParsecs > 1800.0) {
- // scaledRight = scaleMultiply * invariantRight * 0.5f;
- // scaledUp = scaleMultiply * invariantUp * 0.5f;
- // } else {
- dvec3 normal = normalize(eyePosition - dpos.xyz);
- dvec3 newRight = normalize(cross(cameraUp, normal));
- dvec3 newUp = cross(normal, newRight);
- scaledRight = scaleMultiply * newRight;
- scaledUp = scaleMultiply * newUp;
- //}
-
+ dvec3 normal = normalize(eyePosition - dpos.xyz);
+ dvec3 newRight = normalize(cross(cameraUp, normal));
+ dvec3 newUp = cross(normal, newRight);
+ scaledRight = scaleMultiply * newRight;
+ scaledUp = scaleMultiply * newUp;
+
bottomLeftVertex = z_normalization(vec4(cameraViewProjectionMatrix *
dvec4(dpos.xyz - scaledRight - scaledUp, dpos.w)));
gs_screenSpaceDepth = bottomLeftVertex.w;
- topRightVertex = z_normalization(vec4(cameraViewProjectionMatrix *
- dvec4(dpos.xyz + scaledUp + scaledRight, dpos.w)));
+ topRightVertex = z_normalization(vec4(cameraViewProjectionMatrix *
+ dvec4(dpos.xyz + scaledUp + scaledRight, dpos.w)));
- // Testing size:
- // vec3 tmpPos = vec3(eyePositionDelta);
- // vec4 falseBottomLeftVertex = z_normalization(vec4(cameraViewProjectionMatrix *
- // dvec4(tmpPos - scaledRight - scaledUp, dpos.w)));
+ bottomRightVertex = z_normalization(vec4(cameraViewProjectionMatrix *
+ dvec4(dpos.xyz + scaledRight - scaledUp, dpos.w)));
- // vec4 falseTopRightVertex = z_normalization(vec4(cameraViewProjectionMatrix *
- // dvec4(tmpPos + scaledUp + scaledRight, dpos.w)));
- // vec2 halfViewSize = vec2(screenSize.x, screenSize.y) * 0.5f;
- // vec2 topRight = falseTopRightVertex.xy/falseTopRightVertex.w;
- // vec2 bottomLeft = falseBottomLeftVertex.xy/falseBottomLeftVertex.w;
-
- // Complete algebra
- // topRight = ((topRight + vec2(1.0)) * halfViewSize) - vec2(0.5);
- // bottomLeft = ((bottomLeft + vec2(1.0)) * halfViewSize) - vec2(0.5);
- //vec2 sizes = abs(topRight - bottomLeft);
-
- // Optimized version
- // vec2 sizes = abs(halfViewSize * (topRight - bottomLeft));
-
- // float height = sizes.y;
- // float width = sizes.x;
-
- // if ((height > billboardSize) ||
- // (width > billboardSize)) {
- // float correctionScale = height > billboardSize ? billboardSize / height :
- // billboardSize / width;
-
- // scaledRight *= correctionScale;
- // scaledUp *= correctionScale;
- // bottomLeftVertex = z_normalization(vec4(cameraViewProjectionMatrix *
- // dvec4(dpos.xyz - scaledRight - scaledUp, dpos.w)));
- // gs_screenSpaceDepth = bottomLeftVertex.w;
- // topRightVertex = z_normalization(vec4(cameraViewProjectionMatrix *
- // dvec4(dpos.xyz + scaledUp + scaledRight, dpos.w)));
-
-
- // bottomRightVertex = z_normalization(vec4(cameraViewProjectionMatrix *
- // dvec4(dpos.xyz + scaledRight - scaledUp, dpos.w)));
-
- // topLeftVertex = z_normalization(vec4(cameraViewProjectionMatrix *
- // dvec4(dpos.xyz + scaledUp - scaledRight, dpos.w)));
-
- // } else {
- // if (width < 2.0f) {
- // float maxVar = 2.0f;
- // float minVar = 1.0f;
- // float var = (height + width);
- // float ta = ( (var - minVar)/(maxVar - minVar) );
- // if (ta == 0.0f)
- // return;
- // }
- // float minSize = 30.f;
- // if ((width < minSize) || (height < minSize))
- // return;
- bottomRightVertex = z_normalization(vec4(cameraViewProjectionMatrix *
- dvec4(dpos.xyz + scaledRight - scaledUp, dpos.w)));
- topLeftVertex = z_normalization(vec4(cameraViewProjectionMatrix *
+ topLeftVertex = z_normalization(vec4(cameraViewProjectionMatrix *
dvec4(dpos.xyz + scaledUp - scaledRight, dpos.w)));
- // }
-
+
// Build primitive
- gl_Position = topLeftVertex;
- psfCoords = vec2(-1.0, 1.0);
- EmitVertex();
+
gl_Position = bottomLeftVertex;
psfCoords = vec2(-1.0, -1.0);
EmitVertex();
- gl_Position = topRightVertex;
- psfCoords = vec2(1.0, 1.0);
- EmitVertex();
+
gl_Position = bottomRightVertex;
psfCoords = vec2(1.0, -1.0);
EmitVertex();
+
+ gl_Position = topLeftVertex;
+ psfCoords = vec2(-1.0, 1.0);
+ EmitVertex();
+
+ gl_Position = topRightVertex;
+ psfCoords = vec2(1.0, 1.0);
+ EmitVertex();
+
EndPrimitive();
+
}
diff --git a/modules/touch/CMakeLists.txt b/modules/touch/CMakeLists.txt
index 07190880d5..d0b7ec5289 100644
--- a/modules/touch/CMakeLists.txt
+++ b/modules/touch/CMakeLists.txt
@@ -26,6 +26,7 @@ include(${OPENSPACE_CMAKE_EXT_DIR}/module_definition.cmake)
set(HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/ext/levmarq.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/include/directinputsolver.h
${CMAKE_CURRENT_SOURCE_DIR}/include/tuioear.h
${CMAKE_CURRENT_SOURCE_DIR}/include/touchinteraction.h
${CMAKE_CURRENT_SOURCE_DIR}/include/touchmarker.h
@@ -35,6 +36,7 @@ source_group("Header Files" FILES ${HEADER_FILES})
set(SOURCE_FILES
${CMAKE_CURRENT_SOURCE_DIR}/ext/levmarq.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/directinputsolver.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/tuioear.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/touchinteraction.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/touchmarker.cpp
diff --git a/modules/touch/include/directinputsolver.h b/modules/touch/include/directinputsolver.h
new file mode 100644
index 0000000000..50f5cbeceb
--- /dev/null
+++ b/modules/touch/include/directinputsolver.h
@@ -0,0 +1,65 @@
+/*****************************************************************************************
+ * *
+ * OpenSpace *
+ * *
+ * Copyright (c) 2014-2019 *
+ * *
+ * 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_TOUCH___DIRECTINPUT_SOLVER___H__
+#define __OPENSPACE_MODULE_TOUCH___DIRECTINPUT_SOLVER___H__
+
+#include
+#include
+#include
+
+
+namespace openspace {
+
+class Camera;
+class SceneGraphNode;
+
+class DirectInputSolver {
+public:
+ // Stores the selected node, the cursor ID as well as the surface coordinates the
+ // cursor touched
+ struct SelectedBody {
+ long id;
+ SceneGraphNode* node;
+ glm::dvec3 coordinates;
+ };
+
+ DirectInputSolver();
+ bool solve(const std::vector& list,
+ const std::vector& selectedBodies,
+ std::vector* calculatedValues, const Camera& camera);
+ int getNDof() const;
+
+ const LMstat& getLevMarqStat();
+ void setLevMarqVerbosity(bool verbose);
+
+private:
+ int _nDof = 0;
+ LMstat _lmstat;
+};
+
+} // openspace namespace
+
+#endif // __OPENSPACE_MODULE_TOUCH___DIRECTINPUT_SOLVER___H__
+
diff --git a/modules/touch/include/touchinteraction.h b/modules/touch/include/touchinteraction.h
index f8de436b4b..7158973b70 100644
--- a/modules/touch/include/touchinteraction.h
+++ b/modules/touch/include/touchinteraction.h
@@ -27,7 +27,7 @@
#include
-#include
+#include
#include
#include
@@ -38,6 +38,8 @@
#include
#include
+#include
+
//#define TOUCH_DEBUG_PROPERTIES
//#define TOUCH_DEBUG_NODE_PICK_MESSAGES
@@ -79,27 +81,6 @@ public:
glm::dvec2 pan;
};
- // Stores the selected node, the cursor ID as well as the surface coordinates the
- // cursor touched
- struct SelectedBody {
- long id;
- SceneGraphNode* node;
- glm::dvec3 coordinates;
- };
-
- // Used in the LM algorithm
- struct FunctionData {
- std::vector selectedPoints;
- std::vector screenPoints;
- int nDOF;
- glm::dvec2(*castToNDC)(const glm::dvec3&, Camera&, SceneGraphNode*);
- double(*distToMinimize)(double* par, int x, void* fdata, LMstat* lmstat);
- Camera* camera;
- SceneGraphNode* node;
- LMstat stats;
- double objectScreenRadius;
- };
-
/* Main function call
* 1 Checks if doubleTap occured
* 2 Goes through the guiMode() function
@@ -256,9 +237,10 @@ private:
bool _zoomOutTap;
bool _lmSuccess;
bool _guiON;
- std::vector _selected;
+ std::vector _selected;
SceneGraphNode* _pickingSelected = nullptr;
- LMstat _lmstat;
+ DirectInputSolver _solver;
+
glm::dquat _toSlerp;
glm::dvec3 _centroid;
diff --git a/modules/touch/src/directinputsolver.cpp b/modules/touch/src/directinputsolver.cpp
new file mode 100644
index 0000000000..6ceed7dac4
--- /dev/null
+++ b/modules/touch/src/directinputsolver.cpp
@@ -0,0 +1,281 @@
+/*****************************************************************************************
+ * *
+ * OpenSpace *
+ * *
+ * Copyright (c) 2014-2019 *
+ * *
+ * 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
+
+#include
+#include
+
+namespace {
+ // Used in the LM algorithm
+ struct FunctionData {
+ std::vector selectedPoints;
+ std::vector screenPoints;
+ int nDOF;
+ const openspace::Camera* camera;
+ openspace::SceneGraphNode* node;
+ LMstat stats;
+ };
+}
+
+namespace openspace {
+
+DirectInputSolver::DirectInputSolver() {
+ levmarq_init(&_lmstat);
+}
+
+// project back a 3D point in model view to clip space [-1,1] coordinates on the view plane
+glm::dvec2 castToNDC(const glm::dvec3& vec, Camera& camera, SceneGraphNode* node) {
+ glm::dvec3 posInCamSpace = glm::inverse(camera.rotationQuaternion()) *
+ (node->worldRotationMatrix() * vec +
+ (node->worldPosition() - camera.positionVec3()));
+
+ glm::dvec4 clipspace = camera.projectionMatrix() * glm::dvec4(posInCamSpace, 1.0);
+ return (glm::dvec2(clipspace) / clipspace.w);
+}
+
+// Returns the screen point s(xi,par) dependent the transform M(par) and object point xi
+double distToMinimize(double* par, int x, void* fdata, LMstat* lmstat) {
+ FunctionData* ptr = reinterpret_cast(fdata);
+
+ // Apply transform to camera and find the new screen point of the updated camera state
+
+ // { vec2 globalRot, zoom, roll, vec2 localRot }
+ double q[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
+ for (int i = 0; i < ptr->nDOF; ++i) {
+ q[i] = par[i];
+ }
+
+ using namespace glm;
+ // Create variables from current state
+ dvec3 camPos = ptr->camera->positionVec3();
+ dvec3 centerPos = ptr->node->worldPosition();
+
+ dvec3 directionToCenter = normalize(centerPos - camPos);
+ dvec3 lookUp = ptr->camera->lookUpVectorWorldSpace();
+ dvec3 camDirection = ptr->camera->viewDirectionWorldSpace();
+
+ // Make a representation of the rotation quaternion with local and global
+ // rotations
+ dmat4 lookAtMat = lookAt(
+ dvec3(0, 0, 0),
+ directionToCenter,
+ // To avoid problem with lookup in up direction
+ normalize(camDirection + lookUp));
+ dquat globalCamRot = normalize(quat_cast(inverse(lookAtMat)));
+ dquat localCamRot = inverse(globalCamRot) * ptr->camera->rotationQuaternion();
+
+ { // Roll
+ dquat rollRot = angleAxis(q[3], dvec3(0.0, 0.0, 1.0));
+ localCamRot = localCamRot * rollRot;
+ }
+ { // Panning (local rotation)
+ dvec3 eulerAngles(q[5], q[4], 0);
+ dquat panRot = dquat(eulerAngles);
+ localCamRot = localCamRot * panRot;
+ }
+ { // Orbit (global rotation)
+ dvec3 eulerAngles(q[1], q[0], 0);
+ dquat rotationDiffCamSpace = dquat(eulerAngles);
+
+ dvec3 centerToCamera = camPos - centerPos;
+
+ dquat rotationDiffWorldSpace =
+ globalCamRot * rotationDiffCamSpace * inverse(globalCamRot);
+ dvec3 rotationDiffVec3 = centerToCamera * rotationDiffWorldSpace - centerToCamera;
+ camPos += rotationDiffVec3;
+
+ centerToCamera = camPos - centerPos;
+ directionToCenter = normalize(-centerToCamera);
+ dvec3 lookUpWhenFacingCenter =
+ globalCamRot * dvec3(ptr->camera->lookUpVectorCameraSpace());
+ lookAtMat = lookAt(
+ dvec3(0, 0, 0),
+ directionToCenter,
+ lookUpWhenFacingCenter
+ );
+ globalCamRot = normalize(quat_cast(inverse(lookAtMat)));
+ }
+ { // Zooming
+ camPos += directionToCenter * q[2];
+ }
+ // Update the camera state
+ Camera cam = *(ptr->camera);
+ cam.setPositionVec3(camPos);
+ cam.setRotation(globalCamRot * localCamRot);
+
+ // we now have a new position and orientation of camera, project surfacePoint to
+ // the new screen to get distance to minimize
+ glm::dvec2 newScreenPoint = castToNDC(
+ ptr->selectedPoints.at(x),
+ cam,
+ ptr->node
+ );
+ lmstat->pos.push_back(newScreenPoint);
+ return glm::length(ptr->screenPoints.at(x) - newScreenPoint);
+}
+
+// Gradient of distToMinimize w.r.t par (using forward difference)
+void gradient(double* g, double* par, int x, void* fdata, LMstat* lmstat) {
+ FunctionData* ptr = reinterpret_cast(fdata);
+ double f0 = distToMinimize(par, x, fdata, lmstat);
+ // scale value to find minimum step size h, dependant on planet size
+ double scale = log10(ptr->node->boundingSphere());
+ std::vector dPar(ptr->nDOF, 0.0);
+ dPar.assign(par, par + ptr->nDOF);
+
+ for (int i = 0; i < ptr->nDOF; ++i) {
+ // Initial values
+ double h = 1e-8;
+ double lastG = 1;
+ dPar.at(i) += h;
+ double f1 = distToMinimize(dPar.data(), x, fdata, lmstat);
+ dPar.at(i) = par[i];
+ // Iterative process to find the minimum step h that gives a good gradient
+ for (int j = 0; j < 100; ++j) {
+ if ((f1 - f0) != 0 && lastG == 0) { // found minimum step size h
+ // scale up to get a good initial guess value
+ h *= scale * scale * scale;
+
+ // clamp min step size to a fraction of the incoming parameter
+ if (i == 2) {
+ double epsilon = 1e-3;
+ // make sure incoming parameter is larger than 0
+ h = std::max(std::max(std::abs(dPar.at(i)), epsilon) * 0.001, h);
+ }
+ else if (ptr->nDOF == 2) {
+ h = std::max(std::abs(dPar.at(i)) * 0.001, h);
+ }
+
+ // calculate f1 with good h for finite difference
+ dPar.at(i) += h;
+ f1 = distToMinimize(dPar.data(), x, fdata, lmstat);
+ dPar.at(i) = par[i];
+ break;
+ }
+ else if ((f1 - f0) != 0 && lastG != 0) { // h too big
+ h /= scale;
+ }
+ else if ((f1 - f0) == 0) { // h too small
+ h *= scale;
+ }
+ lastG = f1 - f0;
+ dPar.at(i) += h;
+ f1 = distToMinimize(dPar.data(), x, fdata, lmstat);
+ dPar.at(i) = par[i];
+ }
+ g[i] = (f1 - f0) / h;
+ }
+ if (ptr->nDOF == 2) {
+ // normalize on 1 finger case to allow for horizontal/vertical movement
+ for (int i = 0; i < 2; ++i) {
+ g[i] = g[i] / std::abs(g[i]);
+ }
+ }
+ else if (ptr->nDOF == 6) {
+ for (int i = 0; i < ptr->nDOF; ++i) {
+ // lock to only pan and zoom on 3 finger case, no roll/orbit
+ g[i] = (i == 2) ? g[i] : g[i] / std::abs(g[i]);
+ }
+ }
+}
+
+bool DirectInputSolver::solve(const std::vector& list,
+ const std::vector& selectedBodies,
+ std::vector* parameters, const Camera& camera)
+{
+ int nFingers = std::min(static_cast(list.size()), 3);
+ _nDof = std::min(nFingers * 2, 6);
+
+ // Parse input data to be used in the LM algorithm
+ std::vector selectedPoints;
+ std::vector screenPoints;
+
+ for (int i = 0; i < nFingers; ++i) {
+ const SelectedBody& sb = selectedBodies.at(i);
+ selectedPoints.push_back(sb.coordinates);
+ screenPoints.emplace_back(
+ 2 * (list[i].getX() - 0.5),
+ -2 * (list[i].getY() - 0.5)
+ );
+
+ // This might be needed when we're directing the touchtable from another screen?
+ // std::vector::const_iterator c = std::find_if(
+ // list.begin(),
+ // list.end(),
+ // [&sb](const TuioCursor& c) { return c.getSessionID() == sb.id; }
+ // );
+ // if (c != list.end()) {
+ // // normalized -1 to 1 coordinates on screen
+ // screenPoints.emplace_back(2 * (c->getX() - 0.5), -2 * (c->getY() - 0.5));
+ // }
+ // else {
+ // global::moduleEngine.module()->touchInput = {
+ // true,
+ // glm::dvec2(0.0, 0.0),
+ // 1
+ // };
+ // resetAfterInput();
+ // return;
+ // }
+ }
+
+ FunctionData fData = {
+ selectedPoints,
+ screenPoints,
+ _nDof,
+ &camera,
+ selectedBodies.at(0).node,
+ _lmstat
+ };
+ void* dataPtr = reinterpret_cast(&fData);
+
+ bool result = levmarq(
+ _nDof,
+ parameters->data(),
+ static_cast(screenPoints.size()),
+ nullptr,
+ distToMinimize,
+ gradient,
+ dataPtr,
+ &_lmstat
+ );
+
+ return result;
+}
+
+int DirectInputSolver::getNDof() const {
+ return _nDof;
+}
+
+const LMstat& DirectInputSolver::getLevMarqStat() {
+ return _lmstat;
+}
+
+void DirectInputSolver::setLevMarqVerbosity(bool verbose) {
+ _lmstat.verbose = verbose;
+}
+
+} // openspace namespace
+
diff --git a/modules/touch/src/touchinteraction.cpp b/modules/touch/src/touchinteraction.cpp
index 1653b13248..eab3fa0185 100644
--- a/modules/touch/src/touchinteraction.cpp
+++ b/modules/touch/src/touchinteraction.cpp
@@ -23,7 +23,9 @@
****************************************************************************************/
#include
+
#include
+#include
#include
#include
@@ -369,11 +371,8 @@ TouchInteraction::TouchInteraction()
}
});
- levmarq_init(&_lmstat);
-
_time.initSession();
}
-
// Called each frame if there is any input
void TouchInteraction::updateStateFromInput(const std::vector& list,
std::vector& lastProcessed)
@@ -513,231 +512,21 @@ void TouchInteraction::directControl(const std::vector& list) {
#ifdef TOUCH_DEBUG_PROPERTIES
LINFO("DirectControl");
#endif
- // Returns the screen point s(xi,par) dependent the transform M(par) and object
- // point xi
- auto distToMinimize = [](double* par, int x, void* fdata, LMstat* lmstat) {
- FunctionData* ptr = reinterpret_cast(fdata);
-
- // Apply transform to camera and find the new screen point of the updated camera
- // state
-
- // { vec2 globalRot, zoom, roll, vec2 localRot }
- double q[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
- for (int i = 0; i < ptr->nDOF; ++i) {
- q[i] = par[i];
- }
-
- using namespace glm;
- // Create variables from current state
- dvec3 camPos = ptr->camera->positionVec3();
- dvec3 centerPos = ptr->node->worldPosition();
-
- dvec3 directionToCenter = normalize(centerPos - camPos);
- dvec3 lookUp = ptr->camera->lookUpVectorWorldSpace();
- dvec3 camDirection = ptr->camera->viewDirectionWorldSpace();
-
- // Make a representation of the rotation quaternion with local and global
- // rotations
- dmat4 lookAtMat = lookAt(
- dvec3(0, 0, 0),
- directionToCenter,
- // To avoid problem with lookup in up direction
- normalize(camDirection + lookUp));
- dquat globalCamRot = normalize(quat_cast(inverse(lookAtMat)));
- dquat localCamRot = inverse(globalCamRot) * ptr->camera->rotationQuaternion();
-
- { // Roll
- dquat rollRot = angleAxis(q[3], dvec3(0.0, 0.0, 1.0));
- localCamRot = localCamRot * rollRot;
- }
- { // Panning (local rotation)
- dvec3 eulerAngles(q[5], q[4], 0);
- dquat panRot = dquat(eulerAngles);
- localCamRot = localCamRot * panRot;
- }
- { // Orbit (global rotation)
- dvec3 eulerAngles(q[1], q[0], 0);
- dquat rotationDiffCamSpace = dquat(eulerAngles);
-
- dvec3 centerToCamera = camPos - centerPos;
-
- dquat rotationDiffWorldSpace =
- globalCamRot * rotationDiffCamSpace * inverse(globalCamRot);
- dvec3 rotationDiffVec3 =
- centerToCamera * rotationDiffWorldSpace - centerToCamera;
- camPos += rotationDiffVec3;
-
- centerToCamera = camPos - centerPos;
- directionToCenter = normalize(-centerToCamera);
- dvec3 lookUpWhenFacingCenter =
- globalCamRot * dvec3(ptr->camera->lookUpVectorCameraSpace());
- lookAtMat = lookAt(
- dvec3(0, 0, 0),
- directionToCenter,
- lookUpWhenFacingCenter);
- globalCamRot = normalize(quat_cast(inverse(lookAtMat)));
- }
- { // Zooming
- camPos += directionToCenter * q[2];
- }
- // Update the camera state
- Camera cam = *(ptr->camera);
- cam.setPositionVec3(camPos);
- cam.setRotation(globalCamRot * localCamRot);
-
- // we now have a new position and orientation of camera, project surfacePoint to
- // the new screen to get distance to minimize
- glm::dvec2 newScreenPoint = ptr->castToNDC(
- ptr->selectedPoints.at(x),
- cam,
- ptr->node
- );
- lmstat->pos.push_back(newScreenPoint);
- return glm::length(ptr->screenPoints.at(x) - newScreenPoint);
- };
- // Gradient of distToMinimize w.r.t par (using forward difference)
- auto gradient = [](double* g, double* par, int x, void* fdata, LMstat* lmstat) {
- FunctionData* ptr = reinterpret_cast(fdata);
- double h, lastG, f1, f0 = ptr->distToMinimize(par, x, fdata, lmstat);
- // scale value to find minimum step size h, dependant on planet size
- double scale = log10(ptr->node->boundingSphere());
- std::vector dPar(ptr->nDOF, 0.0);
- dPar.assign(par, par + ptr->nDOF);
-
- for (int i = 0; i < ptr->nDOF; ++i) {
- // Initial values
- h = 1e-8;
- lastG = 1;
- dPar.at(i) += h;
- f1 = ptr->distToMinimize(dPar.data(), x, fdata, lmstat);
- dPar.at(i) = par[i];
- // Iterative process to find the minimum step h that gives a good gradient
- for (int j = 0; j < 100; ++j) {
- if ((f1 - f0) != 0 && lastG == 0) { // found minimum step size h
- // scale up to get a good initial guess value
- h *= scale * scale * scale;
-
- // clamp min step size to a fraction of the incoming parameter
- if (i == 2) {
- double epsilon = 1e-3;
- // make sure incoming parameter is larger than 0
- h = std::max(std::max(std::abs(dPar.at(i)), epsilon) * 0.001, h);
- }
- else if (ptr->nDOF == 2) {
- h = std::max(std::abs(dPar.at(i)) * 0.001, h);
- }
-
- // calculate f1 with good h for finite difference
- dPar.at(i) += h;
- f1 = ptr->distToMinimize(dPar.data(), x, fdata, lmstat);
- dPar.at(i) = par[i];
- break;
- }
- else if ((f1 - f0) != 0 && lastG != 0) { // h too big
- h /= scale;
- }
- else if ((f1 - f0) == 0) { // h too small
- h *= scale;
- }
- lastG = f1 - f0;
- dPar.at(i) += h;
- f1 = ptr->distToMinimize(dPar.data(), x, fdata, lmstat);
- dPar.at(i) = par[i];
- }
- g[i] = (f1 - f0) / h;
- }
- if (ptr->nDOF == 2) {
- // normalize on 1 finger case to allow for horizontal/vertical movement
- for (int i = 0; i < 2; ++i) {
- g[i] = g[i]/std::abs(g[i]);
- }
- }
- else if (ptr->nDOF == 6) {
- for (int i = 0; i < ptr->nDOF; ++i) {
- // lock to only pan and zoom on 3 finger case, no roll/orbit
- g[i] = (i == 2) ? g[i] : g[i] / std::abs(g[i]);
- }
- }
- };
-
- // project back a 3D point in model view to clip space [-1,1] coordinates on the view
- // plane
- auto castToNDC = [](const glm::dvec3& vec, Camera& camera, SceneGraphNode* node) {
- glm::dvec3 posInCamSpace = glm::inverse(camera.rotationQuaternion()) *
- (node->rotationMatrix() * vec +
- (node->worldPosition() - camera.positionVec3()));
-
- glm::dvec4 clipspace = camera.projectionMatrix() * glm::dvec4(posInCamSpace, 1.0);
- return (glm::dvec2(clipspace) / clipspace.w);
- };
-
- // only send in first three fingers (to make it easier for LMA to converge on 3+
- // finger case with only zoom/pan)
- int nFingers = std::min(static_cast(list.size()), 3);
- int nDOF = std::min(nFingers * 2, 6);
- std::vector par(nDOF, 0.0);
- par.at(0) = _lastVel.orbit.x; // use _lastVel for orbit
- par.at(1) = _lastVel.orbit.y;
-
- // Parse input data to be used in the LM algorithm
- std::vector selectedPoints;
- std::vector screenPoints;
- for (int i = 0; i < nFingers; ++i) {
- const SelectedBody& sb = _selected.at(i);
- selectedPoints.push_back(sb.coordinates);
-
- std::vector::const_iterator c = std::find_if(
- list.begin(),
- list.end(),
- [&sb](const TuioCursor& c) { return c.getSessionID() == sb.id; }
- );
- if (c != list.end()) {
- // normalized -1 to 1 coordinates on screen
- screenPoints.emplace_back(2 * (c->getX() - 0.5), -2 * (c->getY() - 0.5));
- }
- else {
- global::moduleEngine.module()->touchInput = {
- true,
- glm::dvec2(0.0, 0.0),
- 1
- };
- resetAfterInput();
- return;
- }
- }
-
- FunctionData fData = {
- selectedPoints,
- screenPoints,
- nDOF,
- castToNDC,
- distToMinimize,
- _camera,
- _selected.at(0).node,
- _lmstat,
- _currentRadius
- };
- void* dataPtr = reinterpret_cast(&fData);
// finds best transform values for the new camera state and stores them in par
- _lmSuccess = levmarq(
- nDOF,
- par.data(),
- static_cast(screenPoints.size()),
- nullptr,
- distToMinimize,
- gradient,
- dataPtr,
- &_lmstat
- );
+ std::vector par(6, 0.0);
+ par.at(0) = _lastVel.orbit.x; // use _lastVel for orbit
+ par.at(1) = _lastVel.orbit.y;
+ _lmSuccess = _solver.solve(list, _selected, &par, *_camera);
+ int nDof = _solver.getNDof();
if (_lmSuccess && !_unitTest) {
// if good values were found set new camera state
_vel.orbit = glm::dvec2(par.at(0), par.at(1));
- if (nDOF > 2) {
+ if (nDof > 2) {
_vel.zoom = par.at(2);
_vel.roll = par.at(3);
- if (_panEnabled && nDOF > 4) {
+ if (_panEnabled && nDof > 4) {
_vel.roll = 0.0;
_vel.pan = glm::dvec2(par.at(4), par.at(5));
}
@@ -784,20 +573,18 @@ void TouchInteraction::findSelectedNode(const std::vector& list) {
glm::dquat camToWorldSpace = _camera->rotationQuaternion();
glm::dvec3 camPos = _camera->positionVec3();
- std::vector newSelected;
-
- struct PickingInfo {
- SceneGraphNode* node;
- double pickingDistanceNDC;
- double pickingDistanceWorld;
+ std::vector newSelected;
+
+ //node & distance
+ std::tuple currentlyPicked = {
+ nullptr,
+ std::numeric_limits::max()
};
- std::vector pickingInfo;
-
+
for (const TuioCursor& c : list) {
double xCo = 2 * (c.getX() - 0.5);
double yCo = -2 * (c.getY() - 0.5); // normalized -1 to 1 coordinates on screen
- // vec3(projectionmatrix * clipspace), divide with w?
glm::dvec3 cursorInWorldSpace = camToWorldSpace *
glm::dvec3(glm::inverse(_camera->projectionMatrix()) *
glm::dvec4(xCo, yCo, -1.0, 1.0));
@@ -806,28 +593,27 @@ void TouchInteraction::findSelectedNode(const std::vector& list) {
long id = c.getSessionID();
for (SceneGraphNode* node : selectableNodes) {
- double boundingSphere = node->boundingSphere();
+ double boundingSphereSquared = static_cast(node->boundingSphere()) *
+ static_cast(node->boundingSphere());
glm::dvec3 camToSelectable = node->worldPosition() - camPos;
- double dist = length(glm::cross(cursorInWorldSpace, camToSelectable)) /
- glm::length(cursorInWorldSpace) - boundingSphere;
- if (dist <= 0.0) {
- // finds intersection closest point between boundingsphere and line in
- // world coordinates, assumes line direction is normalized
- double d = glm::dot(raytrace, camToSelectable);
- double root = boundingSphere * boundingSphere -
- glm::dot(camToSelectable, camToSelectable) + d * d;
- if (root > 0) { // two intersection points (take the closest one)
- d -= sqrt(root);
- }
- glm::dvec3 intersectionPoint = camPos + d * raytrace;
- glm::dvec3 pointInModelView = glm::inverse(node->rotationMatrix()) *
- (intersectionPoint - node->worldPosition());
+ double intersectionDist = 0.0;
+ bool intersected = glm::intersectRaySphere(
+ camPos,
+ raytrace,
+ node->worldPosition(),
+ boundingSphereSquared,
+ intersectionDist
+ );
+ if (intersected) {
+ glm::dvec3 intersectionPos = camPos + raytrace * intersectionDist;
+ glm::dvec3 pointInModelView = glm::inverse(node->worldRotationMatrix()) *
+ (intersectionPos - node->worldPosition());
// Add id, node and surface coordinates to the selected list
- std::vector::iterator oldNode = std::find_if(
+ auto oldNode = std::find_if(
newSelected.begin(),
newSelected.end(),
- [id](SelectedBody s) { return s.id == id; }
+ [id](const DirectInputSolver::SelectedBody& s) { return s.id == id; }
);
if (oldNode != newSelected.end()) {
double oldNodeDist = glm::length(
@@ -859,56 +645,44 @@ void TouchInteraction::findSelectedNode(const std::vector& list) {
// We either want to select the object if it's bounding sphere as been
// touched (checked by the first part of this loop above) or if the touch
// point is within a minimum distance of the center
- if (dist <= 0.0 || (ndcDist <= _pickingRadiusMinimum)) {
- // If the user touched the planet directly, this is definitely the one
- // they are interested in => minimum distance
- if (dist <= 0.0) {
+ // If the user touched the planet directly, this is definitely the one
+ // they are interested in => minimum distance
+ if (intersected) {
#ifdef TOUCH_DEBUG_NODE_PICK_MESSAGES
- LINFOC(
- node->identifier(),
- "Picking candidate based on direct touch"
- );
+ LINFOC(
+ node->identifier(),
+ "Picking candidate based on direct touch"
+ );
#endif //#ifdef TOUCH_DEBUG_NODE_PICK_MESSAGES
- pickingInfo.push_back({
- node,
- -std::numeric_limits::max(),
- -std::numeric_limits::max()
- });
- }
- else {
- // The node was considered due to minimum picking distance radius
+ currentlyPicked = {
+ node,
+ -std::numeric_limits::max()
+ };
+ }
+ else if (ndcDist <= _pickingRadiusMinimum) {
+ // The node was considered due to minimum picking distance radius
#ifdef TOUCH_DEBUG_NODE_PICK_MESSAGES
- LINFOC(
- node->identifier(),
- "Picking candidate based on proximity"
- );
+ LINFOC(
+ node->identifier(),
+ "Picking candidate based on proximity"
+ );
#endif //#ifdef TOUCH_DEBUG_NODE_PICK_MESSAGES
- pickingInfo.push_back({
+ double dist = length(camToSelectable);
+ if (dist < std::get<1>(currentlyPicked)) {
+ currentlyPicked = {
node,
- ndcDist,
dist
- });
+ };
}
}
}
}
}
-
- // After we are done with all of the nodes, we can sort the picking list and pick the
- // one that fits best (= is closest or was touched directly)
- std::sort(
- pickingInfo.begin(),
- pickingInfo.end(),
- [](const PickingInfo& lhs, const PickingInfo& rhs) {
- return lhs.pickingDistanceWorld < rhs.pickingDistanceWorld;
- }
- );
-
// If an item has been picked, it's in the first position of the vector now
- if (!pickingInfo.empty()) {
- _pickingSelected = pickingInfo.begin()->node;
+ if (SceneGraphNode* node = std::get<0>(currentlyPicked)) {
+ _pickingSelected = node;
#ifdef TOUCH_DEBUG_NODE_PICK_MESSAGES
LINFOC("Picking", "Picked node: " + _pickingSelected->identifier());
#endif //#ifdef TOUCH_DEBUG_NODE_PICK_MESSAGES
@@ -1360,8 +1134,11 @@ void TouchInteraction::step(double dt) {
else if (_zoomInLimit.value() < zoomInBounds) {
// If zoom in limit is less than the estimated node radius we need to
// make sure we do not get too close to possible height maps
- SurfacePositionHandle posHandle = anchor->calculateSurfacePositionHandle(camPos);
- glm::dvec3 centerToActualSurfaceModelSpace = posHandle.centerToReferenceSurface +
+ SurfacePositionHandle posHandle = anchor->calculateSurfacePositionHandle(
+ camPos
+ );
+ glm::dvec3 centerToActualSurfaceModelSpace =
+ posHandle.centerToReferenceSurface +
posHandle.referenceSurfaceOutDirection * posHandle.heightToSurface;
glm::dvec3 centerToActualSurface = glm::dmat3(anchor->modelTransform()) *
centerToActualSurfaceModelSpace;
@@ -1370,9 +1147,8 @@ void TouchInteraction::step(double dt) {
// Because of heightmaps we should make sure we do not go through the surface
if (_zoomInLimit.value() < nodeRadius) {
#ifdef TOUCH_DEBUG_PROPERTIES
- LINFO(fmt::format(
- "{}: Zoom In Limit should be larger than anchor center to surface, setting it to {}",
- _loggerCat, zoomInBounds));
+ LINFO(fmt::format("{}: Zoom In limit should be larger than anchor "
+ "center to surface, setting it to {}", _loggerCat, zoomInBounds));
#endif
_zoomInLimit.setValue(zoomInBounds);
}
@@ -1392,9 +1168,12 @@ void TouchInteraction::step(double dt) {
double currentPosDistance = length(centerToCamera);
// Possible with other navigations performed outside touch interaction
- bool currentPosViolatingZoomOutLimit = (currentPosDistance >= _zoomOutLimit.value());
- bool willNewPositionViolateZoomOutLimit = (newPosDistance >= _zoomOutLimit.value());
- bool willNewPositionViolateZoomInLimit = (newPosDistance < _zoomInLimit.value());
+ bool currentPosViolatingZoomOutLimit =
+ (currentPosDistance >= _zoomOutLimit.value());
+ bool willNewPositionViolateZoomOutLimit =
+ (newPosDistance >= _zoomOutLimit.value());
+ bool willNewPositionViolateZoomInLimit =
+ (newPosDistance < _zoomInLimit.value());
if (!willNewPositionViolateZoomInLimit && !willNewPositionViolateZoomOutLimit){
camPos += zoomDistanceIncrement;
@@ -1447,7 +1226,7 @@ void TouchInteraction::step(double dt) {
void TouchInteraction::unitTest() {
if (_unitTest) {
- _lmstat.verbose = true;
+ _solver.setLevMarqVerbosity(true);
// set _selected pos and new pos (on screen)
std::vector lastFrame = {
@@ -1468,7 +1247,7 @@ void TouchInteraction::unitTest() {
snprintf(buffer, sizeof(char) * 32, "lmdata%i.csv", _numOfTests);
_numOfTests++;
std::ofstream file(buffer);
- file << _lmstat.data;
+ file << _solver.getLevMarqStat().data;
// clear everything
_selected.clear();
@@ -1480,6 +1259,7 @@ void TouchInteraction::unitTest() {
_lastVel = _vel;
_unitTest = false;
+ _solver.setLevMarqVerbosity(false);
// could be the camera copy in func
}
}
diff --git a/modules/touch/src/win32_touch.cpp b/modules/touch/src/win32_touch.cpp
index 8d248d3a63..03ded0a114 100644
--- a/modules/touch/src/win32_touch.cpp
+++ b/modules/touch/src/win32_touch.cpp
@@ -28,11 +28,8 @@
#include
#include
-
#include
-
#include
-
#include
#include
@@ -42,7 +39,7 @@ namespace {
bool gStarted{ false };
TUIO::TuioServer* gTuioServer{ nullptr };
std::unordered_map gCursorMap;
-}
+} // namespace
namespace openspace {
@@ -69,22 +66,32 @@ LRESULT CALLBACK HookCallback(int nCode, WPARAM wParam, LPARAM lParam) {
// native touch to screen conversion
ScreenToClient(pStruct->hwnd, reinterpret_cast(&p));
- float xPos = (float)p.x / (float)(rect.right - rect.left);
- float yPos = (float)p.y / (float)(rect.bottom - rect.top);
+ float xPos = static_cast(p.x) /
+ static_cast(rect.right - rect.left);
+ float yPos = static_cast(p.y) /
+ static_cast(rect.bottom - rect.top);
if (pointerInfo.pointerFlags & POINTER_FLAG_DOWN) {
// Handle new touchpoint
gTuioServer->initFrame(TUIO::TuioTime::getSessionTime());
- gCursorMap[pointerInfo.pointerId] = gTuioServer->addTuioCursor(xPos, yPos);
+ gCursorMap[pointerInfo.pointerId] = gTuioServer->addTuioCursor(
+ xPos,
+ yPos
+ );
gTuioServer->commitFrame();
}
else if (pointerInfo.pointerFlags & POINTER_FLAG_UPDATE) {
// Handle update of touchpoint
TUIO::TuioTime frameTime = TUIO::TuioTime::getSessionTime();
- if (gCursorMap[pointerInfo.pointerId]->getTuioTime() == frameTime) {
+ if (gCursorMap[pointerInfo.pointerId]->getTuioTime() == frameTime)
+ {
break;
}
gTuioServer->initFrame(frameTime);
- gTuioServer->updateTuioCursor(gCursorMap[pointerInfo.pointerId], xPos, yPos);
+ gTuioServer->updateTuioCursor(
+ gCursorMap[pointerInfo.pointerId],
+ xPos,
+ yPos
+ );
gTuioServer->commitFrame();
}
else if (pointerInfo.pointerFlags & POINTER_FLAG_UP) {
@@ -139,14 +146,23 @@ Win32TouchHook::Win32TouchHook(void* nativeWindow)
const DWORD dwHwndTabletProperty = TABLET_DISABLE_PRESSANDHOLD;
ATOM atom = ::GlobalAddAtom(MICROSOFT_TABLETPENSERVICE_PROPERTY);
- ::SetProp(hWnd, MICROSOFT_TABLETPENSERVICE_PROPERTY, reinterpret_cast(dwHwndTabletProperty));
+ ::SetProp(
+ hWnd,
+ MICROSOFT_TABLETPENSERVICE_PROPERTY,
+ reinterpret_cast(dwHwndTabletProperty)
+ );
::GlobalDeleteAtom(atom);
if (!gStarted) {
gStarted = true;
gTuioServer = new TUIO::TuioServer("localhost", 3333);
TUIO::TuioTime::initSession();
- gTouchHook = SetWindowsHookExW(WH_GETMESSAGE, HookCallback, GetModuleHandleW(NULL), GetCurrentThreadId());
+ gTouchHook = SetWindowsHookExW(
+ WH_GETMESSAGE,
+ HookCallback,
+ GetModuleHandleW(NULL),
+ GetCurrentThreadId()
+ );
if (!gTouchHook) {
LINFO(fmt::format("Failed to setup WindowsHook for touch input redirection"));
delete gTuioServer;
diff --git a/modules/touch/touchmodule.cpp b/modules/touch/touchmodule.cpp
index a47e2fe4d2..f968095a44 100644
--- a/modules/touch/touchmodule.cpp
+++ b/modules/touch/touchmodule.cpp
@@ -164,7 +164,7 @@ TouchModule::TouchModule()
if (nativeWindowHandle) {
_win32TouchHook.reset(new Win32TouchHook(nativeWindowHandle));
}
-#endif //WIN32
+#endif
});
global::callback::deinitializeGL.push_back([&]() {
diff --git a/modules/toyvolume/rendering/renderabletoyvolume.cpp b/modules/toyvolume/rendering/renderabletoyvolume.cpp
index ccb5018780..a5c37bf4e2 100644
--- a/modules/toyvolume/rendering/renderabletoyvolume.cpp
+++ b/modules/toyvolume/rendering/renderabletoyvolume.cpp
@@ -29,8 +29,10 @@
#include
#include
#include
+#include
namespace {
+ constexpr const char* _loggerCat = "Renderable ToyVolume";
constexpr openspace::properties::Property::PropertyInfo SizeInfo = {
"Size",
"Size",
@@ -66,6 +68,13 @@ namespace {
"Color",
"" // @TODO Missing documentation
};
+
+ constexpr openspace::properties::Property::PropertyInfo DownscaleVolumeRenderingInfo = {
+ "Downscale",
+ "Downscale Factor Volume Rendering",
+ "This value set the downscaling factor"
+ " when rendering the current volume."
+ };
} // namespace
namespace openspace {
@@ -78,6 +87,7 @@ RenderableToyVolume::RenderableToyVolume(const ghoul::Dictionary& dictionary)
, _translation(TranslationInfo, glm::vec3(0.f), glm::vec3(0.f), glm::vec3(10.f))
, _rotation(RotationInfo, glm::vec3(0.f, 0.f, 0.f), glm::vec3(0), glm::vec3(6.28f))
, _color(ColorInfo, glm::vec4(1.f, 0.f, 0.f, 0.1f), glm::vec4(0.f), glm::vec4(1.f))
+ , _downScaleVolumeRendering(DownscaleVolumeRenderingInfo, 1.f, 0.1f, 1.f)
{
if (dictionary.hasKeyAndValue(ScalingExponentInfo.identifier)) {
_scalingExponent = static_cast(
@@ -104,6 +114,22 @@ RenderableToyVolume::RenderableToyVolume(const ghoul::Dictionary& dictionary)
if (dictionary.hasKeyAndValue(StepSizeInfo.identifier)) {
_stepSize = static_cast(dictionary.value(StepSizeInfo.identifier));
}
+
+ _downScaleVolumeRendering.setVisibility(
+ openspace::properties::Property::Visibility::Developer
+ );
+ if (dictionary.hasKey("Downscale")) {
+ _downScaleVolumeRendering = dictionary.value("Downscale");
+ }
+
+ if (dictionary.hasKey("Steps")) {
+ _rayCastSteps = static_cast(dictionary.value("Steps"));
+ }
+ else {
+ LINFO("Number of raycasting steps not specified for ToyVolume."
+ " Using default value.");
+ }
+
}
RenderableToyVolume::~RenderableToyVolume() {}
@@ -131,6 +157,7 @@ void RenderableToyVolume::initializeGL() {
addProperty(_translation);
addProperty(_rotation);
addProperty(_color);
+ addProperty(_downScaleVolumeRendering);
}
void RenderableToyVolume::deinitializeGL() {
@@ -167,6 +194,8 @@ void RenderableToyVolume::update(const UpdateData& data) {
_raycaster->setStepSize(_stepSize);
_raycaster->setModelTransform(transform);
_raycaster->setTime(data.time.j2000Seconds());
+ _raycaster->setDownscaleRender(_downScaleVolumeRendering);
+ _raycaster->setMaxSteps(_rayCastSteps);
}
}
diff --git a/modules/toyvolume/rendering/renderabletoyvolume.h b/modules/toyvolume/rendering/renderabletoyvolume.h
index 8c1b0a36e0..d946bd21f9 100644
--- a/modules/toyvolume/rendering/renderabletoyvolume.h
+++ b/modules/toyvolume/rendering/renderabletoyvolume.h
@@ -55,8 +55,11 @@ private:
properties::Vec3Property _translation;
properties::Vec3Property _rotation;
properties::Vec4Property _color;
+ properties::FloatProperty _downScaleVolumeRendering;
std::unique_ptr _raycaster;
+
+ int _rayCastSteps = 1000;
};
} // namespace openspace
diff --git a/shaders/framebuffer/hdrAndFiltering.frag b/shaders/framebuffer/hdrAndFiltering.frag
index b22ebd9bc4..0e2b3b2090 100644
--- a/shaders/framebuffer/hdrAndFiltering.frag
+++ b/shaders/framebuffer/hdrAndFiltering.frag
@@ -38,7 +38,6 @@ uniform float Hue;
uniform float Saturation;
uniform float Value;
uniform float Lightness;
-uniform int nAaSamples;
uniform sampler2D hdrFeedingTexture;
diff --git a/shaders/framebuffer/mergeDownscaledVolume.frag b/shaders/framebuffer/mergeDownscaledVolume.frag
new file mode 100644
index 0000000000..14a6405735
--- /dev/null
+++ b/shaders/framebuffer/mergeDownscaledVolume.frag
@@ -0,0 +1,37 @@
+/*****************************************************************************************
+ * *
+ * OpenSpace *
+ * *
+ * Copyright (c) 2014-2019 *
+ * *
+ * 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. *
+ ****************************************************************************************/
+
+#version __CONTEXT__
+
+layout (location = 0) out vec4 finalColor;
+
+uniform sampler2D downscaledRenderedVolume;
+uniform sampler2D downscaledRenderedVolumeDepth;
+
+in vec2 texCoord;
+
+void main() {
+ finalColor = texture(downscaledRenderedVolume, texCoord);
+ gl_FragDepth = texture(downscaledRenderedVolumeDepth, texCoord).r;
+}
diff --git a/shaders/framebuffer/mergeDownscaledVolume.vert b/shaders/framebuffer/mergeDownscaledVolume.vert
new file mode 100644
index 0000000000..f737e51882
--- /dev/null
+++ b/shaders/framebuffer/mergeDownscaledVolume.vert
@@ -0,0 +1,33 @@
+/*****************************************************************************************
+ * *
+ * OpenSpace *
+ * *
+ * Copyright (c) 2014-2019 *
+ * *
+ * 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. *
+ ****************************************************************************************/
+
+#version __CONTEXT__
+
+layout(location = 0) in vec4 position;
+out vec2 texCoord;
+
+void main() {
+ texCoord = 0.5 + position.xy * 0.5;
+ gl_Position = position;
+}
diff --git a/shaders/framebuffer/raycastframebuffer.frag b/shaders/framebuffer/raycastframebuffer.frag
index 6a949b4cc9..bff04b1dbe 100644
--- a/shaders/framebuffer/raycastframebuffer.frag
+++ b/shaders/framebuffer/raycastframebuffer.frag
@@ -28,10 +28,11 @@ uniform sampler2D exitColorTexture;
uniform sampler2D exitDepthTexture;
uniform sampler2D mainDepthTexture;
-uniform bool insideRaycaster;
uniform vec3 cameraPosInRaycaster;
uniform vec2 windowSize;
+uniform int rayCastSteps;
+
#include "blending.glsl"
#include "rand.glsl"
#include "floatoperations.glsl"
@@ -45,17 +46,17 @@ uniform vec2 windowSize;
out vec4 finalColor;
#define ALPHA_LIMIT 0.99
-#define RAYCAST_MAX_STEPS 1000
#include <#{getEntryPath}>
void main() {
vec2 texCoord = vec2(gl_FragCoord.xy / windowSize);
+ // Boundary position in view space
vec4 exitColorTexture = texture(exitColorTexture, texCoord);
// If we don't have an exit, discard the ray
- if (exitColorTexture.a < 1.0 || exitColorTexture.rgb == vec3(0.0)) {
+ if (exitColorTexture.a < 1.f || exitColorTexture.rgb == vec3(0.f)) {
discard;
}
@@ -63,13 +64,13 @@ void main() {
vec3 exitPos = exitColorTexture.rgb;
float exitDepth = denormalizeFloat(texture(exitDepthTexture, texCoord).x);
- float jitterFactor = 0.5 + 0.5 * rand(gl_FragCoord.xy); // should be between 0.5 and 1.0
+ float jitterFactor = 0.5f + 0.5f * rand(gl_FragCoord.xy); // should be between 0.5 and 1.0
vec3 entryPos;
float entryDepth;
getEntry(entryPos, entryDepth);
// If we don't have an entry, discard the ray
- if (entryPos == vec3(0.0)) {
+ if (entryPos == vec3(0.f)) {
discard;
}
@@ -79,30 +80,30 @@ void main() {
vec3 direction = normalize(diff);
float raycastDepth = length(diff);
- float geoDepth = denormalizeFloat(texelFetch(mainDepthTexture, ivec2(gl_FragCoord), 0).x);
- float geoRatio = clamp((geoDepth - entryDepth) / (exitDepth - entryDepth), 0.0, 1.0);
+ float geoDepth = denormalizeFloat((texture(mainDepthTexture, texCoord).x));
+ float geoRatio = clamp((geoDepth - entryDepth) / (exitDepth - entryDepth), 0.f, 1.f);
raycastDepth = geoRatio * raycastDepth;
- float currentDepth = 0.0;
+ float currentDepth = 0.f;
float nextStepSize = stepSize#{id}(position, direction);
float currentStepSize;
- float previousJitterDistance = 0.0;
+ float previousJitterDistance = 0.f;
int nSteps = 0;
int sampleIndex = 0;
- float opacityDecay = 1.0;
+ float opacityDecay = 1.f;
- vec3 accumulatedColor = vec3(0.0);
- vec3 accumulatedAlpha = vec3(0.0);
+ vec3 accumulatedColor = vec3(0.f);
+ vec3 accumulatedAlpha = vec3(0.f);
for (nSteps = 0;
(accumulatedAlpha.r < ALPHA_LIMIT || accumulatedAlpha.g < ALPHA_LIMIT ||
- accumulatedAlpha.b < ALPHA_LIMIT) && nSteps < RAYCAST_MAX_STEPS;
+ accumulatedAlpha.b < ALPHA_LIMIT) && nSteps < rayCastSteps;
++nSteps)
{
- if (nextStepSize < raycastDepth / 10000000000.0) {
+ if (nextStepSize < raycastDepth / 10000000000.f) {
break;
}
@@ -110,7 +111,7 @@ void main() {
currentDepth += currentStepSize;
float jitteredStepSize = currentStepSize * jitterFactor;
- vec3 jitteredPosition = position + direction*jitteredStepSize;
+ vec3 jitteredPosition = position + direction * jitteredStepSize;
position += direction * currentStepSize;
sample#{id}(jitteredPosition, direction, accumulatedColor, accumulatedAlpha, nextStepSize);
@@ -122,8 +123,9 @@ void main() {
nextStepSize = min(nextStepSize, maxStepSize);
}
- finalColor = vec4(accumulatedColor, (accumulatedAlpha.r + accumulatedAlpha.g + accumulatedAlpha.b) / 3);
+ finalColor = vec4(accumulatedColor, (accumulatedAlpha.r + accumulatedAlpha.g + accumulatedAlpha.b) / 3.f);
finalColor.rgb /= finalColor.a ;
+
gl_FragDepth = normalizeFloat(entryDepth);
}
diff --git a/src/rendering/framebufferrenderer.cpp b/src/rendering/framebufferrenderer.cpp
index 284d2920c3..a6b327149b 100644
--- a/src/rendering/framebufferrenderer.cpp
+++ b/src/rendering/framebufferrenderer.cpp
@@ -59,6 +59,10 @@ namespace {
"renderedTexture", "inverseScreenSize"
};
+ constexpr const std::array DownscaledVolumeUniformNames = {
+ "downscaledRenderedVolume", "downscaledRenderedVolumeDepth"
+ };
+
constexpr const char* ExitFragmentShaderPath =
"${SHADERS}/framebuffer/exitframebuffer.frag";
constexpr const char* RaycastFragmentShaderPath =
@@ -184,6 +188,11 @@ void FramebufferRenderer::initialize() {
glGenFramebuffers(1, &_fxaaBuffers.fxaaFramebuffer);
glGenTextures(1, &_fxaaBuffers.fxaaTexture);
+ // DownscaleVolumeRendering
+ glGenFramebuffers(1, &_downscaleVolumeRendering.framebuffer);
+ glGenTextures(1, &_downscaleVolumeRendering.colorTexture);
+ glGenTextures(1, &_downscaleVolumeRendering.depthbuffer);
+
// Allocate Textures/Buffers Memory
updateResolution();
@@ -307,11 +316,35 @@ void FramebufferRenderer::initialize() {
LERROR("FXAA framebuffer is not complete");
}
+ //================================================//
+ //===== Downscale Volume Rendering Buffers =====//
+ //================================================//
+ glBindFramebuffer(GL_FRAMEBUFFER, _downscaleVolumeRendering.framebuffer);
+ glFramebufferTexture(
+ GL_FRAMEBUFFER,
+ GL_COLOR_ATTACHMENT0,
+ _downscaleVolumeRendering.colorTexture,
+ 0
+ );
+ glFramebufferTexture(
+ GL_FRAMEBUFFER,
+ GL_DEPTH_ATTACHMENT,
+ _downscaleVolumeRendering.depthbuffer,
+ 0
+ );
+
+ status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ if (status != GL_FRAMEBUFFER_COMPLETE) {
+ LERROR("Downscale Volume Rendering framebuffer is not complete");
+ }
+
+
// JCC: Moved to here to avoid NVidia: "Program/shader state performance warning"
// Building programs
updateHDRAndFiltering();
updateFXAA();
updateDeferredcastData();
+ updateDownscaledVolume();
// Sets back to default FBO
glBindFramebuffer(GL_FRAMEBUFFER, _defaultFBO);
@@ -326,6 +359,11 @@ void FramebufferRenderer::initialize() {
_fxaaUniformCache,
FXAAUniformNames
);
+ ghoul::opengl::updateUniformLocations(
+ *_downscaledVolumeProgram,
+ _writeDownscaledVolumeUniformCache,
+ DownscaledVolumeUniformNames
+ );
global::raycasterManager.addListener(*this);
global::deferredcasterManager.addListener(*this);
@@ -342,6 +380,7 @@ void FramebufferRenderer::deinitialize() {
glDeleteFramebuffers(1, &_hdrBuffers.hdrFilteringFramebuffer);
glDeleteFramebuffers(1, &_fxaaBuffers.fxaaFramebuffer);
glDeleteFramebuffers(1, &_pingPongBuffers.framebuffer);
+ glDeleteFramebuffers(1, &_downscaleVolumeRendering.framebuffer);
glDeleteTextures(1, &_gBuffers.colorTexture);
glDeleteTextures(1, &_gBuffers.depthTexture);
@@ -350,7 +389,9 @@ void FramebufferRenderer::deinitialize() {
glDeleteTextures(1, &_fxaaBuffers.fxaaTexture);
glDeleteTextures(1, &_gBuffers.positionTexture);
glDeleteTextures(1, &_gBuffers.normalTexture);
-
+ glDeleteTextures(1, &_downscaleVolumeRendering.colorTexture);
+ glDeleteTextures(1, &_downscaleVolumeRendering.depthbuffer);
+
glDeleteTextures(1, &_pingPongBuffers.colorTexture[1]);
glDeleteTextures(1, &_exitColorTexture);
@@ -459,6 +500,124 @@ void FramebufferRenderer::applyFXAA() {
_fxaaProgram->deactivate();
}
+void FramebufferRenderer::updateDownscaleTextures() {
+ glBindTexture(GL_TEXTURE_2D, _downscaleVolumeRendering.colorTexture);
+ glTexImage2D(
+ GL_TEXTURE_2D,
+ 0,
+ GL_RGBA32F,
+ _resolution.x * _downscaleVolumeRendering.currentDownscaleFactor,
+ _resolution.y * _downscaleVolumeRendering.currentDownscaleFactor,
+ 0,
+ GL_RGBA,
+ GL_FLOAT,
+ nullptr
+ );
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ float volumeBorderColor[] = { 0.0f, 0.0f, 0.0f, 1.0f };
+ glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, volumeBorderColor);
+
+ glBindTexture(GL_TEXTURE_2D, _downscaleVolumeRendering.depthbuffer);
+ glTexImage2D(
+ GL_TEXTURE_2D,
+ 0,
+ GL_DEPTH_COMPONENT32F,
+ _resolution.x * _downscaleVolumeRendering.currentDownscaleFactor,
+ _resolution.y * _downscaleVolumeRendering.currentDownscaleFactor,
+ 0,
+ GL_DEPTH_COMPONENT,
+ GL_FLOAT,
+ nullptr
+ );
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+}
+
+void FramebufferRenderer::writeDownscaledVolume() {
+ const bool doPerformanceMeasurements = global::performanceManager.isEnabled();
+ std::unique_ptr perfInternal;
+
+ if (doPerformanceMeasurements) {
+ perfInternal = std::make_unique(
+ "FramebufferRenderer::render::writeDownscaledVolume"
+ );
+ }
+
+ // Saving current OpenGL state
+ GLboolean blendEnabled = glIsEnabledi(GL_BLEND, 0);
+
+ GLenum blendEquationRGB;
+ glGetIntegerv(GL_BLEND_EQUATION_RGB, &blendEquationRGB);
+
+ GLenum blendEquationAlpha;
+ glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &blendEquationAlpha);
+
+ GLenum blendDestAlpha;
+ glGetIntegerv(GL_BLEND_DST_ALPHA, &blendDestAlpha);
+
+ GLenum blendDestRGB;
+ glGetIntegerv(GL_BLEND_DST_RGB, &blendDestRGB);
+
+ GLenum blendSrcAlpha;
+ glGetIntegerv(GL_BLEND_SRC_ALPHA, &blendSrcAlpha);
+
+ GLenum blendSrcRGB;
+ glGetIntegerv(GL_BLEND_SRC_RGB, &blendSrcRGB);
+
+ glEnablei(GL_BLEND, 0);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+
+ _downscaledVolumeProgram->activate();
+
+ ghoul::opengl::TextureUnit downscaledTextureUnit;
+ downscaledTextureUnit.activate();
+ glBindTexture(
+ GL_TEXTURE_2D,
+ _downscaleVolumeRendering.colorTexture
+ );
+
+ _downscaledVolumeProgram->setUniform(
+ _writeDownscaledVolumeUniformCache.downscaledRenderedVolume,
+ downscaledTextureUnit
+ );
+
+ ghoul::opengl::TextureUnit downscaledDepthUnit;
+ downscaledDepthUnit.activate();
+ glBindTexture(
+ GL_TEXTURE_2D,
+ _downscaleVolumeRendering.depthbuffer
+ );
+
+ _downscaledVolumeProgram->setUniform(
+ _writeDownscaledVolumeUniformCache.downscaledRenderedVolumeDepth,
+ downscaledDepthUnit
+ );
+
+
+ glEnablei(GL_BLEND, 0);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+
+ glDisable(GL_DEPTH_TEST);
+
+ glBindVertexArray(_screenQuad);
+ glDrawArrays(GL_TRIANGLES, 0, 6);
+ glBindVertexArray(0);
+
+ glEnable(GL_DEPTH_TEST);
+
+ _downscaledVolumeProgram->deactivate();
+
+ // Restores blending state
+ glBlendEquationSeparate(blendEquationRGB, blendEquationAlpha);
+ glBlendFuncSeparate(blendSrcRGB, blendDestRGB, blendSrcAlpha, blendDestAlpha);
+
+ if (!blendEnabled) {
+ glDisablei(GL_BLEND, 0);
+ }
+
+}
+
void FramebufferRenderer::update() {
if (_dirtyResolution) {
updateResolution();
@@ -492,6 +651,16 @@ void FramebufferRenderer::update() {
);
}
+ if (_downscaledVolumeProgram->isDirty()) {
+ _downscaledVolumeProgram->rebuildFromFile();
+
+ ghoul::opengl::updateUniformLocations(
+ *_downscaledVolumeProgram,
+ _writeDownscaledVolumeUniformCache,
+ DownscaledVolumeUniformNames
+ );
+ }
+
using K = VolumeRaycaster*;
using V = std::unique_ptr;
for (const std::pair& program : _exitPrograms) {
@@ -651,6 +820,39 @@ void FramebufferRenderer::updateResolution() {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ // Downscale Volume Rendering
+ glBindTexture(GL_TEXTURE_2D, _downscaleVolumeRendering.colorTexture);
+ glTexImage2D(
+ GL_TEXTURE_2D,
+ 0,
+ GL_RGBA32F,
+ _resolution.x * _downscaleVolumeRendering.currentDownscaleFactor,
+ _resolution.y * _downscaleVolumeRendering.currentDownscaleFactor,
+ 0,
+ GL_RGBA,
+ GL_FLOAT,
+ nullptr
+ );
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ float volumeBorderColor[] = { 0.0f, 0.0f, 0.0f, 1.0f };
+ glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, volumeBorderColor);
+
+ glBindTexture(GL_TEXTURE_2D, _downscaleVolumeRendering.depthbuffer);
+ glTexImage2D(
+ GL_TEXTURE_2D,
+ 0,
+ GL_DEPTH_COMPONENT32F,
+ _resolution.x * _downscaleVolumeRendering.currentDownscaleFactor,
+ _resolution.y * _downscaleVolumeRendering.currentDownscaleFactor,
+ 0,
+ GL_DEPTH_COMPONENT,
+ GL_FLOAT,
+ nullptr
+ );
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+
// Volume Rendering Textures
glBindTexture(GL_TEXTURE_2D, _exitColorTexture);
glTexImage2D(
@@ -834,6 +1036,17 @@ void FramebufferRenderer::updateFXAA() {
//_fxaaProgram->setIgnoreUniformLocationError(IgnoreError::Yes);
}
+void FramebufferRenderer::updateDownscaledVolume() {
+ _downscaledVolumeProgram = ghoul::opengl::ProgramObject::Build(
+ "Write Downscaled Volume Program",
+ absPath("${SHADERS}/framebuffer/mergeDownscaledVolume.vert"),
+ absPath("${SHADERS}/framebuffer/mergeDownscaledVolume.frag")
+ );
+ using IgnoreError = ghoul::opengl::ProgramObject::IgnoreError;
+ //_downscaledVolumeProgram->setIgnoreSubroutineUniformLocationError(IgnoreError::Yes);
+ //_downscaledVolumeProgram->setIgnoreUniformLocationError(IgnoreError::Yes);
+}
+
void FramebufferRenderer::render(Scene* scene, Camera* camera, float blackoutFactor) {
// Set OpenGL default rendering state
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &_defaultFBO);
@@ -959,7 +1172,20 @@ void FramebufferRenderer::performRaycasterTasks(const std::vector
exitProgram->deactivate();
}
- glBindFramebuffer(GL_FRAMEBUFFER, _gBuffers.framebuffer);
+ if (raycaster->downscaleRender() < 1.f) {
+ float scaleDown = raycaster->downscaleRender();
+ glBindFramebuffer(GL_FRAMEBUFFER, _downscaleVolumeRendering.framebuffer);
+ glViewport(0, 0, _resolution.x * scaleDown, _resolution.y * scaleDown);
+ if (_downscaleVolumeRendering.currentDownscaleFactor != scaleDown) {
+ _downscaleVolumeRendering.currentDownscaleFactor = scaleDown;
+ updateDownscaleTextures();
+ }
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ }
+ else {
+ glBindFramebuffer(GL_FRAMEBUFFER, _gBuffers.framebuffer);
+ }
+
glm::vec3 cameraPosition;
bool isCameraInside = raycaster->isCameraInside(
raycasterTask.renderData,
@@ -991,6 +1217,8 @@ void FramebufferRenderer::performRaycasterTasks(const std::vector
}
if (raycastProgram) {
+ raycastProgram->setUniform("rayCastSteps", raycaster->maxSteps());
+
raycaster->preRaycast(_raycastData[raycaster], *raycastProgram);
ghoul::opengl::TextureUnit exitColorTextureUnit;
@@ -1008,7 +1236,16 @@ void FramebufferRenderer::performRaycasterTasks(const std::vector
glBindTexture(GL_TEXTURE_2D, _gBuffers.depthTexture);
raycastProgram->setUniform("mainDepthTexture", mainDepthTextureUnit);
- raycastProgram->setUniform("windowSize", static_cast(_resolution));
+ if (raycaster->downscaleRender() < 1.f) {
+ float scaleDown = raycaster->downscaleRender();
+ raycastProgram->setUniform(
+ "windowSize",
+ glm::vec2(_resolution.x * scaleDown, _resolution.y * scaleDown)
+ );
+ }
+ else {
+ raycastProgram->setUniform("windowSize", static_cast(_resolution));
+ }
glDisable(GL_DEPTH_TEST);
glDepthMask(false);
@@ -1029,12 +1266,17 @@ void FramebufferRenderer::performRaycasterTasks(const std::vector
else {
LWARNING("Raycaster is not attached when trying to perform raycaster task");
}
+
+ if (raycaster->downscaleRender() < 1.f) {
+ glViewport(0, 0, _resolution.x, _resolution.y);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _gBuffers.framebuffer);
+ writeDownscaledVolume();
+ }
}
}
void FramebufferRenderer::performDeferredTasks(
- const std::vector& tasks
- )
+ const std::vector& tasks)
{
for (const DeferredcasterTask& deferredcasterTask : tasks) {
Deferredcaster* deferredcaster = deferredcasterTask.deferredcaster;
diff --git a/src/rendering/volumeraycaster.cpp b/src/rendering/volumeraycaster.cpp
index 17d13627c0..954bda7ac7 100644
--- a/src/rendering/volumeraycaster.cpp
+++ b/src/rendering/volumeraycaster.cpp
@@ -33,4 +33,20 @@ bool VolumeRaycaster::isCameraInside(const RenderData&, glm::vec3&) {
return false;
}
+void VolumeRaycaster::setMaxSteps(int nsteps) {
+ _rayCastMaxSteps = nsteps;
+}
+
+int VolumeRaycaster::maxSteps() const {
+ return _rayCastMaxSteps;
+}
+
+void VolumeRaycaster::setDownscaleRender(float value) {
+ _downscaleRenderConst = value;
+}
+
+float VolumeRaycaster::downscaleRender() const {
+ return _downscaleRenderConst;
+}
+
} // namespace openspace