diff --git a/.gitignore b/.gitignore
index c413fb7c41..0980cb3856 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,21 +1,21 @@
-bin/
-build/
-cache/
-tmp/
-ext/SGCT
-.DS_Store
-*.swp
-.vscode
-
-# Windows system files:
-Thumbs.db
-
-# Emacs backup files:
*~
+*.swp
+.DS_Store
+.vscode
+/bin/
+/build/
+/cache/
+Thumbs.db
+tmp/
+
+/documentation
+/doc
+/ext/SGCT
-# generated glsl files
*.gglsl
*.GhoulGenerated.glsl
+*.OpenSpaceGenerated.glsl
+
shaders/generated/*
# CMake stuff
@@ -29,135 +29,67 @@ install_manifest.txt
.cproject
.project
-# Doxygen stuff
-html/
-latex/
shaders/ABuffer/constants.hglsl
-*.OpenSpaceGenerated.glsl
-LuaScripting.txt
-Properties.txt
log.html
-gui/externaltimecontrol/CMakeLists.txt
-gui/externaltimecontrol/main.cpp
-gui/externaltimecontrol/mainwindow.cpp
-gui/externaltimecontrol/mainwindow.h
-data/scene/rosetta/67P/obj/67P_rotated_5_130.obj
-data/spice/NewHorizonsKernels/
-data/spice/RosettaKernels/
-data/scene/newhorizons/pluto/pluto/textures/
-data/scene/newhorizons/pluto/pluto/utcEvents.txt
-data/scene/rosetta/rosetta/obj/mainbodyros.obj
-data/scene/rosetta/rosetta/obj/solarpanelleft.obj
-data/scene/rosetta/rosetta/obj/solarpanelright.obj
-data/scene/rosetta/rosetta/textures/defaultProj.png
-data/scene/rosetta/rosetta/textures/glare_blue.png
-data/scene/rosetta/rosetta/textures/gray.png
-data/scene/rosetta/rosetta/textures/squarefov.png
-data/scene/saturn/textures/saturn.jpg
-data/scene/stars/colorbv.cmap
-data/scene/stars/speck/stars.speck
-data/scene/stars/textures/glare.png
-data/scene/stars/textures/halo.png
-data/scene/sun/textures/marker.png
-data/scene/sun/textures/sun-glare.png
-data/scene/sun/textures/sun.jpg
-data/scene/uranus/textures/uranus.jpg
-data/scene/venus/textures/venus.jpg
-data/scene/dawn/vestaprojection/VestaComet/VestaComet_5000.obj
-data/spice/DawnKernels/
-data/scene/newhorizons/jupiter/jupiter/ProjectionsOfInterest/
-data/scene/rosetta/67P/textures/black.jpg
-data/scene/rosetta/67P/textures/defaultProj.png
-data/scene/rosetta/67P/textures/gray.jpg
-data/scene/rosetta/67P/textures/gray.png
-data/scene/rosetta/67P/textures/texmapflipped.jpg
-data/scene/rosetta/67P/textures/white.jpg
-data/scene/rosetta/67P/textures/white.png
-data/scene/newhorizons/jupiter/callisto/textures/callisto.jpg
-data/scene/dawn/ceres/textures/gray.png
-data/scene/newhorizons/pluto/charon/textures/Charon-Text.png
-data/scene/newhorizons/pluto/charon/textures/charon_highres.jpg
-data/scene/newhorizons/pluto/charon/textures/charon_highres_annotated.jpg
-data/scene/newhorizons/pluto/charon/textures/defaultProj.png
-data/scene/dawn/dawn/obj/mainbodydawn.obj
-data/scene/dawn/dawn/obj/solarpanelleft.obj
-data/scene/dawn/dawn/obj/solarpanelright.obj
-data/scene/dawn/dawn/textures/glare_blue.png
-data/scene/dawn/dawn/textures/gray.png
-data/scene/earth/textures/ToastMapOfEarth.jpg
-data/scene/earth/textures/earth_bluemarble.jpg
-data/scene/earth/textures/earth_bluemarble_height.jpg
-data/scene/earth/textures/earth_night.jpg
-data/scene/earth/textures/marker.png
-data/scene/earth/textures/earth_clouds.jpg
-data/scene/earth/textures/earth_reflectance.png
-data/scene/moon/textures/Moon16k.dds
-data/scene/newhorizons/jupiter/europa/textures/europa.jpg
-data/scene/newhorizons/jupiter/ganymede/textures/ganymede.jpg
-data/scene/newhorizons/jupiter/io/textures/io.jpg
-data/scene/jupiter/jupiter/textures/jupiter.jpg
-data/scene/mars/textures/mars.jpg
-data/scene/mercury/textures/mercury.jpg
-data/scene/milkyway/textures/DarkUniverse_mellinger_8k.jpg
-data/scene/neptune/textures/neptune.jpg
-data/scene/newhorizons/newhorizons/models/Labels.obj
-data/scene/newhorizons/newhorizons/models/NewHorizonsCleanModel.obj
-data/scene/newhorizons/newhorizons/textures/NHTexture.jpg
-data/scene/newhorizons/newhorizons/textures/goldfoilbump.tif
-data/scene/newhorizons/newhorizons/textures/labels.png
-data/scene/pluto/textures/
-data/scene/pluto/textures/Shenk_180.jpg
-data/scene/pluto/textures/pluto_highres_180.jpg
-data/scene/newhorizons/pluto/pluto/assets/core_v9h_obs_getmets_v8_time_fix_nofrcd_mld.txt
-data/scene/newhorizons/pluto/pluto/textures/3.jpg
-data/scene/newhorizons/pluto/pluto/textures/Pluto-Text.png
-data/scene/dawn/vestaprojection/VestaComet/VestaComet.mtl
-data/scene/dawn/vestaprojection/textures/defaultProj_backup.png
-data/scene/dawn/vestaprojection/textures/dummy.jpg
-data/scene/dawn/vestaprojection/textures/glare.png
-data/scene/dawn/vestaprojection/textures/projectMe.png
-data/spice/MAR063.BSP
-data/spice/de430_1850-2150.bsp
-data/spice/jup260.bsp
-data/BATSRUS.cdf
-data/ENLIL.cdf
-data/scene/newhorizons/pluto/pluto/images
-data/spice/nh_kernels/
-data/scene/jupiter/jupiter/textures/Jupiter-text.png
-data/scene/jupiter/callisto/textures/callisto.jpg
-data/scene/jupiter/europa/textures/europa.jpg
-data/scene/jupiter/ganymede/textures/ganymede.jpg
-data/scene/jupiter/io/textures/io.jpg
-data/scene/milkyway-eso/textures/eso0932a_blend.png
-data/scene/stars-denver/denver_colorbv.cmap
-data/scene/stars-denver/speck/stars.speck
-data/scene/stars-denver/textures/halo.png
-data/scene/newhorizons/pluto/pluto/full_images/
-data/scene/rosetta/67P/rosettaimages/
-data/spice/RosettaKernels_New/
-data/scene/newhorizons/pluto/charon/utcEvents.txt
-data/scene/rosetta/67P/obj/67P_HD_2015-05-09.obj
-data/scene/rosetta/67P/obj/may9_map.jpg
-data/scene/rosetta/67P/textures/may9_map.jpg
-data/scene/newhorizons/pluto/charon/textures/cpdem-Mcolor2-MLorriCA-lr-5_ZMfs-cyl.jpg
-data/scene/newhorizons/pluto/charon/textures/cpmap_cyl_HR_0e.jpg
-data/scene/volumetricmilkyway/milkyway/
ScriptLog.txt
-data/scene/atmosphereearth/textures/ToastMapOfEarth.jpg
-data/scene/atmosphereearth/textures/earth_bluemarble.jpg
-data/scene/atmosphereearth/textures/earth_bluemarble_height.jpg
-data/scene/atmosphereearth/textures/earth_clouds.jpg
-data/scene/atmosphereearth/textures/earth_night.jpg
-data/scene/atmosphereearth/textures/earth_reflectance.png
-data/scene/atmosphereearth/textures/marker.png
-data/scene/juno/juno/textures
-data/scene/juno/juno/spice
+
+data/scene/atmosphereearth/textures
+data/scene/dawn/ceres/textures
+data/scene/dawn/dawn/obj
+data/scene/dawn/dawn/textures
+data/scene/dawn/vestaprojection/textures
+data/scene/dawn/vestaprojection/VestaComet
+data/scene/debugglobe/textures
+data/scene/earth/textures
data/scene/juno/juno/Juno.mtl
data/scene/juno/juno/Juno.obj
-KeyboardMapping.txt
-saturn_rings.png
-data/scene/debugglobe/textures/earth_clouds.jpg
-data/scene/debugglobe/textures/earth_reflectance.png
-data/scene/rosetta/rosetta/obj/Rosetta.obj
-data/scene/rosetta/rosetta/rosetta/
-data/scene/rosetta/rosetta/textures/
+data/scene/juno/juno/spice
+data/scene/juno/juno/textures
+data/scene/jupiter/callisto/textures
+data/scene/jupiter/europa/textures
+data/scene/jupiter/ganymede/textures
+data/scene/jupiter/io/textures
+data/scene/jupiter/jupiter/textures
+data/scene/mars/textures
+data/scene/mercury/textures
+data/scene/milkyway/textures
+data/scene/milkyway-eso/textures
+data/scene/moon/textures
+data/scene/neptune/textures
+data/scene/newhorizons/jupiter/callisto/textures
+data/scene/newhorizons/jupiter/europa/textures
+data/scene/newhorizons/jupiter/ganymede/textures
+data/scene/newhorizons/jupiter/io/textures
+data/scene/newhorizons/jupiter/jupiter/ProjectionsOfInterest
+data/scene/newhorizons/newhorizons/models
+data/scene/newhorizons/newhorizons/textures
+data/scene/newhorizons/pluto/charon/textures
+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/pluto/textures
+data/scene/saturn/textures
+data/scene/rosetta/67P/obj
+data/scene/rosetta/67P/rosettaimages
+data/scene/rosetta/67P/textures
+data/scene/rosetta/rosetta/rosetta
+data/scene/rosetta/rosetta/textures
+data/scene/stars/colorbv.cmap
+data/scene/stars/speck
+data/scene/stars/textures
+data/scene/stars-denver/denver_colorbv.cmap
+data/scene/stars-denver/speck
+data/scene/stars-denver/textures
+data/scene/sun/textures
+data/scene/uranus/textures
+data/scene/venus/textures
+data/scene/volumetricmilkyway/milkyway
+data/spice/DawnKernels
+data/spice/jup260.bsp
+data/spice/de430_1850-2150.bsp
+data/spice/MAR063.BSP
+data/spice/NewHorizonsKernels
+data/spice/nh_kernels
+data/spice/Rosetta
+
diff --git a/Doxyfile b/Doxyfile
index f2d2cc9a81..5217764619 100644
--- a/Doxyfile
+++ b/Doxyfile
@@ -1,45 +1,19 @@
-# Doxyfile 1.7.6.1
+# Doxyfile 1.8.8
#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------
-
+
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = OpenSpace
PROJECT_NUMBER =
PROJECT_LOGO =
OUTPUT_DIRECTORY = doc/
-CREATE_SUBDIRS = NO
-OUTPUT_LANGUAGE = English
-BRIEF_MEMBER_DESC = YES
-REPEAT_BRIEF = YES
ALWAYS_DETAILED_SEC = YES
-INLINE_INHERITED_MEMB = NO
-FULL_PATH_NAMES = YES
JAVADOC_AUTOBRIEF = YES
QT_AUTOBRIEF = YES
-
-# This tag can be used to specify a number of aliases that acts
-# as commands in the documentation. An alias has the form "name=value".
-# For example adding "sideeffect=\par Side Effects:\n" will allow you to
-# put the command \sideeffect (or @sideeffect) in the documentation, which
-# will result in a user-defined paragraph with heading "Side Effects:".
-# You can put \n's in the value part of an alias to insert newlines.
-
-ALIASES =
-BUILTIN_STL_SUPPORT = NO
-
-SUBGROUPING = YES
-
-# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and
-# unions are shown inside the group in which they are included (e.g. using
-# @ingroup) instead of on a separate page (for HTML and Man pages) or
-# section (for LaTeX and RTF).
-
-INLINE_GROUPED_CLASSES = NO
INLINE_SIMPLE_STRUCTS = YES
-TYPEDEF_HIDES_STRUCT = NO
-LOOKUP_CACHE_SIZE = 1
+LOOKUP_CACHE_SIZE = 9
#---------------------------------------------------------------------------
# Build related configuration options
@@ -48,405 +22,83 @@ LOOKUP_CACHE_SIZE = 1
EXTRACT_ALL = YES
EXTRACT_PRIVATE = YES
EXTRACT_STATIC = YES
-EXTRACT_LOCAL_CLASSES = YES
-EXTRACT_LOCAL_METHODS = NO
-EXTRACT_ANON_NSPACES = NO
-HIDE_IN_BODY_DOCS = NO
-INTERNAL_DOCS = NO
CASE_SENSE_NAMES = NO
HIDE_SCOPE_NAMES = YES
SHOW_INCLUDE_FILES = YES
-FORCE_LOCAL_INCLUDES = NO
INLINE_INFO = NO
-SORT_MEMBER_DOCS = YES
SORT_BRIEF_DOCS = YES
SORT_MEMBERS_CTORS_1ST = YES
-SORT_GROUP_NAMES = NO
-SORT_BY_SCOPE_NAME = NO
-STRICT_PROTO_MATCHING = NO
-GENERATE_TODOLIST = YES
+GENERATE_TODOLIST = NO
GENERATE_TESTLIST = NO
-GENERATE_BUGLIST = YES
+GENERATE_BUGLIST = NO
GENERATE_DEPRECATEDLIST= YES
MAX_INITIALIZER_LINES = 30
SHOW_USED_FILES = NO
-SHOW_FILES = NO
-SHOW_NAMESPACES = YES
+SHOW_FILES = YES
LAYOUT_FILE =
+EXTENSION_MAPPING = inl=C++
+BUILTIN_STL_SUPPORT = YES
#---------------------------------------------------------------------------
-# configuration options related to warning and progress messages
+# Configuration options related to warning and progress messages
#---------------------------------------------------------------------------
QUIET = YES
-WARNINGS = YES
-WARN_IF_DOC_ERROR = YES
WARN_NO_PARAMDOC = YES
WARN_FORMAT = "$file:$line: $text"
#---------------------------------------------------------------------------
-# configuration options related to the input files
+# Configuration options related to the input files
#---------------------------------------------------------------------------
INPUT = src \
include
INPUT_ENCODING = UTF-8
-FILE_PATTERNS = *.c \
- *.cpp \
+FILE_PATTERNS = *.cpp \
*.h \
*.inl
RECURSIVE = YES
-EXCLUDE =
-EXCLUDE_SYMLINKS = NO
-EXCLUDE_PATTERNS = /ext/* bin/* build/* config/* gui/* kernels/* openspace-data/* scripts/* shaders/*
-EXCLUDE_SYMBOLS =
+EXCLUDE_PATTERNS = ext/* bin/* build/* config/* gui/* kernels/* data/* scripts/* shaders/*
+USE_MDFILE_AS_MAINPAGE = README.md
#---------------------------------------------------------------------------
-# configuration options related to source browsing
+# Configuration options related to source browsing
#---------------------------------------------------------------------------
SOURCE_BROWSER = YES
-INLINE_SOURCES = NO
-STRIP_CODE_COMMENTS = YES
-REFERENCED_BY_RELATION = NO
-REFERENCES_RELATION = NO
-REFERENCES_LINK_SOURCE = YES
VERBATIM_HEADERS = NO
#---------------------------------------------------------------------------
-# configuration options related to the alphabetical class index
+# Configuration options related to the HTML output
#---------------------------------------------------------------------------
-ALPHABETICAL_INDEX = YES
-COLS_IN_ALPHA_INDEX = 4
-IGNORE_PREFIX =
-
-#---------------------------------------------------------------------------
-# configuration options related to the HTML output
-#---------------------------------------------------------------------------
-
-GENERATE_HTML = YES
-HTML_OUTPUT = html
-HTML_FILE_EXTENSION = .html
HTML_HEADER = support/doxygen/header.html
HTML_FOOTER = support/doxygen/footer.html
HTML_STYLESHEET = support/doxygen/stylesheet.css
-#HTML_EXTRA_FILES =
-HTML_COLORSTYLE_HUE = 200
-HTML_COLORSTYLE_SAT = 100
-HTML_COLORSTYLE_GAMMA = 80
-HTML_TIMESTAMP = NO
-HTML_DYNAMIC_SECTIONS = NO
-# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
-# for more information.
-GENERATE_DOCSET = NO
-DOCSET_FEEDNAME =
-DOCSET_BUNDLE_ID =
-DOCSET_PUBLISHER_ID =
-DOCSET_PUBLISHER_NAME =
-GENERATE_HTMLHELP = NO
-CHM_FILE =
-HHC_LOCATION =
-GENERATE_CHI = NO
-CHM_INDEX_ENCODING =
-BINARY_TOC = NO
-TOC_EXPAND = NO
-DISABLE_INDEX = YES
+HTML_COLORSTYLE_HUE = 225
+HTML_COLORSTYLE_SAT = 18
+HTML_COLORSTYLE_GAMMA = 100
GENERATE_TREEVIEW = YES
ENUM_VALUES_PER_LINE = 6
TREEVIEW_WIDTH = 300
-EXT_LINKS_IN_WINDOW = NO
-FORMULA_FONTSIZE = 10
-FORMULA_TRANSPARENT = YES
-USE_MATHJAX = NO
-MATHJAX_RELPATH = http://www.mathjax.org/mathjax
-MATHJAX_EXTENSIONS =
-SEARCHENGINE = YES
-SERVER_BASED_SEARCH = NO
#---------------------------------------------------------------------------
-# configuration options related to the LaTeX output
+# Other output configuration options
#---------------------------------------------------------------------------
-
GENERATE_LATEX = NO
-LATEX_OUTPUT = latex
-LATEX_CMD_NAME = latex
-MAKEINDEX_CMD_NAME = makeindex
-COMPACT_LATEX = NO
-PAPER_TYPE = a4wide
-EXTRA_PACKAGES =
-LATEX_HEADER =
-LATEX_FOOTER =
-PDF_HYPERLINKS = YES
-USE_PDFLATEX = YES
-LATEX_BATCHMODE = NO
-LATEX_HIDE_INDICES = NO
-LATEX_SOURCE_CODE = NO
-LATEX_BIB_STYLE = plain
-
-#---------------------------------------------------------------------------
-# configuration options related to the RTF output
-#---------------------------------------------------------------------------
-
GENERATE_RTF = NO
-RTF_OUTPUT = rtf
-COMPACT_RTF = NO
-RTF_HYPERLINKS = NO
-RTF_STYLESHEET_FILE =
-RTF_EXTENSIONS_FILE =
-
-#---------------------------------------------------------------------------
-# configuration options related to the man page output
-#---------------------------------------------------------------------------
-
GENERATE_MAN = NO
-MAN_OUTPUT = man
-MAN_EXTENSION = .3
-MAN_LINKS = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the XML output
-#---------------------------------------------------------------------------
-
GENERATE_XML = NO
-XML_OUTPUT = xml
-XML_SCHEMA =
-XML_DTD =
-XML_PROGRAMLISTING = YES
-
-#---------------------------------------------------------------------------
-# configuration options for the AutoGen Definitions output
-#---------------------------------------------------------------------------
-
GENERATE_AUTOGEN_DEF = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the Perl module output
-#---------------------------------------------------------------------------
-
GENERATE_PERLMOD = NO
-PERLMOD_LATEX = NO
-PERLMOD_PRETTY = YES
-PERLMOD_MAKEVAR_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
-ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = YES
-SEARCH_INCLUDES = YES
-INCLUDE_PATH =
-INCLUDE_FILE_PATTERNS =
-PREDEFINED =
EXPAND_AS_DEFINED = YES
SKIP_FUNCTION_MACROS = NO
-
-#---------------------------------------------------------------------------
-# Configuration::additions related to external references
-#---------------------------------------------------------------------------
-
-TAGFILES =
-GENERATE_TAGFILE =
-ALLEXTERNALS = NO
-EXTERNAL_GROUPS = YES
-PERL_PATH = /usr/bin/perl
-
-#---------------------------------------------------------------------------
-# Configuration options related to the dot tool
-#---------------------------------------------------------------------------
-
-CLASS_DIAGRAMS = YES
-MSCGEN_PATH =
-HIDE_UNDOC_RELATIONS = YES
-
-# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
-# available from the path. This tool is part of Graphviz, a graph visualization
-# toolkit from AT&T and Lucent Bell Labs. The other options in this section
-# have no effect if this option is set to NO (the default)
-
-HAVE_DOT = NO
-
-# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is
-# allowed to run in parallel. When set to 0 (the default) doxygen will
-# base this on the number of processors available in the system. You can set it
-# explicitly to a value larger than 0 to get control over the balance
-# between CPU load and processing speed.
-
-DOT_NUM_THREADS = 0
-
-# By default doxygen will use the Helvetica font for all dot files that
-# doxygen generates. When you want a differently looking font you can specify
-# the font name using DOT_FONTNAME. You need to make sure dot is able to find
-# the font, which can be done by putting it in a standard location or by setting
-# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the
-# directory containing the font.
-
-DOT_FONTNAME = Helvetica
-
-# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.
-# The default size is 10pt.
-
-DOT_FONTSIZE = 10
-
-# By default doxygen will tell dot to use the Helvetica font.
-# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to
-# set the path where dot can find it.
-
-DOT_FONTPATH =
-
-# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for each documented class showing the direct and
-# indirect inheritance relations. Setting this tag to YES will force the
-# CLASS_DIAGRAMS tag to NO.
-
-CLASS_GRAPH = YES
-
-# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for each documented class showing the direct and
-# indirect implementation dependencies (inheritance, containment, and
-# class references variables) of the class with other documented classes.
-
-COLLABORATION_GRAPH = YES
-
-# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for groups, showing the direct groups dependencies
-
-GROUP_GRAPHS = YES
-
-# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
-# collaboration diagrams in a style similar to the OMG's Unified Modeling
-# Language.
-
-UML_LOOK = NO
-
-# If set to YES, the inheritance and collaboration graphs will show the
-# relations between templates and their instances.
-
-TEMPLATE_RELATIONS = NO
-
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
-# tags are set to YES then doxygen will generate a graph for each documented
-# file showing the direct and indirect include dependencies of the file with
-# other documented files.
-
-INCLUDE_GRAPH = YES
-
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
-# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
-# documented header file showing the documented files that directly or
-# indirectly include this file.
-
-INCLUDED_BY_GRAPH = YES
-
-# If the CALL_GRAPH and HAVE_DOT options are set to YES then
-# doxygen will generate a call dependency graph for every global function
-# or class method. Note that enabling this option will significantly increase
-# the time of a run. So in most cases it will be better to enable call graphs
-# for selected functions only using the \callgraph command.
-
-CALL_GRAPH = NO
-
-# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
-# doxygen will generate a caller dependency graph for every global function
-# or class method. Note that enabling this option will significantly increase
-# the time of a run. So in most cases it will be better to enable caller
-# graphs for selected functions only using the \callergraph command.
-
-CALLER_GRAPH = NO
-
-# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
-# will generate a graphical hierarchy of all classes instead of a textual one.
-
-GRAPHICAL_HIERARCHY = YES
-
-# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
-# then doxygen will show the dependencies a directory has on other directories
-# in a graphical way. The dependency relations are determined by the #include
-# relations between the files in the directories.
-
-DIRECTORY_GRAPH = YES
-
-# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
-# generated by dot. Possible values are svg, png, jpg, or gif.
-# If left blank png will be used. If you choose svg you need to set
-# HTML_FILE_EXTENSION to xhtml in order to make the SVG files
-# visible in IE 9+ (other browsers do not have this requirement).
-
-DOT_IMAGE_FORMAT = png
-
-# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
-# enable generation of interactive SVG images that allow zooming and panning.
-# Note that this requires a modern browser other than Internet Explorer.
-# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you
-# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files
-# visible. Older versions of IE do not have SVG support.
-
-INTERACTIVE_SVG = NO
-
-# The tag DOT_PATH can be used to specify the path where the dot tool can be
-# found. If left blank, it is assumed the dot tool can be found in the path.
-
-DOT_PATH =
-
-# The DOTFILE_DIRS tag can be used to specify one or more directories that
-# contain dot files that are included in the documentation (see the
-# \dotfile command).
-
-DOTFILE_DIRS =
-
-# The MSCFILE_DIRS tag can be used to specify one or more directories that
-# contain msc files that are included in the documentation (see the
-# \mscfile command).
-
-MSCFILE_DIRS =
-
-# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
-# nodes that will be shown in the graph. If the number of nodes in a graph
-# becomes larger than this value, doxygen will truncate the graph, which is
-# visualized by representing a node as a red box. Note that doxygen if the
-# number of direct children of the root node in a graph is already larger than
-# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
-# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
-
-DOT_GRAPH_MAX_NODES = 50
-
-# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
-# graphs generated by dot. A depth value of 3 means that only nodes reachable
-# from the root by following a path via at most 3 edges will be shown. Nodes
-# that lay further from the root node will be omitted. Note that setting this
-# option to 1 or 2 may greatly reduce the computation time needed for large
-# code bases. Also note that the size of a graph can be further restricted by
-# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
-
-MAX_DOT_GRAPH_DEPTH = 0
-
-# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
-# background. This is disabled by default, because dot on Windows does not
-# seem to support this out of the box. Warning: Depending on the platform used,
-# enabling this option may lead to badly anti-aliased labels on the edges of
-# a graph (i.e. they become hard to read).
-
-DOT_TRANSPARENT = NO
-
-# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
-# files in one run (i.e. multiple -o and -T options on the command line). This
-# makes dot run faster, but since only newer versions of dot (>1.8.10)
-# support this, this feature is disabled by default.
-
-DOT_MULTI_TARGETS = NO
-
-# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
-# generate a legend page explaining the meaning of the various boxes and
-# arrows in the dot generated graphs.
-
-GENERATE_LEGEND = YES
-
-# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
-# remove the intermediate dot files that are used to generate
-# the various graphs.
-
-DOT_CLEANUP = YES
diff --git a/config/sgct/VRArenaSimCenter.xml b/config/sgct/VRArenaSimCenter.xml
index 3ce0236e5f..f57ec51789 100644
--- a/config/sgct/VRArenaSimCenter.xml
+++ b/config/sgct/VRArenaSimCenter.xml
@@ -1,82 +1,82 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/config/sgct/single.xml b/config/sgct/single.xml
index 62aea727b1..7b20bcb10c 100644
--- a/config/sgct/single.xml
+++ b/config/sgct/single.xml
@@ -1,24 +1,24 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/config/sgct/single_4k.xml b/config/sgct/single_4k.xml
new file mode 100644
index 0000000000..cb4dd6339c
--- /dev/null
+++ b/config/sgct/single_4k.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/config/sgct/single_fisheye.xml b/config/sgct/single_fisheye.xml
index b72758eb6c..b9bc7415dd 100644
--- a/config/sgct/single_fisheye.xml
+++ b/config/sgct/single_fisheye.xml
@@ -1,37 +1,37 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/config/sgct/single_gui.xml b/config/sgct/single_gui.xml
index e0d1b6bfa8..a3956e40f6 100644
--- a/config/sgct/single_gui.xml
+++ b/config/sgct/single_gui.xml
@@ -1,37 +1,37 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/config/sgct/single_sbs_stereo.xml b/config/sgct/single_sbs_stereo.xml
index ab3d4826fb..d92f95ed66 100644
--- a/config/sgct/single_sbs_stereo.xml
+++ b/config/sgct/single_sbs_stereo.xml
@@ -1,21 +1,21 @@
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
\ No newline at end of file
diff --git a/config/sgct/single_stereo.xml b/config/sgct/single_stereo.xml
index 71f83845c3..8497af6188 100644
--- a/config/sgct/single_stereo.xml
+++ b/config/sgct/single_stereo.xml
@@ -1,25 +1,25 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/config/sgct/single_two_win.xml b/config/sgct/single_two_win.xml
index 7286afb127..4cd802423a 100644
--- a/config/sgct/single_two_win.xml
+++ b/config/sgct/single_two_win.xml
@@ -1,40 +1,40 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/config/sgct/two_nodes.xml b/config/sgct/two_nodes.xml
index 456976ebe5..9ec00bf7bc 100644
--- a/config/sgct/two_nodes.xml
+++ b/config/sgct/two_nodes.xml
@@ -1,44 +1,44 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/data/scene/atmosphereearth/atmosphereearth.mod b/data/scene/atmosphereearth/atmosphereearth.mod
index 7ab2b2121e..166a0bdbad 100644
--- a/data/scene/atmosphereearth/atmosphereearth.mod
+++ b/data/scene/atmosphereearth/atmosphereearth.mod
@@ -129,7 +129,8 @@ return {
Size = {3.0, 11.0},
Origin = "Center",
Billboard = true,
- Texture = "textures/marker.png"
+ Texture = "textures/marker.png",
+ BlendMode = "Additive"
},
Ephemeris = {
Type = "Static",
diff --git a/data/scene/earth/earth.mod b/data/scene/earth/earth.mod
index ca3488ede6..0456dfaa13 100644
--- a/data/scene/earth/earth.mod
+++ b/data/scene/earth/earth.mod
@@ -76,7 +76,12 @@ return {
Size = {3.0, 11.0},
Origin = "Center",
Billboard = true,
- Texture = "textures/marker.png"
+ Texture = "textures/marker.png",
+ BlendMode = "Additive"
+ },
+ Ephemeris = {
+ Type = "Static",
+ Position = {0, 0, 0, 5}
}
}
]]
diff --git a/data/scene/newhorizons/jupiter/callisto/callisto.mod b/data/scene/newhorizons/jupiter/callisto/callisto.mod
index 81fbdb7005..44bae2484b 100644
--- a/data/scene/newhorizons/jupiter/callisto/callisto.mod
+++ b/data/scene/newhorizons/jupiter/callisto/callisto.mod
@@ -22,6 +22,7 @@ return {
Observer = "NEW HORIZONS",
Target = "CALLISTO",
Aberration = "NONE",
+ AspectRatio = 2
},
Instrument = {
Name = "NH_LORRI",
@@ -78,7 +79,8 @@ return {
Size = {1.0, 7.4},
Origin = "Center",
Billboard = true,
- Texture = "textures/Callisto-Text.png"
+ Texture = "textures/Callisto-Text.png",
+ BlendMode = "Additive"
},
--[[
Ephemeris = {
diff --git a/data/scene/newhorizons/jupiter/europa/europa.mod b/data/scene/newhorizons/jupiter/europa/europa.mod
index cc8fed3967..a3e9b4a882 100644
--- a/data/scene/newhorizons/jupiter/europa/europa.mod
+++ b/data/scene/newhorizons/jupiter/europa/europa.mod
@@ -22,6 +22,7 @@ return {
Observer = "NEW HORIZONS",
Target = "EUROPA",
Aberration = "NONE",
+ AspectRatio = 2
},
Instrument = {
Name = "NH_LORRI",
@@ -78,7 +79,8 @@ return {
Size = {1.0, 7.4},
Origin = "Center",
Billboard = true,
- Texture = "textures/Europa-Text.png"
+ Texture = "textures/Europa-Text.png",
+ BlendMode = "Additive"
},
--[[
Ephemeris = {
diff --git a/data/scene/newhorizons/jupiter/ganymede/ganymede.mod b/data/scene/newhorizons/jupiter/ganymede/ganymede.mod
index 1ef503e6fb..11fcfe432b 100644
--- a/data/scene/newhorizons/jupiter/ganymede/ganymede.mod
+++ b/data/scene/newhorizons/jupiter/ganymede/ganymede.mod
@@ -22,6 +22,7 @@ return {
Observer = "NEW HORIZONS",
Target = "GANYMEDE",
Aberration = "NONE",
+ AspectRatio = 2
},
Instrument = {
Name = "NH_LORRI",
@@ -78,7 +79,8 @@ return {
Size = {1.0, 7.4},
Origin = "Center",
Billboard = true,
- Texture = "textures/Ganymede-Text.png"
+ Texture = "textures/Ganymede-Text.png",
+ BlendMode = "Additive"
},
Transform = {
Translation = {
diff --git a/data/scene/newhorizons/jupiter/io/io.mod b/data/scene/newhorizons/jupiter/io/io.mod
index 553ae825f5..76615815b8 100644
--- a/data/scene/newhorizons/jupiter/io/io.mod
+++ b/data/scene/newhorizons/jupiter/io/io.mod
@@ -22,6 +22,7 @@ return {
Observer = "NEW HORIZONS",
Target = "IO",
Aberration = "NONE",
+ AspectRatio = 2
},
Instrument = {
Name = "NH_LORRI",
@@ -78,7 +79,8 @@ return {
Size = {1.0, 7.4},
Origin = "Center",
Billboard = true,
- Texture = "textures/Io-Text.png"
+ Texture = "textures/Io-Text.png",
+ BlendMode = "Additive"
},
Transform = {
Translation = {
diff --git a/data/scene/newhorizons/jupiter/jupiter/jupiter.mod b/data/scene/newhorizons/jupiter/jupiter/jupiter.mod
index c8076e913e..fd8222df3b 100644
--- a/data/scene/newhorizons/jupiter/jupiter/jupiter.mod
+++ b/data/scene/newhorizons/jupiter/jupiter/jupiter.mod
@@ -41,6 +41,7 @@ return {
Observer = "NEW HORIZONS",
Target = "JUPITER",
Aberration = "NONE",
+ AspectRatio = 2
},
DataInputTranslation = {
Instrument = {
@@ -106,7 +107,8 @@ return {
Size = {1.0, 7.5},
Origin = "Center",
Billboard = true,
- Texture = "textures/Jupiter-text.png"
+ Texture = "textures/Jupiter-text.png",
+ BlendMode = "Additive"
},
Transform = {
Translation = {
diff --git a/data/scene/newhorizons/pluto/charon/charon.mod b/data/scene/newhorizons/pluto/charon/charon.mod
index 1e51526c97..8fbe1de3e5 100644
--- a/data/scene/newhorizons/pluto/charon/charon.mod
+++ b/data/scene/newhorizons/pluto/charon/charon.mod
@@ -40,6 +40,7 @@ return {
Observer = "NEW HORIZONS",
Target = "CHARON",
Aberration = "NONE",
+ AspectRatio = 2
},
Instrument = {
Name = "NH_LORRI",
@@ -93,7 +94,8 @@ return {
Size = {1.0, 6.3},
Origin = "Center",
Billboard = true,
- Texture = "textures/Charon-Text.png"
+ Texture = "textures/Charon-Text.png",
+ BlendMode = "Additive"
},
Transform = {
Translation = {
diff --git a/data/scene/newhorizons/pluto/pluto/pluto.mod b/data/scene/newhorizons/pluto/pluto/pluto.mod
index ab6abd4dff..59fe90b53b 100644
--- a/data/scene/newhorizons/pluto/pluto/pluto.mod
+++ b/data/scene/newhorizons/pluto/pluto/pluto.mod
@@ -67,6 +67,7 @@ return {
Observer = "NEW HORIZONS",
Target = "PLUTO",
Aberration = "NONE",
+ AspectRatio = 2
},
DataInputTranslation = {
Instrument = {
@@ -223,7 +224,8 @@ return {
Size = {1.0, 6.3},
Origin = "Center",
Billboard = true,
- Texture = "textures/Pluto-Text.png"
+ Texture = "textures/Pluto-Text.png",
+ BlendMode = "Additive"
},
Transform = {
Translation = {
diff --git a/data/scene/newhorizons/pluto/styx/styx.mod b/data/scene/newhorizons/pluto/styx/styx.mod
index b53af6a70c..ec081220b2 100644
--- a/data/scene/newhorizons/pluto/styx/styx.mod
+++ b/data/scene/newhorizons/pluto/styx/styx.mod
@@ -66,7 +66,8 @@ return {
Size = {1.0, 6.3},
Origin = "Center",
Billboard = true,
- Texture = "textures/Styx-Text.png"
+ Texture = "textures/Styx-Text.png",
+ BlendMode = "Additive"
},
Transform = {
Translation = {
diff --git a/data/scene/osirisrex/bennu/bennu.mod b/data/scene/osirisrex/bennu/bennu.mod
index 50367253ff..33722c7ca9 100644
--- a/data/scene/osirisrex/bennu/bennu.mod
+++ b/data/scene/osirisrex/bennu/bennu.mod
@@ -51,6 +51,7 @@ return {
Observer = "OSIRIS-REX",
Target = BENNU_BODY,
Aberration = "NONE",
+ AspectRatio = 2
},
DataInputTranslation = {
Instruments = {
diff --git a/data/scene/rosetta.scene b/data/scene/rosetta.scene
index 4701468832..befa637e83 100644
--- a/data/scene/rosetta.scene
+++ b/data/scene/rosetta.scene
@@ -9,8 +9,16 @@ function preInitialization()
openspace.spice.loadKernel("${SPICE}/naif0011.tls")
openspace.spice.loadKernel("${SPICE}/pck00010.tpc")
- openspace.time.setTime("2014-08-15T03:05:18.101")
- -- openspace.time.setTime("2014-11-17T03:05:18.101")
+ -- Usual start
+ openspace.time.setTime("2014-08-01T03:05:18.101")
+
+ -- Philae release
+ -- openspace.time.setTime("2014-11-12T08:00:00.000")
+
+ -- Shadow flyby
+ -- openspace.time.setTime("2015-02-14T12:00:00.000")
+
+
-- openspace.time.setTime("2015-07-29T06:02:10.000")
-- openspace.time.setTime("2014 AUG 21 18:00:00")
-- openspace.time.setTime("2015 SEP 10 19:39:00")
@@ -50,7 +58,7 @@ return {
"venus",
"earth",
"mars",
- "jupiter",
+ "jupiter/jupiter",
"saturn",
"uranus",
"neptune",
diff --git a/data/scene/rosetta/67P/67P.data b/data/scene/rosetta/67P/67P.data
index 3c899a9480..57f10bc7d3 100644
--- a/data/scene/rosetta/67P/67P.data
+++ b/data/scene/rosetta/67P/67P.data
@@ -5,6 +5,5 @@ return {
},
TorrentFiles = {
{ File = "67P_rotated_5_130.obj.torrent", Destination = "obj" },
- { File = "RosettaKernels.torrent", Destination = "${SPICE}" }
}
}
\ No newline at end of file
diff --git a/data/scene/rosetta/67P/67P.mod b/data/scene/rosetta/67P/67P.mod
index 296d2f5c53..d28d3874ff 100644
--- a/data/scene/rosetta/67P/67P.mod
+++ b/data/scene/rosetta/67P/67P.mod
@@ -9,28 +9,6 @@ return {
Body = "CHURYUMOV-GERASIMENKO",
Reference = "GALACTIC",
Observer = "SUN",
- Kernels = {
- --needed
- "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp",
- -- SPK
- --long term orbits loaded first
- '${OPENSPACE_DATA}/spice/RosettaKernels_New/SPK/LORL_DL_009_02____P__00268.BSP',
- '${OPENSPACE_DATA}/spice/RosettaKernels_New/SPK/RORL_DL_009_02____P__00268.BSP',
- '${OPENSPACE_DATA}/spice/RosettaKernels_New/SPK/CORL_DL_009_02____P__00268.BSP',
-
- '${OPENSPACE_DATA}/spice/RosettaKernels/SPK/LORL_DL_006_01____H__00156.BSP',
- '${OPENSPACE_DATA}/spice/RosettaKernels/SPK/RORL_DL_006_01____H__00156.BSP',
- '${OPENSPACE_DATA}/spice/RosettaKernels/SPK/CORL_DL_006_01____H__00156.BSP',
-
- --Jan 2014 - May 2015 (version match with 00162 ck files)
- "${OPENSPACE_DATA}/spice/RosettaKernels/SPK/CORB_DV_097_01_______00162.BSP",
- "${OPENSPACE_DATA}/spice/RosettaKernels/SPK/RORB_DV_097_01_______00162.BSP",
- "${OPENSPACE_DATA}/spice/RosettaKernels/SPK/LORB_DV_097_01_______00162.BSP",
-
- "${OPENSPACE_DATA}/spice/RosettaKernels_New/SPK/CORB_DV_211_01_______00288.BSP",
- "${OPENSPACE_DATA}/spice/RosettaKernels_New/SPK/RORB_DV_211_01_______00288.BSP",
- "${OPENSPACE_DATA}/spice/RosettaKernels_New/SPK/LORB_DV_211_01_______00288.BSP",
- }
},
},
GuiName = "/Solar/67PBarycenter",
@@ -50,6 +28,7 @@ return {
Textures = {
Type = "simple",
Color = "textures/gray.jpg",
+ -- Color = "textures/may9_map.jpg",
Project = "textures/defaultProj.png",
Default = "textures/defaultProj.png"
},
@@ -63,7 +42,8 @@ return {
Observer = "ROSETTA",
Target = "CHURYUMOV-GERASIMENKO",
Aberration = "NONE",
- TextureMap = true
+ TextureMap = true,
+ ShadowMap = true
},
DataInputTranslation = {
Instrument = {
@@ -98,10 +78,9 @@ return {
Method = "ELLIPSOID",
Aberration = "NONE",
Fovy = 5.00,
- Aspect = 1,
- Near = 0.01,
- Far = 1000000,
+ Aspect = 1
},
+ BoundingSphereRadius = 5000.0
},
Transform = {
Rotation = {
diff --git a/data/scene/rosetta/67P/RosettaKernels.torrent b/data/scene/rosetta/67P/RosettaKernels.torrent
deleted file mode 100644
index be150ad729..0000000000
Binary files a/data/scene/rosetta/67P/RosettaKernels.torrent and /dev/null differ
diff --git a/data/scene/rosetta/rosetta/Rosetta.torrent b/data/scene/rosetta/rosetta/Rosetta.torrent
new file mode 100644
index 0000000000..c714826b8c
Binary files /dev/null and b/data/scene/rosetta/rosetta/Rosetta.torrent differ
diff --git a/data/scene/rosetta/rosetta/RosettaKernels.torrent b/data/scene/rosetta/rosetta/RosettaKernels.torrent
deleted file mode 100644
index be150ad729..0000000000
Binary files a/data/scene/rosetta/rosetta/RosettaKernels.torrent and /dev/null differ
diff --git a/data/scene/rosetta/rosetta/RosettaKernels_New.torrent b/data/scene/rosetta/rosetta/RosettaKernels_New.torrent
deleted file mode 100644
index cdb32f8b5d..0000000000
Binary files a/data/scene/rosetta/rosetta/RosettaKernels_New.torrent and /dev/null differ
diff --git a/data/scene/rosetta/rosetta/rosetta.data b/data/scene/rosetta/rosetta/rosetta.data
index f49beed4ff..fbef76bd99 100644
--- a/data/scene/rosetta/rosetta/rosetta.data
+++ b/data/scene/rosetta/rosetta/rosetta.data
@@ -4,7 +4,6 @@ return {
{ Identifier = "rosetta_textures", Destination = "textures", Version = 2 }
},
TorrentFiles = {
- { File = "RosettaKernels.torrent", Destination = "${SPICE}" },
- { File = "RosettaKernels_New.torrent", Destination = "${SPICE}" }
+ { File = "Rosetta.torrent", Destination = "${SPICE}" },
}
}
\ No newline at end of file
diff --git a/data/scene/rosetta/rosetta/rosetta.mod b/data/scene/rosetta/rosetta/rosetta.mod
index 0796af4c13..70572026ac 100644
--- a/data/scene/rosetta/rosetta/rosetta.mod
+++ b/data/scene/rosetta/rosetta/rosetta.mod
@@ -1,58 +1,61 @@
RosettaKernels = {
- --needed
- "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp",
- -- SPK
- --long term orbits loaded first
- -- '${OPENSPACE_DATA}/spice/RosettaKernels/SPK/LORL_DL_006_01____H__00156.BSP',
- -- '${OPENSPACE_DATA}/spice/RosettaKernels/SPK/RORL_DL_006_01____H__00156.BSP',
- -- '${OPENSPACE_DATA}/spice/RosettaKernels/SPK/CORL_DL_006_01____H__00156.BSP',
+ "${OPENSPACE_DATA}/spice/Rosetta/SCLK/ROS_160718_STEP.TSC",
+ "${OPENSPACE_DATA}/spice/Rosetta/SCLK/ros_triv.tsc",
- --Jan 2014 - May 2015 (version match with 00162 ck files)
- -- "${OPENSPACE_DATA}/spice/RosettaKernels/SPK/CORB_DV_097_01_______00162.BSP",
- -- "${OPENSPACE_DATA}/spice/RosettaKernels/SPK/RORB_DV_097_01_______00162.BSP",
- -- "${OPENSPACE_DATA}/spice/RosettaKernels/SPK/LORB_DV_097_01_______00162.BSP",
+ "${OPENSPACE_DATA}/spice/Rosetta/SPK/CORB_DV_243_01___T19_00325.BSP",
+ "${OPENSPACE_DATA}/spice/Rosetta/SPK/CORB_DV_223_01___T19_00302.BSP",
+ "${OPENSPACE_DATA}/spice/Rosetta/SPK/CORB_DV_145_01___T19_00216.BSP",
- --IK
- "${OPENSPACE_DATA}/spice/RosettaKernels_New/IK/ROS_NAVCAM_V01.TI",
- "${OPENSPACE_DATA}/spice/RosettaKernels/IK/ROS_NAVCAM_V00-20130102.TI",
+ "${OPENSPACE_DATA}/spice/Rosetta/SPK/LORB_DV_236_01___T19_00318.BSP",
+ "${OPENSPACE_DATA}/spice/Rosetta/SPK/LORB_DV_223_01___T19_00302.BSP",
+ "${OPENSPACE_DATA}/spice/Rosetta/SPK/LORB_DV_145_01___T19_00216.BSP",
+
+ "${OPENSPACE_DATA}/spice/Rosetta/SPK/RORB_DV_243_01___T19_00325.BSP",
+ "${OPENSPACE_DATA}/spice/Rosetta/SPK/RORB_DV_223_01___T19_00302.BSP",
+ "${OPENSPACE_DATA}/spice/Rosetta/SPK/RORB_DV_145_01___T19_00216.BSP",
- --SCLK
- -- "${OPENSPACE_DATA}/spice/RosettaKernels/SCLK/ROS_150227_STEP.TSC",
+ "${OPENSPACE_DATA}/spice/Rosetta/CK/ATNR_P040302093352_00127.BC",
- -- FK
- -- "${OPENSPACE_DATA}/spice/RosettaKernels/FK/ROS_CHURYUMOV_V01.TF",
- -- "${OPENSPACE_DATA}/spice/RosettaKernels/FK/ROS_V24.TF",
+ "${OPENSPACE_DATA}/spice/Rosetta/SPK/ROS_STRUCT_V5.BSP",
+
+ "${OPENSPACE_DATA}/spice/Rosetta/IK/ROS_NAVCAM_V01.TI",
+
+ "${OPENSPACE_DATA}/spice/Rosetta/FK/ROS_CHURYUMOV_V01.TF",
+ "${OPENSPACE_DATA}/spice/Rosetta/FK/ROS_V26.TF",
-- CK
- -- '${OPENSPACE_DATA}/spice/RosettaKernels/CK/RATT_DV_097_01_01____00162.BC',
- -- "${OPENSPACE_DATA}/spice/RosettaKernels/CK/CATT_DV_097_01_______00162.BC",
+ -- Rosetta attitude
+ "${OPENSPACE_DATA}/spice/Rosetta/CK/RATT_DV_243_01_01____00325.BC",
+ "${OPENSPACE_DATA}/spice/Rosetta/CK/RATT_DV_223_01_01____00302.BC",
+ "${OPENSPACE_DATA}/spice/Rosetta/CK/RATT_DV_145_01_01____00216.BC",
- --SCLK
- -- "${OPENSPACE_DATA}/spice/RosettaKernels/SCLK/ROS_150227_STEP.TSC",
- "${OPENSPACE_DATA}/spice/RosettaKernels_New/SCLK/ROS_160425_STEP.TSC",
+ -- Comet attitude
+ "${OPENSPACE_DATA}/spice/Rosetta/CK/CATT_DV_243_01_______00325.BC",
+ "${OPENSPACE_DATA}/spice/Rosetta/CK/CATT_DV_223_01_______00302.BC",
+ "${OPENSPACE_DATA}/spice/Rosetta/CK/CATT_DV_145_01_______00216.BC",
- -- FK
+ -- High gain antenna
+ "${OPENSPACE_DATA}/spice/Rosetta/CK/ROS_HGA_2016_V0035.BC",
+ "${OPENSPACE_DATA}/spice/Rosetta/CK/ROS_HGA_2015_V0053.BC",
+ "${OPENSPACE_DATA}/spice/Rosetta/CK/ROS_HGA_2014_V0044.BC",
- "${OPENSPACE_DATA}/spice/RosettaKernels_New/FK/ROS_CHURYUMOV_V01.TF",
- "${OPENSPACE_DATA}/spice/RosettaKernels_New/FK/ROS_V26.TF",
- -- "${OPENSPACE_DATA}/spice/RosettaKernels/FK/ROS_V24.TF",
- -- CK
- "${OPENSPACE_DATA}/spice/RosettaKernels_New/CK/RATT_DV_211_01_01____00288.BC",
- "${OPENSPACE_DATA}/spice/RosettaKernels_New/CK/CATT_DV_211_01_______00288.BC",
- '${OPENSPACE_DATA}/spice/RosettaKernels/CK/RATT_DV_097_01_01____00162.BC',
- "${OPENSPACE_DATA}/spice/RosettaKernels/CK/CATT_DV_097_01_______00162.BC",
-
- -- PCK
- "${OPENSPACE_DATA}/spice/RosettaKernels_New/PCK/ROS_CGS_RSOC_V03.TPC",
- -- "${OPENSPACE_DATA}/spice/RosettaKernels/PCK/ROS_CGS_RSOC_V03.TPC",
+ -- Solar arrays
+ "${OPENSPACE_DATA}/spice/Rosetta/CK/ROS_SA_2016_V0034.BC",
+ "${OPENSPACE_DATA}/spice/Rosetta/CK/ROS_SA_2015_V0042.BC",
+ "${OPENSPACE_DATA}/spice/Rosetta/CK/ROS_SA_2014_V0047.BC",
-
- "${OPENSPACE_DATA}/spice/RosettaKernels_New/CK/ROS_SA_2014_V0047.BC",
- "${OPENSPACE_DATA}/spice/RosettaKernels_New/CK/ROS_SA_2015_V0042.BC",
- "${OPENSPACE_DATA}/spice/RosettaKernels_New/CK/ROS_SA_2016_V0019.BC",
+ "${OPENSPACE_DATA}/spice/Rosetta/PCK/ROS_CGS_RSOC_V03.TPC",
}
+RotationMatrix = {
+ 0, 1, 0,
+ 0, 0, 1,
+ 1, 0, 0
+}
+
+
+
return {
{
Name = "Rosetta",
@@ -64,7 +67,7 @@ return {
Reference = "GALACTIC",
Observer = "SUN",
Kernels = RosettaKernels
- },
+ },
Rotation = {
Type = "SpiceRotation",
SourceFrame = "ROS_SPACECRAFT",
@@ -73,8 +76,19 @@ return {
}
},
{
- Name = "Rosetta_black_foil",
+ Name = "RosettaModel",
Parent = "Rosetta",
+ Transform = {
+ Scale = {
+ Type = "StaticScale",
+ -- The scale of the model is in cm; OpenSpace is in m
+ Scale = 0.01
+ }
+ }
+ },
+ {
+ Name = "Rosetta_black_foil",
+ Parent = "RosettaModel",
Renderable = {
Type = "RenderableModel",
Body = "ROSETTA",
@@ -85,12 +99,13 @@ return {
Textures = {
Type = "simple",
Color = "textures/foil_silver_ramp.png"
- }
+ },
+ Rotation = { ModelTransform = RotationMatrix }
}
},
{
Name = "Rosetta_black_parts",
- Parent = "Rosetta",
+ Parent = "RosettaModel",
Renderable = {
Type = "RenderableModel",
Body = "ROSETTA",
@@ -101,12 +116,13 @@ return {
Textures = {
Type = "simple",
Color = "textures/foil_silver_ramp.png"
- }
+ },
+ Rotation = { ModelTransform = RotationMatrix }
}
},
{
Name = "Rosetta_dish",
- Parent = "Rosetta",
+ Parent = "RosettaModel",
Renderable = {
Type = "RenderableModel",
Body = "ROSETTA",
@@ -117,12 +133,21 @@ return {
Textures = {
Type = "simple",
Color = "textures/dish_AO.png"
- }
- }
+ },
+ Rotation = { ModelTransform = RotationMatrix }
+
+ },
+ -- Transform = {
+ -- Rotation = {
+ -- Type = "SpiceRotation",
+ -- SourceFrame = "-226071", -- ROS_HGA
+ -- DestinationFrame = "ROS_SPACECRAFT",
+ -- }
+ -- }
},
{
Name = "Rosetta_parts",
- Parent = "Rosetta",
+ Parent = "RosettaModel",
Renderable = {
Type = "RenderableModel",
Body = "ROSETTA",
@@ -133,12 +158,14 @@ return {
Textures = {
Type = "simple",
Color = "textures/parts2_AO.png"
- }
+ },
+ Rotation = { ModelTransform = RotationMatrix }
+
}
},
{
Name = "Rosetta_silver_foil",
- Parent = "Rosetta",
+ Parent = "RosettaModel",
Renderable = {
Type = "RenderableModel",
Body = "ROSETTA",
@@ -149,12 +176,14 @@ return {
Textures = {
Type = "simple",
Color = "textures/foil_silver_ramp.png"
- }
+ },
+ Rotation = { ModelTransform = RotationMatrix }
+
}
},
{
Name = "Rosetta_vents",
- Parent = "Rosetta",
+ Parent = "RosettaModel",
Renderable = {
Type = "RenderableModel",
Body = "ROSETTA",
@@ -165,12 +194,14 @@ return {
Textures = {
Type = "simple",
Color = "textures/tex_01.png"
- }
+ },
+ Rotation = { ModelTransform = RotationMatrix }
+
}
},
{
Name = "Rosetta_wing_a",
- Parent = "Rosetta",
+ Parent = "RosettaModel",
Renderable = {
Type = "RenderableModel",
Body = "ROSETTA",
@@ -181,12 +212,21 @@ return {
Textures = {
Type = "simple",
Color = "textures/tex_01.png"
- }
- }
+ },
+ Rotation = { ModelTransform = RotationMatrix }
+
+ },
+ -- Transform = {
+ -- Rotation = {
+ -- Type = "SpiceRotation",
+ -- SourceFrame = "-226015", -- ROS_SA
+ -- DestinationFrame = "ROS_SPACECRAFT",
+ -- }
+ -- }
},
{
Name = "Rosetta_wing_b",
- Parent = "Rosetta",
+ Parent = "RosettaModel",
Renderable = {
Type = "RenderableModel",
Body = "ROSETTA",
@@ -197,12 +237,21 @@ return {
Textures = {
Type = "simple",
Color = "textures/tex_01.png"
- }
- }
+ },
+ Rotation = { ModelTransform = RotationMatrix }
+
+ },
+ -- Transform = {
+ -- Rotation = {
+ -- Type = "SpiceRotation",
+ -- SourceFrame = "-226025", -- ROS_SA
+ -- DestinationFrame = "ROS_SPACECRAFT",
+ -- }
+ -- }
},
{
Name = "Rosetta_yellow_foil",
- Parent = "Rosetta",
+ Parent = "RosettaModel",
Renderable = {
Type = "RenderableModel",
Body = "ROSETTA",
@@ -213,14 +262,35 @@ return {
Textures = {
Type = "simple",
Color = "textures/foil_gold_ramp.png"
- }
+ },
+ Rotation = { ModelTransform = RotationMatrix }
+
}
},
{
Name = "Philae",
- Parent = "Rosetta"
+ Parent = "67PBarycenter",
-- This should need a transform, but currently the model is intrinsically
-- translated
+ Transform = {
+ Translation = {
+ Type = "SpiceEphemeris",
+ Body = "PHILAE",
+ Reference = "GALACTIC",
+ Observer = "CHURYUMOV-GERASIMENKO",
+ Kernels = RosettaKernels
+ },
+ Rotation = {
+ Type = "SpiceRotation",
+ SourceFrame = "ROS_SPACECRAFT",
+ DestinationFrame = "GALACTIC",
+ },
+ Scale = {
+ Type = "StaticScale",
+ -- The scale of the model is in cm; OpenSpace is in m
+ Scale = 0.01
+ }
+ }
},
{
Name = "Philae_foil",
@@ -235,7 +305,9 @@ return {
Textures = {
Type = "simple",
Color = "textures/foil_silver_ramp.png"
- }
+ },
+ Rotation = { ModelTransform = RotationMatrix }
+
}
},
{
@@ -251,7 +323,9 @@ return {
Textures = {
Type = "simple",
Color = "textures/parts2_AO.png"
- }
+ },
+ Rotation = { ModelTransform = RotationMatrix }
+
}
},
{
@@ -267,7 +341,9 @@ return {
Textures = {
Type = "simple",
Color = "textures/foil_silver_ramp.png"
- }
+ },
+ Rotation = { ModelTransform = RotationMatrix }
+
}
},
{
@@ -283,55 +359,12 @@ return {
Textures = {
Type = "simple",
Color = "textures/tex_01.png"
- }
+ },
+ Rotation = { ModelTransform = RotationMatrix }
+
}
},
- --[[ -- Rosetta Trail Module
- {
- Name = "RosettaTrail",
- Parent = "67P",
- Renderable = {
- Type = "RenderableTrail",
- Body = "ROSETTA",
- Frame = "GALACTIC",
- Observer = "SUN",
- -- 3 Dummy values for compilation:
- TropicalOrbitPeriod = 10000.0,
- EarthOrbitRatio = 2,
- DayLength = 50,
- -- End of Dummy values
- RGB = { 0.7, 0.7, 0.4 },
- Textures = {
- Type = "simple",
- Color = "textures/glare.png"
- },
- },
- GuiName = "RosettaTrail"
- }, --]]
- -- Comet Dance trail
- --[[{
- Name = "RosettaCometTrail",
- Parent = "67P",
- Renderable = {
- Type = "RenderableTrail",
- Body = "ROSETTA",
- Frame = "GALACTIC",
- Observer = "CHURYUMOV-GERASIMENKO",
- TropicalOrbitPeriod = 20000.0,
- EarthOrbitRatio = 2,
- DayLength = 25,
- RGB = { 0.9, 0.2, 0.9 },
- Textures = {
- Type = "simple",
- Color = "textures/glare.png"
- },
- StartTime = "2014 AUG 01 12:00:00",
- EndTime = "2016 MAY 26 12:00:00"
- },
- GuiName = "RosettaCometTrail"
- },
- ]]
- {
+ {
Name = "RosettaCometTrail",
Parent = "67PBarycenter",
Renderable = {
@@ -341,7 +374,7 @@ return {
Frame = "GALACTIC",
Observer = "CHURYUMOV-GERASIMENKO",
-- Optional rendering properties
- LineColor = { 0.9, 0.2, 0.9 },
+ LineColor = { 0.288, 0.375, 0.934 },
PointColor = { 0.9, 0.2, 0.9 },
LineFade = 0.0, -- [0,1]
RenderPart = 0.5, -- [0,1]
@@ -351,23 +384,43 @@ return {
-- Time interval
TimeRange = {
Start = "2014 AUG 01 12:00:00",
- End = "2016 MAY 26 12:00:00"
+ End = "2016 SEP 30 12:00:00"
},
SampleDeltaTime = 3600, -- Seconds between each point
SubSamples = 3,
},
GuiName = "/Solar/RosettaCometTrail"
},
+ {
+ 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"
+ },
+ SampleDeltaTime = 2, -- Seconds between each point
+ SubSamples = 0,
+ },
+ GuiName = "/Solar/RosettaCometTrail"
+ },
{
Name = "NAVCAM",
Parent = "Rosetta",
- -- Transform = {
- -- Rotation = {
- -- Type = "SpiceRotation",
- -- SourceFrame = "NAVCAM",
- -- DestinationFrame = "ROS_SPACECRAFT",
- -- },
- -- },
GuiName = "/Solar/Rosetta_navcam"
},
{
diff --git a/data/scene/sun/sun.mod b/data/scene/sun/sun.mod
index 288335bb39..17caf205be 100644
--- a/data/scene/sun/sun.mod
+++ b/data/scene/sun/sun.mod
@@ -50,7 +50,8 @@ return {
Size = {1.3, 10.5},
Origin = "Center",
Billboard = true,
- Texture = "textures/sun-glare.png"
+ Texture = "textures/sun-glare.png",
+ BlendMode = "Additive"
},
Ephemeris = {
Type = "Spice",
@@ -70,7 +71,8 @@ return {
Size = {3.0, 11.0},
Origin = "Center",
Billboard = true,
- Texture = "textures/marker.png"
+ Texture = "textures/marker.png",
+ BlendMode = "Additive"
},
Ephemeris = {
Type = "Static",
diff --git a/ext/ghoul b/ext/ghoul
index b08559d8b2..e45911445d 160000
--- a/ext/ghoul
+++ b/ext/ghoul
@@ -1 +1 @@
-Subproject commit b08559d8b2d4804348bcfb815bfbd620906e3039
+Subproject commit e45911445d85b884baa017e175d6a175ca421d76
diff --git a/ext/sgct b/ext/sgct
index 70cde82e33..9ad36dbaa5 160000
--- a/ext/sgct
+++ b/ext/sgct
@@ -1 +1 @@
-Subproject commit 70cde82e331406d8bfe406d0e606fefa89d873c7
+Subproject commit 9ad36dbaa55d5267556a32338f8776a85c463321
diff --git a/include/openspace/documentation/core_registration.h b/include/openspace/documentation/core_registration.h
new file mode 100644
index 0000000000..d29259daf2
--- /dev/null
+++ b/include/openspace/documentation/core_registration.h
@@ -0,0 +1,38 @@
+/*****************************************************************************************
+ * *
+ * 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 __CORE_REGISTRATION_H__
+#define __CORE_REGISTRATION_H__
+
+namespace openspace {
+namespace documentation {
+
+class DocumentationEngine;
+
+void registerCoreClasses(documentation::DocumentationEngine& engine);
+
+} // namespace documentation
+} // namespace openspace
+
+#endif // __CORE_REGISTRATION_H__
diff --git a/include/openspace/documentation/documentation.h b/include/openspace/documentation/documentation.h
new file mode 100644
index 0000000000..a200be79a8
--- /dev/null
+++ b/include/openspace/documentation/documentation.h
@@ -0,0 +1,288 @@
+/*****************************************************************************************
+ * *
+ * 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 __DOCUMENTATION_H__
+#define __DOCUMENTATION_H__
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+namespace openspace {
+namespace documentation {
+
+using Optional = ghoul::Boolean;
+using Exhaustive = ghoul::Boolean;
+
+/**
+ * The TestResult structure returns the information from the #testSpecification method. It
+ * contains the information whether test specification test was successful
+ * (TestResult::success) and a list of TestResult::Offense%s (TestResult::offenses). If
+ * TestResult::success is true, TestResult::offenses is guaranteed to be empty.
+ */
+struct TestResult {
+ /**
+ * An Offense is a violation against a specific verifier. The Offense::offender is the
+ * key that caused the offense (in the case of nested tables, it will be fully
+ * qualified identifier) and the Offense::Reason is the reason that caused the
+ * offense.
+ */
+ struct Offense {
+ /**
+ * The Reason for the offense
+ */
+ enum class Reason {
+ MissingKey, ///< The offending key that was requested was not found
+ ExtraKey, ///< The exhaustive documentation contained an extra key
+ WrongType, ///< The key's value was not of the expected type
+ Verification, ///< The value did not pass a necessary non-type verifier
+ UnknownIdentifier ///< If the identifier for a ReferencingVerifier did not exist
+ };
+ /// The offending key that caused the Offense. In the case of a nested table,
+ /// this value will be the fully qualified name of the key
+ std::string offender;
+ /// The Reason that caused this offense
+ Reason reason;
+ };
+ /// Is \c true if the TestResult is positive, \c false otherwise
+ bool success;
+ /// Contains a list of offenses that were found in the test. Is empty if
+ /// TestResult::Success is \c true
+ std::vector offenses;
+};
+
+/**
+ * This exception is thrown by the #testSpecificationAndThrow method if the test detected
+ * a specification violation. This class contains the TestResult that would have otherwise
+ * be returned in a call to #testSpecification.
+ */
+struct SpecificationError : public ghoul::RuntimeError {
+ /**
+ * Creates the SpecificationError exception instance.
+ * \param result The offending TestResult that is passed on
+ * \param component The component that initiated the specification test
+ * \pre \p result%'s TestResult::success must be \c false
+ */
+ SpecificationError(TestResult result, std::string component);
+
+ /// The TestResult that caused the SpecificationError to be thrown
+ TestResult result;
+};
+
+struct Verifier;
+
+/**
+ * A DocumentationEntry provides the specification for a single key, which is tested using
+ * the provided Verifier. Each DocumentationEntry can contain a textual documentation that
+ * describes the entry and is printed when the documentation for a Documentation is
+ * requested. Lastly, each DocumentationEntry can be Optional. If the provided key is the
+ * DocumentationEntry::Wildcard, any key in the containing Documentation will be tested
+ * against the provided verifier. The most convenient way of creating DocumentationEntry%s
+ * is by using an inline initializer list such as:
+ *\verbatim
+DocumentationEntry e = { "key", new IntVerifier, "Documentation text", Optional::Yes };
+\endverbatim
+
+ * Furthermore, these initializer lists can be crated all at once for a Documentation.
+ * Even if the Verifier%s are specified using the \c new operators, they will not leak
+ * memory as the DocumentationEntry takes ownership of them in the constructor.
+ */
+struct DocumentationEntry {
+ /// The wildcard character that will match against every key in a Documentation
+ static const std::string Wildcard;
+
+ /**
+ * The constructor for a DocumentationEntry describing a \p key in a Documentation.
+ * The value for the key (or each value in the case of the
+ * DocumentationEntry::Wildcard) is tested using the \p verifier, that specifies the
+ * conditions that the \p key%'s value has to fulfill. The textual documentation
+ * \p doc shall describe the usage of the key-value pair and will be printed for human
+ * consumption for example in the DocumentationEngine. Each DocumentationEntry can
+ * further be \p optional.
+ * \param key The key for which this DocumentationEntry is valid. If this valid is
+ * equal to DocumentationEntry::Wildcard, each entry in the Documentation that
+ * contains this DocumentationEntry will be matched
+ * \param verifier The Verifier that is used to test the \p key%'s value to determine
+ * if it is a valid value
+ * \param doc The textual documentation that describes the DocumentationEntry in a
+ * human readable format
+ * \param optional Determines whether the Documentation containing this
+ * DocumentationEntry must have a key \p key, or whether it is optional
+ * \pre \p key must not be empty
+ * \pre \p verifier must not be nullptr
+ */
+ DocumentationEntry(std::string key, std::shared_ptr verifier,
+ std::string doc = "", Optional optional = Optional::No);
+
+ /**
+ * The constructor for a DocumentationEntry describing a \p key in a Documentation.
+ * The value for the key (or each value in the case of the
+ * DocumentationEntry::Wildcard) is tested using the \p verifier, that specifies the
+ * conditions that the \p key%'s value has to fulfill. The textual documentation
+ * \p doc shall describe the usage of the key-value pair and will be printed for human
+ * consumption for example in the DocumentationEngine. Each DocumentationEntry can
+ * further be \p optional.
+ * \param key The key for which this DocumentationEntry is valid. If this valid is
+ * equal to DocumentationEntry::Wildcard, each entry in the Documentation that
+ * contains this DocumentationEntry will be matched
+ * \param verifier The Verifier that is used to test the \p key%'s value to determine
+ * if it is a valid value. The DocumentationEntry will take ownership of the passed
+ * object
+ * \param doc The textual documentation that describes the DocumentationEntry in a
+ * human readable format
+ * \param optional Determines whether the Documentation containing this
+ * DocumentationEntry must have a key \p key, or whether it is optional
+ * \pre \p key must not be empty
+ * \pre \p verifier must not be nullptr
+ */
+ DocumentationEntry(std::string key, Verifier* verifier, std::string doc = "",
+ Optional optional = Optional::No);
+
+ /// The key that is described by this DocumentationEntry
+ std::string key;
+ /// The Verifier that is used to test the key's value
+ std::shared_ptr verifier;
+ /// Determines whether the described DocumentationEntry is optional or not
+ Optional optional;
+ /// The textual description of this DocumentationEntry
+ std::string documentation;
+};
+
+
+/**
+ * This struct contains the documentation and specification for a ghoul::Dictionary. It is
+ * used to impose restrictions on keys and values and determine whether a given
+ * ghoul::Dictionary adheres to these specifications (see #testSpecification and
+ * #testSpecificationAndThrow methods). Each Documentation consists of a human-readable
+ * \c name, a list of DocumentationEntry%s that each describe a single key value, and a
+ * flag whether these entries are Exhaustive or not. If a Documentation is Exhaustive, a
+ * ghoul::Dictionary that contains additional keys will fail the specification, whereas a
+ * non-exhaustive Documentation allow for other (potentially non used) keys. The most
+ * convenient way of creating a Documentation is by using nested initializer lists:
+ *\verbatim
+Documentation doc = {
+ "Documentation for an arbitrary dictionary",
+ { // A list of DocumentationEntry%s; also specified using initializer lists
+ { "key1", new IntVerifier, "Documentation key1", Optional::Yes },
+ { "key2", new FloatVerifier, "Documentation key2" },
+ { "key3", new StringVerifier }
+ },
+ Exhaustive::Yes
++;
+\endverbatim
+ *
+ * If multiple DocumentationEntries cover the same key, they are all evaluated for that
+ * specific key. The same holds true if there is a DocumentationEntry with a
+ * DocumentationEntry::Wildcard and a more specialized DocumentationEntry. In this case,
+ * both the wildcard and the specialized entry will be evaluated.
+ */
+struct Documentation {
+ using DocumentationEntries = std::vector;
+
+ /**
+ * Creates a Documentation with a human-readable \p name and a list of \p entries.
+ * \param name The human-readable name of this Documentation
+ * \param id A unique identifier which can be used by applications (or other
+ * Documentation%s to reference this entry
+ * \param entries A list of DocumentationEntry%s that describe the individual keys for
+ * this entrie Documentation
+ * \param exhaustive Determines whether the \p entries are an exhaustive specification
+ * of the object or whether additional, potentially unused, keys are allowed
+ */
+ Documentation(std::string name, std::string id, DocumentationEntries entries = {},
+ Exhaustive exhaustive = Exhaustive::No);
+
+ /**
+ * Creates a Documentation with a human-readable \p name.
+ * \param name The human-readable name of this Documentation
+ * \param entries A list of DocumentationEntry%s that describe the individual keys for
+ * this entrie Documentation
+ * \param exhaustive Determines whether the \p entries are an exhaustive specification
+ * of the object or whether additional, potentially unused, keys are allowed
+ */
+ Documentation(std::string name, DocumentationEntries entries = {},
+ Exhaustive exhaustive = Exhaustive::No);
+
+ /**
+ * Creates a Documentation.
+ * \param entries A list of DocumentationEntry%s that describe the individual keys for
+ * this entrie Documentation
+ * \param exhaustive Determines whether the \p entries are an exhaustive specification
+ * of the object or whether additional, potentially unused, keys are allowed
+ */
+ Documentation(DocumentationEntries entries = {}, Exhaustive exhaustive = Exhaustive::No);
+
+ /// The human-readable name of the Documentation
+ std::string name;
+ /// A unique identifier which can be used to reference this Documentation
+ std::string id;
+ /// A list of specifications that are describing this Documentation
+ DocumentationEntries entries;
+ /// A flag to say wheter the DocumentationEntries are an exhaustive description
+ Exhaustive exhaustive;
+};
+
+/**
+ * This method tests whether a provided ghoul::Dictionary \p dictionary adheres to the
+ * specification \p documentation and returns its result as a TestResult. The TestResult
+ * will contain whether the \p dictionary adheres to the \p documentation and, in
+ * addition, the list of all offending keys together with the reason why they are
+ * offending.
+ * \param documentation The Documentation that the \p dictionary is tested against
+ * \param dictionary The ghoul::Dictionary that is to be tested against the
+ * \p documentation
+ * \return A TestResult that contains the results of the specification testing
+ */
+TestResult testSpecification(const Documentation& documentation,
+ const ghoul::Dictionary& dictionary);
+
+/**
+* This method tests whether a provided ghoul::Dictionary \p dictionary adheres to the
+* specification \p documentation. If the \p dictionary does not adhere to the
+* specification a SpecificationError is thrown, and the exception contains the TestResult
+* that contains more information about the offending keys. If the \p dictionary adheres to
+* the \p documentation, the method returns normally.
+* \param documentation The Documentation that the \p dictionary is tested against
+* \param dictionary The ghoul::Dictionary that is to be tested against the
+* \p documentation
+* \param component The component that is using this method; this argument is passed to the
+* SpecificationError that is thrown in case of not adhering to the \p documentation
+* \throw SpecificationError If the \p dictionary does not adhere to the \p documentation
+*/
+void testSpecificationAndThrow(const Documentation& documentation,
+ const ghoul::Dictionary& dictionary, std::string component);
+
+} // namespace documentation
+
+// We want to make it easier for people to use it, so we pull the Documentation class into
+// the openspace namespace
+using documentation::Documentation;
+
+} // namespace openspace
+
+#endif // __DOCUMENTATION_H__
diff --git a/include/openspace/documentation/documentationengine.h b/include/openspace/documentation/documentationengine.h
new file mode 100644
index 0000000000..7f8851686b
--- /dev/null
+++ b/include/openspace/documentation/documentationengine.h
@@ -0,0 +1,102 @@
+/*****************************************************************************************
+ * *
+ * 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 __DOCUMENTATIONENGINE_H__
+#define __DOCUMENTATIONENGINE_H__
+
+#include
+
+#include
+#include
+
+namespace openspace {
+namespace documentation {
+
+/**
+ * The DocumentationEngine has the ability to collect all Documentation%s that are
+ * produced in the application an write them out as a documentation file for human
+ * consumption.
+ */
+class DocumentationEngine : public ghoul::Singleton {
+public:
+ /**
+ * This exception is thrown by the addDocumentation method if a provided Documentation
+ * has an identifier, but the identifier was registered previously.
+ */
+ struct DuplicateDocumentationException : public ghoul::RuntimeError {
+ /**
+ * Constructor of a DuplicateDocumentationException storing the offending
+ * Documentation for later use.
+ * \param documentation The Documentation whose identifier was previously
+ * registered
+ */
+ DuplicateDocumentationException(Documentation documentation);
+
+ /// The offending Documentation whose identifier was previously registered
+ Documentation documentation;
+ };
+
+ /**
+ * Write the collected Documentation%s to disk at the \p filename in the specified
+ * \p type. A new file is created and silently overwritten in the location that
+ * \p filename is pointed to.
+ * \param filename The file that is to be created containing all the Documentation
+ * information.
+ * \param type The type of documentation that is written. Currently allowed values are
+ * \c text and \c html
+ */
+ void writeDocumentation(const std::string& filename, const std::string& type);
+
+ /**
+ * Adds the \p documentation to the list of Documentation%s that are written to a
+ * documentation file with the writeDocumentation method.
+ * \param documentation The Documentation object that is to be stored for later use
+ * \throws DuplicateDocumentationException If the \p documentation has a non-empty
+ * identifier and it was not unique
+ */
+ void addDocumentation(Documentation documentation);
+
+ /**
+ * Returns a list of all registered Documentation%s
+ * \return A list of all registered Documentation%s
+ */
+ std::vector documentations() const;
+
+ /**
+ * Returns a static reference to the main singleton DocumentationEngine
+ * \return A static reference to the main singleton DocumentationEngine
+ */
+ static DocumentationEngine& ref();
+
+private:
+ /// The list of all Documentation%s that are stored by the DocumentationEngine
+ std::vector _documentations;
+};
+
+} // namespace documentation
+} // namespace openspace
+
+#define DocEng (openspace::documentation::DocumentationEngine::ref())
+
+#endif // __DOCUMENTATIONENGINE_H__
diff --git a/include/openspace/documentation/verifier.h b/include/openspace/documentation/verifier.h
new file mode 100644
index 0000000000..15275a8539
--- /dev/null
+++ b/include/openspace/documentation/verifier.h
@@ -0,0 +1,858 @@
+/*****************************************************************************************
+ * *
+ * 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 __VERIFIER_H__
+#define __VERIFIER_H__
+
+#include
+
+#include
+
+namespace openspace {
+namespace documentation {
+
+/**
+ * The base class of all Verifier%s. Each object must have an Verifier::operator()
+ * overload, that performs the actual testing of the key inside the passed
+ * ghoul::Dictionary and return a TestResult. The Verifier::type method returns a
+ * human-readable representation of the type that is expected by the concret subclass of
+ * Verifier. Furthermore, the Verifier::documentation method returns a human-readable
+ * description of the Verifier subclass and what it tests for.
+ */
+struct Verifier {
+ /**
+ * This method tests whether the \p key contained in the \p dictionary adheres to
+ * whatever the concrete Verifer needs to test. The actual testing depends on the
+ * concrete subclass and can range from type testing (for example IntVerifier or
+ * StringVerifier) to more complex testing (for example DoubleInRangeVerifier or
+ * TableVerifier).
+ * \param dictionary The dictionary that contains the \p key which is to be tested by
+ * this Verifier
+ * \param key The key inside the \p dictionary that is to be tested
+ * \return A TestResult struct that contains information about whether the key adheres
+ * to the demands of the specific Verifier. If it does not, TestResult::offenders will
+ * either contain \p key or, in the case of a TableVerifier, a list of all offending
+ * subkeys as fully qualified names.
+ * \post If the return values' TestResult::success is \c true, its
+ * TestResult::offenders is empty
+ */
+ virtual TestResult operator()(const ghoul::Dictionary& dictionary,
+ const std::string& key) const = 0;
+
+ /**
+ * This method returns a human-readable string describing the type of object that is
+ * handled by the Verifier subclass. This is only used for generating a human-readable
+ * documentation and description of a Documenation object.
+ * \return A human-readable string describing the type of object for the Verifier
+ * \post The return value is not empty
+ */
+ virtual std::string type() const = 0;
+
+ /**
+ * This method returns a human-readable string describing the tests that the concrete
+ * Verifier subclass implements. This is only used for generating a human-readable
+ * documentation and description of a Documentation object.
+ * \return A human-readable string describing the tests that are performed by the
+ * Verifier
+ * \post The return value is not empty
+ */
+ virtual std::string documentation() const = 0;
+};
+
+//----------------------------------------------------------------------------------------
+// General verifiers
+//----------------------------------------------------------------------------------------
+
+/**
+ * The base class Verifier for all Verifier%s that have to test against a specific value
+ * type. This Verifier tests whether a given key exists and whether it has the same type
+ * as the template parameter \c T.
+ * \tparam T The type against which the key's value is tested
+ */
+template
+struct TemplateVerifier : public Verifier {
+ using Type = T;
+
+ /**
+ * Tests whether the \p key contained in the ghoul::Dictionary \p dictionary exists
+ * and has the same type as \c T.
+ * \param dictionary The ghoul::Dictionary that contains the \p key to be tested
+ * \param key The key inside the \p dictinoary that is to be tested
+ * \return A TestResult that contains the information whether the \p key exists in the
+ * \p dictionary and whether the key's value's type agrees with \c T.
+ * \post The return values' TestResult::success is either \c true and
+ * TestResult::offenders is empty, or it is \c false and TestResult::offenders
+ * contains \p key
+ */
+ TestResult operator()(const ghoul::Dictionary& dictionary,
+ const std::string& key) const override;
+
+ std::string documentation() const override;
+};
+
+/**
+ * A Verifier that checks whether a given key inside a ghoul::Dictionary is of type
+ * \c bool. No implicit conversion is considered in this testing.
+ */
+struct BoolVerifier : public TemplateVerifier {
+ std::string type() const override;
+};
+
+/**
+* A Verifier that checks whether a given key inside a ghoul::Dictionary is of type
+* \c double. No implicit conversion is considered in this testing.
+*/
+struct DoubleVerifier : public TemplateVerifier {
+ std::string type() const override;
+};
+
+/**
+* A Verifier that checks whether a given key inside a ghoul::Dictionary is of type
+* \c int. It will also return \c true if the key's value is of type \c double, but is a
+* integer value (for example, 0.0, 12.0, but not
+* 0.5).
+*/
+struct IntVerifier : public TemplateVerifier {
+ TestResult operator()(const ghoul::Dictionary& dict,
+ const std::string& key) const override;
+
+ std::string type() const override;
+};
+
+/**
+* A Verifier that checks whether a given key inside a ghoul::Dictionary is of type
+* std::string. No implicit conversion is considered in this testing.
+*/
+struct StringVerifier : public TemplateVerifier {
+ std::string type() const override;
+};
+
+/**
+* A Verifier that checks whether a given key inside a ghoul::Dictionary is another
+* ghoul::Dictionary. The constructor takes a list of DocumentationEntry%s, which are used
+* recursively to check the contained table. If this list is empty, a simple type testing
+* is performed instead. If the testing finds any offending keys, it will return those keys
+* with fully qualified names, that is, the name of the table will be prepended to the
+* offending keys. Example: If the key \c Table is tested and a passed DocumentationEntry
+* checks for a nested key \c a and this does not comply, this Verifier will return
+* Table.a as an offender.
+*/
+struct TableVerifier : public TemplateVerifier {
+ /**
+ * This constructor takes a list of DocumentationEntry%s that are used recursively to
+ * check the table (= ghoul::Dictionary) contained in the key's value. Similar to the
+ * Documentation, these DocumentationEntry%s can be Exhaustive or not.
+ * \param documentationEntries The DocumentationEntry%s that are used to recursively
+ * test the ghoul::Dictionary that is contained inside. If this list is empty, only a
+ * type check is performed
+ * \param exhaustive Whether the DocumentationEntry%s contained in
+ * \p documentationEntries completely describe the contained table or whether
+ * additional keys are allowed
+ */
+ TableVerifier(std::vector documentationEntries = {},
+ Exhaustive exhaustive = Exhaustive::No);
+
+ /**
+ * Checks whether the \p key%'s value is a table (= ghoul::Dictionary) and (if
+ * provided) recursively checks whether the table adheres to the DocumentationEntry%s
+ * provided in the constructor. If the testing finds any offending keys, it will
+ * return those keys with fully qualified names, that is, the name of the table will
+ * be prepended to the offending keys.
+ * \param dictionary The ghoul::Dictionary that is to be tested for the \p key
+ * \param key The key for which the \p dictionary is tested
+ * \return A TestResult containing the results of the testing. If DocumentationEntry%s
+ * were specified in the constructor and one of those values find an offending key
+ * inside the table, it's name will be returned with a fully qualified name by
+ * prepending the name (= \key) of the table.
+ */
+ TestResult operator()(const ghoul::Dictionary& dictionary,
+ const std::string& key) const override;
+
+ std::string type() const override;
+
+ /// The documentations passed in the constructor
+ std::vector documentations;
+ /// Flag that specifies whether the TableVerifier::documentation exhaustively
+ /// describes the table or whether additional keys are allowed
+ Exhaustive exhaustive;
+};
+
+//----------------------------------------------------------------------------------------
+// Vector verifiers
+//----------------------------------------------------------------------------------------
+
+/**
+ * This struct is the base class for all Verifier%s that check for \c glm vector types.
+ * The template parameter for the subclasses is the containing type, not the full vector
+ * type. For example to check for glm::dvec3, one would create a
+ * Vector3Verifier.
+ */
+struct VectorVerifier {};
+
+/**
+ * This Verifier checks whether the value is of type glm::tvec2
+ */
+template
+struct Vector2Verifier : public TemplateVerifier>, public VectorVerifier {
+ std::string type() const override;
+};
+
+/**
+* This Verifier checks whether the value is of type glm::tvec3
+*/
+template
+struct Vector3Verifier : public TemplateVerifier>, public VectorVerifier {
+ std::string type() const override;
+};
+
+/**
+* This Verifier checks whether the value is of type glm::tvec4
+*/
+template
+struct Vector4Verifier : public TemplateVerifier>, public VectorVerifier {
+ std::string type() const override;
+};
+
+//----------------------------------------------------------------------------------------
+// Operator verifiers
+//----------------------------------------------------------------------------------------
+
+/**
+ * This is the abstract base class of all binary operator-based verifiers. This class
+ * takes two template parameters. The first is the Verifier that one would use to only
+ * check for the type of the object, for example IntVerifier. The second argument is a
+ * function object that has its operator() function overloaded and returns a
+ * boolean value. In these cases, the \c std function objects std::less,
+ * std::equal_to, etc are used.
+ *
+ * This verifier will apply the \c Operator to the stored value and the incoming value
+ * (after type checking) and will check if the \c Operator returns \c true or \c false.
+ * The incoming value is used as the first argument and the stored value as the second
+ * argument to the \c Operator. If the type checking fails, the offense reason
+ * TestResult::Offense::Reason::WrongType is returned. If the \c Operator fails, the
+ * reason TestResult::Offense::Verification is returned instead.
+ */
+template
+struct OperatorVerifier : public T {
+ /**
+ * Constructor for an OperatorVerifier. As all operators need to compare the incoming
+ * value to a stored value, we require the comparison \p value to be passed in here.
+ * \param value The value against which the tested value is compared using the
+ * \c Operator
+ */
+ OperatorVerifier(typename T::Type value);
+
+ /**
+ * First checks whether the \p dictionary contains the passed \p key and whether the
+ * \p key%'s value is correct using the template paramater \c T as a verifier. Then,
+ * the \p key%'s value is checked against the stored OperatorVerifier::value using the
+ * \c Operator.
+ * \param dictionary The ghoul::Dictionary that contains the \p key to be tested
+ * \param key The key inside the \p dictinoary that is to be tested
+ * \return A TestResult containing the results of the specification testing. If the
+ * \p key%'s value has the wrong type, it will be added to the TestResult's offense
+ * list with the reason TestResult::Offense::Reason::WrongType; if the \c Operator
+ * returns false, it will be added with the reason TestResult::Offense::Verification
+ * instead.
+ */
+ TestResult operator()(const ghoul::Dictionary& dictionary,
+ const std::string& key) const override;
+
+ /// The stored value which is passed to the \c Operator as a second argument
+ typename T::Type value;
+};
+
+/**
+ * This Verifier checks whether the incoming value is strictly smaller than the stored
+ * value. Due to the operator type restrictions, \c T cannot be a subclass of (or the same
+ * as) BoolVerifier, StringVerifier, TableVerifier, or VectorVerifier.
+ */
+template
+struct LessVerifier : public OperatorVerifier> {
+ static_assert(!std::is_base_of_v, "T cannot be BoolVerifier");
+ static_assert(!std::is_base_of_v, "T cannot be StringVerifier");
+ static_assert(!std::is_base_of_v, "T cannot be TableVerifier");
+ static_assert(!std::is_base_of_v, "T cannot be VectorVerifier");
+
+ using OperatorVerifier::OperatorVerifier;
+
+ std::string documentation() const;
+};
+
+/**
+* This Verifier checks whether the incoming value is smaller than or equal to the stored
+* value. Due to the operator type restrictions, \c T cannot be a subclass of (or the same
+* as) BoolVerifier, StringVerifier, TableVerifier, or VectorVerifier.
+*/
+template
+struct LessEqualVerifier : public OperatorVerifier> {
+ static_assert(!std::is_base_of_v, "T cannot be BoolVerifier");
+ static_assert(!std::is_base_of_v, "T cannot be StringVerifier");
+ static_assert(!std::is_base_of_v, "T cannot be TableVerifier");
+ static_assert(!std::is_base_of_v, "T cannot be VectorVerifier");
+
+ using OperatorVerifier::OperatorVerifier;
+
+ std::string documentation() const override;
+};
+
+/**
+* This Verifier checks whether the incoming value is strictly greater than the stored
+* value. Due to the operator type restrictions, \c T cannot be a subclass of (or the same
+* as) BoolVerifier, StringVerifier, TableVerifier, or VectorVerifier.
+*/
+template
+struct GreaterVerifier : public OperatorVerifier> {
+ static_assert(!std::is_base_of_v, "T cannot be BoolVerifier");
+ static_assert(!std::is_base_of_v, "T cannot be StringVerifier");
+ static_assert(!std::is_base_of_v, "T cannot be TableVerifier");
+ static_assert(!std::is_base_of_v, "T cannot be VectorVerifier");
+
+ using OperatorVerifier::OperatorVerifier;
+
+ std::string documentation() const override;
+};
+
+/**
+* This Verifier checks whether the incoming value is greater than or equal to the stored
+* value. Due to the operator type restrictions, \c T cannot be a subclass of (or the same
+* as) BoolVerifier, StringVerifier, TableVerifier, or VectorVerifier.
+*/
+template
+struct GreaterEqualVerifier : public OperatorVerifier> {
+ static_assert(!std::is_base_of_v, "T cannot be BoolVerifier");
+ static_assert(!std::is_base_of_v, "T cannot be StringVerifier");
+ static_assert(!std::is_base_of_v, "T cannot be TableVerifier");
+ static_assert(!std::is_base_of_v, "T cannot be VectorVerifier");
+
+ using OperatorVerifier::OperatorVerifier;
+
+ std::string documentation() const override;
+};
+
+/**
+* This Verifier checks whether the incoming value is equal to the stored value. Due to the
+* operator type restrictions, \c T cannot be a subclass of (or the same as) TableVerifier.
+*/
+template
+struct EqualVerifier : public OperatorVerifier> {
+ static_assert(!std::is_base_of_v, "T cannot be TableVerifier");
+
+ using OperatorVerifier::OperatorVerifier;
+
+ std::string documentation() const override;
+};
+
+/**
+* This Verifier checks whether the incoming value is unequal to the store value. Due to
+* the operator type restrictions, \c T cannot be a subclass of (or the same as)
+* TableVerifier.
+*/
+template
+struct UnequalVerifier : public OperatorVerifier> {
+ static_assert(!std::is_base_of_v, "T cannot be TableVerifier");
+
+ using OperatorVerifier::OperatorVerifier;
+
+ std::string documentation() const override;
+};
+
+//----------------------------------------------------------------------------------------
+// List verifiers
+//----------------------------------------------------------------------------------------
+
+/**
+ * This Verifier checks whether the incoming value is of the correct type, using the
+ * Verifier passed as a template parameter \c T and then checks whether it is part of a
+ * list that is passed to the constructor. To the missing equality operator, \c T cannot
+ * be a subclass of (or the same as) TableVerifier.
+ */
+template
+struct InListVerifier : public T {
+ static_assert(!std::is_base_of_v, "T cannot be TableVerifier");
+
+ /**
+ * Constructs an InListVerifier that checks whether the incoming value is of the
+ * correct type and whether the value is part of the list passed as \p values.
+ * \param values The list of values against which the incoming value is tested
+ */
+ InListVerifier(std::vector values);
+
+ /**
+ * Tests whether the \p key exists in the \p dictionary, whether it has the correct
+ * type by invoking the template parameter \c T, and then tests if the \p key's value
+ * is part of the list passed to the constructor.
+ * \param dictionary The ghoul::Dictionary that contains the \p key
+ * \param key The key that is contained in the \p dictionary and whose value is tested
+ * \return A TestResult containing the results of the specification testing. If the
+ * \p key%'s value has the wrong type, it will be added to the TestResult's offense
+ * list with the reason TestResult::Offense::Reason::WrongType; if the value is not
+ * in the list, it will be added with the reason TestResult::Offense::Verification
+ * instead.
+ */
+ TestResult operator()(const ghoul::Dictionary& dictionary,
+ const std::string& key) const override;
+
+ std::string documentation() const override;
+
+ /// The list of values against which the incoming value is tested
+ std::vector values;
+};
+
+/**
+* This Verifier checks whether the incoming value is of the correct type, using the
+* Verifier passed as a template parameter \c T and then checks whether it is not part of a
+* list that is passed to the constructor. To the missing equality operator, \c T cannot
+* be a subclass of (or the same as) TableVerifier.
+*/
+template
+struct NotInListVerifier : public T {
+ static_assert(!std::is_base_of_v, "T cannot be TableVerifier");
+
+ /**
+ * Constructs a NotInListVerifier that checks whether the incoming value is of the
+ * correct type and whether the value is not part of the list passed as \p values.
+ * \param values The list of values against which the incoming value is tested
+ */
+ NotInListVerifier(std::vector values);
+
+ /**
+ * Tests whether the \p key exists in the \p dictionary, whether it has the correct
+ * type by invoking the template parameter \c T, and then tests if the \p key's value
+ * is not part of the list passed to the constructor.
+ * \param dictionary The ghoul::Dictionary that contains the \p key
+ * \param key The key that is contained in the \p dictionary and whose value is tested
+ * \return A TestResult containing the results of the specification testing. If the
+ * \p key%'s value has the wrong type, it will be added to the TestResult's offense
+ * list with the reason TestResult::Offense::Reason::WrongType; if the value is in the
+ * list, it will be added with the reason TestResult::Offense::Verification instead.
+ */
+ TestResult operator()(const ghoul::Dictionary& dictionary,
+ const std::string& key) const override;
+
+ std::string documentation() const override;
+
+ std::vector values;
+};
+
+//----------------------------------------------------------------------------------------
+// Range verifiers
+//----------------------------------------------------------------------------------------
+
+/**
+* This Verifier checks whether the incoming value is of the correct type, using the
+* Verifier passed as a template parameter \c T and then checks whether it is greater or
+* equal to a lower limit and less or equal to a higher limit. To the missing comparison
+* operators, \c T cannot be a subclass of (or the same as) BoolVerifier, StringVerifier,
+* TableVerifier, or VectorVerifier. Both the lower and the higher limit are inclusive).
+*/
+template
+struct InRangeVerifier : public T {
+ static_assert(!std::is_base_of_v, "T cannot be BoolVerifier");
+ static_assert(!std::is_base_of_v, "T cannot be StringVerifier");
+ static_assert(!std::is_base_of_v, "T cannot be TableVerifier");
+ static_assert(!std::is_base_of_v, "T cannot be VectorVerifier");
+
+ /**
+ * Constructs a InRangeVerifier that checks whether the incoming value is of the
+ * correct type and whether the value is greater or equal to \p lower and less or equal
+ * to \upper.
+ * \param lower The (inclusive) lower limit of the range
+ * \param upper The (inclusive) upper limit of the range
+ * \pre \p lower must be smaller or equal to \p upper
+ */
+ InRangeVerifier(typename T::Type lower, typename T::Type upper);
+
+ /**
+ * Tests whether the \p key exists in the \p dictionary, whether it has the correct
+ * type by invoking the template parameter \c T, and then tests if the \p key's value
+ * is between the lower and upper limits (both inclusive) that were passed to the
+ * constructor.
+ * \param dictionary The ghoul::Dictionary that contains the \p key
+ * \param key The key that is contained in the \p dictionary and whose value is tested
+ * \return A TestResult containing the results of the specification testing. If the
+ * \p key%'s value has the wrong type, it will be added to the TestResult's offense
+ * list with the reason TestResult::Offense::Reason::WrongType; if the value is outside
+ * the range defined by the lower and upper limits passed to the constructor, it will
+ * be added with the reason TestResult::Offense::Verification instead.
+ */
+ TestResult operator()(const ghoul::Dictionary& dictionary,
+ const std::string& key) const override;
+
+ std::string documentation() const override;
+
+ typename T::Type lower;
+ typename T::Type upper;
+};
+
+/**
+* This Verifier checks whether the incoming value is of the correct type, using the
+* Verifier passed as a template parameter \c T and then checks whether it is outside the
+* (exclusive) range defined by a lower and upper limit. To the missing comparison
+* operators, \c T cannot be a subclass of (or the same as) BoolVerifier, StringVerifier,
+* TableVerifier, or VectorVerifier. Both the lower and the higher limit are exclusive).
+*/
+template
+struct NotInRangeVerifier : public T {
+ static_assert(!std::is_base_of_v, "T cannot be BoolVerifier");
+ static_assert(!std::is_base_of_v, "T cannot be StringVerifier");
+ static_assert(!std::is_base_of_v, "T cannot be TableVerifier");
+ static_assert(!std::is_base_of_v, "T cannot be VectorVerifier");
+
+ /**
+ * Constructs a InRangeVerifier that checks whether the incoming value is of the
+ * correct type and whether the value is less then \p lower and greater than \upper.
+ * \param lower The (exclusive) lower limit of the range
+ * \param upper The (exclusive) upper limit of the range
+ * \pre \p lower must be smaller or equal to \p upper
+ */
+ NotInRangeVerifier(typename T::Type lower, typename T::Type upper);
+
+ /**
+ * Tests whether the \p key exists in the \p dictionary, whether it has the correct
+ * type by invoking the template parameter \c T, and then tests if the \p key's value
+ * is outside the lower and upper limits (both exclusive) that were passed to the
+ * constructor.
+ * \param dictionary The ghoul::Dictionary that contains the \p key
+ * \param key The key that is contained in the \p dictionary and whose value is tested
+ * \return A TestResult containing the results of the specification testing. If the
+ * \p key%'s value has the wrong type, it will be added to the TestResult's offense
+ * list with the reason TestResult::Offense::Reason::WrongType; if the value is greater
+ * or equal to the lower limit and less or equal to the upper limit, it will be added
+ * with the reason TestResult::Offense::Verification instead.
+ */
+ TestResult operator()(const ghoul::Dictionary& dictionary,
+ const std::string& key) const override;
+
+ std::string documentation() const override;
+
+ typename T::Type lower;
+ typename T::Type upper;
+};
+
+
+//----------------------------------------------------------------------------------------
+// Misc verifiers
+//----------------------------------------------------------------------------------------
+
+/**
+ * This Verifier only checks for the correct type of the incoming value. If the
+ * documentation is requested, it will return an additional string that is the annotation.
+ * This can be used to specify further conditions that are hard (or impossible) to codify,
+ * but the user should be notified about. This, for example, can be that used to notify
+ * the user that the parameter should be a file of a specific type.
+ */
+template
+struct AnnotationVerifier : public T {
+ /**
+ * Constructs an AnnotationVerifier that contains the passed \p annotation which is
+ * passed to the user when a documentation is requested.
+ * \param annotation The annotation that is stored and returned to the user when it
+ * is requested.
+ * \pre annotation must not be empty
+ */
+ AnnotationVerifier(std::string annotation);
+
+ std::string documentation() const override;
+
+ /// The annotation that is returned to the user in the documentation
+ std::string annotation;
+};
+
+/**
+ * This Verifier can reference and apply other Documentation%s that have been registered
+ * with a DocumentationEngine. The dependency is only resolved when the operator() is
+ * called, at which the referencing Documentation must have been registered, or the
+ * TestResult will contain an offense of TestResult::Offense::Reason::UnknownIdentifier.
+ * If the referenced Documentation exists, the stored Table will be checked against that
+ * Documentation.
+ */
+struct ReferencingVerifier : public TableVerifier {
+ /**
+ * Creates a ReferencingVerifier that references a documentation with the provided
+ * \p identifier. The ReferencingVerifier will use the static DocumentationEngine to
+ * retrieve Documentation%s and find the \p identifier among them.
+ * \param identifier The identifier of the Documentation that this Verifier references
+ */
+ ReferencingVerifier(std::string identifier);
+
+ /**
+ * Checks whether the \p key in the \p dictionary exists and is of type Table (similar
+ * to the TableVerifier). If it exists and is a Table, the Documentation referenced by
+ * the identifier provided in the constructor is used to validate the Table. If the
+ * identifier does not name a registered Documentation, the TestResult::offenses
+ * will contain the \p key and TestResult::Offense::Reason::UnknownIdentifier will be
+ * signaled. If the identifier exists and the \p key%'s value does not comply with the
+ * Documentation, the offending keys will be returned in the TestResult with their
+ * fully qualified names.
+ * \param dictionary The ghoul::Dictionary whose \p key should be tested
+ * \param key The key contained in the \p dictionary that should be tested
+ * \return A TestResult struct that contains the results of the testing
+ */
+ TestResult operator()(const ghoul::Dictionary& dictionary,
+ const std::string& key) const override;
+
+ std::string documentation() const override;
+
+ /// The identifier that references another Documentation registered with the
+ /// DocumentationEngine
+ std::string identifier;
+};
+
+//----------------------------------------------------------------------------------------
+// Misc verifiers
+//----------------------------------------------------------------------------------------
+
+/**
+ * This Verifier takes two Verifiers and performs a boolean \c and operation on their
+ * results. In essence, a value only passes this Verifier if it passes both Verifier%s
+ * that are passed in the constructor. Opposed to the C++ &&
+ * operator, the AndVerifier does not perform any short-circut evaluation.
+ */
+struct AndVerifier : public Verifier {
+ /**
+ * Constructs an AndVerifier with two Verifiers which must be cleared by incoming
+ * values in order to pass this Verifier.
+ * \param lhs The first Verifier that is to be tested
+ * \param rhs The second Verifier that is to be tested
+ * \pre lhs must not be nullptr
+ * \pre rhs must not be nullptr
+ */
+ AndVerifier(Verifier* lhs, Verifier* rhs);
+
+ /**
+ * Checks whether the \p dictionary contains the \p key and whether this key passes
+ * both Verifier%'s that were passed in the constructor. If the value fails either
+ * of the two Verifiers, it is only added once to the TestResult::offenses list with
+ * a reason of TestResult::Offense::Reason::Verification.
+ * \param dictionary The ghoul::Dictionary that is to be tested
+ * \param key The key contained in \p dictionary that is to be tested
+ * \return A TestResult object that contains the test results. If the value fails
+ * either of the two Verifiers, TestResult::success is \c false and the
+ * TestResult::offenses list contains \p with a reason of
+ * TestResult::Offense::Reason::Verification. If \p key%'s value passes both
+ * Verifier%s, the result's TestResult::success is \c true and the
+ * TestResult::offenses is empty.
+ */
+ TestResult operator()(const ghoul::Dictionary& dictionary,
+ const std::string& key) const override;
+
+ std::string type() const override;
+ std::string documentation() const override;
+
+ /// The first Verifier that incoming values are tested against
+ std::shared_ptr lhs;
+ /// The second Verifier that incoming values are tested against
+ std::shared_ptr rhs;
+};
+
+/**
+* This Verifier takes two Verifiers and performs a boolean \c or operation on their
+* results. In essence, a value only passes this Verifier if it passes either of the two
+* Verifier%s that are passed in the constructor. Opposed to the C++
+* || operator, the OrVerifier does not perform any short-circut evaluation.
+*/
+struct OrVerifier : public Verifier {
+ /**
+ * Constructs an OrVerifier with two Verifiers, either of which must be cleared by
+ * incoming values in order to pass this Verifier.
+ * \param lhs The first Verifier that is to be tested
+ * \param rhs The second Verifier that is to be tested
+ * \pre lhs must not be nullptr
+ * \pre rhs must not be nullptr
+ */
+ OrVerifier(Verifier* lhs, Verifier* rhs);
+
+ /**
+ * Checks whether the \p dictionary contains the \p key and whether this key passes
+ * either of the two Verifier%'s that were passed in the constructor. If the value
+ * fails both Verifiers, it is added to the TestResult::offenses list with a reason of
+ * TestResult::Offense::Reason::Verification.
+ * \param dictionary The ghoul::Dictionary that is to be tested
+ * \param key The key contained in \p dictionary that is to be tested
+ * \return A TestResult object that contains the test results. If the value fails
+ * both Verifiers, TestResult::success is \c false and the TestResult::offenses list
+ * contains \p with a reason of TestResult::Offense::Reason::Verification. If \p key%'s
+ * value passes either of the two Verifier%s, the result's TestResult::success is
+ * \c true and the TestResult::offenses is empty.
+ */
+ TestResult operator()(const ghoul::Dictionary& dict,
+ const std::string& key) const override;
+
+ std::string type() const override;
+ std::string documentation() const override;
+
+ /// The first Verifier that incoming values are tested against
+ std::shared_ptr lhs;
+ /// The second Verifier that incoming values are tested against
+ std::shared_ptr rhs;
+};
+
+/// A short-hand definition for a Verifier checking for glm::bvec2
+using BoolVector2Verifier = Vector2Verifier;
+/// A short-hand definition for a Verifier checking for glm::ivec2
+using IntVector2Verifier = Vector2Verifier;
+/// A short-hand definition for a Verifier checking for glm::dvec2
+using DoubleVector2Verifier = Vector2Verifier;
+/// A short-hand definition for a Verifier checking for glm::bvec3
+using BoolVector3Verifier = Vector3Verifier;
+/// A short-hand definition for a Verifier checking for glm::ivec3
+using IntVector3Verifier = Vector3Verifier;
+/// A short-hand definition for a Verifier checking for glm::dvec3
+using DoubleVector3Verifier = Vector3Verifier;
+/// A short-hand definition for a Verifier checking for glm::bvec4
+using BoolVector4Verifier = Vector4Verifier;
+/// A short-hand definition for a Verifier checking for glm::ivec4
+using IntVector4Verifier = Vector4Verifier;
+/// A short-hand definition for a Verifier checking for glm::dvec4
+using DoubleVector4Verifier = Vector4Verifier;
+
+/// A short-hand definition for a LessVerifier with a type check for \c int
+using IntLessVerifier = LessVerifier;
+/// A short-hand definition for a LessVerifier with a type check for \c double
+using DoubleLessVerifier = LessVerifier;
+/// A short-hand definition for a LessEqualVerifier with a type check for \c int
+using IntLessEqualVerifier = LessEqualVerifier;
+/// A short-hand definition for a LessEqualVerifier with a type check for \c double
+using DoubleLessEqualVerifier = LessEqualVerifier;
+/// A short-hand definition for a GreaterVerifier with a type check for \c int
+using IntGreaterVerifier = GreaterVerifier;
+/// A short-hand definition for a GreaterVerifier with a type check for \c double
+using DoubleGreaterVerifier = GreaterVerifier;
+/// A short-hand definition for a GreaterEqualVerifier with a type check for \c int
+using IntGreaterEqualVerifier = GreaterEqualVerifier;
+/// A short-hand definition for a GreaterEqualVerifier with a type check for \c double
+using DoubleGreaterEqualVerifier = GreaterEqualVerifier;
+/// A short-hand definition for a EqualVerifier with a type check for \c bool
+using BoolEqualVerifier = EqualVerifier;
+/// A short-hand definition for a EqualVerifier with a type check for \c int
+using IntEqualVerifier = EqualVerifier;
+/// A short-hand definition for a EqualVerifier with a type check for \c double
+using DoubleEqualVerifier = EqualVerifier;
+/// A short-hand definition for a EqualVerifier with a type check for \c string
+using StringEqualVerifier = EqualVerifier;
+/// A short-hand definition for a UnequalVerifier with a type check for \c bool
+using BoolUnequalVerifier = UnequalVerifier;
+/// A short-hand definition for a UnequalVerifier with a type check for \c int
+using IntUnequalVerifier = UnequalVerifier;
+/// A short-hand definition for a UnequalVerifier with a type check for \c double
+using DoubleUnequalVerifier = UnequalVerifier;
+/// A short-hand definition for a UnequalVerifier with a type check for \c string
+using StringUnequalVerifier = UnequalVerifier;
+
+/// A short-hand definition for a InListVerifier with a type check for \c bool
+using BoolInListVerifier = InListVerifier;
+/// A short-hand definition for a InListVerifier with a type check for \c int
+using IntInListVerifier = InListVerifier;
+/// A short-hand definition for a InListVerifier with a type check for \c double
+using DoubleInListVerifier = InListVerifier;
+/// A short-hand definition for a InListVerifier with a type check for \c string
+using StringInListVerifier = InListVerifier;
+/// A short-hand definition for a NotInListVerifier with a type check for \c bool
+using BoolNotInListVerifier = NotInListVerifier;
+/// A short-hand definition for a NotInListVerifier with a type check for \c int
+using IntNotInListVerifier = NotInListVerifier;
+/// A short-hand definition for a NotInListVerifier with a type check for \c double
+using DoubleNotInListVerifier = NotInListVerifier;
+/// A short-hand definition for a NotInListVerifier with a type check for \c string
+using StringNotInListVerifier = NotInListVerifier;
+
+/// A short-hand definition for a InRangeVerifier with a type check for \c int
+using IntInRangeVerifier = InRangeVerifier;
+/// A short-hand definition for a InRangeVerifier with a type check for \c double
+using DoubleInRangeVerifier = InRangeVerifier;
+/// A short-hand definition for a NotInRangeVerifier with a type check for \c int
+using IntNotInRangeVerifier = NotInRangeVerifier;
+/// A short-hand definition for a NotInRangeVerifier with a type check for \c double
+using DoubleNotInRangeVerifier = NotInRangeVerifier;
+
+/// A short-hand definition for a AnnotationVerifier with a type check for \c bool
+using BoolAnnotationVerifier = AnnotationVerifier;
+/// A short-hand definition for a AnnotationVerifier with a type check for \c int
+using IntAnnotationVerifier = AnnotationVerifier;
+/// A short-hand definition for a AnnotationVerifier with a type check for \c double
+using DoubleAnnotationVerifier = AnnotationVerifier;
+/// A short-hand definition for a AnnotationVerifier with a type check for \c string
+using StringAnnotationVerifier = AnnotationVerifier;
+/// A short-hand definition for a AnnotationVerifier with a type check for
+/// ghoul::Dictionary
+using TableAnnotationVerifier = AnnotationVerifier;
+
+// Definitions of external templates that are instantiated in the cpp file
+// This cuts down the compilation times as almost all of the possible template types do
+// not need to be instantiated multiple times
+extern template struct Vector2Verifier;
+extern template struct Vector2Verifier;
+extern template struct Vector2Verifier;
+extern template struct Vector3Verifier;
+extern template struct Vector3Verifier;
+extern template struct Vector3Verifier;
+extern template struct Vector4Verifier;
+extern template struct Vector4Verifier;
+extern template struct Vector4Verifier;
+
+extern template struct LessVerifier;
+extern template struct LessVerifier;
+extern template struct LessEqualVerifier;
+extern template struct LessEqualVerifier;
+extern template struct GreaterVerifier;
+extern template struct GreaterVerifier;
+extern template struct GreaterEqualVerifier;
+extern template struct GreaterEqualVerifier;
+extern template struct EqualVerifier;
+extern template struct EqualVerifier;
+extern template struct EqualVerifier;
+extern template struct EqualVerifier;
+extern template struct UnequalVerifier;
+extern template struct UnequalVerifier;
+extern template struct UnequalVerifier;
+extern template struct UnequalVerifier;
+
+extern template struct InListVerifier;
+extern template struct InListVerifier;
+extern template struct InListVerifier;
+extern template struct InListVerifier;
+extern template struct NotInListVerifier;
+extern template struct NotInListVerifier;
+extern template struct NotInListVerifier;
+extern template struct NotInListVerifier;
+
+extern template struct InRangeVerifier;
+extern template struct InRangeVerifier;
+extern template struct NotInRangeVerifier;
+extern template struct NotInRangeVerifier;
+
+extern template struct AnnotationVerifier;
+extern template struct AnnotationVerifier;
+extern template struct AnnotationVerifier;
+extern template struct AnnotationVerifier;
+extern template struct AnnotationVerifier;
+
+
+} // namespace documentation
+} // namespace openspace
+
+#include "verifier.inl"
+
+#endif // __VERIFIER_H__
diff --git a/include/openspace/documentation/verifier.inl b/include/openspace/documentation/verifier.inl
new file mode 100644
index 0000000000..5c4fad2389
--- /dev/null
+++ b/include/openspace/documentation/verifier.inl
@@ -0,0 +1,303 @@
+/*****************************************************************************************
+ * *
+ * 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
+
+namespace std {
+ std::string to_string(std::string value);
+}
+
+namespace openspace {
+namespace documentation {
+
+template
+TestResult TemplateVerifier::operator()(const ghoul::Dictionary& dict,
+ const std::string& key) const
+{
+ if (dict.hasKeyAndValue(key)) {
+ return { true, {} };
+ }
+ else {
+ if (dict.hasKey(key)) {
+ return { false, { { key, TestResult::Offense::Reason::WrongType } } };
+ }
+ else {
+ return { false, { { key, TestResult::Offense::Reason::MissingKey } } };
+ }
+ }
+}
+
+template
+std::string TemplateVerifier::documentation() const {
+ return "Type testing of '" + type() + "'";
+}
+
+template
+std::string Vector2Verifier::type() const {
+ using namespace std::string_literals;
+
+ return "Vector2<"s + typeid(T).name() + ">";
+}
+
+template
+std::string Vector3Verifier::type() const {
+ using namespace std::string_literals;
+
+ return "Vector3<"s + typeid(T).name() + ">";
+}
+
+template
+std::string Vector4Verifier::type() const {
+ using namespace std::string_literals;
+
+ return "Vector4<"s + typeid(T).name() + ">";
+}
+
+template
+OperatorVerifier::OperatorVerifier(typename T::Type value)
+ : value(std::move(value))
+{}
+
+template
+TestResult OperatorVerifier::operator()(const ghoul::Dictionary& dict,
+ const std::string& key) const
+{
+ TestResult res = T::operator()(dict, key);
+ if (res.success) {
+ if (Operator()(dict.value(key), value)) {
+ return { true, {} };
+ }
+ else {
+ return { false, { { key, TestResult::Offense::Reason::Verification }}};
+ }
+ }
+ else {
+ return res;
+ }
+}
+
+template
+std::string LessVerifier::documentation() const {
+ return "Less than: " + std::to_string(value);
+}
+
+template
+std::string LessEqualVerifier::documentation() const {
+ return "Less or equal to: " + std::to_string(value);
+}
+
+template
+std::string GreaterVerifier::documentation() const {
+ return "Greater than: " + std::to_string(value);
+}
+
+template
+std::string GreaterEqualVerifier::documentation() const {
+ return "Greater or equal to: " + std::to_string(value);
+}
+
+template
+std::string EqualVerifier::documentation() const {
+ return "Equal to: " + std::to_string(value);
+}
+
+template
+std::string UnequalVerifier::documentation() const {
+ return "Unequal to: " + std::to_string(value);
+}
+
+template
+InListVerifier::InListVerifier(std::vector values)
+ : values(std::move(values))
+{}
+
+template
+TestResult InListVerifier::operator()(const ghoul::Dictionary& dict,
+ const std::string& key) const
+{
+ TestResult res = T::operator()(dict, key);
+ if (res.success) {
+ typename T::Type value = dict.value(key);
+
+ auto it = std::find(values.begin(), values.end(), value);
+
+ if (it != values.end()) {
+ return { true, {} };
+ }
+ else {
+ return { false, { { key, TestResult::Offense::Reason::Verification } } };
+ }
+ }
+ else {
+ return res;
+ }
+}
+
+template
+std::string InListVerifier::documentation() const {
+ std::string result = "In list { ";
+
+ std::stringstream s;
+ std::copy(
+ values.begin(),
+ values.end(),
+ std::ostream_iterator(s, ",")
+ );
+
+ std::string joined = s.str();
+ // We need to remove a trailing ',' at the end of the string
+ result += joined.substr(0, joined.size() - 1);
+
+ result += " }";
+ return result;
+}
+
+template
+NotInListVerifier::NotInListVerifier(std::vector values)
+ : values(std::move(values))
+{}
+
+template
+TestResult NotInListVerifier::operator()(const ghoul::Dictionary& dict,
+ const std::string& key) const
+{
+ TestResult res = T::operator()(dict, key);
+ if (res.success) {
+ typename T::Type value = dict.value(key);
+
+ auto it = std::find(values.begin(), values.end(), value);
+
+ if (it == values.end()) {
+ return { true, {} };
+ }
+ else {
+ return { false, { { key, TestResult::Offense::Reason::Verification } } };
+ }
+ }
+ else {
+ return res;
+ }
+}
+
+template
+std::string NotInListVerifier::documentation() const {
+ std::string result = "Not in list { ";
+
+ std::stringstream s;
+ std::copy(
+ values.begin(),
+ values.end(),
+ std::ostream_iterator(s, ",")
+ );
+
+ std::string joined = s.str();
+ // We need to remove a trailing ',' at the end of the string
+ result += joined.substr(0, joined.size() - 1);
+
+ result += " }";
+ return result;
+}
+
+template
+InRangeVerifier::InRangeVerifier(typename T::Type lower, typename T::Type upper)
+ : lower(std::move(lower))
+ , upper(std::move(upper))
+{
+ ghoul_assert(lower <= upper, "lower must be smaller or equal to upper");
+}
+
+template
+TestResult InRangeVerifier::operator()(const ghoul::Dictionary& dict,
+ const std::string& key) const
+{
+ TestResult res = T::operator()(dict, key);
+ if (res.success) {
+ typename T::Type val = dict.value(key);
+
+ if (val >= lower && val <= upper) {
+ return { true, {} };
+ }
+ else {
+ return { false, { { key, TestResult::Offense::Reason::Verification } } };
+ }
+ }
+ else {
+ return res;
+ }
+}
+
+template
+std::string InRangeVerifier::documentation() const {
+ return "In range: ( " + std::to_string(lower) + "," +
+ std::to_string(upper) + " )";
+}
+
+template
+NotInRangeVerifier::NotInRangeVerifier(typename T::Type lower, typename T::Type upper)
+ : lower(std::move(lower))
+ , upper(std::move(upper))
+{
+ ghoul_assert(lower <= upper, "lower must be smaller or equal to upper");
+}
+
+template
+TestResult NotInRangeVerifier::operator()(const ghoul::Dictionary& dict,
+ const std::string& key) const {
+ TestResult res = T::operator()(dict, key);
+ if (res.success) {
+ typename T::Type val = dict.value(key);
+
+ if (val >= lower && val <= upper) {
+ return { false, { { key, TestResult::Offense::Reason::Verification } } };
+ }
+ else {
+ return { true, {} };
+ }
+ }
+ else {
+ return res;
+ }
+}
+
+template
+std::string NotInRangeVerifier::documentation() const {
+ return "Not in range: ( " + std::to_string(lower) + "," +
+ std::to_string(upper) + " )";
+}
+
+
+template
+AnnotationVerifier::AnnotationVerifier(std::string annotation)
+ : annotation(std::move(annotation))
+{
+ ghoul_assert(!this->annotation.empty(), "Annotation must not be empty");
+}
+
+template
+std::string AnnotationVerifier::documentation() const {
+ return annotation;
+}
+
+} // namespace documentation
+} // namespace openspace
diff --git a/include/openspace/engine/configurationmanager.h b/include/openspace/engine/configurationmanager.h
index 23a5109043..f242c6440f 100644
--- a/include/openspace/engine/configurationmanager.h
+++ b/include/openspace/engine/configurationmanager.h
@@ -25,6 +25,8 @@
#ifndef __CONFIGURATIONMANAGER_H__
#define __CONFIGURATIONMANAGER_H__
+#include
+
#include
namespace openspace {
@@ -49,22 +51,22 @@ public:
/// The key that stores the location of the SGCT configuration file that is used on
/// application launch
static const std::string KeyConfigSgct;
- /// The key that stores the type of Lua documentation that should be stored
- static const std::string KeyLuaDocumentationType;
- /// The key that stores the save location of the Lua documentation
- static const std::string KeyLuaDocumentationFile;
- /// The key that stores the type of scripting log that should be stored
- static const std::string KeyScriptLogType;
- /// The key that stores the save location of the scripting log
- static const std::string KeyScriptLogFile;
- /// The key that stores the type of Property documentation that should be stored
- static const std::string KeyPropertyDocumentationType;
- /// The key that stores the save location of the Property documentation
- static const std::string KeyPropertyDocumentationFile;
- /// The key that stores the type of keyboard bindings that should be stored
- static const std::string KeyKeyboardShortcutsType;
- /// The key that stores the save location of the keyboard bindings file
- static const std::string KeyKeyboardShortcutsFile;
+ /// The part of the key that defines the type
+ static const std::string PartType;
+ /// The part of the key that defines the file
+ static const std::string PartFile;
+ /// The key that stores the Lua documentation
+ static const std::string KeyLuaDocumentation;
+ /// The key that stores the scripting log
+ static const std::string KeyScriptLog;
+ /// The key that stores the Property documentation
+ static const std::string KeyPropertyDocumentation;
+ /// The key that stores the keyboard bindings that should be stored
+ static const std::string KeyKeyboardShortcuts;
+ /// The key that stores the main documentation
+ static const std::string KeyDocumentation;
+ /// The key that stores the factory documentation values
+ static const std::string KeyFactoryDocumentation;
/// The key that stores the location of the scene file that is initially loaded
static const std::string KeyConfigScene;
/// The key that stores the subdirectory containing a list of all startup scripts to
@@ -73,18 +75,24 @@ public:
/// The key that stores the subdirectory containing a list of all settings scripts to
/// be executed on application start and after the scene file is loaded
static const std::string KeySettingsScript;
+ /// The key that stores the settings for determining log-related settings
+ static const std::string KeyLogging;
/// The key that stores the desired LogLevel for the whole application
/// \sa ghoul::logging::LogManager
- static const std::string KeyLogLevel;
+ static const std::string PartLogLevel;
/// The key that stores whether the log should be immediately flushed after a n
/// \sa ghoul::logging::LogManager
- static const std::string KeyLogImmediateFlush;
+ static const std::string PartImmediateFlush;
/// The key that stores a subdirectory with a description for additional
/// ghoul::logging::Log%s to be created
/// \sa LogFactory
- static const std::string KeyLogs;
+ static const std::string PartLogs;
+ /// The key that stores whether a log should be appended to or should be overwritten
+ static const std::string PartAppend;
/// The key that stores the verbosity (None, Minimal, Default, Full) of the system
/// capabilities components
+ static const std::string PartCapabilitiesVerbosity;
+ /// The full key that stores the verbosity of the system capabilities component
static const std::string KeyCapabilitiesVerbosity;
/// The key that stores the time (in seconds) that the application will wait before
/// shutting down after the shutdown call is made
@@ -95,6 +103,9 @@ public:
/// The key that sets the request URL that is used to request additional data to be
/// downloaded
static const std::string KeyDownloadRequestURL;
+ /// The key that stores the switch for enabling/disabling the rendering on a master
+ /// computer
+ static const std::string KeyRenderingMethod;
/**
* Iteratively walks the directory structure starting with \p filename to find the
@@ -123,6 +134,8 @@ public:
*/
void loadFromFile(const std::string& filename);
+ static Documentation Documentation();
+
private:
/**
* Checks whether the loaded configuration file is complete, that is specifying the
diff --git a/include/openspace/interaction/interactionmode.h b/include/openspace/interaction/interactionmode.h
index 1a53683c8f..22c495266c 100644
--- a/include/openspace/interaction/interactionmode.h
+++ b/include/openspace/interaction/interactionmode.h
@@ -179,9 +179,9 @@ public:
class MouseStates
{
public:
- /*!
+ /**
\param sensitivity
- \param velocityScalefactor can be set to 60 to remove the inertia of the
+ \param velocityScaleFactor can be set to 60 to remove the inertia of the
interaction. Lower value will make it harder to move the camera.
*/
MouseStates(double sensitivity, double velocityScaleFactor);
diff --git a/include/openspace/properties/numericalproperty.h b/include/openspace/properties/numericalproperty.h
index 33a179b7fd..ffa257a16c 100644
--- a/include/openspace/properties/numericalproperty.h
+++ b/include/openspace/properties/numericalproperty.h
@@ -48,7 +48,10 @@ public:
bool setStringValue(std::string value) override;
T minValue() const;
+ void setMinValue(T value);
+
T maxValue() const;
+ void setMaxValue(T value);
virtual std::string className() const override;
diff --git a/include/openspace/properties/numericalproperty.inl b/include/openspace/properties/numericalproperty.inl
index 964c29190d..86f04e8f62 100644
--- a/include/openspace/properties/numericalproperty.inl
+++ b/include/openspace/properties/numericalproperty.inl
@@ -329,11 +329,21 @@ T NumericalProperty::minValue() const {
return _minimumValue;
}
+template
+void NumericalProperty::setMinValue(T value) {
+ _minimumValue = std::move(value);
+}
+
template
T NumericalProperty::maxValue() const {
return _maximumValue;
}
+template
+void NumericalProperty::setMaxValue(T value) {
+ _maximumValue = std::move(value);
+}
+
template
std::string NumericalProperty::generateAdditionalDescription() const {
std::string result;
diff --git a/include/openspace/properties/optionproperty.h b/include/openspace/properties/optionproperty.h
index 42bca29af6..39466779cf 100644
--- a/include/openspace/properties/optionproperty.h
+++ b/include/openspace/properties/optionproperty.h
@@ -60,9 +60,16 @@ public:
* to its super class.
* \param identifier A unique identifier for this property
* \param guiName The GUI name that should be used to represent this property
- * \param displayType Optional DisplayType for GUI (default RADIO)
*/
OptionProperty(std::string identifier, std::string guiName);
+
+ /**
+ * The constructor delegating the identifier and the guiName
+ * to its super class.
+ * \param identifier A unique identifier for this property
+ * \param guiName The GUI name that should be used to represent this property
+ * \param displayType Optional DisplayType for GUI (default RADIO)
+ */
OptionProperty(std::string identifier, std::string guiName, DisplayType displayType);
/**
diff --git a/include/openspace/properties/property.h b/include/openspace/properties/property.h
index 3ec235e341..c3cdb71572 100644
--- a/include/openspace/properties/property.h
+++ b/include/openspace/properties/property.h
@@ -71,6 +71,8 @@ public:
* \param identifier A unique identifier for this property. It has to be unique to the
* PropertyOwner and cannot contain any .s
* \param guiName The human-readable GUI name for this Property
+ * \pre \p identifier must not be empty
+ * \pre \p guiName must not be empty
*/
Property(std::string identifier, std::string guiName);
diff --git a/include/openspace/properties/scalarproperty.h b/include/openspace/properties/scalarproperty.h
index 29cdb9100c..7576edd37d 100644
--- a/include/openspace/properties/scalarproperty.h
+++ b/include/openspace/properties/scalarproperty.h
@@ -25,6 +25,77 @@
#ifndef __SCALARPROPERTY_H__
#define __SCALARPROPERTY_H__
+ /**
+ * \file scalarproperty.h
+ *
+ * \addtogroup openspace
+ * @{
+ * \addtogroup properties
+ * @{
+
+ * \class BoolProperty
+ * This class is a concrete implementation of openspace::properties::TemplateProperty with
+ * the type bool.
+
+ * \class CharProperty
+ * This class is a concrete implementation of openspace::properties::TemplateProperty with
+ * the type char.
+
+ * \class SignedCharProperty
+ * This class is a concrete implementation of openspace::properties::TemplateProperty with
+ * the type signed char.
+
+ * \class UCharProperty
+ * This class is a concrete implementation of openspace::properties::TemplateProperty with
+ * the type unsigned char.
+
+ * \class ShortProperty
+ * This class is a concrete implementation of openspace::properties::TemplateProperty with
+ * the type short.
+
+ * \class UShortProperty
+ * This class is a concrete implementation of openspace::properties::TemplateProperty with
+ * the type unsigned short.
+
+ * \class IntProperty
+ * This class is a concrete implementation of openspace::properties::TemplateProperty with
+ * the type int.
+
+ * \class UIntProperty
+ * This class is a concrete implementation of openspace::properties::TemplateProperty with
+ * the type unsigned int.
+
+ * \class LongProperty
+ * This class is a concrete implementation of openspace::properties::TemplateProperty with
+ * the type long.
+
+ * \class ULongProperty
+ * This class is a concrete implementation of openspace::properties::TemplateProperty with
+ * the type unsigned long.
+
+ * \class LongLongProperty
+ * This class is a concrete implementation of openspace::properties::TemplateProperty with
+ * the type long long.
+
+ * \class ULongLongProperty
+ * This class is a concrete implementation of openspace::properties::TemplateProperty with
+ * the type unsigned long long.
+
+ * \class FloatProperty
+ * This class is a concrete implementation of openspace::properties::TemplateProperty with
+ * the type float.
+
+ * \class DoubleProperty
+ * This class is a concrete implementation of openspace::properties::TemplateProperty with
+ * the type double.
+
+ * \class LongDoubleProperty
+ * This class is a concrete implementation of openspace::properties::TemplateProperty with
+ * the type long double.
+
+ * @} @}
+ */
+
#include "openspace/properties/numericalproperty.h"
namespace openspace {
diff --git a/include/openspace/properties/templateproperty.inl b/include/openspace/properties/templateproperty.inl
index 3567784124..ec8f8509a6 100644
--- a/include/openspace/properties/templateproperty.inl
+++ b/include/openspace/properties/templateproperty.inl
@@ -38,7 +38,7 @@ namespace properties {
// C++ class name for which a typedef will be created
// TYPE = The template parameter T for which the TemplateProperty is specialized
#define REGISTER_TEMPLATEPROPERTY_HEADER(CLASS_NAME, TYPE) \
- typedef TemplateProperty CLASS_NAME; \
+ using CLASS_NAME = TemplateProperty; \
\
template <> \
std::string PropertyDelegate>::className(); \
diff --git a/include/openspace/rendering/abufferrenderer.h b/include/openspace/rendering/abufferrenderer.h
index 4a9689fa9f..8a8dd5dba6 100644
--- a/include/openspace/rendering/abufferrenderer.h
+++ b/include/openspace/rendering/abufferrenderer.h
@@ -105,7 +105,7 @@ private:
/**
* When a volume is attached or detached from the scene graph,
* the resolve program needs to be recompiled.
- * The #_volumes map keeps track of which volumes that can
+ * The _volumes map keeps track of which volumes that can
* be rendered using the current resolve program, along with their raycast data
* (id, namespace, etc)
*/
diff --git a/include/openspace/rendering/renderable.h b/include/openspace/rendering/renderable.h
index 790c01419b..77904bd646 100644
--- a/include/openspace/rendering/renderable.h
+++ b/include/openspace/rendering/renderable.h
@@ -1,4 +1,3 @@
-
/*****************************************************************************************
* *
* OpenSpace *
@@ -33,6 +32,8 @@
#include
+#include
+
// Forward declare to minimize dependencies
namespace ghoul {
@@ -51,6 +52,13 @@ class PowerScaledCoordinate;
class Renderable : public properties::PropertyOwner {
public:
+ enum class RenderBin : int {
+ Background = 1,
+ Opaque = 2,
+ Transparent = 4,
+ Overlay = 8
+ };
+
static Renderable* createFromDictionary(const ghoul::Dictionary& dictionary);
// constructors & destructor
@@ -64,14 +72,18 @@ public:
virtual bool isReady() const = 0;
bool isEnabled() const;
- void setBoundingSphere(const PowerScaledScalar& boundingSphere);
- const PowerScaledScalar& getBoundingSphere();
+ void setBoundingSphere(PowerScaledScalar boundingSphere);
+ PowerScaledScalar getBoundingSphere();
virtual void render(const RenderData& data);
virtual void render(const RenderData& data, RendererTasks& rendererTask);
virtual void postRender(const RenderData& data);
virtual void update(const UpdateData& data);
+ RenderBin renderBin() const;
+ void setRenderBin(RenderBin bin);
+ bool matchesRenderBinMask(int binMask);
+
bool isVisible() const;
bool hasTimeInterval();
@@ -81,10 +93,13 @@ public:
static void setPscUniforms(ghoul::opengl::ProgramObject& program, const Camera& camera, const PowerScaledCoordinate& position);
+ static Documentation Documentation();
+
protected:
properties::BoolProperty _enabled;
private:
+ RenderBin _renderBin;
PowerScaledScalar boundingSphere_;
std::string _startTime;
std::string _endTime;
diff --git a/include/openspace/rendering/screenspacerenderable.h b/include/openspace/rendering/screenspacerenderable.h
index 9fa4c175c8..46cea14e32 100644
--- a/include/openspace/rendering/screenspacerenderable.h
+++ b/include/openspace/rendering/screenspacerenderable.h
@@ -35,6 +35,8 @@
#include
#include
+#include
+
namespace openspace {
/**
@@ -63,6 +65,8 @@ public:
glm::vec3 sphericalPosition() const;
float depth() const;
+ static openspace::Documentation Documentation();
+
protected:
void createPlane();
void useEuclideanCoordinates(bool b);
diff --git a/include/openspace/scene/ephemeris.h b/include/openspace/scene/ephemeris.h
index 026e024b24..ff7ae0a441 100644
--- a/include/openspace/scene/ephemeris.h
+++ b/include/openspace/scene/ephemeris.h
@@ -29,6 +29,8 @@
#include