mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-02-28 16:09:46 -06:00
Merge branch 'master' into feature/AALines2
This commit is contained in:
@@ -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 ()
|
||||
|
||||
@@ -6,7 +6,7 @@ local textures = asset.syncedResource({
|
||||
Name = "2dF Textures",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "digitaluniverse_2dF_textures",
|
||||
Version = 1
|
||||
Version = 2
|
||||
})
|
||||
|
||||
local speck = asset.syncedResource({
|
||||
@@ -24,7 +24,7 @@ local object = {
|
||||
Color = { 1.0, 1.0, 1.0 },
|
||||
Opacity = 1.0,
|
||||
File = speck .. "/2dF.speck",
|
||||
Texture = textures .. "/point3.png",
|
||||
Texture = textures .. "/point3A.png",
|
||||
ColorMap = speck .. "/2dF.cmap",
|
||||
ColorOption = { "redshift", "proximity" },
|
||||
ColorRange = { { 0.0, 0.075 }, { 1.0, 25.0 } },
|
||||
|
||||
@@ -6,7 +6,7 @@ local textures = asset.syncedResource({
|
||||
Name = "2MASS Textures",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "digitaluniverse_2mass_textures",
|
||||
Version = 1
|
||||
Version = 2
|
||||
})
|
||||
|
||||
local speck = asset.syncedResource({
|
||||
@@ -24,7 +24,7 @@ local object = {
|
||||
Color = { 1.0, 0.4, 0.2 },
|
||||
Opacity = 1.0,
|
||||
File = speck .. "/2MASS.speck",
|
||||
Texture = textures .. "/point3.png",
|
||||
Texture = textures .. "/point3A.png",
|
||||
ColorMap = speck .. "/lss.cmap",
|
||||
ColorOption = { "redshift", "prox5Mpc" },
|
||||
ColorRange = { { 0.0, 0.075 }, { 1.0, 50.0 } },
|
||||
|
||||
@@ -6,7 +6,7 @@ local textures = asset.syncedResource({
|
||||
Name = "6dF Textures",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "digitaluniverse_6dF_textures",
|
||||
Version = 1
|
||||
Version = 2
|
||||
})
|
||||
|
||||
local speck = asset.syncedResource({
|
||||
@@ -24,7 +24,7 @@ local object = {
|
||||
Color = { 1.0, 1.0, 0.0 },
|
||||
Opacity = 1.0,
|
||||
File = speck .. "/6dF.speck",
|
||||
Texture = textures .. "/point3.png",
|
||||
Texture = textures .. "/point3A.png",
|
||||
ColorMap = speck .. "/6dF.cmap",
|
||||
ColorOption = { "redshift", "proximity" },
|
||||
ColorRange = { { 0.0, 0.075 }, { 1.0, 10.0 } },
|
||||
|
||||
@@ -6,7 +6,7 @@ local textures = asset.syncedResource({
|
||||
Name = "Abell Textures",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "digitaluniverse_abell_textures",
|
||||
Version = 1
|
||||
Version = 2
|
||||
})
|
||||
|
||||
local speck = asset.syncedResource({
|
||||
@@ -25,7 +25,7 @@ local object = {
|
||||
Opacity = 1.0,
|
||||
--ColorMap = speck .. "/abell.cmap",
|
||||
File = speck .. "/abell.speck",
|
||||
Texture = textures .. "/point3.png",
|
||||
Texture = textures .. "/point3A.png",
|
||||
LabelFile = speck .. "/abell.label",
|
||||
TextColor = { 0.0, 0.8, 0.0, 1.0 },
|
||||
TextSize = 22,
|
||||
|
||||
@@ -6,7 +6,7 @@ local textures = asset.syncedResource({
|
||||
Name = "Quasars Textures",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "digitaluniverse_quasars_textures",
|
||||
Version = 1
|
||||
Version = 2
|
||||
})
|
||||
|
||||
local speck = asset.syncedResource({
|
||||
@@ -24,7 +24,7 @@ local object = {
|
||||
Color = { 1.0, 0.4, 0.2 },
|
||||
Opacity = 0.95,
|
||||
File = speck .. "/quasars.speck",
|
||||
Texture = textures .. "/point3.png",
|
||||
Texture = textures .. "/point3A.png",
|
||||
Unit = "Mpc",
|
||||
ScaleFactor = 540.9,
|
||||
-- Fade in value in the same unit as "Unit"
|
||||
|
||||
@@ -6,7 +6,7 @@ local textures = asset.syncedResource({
|
||||
Name = "Sloan Digital Sky Survey Textures",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "digitaluniverse_sloandss_textures",
|
||||
Version = 1
|
||||
Version = 2
|
||||
})
|
||||
|
||||
local speck = asset.syncedResource({
|
||||
@@ -28,7 +28,7 @@ local object = {
|
||||
ColorMap = speck .. "/SDSSgals.cmap",
|
||||
ColorOption = { "redshift", "proximity" },
|
||||
ColorRange = { { 0.0, 0.075 }, { 1.0, 50.0 } },
|
||||
Texture = textures .. "/point3.png",
|
||||
Texture = textures .. "/point3A.png",
|
||||
Unit = "Mpc",
|
||||
-- Fade in value in the same unit as "Unit"
|
||||
FadeInDistances = { 220.0, 650.0 },
|
||||
|
||||
@@ -6,7 +6,7 @@ local textures = asset.syncedResource({
|
||||
Name = "Galaxy Superclusters Textures",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "digitaluniverse_superclusters_textures",
|
||||
Version = 1
|
||||
Version = 2
|
||||
})
|
||||
|
||||
local speck = asset.syncedResource({
|
||||
@@ -25,7 +25,7 @@ local object = {
|
||||
Color = { 1.0, 1.0, 1.0 },
|
||||
Opacity = 0.65,
|
||||
File = speck .. "/superclust.speck",
|
||||
Texture = textures .. "/point3.png",
|
||||
Texture = textures .. "/point3A.png",
|
||||
LabelFile = speck .. "/superclust.label",
|
||||
TextColor = { 0.9, 0.9, 0.9, 1.0 },
|
||||
ScaleFactor = 531.0,
|
||||
|
||||
@@ -6,7 +6,7 @@ local textures = asset.syncedResource({
|
||||
Name = "Tully Textures",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "digitaluniverse_tully_textures",
|
||||
Version = 2
|
||||
Version = 3
|
||||
})
|
||||
|
||||
local speck = asset.syncedResource({
|
||||
@@ -25,7 +25,7 @@ local tullyPoints = {
|
||||
Opacity = 0.99,
|
||||
ScaleFactor = 500.0,
|
||||
File = speck .. "/tully.speck",
|
||||
Texture = textures .. "/point3.png",
|
||||
Texture = textures .. "/point3A.png",
|
||||
--ColorMap = speck .. "/tully.cmap",
|
||||
ColorMap = speck .. "/lss.cmap",
|
||||
--ColorOption = { "proximity" },
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -2,7 +2,7 @@ local assetHelper = asset.require('util/asset_helper')
|
||||
local transforms = asset.require('./transforms')
|
||||
asset.require("spice/base")
|
||||
asset.request('./trail')
|
||||
local labelsPath = asset.require('./pluto_labels').LabelsPath
|
||||
local labelsPath = asset.require('./pluto_globelabels').LabelsPath
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ local assetHelper = asset.require('util/asset_helper')
|
||||
local transforms = asset.require('./transforms')
|
||||
asset.require("spice/base")
|
||||
asset.request('./trail')
|
||||
local labelsPath = asset.require('./pluto_labels').LabelsPath
|
||||
local labelsPath = asset.require('./pluto_globelabels').LabelsPath
|
||||
|
||||
|
||||
|
||||
@@ -59,6 +59,25 @@ local Pluto = {
|
||||
}
|
||||
}
|
||||
|
||||
local PlutoLabel = {
|
||||
Identifier = "PlutoLabel",
|
||||
Parent = Pluto.Identifier,
|
||||
Renderable = {
|
||||
Enabled = false,
|
||||
Type = "RenderableLabels",
|
||||
LabelText = "Pluto",
|
||||
FontSize = 100.0,
|
||||
LabelSize = 8.9,
|
||||
LabelMaxSize = 100.0,
|
||||
LabelMinSize = 1.0,
|
||||
BlendMode = "Additive",
|
||||
LabelOrientationOption = "Camera View Direction"
|
||||
},
|
||||
Tag = { "solarsystem_labels" },
|
||||
GUI = {
|
||||
Name = "Pluto Label",
|
||||
Path = "/Solar System/Dwarf Planets/Pluto"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
assetHelper.registerSceneGraphNodesAndExport(asset, { Pluto })
|
||||
assetHelper.registerSceneGraphNodesAndExport(asset, { Pluto, PlutoLabel })
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -287,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 })
|
||||
|
||||
@@ -56,7 +56,7 @@ local registerSatelliteGroupObjects = function(containingAsset, group, tleFolder
|
||||
Renderable = {
|
||||
Type = "RenderableSatellites",
|
||||
Path = file,
|
||||
Segments = 160,
|
||||
Segments = 120,
|
||||
Color = color,
|
||||
Fade = 0.5
|
||||
},
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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 })
|
||||
|
||||
@@ -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 })
|
||||
|
||||
@@ -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 })
|
||||
|
||||
@@ -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 })
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -57,6 +57,26 @@ local SaturnRings = {
|
||||
}
|
||||
}
|
||||
|
||||
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, SaturnRings, SaturnLabel })
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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 })
|
||||
|
||||
66
data/assets/scene/solarsystem/planets/venus/atmosphere.asset
Normal file
66
data/assets/scene/solarsystem/planets/venus/atmosphere.asset
Normal file
@@ -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 })
|
||||
@@ -0,0 +1,21 @@
|
||||
<GDAL_WMS>
|
||||
<Service name="TMS">
|
||||
<ServerUrl>http://openspace.sci.utah.edu/Venus/MagellanDEM/tile/${z}/${y}/${x}</ServerUrl>
|
||||
</Service>
|
||||
<DataWindow>
|
||||
<UpperLeftX>-180.0</UpperLeftX>
|
||||
<UpperLeftY>90.0</UpperLeftY>
|
||||
<LowerRightX>180.0</LowerRightX>
|
||||
<LowerRightY>-90.0</LowerRightY>
|
||||
<SizeX>8192</SizeX>
|
||||
<SizeY>4096</SizeY>
|
||||
<TileLevel>4</TileLevel>
|
||||
<YOrigin>top</YOrigin>
|
||||
</DataWindow>
|
||||
<Projection>GEOGCS["GCS_Venus",DATUM["D_Venus",SPHEROID["Venus",6051000,0]],PRIMEM["Reference_Meridian",0],UNIT["Degree",0.0174532925199433]]</Projection>
|
||||
<BlockSizeX>256</BlockSizeX>
|
||||
<BlockSizeY>256</BlockSizeY>
|
||||
<BandsCount>1</BandsCount>
|
||||
<MaxConnections>10</MaxConnections>
|
||||
<Timeout>5</Timeout>
|
||||
</GDAL_WMS>
|
||||
@@ -0,0 +1,21 @@
|
||||
<GDAL_WMS>
|
||||
<Service name="TMS">
|
||||
<ServerUrl>http://openspace.sci.utah.edu/Venus/MagellanMosaic/tile/${z}/${y}/${x}</ServerUrl>
|
||||
</Service>
|
||||
<DataWindow>
|
||||
<UpperLeftX>-180.0</UpperLeftX>
|
||||
<UpperLeftY>84.0</UpperLeftY>
|
||||
<LowerRightX>180.0</LowerRightX>
|
||||
<LowerRightY>-80.0</LowerRightY>
|
||||
<SizeX>506928</SizeX>
|
||||
<SizeY>230948</SizeY>
|
||||
<TileLevel>9</TileLevel>
|
||||
<YOrigin>top</YOrigin>
|
||||
</DataWindow>
|
||||
<Projection>GEOGCS["GCS_Venus",DATUM["D_Venus",SPHEROID["Venus_localRadius",6051000,0]],PRIMEM["Reference_Meridian",0],UNIT["Degree",0.0174532925199433]]</Projection>
|
||||
<BlockSizeX>512</BlockSizeX>
|
||||
<BlockSizeY>512</BlockSizeY>
|
||||
<BandsCount>1</BandsCount>
|
||||
<MaxConnections>10</MaxConnections>
|
||||
<Timeout>5</Timeout>
|
||||
</GDAL_WMS>
|
||||
@@ -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 })
|
||||
|
||||
@@ -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 })
|
||||
|
||||
@@ -395,9 +395,7 @@ public:
|
||||
/**
|
||||
* Default view options that can be used in the Property::setViewOption method. The
|
||||
* values are: Property::ViewOptions::Color = \c color,
|
||||
* Property::ViewOptions::LightPosition = \c lightPosition,
|
||||
* Property::ViewOptions::PowerScaledScalar = \c powerScaledScalar, and
|
||||
* Property::ViewOptions::PowerScaledCoordinate = \c powerScaledCoordinate.
|
||||
* Property::ViewOptions::LightPosition = \c lightPosition
|
||||
*/
|
||||
struct ViewOptions {
|
||||
static const char* Color;
|
||||
|
||||
@@ -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<VolumeRaycaster*, RaycastData> _raycastData;
|
||||
RaycasterProgObjMap _exitPrograms;
|
||||
@@ -122,10 +126,13 @@ private:
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _hdrFilteringProgram;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _tmoProgram;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _fxaaProgram;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _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;
|
||||
|
||||
@@ -75,6 +75,8 @@ public:
|
||||
|
||||
protected:
|
||||
void createShaders();
|
||||
std::string makeUniqueIdentifier(std::string name);
|
||||
|
||||
glm::mat4 scaleMatrix();
|
||||
glm::mat4 globalRotationMatrix();
|
||||
glm::mat4 translationMatrix();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
#ifndef __OPENSPACE_CORE___CAMERA___H__
|
||||
#define __OPENSPACE_CORE___CAMERA___H__
|
||||
|
||||
#include <openspace/util/powerscaledcoordinate.h>
|
||||
#include <openspace/util/syncdata.h>
|
||||
#include <ghoul/glm.h>
|
||||
#include <mutex>
|
||||
@@ -36,7 +35,6 @@ class SceneGraphNode;
|
||||
|
||||
/**
|
||||
* This class still needs some more love. Suggested improvements:
|
||||
* - Remove psc from the camera class interface.
|
||||
* - Accessors should return constant references to double precision class members.
|
||||
* - Remove the scaling variable (What is it used for?)
|
||||
* - Remove the maxFov and sinMaxfov variables. Redundant since the fov is embedded
|
||||
|
||||
@@ -1,114 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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_CORE___POWERSCALEDCOORDINATE___H__
|
||||
#define __OPENSPACE_CORE___POWERSCALEDCOORDINATE___H__
|
||||
|
||||
#include <ghoul/glm.h>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
class PowerScaledScalar;
|
||||
|
||||
class PowerScaledCoordinate {
|
||||
public:
|
||||
// constructors
|
||||
PowerScaledCoordinate() = default;
|
||||
|
||||
PowerScaledCoordinate(PowerScaledCoordinate&& rhs);
|
||||
PowerScaledCoordinate(const PowerScaledCoordinate& rhs);
|
||||
|
||||
// Sets the power scaled coordinates directly
|
||||
PowerScaledCoordinate(glm::vec4 v);
|
||||
PowerScaledCoordinate(float f1, float f2, float f3, float f4);
|
||||
// Sets the power scaled coordinates with w = 0
|
||||
PowerScaledCoordinate(glm::vec3 v);
|
||||
|
||||
static PowerScaledCoordinate CreatePowerScaledCoordinate(double d1, double d2,
|
||||
double d3);
|
||||
|
||||
// get functions
|
||||
// return the full, unmodified PSC
|
||||
const glm::vec4& vec4() const;
|
||||
|
||||
// returns the rescaled, "normal" coordinates
|
||||
glm::vec3 vec3() const;
|
||||
|
||||
// return the full psc as dvec4()
|
||||
glm::dvec4 dvec4() const;
|
||||
|
||||
// rescaled return as dvec3
|
||||
glm::dvec3 dvec3() const;
|
||||
|
||||
// length of the vector as a pss
|
||||
float length() const;
|
||||
glm::vec3 direction() const;
|
||||
|
||||
// operator overloading
|
||||
PowerScaledCoordinate& operator=(const PowerScaledCoordinate& rhs);
|
||||
PowerScaledCoordinate& operator=(PowerScaledCoordinate&& rhs);
|
||||
PowerScaledCoordinate& operator+=(const PowerScaledCoordinate& rhs);
|
||||
PowerScaledCoordinate operator+(const PowerScaledCoordinate& rhs) const;
|
||||
PowerScaledCoordinate& operator-=(const PowerScaledCoordinate& rhs);
|
||||
PowerScaledCoordinate operator-(const PowerScaledCoordinate& rhs) const;
|
||||
float& operator[](unsigned int idx);
|
||||
float operator[](unsigned int idx) const;
|
||||
double dot(const PowerScaledCoordinate& rhs) const;
|
||||
double angle(const PowerScaledCoordinate& rhs) const;
|
||||
|
||||
// scalar operators
|
||||
PowerScaledCoordinate operator*(const double& rhs) const;
|
||||
PowerScaledCoordinate operator*(const float& rhs) const;
|
||||
PowerScaledCoordinate operator*(const glm::mat4& matrix) const;
|
||||
|
||||
|
||||
// comparison
|
||||
bool operator==(const PowerScaledCoordinate& other) const;
|
||||
bool operator!=(const PowerScaledCoordinate& other) const;
|
||||
bool operator<(const PowerScaledCoordinate& other) const;
|
||||
bool operator>(const PowerScaledCoordinate& other) const;
|
||||
bool operator<=(const PowerScaledCoordinate& other) const;
|
||||
bool operator>=(const PowerScaledCoordinate& other) const;
|
||||
|
||||
// glm integration
|
||||
PowerScaledCoordinate& operator=(const glm::dvec4& rhs);
|
||||
PowerScaledCoordinate& operator=(const glm::vec4& rhs);
|
||||
PowerScaledCoordinate& operator=(const glm::dvec3& rhs);
|
||||
PowerScaledCoordinate& operator=(const glm::vec3& rhs);
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& os, const PowerScaledCoordinate& rhs);
|
||||
|
||||
// allow the power scaled scalars to access private members
|
||||
friend class PowerScaledScalar;
|
||||
|
||||
private:
|
||||
// internal glm vector
|
||||
glm::vec4 _vec = glm::vec4(0.f);
|
||||
};
|
||||
|
||||
typedef PowerScaledCoordinate psc;
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_CORE___POWERSCALEDCOORDINATE___H__
|
||||
@@ -22,22 +22,20 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_CORE___POWERSCALEDSPHERE___H__
|
||||
#define __OPENSPACE_CORE___POWERSCALEDSPHERE___H__
|
||||
#ifndef __OPENSPACE_CORE___SPHERE___H__
|
||||
#define __OPENSPACE_CORE___SPHERE___H__
|
||||
|
||||
#include <ghoul/glm.h>
|
||||
#include <ghoul/opengl/ghoul_gl.h>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
class PowerScaledSphere;
|
||||
|
||||
class PowerScaledSphere {
|
||||
class Sphere {
|
||||
public:
|
||||
PowerScaledSphere(float radius, int segments = 8);
|
||||
PowerScaledSphere(glm::vec3 radius, int segments);
|
||||
PowerScaledSphere(const PowerScaledSphere& cpy);
|
||||
~PowerScaledSphere();
|
||||
Sphere(float radius, int segments = 8);
|
||||
Sphere(glm::vec3 radius, int segments);
|
||||
Sphere(const Sphere& cpy);
|
||||
~Sphere();
|
||||
|
||||
bool initialize();
|
||||
|
||||
@@ -62,4 +60,4 @@ public:
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_CORE___POWERSCALEDSPHERE___H__
|
||||
#endif // __OPENSPACE_CORE___SPHERE___H__
|
||||
@@ -652,36 +652,6 @@ public:
|
||||
FieldOfViewMethod method, AberrationCorrection aberrationCorrection,
|
||||
double& ephemerisTime) const;
|
||||
|
||||
/**
|
||||
* Determine whether a specific \p target is in the field-of-view of a specified
|
||||
* \p instrument or an \p observer at a given time. The reference frame used is
|
||||
* derived from the \p target by converting it into an \c IAU inertial reference
|
||||
* frame.
|
||||
*
|
||||
* \param target The name or NAIF ID code string of the target
|
||||
* \param observer The name or NAIF ID code string of the observer
|
||||
* \param instrument The name or NAIF ID code string of the instrument
|
||||
* \param method The type of shape model used for the target
|
||||
* \param aberrationCorrection The aberration correction method
|
||||
* \param ephemerisTime Time of the observation (seconds past J2000)
|
||||
* \return \c true if the target is visible, \c false otherwise
|
||||
*
|
||||
* \throw SpiceException If the \p target or \p observer do not name valid
|
||||
* NAIF objects, the \p target or \p observer name the same NAIF object, the
|
||||
* \p instrument does not name a valid NAIF object, or insufficient kernel
|
||||
* information has been loaded.
|
||||
* \pre \p target must not be empty.
|
||||
* \pre \p observer must not be empty.
|
||||
* \pre \p target and \p observer must not be different strings
|
||||
* \pre \p referenceFrame must not be empty.
|
||||
* \pre \p instrument must not be empty.
|
||||
*
|
||||
* \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/fovtrg_c.html
|
||||
*/
|
||||
bool isTargetInFieldOfView(const std::string& target, const std::string& observer,
|
||||
const std::string& instrument, FieldOfViewMethod method,
|
||||
AberrationCorrection aberrationCorrection, double& ephemerisTime) const;
|
||||
|
||||
/// Struct that is used as the return value from the #targetState method
|
||||
struct TargetStateResult {
|
||||
/// The target position
|
||||
@@ -902,26 +872,6 @@ public:
|
||||
AberrationCorrection aberrationCorrection, double ephemerisTime,
|
||||
int numberOfTerminatorPoints);
|
||||
|
||||
/**
|
||||
* This function adds a frame to a body.
|
||||
*
|
||||
* \param body - the name of the body
|
||||
* \param frame - the name of the frame
|
||||
* \return false if the arguments are empty
|
||||
*
|
||||
* \todo I think this function should die ---abock
|
||||
*/
|
||||
bool addFrame(std::string body, std::string frame);
|
||||
|
||||
/**
|
||||
* This function returns the frame of a body if defined, otherwise it returns
|
||||
* IAU_ + body (most frames are known by the International Astronomical Union)
|
||||
* \param body - the name of the body
|
||||
* \return the frame of the body
|
||||
* \todo I think this function should die ---abock
|
||||
*/
|
||||
std::string frameFromBody(const std::string& body) const;
|
||||
|
||||
/**
|
||||
* Sets the SpiceManager's exception handling. If UseException::No is passed to this
|
||||
* function, all subsequent calls will not throw an error, but fail silently instead.
|
||||
@@ -1048,8 +998,6 @@ private:
|
||||
std::map<int, std::vector< std::pair<double, double>>> _spkIntervals;
|
||||
std::map<int, std::set<double>> _ckCoverageTimes;
|
||||
std::map<int, std::set<double>> _spkCoverageTimes;
|
||||
// Vector of pairs: Body, Frame
|
||||
std::vector<std::pair<std::string, std::string>> _frameByBody;
|
||||
|
||||
/// Stores whether the SpiceManager throws exceptions (Yes) or fails silently (No)
|
||||
UseException _useExceptions = UseException::Yes;
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
#define __OPENSPACE_CORE___UPDATESTRUCTURES___H__
|
||||
|
||||
#include <openspace/util/camera.h>
|
||||
#include <openspace/util/powerscaledcoordinate.h>
|
||||
#include <openspace/util/time.h>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
@@ -60,7 +60,6 @@
|
||||
#include <modules/atmosphere/rendering/atmospheredeferredcaster.h>
|
||||
|
||||
#include <modules/atmosphere/rendering/renderableatmosphere.h>
|
||||
#include <openspace/util/powerscaledcoordinate.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
#include <openspace/util/spicemanager.h>
|
||||
#include <openspace/rendering/renderable.h>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include <modules/base/lightsource/cameralightsource.h>
|
||||
#include <modules/base/lightsource/scenegraphlightsource.h>
|
||||
#include <modules/base/rendering/renderablecartesianaxes.h>
|
||||
#include <modules/base/rendering/renderablelabels.h>
|
||||
#include <modules/base/rendering/renderablemodel.h>
|
||||
#include <modules/base/rendering/renderablenodeline.h>
|
||||
#include <modules/base/rendering/renderablesphere.h>
|
||||
@@ -123,6 +124,7 @@ void BaseModule::internalInitialize(const ghoul::Dictionary&) {
|
||||
|
||||
fRenderable->registerClass<RenderableBoxGrid>("RenderableBoxGrid");
|
||||
fRenderable->registerClass<RenderableCartesianAxes>("RenderableCartesianAxes");
|
||||
fRenderable->registerClass<RenderableLabels>("RenderableLabels");
|
||||
fRenderable->registerClass<RenderableModel>("RenderableModel");
|
||||
fRenderable->registerClass<RenderableNodeLine>("RenderableNodeLine");
|
||||
fRenderable->registerClass<RenderablePlaneImageLocal>("RenderablePlaneImageLocal");
|
||||
@@ -191,6 +193,7 @@ std::vector<documentation::Documentation> BaseModule::documentations() const {
|
||||
DashboardItemVelocity::Documentation(),
|
||||
|
||||
RenderableBoxGrid::Documentation(),
|
||||
RenderableLabels::Documentation(),
|
||||
RenderableModel::Documentation(),
|
||||
RenderableNodeLine::Documentation(),
|
||||
RenderablePlane::Documentation(),
|
||||
|
||||
816
modules/base/rendering/renderablelabels.cpp
Normal file
816
modules/base/rendering/renderablelabels.cpp
Normal file
@@ -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 <modules/base/rendering/renderablelabels.h>
|
||||
|
||||
#include <modules/base/basemodule.h>
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/documentation/verifier.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/filesystem/cachemanager.h>
|
||||
#include <ghoul/misc/crc32.h>
|
||||
#include <ghoul/misc/templatefactory.h>
|
||||
#include <ghoul/io/texture/texturereader.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/font/fontmanager.h>
|
||||
#include <ghoul/font/fontrenderer.h>
|
||||
#include <ghoul/misc/defer.h>
|
||||
#include <ghoul/opengl/programobject.h>
|
||||
#include <ghoul/opengl/texture.h>
|
||||
#include <ghoul/opengl/textureunit.h>
|
||||
#include <ghoul/glm.h>
|
||||
#include <glm/gtx/string_cast.hpp>
|
||||
|
||||
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<std::string>(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<std::string>(LabelOrientationOptionInfo.identifier)) {
|
||||
const std::string o = dictionary.value<std::string>(
|
||||
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<std::string>(LabelTextInfo.identifier);
|
||||
}
|
||||
addProperty(_labelText);
|
||||
|
||||
addProperty(_labelOrientationOption);
|
||||
|
||||
_labelColor.setViewOption(properties::Property::ViewOptions::Color);
|
||||
if (dictionary.hasKey(LabelColorInfo.identifier)) {
|
||||
_labelColor = dictionary.value<glm::vec4>(LabelColorInfo.identifier);
|
||||
}
|
||||
addProperty(_labelColor);
|
||||
|
||||
if (dictionary.hasKey(FontSizeInfo.identifier)) {
|
||||
_fontSize = dictionary.value<float>(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<float>(LabelSizeInfo.identifier);
|
||||
}
|
||||
addProperty(_labelSize);
|
||||
|
||||
if (dictionary.hasKey(LabelMinSizeInfo.identifier)) {
|
||||
_labelMinSize = dictionary.value<float>(LabelMinSizeInfo.identifier);
|
||||
}
|
||||
addProperty(_labelMinSize);
|
||||
|
||||
if (dictionary.hasKey(LabelMaxSizeInfo.identifier)) {
|
||||
_labelMaxSize = dictionary.value<float>(LabelMaxSizeInfo.identifier);
|
||||
}
|
||||
addProperty(_labelMaxSize);
|
||||
|
||||
if (dictionary.hasKey(TransformationMatrixInfo.identifier)) {
|
||||
_transformationMatrix = dictionary.value<glm::dmat4>(
|
||||
TransformationMatrixInfo.identifier
|
||||
);
|
||||
}
|
||||
|
||||
if (dictionary.hasKey(PixelSizeControlInfo.identifier)) {
|
||||
_pixelSizeControl = dictionary.value<bool>(PixelSizeControlInfo.identifier);
|
||||
addProperty(_pixelSizeControl);
|
||||
}
|
||||
|
||||
if (dictionary.hasKey(EnableFadingEffectInfo.identifier)) {
|
||||
_enableFadingEffect = dictionary.value<bool>(EnableFadingEffectInfo.identifier);
|
||||
}
|
||||
addProperty(_enableFadingEffect);
|
||||
|
||||
if (dictionary.hasKey(FadeStartDistInfo.identifier)) {
|
||||
_fadeStartDistance = dictionary.value<float>(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<std::string>(
|
||||
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<float>(FadeStartSpeedInfo.identifier);
|
||||
}
|
||||
|
||||
addProperty(_fadeStartSpeed);
|
||||
|
||||
if (dictionary.hasKey(FadeEndDistInfo.identifier)) {
|
||||
_fadeEndDistance = dictionary.value<float>(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<std::string>(
|
||||
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<float>(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<int>(_labelMinSize);
|
||||
labelInfo.maxSize = static_cast<int>(_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>(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<float>(PARSEC);
|
||||
break;
|
||||
case Kiloparsec:
|
||||
scale = static_cast<float>(1e3 * PARSEC);
|
||||
break;
|
||||
case Megaparsec:
|
||||
scale = static_cast<float>(1e6 * PARSEC);
|
||||
break;
|
||||
case Gigaparsec:
|
||||
scale = static_cast<float>(1e9 * PARSEC);
|
||||
break;
|
||||
case GigalightYears:
|
||||
scale = static_cast<float>(306391534.73091 * PARSEC);
|
||||
break;
|
||||
}
|
||||
|
||||
return scale;
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
134
modules/base/rendering/renderablelabels.h
Normal file
134
modules/base/rendering/renderablelabels.h
Normal file
@@ -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 <openspace/rendering/renderable.h>
|
||||
|
||||
#include <openspace/properties/optionproperty.h>
|
||||
#include <openspace/properties/stringproperty.h>
|
||||
#include <openspace/properties/scalar/boolproperty.h>
|
||||
#include <openspace/properties/scalar/floatproperty.h>
|
||||
#include <openspace/properties/vector/vec2property.h>
|
||||
#include <openspace/properties/vector/vec4property.h>
|
||||
|
||||
#include <ghoul/opengl/ghoul_gl.h>
|
||||
#include <ghoul/opengl/uniformcache.h>
|
||||
|
||||
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<ghoul::fontrendering::Font> _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__
|
||||
@@ -29,7 +29,7 @@
|
||||
#include <openspace/documentation/verifier.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/util/powerscaledsphere.h>
|
||||
#include <openspace/util/sphere.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
#include <ghoul/glm.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
@@ -304,7 +304,7 @@ bool RenderableSphere::isReady() const {
|
||||
}
|
||||
|
||||
void RenderableSphere::initializeGL() {
|
||||
_sphere = std::make_unique<PowerScaledSphere>(_size, _segments);
|
||||
_sphere = std::make_unique<Sphere>(_size, _segments);
|
||||
_sphere->initialize();
|
||||
|
||||
_shader = BaseModule::ProgramObjectManager.request(
|
||||
@@ -467,7 +467,7 @@ void RenderableSphere::update(const UpdateData&) {
|
||||
}
|
||||
|
||||
if (_sphereIsDirty) {
|
||||
_sphere = std::make_unique<PowerScaledSphere>(_size, _segments);
|
||||
_sphere = std::make_unique<Sphere>(_size, _segments);
|
||||
_sphere->initialize();
|
||||
_sphereIsDirty = false;
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace ghoul::opengl {
|
||||
|
||||
namespace openspace {
|
||||
|
||||
class PowerScaledSphere;
|
||||
class Sphere;
|
||||
struct RenderData;
|
||||
struct UpdateData;
|
||||
|
||||
@@ -80,7 +80,7 @@ private:
|
||||
ghoul::opengl::ProgramObject* _shader = nullptr;
|
||||
std::unique_ptr<ghoul::opengl::Texture> _texture;
|
||||
|
||||
std::unique_ptr<PowerScaledSphere> _sphere;
|
||||
std::unique_ptr<Sphere> _sphere;
|
||||
|
||||
UniformCache(opacity, modelViewProjection, modelViewRotation, colorTexture,
|
||||
_mirrorTexture) _uniformCache;
|
||||
|
||||
@@ -151,24 +151,15 @@ ScreenSpaceDashboard::ScreenSpaceDashboard(const ghoul::Dictionary& dictionary)
|
||||
"ScreenSpaceDashboard"
|
||||
);
|
||||
|
||||
int iIdentifier = 0;
|
||||
if (_identifier.empty()) {
|
||||
static int id = 0;
|
||||
iIdentifier = id;
|
||||
|
||||
if (iIdentifier == 0) {
|
||||
setIdentifier("ScreenSpaceDashboard");
|
||||
}
|
||||
else {
|
||||
setIdentifier("ScreenSpaceDashboard" + std::to_string(iIdentifier));
|
||||
}
|
||||
++id;
|
||||
std::string identifier;
|
||||
if (dictionary.hasKeyAndValue<std::string>(KeyIdentifier)) {
|
||||
identifier = dictionary.value<std::string>(KeyIdentifier);
|
||||
}
|
||||
|
||||
if (_guiName.empty()) {
|
||||
// Adding an extra space to the user-facing name as it looks nicer
|
||||
setGuiName("ScreenSpaceDashboard " + std::to_string(iIdentifier));
|
||||
else {
|
||||
identifier = "ScreenSpaceDashboard";
|
||||
}
|
||||
identifier = makeUniqueIdentifier(identifier);
|
||||
setIdentifier(std::move(identifier));
|
||||
|
||||
if (dictionary.hasKey(UseMainInfo.identifier)) {
|
||||
_useMainDashboard = dictionary.value<bool>(UseMainInfo.identifier);
|
||||
|
||||
@@ -78,24 +78,15 @@ ScreenSpaceImageLocal::ScreenSpaceImageLocal(const ghoul::Dictionary& dictionary
|
||||
"ScreenSpaceImageLocal"
|
||||
);
|
||||
|
||||
int iIdentifier = 0;
|
||||
if (_identifier.empty()) {
|
||||
static int id = 0;
|
||||
iIdentifier = id;
|
||||
|
||||
if (iIdentifier == 0) {
|
||||
setIdentifier("ScreenSpaceImageLocal");
|
||||
}
|
||||
else {
|
||||
setIdentifier("ScreenSpaceImageLocal" + std::to_string(iIdentifier));
|
||||
}
|
||||
++id;
|
||||
std::string identifier;
|
||||
if (dictionary.hasKeyAndValue<std::string>(KeyIdentifier)) {
|
||||
identifier = dictionary.value<std::string>(KeyIdentifier);
|
||||
}
|
||||
|
||||
if (_guiName.empty()) {
|
||||
// Adding an extra space to the user-facing name as it looks nicer
|
||||
setGuiName("ScreenSpaceImageLocal " + std::to_string(iIdentifier));
|
||||
else {
|
||||
identifier = "ScreenSpaceImageLocal";
|
||||
}
|
||||
identifier = makeUniqueIdentifier(identifier);
|
||||
setIdentifier(identifier);
|
||||
|
||||
_texturePath.onChange([this]() {
|
||||
if (!FileSys.fileExists(FileSys.absolutePath(_texturePath))) {
|
||||
|
||||
@@ -80,24 +80,15 @@ ScreenSpaceImageOnline::ScreenSpaceImageOnline(const ghoul::Dictionary& dictiona
|
||||
"ScreenSpaceImageOnline"
|
||||
);
|
||||
|
||||
int iIdentifier = 0;
|
||||
if (_identifier.empty()) {
|
||||
static int id = 0;
|
||||
iIdentifier = id;
|
||||
|
||||
if (iIdentifier == 0) {
|
||||
setIdentifier("ScreenSpaceImageOnline");
|
||||
}
|
||||
else {
|
||||
setIdentifier("ScreenSpaceImageOnline" + std::to_string(iIdentifier));
|
||||
}
|
||||
++id;
|
||||
std::string identifier;
|
||||
if (dictionary.hasKeyAndValue<std::string>(KeyIdentifier)) {
|
||||
identifier = dictionary.value<std::string>(KeyIdentifier);
|
||||
}
|
||||
|
||||
if (_guiName.empty()) {
|
||||
// Adding an extra space to the user-facing name as it looks nicer
|
||||
setGuiName("ScreenSpaceImageOnline " + std::to_string(iIdentifier));
|
||||
else {
|
||||
identifier = "ScreenSpaceImageOnline";
|
||||
}
|
||||
identifier = makeUniqueIdentifier(identifier);
|
||||
setIdentifier(std::move(identifier));
|
||||
|
||||
_texturePath.onChange([this]() { _textureIsDirty = true; });
|
||||
addProperty(_texturePath);
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
// @TODO (abock, 2019-12-27) Move this file to the spacecraftinstruments module
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
#include "PowerScaling/powerScaling_vs.hglsl"
|
||||
@@ -36,7 +38,7 @@ uniform mat4 modelViewProjectionTransform;
|
||||
|
||||
|
||||
void main() {
|
||||
vec4 position = vec4(in_position.xyz * pow(10, in_position.w), 1);
|
||||
vec4 position = vec4(in_position.xyz, 1);
|
||||
vec4 positionClipSpace = modelViewProjectionTransform * position;
|
||||
vec4 positionScreenSpace = z_normalization(positionClipSpace);
|
||||
|
||||
|
||||
@@ -103,7 +103,9 @@ void CefWebGuiModule::startOrStopGui() {
|
||||
new GUIKeyboardHandler
|
||||
);
|
||||
_instance->initialize();
|
||||
_instance->loadUrl(_url);
|
||||
if (!_url.value().empty()) {
|
||||
_instance->loadUrl(_url);
|
||||
}
|
||||
}
|
||||
if (_visible) {
|
||||
webBrowserModule->attachEventHandler(_instance.get());
|
||||
|
||||
@@ -42,7 +42,6 @@
|
||||
#include <ghoul/opengl/textureunit.h>
|
||||
#include <ghoul/font/fontmanager.h>
|
||||
#include <ghoul/font/fontrenderer.h>
|
||||
#include <ghoul/font/fontrenderer.h>
|
||||
#include <ghoul/glm.h>
|
||||
#include <glm/gtx/string_cast.hpp>
|
||||
#include <array>
|
||||
@@ -814,21 +813,23 @@ void RenderableBillboardsCloud::renderBillboards(const RenderData& data,
|
||||
_program->setUniform(_uniformCache.cameraPos, data.camera.positionVec3());
|
||||
_program->setUniform(
|
||||
_uniformCache.cameraLookup,
|
||||
data.camera.lookUpVectorWorldSpace()
|
||||
glm::vec3(data.camera.lookUpVectorWorldSpace())
|
||||
);
|
||||
_program->setUniform(_uniformCache.renderOption, _renderOption.value());
|
||||
_program->setUniform(_uniformCache.modelMatrix, modelMatrix);
|
||||
_program->setUniform(
|
||||
_uniformCache.cameraViewProjectionMatrix,
|
||||
glm::dmat4(data.camera.projectionMatrix()) * data.camera.combinedViewMatrix()
|
||||
glm::mat4(
|
||||
glm::dmat4(data.camera.projectionMatrix()) * data.camera.combinedViewMatrix()
|
||||
)
|
||||
);
|
||||
_program->setUniform(_uniformCache.minBillboardSize, _billboardMinSize); // in pixels
|
||||
_program->setUniform(_uniformCache.maxBillboardSize, _billboardMaxSize); // in pixels
|
||||
_program->setUniform(_uniformCache.color, _pointColor);
|
||||
_program->setUniform(_uniformCache.alphaValue, _opacity);
|
||||
_program->setUniform(_uniformCache.scaleFactor, _scaleFactor);
|
||||
_program->setUniform(_uniformCache.up, orthoUp);
|
||||
_program->setUniform(_uniformCache.right, orthoRight);
|
||||
_program->setUniform(_uniformCache.up, glm::vec3(orthoUp));
|
||||
_program->setUniform(_uniformCache.right, glm::vec3(orthoRight));
|
||||
_program->setUniform(_uniformCache.fadeInValue, fadeInVariable);
|
||||
|
||||
_program->setUniform(
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -35,18 +35,23 @@ uniform sampler2D spriteTexture;
|
||||
uniform bool hasColorMap;
|
||||
uniform float fadeInValue;
|
||||
|
||||
Fragment getFragment() {
|
||||
|
||||
Fragment getFragment() {
|
||||
vec4 textureColor = texture(spriteTexture, texCoord);
|
||||
|
||||
if (textureColor.a == 0.f || gs_colorMap.a == 0.f || ta == 0.f || fadeInValue == 0.f)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
|
||||
vec4 fullColor = vec4(1.0);
|
||||
|
||||
if (hasColorMap) {
|
||||
fullColor = vec4(
|
||||
gs_colorMap.rgb * textureColor.rgb,
|
||||
gs_colorMap.rgb * textureColor.rgb,
|
||||
gs_colorMap.a * textureColor.a * alphaValue
|
||||
);
|
||||
} else {
|
||||
);
|
||||
}
|
||||
else {
|
||||
fullColor = vec4(color.rgb * textureColor.rgb, textureColor.a * alphaValue);
|
||||
}
|
||||
|
||||
@@ -58,13 +63,13 @@ Fragment getFragment() {
|
||||
}
|
||||
|
||||
Fragment frag;
|
||||
frag.color = fullColor;
|
||||
frag.depth = vs_screenSpaceDepth;
|
||||
frag.color = fullColor;
|
||||
frag.depth = vs_screenSpaceDepth;
|
||||
// Setting the position of the billboards to not interact
|
||||
// with the ATM.
|
||||
frag.gPosition = vec4(-1e32, -1e32, -1e32, 1.0);
|
||||
frag.gNormal = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
frag.gPosition = vec4(-1e32, -1e32, -1e32, 1.0);
|
||||
frag.gNormal = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
//frag.disableLDR2HDR = true;
|
||||
|
||||
return frag;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,16 +30,16 @@ layout(points) in;
|
||||
layout(triangle_strip, max_vertices = 4) out;
|
||||
|
||||
uniform float scaleFactor;
|
||||
uniform dvec3 up;
|
||||
uniform dvec3 right;
|
||||
uniform vec3 up;
|
||||
uniform vec3 right;
|
||||
uniform dvec3 cameraPosition; // in world space (no SGCT View was considered)
|
||||
uniform dvec3 cameraLookUp; // in world space (no SGCT View was considered)
|
||||
uniform vec3 cameraLookUp; // in world space (no SGCT View was considered)
|
||||
uniform int renderOption;
|
||||
uniform vec2 screenSize;
|
||||
uniform float maxBillboardSize;
|
||||
uniform float minBillboardSize;
|
||||
|
||||
uniform dmat4 cameraViewProjectionMatrix;
|
||||
uniform mat4 cameraViewProjectionMatrix;
|
||||
uniform dmat4 modelMatrix;
|
||||
|
||||
uniform float correctionSizeFactor;
|
||||
@@ -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;
|
||||
@@ -94,11 +94,11 @@ void main() {
|
||||
dvec4 dpos = dvec4(dvec3(pos.xyz) * unit, 1.0);
|
||||
dpos = modelMatrix * dpos;
|
||||
|
||||
double scaleMultiply = exp(scaleFactor * 0.10);
|
||||
float scaleMultiply = exp(scaleFactor * 0.10f);
|
||||
scaleMultiply = hasDvarScaling ? dvarScaling[0] * scaleMultiply : scaleMultiply;
|
||||
|
||||
dvec3 scaledRight = dvec3(0.0);
|
||||
dvec3 scaledUp = dvec3(0.0);
|
||||
vec3 scaledRight = vec3(0.f);
|
||||
vec3 scaledUp = vec3(0.f);
|
||||
|
||||
vec4 initialPosition, secondPosition, thirdPosition, crossCorner;
|
||||
|
||||
@@ -106,15 +106,15 @@ void main() {
|
||||
scaledRight = scaleMultiply * right * 0.5f;
|
||||
scaledUp = scaleMultiply * up * 0.5f;
|
||||
} else if (renderOption == 1) {
|
||||
dvec3 normal = normalize(cameraPosition - dpos.xyz);
|
||||
dvec3 newRight = normalize(cross(cameraLookUp, normal));
|
||||
dvec3 newUp = cross(normal, newRight);
|
||||
vec3 normal = vec3(normalize(cameraPosition - dpos.xyz));
|
||||
vec3 newRight = normalize(cross(cameraLookUp, normal));
|
||||
vec3 newUp = cross(normal, newRight);
|
||||
|
||||
if (!enabledRectSizeControl) {
|
||||
double distCamera = length(cameraPosition - dpos.xyz);
|
||||
float expVar = float(-distCamera) / pow(10.f, correctionSizeEndDistance);
|
||||
double factorVar = double(pow(10, correctionSizeFactor));
|
||||
scaleMultiply *= 1.0 / (1.0 + factorVar * double(exp(expVar)));
|
||||
float factorVar = pow(10.f, correctionSizeFactor);
|
||||
scaleMultiply *= 1.f / (1.f + factorVar * exp(expVar));
|
||||
}
|
||||
|
||||
scaledRight = scaleMultiply * newRight * 0.5f;
|
||||
@@ -122,11 +122,13 @@ void main() {
|
||||
}
|
||||
|
||||
if (enabledRectSizeControl) {
|
||||
initialPosition = z_normalization(vec4(cameraViewProjectionMatrix *
|
||||
dvec4(dpos.xyz - scaledRight - scaledUp, dpos.w)));
|
||||
initialPosition = z_normalization(cameraViewProjectionMatrix *
|
||||
vec4(vec3(dpos.xyz) - scaledRight - scaledUp, dpos.w));
|
||||
|
||||
vs_screenSpaceDepth = initialPosition.w;
|
||||
crossCorner = z_normalization(vec4(cameraViewProjectionMatrix *
|
||||
dvec4(dpos.xyz + scaledUp + scaledRight, dpos.w)));
|
||||
|
||||
crossCorner = z_normalization(cameraViewProjectionMatrix *
|
||||
vec4(vec3(dpos.xyz) + scaledUp + scaledRight, dpos.w));
|
||||
|
||||
// Testing size for rectangular viewport:
|
||||
vec2 halfViewSize = vec2(screenSize.x, screenSize.y) * 0.5f;
|
||||
@@ -158,30 +160,35 @@ void main() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
initialPosition = z_normalization(vec4(cameraViewProjectionMatrix *
|
||||
dvec4(dpos.xyz - scaledRight - scaledUp, dpos.w)));
|
||||
vs_screenSpaceDepth = initialPosition.w;
|
||||
secondPosition = z_normalization(vec4(cameraViewProjectionMatrix *
|
||||
dvec4(dpos.xyz + scaledRight - scaledUp, dpos.w)));
|
||||
crossCorner = z_normalization(vec4(cameraViewProjectionMatrix *
|
||||
dvec4(dpos.xyz + scaledUp + scaledRight, dpos.w)));
|
||||
thirdPosition = z_normalization(vec4(cameraViewProjectionMatrix *
|
||||
dvec4(dpos.xyz + scaledUp - scaledRight, dpos.w)));
|
||||
|
||||
// Saving one matrix multiplication:
|
||||
vec4 dposClip = cameraViewProjectionMatrix * vec4(dpos);
|
||||
vec4 scaledRightClip = cameraViewProjectionMatrix * vec4(scaledRight, 0.0);
|
||||
vec4 scaledUpClip = cameraViewProjectionMatrix * vec4(scaledUp, 0.0);
|
||||
|
||||
initialPosition = z_normalization(dposClip - scaledRightClip - scaledUpClip);
|
||||
vs_screenSpaceDepth = initialPosition.w;
|
||||
secondPosition = z_normalization(dposClip + scaledRightClip - scaledUpClip);
|
||||
crossCorner = z_normalization(dposClip + scaledUpClip + scaledRightClip);
|
||||
thirdPosition = z_normalization(dposClip + scaledUpClip - scaledRightClip);
|
||||
|
||||
// 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();
|
||||
}
|
||||
@@ -34,7 +34,9 @@
|
||||
#include <openspace/util/boxgeometry.h>
|
||||
#include <openspace/util/distanceconstants.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
#include <ghoul/fmt.h>
|
||||
#include <ghoul/glm.h>
|
||||
#include <ghoul/filesystem/cachemanager.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/io/texture/texturereader.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
@@ -46,18 +48,21 @@
|
||||
#include <fstream>
|
||||
|
||||
namespace {
|
||||
constexpr int8_t CurrentCacheVersion = 1;
|
||||
|
||||
constexpr const char* GlslRaycastPath =
|
||||
"${MODULES}/galaxy/shaders/galaxyraycast.glsl";
|
||||
"${MODULE_GALAXY}/shaders/galaxyraycast.glsl";
|
||||
constexpr const char* GlslBoundsVsPath =
|
||||
"${MODULES}/galaxy/shaders/raycasterbounds_vs.glsl";
|
||||
"${MODULE_GALAXY}/shaders/raycasterbounds_vs.glsl";
|
||||
constexpr const char* GlslBoundsFsPath =
|
||||
"${MODULES}/galaxy/shaders/raycasterbounds_fs.glsl";
|
||||
constexpr const char* _loggerCat = "Renderable Galaxy";
|
||||
"${MODULE_GALAXY}/shaders/raycasterbounds_fs.glsl";
|
||||
constexpr const char* _loggerCat = "Renderable Galaxy";
|
||||
|
||||
constexpr const std::array<const char*, 4> UniformNamesPoints = {
|
||||
"modelMatrix", "cameraViewProjectionMatrix", "eyePosition",
|
||||
"opacityCoefficient"
|
||||
};
|
||||
|
||||
constexpr const std::array<const char*, 5> UniformNamesBillboards = {
|
||||
"modelMatrix", "cameraViewProjectionMatrix",
|
||||
"cameraUp", "eyePosition", "psfTexture"
|
||||
@@ -117,11 +122,55 @@ 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."
|
||||
};
|
||||
|
||||
void saveCachedFile(const std::string& file, const std::vector<glm::vec3>& positions,
|
||||
const std::vector<glm::vec3>& colors, int64_t nPoints,
|
||||
float pointsRatio)
|
||||
{
|
||||
std::ofstream fileStream(file, std::ofstream::binary);
|
||||
|
||||
if (!fileStream.good()) {
|
||||
LERROR(fmt::format("Error opening file '{}' for save cache file", file));
|
||||
return;
|
||||
}
|
||||
|
||||
fileStream.write(reinterpret_cast<const char*>(&CurrentCacheVersion), sizeof(int8_t));
|
||||
fileStream.write(reinterpret_cast<const char*>(&nPoints), sizeof(int64_t));
|
||||
fileStream.write(reinterpret_cast<const char*>(&pointsRatio), sizeof(float));
|
||||
uint64_t nPositions = static_cast<uint64_t>(positions.size());
|
||||
fileStream.write(reinterpret_cast<const char*>(&nPositions), sizeof(uint64_t));
|
||||
fileStream.write(
|
||||
reinterpret_cast<const char*>(positions.data()),
|
||||
positions.size() * sizeof(glm::vec3)
|
||||
);
|
||||
uint64_t nColors = static_cast<uint64_t>(colors.size());
|
||||
fileStream.write(reinterpret_cast<const char*>(&nColors), sizeof(uint64_t));
|
||||
fileStream.write(
|
||||
reinterpret_cast<const char*>(colors.data()),
|
||||
colors.size() * sizeof(glm::vec3)
|
||||
);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
|
||||
RenderableGalaxy::RenderableGalaxy(const ghoul::Dictionary& dictionary)
|
||||
RenderableGalaxy::RenderableGalaxy(const ghoul::Dictionary& dictionary)
|
||||
: Renderable(dictionary)
|
||||
, _volumeRenderingEnabled(VolumeRenderingEnabledInfo, true)
|
||||
, _starRenderingEnabled(StarRenderingEnabledInfo, true)
|
||||
@@ -135,6 +184,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);
|
||||
@@ -149,7 +200,7 @@ namespace openspace {
|
||||
if (dictionary.hasKeyAndValue<bool>(VolumeRenderingEnabledInfo.identifier)) {
|
||||
_volumeRenderingEnabled = dictionary.value<bool>(
|
||||
VolumeRenderingEnabledInfo.identifier
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
if (dictionary.hasKeyAndValue<bool>(StarRenderingEnabledInfo.identifier)) {
|
||||
@@ -224,6 +275,21 @@ namespace openspace {
|
||||
LERROR("No volume dimensions specified.");
|
||||
}
|
||||
|
||||
if (volumeDictionary.hasKey(NumberOfRayCastingStepsInfo.identifier)) {
|
||||
_numberOfRayCastingSteps = static_cast<float>(
|
||||
volumeDictionary.value<double>(NumberOfRayCastingStepsInfo.identifier)
|
||||
);
|
||||
}
|
||||
else {
|
||||
LINFO("Number of raycasting steps not specified. Using default value.");
|
||||
}
|
||||
|
||||
_downScaleVolumeRendering.setVisibility(properties::Property::Visibility::Developer);
|
||||
if (volumeDictionary.hasKey(DownscaleVolumeRenderingInfo.identifier)) {
|
||||
_downScaleVolumeRendering =
|
||||
volumeDictionary.value<float>(DownscaleVolumeRenderingInfo.identifier);
|
||||
}
|
||||
|
||||
if (!dictionary.hasKeyAndValue<ghoul::Dictionary>("Points")) {
|
||||
LERROR("No points dictionary specified.");
|
||||
}
|
||||
@@ -240,7 +306,7 @@ namespace openspace {
|
||||
if (pointsDictionary.hasKeyAndValue<double>(EnabledPointsRatioInfo.identifier)) {
|
||||
_enabledPointsRatio = static_cast<float>(
|
||||
pointsDictionary.value<double>(EnabledPointsRatioInfo.identifier)
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
std::string pointSpreadFunctionTexturePath;
|
||||
@@ -260,6 +326,7 @@ void RenderableGalaxy::initializeGL() {
|
||||
_aspect = static_cast<glm::vec3>(_volumeDimensions);
|
||||
_aspect /= std::max(std::max(_aspect.x, _aspect.y), _aspect.z);
|
||||
|
||||
// The volume
|
||||
volume::RawVolumeReader<glm::tvec4<GLubyte>> reader(
|
||||
_volumeFilename,
|
||||
_volumeDimensions
|
||||
@@ -272,10 +339,11 @@ void RenderableGalaxy::initializeGL() {
|
||||
GL_RGBA,
|
||||
GL_UNSIGNED_BYTE,
|
||||
ghoul::opengl::Texture::FilterMode::Linear,
|
||||
ghoul::opengl::Texture::WrappingMode::ClampToEdge);
|
||||
ghoul::opengl::Texture::WrappingMode::ClampToEdge
|
||||
);
|
||||
|
||||
_texture->setPixelData(reinterpret_cast<char*>(
|
||||
_volume->data()),
|
||||
_texture->setPixelData(
|
||||
reinterpret_cast<char*>(_volume->data()),
|
||||
ghoul::opengl::Texture::TakeOwnership::No
|
||||
);
|
||||
|
||||
@@ -307,133 +375,141 @@ void RenderableGalaxy::initializeGL() {
|
||||
addProperty(_enabledPointsRatio);
|
||||
addProperty(_translation);
|
||||
addProperty(_rotation);
|
||||
addProperty(_downScaleVolumeRendering);
|
||||
addProperty(_numberOfRayCastingSteps);
|
||||
|
||||
// initialize points.
|
||||
if (!_pointsFilename.empty()) {
|
||||
_pointsProgram = global::renderEngine.buildRenderProgram(
|
||||
"Galaxy points",
|
||||
absPath("${MODULE_GALAXY}/shaders/points_vs.glsl"),
|
||||
absPath("${MODULE_GALAXY}/shaders/points_fs.glsl")
|
||||
);
|
||||
_billboardsProgram = global::renderEngine.buildRenderProgram(
|
||||
"Galaxy billboard",
|
||||
absPath("${MODULE_GALAXY}/shaders/billboard_vs.glsl"),
|
||||
absPath("${MODULE_GALAXY}/shaders/billboard_fs.glsl"),
|
||||
absPath("${MODULE_GALAXY}/shaders/billboard_ge.glsl")
|
||||
);
|
||||
|
||||
if (!_pointSpreadFunctionTexturePath.empty()) {
|
||||
_pointSpreadFunctionTexture = ghoul::io::TextureReader::ref().loadTexture(
|
||||
absPath(_pointSpreadFunctionTexturePath)
|
||||
);
|
||||
|
||||
if (_pointSpreadFunctionTexture) {
|
||||
LDEBUG(fmt::format(
|
||||
"Loaded texture from '{}'",
|
||||
absPath(_pointSpreadFunctionTexturePath)
|
||||
));
|
||||
_pointSpreadFunctionTexture->uploadTexture();
|
||||
}
|
||||
_pointSpreadFunctionTexture->setFilter(
|
||||
ghoul::opengl::Texture::FilterMode::AnisotropicMipMap
|
||||
);
|
||||
|
||||
_pointSpreadFunctionFile = std::make_unique<ghoul::filesystem::File>(
|
||||
_pointSpreadFunctionTexturePath
|
||||
);
|
||||
}
|
||||
|
||||
ghoul::opengl::updateUniformLocations(
|
||||
*_pointsProgram,
|
||||
_uniformCachePoints,
|
||||
UniformNamesPoints
|
||||
);
|
||||
ghoul::opengl::updateUniformLocations(
|
||||
*_billboardsProgram,
|
||||
_uniformCacheBillboards,
|
||||
UniformNamesBillboards
|
||||
);
|
||||
|
||||
_pointsProgram->setIgnoreUniformLocationError(
|
||||
ghoul::opengl::ProgramObject::IgnoreError::Yes
|
||||
);
|
||||
|
||||
GLint positionAttrib = _pointsProgram->attributeLocation("in_position");
|
||||
GLint colorAttrib = _pointsProgram->attributeLocation("in_color");
|
||||
|
||||
std::ifstream pointFile(_pointsFilename, std::ios::in);
|
||||
|
||||
std::vector<glm::vec3> pointPositions;
|
||||
std::vector<glm::vec3> pointColors;
|
||||
int64_t nPoints;
|
||||
|
||||
// Read header for OFF (Object File Format)
|
||||
std::string line;
|
||||
std::getline(pointFile, line);
|
||||
|
||||
// Read point count
|
||||
std::getline(pointFile, line);
|
||||
std::istringstream iss(line);
|
||||
iss >> nPoints;
|
||||
|
||||
// Prepare point reading
|
||||
_nPoints = static_cast<size_t>(nPoints);
|
||||
float maxdist = 0;
|
||||
|
||||
// Read points
|
||||
float x, y, z, r, g, b, a;
|
||||
for (size_t i = 0;
|
||||
i < static_cast<size_t>(_nPoints * _enabledPointsRatio.maxValue()) + 1;
|
||||
++i)
|
||||
{
|
||||
std::getline(pointFile, line);
|
||||
std::istringstream issp(line);
|
||||
issp >> x >> y >> z >> r >> g >> b >> a;
|
||||
|
||||
//Convert klioparsec to meters
|
||||
glm::vec3 position = glm::vec3(x, y, z);
|
||||
position *= (openspace::distanceconstants::Parsec * 100);
|
||||
|
||||
maxdist = std::max(maxdist, glm::length(position));
|
||||
|
||||
pointPositions.emplace_back(position);
|
||||
pointColors.emplace_back(r, g, b);
|
||||
}
|
||||
|
||||
pointFile.close();
|
||||
|
||||
std::cout << maxdist << std::endl;
|
||||
|
||||
glGenVertexArrays(1, &_pointsVao);
|
||||
glGenBuffers(1, &_positionVbo);
|
||||
glGenBuffers(1, &_colorVbo);
|
||||
|
||||
glBindVertexArray(_pointsVao);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _positionVbo);
|
||||
glBufferData(GL_ARRAY_BUFFER,
|
||||
pointPositions.size() * sizeof(glm::vec3),
|
||||
pointPositions.data(),
|
||||
GL_STATIC_DRAW
|
||||
);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _colorVbo);
|
||||
glBufferData(GL_ARRAY_BUFFER,
|
||||
pointColors.size() * sizeof(glm::vec3),
|
||||
pointColors.data(),
|
||||
GL_STATIC_DRAW
|
||||
);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _positionVbo);
|
||||
glEnableVertexAttribArray(positionAttrib);
|
||||
glVertexAttribPointer(positionAttrib, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _colorVbo);
|
||||
glEnableVertexAttribArray(colorAttrib);
|
||||
glVertexAttribPointer(colorAttrib, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
if (_pointsFilename.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
_pointsProgram = global::renderEngine.buildRenderProgram(
|
||||
"Galaxy points",
|
||||
absPath("${MODULE_GALAXY}/shaders/points_vs.glsl"),
|
||||
absPath("${MODULE_GALAXY}/shaders/points_fs.glsl")
|
||||
);
|
||||
_billboardsProgram = global::renderEngine.buildRenderProgram(
|
||||
"Galaxy billboard",
|
||||
absPath("${MODULE_GALAXY}/shaders/billboard_vs.glsl"),
|
||||
absPath("${MODULE_GALAXY}/shaders/billboard_fs.glsl"),
|
||||
absPath("${MODULE_GALAXY}/shaders/billboard_ge.glsl")
|
||||
);
|
||||
|
||||
if (!_pointSpreadFunctionTexturePath.empty()) {
|
||||
_pointSpreadFunctionTexture = ghoul::io::TextureReader::ref().loadTexture(
|
||||
absPath(_pointSpreadFunctionTexturePath)
|
||||
);
|
||||
|
||||
if (_pointSpreadFunctionTexture) {
|
||||
LDEBUG(fmt::format(
|
||||
"Loaded texture from '{}'",
|
||||
absPath(_pointSpreadFunctionTexturePath)
|
||||
));
|
||||
_pointSpreadFunctionTexture->uploadTexture();
|
||||
}
|
||||
_pointSpreadFunctionTexture->setFilter(
|
||||
ghoul::opengl::Texture::FilterMode::AnisotropicMipMap
|
||||
);
|
||||
|
||||
_pointSpreadFunctionFile = std::make_unique<ghoul::filesystem::File>(
|
||||
_pointSpreadFunctionTexturePath
|
||||
);
|
||||
}
|
||||
|
||||
ghoul::opengl::updateUniformLocations(
|
||||
*_pointsProgram,
|
||||
_uniformCachePoints,
|
||||
UniformNamesPoints
|
||||
);
|
||||
ghoul::opengl::updateUniformLocations(
|
||||
*_billboardsProgram,
|
||||
_uniformCacheBillboards,
|
||||
UniformNamesBillboards
|
||||
);
|
||||
|
||||
_pointsProgram->setIgnoreUniformLocationError(
|
||||
ghoul::opengl::ProgramObject::IgnoreError::Yes
|
||||
);
|
||||
|
||||
GLint positionAttrib = _pointsProgram->attributeLocation("in_position");
|
||||
GLint colorAttrib = _pointsProgram->attributeLocation("in_color");
|
||||
|
||||
|
||||
std::vector<glm::vec3> pointPositions;
|
||||
std::vector<glm::vec3> pointColors;
|
||||
|
||||
std::string cachedPointsFile = FileSys.cacheManager()->cachedFilename(
|
||||
_pointsFilename,
|
||||
ghoul::filesystem::CacheManager::Persistent::Yes
|
||||
);
|
||||
const bool hasCachedFile = FileSys.fileExists(cachedPointsFile);
|
||||
if (hasCachedFile) {
|
||||
LINFO(fmt::format("Cached file '{}' used for galaxy point file '{}'",
|
||||
cachedPointsFile, _pointsFilename
|
||||
));
|
||||
|
||||
Result res = loadCachedFile(cachedPointsFile);
|
||||
if (res.success) {
|
||||
pointPositions = std::move(res.positions);
|
||||
pointColors = std::move(res.color);
|
||||
}
|
||||
else {
|
||||
FileSys.cacheManager()->removeCacheFile(_pointsFilename);
|
||||
Result res = loadPointFile(_pointsFilename);
|
||||
pointPositions = std::move(res.positions);
|
||||
pointColors = std::move(res.color);
|
||||
saveCachedFile(
|
||||
cachedPointsFile,
|
||||
pointPositions,
|
||||
pointColors,
|
||||
_nPoints,
|
||||
_enabledPointsRatio
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Result res = loadPointFile(_pointsFilename);
|
||||
ghoul_assert(res.success, "Point file loading failed");
|
||||
pointPositions = std::move(res.positions);
|
||||
pointColors = std::move(res.color);
|
||||
saveCachedFile(
|
||||
cachedPointsFile,
|
||||
pointPositions,
|
||||
pointColors,
|
||||
_nPoints,
|
||||
_enabledPointsRatio
|
||||
);
|
||||
}
|
||||
|
||||
glGenVertexArrays(1, &_pointsVao);
|
||||
glGenBuffers(1, &_positionVbo);
|
||||
glGenBuffers(1, &_colorVbo);
|
||||
|
||||
glBindVertexArray(_pointsVao);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _positionVbo);
|
||||
glBufferData(GL_ARRAY_BUFFER,
|
||||
pointPositions.size() * sizeof(glm::vec3),
|
||||
pointPositions.data(),
|
||||
GL_STATIC_DRAW
|
||||
);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _colorVbo);
|
||||
glBufferData(GL_ARRAY_BUFFER,
|
||||
pointColors.size() * sizeof(glm::vec3),
|
||||
pointColors.data(),
|
||||
GL_STATIC_DRAW
|
||||
);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _positionVbo);
|
||||
glEnableVertexAttribArray(positionAttrib);
|
||||
glVertexAttribPointer(positionAttrib, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _colorVbo);
|
||||
glEnableVertexAttribArray(colorAttrib);
|
||||
glVertexAttribPointer(colorAttrib, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
void RenderableGalaxy::deinitializeGL() {
|
||||
@@ -441,6 +517,10 @@ void RenderableGalaxy::deinitializeGL() {
|
||||
global::raycasterManager.detachRaycaster(*_raycaster);
|
||||
_raycaster = nullptr;
|
||||
}
|
||||
|
||||
glDeleteVertexArrays(1, &_pointsVao);
|
||||
glDeleteBuffers(1, &_positionVbo);
|
||||
glDeleteBuffers(1, &_colorVbo);
|
||||
}
|
||||
|
||||
bool RenderableGalaxy::isReady() const {
|
||||
@@ -448,41 +528,44 @@ bool RenderableGalaxy::isReady() const {
|
||||
}
|
||||
|
||||
void RenderableGalaxy::update(const UpdateData& data) {
|
||||
if (_raycaster) {
|
||||
//glm::mat4 transform = glm::translate(, static_cast<glm::vec3>(_translation));
|
||||
const glm::vec3 eulerRotation = static_cast<glm::vec3>(_rotation);
|
||||
glm::mat4 transform = glm::rotate(
|
||||
glm::mat4(1.0),
|
||||
eulerRotation.x,
|
||||
glm::vec3(1, 0, 0)
|
||||
);
|
||||
transform = glm::rotate(transform, eulerRotation.y, glm::vec3(0, 1, 0));
|
||||
transform = glm::rotate(transform, eulerRotation.z, glm::vec3(0, 0, 1));
|
||||
|
||||
glm::mat4 volumeTransform = glm::scale(transform, _volumeSize);
|
||||
_pointTransform = transform;
|
||||
//_pointTransform = glm::scale(transform, _pointScaling);
|
||||
|
||||
const glm::vec4 translation = glm::vec4(_translation.value()*_volumeSize, 0.0);
|
||||
|
||||
// Todo: handle floating point overflow, to actually support translation.
|
||||
|
||||
volumeTransform[3] += translation;
|
||||
_pointTransform[3] += translation;
|
||||
|
||||
_raycaster->setStepSize(_stepSize);
|
||||
_raycaster->setAspect(_aspect);
|
||||
_raycaster->setModelTransform(volumeTransform);
|
||||
_raycaster->setAbsorptionMultiplier(_absorptionMultiply);
|
||||
_raycaster->setEmissionMultiplier(_emissionMultiply);
|
||||
_raycaster->setTime(data.time.j2000Seconds());
|
||||
if (!_raycaster) {
|
||||
return;
|
||||
}
|
||||
//glm::mat4 transform = glm::translate(, static_cast<glm::vec3>(_translation));
|
||||
const glm::vec3 eulerRotation = static_cast<glm::vec3>(_rotation);
|
||||
glm::mat4 transform = glm::rotate(
|
||||
glm::mat4(1.0),
|
||||
eulerRotation.x,
|
||||
glm::vec3(1, 0, 0)
|
||||
);
|
||||
transform = glm::rotate(transform, eulerRotation.y, glm::vec3(0, 1, 0));
|
||||
transform = glm::rotate(transform, eulerRotation.z, glm::vec3(0, 0, 1));
|
||||
|
||||
glm::mat4 volumeTransform = glm::scale(transform, _volumeSize);
|
||||
_pointTransform = transform;
|
||||
//_pointTransform = glm::scale(transform, _pointScaling);
|
||||
|
||||
const glm::vec4 translation = glm::vec4(_translation.value()*_volumeSize, 0.0);
|
||||
|
||||
// Todo: handle floating point overflow, to actually support translation.
|
||||
|
||||
volumeTransform[3] += translation;
|
||||
_pointTransform[3] += translation;
|
||||
|
||||
_raycaster->setDownscaleRender(_downScaleVolumeRendering);
|
||||
_raycaster->setMaxSteps(_numberOfRayCastingSteps);
|
||||
_raycaster->setStepSize(_stepSize);
|
||||
_raycaster->setAspect(_aspect);
|
||||
_raycaster->setModelTransform(volumeTransform);
|
||||
_raycaster->setAbsorptionMultiplier(_absorptionMultiply);
|
||||
_raycaster->setEmissionMultiplier(_emissionMultiply);
|
||||
_raycaster->setTime(data.time.j2000Seconds());
|
||||
}
|
||||
|
||||
void RenderableGalaxy::render(const RenderData& data, RendererTasks& tasks) {
|
||||
// Render the volume
|
||||
if (_raycaster && _volumeRenderingEnabled) {
|
||||
RaycasterTask task{ _raycaster.get(), data };
|
||||
RaycasterTask task { _raycaster.get(), data };
|
||||
|
||||
const glm::vec3 position = data.camera.positionVec3();
|
||||
const float length = safeLength(position);
|
||||
@@ -499,15 +582,19 @@ void RenderableGalaxy::render(const RenderData& data, RendererTasks& tasks) {
|
||||
float opacityCoefficient = 1.f;
|
||||
if (length < lowerRampStart) {
|
||||
opacityCoefficient = 0.f; // camera really close
|
||||
} else if (length < lowerRampEnd) {
|
||||
}
|
||||
else if (length < lowerRampEnd) {
|
||||
opacityCoefficient = (length - lowerRampStart) /
|
||||
(lowerRampEnd - lowerRampStart);
|
||||
} else if (length < upperRampStart) {
|
||||
}
|
||||
else if (length < upperRampStart) {
|
||||
opacityCoefficient = 1.f; // sweet spot (max)
|
||||
} else if (length < upperRampEnd) {
|
||||
}
|
||||
else if (length < upperRampEnd) {
|
||||
opacityCoefficient = 1.f - (length - upperRampStart) /
|
||||
(upperRampEnd - upperRampStart); //fade out
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
opacityCoefficient = 0;
|
||||
}
|
||||
|
||||
@@ -534,163 +621,166 @@ void RenderableGalaxy::render(const RenderData& data, RendererTasks& tasks) {
|
||||
}
|
||||
|
||||
void RenderableGalaxy::renderPoints(const RenderData& data) {
|
||||
if (_pointsProgram) {
|
||||
// Saving current OpenGL state
|
||||
GLenum blendEquationRGB;
|
||||
GLenum blendEquationAlpha;
|
||||
GLenum blendDestAlpha;
|
||||
GLenum blendDestRGB;
|
||||
GLenum blendSrcAlpha;
|
||||
GLenum blendSrcRGB;
|
||||
GLboolean depthMask;
|
||||
|
||||
glGetIntegerv(GL_BLEND_EQUATION_RGB, &blendEquationRGB);
|
||||
glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &blendEquationAlpha);
|
||||
glGetIntegerv(GL_BLEND_DST_ALPHA, &blendDestAlpha);
|
||||
glGetIntegerv(GL_BLEND_DST_RGB, &blendDestRGB);
|
||||
glGetIntegerv(GL_BLEND_SRC_ALPHA, &blendSrcAlpha);
|
||||
glGetIntegerv(GL_BLEND_SRC_RGB, &blendSrcRGB);
|
||||
|
||||
glGetBooleanv(GL_DEPTH_WRITEMASK, &depthMask);
|
||||
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
glDepthMask(false);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
_pointsProgram->activate();
|
||||
|
||||
glm::dmat4 rotMatrix = glm::rotate(
|
||||
glm::dmat4(1.0),
|
||||
glm::pi<double>(),
|
||||
glm::dvec3(1.0, 0.0, 0.0)) *
|
||||
glm::rotate(glm::dmat4(1.0), 3.1248, glm::dvec3(0.0, 1.0, 0.0)) *
|
||||
glm::rotate(glm::dmat4(1.0), 4.45741, glm::dvec3(0.0, 0.0, 1.0)
|
||||
);
|
||||
|
||||
glm::dmat4 modelMatrix =
|
||||
glm::translate(glm::dmat4(1.0), data.modelTransform.translation) *
|
||||
glm::dmat4(data.modelTransform.rotation) * rotMatrix *
|
||||
glm::dmat4(glm::scale(glm::dmat4(1.0), glm::dvec3(data.modelTransform.scale)));
|
||||
|
||||
glm::dmat4 projectionMatrix = glm::dmat4(data.camera.projectionMatrix());
|
||||
|
||||
glm::dmat4 cameraViewProjectionMatrix = projectionMatrix *
|
||||
data.camera.combinedViewMatrix();
|
||||
|
||||
_pointsProgram->setUniform(_uniformCachePoints.modelMatrix, modelMatrix);
|
||||
_pointsProgram->setUniform(
|
||||
_uniformCachePoints.cameraViewProjectionMatrix,
|
||||
cameraViewProjectionMatrix
|
||||
);
|
||||
|
||||
glm::dvec3 eyePosition = glm::dvec3(
|
||||
glm::inverse(data.camera.combinedViewMatrix()) *
|
||||
glm::dvec4(0.0, 0.0, 0.0, 1.0)
|
||||
);
|
||||
_pointsProgram->setUniform(_uniformCachePoints.eyePosition, eyePosition);
|
||||
_pointsProgram->setUniform(
|
||||
_uniformCachePoints.opacityCoefficient,
|
||||
_opacityCoefficient
|
||||
);
|
||||
|
||||
glBindVertexArray(_pointsVao);
|
||||
glDrawArrays(GL_POINTS, 0, static_cast<GLsizei>(_nPoints * _enabledPointsRatio));
|
||||
|
||||
glBindVertexArray(0);
|
||||
|
||||
_pointsProgram->deactivate();
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(true);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
// Restores OpenGL blending state
|
||||
glBlendEquationSeparate(blendEquationRGB, blendEquationAlpha);
|
||||
glBlendFuncSeparate(blendSrcRGB, blendDestRGB, blendSrcAlpha, blendDestAlpha);
|
||||
glDepthMask(depthMask);
|
||||
if (!_pointsProgram) {
|
||||
return;
|
||||
}
|
||||
// Saving current OpenGL state
|
||||
GLenum blendEquationRGB;
|
||||
GLenum blendEquationAlpha;
|
||||
GLenum blendDestAlpha;
|
||||
GLenum blendDestRGB;
|
||||
GLenum blendSrcAlpha;
|
||||
GLenum blendSrcRGB;
|
||||
GLboolean depthMask;
|
||||
|
||||
glGetIntegerv(GL_BLEND_EQUATION_RGB, &blendEquationRGB);
|
||||
glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &blendEquationAlpha);
|
||||
glGetIntegerv(GL_BLEND_DST_ALPHA, &blendDestAlpha);
|
||||
glGetIntegerv(GL_BLEND_DST_RGB, &blendDestRGB);
|
||||
glGetIntegerv(GL_BLEND_SRC_ALPHA, &blendSrcAlpha);
|
||||
glGetIntegerv(GL_BLEND_SRC_RGB, &blendSrcRGB);
|
||||
|
||||
glGetBooleanv(GL_DEPTH_WRITEMASK, &depthMask);
|
||||
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
glDepthMask(false);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
_pointsProgram->activate();
|
||||
|
||||
glm::dmat4 rotMatrix = glm::rotate(
|
||||
glm::dmat4(1.0),
|
||||
glm::pi<double>(),
|
||||
glm::dvec3(1.0, 0.0, 0.0)) *
|
||||
glm::rotate(glm::dmat4(1.0), 3.1248, glm::dvec3(0.0, 1.0, 0.0)) *
|
||||
glm::rotate(glm::dmat4(1.0), 4.45741, glm::dvec3(0.0, 0.0, 1.0)
|
||||
);
|
||||
|
||||
glm::dmat4 modelMatrix =
|
||||
glm::translate(glm::dmat4(1.0), data.modelTransform.translation) *
|
||||
glm::dmat4(data.modelTransform.rotation) * rotMatrix *
|
||||
glm::dmat4(glm::scale(glm::dmat4(1.0), glm::dvec3(data.modelTransform.scale)));
|
||||
|
||||
glm::dmat4 projectionMatrix = glm::dmat4(data.camera.projectionMatrix());
|
||||
|
||||
glm::dmat4 cameraViewProjectionMatrix = projectionMatrix *
|
||||
data.camera.combinedViewMatrix();
|
||||
|
||||
_pointsProgram->setUniform(_uniformCachePoints.modelMatrix, modelMatrix);
|
||||
_pointsProgram->setUniform(
|
||||
_uniformCachePoints.cameraViewProjectionMatrix,
|
||||
cameraViewProjectionMatrix
|
||||
);
|
||||
|
||||
glm::dvec3 eyePosition = glm::dvec3(
|
||||
glm::inverse(data.camera.combinedViewMatrix()) *
|
||||
glm::dvec4(0.0, 0.0, 0.0, 1.0)
|
||||
);
|
||||
_pointsProgram->setUniform(_uniformCachePoints.eyePosition, eyePosition);
|
||||
_pointsProgram->setUniform(
|
||||
_uniformCachePoints.opacityCoefficient,
|
||||
_opacityCoefficient
|
||||
);
|
||||
|
||||
glBindVertexArray(_pointsVao);
|
||||
glDrawArrays(GL_POINTS, 0, static_cast<GLsizei>(_nPoints * _enabledPointsRatio));
|
||||
|
||||
glBindVertexArray(0);
|
||||
|
||||
_pointsProgram->deactivate();
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(true);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
// Restores OpenGL blending state
|
||||
glBlendEquationSeparate(blendEquationRGB, blendEquationAlpha);
|
||||
glBlendFuncSeparate(blendSrcRGB, blendDestRGB, blendSrcAlpha, blendDestAlpha);
|
||||
glDepthMask(depthMask);
|
||||
}
|
||||
|
||||
void RenderableGalaxy::renderBillboards(const RenderData& data) {
|
||||
if (_billboardsProgram) {
|
||||
// Saving current OpenGL state
|
||||
GLenum blendEquationRGB;
|
||||
GLenum blendEquationAlpha;
|
||||
GLenum blendDestAlpha;
|
||||
GLenum blendDestRGB;
|
||||
GLenum blendSrcAlpha;
|
||||
GLenum blendSrcRGB;
|
||||
GLboolean depthMask;
|
||||
|
||||
glGetIntegerv(GL_BLEND_EQUATION_RGB, &blendEquationRGB);
|
||||
glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &blendEquationAlpha);
|
||||
glGetIntegerv(GL_BLEND_DST_ALPHA, &blendDestAlpha);
|
||||
glGetIntegerv(GL_BLEND_DST_RGB, &blendDestRGB);
|
||||
glGetIntegerv(GL_BLEND_SRC_ALPHA, &blendSrcAlpha);
|
||||
glGetIntegerv(GL_BLEND_SRC_RGB, &blendSrcRGB);
|
||||
|
||||
glGetBooleanv(GL_DEPTH_WRITEMASK, &depthMask);
|
||||
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
glDepthMask(false);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
_billboardsProgram->activate();
|
||||
|
||||
glm::dmat4 rotMatrix = glm::rotate(
|
||||
glm::dmat4(1.0),
|
||||
glm::pi<double>(),
|
||||
glm::dvec3(1.0, 0.0, 0.0)) *
|
||||
glm::rotate(glm::dmat4(1.0), 3.1248, glm::dvec3(0.0, 1.0, 0.0)) *
|
||||
glm::rotate(glm::dmat4(1.0), 4.45741, glm::dvec3(0.0, 0.0, 1.0)
|
||||
);
|
||||
|
||||
glm::dmat4 modelMatrix =
|
||||
glm::translate(glm::dmat4(1.0), data.modelTransform.translation) *
|
||||
glm::dmat4(data.modelTransform.rotation) * rotMatrix *
|
||||
glm::dmat4(glm::scale(glm::dmat4(1.0), glm::dvec3(data.modelTransform.scale)));
|
||||
|
||||
glm::dmat4 projectionMatrix = glm::dmat4(data.camera.projectionMatrix());
|
||||
|
||||
glm::dmat4 cameraViewProjectionMatrix = projectionMatrix *
|
||||
data.camera.combinedViewMatrix();
|
||||
|
||||
_billboardsProgram->setUniform(_uniformCacheBillboards.modelMatrix, modelMatrix);
|
||||
_billboardsProgram->setUniform(
|
||||
_uniformCacheBillboards.cameraViewProjectionMatrix,
|
||||
cameraViewProjectionMatrix
|
||||
);
|
||||
|
||||
glm::dvec3 eyePosition = glm::dvec3(
|
||||
glm::inverse(data.camera.combinedViewMatrix()) *
|
||||
glm::dvec4(0.0, 0.0, 0.0, 1.0)
|
||||
);
|
||||
_billboardsProgram->setUniform(_uniformCacheBillboards.eyePosition, eyePosition);
|
||||
|
||||
glm::dvec3 cameraUp = data.camera.lookUpVectorWorldSpace();
|
||||
_billboardsProgram->setUniform(_uniformCacheBillboards.cameraUp, cameraUp);
|
||||
|
||||
ghoul::opengl::TextureUnit psfUnit;
|
||||
psfUnit.activate();
|
||||
_pointSpreadFunctionTexture->bind();
|
||||
_billboardsProgram->setUniform(_uniformCacheBillboards.psfTexture, psfUnit);
|
||||
|
||||
glBindVertexArray(_pointsVao);
|
||||
glDrawArrays(GL_POINTS, 0, static_cast<GLsizei>(_nPoints * _enabledPointsRatio));
|
||||
|
||||
glBindVertexArray(0);
|
||||
|
||||
_billboardsProgram->deactivate();
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(true);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
// Restores OpenGL blending state
|
||||
glBlendEquationSeparate(blendEquationRGB, blendEquationAlpha);
|
||||
glBlendFuncSeparate(blendSrcRGB, blendDestRGB, blendSrcAlpha, blendDestAlpha);
|
||||
glDepthMask(depthMask);
|
||||
if (!_billboardsProgram) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Saving current OpenGL state
|
||||
GLenum blendEquationRGB;
|
||||
GLenum blendEquationAlpha;
|
||||
GLenum blendDestAlpha;
|
||||
GLenum blendDestRGB;
|
||||
GLenum blendSrcAlpha;
|
||||
GLenum blendSrcRGB;
|
||||
GLboolean depthMask;
|
||||
|
||||
glGetIntegerv(GL_BLEND_EQUATION_RGB, &blendEquationRGB);
|
||||
glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &blendEquationAlpha);
|
||||
glGetIntegerv(GL_BLEND_DST_ALPHA, &blendDestAlpha);
|
||||
glGetIntegerv(GL_BLEND_DST_RGB, &blendDestRGB);
|
||||
glGetIntegerv(GL_BLEND_SRC_ALPHA, &blendSrcAlpha);
|
||||
glGetIntegerv(GL_BLEND_SRC_RGB, &blendSrcRGB);
|
||||
|
||||
glGetBooleanv(GL_DEPTH_WRITEMASK, &depthMask);
|
||||
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
glDepthMask(false);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
_billboardsProgram->activate();
|
||||
|
||||
glm::dmat4 rotMatrix = glm::rotate(
|
||||
glm::dmat4(1.0),
|
||||
glm::pi<double>(),
|
||||
glm::dvec3(1.0, 0.0, 0.0)) *
|
||||
glm::rotate(glm::dmat4(1.0), 3.1248, glm::dvec3(0.0, 1.0, 0.0)) *
|
||||
glm::rotate(glm::dmat4(1.0), 4.45741, glm::dvec3(0.0, 0.0, 1.0)
|
||||
);
|
||||
|
||||
glm::dmat4 modelMatrix =
|
||||
glm::translate(glm::dmat4(1.0), data.modelTransform.translation) *
|
||||
glm::dmat4(data.modelTransform.rotation) * rotMatrix *
|
||||
glm::dmat4(glm::scale(glm::dmat4(1.0), glm::dvec3(data.modelTransform.scale)));
|
||||
|
||||
glm::dmat4 projectionMatrix = glm::dmat4(data.camera.projectionMatrix());
|
||||
|
||||
glm::dmat4 cameraViewProjectionMatrix = projectionMatrix *
|
||||
data.camera.combinedViewMatrix();
|
||||
|
||||
_billboardsProgram->setUniform(_uniformCacheBillboards.modelMatrix, modelMatrix);
|
||||
_billboardsProgram->setUniform(
|
||||
_uniformCacheBillboards.cameraViewProjectionMatrix,
|
||||
cameraViewProjectionMatrix
|
||||
);
|
||||
|
||||
glm::dvec3 eyePosition = glm::dvec3(
|
||||
glm::inverse(data.camera.combinedViewMatrix()) *
|
||||
glm::dvec4(0.0, 0.0, 0.0, 1.0)
|
||||
);
|
||||
_billboardsProgram->setUniform(_uniformCacheBillboards.eyePosition, eyePosition);
|
||||
|
||||
glm::dvec3 cameraUp = data.camera.lookUpVectorWorldSpace();
|
||||
_billboardsProgram->setUniform(_uniformCacheBillboards.cameraUp, cameraUp);
|
||||
|
||||
ghoul::opengl::TextureUnit psfUnit;
|
||||
psfUnit.activate();
|
||||
_pointSpreadFunctionTexture->bind();
|
||||
_billboardsProgram->setUniform(_uniformCacheBillboards.psfTexture, psfUnit);
|
||||
|
||||
glBindVertexArray(_pointsVao);
|
||||
glDrawArrays(GL_POINTS, 0, static_cast<GLsizei>(_nPoints * _enabledPointsRatio));
|
||||
|
||||
glBindVertexArray(0);
|
||||
|
||||
_billboardsProgram->deactivate();
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(true);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
// Restores OpenGL blending state
|
||||
glBlendEquationSeparate(blendEquationRGB, blendEquationAlpha);
|
||||
glBlendFuncSeparate(blendSrcRGB, blendDestRGB, blendSrcAlpha, blendDestAlpha);
|
||||
glDepthMask(depthMask);
|
||||
}
|
||||
|
||||
float RenderableGalaxy::safeLength(const glm::vec3& vector) const {
|
||||
@@ -700,4 +790,95 @@ float RenderableGalaxy::safeLength(const glm::vec3& vector) const {
|
||||
return glm::length(vector / maxComponent) * maxComponent;
|
||||
}
|
||||
|
||||
RenderableGalaxy::Result RenderableGalaxy::loadPointFile(const std::string& file) {
|
||||
std::vector<glm::vec3> pointPositions;
|
||||
std::vector<glm::vec3> pointColors;
|
||||
int64_t nPoints;
|
||||
|
||||
std::ifstream pointFile(_pointsFilename, std::ios::in);
|
||||
|
||||
// Read header for OFF (Object File Format)
|
||||
std::string line;
|
||||
std::getline(pointFile, line);
|
||||
|
||||
// Read point count
|
||||
std::getline(pointFile, line);
|
||||
std::istringstream iss(line);
|
||||
iss >> nPoints;
|
||||
|
||||
// Prepare point reading
|
||||
_nPoints = static_cast<size_t>(nPoints);
|
||||
|
||||
// Read points
|
||||
float x, y, z, r, g, b, a;
|
||||
for (size_t i = 0;
|
||||
i < static_cast<size_t>(_nPoints * _enabledPointsRatio.maxValue()) + 1;
|
||||
++i)
|
||||
{
|
||||
std::getline(pointFile, line);
|
||||
std::istringstream issp(line);
|
||||
issp >> x >> y >> z >> r >> g >> b >> a;
|
||||
|
||||
// Convert kiloparsec to meters
|
||||
glm::vec3 position = glm::vec3(x, y, z);
|
||||
position *= (distanceconstants::Parsec * 100);
|
||||
|
||||
pointPositions.emplace_back(position);
|
||||
pointColors.emplace_back(r, g, b);
|
||||
}
|
||||
|
||||
Result res;
|
||||
res.success = true;
|
||||
res.positions = std::move(pointPositions);
|
||||
res.color = std::move(pointColors);
|
||||
return res;
|
||||
}
|
||||
|
||||
RenderableGalaxy::Result RenderableGalaxy::loadCachedFile(const std::string& file) {
|
||||
std::ifstream fileStream(file, std::ifstream::binary);
|
||||
if (!fileStream.good()) {
|
||||
LERROR(fmt::format("Error opening file '{}' for loading cache file", file));
|
||||
return { false, {}, {} };
|
||||
}
|
||||
|
||||
int8_t cacheVersion;
|
||||
fileStream.read(reinterpret_cast<char*>(&cacheVersion), sizeof(int8_t));
|
||||
if (cacheVersion != CurrentCacheVersion) {
|
||||
LINFO(fmt::format("Removing cache file '{}' as the version changed"));
|
||||
return { false, {}, {} };
|
||||
}
|
||||
|
||||
int64_t nPoints;
|
||||
fileStream.read(reinterpret_cast<char*>(&nPoints), sizeof(int64_t));
|
||||
_nPoints = static_cast<size_t>(nPoints);
|
||||
|
||||
float enabledPointsRatio;
|
||||
fileStream.read(reinterpret_cast<char*>(&enabledPointsRatio), sizeof(float));
|
||||
_enabledPointsRatio = enabledPointsRatio;
|
||||
|
||||
uint64_t nPositions;
|
||||
fileStream.read(reinterpret_cast<char*>(&nPositions), sizeof(uint64_t));
|
||||
std::vector<glm::vec3> positions;
|
||||
positions.resize(nPositions);
|
||||
fileStream.read(
|
||||
reinterpret_cast<char*>(positions.data()),
|
||||
nPositions * sizeof(glm::vec3)
|
||||
);
|
||||
|
||||
uint64_t nColors;
|
||||
fileStream.read(reinterpret_cast<char*>(&nColors), sizeof(uint64_t));
|
||||
std::vector<glm::vec3> colors;
|
||||
colors.resize(nColors);
|
||||
fileStream.read(
|
||||
reinterpret_cast<char*>(colors.data()),
|
||||
nColors * sizeof(glm::vec3)
|
||||
);
|
||||
|
||||
Result result;
|
||||
result.success = true;
|
||||
result.positions = std::move(positions);
|
||||
result.color = std::move(colors);
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -33,9 +33,7 @@
|
||||
#include <ghoul/opengl/ghoul_gl.h>
|
||||
#include <ghoul/opengl/uniformcache.h>
|
||||
|
||||
namespace ghoul::opengl {
|
||||
class ProgramObject;
|
||||
} // namespace ghoul::opengl
|
||||
namespace ghoul::opengl { class ProgramObject; }
|
||||
|
||||
namespace openspace {
|
||||
|
||||
@@ -60,6 +58,14 @@ private:
|
||||
void renderBillboards(const RenderData& data);
|
||||
float safeLength(const glm::vec3& vector) const;
|
||||
|
||||
struct Result {
|
||||
bool success;
|
||||
std::vector<glm::vec3> positions;
|
||||
std::vector<glm::vec3> color;
|
||||
};
|
||||
Result loadPointFile(const std::string& file);
|
||||
Result loadCachedFile(const std::string& file);
|
||||
|
||||
glm::vec3 _volumeSize;
|
||||
glm::vec3 _pointScaling;
|
||||
properties::BoolProperty _volumeRenderingEnabled;
|
||||
@@ -71,6 +77,8 @@ private:
|
||||
properties::FloatProperty _enabledPointsRatio;
|
||||
properties::Vec3Property _translation;
|
||||
properties::Vec3Property _rotation;
|
||||
properties::FloatProperty _downScaleVolumeRendering;
|
||||
properties::FloatProperty _numberOfRayCastingSteps;
|
||||
|
||||
std::unique_ptr<ghoul::opengl::Texture> _pointSpreadFunctionTexture;
|
||||
std::unique_ptr<ghoul::filesystem::File> _pointSpreadFunctionFile;
|
||||
|
||||
@@ -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});
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/util/powerscaledsphere.h>
|
||||
#include <openspace/util/sphere.h>
|
||||
#include <modules/iswa/util/dataprocessorjson.h>
|
||||
#include <modules/iswa/rendering/iswabasegroup.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
@@ -88,7 +88,7 @@ void DataSphere::initializeGL() {
|
||||
bool DataSphere::createGeometry() {
|
||||
const float radius = 6.371f * _radius * glm::pow(10.f, 6.f);
|
||||
int segments = 100;
|
||||
_sphere = std::make_unique<PowerScaledSphere>(radius, segments);
|
||||
_sphere = std::make_unique<Sphere>(radius, segments);
|
||||
_sphere->initialize();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
namespace openspace {
|
||||
|
||||
class PowerScaledSphere;
|
||||
class Sphere;
|
||||
|
||||
/**
|
||||
* DataSphere is a concrete IswaCygnet with data files as its input source. The class
|
||||
@@ -53,7 +53,7 @@ protected:
|
||||
void setUniforms() override;
|
||||
std::vector<float*> textureData() override;
|
||||
|
||||
std::unique_ptr<PowerScaledSphere> _sphere;
|
||||
std::unique_ptr<Sphere> _sphere;
|
||||
float _radius;
|
||||
};
|
||||
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/scripting/scriptengine.h>
|
||||
#include <openspace/util/powerscaledcoordinate.h>
|
||||
#include <openspace/util/time.h>
|
||||
#include <openspace/util/timemanager.h>
|
||||
#include <openspace/util/transformationmanager.h>
|
||||
@@ -157,12 +156,13 @@ void IswaCygnet::render(const RenderData& data, RendererTasks&) {
|
||||
}
|
||||
transform = transform * _rotation;
|
||||
|
||||
psc position =
|
||||
glm::vec4 pposition =
|
||||
static_cast<glm::vec4>(glm::dvec4(data.modelTransform.translation, 0.0)) +
|
||||
transform * glm::vec4(
|
||||
_data.spatialScale.x * _data.offset,
|
||||
_data.spatialScale.w
|
||||
);
|
||||
glm::vec3 position = glm::vec3(pposition) * pow(10.f, pposition.w);
|
||||
|
||||
// Activate shader
|
||||
_shader->activate();
|
||||
@@ -173,7 +173,7 @@ void IswaCygnet::render(const RenderData& data, RendererTasks&) {
|
||||
_shader->setUniform("ModelTransform", transform);
|
||||
|
||||
_shader->setUniform("campos", glm::vec4(data.camera.positionVec3(), 1.f));
|
||||
_shader->setUniform("objpos", glm::vec4(position.vec3(), 0.f));
|
||||
_shader->setUniform("objpos", glm::vec4(position, 0.f));
|
||||
_shader->setUniform("camrot", glm::mat4(data.camera.viewRotationMatrix()));
|
||||
_shader->setUniform("scaling", glm::vec2(1.f, 0.f));
|
||||
|
||||
|
||||
Submodule modules/kameleon/ext/kameleon updated: 1b4549edc7...338d482c86
@@ -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,9 +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(
|
||||
Documentation(),
|
||||
@@ -332,16 +317,32 @@ RenderableSatellites::RenderableSatellites(const ghoul::Dictionary& dictionary)
|
||||
|
||||
_path = dictionary.value<std::string>(PathInfo.identifier);
|
||||
_nSegments = static_cast<int>(dictionary.value<double>(SegmentsInfo.identifier));
|
||||
_lineFade = static_cast<float>(dictionary.value<double>(FadeInfo.identifier));
|
||||
|
||||
if (dictionary.hasKeyAndValue<glm::vec3>(LineColorInfo.identifier)) {
|
||||
_appearance.lineColor = dictionary.value<glm::vec3>(LineColorInfo.identifier);
|
||||
}
|
||||
if (dictionary.hasKeyAndValue<double>("FadeInfo")) {
|
||||
_appearance.lineFade = static_cast<float>(
|
||||
dictionary.value<double>("FadeInfo")
|
||||
);
|
||||
}
|
||||
else {
|
||||
_appearance.lineFade = 20;
|
||||
}
|
||||
|
||||
auto reinitializeTrailBuffers = [this]() {
|
||||
initializeGL();
|
||||
};
|
||||
|
||||
_path.onChange(reinitializeTrailBuffers);
|
||||
_nSegments.onChange(reinitializeTrailBuffers);
|
||||
|
||||
addPropertySubOwner(_appearance);
|
||||
addProperty(_path);
|
||||
addProperty(_nSegments);
|
||||
addProperty(_lineFade);
|
||||
addProperty(_opacity);
|
||||
|
||||
setRenderBin(Renderable::RenderBin::Overlay);
|
||||
}
|
||||
|
||||
|
||||
@@ -484,7 +485,6 @@ void RenderableSatellites::initializeGL() {
|
||||
_uniformCache.opacity = _programObject->uniformLocation("opacity");
|
||||
|
||||
updateBuffers();
|
||||
setRenderBin(Renderable::RenderBin::Overlay);
|
||||
}
|
||||
|
||||
void RenderableSatellites::deinitializeGL() {
|
||||
@@ -523,9 +523,12 @@ void RenderableSatellites::render(const RenderData& data, RendererTasks&) {
|
||||
data.camera.combinedViewMatrix() * modelTransform
|
||||
);
|
||||
|
||||
// Because we want the property to work similar to the planet trails
|
||||
float fade = static_cast<float>(pow(_appearance.lineFade.maxValue() - _appearance.lineFade, 2.0));
|
||||
|
||||
_programObject->setUniform(_uniformCache.projection, data.camera.projectionMatrix());
|
||||
_programObject->setUniform(_uniformCache.color, _appearance.lineColor);
|
||||
_programObject->setUniform(_uniformCache.lineFade, _appearance.lineFade);
|
||||
_programObject->setUniform(_uniformCache.lineFade, fade);
|
||||
|
||||
glLineWidth(_appearance.lineWidth);
|
||||
|
||||
@@ -604,10 +607,10 @@ void RenderableSatellites::updateBuffers() {
|
||||
);
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(TrailVBOLayout), (GLvoid*)0); // stride : 4*sizeof(GL_FLOAT) + 2*sizeof(GL_DOUBLE)
|
||||
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(TrailVBOLayout), nullptr);
|
||||
|
||||
glEnableVertexAttribArray(1);
|
||||
glVertexAttribPointer(1, 2, GL_DOUBLE, GL_FALSE, sizeof(TrailVBOLayout), (GLvoid*)(4*sizeof(GL_FLOAT)) );
|
||||
glVertexAttribPointer(1, 2, GL_DOUBLE, GL_FALSE, sizeof(TrailVBOLayout), (GLvoid*)(4 * sizeof(GL_FLOAT)));
|
||||
|
||||
|
||||
glBindVertexArray(0);
|
||||
|
||||
@@ -94,10 +94,6 @@ private:
|
||||
/// trail.
|
||||
std::vector<TrailVBOLayout> _vertexBufferData;
|
||||
|
||||
/// The index array that is potentially used in the draw call. If this is empty, no
|
||||
/// element draw call is used.
|
||||
std::vector<unsigned int> _indexBufferData;
|
||||
|
||||
GLuint _vertexArray;
|
||||
GLuint _vertexBuffer;
|
||||
GLuint _indexBuffer;
|
||||
@@ -113,8 +109,6 @@ private:
|
||||
properties::StringProperty _path;
|
||||
properties::UIntProperty _nSegments;
|
||||
|
||||
properties::DoubleProperty _lineFade;
|
||||
|
||||
RenderableTrail::Appearance _appearance;
|
||||
|
||||
glm::vec3 _position;
|
||||
|
||||
@@ -25,9 +25,9 @@
|
||||
#include <modules/space/rendering/simplespheregeometry.h>
|
||||
|
||||
#include <openspace/documentation/verifier.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/rendering/renderable.h>
|
||||
#include <openspace/util/powerscaledsphere.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/util/sphere.h>
|
||||
|
||||
namespace {
|
||||
constexpr openspace::properties::Property::PropertyInfo RadiusInfo = {
|
||||
@@ -124,7 +124,7 @@ void SimpleSphereGeometry::createSphere() {
|
||||
const glm::vec3 radius = _radius.value();
|
||||
|
||||
delete _sphere;
|
||||
_sphere = new PowerScaledSphere(radius, _segments);
|
||||
_sphere = new Sphere(radius, _segments);
|
||||
_sphere->initialize();
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
namespace openspace {
|
||||
class Renderable;
|
||||
class PowerScaledSphere;
|
||||
class Sphere;
|
||||
} // namespace openspace
|
||||
|
||||
namespace openspace::documentation { struct Documentation; }
|
||||
@@ -57,7 +57,7 @@ private:
|
||||
|
||||
properties::Vec3Property _radius;
|
||||
properties::IntProperty _segments;
|
||||
PowerScaledSphere* _sphere;
|
||||
Sphere* _sphere;
|
||||
};
|
||||
|
||||
} // namespace openspace::planetgeometry
|
||||
|
||||
@@ -63,15 +63,25 @@ Fragment getFragment() {
|
||||
vertexDistance_f += 1.0;
|
||||
}
|
||||
|
||||
float invert = 1.0 - vertexDistance_f;
|
||||
float fade = clamp(invert * lineFade, 0.0, 1.0);
|
||||
float invert = pow((1.0 - vertexDistance_f), lineFade);
|
||||
float fade = clamp(invert, 0.0, 1.0);
|
||||
|
||||
// Currently even fully transparent lines can occlude other lines, thus we discard
|
||||
// these fragments since debris and satellites are rendered so close to each other
|
||||
if (fade < 0.05) {
|
||||
discard;
|
||||
}
|
||||
Fragment frag;
|
||||
|
||||
// Use additive blending for some values to make the discarding less abrupt
|
||||
if (fade < 0.15) {
|
||||
frag.blend = BLEND_MODE_ADDITIVE;
|
||||
}
|
||||
|
||||
frag.color = vec4(color, fade * opacity);
|
||||
frag.depth = vs_position_w;
|
||||
frag.gPosition = viewSpacePosition;
|
||||
frag.gNormal = vec4(1, 1, 1, 0);
|
||||
// frag.blend = BLEND_MODE_ADDITIVE;
|
||||
|
||||
|
||||
// to debug using colors use this if-statment.
|
||||
|
||||
@@ -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();
|
||||
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/documentation/verifier.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
@@ -151,7 +152,6 @@ namespace {
|
||||
return 0.5 * bisect(p1, half, testFunction, half);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
@@ -294,7 +294,10 @@ RenderableFov::RenderableFov(const ghoul::Dictionary& dictionary)
|
||||
if (dictionary.hasKey(KeyFrameConversions)) {
|
||||
ghoul::Dictionary fc = dictionary.value<ghoul::Dictionary>(KeyFrameConversions);
|
||||
for (const std::string& key : fc.keys()) {
|
||||
openspace::SpiceManager::ref().addFrame(key, fc.value<std::string>(key));
|
||||
global::moduleEngine.module<SpacecraftInstrumentsModule>()->addFrame(
|
||||
key,
|
||||
fc.value<std::string>(key)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -524,7 +527,12 @@ void RenderableFov::computeIntercepts(const UpdateData& data, const std::string&
|
||||
{
|
||||
const bool convert = (ref.find("IAU_") == std::string::npos);
|
||||
if (convert) {
|
||||
return { SpiceManager::ref().frameFromBody(target), true };
|
||||
return {
|
||||
global::moduleEngine.module<SpacecraftInstrumentsModule>()->frameFromBody(
|
||||
target
|
||||
),
|
||||
true
|
||||
};
|
||||
}
|
||||
else {
|
||||
return { ref, false };
|
||||
@@ -917,6 +925,7 @@ std::pair<std::string, bool> RenderableFov::determineTarget(double time) {
|
||||
bool inFOV = SpiceManager::ref().isTargetInFieldOfView(
|
||||
pt,
|
||||
_instrument.spacecraft,
|
||||
global::moduleEngine.module<SpacecraftInstrumentsModule>()->frameFromBody(pt),
|
||||
_instrument.name,
|
||||
SpiceManager::FieldOfViewMethod::Ellipsoid,
|
||||
_instrument.aberrationCorrection,
|
||||
|
||||
@@ -461,11 +461,7 @@ void RenderableModelProjection::attitudeParameters(double time) {
|
||||
lightTime
|
||||
);
|
||||
|
||||
// @TODO: Remove this and replace with cpos = p * 1000 ?
|
||||
psc position = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z);
|
||||
|
||||
position[3] += 4;
|
||||
const glm::vec3 cpos = position.vec3();
|
||||
const glm::vec3 cpos = p * 10000.0;
|
||||
|
||||
const float distance = glm::length(cpos);
|
||||
const float radius = boundingSphere();
|
||||
|
||||
@@ -24,8 +24,10 @@
|
||||
|
||||
#include <modules/spacecraftinstruments/rendering/renderableplaneprojection.h>
|
||||
|
||||
#include <modules/spacecraftinstruments/spacecraftinstrumentsmodule.h>
|
||||
#include <modules/spacecraftinstruments/util/imagesequencer.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/scene/scene.h>
|
||||
@@ -227,8 +229,7 @@ void RenderablePlaneProjection::updatePlane(const Image& img, double currentTime
|
||||
);
|
||||
// The apparent position, CN+S, makes image align best with target
|
||||
|
||||
// @TODO: Remove these powerscaled coordinates
|
||||
psc projection[4];
|
||||
glm::dvec3 projection[4];
|
||||
for (size_t j = 0; j < bounds.size(); ++j) {
|
||||
bounds[j] = SpiceManager::ref().frameTransformationMatrix(
|
||||
frame,
|
||||
@@ -246,12 +247,8 @@ void RenderablePlaneProjection::updatePlane(const Image& img, double currentTime
|
||||
currentTime
|
||||
) * cornerPosition;
|
||||
|
||||
projection[j] = PowerScaledCoordinate::CreatePowerScaledCoordinate(
|
||||
cornerPosition[0],
|
||||
cornerPosition[1],
|
||||
cornerPosition[2]
|
||||
);
|
||||
projection[j][3] += 3;
|
||||
// km -> m
|
||||
projection[j] = cornerPosition * 1000.0;
|
||||
}
|
||||
|
||||
if (!_moving) {
|
||||
@@ -264,21 +261,28 @@ void RenderablePlaneProjection::updatePlane(const Image& img, double currentTime
|
||||
}
|
||||
}
|
||||
|
||||
glm::vec3 p[4] = {
|
||||
glm::vec3(projection[0]),
|
||||
glm::vec3(projection[1]),
|
||||
glm::vec3(projection[2]),
|
||||
glm::vec3(projection[3])
|
||||
|
||||
};
|
||||
const GLfloat vertex_data[] = {
|
||||
// square of two triangles drawn within fov in target coordinates
|
||||
// x y z w s t
|
||||
// Lower left 1
|
||||
projection[1][0], projection[1][1], projection[1][2], projection[1][3], 0, 0,
|
||||
p[1].x, p[1].y, p[1].z, 0.f, 0.f, 0.f,
|
||||
// Upper right 2
|
||||
projection[3][0], projection[3][1], projection[3][2], projection[3][3], 1, 1,
|
||||
p[3].x, p[3].y, p[3].z, 0.f, 1.f, 1.f,
|
||||
// Upper left 3
|
||||
projection[2][0], projection[2][1], projection[2][2], projection[2][3], 0, 1,
|
||||
p[2].x, p[2].y, p[2].z, 0.f, 0.f, 1.f,
|
||||
// Lower left 4 = 1
|
||||
projection[1][0], projection[1][1], projection[1][2], projection[1][3], 0, 0,
|
||||
p[1].x, p[1].y, p[1].z, 0.f, 0.f, 0.f,
|
||||
// Lower right 5
|
||||
projection[0][0], projection[0][1], projection[0][2], projection[0][3], 1, 0,
|
||||
p[0].x, p[0].y, p[0].z, 0.f, 1.f, 0.f,
|
||||
// Upper left 6 = 2
|
||||
projection[3][0], projection[3][1], projection[3][2], projection[3][3], 1, 1,
|
||||
p[3].x, p[3].y, p[3].z, 0.f, 1.f, 1.f,
|
||||
};
|
||||
|
||||
glBindVertexArray(_quad);
|
||||
@@ -307,7 +311,8 @@ void RenderablePlaneProjection::setTarget(std::string body) {
|
||||
return;
|
||||
}
|
||||
|
||||
_target.frame = SpiceManager::ref().frameFromBody(body);
|
||||
_target.frame =
|
||||
global::moduleEngine.module<SpacecraftInstrumentsModule>()->frameFromBody(body);
|
||||
_target.body = std::move(body);
|
||||
}
|
||||
|
||||
|
||||
@@ -94,4 +94,31 @@ SpacecraftInstrumentsModule::documentations() const
|
||||
};
|
||||
}
|
||||
|
||||
bool SpacecraftInstrumentsModule::addFrame(std::string body, std::string frame) {
|
||||
if (body.empty() || frame.empty()) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
_frameByBody.emplace_back(body, frame);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
std::string SpacecraftInstrumentsModule::frameFromBody(const std::string& body) {
|
||||
for (const std::pair<std::string, std::string>& pair : _frameByBody) {
|
||||
if (pair.first == body) {
|
||||
return pair.second;
|
||||
}
|
||||
}
|
||||
|
||||
constexpr const char* unionPrefix = "IAU_";
|
||||
|
||||
if (body.find(unionPrefix) == std::string::npos) {
|
||||
return unionPrefix + body;
|
||||
}
|
||||
else {
|
||||
return body;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -41,10 +41,16 @@ public:
|
||||
|
||||
static ghoul::opengl::ProgramObjectManager ProgramObjectManager;
|
||||
|
||||
bool addFrame(std::string body, std::string frame);
|
||||
std::string frameFromBody(const std::string& body);
|
||||
|
||||
protected:
|
||||
void internalInitialize(const ghoul::Dictionary&) override;
|
||||
void internalDeinitialize() override;
|
||||
void internalDeinitializeGL() override;
|
||||
|
||||
private:
|
||||
std::vector<std::pair<std::string, std::string>> _frameByBody;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -101,17 +101,17 @@ RenderablePlaneSpout::RenderablePlaneSpout(const ghoul::Dictionary& dictionary)
|
||||
iIdentifier = id;
|
||||
|
||||
if (iIdentifier == 0) {
|
||||
setIdentifier("ScreenSpaceSpout");
|
||||
setIdentifier("RenderablePlaneSpout");
|
||||
}
|
||||
else {
|
||||
setIdentifier("ScreenSpaceSpout" + std::to_string(iIdentifier));
|
||||
setIdentifier("RenderablePlaneSpout" + std::to_string(iIdentifier));
|
||||
}
|
||||
++id;
|
||||
}
|
||||
|
||||
if (_guiName.empty()) {
|
||||
// Adding an extra space to the user-facing name as it looks nicer
|
||||
setGuiName("ScreenSpaceSpout " + std::to_string(iIdentifier));
|
||||
setGuiName("RenderablePlaneSpout " + std::to_string(iIdentifier));
|
||||
}
|
||||
|
||||
if (dictionary.hasKey(NameInfo.identifier)) {
|
||||
|
||||
@@ -93,24 +93,15 @@ ScreenSpaceSpout::ScreenSpaceSpout(const ghoul::Dictionary& dictionary)
|
||||
"ScreenSpaceSpout"
|
||||
);
|
||||
|
||||
int iIdentifier = 0;
|
||||
if (_identifier.empty()) {
|
||||
static int id = 0;
|
||||
iIdentifier = id;
|
||||
|
||||
if (iIdentifier == 0) {
|
||||
setIdentifier("ScreenSpaceSpout");
|
||||
}
|
||||
else {
|
||||
setIdentifier("ScreenSpaceSpout" + std::to_string(iIdentifier));
|
||||
}
|
||||
++id;
|
||||
std::string identifier;
|
||||
if (dictionary.hasKeyAndValue<std::string>(KeyIdentifier)) {
|
||||
identifier = dictionary.value<std::string>(KeyIdentifier);
|
||||
}
|
||||
|
||||
if (_guiName.empty()) {
|
||||
// Adding an extra space to the user-facing name as it looks nicer
|
||||
setGuiName("ScreenSpaceSpout " + std::to_string(iIdentifier));
|
||||
else {
|
||||
identifier = "ScreenSpaceSpout";
|
||||
}
|
||||
identifier = makeUniqueIdentifier(identifier);
|
||||
setIdentifier(std::move(identifier));
|
||||
|
||||
if (dictionary.hasKey(NameInfo.identifier)) {
|
||||
_spoutName = dictionary.value<std::string>(NameInfo.identifier);
|
||||
|
||||
@@ -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
|
||||
|
||||
65
modules/touch/include/directinputsolver.h
Normal file
65
modules/touch/include/directinputsolver.h
Normal file
@@ -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 <modules/touch/ext/levmarq.h>
|
||||
#include <modules/touch/ext/libTUIO11/TUIO/TuioCursor.h>
|
||||
#include <vector>
|
||||
|
||||
|
||||
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<TUIO::TuioCursor>& list,
|
||||
const std::vector<SelectedBody>& selectedBodies,
|
||||
std::vector<double>* 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__
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
#include <openspace/properties/propertyowner.h>
|
||||
|
||||
#include <modules/touch/ext/levmarq.h>
|
||||
#include <modules/touch/include/directinputsolver.h>
|
||||
#include <modules/touch/include/tuioear.h>
|
||||
|
||||
#include <openspace/properties/scalar/boolproperty.h>
|
||||
@@ -38,6 +38,8 @@
|
||||
#include <openspace/properties/vector/ivec2property.h>
|
||||
#include <openspace/properties/vector/vec4property.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
//#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<glm::dvec3> selectedPoints;
|
||||
std::vector<glm::dvec2> 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<SelectedBody> _selected;
|
||||
std::vector<DirectInputSolver::SelectedBody> _selected;
|
||||
SceneGraphNode* _pickingSelected = nullptr;
|
||||
LMstat _lmstat;
|
||||
DirectInputSolver _solver;
|
||||
|
||||
glm::dquat _toSlerp;
|
||||
glm::dvec3 _centroid;
|
||||
|
||||
|
||||
281
modules/touch/src/directinputsolver.cpp
Normal file
281
modules/touch/src/directinputsolver.cpp
Normal file
@@ -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 <modules/touch/include/touchinteraction.h>
|
||||
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/util/camera.h>
|
||||
|
||||
namespace {
|
||||
// Used in the LM algorithm
|
||||
struct FunctionData {
|
||||
std::vector<glm::dvec3> selectedPoints;
|
||||
std::vector<glm::dvec2> 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<FunctionData*>(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<FunctionData*>(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<double> 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<TUIO::TuioCursor>& list,
|
||||
const std::vector<SelectedBody>& selectedBodies,
|
||||
std::vector<double>* parameters, const Camera& camera)
|
||||
{
|
||||
int nFingers = std::min(static_cast<int>(list.size()), 3);
|
||||
_nDof = std::min(nFingers * 2, 6);
|
||||
|
||||
// Parse input data to be used in the LM algorithm
|
||||
std::vector<glm::dvec3> selectedPoints;
|
||||
std::vector<glm::dvec2> 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<TuioCursor>::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<ImGUIModule>()->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<void*>(&fData);
|
||||
|
||||
bool result = levmarq(
|
||||
_nDof,
|
||||
parameters->data(),
|
||||
static_cast<int>(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
|
||||
|
||||
@@ -23,7 +23,9 @@
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/engine/globals.h>
|
||||
|
||||
#include <modules/touch/include/touchinteraction.h>
|
||||
#include <modules/touch/include/directinputsolver.h>
|
||||
#include <modules/imgui/imguimodule.h>
|
||||
|
||||
#include <openspace/interaction/orbitalnavigator.h>
|
||||
@@ -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<TuioCursor>& list,
|
||||
std::vector<Point>& lastProcessed)
|
||||
@@ -513,231 +512,21 @@ void TouchInteraction::directControl(const std::vector<TuioCursor>& 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<FunctionData*>(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<FunctionData*>(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<double> 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<int>(list.size()), 3);
|
||||
int nDOF = std::min(nFingers * 2, 6);
|
||||
std::vector<double> 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<glm::dvec3> selectedPoints;
|
||||
std::vector<glm::dvec2> screenPoints;
|
||||
for (int i = 0; i < nFingers; ++i) {
|
||||
const SelectedBody& sb = _selected.at(i);
|
||||
selectedPoints.push_back(sb.coordinates);
|
||||
|
||||
std::vector<TuioCursor>::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<ImGUIModule>()->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<void*>(&fData);
|
||||
|
||||
// finds best transform values for the new camera state and stores them in par
|
||||
_lmSuccess = levmarq(
|
||||
nDOF,
|
||||
par.data(),
|
||||
static_cast<int>(screenPoints.size()),
|
||||
nullptr,
|
||||
distToMinimize,
|
||||
gradient,
|
||||
dataPtr,
|
||||
&_lmstat
|
||||
);
|
||||
std::vector<double> 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<TuioCursor>& list) {
|
||||
|
||||
glm::dquat camToWorldSpace = _camera->rotationQuaternion();
|
||||
glm::dvec3 camPos = _camera->positionVec3();
|
||||
std::vector<SelectedBody> newSelected;
|
||||
|
||||
struct PickingInfo {
|
||||
SceneGraphNode* node;
|
||||
double pickingDistanceNDC;
|
||||
double pickingDistanceWorld;
|
||||
std::vector<DirectInputSolver::SelectedBody> newSelected;
|
||||
|
||||
//node & distance
|
||||
std::tuple<SceneGraphNode*, double> currentlyPicked = {
|
||||
nullptr,
|
||||
std::numeric_limits<double>::max()
|
||||
};
|
||||
std::vector<PickingInfo> 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<TuioCursor>& list) {
|
||||
long id = c.getSessionID();
|
||||
|
||||
for (SceneGraphNode* node : selectableNodes) {
|
||||
double boundingSphere = node->boundingSphere();
|
||||
double boundingSphereSquared = static_cast<double>(node->boundingSphere()) *
|
||||
static_cast<double>(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<SelectedBody>::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<TuioCursor>& 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<double>::max(),
|
||||
-std::numeric_limits<double>::max()
|
||||
});
|
||||
}
|
||||
else {
|
||||
// The node was considered due to minimum picking distance radius
|
||||
currentlyPicked = {
|
||||
node,
|
||||
-std::numeric_limits<double>::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<TuioCursor> 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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,11 +28,8 @@
|
||||
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/engine/windowdelegate.h>
|
||||
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
|
||||
#include <TUIO/TuioServer.h>
|
||||
|
||||
#include <tchar.h>
|
||||
#include <tpcshrd.h>
|
||||
|
||||
@@ -42,7 +39,7 @@ namespace {
|
||||
bool gStarted{ false };
|
||||
TUIO::TuioServer* gTuioServer{ nullptr };
|
||||
std::unordered_map<UINT, TUIO::TuioCursor*> 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<LPPOINT>(&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<float>(p.x) /
|
||||
static_cast<float>(rect.right - rect.left);
|
||||
float yPos = static_cast<float>(p.y) /
|
||||
static_cast<float>(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<HANDLE>(dwHwndTabletProperty));
|
||||
::SetProp(
|
||||
hWnd,
|
||||
MICROSOFT_TABLETPENSERVICE_PROPERTY,
|
||||
reinterpret_cast<HANDLE>(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;
|
||||
|
||||
@@ -164,7 +164,7 @@ TouchModule::TouchModule()
|
||||
if (nativeWindowHandle) {
|
||||
_win32TouchHook.reset(new Win32TouchHook(nativeWindowHandle));
|
||||
}
|
||||
#endif //WIN32
|
||||
#endif
|
||||
});
|
||||
|
||||
global::callback::deinitializeGL.push_back([&]() {
|
||||
|
||||
@@ -29,8 +29,10 @@
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/rendering/raycastermanager.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
|
||||
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<double>(ScalingExponentInfo.identifier)) {
|
||||
_scalingExponent = static_cast<int>(
|
||||
@@ -104,6 +114,22 @@ RenderableToyVolume::RenderableToyVolume(const ghoul::Dictionary& dictionary)
|
||||
if (dictionary.hasKeyAndValue<double>(StepSizeInfo.identifier)) {
|
||||
_stepSize = static_cast<float>(dictionary.value<double>(StepSizeInfo.identifier));
|
||||
}
|
||||
|
||||
_downScaleVolumeRendering.setVisibility(
|
||||
openspace::properties::Property::Visibility::Developer
|
||||
);
|
||||
if (dictionary.hasKey("Downscale")) {
|
||||
_downScaleVolumeRendering = dictionary.value<float>("Downscale");
|
||||
}
|
||||
|
||||
if (dictionary.hasKey("Steps")) {
|
||||
_rayCastSteps = static_cast<int>(dictionary.value<float>("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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -55,8 +55,11 @@ private:
|
||||
properties::Vec3Property _translation;
|
||||
properties::Vec3Property _rotation;
|
||||
properties::Vec4Property _color;
|
||||
properties::FloatProperty _downScaleVolumeRendering;
|
||||
|
||||
std::unique_ptr<ToyVolumeRaycaster> _raycaster;
|
||||
|
||||
int _rayCastSteps = 1000;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
|
||||
#include <modules/toyvolume/rendering/toyvolumeraycaster.h>
|
||||
|
||||
#include <openspace/util/powerscaledcoordinate.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
#include <openspace/rendering/renderable.h>
|
||||
#include <vector>
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
#include <sstream>
|
||||
#include <ghoul/opengl/programobject.h>
|
||||
#include <ghoul/opengl/textureunit.h>
|
||||
#include <openspace/util/powerscaledcoordinate.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
#include <openspace/rendering/renderable.h>
|
||||
#include <modules/volume/transferfunctionhandler.h>
|
||||
|
||||
@@ -72,13 +72,16 @@ ScreenSpaceBrowser::ScreenSpaceBrowser(const ghoul::Dictionary &dictionary)
|
||||
, _dimensions(DimensionsInfo, glm::vec2(0.f), glm::vec2(0.f), glm::vec2(3000.f))
|
||||
, _reload(ReloadInfo)
|
||||
{
|
||||
if (dictionary.hasKey(KeyIdentifier)) {
|
||||
setIdentifier(dictionary.value<std::string>(KeyIdentifier));
|
||||
} else {
|
||||
static int id = 0;
|
||||
setIdentifier("ScreenSpaceBrowser " + std::to_string(id));
|
||||
++id;
|
||||
|
||||
std::string identifier;
|
||||
if (dictionary.hasKeyAndValue<std::string>(KeyIdentifier)) {
|
||||
identifier = dictionary.value<std::string>(KeyIdentifier);
|
||||
}
|
||||
else {
|
||||
identifier = "ScreenSpaceBrowser";
|
||||
}
|
||||
identifier = makeUniqueIdentifier(identifier);
|
||||
setIdentifier(identifier);
|
||||
|
||||
if (dictionary.hasKeyAndValue<std::string>(UrlInfo.identifier)) {
|
||||
_url = dictionary.value<std::string>(UrlInfo.identifier);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user