diff --git a/data/scene/atmosphereearth/atmosphereearth.mod b/data/scene/atmosphereearth/atmosphereearth.mod index 656ae228b0..4d1bda3a18 100644 --- a/data/scene/atmosphereearth/atmosphereearth.mod +++ b/data/scene/atmosphereearth/atmosphereearth.mod @@ -107,15 +107,20 @@ return { Name = "EarthTrail", Parent = "SolarSystemBarycenter", Renderable = { - Type = "RenderableTrail", - Body = "EARTH", - Frame = "GALACTIC", - Observer = "SUN", - RGB = { 0.5, 0.8, 1.0}, - TropicalOrbitPeriod = 365.242, - EarthOrbitRatio = 1, - DayLength = 24 - } + Type = "RenderableTrailOrbit", + Translation = { + Type = "SpiceTranslation", + Body = "EARTH", + Observer = "SUN" + }, + Color = { 0.5, 0.8, 1.0 }, + -- StartTime = "2016 JUN 01 12:00:00.000", + -- EndTime = "2017 JAN 01 12:00:00.000", + -- SampleInterval = 3600 + Period = 365.242, + Resolution = 1000 + }, + GuiName = "/Solar/EarthTrail" }, { Name = "EarthMarker", diff --git a/data/scene/debugglobe/debugglobe.mod b/data/scene/debugglobe/debugglobe.mod index 7f559dce3a..9068f6accc 100644 --- a/data/scene/debugglobe/debugglobe.mod +++ b/data/scene/debugglobe/debugglobe.mod @@ -174,16 +174,21 @@ return { Name = "EarthTrail", Parent = "SolarSystemBarycenter", Renderable = { - Type = "RenderableTrail", - Body = "EARTH", - Frame = "GALACTIC", - Observer = "SUN", - RGB = { 0.5, 0.8, 1.0}, - TropicalOrbitPeriod = 365.242, - EarthOrbitRatio = 1, - DayLength = 24 - } - } + Type = "RenderableTrailOrbit", + Translation = { + Type = "SpiceTranslation", + Body = "EARTH", + Observer = "SUN" + }, + Color = { 0.5, 0.8, 1.0 }, + -- StartTime = "2016 JUN 01 12:00:00.000", + -- EndTime = "2017 JAN 01 12:00:00.000", + -- SampleInterval = 3600 + Period = 365.242, + Resolution = 1000 + }, + GuiName = "/Solar/EarthTrail" + }, --[[, { Name = "DebugPlane", diff --git a/data/scene/earth/earth.mod b/data/scene/earth/earth.mod index d59d6bec41..902eefcdfc 100644 --- a/data/scene/earth/earth.mod +++ b/data/scene/earth/earth.mod @@ -55,14 +55,18 @@ return { Name = "EarthTrail", Parent = "SolarSystemBarycenter", Renderable = { - Type = "RenderableTrail", - Body = "EARTH", - Frame = "GALACTIC", - Observer = "SUN", - RGB = { 0.5, 0.8, 1.0}, - TropicalOrbitPeriod = 365.242, - EarthOrbitRatio = 1, - DayLength = 24 + Type = "RenderableTrailOrbit", + Translation = { + Type = "SpiceTranslation", + Body = "EARTH", + Observer = "SUN" + }, + Color = { 0.5, 0.8, 1.0 }, + -- StartTime = "2016 JUN 01 12:00:00.000", + -- EndTime = "2017 JAN 01 12:00:00.000", + -- SampleInterval = 3600 + Period = 365.242, + Resolution = 1000 }, GuiName = "/Solar/EarthTrail" }, diff --git a/data/scene/jupiter/callisto/callisto.mod b/data/scene/jupiter/callisto/callisto.mod index 6e4a850cc8..74c3360adf 100644 --- a/data/scene/jupiter/callisto/callisto.mod +++ b/data/scene/jupiter/callisto/callisto.mod @@ -45,19 +45,15 @@ return { Name = "CallistoTrail", Parent = "JupiterBarycenter", Renderable = { - Type = "RenderableTrail", - Body = "CALLISTO", - Frame = "GALACTIC", - Observer = "JUPITER BARYCENTER", - RGB = { 0.4, 0.3, 0.01 }, - TropicalOrbitPeriod = 60 , - EarthOrbitRatio = 0.045, - DayLength = 9.9259, - Textures = { - Type = "simple", - Color = "${COMMON_MODULE}/textures/glare_blue.png", - -- need to add different texture - }, + Type = "RenderableTrailOrbit", + Translation = { + Type = "SpiceTranslation", + Body = "CALLISTO", + Observer = "JUPITER BARYCENTER", + }, + Color = { 0.4, 0.3, 0.01 }, + Period = 17, + Resolution = 1000 } } } diff --git a/data/scene/jupiter/europa/europa.mod b/data/scene/jupiter/europa/europa.mod index 38d973e463..54df372720 100644 --- a/data/scene/jupiter/europa/europa.mod +++ b/data/scene/jupiter/europa/europa.mod @@ -41,19 +41,15 @@ return { Name = "EuropaTrail", Parent = "JupiterBarycenter", Renderable = { - Type = "RenderableTrail", - Body = "EUROPA", - Frame = "GALACTIC", - Observer = "JUPITER BARYCENTER", - RGB = { 0.5, 0.3, 0.3 }, - TropicalOrbitPeriod = 60, - EarthOrbitRatio = 0.01, - DayLength = 9.9259, - Textures = { - Type = "simple", - Color = "${COMMON_MODULE}/textures/glare_blue.png", - -- need to add different texture - }, + Type = "RenderableTrailOrbit", + Translation = { + Type = "SpiceTranslation", + Body = "EUROPA", + Observer = "JUPITER BARYCENTER", + }, + Color = { 0.5, 0.3, 0.3 }, + Period = 85 / 24, + Resolution = 1000 } } } diff --git a/data/scene/jupiter/ganymede/ganymede.mod b/data/scene/jupiter/ganymede/ganymede.mod index 9f699d122a..c2c9fdca08 100644 --- a/data/scene/jupiter/ganymede/ganymede.mod +++ b/data/scene/jupiter/ganymede/ganymede.mod @@ -45,19 +45,15 @@ return { Name = "GanymedeTrail", Parent = "JupiterBarycenter", Renderable = { - Type = "RenderableTrail", - Body = "GANYMEDE", - Frame = "GALACTIC", - Observer = "JUPITER BARYCENTER", - RGB = { 0.4, 0.3, 0.3 }, - TropicalOrbitPeriod = 60 , - EarthOrbitRatio = 0.019, - DayLength = 9.9259, - Textures = { - Type = "simple", - Color = "${COMMON_MODULE}/textures/glare_blue.png", - -- need to add different texture - }, + Type = "RenderableTrailOrbit", + Translation = { + Type = "SpiceTranslation", + Body = "GANYMEDE", + Observer = "JUPITER BARYCENTER", + }, + Color = { 0.4, 0.3, 0.3 }, + Period = 172 / 24, + Resolution = 1000 } } } diff --git a/data/scene/jupiter/io/io.mod b/data/scene/jupiter/io/io.mod index 97d00d47b3..03d28e60d1 100644 --- a/data/scene/jupiter/io/io.mod +++ b/data/scene/jupiter/io/io.mod @@ -45,19 +45,15 @@ return { Name = "IoTrail", Parent = "JupiterBarycenter", Renderable = { - Type = "RenderableTrail", - Body = "IO", - Frame = "GALACTIC", - Observer = "JUPITER BARYCENTER", - RGB = { 0.4, 0.4, 0.2 }, - TropicalOrbitPeriod = 40 , - EarthOrbitRatio = 0.0045, - DayLength = 9.9259, - Textures = { - Type = "simple", - Color = "${COMMON_MODULE}/textures/glare_blue.png", - -- need to add different texture - }, + Type = "RenderableTrailOrbit", + Translation = { + Type = "SpiceTranslation", + Body = "IO", + Observer = "JUPITER BARYCENTER", + }, + Color = { 0.4, 0.4, 0.2 }, + Period = 42 / 24, + Resolution = 1000 } } } diff --git a/data/scene/jupiter/jupiter/jupiter.mod b/data/scene/jupiter/jupiter/jupiter.mod index 70a4d65078..6302b66739 100644 --- a/data/scene/jupiter/jupiter/jupiter.mod +++ b/data/scene/jupiter/jupiter/jupiter.mod @@ -56,19 +56,15 @@ return { Name = "JupiterTrail", Parent = "SolarSystemBarycenter", Renderable = { - Type = "RenderableTrail", - Body = "JUPITER BARYCENTER", - Frame = "GALACTIC", - Observer = "SUN", - RGB = { 0.8, 0.7, 0.7 }, - TropicalOrbitPeriod = 4330.595 , - EarthOrbitRatio = 11.857, - DayLength = 9.9259, - Textures = { - Type = "simple", - Color = "${COMMON_MODULE}/textures/glare_blue.png", - -- need to add different texture - }, + Type = "RenderableTrailOrbit", + Translation = { + Type = "SpiceTranslation", + Body = "JUPITER BARYCENTER", + Observer = "SUN", + }, + Color = { 0.8, 0.7, 0.7 }, + Period = 4330.595, + Resolution = 1000 } } } diff --git a/data/scene/lodearth/lodearth.mod b/data/scene/lodearth/lodearth.mod index c70e3f0233..f146427341 100644 --- a/data/scene/lodearth/lodearth.mod +++ b/data/scene/lodearth/lodearth.mod @@ -18,15 +18,20 @@ return { Name = "EarthTrail", Parent = "SolarSystemBarycenter", Renderable = { - Type = "RenderableTrail", - Body = "EARTH", - Frame = "GALACTIC", - Observer = "SUN", - RGB = { 0.5, 0.8, 1.0}, - TropicalOrbitPeriod = 365.242, - EarthOrbitRatio = 1, - DayLength = 24 - } + Type = "RenderableTrailOrbit", + Translation = { + Type = "SpiceTranslation", + Body = "EARTH", + Observer = "SUN" + }, + Color = { 0.5, 0.8, 1.0 }, + -- StartTime = "2016 JUN 01 12:00:00.000", + -- EndTime = "2017 JAN 01 12:00:00.000", + -- SampleInterval = 3600 + Period = 365.242, + Resolution = 1000 + }, + GuiName = "/Solar/EarthTrail" }, -- RenderableGlobe module { diff --git a/data/scene/lodesritest/lodesritest.mod b/data/scene/lodesritest/lodesritest.mod index db213b3e6c..4e7bf26353 100644 --- a/data/scene/lodesritest/lodesritest.mod +++ b/data/scene/lodesritest/lodesritest.mod @@ -9,14 +9,18 @@ return { Name = "EarthTrail", Parent = "SolarSystemBarycenter", Renderable = { - Type = "RenderableTrail", - Body = "EARTH", - Frame = "GALACTIC", - Observer = "SUN", - RGB = { 0.5, 0.8, 1.0}, - TropicalOrbitPeriod = 365.242, - EarthOrbitRatio = 1, - DayLength = 24 + Type = "RenderableTrailOrbit", + Translation = { + Type = "SpiceTranslation", + Body = "EARTH", + Observer = "SUN" + }, + Color = { 0.5, 0.8, 1.0 }, + -- StartTime = "2016 JUN 01 12:00:00.000", + -- EndTime = "2017 JAN 01 12:00:00.000", + -- SampleInterval = 3600 + Period = 365.242, + Resolution = 1000 }, GuiName = "/Solar/EarthTrail" }, diff --git a/data/scene/lodmars/lodmars.mod b/data/scene/lodmars/lodmars.mod index f6e1bceb4c..7fe9e9c830 100644 --- a/data/scene/lodmars/lodmars.mod +++ b/data/scene/lodmars/lodmars.mod @@ -130,16 +130,17 @@ return { -- MarsTrail module { Name = "MarsTrail", - Parent = "Sun", + Parent = "SolarSystemBarycenter", Renderable = { - Type = "RenderableTrail", - Body = "MARS BARYCENTER", - Frame = "GALACTIC", - Observer = "SUN", - RGB = { 1, 0.8, 0.5 }, - TropicalOrbitPeriod = 686.973, - EarthOrbitRatio = 1.881, - DayLength = 24.6597, + Type = "RenderableTrailOrbit", + Translation = { + Type = "SpiceTranslation", + Body = "MARS BARYCENTER", + Observer = "SUN", + }, + Color = { 0.814, 0.305, 0.220 }, + Period = 686.973, + Resolution = 1000 } } } diff --git a/data/scene/lodmercury/lodmercury.mod b/data/scene/lodmercury/lodmercury.mod index 1bb59aea98..0b1030932a 100644 --- a/data/scene/lodmercury/lodmercury.mod +++ b/data/scene/lodmercury/lodmercury.mod @@ -74,14 +74,15 @@ return { Name = "MercuryTrail", Parent = "SolarSystemBarycenter", Renderable = { - Type = "RenderableTrail", - Body = "MERCURY", - Frame = "GALACTIC", - Observer = "SUN", - RGB = {0.6, 0.5, 0.5 }, - TropicalOrbitPeriod = 87.968 , - EarthOrbitRatio = 0.241, - DayLength = 4222.6, - }, + Type = "RenderableTrailOrbit", + Translation = { + Type = "SpiceTranslation", + Body = "MERCURY", + Observer = "SUN", + }, + Color = {0.6, 0.5, 0.5 }, + Period = 87.968, + Resolution = 100 + } } } diff --git a/data/scene/lodmoon/lodmoon.mod b/data/scene/lodmoon/lodmoon.mod index 78980a943e..02d10bb23a 100644 --- a/data/scene/lodmoon/lodmoon.mod +++ b/data/scene/lodmoon/lodmoon.mod @@ -63,14 +63,15 @@ return { Name = "MoonTrail", Parent = "EarthBarycenter", Renderable = { - Type = "RenderableTrail", - Body = "MOON", - Frame = "GALACTIC", - Observer = "EARTH BARYCENTER", - RGB = { 0.5, 0.3, 0.3 }, - TropicalOrbitPeriod = 60, - EarthOrbitRatio = 0.01, - DayLength = 1.0, - } + Type = "RenderableTrailOrbit", + Translation = { + Type = "SpiceTranslation", + Body = "MOON", + Observer = "EARTH BARYCENTER", + }, + Color = { 0.5, 0.3, 0.3 }, + Period = 27, + Resolution = 1000 + }, } } diff --git a/data/scene/mars/mars.mod b/data/scene/mars/mars.mod index e51dba4807..0b8a5dd0eb 100644 --- a/data/scene/mars/mars.mod +++ b/data/scene/mars/mars.mod @@ -3,6 +3,14 @@ return { { Name = "MarsBarycenter", Parent = "SolarSystemBarycenter", + Transform = { + Translation = { + Type = "SpiceTranslation", + Body = "MARS BARYCENTER", + Observer = "SUN", + Kernels = "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" + } + } }, -- Mars module { @@ -28,41 +36,27 @@ return { } }, Transform = { - Translation = { - Type = "SpiceTranslation", - Body = "MARS BARYCENTER", - Observer = "SUN", - Kernels = "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" - }, Rotation = { Type = "SpiceRotation", SourceFrame = "IAU_MARS", DestinationFrame = "ECLIPJ2000", }, - Scale = { - Type = "StaticScale", - Scale = 1, - }, } }, -- MarsTrail module { Name = "MarsTrail", - Parent = "MarsBarycenter", + Parent = "SolarSystemBarycenter", Renderable = { - Type = "RenderableTrail", - Body = "MARS BARYCENTER", - Frame = "GALACTIC", - Observer = "SUN", - RGB = { 1, 0.8, 0.5 }, - TropicalOrbitPeriod = 686.973, - EarthOrbitRatio = 1.881, - DayLength = 24.6597, - Textures = { - Type = "simple", - Color = "${COMMON_MODULE}/textures/glare_blue.png", - -- need to add different texture - }, + Type = "RenderableTrailOrbit", + Translation = { + Type = "SpiceTranslation", + Body = "MARS BARYCENTER", + Observer = "SUN", + }, + Color = { 0.814, 0.305, 0.220 }, + Period = 686.973, + Resolution = 1000 } } } diff --git a/data/scene/mercury/mercury.mod b/data/scene/mercury/mercury.mod index 83b2146d18..75bf33560e 100644 --- a/data/scene/mercury/mercury.mod +++ b/data/scene/mercury/mercury.mod @@ -52,19 +52,15 @@ return { Name = "MercuryTrail", Parent = "SolarSystemBarycenter", Renderable = { - Type = "RenderableTrail", - Body = "MERCURY", - Frame = "GALACTIC", - Observer = "SUN", - RGB = {0.6, 0.5, 0.5 }, - TropicalOrbitPeriod = 87.968 , - EarthOrbitRatio = 0.241, - DayLength = 4222.6, - Textures = { - Type = "simple", - Color = "${COMMON_MODULE}/textures/glare_blue.png", - -- need to add different texture - }, + Type = "RenderableTrailOrbit", + Translation = { + Type = "SpiceTranslation", + Body = "MERCURY", + Observer = "SUN", + }, + Color = {0.6, 0.5, 0.5 }, + Period = 87.968, + Resolution = 100 } } } diff --git a/data/scene/missions/dawn/dawn/dawn.mod b/data/scene/missions/dawn/dawn/dawn.mod index 65e003ac47..3d4a14e917 100644 --- a/data/scene/missions/dawn/dawn/dawn.mod +++ b/data/scene/missions/dawn/dawn/dawn.mod @@ -698,24 +698,18 @@ return { -- Dawn Trail Module { Name = "DawnTrail2", - Parent = "Root", + Parent = "SolarSystemBarycenter", Renderable = { - Type = "RenderableTrail", - Body = "DAWN", - Frame = "GALACTIC", - Observer = "SUN", - -- 3 Dummy values for compilation: - TropicalOrbitPeriod = 10000.0, - EarthOrbitRatio = 1, - DayLength = 50, - -- End of Dummy values - RGB = { 0.7, 0.4, 0.9 }, - Textures = { - Type = "simple", - Color = "textures/glare.png" - }, + Type = "RenderableTrailTrajectory", + Translation = { + Type = "SpiceTranslation", + Body = "DAWN", + Observer = "SUN", + }, + Color = { 0.7, 0.4, 0.9 }, StartTime = "2007 SEP 26 13:28:00", - EndTime = "2012 SEP 12 12:00:00" + EndTime = "2012 SEP 12 12:00:00", + SampleInterval = 3600 * 24 }, }, -- diff --git a/data/scene/missions/dawn/vestaprojection/vestaprojection.mod b/data/scene/missions/dawn/vestaprojection/vestaprojection.mod index 4de4d75dee..f0b8cc87b6 100644 --- a/data/scene/missions/dawn/vestaprojection/vestaprojection.mod +++ b/data/scene/missions/dawn/vestaprojection/vestaprojection.mod @@ -100,24 +100,16 @@ return { Name = "VestaTrail", Parent = "SolarSystemBarycenter", Renderable = { - Type = "RenderableTrail", - Body = "VESTA", - Frame = "GALACTIC", - Observer = "SUN", - - -- 3 Dummy values for compilation: - TropicalOrbitPeriod = 500.0, - EarthOrbitRatio = 0.2, - DayLength = 2, - -- End of Dummy values - - RGB = { 0.7, 0.8, 0.7 }, - Textures = { - Type = "simple", - Color = "textures/glare.png" - }, + Type = "RenderableTrailOrbit", + Translation = { + Type = "SpiceTranslation", + Body = "VESTA", + Observer = "SUN", + }, + Color = { 0.7, 0.8, 0.7 }, StartTime = "2007 JUL 20 12:00:00", - EndTime = "2018 JAN 22 12:00:00" + EndTime = "2018 JAN 22 12:00:00", + SampleInterval = 3600 * 24 } } } diff --git a/data/scene/missions/newhorizons/jupiter/callisto/callisto.mod b/data/scene/missions/newhorizons/jupiter/callisto/callisto.mod index 5454e41ed6..acf03fd873 100644 --- a/data/scene/missions/newhorizons/jupiter/callisto/callisto.mod +++ b/data/scene/missions/newhorizons/jupiter/callisto/callisto.mod @@ -82,20 +82,15 @@ return { Name = "CallistoTrail", Parent = "JupiterBarycenter", Renderable = { - Type = "RenderableTrail", - Body = "CALLISTO", - Frame = "GALACTIC", - Observer = "JUPITER BARYCENTER", - RGB = { 0.7, 0.4, 0.2 }, - TropicalOrbitPeriod = 80 , - EarthOrbitRatio = 0.04, - DayLength = 9.9259, - LineFade = 2.0, - Textures = { - Type = "simple", - Color = "${COMMON_MODULE}/textures/glare_blue.png", - -- need to add different texture + Type = "RenderableTrailOrbit", + Translation = { + Type = "SpiceTranslation", + Body = "CALLISTO", + Observer = "JUPITER BARYCENTER", }, - }, + Color = { 0.4, 0.3, 0.01 }, + Period = 17, + Resolution = 1000 + } } } diff --git a/data/scene/missions/newhorizons/jupiter/europa/europa.mod b/data/scene/missions/newhorizons/jupiter/europa/europa.mod index 31933603e7..1bec7e5c9b 100644 --- a/data/scene/missions/newhorizons/jupiter/europa/europa.mod +++ b/data/scene/missions/newhorizons/jupiter/europa/europa.mod @@ -82,20 +82,15 @@ return { Name = "EuropaTrail", Parent = "JupiterBarycenter", Renderable = { - Type = "RenderableTrail", - Body = "EUROPA", - Frame = "GALACTIC", - Observer = "JUPITER BARYCENTER", - RGB = { 0.7, 0.4, 0.2 }, - TropicalOrbitPeriod = 80 , - EarthOrbitRatio = 0.009, - DayLength = 9.9259, - LineFade = 2.0, - Textures = { - Type = "simple", - Color = "${COMMON_MODULE}/textures/glare_blue.png", - -- need to add different texture - }, - }, + Type = "RenderableTrailOrbit", + Translation = { + Type = "SpiceTranslation", + Body = "EUROPA", + Observer = "JUPITER BARYCENTER", + }, + Color = { 0.5, 0.3, 0.3 }, + Period = 85 / 24, + Resolution = 1000 + } } } diff --git a/data/scene/missions/newhorizons/jupiter/ganymede/ganymede.mod b/data/scene/missions/newhorizons/jupiter/ganymede/ganymede.mod index 0e7952fa87..401babcca6 100644 --- a/data/scene/missions/newhorizons/jupiter/ganymede/ganymede.mod +++ b/data/scene/missions/newhorizons/jupiter/ganymede/ganymede.mod @@ -76,20 +76,15 @@ return { Name = "GanymedeTrail", Parent = "JupiterBarycenter", Renderable = { - Type = "RenderableTrail", - Body = "GANYMEDE", - Frame = "GALACTIC", - Observer = "JUPITER BARYCENTER", - RGB = { 0.7, 0.4, 0.2 }, - TropicalOrbitPeriod = 80 , - EarthOrbitRatio = 0.018, - DayLength = 9.9259, - LineFade = 2.0, - Textures = { - Type = "simple", - Color = "${COMMON_MODULE}/textures/glare_blue.png", - -- need to add different texture - }, - }, + Type = "RenderableTrailOrbit", + Translation = { + Type = "SpiceTranslation", + Body = "GANYMEDE", + Observer = "JUPITER BARYCENTER", + }, + Color = { 0.4, 0.3, 0.3 }, + Period = 172 / 24, + Resolution = 1000 + } } } diff --git a/data/scene/missions/newhorizons/jupiter/io/io.mod b/data/scene/missions/newhorizons/jupiter/io/io.mod index e6b481c40c..c41b45f29b 100644 --- a/data/scene/missions/newhorizons/jupiter/io/io.mod +++ b/data/scene/missions/newhorizons/jupiter/io/io.mod @@ -92,20 +92,15 @@ return { Name = "IoTrail", Parent = "JupiterBarycenter", Renderable = { - Type = "RenderableTrail", - Body = "IO", - Frame = "GALACTIC", - Observer = "JUPITER BARYCENTER", - RGB = { 0.7, 0.4, 0.2 }, - TropicalOrbitPeriod = 100 , - EarthOrbitRatio = 0.0045, - DayLength = 9.9259, - LineFade = 2.0, - Textures = { - Type = "simple", - Color = "${COMMON_MODULE}/textures/glare_blue.png", - -- need to add different texture - }, - }, + Type = "RenderableTrailOrbit", + Translation = { + Type = "SpiceTranslation", + Body = "IO", + Observer = "JUPITER BARYCENTER", + }, + Color = { 0.4, 0.4, 0.2 }, + Period = 42 / 24, + Resolution = 1000 + } } } diff --git a/data/scene/missions/newhorizons/jupiter/jupiter/jupiter.mod b/data/scene/missions/newhorizons/jupiter/jupiter/jupiter.mod index b1d3377eac..079357b2ad 100644 --- a/data/scene/missions/newhorizons/jupiter/jupiter/jupiter.mod +++ b/data/scene/missions/newhorizons/jupiter/jupiter/jupiter.mod @@ -115,24 +115,20 @@ return { }, }, -- JupiterTrail module - { - Name = "JupiterTrail", - Parent = "SolarSystemBarycenter", - Renderable = { - Type = "RenderableTrail", - Body = "JUPITER BARYCENTER", - Frame = "GALACTIC", - Observer = "SUN", - RGB = { 0.8, 0.7, 0.7 }, - TropicalOrbitPeriod = 4330.595 , - EarthOrbitRatio = 11.857, - DayLength = 9.9259, - Textures = { - Type = "simple", - Color = "${COMMON_MODULE}/textures/glare_blue.png", - -- need to add different texture - }, - }, - } + { + Name = "JupiterTrail", + Parent = "SolarSystemBarycenter", + Renderable = { + Type = "RenderableTrailOrbit", + Translation = { + Type = "SpiceTranslation", + Body = "JUPITER BARYCENTER", + Observer = "SUN", + }, + Color = { 0.8, 0.7, 0.7 }, + Period = 4330.595, + Resolution = 1000 + } + } } diff --git a/data/scene/missions/newhorizons/newhorizons/newhorizons.mod b/data/scene/missions/newhorizons/newhorizons/newhorizons.mod index c683779d8f..f7fb7f73be 100644 --- a/data/scene/missions/newhorizons/newhorizons/newhorizons.mod +++ b/data/scene/missions/newhorizons/newhorizons/newhorizons.mod @@ -176,26 +176,21 @@ return { Name = "NewHorizonsTrailPluto", Parent = "PlutoBarycenter", Renderable = { - Type = "RenderableTrailNew", - -- Spice - Body = "NEW HORIZONS", - Frame = "GALACTIC", - Observer = "PLUTO BARYCENTER", - -- Optional rendering properties - LineColor = { 1.0, 0.8, 0.4 }, - PointColor = { 1.0, 0.8, 0.4 }, - LineFade = 0.0, -- [0,1] - RenderPart = 1, - LineWidth = 2, - ShowTimeStamps = true, - RenderFullTrail = true, - -- Time interval - TimeRange = { - Start = "2015 JUL 07 12:00:00", - End = "2015 JUL 17 12:00:00" + Type = "RenderableTrailTrajectory", + Translation = { + Type = "SpiceTranslation", + Body = "NEW HORIZONS", + Observer = "PLUTO BARYCENTER" }, - SampleDeltaTime = 3600, -- Seconds between each point - SubSamples = 3, + Color = { 1.0, 0.8, 0.4 }, + ShowFullTrail = true, + StartTime = "2015 JUL 07 12:00:00", + EndTime = "2015 JUL 17 12:00:00", + PointSize = 5, + SampleInterval = 3600, + TimeStampSubsampleFactor = 4, + EnableFade = false, + Rendering = "Lines+Points" }, }, --[[ diff --git a/data/scene/missions/newhorizons/pluto/charon/charon.mod b/data/scene/missions/newhorizons/pluto/charon/charon.mod index 01c370acc6..4cfff1d131 100644 --- a/data/scene/missions/newhorizons/pluto/charon/charon.mod +++ b/data/scene/missions/newhorizons/pluto/charon/charon.mod @@ -104,19 +104,15 @@ return { Name = "CharonTrail", Parent = "PlutoBarycenter", Renderable = { - Type = "RenderableTrail", - Body = "CHARON", - Frame = "GALACTIC", - Observer = "PLUTO BARYCENTER", - RGB = {0.00,0.62,1.00}, - TropicalOrbitPeriod = 120 , - EarthOrbitRatio = 0.03, - DayLength = 1, - Textures = { - Type = "simple", - Color = "${COMMON_MODULE}/textures/glare_blue.png", - -- need to add different texture - }, + Type = "RenderableTrailOrbit", + Translation = { + Type = "SpiceTranslation", + Body = "CHARON", + Observer = "PLUTO BARYCENTER", + }, + Color = {0.00, 0.62, 1.00}, + Period = 6.38725, + Resolution = 1000 }, } } diff --git a/data/scene/missions/newhorizons/pluto/hydra/hydra.mod b/data/scene/missions/newhorizons/pluto/hydra/hydra.mod index fe07fe078c..8dcf6d2d0f 100644 --- a/data/scene/missions/newhorizons/pluto/hydra/hydra.mod +++ b/data/scene/missions/newhorizons/pluto/hydra/hydra.mod @@ -63,20 +63,15 @@ return { Name = "HydraTrail", Parent = "PlutoBarycenter", Renderable = { - Type = "RenderableTrail", - Body = "HYDRA", - Frame = "GALACTIC", - Observer = "PLUTO BARYCENTER", - RGB = {0.00,0.62,1.00}, - TropicalOrbitPeriod = 150 , - EarthOrbitRatio = 0.2, - DayLength = 1, - DayLength = 16.11, - Textures = { - Type = "simple", - Color = "${COMMON_MODULE}/textures/glare_blue.png", - -- need to add different texture - }, + Type = "RenderableTrailOrbit", + Translation = { + Type = "SpiceTranslation", + Body = "HYDRA", + Observer = "PLUTO BARYCENTER", + }, + Color = {0.00, 0.62, 1.00}, + Period = 38.20177, + Resolution = 1000 }, } diff --git a/data/scene/missions/newhorizons/pluto/kerberos/kerberos.mod b/data/scene/missions/newhorizons/pluto/kerberos/kerberos.mod index 8690a6317a..595baf13e8 100644 --- a/data/scene/missions/newhorizons/pluto/kerberos/kerberos.mod +++ b/data/scene/missions/newhorizons/pluto/kerberos/kerberos.mod @@ -58,25 +58,20 @@ return { }, }, }, - -- StyxTrail module + -- KerberosTrail module { Name = "KerberosTrail", Parent = "PlutoBarycenter", Renderable = { - Type = "RenderableTrail", - Body = "KERBEROS", - Frame = "GALACTIC", - Observer = "PLUTO BARYCENTER", - RGB = {0.00,0.62,1.00}, - TropicalOrbitPeriod = 150 , - EarthOrbitRatio = 0.2, - DayLength = 1, - DayLength = 16.11, - Textures = { - Type = "simple", - Color = "${COMMON_MODULE}/textures/glare_blue.png", - -- need to add different texture - }, + Type = "RenderableTrailOrbit", + Translation = { + Type = "SpiceTranslation", + Body = "KERBEROS", + Observer = "PLUTO BARYCENTER", + }, + Color = {0.00, 0.62, 1.00}, + Period = 32.16756, + Resolution = 1000 }, } diff --git a/data/scene/missions/newhorizons/pluto/nix/nix.mod b/data/scene/missions/newhorizons/pluto/nix/nix.mod index 84d923c36d..da05401b4e 100644 --- a/data/scene/missions/newhorizons/pluto/nix/nix.mod +++ b/data/scene/missions/newhorizons/pluto/nix/nix.mod @@ -52,25 +52,20 @@ return { Texture = "textures/Nix-Text.png" }, }, - -- StyxTrail module + -- NixTrail module { Name = "NixTrail", Parent = "PlutoBarycenter", Renderable = { - Type = "RenderableTrail", - Body = "NIX", - Frame = "GALACTIC", - Observer = "PLUTO BARYCENTER", - RGB = {0.00,0.62,1.00}, - TropicalOrbitPeriod = 150 , - EarthOrbitRatio = 0.12, - DayLength = 1, - DayLength = 16.11, - Textures = { - Type = "simple", - Color = "${COMMON_MODULE}/textures/glare_blue.png", - -- need to add different texture - }, + Type = "RenderableTrailOrbit", + Translation = { + Type = "SpiceTranslation", + Body = "NIX", + Observer = "PLUTO BARYCENTER", + }, + Color = {0.00, 0.62, 1.00}, + Period = 24.85463, + Resolution = 1000 }, } diff --git a/data/scene/missions/newhorizons/pluto/pluto/pluto.mod b/data/scene/missions/newhorizons/pluto/pluto/pluto.mod index 4434ec1cb0..e512b74708 100644 --- a/data/scene/missions/newhorizons/pluto/pluto/pluto.mod +++ b/data/scene/missions/newhorizons/pluto/pluto/pluto.mod @@ -237,19 +237,15 @@ return { Name = "PlutoBarycentricTrail", Parent = "PlutoBarycenter", Renderable = { - Type = "RenderableTrail", - Body = "PLUTO", - Frame = "GALACTIC", - Observer = "PLUTO BARYCENTER", - RGB = {0.00,0.62,1.00}, - TropicalOrbitPeriod = 120 , - EarthOrbitRatio = 0.03, - DayLength = 1, - Textures = { - Type = "simple", - Color = "${COMMON_MODULE}/textures/glare_blue.png", - -- need to add different texture - }, + Type = "RenderableTrailOrbit", + Translation = { + Type = "SpiceTranslation", + Body = "PLUTO", + Observer = "PLUTO BARYCENTER", + }, + Color = {0.00, 0.62, 1.00}, + Period = 6.38723, + Resolution = 1000 }, }, -- PlutoTrail module @@ -257,19 +253,17 @@ return { Name = "PlutoTrail", Parent = "SolarSystemBarycenter", Renderable = { - Type = "RenderableTrail", - Body = "PLUTO BARYCENTER", - Frame = "GALACTIC", - Observer = "SUN", - RGB = { 0.3, 0.7, 0.3 }, - TropicalOrbitPeriod = 90588 , - EarthOrbitRatio = 248.02, - DayLength = 9.9259, - Textures = { - Type = "simple", - Color = "${COMMON_MODULE}/textures/glare_blue.png", - -- need to add different texture - }, + Type = "RenderableTrailOrbit", + Translation = { + Type = "SpiceTranslation", + Body = "PLUTO BARYCENTER", + Observer = "SUN", + }, + Color = { 0.3, 0.7, 0.3 }, + -- Not the actual Period, but the SPICE kernels we have only + -- go back to 1850, about 150 yeays ago + Period = 160 * 365.242, + Resolution = 1000 }, } } diff --git a/data/scene/missions/newhorizons/pluto/styx/styx.mod b/data/scene/missions/newhorizons/pluto/styx/styx.mod index 2c2cf774b1..559062be97 100644 --- a/data/scene/missions/newhorizons/pluto/styx/styx.mod +++ b/data/scene/missions/newhorizons/pluto/styx/styx.mod @@ -64,21 +64,15 @@ return { Name = "StyxTrail", Parent = "PlutoBarycenter", Renderable = { - Type = "RenderableTrail", - Body = "STYX", - Frame = "GALACTIC", - Observer = "PLUTO BARYCENTER", - RGB = {0.00,0.62,1.00}, - TropicalOrbitPeriod = 150 , - EarthOrbitRatio = 0.12, - DayLength = 1, - DayLength = 16.11, - Textures = { - Type = "simple", - Color = "${COMMON_MODULE}/textures/glare_blue.png", - -- need to add different texture - }, + Type = "RenderableTrailOrbit", + Translation = { + Type = "SpiceTranslation", + Body = "STYX", + Observer = "PLUTO BARYCENTER", + }, + Color = {0.00, 0.62, 1.00}, + Period = 20.16155, + Resolution = 1000 }, } - } diff --git a/data/scene/missions/osirisrex/bennu/bennu.mod b/data/scene/missions/osirisrex/bennu/bennu.mod index 5835657356..d7718f66bb 100644 --- a/data/scene/missions/osirisrex/bennu/bennu.mod +++ b/data/scene/missions/osirisrex/bennu/bennu.mod @@ -97,25 +97,16 @@ return { Name = "BennuTrail", Parent = "SolarSystemBarycenter", Renderable = { - Type = "RenderableTrailNew", - -- Spice - Body = BENNU_BODY, - Frame = "GALACTIC", - Observer = "SUN", - -- Optional rendering properties - LineColor = { 0.4, 0.0, 0.7}, - PointColor = { 0.4, 0.0, 0.7}, - LineFade = 0, -- [0,1] - RenderPart = 0.12, - LineWidth = 2, - ShowTimeStamps = false, - -- Time interval - TimeRange = { - Start = "2015 JAN 01 00:00:00.000", - End = "2023 MAY 31 00:00:00.000", + Type = "RenderableTrailTrajectory", + Translation = { + Type = "SpiceTranslation", + Body = BENNU_BODY, + Observer = "SUN", }, - SampleDeltaTime = 3600, -- Seconds between each point - SubSamples = 0, + Color = { 0.4, 0.0, 0.7}, + StartTime = "2015 JAN 01 00:00:00.000", + EndTime = "2023 MAY 31 00:00:00.000", + SampleInterval = 3600, }, }, } diff --git a/data/scene/missions/osirisrex/osirisrex/osirisrex.mod b/data/scene/missions/osirisrex/osirisrex/osirisrex.mod index 83b3432517..5d6fcca8b5 100644 --- a/data/scene/missions/osirisrex/osirisrex/osirisrex.mod +++ b/data/scene/missions/osirisrex/osirisrex/osirisrex.mod @@ -339,26 +339,17 @@ return { Name = "OsirisRexTrailEarth", Parent = "Earth", Renderable = { - Type = "RenderableTrailNew", - -- Spice - Body = "OSIRIS-REX", - Frame = "IAU_EARTH", + Type = "RenderableTrailTrajectory", + Translation = { + Type = "SpiceTranslation", + Body = "OSIRIS-REX", + Frame = "IAU_EARTH", Observer = "EARTH", - -- Optional rendering properties - LineColor = { 0.9, 0.9, 0.0 }, - PointColor = { 0.9, 0.9, 0.0 }, - LineFade = 0.0, -- [0,1] - RenderPart = 1, - LineWidth = 2, - ShowTimeStamps = false, - RenderFullTrail = false, - -- Time interval - TimeRange = { - Start = "2016 SEP 8 23:05:00.50", - End = "2016 SEP 9 00:05:00", }, - SampleDeltaTime = 60, -- Seconds between each point - SubSamples = 59, + Color = { 0.9, 0.9, 0.0 }, + StartTime = "2016 SEP 8 23:05:00.50", + EndTime = "2016 SEP 9 00:05:00", + SampleInterval = 60, }, }, @@ -367,26 +358,16 @@ return { Name = "OsirisRexTrailSolarSystem", Parent = "SolarSystemBarycenter", Renderable = { - Type = "RenderableTrailNew", - -- Spice - Body = "OSIRIS-REX", - Frame = "GALACTIC", - Observer = "SUN", - -- Optional rendering properties - LineColor = { 0.2, 0.9, 0.2 }, - PointColor = { 0.2, 0.9, 0.2 }, - LineFade = 0.0, -- [0,1] - RenderPart = 0.13, - LineWidth = 2, - ShowTimeStamps = false, - RenderFullTrail = false, - -- Time interval - TimeRange = { - Start = "2016 SEP 8 23:05:00.50", - End = "2023 SEP 24 12:00:00", + Type = "RenderableTrailTrajectory", + Translation = { + Type = "SpiceTranslation", + Body = "OSIRIS-REX", + Observer = "SUN", }, - SampleDeltaTime = 3600, -- Seconds between each point - SubSamples = 0, + Color = { 0.2, 0.9, 0.2 }, + StartTime = "2016 SEP 8 23:05:00.50", + EndTime = "2023 SEP 24 12:00:00", + SampleInterval = 3600, }, }, @@ -395,28 +376,16 @@ return { Name = "OsirisRexTrailBennu", Parent = "BennuBarycenter", Renderable = { - Type = "RenderableTrailNew", - -- Spice - Body = "OSIRIS-REX", - Frame = "GALACTIC", - Observer = BENNU_BODY, - -- Optional rendering properties - LineColor = { 0.9, 0.2, 0.9 }, - PointColor = { 0.9, 0.2, 0.9 }, - LineFade = 0.5, -- [0,1] - RenderPart = 0.06, - LineWidth = 2, - ShowTimeStamps = false, - RenderFullTrail = false, - -- Time interval - TimeRange = { - Start = "2016 SEP 8 23:05:00.50", - End = "2023 SEP 24 12:00:00", + Type = "RenderableTrailTrajectory", + Translation = { + Type = "SpiceTranslation", + Body = "OSIRIS-REX", + Observer = BENNU_BODY, }, - SampleDeltaTime = 3600, -- Seconds between each point - SubSamples = 3, + Color = { 0.9, 0.2, 0.9 }, + StartTime = "2016 SEP 8 23:05:00.50", + EndTime = "2023 SEP 24 12:00:00", + SampleInterval = 3600, }, }, - - } diff --git a/data/scene/missions/rosetta/67P/67P.mod b/data/scene/missions/rosetta/67P/67P.mod index 5358b6b9ce..1582a2b6c0 100644 --- a/data/scene/missions/rosetta/67P/67P.mod +++ b/data/scene/missions/rosetta/67P/67P.mod @@ -82,34 +82,24 @@ return { }, }, }, - -- 67P Trail Module + -- -- 67P Trail Module { Name = "67PTrail", Parent = "SolarSystemBarycenter", Renderable = { - Type = "RenderableTrailNew", - -- Spice - Body = "CHURYUMOV-GERASIMENKO", - Frame = "GALACTIC", - Observer = "SUN", - -- Optional rendering properties - LineColor = { 0.1, 0.9, 0.2 }, - PointColor = { 0.1, 0.9, 0.2 }, - LineFade = 0.5, -- [0,1] - RenderPart = 0.5, - LineWidth = 2, - ShowTimeStamps = false, - RenderFullTrail = false, - -- Time interval - TimeRange = { - Start = "2014 JAN 01 00:00:00.000", - End = "2017 JAN 01 00:00:00.000", + Type = "RenderableTrailTrajectory", + Translation = { + Type = "SpiceTranslation", + Body = "CHURYUMOV-GERASIMENKO", + Observer = "SUN", }, - SampleDeltaTime = 3600, -- Seconds between each point - SubSamples = 0, + Color = { 0.1, 0.9, 0.2 }, + StartTime = "2014 JAN 01 00:00:00.000", + EndTime = "2017 JAN 01 00:00:00.000", + SampleInterval = 3600, }, }, - --[[ + [[ { Name = "67PTrail", Parent = "SolarSystemBarycenter", diff --git a/data/scene/missions/rosetta/rosetta/rosetta.mod b/data/scene/missions/rosetta/rosetta/rosetta.mod index dffee7acb6..930a4941df 100644 --- a/data/scene/missions/rosetta/rosetta/rosetta.mod +++ b/data/scene/missions/rosetta/rosetta/rosetta.mod @@ -365,52 +365,32 @@ return { Name = "RosettaCometTrail", Parent = "67PBarycenter", Renderable = { - Type = "RenderableTrailNew", - -- Spice - Body = "ROSETTA", - Frame = "GALACTIC", - Observer = "CHURYUMOV-GERASIMENKO", - -- Optional rendering properties - LineColor = { 0.288, 0.375, 0.934 }, - PointColor = { 0.9, 0.2, 0.9 }, - LineFade = 0.0, -- [0,1] - RenderPart = 0.5, -- [0,1] - LineWidth = 2, - ShowTimeStamps = false, - RenderFullTrail = false, - -- Time interval - TimeRange = { - Start = "2014 AUG 01 12:00:00", - End = "2016 SEP 30 12:00:00" + Type = "RenderableTrailTrajectory", + Translation = { + Type = "SpiceTranslation", + Body = "ROSETTA", + Observer = "CHURYUMOV-GERASIMENKO", }, - SampleDeltaTime = 3600, -- Seconds between each point - SubSamples = 3, + Color = { 0.288, 0.375, 0.934 }, + StartTime = "2014 AUG 01 12:00:00", + EndTime = "2016 SEP 30 12:00:00", + SampleInterval = 3600, }, }, { Name = "PhilaeTrail", Parent = "67PBarycenter", Renderable = { - Type = "RenderableTrailNew", - -- Spice - Body = "PHILAE", - Frame = "GALACTIC", - Observer = "CHURYUMOV-GERASIMENKO", - -- Optional rendering properties - LineColor = { 1.0, 1.0, 1.0 }, - PointColor = { 0.9, 0.2, 0.9 }, - LineFade = 0.0, -- [0,1] - RenderPart = 0.5, -- [0,1] - LineWidth = 2, - ShowTimeStamps = false, - RenderFullTrail = false, - -- Time interval - TimeRange = { - Start = "2014 NOV 12 08:35:00", - End = "2014 NOV 12 17:00:00" + Type = "RenderableTrailTrajectory", + Translation = { + Type = "SpiceTranslation", + Body = "PHILAE", + Observer = "CHURYUMOV-GERASIMENKO", }, - SampleDeltaTime = 2, -- Seconds between each point - SubSamples = 0, + Color = { 0.8, 0.5, 1.0 }, + StartTime = "2014 NOV 12 08:35:00", + EndTime = "2014 NOV 12 17:00:00", + SampleInterval = 2, }, }, { diff --git a/data/scene/moon/moon.mod b/data/scene/moon/moon.mod index d1683df018..b58b056dcb 100644 --- a/data/scene/moon/moon.mod +++ b/data/scene/moon/moon.mod @@ -47,19 +47,15 @@ return { Name = "MoonTrail", Parent = "EarthBarycenter", Renderable = { - Type = "RenderableTrail", - Body = "MOON", - Frame = "GALACTIC", - Observer = "EARTH BARYCENTER", - RGB = { 0.5, 0.3, 0.3 }, - TropicalOrbitPeriod = 60, - EarthOrbitRatio = 0.01, - DayLength = 1.0, - Textures = { - Type = "simple", - Color = "${COMMON_MODULE}/textures/glare_blue.png", - -- need to add different texture - }, + Type = "RenderableTrailOrbit", + Translation = { + Type = "SpiceTranslation", + Body = "MOON", + Observer = "EARTH BARYCENTER", + }, + Color = { 0.5, 0.3, 0.3 }, + Period = 27, + Resolution = 1000 }, } } diff --git a/data/scene/neptune/neptune.mod b/data/scene/neptune/neptune.mod index 2a44ae7098..a4e6ef0107 100644 --- a/data/scene/neptune/neptune.mod +++ b/data/scene/neptune/neptune.mod @@ -40,19 +40,15 @@ return { Name = "NeptuneTrail", Parent = "NeptuneBarycenter", Renderable = { - Type = "RenderableTrail", - Body = "NEPTUNE BARYCENTER", - Frame = "GALACTIC", - Observer = "SUN", - RGB = {0.2, 0.5, 1.0 }, - TropicalOrbitPeriod = 59799.9 , - EarthOrbitRatio = 163.73, - DayLength = 16.11, - Textures = { - Type = "simple", - Color = "${COMMON_MODULE}/textures/glare_blue.png", - -- need to add different texture - }, + Type = "RenderableTrailOrbit", + Translation = { + Type = "SpiceTranslation", + Body = "NEPTUNE BARYCENTER", + Observer = "SUN", + }, + Color = {0.2, 0.5, 1.0 }, + Period = 60200, + Resolution = 1000 }, } } diff --git a/data/scene/pluto/pluto.mod b/data/scene/pluto/pluto.mod index e8bdf8b37e..336913415c 100644 --- a/data/scene/pluto/pluto.mod +++ b/data/scene/pluto/pluto.mod @@ -85,42 +85,49 @@ return { Name = "CharonTrail", Parent = "PlutoBarycenter", Renderable = { - Type = "RenderableTrail", - Body = "CHARON", - Frame = "GALACTIC", - Observer = "PLUTO BARYCENTER", - RGB = {0.00,0.62,1.00}, - TropicalOrbitPeriod = 120 , - EarthOrbitRatio = 0.03, - DayLength = 1, - Textures = { - Type = "simple", - Color = "${COMMON_MODULE}/textures/glare_blue.png", - -- need to add different texture - }, + Type = "RenderableTrailOrbit", + Translation = { + Type = "SpiceTranslation", + Body = "CHARON", + Observer = "PLUTO BARYCENTER", + }, + Color = {0.00,0.62,1.00}, + Period = 6.38725, + Resolution = 1000, }, - } - --[[ + }, -- PlutoTrail module { - Name = "PlutoTrail", + Name = "PlutoTrailSolarSystem", Parent = "SolarSystemBarycenter", Renderable = { - Type = "RenderableTrail", - Body = "PLUTO BARYCENTER", - Frame = "GALACTIC", - Observer = "SUN", - RGB = {0.58, 0.61, 1.00}, - TropicalOrbitPeriod = 59799.9 , - EarthOrbitRatio = 163.73, - DayLength = 16.11, - Textures = { - Type = "simple", - Color = "${COMMON_MODULE}/textures/glare_blue.png", - -- need to add different texture - }, + Type = "RenderableTrailOrbit", + Translation = { + Type = "SpiceTranslation", + Body = "PLUTO BARYCENTER", + Observer = "SUN", + }, + Color = {0.58, 0.61, 1.00}, + Period = 247.92 * 365.242, + Resolution = 1000 + }, + GuiName = "/Solar/PlutoTrail" + }, + { + Name = "PlutoTrailPluto", + Parent = "PlutoBarycenter", + Renderable = { + Type = "RenderableTrailOrbit", + Translation = { + Type = "SpiceTranslation", + Body = "PLUTO", + Observer = "PLUTO BARYCENTER", + }, + Color = {0.58, 0.61, 1.00}, + Period = 6.38725, + Resolution = 1000 }, GuiName = "/Solar/PlutoTrail" } ---]] + } diff --git a/data/scene/rosetta.scene b/data/scene/rosetta.scene index 1142961cc4..361397876f 100644 --- a/data/scene/rosetta.scene +++ b/data/scene/rosetta.scene @@ -57,7 +57,7 @@ return { "jupiter/jupiter", "saturn/saturn", "uranus", - "neptune", + -- "neptune", "stars", "milkyway", "missions/rosetta", diff --git a/data/scene/saturn/dione/dione.mod b/data/scene/saturn/dione/dione.mod index 6691cc3d8c..d132bea897 100644 --- a/data/scene/saturn/dione/dione.mod +++ b/data/scene/saturn/dione/dione.mod @@ -33,14 +33,15 @@ return { Name = "DioneTrail", Parent = "SaturnBarycenter", Renderable = { - Type = "RenderableTrail", - Body = "DIONE", - Frame = "GALACTIC", - Observer = "SATURN BARYCENTER", - RGB = { 0.5, 0.3, 0.3 }, - TropicalOrbitPeriod = 60, - EarthOrbitRatio = 0.0075, - DayLength = 0.9424218 + Type = "RenderableTrailOrbit", + Translation = { + Type = "SpiceTranslation", + Body = "DIONE", + Observer = "SATURN BARYCENTER", + }, + Color = { 0.5, 0.3, 0.3 }, + Period = 66 / 24, + Resolution = 1000 } } } \ No newline at end of file diff --git a/data/scene/saturn/enceladus/enceladus.mod b/data/scene/saturn/enceladus/enceladus.mod index b0bb0138a3..1d3011e4c8 100644 --- a/data/scene/saturn/enceladus/enceladus.mod +++ b/data/scene/saturn/enceladus/enceladus.mod @@ -33,14 +33,15 @@ return { Name = "EnceladusTrail", Parent = "SaturnBarycenter", Renderable = { - Type = "RenderableTrail", - Body = "ENCELADUS", - Frame = "GALACTIC", - Observer = "SATURN BARYCENTER", - RGB = { 0.5, 0.3, 0.3 }, - TropicalOrbitPeriod = 60, - EarthOrbitRatio = 0.005, - DayLength = 0.9424218 + Type = "RenderableTrailOrbit", + Translation = { + Type = "SpiceTranslation", + Body = "ENCELADUS", + Observer = "SATURN BARYCENTER", + }, + Color = { 0.5, 0.3, 0.3 }, + Period = 33 / 24, + Resolution = 1000 } } } \ No newline at end of file diff --git a/data/scene/saturn/iapetus/iapetus.mod b/data/scene/saturn/iapetus/iapetus.mod index e088dfc212..a390af3ec4 100644 --- a/data/scene/saturn/iapetus/iapetus.mod +++ b/data/scene/saturn/iapetus/iapetus.mod @@ -33,14 +33,15 @@ return { Name = "IapetusTrail", Parent = "SaturnBarycenter", Renderable = { - Type = "RenderableTrail", - Body = "IAPETUS", - Frame = "GALACTIC", - Observer = "SATURN BARYCENTER", - RGB = { 0.5, 0.3, 0.3 }, - TropicalOrbitPeriod = 60, - EarthOrbitRatio = 0.1, - DayLength = 0.9424218 + Type = "RenderableTrailOrbit", + Translation = { + Type = "SpiceTranslation", + Body = "IAPETUS", + Observer = "SATURN BARYCENTER", + }, + Color = { 0.5, 0.3, 0.3 }, + Period = 79, + Resolution = 1000 } } } \ No newline at end of file diff --git a/data/scene/saturn/mimas/mimas.mod b/data/scene/saturn/mimas/mimas.mod index 9f50cf0fd7..bf7b451d83 100644 --- a/data/scene/saturn/mimas/mimas.mod +++ b/data/scene/saturn/mimas/mimas.mod @@ -33,14 +33,15 @@ return { Name = "MimasTrail", Parent = "SaturnBarycenter", Renderable = { - Type = "RenderableTrail", - Body = "MIMAS", - Frame = "GALACTIC", - Observer = "SATURN BARYCENTER", - RGB = { 0.5, 0.3, 0.3 }, - TropicalOrbitPeriod = 60, - EarthOrbitRatio = 0.0025, - DayLength = 0.9424218 + Type = "RenderableTrailOrbit", + Translation = { + Type = "SpiceTranslation", + Body = "MIMAS", + Observer = "SATURN BARYCENTER", + }, + Color = { 0.5, 0.3, 0.3 }, + Period = 23 / 24, + Resolution = 1000 } } } \ No newline at end of file diff --git a/data/scene/saturn/rhea/rhea.mod b/data/scene/saturn/rhea/rhea.mod index 9decfcb31a..623dd479a6 100644 --- a/data/scene/saturn/rhea/rhea.mod +++ b/data/scene/saturn/rhea/rhea.mod @@ -33,14 +33,15 @@ return { Name = "RheaTrail", Parent = "SaturnBarycenter", Renderable = { - Type = "RenderableTrail", - Body = "RHEA", - Frame = "GALACTIC", - Observer = "SATURN BARYCENTER", - RGB = { 0.5, 0.3, 0.3 }, - TropicalOrbitPeriod = 60, - EarthOrbitRatio = 0.01, - DayLength = 0.9424218 + Type = "RenderableTrailOrbit", + Translation = { + Type = "SpiceTranslation", + Body = "RHEA", + Observer = "SATURN BARYCENTER", + }, + Color = { 0.5, 0.3, 0.3 }, + Period = 108 / 24, + Resolution = 1000 } } } \ No newline at end of file diff --git a/data/scene/saturn/saturn/saturn.mod b/data/scene/saturn/saturn/saturn.mod index 07884ab016..aea907718b 100644 --- a/data/scene/saturn/saturn/saturn.mod +++ b/data/scene/saturn/saturn/saturn.mod @@ -65,19 +65,15 @@ return { Name = "SaturnTrail", Parent = "SolarSystemBarycenter", Renderable = { - Type = "RenderableTrail", - Body = "SATURN BARYCENTER", - Frame = "GALACTIC", + Type = "RenderableTrailOrbit", + Translation = { + Type = "SpiceTranslation", + Body = "SATURN BARYCENTER", Observer = "SUN", - RGB = {0.85,0.75,0.51 }, - TropicalOrbitPeriod = 10746.94 , - EarthOrbitRatio = 29.424, - DayLength = 10.656, - Textures = { - Type = "simple", - Color = "${COMMON_MODULE}/textures/glare_blue.png", - -- need to add different texture - }, + }, + Color = {0.85,0.75,0.51 }, + Period = 10746.94, + Resolution = 1000 }, } } diff --git a/data/scene/saturn/tethys/tethys.mod b/data/scene/saturn/tethys/tethys.mod index aff56a91ea..eb2a84b3f9 100644 --- a/data/scene/saturn/tethys/tethys.mod +++ b/data/scene/saturn/tethys/tethys.mod @@ -33,14 +33,15 @@ return { Name = "TethysTrail", Parent = "SaturnBarycenter", Renderable = { - Type = "RenderableTrail", - Body = "TETHYS", - Frame = "GALACTIC", - Observer = "SATURN BARYCENTER", - RGB = { 0.5, 0.3, 0.3 }, - TropicalOrbitPeriod = 60, - EarthOrbitRatio = 0.005, - DayLength = 0.9424218 + Type = "RenderableTrailOrbit", + Translation = { + Type = "SpiceTranslation", + Body = "TETHYS", + Observer = "SATURN BARYCENTER", + }, + Color = { 0.5, 0.3, 0.3 }, + Period = 45 / 24, + Resolution = 1000 } } } \ No newline at end of file diff --git a/data/scene/saturn/titan/titan.mod b/data/scene/saturn/titan/titan.mod index b0bc0814d9..83e366c7ba 100644 --- a/data/scene/saturn/titan/titan.mod +++ b/data/scene/saturn/titan/titan.mod @@ -33,14 +33,15 @@ return { Name = "TitanTrail", Parent = "SaturnBarycenter", Renderable = { - Type = "RenderableTrail", - Body = "TITAN", - Frame = "GALACTIC", - Observer = "SATURN BARYCENTER", - RGB = { 0.5, 0.3, 0.3 }, - TropicalOrbitPeriod = 60, - EarthOrbitRatio = 0.05, - DayLength = 0.9424218 + Type = "RenderableTrailOrbit", + Translation = { + Type = "SpiceTranslation", + Body = "TITAN", + Observer = "SATURN BARYCENTER", + }, + Color = { 0.5, 0.3, 0.3 }, + Period = 16, + Resolution = 1000 } } } \ No newline at end of file diff --git a/data/scene/uranus/uranus.mod b/data/scene/uranus/uranus.mod index 1653178896..84d52018c0 100644 --- a/data/scene/uranus/uranus.mod +++ b/data/scene/uranus/uranus.mod @@ -51,19 +51,15 @@ return { Name = "UranusTrail", Parent = "UranusBarycenter", Renderable = { - Type = "RenderableTrail", - Body = "URANUS BARYCENTER", - Frame = "GALACTIC", - Observer = "SUN", - RGB = {0.60,0.95,1.00 }, - TropicalOrbitPeriod = 30588.740 , - EarthOrbitRatio = 83.749, - DayLength = 17.24, - Textures = { - Type = "simple", - Color = "${COMMON_MODULE}/textures/glare_blue.png", - -- need to add different texture - }, + Type = "RenderableTrailOrbit", + Translation = { + Type = "SpiceTranslation", + Body = "URANUS BARYCENTER", + Observer = "SUN", + }, + Color = {0.60, 0.95, 1.00 }, + Period = 30588.740, + Resolution = 1000 }, } } diff --git a/data/scene/venus/venus.mod b/data/scene/venus/venus.mod index 6ea5a5afac..d6f4eda333 100644 --- a/data/scene/venus/venus.mod +++ b/data/scene/venus/venus.mod @@ -46,19 +46,15 @@ return { Name = "VenusTrail", Parent = "SolarSystemBarycenter", Renderable = { - Type = "RenderableTrail", - Body = "VENUS BARYCENTER", - Frame = "GALACTIC", - Observer = "SUN", - RGB = {1, 0.5, 0.2}, - TropicalOrbitPeriod = 224.695 , - EarthOrbitRatio = 0.615, - DayLength = 2802.0, - Textures = { - Type = "simple", - Color = "${COMMON_MODULE}/textures/glare_blue.png", - -- need to add different texture - }, + Type = "RenderableTrailOrbit", + Translation = { + Type = "SpiceTranslation", + Body = "VENUS BARYCENTER", + Observer = "SUN", + }, + Color = { 1.0, 0.5, 0.2 }, + Period = 224.695, + Resolution = 1000 }, } } diff --git a/include/openspace/properties/optionproperty.h b/include/openspace/properties/optionproperty.h index 7f153af8da..d811807aa5 100644 --- a/include/openspace/properties/optionproperty.h +++ b/include/openspace/properties/optionproperty.h @@ -95,11 +95,11 @@ public: void addOption(int value, std::string desc); /** - * Appends options with vectors of values and descriptions - * \param values A std::vector of values for the options - * \param descs A std::vector of descriptions for each value + * Adds multiple options to the OptionProperty. Each value in the vector consists of + * an integer value and a string description. + * \param options Pairs of that are added to the OptionProperty */ - void addOptions(std::vector values, std::vector descs); + void addOptions(std::vector> options); /** * Returns the list of available options. diff --git a/include/openspace/scene/translation.h b/include/openspace/scene/translation.h index d2d64118fa..2fba7f86e8 100644 --- a/include/openspace/scene/translation.h +++ b/include/openspace/scene/translation.h @@ -40,9 +40,12 @@ public: virtual ~Translation(); virtual bool initialize(); + virtual glm::dvec3 position() const = 0; virtual void update(const UpdateData& data); + glm::dvec3 position(double time); + static openspace::Documentation Documentation(); }; diff --git a/include/openspace/util/updatestructures.h b/include/openspace/util/updatestructures.h index 72116a7899..1f33fdb519 100644 --- a/include/openspace/util/updatestructures.h +++ b/include/openspace/util/updatestructures.h @@ -46,6 +46,7 @@ struct UpdateData { TransformData modelTransform; double time; double delta; + bool timePaused; bool isTimeJump; bool doPerformanceMeasurement; }; diff --git a/modules/base/CMakeLists.txt b/modules/base/CMakeLists.txt index 26ca3f53be..3218c1352d 100644 --- a/modules/base/CMakeLists.txt +++ b/modules/base/CMakeLists.txt @@ -38,7 +38,8 @@ set(HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablesphericalgrid.h ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablestars.h ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderabletrail.h - ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderabletrailnew.h + ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderabletrailorbit.h + ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderabletrailtrajectory.h ${CMAKE_CURRENT_SOURCE_DIR}/rendering/simplespheregeometry.h ${CMAKE_CURRENT_SOURCE_DIR}/rendering/screenspaceframebuffer.h ${CMAKE_CURRENT_SOURCE_DIR}/rendering/screenspaceimage.h @@ -64,7 +65,8 @@ set(SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablesphericalgrid.cpp ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablestars.cpp ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderabletrail.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderabletrailnew.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderabletrailorbit.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderabletrailtrajectory.cpp ${CMAKE_CURRENT_SOURCE_DIR}/rendering/simplespheregeometry.cpp ${CMAKE_CURRENT_SOURCE_DIR}/rendering/screenspaceframebuffer.cpp ${CMAKE_CURRENT_SOURCE_DIR}/rendering/screenspaceimage.cpp @@ -79,10 +81,6 @@ source_group("Source Files" FILES ${SOURCE_FILES}) set(SHADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/shaders/constellationbounds_fs.glsl ${CMAKE_CURRENT_SOURCE_DIR}/shaders/constellationbounds_vs.glsl - ${CMAKE_CURRENT_SOURCE_DIR}/shaders/ephemeris_fs.glsl - ${CMAKE_CURRENT_SOURCE_DIR}/shaders/ephemeris_vs.glsl - ${CMAKE_CURRENT_SOURCE_DIR}/shaders/renderabletrailnew_fs.glsl - ${CMAKE_CURRENT_SOURCE_DIR}/shaders/renderabletrailnew_vs.glsl ${CMAKE_CURRENT_SOURCE_DIR}/shaders/imageplane_fs.glsl ${CMAKE_CURRENT_SOURCE_DIR}/shaders/imageplane_vs.glsl ${CMAKE_CURRENT_SOURCE_DIR}/shaders/model_fs.glsl @@ -96,6 +94,8 @@ set(SHADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/shaders/plane_vs.glsl ${CMAKE_CURRENT_SOURCE_DIR}/shaders/pscstandard_fs.glsl ${CMAKE_CURRENT_SOURCE_DIR}/shaders/pscstandard_vs.glsl + ${CMAKE_CURRENT_SOURCE_DIR}/shaders/renderabletrail_fs.glsl + ${CMAKE_CURRENT_SOURCE_DIR}/shaders/renderabletrail_vs.glsl ${CMAKE_CURRENT_SOURCE_DIR}/shaders/rings_vs.glsl ${CMAKE_CURRENT_SOURCE_DIR}/shaders/rings_fs.glsl ${CMAKE_CURRENT_SOURCE_DIR}/shaders/sphere_fs.glsl diff --git a/modules/base/basemodule.cpp b/modules/base/basemodule.cpp index 771253709e..7db855fb09 100644 --- a/modules/base/basemodule.cpp +++ b/modules/base/basemodule.cpp @@ -30,16 +30,16 @@ #include -#include #include -#include -#include -#include +#include #include +#include #include #include #include -#include +#include +#include +#include #include #include #include @@ -105,8 +105,8 @@ void BaseModule::internalInitialize() { fRenderable->registerClass("RenderableSphere"); fRenderable->registerClass("RenderableSphericalGrid"); fRenderable->registerClass("RenderableStars"); - fRenderable->registerClass("RenderableTrail"); - fRenderable->registerClass("RenderableTrailNew"); + fRenderable->registerClass("RenderableTrailOrbit"); + fRenderable->registerClass("RenderableTrailTrajectory"); auto fTranslation = FactoryManager::ref().factory(); ghoul_assert(fTranslation, "Ephemeris factory was not created"); @@ -141,6 +141,8 @@ std::vector BaseModule::documentations() const { StaticTranslation::Documentation(), SpiceTranslation::Documentation(), RenderableRings::Documentation(), + RenderableTrailOrbit::Documentation(), + RenderableTrailTrajectory::Documentation(), modelgeometry::ModelGeometry::Documentation(), planetgeometry::PlanetGeometry::Documentation() }; diff --git a/modules/base/rendering/renderabletrail.cpp b/modules/base/rendering/renderabletrail.cpp index a95cb3054d..9ca1e97652 100644 --- a/modules/base/rendering/renderabletrail.cpp +++ b/modules/base/rendering/renderabletrail.cpp @@ -23,199 +23,351 @@ ****************************************************************************************/ #include -#include -#include -#include -#include +#include #include #include -#include - -#include -#include - - -/* TODO for this class: -* In order to add geometry shader (for pretty-draw), -* need to pack each consecutive point pair into a vec2 -* in order to draw quad between them. -*/ +#include namespace { - const std::string _loggerCat = "RenderableTrail"; - //constants - const std::string keyName = "Name"; - const std::string keyBody = "Body"; - const std::string keyObserver = "Observer"; - const std::string keyFrame = "Frame"; - const std::string keyPathModule = "ModulePath"; - const std::string keyColor = "RGB"; - const std::string keyTropicalOrbitPeriod = "TropicalOrbitPeriod"; - const std::string keyEarthOrbitRatio = "EarthOrbitRatio"; - const std::string keyDayLength = "DayLength"; - const std::string keyStamps = "TimeStamps"; + static const char* KeyTranslation = "Translation"; + static const char* KeyColor = "Color"; + static const char* KeyEnableFade = "EnableFade"; + static const char* KeyFade = "Fade"; + static const char* KeyLineWidth = "LineWidth"; + static const char* KeyPointSize = "PointSize"; + static const char* KeyRendering = "Rendering"; + + // The possible values for the _renderingModes property + enum RenderingMode { + RenderingModeLines = 0, + RenderingModePoints, + RenderingModeLinesPoints + }; + + // Fragile! Keep in sync with documentation + static const std::map RenderingModeConversion = { + { "Lines", RenderingModeLines }, + { "Points", RenderingModePoints }, + { "Lines+Points", RenderingModeLinesPoints }, + { "Points+Lines", RenderingModeLinesPoints } + }; } namespace openspace { +Documentation RenderableTrail::Documentation() { +using namespace documentation; + return { + "RenderableTrail", + "base_renderable_renderabletrail", + { + { + KeyTranslation, + new ReferencingVerifier("core_transform_translation"), + "This object is used to compute locations along the path. Any " + "Translation object can be used here.", + Optional::No + }, + { + KeyColor, + new DoubleVector3Verifier, + "The main color the for lines and points on this trail. The value is " + "interpreted as an RGB value.", + Optional::No + }, + { + KeyEnableFade, + new BoolVerifier, + "Toggles whether the trail should fade older points out. If this value " + "is 'true', the 'Fade' parameter determines the speed of fading. If this " + "value is 'false', the entire trail is rendered at full opacity and " + "color. The default value is 'true'.", + Optional::Yes + }, + { + KeyFade, + new DoubleVerifier, + "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. This value defaults to " + "1.0.", + Optional::Yes + }, + { + KeyLineWidth, + new DoubleVerifier, + "This value specifies the line width of the trail if this rendering " + "method is selected. It defaults to 2.0.", + Optional::Yes + }, + { + KeyPointSize, + new DoubleVerifier, + "This value specifies the base size of the points along the line if this " + "rendering method is selected. If a subsampling of the values is " + "performed, the subsampled values are half this size. The default value " + "is 1.0.", + Optional::Yes + }, + { + KeyRendering, + new StringInListVerifier( + // Taken from the RenderingModeConversion map above + { "Lines", "Points", "Lines+Points", "Points + Lines" } + ), + "Determines how the trail should be rendered to the screen. If 'Lines' " + "is selected, only the line part is visible, if 'Points' is selected, " + "only the corresponding points (and subpoints) are shown. " + "Lines+Points' shows both parts. On default, only the lines are rendered", + Optional::Yes + } + }, + Exhaustive::No + }; +} + RenderableTrail::RenderableTrail(const ghoul::Dictionary& dictionary) : Renderable(dictionary) - , _lineColor("lineColor", "Line Color") - , _lineFade("lineFade", "Line Fade", 0.75f, 0.f, 5.f) + , _lineColor("lineColor", "Color", glm::vec3(1.f), glm::vec3(0.f), glm::vec3(1.f)) + , _useLineFade("useLineFade", "Use Line Fade", true) + , _lineFade("lineFade", "Line Fade", 1.f, 0.f, 20.f) , _lineWidth("lineWidth", "Line Width", 2.f, 1.f, 20.f) - , _showTimestamps("timestamps", "Show Timestamps", false) - , _programObject(nullptr) - , _successfullDictionaryFetch(true) - , _vaoID(0) - , _vBufferID(0) - , _needsSweep(true) - , _oldTime(std::numeric_limits::max()) - , _tropic(0.f) - , _ratio(0.f) - , _day(0.f) - , _increment(0.f) + , _pointSize("pointSize", "Point Size", 1, 1, 64) + , _renderingModes( + "renderingMode", + "Rendering Mode", + properties::OptionProperty::DisplayType::Dropdown + ) { - _successfullDictionaryFetch &= dictionary.getValue(keyBody, _target); - _successfullDictionaryFetch &= dictionary.getValue(keyObserver, _observer); - _successfullDictionaryFetch &= dictionary.getValue(keyFrame, _frame); - _successfullDictionaryFetch &= dictionary.getValue(keyTropicalOrbitPeriod, _tropic); - _successfullDictionaryFetch &= dictionary.getValue(keyEarthOrbitRatio, _ratio); - _successfullDictionaryFetch &= dictionary.getValue(keyDayLength, _day); - // values in modfiles set from here - // http://nssdc.gsfc.nasa.gov/planetary/factsheet/marsfact.html + _translation = std::unique_ptr(Translation::createFromDictionary( + dictionary.value(KeyTranslation) + )); - glm::vec3 color(0.f); - if (dictionary.hasKeyAndValue(keyColor)) - dictionary.getValue(keyColor, color); - _lineColor = color; - - bool timeStamps = false; - if (dictionary.hasKeyAndValue(keyStamps)) - dictionary.getValue(keyStamps, timeStamps); - _showTimestamps = timeStamps; - addProperty(_showTimestamps); - - _lineColor.setViewOption(properties::Property::ViewOptions::Color); + _lineColor = dictionary.value(KeyColor); addProperty(_lineColor); + if (dictionary.hasKeyAndValue(KeyEnableFade)) { + _useLineFade = dictionary.value(KeyEnableFade); + } + addProperty(_useLineFade); + + if (dictionary.hasKeyAndValue(KeyFade)) { + _lineFade = dictionary.value(KeyFade); + } addProperty(_lineFade); + if (dictionary.hasKeyAndValue(KeyLineWidth)) { + _lineWidth = dictionary.value(KeyLineWidth); + } addProperty(_lineWidth); - _distanceFade = 1.0; + + if (dictionary.hasKeyAndValue(KeyPointSize)) { + _pointSize = dictionary.value(KeyPointSize); + } + addProperty(_pointSize); + + _renderingModes.addOptions({ + { RenderingModeLines, "Lines" }, + { RenderingModePoints, "Points" }, + { RenderingModeLinesPoints, "Lines+Points" } + }); + + // This map is not accessed out of order as long as the Documentation is adapted + // whenever the map changes. The documentation will check for valid values + if (dictionary.hasKeyAndValue(KeyRendering)) { + _renderingModes = RenderingModeConversion.at( + dictionary.value(KeyRendering) + ); + } + else { + _renderingModes = RenderingModeLines; + } + addProperty(_renderingModes); } bool RenderableTrail::initialize() { - if (!_successfullDictionaryFetch) { - LERROR("The following keys need to be set in the Dictionary. Cannot initialize!"); - LERROR(keyBody << ": " << _target); - LERROR(keyObserver << ": " << _observer); - LERROR(keyFrame << ": " << _frame); - LERROR(keyTropicalOrbitPeriod << ": " << _tropic); - LERROR(keyEarthOrbitRatio << ": " << _ratio); - LERROR(keyDayLength << ": " << _day); - return false; - } - - bool completeSuccess = true; - RenderEngine& renderEngine = OsEng.renderEngine(); - _programObject = renderEngine.buildRenderProgram("EphemerisProgram", - "${MODULE_BASE}/shaders/ephemeris_vs.glsl", - "${MODULE_BASE}/shaders/ephemeris_fs.glsl"); + _programObject = renderEngine.buildRenderProgram( + "EphemerisProgram", + "${MODULE_BASE}/shaders/renderabletrail_vs.glsl", + "${MODULE_BASE}/shaders/renderabletrail_fs.glsl" + ); setRenderBin(Renderable::RenderBin::Overlay); - if (!_programObject) - return false; - - return completeSuccess; + return true; } bool RenderableTrail::deinitialize() { - glDeleteVertexArrays(1, &_vaoID); - glDeleteBuffers(1, &_vBufferID); - RenderEngine& renderEngine = OsEng.renderEngine(); if (_programObject) { renderEngine.removeRenderProgram(_programObject); _programObject = nullptr; } - return true; } bool RenderableTrail::isReady() const { - return (_programObject != nullptr) && _successfullDictionaryFetch; + return _programObject != nullptr; } -void RenderableTrail::render(const RenderData& data) { +void RenderableTrail::render(const RenderData & data) { _programObject->activate(); - //psc currentPosition = data.position; - //psc campos = data.camera.position(); - //glm::mat4 camrot = glm::mat4(data.camera.viewRotationMatrix()); - //glm::mat4 transform = glm::mat4(1); - - // setup the data to the shader - //_programObject->setUniform("ViewProjection", data.camera.viewProjectionMatrix()); - //_programObject->setUniform("ModelTransform", transform); - //setPscUniforms(*_programObject.get(), data.camera, data.position); - - // Calculate variables to be used as uniform variables in shader - glm::dvec3 bodyPosition = data.modelTransform.translation; - - // Model transform and view transform needs to be in double precision glm::dmat4 modelTransform = - glm::translate(glm::dmat4(1.0), bodyPosition) * - glm::dmat4(data.modelTransform.rotation) * // Spice rotation + glm::translate(glm::dmat4(1.0), data.modelTransform.translation) * + glm::dmat4(data.modelTransform.rotation) * glm::dmat4(glm::scale(glm::dmat4(1.0), glm::dvec3(data.modelTransform.scale))); - glm::dmat4 modelViewTransform = data.camera.combinedViewMatrix() * modelTransform; - _programObject->setUniform("modelViewTransform", glm::mat4(modelViewTransform)); _programObject->setUniform("projectionTransform", data.camera.projectionMatrix()); _programObject->setUniform("color", _lineColor); - _programObject->setUniform("nVertices", static_cast(_vertexArray.size())); - _programObject->setUniform("lineFade", _lineFade); - _programObject->setUniform("forceFade", _distanceFade); + _programObject->setUniform("useLineFade", _useLineFade); + if (_useLineFade) { + _programObject->setUniform("lineFade", _lineFade); + } - //const psc& position = data.camera.position(); - //const psc& origin = openspace::OpenSpaceEngine::ref().interactionHandler()->focusNode()->worldPosition(); - //const PowerScaledScalar& pssl = (position - origin).length(); - // - //if (pssl[0] < 0.000001){ - // if (_distanceFade > 0.0f) _distanceFade -= 0.05f; - // _programObject->setUniform("forceFade", _distanceFade); - //} - //else{ - // if (_distanceFade < 1.0f) _distanceFade += 0.05f; - // _programObject->setUniform("forceFade", _distanceFade); - //} + static std::map SortingMapping = { + // Fragile! Keep in sync with shader + { RenderInformation::VertexSorting::NewestFirst, 0 }, + { RenderInformation::VertexSorting::OldestFirst, 1 }, + { RenderInformation::VertexSorting::NoSorting, 2} + }; bool usingFramebufferRenderer = - OsEng.renderEngine().rendererImplementation() == RenderEngine::RendererImplementation::Framebuffer; - + OsEng.renderEngine().rendererImplementation() == + RenderEngine::RendererImplementation::Framebuffer; + if (usingFramebufferRenderer) { glDepthMask(false); glBlendFunc(GL_SRC_ALPHA, GL_ONE); } - glLineWidth(_lineWidth); + bool renderLines = + _renderingModes == RenderingModeLines | + _renderingModes == RenderingModeLinesPoints; - glBindVertexArray(_vaoID); - glDrawArrays(GL_LINE_STRIP, 0, static_cast(_vertexArray.size())); - glBindVertexArray(0); + bool renderPoints = + _renderingModes == RenderingModePoints | + _renderingModes == RenderingModeLinesPoints; - glLineWidth(1.f); - - if (_showTimestamps){ - glPointSize(5.f); - glBindVertexArray(_vaoID); - glDrawArrays(GL_POINTS, 0, static_cast(_vertexArray.size())); - glBindVertexArray(0); + if (renderLines) { + glLineWidth(_lineWidth); + } + if (renderPoints) { + glEnable(GL_PROGRAM_POINT_SIZE); } + auto render = [renderLines, renderPoints, p = _programObject.get(), &data, + &modelTransform, pointSize = _pointSize.value()] + (RenderInformation& info, int nVertices, int offset) + { + // We pass in the model view transformation matrix as double in order to maintain + // high precision for vertices; especially for the trails, a high vertex precision + // is necessary as they are usually far away from their reference + p->setUniform( + "modelViewTransform", + data.camera.combinedViewMatrix() * modelTransform * info._localTransform + ); + + // The vertex sorting method is used to tweak the fading along the trajectory + p->setUniform( + "vertexSortingMethod", + SortingMapping[info.sorting] + ); + + // This value is subtracted from the vertex id in the case of a potential ring + // buffer (as used in RenderableTrailOrbit) to keep the first vertex at its + // brightest + p->setUniform( + "idOffset", + offset + ); + + p->setUniform("nVertices", nVertices); + + if (renderPoints) { + // The stride parameter determines the distance between larger points and + // smaller ones + p->setUniform("stride", info.stride); + p->setUniform("pointSize", pointSize); + } + + // Fragile! Keep in sync with fragment shader + enum RenderPhase { + RenderPhaseLines = 0, + RenderPhasePoints + }; + + glBindVertexArray(info._vaoID); + if (renderLines) { + p->setUniform("renderPhase", RenderPhaseLines); + // Subclasses of this renderer might be using the index array or might now be + // so we check if there is data available and if there isn't, we use the + // glDrawArrays draw call; otherwise the glDrawElements + if (info._iBufferID == 0) { + glDrawArrays( + GL_LINE_STRIP, + info.first, + info.count + ); + } + else { + glDrawElements( + GL_LINE_STRIP, + info.count, + GL_UNSIGNED_INT, + reinterpret_cast(info.first * sizeof(unsigned int)) + ); + } + } + if (renderPoints) { + // Subclasses of this renderer might be using the index array or might now be + // so we check if there is data available and if there isn't, we use the + // glDrawArrays draw call; otherwise the glDrawElements + p->setUniform("renderPhase", RenderPhasePoints); + if (info._iBufferID == 0) { + glDrawArrays(GL_POINTS, info.first, info.count); + } + else { + glDrawElements( + GL_POINTS, + info.count, + GL_UNSIGNED_INT, + reinterpret_cast(info.first * sizeof(unsigned int)) + ); + } + } + }; + + // The combined size of vertices; -1 because we duplicate the penultimate point + int totalNumber = + _primaryRenderInformation.count + _floatingRenderInformation.count - 1; + + // The primary information might use an index buffer, so we might need to start at an + // offset + int primaryOffset = + _primaryRenderInformation._iBufferID == 0 ? 0 : _primaryRenderInformation.first; + + // Render the primary batch of vertices + render(_primaryRenderInformation, totalNumber, primaryOffset); + + // The secondary batch is optional,. so we need to check whether we have any data here + if (_floatingRenderInformation._vaoID == 0 || _floatingRenderInformation.count == 0) { + render( + _floatingRenderInformation, + totalNumber, + // -1 because we duplicate the penultimate point between the vertices + primaryOffset + _primaryRenderInformation.count - 1 + ); + } + + if (renderPoints) { + glDisable(GL_PROGRAM_POINT_SIZE); + } + + glBindVertexArray(0); if (usingFramebufferRenderer) { glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -225,144 +377,4 @@ void RenderableTrail::render(const RenderData& data) { _programObject->deactivate(); } -void RenderableTrail::update(const UpdateData& data) { - if (data.isTimeJump) - _needsSweep = true; - - if (_needsSweep) { - fullYearSweep(data.time); - sendToGPU(); - _needsSweep = false; - return; - } - - double lightTime = 0.0; - - bool intervalSet = hasTimeInterval(); - double start = -DBL_MAX; - double end = DBL_MAX; - if (intervalSet) { - getInterval(start, end); - } - - // Points in the vertex array should always have a fixed distance. For this reason we - // keep the first entry in the array floating and always pointing to the current date - // As soon as the time difference between the current time and the last time is bigger - // than the fixed distance, we need to create a new fixed point - double deltaTime = std::abs(data.time - _oldTime); - int nValues = static_cast(floor(deltaTime / _increment)); - - glm::dvec3 p; - // Update the floating current time - if (start > data.time) - p = SpiceManager::ref().targetPosition(_target, _observer, _frame, {}, start, lightTime); - else if (end < data.time) - p = SpiceManager::ref().targetPosition(_target, _observer, _frame, {}, end, lightTime); - else - p = SpiceManager::ref().targetPosition(_target, _observer, _frame, {}, data.time, lightTime); - - psc pscPos = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); - - pscPos[3] += 3; // KM to M - _vertexArray[0] = { pscPos[0], pscPos[1], pscPos[2], pscPos[3] }; - - if (nValues != 0) { - std::vector tmp(nValues); - for (int i = nValues; i > 0; --i) { - double et = _oldTime + i * _increment; - if (start > et) - et = start; - else if (end < et) - et = end; - glm::dvec3 p = - SpiceManager::ref().targetPosition(_target, _observer, _frame, {}, et, lightTime); - pscPos = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); - pscPos[3] += 3; - tmp[nValues - i] = { pscPos[0], pscPos[1], pscPos[2], pscPos[3] }; - } - - size_t size = _vertexArray.size(); - _vertexArray.insert(_vertexArray.begin() + 1, tmp.begin(), tmp.end()); - _vertexArray.resize(size); - - _oldTime += nValues * _increment; - } - - glBindBuffer(GL_ARRAY_BUFFER, _vBufferID); - glBufferSubData(GL_ARRAY_BUFFER, 0, _vertexArray.size() * sizeof(TrailVBOLayout), &_vertexArray[0]); -} - -/* This algorithm estimates and precomputes the number of segments required for -* any planetary object in space, given a tropical orbit period and earth-to-planet -* orbit ratio. In doing so, it finds the exact increment of time corresponding -* to a planetary year. -* Therefore all planets need said constants, for other objects we need a different, -* and most likely heuristic measure to easily estimate a nodal time-increment. -* Trivial, yet - a TODO. -*/ -void RenderableTrail::fullYearSweep(double time) { - const int SecondsPerEarthYear = 31540000; - - double lightTime = 0.0; - float planetYear = SecondsPerEarthYear * _ratio; - int segments = static_cast(_tropic); - - bool intervalSet = hasTimeInterval(); - double start = -DBL_MAX; - double end = DBL_MAX; - if (intervalSet) { - intervalSet &= getInterval(start, end); - } - - _increment = planetYear / _tropic; - - _oldTime = time; - - _vertexArray.resize(segments+2); - glm::dvec3 p; - bool failed = false; - for (int i = 0; i < segments+2; i++) { - if (start > time && intervalSet) { - time = start; - } - else if (end < time && intervalSet) { - time = end; - } - - if (!failed || intervalSet) { - try { - p = - SpiceManager::ref().targetPosition(_target, _observer, _frame, {}, time, lightTime); - } - catch (const SpiceManager::SpiceException& e) { - // This fires for PLUTO BARYCENTER and SUN and uses the only value sometimes? - // ---abock - //LERROR(e.what()); - failed = true; - } - } - - psc pscPos = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); - pscPos[3] += 3; - - _vertexArray[i] = {pscPos[0], pscPos[1], pscPos[2], pscPos[3]}; - time -= _increment; - } - -} - -void RenderableTrail::sendToGPU() { - glGenVertexArrays(1, &_vaoID); - glGenBuffers(1, &_vBufferID); - - glBindVertexArray(_vaoID); - glBindBuffer(GL_ARRAY_BUFFER, _vBufferID); - glBufferData(GL_ARRAY_BUFFER, _vertexArray.size() * sizeof(TrailVBOLayout), NULL, GL_STREAM_DRAW); // orphaning the buffer, sending NULL data. - glBufferSubData(GL_ARRAY_BUFFER, 0, _vertexArray.size() * sizeof(TrailVBOLayout), &_vertexArray[0]); - - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0); - glBindVertexArray(0); -} - } // namespace openspace diff --git a/modules/base/rendering/renderabletrail.h b/modules/base/rendering/renderabletrail.h index fbdb5bf0e2..a43dc7974f 100644 --- a/modules/base/rendering/renderabletrail.h +++ b/modules/base/rendering/renderabletrail.h @@ -26,6 +26,10 @@ #define __RENDERABLETRAIL_H__ #include + +#include +#include +#include #include #include @@ -40,53 +44,117 @@ namespace opengl { namespace openspace { +class Translation; + +/** + * This is the base class for a trail that is drawn behind an arbitrary object. The two + * concreate implementations are RenderableTrailOrbit, for objects that have a (roughly) + * repeating orbit, and RenderableTrailTrajectory, for objects that are less orbit-like. + * The main difference between two subclasses is that RenderableTrailOrbit updates itself + * continously, whereas RenderableTrailTrajectory precomputes the entire trail in advance. + * + * This class is responsible for the rendering of the vertex buffer objects which are + * filled by the subclasses. The buffers contain a list of TrailVBOLayout objects that is + * the three dimensional position for each point along the line. + * + * Trails can be rendered either as lines, as points, or a combination of both with + * varying colors, line thicknesses, or fading settings. If trails are rendered as points, + * the RenderInformation's \c stride parameter determines the number of points between + * larger points. A potential use case for this is showing the passage of time along a + * trail by using a point separation of one hour and a subsampling of 4, you would get a + * point every 15 minutes with every hourly point being bigger. + * + * The positions for each point along the trail is provided through a Translation object, + * the type of which is specified in the dictionary that is passed to the constructor. A + * typical implementation of Translation used for the trail would be a SpiceTranslation. + */ class RenderableTrail : public Renderable { public: - explicit RenderableTrail(const ghoul::Dictionary& dictionary); - bool initialize() override; bool deinitialize() override; bool isReady() const override; + /** + * The render method will set up the shader information and then render first the + * information contained in the the \c _primaryRenderInformation, then the optional + * \c _floatingRenderInformation using the provided \p data + * \param data The data that is necessary to render this Renderable + */ void render(const RenderData& data) override; - void update(const UpdateData& data) override; -private: +protected: + explicit RenderableTrail(const ghoul::Dictionary& dictionary); + + /// Returns the documentation entries that the con + static openspace::Documentation Documentation(); + + /// The layout of the VBOs struct TrailVBOLayout { - float x, y, z, e; + float x, y, z; }; - void fullYearSweep(double time); - void sendToGPU(); - - properties::Vec3Property _lineColor; - properties::FloatProperty _lineFade; - properties::FloatProperty _lineWidth; - properties::BoolProperty _showTimestamps; - - std::unique_ptr _programObject; - - bool _successfullDictionaryFetch; - - std::string _target; - std::string _observer; - std::string _frame; - - float _tropic; - float _ratio; - float _day; - - GLuint _vaoID; - GLuint _vBufferID; - - bool _needsSweep; - + /// The backend storage for the vertex buffer object containing all points for this + /// trail. std::vector _vertexArray; - float _increment; - double _oldTime = 0.0; - float _distanceFade; + /// The index array that is potentially used in the draw call. If this is empty, no + /// element draw call is used. + std::vector _indexArray; + + /// The Translation object that provides the position of the individual trail points + std::unique_ptr _translation; + + /// The RenderInformation contains information filled in by the concrete subclasses to + /// be used by this class. + struct RenderInformation { + enum class VertexSorting { + NewestFirst = 0, ///< Newer vertices have a lower index than older ones + OldestFirst, ///< Older vertices have a lower index than newer ones + NoSorting ///< No ordering in the vertices; no fading applied + }; + /// The first element in the vertex buffer to be rendered + GLint first = 0; + /// The number of values to be rendered + GLsizei count = 0; + /// The stride between 'major' points in the array + int stride = 1; + /// Sorting of the vertices; required for correct fading + VertexSorting sorting = VertexSorting::NoSorting; + + /// Local model matrix transformation, used for rendering in camera space + glm::dmat4 _localTransform = glm::dmat4(1.0); + + /// The vertex array object for this RenderInformation + GLuint _vaoID = 0; + /// The main vertex buffer object + GLuint _vBufferID = 0; + /// The optional index buffer object + GLuint _iBufferID = 0; + }; + + /// Primary set of information about the main rendering parts + RenderInformation _primaryRenderInformation; + /// Optional render information that contains information about the last, floating + /// part of the trail + RenderInformation _floatingRenderInformation; + +private: + /// Specifies the base color of the line before fading + properties::Vec3Property _lineColor; + /// Settings that enables or disables the line fading + properties::BoolProperty _useLineFade; + /// Specifies a multiplicative factor that fades out the line + properties::FloatProperty _lineFade; + /// Line width for the line rendering part + properties::FloatProperty _lineWidth; + /// Point size for the point rendering part + properties::IntProperty _pointSize; + /// The option determining which rendering method to use + properties::OptionProperty _renderingModes; + + /// Program object used to render the data stored in RenderInformation + std::unique_ptr _programObject; }; } // namespace openspace diff --git a/modules/base/rendering/renderabletrailnew.cpp b/modules/base/rendering/renderabletrailnew.cpp deleted file mode 100644 index 20eb7da66f..0000000000 --- a/modules/base/rendering/renderabletrailnew.cpp +++ /dev/null @@ -1,416 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2016 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include -#include - -namespace { - const std::string _loggerCat = "RenderableTrailNew"; - - // Spice - const std::string keyBody = "Body"; - const std::string keyFrame = "Frame"; - const std::string keyObserver = "Observer"; - // Rendering properties - const std::string keyLineColor = "LineColor"; - const std::string keyPointColor = "PointColor"; - const std::string keyLineFade = "LineFade"; - const std::string keyLineWidth = "LineWidth"; - const std::string keyRenderPart = "RenderPart"; - const std::string keyShowTimeStamps = "ShowTimeStamps"; - const std::string keyRenderFullTrail = "RenderFullTrail"; - // Time interval - const std::string keyTimeRange = "TimeRange"; - const std::string keySampleDeltaTime = "SampleDeltaTime"; - const std::string keySubSamples = "SubSamples"; - // Static Constants - static const glm::vec3 DEFAULT_COLOR = glm::vec3(1.0f); - static const float DEFAULT_LINE_FADE = 0.5f; - static const float DEFAULT_LINE_WIDTH = 2.0f; - static const int DEFAULT_POINT_STEPS = 1; - static const int DEFAULT_RENDER_PART = 1; - static const bool DEFAULT_SHOW_TIME_STAMPS = false; - static const bool DEFAULT_RENDER_FULL_TRAIL = false; -} - -namespace openspace { - -RenderableTrailNew::RenderableTrailNew(const ghoul::Dictionary& dictionary) - : Renderable(dictionary) - // Properties - , _lineColor("lineColor", "Line Color", DEFAULT_COLOR, glm::vec3(0), glm::vec3(1)) - , _pointColor("pointColor", "Point Color", DEFAULT_COLOR, glm::vec3(0), glm::vec3(1)) - , _lineFade("lineFade", "Line Fade", DEFAULT_LINE_FADE, 0, 1) - , _lineWidth("lineWidth", "Line Width", DEFAULT_LINE_WIDTH, 1, 10) - , _renderPart("renderPart", "Render Part", DEFAULT_RENDER_PART, 0, DEFAULT_RENDER_PART) - , _showTimeStamps("showTimeStamps", "Show TimeStamps", DEFAULT_SHOW_TIME_STAMPS) - , _renderFullTrail("renderFullTrail", "Render Full Trail", DEFAULT_RENDER_FULL_TRAIL) - // OpenGL - , _vaoGlobalID(0) - , _vBufferGlobalID(0) - , _vaoLocalID(0) - , _vBufferLocalID(0) - // Other - , _programObject(nullptr) - , _successfullDictionaryFetch(true) - , _currentTimeClamped(0) - , _subSamples(0) -{ - ghoul::Dictionary timeRangeDict; - - // Values that needs to be set - _successfullDictionaryFetch &= dictionary.getValue(keyBody, _body); - _successfullDictionaryFetch &= dictionary.getValue(keyObserver, _observer); - _successfullDictionaryFetch &= dictionary.getValue(keyFrame, _frame); - _successfullDictionaryFetch &= dictionary.getValue(keySampleDeltaTime, _sampleDeltaTime); - _successfullDictionaryFetch &= dictionary.getValue(keyTimeRange, timeRangeDict); - _successfullDictionaryFetch &= TimeRange::initializeFromDictionary( - timeRangeDict, _timeRange); - - // Validate - _successfullDictionaryFetch &= _sampleDeltaTime > 0; - - // Initialize optional values - glm::vec3 lineColor = glm::vec3(DEFAULT_COLOR); - glm::vec3 pointColor = glm::vec3(DEFAULT_COLOR); - float lineFade = DEFAULT_LINE_FADE; - float lineWidth = DEFAULT_LINE_WIDTH; - float pointSteps = DEFAULT_POINT_STEPS; - double renderPart = DEFAULT_RENDER_PART; - bool showTimeStamps = DEFAULT_SHOW_TIME_STAMPS; - bool renderFullTrail = DEFAULT_RENDER_FULL_TRAIL; - - // Fetch from dictionary - dictionary.getValue(keyLineColor, lineColor); - dictionary.getValue(keyPointColor, pointColor); - dictionary.getValue(keyLineFade, lineFade); - dictionary.getValue(keyLineWidth, lineWidth); - dictionary.getValue(keyRenderPart, renderPart); - dictionary.getValue(keyShowTimeStamps, showTimeStamps); - dictionary.getValue(keyRenderFullTrail, renderFullTrail); - float fSubSamples; // ghoul can not read ints from dictionaries... - if (dictionary.getValue(keySubSamples, fSubSamples)) - _subSamples = fSubSamples; - - // Set property values - _lineColor = lineColor; - _pointColor = pointColor; - _lineFade = lineFade; - _lineWidth = lineWidth; - _renderPart = renderPart; - _showTimeStamps = showTimeStamps; - _renderFullTrail = renderFullTrail; - - // Add all properties and set view options - addProperty(_lineColor); - addProperty(_pointColor); - addProperty(_lineFade); - addProperty(_lineWidth); - addProperty(_renderPart); - addProperty(_showTimeStamps); - addProperty(_renderFullTrail); - - _lineColor.setViewOption(properties::Property::ViewOptions::Color); - _pointColor.setViewOption(properties::Property::ViewOptions::Color); -} - -bool RenderableTrailNew::initialize() { - if (!_successfullDictionaryFetch) { - LERROR("The following keys need to be set in the Dictionary. Cannot initialize!"); - LERROR(keyBody << ": " << _body); - LERROR(keyObserver << ": " << _observer); - LERROR(keyFrame << ": " << _frame); - LERROR(keyTimeRange); - return false; - } - if (_subSamples < 0) - LERROR("SubSamples must not be less than 0: " << _subSamples); - - RenderEngine& renderEngine = OsEng.renderEngine(); - _programObject = renderEngine.buildRenderProgram("RenderableTrailNewProgram", - "${MODULE_BASE}/shaders/renderabletrailnew_vs.glsl", - "${MODULE_BASE}/shaders/renderabletrailnew_fs.glsl"); - - if (!_programObject) - return false; - - sweepTimeRange(); - initializeGlobalOpenGLPathData(); - initializeLocalOpenGLPathData(); - - return true; -} - -void RenderableTrailNew::initializeGlobalOpenGLPathData() { - glGenVertexArrays(1, &_vaoGlobalID); - glGenBuffers(1, &_vBufferGlobalID); - - glBindVertexArray(_vaoGlobalID); - glBindBuffer(GL_ARRAY_BUFFER, _vBufferGlobalID); - // No need to update the trail several times, no need for stream draw. - glBufferData( - GL_ARRAY_BUFFER, - _vertexPositionArray.size() * sizeof(glm::vec3), - &_vertexPositionArray[0], - GL_STATIC_DRAW); - - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); - glBindVertexArray(0); -} - -void RenderableTrailNew::initializeLocalOpenGLPathData() { - glGenVertexArrays(1, &_vaoLocalID); - glGenBuffers(1, &_vBufferLocalID); - - glBindVertexArray(_vaoLocalID); - - glBindBuffer(GL_ARRAY_BUFFER, _vBufferLocalID); - - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); - - glBindVertexArray(0); -} - -void RenderableTrailNew::deInitializeGlobalOpenGLPathData() { - glDeleteVertexArrays(1, &_vaoGlobalID); - glDeleteBuffers(1, &_vBufferGlobalID); -} - -void RenderableTrailNew::deInitializeLocalOpenGLPathData() { - glDeleteVertexArrays(1, &_vaoLocalID); - glDeleteBuffers(1, &_vBufferLocalID); -} - -bool RenderableTrailNew::deinitialize() { - deInitializeGlobalOpenGLPathData(); - deInitializeLocalOpenGLPathData(); - - RenderEngine& renderEngine = OsEng.renderEngine(); - if (_programObject) { - renderEngine.removeRenderProgram(_programObject); - _programObject = nullptr; - } - - return true; -} - -void RenderableTrailNew::sweepTimeRange() { - double lightTime = 0.0; - double subDeltaTime = _sampleDeltaTime / (1 + _subSamples); - glm::dvec3 bodyPosition; - // Loop through all points from time range start to end - for (double t = _timeRange.start; t < _timeRange.end; t += subDeltaTime) { - try { - bodyPosition = SpiceManager::ref().targetPosition( - _body, _observer, _frame, {}, t, lightTime); - } - catch (const SpiceManager::SpiceException& e) { - LERROR(e.what()); - break; - } - // Convert from km used by SPICE to meters used by OpenSpace - bodyPosition *= 1000; - _vertexPositionArray.push_back(glm::vec3(bodyPosition)); - } - // Last point - bodyPosition = SpiceManager::ref().targetPosition( - _body, _observer, _frame, {}, _timeRange.end, lightTime); - _vertexPositionArray.push_back(glm::vec3(bodyPosition)); -} - -bool RenderableTrailNew::isReady() const { - return (_programObject != nullptr) && _successfullDictionaryFetch; -} - -void RenderableTrailNew::render(const RenderData& data) { - _programObject->activate(); - if (_renderFullTrail.value() == true) { - preRender(_vertexPositionArray.size()); - preRenderSubPathGlobally(data); - // Easy but not beautiful solution to render all vertices with max alpha - _programObject->setUniform( - "vertexIDPadding", static_cast(_vertexPositionArray.size())); - - renderLines(_vaoGlobalID, _vertexPositionArray.size() - 1); - if (_showTimeStamps) { - renderPoints(_vaoGlobalID, _vertexPositionArray.size() - 1); - } - } - else { // Only render the trail up to the point of the object body - int nVerticesToDraw = glm::ceil(_vertexPositionArray.size() * - (_currentTimeClamped - _timeRange.start) / (_timeRange.end - _timeRange.start)); - - nVerticesToDraw = glm::min( - nVerticesToDraw, static_cast(_vertexPositionArray.size())) - 1; - if (nVerticesToDraw > 1) { - preRender(nVerticesToDraw); - // Perform rendering of the bulk of the trail in single floating point precision - preRenderSubPathGlobally(data); - // The last vertex is drawn with higher precision after this - // Hence we subtract one vertex from the ones to draw globally - int nVerticesToDrawGlobally = nVerticesToDraw - 1; - renderLines(_vaoGlobalID, nVerticesToDrawGlobally); - if (_showTimeStamps) { - renderPoints(_vaoGlobalID, nVerticesToDrawGlobally); - } - - // The last line segment is rendered relative to body to achieve high precision - preRenderSubPathLocally(data, nVerticesToDraw); - renderLines(_vaoLocalID, 2); - if (_showTimeStamps) { - renderPoints(_vaoLocalID, 2); - } - } - else if (_currentTimeClamped > _timeRange.start) { - preRenderSubPathLocally(data, 2); - renderLines(_vaoLocalID, 2); - } - } - _programObject->deactivate(); -} - -void RenderableTrailNew::preRender(int totalNumVerticesToDraw) { - // Upload uniforms that are the same for global and local rendering to the program - _programObject->setUniform("lineFade", _lineFade.value()); - _programObject->setUniform("subSamples", _subSamples); - _programObject->setUniform("maxNumVertices", - static_cast(_renderPart.value() * _vertexPositionArray.size())); - _programObject->setUniform("numVertices", totalNumVerticesToDraw); -} - -void RenderableTrailNew::preRenderSubPathGlobally(const RenderData& data) { - // Model transform and view transform needs to be in double precision - glm::dmat4 modelViewTransform = data.camera.combinedViewMatrix() * _modelTransform; - glm::mat4 modelViewProjectionTransform = - data.camera.projectionMatrix() * glm::mat4(modelViewTransform); - - // Upload uniforms that are specific to global rendering to the shader program - _programObject->setUniform( - "modelViewProjectionTransform", modelViewProjectionTransform); - _programObject->setUniform("vertexIDPadding", 0); -} - -void RenderableTrailNew::preRenderSubPathLocally( - const RenderData& data, int totalNumVerticesToDraw) { - glm::dvec3 v0; // Vertex that connects to the global part of the trail - glm::dvec3 v1; // last vertex of the trail is in the position of the body - - v0 = _vertexPositionArray[totalNumVerticesToDraw - 2]; - v1 = _clampedBodyPosition; - - // Define positions relative to body (v1) which gives the high precision - glm::vec3 vertexData[2] = {glm::vec3(v0 - v1), glm::vec3(0)}; - - // Translation translates from the position of body so vertices should - // be defined relative to body (hence the added v1 in translation part of model matrix) - glm::dmat4 localTranslation = glm::translate(glm::dmat4(1.0), v1); - glm::dmat4 modelTransformLocal = _modelTransform * localTranslation; - glm::dmat4 modelViewTransform = data.camera.combinedViewMatrix() * modelTransformLocal; - glm::mat4 modelViewProjectionTransform = - data.camera.projectionMatrix() * glm::mat4(modelViewTransform); - - // Upload the new MVP matrix to the shader program - _programObject->setUniform( - "modelViewProjectionTransform", modelViewProjectionTransform); - _programObject->setUniform("vertexIDPadding", totalNumVerticesToDraw - 2); - - // Update the attribute data on the GPU - glBindBuffer(GL_ARRAY_BUFFER, _vBufferLocalID); - glBufferData( - GL_ARRAY_BUFFER, - 2 * sizeof(glm::vec3), // Only two vertices for this part of the trail - vertexData, // Two vertices - GL_DYNAMIC_DRAW); // This part of the path is rendered dynamically - - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); -} - -void RenderableTrailNew::renderLines(GLuint vao, int numberOfVertices) { - glLineWidth(_lineWidth); - - _programObject->setUniform("color", _lineColor.value()); - - glBindVertexArray(vao); - glDrawArrays(GL_LINE_STRIP, 0, static_cast(numberOfVertices)); - glBindVertexArray(0); - - glLineWidth(1.f); -} - -void RenderableTrailNew::renderPoints(GLuint vao, int numberOfVertices) { - glEnable(GL_PROGRAM_POINT_SIZE); - - _programObject->setUniform("color", _pointColor.value()); - _programObject->setUniform("pointSize", static_cast(_lineWidth * 3)); - - glBindVertexArray(vao); - glDrawArrays(GL_POINTS, 0, static_cast(numberOfVertices)); - glBindVertexArray(0); - - glDisable(GL_PROGRAM_POINT_SIZE); -} - -void RenderableTrailNew::update(const UpdateData& data) { - _currentTimeClamped = glm::clamp(data.time, _timeRange.start, _timeRange.end); - _modelTransform = - glm::translate(glm::dmat4(1.0), data.modelTransform.translation) * - glm::dmat4(data.modelTransform.rotation) * - glm::dmat4(glm::scale(glm::dmat4(1.0), glm::dvec3(data.modelTransform.scale))); - - // Fetch the body position using SPICE - double lightTime = 0.0; - try { - _clampedBodyPosition = SpiceManager::ref().targetPosition( - _body, _observer, _frame, {}, _currentTimeClamped, lightTime); - } - catch (const SpiceManager::SpiceException& e) { - try { - _clampedBodyPosition = SpiceManager::ref().targetPosition( - _body, _observer, _frame, {}, _currentTimeClamped, _timeRange.end); - } - catch (const SpiceManager::SpiceException& e) { - return; - } - } - // Convert from km used by SPICE to meters used by OpenSpace - _clampedBodyPosition *= 1000; -} - -} // namespace openspace diff --git a/modules/base/rendering/renderabletrailorbit.cpp b/modules/base/rendering/renderabletrailorbit.cpp new file mode 100644 index 0000000000..ca154b3607 --- /dev/null +++ b/modules/base/rendering/renderabletrailorbit.cpp @@ -0,0 +1,455 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include + +#include +#include + +#include + +// This class is using a VBO ring buffer + a constantly updated point as follows: +// Structure of the array with a _resolution of 16. FF denotes the floating position that +// is updated every frame: +// --------------------------------------------------------------------------------- +// | FF | | | | | | | | | | | | | | | | +// --------------------------------------------------------------------------------- +// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 +// <------ newer in time oldest +// +// In the begining the floating value starts at 0; this means that array element 0 is +// updated and uploaded to the GPU at every frame. The FF+1 element is the newest fixed +// location and FF-1 element is the oldest fixed location (including wrapping around the +// array) with the times of _lastPointTime and _firstPointTime. +// +// If the time progresses forwards and abs(time - _lastPointTime) becomes big enough, the +// oldest point is removed and a new fixed location is added. In the ring buffer this +// would be represented as: +// --------------------------------------------------------------------------------- +// | | | | | | | | | | | | | | | | FF | +// --------------------------------------------------------------------------------- +// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 +// <------ newer in time oldest +// +// Thus making the floating point traverse backwards through the array and element 0 being +// the newest fixed point. If the time processes backwards, the floating point moves +// towards the upper areas of the array instead. +// In both cases, only the values that have been changed will be uploaded to the GPU. +// +// For the rendering, this is achieved by using an index buffer that is twice the size of +// the vertex buffer containing identical two sequences indexing the vertex array. +// In an example of size 8: +// --------------------------------------------------------------------------------------- +// |0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15| 0| 1| 2| 3| 4| 5| 6| 7| 8| 9|10|11|12|13|14|15| +// --------------------------------------------------------------------------------------- +// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 +// +// The rendering step needs to know only the offset into the array (denoted by FF as the +// floating position above) and use the index array from the position. Since the indices +// in this array wrap around, so will the rendering of the vertices. Example: +// FF := 10 +// Rendering 16 elements will 'generate' the index buffer: +// 10 11 12 13 14 15 00 01 02 03 04 05 06 07 08 09 +// +// +// NB: This method was implemented without a ring buffer before by manually shifting the +// items in memory as was shown to be much slower than the current system. ---abock + +namespace { + const char* KeyPeriod = "Period"; + const char* KeyResolution = "Resolution"; +} + +namespace openspace { + +openspace::Documentation RenderableTrailOrbit::Documentation() { + using namespace documentation; + openspace::Documentation doc{ + "RenderableTrailOrbit", + "base_renderable_renderabletrailorbit", + { + { + "Type", + new StringEqualVerifier("RenderableTrailOrbit"), + "", + Optional::No + }, + { + KeyPeriod, + new DoubleVerifier, + "The objects period, i.e. the length of its orbit around the parent " + "object given in (Earth) days. In the case of Earth, this would be a " + "sidereal year (=365.242 days). If this values is specified as multiples " + "of the period, it is possible to show the effects of precession.", + Optional::No + }, + { + KeyResolution, + new IntVerifier, + "The number of samples along the orbit. This determines the resolution " + "of the trail; the tradeoff being that a higher resolution is able to " + "resolve more detail, but will take more resources while rendering, too. " + "The higher, the smoother the trail, but also more memory will be used.", + Optional::No + } + } + }; + + // Insert the parents documentation entries until we have a verifier that can deal + // with class hierarchy + openspace::Documentation parentDoc = RenderableTrail::Documentation(); + doc.entries.insert( + doc.entries.end(), + parentDoc.entries.begin(), + parentDoc.entries.end() + ); + + return doc; +} + +RenderableTrailOrbit::RenderableTrailOrbit(const ghoul::Dictionary& dictionary) + : RenderableTrail(dictionary) + , _period("period", "Period in days", 0.0, 0.0, 1e9) + , _resolution("resoluion", "Number of Samples along Orbit", 10000, 1, 1e6) + , _needsFullSweep(true) + , _indexBufferDirty(true) +{ + documentation::testSpecificationAndThrow( + Documentation(), + dictionary, + "RenderableTrailOrbit" + ); + + // Period is in days + using namespace std::chrono; + int factor = duration_cast(hours(24)).count(); + _period = dictionary.value(KeyPeriod) * factor; + _period.onChange([&] { _needsFullSweep = true; _indexBufferDirty = true; }); + addProperty(_period); + + _resolution = static_cast(dictionary.value(KeyResolution)); + _resolution.onChange([&] { _needsFullSweep = true; _indexBufferDirty = true; }); + addProperty(_resolution); + + // We store the vertices with (excluding the wrapping) decending temporal order + _primaryRenderInformation.sorting = RenderInformation::VertexSorting::NewestFirst; +} + +bool RenderableTrailOrbit::initialize() { + bool res = RenderableTrail::initialize(); + + glGenVertexArrays(1, &_primaryRenderInformation._vaoID); + glGenBuffers(1, &_primaryRenderInformation._vBufferID); + glGenBuffers(1, &_primaryRenderInformation._iBufferID); + + return res; +} + +bool RenderableTrailOrbit::deinitialize() { + glDeleteVertexArrays(1, &_primaryRenderInformation._vaoID); + glDeleteBuffers(1, &_primaryRenderInformation._vBufferID); + glDeleteBuffers(1, &_primaryRenderInformation._iBufferID); + + return RenderableTrail::deinitialize(); +} + +void RenderableTrailOrbit::update(const UpdateData& data) { + // Overview: + // 1. Update trails + // 2. Update floating position + // 3. Determine which parts of the array to upload and upload the data + + // Early bailout when we don't move in time + if (data.timePaused || data.delta == 0.0) { + return; + } + + + // 1 + // Update the trails; the report contains whether any of the other values has been + // touched and if so, how many + UpdateReport report = updateTrails(data); + + // 2 + // Write the current location into the floating position + glm::vec3 p = _translation->position(data.time); + _vertexArray[_primaryRenderInformation.first] = { p.x, p.y, p.z }; + + glBindVertexArray(_primaryRenderInformation._vaoID); + glBindBuffer(GL_ARRAY_BUFFER, _primaryRenderInformation._vBufferID); + + // 3 + if (!report.needsUpdate) { + // If no other values have been touched, we only need to upload the floating value + glBufferSubData( + GL_ARRAY_BUFFER, + _primaryRenderInformation.first * sizeof(TrailVBOLayout), + sizeof(TrailVBOLayout), + _vertexArray.data() + _primaryRenderInformation.first + ); + } + else { + // Otherwise we need to check how many values have been changed + if (report.nUpdated == UpdateReport::All) { + // If all of the values have been invalidated, we need to upload the entire + // array + glBufferData( + GL_ARRAY_BUFFER, + _vertexArray.size() * sizeof(TrailVBOLayout), + _vertexArray.data(), + GL_STREAM_DRAW + ); + + if (_indexBufferDirty) { + // We only need to upload the index buffer if it has been invalidated + // by changing the number of values we want to represent + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _primaryRenderInformation._iBufferID); + glBufferData( + GL_ELEMENT_ARRAY_BUFFER, + _indexArray.size() * sizeof(unsigned int), + _indexArray.data(), + GL_STATIC_DRAW + ); + _indexBufferDirty = false; + } + } + else { + // The lambda expression that will upload parts of the array starting at + // begin and containing length number of elements + auto upload = [this](int begin, int length) { + glBufferSubData( + GL_ARRAY_BUFFER, + begin * sizeof(TrailVBOLayout), + sizeof(TrailVBOLayout) * length, + _vertexArray.data() + begin + ); + }; + + // Only update the changed ones + // Since we are using a ring buffer, the number of updated needed might be + // bigger than our current points, which means we have to split the upload + // into two calls. + if (report.nUpdated > 0) { + // deltaT is positive, so the pointer is moving backwards and update has + // to happen towards the front + + // Starting index + int i = _primaryRenderInformation.first; + // Number of values + int n = report.nUpdated + 1; // +1 for the floating position + // Total size of the array + int s = _primaryRenderInformation.count; + + if (i + n <= s) { + // The current index is small enough to just use one upload call + upload(i, n); + } + else { + // The current index is too close to the wrap around part, so we need + // to split the upload into two parts: + // 1. from the current index to the end of the array + // 2. the rest starting from the beginning of the array + int first = s - i; + int second = n - first; + upload(i, first); // 1 + upload(0, second); // 2 + } + } + else { + // deltaT is negative, so the pointer is moving forwards + + // The current index + int i = _primaryRenderInformation.first; + // Number of values + int n = report.nUpdated + 1; // +1 for the floating position + // Total size of the array + int s = _primaryRenderInformation.count; + + if (i + 1 >= n) { + // The current index is big enough to fit everything into one call + upload(i+1 - n, n); + } + else { + // The current index is too close to the beginning of the array, so we + // need to split the upload into two parts: + // 1. from the beginning of the array to the current index + // 2. filling the back of the array with the rest + int b = n - (i + 1); + upload(0, i + 1); // 1 + upload(s-b, b); // 2 + } + } + } + } + + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); + + glBindVertexArray(0); +} + +RenderableTrailOrbit::UpdateReport RenderableTrailOrbit::updateTrails( + const UpdateData& data) +{ + // If we are doing a time jump, it is in general faster to recalculate everything + // than to only update parts of the array + if (data.isTimeJump) { + _needsFullSweep = true; + } + if (_needsFullSweep) { + fullSweep(data.time); + return { true, UpdateReport::All } ; + } + + // When time stands still (at the iron hill), we don't need to perform any work + if (data.delta == 0.0) { + return { false, 0 }; + } + + double secondsPerPoint = _period / (_resolution - 1); + // How much time has passed since the last permanent point + double delta = data.time - _lastPointTime; + + // We'd like to test for equality with 0 here, but due to rounding issues, we won't + // get there. If this check is not here, we will trigger the positive or negative + // branch below even though we don't have to + // + // This might become a bigger issue if we are starting to look at very short time + // intervals + const double Epsilon = 1e-7; + if (abs(delta) < Epsilon) { + return { false, 0 }; + } + + if (delta > 0.0) { + // Check whether we need to drop a new permanent point. This is only the case if + // enough (> secondsPerPoint) time has passed since the last permanent point + if (abs(delta) < secondsPerPoint) { + return { false, 0 }; + } + + // See how many points we need to drop + int nNewPoints = floor(delta / secondsPerPoint); + + // If we would need to generate more new points than there are total points in the + // array, it is faster to regenerate the entire array + if (nNewPoints >= _resolution) { + fullSweep(data.time); + return { true, UpdateReport::All }; + } + + for (int i = 0; i < nNewPoints; ++i) { + _lastPointTime += secondsPerPoint; + + // Get the new permanent point and write it into the (previously) floating + // location + glm::vec3 p = _translation->position(_lastPointTime); + _vertexArray[_primaryRenderInformation.first] = { p.x, p.y, p.z }; + + // Move the current pointer back one step to be used as the new floating + // location + --_primaryRenderInformation.first; + // And loop around if necessary + if (_primaryRenderInformation.first < 0) { + _primaryRenderInformation.first += _primaryRenderInformation.count; + } + } + + // The previously oldest permanent point has been moved nNewPoints steps into the + // future + _firstPointTime += nNewPoints * secondsPerPoint; + + return { true, nNewPoints }; + } + else { + // See how many new points needs to be generated. Delta is negative, so we need + // to invert the ratio + int nNewPoints = -(floor(delta / secondsPerPoint)); + + // If we would need to generate more new points than there are total points in the + // array, it is faster to regenerate the entire array + if (nNewPoints >= _resolution) { + fullSweep(data.time); + return { true, UpdateReport::All }; + } + + for (int i = 0; i < nNewPoints; ++i) { + _firstPointTime -= secondsPerPoint; + + // Get the new permanent point and write it into the (previously) floating + // location + glm::vec3 p = _translation->position(_firstPointTime); + _vertexArray[_primaryRenderInformation.first] = { p.x, p.y, p.z }; + + // if we are on the upper bounds of the array, we start at 0 + if (_primaryRenderInformation.first == _primaryRenderInformation.count - 1) { + // If it is at the beginning, set it to the end first + _primaryRenderInformation.first = 0; + } + else { + // Move the current pointer fowards one step to be used as the new floating + ++_primaryRenderInformation.first; + } + } + + // The previously youngest point has become nNewPoints steps older + _lastPointTime -= nNewPoints * secondsPerPoint; + + return { true, -nNewPoints }; + } +} + +void RenderableTrailOrbit::fullSweep(double time) { + // Reserve the space for the vertices + _vertexArray.clear(); + _vertexArray.resize(_resolution); + + // The index buffer stays constant until we change the size of the array + if (_indexBufferDirty) { + // Create the index buffer and fill it with two ranges for [0, _resolution) + _indexArray.clear(); + _indexArray.resize(_resolution * 2); + std::iota(_indexArray.begin(), _indexArray.begin() + _resolution, 0); + std::iota(_indexArray.begin() + _resolution, _indexArray.end(), 0); + } + + _lastPointTime = time; + + double secondsPerPoint = _period / (_resolution - 1); + // starting at 1 because the first position is a floating current one + for (int i = 1; i < _resolution; ++i) { + glm::vec3 p = _translation->position(time); + _vertexArray[i] = { p.x, p.y, p.z }; + + time -= secondsPerPoint; + } + + _primaryRenderInformation.first = 0; + _primaryRenderInformation.count = _resolution; + + _firstPointTime = time + secondsPerPoint; + _needsFullSweep = false; +} + +} // namespace openspace diff --git a/modules/base/rendering/renderabletrailorbit.h b/modules/base/rendering/renderabletrailorbit.h new file mode 100644 index 0000000000..68ec1ca7f1 --- /dev/null +++ b/modules/base/rendering/renderabletrailorbit.h @@ -0,0 +1,104 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * 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 __RENDERABLETRAILORBIT_H__ +#define __RENDERABLETRAILORBIT_H__ + +#include + +#include +#include + +namespace openspace { + +/** + * This concrete implementation of a RenderableTrail renders an updated trail behind an + * object that is likely to have an orbit-like path. However, this is not required and + * this class can render any kind of trail as long as it's individual positions can be + * dynamically queried at runtime. This class always renders a number of points equal to + * the _resolution number. If the time progresses, old points are discarded and new points + * are rendered. Each of these fixed points are fixed time steps apart, where as the most + * current point is floating and updated every frame. The _period determines the length of + * the trail (the distance between the newest and oldest point being _period days). + */ +class RenderableTrailOrbit : public RenderableTrail { +public: + explicit RenderableTrailOrbit(const ghoul::Dictionary& dictionary); + + bool initialize() override; + bool deinitialize() override; + + void update(const UpdateData& data) override; + + static openspace::Documentation Documentation(); + +private: + /** + * Performs a full sweep of the orbit and fills the entire vertex buffer object. + * \param time The current time up to which the full sweep should be performed + */ + void fullSweep(double time); + + /// This structure is returned from the #updateTrails method and gives information + /// about which parts of the vertex array to update + struct UpdateReport { + static const int All = 0; ///< The entire array was touched in the update + + /// If \c true at least one point was touched + bool needsUpdate; + /// Returns the number of fixed points that were touched in the update method + /// If this value is negative, the newest values were replaced, if positive the + /// oldest + int nUpdated; + }; + /** + * Updates the trail based on the new incoming UpdateData information. This function + * might update an arbitrary number of values in the vertex buffer and returns an + * UpdateReport that will tell the #update method how many values were modified. + * \param data The UpdateData struct that comes from the #update method + * \return The UpdateReport containing information which array parts were touched + */ + UpdateReport updateTrails(const UpdateData& data); + + /// The orbital period of the RenderableTrail in days + properties::DoubleProperty _period; + /// The number of points that should be sampled between _period and now + properties::IntProperty _resolution; + + /// A dirty flag that determines whether a full sweep (recomputing of all values) + /// is necessary + bool _needsFullSweep; + /// A dirty flag to determine whether the index buffer needs to be regenerated and + /// then reuploaded + bool _indexBufferDirty; + + /// The time stamp of the oldest point in the array + double _firstPointTime; + /// The time stamp of the newest fixed point in the array + double _lastPointTime; +}; + +} // namespace openspace + +#endif // __RENDERABLETRAILORBIT_H__ diff --git a/modules/base/rendering/renderabletrailtrajectory.cpp b/modules/base/rendering/renderabletrailtrajectory.cpp new file mode 100644 index 0000000000..9aa9d1606e --- /dev/null +++ b/modules/base/rendering/renderabletrailtrajectory.cpp @@ -0,0 +1,314 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include + +#include +#include +#include + +// This class creates the entire trajectory at once and keeps it in memory the entire +// time. This means that there is no need for updating the trail at runtime, but also that +// the whole trail has to fit in memory. +// Opposed to the RenderableTrailOrbit, no index buffer is needed as the vertex can be +// written into the vertex buffer object continuously and then selected by using the +// count variable from the RenderInformation struct to toggle rendering of the entire path +// or subpath. +// In addition, this RenderableTrail implementation uses an additional RenderInformation +// bucket that contains the line from the last shown point to the current location of the +// object iff not the entire path is shown and the object is between _startTime and +// _endTime. This buffer is updated every frame. + +namespace { + const char* KeyTranslation = "Translation"; + const char* KeyStartTime = "StartTime"; + const char* KeyEndTime = "EndTime"; + const char* KeySampleInterval = "SampleInterval"; + const char* KeyTimeStampSubsample = "TimeStampSubsampleFactor"; + const char* KeyShowFullTrail = "ShowFullTrail"; +} + +namespace openspace { + +openspace::Documentation RenderableTrailTrajectory::Documentation() { + using namespace documentation; + openspace::Documentation doc { + "RenderableTrailTrajectory", + "base_renderable_renderabletrailtrajectory", + { + { + "Type", + new StringEqualVerifier("RenderableTrailTrajectory"), + "", + Optional::No + }, + { + KeyStartTime, + new StringAnnotationVerifier("A valid date"), + "The start time for the range of this trajectory. The date must be in " + "ISO 8601 format: YYYY MM DD HH:mm:ss.xxx", + Optional::No + }, + { + KeyEndTime, + new StringAnnotationVerifier("A valid date"), + "The end time for the range of this trajectory. The date must be in " + "ISO 8601 format: YYYY MM DD HH:mm:ss.xxx", + Optional::No + }, + { + KeySampleInterval, + new DoubleVerifier, + "The interval between samples of the trajectory. This value (together " + "with 'TimeStampSubsampleFactor') determines how far apart (in time) the " + "samples are spaced along the trajectory. The time interval between " + "'StartTime' and 'EndTime' is split into 'SampleInterval' * " + "'TimeStampSubsampleFactor' segments.", + Optional::No + }, + { + KeyTimeStampSubsample, + new IntVerifier, + "The factor that is used to create subsamples along the trajectory. This " + "value (together with 'SampleInterval') determines how far apart (in " + "time) the samples are spaced along the trajectory. The time interval " + "between 'StartTime' and 'EndTime' is split into 'SampleInterval' * " + "'TimeStampSubsampleFactor' segments. The default value for this is 1", + Optional::Yes + }, + { + KeyShowFullTrail, + new BoolVerifier, + "If this value is set to 'true', the entire trail will be rendered; if " + "it is 'false', only the trail until the current time in the application " + "will be shown. The default value for this setting is 'false'.", + Optional::Yes + } + } + }; + + // Insert the parents documentation entries until we have a verifier that can deal + // with class hierarchy + openspace::Documentation parentDoc = RenderableTrail::Documentation(); + doc.entries.insert( + doc.entries.end(), + parentDoc.entries.begin(), + parentDoc.entries.end() + ); + + return doc; +} + +RenderableTrailTrajectory::RenderableTrailTrajectory(const ghoul::Dictionary& dictionary) + : RenderableTrail(dictionary) + , _startTime("startTime", "Start Time") + , _endTime("endTime", "End Time") + , _sampleInterval("sampleInterval", "Sample Interval", 2.0, 2.0, 1e6) + , _timeStampSubsamplingFactor( + "subSample", + "Time Stamp Subsampling Factor", + 1, 1, 1e9 + ) + , _renderFullTrail("renderFullTrail", "Render Full Trail", false) + , _needsFullSweep(true) + , _subsamplingIsDirty(true) +{ + documentation::testSpecificationAndThrow( + Documentation(), + dictionary, + "RenderableTrailTrajectory" + ); + + _startTime = dictionary.value(KeyStartTime); + _startTime.onChange([this] { _needsFullSweep = true; }); + addProperty(_startTime); + + _endTime = dictionary.value(KeyEndTime); + _endTime.onChange([this] { _needsFullSweep = true; }); + addProperty(_endTime); + + _sampleInterval = dictionary.value(KeySampleInterval); + _sampleInterval.onChange([this] { _needsFullSweep = true; }); + addProperty(_sampleInterval); + + if (dictionary.hasKeyAndValue(KeyTimeStampSubsample)) { + _timeStampSubsamplingFactor = dictionary.value(KeyTimeStampSubsample); + } + _timeStampSubsamplingFactor.onChange([this] { _subsamplingIsDirty = true; }); + addProperty(_timeStampSubsamplingFactor); + + if (dictionary.hasKeyAndValue(KeyShowFullTrail)) { + _renderFullTrail = dictionary.value(KeyShowFullTrail); + } + addProperty(_renderFullTrail); + + // We store the vertices with ascending temporal order + _primaryRenderInformation.sorting = RenderInformation::VertexSorting::OldestFirst; +} + +bool RenderableTrailTrajectory::initialize() { + bool res = RenderableTrail::initialize(); + + // We don't need an index buffer, so we keep it at the default value of 0 + glGenVertexArrays(1, &_primaryRenderInformation._vaoID); + glGenBuffers(1, &_primaryRenderInformation._vBufferID); + + // We do need an additional render information bucket for the additional line from the + // last shown permanent line to the current position of the object + glGenVertexArrays(1, &_floatingRenderInformation._vaoID); + glGenBuffers(1, &_floatingRenderInformation._vBufferID); + _floatingRenderInformation.sorting = RenderInformation::VertexSorting::NoSorting; + + return res; +} + +bool RenderableTrailTrajectory::deinitialize() { + glDeleteVertexArrays(1, &_primaryRenderInformation._vaoID); + glDeleteBuffers(1, &_primaryRenderInformation._vBufferID); + + glDeleteVertexArrays(1, &_floatingRenderInformation._vaoID); + glDeleteBuffers(1, &_floatingRenderInformation._vBufferID); + + return RenderableTrail::deinitialize(); +} + +void RenderableTrailTrajectory::update(const UpdateData& data) { + if (_needsFullSweep) { + // Convert the start and end time from string representations to J2000 seconds + _start = SpiceManager::ref().ephemerisTimeFromDate(_startTime); + _end = SpiceManager::ref().ephemerisTimeFromDate(_endTime); + + double totalSampleInterval = _sampleInterval / _timeStampSubsamplingFactor; + // How many values do we need to compute given the distance between the start and + // end date and the desired sample interval + int nValues = (_end - _start) / totalSampleInterval; + + // Make space for the vertices + _vertexArray.clear(); + _vertexArray.resize(nValues); + + // ... fill all of the values + for (int i = 0; i < nValues; ++i) { + glm::vec3 p = _translation->position(_start + i * totalSampleInterval); + _vertexArray[i] = { p.x, p.y, p.z }; + } + + // ... and upload them to the GPU + glBindVertexArray(_primaryRenderInformation._vaoID); + glBindBuffer(GL_ARRAY_BUFFER, _primaryRenderInformation._vBufferID); + glBufferData( + GL_ARRAY_BUFFER, + _vertexArray.size() * sizeof(TrailVBOLayout), + _vertexArray.data(), + GL_STATIC_DRAW + ); + + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); + + // We clear the indexArray just in case. The base class will take care not to use + // it if it is empty + _indexArray.clear(); + + _subsamplingIsDirty = true; + _needsFullSweep = false; + } + + // This has to be done every update step; + if (_renderFullTrail) { + // If the full trail should be rendered at all times, we can directly render the + // entire set + _primaryRenderInformation.first = 0; + _primaryRenderInformation.count = _vertexArray.size(); + } + else { + // If only trail so far should be rendered, we need to find the corresponding time + // in the array and only render it until then + _primaryRenderInformation.first = 0; + double t = (data.time - _start) / (_end - _start); + _primaryRenderInformation.count = std::min( + ceil(_vertexArray.size() * t), + _vertexArray.size() - 1 + ); + } + + // If we are inside the valid time, we additionally want to draw a line from the last + // correct point to the current location of the object + if (data.time >= _start && data.time <= _end && !_renderFullTrail) { + // Copy the last valid location + glm::dvec3 v0( + _vertexArray[_primaryRenderInformation.count - 1].x, + _vertexArray[_primaryRenderInformation.count - 1].y, + _vertexArray[_primaryRenderInformation.count - 1].z + ); + + // And get the current location of the object + glm::dvec3 p = _translation->position(data.time); + glm::dvec3 v1 = { p.x, p.y, p.z }; + + // Comptue the difference between the points in double precision + glm::dvec3 p0 = v0 - v1; + _auxiliaryVboData[0] = { + static_cast(p0.x), + static_cast(p0.y), + static_cast(p0.z) + }; + _auxiliaryVboData[1] = { 0.f, 0.f, 0.f }; + + // Fill the render info with the data + _floatingRenderInformation.first = 0; + _floatingRenderInformation.count = 2; + + _floatingRenderInformation._localTransform = glm::translate(glm::dmat4(1.0), v1); + + glBindVertexArray(_floatingRenderInformation._vaoID); + glBindBuffer(GL_ARRAY_BUFFER, _floatingRenderInformation._vBufferID); + glBufferData( + GL_ARRAY_BUFFER, + _auxiliaryVboData.size() * sizeof(TrailVBOLayout), + _auxiliaryVboData.data(), + GL_DYNAMIC_DRAW + ); + + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); + } + else { + // if we are outside of the valid range, we don't render anything + _floatingRenderInformation.first = 0; + _floatingRenderInformation.count = 0; + } + + if (_subsamplingIsDirty) { + // If the subsampling information has changed (either by a property change or by + // a request of a full sweep) we update it here + _primaryRenderInformation.stride = _timeStampSubsamplingFactor; + _floatingRenderInformation.stride = _timeStampSubsamplingFactor; + _subsamplingIsDirty = false; + } + + glBindVertexArray(0); +} + +} // namespace openspace diff --git a/modules/base/rendering/renderabletrailnew.h b/modules/base/rendering/renderabletrailtrajectory.h similarity index 50% rename from modules/base/rendering/renderabletrailnew.h rename to modules/base/rendering/renderabletrailtrajectory.h index fe469892d9..b913d40118 100644 --- a/modules/base/rendering/renderabletrailnew.h +++ b/modules/base/rendering/renderabletrailtrajectory.h @@ -22,95 +22,66 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#ifndef __RENDERABLETRAILNEW_H__ -#define __RENDERABLETRAILNEW_H__ +#ifndef __RENDERABLETRAILTRAJECTORY_H__ +#define __RENDERABLETRAILTRAJECTORY_H__ -#include +#include + +#include +#include #include -#include - -#include - -#include - -namespace ghoul { -namespace opengl { - class ProgramObject; - class Texture; -} -} namespace openspace { /** - * This class currently has a temporary name until it is merged with or replaces - * RenderableTrail. It renders the trail with higher precision close to the - * position of the body of a renderable. The lua mod dictionary describing the - * renderable trail is changed. -*/ -class RenderableTrailNew : public Renderable { + * This concrete implementation of a RenderableTrail renders a fixed trail, regardless of + * its shape. The trail is sampled equitemporal (with an interval of _sampleInterval in + * seconds) between the _startTime and the _endTime. No further update is needed until any + * of these three values is changed. If _renderFullTrail is true, the entirety of the + * trail is rendered, regardless of the simulation time. If it is false, the trail is only + * rendered from the past to the current simulation time, not showing any part of the + * trail in the future. If _renderFullTrail is false, the current position of the object + * has to be updated constantly to make the trail connect to the object that has the + * trail. + */ +class RenderableTrailTrajectory : public RenderableTrail { public: - explicit RenderableTrailNew(const ghoul::Dictionary& dictionary); + explicit RenderableTrailTrajectory(const ghoul::Dictionary& dictionary); bool initialize() override; bool deinitialize() override; - bool isReady() const override; - - void render(const RenderData& data) override; void update(const UpdateData& data) override; + + static openspace::Documentation Documentation(); private: - void sweepTimeRange(); + /// The start time of the trail + properties::StringProperty _startTime; + /// The end time of the trail + properties::StringProperty _endTime; + /// The interval (in seconds) between sample points + properties::DoubleProperty _sampleInterval; + /// The factor that determines the time stamp subsampling, using different sized + /// points along the trajectory + properties::IntProperty _timeStampSubsamplingFactor; + /// Determines whether the full trail should be rendered or the future trail removed + properties::BoolProperty _renderFullTrail; - void initializeGlobalOpenGLPathData(); - void initializeLocalOpenGLPathData(); + /// Dirty flag that determines whether the full vertex buffer needs to be resampled + bool _needsFullSweep; - void deInitializeGlobalOpenGLPathData(); - void deInitializeLocalOpenGLPathData(); + /// Dirty flag to determine whether the stride information needs to be changed + bool _subsamplingIsDirty; - void preRender(int totalNumVerticesToDraw); - void preRenderSubPathGlobally(const RenderData& renderData); - void preRenderSubPathLocally(const RenderData& renderData, int totalNumVerticesToDraw); + std::array _auxiliaryVboData; - void renderLines(GLuint vao, int numberOfVertices); - void renderPoints(GLuint vao, int numberOfVertices); - - // Spice - std::string _body; - std::string _observer; - std::string _frame; - - // Properties - properties::Vec3Property _lineColor; - properties::Vec3Property _pointColor; - properties::FloatProperty _lineFade; - properties::FloatProperty _lineWidth; - properties::FloatProperty _renderPart; - properties::BoolProperty _showTimeStamps; - properties::BoolProperty _renderFullTrail; - - // OpenGL - GLuint _vaoGlobalID; - GLuint _vBufferGlobalID; - - GLuint _vaoLocalID; - GLuint _vBufferLocalID; - - // Other - bool _successfullDictionaryFetch; - TimeRange _timeRange; - double _sampleDeltaTime; - int _subSamples; - std::unique_ptr _programObject; - std::vector _vertexPositionArray; - - // Data updated in update function - double _currentTimeClamped; // Time clamped to time range - glm::dmat4 _modelTransform; - glm::dvec3 _clampedBodyPosition; // Position of body clamped to time range + /// The conversion of the _startTime into the internal time format + double _start; + /// The conversion of the _endTime into the internal time format + double _end; }; } // namespace openspace -#endif // __RENDERABLETRAILNEW_H__ +#endif // __RENDERABLETRAILTRAJECTORY_H__ diff --git a/modules/base/shaders/ephemeris_fs.glsl b/modules/base/shaders/renderabletrail_fs.glsl similarity index 71% rename from modules/base/shaders/ephemeris_fs.glsl rename to modules/base/shaders/renderabletrail_fs.glsl index a77149b371..288aa5dc12 100644 --- a/modules/base/shaders/ephemeris_fs.glsl +++ b/modules/base/shaders/renderabletrail_fs.glsl @@ -22,21 +22,46 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -uniform float forceFade; -uniform vec3 color; +// Fragile! Keep in sync with RenderableTrail::render::RenderPhase +#define RenderPhaseLines 0 +#define RenderPhasePoints 1 + +#define Delta 0.25 in vec4 vs_positionScreenSpace; in float fade; -#include "PowerScaling/powerScaling_fs.hglsl" +uniform vec3 color; +uniform int renderPhase; + #include "fragment.glsl" Fragment getFragment() { - vec4 c = vec4(color * fade * forceFade, 1.0); Fragment frag; - frag.color = c; + frag.color = vec4(color * fade, fade); frag.depth = vs_positionScreenSpace.w; frag.blend = BLEND_MODE_ADDITIVE; + if (renderPhase == RenderPhasePoints) { + // Use the length of the vector (dot(circCoord, circCoord)) as factor in the + // smoothstep to gradually decrease the alpha on the edges of the point + vec2 circCoord = 2.0 * gl_PointCoord - 1.0; + frag.color.a *= 1.0 - smoothstep(1.0 - Delta, 1.0, dot(circCoord, circCoord)); + + + + // if (dot(circCoord, circCoord) > 1.0) { + + // } + // frag.color.a *= smoothstep(); + + // // Check for length > 1.0 without a square root + // frag.color.a *= smoothstep(dot(circCoord, circCoord), 1.0, 1.0 - 1.0 / pointSize); + // if (dot(circCoord, circCoord) > 1.0) { + // discard; + // } + } + + return frag; } diff --git a/modules/base/shaders/ephemeris_vs.glsl b/modules/base/shaders/renderabletrail_vs.glsl similarity index 66% rename from modules/base/shaders/ephemeris_vs.glsl rename to modules/base/shaders/renderabletrail_vs.glsl index 5339a6321a..2db1690fda 100644 --- a/modules/base/shaders/ephemeris_vs.glsl +++ b/modules/base/shaders/renderabletrail_vs.glsl @@ -24,28 +24,56 @@ #version __CONTEXT__ -uniform mat4 modelViewTransform; -uniform mat4 projectionTransform; -uniform vec4 objectVelocity; +// Fragile! Keep in sync with RenderableTrail::render +#define VERTEX_SORTING_NEWESTFIRST 0 +#define VERTEX_SORTING_OLDESTFIRST 1 +#define VERTEX_SORTING_NOSORTING 2 -uniform uint nVertices; -uniform float lineFade; - -layout(location = 0) in vec4 in_point_position; +layout(location = 0) in vec3 in_point_position; out vec4 vs_positionScreenSpace; out float fade; +uniform dmat4 modelViewTransform; +uniform mat4 projectionTransform; + +uniform int idOffset; +uniform int nVertices; +uniform bool useLineFade; +uniform float lineFade; +uniform int vertexSortingMethod; +uniform int pointSize; +uniform int stride; + #include "PowerScaling/powerScaling_vs.hglsl" void main() { - float id = float(gl_VertexID) / float(nVertices * lineFade); - fade = 1.0 - id; + int modId = gl_VertexID; - // Convert from psc to regular homogenous coordinates - vec4 position = vec4(in_point_position.xyz * pow(10, in_point_position.w), 1); - vec4 positionClipSpace = projectionTransform * modelViewTransform * position; - vs_positionScreenSpace = z_normalization(positionClipSpace); - + if ((vertexSortingMethod != VERTEX_SORTING_NOSORTING) && useLineFade) { + // Account for a potential rolling buffer + modId = gl_VertexID - idOffset; + if (modId < 0) { + modId += nVertices; + } + + // Convert the index to a [0,1] ranger + float id = float(modId) / float(nVertices); + + if (vertexSortingMethod == VERTEX_SORTING_NEWESTFIRST) { + id = 1.0 - id; + } + + fade = clamp(id * lineFade, 0.0, 1.0); + } + else { + fade = 1.0; + } + + vs_positionScreenSpace = z_normalization( + projectionTransform * vec4(modelViewTransform * dvec4(in_point_position, 1)) + ); + + gl_PointSize = (stride == 1 || int(modId) % stride == 0) ? float(pointSize) : float(pointSize) / 2; gl_Position = vs_positionScreenSpace; -} \ No newline at end of file +} diff --git a/modules/base/shaders/renderabletrailnew_fs.glsl b/modules/base/shaders/renderabletrailnew_fs.glsl deleted file mode 100644 index ea0f97a653..0000000000 --- a/modules/base/shaders/renderabletrailnew_fs.glsl +++ /dev/null @@ -1,46 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2016 * - * * - * 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. * - ****************************************************************************************/ - -// Inputs -in vec4 vs_positionScreenSpace; -in float vs_alpha; - -// Uniforms -uniform float forceFade; -uniform vec3 color; - -#include "PowerScaling/powerScaling_fs.hglsl" -#include "fragment.glsl" - -Fragment getFragment() { - if (vs_alpha < 0.01) - discard; - vec4 c = vec4(color, vs_alpha); - - Fragment frag; - frag.color = c; - frag.depth = vs_positionScreenSpace.w; - - return frag; -} \ No newline at end of file diff --git a/modules/base/shaders/renderabletrailnew_vs.glsl b/modules/base/shaders/renderabletrailnew_vs.glsl deleted file mode 100644 index c4bff29a34..0000000000 --- a/modules/base/shaders/renderabletrailnew_vs.glsl +++ /dev/null @@ -1,58 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2016 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#version __CONTEXT__ - -// Attributes -layout(location = 0) in vec3 in_position; - -// Uniforms -uniform mat4 modelViewProjectionTransform; - -uniform int numVertices; -uniform int maxNumVertices; -uniform int subSamples; -uniform float lineFade; -uniform int vertexIDPadding; -uniform float pointSize; - -// Outputs -out vec4 vs_positionScreenSpace; -out float vs_alpha; - -#include "PowerScaling/powerScaling_vs.hglsl" - -void main() { - int vertexID = gl_VertexID + vertexIDPadding; - int threshHold = int(lineFade * numVertices); - int nVisibleVertices = min((int(numVertices) - threshHold), maxNumVertices); - vs_alpha = clamp((vertexID - (int(numVertices) - nVisibleVertices)) - / float(nVisibleVertices), 0, 1); - - vec4 positionClipSpace = modelViewProjectionTransform * vec4(in_position, 1); - vs_positionScreenSpace = z_normalization(positionClipSpace); - - gl_PointSize = (subSamples == 0 || vertexID % subSamples == 0) ? pointSize : pointSize / 2; - gl_Position = vs_positionScreenSpace; -} \ No newline at end of file diff --git a/modules/base/translation/spicetranslation.cpp b/modules/base/translation/spicetranslation.cpp index 2fd3942c2a..9f3ce6b2c9 100644 --- a/modules/base/translation/spicetranslation.cpp +++ b/modules/base/translation/spicetranslation.cpp @@ -32,11 +32,12 @@ #include namespace { - const std::string KeyBody = "Body"; - const std::string KeyObserver = "Observer"; - const std::string KeyKernels = "Kernels"; + const char* KeyBody = "Body"; + const char* KeyObserver = "Observer"; + const char* KeyFrame = "Frame"; + const char* KeyKernels = "Kernels"; - const std::string ReferenceFrame = "GALACTIC"; + const char* DefaultReferenceFrame = "GALACTIC"; } namespace openspace { @@ -44,7 +45,7 @@ namespace openspace { Documentation SpiceTranslation::Documentation() { using namespace openspace::documentation; - return { + return{ "Spice Translation", "base_translation_spicetranslation", { @@ -71,12 +72,19 @@ Documentation SpiceTranslation::Documentation() { "integer id code (such as '0').", Optional::No }, + { + KeyFrame, + new StringAnnotationVerifier( + "A valid SPICE NAIF name for a reference frame" + ), + "This is the SPICE NAIF name for the reference frame in which the " + "position should be retrieved. The default value is GALACTIC", + Optional::Yes + }, { KeyKernels, new OrVerifier( - new TableVerifier({ - { "*", new StringVerifier } - }), + new StringListVerifier, new StringVerifier ), "A single kernel or list of kernels that this SpiceTranslation depends " @@ -92,6 +100,7 @@ Documentation SpiceTranslation::Documentation() { SpiceTranslation::SpiceTranslation(const ghoul::Dictionary& dictionary) : _target("target", "Target", "") , _origin("origin", "Origin", "") + , _frame("frame", "Reference Frame", DefaultReferenceFrame) , _kernelsLoadedSuccessfully(true) { documentation::testSpecificationAndThrow( @@ -103,6 +112,10 @@ SpiceTranslation::SpiceTranslation(const ghoul::Dictionary& dictionary) _target = dictionary.value(KeyBody); _origin = dictionary.value(KeyObserver); + if (dictionary.hasKey(KeyFrame)) { + _frame = dictionary.value(KeyFrame); + } + auto loadKernel = [](const std::string& kernel) { if (!FileSys.fileExists(kernel)) { throw SpiceManager::SpiceException("Kernel '" + kernel + "' does not exist"); @@ -142,7 +155,7 @@ glm::dvec3 SpiceTranslation::position() const { void SpiceTranslation::update(const UpdateData& data) { double lightTime = 0.0; _position = SpiceManager::ref().targetPosition( - _target, _origin, ReferenceFrame, {}, data.time, lightTime + _target, _origin, _frame, {}, data.time, lightTime ) * glm::pow(10.0, 3.0); } diff --git a/modules/base/translation/spicetranslation.h b/modules/base/translation/spicetranslation.h index 38a19c35fa..74bb507fb0 100644 --- a/modules/base/translation/spicetranslation.h +++ b/modules/base/translation/spicetranslation.h @@ -43,6 +43,7 @@ public: private: properties::StringProperty _target; properties::StringProperty _origin; + properties::StringProperty _frame; glm::dvec3 _position; bool _kernelsLoadedSuccessfully; diff --git a/modules/onscreengui/include/renderproperties.h b/modules/onscreengui/include/renderproperties.h index 29433f3bba..0470190e00 100644 --- a/modules/onscreengui/include/renderproperties.h +++ b/modules/onscreengui/include/renderproperties.h @@ -38,6 +38,7 @@ void renderBoolProperty(properties::Property* prop, const std::string& ownerName void renderOptionProperty(properties::Property* prop, const std::string& ownerName); void renderSelectionProperty(properties::Property* prop, const std::string& ownerName); void renderStringProperty(properties::Property* prop, const std::string& ownerName); +void renderDoubleProperty(properties::Property* prop, const std::string& ownerName); void renderIntProperty(properties::Property* prop, const std::string& ownerName); void renderIVec2Property(properties::Property* prop, const std::string& ownerName); void renderIVec3Property(properties::Property* prop, const std::string& ownerName); diff --git a/modules/onscreengui/src/guipropertycomponent.cpp b/modules/onscreengui/src/guipropertycomponent.cpp index bbd9431fd4..85c0de774f 100644 --- a/modules/onscreengui/src/guipropertycomponent.cpp +++ b/modules/onscreengui/src/guipropertycomponent.cpp @@ -150,6 +150,7 @@ void GuiPropertyComponent::renderProperty(properties::Property* prop, properties using Func = std::function; static std::map FunctionMapping = { { "BoolProperty", &renderBoolProperty }, + { "DoubleProperty", &renderDoubleProperty}, { "IntProperty", &renderIntProperty }, { "IVec2Property", &renderIVec2Property }, { "IVec3Property", &renderIVec3Property }, diff --git a/modules/onscreengui/src/renderproperties.cpp b/modules/onscreengui/src/renderproperties.cpp index 9644ad3df9..37fad524de 100644 --- a/modules/onscreengui/src/renderproperties.cpp +++ b/modules/onscreengui/src/renderproperties.cpp @@ -147,13 +147,36 @@ void renderStringProperty(Property* prop, const std::string& ownerName) { #else strcpy(buffer, p->value().c_str()); #endif - ImGui::InputText(name.c_str(), buffer, bufferSize); + bool hasNewValue = ImGui::InputText( + name.c_str(), + buffer, + bufferSize, + ImGuiInputTextFlags_EnterReturnsTrue + ); renderTooltip(prop); - std::string newValue(buffer); - if (newValue != p->value()) { - executeScript(p->fullyQualifiedIdentifier(), "'" + newValue + "'"); + if (hasNewValue) { + executeScript(p->fullyQualifiedIdentifier(), "'" + std::string(buffer) + "'"); + } + + ImGui::PopID(); +} + +void renderDoubleProperty(properties::Property* prop, const std::string& ownerName) { + DoubleProperty* p = static_cast(prop); + std::string name = p->guiName(); + ImGui::PushID((ownerName + "." + name).c_str()); + + float value = *p; + float min = p->minValue(); + float max = p->maxValue(); + + ImGui::SliderFloat(name.c_str(), &value, min, max); + renderTooltip(prop); + + if (value != static_cast(p->value())) { + executeScript(p->fullyQualifiedIdentifier(), std::to_string(value)); } ImGui::PopID(); @@ -317,9 +340,10 @@ void renderVec3Property(Property* prop, const std::string& ownerName) { float min = std::min(std::min(p->minValue().x, p->minValue().y), p->minValue().z); float max = std::max(std::max(p->maxValue().x, p->maxValue().y), p->maxValue().z); + ImGui::SliderFloat3( name.c_str(), - &value.x, + glm::value_ptr(value), min, max ); diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 02208ee491..4a96a5a2f3 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -895,13 +895,13 @@ void OpenSpaceEngine::postSynchronizationPreDraw() { _shutdownCountdown -= _windowWrapper->averageDeltaTime(); } + _renderEngine->updateSceneGraph(); _renderEngine->updateFade(); _renderEngine->updateRenderer(); _renderEngine->updateScreenSpaceRenderables(); _renderEngine->updateShaderPrograms(); if (!_isMaster) { - _renderEngine->updateSceneGraph(); _renderEngine->camera()->invalidateCache(); } diff --git a/src/properties/optionproperty.cpp b/src/properties/optionproperty.cpp index f3a6112f9c..c1629544d9 100644 --- a/src/properties/optionproperty.cpp +++ b/src/properties/optionproperty.cpp @@ -57,9 +57,7 @@ const std::vector& OptionProperty::options() const { } void OptionProperty::addOption(int value, std::string desc) { - Option option; - option.value = value; - option.description = desc; + Option option = { std::move(value), std::move(desc) }; for (const auto& o : _options) { if (o.value == option.value) { @@ -72,20 +70,9 @@ void OptionProperty::addOption(int value, std::string desc) { _options.push_back(std::move(option)); } -void OptionProperty::addOptions(std::vector values, std::vector descs) { - if (values.size() != descs.size()) { - LERROR("Skipping " << this->fullyQualifiedIdentifier() << ": " - << "number of values (" << values.size() << ") " - << "does not equal number of descriptions (" << descs.size() << ")" - ); - return; - } - for (int i = 0; i < values.size(); i++) { - LDEBUG(this->fullyQualifiedIdentifier() << ": Adding " - << descs[i] - << " (" << values[i] << ")" - ); - this->addOption(values[i], descs[i]); +void OptionProperty::addOptions(std::vector> options) { + for (std::pair& p : options) { + addOption(std::move(p.first), std::move(p.second)); } } diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 32a9c46757..4118890321 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -369,6 +369,7 @@ void RenderEngine::updateSceneGraph() { 1, Time::ref().j2000Seconds(), Time::ref().deltaTime(), + Time::ref().paused(), Time::ref().timeJumped(), _performanceManager != nullptr }); diff --git a/src/scene/translation.cpp b/src/scene/translation.cpp index ad0cbcafef..8fe9513bce 100644 --- a/src/scene/translation.cpp +++ b/src/scene/translation.cpp @@ -85,4 +85,17 @@ bool Translation::initialize() { void Translation::update(const UpdateData& data) {} +glm::dvec3 Translation::position(double time) { + update({ + {}, + time, + 1.0, + false, + false + }); + + return position(); +} + + } // namespace openspace diff --git a/src/util/time.cpp b/src/util/time.cpp index 102faf22d1..5f4f142323 100644 --- a/src/util/time.cpp +++ b/src/util/time.cpp @@ -81,7 +81,6 @@ Time Time::now() { return now; } - bool Time::isInitialized() { return (_instance != nullptr); }