Merge branch 'master' into feature/AALines2

This commit is contained in:
Jonathas Costa
2020-01-06 09:43:04 -05:00
113 changed files with 3053 additions and 1626 deletions

View File

@@ -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 ()

View File

@@ -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 } },

View File

@@ -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 } },

View File

@@ -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 } },

View File

@@ -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,

View File

@@ -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"

View File

@@ -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 },

View File

@@ -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,

View File

@@ -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" },

View File

@@ -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",

View File

@@ -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

View File

@@ -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 })

View File

@@ -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')

View File

@@ -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 })

View File

@@ -56,7 +56,7 @@ local registerSatelliteGroupObjects = function(containingAsset, group, tleFolder
Renderable = {
Type = "RenderableSatellites",
Path = file,
Segments = 160,
Segments = 120,
Color = color,
Fade = 0.5
},

View File

@@ -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

View File

@@ -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")

View File

@@ -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

View File

@@ -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

View File

@@ -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 })

View File

@@ -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 })

View File

@@ -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 })

View File

@@ -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 })

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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 })

View File

@@ -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

View File

@@ -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")

View File

@@ -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 })

View 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 })

View File

@@ -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>

View File

@@ -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>

View File

@@ -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 })

View File

@@ -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 })

View File

@@ -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;

View File

@@ -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;

View File

@@ -75,6 +75,8 @@ public:
protected:
void createShaders();
std::string makeUniqueIdentifier(std::string name);
glm::mat4 scaleMatrix();
glm::mat4 globalRotationMatrix();
glm::mat4 translationMatrix();

View File

@@ -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

View File

@@ -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

View File

@@ -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__

View File

@@ -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__

View File

@@ -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;

View File

@@ -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 {

View File

@@ -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>

View File

@@ -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

View File

@@ -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(),

View 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

View 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__

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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);

View File

@@ -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))) {

View File

@@ -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);

View File

@@ -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);

View File

@@ -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());

View File

@@ -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(

View File

@@ -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;
}
}

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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});
}

View File

@@ -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;
}

View File

@@ -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;
};

View File

@@ -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));

View File

@@ -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);

View File

@@ -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;

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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.

View File

@@ -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();
}

View File

@@ -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,

View File

@@ -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();

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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

View File

@@ -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)) {

View File

@@ -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);

View File

@@ -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

View 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__

View File

@@ -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;

View 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

View File

@@ -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
}
}

View File

@@ -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;

View File

@@ -164,7 +164,7 @@ TouchModule::TouchModule()
if (nativeWindowHandle) {
_win32TouchHook.reset(new Win32TouchHook(nativeWindowHandle));
}
#endif //WIN32
#endif
});
global::callback::deinitializeGL.push_back([&]() {

View File

@@ -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);
}
}

View File

@@ -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

View File

@@ -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>

View File

@@ -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>

View File

@@ -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