Solve conflict

This commit is contained in:
kalbl
2016-11-23 13:34:38 +01:00
130 changed files with 2737 additions and 4309 deletions

View File

@@ -31,8 +31,9 @@
#include <ghoul/ghoul.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/filesystem/file.h>
#include <ghoul/misc/dictionary.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/lua/ghoul_lua.h>
#include <ghoul/misc/dictionary.h>
#include <QApplication>
#include <QCheckBox>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -139,16 +139,17 @@ return {
-- Trail 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
}
}
}

View File

@@ -78,14 +78,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
}
}
}

View File

@@ -61,14 +61,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
},
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -57,7 +57,7 @@ return {
"jupiter/jupiter",
"saturn/saturn",
"uranus",
"neptune",
-- "neptune",
"stars",
"milkyway",
"missions/rosetta",

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -5,9 +5,9 @@ return {
Parent = "Root",
Renderable = {
Type = "RenderableStars",
File = "${OPENSPACE_DATA}/scene/stars/speck/stars.speck",
Texture = "${OPENSPACE_DATA}/scene/stars/textures/halo.png",
ColorMap = "${OPENSPACE_DATA}/scene/stars/colorbv.cmap"
File = "speck/stars.speck",
Texture = "textures/halo.png",
ColorMap = "colorbv.cmap"
},
}
}

View File

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

View File

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

View File

@@ -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<int> of values for the options
* \param descs A std::vector<string> 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 <option, description> that are added to the OptionProperty
*/
void addOptions(std::vector<int> values, std::vector<std::string> descs);
void addOptions(std::vector<std::pair<int, std::string>> options);
/**
* Returns the list of available options.

View File

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

View File

@@ -46,6 +46,7 @@ struct UpdateData {
TransformData modelTransform;
double time;
double delta;
bool timePaused;
bool isTimeJump;
bool doPerformanceMeasurement;
};

View File

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

View File

@@ -30,16 +30,16 @@
#include <ghoul/misc/assert.h>
#include <modules/base/rendering/renderablemodel.h>
#include <modules/base/rendering/renderableconstellationbounds.h>
#include <modules/base/rendering/renderablestars.h>
#include <modules/base/rendering/renderabletrail.h>
#include <modules/base/rendering/renderabletrailnew.h>
#include <modules/base/rendering/renderablemodel.h>
#include <modules/base/rendering/renderablepath.h>
#include <modules/base/rendering/renderableplanet.h>
#include <modules/base/rendering/renderablerings.h>
#include <modules/base/rendering/renderablesphere.h>
#include <modules/base/rendering/renderablesphericalgrid.h>
#include <modules/base/rendering/renderableplanet.h>
#include <modules/base/rendering/renderablestars.h>
#include <modules/base/rendering/renderabletrailorbit.h>
#include <modules/base/rendering/renderabletrailtrajectory.h>
#include <modules/base/rendering/simplespheregeometry.h>
#include <modules/base/rendering/renderableplane.h>
#include <modules/base/rendering/simplespheregeometry.h>
@@ -105,8 +105,8 @@ void BaseModule::internalInitialize() {
fRenderable->registerClass<RenderableSphere>("RenderableSphere");
fRenderable->registerClass<RenderableSphericalGrid>("RenderableSphericalGrid");
fRenderable->registerClass<RenderableStars>("RenderableStars");
fRenderable->registerClass<RenderableTrail>("RenderableTrail");
fRenderable->registerClass<RenderableTrailNew>("RenderableTrailNew");
fRenderable->registerClass<RenderableTrailOrbit>("RenderableTrailOrbit");
fRenderable->registerClass<RenderableTrailTrajectory>("RenderableTrailTrajectory");
auto fTranslation = FactoryManager::ref().factory<Translation>();
ghoul_assert(fTranslation, "Ephemeris factory was not created");
@@ -141,6 +141,8 @@ std::vector<Documentation> BaseModule::documentations() const {
StaticTranslation::Documentation(),
SpiceTranslation::Documentation(),
RenderableRings::Documentation(),
RenderableTrailOrbit::Documentation(),
RenderableTrailTrajectory::Documentation(),
modelgeometry::ModelGeometry::Documentation(),
planetgeometry::PlanetGeometry::Documentation()
};

View File

@@ -22,12 +22,9 @@
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
// temporary includes (will fix as soon as I figure out how class hierarchy should work,
// ie after I see model on screen)
// open space includes
#include <openspace/rendering/renderengine.h>
#include <modules/base/rendering/renderablemodel.h>
#include <openspace/rendering/renderengine.h>
#include <modules/base/rendering/modelgeometry.h>
#include <openspace/engine/configurationmanager.h>
@@ -37,7 +34,6 @@
#include <openspace/scene/scenegraphnode.h>
#include <openspace/util/time.h>
#include <openspace/util/spicemanager.h>
#include <openspace/engine/openspaceengine.h>
@@ -177,18 +173,6 @@ void RenderableModel::render(const RenderData& data) {
double lt;
// Fade away if it does not have spice coverage
double time = openspace::Time::ref().j2000Seconds();
bool targetPositionCoverage = openspace::SpiceManager::ref().hasSpkCoverage(_target, time);
if (!targetPositionCoverage) {
int frame = _frameCount % 180;
float fadingFactor = static_cast<float>(sin((frame * M_PI) / 180));
_alpha = 0.5f + fadingFactor * 0.5f;
}
else
_alpha = 1.0f;
// Fading
if (_performFade && _fading > 0.f) {
_fading = _fading - 0.01f;
@@ -261,7 +245,7 @@ void RenderableModel::update(const UpdateData& data) {
//}
double lt;
_sunPos = openspace::SpiceManager::ref().targetPosition("SUN", "SUN", "GALACTIC", {}, _time, lt);
_sunPos = OsEng.renderEngine().scene()->sceneGraphNode("Sun")->worldPosition();
}
void RenderableModel::loadTexture() {

View File

@@ -24,6 +24,7 @@
#include <modules/base/rendering/renderablestars.h>
#include <openspace/documentation/verifier.h>
#include <openspace/util/updatestructures.h>
#include <openspace/engine/openspaceengine.h>
#include <openspace/rendering/renderengine.h>
@@ -31,6 +32,8 @@
#include <ghoul/filesystem/filesystem>
#include <ghoul/misc/templatefactory.h>
#include <ghoul/io/texture/texturereader.h>
#include <ghoul/opengl/programobject.h>
#include <ghoul/opengl/texture.h>
#include <ghoul/opengl/textureunit.h>
#include <array>
@@ -44,9 +47,6 @@ namespace {
const std::string KeyTexture = "Texture";
const std::string KeyColorMap = "ColorMap";
ghoul::filesystem::File* _psfTextureFile;
ghoul::filesystem::File* _colorTextureFile;
const int8_t CurrentCacheVersion = 1;
struct ColorVBOLayout {
@@ -82,6 +82,46 @@ namespace {
namespace openspace {
openspace::Documentation RenderableStars::Documentation() {
using namespace documentation;
return {
"RenderableStars",
"base_renderablestars",
{
{
"Type",
new StringEqualVerifier("RenderableStars"),
"",
Optional::No
},
{
KeyFile,
new StringVerifier,
"The path to the SPECK file that contains information about the stars "
"being rendered.",
Optional::No
},
{
KeyTexture,
new StringVerifier,
"The path to the texture that should be used as a point spread function "
"for the stars. The path is relative to the location of the .mod file "
"and can contain file system token.",
Optional::No
},
{
KeyColorMap,
new StringVerifier,
"The path to the texture that is used to convert from the B-V value of "
"the star to its color. The texture is used as a one dimensional lookup "
"function.",
Optional::No
}
}
};
}
RenderableStars::RenderableStars(const ghoul::Dictionary& dictionary)
: Renderable(dictionary)
, _pointSpreadFunctionTexturePath("psfTexture", "Point Spread Function Texture")
@@ -101,47 +141,54 @@ RenderableStars::RenderableStars(const ghoul::Dictionary& dictionary)
, _vao(0)
, _vbo(0)
{
using ghoul::filesystem::File;
using File = ghoul::filesystem::File;
std::string texturePath = "";
dictionary.getValue(KeyTexture, texturePath);
_pointSpreadFunctionTexturePath = absPath(texturePath);
_psfTextureFile = new File(_pointSpreadFunctionTexturePath);
documentation::testSpecificationAndThrow(
Documentation(),
dictionary,
"RenderableStars"
);
dictionary.getValue(KeyColorMap, texturePath);
_colorTexturePath = absPath(texturePath);
_colorTextureFile = new File(_colorTexturePath);
_pointSpreadFunctionTexturePath = absPath(dictionary.value<std::string>(KeyTexture));
_pointSpreadFunctionFile = std::make_unique<File>(_pointSpreadFunctionTexturePath);
bool success = dictionary.getValue(KeyFile, _speckFile);
if (!success) {
LERROR("SpeckDataSource did not contain key '" << KeyFile << "'");
return;
}
_speckFile = absPath(_speckFile);
_colorTexturePath = absPath(dictionary.value<std::string>(KeyColorMap));
_colorTextureFile = std::make_unique<File>(_colorTexturePath);
_speckFile = absPath(dictionary.value<std::string>(KeyFile));
//_colorOption.addOptions({
// { ColorOption::Color, "Color" },
// { ColorOption::Velocity, "Velocity" },
// { ColorOption::Speed, "Speed" }
//});
_colorOption.addOption(ColorOption::Color, "Color");
_colorOption.addOption(ColorOption::Velocity, "Velocity");
_colorOption.addOption(ColorOption::Speed, "Speed");
addProperty(_colorOption);
_colorOption.onChange([&]{ _dataIsDirty = true;});
addProperty(_pointSpreadFunctionTexturePath);
_pointSpreadFunctionTexturePath.onChange([&]{ _pointSpreadFunctionTextureIsDirty = true; });
_psfTextureFile->setCallback([&](const File&) { _pointSpreadFunctionTextureIsDirty = true; });
_pointSpreadFunctionTexturePath.onChange(
[&]{ _pointSpreadFunctionTextureIsDirty = true; }
);
_pointSpreadFunctionFile->setCallback(
[&](const File&) { _pointSpreadFunctionTextureIsDirty = true; }
);
addProperty(_colorTexturePath);
_colorTexturePath.onChange([&]{ _colorTextureIsDirty = true; });
_colorTextureFile->setCallback([&](const File&) { _colorTextureIsDirty = true; });
_colorTextureFile->setCallback(
[&](const File&) { _colorTextureIsDirty = true; }
);
addProperty(_alphaValue);
addProperty(_scaleFactor);
addProperty(_minBillboardSize);
}
RenderableStars::~RenderableStars() {
delete _psfTextureFile;
delete _colorTextureFile;
}
RenderableStars::~RenderableStars() {}
bool RenderableStars::isReady() const {
return (_program != nullptr) && (!_fullData.empty());
@@ -156,8 +203,9 @@ bool RenderableStars::initialize() {
"${MODULE_BASE}/shaders/star_fs.glsl",
"${MODULE_BASE}/shaders/star_ge.glsl");
if (!_program)
if (!_program) {
return false;
}
completeSuccess &= loadData();
completeSuccess &= (_pointSpreadFunctionTexture != nullptr);
@@ -212,14 +260,12 @@ void RenderableStars::render(const RenderData& data) {
ghoul::opengl::TextureUnit psfUnit;
psfUnit.activate();
if (_pointSpreadFunctionTexture)
_pointSpreadFunctionTexture->bind();
_pointSpreadFunctionTexture->bind();
_program->setUniform("psfTexture", psfUnit);
ghoul::opengl::TextureUnit colorUnit;
colorUnit.activate();
if (_colorTexture)
_colorTexture->bind();
_colorTexture->bind();
_program->setUniform("colorTexture", colorUnit);
glBindVertexArray(_vao);
@@ -253,10 +299,12 @@ void RenderableStars::update(const UpdateData& data) {
}
glBindVertexArray(_vao);
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
glBufferData(GL_ARRAY_BUFFER,
size*sizeof(GLfloat),
glBufferData(
GL_ARRAY_BUFFER,
size * sizeof(GLfloat),
&_slicedData[0],
GL_STATIC_DRAW);
GL_STATIC_DRAW
);
GLint positionAttrib = _program->attributeLocation("in_position");
GLint brightnessDataAttrib = _program->attributeLocation("in_brightness");
@@ -316,17 +364,27 @@ void RenderableStars::update(const UpdateData& data) {
LDEBUG("Reloading Point Spread Function texture");
_pointSpreadFunctionTexture = nullptr;
if (_pointSpreadFunctionTexturePath.value() != "") {
_pointSpreadFunctionTexture = std::move(ghoul::io::TextureReader::ref().loadTexture(absPath(_pointSpreadFunctionTexturePath)));
_pointSpreadFunctionTexture = std::move(
ghoul::io::TextureReader::ref().loadTexture(
absPath(_pointSpreadFunctionTexturePath)
)
);
if (_pointSpreadFunctionTexture) {
LDEBUG("Loaded texture from '" << absPath(_pointSpreadFunctionTexturePath) << "'");
LDEBUG("Loaded texture from '" <<
absPath(_pointSpreadFunctionTexturePath) << "'");
_pointSpreadFunctionTexture->uploadTexture();
}
_pointSpreadFunctionTexture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap);
delete _psfTextureFile;
_psfTextureFile = new ghoul::filesystem::File(_pointSpreadFunctionTexturePath);
_psfTextureFile->setCallback([&](const ghoul::filesystem::File&) { _pointSpreadFunctionTextureIsDirty = true; });
_pointSpreadFunctionFile = std::make_unique<ghoul::filesystem::File>(
_pointSpreadFunctionTexturePath
);
_pointSpreadFunctionFile->setCallback(
[&](const ghoul::filesystem::File&) {
_pointSpreadFunctionTextureIsDirty = true;
}
);
}
_pointSpreadFunctionTextureIsDirty = false;
}
@@ -341,9 +399,12 @@ void RenderableStars::update(const UpdateData& data) {
_colorTexture->uploadTexture();
}
delete _colorTextureFile;
_colorTextureFile = new ghoul::filesystem::File(_colorTexturePath);
_colorTextureFile->setCallback([&](const ghoul::filesystem::File&) { _colorTextureIsDirty = true; });
_colorTextureFile = std::make_unique<ghoul::filesystem::File>(
_colorTexturePath
);
_colorTextureFile->setCallback(
[&](const ghoul::filesystem::File&) { _colorTextureIsDirty = true; }
);
}
_colorTextureIsDirty = false;
}
@@ -361,12 +422,14 @@ bool RenderableStars::loadData() {
LINFO("Cached file '" << cachedFile << "' used for Speck file '" << _file << "'");
bool success = loadCachedFile(cachedFile);
if (success)
if (success) {
return true;
else
}
else {
FileSys.cacheManager()->removeCacheFile(_file);
// Intentional fall-through to the 'else' computation to generate the cache
// file for the next run
}
}
else {
LINFO("Cache for Speck file '" << _file << "' not found");
@@ -374,8 +437,9 @@ bool RenderableStars::loadData() {
LINFO("Loading Speck file '" << _file << "'");
bool success = readSpeckFile();
if (!success)
if (!success) {
return false;
}
LINFO("Saving cache");
success = saveCachedFile(cachedFile);
@@ -401,8 +465,9 @@ bool RenderableStars::readSpeckFile() {
std::ifstream::streampos position = file.tellg();
std::getline(file, line);
if (line[0] == '#' || line.empty())
if (line[0] == '#' || line.empty()) {
continue;
}
if (line.substr(0, 7) != "datavar" &&
line.substr(0, 10) != "texturevar" &&
@@ -437,8 +502,9 @@ bool RenderableStars::readSpeckFile() {
std::getline(file, line);
std::stringstream str(line);
for (int i = 0; i < _nValuesPerStar; ++i)
for (int i = 0; i < _nValuesPerStar; ++i) {
str >> values[i];
}
_fullData.insert(_fullData.end(), values.begin(), values.end());
} while (!file.eof());

View File

@@ -26,15 +26,25 @@
#define __RENDERABLESTARS_H__
#include <openspace/rendering/renderable.h>
#include <openspace/documentation/documentation.h>
#include <openspace/properties/stringproperty.h>
#include <openspace/properties/optionproperty.h>
#include <openspace/properties/vectorproperty.h>
#include <ghoul/opengl/programobject.h>
#include <ghoul/opengl/texture.h>
namespace ghoul {
namespace filesystem {
class File;
}
}
namespace openspace {
namespace opengl {
class ProgramObject;
class Texture;
}
class RenderableStars : public Renderable {
public:
explicit RenderableStars(const ghoul::Dictionary& dictionary);
@@ -48,6 +58,8 @@ public:
void render(const RenderData& data) override;
void update(const UpdateData& data) override;
static openspace::Documentation Documentation();
private:
enum ColorOption {
Color = 0,
@@ -64,10 +76,12 @@ private:
properties::StringProperty _pointSpreadFunctionTexturePath;
std::unique_ptr<ghoul::opengl::Texture> _pointSpreadFunctionTexture;
std::unique_ptr<ghoul::filesystem::File> _pointSpreadFunctionFile;
bool _pointSpreadFunctionTextureIsDirty;
properties::StringProperty _colorTexturePath;
std::unique_ptr<ghoul::opengl::Texture> _colorTexture;
std::unique_ptr<ghoul::filesystem::File> _colorTextureFile;
bool _colorTextureIsDirty;
properties::OptionProperty _colorOption;

View File

@@ -23,199 +23,351 @@
****************************************************************************************/
#include <modules/base/rendering/renderabletrail.h>
#include <openspace/util/time.h>
#include <openspace/util/spicemanager.h>
#include <openspace/util/updatestructures.h>
#include <ghoul/opengl/programobject.h>
#include <openspace/documentation/verifier.h>
#include <openspace/engine/openspaceengine.h>
#include <openspace/rendering/renderengine.h>
#include <openspace/interaction/interactionhandler.h>
#include <limits>
#include <stdint.h>
/* 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 <openspace/scene/translation.h>
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<std::string, RenderingMode> 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<double>::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>(Translation::createFromDictionary(
dictionary.value<ghoul::Dictionary>(KeyTranslation)
));
glm::vec3 color(0.f);
if (dictionary.hasKeyAndValue<glm::vec3>(keyColor))
dictionary.getValue(keyColor, color);
_lineColor = color;
bool timeStamps = false;
if (dictionary.hasKeyAndValue<bool>(keyStamps))
dictionary.getValue(keyStamps, timeStamps);
_showTimestamps = timeStamps;
addProperty(_showTimestamps);
_lineColor.setViewOption(properties::Property::ViewOptions::Color);
_lineColor = dictionary.value<glm::vec3>(KeyColor);
addProperty(_lineColor);
if (dictionary.hasKeyAndValue<bool>(KeyEnableFade)) {
_useLineFade = dictionary.value<bool>(KeyEnableFade);
}
addProperty(_useLineFade);
if (dictionary.hasKeyAndValue<double>(KeyFade)) {
_lineFade = dictionary.value<double>(KeyFade);
}
addProperty(_lineFade);
if (dictionary.hasKeyAndValue<double>(KeyLineWidth)) {
_lineWidth = dictionary.value<double>(KeyLineWidth);
}
addProperty(_lineWidth);
_distanceFade = 1.0;
if (dictionary.hasKeyAndValue<double>(KeyPointSize)) {
_pointSize = dictionary.value<double>(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<std::string>(KeyRendering)) {
_renderingModes = RenderingModeConversion.at(
dictionary.value<std::string>(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<unsigned int>(_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<RenderInformation::VertexSorting, int> 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<GLsizei>(_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<GLsizei>(_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<void*>(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<void*>(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<int>(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<TrailVBOLayout> 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<int>(_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

View File

@@ -26,6 +26,10 @@
#define __RENDERABLETRAIL_H__
#include <openspace/rendering/renderable.h>
#include <openspace/documentation/documentation.h>
#include <openspace/properties/optionproperty.h>
#include <openspace/properties/scalarproperty.h>
#include <openspace/properties/stringproperty.h>
#include <openspace/properties/vectorproperty.h>
@@ -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<ghoul::opengl::ProgramObject> _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<TrailVBOLayout> _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<unsigned int> _indexArray;
/// The Translation object that provides the position of the individual trail points
std::unique_ptr<Translation> _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<ghoul::opengl::ProgramObject> _programObject;
};
} // namespace openspace

View File

@@ -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 <modules/base/rendering/renderabletrailnew.h>
#include <openspace/util/time.h>
#include <openspace/util/spicemanager.h>
#include <openspace/util/updatestructures.h>
#include <openspace/util/timerange.h>
#include <openspace/engine/openspaceengine.h>
#include <openspace/rendering/renderengine.h>
#include <openspace/interaction/interactionhandler.h>
#include <ghoul/opengl/programobject.h>
#include <limits>
#include <stdint.h>
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<int>(_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<int>(_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<int>(_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<GLsizei>(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<float>(_lineWidth * 3));
glBindVertexArray(vao);
glDrawArrays(GL_POINTS, 0, static_cast<GLsizei>(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

View File

@@ -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 <modules/base/rendering/renderabletrailorbit.h>
#include <openspace/documentation/verifier.h>
#include <openspace/scene/translation.h>
#include <numeric>
// 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<seconds>(hours(24)).count();
_period = dictionary.value<double>(KeyPeriod) * factor;
_period.onChange([&] { _needsFullSweep = true; _indexBufferDirty = true; });
addProperty(_period);
_resolution = static_cast<int>(dictionary.value<double>(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

View File

@@ -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 <modules/base/rendering/renderabletrail.h>
#include <openspace/documentation/documentation.h>
#include <openspace/properties/scalarproperty.h>
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__

View File

@@ -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 <modules/base/rendering/renderabletrailtrajectory.h>
#include <openspace/documentation/verifier.h>
#include <openspace/scene/translation.h>
#include <openspace/util/spicemanager.h>
// 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<std::string>(KeyStartTime);
_startTime.onChange([this] { _needsFullSweep = true; });
addProperty(_startTime);
_endTime = dictionary.value<std::string>(KeyEndTime);
_endTime.onChange([this] { _needsFullSweep = true; });
addProperty(_endTime);
_sampleInterval = dictionary.value<double>(KeySampleInterval);
_sampleInterval.onChange([this] { _needsFullSweep = true; });
addProperty(_sampleInterval);
if (dictionary.hasKeyAndValue<double>(KeyTimeStampSubsample)) {
_timeStampSubsamplingFactor = dictionary.value<double>(KeyTimeStampSubsample);
}
_timeStampSubsamplingFactor.onChange([this] { _subsamplingIsDirty = true; });
addProperty(_timeStampSubsamplingFactor);
if (dictionary.hasKeyAndValue<bool>(KeyShowFullTrail)) {
_renderFullTrail = dictionary.value<bool>(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<GLsizei>(
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<float>(p0.x),
static_cast<float>(p0.y),
static_cast<float>(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

View File

@@ -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 <openspace/rendering/renderable.h>
#include <modules/base/rendering/renderabletrail.h>
#include <openspace/documentation/documentation.h>
#include <openspace/properties/scalarproperty.h>
#include <openspace/properties/stringproperty.h>
#include <openspace/properties/vectorproperty.h>
#include <openspace/util/timerange.h>
#include <ghoul/opengl/ghoul_gl.h>
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<TrailVBOLayout, 2> _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<ghoul::opengl::ProgramObject> _programObject;
std::vector<glm::vec3> _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__

View File

@@ -1,85 +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. *
****************************************************************************************/
// Atmosphere Rendering Parameters
uniform float Rg;
uniform float Rt;
uniform float AVERAGE_GROUND_REFLECTANCE;
uniform float HR;
uniform vec3 betaR;
uniform float HM;
uniform vec3 betaMSca;
uniform vec3 betaMEx;
uniform float mieG;
const float ATM_EPSILON = 1.0;
// const float RL = Rt + 1.0;
// const float Rg = 6360.0;
// const float Rt = 6420.0;
// const float RL = 6421.0;
// const float ATM_EPSILON = 1.0;
// const float AVERAGE_GROUND_REFLECTANCE = 0.1;
// // Rayleigh
// const float HR = 8.0;
// const vec3 betaR = vec3(5.8e-3, 1.35e-2, 3.31e-2);
// // Mie
// // DEFAULT
// const float HM = 1.2;
// const vec3 betaMSca = vec3(4e-3);
// //const vec3 betaMSca = vec3(2e-5);
// const vec3 betaMEx = betaMSca / 0.9;
// const float mieG = 1.0;
// Integration steps
const int TRANSMITTANCE_STEPS = 500;
const int INSCATTER_INTEGRAL_SAMPLES = 50;
const int IRRADIANCE_INTEGRAL_SAMPLES = 32;
const int INSCATTER_SPHERICAL_INTEGRAL_SAMPLES = 16;
// The next values crash NVIDIA driver for Quadro K620 -- JCC
// const int TRANSMITTANCE_INTEGRAL_SAMPLES = 1000;
// const int INSCATTER_INTEGRAL_SAMPLES = 100;
// const int IRRADIANCE_INTEGRAL_SAMPLES = 64;
// const int INSCATTER_SPHERICAL_INTEGRAL_SAMPLES = 32;
const float M_PI = 3.141592657;
const int TRANSMITTANCE_W = 256;
const int TRANSMITTANCE_H = 64;
const int SKY_W = 64;
const int SKY_H = 16;
const int OTHER_TEXTURES_W = 64;
const int OTHER_TEXTURES_H = 16;
const int RES_R = 32;
const int RES_MU = 128;
const int RES_MU_S = 32;
const int RES_NU = 8;

View File

@@ -1,501 +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. *
****************************************************************************************/
#define EPSILON 0.0001f
// Sun Irradiance
const float ISun = 50.0;
const uint numberOfShadows = 1;
struct ShadowRenderingStruct {
float xu, xp;
float rs, rc;
vec3 sourceCasterVec;
vec3 casterPositionVec;
bool isShadowing;
};
uniform ShadowRenderingStruct shadowDataArray[numberOfShadows];
uniform mat4 completeInverse;
uniform mat4 projInverse;
uniform vec4 campos;
uniform vec4 objpos;
uniform vec3 sun_pos;
uniform vec4 cameraPosObj;
uniform vec4 planetPositionObj;
uniform vec3 sunPositionObj;
uniform bool _performShading = true;
uniform float transparency;
uniform int shadows;
uniform float screenX;
uniform float screenY;
uniform float screenWIDTH;
uniform float screenHEIGHT;
uniform float time;
uniform sampler2D texture1;
uniform sampler2D nightTex;
uniform sampler2D cloudsTexture;
uniform sampler2D reflectanceTexture;
uniform sampler2D transmittanceTexture;
uniform sampler2D irradianceTexture;
uniform sampler3D inscatterTexture;
in vec2 vs_st;
in vec2 vs_nightTex;
in vec4 vs_normal;
in vec4 vs_position;
in vec4 vs_posWorld;
#include "hdr.glsl"
#include "PowerScaling/powerScaling_fs.hglsl"
#include "fragment.glsl"
#include "atmosphere_common.glsl"
vec4 butterworthFunc(const float d, const float r, const float n) {
return vec4(vec3(sqrt(r/(r + pow(d, 2*n)))), 1.0);
}
/*******************************************************************************
****** ALL CALCULATIONS FOR ATMOSPHERE ARE KM AND IN OBJECT SPACE SYSTEM ******
*******************************************************************************/
/* Calculates the intersection of the view ray direction with the atmosphere and
* returns the first intersection (0.0 when inside atmosphere): offset
* and the second intersection: maxLength
*/
struct Ray {
vec4 origin;
vec4 direction;
};
struct Ellipsoid {
vec4 center;
vec4 size;
};
bool intersectEllipsoid(const Ray ray, const Ellipsoid ellipsoid, out float offset, out float maxLength) {
vec4 O_C = ray.origin-ellipsoid.center;
vec4 dir = normalize(ray.direction);
offset = 0.0f;
maxLength = 0.0f;
float a =
((dir.x*dir.x)/(ellipsoid.size.x*ellipsoid.size.x))
+ ((dir.y*dir.y)/(ellipsoid.size.y*ellipsoid.size.y))
+ ((dir.z*dir.z)/(ellipsoid.size.z*ellipsoid.size.z));
float b =
((2.f*O_C.x*dir.x)/(ellipsoid.size.x*ellipsoid.size.x))
+ ((2.f*O_C.y*dir.y)/(ellipsoid.size.y*ellipsoid.size.y))
+ ((2.f*O_C.z*dir.z)/(ellipsoid.size.z*ellipsoid.size.z));
float c =
((O_C.x*O_C.x)/(ellipsoid.size.x*ellipsoid.size.x))
+ ((O_C.y*O_C.y)/(ellipsoid.size.y*ellipsoid.size.y))
+ ((O_C.z*O_C.z)/(ellipsoid.size.z*ellipsoid.size.z))
- 1.f;
float d = ((b*b)-(4.f*a*c));
if ( d<0.f || a==0.f || b==0.f || c==0.f )
return false;
d = sqrt(d);
float t1 = (-b+d)/(2.f*a);
float t2 = (-b-d)/(2.f*a);
if( t1<=EPSILON && t2<=EPSILON )
return false; // both intersections are behind the ray origin
bool back = (t1<=EPSILON || t2<=EPSILON); // If only one intersection (t>0) then we are inside the ellipsoid and the intersection is at the back of the ellipsoid
float t=0.f;
if( t1<=EPSILON )
t = t2;
else
if( t2<=EPSILON )
t = t1;
else
t=(t1<t2) ? t1 : t2;
if( t<EPSILON ) return false; // Too close to intersection
vec4 intersection = ray.origin + t*dir;
vec4 normal = intersection-ellipsoid.center;
normal.x = 2.f*normal.x/(ellipsoid.size.x*ellipsoid.size.x);
normal.y = 2.f*normal.y/(ellipsoid.size.y*ellipsoid.size.y);
normal.z = 2.f*normal.z/(ellipsoid.size.z*ellipsoid.size.z);
normal.w = 0.f;
normal *= (back) ? -1.f : 1.f;
normal = normalize(normal);
return true;
}
bool intersectAtmosphere(const vec4 planetPos, const vec3 rayDirection, const float sphereRadius,
out float offset, out float maxLength) {
offset = 0.0f;
maxLength = 0.0f;
vec3 l = planetPos.xyz - cameraPosObj.xyz;
float s = dot(l, rayDirection);
float l2 = dot(l, l);
// sphereRadius in Km
float r = sphereRadius - EPSILON; // EPSILON to avoid surface acne
float r2 = r * r;
if (l2 <= r2) {
// ray origin inside sphere
float m2 = l2 - (s*s);
float q = sqrt(r2 - m2);
maxLength = s + q;
return true;
}
else if (s >= 0.0) {
// ray outside sphere
float m2 = l2 - (s*s);
if (m2 <= r2) {
// ray hits atmosphere
float q = sqrt(r2 - m2);
offset = s-q;
maxLength = (s+q)-offset;
return true;
}
}
return false;
}
// Rayleigh phase function
float phaseFunctionR(float mu) {
return (3.0 / (16.0 * M_PI)) * (1.0 + mu * mu);
}
// Mie phase function
float phaseFunctionM(float mu) {
return 1.5 * 1.0 / (4.0 * M_PI) * (1.0 - mieG*mieG) * pow(1.0 + (mieG*mieG) - 2.0*mieG*mu, -3.0/2.0) * (1.0 + mu * mu) / (2.0 + mieG*mieG);
}
float opticalDepth(float H, float r, float mu, float d) {
float a = sqrt((0.5/H)*r);
vec2 a01 = a*vec2(mu, mu + d / r);
vec2 a01s = sign(a01);
vec2 a01sq = a01*a01;
float x = a01s.y > a01s.x ? exp(a01sq.x) : 0.0;
vec2 y = a01s / (2.3193*abs(a01) + sqrt(1.52*a01sq + 4.0)) * vec2(1.0, exp(-d/H*(d/(2.0*r)+mu)));
return sqrt((6.2831*H)*r) * exp((Rg-r)/H) * (x + dot(y, vec2(1.0, -1.0)));
}
vec4 texture4D(sampler3D table, float r, float mu, float muS, float nu)
{
float H = sqrt(Rt * Rt - Rg * Rg);
float rho = sqrt(r * r - Rg * Rg);
float rmu = r * mu;
float delta = rmu * rmu - r * r + Rg * Rg;
vec4 cst = rmu < 0.0 && delta > 0.0 ? vec4(1.0, 0.0, 0.0, 0.5 - 0.5 / float(RES_MU)) : vec4(-1.0, H * H, H, 0.5 + 0.5 / float(RES_MU));
float uR = 0.5 / float(RES_R) + rho / H * (1.0 - 1.0 / float(RES_R));
float uMu = cst.w + (rmu * cst.x + sqrt(delta + cst.y)) / (rho + cst.z) * (0.5 - 1.0 / float(RES_MU));
float uMuS = 0.5 / float(RES_MU_S) + (atan(max(muS, -0.1975) * tan(1.26 * 1.1)) / 1.1 + (1.0 - 0.26)) * 0.5 * (1.0 - 1.0 / float(RES_MU_S));
float lerp = (nu + 1.0) / 2.0 * (float(RES_NU) - 1.0);
float uNu = floor(lerp);
lerp = lerp - uNu;
return texture(table, vec3((uNu + uMuS) / float(RES_NU), uMu, uR)) * (1.0 - lerp) +
texture(table, vec3((uNu + uMuS + 1.0) / float(RES_NU), uMu, uR)) * lerp;
}
vec3 analyticTransmittance(float r, float mu, float d) {
return exp(- betaR * opticalDepth(HR, r, mu, d) - betaMEx * opticalDepth(HM, r, mu, d));
}
vec3 getMie(vec4 rayMie) {
return rayMie.rgb * rayMie.a / max(rayMie.r, 1e-4) * (betaR.r / betaR);
}
vec2 getTransmittanceUV(float r, float mu) {
float uR, uMu;
uR = sqrt((r - Rg) / (Rt - Rg));
uMu = atan((mu + 0.15) / (1.0 + 0.15) * tan(1.5)) / 1.5;
return vec2(uMu, uR);
}
vec3 transmittanceFromTexture(float r, float mu) {
vec2 uv = getTransmittanceUV(r, mu);
return texture(transmittanceTexture, uv).rgb;
}
vec3 transmittanceWithShadow(float r, float mu) {
return mu < -sqrt(1.0 - (Rg / r) * (Rg / r)) ? vec3(0.0) : transmittanceFromTexture(r, mu);
}
vec3 transmittance(float r, float mu, vec3 v, vec3 x0) {
vec3 result;
float r1 = length(x0);
float mu1 = dot(x0, v) / r;
if (mu > 0.0) {
result = min(transmittanceFromTexture(r, mu) /
transmittanceFromTexture(r1, mu1), 1.0);
} else {
result = min(transmittanceFromTexture(r1, -mu1) /
transmittanceFromTexture(r, -mu), 1.0);
}
return result;
}
vec2 getIrradianceUV(float r, float muS) {
float uR = (r - Rg) / (Rt - Rg);
float uMuS = (muS + 0.2) / (1.0 + 0.2);
return vec2(uMuS, uR);
}
vec3 irradiance(sampler2D sampler, float r, float muS) {
vec2 uv = getIrradianceUV(r, muS);
return texture(sampler, uv).rgb;
}
/*
* Calculates the light scattering in the view direction comming from other
* light rays scattered in the atmosphere.
* The view direction here is the ray: x + tv, s is the sun direction,
* r and mu the position and zenith cossine angle as in the paper.
*/
vec3 inscatterLight(inout vec3 x, inout float t, vec3 v, vec3 s,
out float r, out float mu, out vec3 attenuation) {
vec3 result;
r = length(x);
mu = dot(x, v) / r;
float d = -r * mu - sqrt(r * r * (mu * mu - 1.0) + Rt * Rt);
if (d > 0.0) {
x += d * v;
t -= d;
mu = (r * mu + d) / Rt;
r = Rt;
}
// Intersects atmosphere?
if (r <= Rt) {
float nu = dot(v, s);
float muS = dot(x, s) / r;
float phaseR = phaseFunctionR(nu);
float phaseM = phaseFunctionM(nu);
vec4 inscatter = max(texture4D(inscatterTexture, r, mu, muS, nu), 0.0);
if (t > 0.0) {
vec3 x0 = x + t * v;
float r0 = length(x0);
float rMu0 = dot(x0, v);
float mu0 = rMu0 / r0;
float muS0 = dot(x0, s) / r0;
attenuation = analyticTransmittance(r, mu, t);
//attenuation = transmittance(r, mu, v, x+t*v);
//The following Code is generating surface acne on atmosphere. JCC
// We need a better acne avoindance constant (0.01). Done!! Adaptive from distance to x
if (r0 > Rg + 0.1*r) {
inscatter = max(inscatter - attenuation.rgbr * texture4D(inscatterTexture, r0, mu0, muS0, nu), 0.0);
const float EPS = 0.004;
float muHoriz = -sqrt(1.0 - (Rg / r) * (Rg / r));
if (abs(mu - muHoriz) < EPS) {
float a = ((mu - muHoriz) + EPS) / (2.0 * EPS);
mu = muHoriz - EPS;
r0 = sqrt(r * r + t * t + 2.0 * r * t * mu);
mu0 = (r * mu + t) / r0;
vec4 inScatter0 = texture4D(inscatterTexture, r, mu, muS, nu);
vec4 inScatter1 = texture4D(inscatterTexture, r0, mu0, muS0, nu);
vec4 inScatterA = max(inScatter0 - attenuation.rgbr * inScatter1, 0.0);
mu = muHoriz + EPS;
r0 = sqrt(r * r + t * t + 2.0 * r * t * mu);
mu0 = (r * mu + t) / r0;
inScatter0 = texture4D(inscatterTexture, r, mu, muS, nu);
inScatter1 = texture4D(inscatterTexture, r0, mu0, muS0, nu);
vec4 inScatterB = max(inScatter0 - attenuation.rgbr * inScatter1, 0.0);
inscatter = mix(inScatterA, inScatterB, a);
}
}
}
inscatter.w *= smoothstep(0.00, 0.02, muS);
result = max(inscatter.rgb * phaseR + getMie(inscatter) * phaseM, 0.0);
} else {
// No intersection with earth
result = vec3(0.0);
}
return result * ISun;
}
vec3 groundColor(vec3 x, float t, vec3 v, vec3 s, float r, float mu, vec3 attenuation)
{
vec3 result;
// Ray hits ground
if (t > 0.0) {
vec3 x0 = x + t * v;
float r0 = length(x0);
vec3 n = x0 / r0;
// Fixing texture coordinates:
vec4 reflectance = texture(reflectanceTexture, vs_st) * vec4(0.2, 0.2, 0.2, 1.0);
// The following code is generating surface acne in ground.
// It is only necessary inside atmosphere rendering. JCC
// if (r0 > Rg + 0.01) {
// reflectance = vec4(0.4, 0.4, 0.4, 0.0);
// }
float muS = dot(n, s);
vec3 sunLight = transmittanceWithShadow(r0, muS);
vec3 groundSkyLight = irradiance(irradianceTexture, r0, muS);
vec4 clouds = vec4(0.85)*texture(cloudsTexture, vs_st);
vec3 groundColor = (reflectance.rgb + clouds.rgb) *
(max(muS, 0.0) * sunLight + groundSkyLight) * ISun / M_PI;
// Yellowish reflection from sun on oceans and rivers
if (reflectance.w > 0.0) {
vec3 h = normalize(s - v);
float fresnel = 0.02 + 0.98 * pow(1.0 - dot(-v, h), 5.0);
float waterBrdf = fresnel * pow(max(dot(h, n), 0.0), 150.0);
groundColor += reflectance.w * max(waterBrdf, 0.0) * sunLight * ISun;
}
result = attenuation * groundColor;
} else {
// No hit
result = vec3(0.0);
}
return result;
}
vec3 sunColor(vec3 x, float t, vec3 v, vec3 s, float r, float mu) {
if (t > 0.0) {
return vec3(0.0);
} else {
vec3 transmittance = r <= Rt ? transmittanceWithShadow(r, mu) : vec3(1.0);
float isun = step(cos(M_PI / 180.0), dot(v, s)) * ISun;
return transmittance * isun;
}
}
/***********************************************************************
******* CALCULATIONS FOR SHADOWS ARE IN WORLD SPACE IN METERS *********
***********************************************************************/
// TODO: Change calculations for view space in KM.
vec4 calcShadow(const ShadowRenderingStruct shadowInfoArray[numberOfShadows], const vec3 position) {
if (shadowInfoArray[0].isShadowing) {
vec3 pc = shadowInfoArray[0].casterPositionVec - position;
vec3 sc_norm = normalize(shadowInfoArray[0].sourceCasterVec); // we can pass this normalized to the shader
vec3 pc_proj = dot(pc, sc_norm) * sc_norm;
vec3 d = pc - pc_proj;
float length_d = length(d);
float length_pc_proj = length(pc_proj);
float r_p_pi = shadowInfoArray[0].rc * (length_pc_proj + shadowInfoArray[0].xp) / shadowInfoArray[0].xp;
//float r_u_pi = shadowInfoArray[0].rc * (length_pc_proj + shadowInfoArray[0].xu) / shadowInfoArray[0].xu;
float r_u_pi = shadowInfoArray[0].rc * (shadowInfoArray[0].xu - length_pc_proj) / shadowInfoArray[0].xu;
if ( length_d < r_u_pi ) { // umbra
//return vec4(0.0, 0.0, 0.0, 1.0);
//return vec4(1.0, 0.0, 0.0, 1.0);
return butterworthFunc(length_d, r_u_pi, 4.0);
}
else if ( length_d < r_p_pi ) {// penumbra
//return vec4(0.5, 0.5, 0.5, 1.0);
//return vec4(0.0, 1.0, 0.0, 1.0);
return vec4(vec3(length_d/r_p_pi), 1.0);
}
}
return vec4(1.0);
}
Fragment getFragment() {
vec4 position = vs_position;
float depth = pscDepth(position);
vec4 diffuse = texture(texture1, vs_st);
vec4 diffuse2 = texture(nightTex, vs_st);
vec4 clouds = texture(cloudsTexture, vs_st);
Fragment frag;
if (_performShading) {
// atmosphere
vec4 viewport = vec4(screenX, screenY, screenWIDTH, screenHEIGHT);
vec4 ndcPos;
ndcPos.xy = ((2.0 * gl_FragCoord.xy) - (2.0 * viewport.xy)) / (viewport.zw) - 1;
ndcPos.z = (2.0 * gl_FragCoord.z - gl_DepthRange.near - gl_DepthRange.far) /
(gl_DepthRange.far - gl_DepthRange.near);
ndcPos.w = 1.0;
vec4 clipPos = ndcPos / gl_FragCoord.w;
vec4 projCoords = projInverse * clipPos;
vec4 viewDirection = normalize(completeInverse * vec4(projCoords.xyz, 0.0));
vec3 v = normalize(viewDirection.xyz);
float offset, maxLength;
vec4 ppos = vec4(0.0);
//if (intersectAtmosphere(planetPositionObj, v, Rt, offset, maxLength)) {
if (intersectAtmosphere(ppos, v, Rg, offset, maxLength)) {
// Following paper nomenclature
float t = offset;
vec3 x = cameraPosObj.xyz;// + offset * v;
float r = length(x);
float mu = dot(x, v) / r;
vec3 s = normalize(sunPositionObj);
vec3 attenuation;
vec3 inscatterColor = inscatterLight(x, t, v, s, r, mu, attenuation);
vec3 groundColor = groundColor(x, t, v, s, r, mu, attenuation);
vec3 sunColor = sunColor(x, t, v, s, r, mu);
//diffuse = HDR(vec4(sunColor + groundColor + inscatterColor, 1.0));
//diffuse = HDR(vec4(sunColor, 1.0));
//diffuse = HDR(vec4(groundColor, 1.0));
//diffuse = HDR(vec4(inscatterColor, 1.0));
//diffuse = HDR(vec4(sunColor + groundColor + inscatterColor, 1.0) + diffuse2);
diffuse = HDR((vec4(sunColor + groundColor + inscatterColor, 1.0) + diffuse2) *
calcShadow(shadowDataArray, vs_posWorld.xyz) );
}
// else
// diffuse = HDR(diffuse);
}
diffuse[3] = transparency;
frag.color = diffuse;
frag.depth = depth;
return frag;
}

View File

@@ -1,76 +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__
uniform mat4 ViewProjection;
uniform mat4 ModelTransform;
uniform mat4 NormalTransform;
layout(location = 0) in vec4 in_position;
layout(location = 1) in vec2 in_st;
layout(location = 2) in vec3 in_normal;
//layout(location = 3) in vec2 in_nightTex;
out vec2 vs_st;
out vec4 vs_normal;
out vec4 vs_position;
out vec4 vs_posWorld;
out float s;
out vec4 ray;
#include "PowerScaling/powerScaling_vs.hglsl"
void main()
{
// set variables
vs_st = in_st;
vs_position = in_position;
vec4 tmp = in_position;
// this is wrong for the normal. The normal transform is the transposed inverse of the model transform
//vs_normal = normalize(ModelTransform * vec4(in_normal,0));
// This is the wright transformation for the normals
vs_normal = normalize(NormalTransform * vec4(in_normal,0));
// The position is not in world coordinates, it is in
// regular view/eye coordinates.
vec4 position = pscTransform(tmp, ModelTransform);
// Vertex position in world coordinates in meters and
// with no powerscalling coordiantes
vec3 local_vertex_pos = mat3(ModelTransform) * in_position.xyz;
vec4 vP = psc_addition(vec4(local_vertex_pos,in_position.w),objpos);
vec4 conv = vec4(vP.xyz * pow(10,vP.w), 1.0);
vs_posWorld = conv;
vs_position = tmp;
// Now the position is transformed from view coordinates to SGCT projection
// coordinates.
position = ViewProjection * position;
gl_Position = z_normalization(position);
}

View File

@@ -1,48 +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 "atmosphere_common.glsl"
#include "fragment.glsl"
#include "PowerScaling/powerScalingMath.hglsl"
layout(location = 1) out vec4 renderTableColor;
// See paper algorithm
uniform int line;
uniform sampler2D deltaETexture;
Fragment getFragment() {
if (line == 4)
renderTableColor = vec4(0.0);
else if (line == 10) {
vec2 uv = gl_FragCoord.xy / vec2(OTHER_TEXTURES_W, OTHER_TEXTURES_H);
renderTableColor = texture(deltaETexture, uv);
}
Fragment frag;
frag.color = vec4(1.0);
frag.depth = 1.0;
return frag;
}

View File

@@ -1,31 +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__
layout(location = 0) in vec3 in_position;
void main() {
gl_Position = vec4(in_position, 1.0);
}

View File

@@ -1,192 +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 "atmosphere_common.glsl"
#include "fragment.glsl"
#include "PowerScaling/powerScalingMath.hglsl"
layout(location = 1) out vec4 renderTarget1;
uniform float r;
uniform vec4 dhdH;
uniform sampler2D transmittanceTexture;
uniform sampler2D deltaETexture;
uniform sampler3D deltaSRTexture;
uniform sampler3D deltaSMTexture;
uniform float first;
const float dphi = M_PI / float(INSCATTER_SPHERICAL_INTEGRAL_SAMPLES);
const float dtheta = M_PI / float(INSCATTER_SPHERICAL_INTEGRAL_SAMPLES);
void getMuMuSNu(const float r, vec4 dhdH, out float mu, out float mu_s, out float nu) {
float x = gl_FragCoord.x - 0.5;
float y = gl_FragCoord.y - 0.5;
if (y < float(RES_MU) / 2.0) {
float d = 1.0 - y / (float(RES_MU) / 2.0 - 1.0);
d = min(max(dhdH.z, d * dhdH.w), dhdH.w * 0.999);
mu = (Rg * Rg - r * r - d * d) / (2.0 * r * d);
mu = min(mu, -sqrt(1.0 - (Rg / r) * (Rg / r)) - 0.001);
} else {
float d = (y - float(RES_MU) / 2.0) / (float(RES_MU) / 2.0 - 1.0);
d = min(max(dhdH.x, d * dhdH.y), dhdH.y * 0.999);
mu = (Rt * Rt - r * r - d * d) / (2.0 * r * d);
}
mu_s = mod(x, float(RES_MU_S)) / (float(RES_MU_S) - 1.0);
mu_s = tan((2.0 * mu_s - 1.0 + 0.26) * 1.1) / tan(1.26 * 1.1);
nu = -1.0 + floor(x / float(RES_MU_S)) / (float(RES_NU) - 1.0) * 2.0;
}
vec3 transmittanceFromTexture(const float r, const float mu) {
float u_r = sqrt((r - Rg) / (Rt - Rg));
// See Colliene to understand the different mapping.
float u_mu = atan((mu + 0.15) / (1.0 + 0.15) * tan(1.5)) / 1.5;
return texture(transmittanceTexture, vec2(u_mu, u_r)).rgb;
}
vec3 transmittance(const float r, const float mu, float d) {
vec3 result;
float r1 = sqrt(r * r + d * d + 2.0 * r * mu * d);
float mu1 = (r * mu + d) / r1;
if (mu > 0.0) {
result = min(transmittanceFromTexture(r, mu) /
transmittanceFromTexture(r1, mu1), 1.0);
} else {
result = min(transmittanceFromTexture(r1, -mu1) /
transmittanceFromTexture(r, -mu), 1.0);
}
return result;
}
// Rayleigh phase
float phaseFunctionR(const float mu) {
return (3.0 / (16.0 * M_PI)) * (1.0 + mu * mu);
}
// Mie phase
float phaseFunctionM(const float mu) {
return (3.0 / (8.0 * M_PI)) *
( ( (1.0 - (mieG*mieG) ) * (1+mu*mu) ) /
( (2+mieG*mieG) * pow(1+mieG*mieG - 2.0*mieG*mu, 3.0/2.0) ) );
}
vec3 irradiance(sampler2D calcTexture, const float r, const float mu_s) {
float u_r = (r - Rg) / (Rt - Rg);
float u_mu_s = (mu_s + 0.2) / (1.0 + 0.2);
return texture(calcTexture, vec2(u_mu_s, u_r)).rgb;
}
vec4 texture4D(sampler3D table, const float r, const float mu,
const float mu_s, const float nu)
{
float H = sqrt(Rt * Rt - Rg * Rg);
float rho = sqrt(r * r - Rg * Rg);
float rmu = r * mu;
float delta = rmu * rmu - r * r + Rg * Rg;
vec4 cst = rmu < 0.0 && delta > 0.0 ? vec4(1.0, 0.0, 0.0, 0.5 - 0.5 / float(RES_MU)) : vec4(-1.0, H * H, H, 0.5 + 0.5 / float(RES_MU));
float u_r = 0.5 / float(RES_R) + rho / H * (1.0 - 1.0 / float(RES_R));
float u_mu = cst.w + (rmu * cst.x + sqrt(delta + cst.y)) / (rho + cst.z) * (0.5 - 1.0 / float(RES_MU));
float u_mu_s = 0.5 / float(RES_MU_S) + (atan(max(mu_s, -0.1975) * tan(1.26 * 1.1)) / 1.1 + (1.0 - 0.26)) * 0.5 * (1.0 - 1.0 / float(RES_MU_S));
float lerp = (nu + 1.0) / 2.0 * (float(RES_NU) - 1.0);
float uNu = floor(lerp);
lerp = lerp - uNu;
return texture(table, vec3((uNu + u_mu_s) / float(RES_NU), u_mu, u_r)) * (1.0 - lerp) +
texture(table, vec3((uNu + u_mu_s + 1.0) / float(RES_NU), u_mu, u_r)) * lerp;
}
void inscatter(float r, float mu, float mu_s, float nu, out vec3 raymie) {
r = clamp(r, Rg, Rt);
mu = clamp(mu, -1.0, 1.0);
mu_s = clamp(mu_s, -1.0, 1.0);
float var = sqrt(1.0 - mu * mu) * sqrt(1.0 - mu_s * mu_s);
nu = clamp(nu, mu_s * mu - var, mu_s * mu + var);
float cthetamin = -sqrt(1.0 - (Rg / r) * (Rg / r));
vec3 v = vec3(sqrt(1.0 - mu * mu), 0.0, mu);
float sx = v.x == 0.0 ? 0.0 : (nu - mu_s * mu) / v.x;
vec3 s = vec3(sx, sqrt(max(0.0, 1.0 - sx * sx - mu_s * mu_s)), mu_s);
raymie = vec3(0.0);
for (int itheta = 0; itheta < INSCATTER_SPHERICAL_INTEGRAL_SAMPLES; ++itheta) {
float theta = (float(itheta) + 0.5) * dtheta;
float ctheta = cos(theta);
float greflectance = 0.0;
float dground = 0.0;
vec3 gtransp = vec3(0.0);
if (ctheta < cthetamin) {
greflectance = AVERAGE_GROUND_REFLECTANCE / M_PI;
dground = -r * ctheta - sqrt(r * r * (ctheta * ctheta - 1.0) + Rg * Rg);
gtransp = transmittance(Rg, -(r * ctheta + dground) / Rg, dground);
}
for (int iphi = 0; iphi < 2 * INSCATTER_SPHERICAL_INTEGRAL_SAMPLES; ++iphi) {
float phi = (float(iphi) + 0.5) * dphi;
float dw = dtheta * dphi * sin(theta);
vec3 w = vec3(cos(phi) * sin(theta), sin(phi) * sin(theta), ctheta);
float nu1 = dot(s, w);
float nu2 = dot(v, w);
float pr2 = phaseFunctionR(nu2);
float pm2 = phaseFunctionM(nu2);
vec3 gnormal = (vec3(0.0, 0.0, r) + dground * w) / Rg;
vec3 girradiance = irradiance(deltaETexture, Rg, dot(gnormal, s));
vec3 raymie1;
raymie1 = greflectance * girradiance * gtransp;
if (first == 1.0) {
float pr1 = phaseFunctionR(nu1);
float pm1 = phaseFunctionM(nu1);
vec3 ray1 = texture4D(deltaSRTexture, r, w.z, mu_s, nu1).rgb;
vec3 mie1 = texture4D(deltaSMTexture, r, w.z, mu_s, nu1).rgb;
raymie1 += ray1 * pr1 + mie1 * pm1;
} else {
raymie1 += texture4D(deltaSRTexture, r, w.z, mu_s, nu1).rgb;
}
raymie += raymie1 * (betaR * exp(-(r - Rg) / HR) * pr2 + betaMSca * exp(-(r - Rg) / HM) * pm2) * dw;
}
}
}
Fragment getFragment() {
vec3 raymie;
float mu, mu_s, nu;
getMuMuSNu(r, dhdH, mu, mu_s, nu);
inscatter(r, mu, mu_s, nu, raymie);
renderTarget1 = vec4(raymie, 1.0);
Fragment frag;
frag.color = vec4(1.0);
frag.depth = 1.0;
return frag;
}

View File

@@ -1,41 +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__
uniform int layer;
layout (triangles) in;
layout (triangle_strip, max_vertices = 3) out;
void main()
{
int n;
for (n = 0; n < gl_in.length(); ++n) {
gl_Position = gl_in[n].gl_Position;
gl_Layer = layer;
EmitVertex();
}
EndPrimitive();
}

View File

@@ -1,31 +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__
layout(location = 0) in vec3 in_position;
void main() {
gl_Position = vec4(in_position, 1.0);
}

View File

@@ -1,51 +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 "atmosphere_common.glsl"
#include "fragment.glsl"
#include "PowerScaling/powerScalingMath.hglsl"
layout(location = 1) out vec4 renderTarget1;
uniform int layer;
uniform sampler3D deltaSRTexture;
uniform sampler3D deltaSMTexture;
Fragment getFragment() {
vec3 uvw = vec3(gl_FragCoord.xy, float(layer) + 0.5) / vec3(ivec3(RES_MU_S * RES_NU, RES_MU, RES_R));
vec4 ray = texture(deltaSRTexture, uvw);
vec4 mie = texture(deltaSMTexture, uvw);
// We are using only the red component of the Mie scattering
// See the Precomputed Atmosphere Scattering paper for details about
// the angular precision.
renderTarget1 = vec4(ray.rgb, mie.r);
Fragment frag;
frag.color = vec4(1.0);
frag.depth = 1.0;
return frag;
}

View File

@@ -1,41 +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__
uniform int layer;
layout (triangles) in;
layout (triangle_strip, max_vertices = 3) out;
void main()
{
int n;
for (n = 0; n < gl_in.length(); ++n) {
gl_Position = gl_in[n].gl_Position;
gl_Layer = layer;
EmitVertex();
}
EndPrimitive();
}

View File

@@ -1,31 +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__
layout(location = 0) in vec3 in_position;
void main() {
gl_Position = vec4(in_position, 1.0);
}

View File

@@ -1,54 +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 "atmosphere_common.glsl"
#include "fragment.glsl"
#include "PowerScaling/powerScalingMath.hglsl"
layout(location = 1) out vec4 renderTarget1;
uniform int layer;
uniform sampler3D deltaSTexture;
// Rayleigh phase
float phaseFunctionR(const float mu) {
return (3.0 / (16.0 * M_PI)) * (1.0 + mu * mu);
}
Fragment getFragment() {
float x = gl_FragCoord.x - 0.5;
float y = gl_FragCoord.y - 0.5;
float nu = -1.0 + floor(x / float(RES_MU_S)) / (float(RES_NU) - 1.0) * 2.0;
vec3 uvw = vec3(gl_FragCoord.xy, float(layer) + 0.5) / vec3(ivec3(RES_MU_S * RES_NU, RES_MU, RES_R));
renderTarget1 = vec4(texture(deltaSTexture, uvw).rgb / phaseFunctionR(nu), 1.0);
Fragment frag;
frag.color = vec4(1.0);
frag.depth = 1.0;
return frag;
}

View File

@@ -1,41 +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__
uniform int layer;
layout (triangles) in;
layout (triangle_strip, max_vertices = 3) out;
void main()
{
int n;
for (n = 0; n < gl_in.length(); ++n) {
gl_Position = gl_in[n].gl_Position;
gl_Layer = layer;
EmitVertex();
}
EndPrimitive();
}

View File

@@ -1,31 +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__
layout(location = 0) in vec3 in_position;
void main() {
gl_Position = vec4(in_position, 1.0);
}

View File

@@ -1,35 +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. *
****************************************************************************************/
uniform float exposure;
vec4 HDR(vec4 color) {
color *= exposure;
color.r = color.r < 1.413 ? pow(color.r * 0.38317, 1.0 / 2.2) : 1.0 - exp(-color.r);
color.g = color.g < 1.413 ? pow(color.g * 0.38317, 1.0 / 2.2) : 1.0 - exp(-color.g);
color.b = color.b < 1.413 ? pow(color.b * 0.38317, 1.0 / 2.2) : 1.0 - exp(-color.b);
return color;
}

View File

@@ -1,154 +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 "atmosphere_common.glsl"
#include "fragment.glsl"
#include "PowerScaling/powerScalingMath.hglsl"
layout(location = 1) out vec4 renderTarget1;
layout(location = 2) out vec4 renderTarget2;
uniform float r;
uniform vec4 dhdH;
uniform sampler2D transmittanceTexture;
// In the following shaders r (altitude) is the length of vector/position x in the
// atmosphere (or on the top of it when considering an observer in space),
// where the light is comming from the opposity direction of the view direction,
// here the vector v or viewDirection.
// Rg is the planet radius
void getMuMuSNu(const float r, vec4 dhdH, out float mu, out float mu_s, out float nu) {
float x = gl_FragCoord.x - 0.5;
float y = gl_FragCoord.y - 0.5;
if (y < float(RES_MU) / 2.0) {
float d = 1.0 - y / (float(RES_MU) / 2.0 - 1.0);
d = min(max(dhdH.z, d * dhdH.w), dhdH.w * 0.999);
mu = (Rg * Rg - r * r - d * d) / (2.0 * r * d);
mu = min(mu, -sqrt(1.0 - (Rg / r) * (Rg / r)) - 0.001);
} else {
float d = (y - float(RES_MU) / 2.0) / (float(RES_MU) / 2.0 - 1.0);
d = min(max(dhdH.x, d * dhdH.y), dhdH.y * 0.999);
mu = (Rt * Rt - r * r - d * d) / (2.0 * r * d);
}
mu_s = mod(x, float(RES_MU_S)) / (float(RES_MU_S) - 1.0);
mu_s = tan((2.0 * mu_s - 1.0 + 0.26) * 1.1) / tan(1.26 * 1.1);
nu = -1.0 + floor(x / float(RES_MU_S)) / (float(RES_NU) - 1.0) * 2.0;
}
vec3 transmittanceFromTexture(const float r, const float mu) {
float u_r = sqrt((r - Rg) / (Rt - Rg));
// See Colliene to understand the different mapping.
float u_mu = atan((mu + 0.15) / (1.0 + 0.15) * tan(1.5)) / 1.5;
return texture(transmittanceTexture, vec2(u_mu, u_r)).rgb;
}
vec3 transmittance(const float r, const float mu, float d) {
vec3 result;
float r1 = sqrt(r * r + d * d + 2.0 * r * mu * d);
float mu1 = (r * mu + d) / r1;
if (mu > 0.0) {
result = min(transmittanceFromTexture(r, mu) /
transmittanceFromTexture(r1, mu1), 1.0);
} else {
result = min(transmittanceFromTexture(r1, -mu1) /
transmittanceFromTexture(r, -mu), 1.0);
}
return result;
}
void integrand(const float r, const float mu, const float muS, const float nu,
const float t, out vec3 ray, out vec3 mie) {
ray = vec3(0.0);
mie = vec3(0.0);
float ri = sqrt(r * r + t * t + 2.0 * r * mu * t);
float muSi = (nu * t + muS * r) / ri;
ri = max(Rg, ri);
if (muSi >= -sqrt(1.0 - Rg * Rg / (ri * ri))) {
vec3 ti = transmittance(r, mu, t) * transmittanceFromTexture(ri, muSi);
ray = exp(-(ri - Rg) / HR) * ti;
mie = exp(-(ri - Rg) / HM) * ti;
}
}
float rayDistance(const float r, const float mu) {
// cosine law
float distanceAtmosphereIntersect = -r * mu + sqrt(r * r * (mu * mu - 1.0) +
(Rt + ATM_EPSILON)*(Rt + ATM_EPSILON));
float distance = distanceAtmosphereIntersect;
float delta = r * r * (mu * mu - 1.0) + Rg * Rg;
// No imaginary numbers... :-)
if (delta >= 0.0) {
float distanceEarthIntersect = -r * mu - sqrt(delta);
if (distanceEarthIntersect >= 0.0) {
distance = min(distanceAtmosphereIntersect, distanceEarthIntersect);
}
}
return distance;
}
void inscatter(float r, float mu, float muS, float nu, out vec3 ray, out vec3 mie) {
// Integrating using the Trapezoidal rule:
// Integral(f(y)dy)(from a to b) = (b-a)/2n_steps*(Sum(f(y_i+1)+f(y_i)))
ray = vec3(0.0);
mie = vec3(0.0);
float dx = rayDistance(r, mu) / float(INSCATTER_INTEGRAL_SAMPLES);
float xi = 0.0;
vec3 rayi;
vec3 miei;
integrand(r, mu, muS, nu, 0.0, rayi, miei);
for (int i = 1; i <= INSCATTER_INTEGRAL_SAMPLES; ++i) {
float xj = float(i) * dx;
vec3 rayj;
vec3 miej;
integrand(r, mu, muS, nu, xj, rayj, miej);
ray += (rayi + rayj) / 2.0 * dx;
mie += (miei + miej) / 2.0 * dx;
xi = xj;
rayi = rayj;
miei = miej;
}
ray *= betaR;
mie *= betaMSca;
}
Fragment getFragment() {
vec3 ray;
vec3 mie;
float mu, muS, nu;
getMuMuSNu(r, dhdH, mu, muS, nu);
inscatter(r, mu, muS, nu, ray, mie);
// store separately Rayleigh and Mie contributions, WITHOUT the phase function factor
// (cf "Angular precision")
renderTarget1 = vec4(ray, 1.0);
renderTarget2 = vec4(mie, 1.0);
Fragment frag;
frag.color = vec4(1.0);
frag.depth = 1.0;
return frag;
}

View File

@@ -1,41 +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__
uniform int layer;
layout (triangles) in;
layout (triangle_strip, max_vertices=3) out;
void main()
{
int n;
for (n = 0; n < gl_in.length(); ++n) {
gl_Position = gl_in[n].gl_Position;
gl_Layer = layer;
EmitVertex();
}
EndPrimitive();
}

View File

@@ -1,31 +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__
layout(location = 0) in vec3 in_position;
void main() {
gl_Position = vec4(in_position, 1.0);
}

View File

@@ -1,155 +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 "atmosphere_common.glsl"
#include "fragment.glsl"
#include "PowerScaling/powerScalingMath.hglsl"
layout(location = 1) out vec4 renderTarget1;
uniform float r;
uniform vec4 dhdH;
uniform sampler2D transmittanceTexture;
uniform sampler3D deltaJTexture;
void getMuMuSNu(const float r, vec4 dhdH, out float mu, out float mu_s, out float nu) {
float x = gl_FragCoord.x - 0.5;
float y = gl_FragCoord.y - 0.5;
if (y < float(RES_MU) / 2.0) {
float d = 1.0 - y / (float(RES_MU) / 2.0 - 1.0);
d = min(max(dhdH.z, d * dhdH.w), dhdH.w * 0.999);
mu = (Rg * Rg - r * r - d * d) / (2.0 * r * d);
mu = min(mu, -sqrt(1.0 - (Rg / r) * (Rg / r)) - 0.001);
} else {
float d = (y - float(RES_MU) / 2.0) / (float(RES_MU) / 2.0 - 1.0);
d = min(max(dhdH.x, d * dhdH.y), dhdH.y * 0.999);
mu = (Rt * Rt - r * r - d * d) / (2.0 * r * d);
}
mu_s = mod(x, float(RES_MU_S)) / (float(RES_MU_S) - 1.0);
mu_s = tan((2.0 * mu_s - 1.0 + 0.26) * 1.1) / tan(1.26 * 1.1);
nu = -1.0 + floor(x / float(RES_MU_S)) / (float(RES_NU) - 1.0) * 2.0;
}
vec4 texture4D(sampler3D table, float r, float mu, float muS, float nu)
{
float H = sqrt(Rt * Rt - Rg * Rg);
float rho = sqrt(r * r - Rg * Rg);
float rmu = r * mu;
float delta = rmu * rmu - r * r + Rg * Rg;
vec4 cst = rmu < 0.0 && delta > 0.0 ? vec4(1.0, 0.0, 0.0, 0.5 - 0.5 / float(RES_MU)) : vec4(-1.0, H * H, H, 0.5 + 0.5 / float(RES_MU));
float uR = 0.5 / float(RES_R) + rho / H * (1.0 - 1.0 / float(RES_R));
float uMu = cst.w + (rmu * cst.x + sqrt(delta + cst.y)) / (rho + cst.z) * (0.5 - 1.0 / float(RES_MU));
float uMuS = 0.5 / float(RES_MU_S) + (atan(max(muS, -0.1975) * tan(1.26 * 1.1)) / 1.1 + (1.0 - 0.26)) * 0.5 * (1.0 - 1.0 / float(RES_MU_S));
float lerp = (nu + 1.0) / 2.0 * (float(RES_NU) - 1.0);
float uNu = floor(lerp);
lerp = lerp - uNu;
return texture(table, vec3((uNu + uMuS) / float(RES_NU), uMu, uR)) * (1.0 - lerp) +
texture(table, vec3((uNu + uMuS + 1.0) / float(RES_NU), uMu, uR)) * lerp;
}
float limit(float r, float mu) {
float dout = -r * mu + sqrt(r * r * (mu * mu - 1.0) + ((Rt+ATM_EPSILON) * (Rt+ATM_EPSILON)));
float delta2 = r * r * (mu * mu - 1.0) + Rg * Rg;
if (delta2 >= 0.0) {
float din = -r * mu - sqrt(delta2);
if (din >= 0.0) {
dout = min(dout, din);
}
}
return dout;
}
vec3 transmittanceFromTexture(const float r, const float mu) {
float u_r = sqrt((r - Rg) / (Rt - Rg));
// See Colliene to understand the different mapping.
float u_mu = atan((mu + 0.15) / (1.0 + 0.15) * tan(1.5)) / 1.5;
return texture(transmittanceTexture, vec2(u_mu, u_r)).rgb;
}
vec3 transmittance(const float r, const float mu, const float d) {
vec3 result;
float r1 = sqrt(r * r + d * d + 2.0 * r * mu * d);
float mu1 = (r * mu + d) / r1;
if (mu > 0.0) {
result = min(transmittanceFromTexture(r, mu) /
transmittanceFromTexture(r1, mu1), 1.0);
} else {
result = min(transmittanceFromTexture(r1, -mu1) /
transmittanceFromTexture(r, -mu), 1.0);
}
return result;
}
vec3 integrand(float r, float mu, float muS, float nu, float t) {
float ri = sqrt(r * r + t * t + 2.0 * r * mu * t);
float mui = (r * mu + t) / ri;
float muSi = (nu * t + muS * r) / ri;
return texture4D(deltaJTexture, ri, mui, muSi, nu).rgb * transmittance(r, mu, t);
}
float rayDistance(const float r, const float mu) {
// cosine law
float distanceAtmosphereIntersect = -r * mu + sqrt(r * r * (mu * mu - 1.0) +
(Rt + ATM_EPSILON)*(Rt + ATM_EPSILON));
float distance = distanceAtmosphereIntersect;
float delta = r * r * (mu * mu - 1.0) + Rg * Rg;
// No imaginary numbers... :-)
if (delta >= 0.0) {
float distanceEarthIntersect = -r * mu - sqrt(delta);
if (distanceEarthIntersect >= 0.0) {
distance = min(distanceAtmosphereIntersect, distanceEarthIntersect);
}
}
return distance;
}
vec3 inscatter(float r, float mu, float muS, float nu) {
vec3 raymie = vec3(0.0);
float dx = rayDistance(r, mu) / float(INSCATTER_INTEGRAL_SAMPLES);
float xi = 0.0;
vec3 raymiei = integrand(r, mu, muS, nu, 0.0);
for (int i = 1; i <= INSCATTER_INTEGRAL_SAMPLES; ++i) {
float xj = float(i) * dx;
vec3 raymiej = integrand(r, mu, muS, nu, xj);
raymie += (raymiei + raymiej) / 2.0 * dx;
xi = xj;
raymiei = raymiej;
}
return raymie;
}
Fragment getFragment() {
float mu, muS, nu;
getMuMuSNu(r, dhdH, mu, muS, nu);
renderTarget1 = vec4(inscatter(r, mu, muS, nu), 1.0);
Fragment frag;
frag.color = vec4(1.0);
frag.depth = 1.0;
return frag;
}

View File

@@ -1,41 +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__
uniform int layer;
layout (triangles) in;
layout (triangle_strip, max_vertices = 3) out;
void main()
{
int n;
for (n = 0; n < gl_in.length(); ++n) {
gl_Position = gl_in[n].gl_Position;
gl_Layer = layer;
EmitVertex();
}
EndPrimitive();
}

View File

@@ -1,31 +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__
layout(location = 0) in vec3 in_position;
void main() {
gl_Position = vec4(in_position, 1.0);
}

View File

@@ -1,57 +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 "atmosphere_common.glsl"
#include "fragment.glsl"
#include "PowerScaling/powerScalingMath.hglsl"
layout(location = 1) out vec4 renderTableColor;
uniform sampler2D transmittanceTexture;
void getRAndMu(out float r, out float mu) {
// See Bruneton and Colliene to understand the mapping.
mu = -0.2 + (gl_FragCoord.x - 0.5) / (float(OTHER_TEXTURES_W) - 1.0) * (1.0 + 0.2);
r = Rg + (gl_FragCoord.y - 0.5) / (float(OTHER_TEXTURES_H) - 1.0) * (Rt - Rg);
}
vec3 transmittance(const float r, const float mu) {
float u_r = sqrt((r - Rg) / (Rt - Rg));
// See Colliene to understand the different mapping.
float u_mu = atan((mu + 0.15) / (1.0 + 0.15) * tan(1.5)) / 1.5;
return texture(transmittanceTexture, vec2(u_mu, u_r)).rgb;
}
Fragment getFragment() {
float mu, r;
getRAndMu(r, mu);
renderTableColor = vec4(transmittance(r, mu) * max(mu, 0.0), 1.0);
Fragment frag;
frag.color = vec4(1.0);
frag.depth = 1.0;
return frag;
}

View File

@@ -1,31 +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__
layout(location = 0) in vec3 in_position;
void main() {
gl_Position = vec4(in_position, 1.0);
}

View File

@@ -1,101 +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 "atmosphere_common.glsl"
#include "fragment.glsl"
#include "PowerScaling/powerScalingMath.hglsl"
layout(location = 1) out vec4 renderTableColor;
uniform float first;
const float dphi = M_PI / float(IRRADIANCE_INTEGRAL_SAMPLES);
const float dtheta = M_PI / float(IRRADIANCE_INTEGRAL_SAMPLES);
uniform sampler2D transmittanceTexture;
uniform sampler3D deltaSRTexture;
uniform sampler3D deltaSMTexture;
// Rayleigh phase
float phaseFunctionR(const float mu) {
return (3.0 / (16.0 * M_PI)) * (1.0 + mu * mu);
}
// Mie phase
float phaseFunctionM(const float mu) {
return (3.0 / (8.0 * M_PI)) *
( ( (1.0 - (mieG*mieG) ) * (1+mu*mu) ) /
( (2+mieG*mieG) * pow(1+mieG*mieG - 2.0*mieG*mu, 3.0/2.0) ) );
}
vec4 texture4D(sampler3D table, const float r, const float mu,
const float muS, const float nu)
{
float H = sqrt(Rt * Rt - Rg * Rg);
float rho = sqrt(r * r - Rg * Rg);
float rmu = r * mu;
float delta = rmu * rmu - r * r + Rg * Rg;
vec4 cst = rmu < 0.0 && delta > 0.0 ? vec4(1.0, 0.0, 0.0, 0.5 - 0.5 / float(RES_MU)) : vec4(-1.0, H * H, H, 0.5 + 0.5 / float(RES_MU));
float uR = 0.5 / float(RES_R) + rho / H * (1.0 - 1.0 / float(RES_R));
float uMu = cst.w + (rmu * cst.x + sqrt(delta + cst.y)) / (rho + cst.z) * (0.5 - 1.0 / float(RES_MU));
float uMuS = 0.5 / float(RES_MU_S) + (atan(max(muS, -0.1975) * tan(1.26 * 1.1)) / 1.1 + (1.0 - 0.26)) * 0.5 * (1.0 - 1.0 / float(RES_MU_S));
float lerp = (nu + 1.0) / 2.0 * (float(RES_NU) - 1.0);
float uNu = floor(lerp);
lerp = lerp - uNu;
return texture(table, vec3((uNu + uMuS) / float(RES_NU), uMu, uR)) * (1.0 - lerp) +
texture(table, vec3((uNu + uMuS + 1.0) / float(RES_NU), uMu, uR)) * lerp;
}
Fragment getFragment() {
float r = Rg + (gl_FragCoord.y - 0.5) / (float(SKY_H) - 1.0) * (Rt - Rg);
float mu_s = -0.2 + (gl_FragCoord.x - 0.5) / (float(SKY_W) - 1.0) * (1.0 + 0.2);
vec3 s = vec3(max(sqrt(1.0 - mu_s * mu_s), 0.0), 0.0, mu_s);
vec3 result = vec3(0.0);
for (int iphi = 0; iphi < 2 * IRRADIANCE_INTEGRAL_SAMPLES; ++iphi) {
float phi = (float(iphi) + 0.5) * dphi;
for (int itheta = 0; itheta < IRRADIANCE_INTEGRAL_SAMPLES / 2; ++itheta) {
float theta = (float(itheta) + 0.5) * dtheta;
float dw = dtheta * dphi * sin(theta);
vec3 w = vec3(cos(phi) * sin(theta), sin(phi) * sin(theta), cos(theta));
float nu = dot(s, w);
if (first == 1.0) {
float pr1 = phaseFunctionR(nu);
float pm1 = phaseFunctionM(nu);
vec3 ray1 = texture4D(deltaSRTexture, r, w.z, mu_s, nu).rgb;
vec3 mie1 = texture4D(deltaSMTexture, r, w.z, mu_s, nu).rgb;
result += (ray1 * pr1 + mie1 * pm1) * w.z * dw;
} else {
result += texture4D(deltaSRTexture, r, w.z, mu_s, nu).rgb * w.z * dw;
}
}
}
renderTableColor = vec4(result, 0.0);
Fragment frag;
frag.color = vec4(1.0);
frag.depth = 1.0;
return frag;
}

View File

@@ -1,31 +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__
layout(location = 0) in vec3 in_position;
void main() {
gl_Position = vec4(in_position, 1.0);
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,109 +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 "atmosphere_common.glsl"
#include "fragment.glsl"
#include "PowerScaling/powerScalingMath.hglsl"
layout(location = 1) out vec4 renderTableColor;
// In the following shaders r (altitude) is the length of vector/position x in the
// atmosphere (or on the top of it when considering an observer in space),
// where the light is comming from the opposity direction of the view direction,
// here the vector v or viewDirection.
// Rg is the planet radius
float rayDistance(const float r, const float mu) {
// cosine law
float distanceAtmosphereIntersect = -r * mu + sqrt(r * r * (mu * mu - 1.0) +
(Rt + ATM_EPSILON)*(Rt + ATM_EPSILON));
float distance = distanceAtmosphereIntersect;
float delta = r * r * (mu * mu - 1.0) + Rg * Rg;
// No imaginary numbers... :-)
if (delta >= 0.0) {
float distanceEarthIntersect = -r * mu - sqrt(delta);
if (distanceEarthIntersect >= 0.0) {
distance = min(distanceAtmosphereIntersect, distanceEarthIntersect);
}
}
return distance;
}
float opticalDepth(const float r, const float mu, const float scaleHeight) {
float r2 = r*r;
// Is ray below horizon?
// cosine law for triangles: y_i^2 = a^2 + b^2 - 2abcos(alpha)
float cosZenithHorizon = -sqrt(1.0 - ((Rg*Rg)/r2));
if (mu < cosZenithHorizon)
return 1e9;
// Integrating using the Trapezoidal rule:
// Integral(f(y)dy)(from a to b) = (b-a)/2n_steps*(Sum(f(y_i+1)+f(y_i)))
float b_a = rayDistance(r, mu);
float deltaStep = b_a / float(TRANSMITTANCE_STEPS);
// cosine law
float y_i = exp(-(r - Rg) / scaleHeight);
float x_step = 0.0;
float accumulation = 0.0;
for (int i = 1; i <= TRANSMITTANCE_STEPS; ++i) {
float x_i = float(i) * deltaStep;
// cosine law for triangles: y_i^2 = a^2 + b^2 - 2abcos(alpha)
// In this case, a = r, b = x_i and cos(alpha) = cos(PI-zenithView) = mu
float y_ii = exp(-(sqrt(r2 + x_i * x_i + 2.0 * x_i * r * mu) - Rg) / scaleHeight);
accumulation += (y_ii + y_i);
//x_step = x_i;
y_i = y_ii;
}
return accumulation * (b_a/(2*TRANSMITTANCE_STEPS));
}
void getRandMU(out float r, out float mu) {
float u_mu = gl_FragCoord.x / float(TRANSMITTANCE_W);
float u_r = gl_FragCoord.y / float(TRANSMITTANCE_H);
// In the paper u_r^2 = (r^2-Rg^2)/(Rt^2-Rg^2)
r = sqrt(Rg*Rg + (u_r * u_r) * (Rt*Rt - Rg*Rg));
// In the paper the author suggest mu = dot(v,x)/||x|| with ||v|| = 1.0
// Later he proposes u_mu = (1-exp(-3mu-0.6))/(1-exp(-3.6))
// But the below one is better. See Colliene.
mu = -0.15 + tan(1.5 * u_mu) / tan(1.5) * (1.0 + 0.15);
}
Fragment getFragment() {
float r, mu;
getRandMU(r, mu);
vec3 depth = betaMEx * opticalDepth(r, mu, HM) + betaR * opticalDepth(r, mu, HR);
renderTableColor = vec4(exp(-depth), 1.0);
Fragment frag;
frag.color = vec4(1.0);
frag.depth = 1.0;
return frag;
}

View File

@@ -1,31 +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__
layout(location = 0) in vec3 in_position;
void main() {
gl_Position = vec4(in_position, 1.0);
}

View File

@@ -32,11 +32,12 @@
#include <openspace/documentation/verifier.h>
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<std::string>(KeyBody);
_origin = dictionary.value<std::string>(KeyObserver);
if (dictionary.hasKey(KeyFrame)) {
_frame = dictionary.value<std::string>(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);
}

View File

@@ -43,6 +43,7 @@ public:
private:
properties::StringProperty _target;
properties::StringProperty _origin;
properties::StringProperty _frame;
glm::dvec3 _position;
bool _kernelsLoadedSuccessfully;

View File

@@ -462,7 +462,7 @@ bool RenderablePlanetProjection::loadTextures() {
if (_colorTexturePath.value() != "") {
_baseTexture = ghoul::io::TextureReader::ref().loadTexture(_colorTexturePath);
if (_baseTexture) {
ghoul::opengl::convertTextureFormat(Texture::Format::RGB, *_baseTexture);
ghoul::opengl::convertTextureFormat(*_baseTexture, Texture::Format::RGB);
_baseTexture->uploadTexture();
_baseTexture->setFilter(Texture::FilterMode::Linear);
}
@@ -472,7 +472,7 @@ bool RenderablePlanetProjection::loadTextures() {
if (_heightMapTexturePath.value() != "") {
_heightMapTexture = ghoul::io::TextureReader::ref().loadTexture(_heightMapTexturePath);
if (_heightMapTexture) {
ghoul::opengl::convertTextureFormat(Texture::Format::RGB, *_heightMapTexture);
ghoul::opengl::convertTextureFormat(*_heightMapTexture, Texture::Format::RGB);
_heightMapTexture->uploadTexture();
_heightMapTexture->setFilter(Texture::FilterMode::Linear);
}

View File

@@ -875,7 +875,7 @@ std::shared_ptr<ghoul::opengl::Texture> ProjectionComponent::loadProjectionTextu
unique_ptr<Texture> texture = TextureReader::ref().loadTexture(absPath(texturePath));
if (texture) {
if (texture->format() == Texture::Format::Red)
ghoul::opengl::convertTextureFormat(ghoul::opengl::Texture::Format::RGB, *texture);
ghoul::opengl::convertTextureFormat(*texture, Texture::Format::RGB);
texture->uploadTexture();
// TODO: AnisotropicMipMap crashes on ATI cards ---abock
//_textureProj->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap);

Some files were not shown because too many files have changed in this diff Show More