From 428f488bb6989771ac28ea30ca8d8d4e8480d8ca Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Tue, 20 Sep 2016 19:24:14 +0200 Subject: [PATCH] Add documentation to Ephemeris classes Remove unused "Reference" specification from mod files Add osirisrex files to gitgnore Make Ephemeris values into properties --- .gitignore | 5 + .../scene/atmosphereearth/atmosphereearth.mod | 12 +- data/scene/batsrus/batsrus.mod | 4 +- data/scene/common/common.mod | 6 +- .../constellationbounds.mod | 3 - data/scene/dawn/ceres/ceres.mod | 8 +- data/scene/dawn/dawn/dawn.mod | 7 +- .../dawn/vestaprojection/vestaprojection.mod | 9 +- data/scene/debugglobe/debugglobe.mod | 11 +- data/scene/debugmodel/debugmodel.mod | 25 ---- data/scene/earth/earth.mod | 5 +- data/scene/enlil/enlil.mod | 9 +- data/scene/enlilnh/enlilnh.mod | 7 +- data/scene/fieldlines/fieldlines.mod | 35 +---- data/scene/flare/flare.mod | 7 +- .../scene/grids/gridEcliptic/gridEcliptic.mod | 19 +-- .../grids/gridEquatorial/gridEquatorial.mod | 8 +- .../scene/grids/gridGalactic/gridGalactic.mod | 25 +--- data/scene/imageplane/imageplane.mod | 34 ----- data/scene/imageplane/textures/squarefov.png | Bin 5753 -> 0 bytes data/scene/imageplane/textures/test.jpg | Bin 65106 -> 0 bytes data/scene/juno/juno/juno.mod | 4 +- data/scene/jupiter/callisto/callisto.mod | 11 +- data/scene/jupiter/europa/europa.mod | 11 +- data/scene/jupiter/ganymede/ganymede.mod | 11 +- data/scene/jupiter/io/io.mod | 11 +- data/scene/jupiter/jupiter/jupiter.mod | 11 +- data/scene/jupiter/textures/Jupiter-text.png | Bin 2406 -> 0 bytes data/scene/lodearth/lodearth.mod | 11 +- data/scene/lodesritest/lodesritest.mod | 32 +--- data/scene/lodmars/lodmars.mod | 12 +- data/scene/lodmercury/lodmercury.mod | 7 +- data/scene/lodmoon/lodmoon.mod | 11 +- data/scene/mars/mars.mod | 11 +- data/scene/mercury/mercury.mod | 11 +- data/scene/milkyway-eso/milkyway-eso.mod | 5 +- data/scene/milkyway/milkyway.mod | 5 +- data/scene/moon/moon.mod | 11 +- data/scene/neptune/neptune.mod | 10 +- data/scene/newhorizons.scene | 1 - .../newhorizons/jupiter/callisto/callisto.mod | 25 +--- .../newhorizons/jupiter/europa/europa.mod | 23 +-- .../newhorizons/jupiter/ganymede/ganymede.mod | 23 +-- data/scene/newhorizons/jupiter/io/io.mod | 7 +- .../newhorizons/jupiter/jupiter/jupiter.mod | 7 +- .../newhorizons/newhorizons/newhorizons.mod | 16 -- .../newhorizonsfov/newhorizonsfov.mod | 11 -- .../newhorizonspath/newhorizonspath.mod | 1 - .../newhorizonstrail/newhorizonstrail.mod | 1 - .../scene/newhorizons/pluto/charon/charon.mod | 23 --- data/scene/newhorizons/pluto/hydra/hydra.mod | 23 --- .../newhorizons/pluto/kerberos/kerberos.mod | 23 --- data/scene/newhorizons/pluto/nix/nix.mod | 23 --- data/scene/newhorizons/pluto/pluto/pluto.mod | 46 ------ data/scene/newhorizons/pluto/styx/styx.mod | 24 --- data/scene/osirisrex/bennu/bennu.mod | 6 - data/scene/osirisrex/osirisrex/osirisrex.mod | 17 +-- data/scene/pluto/pluto.mod | 22 +-- data/scene/rosetta/67P/67P.mod | 4 - data/scene/rosetta/rosetta/rosetta.mod | 7 - data/scene/saturn/saturn.mod | 7 +- data/scene/stars-denver/stars-denver.mod | 3 - data/scene/stars/stars.mod | 3 - data/scene/sun/sun.mod | 15 +- data/scene/toyvolume/toyvolume.mod | 19 +-- data/scene/uranus/uranus.mod | 7 +- data/scene/venus/venus.mod | 10 +- .../volumetricmilkyway/volumetricmilkyway.mod | 5 - .../openspace/documentation/documentation.h | 9 ++ include/openspace/scene/ephemeris.h | 15 +- include/openspace/scene/scale.h | 9 +- modules/base/basemodule.cpp | 4 +- modules/base/ephemeris/spiceephemeris.cpp | 137 +++++++++++------- modules/base/ephemeris/spiceephemeris.h | 14 +- modules/base/ephemeris/staticephemeris.cpp | 58 +++++++- modules/base/ephemeris/staticephemeris.h | 16 +- modules/base/rendering/renderableplanet.cpp | 3 +- src/documentation/documentation.cpp | 16 ++ src/scene/ephemeris.cpp | 7 +- src/scene/scale.cpp | 7 +- src/scene/scenegraph.cpp | 13 +- 81 files changed, 307 insertions(+), 827 deletions(-) delete mode 100644 data/scene/debugmodel/debugmodel.mod delete mode 100644 data/scene/imageplane/imageplane.mod delete mode 100644 data/scene/imageplane/textures/squarefov.png delete mode 100644 data/scene/imageplane/textures/test.jpg delete mode 100644 data/scene/jupiter/textures/Jupiter-text.png diff --git a/.gitignore b/.gitignore index 0980cb3856..1006d42b46 100644 --- a/.gitignore +++ b/.gitignore @@ -68,6 +68,10 @@ data/scene/newhorizons/pluto/pluto/assets data/scene/newhorizons/pluto/pluto/full_images data/scene/newhorizons/pluto/pluto/images data/scene/newhorizons/pluto/pluto/textures +data/scene/osirisrex/bennu/models +data/scene/osirisrex/bennu/textures +data/scene/osirisrex/osirisrex/models +data/scene/osirisrex/osirisrex/textures data/scene/pluto/textures data/scene/saturn/textures data/scene/rosetta/67P/obj @@ -91,5 +95,6 @@ data/spice/de430_1850-2150.bsp data/spice/MAR063.BSP data/spice/NewHorizonsKernels data/spice/nh_kernels +data/spice/OsirisRexKernels data/spice/Rosetta diff --git a/data/scene/atmosphereearth/atmosphereearth.mod b/data/scene/atmosphereearth/atmosphereearth.mod index 166a0bdbad..f54904ac1f 100644 --- a/data/scene/atmosphereearth/atmosphereearth.mod +++ b/data/scene/atmosphereearth/atmosphereearth.mod @@ -7,11 +7,8 @@ return { Ephemeris = { Type = "Spice", Body = "EARTH BARYCENTER", - Reference = "ECLIPJ2000", Observer = "SUN", - Kernels = { - "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" - } + Kernels = "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" }, }, -- Earth module @@ -101,9 +98,7 @@ return { -- G = 0.65, -- }, } - }, - - GuiName = "/Solar/Planets/Earth" + } }, -- EarthTrail module { @@ -118,8 +113,7 @@ return { TropicalOrbitPeriod = 365.242, EarthOrbitRatio = 1, DayLength = 24 - }, - GuiName = "/Solar/EarthTrail" + } }, { Name = "EarthMarker", diff --git a/data/scene/batsrus/batsrus.mod b/data/scene/batsrus/batsrus.mod index f512afb550..a948893e53 100644 --- a/data/scene/batsrus/batsrus.mod +++ b/data/scene/batsrus/batsrus.mod @@ -57,8 +57,6 @@ return { TransferFunctionName = "BatsrusPTF", TransferFunction = "transferfunctions/p.txt", Sampler = "psampler.glsl", - }, - GuiName = "/Volumes/Volume" + } } - --]] } \ No newline at end of file diff --git a/data/scene/common/common.mod b/data/scene/common/common.mod index aa9e0d050c..22ac4fa860 100644 --- a/data/scene/common/common.mod +++ b/data/scene/common/common.mod @@ -2,10 +2,6 @@ return { -- Solar System module { Name = "SolarSystem", - Parent = "Root", - Ephemeris = { - Type = "Static", - Position = { 0, 0, 0, 0} - } + Parent = "Root" }, } \ No newline at end of file diff --git a/data/scene/constellationbounds/constellationbounds.mod b/data/scene/constellationbounds/constellationbounds.mod index 8d1ff2f91b..e23d57dc37 100644 --- a/data/scene/constellationbounds/constellationbounds.mod +++ b/data/scene/constellationbounds/constellationbounds.mod @@ -8,9 +8,6 @@ return { File = "${OPENSPACE_DATA}/scene/constellationbounds/data/bound_20.dat", ConstellationFile = "${OPENSPACE_DATA}/scene/constellationbounds/data/constellations.dat", ReferenceFrame = "J2000" - }, - Ephemeris = { - Type = "Static" } } } \ No newline at end of file diff --git a/data/scene/dawn/ceres/ceres.mod b/data/scene/dawn/ceres/ceres.mod index 2c2406d4a6..ff9c413a2a 100644 --- a/data/scene/dawn/ceres/ceres.mod +++ b/data/scene/dawn/ceres/ceres.mod @@ -23,7 +23,6 @@ return { Ephemeris = { Type = "Spice", Body = "CERES", - Reference = "GALACTIC", Observer = "SUN", Kernels = { "${OPENSPACE_DATA}/spice/DawnKernels/pck/dawn_ceres_v01.tpc", @@ -35,9 +34,7 @@ return { Type = "Spice", Frame = "IAU_CERES", Reference = "GALACTIC" - }, - - GuiName = "/Solar/Ceres" + } }, --[[ Ceres Trail Module { @@ -62,8 +59,7 @@ return { }, StartTime = "2010 JAN 01T00:00:00", EndTime = "2018 JAN 22 12:00:00" - }, - GuiName = "/Solar/CeresTrail" + } } --]] } \ No newline at end of file diff --git a/data/scene/dawn/dawn/dawn.mod b/data/scene/dawn/dawn/dawn.mod index e93fd3522b..65e003ac47 100644 --- a/data/scene/dawn/dawn/dawn.mod +++ b/data/scene/dawn/dawn/dawn.mod @@ -25,7 +25,6 @@ return { Ephemeris = { Type = "Spice", Body = "DAWN", - Reference = "GALACTIC", Observer = "SUN", Kernels = { "${OPENSPACE_DATA}/spice/DawnKernels/spk/dawn_ref_070926-150201_070829.bsp", @@ -621,8 +620,7 @@ return { "${OPENSPACE_DATA}/spice/DawnKernels/ck/dawn_sa_120903_120909.bc", "${OPENSPACE_DATA}/spice/DawnKernels/ck/dawn_sa_120910_120916.bc", } - }, - GuiName = "/Solar/Dawn" + } }, -- Dawn Solar Array module 1 @@ -719,7 +717,6 @@ return { StartTime = "2007 SEP 26 13:28:00", EndTime = "2012 SEP 12 12:00:00" }, - GuiName = "DawnTrail" }, -- -- -- Dawn Trail Module @@ -771,7 +768,6 @@ return { "CERES" } }, - GuiName = "/Solar/Dawn_FC1" }, -- DawnFov 1 @@ -798,6 +794,5 @@ return { "CERES" } }, - GuiName = "/Solar/Dawn_FC" }, } diff --git a/data/scene/dawn/vestaprojection/vestaprojection.mod b/data/scene/dawn/vestaprojection/vestaprojection.mod index bb5dc312ae..4de4d75dee 100644 --- a/data/scene/dawn/vestaprojection/vestaprojection.mod +++ b/data/scene/dawn/vestaprojection/vestaprojection.mod @@ -88,16 +88,12 @@ return { Ephemeris = { Type = "Spice", Body = "VESTA", - Reference = "GALACTIC", Observer = "SUN", Kernels = { --"${OPENSPACE_DATA}/spice/DAWN_KERNELS/pck/dawn_vesta_v06.tpc", "${OPENSPACE_DATA}/spice/DawnKernels/spk/sb_vesta_071107.bsp", } - }, - - - GuiName = "/Solar/Vesta" + } }, -- Vesta Trail Module { @@ -122,7 +118,6 @@ return { }, StartTime = "2007 JUL 20 12:00:00", EndTime = "2018 JAN 22 12:00:00" - }, - GuiName = "/Solar/VestaTrail" + } } } diff --git a/data/scene/debugglobe/debugglobe.mod b/data/scene/debugglobe/debugglobe.mod index ae21e2f03a..7f559dce3a 100644 --- a/data/scene/debugglobe/debugglobe.mod +++ b/data/scene/debugglobe/debugglobe.mod @@ -7,11 +7,8 @@ return { Ephemeris = { Type = "Spice", Body = "EARTH BARYCENTER", - Reference = "ECLIPJ2000", Observer = "SUN", - Kernels = { - "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" - } + Kernels = "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" }, }, -- RenderableGlobe module @@ -170,8 +167,7 @@ return { Kernels = { "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" } - }, - GuiName = "/Solar/Planets/DebugGlobe" + } }, -- EarthTrail module { @@ -186,8 +182,7 @@ return { TropicalOrbitPeriod = 365.242, EarthOrbitRatio = 1, DayLength = 24 - }, - GuiName = "/Solar/EarthTrail" + } } --[[, { diff --git a/data/scene/debugmodel/debugmodel.mod b/data/scene/debugmodel/debugmodel.mod deleted file mode 100644 index 3bfbd088af..0000000000 --- a/data/scene/debugmodel/debugmodel.mod +++ /dev/null @@ -1,25 +0,0 @@ -return { - { - Name = "DebugModel", - Parent = "Root", - Renderable = { - Type = "RenderableModel", - Body = "SUN", - Geometry = { - Type = "MultiModelGeometry", - GeometryFile = "models/OSIRIS-REx GSFC Animation/OSIRIS-REx GSFC Animation/OREXE1.obj", - Magnification = 4, - }, - Textures = { - Type = "simple", - Color = "textures/NHTexture.jpg", - }, - Shading = { - PerformShading = true, - Fadeable = false, - Ghosting = false, - }, - }, - GuiName = "/Solar/DebugModel" - }, -} \ No newline at end of file diff --git a/data/scene/earth/earth.mod b/data/scene/earth/earth.mod index 0456dfaa13..cda7130a76 100644 --- a/data/scene/earth/earth.mod +++ b/data/scene/earth/earth.mod @@ -33,11 +33,8 @@ return { Translation = { Type = "SpiceEphemeris", Body = "EARTH", - Reference = "ECLIPJ2000", Observer = "SUN", - Kernels = { - "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" - } + Kernels = "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" }, Rotation = { Type = "SpiceRotation", diff --git a/data/scene/enlil/enlil.mod b/data/scene/enlil/enlil.mod index ae6f91073f..6d31327448 100644 --- a/data/scene/enlil/enlil.mod +++ b/data/scene/enlil/enlil.mod @@ -4,14 +4,9 @@ return { { Name = "Enlil", Parent = "Root", - Ephemeris = { - Type = "Static", - Position = { 0.0, 0.0, 0.0, 0} - }, RenderableToggle = "e", Renderable = { Type = "RenderableVolumeGL", - ---[[ BoxScaling = { f, f, f}, VolumeName = "EnlilVolume", Volume = "${OPENSPACE_DATA}/enlil/Hong_Xie_120312_SH_1.enlil.0016.cdf", @@ -26,8 +21,6 @@ return { TransferFunction = "transferfunctions/t2.txt", -- TransferFunction = "transferfunctions/t1.txt", Sampler = "sampler.glsl", - --]] - }, - GuiName = "/Volumes/Volume" + } } } diff --git a/data/scene/enlilnh/enlilnh.mod b/data/scene/enlilnh/enlilnh.mod index 78a1e2bd07..b065e04501 100644 --- a/data/scene/enlilnh/enlilnh.mod +++ b/data/scene/enlilnh/enlilnh.mod @@ -3,10 +3,6 @@ return { { Name = "Enlil New Horizons", Parent = "Root", - Ephemeris = { - Type = "Static", - Position = { 0.0, 0.0, 0.0, 0} - }, Renderable = { Type = "RenderableMultiresVolume", ReferenceFrame = "HEEQ", @@ -18,7 +14,6 @@ return { ErrorHistogramsSource = "tsp/enlil_nh_128_128_16_50.errorHistograms", TransferFunction = "transferfunctions/fire.txt", BrickSelector = "tf", - }, - GuiName = "/Volumes/ENLIL New Horizons" + } } } diff --git a/data/scene/fieldlines/fieldlines.mod b/data/scene/fieldlines/fieldlines.mod index c017daa93d..e0609029cb 100644 --- a/data/scene/fieldlines/fieldlines.mod +++ b/data/scene/fieldlines/fieldlines.mod @@ -10,10 +10,6 @@ return { { Name = "Fieldlines1", Parent = "Earth", - Ephemeris = { - Type = "Static", - Position = { 0, 0, 0, 0}, - }, Renderable = { Type = "RenderableFieldlines", VectorField = { @@ -30,16 +26,11 @@ return { Type = "File", File = '${OPENSPACE_DATA}/scene/fieldlines/bats_seeds/BATS_R_US_closed_seeds_all.txt'; } - }, - GuiName = "/Geometry/Fieldlines" + } }, { Name = "Fieldlines2", Parent = "Earth", - Ephemeris = { - Type = "Static", - Position = { 0, 0, 0, 0}, - }, Renderable = { Type = "RenderableFieldlines", VectorField = { @@ -56,16 +47,11 @@ return { Type = "File", File = '${OPENSPACE_DATA}/scene/fieldlines/bats_seeds/BATS_R_US_open_north_all.txt' } - }, - GuiName = "/Geometry/Fieldlines" + } }, { Name = "Fieldlines3", Parent = "Earth", - Ephemeris = { - Type = "Static", - Position = { 0, 0, 0, 0}, - }, Renderable = { Type = "RenderableFieldlines", VectorField = { @@ -82,16 +68,11 @@ return { Type = "File", File = '${OPENSPACE_DATA}/scene/fieldlines/bats_seeds/BATS_R_US_open_south_all.txt' } - }, - GuiName = "/Geometry/Fieldlines" + } }, { Name = "Fieldlines4", Parent = "Earth", - Ephemeris = { - Type = "Static", - Position = { 0, 0, 0, 0}, - }, Renderable = { Type = "RenderableFieldlines", VectorField = { @@ -108,16 +89,11 @@ return { Type = "File", File = '${OPENSPACE_DATA}/scene/fieldlines/bats_seeds/BATS_R_US_solar_wind_all.txt' } - }, - GuiName = "/Geometry/Fieldlines" + } }, { Name = "Fieldlines5", Parent = "Earth", - Ephemeris = { - Type = "Static", - Position = { 0, 0, 0, 0}, - }, Renderable = { Type = "RenderableFieldlines", VectorField = { @@ -134,7 +110,6 @@ return { Type = "File", File = '${OPENSPACE_DATA}/scene/fieldlines/bats_seeds/BATS_R_US_separatrix_seeds_all.txt' } - }, - GuiName = "/Geometry/Fieldlines" + } } } \ No newline at end of file diff --git a/data/scene/flare/flare.mod b/data/scene/flare/flare.mod index 6dbf429c68..c0b9b8b5dd 100644 --- a/data/scene/flare/flare.mod +++ b/data/scene/flare/flare.mod @@ -3,10 +3,6 @@ return { { Name = "Flare", Parent = "Root", - Ephemeris = { - Type = "Static", - Position = { 0, 0, 0, 0} - }, Renderable = { Type = "RenderableFlare", Source = "${OPENSPACE_DATA}/enlil_64_32_8.tsp", @@ -23,7 +19,6 @@ return { tsp_traveral_stepsize = 0.02, raycaster_stepsize = 0.005, - }, - GuiName = "/Volumes/Flare" + } } } \ No newline at end of file diff --git a/data/scene/grids/gridEcliptic/gridEcliptic.mod b/data/scene/grids/gridEcliptic/gridEcliptic.mod index 3aea1790ae..ed4e7fb452 100644 --- a/data/scene/grids/gridEcliptic/gridEcliptic.mod +++ b/data/scene/grids/gridEcliptic/gridEcliptic.mod @@ -3,7 +3,6 @@ return { { Name = "SphericalGrid", Parent = "Root", - Static = true, Renderable = { Type = "RenderableSphericalGrid", GridType = "ECLIPJ2000", @@ -13,22 +12,6 @@ return { -0.09647644, 0.8622859, 0.4971472 , 0.0, 0.0 , 0.0 , 0.0 , 1.0 }, GridSegments = 36, - }, - Ephemeris = { - Type = "Static" -- for now, might change. - }, - - --[[ - Ephemeris = { - Type = "Spice", - Body = "EARTH", - Reference = "ECLIPJ2000", - Observer = "EARTH BARYCENTER", - Kernels = { - "kernels/earth.bsp" - } - }, - --]] - GuiName = "/Grid/Ecliptic" + } } } \ No newline at end of file diff --git a/data/scene/grids/gridEquatorial/gridEquatorial.mod b/data/scene/grids/gridEquatorial/gridEquatorial.mod index e35fdf7ee6..ccee24ccad 100644 --- a/data/scene/grids/gridEquatorial/gridEquatorial.mod +++ b/data/scene/grids/gridEquatorial/gridEquatorial.mod @@ -3,7 +3,6 @@ return { { Name = "SphericalGrid", Parent = "Root", - Static = true, Renderable = { Type = "RenderableSphericalGrid", GridType = "ICRF", @@ -13,11 +12,6 @@ return { -0.483835 , 0.7469823, 0.4559838, 0.0, 0.0 , 0.0 , 0.0 , 1.0 }, GridSegments = 36, - }, - Ephemeris = { - Type = "Static" -- for now, might change. - }, - - GuiName = "/Grid/Equatorial" + } } } \ No newline at end of file diff --git a/data/scene/grids/gridGalactic/gridGalactic.mod b/data/scene/grids/gridGalactic/gridGalactic.mod index 95f25afe4f..b27d939b6c 100644 --- a/data/scene/grids/gridGalactic/gridGalactic.mod +++ b/data/scene/grids/gridGalactic/gridGalactic.mod @@ -3,32 +3,15 @@ return { { Name = "gridGalactic", Parent = "SolarSystem", - Static = true, Renderable = { Type = "RenderableSphericalGrid", GridType = "GALACTIC", GridColor = { 0.0, 0.4, 0.4, 1}, - GridMatrix = { 1.0, 0.0, 0.0, 0.0, - 0.0, 1.0, 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, + GridMatrix = { 1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 }, GridSegments = 36, - }, - Ephemeris = { - Type = "Static" -- for now, might change. - }, - - --[[ - Ephemeris = { - Type = "Spice", - Body = "EARTH", - Reference = "ECLIPJ2000", - Observer = "EARTH BARYCENTER", - Kernels = { - "kernels/earth.bsp" - } - }, - --]] - GuiName = "/Grid/Galactic" + } } } \ No newline at end of file diff --git a/data/scene/imageplane/imageplane.mod b/data/scene/imageplane/imageplane.mod deleted file mode 100644 index 6d6cf14f06..0000000000 --- a/data/scene/imageplane/imageplane.mod +++ /dev/null @@ -1,34 +0,0 @@ -return { - -- Latest image taken by LORRI - --[[ - { - Name = "ImagePlane", - Parent = "PlutoProjection", - Renderable = { - Type = "RenderablePlaneProjection", - Frame = "NH_SPACECRAFT", - DefaultTarget = "PLUTO", - Spacecraft = "NEW HORIZONS", - Instrument = "NH_LORRI", - Moving = false, - Texture = "textures/squarefov.png", - }, - }, - - -- LORRI FoV square - { - Name = "ImagePlane2", - Parent = "NewHorizons", - Renderable = { - Type = "RenderablePlaneProjection", - Frame = "IAU_JUPITER", - DefaultTarget = "JUPITER", - Spacecraft = "NEW HORIZONS", - Instrument = "NH_LORRI", - Moving = true, - Texture = "textures/squarefov.png", - }, - } - ]] -} - diff --git a/data/scene/imageplane/textures/squarefov.png b/data/scene/imageplane/textures/squarefov.png deleted file mode 100644 index 1d48dc35f457893d0c55ee9b85f8b9009c6dc404..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5753 zcmeHL&nrYx6h6=RF*8x5BnGcYp)`|~COjJP79=TTW2GojBt^MV;y;*$t)(gd!TTp{ zretX$Wotq1xo>lOz1}@%aW#v#c;}sN-~G;azkBB0+uX0ME_LMl@&M4`FIUz9nq}Gy z*;e_w8ko3|uiWwS_6fk`Fh0)tt)>3ebenm}-m<2cNUmk-ZjK z;i!K0J~M;_Um3-t!Hg-buu>+lMAA|;fD2UwqubzNFsIUEfKCixN|Xx?NVu*= diff --git a/data/scene/imageplane/textures/test.jpg b/data/scene/imageplane/textures/test.jpg deleted file mode 100644 index 1978087d080157c1f9fb3cd98e6047727a5c7d91..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65106 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�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 diff --git a/data/scene/juno/juno/juno.mod b/data/scene/juno/juno/juno.mod index 01006cfa80..ec95c0c83f 100644 --- a/data/scene/juno/juno/juno.mod +++ b/data/scene/juno/juno/juno.mod @@ -31,7 +31,6 @@ return { Ephemeris = { Type = "Spice", Body = "JUNO", - Reference = "GALACTIC", Observer = "JUPITER BARYCENTER", Kernels = { "spice/JNO_SCLKSCET.00039.tsc", @@ -120,8 +119,7 @@ return { "spice/ck/juno_sc_prl_160729_160826_jm0002rp_v01.bc", "spice/ck/juno_sc_prl_161115_161213_jx0405rp_v01.bc" } - }, - GuiName = "/Solar/Juno" + } }, --NewHorizonsTrail module { diff --git a/data/scene/jupiter/callisto/callisto.mod b/data/scene/jupiter/callisto/callisto.mod index 1288472c2a..1af5b70f73 100644 --- a/data/scene/jupiter/callisto/callisto.mod +++ b/data/scene/jupiter/callisto/callisto.mod @@ -26,11 +26,8 @@ return { Translation = { Type = "SpiceEphemeris", Body = "CALLISTO", - Reference = "ECLIPJ2000", Observer = "JUPITER BARYCENTER", - Kernels = { - "${OPENSPACE_DATA}/spice/jup260.bsp" - } + Kernels = "${OPENSPACE_DATA}/spice/jup260.bsp" }, Rotation = { Type = "SpiceRotation", @@ -41,8 +38,7 @@ return { Type = "StaticScale", Scale = 1, }, - }, - GuiName = "/Solar/Planets/Callisto" + } }, -- CallistoTrail module { @@ -62,7 +58,6 @@ return { Color = "${COMMON_MODULE}/textures/glare_blue.png", -- need to add different texture }, - }, - GuiName = "/Solar/CallistoTrail" + } } } diff --git a/data/scene/jupiter/europa/europa.mod b/data/scene/jupiter/europa/europa.mod index 15ec4270e2..44c2ded0a5 100644 --- a/data/scene/jupiter/europa/europa.mod +++ b/data/scene/jupiter/europa/europa.mod @@ -26,11 +26,8 @@ return { Translation = { Type = "SpiceEphemeris", Body = "EUROPA", - Reference = "ECLIPJ2000", Observer = "JUPITER BARYCENTER", - Kernels = { - "${OPENSPACE_DATA}/spice/jup260.bsp" - } + Kernels = "${OPENSPACE_DATA}/spice/jup260.bsp" }, Rotation = { Type = "SpiceRotation", @@ -41,8 +38,7 @@ return { Type = "StaticScale", Scale = 1, }, - }, - GuiName = "/Solar/Planets/EUROPA" + } }, -- EuropaTrail module { @@ -62,7 +58,6 @@ return { Color = "${COMMON_MODULE}/textures/glare_blue.png", -- need to add different texture }, - }, - GuiName = "/Solar/EuropaTrail" + } } } diff --git a/data/scene/jupiter/ganymede/ganymede.mod b/data/scene/jupiter/ganymede/ganymede.mod index b7710e3124..c31809f2be 100644 --- a/data/scene/jupiter/ganymede/ganymede.mod +++ b/data/scene/jupiter/ganymede/ganymede.mod @@ -26,11 +26,8 @@ return { Translation = { Type = "SpiceEphemeris", Body = "GANYMEDE", - Reference = "ECLIPJ2000", Observer = "JUPITER BARYCENTER", - Kernels = { - "${OPENSPACE_DATA}/spice/jup260.bsp" - } + Kernels = "${OPENSPACE_DATA}/spice/jup260.bsp" }, Rotation = { Type = "SpiceRotation", @@ -41,8 +38,7 @@ return { Type = "StaticScale", Scale = 1, }, - }, - GuiName = "/Solar/Planets/Ganymede" + } }, -- GanymedeTrail module { @@ -62,7 +58,6 @@ return { Color = "${COMMON_MODULE}/textures/glare_blue.png", -- need to add different texture }, - }, - GuiName = "/Solar/GanymedeTrail" + } } } diff --git a/data/scene/jupiter/io/io.mod b/data/scene/jupiter/io/io.mod index 7019330621..ba04eb8c6d 100644 --- a/data/scene/jupiter/io/io.mod +++ b/data/scene/jupiter/io/io.mod @@ -26,11 +26,8 @@ return { Translation = { Type = "SpiceEphemeris", Body = "IO", - Reference = "ECLIPJ2000", Observer = "JUPITER BARYCENTER", - Kernels = { - "${OPENSPACE_DATA}/spice/jup260.bsp" - } + Kernels = "${OPENSPACE_DATA}/spice/jup260.bsp" }, Rotation = { Type = "SpiceRotation", @@ -41,8 +38,7 @@ return { Type = "StaticScale", Scale = 1, }, - }, - GuiName = "/Solar/Planets/Jupiter" + } }, -- IoTrail module { @@ -62,7 +58,6 @@ return { Color = "${COMMON_MODULE}/textures/glare_blue.png", -- need to add different texture }, - }, - GuiName = "/Solar/IoTrail" + } } } diff --git a/data/scene/jupiter/jupiter/jupiter.mod b/data/scene/jupiter/jupiter/jupiter.mod index b8c3752bf6..6d51c47314 100644 --- a/data/scene/jupiter/jupiter/jupiter.mod +++ b/data/scene/jupiter/jupiter/jupiter.mod @@ -7,11 +7,8 @@ return { Translation = { Type = "SpiceEphemeris", Body = "JUPITER BARYCENTER", - Reference = "ECLIPJ2000", Observer = "SUN", - Kernels = { - "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" - } + Kernels = "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" }, }, }, @@ -52,8 +49,7 @@ return { Type = "StaticScale", Scale = 1, }, - }, - GuiName = "/Solar/Planets/Jupiter" + } }, -- JupiterTrail module { @@ -73,7 +69,6 @@ return { Color = "${COMMON_MODULE}/textures/glare_blue.png", -- need to add different texture }, - }, - GuiName = "/Solar/JupiterTrail" + } } } diff --git a/data/scene/jupiter/textures/Jupiter-text.png b/data/scene/jupiter/textures/Jupiter-text.png deleted file mode 100644 index c8ec1a2b71cb62ad6697a0d733deffaf3723683c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2406 zcmdT_eN>ZG7{Bkfwh4&S4H;}hAVWQ5Vy1{Kn0$%}LQz5)jjy2%9Js;25Vp`07$0>+ z91MZ5BoYx4430G4P?!e?BS^+KD9S)gD4>9-b?>xJ=hW%zzwSBjec$)F&wW0A&+oZ6 zGr-?xxrwz20ARWAF3*<$AdbWDMJgH2&%P2n0bk_s7kxb88;%8!D{1hxEN)kb7ywf` zdN5E}#DqeM#MjS@GEA_ht$J>gO09z;&cUEyiH9gQHtLWB{sQ1}I4VpM6=^FyC^=y3 zr^v0=)_qi0yf=qp7uY9L z=R)=W@u+TeB2|}bGy=Po& z?eBz3cb!N8#Q6)xZl%#zhTVm3@or_fGE$Q!EbW{p!T@4UTwO3^S|pmf3wa7+UBmix zKlM+R`AX-M3$DWB*%M~!#2=!$GrdPdC!#a*c8jCx4pc~f_Q{EDPUr~ddhbskpknRc zkvOuA?z0cHwI2w|*BkDOAE?OOtrYL?Ha-M-JxgOOrMQw(a`58_Y1fMSCb|TWzH}~8 zw-mndWYXtbM_Skc$JdR69;RWsH)f#Mg)CJVy0^nR@XNAmmUE?TXRY*|t<>mtsB7Xd6n}6im9CD8U%B7g*qid?tJF7X6jY86@AqJ&9Ux;%Q5vd@Z704&K^1CZfY5j* z0SMymnV$A0zbrVn>D{u64dxmIo|PBb8}{X%zcs(lYIta7^3>dj z?^Qs7Hq8csk0+I0nVBjK`*CRkK#!VZ$%}N$$5=%Y>lN748;jp}PK4 z=kkF(00U-3T`~s{lw+Isl+AVVCo#lY)9W16BK&2=p#=~ys(8rZl z&8&p-30_B)sjop|J?^JJYmCO5n&(VVJ~UrM9q@^Ec!QA=H;BkZ?P$W`Y6oM{bBvyF z-N1SR^tA1otnNqCVLKz=A~#OEJVF3C+-b9cIS1sg%a!dyhI*)%=I7u3f}>xBfJ$$0 zNncn79pPgvWY0D~JMCi0#HsPQS#EiiAA&=9D1y-4a!-4Z13QsVe4#jat}nO`H?i4& z^3}piO{hG38kSwo^*Se5%LdTampQm1|-?fbzP40~G>-#^?25rvnBLCkp!dGdiQ_9kc%_h!b$5|9mh zvl&DhK0PZrx{>V+)o=%<#(A`Rp}x%umV`gEV$8~`y}SV(o-vn?hN@G$^cKNmjiU(d zr|YrHfzqm?ACBgx-P&CJD%^leSbSxVOH0$sVj<29c7)#ex0hG@Rn8pS9QstuaTojx za}V%f6;@CX{?Yfz)<<)S%8zQVOy(sJY&+z3iGyajeW3qF`^pXNC%121-A%=(g%|9A zTs7lRbuYN`vx3;I-q9`U{R!Et&O}5ET4Uok=@P!sAab4Rq4swSrKLVJVdw>_go%nH z%E`PrEMT@!MCH2`?|vyvrC0|*$--*sUs2S^OGK8euNOtI8DRoY{c+F8>5W71Rw8g{ zdVmz;hbE)FJel#Z&mKCFY+K>AB{$E2zazITq$A#;B6wjylz+S1c-ZenkRYg6WZR8e z8RE0QDw1{ts592}78etN5iTm!V`}LVUJ(&_z3u|QbW&0?hc;$x -#include -#include +#include #include +#include + +#include namespace openspace { -class Ephemeris { +class Ephemeris : public properties::PropertyOwner { public: static Ephemeris* createFromDictionary(const ghoul::Dictionary& dictionary); - Ephemeris(const ghoul::Dictionary& dictionary); virtual ~Ephemeris(); virtual bool initialize(); - virtual const glm::dvec3& position() const = 0; + virtual glm::dvec3 position() const = 0; virtual void update(const UpdateData& data); static openspace::Documentation Documentation(); - -protected: - Ephemeris(); }; } // namespace openspace diff --git a/include/openspace/scene/scale.h b/include/openspace/scene/scale.h index 86e4fcaac8..40a694af4a 100644 --- a/include/openspace/scene/scale.h +++ b/include/openspace/scene/scale.h @@ -25,11 +25,12 @@ #ifndef __SCALE_H__ #define __SCALE_H__ -#include -#include #include #include +#include + +#include namespace openspace { @@ -37,16 +38,12 @@ class Scale : public properties::PropertyOwner { public: static Scale* createFromDictionary(const ghoul::Dictionary& dictionary); - Scale(const ghoul::Dictionary& dictionary); virtual ~Scale(); virtual bool initialize(); virtual double scaleValue() const = 0; virtual void update(const UpdateData& data); static openspace::Documentation Documentation(); - -protected: - Scale(); }; } // namespace openspace diff --git a/modules/base/basemodule.cpp b/modules/base/basemodule.cpp index 8694b42b35..e1725442fe 100644 --- a/modules/base/basemodule.cpp +++ b/modules/base/basemodule.cpp @@ -136,7 +136,9 @@ void BaseModule::internalInitialize() { std::vector BaseModule::documentations() const { return { - StaticScale::Documentation() + StaticScale::Documentation(), + StaticEphemeris::Documentation(), + SpiceEphemeris::Documentation() }; } diff --git a/modules/base/ephemeris/spiceephemeris.cpp b/modules/base/ephemeris/spiceephemeris.cpp index 85df8a21c9..59d6e6a1b4 100644 --- a/modules/base/ephemeris/spiceephemeris.cpp +++ b/modules/base/ephemeris/spiceephemeris.cpp @@ -29,83 +29,118 @@ #include -namespace { - const std::string _loggerCat = "SpiceEphemeris"; - //const std::string keyGhosting = "EphmerisGhosting"; +#include +namespace { const std::string KeyBody = "Body"; - const std::string KeyOrigin = "Observer"; + const std::string KeyObserver = "Observer"; const std::string KeyKernels = "Kernels"; + + const std::string ReferenceFrame = "GALACTIC"; } namespace openspace { +Documentation SpiceEphemeris::Documentation() { + using namespace openspace::documentation; + + return { + "Spice Translation", + "base_translation_spicetranslation", + { + { + "Type", + new StringEqualVerifier("SpiceEphemeris"), + "", + Optional::No + }, + { + KeyBody, + new StringAnnotationVerifier("A valid SPICE NAIF name or identifier"), + "This is the SPICE NAIF name for the body whose translation is to be " + "computed by the SpiceTranslation. It can either be a fully qualified " + "name (such as 'EARTH') or a NAIF integer id code (such as '399').", + Optional::No + }, + { + KeyObserver, + new StringAnnotationVerifier("A valid SPICE NAIF name or identifier"), + "This is the SPICE NAIF name for the parent of the body whose " + "translation is to be computed by the SpiceTranslation. It can either be " + "a fully qualified name (such as 'SOLAR SYSTEM BARYCENTER') or a NAIF " + "integer id code (such as '0').", + Optional::No + }, + { + KeyKernels, + new OrVerifier( + new TableVerifier({ + { "*", new StringVerifier } + }), + new StringVerifier + ), + "A single kernel or list of kernels that this SpiceTranslation depends " + "on. All provided kernels will be loaded before any other operation is " + "performed.", + Optional::Yes + } + }, + Exhaustive::Yes + }; +} + SpiceEphemeris::SpiceEphemeris(const ghoul::Dictionary& dictionary) - : _targetName("") - , _originName("") - , _position() + : _target("target", "Target", "") + , _origin("origin", "Origin", "") , _kernelsLoadedSuccessfully(true) { - const bool hasBody = dictionary.getValue(KeyBody, _targetName); - if (!hasBody) - LERROR("SpiceEphemeris does not contain the key '" << KeyBody << "'"); + documentation::testSpecificationAndThrow( + Documentation(), + dictionary, + "SpiceEphemeris" + ); - const bool hasObserver = dictionary.getValue(KeyOrigin, _originName); - if (!hasObserver) - LERROR("SpiceEphemeris does not contain the key '" << KeyOrigin << "'"); - - //dictionary.getValue(keyGhosting, _ghosting); - - ghoul::Dictionary kernels; - dictionary.getValue(KeyKernels, kernels); - for (size_t i = 1; i <= kernels.size(); ++i) { - std::string kernel; - bool success = kernels.getValue(std::to_string(i), kernel); - if (!success) { - LERROR("'" << KeyKernels << "' has to be an array-style table"); - break; - } + _target = dictionary.value(KeyBody); + _origin = dictionary.value(KeyObserver); + auto loadKernel = [](const std::string& kernel) { if (!FileSys.fileExists(kernel)) { - LERROR("Kernel '" << kernel << "' does not exist"); - continue; + throw SpiceManager::SpiceException("Kernel '" + kernel + "' does not exist"); } try { SpiceManager::ref().loadKernel(kernel); - _kernelsLoadedSuccessfully = true; } - catch (const SpiceManager::SpiceException& e) { - LERROR("Could not load SPICE kernel: " << e.what()); - _kernelsLoadedSuccessfully = false; + catch (const SpiceManager::SpiceException& exception) { + LERRORC("SpiceEphemeris", exception.message); + } + }; + + if (dictionary.hasKey(KeyKernels)) { + // Due to the specification, we can be sure it is either a Dictionary or a string + if (dictionary.hasValue(KeyKernels)) { + std::string kernel = dictionary.value(KeyKernels); + loadKernel(kernel); + } + else { + ghoul::Dictionary kernels = dictionary.value(KeyKernels); + for (size_t i = 1; i <= kernels.size(); ++i) { + std::string kernel = kernels.value(std::to_string(i)); + loadKernel(kernel); + } } } } -const glm::dvec3& SpiceEphemeris::position() const { +glm::dvec3 SpiceEphemeris::position() const { return _position; } void SpiceEphemeris::update(const UpdateData& data) { - if (!_kernelsLoadedSuccessfully) - return; - double lightTime = 0.0; - glm::dvec3 position = SpiceManager::ref().targetPosition( - _targetName, _originName, "GALACTIC", {}, data.time, lightTime); - - //double interval = openspace::ImageSequencer::ref().getIntervalLength(); - //if (_ghosting == "TRUE" && interval > 60){ - // double _time = openspace::ImageSequencer::ref().getNextCaptureTime(); - // SpiceManager::ref().getTargetPosition(_targetName, _originName, - // "GALACTIC", "NONE", _time, position, lightTime); - //} - // - - - //_position = psc::CreatePowerScaledCoordinate(position.x, position.y, position.z); - //_position[3] += 3; - _position = position * glm::pow(10.0, 3.0); + _position = SpiceManager::ref().targetPosition( + _target, _origin, ReferenceFrame, {}, data.time, lightTime + ) * glm::pow(10.0, 3.0); } -} // namespace openspace \ No newline at end of file +} // namespace openspace diff --git a/modules/base/ephemeris/spiceephemeris.h b/modules/base/ephemeris/spiceephemeris.h index 973c388072..92d9991e1e 100644 --- a/modules/base/ephemeris/spiceephemeris.h +++ b/modules/base/ephemeris/spiceephemeris.h @@ -27,23 +27,25 @@ #include -#include +#include +#include namespace openspace { class SpiceEphemeris : public Ephemeris { public: SpiceEphemeris(const ghoul::Dictionary& dictionary); - virtual const glm::dvec3& position() const; + glm::dvec3 position() const; void update(const UpdateData& data) override; + static openspace::Documentation Documentation(); + private: - std::string _targetName; - std::string _originName; + properties::StringProperty _target; + properties::StringProperty _origin; + glm::dvec3 _position; bool _kernelsLoadedSuccessfully; - //std::string _ghosting; - std::string _name; }; } // namespace openspace diff --git a/modules/base/ephemeris/staticephemeris.cpp b/modules/base/ephemeris/staticephemeris.cpp index e95e324546..551da7a05c 100644 --- a/modules/base/ephemeris/staticephemeris.cpp +++ b/modules/base/ephemeris/staticephemeris.cpp @@ -24,27 +24,69 @@ #include +#include + namespace { const std::string KeyPosition = "Position"; } namespace openspace { -StaticEphemeris::StaticEphemeris(const ghoul::Dictionary& dictionary) - : _position(0.0, 0.0, 0.0) +Documentation StaticEphemeris::Documentation() { + using namespace openspace::documentation; + return { + "Static Translation", + "base_transform_translation_static", + { + { + "Type", + new StringEqualVerifier("StaticEphemeris"), + "", + Optional::No + }, + { + KeyPosition, + new DoubleVector3Verifier, + "Specifies the position (in meters) that this scenegraph node is located " + "at relative to its parent", + Optional::No + } + }, + Exhaustive::Yes + }; +} + + +StaticEphemeris::StaticEphemeris() + : _position( + "position", + "Position", + glm::dvec3(0.0), + glm::dvec3(-std::numeric_limits::max()), + glm::dvec3(std::numeric_limits::max()) + ) { - const bool hasPosition = dictionary.hasKeyAndValue(KeyPosition); - if (hasPosition) { - dictionary.getValue(KeyPosition, _position); - } + addProperty(_position); +} + +StaticEphemeris::StaticEphemeris(const ghoul::Dictionary& dictionary) + : StaticEphemeris() +{ + documentation::testSpecificationAndThrow( + Documentation(), + dictionary, + "StaticEphemeris" + ); + + _position = dictionary.value(KeyPosition); } StaticEphemeris::~StaticEphemeris() {} -const glm::dvec3& StaticEphemeris::position() const { +glm::dvec3 StaticEphemeris::position() const { return _position; } void StaticEphemeris::update(const UpdateData&) {} -} // namespace openspace \ No newline at end of file +} // namespace openspace diff --git a/modules/base/ephemeris/staticephemeris.h b/modules/base/ephemeris/staticephemeris.h index 491a872b7a..d85f3eba41 100644 --- a/modules/base/ephemeris/staticephemeris.h +++ b/modules/base/ephemeris/staticephemeris.h @@ -27,17 +27,23 @@ #include +#include +#include + namespace openspace { -class StaticEphemeris: public Ephemeris { +class StaticEphemeris : public Ephemeris { public: - StaticEphemeris(const ghoul::Dictionary& dictionary - = ghoul::Dictionary()); + StaticEphemeris(); + StaticEphemeris(const ghoul::Dictionary& dictionary); virtual ~StaticEphemeris(); - virtual const glm::dvec3& position() const; + virtual glm::dvec3 position() const; virtual void update(const UpdateData& data) override; + + static openspace::Documentation Documentation(); + private: - glm::dvec3 _position; + properties::DVec3Property _position; }; } // namespace openspace diff --git a/modules/base/rendering/renderableplanet.cpp b/modules/base/rendering/renderableplanet.cpp index 8cc278a29c..eac80732c3 100644 --- a/modules/base/rendering/renderableplanet.cpp +++ b/modules/base/rendering/renderableplanet.cpp @@ -599,8 +599,7 @@ bool RenderablePlanet::isReady() const { return ready; } -void RenderablePlanet::render(const RenderData& data) -{ +void RenderablePlanet::render(const RenderData& data) { // activate shader _programObject->activate(); diff --git a/src/documentation/documentation.cpp b/src/documentation/documentation.cpp index 5cda43ce74..52a652ed92 100644 --- a/src/documentation/documentation.cpp +++ b/src/documentation/documentation.cpp @@ -51,6 +51,22 @@ namespace std { std::string to_string(std::string value) { return value; } + +std::string to_string(openspace::documentation::TestResult::Offense::Reason reason) { + switch (reason) { + case openspace::documentation::TestResult::Offense::Reason::ExtraKey: + return "Extra key"; + case openspace::documentation::TestResult::Offense::Reason::MissingKey: + return "Missing key"; + case openspace::documentation::TestResult::Offense::Reason::UnknownIdentifier: + return "Unknown identifier"; + case openspace::documentation::TestResult::Offense::Reason::Verification: + return "Verification failed"; + case openspace::documentation::TestResult::Offense::Reason::WrongType: + return "Wrong type"; + } +} + } // namespace std namespace openspace { diff --git a/src/scene/ephemeris.cpp b/src/scene/ephemeris.cpp index 7bba161310..9051d5a977 100644 --- a/src/scene/ephemeris.cpp +++ b/src/scene/ephemeris.cpp @@ -51,7 +51,8 @@ Documentation Ephemeris::Documentation() { "on application startup into the FactoryDocumentation.", Optional::No } - } + }, + Exhaustive::No }; } @@ -74,10 +75,6 @@ Ephemeris* Ephemeris::createFromDictionary(const ghoul::Dictionary& dictionary) return result; } -Ephemeris::Ephemeris() {} - -Ephemeris::Ephemeris(const ghoul::Dictionary& dictionary) {} - Ephemeris::~Ephemeris() {} bool Ephemeris::initialize() { diff --git a/src/scene/scale.cpp b/src/scene/scale.cpp index 22bd2d7cbe..c58c83ead6 100644 --- a/src/scene/scale.cpp +++ b/src/scene/scale.cpp @@ -51,7 +51,8 @@ Documentation Scale::Documentation() { "application startup into the FactoryDocumentation.", Optional::No } - } + }, + Exhaustive::No }; } @@ -71,10 +72,6 @@ Scale* Scale::createFromDictionary(const ghoul::Dictionary& dictionary) { return result; } -Scale::Scale() {} - -Scale::Scale(const ghoul::Dictionary& dictionary) {} - Scale::~Scale() {} bool Scale::initialize() { diff --git a/src/scene/scenegraph.cpp b/src/scene/scenegraph.cpp index 4c84157a54..ed78e988c0 100644 --- a/src/scene/scenegraph.cpp +++ b/src/scene/scenegraph.cpp @@ -345,8 +345,17 @@ bool SceneGraph::loadFromFile(const std::string& sceneDescription) { }; for (const ModuleInformation& i : moduleDictionaries) { - LINFO("Adding module: " << i.moduleName); - addModule(i); + try { + LINFO("Adding module: " << i.moduleName); + addModule(i); + } + catch (const documentation::SpecificationError& specError) { + LERROR("Error loading module: " << i.moduleName); + LERRORC(specError.component, specError.message); + for (const auto& offense : specError.result.offenses) { + LERRORC(offense.offender, std::to_string(offense.reason)); + } + } } } // ghoul::lua::destroyLuaState(state);