diff --git a/.gitignore b/.gitignore index c413fb7c41..1006d42b46 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,72 @@ 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/osirisrex/bennu/models +data/scene/osirisrex/bennu/textures +data/scene/osirisrex/osirisrex/models +data/scene/osirisrex/osirisrex/textures +data/scene/pluto/textures +data/scene/saturn/textures +data/scene/rosetta/67P/obj +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/OsirisRexKernels +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/apps/OpenSpace/main.cpp b/apps/OpenSpace/main.cpp index 094f376248..49b47645a9 100644 --- a/apps/OpenSpace/main.cpp +++ b/apps/OpenSpace/main.cpp @@ -214,34 +214,97 @@ void mainInitFunc() { } -void mainPreSyncFunc() { - OsEng.setRunTime(sgct::Engine::getTime()); - OsEng.preSynchronization(); +struct FunctionLogKey { + char begin, end; +}; + +#include + + +std::stringstream& operator<<(std::stringstream& o, const FunctionLogKey& l) { + o << l.begin << l.end; + return o; } + + +const FunctionLogKey PRE_SYNC = { '1', '2' }; +const FunctionLogKey ENCODE = { 'E', 'e' }; +const FunctionLogKey DECODE = { 'D', 'd' }; +const FunctionLogKey POST_SYNC = { '3', '4' }; +const FunctionLogKey RENDER = { 'R', 'r' }; +const FunctionLogKey POST_DRAW = { 'P', 'p' }; + +std::stringstream minilog; +std::stringstream masterlog; +std::stringstream slavelog; + +const std::string EXPECTED_MASTER_LOG = (masterlog << PRE_SYNC << ENCODE << POST_SYNC << RENDER << POST_DRAW).str(); +const std::string EXPECTED_SLAVE_LOG = (slavelog << PRE_SYNC << DECODE << POST_SYNC << RENDER << POST_DRAW).str(); + +#define LOG_BEGIN(x) minilog << (x).begin +#define LOG_END(x) minilog << (x).end + + +void mainPreSyncFunc() { + LOG_BEGIN(PRE_SYNC); + OsEng.setRunTime(sgct::Engine::getTime()); + OsEng.preSynchronization(); + LOG_END(PRE_SYNC); +} + +volatile bool busyWaitDecode = false; void mainPostSyncPreDrawFunc() { + if (OsEng.useBusyWaitForDecode() && !sgct::Engine::instance()->isMaster()) { + while (minilog.str().size() && minilog.str().back() != DECODE.end) { + std::this_thread::sleep_for(std::chrono::microseconds(10)); + } + } + LOG_BEGIN(POST_SYNC); OsEng.postSynchronizationPreDraw(); + LOG_END(POST_SYNC); } void mainRenderFunc() { + LOG_BEGIN(RENDER); using glm::mat4; using glm::translate; //not the most efficient, but for clarity @JK - + mat4 userMatrix = translate(mat4(1.f), _sgctEngine->getDefaultUserPtr()->getPos()); mat4 sceneMatrix = _sgctEngine->getModelMatrix(); mat4 viewMatrix = _sgctEngine->getCurrentViewMatrix() * userMatrix; - + //dont shift nav-direction on master, makes it very tricky to navigate @JK if (!OsEng.ref().isMaster()) viewMatrix = viewMatrix * sceneMatrix; mat4 projectionMatrix = _sgctEngine->getCurrentProjectionMatrix(); OsEng.render(projectionMatrix, viewMatrix); + LOG_END(RENDER); } void mainPostDrawFunc() { + LOG_BEGIN(POST_DRAW); OsEng.postDraw(); + LOG_END(POST_DRAW); + + if (OsEng.logSGCTOutOfOrderErrors()) { + if (sgct::Engine::instance()->isMaster()) { + if (minilog.str() != EXPECTED_MASTER_LOG) { + LERRORC("Minilog", "Bad combination: " << minilog.str()); + } + } + else { + if (minilog.str() != EXPECTED_SLAVE_LOG) { + LERRORC("Minilog", "Bad combination: " << minilog.str()); + } + } + } + + + // clear + minilog.str(std::string()); } void mainExternalControlCallback(const char* receivedChars, int size) { @@ -255,7 +318,7 @@ void mainKeyboardCallback(int key, int, int action, int mods) { openspace::Key(key), openspace::KeyModifier(mods), openspace::KeyAction(action) - ); + ); } } @@ -264,7 +327,7 @@ void mainMouseButtonCallback(int key, int action) { OsEng.mouseButtonCallback( openspace::MouseButton(key), openspace::MouseAction(action) - ); + ); } } @@ -284,11 +347,16 @@ void mainCharCallback(unsigned int codepoint, int mods) { } void mainEncodeFun() { + LOG_BEGIN(ENCODE); OsEng.encode(); + LOG_END(ENCODE); } void mainDecodeFun() { + LOG_BEGIN(DECODE); OsEng.decode(); + LOG_END(DECODE); + } void mainLogCallback(const char* msg) { 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..f54904ac1f 100644 --- a/data/scene/atmosphereearth/atmosphereearth.mod +++ b/data/scene/atmosphereearth/atmosphereearth.mod @@ -7,11 +7,8 @@ return { Ephemeris = { Type = "Spice", Body = "EARTH BARYCENTER", - Reference = "ECLIPJ2000", Observer = "SUN", - Kernels = { - "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" - } + Kernels = "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" }, }, -- Earth module @@ -101,9 +98,7 @@ return { -- G = 0.65, -- }, } - }, - - GuiName = "/Solar/Planets/Earth" + } }, -- EarthTrail module { @@ -118,8 +113,7 @@ return { TropicalOrbitPeriod = 365.242, EarthOrbitRatio = 1, DayLength = 24 - }, - GuiName = "/Solar/EarthTrail" + } }, { Name = "EarthMarker", @@ -129,7 +123,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/batsrus/batsrus.mod b/data/scene/batsrus/batsrus.mod index f512afb550..a948893e53 100644 --- a/data/scene/batsrus/batsrus.mod +++ b/data/scene/batsrus/batsrus.mod @@ -57,8 +57,6 @@ return { TransferFunctionName = "BatsrusPTF", TransferFunction = "transferfunctions/p.txt", Sampler = "psampler.glsl", - }, - GuiName = "/Volumes/Volume" + } } - --]] } \ No newline at end of file diff --git a/data/scene/common/common.mod b/data/scene/common/common.mod index aa9e0d050c..22ac4fa860 100644 --- a/data/scene/common/common.mod +++ b/data/scene/common/common.mod @@ -2,10 +2,6 @@ return { -- Solar System module { Name = "SolarSystem", - Parent = "Root", - Ephemeris = { - Type = "Static", - Position = { 0, 0, 0, 0} - } + Parent = "Root" }, } \ No newline at end of file diff --git a/data/scene/constellationbounds/constellationbounds.mod b/data/scene/constellationbounds/constellationbounds.mod index 8d1ff2f91b..e23d57dc37 100644 --- a/data/scene/constellationbounds/constellationbounds.mod +++ b/data/scene/constellationbounds/constellationbounds.mod @@ -8,9 +8,6 @@ return { File = "${OPENSPACE_DATA}/scene/constellationbounds/data/bound_20.dat", ConstellationFile = "${OPENSPACE_DATA}/scene/constellationbounds/data/constellations.dat", ReferenceFrame = "J2000" - }, - Ephemeris = { - Type = "Static" } } } \ No newline at end of file diff --git a/data/scene/dawn/ceres/ceres.mod b/data/scene/dawn/ceres/ceres.mod index 2c2406d4a6..ff9c413a2a 100644 --- a/data/scene/dawn/ceres/ceres.mod +++ b/data/scene/dawn/ceres/ceres.mod @@ -23,7 +23,6 @@ return { Ephemeris = { Type = "Spice", Body = "CERES", - Reference = "GALACTIC", Observer = "SUN", Kernels = { "${OPENSPACE_DATA}/spice/DawnKernels/pck/dawn_ceres_v01.tpc", @@ -35,9 +34,7 @@ return { Type = "Spice", Frame = "IAU_CERES", Reference = "GALACTIC" - }, - - GuiName = "/Solar/Ceres" + } }, --[[ Ceres Trail Module { @@ -62,8 +59,7 @@ return { }, StartTime = "2010 JAN 01T00:00:00", EndTime = "2018 JAN 22 12:00:00" - }, - GuiName = "/Solar/CeresTrail" + } } --]] } \ No newline at end of file diff --git a/data/scene/dawn/dawn/dawn.mod b/data/scene/dawn/dawn/dawn.mod index e93fd3522b..65e003ac47 100644 --- a/data/scene/dawn/dawn/dawn.mod +++ b/data/scene/dawn/dawn/dawn.mod @@ -25,7 +25,6 @@ return { Ephemeris = { Type = "Spice", Body = "DAWN", - Reference = "GALACTIC", Observer = "SUN", Kernels = { "${OPENSPACE_DATA}/spice/DawnKernels/spk/dawn_ref_070926-150201_070829.bsp", @@ -621,8 +620,7 @@ return { "${OPENSPACE_DATA}/spice/DawnKernels/ck/dawn_sa_120903_120909.bc", "${OPENSPACE_DATA}/spice/DawnKernels/ck/dawn_sa_120910_120916.bc", } - }, - GuiName = "/Solar/Dawn" + } }, -- Dawn Solar Array module 1 @@ -719,7 +717,6 @@ return { StartTime = "2007 SEP 26 13:28:00", EndTime = "2012 SEP 12 12:00:00" }, - GuiName = "DawnTrail" }, -- -- -- Dawn Trail Module @@ -771,7 +768,6 @@ return { "CERES" } }, - GuiName = "/Solar/Dawn_FC1" }, -- DawnFov 1 @@ -798,6 +794,5 @@ return { "CERES" } }, - GuiName = "/Solar/Dawn_FC" }, } diff --git a/data/scene/dawn/vestaprojection/vestaprojection.mod b/data/scene/dawn/vestaprojection/vestaprojection.mod index bb5dc312ae..4de4d75dee 100644 --- a/data/scene/dawn/vestaprojection/vestaprojection.mod +++ b/data/scene/dawn/vestaprojection/vestaprojection.mod @@ -88,16 +88,12 @@ return { Ephemeris = { Type = "Spice", Body = "VESTA", - Reference = "GALACTIC", Observer = "SUN", Kernels = { --"${OPENSPACE_DATA}/spice/DAWN_KERNELS/pck/dawn_vesta_v06.tpc", "${OPENSPACE_DATA}/spice/DawnKernels/spk/sb_vesta_071107.bsp", } - }, - - - GuiName = "/Solar/Vesta" + } }, -- Vesta Trail Module { @@ -122,7 +118,6 @@ return { }, StartTime = "2007 JUL 20 12:00:00", EndTime = "2018 JAN 22 12:00:00" - }, - GuiName = "/Solar/VestaTrail" + } } } diff --git a/data/scene/debugglobe/debugglobe.mod b/data/scene/debugglobe/debugglobe.mod index ae21e2f03a..7f559dce3a 100644 --- a/data/scene/debugglobe/debugglobe.mod +++ b/data/scene/debugglobe/debugglobe.mod @@ -7,11 +7,8 @@ return { Ephemeris = { Type = "Spice", Body = "EARTH BARYCENTER", - Reference = "ECLIPJ2000", Observer = "SUN", - Kernels = { - "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" - } + Kernels = "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" }, }, -- RenderableGlobe module @@ -170,8 +167,7 @@ return { Kernels = { "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" } - }, - GuiName = "/Solar/Planets/DebugGlobe" + } }, -- EarthTrail module { @@ -186,8 +182,7 @@ return { TropicalOrbitPeriod = 365.242, EarthOrbitRatio = 1, DayLength = 24 - }, - GuiName = "/Solar/EarthTrail" + } } --[[, { diff --git a/data/scene/debugglobe/textures/arrows.png b/data/scene/debugglobe/textures/arrows.png new file mode 100644 index 0000000000..d10df6684c Binary files /dev/null and b/data/scene/debugglobe/textures/arrows.png differ diff --git a/data/scene/debugmodel/debugmodel.mod b/data/scene/debugmodel/debugmodel.mod deleted file mode 100644 index 3bfbd088af..0000000000 --- a/data/scene/debugmodel/debugmodel.mod +++ /dev/null @@ -1,25 +0,0 @@ -return { - { - Name = "DebugModel", - Parent = "Root", - Renderable = { - Type = "RenderableModel", - Body = "SUN", - Geometry = { - Type = "MultiModelGeometry", - GeometryFile = "models/OSIRIS-REx GSFC Animation/OSIRIS-REx GSFC Animation/OREXE1.obj", - Magnification = 4, - }, - Textures = { - Type = "simple", - Color = "textures/NHTexture.jpg", - }, - Shading = { - PerformShading = true, - Fadeable = false, - Ghosting = false, - }, - }, - GuiName = "/Solar/DebugModel" - }, -} \ No newline at end of file diff --git a/data/scene/earth/earth.mod b/data/scene/earth/earth.mod index ca3488ede6..cda7130a76 100644 --- a/data/scene/earth/earth.mod +++ b/data/scene/earth/earth.mod @@ -33,11 +33,8 @@ return { Translation = { Type = "SpiceEphemeris", Body = "EARTH", - Reference = "ECLIPJ2000", Observer = "SUN", - Kernels = { - "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" - } + Kernels = "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" }, Rotation = { Type = "SpiceRotation", @@ -76,7 +73,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/enlil/enlil.mod b/data/scene/enlil/enlil.mod index ae6f91073f..6d31327448 100644 --- a/data/scene/enlil/enlil.mod +++ b/data/scene/enlil/enlil.mod @@ -4,14 +4,9 @@ return { { Name = "Enlil", Parent = "Root", - Ephemeris = { - Type = "Static", - Position = { 0.0, 0.0, 0.0, 0} - }, RenderableToggle = "e", Renderable = { Type = "RenderableVolumeGL", - ---[[ BoxScaling = { f, f, f}, VolumeName = "EnlilVolume", Volume = "${OPENSPACE_DATA}/enlil/Hong_Xie_120312_SH_1.enlil.0016.cdf", @@ -26,8 +21,6 @@ return { TransferFunction = "transferfunctions/t2.txt", -- TransferFunction = "transferfunctions/t1.txt", Sampler = "sampler.glsl", - --]] - }, - GuiName = "/Volumes/Volume" + } } } diff --git a/data/scene/enlilnh/enlilnh.mod b/data/scene/enlilnh/enlilnh.mod index 78a1e2bd07..b065e04501 100644 --- a/data/scene/enlilnh/enlilnh.mod +++ b/data/scene/enlilnh/enlilnh.mod @@ -3,10 +3,6 @@ return { { Name = "Enlil New Horizons", Parent = "Root", - Ephemeris = { - Type = "Static", - Position = { 0.0, 0.0, 0.0, 0} - }, Renderable = { Type = "RenderableMultiresVolume", ReferenceFrame = "HEEQ", @@ -18,7 +14,6 @@ return { ErrorHistogramsSource = "tsp/enlil_nh_128_128_16_50.errorHistograms", TransferFunction = "transferfunctions/fire.txt", BrickSelector = "tf", - }, - GuiName = "/Volumes/ENLIL New Horizons" + } } } diff --git a/data/scene/fieldlines/fieldlines.mod b/data/scene/fieldlines/fieldlines.mod index c017daa93d..e0609029cb 100644 --- a/data/scene/fieldlines/fieldlines.mod +++ b/data/scene/fieldlines/fieldlines.mod @@ -10,10 +10,6 @@ return { { Name = "Fieldlines1", Parent = "Earth", - Ephemeris = { - Type = "Static", - Position = { 0, 0, 0, 0}, - }, Renderable = { Type = "RenderableFieldlines", VectorField = { @@ -30,16 +26,11 @@ return { Type = "File", File = '${OPENSPACE_DATA}/scene/fieldlines/bats_seeds/BATS_R_US_closed_seeds_all.txt'; } - }, - GuiName = "/Geometry/Fieldlines" + } }, { Name = "Fieldlines2", Parent = "Earth", - Ephemeris = { - Type = "Static", - Position = { 0, 0, 0, 0}, - }, Renderable = { Type = "RenderableFieldlines", VectorField = { @@ -56,16 +47,11 @@ return { Type = "File", File = '${OPENSPACE_DATA}/scene/fieldlines/bats_seeds/BATS_R_US_open_north_all.txt' } - }, - GuiName = "/Geometry/Fieldlines" + } }, { Name = "Fieldlines3", Parent = "Earth", - Ephemeris = { - Type = "Static", - Position = { 0, 0, 0, 0}, - }, Renderable = { Type = "RenderableFieldlines", VectorField = { @@ -82,16 +68,11 @@ return { Type = "File", File = '${OPENSPACE_DATA}/scene/fieldlines/bats_seeds/BATS_R_US_open_south_all.txt' } - }, - GuiName = "/Geometry/Fieldlines" + } }, { Name = "Fieldlines4", Parent = "Earth", - Ephemeris = { - Type = "Static", - Position = { 0, 0, 0, 0}, - }, Renderable = { Type = "RenderableFieldlines", VectorField = { @@ -108,16 +89,11 @@ return { Type = "File", File = '${OPENSPACE_DATA}/scene/fieldlines/bats_seeds/BATS_R_US_solar_wind_all.txt' } - }, - GuiName = "/Geometry/Fieldlines" + } }, { Name = "Fieldlines5", Parent = "Earth", - Ephemeris = { - Type = "Static", - Position = { 0, 0, 0, 0}, - }, Renderable = { Type = "RenderableFieldlines", VectorField = { @@ -134,7 +110,6 @@ return { Type = "File", File = '${OPENSPACE_DATA}/scene/fieldlines/bats_seeds/BATS_R_US_separatrix_seeds_all.txt' } - }, - GuiName = "/Geometry/Fieldlines" + } } } \ No newline at end of file diff --git a/data/scene/flare/flare.mod b/data/scene/flare/flare.mod index 6dbf429c68..c0b9b8b5dd 100644 --- a/data/scene/flare/flare.mod +++ b/data/scene/flare/flare.mod @@ -3,10 +3,6 @@ return { { Name = "Flare", Parent = "Root", - Ephemeris = { - Type = "Static", - Position = { 0, 0, 0, 0} - }, Renderable = { Type = "RenderableFlare", Source = "${OPENSPACE_DATA}/enlil_64_32_8.tsp", @@ -23,7 +19,6 @@ return { tsp_traveral_stepsize = 0.02, raycaster_stepsize = 0.005, - }, - GuiName = "/Volumes/Flare" + } } } \ No newline at end of file diff --git a/data/scene/globebrowsing.scene b/data/scene/globebrowsing.scene index df55b5969a..f1d2bc3e15 100644 --- a/data/scene/globebrowsing.scene +++ b/data/scene/globebrowsing.scene @@ -41,14 +41,16 @@ return { ScenePath = ".", CommonFolder = "common", Camera = { - Focus = "LodMars", + Focus = "Mars", Position = {138530625167.228241, 42217005217.825005, -46336405755.934372}, Rotation = {0.633883, 0.492158, -0.123913, -0.583625}, }, Modules = { "lodearth", + "lodmoon", "lodmars", + "lodmercury", "sun", "stars", "milkyway", diff --git a/data/scene/grids/gridEcliptic/gridEcliptic.mod b/data/scene/grids/gridEcliptic/gridEcliptic.mod index 3aea1790ae..ed4e7fb452 100644 --- a/data/scene/grids/gridEcliptic/gridEcliptic.mod +++ b/data/scene/grids/gridEcliptic/gridEcliptic.mod @@ -3,7 +3,6 @@ return { { Name = "SphericalGrid", Parent = "Root", - Static = true, Renderable = { Type = "RenderableSphericalGrid", GridType = "ECLIPJ2000", @@ -13,22 +12,6 @@ return { -0.09647644, 0.8622859, 0.4971472 , 0.0, 0.0 , 0.0 , 0.0 , 1.0 }, GridSegments = 36, - }, - Ephemeris = { - Type = "Static" -- for now, might change. - }, - - --[[ - Ephemeris = { - Type = "Spice", - Body = "EARTH", - Reference = "ECLIPJ2000", - Observer = "EARTH BARYCENTER", - Kernels = { - "kernels/earth.bsp" - } - }, - --]] - GuiName = "/Grid/Ecliptic" + } } } \ No newline at end of file diff --git a/data/scene/grids/gridEquatorial/gridEquatorial.mod b/data/scene/grids/gridEquatorial/gridEquatorial.mod index e35fdf7ee6..ccee24ccad 100644 --- a/data/scene/grids/gridEquatorial/gridEquatorial.mod +++ b/data/scene/grids/gridEquatorial/gridEquatorial.mod @@ -3,7 +3,6 @@ return { { Name = "SphericalGrid", Parent = "Root", - Static = true, Renderable = { Type = "RenderableSphericalGrid", GridType = "ICRF", @@ -13,11 +12,6 @@ return { -0.483835 , 0.7469823, 0.4559838, 0.0, 0.0 , 0.0 , 0.0 , 1.0 }, GridSegments = 36, - }, - Ephemeris = { - Type = "Static" -- for now, might change. - }, - - GuiName = "/Grid/Equatorial" + } } } \ No newline at end of file diff --git a/data/scene/grids/gridGalactic/gridGalactic.mod b/data/scene/grids/gridGalactic/gridGalactic.mod index 95f25afe4f..b27d939b6c 100644 --- a/data/scene/grids/gridGalactic/gridGalactic.mod +++ b/data/scene/grids/gridGalactic/gridGalactic.mod @@ -3,32 +3,15 @@ return { { Name = "gridGalactic", Parent = "SolarSystem", - Static = true, Renderable = { Type = "RenderableSphericalGrid", GridType = "GALACTIC", GridColor = { 0.0, 0.4, 0.4, 1}, - GridMatrix = { 1.0, 0.0, 0.0, 0.0, - 0.0, 1.0, 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, + GridMatrix = { 1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 }, GridSegments = 36, - }, - Ephemeris = { - Type = "Static" -- for now, might change. - }, - - --[[ - Ephemeris = { - Type = "Spice", - Body = "EARTH", - Reference = "ECLIPJ2000", - Observer = "EARTH BARYCENTER", - Kernels = { - "kernels/earth.bsp" - } - }, - --]] - GuiName = "/Grid/Galactic" + } } } \ No newline at end of file diff --git a/data/scene/imageplane/imageplane.mod b/data/scene/imageplane/imageplane.mod deleted file mode 100644 index 6d6cf14f06..0000000000 --- a/data/scene/imageplane/imageplane.mod +++ /dev/null @@ -1,34 +0,0 @@ -return { - -- Latest image taken by LORRI - --[[ - { - Name = "ImagePlane", - Parent = "PlutoProjection", - Renderable = { - Type = "RenderablePlaneProjection", - Frame = "NH_SPACECRAFT", - DefaultTarget = "PLUTO", - Spacecraft = "NEW HORIZONS", - Instrument = "NH_LORRI", - Moving = false, - Texture = "textures/squarefov.png", - }, - }, - - -- LORRI FoV square - { - Name = "ImagePlane2", - Parent = "NewHorizons", - Renderable = { - Type = "RenderablePlaneProjection", - Frame = "IAU_JUPITER", - DefaultTarget = "JUPITER", - Spacecraft = "NEW HORIZONS", - Instrument = "NH_LORRI", - Moving = true, - Texture = "textures/squarefov.png", - }, - } - ]] -} - diff --git a/data/scene/imageplane/textures/squarefov.png b/data/scene/imageplane/textures/squarefov.png deleted file mode 100644 index 1d48dc35f4..0000000000 Binary files a/data/scene/imageplane/textures/squarefov.png and /dev/null differ diff --git a/data/scene/imageplane/textures/test.jpg b/data/scene/imageplane/textures/test.jpg deleted file mode 100644 index 1978087d08..0000000000 Binary files a/data/scene/imageplane/textures/test.jpg and /dev/null differ diff --git a/data/scene/juno/juno/juno.mod b/data/scene/juno/juno/juno.mod index 01006cfa80..ec95c0c83f 100644 --- a/data/scene/juno/juno/juno.mod +++ b/data/scene/juno/juno/juno.mod @@ -31,7 +31,6 @@ return { Ephemeris = { Type = "Spice", Body = "JUNO", - Reference = "GALACTIC", Observer = "JUPITER BARYCENTER", Kernels = { "spice/JNO_SCLKSCET.00039.tsc", @@ -120,8 +119,7 @@ return { "spice/ck/juno_sc_prl_160729_160826_jm0002rp_v01.bc", "spice/ck/juno_sc_prl_161115_161213_jx0405rp_v01.bc" } - }, - GuiName = "/Solar/Juno" + } }, --NewHorizonsTrail module { diff --git a/data/scene/jupiter/callisto/callisto.mod b/data/scene/jupiter/callisto/callisto.mod index 1288472c2a..1af5b70f73 100644 --- a/data/scene/jupiter/callisto/callisto.mod +++ b/data/scene/jupiter/callisto/callisto.mod @@ -26,11 +26,8 @@ return { Translation = { Type = "SpiceEphemeris", Body = "CALLISTO", - Reference = "ECLIPJ2000", Observer = "JUPITER BARYCENTER", - Kernels = { - "${OPENSPACE_DATA}/spice/jup260.bsp" - } + Kernels = "${OPENSPACE_DATA}/spice/jup260.bsp" }, Rotation = { Type = "SpiceRotation", @@ -41,8 +38,7 @@ return { Type = "StaticScale", Scale = 1, }, - }, - GuiName = "/Solar/Planets/Callisto" + } }, -- CallistoTrail module { @@ -62,7 +58,6 @@ return { Color = "${COMMON_MODULE}/textures/glare_blue.png", -- need to add different texture }, - }, - GuiName = "/Solar/CallistoTrail" + } } } diff --git a/data/scene/jupiter/europa/europa.mod b/data/scene/jupiter/europa/europa.mod index 15ec4270e2..44c2ded0a5 100644 --- a/data/scene/jupiter/europa/europa.mod +++ b/data/scene/jupiter/europa/europa.mod @@ -26,11 +26,8 @@ return { Translation = { Type = "SpiceEphemeris", Body = "EUROPA", - Reference = "ECLIPJ2000", Observer = "JUPITER BARYCENTER", - Kernels = { - "${OPENSPACE_DATA}/spice/jup260.bsp" - } + Kernels = "${OPENSPACE_DATA}/spice/jup260.bsp" }, Rotation = { Type = "SpiceRotation", @@ -41,8 +38,7 @@ return { Type = "StaticScale", Scale = 1, }, - }, - GuiName = "/Solar/Planets/EUROPA" + } }, -- EuropaTrail module { @@ -62,7 +58,6 @@ return { Color = "${COMMON_MODULE}/textures/glare_blue.png", -- need to add different texture }, - }, - GuiName = "/Solar/EuropaTrail" + } } } diff --git a/data/scene/jupiter/ganymede/ganymede.mod b/data/scene/jupiter/ganymede/ganymede.mod index b7710e3124..c31809f2be 100644 --- a/data/scene/jupiter/ganymede/ganymede.mod +++ b/data/scene/jupiter/ganymede/ganymede.mod @@ -26,11 +26,8 @@ return { Translation = { Type = "SpiceEphemeris", Body = "GANYMEDE", - Reference = "ECLIPJ2000", Observer = "JUPITER BARYCENTER", - Kernels = { - "${OPENSPACE_DATA}/spice/jup260.bsp" - } + Kernels = "${OPENSPACE_DATA}/spice/jup260.bsp" }, Rotation = { Type = "SpiceRotation", @@ -41,8 +38,7 @@ return { Type = "StaticScale", Scale = 1, }, - }, - GuiName = "/Solar/Planets/Ganymede" + } }, -- GanymedeTrail module { @@ -62,7 +58,6 @@ return { Color = "${COMMON_MODULE}/textures/glare_blue.png", -- need to add different texture }, - }, - GuiName = "/Solar/GanymedeTrail" + } } } diff --git a/data/scene/jupiter/io/io.mod b/data/scene/jupiter/io/io.mod index 7019330621..ba04eb8c6d 100644 --- a/data/scene/jupiter/io/io.mod +++ b/data/scene/jupiter/io/io.mod @@ -26,11 +26,8 @@ return { Translation = { Type = "SpiceEphemeris", Body = "IO", - Reference = "ECLIPJ2000", Observer = "JUPITER BARYCENTER", - Kernels = { - "${OPENSPACE_DATA}/spice/jup260.bsp" - } + Kernels = "${OPENSPACE_DATA}/spice/jup260.bsp" }, Rotation = { Type = "SpiceRotation", @@ -41,8 +38,7 @@ return { Type = "StaticScale", Scale = 1, }, - }, - GuiName = "/Solar/Planets/Jupiter" + } }, -- IoTrail module { @@ -62,7 +58,6 @@ return { Color = "${COMMON_MODULE}/textures/glare_blue.png", -- need to add different texture }, - }, - GuiName = "/Solar/IoTrail" + } } } diff --git a/data/scene/jupiter/jupiter/jupiter.mod b/data/scene/jupiter/jupiter/jupiter.mod index b8c3752bf6..6d51c47314 100644 --- a/data/scene/jupiter/jupiter/jupiter.mod +++ b/data/scene/jupiter/jupiter/jupiter.mod @@ -7,11 +7,8 @@ return { Translation = { Type = "SpiceEphemeris", Body = "JUPITER BARYCENTER", - Reference = "ECLIPJ2000", Observer = "SUN", - Kernels = { - "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" - } + Kernels = "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" }, }, }, @@ -52,8 +49,7 @@ return { Type = "StaticScale", Scale = 1, }, - }, - GuiName = "/Solar/Planets/Jupiter" + } }, -- JupiterTrail module { @@ -73,7 +69,6 @@ return { Color = "${COMMON_MODULE}/textures/glare_blue.png", -- need to add different texture }, - }, - GuiName = "/Solar/JupiterTrail" + } } } diff --git a/data/scene/jupiter/textures/Jupiter-text.png b/data/scene/jupiter/textures/Jupiter-text.png deleted file mode 100644 index c8ec1a2b71..0000000000 Binary files a/data/scene/jupiter/textures/Jupiter-text.png and /dev/null differ diff --git a/data/scene/lodearth/lodearth.mod b/data/scene/lodearth/lodearth.mod index 9e2fe6fa64..f7ca2e8291 100644 --- a/data/scene/lodearth/lodearth.mod +++ b/data/scene/lodearth/lodearth.mod @@ -1,3 +1,4 @@ +earthEllipsoid = {6378137.0, 6378137.0, 6356752.314245} -- Earth's radii return { -- Earth barycenter module { @@ -7,11 +8,8 @@ return { Translation = { Type = "SpiceEphemeris", Body = "EARTH", - Reference = "ECLIPJ2000", Observer = "SUN", - Kernels = { - "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" - } + Kernels = "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" }, }, }, @@ -28,12 +26,11 @@ return { TropicalOrbitPeriod = 365.242, EarthOrbitRatio = 1, DayLength = 24 - }, - GuiName = "/Solar/EarthTrail" + } }, -- RenderableGlobe module { - Name = "LodEarth", + Name = "Earth", Parent = "EarthBarycenter", Transform = { Rotation = { @@ -48,7 +45,7 @@ return { }, Renderable = { Type = "RenderableGlobe", - Radii = {6378137.0, 6378137.0, 6356752.314245}, -- Earth's radii + Radii = earthEllipsoid, CameraMinHeight = 300, InteractionDepthBelowEllipsoid = 0, -- Useful when having negative height map values SegmentsPerPatch = 64, @@ -62,25 +59,25 @@ return { { Type = "Temporal", Name = "Temporal VIIRS SNPP", - FilePath = "map_service_configs/Temporal_VIIRS_SNPP_CorrectedReflectance_TrueColor.xml", + FilePath = "map_service_configs/GIBS/Temporal_VIIRS_SNPP_CorrectedReflectance_TrueColor.xml", }, { Type = "SingleImage", Name = "Debug Tiles", - FilePath = "../debugglobe/textures/test_tile.png", + FilePath = "textures/test_tile.png", }, { Type = "Temporal", Name = "Temporal MODIS Aqua CorrectedRecflectance TrueColor", - FilePath = "map_service_configs/Temporal_MODIS_Aqua_CorrectedReflectance_TrueColor.xml", + FilePath = "map_service_configs/GIBS/Temporal_MODIS_Aqua_CorrectedReflectance_TrueColor.xml", }, { Name = "MODIS_Terra_CorrectedReflectance_TrueColor", - FilePath = "map_service_configs/MODIS_Terra_CorrectedReflectance_TrueColor.xml", + FilePath = "map_service_configs/GIBS/MODIS_Terra_CorrectedReflectance_TrueColor.xml", }, { Name = "ESRI Imagery World 2D", - FilePath = "map_service_configs/ESRI_Imagery_World_2D.wms", + FilePath = "map_service_configs/ESRI/ESRI_Imagery_World_2D.wms", Enabled = true, } }, @@ -90,41 +87,45 @@ return { NightTextures = { { Name = "Earth at Night 2012", - FilePath = "map_service_configs/VIIRS_CityLights_2012.xml", + FilePath = "map_service_configs/GIBS/VIIRS_CityLights_2012.xml", }, }, WaterMasks = { { Name = "MODIS_Water_Mask", - FilePath = "map_service_configs/MODIS_Water_Mask.xml", + FilePath = "map_service_configs/GIBS/MODIS_Water_Mask.xml", }, }, Overlays = { { Name = "Coastlines", - FilePath = "map_service_configs/Coastlines.xml", + FilePath = "map_service_configs/GIBS/Coastlines.xml", }, { Name = "Reference_Features", - FilePath = "map_service_configs/Reference_Features.xml", + FilePath = "map_service_configs/GIBS/Reference_Features.xml", }, { Name = "Reference_Labels", - FilePath = "map_service_configs/Reference_Labels.xml", + FilePath = "map_service_configs/GIBS/Reference_Labels.xml", + }, + { + Type = "SizeReference", + Name = "Size Reference", + Radii = earthEllipsoid, + BackgroundImagePath = "../debugglobe/textures/arrows.png", }, }, HeightMaps = { { Name = "Terrain tileset", - FilePath = "map_service_configs/TERRAIN.wms", + FilePath = "map_service_configs/ESRI/TERRAIN.wms", Enabled = true, + MinimumPixelSize = 90, + DoPreProcessing = true, }, }, - HeightMapOverlays = { - - }, }, - }, - GuiName = "/Solar/Planets/LodEarth" + } }, } \ No newline at end of file diff --git a/data/scene/lodearth/map_service_configs/ESRI_Imagery_World_2D.wms b/data/scene/lodearth/map_service_configs/ESRI/ESRI_Imagery_World_2D.wms similarity index 100% rename from data/scene/lodearth/map_service_configs/ESRI_Imagery_World_2D.wms rename to data/scene/lodearth/map_service_configs/ESRI/ESRI_Imagery_World_2D.wms diff --git a/data/scene/lodearth/map_service_configs/TERRAIN.wms b/data/scene/lodearth/map_service_configs/ESRI/TERRAIN.wms similarity index 100% rename from data/scene/lodearth/map_service_configs/TERRAIN.wms rename to data/scene/lodearth/map_service_configs/ESRI/TERRAIN.wms diff --git a/data/scene/lodearth/map_service_configs/Coastlines.xml b/data/scene/lodearth/map_service_configs/GIBS/Coastlines.xml similarity index 100% rename from data/scene/lodearth/map_service_configs/Coastlines.xml rename to data/scene/lodearth/map_service_configs/GIBS/Coastlines.xml diff --git a/data/scene/lodearth/map_service_configs/GIBS_Aqua_MODIS_true.xml b/data/scene/lodearth/map_service_configs/GIBS/GIBS_Aqua_MODIS_true.xml similarity index 100% rename from data/scene/lodearth/map_service_configs/GIBS_Aqua_MODIS_true.xml rename to data/scene/lodearth/map_service_configs/GIBS/GIBS_Aqua_MODIS_true.xml diff --git a/data/scene/lodearth/map_service_configs/MODIS_Terra_Brightness_Temp_Band31_Day.xml b/data/scene/lodearth/map_service_configs/GIBS/MODIS_Terra_Brightness_Temp_Band31_Day.xml similarity index 100% rename from data/scene/lodearth/map_service_configs/MODIS_Terra_Brightness_Temp_Band31_Day.xml rename to data/scene/lodearth/map_service_configs/GIBS/MODIS_Terra_Brightness_Temp_Band31_Day.xml diff --git a/data/scene/lodearth/map_service_configs/MODIS_Terra_CorrectedReflectance_TrueColor.xml b/data/scene/lodearth/map_service_configs/GIBS/MODIS_Terra_CorrectedReflectance_TrueColor.xml similarity index 100% rename from data/scene/lodearth/map_service_configs/MODIS_Terra_CorrectedReflectance_TrueColor.xml rename to data/scene/lodearth/map_service_configs/GIBS/MODIS_Terra_CorrectedReflectance_TrueColor.xml diff --git a/data/scene/lodearth/map_service_configs/MODIS_Terra_CorrectedReflectance_TrueColor_temporal.xml b/data/scene/lodearth/map_service_configs/GIBS/MODIS_Terra_CorrectedReflectance_TrueColor_temporal.xml similarity index 100% rename from data/scene/lodearth/map_service_configs/MODIS_Terra_CorrectedReflectance_TrueColor_temporal.xml rename to data/scene/lodearth/map_service_configs/GIBS/MODIS_Terra_CorrectedReflectance_TrueColor_temporal.xml diff --git a/data/scene/lodearth/map_service_configs/MODIS_Water_Mask.xml b/data/scene/lodearth/map_service_configs/GIBS/MODIS_Water_Mask.xml similarity index 100% rename from data/scene/lodearth/map_service_configs/MODIS_Water_Mask.xml rename to data/scene/lodearth/map_service_configs/GIBS/MODIS_Water_Mask.xml diff --git a/data/scene/lodearth/map_service_configs/Reference_Features.xml b/data/scene/lodearth/map_service_configs/GIBS/Reference_Features.xml similarity index 100% rename from data/scene/lodearth/map_service_configs/Reference_Features.xml rename to data/scene/lodearth/map_service_configs/GIBS/Reference_Features.xml diff --git a/data/scene/lodearth/map_service_configs/Reference_Labels.xml b/data/scene/lodearth/map_service_configs/GIBS/Reference_Labels.xml similarity index 100% rename from data/scene/lodearth/map_service_configs/Reference_Labels.xml rename to data/scene/lodearth/map_service_configs/GIBS/Reference_Labels.xml diff --git a/data/scene/lodearth/map_service_configs/TERRA_CR_B143_2016-04-12.wms b/data/scene/lodearth/map_service_configs/GIBS/TERRA_CR_B143_2016-04-12.wms similarity index 100% rename from data/scene/lodearth/map_service_configs/TERRA_CR_B143_2016-04-12.wms rename to data/scene/lodearth/map_service_configs/GIBS/TERRA_CR_B143_2016-04-12.wms diff --git a/data/scene/lodearth/map_service_configs/Temporal_Aqua_Orbit_Asc.xml b/data/scene/lodearth/map_service_configs/GIBS/Temporal_Aqua_Orbit_Asc.xml similarity index 100% rename from data/scene/lodearth/map_service_configs/Temporal_Aqua_Orbit_Asc.xml rename to data/scene/lodearth/map_service_configs/GIBS/Temporal_Aqua_Orbit_Asc.xml diff --git a/data/scene/lodearth/map_service_configs/Temporal_MODIS_Aqua_CorrectedReflectance_TrueColor.xml b/data/scene/lodearth/map_service_configs/GIBS/Temporal_MODIS_Aqua_CorrectedReflectance_TrueColor.xml similarity index 100% rename from data/scene/lodearth/map_service_configs/Temporal_MODIS_Aqua_CorrectedReflectance_TrueColor.xml rename to data/scene/lodearth/map_service_configs/GIBS/Temporal_MODIS_Aqua_CorrectedReflectance_TrueColor.xml diff --git a/data/scene/lodearth/map_service_configs/Temporal_VIIRS_SNPP_CorrectedReflectance_TrueColor.xml b/data/scene/lodearth/map_service_configs/GIBS/Temporal_VIIRS_SNPP_CorrectedReflectance_TrueColor.xml similarity index 100% rename from data/scene/lodearth/map_service_configs/Temporal_VIIRS_SNPP_CorrectedReflectance_TrueColor.xml rename to data/scene/lodearth/map_service_configs/GIBS/Temporal_VIIRS_SNPP_CorrectedReflectance_TrueColor.xml diff --git a/data/scene/lodearth/map_service_configs/VIIRS_CityLights_2012.xml b/data/scene/lodearth/map_service_configs/GIBS/VIIRS_CityLights_2012.xml similarity index 100% rename from data/scene/lodearth/map_service_configs/VIIRS_CityLights_2012.xml rename to data/scene/lodearth/map_service_configs/GIBS/VIIRS_CityLights_2012.xml diff --git a/data/scene/lodearth/map_service_configs/VIIRS_SNPP_CorrectedReflectance_TrueColor.xml b/data/scene/lodearth/map_service_configs/GIBS/VIIRS_SNPP_CorrectedReflectance_TrueColor.xml similarity index 100% rename from data/scene/lodearth/map_service_configs/VIIRS_SNPP_CorrectedReflectance_TrueColor.xml rename to data/scene/lodearth/map_service_configs/GIBS/VIIRS_SNPP_CorrectedReflectance_TrueColor.xml diff --git a/data/scene/lodearth/map_service_configs/ASTER_GDEM_Greyscale_Shaded_Relief.xml b/data/scene/lodearth/map_service_configs/other/ASTER_GDEM_Greyscale_Shaded_Relief.xml similarity index 100% rename from data/scene/lodearth/map_service_configs/ASTER_GDEM_Greyscale_Shaded_Relief.xml rename to data/scene/lodearth/map_service_configs/other/ASTER_GDEM_Greyscale_Shaded_Relief.xml diff --git a/data/scene/lodearth/map_service_configs/Landsat_WELD_CorrectedReflectance_TrueColor_Global_Monthly_v3_STD_temporal.xml b/data/scene/lodearth/map_service_configs/other/Landsat_WELD_CorrectedReflectance_TrueColor_Global_Monthly_v3_STD_temporal.xml similarity index 100% rename from data/scene/lodearth/map_service_configs/Landsat_WELD_CorrectedReflectance_TrueColor_Global_Monthly_v3_STD_temporal.xml rename to data/scene/lodearth/map_service_configs/other/Landsat_WELD_CorrectedReflectance_TrueColor_Global_Monthly_v3_STD_temporal.xml diff --git a/data/scene/lodearth/map_service_configs/MLS_O3_46hPa_Day.xml b/data/scene/lodearth/map_service_configs/other/MLS_O3_46hPa_Day.xml similarity index 100% rename from data/scene/lodearth/map_service_configs/MLS_O3_46hPa_Day.xml rename to data/scene/lodearth/map_service_configs/other/MLS_O3_46hPa_Day.xml diff --git a/data/scene/lodearth/map_service_configs/OpenStreetMap.xml b/data/scene/lodearth/map_service_configs/other/OpenStreetMap.xml similarity index 100% rename from data/scene/lodearth/map_service_configs/OpenStreetMap.xml rename to data/scene/lodearth/map_service_configs/other/OpenStreetMap.xml diff --git a/data/scene/lodearth/map_service_configs/frmt_wms_virtualearth.xml b/data/scene/lodearth/map_service_configs/other/frmt_wms_virtualearth.xml similarity index 100% rename from data/scene/lodearth/map_service_configs/frmt_wms_virtualearth.xml rename to data/scene/lodearth/map_service_configs/other/frmt_wms_virtualearth.xml diff --git a/data/scene/lodearth/map_service_configs/test.wms b/data/scene/lodearth/map_service_configs/other/test.wms similarity index 100% rename from data/scene/lodearth/map_service_configs/test.wms rename to data/scene/lodearth/map_service_configs/other/test.wms diff --git a/data/scene/lodearth/textures/ToastMapOfEarth.jpg b/data/scene/lodearth/textures/ToastMapOfEarth.jpg deleted file mode 100644 index 9064235622..0000000000 Binary files a/data/scene/lodearth/textures/ToastMapOfEarth.jpg and /dev/null differ diff --git a/data/scene/lodearth/textures/earth_bluemarble.jpg b/data/scene/lodearth/textures/earth_bluemarble.jpg deleted file mode 100644 index 55b715d061..0000000000 Binary files a/data/scene/lodearth/textures/earth_bluemarble.jpg and /dev/null differ diff --git a/data/scene/lodearth/textures/earth_bluemarble_height.jpg b/data/scene/lodearth/textures/earth_bluemarble_height.jpg deleted file mode 100644 index 6658823163..0000000000 Binary files a/data/scene/lodearth/textures/earth_bluemarble_height.jpg and /dev/null differ diff --git a/data/scene/lodearth/textures/earth_night.jpg b/data/scene/lodearth/textures/earth_night.jpg deleted file mode 100644 index bf1a1a483c..0000000000 Binary files a/data/scene/lodearth/textures/earth_night.jpg and /dev/null differ diff --git a/data/scene/lodearth/textures/marker.png b/data/scene/lodearth/textures/marker.png deleted file mode 100644 index fc42c047b8..0000000000 Binary files a/data/scene/lodearth/textures/marker.png and /dev/null differ diff --git a/data/scene/lodesritest/lodesritest.mod b/data/scene/lodesritest/lodesritest.mod index a6ee718e67..db213b3e6c 100644 --- a/data/scene/lodesritest/lodesritest.mod +++ b/data/scene/lodesritest/lodesritest.mod @@ -3,9 +3,6 @@ return { { Name = "EarthBarycenter", Parent = "SolarSystemBarycenter", - Ephemeris = { - Type = "Static" - } }, -- EarthTrail module { @@ -30,11 +27,8 @@ return { Ephemeris = { Type = "Spice", Body = "EARTH", - Reference = "ECLIPJ2000", Observer = "SUN", - Kernels = { - "${OPENSPACE_DATA}/spice/de430.bsp" - } + Kernels = "${OPENSPACE_DATA}/spice/de430.bsp" }, Rotation = { Type = "Spice", @@ -86,8 +80,7 @@ return { HeightMapOverlays = { }, }, - }, - GuiName = "/Solar/Planets/LodEarth" + } }, { Name = "LodMoon", @@ -95,11 +88,8 @@ return { Ephemeris = { Type = "Spice", Body = "MOON", - Reference = "ECLIPJ2000", Observer = "SUN", - Kernels = { - "${OPENSPACE_DATA}/spice/de430.bsp" - } + Kernels = "${OPENSPACE_DATA}/spice/de430.bsp" }, Rotation = { Type = "Spice", @@ -180,11 +170,8 @@ return { Ephemeris = { Type = "Spice", Body = "MARS", - Reference = "ECLIPJ2000", Observer = "SUN", - Kernels = { - "${OPENSPACE_DATA}/spice/MAR063.BSP" - } + Kernels = "${OPENSPACE_DATA}/spice/MAR063.BSP" }, Rotation = { Type = "Spice", @@ -243,8 +230,7 @@ return { HeightMapOverlays = { }, }, - }, - GuiName = "/Solar/Planets/LodEarth" + } }, { Name = "LodMercury", @@ -252,11 +238,8 @@ return { Ephemeris = { Type = "Spice", Body = "MERCURY", - Reference = "ECLIPJ2000", Observer = "SUN", - Kernels = { - "${OPENSPACE_DATA}/spice/de430.bsp" - } + Kernels = "${OPENSPACE_DATA}/spice/de430.bsp" }, Rotation = { Type = "Spice", @@ -303,7 +286,6 @@ return { }, }, - }, - GuiName = "/Solar/Planets/LodEarth" + } }, } diff --git a/data/scene/lodmars/lodmars.mod b/data/scene/lodmars/lodmars.mod index b378e8859b..dce7bf881b 100644 --- a/data/scene/lodmars/lodmars.mod +++ b/data/scene/lodmars/lodmars.mod @@ -1,27 +1,27 @@ +local marsEllipsoid = {3396190.0, 3396190.0, 3376200.0} return { -- Mars barycenter module { Name = "MarsBarycenter", Parent = "SolarSystemBarycenter", - }, - -- RenderableGlobe module - { - Name = "LodMars", - Parent = "MarsBarycenter", Transform = { Translation = { Type = "SpiceEphemeris", Body = "MARS BARYCENTER", - Reference = "ECLIPJ2000", Observer = "SUN", - Kernels = { - "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" - } + Kernels = "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" }, + }, + }, + -- RenderableGlobe module + { + Name = "Mars", + Parent = "MarsBarycenter", + Transform = { Rotation = { Type = "SpiceRotation", SourceFrame = "IAU_MARS", - DestinationFrame = "ECLIPJ2000", + DestinationFrame = "GALACTIC", }, Scale = { Type = "StaticScale", @@ -30,9 +30,7 @@ return { }, Renderable = { Type = "RenderableGlobe", - Frame = "IAU_MARS", - Body = "MARS BARYCENTER", - Radii = {3396190.0, 3396190.0, 3376200.0}, -- Mars' radii + Radii = marsEllipsoid, CameraMinHeight = 1000, InteractionDepthBelowEllipsoid = 10000, -- Useful when having negative height map values SegmentsPerPatch = 90, @@ -51,11 +49,10 @@ return { { Name = "MARS_Viking_MDIM21", FilePath = "map_service_configs/MARS_Viking_MDIM21.xml", - Enabled = true, }, { Name = "Mars Viking Clr", - FilePath = "map_datasets/Mars_Viking_ClrMosaic_global_925m_longlat_full.vrt", + FilePath = "map_datasets/Viking/Mars_Viking_ClrMosaic_global_925m_longlat_full.vrt", Enabled = true, }, }, @@ -66,13 +63,21 @@ return { Enabled = true, }, { - Name = "West_Candor_Chasma_longlat_global", - FilePath = "map_datasets/West_Candor_Chasma_longlat_global.vrt", + Name = "West Candor Chasma", + FilePath = "map_datasets/CTX/West_Candor_Chasma_longlat_global.vrt", --Enabled = true, }, { Name = "Layered Rock Outcrops in Southwest Candor Chasma", - FilePath = "map_datasets/Layered_Rock_Outcrops_in_Southwest_Candor_Chasma_A.vrt", + FilePath = "map_datasets/HiRISE/Layered_Rock_Outcrops_in_Southwest_Candor_Chasma_Texture.vrt", + }, + { + Name = "MER_Meridianni_Endeavor_Basemap_25cm", + FilePath = "map_datasets/Basemap/MER_Meridianni_Endeavor_Basemap_25cm.vrt", + }, + { + Name = "Part of Area Traversed by the Mars Exploration Rover", + FilePath = "map_datasets/HiRISE/Part_of_Area_Traversed_by_the_Mars_Exploration_Rover_Texture.vrt", }, }, NightTextures = { @@ -86,34 +91,46 @@ return { Type = "ChunkIndex", Name = "Indices", }, + { + Type = "SizeReference", + Name = "Size Reference", + Radii = marsEllipsoid, + BackgroundImagePath = "../debugglobe/textures/arrows.png", + }, }, HeightMaps = { { Name = "Mola Elevation", FilePath = "map_service_configs/Mola_Elevation.xml", Enabled = true, + MinimumPixelSize = 90, + DoPreProcessing = true, }, { - Name = "West_Candor_Chasma_DEM_longlat_global", - FilePath = "map_datasets/West_Candor_Chasma_DEM_longlat_global.vrt", + Name = "West Candor Chasma", + FilePath = "map_datasets/CTX/West_Candor_Chasma_DEM_longlat_global.vrt", --Enabled = true, + MinimumPixelSize = 90, + DoPreProcessing = true, }, { Name = "Layered Rock Outcrops in Southwest Candor Chasma", - FilePath = "map_datasets/Layered_Rock_Outcrops_in_Southwest_Candor_Chasma_DEM.vrt", + FilePath = "map_datasets/HiRISE/Layered_Rock_Outcrops_in_Southwest_Candor_Chasma_Heightmap.vrt", + MinimumPixelSize = 90, + DoPreProcessing = true, + }, + { + Name = "Part of Area Traversed by the Mars Exploration Rover", + FilePath = "map_datasets/HiRISE/Part_of_Area_Traversed_by_the_Mars_Exploration_Rover_Heightmap.vrt", }, }, - HeightMapOverlays = { - }, }, - }, - - GuiName = "/Solar/Planets/LodMars" + } }, -- MarsTrail module { Name = "MarsTrail", - Parent = "MarsBarycenter", + Parent = "Sun", Renderable = { Type = "RenderableTrail", Body = "MARS BARYCENTER", @@ -123,12 +140,6 @@ return { TropicalOrbitPeriod = 686.973, EarthOrbitRatio = 1.881, DayLength = 24.6597, - Textures = { - Type = "simple", - Color = "${COMMON_MODULE}/textures/glare_blue.png", - -- need to add different texture - }, - }, - GuiName = "/Solar/MarsTrail" + } } } diff --git a/data/scene/lodmars/map_service_configs/CTX_Mosaic.xml b/data/scene/lodmars/map_service_configs/CTX_Mosaic.xml index 0e7b835a0f..9f7a65afb5 100644 --- a/data/scene/lodmars/map_service_configs/CTX_Mosaic.xml +++ b/data/scene/lodmars/map_service_configs/CTX_Mosaic.xml @@ -12,9 +12,4 @@ 256 256 - - ./ctx_wms_cache - 2 - .jpg - \ No newline at end of file diff --git a/data/scene/lodmercury/lodmercury.mod b/data/scene/lodmercury/lodmercury.mod new file mode 100644 index 0000000000..f949495ff1 --- /dev/null +++ b/data/scene/lodmercury/lodmercury.mod @@ -0,0 +1,87 @@ +return { + -- Mercury barycenter module + { + Name = "MercuryBarycenter", + Parent = "SolarSystemBarycenter", + Transform = { + Translation = { + Type = "SpiceEphemeris", + Body = "MERCURY", + Observer = "SUN", + Kernels = "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" + }, + }, + }, + + -- RenderableGlobe module + { + Name = "Mercury", + Parent = "MercuryBarycenter", + Transform = { + Rotation = { + Type = "SpiceRotation", + SourceFrame = "IAU_MERCURY", + DestinationFrame = "GALACTIC", + }, + Scale = { + Type = "StaticScale", + Scale = 1, + }, + }, + Renderable = { + Type = "RenderableGlobe", + Radii = {2439700, 2439700.0, 2439700.0}, + Frame = "IAU_MERCURY", + Body = "MERCURY", + + CameraMinHeight = 300, + InteractionDepthBelowEllipsoid = 0, -- Useful when having negative height map values + SegmentsPerPatch = 64, + TextureInitData = { + ColorTextureMinimumSize = 512, + OverlayMinimumSize = 512, + HeightMapMinimumSize = 64, + }, + Textures = { + ColorTextures = { + { + Name = "On Mercury Color", + FilePath = "map_service_configs/OnMercuryColor.xml", + Enabled = true, + }, + { + Name = "On Mercury Image", + FilePath = "map_service_configs/OnMercuryImage.xml", + }, + }, + GrayScaleOverlays = { }, + NightTextures = { }, + WaterMasks = { }, + Overlays = { }, + HeightMaps = { + { + Name = "On Mercury Height", + FilePath = "map_service_configs/OnMercuryElevationGaskell.xml", + Enabled = true, + }, + }, + }, + }, + }, + + -- MercuryTrail module + { + Name = "MercuryTrail", + Parent = "SolarSystemBarycenter", + Renderable = { + Type = "RenderableTrail", + Body = "MERCURY", + Frame = "GALACTIC", + Observer = "SUN", + RGB = {0.6, 0.5, 0.5 }, + TropicalOrbitPeriod = 87.968 , + EarthOrbitRatio = 0.241, + DayLength = 4222.6, + }, + } +} diff --git a/data/scene/lodmercury/map_service_configs/OnMercuryColor.xml b/data/scene/lodmercury/map_service_configs/OnMercuryColor.xml new file mode 100644 index 0000000000..d53cb3ad5e --- /dev/null +++ b/data/scene/lodmercury/map_service_configs/OnMercuryColor.xml @@ -0,0 +1,30 @@ + + + http://192.168.1.167/OnMercury/wms.cgi? + Color 665m + + + + -180.0 + 90 + 180.0 + -90 + 20 + 2 + 1 + top + + 512 + 512 + \ No newline at end of file diff --git a/data/scene/lodmercury/map_service_configs/OnMercuryElevationGaskell.xml b/data/scene/lodmercury/map_service_configs/OnMercuryElevationGaskell.xml new file mode 100644 index 0000000000..0563b2d018 --- /dev/null +++ b/data/scene/lodmercury/map_service_configs/OnMercuryElevationGaskell.xml @@ -0,0 +1,24 @@ + + + http://192.168.1.167/OnMercury/wms.cgi? + + Elevation 16bit, Gaskell + + + -180.0 + 90 + 180.0 + -90 + 8 + 2 + 1 + top + + 512 + 512 + \ No newline at end of file diff --git a/data/scene/lodmercury/map_service_configs/OnMercuryImage.xml b/data/scene/lodmercury/map_service_configs/OnMercuryImage.xml new file mode 100644 index 0000000000..d50931e40e --- /dev/null +++ b/data/scene/lodmercury/map_service_configs/OnMercuryImage.xml @@ -0,0 +1,31 @@ + + + http://192.168.1.167/OnMercury/wms.cgi? + Mercury Image + + + + -180.0 + 90 + 180.0 + -90 + 20 + 2 + 1 + top + + 512 + 512 + \ No newline at end of file diff --git a/data/scene/lodmoon/lodmoon.mod b/data/scene/lodmoon/lodmoon.mod new file mode 100644 index 0000000000..d295f114f9 --- /dev/null +++ b/data/scene/lodmoon/lodmoon.mod @@ -0,0 +1,76 @@ +return { + -- Moon module + { + Name = "Moon", + Parent = "EarthBarycenter", + Transform = { + Translation = { + Type = "SpiceEphemeris", + Body = "MOON", + Observer = "EARTH BARYCENTER", + Kernels = "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" + }, + Rotation = { + Type = "SpiceRotation", + SourceFrame = "IAU_MOON", + DestinationFrame = "GALACTIC" + }, + }, + Renderable = { + Type = "RenderableGlobe", + Radii = {1737000, 1737000, 1737000}, -- Moons's radius + CameraMinHeight = 300, + InteractionDepthBelowEllipsoid = 5000, -- Useful when having negative height map values + SegmentsPerPatch = 64, + TextureInitData = { + ColorTextureMinimumSize = 512,--512, + OverlayMinimumSize = 512, + HeightMapMinimumSize = 64, + }, + Textures = { + ColorTextures = { + }, + GrayScaleOverlays = { + --[[ + { + Name = "OnMoonColorGrayscale", + FilePath = "map_service_configs/OnMoonGrayscaleOverlay.vrt", + Enabled = true, + }, + ]] + }, + NightTextures = { + + }, + WaterMasks = { + + }, + Overlays = { + + }, + HeightMaps = { + { + Name = "OnMoonHeight", + FilePath = "map_service_configs/OnMoonHeight.xml", + Enabled = true, + }, + }, + }, + } + }, + -- MoonTrail module + { + Name = "MoonTrail", + Parent = "EarthBarycenter", + Renderable = { + Type = "RenderableTrail", + Body = "MOON", + Frame = "GALACTIC", + Observer = "EARTH BARYCENTER", + RGB = { 0.5, 0.3, 0.3 }, + TropicalOrbitPeriod = 60, + EarthOrbitRatio = 0.01, + DayLength = 1.0, + } + } +} diff --git a/data/scene/lodmoon/map_service_configs/OnMoonColor.xml b/data/scene/lodmoon/map_service_configs/OnMoonColor.xml new file mode 100644 index 0000000000..5ba619a141 --- /dev/null +++ b/data/scene/lodmoon/map_service_configs/OnMoonColor.xml @@ -0,0 +1,65 @@ + + + http://onmoon.lmmp.nasa.gov/wms.cgi? + LRO WAC Mosaic, LMMP + + + + + + -180.0 + 90 + 180.0 + -90 + 20 + 2 + 1 + top + + 512 + 512 + \ No newline at end of file diff --git a/data/scene/lodmoon/map_service_configs/OnMoonGrayscaleOverlay.vrt b/data/scene/lodmoon/map_service_configs/OnMoonGrayscaleOverlay.vrt new file mode 100644 index 0000000000..6959072a78 --- /dev/null +++ b/data/scene/lodmoon/map_service_configs/OnMoonGrayscaleOverlay.vrt @@ -0,0 +1,28 @@ + + GEOGCS["GCS_Moon_2000",DATUM["D_Moon_2000",SPHEROID["Moon_2000_IAU_IAG",1737400.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]] + -1.8000000000000000e+02, 2.1972656250000000e-03, 0.0000000000000000e+00, 9.0000000000000000e+01, 0.0000000000000000e+00, -2.1972656250000000e-03 + + 0 + 1 + Gray + + OnMoonColor.xml + 1 + + + + 0 + + + + Alpha + + white_geo.tif + 1 + + + + + + + diff --git a/data/scene/lodmoon/map_service_configs/OnMoonHeight.xml b/data/scene/lodmoon/map_service_configs/OnMoonHeight.xml new file mode 100644 index 0000000000..4c19299b75 --- /dev/null +++ b/data/scene/lodmoon/map_service_configs/OnMoonHeight.xml @@ -0,0 +1,21 @@ + + + http://onmoon.lmmp.nasa.gov/raw/wms.cgi? + Lunar Elevation v2, half meters + + + + -180.0 + 90 + 180.0 + -90 + 24 + 2 + 1 + top + + 512 + 512 + \ No newline at end of file diff --git a/data/scene/lodmoon/map_service_configs/OnMoonNight.vrt b/data/scene/lodmoon/map_service_configs/OnMoonNight.vrt new file mode 100644 index 0000000000..0741ac74c3 --- /dev/null +++ b/data/scene/lodmoon/map_service_configs/OnMoonNight.vrt @@ -0,0 +1,49 @@ + + GEOGCS["GCS_Moon_2000",DATUM["D_Moon_2000",SPHEROID["Moon_2000_IAU_IAG",1737400.0,0.0]],PRIMEM["Reference_Meridian",0.0],UNIT["Degree",0.0174532925199433]] + -1.8000000000000000e+02, 2.1972656250000000e-03, 0.0000000000000000e+00, 9.0000000000000000e+01, 0.0000000000000000e+00, -2.1972656250000000e-03 + + 0 + 1 + Red + + OnMoonColor.xml + 1 + + + + 0 + 16 + 0 + + + + 0 + 1 + Green + + OnMoonColor.xml + 1 + + + + 0 + 16 + 0 + + + + 0 + 1 + Blue + + OnMoonColor.xml + 1 + + + + 0 + 16 + 0 + + + diff --git a/data/scene/mars/mars.mod b/data/scene/mars/mars.mod index 27c3219930..20dc40c5ea 100644 --- a/data/scene/mars/mars.mod +++ b/data/scene/mars/mars.mod @@ -31,11 +31,8 @@ return { Translation = { Type = "SpiceEphemeris", Body = "MARS BARYCENTER", - Reference = "ECLIPJ2000", Observer = "SUN", - Kernels = { - "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" - } + Kernels = "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" }, Rotation = { Type = "SpiceRotation", @@ -46,8 +43,7 @@ return { Type = "StaticScale", Scale = 1, }, - }, - GuiName = "/Solar/Planets/Mars" + } }, -- MarsTrail module { @@ -67,7 +63,6 @@ return { Color = "${COMMON_MODULE}/textures/glare_blue.png", -- need to add different texture }, - }, - GuiName = "/Solar/MarsTrail" + } } } diff --git a/data/scene/mercury/mercury.mod b/data/scene/mercury/mercury.mod index d77b76f693..caacb59af8 100644 --- a/data/scene/mercury/mercury.mod +++ b/data/scene/mercury/mercury.mod @@ -31,11 +31,8 @@ return { Translation = { Type = "SpiceEphemeris", Body = "MERCURY", - Reference = "ECLIPJ2000", Observer = "SUN", - Kernels = { - "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" - } + Kernels = "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" }, Rotation = { Type = "SpiceRotation", @@ -46,8 +43,7 @@ return { Type = "StaticScale", Scale = 1, }, - }, - GuiName = "/Solar/Planets/Mercury" + } }, -- MercuryTrail module { @@ -67,7 +63,6 @@ return { Color = "${COMMON_MODULE}/textures/glare_blue.png", -- need to add different texture }, - }, - GuiName = "/Solar/MercuryTrail" + } } } diff --git a/data/scene/milkyway-eso/milkyway-eso.mod b/data/scene/milkyway-eso/milkyway-eso.mod index dc668afbb3..0a080a28d5 100644 --- a/data/scene/milkyway-eso/milkyway-eso.mod +++ b/data/scene/milkyway-eso/milkyway-eso.mod @@ -2,12 +2,9 @@ return { { Name = "MilkyWay", Parent = "SolarSystem", - Ephemeris = { - Type = "Static" - }, Renderable = { Type = "RenderableSphere", - Size = {10, 20}, + Size = { 10, 20 }, Segments = 40, Texture = "textures/eso0932a_blend.png", Orientation = "Inside/Outside" diff --git a/data/scene/milkyway/milkyway.mod b/data/scene/milkyway/milkyway.mod index 148ac2b331..8fa37be7a5 100644 --- a/data/scene/milkyway/milkyway.mod +++ b/data/scene/milkyway/milkyway.mod @@ -2,12 +2,9 @@ return { { Name = "MilkyWay", Parent = "SolarSystem", - Ephemeris = { - Type = "Static" - }, Renderable = { Type = "RenderableSphere", - Size = {10, 22}, + Size = { 10, 22 }, Segments = 40, Texture = "textures/DarkUniverse_mellinger_8k.jpg", Orientation = "Inside/Outside" diff --git a/data/scene/moon/moon.mod b/data/scene/moon/moon.mod index bd941e815a..586cdc1081 100644 --- a/data/scene/moon/moon.mod +++ b/data/scene/moon/moon.mod @@ -5,8 +5,8 @@ return { Parent = "EarthBarycenter", Renderable = { Type = "RenderablePlanet", - Frame = "IAU_MOON", - Body = "MOON", + Frame = "IAU_MOON", + Body = "MOON", Geometry = { Type = "SimpleSphere", Radius = { 1.737, 6}, @@ -28,21 +28,19 @@ return { --Color = "textures/moonmap4k.jpg", }, }, - Ephemeris = { - Type = "Spice", - Body = "MOON", - Reference = "ECLIPJ2000", - Observer = "EARTH BARYCENTER", - Kernels = { - "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" - } + Transform = { + Translation = { + Type = "SpiceEphemeris", + Body = "MOON", + Observer = "EARTH BARYCENTER", + Kernels = "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" + }, + Rotation = { + Type = "SpiceRotation", + SourceFrame = "IAU_MOON", + DestinationFrame = "ECLIPJ2000" + }, }, - Rotation = { - Type = "Spice", - Frame = "IAU_MOON", - Reference = "ECLIPJ2000" - }, - GuiName = "/Solar/Planets/MOON" }, -- MoonTrail module { @@ -63,6 +61,5 @@ return { -- need to add different texture }, }, - GuiName = "/Solar/MoonTrail" } } diff --git a/data/scene/neptune/neptune.mod b/data/scene/neptune/neptune.mod index 23e0e41dbf..2a44ae7098 100644 --- a/data/scene/neptune/neptune.mod +++ b/data/scene/neptune/neptune.mod @@ -3,9 +3,6 @@ return { { Name = "NeptuneBarycenter", Parent = "SolarSystemBarycenter", - Ephemeris = { - Type = "Static" - } }, -- Neptune module @@ -29,18 +26,14 @@ return { Ephemeris = { Type = "Spice", Body = "NEPTUNE BARYCENTER", - Reference = "ECLIPJ2000", Observer = "SUN", - Kernels = { - "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" - } + Kernels = "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" }, Rotation = { Type = "Spice", Frame = "IAU_NEPTUNE", Reference = "ECLIPJ2000" }, - GuiName = "/Solar/Planets/Neptune" }, -- NeptuneTrail module { @@ -61,6 +54,5 @@ return { -- need to add different texture }, }, - GuiName = "/Solar/NeptuneTrail" } } diff --git a/data/scene/newhorizons.scene b/data/scene/newhorizons.scene index 71841075fc..812f30ee3d 100644 --- a/data/scene/newhorizons.scene +++ b/data/scene/newhorizons.scene @@ -70,7 +70,6 @@ return { -- "stars-denver", "milkyway", -- "milkyway-eso", - "imageplane", "newhorizons/newhorizons", "newhorizons/newhorizonsfov", } diff --git a/data/scene/newhorizons/jupiter/callisto/callisto.mod b/data/scene/newhorizons/jupiter/callisto/callisto.mod index 81fbdb7005..c00cd996e1 100644 --- a/data/scene/newhorizons/jupiter/callisto/callisto.mod +++ b/data/scene/newhorizons/jupiter/callisto/callisto.mod @@ -6,7 +6,7 @@ return { Renderable = { Type = "RenderablePlanetProjection", Frame = "IAU_CALLISTO", - Body = "CALLISTO", + Body = "CALLISTO", Geometry = { Type = "SimpleSphere", Radius = { 1.8213, 6 }, @@ -22,6 +22,7 @@ return { Observer = "NEW HORIZONS", Target = "CALLISTO", Aberration = "NONE", + AspectRatio = 2 }, Instrument = { Name = "NH_LORRI", @@ -36,31 +37,12 @@ return { "JUPITER", "IO", "EUROPA", "GANYMEDE", "CALLISTO" } }, - --[[ - Ephemeris = { - Type = "Spice", - Body = "CALLISTO", - Reference = "ECLIPJ2000", - Observer = "JUPITER BARYCENTER", - Kernels = { - "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" - } - }, - Rotation = { - Type = "Spice", - Frame = "IAU_CALLISTO", - Reference = "ECLIPJ2000" - }, - ]] Transform = { Translation = { Type = "SpiceEphemeris", Body = "CALLISTO", - Reference = "ECLIPJ2000", Observer = "JUPITER BARYCENTER", - Kernels = { - "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" - } + Kernels = "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" }, Rotation = { Type = "SpiceRotation", @@ -68,7 +50,6 @@ return { DestinationFrame = "ECLIPJ2000", }, }, - GuiName = "/Solar/Planets/Jupiter" }, { Name = "CallistoText", @@ -78,7 +59,8 @@ return { Size = {1.0, 7.4}, Origin = "Center", Billboard = true, - Texture = "textures/Callisto-Text.png" + Texture = "textures/Callisto-Text.png", + BlendMode = "Additive" }, --[[ Ephemeris = { @@ -113,6 +95,5 @@ return { -- need to add different texture }, }, - GuiName = "/Solar/CallistoTrail" } } diff --git a/data/scene/newhorizons/jupiter/europa/europa.mod b/data/scene/newhorizons/jupiter/europa/europa.mod index cc8fed3967..fc7c032a2b 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", @@ -36,31 +37,12 @@ return { "JUPITER", "IO", "EUROPA", "GANYMEDE", "CALLISTO" } }, - --[[ - Ephemeris = { - Type = "Spice", - Body = "EUROPA", - Reference = "ECLIPJ2000", - Observer = "JUPITER BARYCENTER", - Kernels = { - "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" - } - }, - Rotation = { - Type = "Spice", - Frame = "IAU_EUROPA", - Reference = "ECLIPJ2000" - }, - ]] Transform = { Translation = { Type = "SpiceEphemeris", Body = "EUROPA", - Reference = "ECLIPJ2000", Observer = "JUPITER BARYCENTER", - Kernels = { - "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" - } + Kernels = "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" }, Rotation = { Type = "SpiceRotation", @@ -68,7 +50,6 @@ return { DestinationFrame = "ECLIPJ2000", }, }, - GuiName = "/Solar/Planets/Jupiter" }, { Name = "EuropaText", @@ -78,7 +59,8 @@ return { Size = {1.0, 7.4}, Origin = "Center", Billboard = true, - Texture = "textures/Europa-Text.png" + Texture = "textures/Europa-Text.png", + BlendMode = "Additive" }, --[[ Ephemeris = { @@ -113,6 +95,5 @@ return { -- need to add different texture }, }, - GuiName = "/Solar/EuropaTrail" } } diff --git a/data/scene/newhorizons/jupiter/ganymede/ganymede.mod b/data/scene/newhorizons/jupiter/ganymede/ganymede.mod index 1ef503e6fb..3f14d6495f 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", @@ -40,11 +41,8 @@ return { Translation = { Type = "SpiceEphemeris", Body = "GANYMEDE", - Reference = "ECLIPJ2000", Observer = "JUPITER BARYCENTER", - Kernels = { - "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" - } + Kernels = "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" }, Rotation = { Type = "SpiceRotation", @@ -52,23 +50,6 @@ return { DestinationFrame = "ECLIPJ2000", }, }, - --[[ - Ephemeris = { - Type = "Spice", - Body = "GANYMEDE", - Reference = "ECLIPJ2000", - Observer = "JUPITER BARYCENTER", - Kernels = { - "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" - } - }, - Rotation = { - Type = "Spice", - Frame = "IAU_GANYMEDE", - Reference = "ECLIPJ2000" - }, - ]] - GuiName = "/Solar/Planets/Jupiter" }, { Name = "GanymedeText", @@ -78,7 +59,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 = { @@ -107,6 +89,5 @@ return { -- need to add different texture }, }, - GuiName = "/Solar/GanymedeTrail" } } diff --git a/data/scene/newhorizons/jupiter/io/io.mod b/data/scene/newhorizons/jupiter/io/io.mod index 553ae825f5..7fde7e5650 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", @@ -40,11 +41,8 @@ return { Translation = { Type = "SpiceEphemeris", Body = "IO", - Reference = "ECLIPJ2000", Observer = "JUPITER BARYCENTER", - Kernels = { - "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" - } + Kernels = "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" }, Rotation = { Type = "SpiceRotation", @@ -68,7 +66,6 @@ return { Reference = "ECLIPJ2000" }, ]] - GuiName = "/Solar/Planets/Jupiter" }, { Name = "IoText", @@ -78,7 +75,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 = { @@ -107,6 +105,5 @@ return { -- need to add different texture }, }, - GuiName = "/Solar/IoTrail" } } diff --git a/data/scene/newhorizons/jupiter/jupiter/jupiter.mod b/data/scene/newhorizons/jupiter/jupiter/jupiter.mod index c8076e913e..ccb6649f29 100644 --- a/data/scene/newhorizons/jupiter/jupiter/jupiter.mod +++ b/data/scene/newhorizons/jupiter/jupiter/jupiter.mod @@ -7,11 +7,8 @@ return { Translation = { Type = "SpiceEphemeris", Body = "JUPITER BARYCENTER", - Reference = "ECLIPJ2000", Observer = "SUN", - Kernels = { - "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" - } + Kernels = "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" }, }, }, @@ -41,6 +38,7 @@ return { Observer = "NEW HORIZONS", Target = "JUPITER", Aberration = "NONE", + AspectRatio = 2 }, DataInputTranslation = { Instrument = { @@ -96,7 +94,6 @@ return { DestinationFrame = "GALACTIC", }, }, - GuiName = "/Solar/Planets/Jupiter" }, { Name = "JupiterText", @@ -106,7 +103,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 = { @@ -134,7 +132,6 @@ return { -- need to add different texture }, }, - GuiName = "/Solar/JupiterTrail" } } diff --git a/data/scene/newhorizons/newhorizons/newhorizons.mod b/data/scene/newhorizons/newhorizons/newhorizons.mod index 7b4b4c1eca..a4ba9124f4 100644 --- a/data/scene/newhorizons/newhorizons/newhorizons.mod +++ b/data/scene/newhorizons/newhorizons/newhorizons.mod @@ -102,23 +102,10 @@ return { Ghosting = false, }, }, - --[[ - Ephemeris = { - Type = "Spice", - Body = "NEW HORIZONS", - -- Reference = "ECLIPJ2000", - Reference = "GALACTIC", - -- Observer = "PLUTO BARYCENTER", - Observer = "SUN", - -- Observer = "JUPITER BARYCENTER", - Kernels = NewHorizonsKernels - }, - ]] Transform = { Translation = { Type = "SpiceEphemeris", Body = "NEW HORIZONS", - Reference = "GALACTIC", Observer = "SUN", Kernels = NewHorizonsKernels }, @@ -128,7 +115,6 @@ return { DestinationFrame = "GALACTIC", }, }, - GuiName = "/Solar/NewHorizons" }, --NewHorizonsTrail module --[[{ @@ -181,7 +167,6 @@ return { Ghosting = false, }, }, - GuiName = "/Solar/NewHorizons" }, { @@ -209,7 +194,6 @@ return { SampleDeltaTime = 3600, -- Seconds between each point SubSamples = 3, }, - GuiName = "/Solar/NewHorizonsTrailPluto" }, --[[ -- NewHorizonsPath module diff --git a/data/scene/newhorizons/newhorizonsfov/newhorizonsfov.mod b/data/scene/newhorizons/newhorizonsfov/newhorizonsfov.mod index e33f7136b8..f2b4fab3f5 100644 --- a/data/scene/newhorizons/newhorizonsfov/newhorizonsfov.mod +++ b/data/scene/newhorizons/newhorizonsfov/newhorizonsfov.mod @@ -24,7 +24,6 @@ return { "Jupiter", "Io", "Europa", "Ganymede", "Callisto" } }, - GuiName = "/Solar/NH_LORRI" }, -- NewHorizonsFov module NH_RALPH_LEISA { @@ -51,7 +50,6 @@ return { "Jupiter", "Io", "Europa", "Ganymede", "Callisto" } }, - GuiName = "/Solar/NH_RALPH_LEISA" }, -- NewHorizonsFov module NH_RALPH_MVIC_PAN1 @@ -79,7 +77,6 @@ return { "Jupiter", "Io", "Europa", "Ganymede", "Callisto" } }, - GuiName = "/Solar/NH_RALPH_MVIC_PAN1" }, -- NewHorizonsFov module NH_RALPH_MVIC_PAN2 { @@ -107,7 +104,6 @@ return { } }, - GuiName = "/Solar/NH_RALPH_MVIC_PAN2" }, -- NewHorizonsFov module NH_RALPH_MVIC_RED { @@ -135,7 +131,6 @@ return { } }, - GuiName = "/Solar/NH_RALPH_MVIC_RED" }, -- NewHorizonsFov module NH_RALPH_MVIC_BLUE { @@ -162,7 +157,6 @@ return { "Jupiter", "Io", "Europa", "Ganymede", "Callisto" } }, - GuiName = "/Solar/NH_RALPH_MVIC_BLUE" }, -- NewHorizonsFov module NH_RALPH_MVIC_FT { @@ -189,7 +183,6 @@ return { "Jupiter", "Io", "Europa", "Ganymede", "Callisto" } }, - GuiName = "/Solar/NH_RALPH_MVIC_FT" }, -- NewHorizonsFov module NH_RALPH_MVIC_METHANE { @@ -216,7 +209,6 @@ return { "Jupiter", "Io", "Europa", "Ganymede", "Callisto" } }, - GuiName = "/Solar/NH_RALPH_MVIC_METHANE" }, -- NewHorizonsFov module NH_RALPH_MVIC_NIR { @@ -243,7 +235,6 @@ return { "Jupiter", "Io", "Europa", "Ganymede", "Callisto" } }, - GuiName = "/Solar/NH_RALPH_MVIC_METHANE" }, -- NewHorizonsFov module NH_ALICE_AIRGLOW { @@ -270,7 +261,6 @@ return { "Jupiter", "Io", "Europa", "Ganymede", "Callisto" } }, - GuiName = "/Solar/NH_ALICE_AIRGLOW" }, -- NewHorizonsFov module NH_ALICE_SOC { @@ -297,7 +287,6 @@ return { "Jupiter", "Io", "Europa", "Ganymede", "Callisto" } }, - GuiName = "/Solar/NH_ALICE_SOC" }, { Name = "NH_REX", diff --git a/data/scene/newhorizons/newhorizonspath/newhorizonspath.mod b/data/scene/newhorizons/newhorizonspath/newhorizonspath.mod index 6ebf488e5f..d11cb2a8bb 100644 --- a/data/scene/newhorizons/newhorizonspath/newhorizonspath.mod +++ b/data/scene/newhorizons/newhorizonspath/newhorizonspath.mod @@ -15,6 +15,5 @@ return { -- need to add different texture }, }, - GuiName = "/Solar/NewHorizonsPath" } } \ No newline at end of file diff --git a/data/scene/newhorizons/newhorizonstrail/newhorizonstrail.mod b/data/scene/newhorizons/newhorizonstrail/newhorizonstrail.mod index ac6d22401b..e8a334b6ae 100644 --- a/data/scene/newhorizons/newhorizonstrail/newhorizonstrail.mod +++ b/data/scene/newhorizons/newhorizonstrail/newhorizonstrail.mod @@ -18,6 +18,5 @@ return { -- need to add different texture }, }, - GuiName = "/Solar/NewHorizonsTrail" } } \ No newline at end of file diff --git a/data/scene/newhorizons/pluto/charon/charon.mod b/data/scene/newhorizons/pluto/charon/charon.mod index 1e51526c97..f7a2f5e35a 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", @@ -55,25 +56,10 @@ return { "CHARON" } }, - --[[ - Ephemeris = { - Type = "Spice", - Body = "CHARON", - Reference = "ECLIPJ2000", - Observer = "PLUTO BARYCENTER", - Kernels = NewHorizonsKernels - }, - Rotation = { - Type = "Spice", - Frame = "IAU_CHARON", - Reference = "ECLIPJ2000" - }, - ]] Transform = { Translation = { Type = "SpiceEphemeris", Body = "CHARON", - Reference = "GALACTIC", Observer = "PLUTO BARYCENTER", Kernels = NewHorizonsKernels }, @@ -83,7 +69,6 @@ return { DestinationFrame = "GALACTIC" }, }, - GuiName = "/Solar/Planets/Charon" }, { Name = "CharonText", @@ -93,7 +78,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 = { @@ -101,12 +87,6 @@ return { Position = {0, -1000000, 0} }, }, - --[[ - Ephemeris = { - Type = "Static", - Position = {0, -10, 0, 5} - } - ]] }, { Name = "CharonShadow", @@ -141,6 +121,5 @@ return { -- need to add different texture }, }, - GuiName = "/Solar/CharonTrail" } } diff --git a/data/scene/newhorizons/pluto/hydra/hydra.mod b/data/scene/newhorizons/pluto/hydra/hydra.mod index 272f45c417..89246a82f6 100644 --- a/data/scene/newhorizons/pluto/hydra/hydra.mod +++ b/data/scene/newhorizons/pluto/hydra/hydra.mod @@ -27,25 +27,10 @@ return { Color = "textures/gray.jpg", } }, - --[[ - Ephemeris = { - Type = "Spice", - Body = "Hydra", - Reference = "ECLIPJ2000", - Observer = "PLUTO BARYCENTER", - Kernels = NewHorizonsKernels - }, - Rotation = { - Type = "Spice", - Frame = "IAU_PLUTO", - Reference = "ECLIPJ2000" - }, - ]] Transform = { Translation = { Type = "SpiceEphemeris", Body = "HYDRA", - Reference = "ECLIPJ2000", Observer = "PLUTO BARYCENTER", Kernels = NewHorizonsKernels }, @@ -55,7 +40,6 @@ return { DestinationFrame = "ECLIPJ2000" }, }, - GuiName = "/Solar/Planets/Hydra" }, { Name = "HydraText", @@ -73,12 +57,6 @@ return { Position = {1000000, 0, 1000000}, }, }, - --[[ - Ephemeris = { - Type = "Static", - Position = {1, 0, 1, 6} - } - ]] }, -- HydraTrail module { @@ -100,7 +78,6 @@ return { -- need to add different texture }, }, - GuiName = "/Solar/HydraTrail" } } diff --git a/data/scene/newhorizons/pluto/kerberos/kerberos.mod b/data/scene/newhorizons/pluto/kerberos/kerberos.mod index 4fa0d6d45c..ba541c4de2 100644 --- a/data/scene/newhorizons/pluto/kerberos/kerberos.mod +++ b/data/scene/newhorizons/pluto/kerberos/kerberos.mod @@ -27,25 +27,10 @@ return { Color = "textures/gray.jpg", } }, - --[[ - Ephemeris = { - Type = "Spice", - Body = "KERBEROS", - Reference = "ECLIPJ2000", - Observer = "PLUTO BARYCENTER", - Kernels = NewHorizonsKernels - }, - Rotation = { - Type = "Spice", - Frame = "IAU_PLUTO", - Reference = "ECLIPJ2000" - }, - ]] Transform = { Translation = { Type = "SpiceEphemeris", Body = "KERBEROS", - Reference = "ECLIPJ2000", Observer = "PLUTO BARYCENTER", Kernels = NewHorizonsKernels }, @@ -55,7 +40,6 @@ return { DestinationFrame = "ECLIPJ2000" }, }, - GuiName = "/Solar/Planets/Kerberos" }, { Name = "KerberosText", @@ -67,12 +51,6 @@ return { Billboard = true, Texture = "textures/Kerberos-Text.png" }, - --[[ - Ephemeris = { - Type = "Static", - Position = {1, 0, 1, 6} - } - ]] Transform = { Translation = { Type = "StaticEphemeris", @@ -100,7 +78,6 @@ return { -- need to add different texture }, }, - GuiName = "/Solar/KerberosTrail" } } diff --git a/data/scene/newhorizons/pluto/nix/nix.mod b/data/scene/newhorizons/pluto/nix/nix.mod index 483c3174c6..10145a29ae 100644 --- a/data/scene/newhorizons/pluto/nix/nix.mod +++ b/data/scene/newhorizons/pluto/nix/nix.mod @@ -31,7 +31,6 @@ return { Translation = { Type = "SpiceEphemeris", Body = "NIX", - Reference = "ECLIPJ2000", Observer = "PLUTO BARYCENTER", Kernels = NewHorizonsKernels }, @@ -41,21 +40,6 @@ return { DestinationFrame = "ECLIPJ2000" }, }, - --[[ - Ephemeris = { - Type = "Spice", - Body = "NIX", - Reference = "ECLIPJ2000", - Observer = "PLUTO BARYCENTER", - Kernels = NewHorizonsKernels - }, - Rotation = { - Type = "Spice", - Frame = "IAU_PLUTO", - Reference = "ECLIPJ2000" - }, - ]] - GuiName = "/Solar/Planets/Nix" }, { Name = "NixText", @@ -67,12 +51,6 @@ return { Billboard = true, Texture = "textures/Nix-Text.png" }, - --[[ - Ephemeris = { - Type = "Static", - Position = {0, 0, 0, 0} - } - ]] }, -- StyxTrail module { @@ -94,7 +72,6 @@ return { -- need to add different texture }, }, - GuiName = "/Solar/NixTrail" } } diff --git a/data/scene/newhorizons/pluto/pluto/pluto.mod b/data/scene/newhorizons/pluto/pluto/pluto.mod index ab6abd4dff..c6bae149dd 100644 --- a/data/scene/newhorizons/pluto/pluto/pluto.mod +++ b/data/scene/newhorizons/pluto/pluto/pluto.mod @@ -21,20 +21,10 @@ return { { Name = "PlutoBarycenter", Parent = "SolarSystemBarycenter", - --[[ - Ephemeris = { - Type = "Spice", - Body = "PLUTO BARYCENTER", - Reference = "ECLIPJ2000", - Observer = "SUN", - Kernels = NewHorizonsKernels - }, - ]] Transform = { Translation = { Type = "SpiceEphemeris", Body = "PLUTO BARYCENTER", - Reference = "ECLIPJ2000", Observer = "SUN", Kernels = NewHorizonsKernels }, @@ -67,6 +57,7 @@ return { Observer = "NEW HORIZONS", Target = "PLUTO", Aberration = "NONE", + AspectRatio = 2 }, DataInputTranslation = { Instrument = { @@ -164,25 +155,10 @@ return { "P4", } }, - --[[ - Ephemeris = { - Type = "Spice", - Body = "PLUTO", - Reference = "GALACTIC", - Observer = "PLUTO BARYCENTER", - Kernels = NewHorizonsKernels - }, - Rotation = { - Type = "Spice", - Frame = "IAU_PLUTO", - Reference = "GALACTIC" - }, - ]] Transform = { Translation = { Type = "SpiceEphemeris", Body = "PLUTO", - Reference = "GALACTIC", Observer = "PLUTO BARYCENTER", Kernels = NewHorizonsKernels }, @@ -192,7 +168,6 @@ return { DestinationFrame = "GALACTIC", } }, - GuiName = "/Solar/Planets/Pluto" }, { Name = "PlutoBarycenterLabel", @@ -208,12 +183,6 @@ return { MieColor = {1.0, 1.0, 1.0} } }, - --[[ - Ephemeris = { - Type = "Static", - Position = {0, 0, 0, 1} - }, - ]] }, { Name = "PlutoText", @@ -223,7 +192,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 = { @@ -231,12 +201,6 @@ return { Position = {0, -2000000, 0} }, }, - --[[ - Ephemeris = { - Type = "Static", - Position = {0, -20, 0, 5} - } - ]] }, { Name = "PlutoTexture", @@ -255,12 +219,6 @@ return { Position = {0, -4000000, 0} }, }, - --[[ - Ephemeris = { - Type = "Static", - Position = {0, 0, 40, 5} - } - ]] }, { Name = "PlutoShadow", @@ -295,7 +253,6 @@ return { -- need to add different texture }, }, - GuiName = "/Solar/CharonTrail" }, -- PlutoTrail module { @@ -316,6 +273,5 @@ return { -- need to add different texture }, }, - GuiName = "/Solar/PlutoTrail" } } diff --git a/data/scene/newhorizons/pluto/styx/styx.mod b/data/scene/newhorizons/pluto/styx/styx.mod index b53af6a70c..52918a7d26 100644 --- a/data/scene/newhorizons/pluto/styx/styx.mod +++ b/data/scene/newhorizons/pluto/styx/styx.mod @@ -27,26 +27,10 @@ return { Color = "textures/gray.jpg", } }, - --[[ - Ephemeris = { - Type = "Spice", - Body = "STYX", - Reference = "ECLIPJ2000", - Observer = "PLUTO BARYCENTER", - Kernels = NewHorizonsKernels - }, - Rotation = { - Type = "Spice", - Frame = "IAU_PLUTO", - Reference = "ECLIPJ2000" - }, - ]] - Transform = { Translation = { Type = "SpiceEphemeris", Body = "STYX", - Reference = "ECLIPJ2000", Observer = "PLUTO BARYCENTER", Kernels = NewHorizonsKernels }, @@ -56,7 +40,6 @@ return { DestinationFrame = "ECLIPJ2000" }, }, - GuiName = "/Solar/Planets/Styx" }, { Name = "StyxText", @@ -66,7 +49,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 = { @@ -74,12 +58,6 @@ return { Position = {1000000, 0, 1000000} }, }, - --[[ - Ephemeris = { - Type = "Static", - Position = {1, 0, 1, 6} - } - ]] }, -- StyxTrail module { @@ -101,7 +79,6 @@ return { -- need to add different texture }, }, - GuiName = "/Solar/CharonTrail" } } diff --git a/data/scene/osirisrex.scene b/data/scene/osirisrex.scene index a20c35d1aa..44d4a4052e 100644 --- a/data/scene/osirisrex.scene +++ b/data/scene/osirisrex.scene @@ -2,6 +2,8 @@ TextureResolution = "med" -- TextureResolution = "high" +local startTime = "2016 SEP 8 23:05:00.50" + function preInitialization() --[[ The scripts in this function are executed after the scene is loaded but before the @@ -10,8 +12,6 @@ function preInitialization() critical objects. ]]-- - dofile(openspace.absPath('${SCRIPTS}/bind_keys.lua')) - -- Load Spice Kernels openspace.spice.loadKernel("${OPENSPACE_DATA}/spice/de430_1850-2150.bsp") @@ -39,6 +39,7 @@ function preInitialization() -- Low res SPK openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/background/spk/orx_160917_231024_pgaa3_day15m60_v1.bsp") openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/background/spk/orx_160914_231024_pgaa3_day12m60_v1.bsp") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/background/spk/orx_160908_231024_pgaa3_day06m60_v1.bsp") openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/background/spk/spk_orx_160908_231024_pgaa2_day06m60_v3.bsp") openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/background/spk/orx_160908_231024_pgaa2_day06m60.bsp") @@ -50,6 +51,19 @@ function preInitialization() openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/background/spk/de421.bsp") openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/background/spk/sb-101955-76.bsp") + -- Nominal_Profile_LowRes + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Profile_LowRes/Approach_600s_20180816T230000_20181119T010000.bsp") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Profile_LowRes/Approach_NominalProfile_600s_20180816T230000_20181119T010000.bc") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Profile_LowRes/DetailedSurvey_600s_20190108T000000_20190317T000000.bsp") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Profile_LowRes/DetailedSurvey_NominalProfile_600s_20190108T000000_20190317T000000.bc") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Profile_LowRes/OrbitalA_600s_20181203T230000_20190109T000000.bsp") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Profile_LowRes/OrbitalA_NominalProfile_600s_20181203T230000_20190109T000000.bc") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Profile_LowRes/OrbitalB_600s_20190316T000000_20190521T000000.bsp") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Profile_LowRes/OrbitalB_NominalProfile600s_20190316T000000_20190521T000000.bc") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Profile_LowRes/PrelimSurvey_600s_20181119T230000_20181204T010000.bsp") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Profile_LowRes/PrelimSurvey_NominalProfile_600s_20181119T230000_20181204T010000.bc") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Profile_LowRes/Recon_600s_20190519T000000_20190830T000000.bsp") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Profile_LowRes/Recon_NominalProfile_600s_20190519T000000_20190830T000000.bc") -- Nominal_Observations_Science openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/03_Approach/DustSearch_v1/Phase03_AP_DustSearch_1.bc") @@ -80,15 +94,19 @@ function preInitialization() openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/04_PrelimSurvey/PolyCam_v1/Phase04_PS_PolyCam_4.bc") openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/04_PrelimSurvey/PolyCam_v1/Phase04_PS_PolyCam_5.bc") openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/04_PrelimSurvey/PolyCam_v1/Phase04_PS_PolyCam_6.bc") + --openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/06_DetailedSurvey/BaseballDiamond_v2/atl_19013_18_BBD1_info.TXT") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/06_DetailedSurvey/BaseballDiamond_v2/atl_19013_18_BBD1_v2.bc") --openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/06_DetailedSurvey/BaseballDiamond_v2/atl_19014_16_BBD2_info.TXT") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/06_DetailedSurvey/BaseballDiamond_v2/atl_19014_16_BBD2_v2.bc") --openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/06_DetailedSurvey/BaseballDiamond_v2/atl_19020_18_BBD3_info.TXT") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/06_DetailedSurvey/BaseballDiamond_v2/atl_19020_18_BBD3_v2.bc") --openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/06_DetailedSurvey/BaseballDiamond_v2/atl_19021_19_BBD4_info.TXT") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/06_DetailedSurvey/BaseballDiamond_v2/atl_19021_19_BBD4_v2.bc") --openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/06_DetailedSurvey/BaseballDiamond_v2/README.txt") + + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/06_DetailedSurvey/BaseballDiamond_v2/atl_19013_18_BBD1_v2.bc") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/06_DetailedSurvey/BaseballDiamond_v2/atl_19014_16_BBD2_v2.bc") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/06_DetailedSurvey/BaseballDiamond_v2/atl_19020_18_BBD3_v2.bc") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/06_DetailedSurvey/BaseballDiamond_v2/atl_19021_19_BBD4_v2.bc") + + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/06_DetailedSurvey/EquatorialStations_v1/Phase06_DS_Equatorial_Stations_1.bc") openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/06_DetailedSurvey/EquatorialStations_v1/Phase06_DS_Equatorial_Stations_2.bc") openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/06_DetailedSurvey/EquatorialStations_v1/Phase06_DS_Equatorial_Stations_3.bc") @@ -104,48 +122,51 @@ function preInitialization() openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/07_OrbitalB/CandidateSampleSite_v2/CSS_Mapping_1.a") openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/07_OrbitalB/CandidateSampleSite_v2/CSS_Mapping_2.a") openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/07_OrbitalB/CandidateSampleSite_v2/CSS_Mapping_3.a") + --openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/225m_Sortie_v2/Case02_0Latitude.wmv") --openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/225m_Sortie_v2/Case05_20negLatitude.wmv") --openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/225m_Sortie_v2/Case08_40negLatitude.wmv") --openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/225m_Sortie_v2/Case11_60negLatitude.wmv") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/225m_Sortie_v2/ORX_Recon_225mSortie_Case02.bsp") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/225m_Sortie_v2/ORX_Recon_225mSortie_Case05.bsp") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/225m_Sortie_v2/ORX_Recon_225mSortie_Case08.bsp") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/225m_Sortie_v2/ORX_Recon_225mSortie_Case11.bsp") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/225m_Sortie_v2/Recon_225mSortie_Case02_0Latitude.bc") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/225m_Sortie_v2/Recon_225mSortie_Case05_20negLatitude.bc") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/225m_Sortie_v2/Recon_225mSortie_Case08_40negLatitude.bc") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/225m_Sortie_v2/Recon_225mSortie_Case11_60negLatitude.bc") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/525m_Sortie_v2/ORX_Recon_525mSortie_Case02.bsp") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/525m_Sortie_v2/ORX_Recon_525mSortie_Case05.bsp") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/525m_Sortie_v2/Recon_525mSortie_Case02_0Latitude.bc") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/525m_Sortie_v2/Recon_525mSortie_Case02_atl_19145_04.atf") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/525m_Sortie_v2/Recon_525mSortie_Case05_20negLatitude.bc") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/525m_Sortie_v2/Recon_525mSortie_Case05_atl_19145_04.atf") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/525m_Sortie_v2/Recon_525mSortie_Case05_NominalProfile.bc") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/525m_Sortie_v2/Recon_525mSortie_Case08_NominalProfile.bc") - -- Nominal_Profile_LowRes - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Profile_LowRes/Approach_600s_20180816T230000_20181119T010000.bsp") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Profile_LowRes/Approach_NominalProfile_600s_20180816T230000_20181119T010000.bc") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Profile_LowRes/DetailedSurvey_600s_20190108T000000_20190317T000000.bsp") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Profile_LowRes/DetailedSurvey_NominalProfile_600s_20190108T000000_20190317T000000.bc") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Profile_LowRes/OrbitalA_600s_20181203T230000_20190109T000000.bsp") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Profile_LowRes/OrbitalA_NominalProfile_600s_20181203T230000_20190109T000000.bc") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Profile_LowRes/OrbitalB_600s_20190316T000000_20190521T000000.bsp") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Profile_LowRes/OrbitalB_NominalProfile600s_20190316T000000_20190521T000000.bc") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Profile_LowRes/PrelimSurvey_600s_20181119T230000_20181204T010000.bsp") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Profile_LowRes/PrelimSurvey_NominalProfile_600s_20181119T230000_20181204T010000.bc") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Profile_LowRes/Recon_600s_20190519T000000_20190830T000000.bsp") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Profile_LowRes/Recon_NominalProfile_600s_20190519T000000_20190830T000000.bc") - + local case = 2 -- Right now we only have the image times for case 2 + + if case == 2 then + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/525m_Sortie_v2/ORX_Recon_525mSortie_Case02.bsp") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/525m_Sortie_v2/Recon_525mSortie_Case02_0Latitude.bc") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/525m_Sortie_v2/Recon_525mSortie_Case02_atl_19145_04.atf") + + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/225m_Sortie_v2/ORX_Recon_225mSortie_Case02.bsp") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/225m_Sortie_v2/Recon_225mSortie_Case02_0Latitude.bc") + elseif case == 5 then + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/525m_Sortie_v2/ORX_Recon_525mSortie_Case05.bsp") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/525m_Sortie_v2/Recon_525mSortie_Case05_20negLatitude.bc") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/525m_Sortie_v2/Recon_525mSortie_Case05_atl_19145_04.atf") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/525m_Sortie_v2/Recon_525mSortie_Case05_NominalProfile.bc") + + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/225m_Sortie_v2/ORX_Recon_225mSortie_Case05.bsp") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/225m_Sortie_v2/Recon_225mSortie_Case05_20negLatitude.bc") + elseif case == 8 then + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/525m_Sortie_v2/Recon_525mSortie_Case08_NominalProfile.bc") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/225m_Sortie_v2/ORX_Recon_225mSortie_Case08.bsp") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/225m_Sortie_v2/Recon_225mSortie_Case08_40negLatitude.bc") + elseif case == 11 then + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/225m_Sortie_v2/ORX_Recon_225mSortie_Case11.bsp") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/225m_Sortie_v2/Recon_225mSortie_Case11_60negLatitude.bc") + end + -- Load planetary constants openspace.spice.loadKernel("${SPICE}/pck00010.tpc") - -- openspace.time.setTime("2018-12-20T22:47:00.00") - --openspace.time.setTime("2019-05-25T03:57:55.00") - openspace.time.setTime("2016 SEP 8 23:05:00.50") - openspace.time.setDeltaTime(0) + dofile(openspace.absPath('${SCRIPTS}/bind_keys.lua')) + dofile(openspace.absPath('${SCRIPTS}/bind_keys_osirisrex.lua')) + + --local startTime = "2019 APR 16 12:03:00.00" + + openspace.scriptScheduler.load("${OPENSPACE_DATA}/scene/osirisrex/scheduled_scripts.lua") + + -- Removing the line below will cause all scripts prior to to be executed during initialization + -- openspace.scriptScheduler.skipTo(startTime); + end function postInitialization() @@ -165,12 +186,17 @@ function postInitialization() openspace.setPropertyValue("MilkyWay.renderable.transparency", 0.55) openspace.setPropertyValue("MilkyWay.renderable.segments", 50) - -- Rotate Osiris Rex model to match the specification in the spice data - openspace.setPropertyValue("OsirisRex.renderable.modelrotation", {90.0, 0.0, 0.0}) + -- Activate night textures and water masks + openspace.setPropertyValue("Earth.RenderableGlobe.WaterMasks", {0, 1}); + openspace.setPropertyValue("Earth.RenderableGlobe.NightTextures", {0, 1}); + openspace.setPropertyValue("Earth.RenderableGlobe.Atmosphere", true); openspace.printInfo("Done setting default values") openspace.loadMission("${OPENSPACE_DATA}/scene/osirisrex/osirisrex/osirisrex.mission") + openspace.time.setTime(startTime) + openspace.time.setDeltaTime(0) + openspace.resetCameraDirection() end @@ -179,21 +205,23 @@ return { CommonFolder = "common", Camera = { Focus = "OsirisRex", - Position = {100, 0, 0}, - Rotation = {0.668258, -0.089482, 0.589040, 0.445484}, + Position = {26974590199.661884, 76314608558.908020, -127086452897.101791}, + Rotation = {0.729548, -0.126024, 0.416827, 0.527382}, }, Modules = { "sun", - --"mercury", - --"venus", + "lodmercury", + "venus", "lodearth", - --"mars", - --"saturn", - --"uranus", - --"neptune", - --"stars", + "lodmoon", + "lodmars", + "jupiter", + "saturn", + "uranus", + "neptune", + "stars", -- "stars-denver", - --"milkyway", + "milkyway", -- "milkyway-eso", --"imageplane", "osirisrex", diff --git a/data/scene/osirisrex/bennu/bennu.data b/data/scene/osirisrex/bennu/bennu.data new file mode 100644 index 0000000000..eefac04a5b --- /dev/null +++ b/data/scene/osirisrex/bennu/bennu.data @@ -0,0 +1,6 @@ +return { + FileRequest = { + { Identifier = "bennu_models", Destination = "models", Version = 1 }, + { Identifier = "bennu_textures", Destination = "textures", Version = 1 } + }, +} \ No newline at end of file diff --git a/data/scene/osirisrex/bennu/bennu.mod b/data/scene/osirisrex/bennu/bennu.mod index 7c558e16f8..6ab9afaa94 100644 --- a/data/scene/osirisrex/bennu/bennu.mod +++ b/data/scene/osirisrex/bennu/bennu.mod @@ -11,12 +11,9 @@ return { Translation = { Type = "SpiceEphemeris", Body = BENNU_BODY, - Reference = "GALACTIC", Observer = "SUN", }, }, - - GuiName = "/Solar/Bennu" }, { Name = "Bennu2", @@ -27,7 +24,7 @@ return { Body = BENNU_BODY, Geometry = { Type = "MultiModelGeometry", - GeometryFile = "models/BennuResized.obj", + GeometryFile = "models/BennuTextured.obj", Magnification = 0, }, Shading = { @@ -37,7 +34,7 @@ return { }, Textures = { Type = "simple", - Color = "textures/osirisTex.png", + Color = "textures/gray.png", Project = "textures/defaultProj.png", Default = "textures/defaultProj.png" }, @@ -48,9 +45,10 @@ return { Projection = { Sequence = "InstrumentTimes", SequenceType = "instrument-times", - Observer = "SUN", + Observer = "OSIRIS-REX", Target = BENNU_BODY, Aberration = "NONE", + AspectRatio = 2 }, DataInputTranslation = { Instruments = { @@ -59,8 +57,8 @@ return { Spice = {"ORX_OCAMS_POLYCAM"}, Files = { "BaseballDiamond_PolyCam.txt", - "OrbitalB_Site08_PolyCamImages.txt", - "Recon_225m_Equatorial_PolyCam", + --"OrbitalB_Site08_PolyCamImages.txt", + "Recon_225m_Equatorial_PolyCam.txt", }, }, ORX_REXIS = { @@ -82,7 +80,7 @@ return { Name = "ORX_OCAMS_POLYCAM", Method = "ELLIPSOID", Aberration = "NONE", - Fovy = 5.00, + Fovy = 0.792, Aspect = 1, Near = 0.01, Far = 1000000, @@ -96,8 +94,6 @@ return { DestinationFrame = "GALACTIC", }, }, - - GuiName = "/Solar/Bennu" }, { Name = "BennuTrail", @@ -123,6 +119,5 @@ return { SampleDeltaTime = 3600, -- Seconds between each point SubSamples = 0, }, - GuiName = "OsirisRexTrailLocal" }, } diff --git a/data/scene/osirisrex/osirisrex/OsirisRexKernels.torrent b/data/scene/osirisrex/osirisrex/OsirisRexKernels.torrent new file mode 100644 index 0000000000..e57e964ea3 --- /dev/null +++ b/data/scene/osirisrex/osirisrex/OsirisRexKernels.torrent @@ -0,0 +1,61 @@ +d8:announce44:udp://tracker.openbittorrent.com:80/announce13:announce-listll44:udp://tracker.openbittorrent.com:80/announceel42:udp://tracker.opentrackr.org:1337/announceee10:created by14:uTorrent/3.4.813:creation datei1474398496e8:encoding5:UTF-84:infod5:filesld6:lengthi373e4:pathl28:Nominal_Observations_Science6:READMEeed6:lengthi572e4:pathl10:background6:READMEeed6:lengthi748e4:pathl22:Nominal_Profile_LowRes6:READMEeed6:lengthi1126e4:pathl10:background3:spk34:OREX_20160908_M60_complete.bsp.lbleed6:lengthi1126e4:pathl10:background3:spk34:OREX_20160904_M45_complete.bsp.lbleed6:lengthi1176e4:pathl10:background3:spk43:orx_160917_231024_pgaa3_day15m60_v1.bsp.lbleed6:lengthi1176e4:pathl10:background3:spk43:orx_160914_231024_pgaa3_day12m60_v1.bsp.lbleed6:lengthi1180e4:pathl28:Nominal_Observations_Science11:07_OrbitalB22:CandidateSampleSite_v26:READMEeed6:lengthi1291e4:pathl16:EARTHFIXEDIAU.TFeed6:lengthi1302e4:pathl28:Nominal_Observations_Science8:08_Recon14:225m_Sortie_v26:READMEeed6:lengthi1398e4:pathl28:Nominal_Observations_Science17:06_DetailedSurvey18:BaseballDiamond_v210:README.txteed6:lengthi1930e4:pathl28:Nominal_Observations_Science17:06_DetailedSurvey18:BaseballDiamond_v226:atl_19020_18_BBD3_info.TXTeed6:lengthi1930e4:pathl28:Nominal_Observations_Science17:06_DetailedSurvey18:BaseballDiamond_v226:atl_19013_18_BBD1_info.TXTeed6:lengthi1935e4:pathl28:Nominal_Observations_Science17:06_DetailedSurvey18:BaseballDiamond_v226:atl_19014_16_BBD2_info.TXTeed6:lengthi1936e4:pathl28:Nominal_Observations_Science17:06_DetailedSurvey18:BaseballDiamond_v226:atl_19021_19_BBD4_info.TXTeed6:lengthi2203e4:pathl10:background3:spk40:orx_160908_231024_pgaa2_day06m60.bsp.lbleed6:lengthi2607e4:pathl10:background3:spk43:orx_160908_231024_pgaa3_day06m60_v1.bsp.lbleed6:lengthi3212e4:pathl10:background3:pck13:bennu_v10.tpceed6:lengthi3529e4:pathl10:background3:pck17:bennu_SPH250m.tpceed6:lengthi3579e4:pathl10:background3:spk47:spk_orx_160908_231024_pgaa2_day06m60_v3.bsp.lbleed6:lengthi3761e4:pathl28:Nominal_Observations_Science8:08_Recon14:525m_Sortie_v240:Recon_525mSortie_Case02_atl_19145_04.atfeed6:lengthi4090e4:pathl28:Nominal_Observations_Science8:08_Recon14:525m_Sortie_v240:Recon_525mSortie_Case05_atl_19145_04.atfeed6:lengthi4485e4:pathl10:background2:ik15:orx_otes_v00.tieed6:lengthi4893e4:pathl10:background4:sclk22:ORX_SCLKSCET.00000.tsceed6:lengthi4933e4:pathl10:background2:ik18:orx_stowcam_v00.tieed6:lengthi4988e4:pathl10:background2:ik14:orx_ola_v00.tieed6:lengthi4994e4:pathl10:background2:ik16:orx_ovirs_v00.tieed6:lengthi5013e4:pathl10:background2:ik16:orx_lidar_v00.tieed6:lengthi5086e4:pathl10:background3:lsk12:naif0011.tlseed6:lengthi5100e4:pathl10:background2:ik16:orx_rexis_v00.tieed6:lengthi7469e4:pathl10:background2:ik17:orx_struct_v00.tieed6:lengthi8311e4:pathl10:background2:ik17:orx_navcam_v00.tieed6:lengthi17799e4:pathl10:background2:ik16:orx_ocams_v03.tieed6:lengthi25600e4:pathl10:background3:spk16:sb-101955-76.bspeed6:lengthi33792e4:pathl28:Nominal_Observations_Science8:08_Recon14:525m_Sortie_v241:Recon_525mSortie_Case05_NominalProfile.bceed6:lengthi33792e4:pathl28:Nominal_Observations_Science8:08_Recon14:525m_Sortie_v241:Recon_525mSortie_Case08_NominalProfile.bceed6:lengthi39936e4:pathl10:background3:spk30:OREX_20160904_M45_complete.bspeed6:lengthi43008e4:pathl10:background3:spk30:OREX_20160908_M60_complete.bspeed6:lengthi73782e4:pathl10:background2:fk10:orx_v04.tfeed6:lengthi145408e4:pathl22:Nominal_Profile_LowRes67:PrelimSurvey_NominalProfile_600s_20181119T230000_20181204T010000.bceed6:lengthi150528e4:pathl28:Nominal_Observations_Science8:08_Recon14:525m_Sortie_v236:Recon_525mSortie_Case02_0Latitude.bceed6:lengthi151552e4:pathl28:Nominal_Observations_Science8:08_Recon14:525m_Sortie_v240:Recon_525mSortie_Case05_20negLatitude.bceed6:lengthi165888e4:pathl28:Nominal_Observations_Science8:08_Recon14:225m_Sortie_v236:Recon_225mSortie_Case02_0Latitude.bceed6:lengthi167936e4:pathl22:Nominal_Profile_LowRes53:PrelimSurvey_600s_20181119T230000_20181204T010000.bspeed6:lengthi184320e4:pathl28:Nominal_Observations_Science8:08_Recon14:225m_Sortie_v240:Recon_225mSortie_Case05_20negLatitude.bceed6:lengthi195584e4:pathl28:Nominal_Observations_Science15:04_PrelimSurvey6:OLA_v127:Phase04_PS_OLA_Nominal_1.bceed6:lengthi195584e4:pathl28:Nominal_Observations_Science15:04_PrelimSurvey6:OLA_v127:Phase04_PS_OLA_Nominal_4.bceed6:lengthi195584e4:pathl28:Nominal_Observations_Science15:04_PrelimSurvey6:OLA_v127:Phase04_PS_OLA_Nominal_3.bceed6:lengthi205824e4:pathl28:Nominal_Observations_Science8:08_Recon14:225m_Sortie_v240:Recon_225mSortie_Case08_40negLatitude.bceed6:lengthi224256e4:pathl28:Nominal_Observations_Science8:08_Recon14:225m_Sortie_v240:Recon_225mSortie_Case11_60negLatitude.bceed6:lengthi235520e4:pathl28:Nominal_Observations_Science15:04_PrelimSurvey6:OLA_v127:Phase04_PS_OLA_Nominal_2.bceed6:lengthi336896e4:pathl22:Nominal_Profile_LowRes49:OrbitalA_600s_20181203T230000_20190109T000000.bspeed6:lengthi337920e4:pathl22:Nominal_Profile_LowRes63:OrbitalA_NominalProfile_600s_20181203T230000_20190109T000000.bceed6:lengthi370688e4:pathl10:background3:dsk25:RQ36mod.oct12_CCv0001.bdseed6:lengthi578560e4:pathl22:Nominal_Profile_LowRes49:OrbitalB_600s_20190316T000000_20190521T000000.bspeed6:lengthi594944e4:pathl22:Nominal_Profile_LowRes55:DetailedSurvey_600s_20190108T000000_20190317T000000.bspeed6:lengthi614400e4:pathl22:Nominal_Profile_LowRes62:OrbitalB_NominalProfile600s_20190316T000000_20190521T000000.bceed6:lengthi629760e4:pathl28:Nominal_Observations_Science11:07_OrbitalB22:CandidateSampleSite_v127:Phase07_OB_CSS_Mapping_3.bceed6:lengthi629760e4:pathl28:Nominal_Observations_Science11:07_OrbitalB22:CandidateSampleSite_v127:Phase07_OB_CSS_Mapping_2.bceed6:lengthi629760e4:pathl28:Nominal_Observations_Science11:07_OrbitalB22:CandidateSampleSite_v127:Phase07_OB_CSS_Mapping_1.bceed6:lengthi632832e4:pathl22:Nominal_Profile_LowRes69:DetailedSurvey_NominalProfile_600s_20190108T000000_20190317T000000.bceed6:lengthi738304e4:pathl28:Nominal_Observations_Science8:08_Recon14:225m_Sortie_v231:ORX_Recon_225mSortie_Case02.bspeed6:lengthi805888e4:pathl22:Nominal_Profile_LowRes49:Approach_600s_20180816T230000_20181119T010000.bspeed6:lengthi817152e4:pathl28:Nominal_Observations_Science8:08_Recon14:225m_Sortie_v231:ORX_Recon_225mSortie_Case05.bspeed6:lengthi873472e4:pathl22:Nominal_Profile_LowRes63:Approach_NominalProfile_600s_20180816T230000_20181119T010000.bceed6:lengthi878592e4:pathl22:Nominal_Profile_LowRes46:Recon_600s_20190519T000000_20190830T000000.bspeed6:lengthi928768e4:pathl28:Nominal_Observations_Science8:08_Recon14:225m_Sortie_v231:ORX_Recon_225mSortie_Case11.bspeed6:lengthi935936e4:pathl28:Nominal_Observations_Science8:08_Recon14:225m_Sortie_v231:ORX_Recon_225mSortie_Case08.bspeed6:lengthi956416e4:pathl22:Nominal_Profile_LowRes60:Recon_NominalProfile_600s_20190519T000000_20190830T000000.bceed6:lengthi1091584e4:pathl28:Nominal_Observations_Science11:03_Approach13:LightCurve_v126:Phase03_AP_LightCurve_1.bceed6:lengthi1091584e4:pathl28:Nominal_Observations_Science11:03_Approach13:LightCurve_v126:Phase03_AP_LightCurve_2.bceed6:lengthi1091584e4:pathl28:Nominal_Observations_Science11:03_Approach16:PhaseFunction_v129:Phase03_AP_PhaseFunction_1.bceed6:lengthi1097728e4:pathl28:Nominal_Observations_Science11:03_Approach15:NatSatSearch_v125:Phase03_AP_SatSearch_1.bceed6:lengthi1104896e4:pathl28:Nominal_Observations_Science15:04_PrelimSurvey10:PolyCam_v123:Phase04_PS_PolyCam_1.bceed6:lengthi1104896e4:pathl28:Nominal_Observations_Science15:04_PrelimSurvey10:PolyCam_v123:Phase04_PS_PolyCam_5.bceed6:lengthi1112064e4:pathl28:Nominal_Observations_Science11:03_Approach13:DustSearch_v126:Phase03_AP_DustSearch_1.bceed6:lengthi1112064e4:pathl28:Nominal_Observations_Science11:03_Approach13:ShapeModel_v126:Phase03_AP_ShapeModel_7.bceed6:lengthi1119232e4:pathl28:Nominal_Observations_Science11:03_Approach13:ShapeModel_v126:Phase03_AP_ShapeModel_1.bceed6:lengthi1119232e4:pathl28:Nominal_Observations_Science11:03_Approach15:NatSatSearch_v125:Phase03_AP_SatSearch_2.bceed6:lengthi1119232e4:pathl28:Nominal_Observations_Science11:03_Approach13:ShapeModel_v126:Phase03_AP_ShapeModel_3.bceed6:lengthi1119232e4:pathl28:Nominal_Observations_Science11:03_Approach13:ShapeModel_v126:Phase03_AP_ShapeModel_5.bceed6:lengthi1119232e4:pathl28:Nominal_Observations_Science11:03_Approach13:ShapeModel_v126:Phase03_AP_ShapeModel_4.bceed6:lengthi1119232e4:pathl28:Nominal_Observations_Science11:03_Approach13:ShapeModel_v126:Phase03_AP_ShapeModel_2.bceed6:lengthi1158144e4:pathl28:Nominal_Observations_Science15:04_PrelimSurvey12:MapCamOLA_v124:Phase04_PS_MC_2_v1_1a.bceed6:lengthi1158144e4:pathl28:Nominal_Observations_Science15:04_PrelimSurvey12:MapCamOLA_v124:Phase04_PS_MC_1_v1_1a.bceed6:lengthi1159168e4:pathl28:Nominal_Observations_Science17:06_DetailedSurvey18:BaseballDiamond_v223:atl_19014_16_BBD2_v2.bceed6:lengthi1159168e4:pathl28:Nominal_Observations_Science15:04_PrelimSurvey10:PolyCam_v123:Phase04_PS_PolyCam_3.bceed6:lengthi1159168e4:pathl28:Nominal_Observations_Science17:06_DetailedSurvey18:BaseballDiamond_v223:atl_19020_18_BBD3_v2.bceed6:lengthi1159168e4:pathl28:Nominal_Observations_Science15:04_PrelimSurvey10:PolyCam_v123:Phase04_PS_PolyCam_2.bceed6:lengthi1159168e4:pathl28:Nominal_Observations_Science17:06_DetailedSurvey18:BaseballDiamond_v223:atl_19021_19_BBD4_v2.bceed6:lengthi1159168e4:pathl28:Nominal_Observations_Science15:04_PrelimSurvey10:PolyCam_v123:Phase04_PS_PolyCam_6.bceed6:lengthi1159168e4:pathl28:Nominal_Observations_Science17:06_DetailedSurvey18:BaseballDiamond_v223:atl_19013_18_BBD1_v2.bceed6:lengthi1646592e4:pathl28:Nominal_Observations_Science8:08_Recon14:525m_Sortie_v231:ORX_Recon_525mSortie_Case02.bspeed6:lengthi1668096e4:pathl28:Nominal_Observations_Science8:08_Recon14:525m_Sortie_v231:ORX_Recon_525mSortie_Case05.bspeed6:lengthi1748992e4:pathl10:background3:spk43:spk_orx_160908_231024_pgaa2_day06m60_v3.bspeed6:lengthi1974272e4:pathl10:background3:spk39:orx_160914_231024_pgaa3_day12m60_v1.bspeed6:lengthi1978368e4:pathl10:background3:spk39:orx_160917_231024_pgaa3_day15m60_v1.bspeed6:lengthi1982464e4:pathl10:background3:spk39:orx_160908_231024_pgaa3_day06m60_v1.bspeed6:lengthi2150400e4:pathl28:Nominal_Observations_Science17:06_DetailedSurvey21:EquatorialStations_v135:Phase06_DS_Equatorial_Stations_7.bceed6:lengthi2191360e4:pathl28:Nominal_Observations_Science17:06_DetailedSurvey21:EquatorialStations_v135:Phase06_DS_Equatorial_Stations_1.bceed6:lengthi2204672e4:pathl28:Nominal_Observations_Science17:06_DetailedSurvey21:EquatorialStations_v135:Phase06_DS_Equatorial_Stations_2.bceed6:lengthi2204672e4:pathl28:Nominal_Observations_Science15:04_PrelimSurvey10:PolyCam_v123:Phase04_PS_PolyCam_4.bceed6:lengthi2219008e4:pathl28:Nominal_Observations_Science17:06_DetailedSurvey14:PlumeSearch_v128:Phase06_DS_Plume_Search_1.bceed6:lengthi2233344e4:pathl28:Nominal_Observations_Science17:06_DetailedSurvey21:EquatorialStations_v135:Phase06_DS_Equatorial_Stations_6.bceed6:lengthi2313216e4:pathl28:Nominal_Observations_Science17:06_DetailedSurvey21:EquatorialStations_v135:Phase06_DS_Equatorial_Stations_3.bceed6:lengthi2313216e4:pathl28:Nominal_Observations_Science17:06_DetailedSurvey21:EquatorialStations_v135:Phase06_DS_Equatorial_Stations_5.bceed6:lengthi2313216e4:pathl28:Nominal_Observations_Science17:06_DetailedSurvey21:EquatorialStations_v135:Phase06_DS_Equatorial_Stations_4.bceed6:lengthi2313216e4:pathl28:Nominal_Observations_Science17:06_DetailedSurvey14:PlumeSearch_v128:Phase06_DS_Plume_Search_2.bceed6:lengthi2633728e4:pathl10:background3:spk36:orx_160908_231024_pgaa2_day06m60.bspeed6:lengthi2970586e4:pathl28:Nominal_Observations_Science11:07_OrbitalB22:CandidateSampleSite_v215:CSS_Mapping_3.aeed6:lengthi3021223e4:pathl28:Nominal_Observations_Science11:07_OrbitalB22:CandidateSampleSite_v215:CSS_Mapping_1.aeed6:lengthi3030213e4:pathl28:Nominal_Observations_Science11:07_OrbitalB22:CandidateSampleSite_v215:CSS_Mapping_2.aeed6:lengthi4433920e4:pathl28:Nominal_Observations_Science11:03_Approach13:ShapeModel_v126:Phase03_AP_ShapeModel_6.bceed6:lengthi4462592e4:pathl28:Nominal_Observations_Science11:03_Approach13:SpectraMap_v126:Phase03_AP_SpectraMap_1.bceed6:lengthi9973760e4:pathl28:Nominal_Observations_Science11:03_Approach13:ShapeModel_v126:Phase03_AP_ShapeModel_8.bceed6:lengthi9973760e4:pathl28:Nominal_Observations_Science11:03_Approach13:ShapeModel_v136:Phase03_AP_ShapeModel_9_Forced4x4.bceed6:lengthi16790528e4:pathl10:background3:spk9:de421.bspeed6:lengthi19461569e4:pathl28:Nominal_Observations_Science8:08_Recon14:225m_Sortie_v220:Case02_0Latitude.wmveed6:lengthi32365635e4:pathl28:Nominal_Observations_Science8:08_Recon14:225m_Sortie_v224:Case05_20negLatitude.wmveed6:lengthi34165695e4:pathl28:Nominal_Observations_Science8:08_Recon14:225m_Sortie_v224:Case08_40negLatitude.wmveed6:lengthi39341755e4:pathl28:Nominal_Observations_Science8:08_Recon14:225m_Sortie_v224:Case11_60negLatitude.wmveee4:name16:OsirisRexKernels12:piece lengthi262144e6:pieces19620:ïâ¹ÈnŠH¬€âZió„Çžh#ŽVañP·ýº«À°÷€¬à@ˆD.hÿ¾Glåà “±wº†¥¸åÏ펧ã^ù7zÀKúÙïUê°hj1Ä^ÜìÿÝ4k5AàT¥ð½'«³‹3W…W˜Æ:0Eþ¤@YV ÚX€¸êZçñî™d1ébòm’S–Õ©ì+Ùó¨ç„½¥A}¶«éÑÜû˜¬¼ëŽÍࣈ*£³¹…dP0Uµ*"õïnón÷…@U!yÈ2ìüÞÆ®j½î!£°ø.IòÜ…ÑÔÅOPbïK’‰ +i ª)?ÕhОˆ%åúžN7ø”bOæ‰çíù*±ê4ô6Y”hù>¿ £˜³v·¬¢™LMoMr÷Ïb]PT( §l/w,鱡XxÔ3·Òa)çœj­ +ÖÔžG'w-¬Èlõ^t¨ÜN;¹’ê¢CÌ[¶¸GäïÊmÔËþAqÄ^ÃÔµÑXfR yøD72^+‡¨¶ïòÉ×kÔ“¬Då™Nðbpã…œµªݼíÇm˜Ž‹gÔ€;;†=eaVµí˜ŠDjvˆEg®Ò«&Ý÷—èÔ5…~6hÐwÿN›bñBãöHûï;¿`±-Ìg6^“ó3Æ·rx¿Fx”gûÄkkwþÙ©™§©žÿÆÒÇ¢ƒÝCìFºÎ[mÐ[TŽ¡O=_5& Ä“¿ª‹rþ¦P"hÐå¥jLrx ùqúÃvMÓ¢uÂdÐçä›2ÔñêlçCG#‡àp”¢ªö(úú­=ÅWç4ðøqØ}ÐÞþlL øàχÐ5ËmÆS²ÎF`ü7t=€Ù/´™jU¥PO0Ï€Öz:‚4Ñ40 ŠëD×ÖÙ&%ùBÓ  u9NýíAXÝ™¹;΄ƒ3zàr„§„ػʙh¢?®àeÊÄãE’Ô; ]1 Ȱ)«·²åyBhCû¿„dÌ\¦G'ëa:Œ½¹W!Èûœœ¥&&Üzœ­&ÅKÛÈ+ömÄ&£b=Ä)ýj cCÇÂ?þFÚÁrZHÚ9HÞ¼[,‹îfêÍ#À)­?íS¿Öz¨¦:âÇÊæø`É™jš¶¥Ž•A/ü°Ò‡Þ¤ôÿ3ñ—’ƒ‡^ð\ˆßÇWÙâ<ÊžtžŠé5·Aq¯ÜùŒ%#¯¶@:Ü‹o™P–ôèI¢å2Ñ“dÖ8n‡%•¤fO/‘<€-!šæm"îðÆ‹=½Ë1Ðt”È;Ÿç„Ðéä×¶4!Šå8¶]::hE*6i‡×rñÂç~ËcReÁCz:úVs5+“Ây +ƒÒH‚ñÜGÃo¸e¬î„ˆd+cAèôŽÄ°¡ü…JDº/Åß¶€#ò‰‚K§p¨¿åñ2ò Ùï7ÏBOª< ZY1Äõ=ÙÙüc„y^IdW‡v¬£û0¤ ˆ'4VR~ŒøìÈêüìÚ¼yâwºÊ ž±- tX¼d3ž M¸á@…5­˜-°ujë¢ùPS®d ¢GjHµj Ú»}⡋ʳ¦DÃê¹É|ä +ãa_Þ[Fniد$‘ðCÙÿJyI8þN]•p¥.µ÷ÚUãó® ËÎ~6Ñb([(ÞóÂ;½ +£‘“»µséÒÙŠÏóÞ6–ŽÄã‹án°V5NxÃ@¢yiúŽíªBœIŸa"Äÿw±†óã[µÄÕ÷|M¥ðànB@—Ñz}’·ó 9ËZý²ë’èÔ<àæ9¸gÈpÃ] +¥×ÌÚIðõT®’~[`#öv°KÈÈ¢´4 w`.¨@ú?°yí;€E"§­¿œTTc1ÊKIòRTy5nç>ïy‰:Èù(tGÏcF"æ£?CPýàië}ÎmÄIK¤p‹"‡zóÉ‘³ýåÎÂu’cÁ€Õ¨ bLŒIõº@í*Ög«·æþäΘÑÍ䔇,É×D ÀÂ_^úû7Z‰W®‘‚dlFÀÅÏø:yW^°÷›Äj½ÌúÁV'û†[Î bDÿš‰Ô¯ñ<›BîAŒ`™ê0„¤àXâèÊ/ÊòƒE˜™÷,®”I¦“›HûâE’ß~Q‘ tƒÔýÄFÃgÞOõ~»ñð\8é_]mùHK‰KìîØwHðc›ŒVô+oæFh§}uÝÐì‹A4 ÍlÌúéoû¤Ø»6ŠŽU|çE¨Š=Àù;ÜÏØdÚ8éË ˜ÁÀæÃ>ê ¡¸»¨Ú¤ûµÿZ;á.éGGtCÏGâ6íy¨AÅ´4gmGôå9ý*dFz¶ãÀy Gß ž1í -þ`wšT™ÒÐ$txŽ¡UŸ"kò½€(.:$¢ ¥xcMpe›ÜéU°ÐIhfæDÞ…Jcš`!;ÿÖ“¹`©ªÚ¥?Sßa˜<Â`ìßVCx2ÞbÏ7 „_>Óý—ýãy&ÇP,·=&dðu•×ÒêŽz<È’~Œwµ:´,¡A˜ø%OËdú%^G»jÙ’’9rG¢ xØäëÊrmè„Mìs•œšª,!{Tx¹ªÏ,t3Ì =eÙ¤÷À\Œ6DFa~ů,(_ø Ø ëOqWU¡ JÛ™`F€*XkËð “c²“; û]ÊöØx+6qì)ý_¹Ù»¼Éßãk¨“TˆkÜ"½µÔ´þ.5SëÍð™„ËViTý«CIË ºÖ)ãG˜aáZ´u"1äŠïk(à»·™5ÿ„«ÓâÃ-«®¿™ „|^Ýkÿœå#ÙᾺ69œ)Ìgœ¿Ä×á»B$Såq"ö½>繦¢„€»aó #^i"ë —FbbbÕ;º§ÃÎe±5Iy UóQn 2ï¡ %pMå{DZðK™½Eü>àKöˆ¼Y´³£z}ë›Z, Hk ö +¼Ò¼ÌÊÆ¡ $ÎýCó>20^·Åâ}+®/BÑÅ [ˆeB#l”2è\Z¯Ôr­Mü¯@Ñ•_‹.ŽÑK—¾‡I¡#(V àÞ·ÉRæ8ñP-±’‘P/Ä½ê¤Æ1Ý:…–Z'û\Ô×nDÜå¤ÀǯG£nnæôÖq x0‹üðLO–Mëo@þÂþfçq÷tLän}¬³ ˜$…›ðcš,›}vù²ÔØn.mƒÇ2‰79û 'ÝE³Øo%Îê@6*uà9ðm2õ%A& ©tå…úZP‘ $ÝüÒìþËÿGþ»‹âAº¢.=¦ôÇ”¿…-au2„UX&n+Då$«•&d~˜7ÇV1}†ˆ@Ký¦F5ƒ"®ð>x±¦4¦ pIú-Öxœˆ‰DgN\ ¹ó”!DzyEf’¸j¸E3r~ð {)?C#/­!i)!Št¥Ü¼àµtºÿ7-vùˆzqýQ´MP2HeØ(º³’ ñó$›úNÍ`bµeé ðÇ ÷ÝŸËZC +g‹f‰qôrÞ¤‘:¢ÇG¬'V¼¸ûQñdsâãjd~z™Ú¹íÙ[“å°w´`²uÑÿl \áSè\§n?ÌlëÜø’f8œo†ýåò­ozäàj°|žÙ€ýy®&üÛªö-U9U´î‰«»SÃåæZ0h:òƒ«§Ê™æ¼xÌ>§N]M$7Ì´ñ:zR ·ruÛÛúÎÞf±‚Œ1þ‘¸ý[ò(ÖøÃ&œNݽ(².FGŸ{¿=•î¬ákøjä2ÄÃÁþìV»£¡ÿRvéënÔ„D3ÈÙÇ^NézíGm†,ŒÀTcl™°Öo O5(æÂæÐxU¤üs™F¬ꇺ‰™œ[ Ï…^6O¼ +Qõ´†é9Qd LäJö‘MUF™øÊ¼¡ò VQÔìZÅEPvAlPÖ€])q›Œx9‘T°Ž/ìÎÙ˲¿ kŠöeû×ôlÈÅVÞtïÓ ,¿à~·=ãü9áÒöK3×z*M&Øê·;KžkoÞz4Ç“WEºyÐoq°u»KΘtwLí!LÍ» å_Ôì+1s¶¢“„Ì•kGõ{áåpöåÍlYgªè—.k$ótá\çèFazëÄŠƒnäü}%j|ØYÞð*ïk{ Úc¶RlaÆ3sZaÖ­yÁ©wj,¼ÖýWÝ ¼5]oŽ®”kFrAd*6°Ü@/P,Û×M*$¥?¤ô¿³¿Þo §2ª§Ö@À9V“Õç¥OÛgËöÎÍ7T|1[u‘÷ë½4Þõw#/VWkÕ3,ùŽçÏÛl“I7D/‡¹ÒÖ‘vs- sp¢ÆÐZdY9·©ƒ {y°t¤jî­û?õª_( +HùÍÄH1‚Õ=Pâÿú<;w˜æ™Kµ‚Ït–ý>Ž:г™ì +'%¤c™–ÿ?kÕŒ[ûÄVŽÌš%;}l'¸ÑãK\ÉÑJ¶%  ØÀÆÎ«ºü$%Êy”dÓ»ŽWD–Ê9Ž@…Ï4&ö6DŽÐU¢w®|÷=Ö!ha¶¶žÁQÐlE–B—Lð _³m/„Ÿñ²è!U:j½NYç‡6ÜJ¿|R:þ¥î$Ó¡6«c×>yô¯\°ß¦De± %—¾|’¿m¢í+ `Æo3†GEÃთ\d#\¼$ÔG”X·DÄ/w‰DY•) €hš7Æ» HÂE8¢ý9i}–ÃÖÏM¤¢¨¬!ãÜ w\øUWFÐ0]ÿf»Éñ[[M¥#"WÎ7ٟŰFy¹ˆU¨¥—›²¿ÒÚ¹=¹Š¹È¾ÕéúóRkûE>„ª›f¯ diåæ’ä‚ãÑþ^}ó™¿KôúUeðVp_õà&•:¤sKK+šó4´ÝöeE‚§Ø6¶ŒàØfÔèuàÔ4ò B]Õ7ú&òRo1!oX]¥O=7°abE-ȃÞþïë[3 +NÈ$Òòºø±iÈÿ}‰¶þy…ERÕØ)œYíÖHl«vù=éµNU/c.Á»| û¦“™˜/wbÅMø±Œ þ'žúØ¡þ‹xådÙØ\²èü¾¨©CiNЃջ²êv§:0&Ž…M õznü®":¨ô¯XqZp$0â D€ÿqtÂÞ¨kY\¹ê½ó:$éí0øªÞѨ–õ£ÜØü²$ì­•-à›7do›ïƒcçb":2jꪖѧ¤Òi;½0.:+U>ŽHAù»Ô°[bêI6OSÍ^Ÿõ«pÑ©ù¡,Aˆ[…|Ýq‹ÿÐæ$9è÷ºeÔi0÷’g»_«eo‚»´côÆé èUjæXf¤%ÆP‚ I*„4+Æ·]Âá£BŽÍ­næ”ææ?X‘˜3ð=…‘ŽLê9B Ò6²4ú@A ¸~¯¨ñƒüYÞl!$Ôªu”$œíò2‡˜ LÃ^÷öõOþiô&k¢) Í¼G§sm·xë×¢-›Jd6q‘@D €î Sq +¨G±ùJÏÅæxì1fwQ;îYâ—öhË­‚?ôeë"Ý÷¤¬vѾ=Ž€šÀ+fðñª“c§5Nñˆ®ã¢®¢Ð-žœ;Ê€¬\ãþ²×"ˆIhÁÜã0û9*;„)FËRú¿j©IeQ›ž¢˜óLÝŒ” ¤gô¸D2kÜzÒmPEŽz¢ÔJSA‡>³þ`äì«,»sSö²ŽtÖ^ó²Ï i,/ägyîïdžýzêïXÜŠ†SQ*P²ÜÑDž2ýu-(3J9qžd«©ÝPéå}iO}ÐþRB‹‡‘^nÕ Âý¬È-̈âdf÷Š$õ½mkŽ+úë7’-ßcí7Aì‚ã²+Þ"Ìë%¾Ê0ÆhÒ„f˜µ|L2u¯jt€ðvîá*e—f…7¿p•R¿âG/y`»®_§5JkøãmÒ(×úïq¬W ÂÓó~›)B„ªöº4Îø‚™qfCéTâdëÆCdÒ‡oÍþâ· ‡ n£HÉ-9Ù¯[‹bÆçÚÙo¥üyWìSÓÑŸˆ¦ÍK2g’ã¸îMkÔ€ +½Õå7SŠWÝ­KZyoü2;X kšÙˆ|?«Å¹`\s¸m*Q+Bϯ‘ âûòø'ú(õ]È£Ulôí’œ +c´ö[”²[’®a.õ˜J¹Ñ׃n@œ{j_¤|9–$éÄ{ks½*áyc[»2>tÁTý8àí ÙÉlRÙüä»FFÈѤéÖ,0žš`[s̳0»L’ý0g«O{“hø¨Lƒß ïSéŒØüŠš(-\v…MÇI‡¯äíAN«eÅL¬ÕD¡HLëà$kŒƒg™D×Hêß’´ èâÓ¤KŽ=ßòO{Û'>¯q¶BáïÑŠªé ¨Òå¬ê_IÔ&Se‰'5kV…XïE¿?á +Æf;ïÍJvœ©ÉÃZé ¡Bˆ¸Ûy¡*ÃëÏ:³Ì6O_G˜êÇßL.›Zͽ‹üé…¦Ã*œñ¨«Ê!€"xîåÕl.ô¤ò™ö¤!Kv<9ÇG¼/4A¯?&»9㘥¬œ|S´³FáoMrc ªt9=Ëc]¼#T‰Úåϼ&›†øûûç±*NS¨D¦»qÝûrÚ:„'¬çíœ/Ãp.0øðŒ#Î7°¾bš²âd%Oz·ª&J½ÅûÒ‘¹7Zåh}í¡S†¬bÐ\8æn–+á Ÿ|öxŠ$lýàÙUˆU¶õöp<_Þi¹õ*t^ãz‹¢éU™<…PœîÕ좷©pèOh"ð¬T‘<÷ºgœ¯hl\1k1»<°¼n|ÓU©»$ßÏèjwQ 2w(úV]3±ê  + þ Aæû|¤»âÂÊLð‡O*T3:€tt2ƒ+1-IGqZaiý¾&V7‘ÇÌ!9Í©QÊûò@8*³¾ÈêÂñâÿøöÇg#–*-ñ¼È#޶Ø3+ZëtîoÀc± 0¦Þ §¨{ò”(Æ“f±¼¶ï¶éæâ‰â)Õt«Ðƒ®ˆÑžö&v¹•êøõz(v²mû³éŸèòÉÃ>CÀk©íŠlOÎuß“¼‹ãŠšOFðXøä€,í¢Þ,þXc$P„Ž}vú}Ïž(|x[«(QLXmZ-Ъ‹[ñÜeŠå¤«×çn¨°.¸ÛžyžwöAÈ•âr¼5æÞT¹A­?½—Ô¡d-ƒóéóôF¦sjZ'½ŠêV¸!5αýôƒR>òÞ¿ñ»ÓЦ”°ù0䃰 ’HØð¬ÃìSk çÕ‹f˜((j³»`®‡V<ûè°³­ý+™#3‹Þ(KFa.gM‚D­«3ª{NŸý‰¢½‘/ u`‚Ûpo ¥("ds&ÈPvtµEmÊCÕ“ò¦Úep3YaÚ¦K½I;A%’_í„1 œwIr÷LðGedYÚÈBI> œxÉ$wwzŽe¯X雽b}/7E+ZÉTw +Ǻê"‹d(ø€ÀâW‡æ¤ã¾ˆ˜£Û˳®$Äåé¼HR—…VãƒÃ<ãoêÃe0w¦TLM±Cw¤6UÅé&ßn ãkÖË6¶C²=‰7ÝdøÇY,Ú_Ñö… TÅ+m"šåKÍ+fk<¥˜HûÁ)Á¦jjpži +t«ëÃÊž¨ã® ¿Žª²Zº8bÅ26ͪpÊ*»?_O(äêcq±Q/“\ B Îïâpàø‹,.ЗǗMèeÛ©ï•Åe™ *üîÀ«IïïL[õ>¸³#3»«É‹•Gje±P7å§QKлˆ.U$™àÀÂJ€³Ë9­¼’\[Ænù0ÿ…½ÜKìÁÅb\?ìÿÿ.m`t_­˜¿…¡CÝã&”Yiº˜%×Ú‡iØ·ú5γC‡©1+Vu¨ì„*ã'H6÷çŽèØ9ŸãÿMXs§cœÙ}nÐ@v=tÐÏ¡„1%µ'HÔa¸Ü1,É["Æ-ß|ü™ä¡O²?âFlóºoÍ(Þ«<wˆÅÀ‹3N$G†¬fùî˜åˆ™Á‹mUïõé{ÄÛb‘ZcÝØÄÿ®¦5í±<:ôv– ‘ÐЩˆ'âë^Öb˜Hœ>c> 7³c5Ñe%uÔ-Û‹d”t§Î‹“›¢öo7ÔÛ`À˜è쮣¹u†-ŸëÝFÎéÄ»ý·‰´Dè…ãÏæ’¹¦wŸÊj "+fjò^Á'ÜÙM‘­./â/š´4`;¹w|Z,ÌКŽßÀš Ï> M<Á:ëÃý|ó´bê©b°j®GNì]±³TXüÛÞóæÐ½ÙI»†Š tù$ÿuaŒN‚l¬èH;­_´õW…d\Ôùv8CÏþ'U‡>£B¡ýH›Ózhê"¤Ÿ££¶PɲðªV£B\8¨¿úe¦‰ÝŒÙñ sY-ȨubÍ‹LGÊéðf¤âµ—R+z;P AZð¨¾l³n¬Ïp‡aÓŠ¾ßK3]ü*I‚ÀÄLì…½®¶Éëo*…r½Á°›Ú%ä + ç é‰Â-ëWƬæ’e€Ž±«¡&pžs{Ük9ÔƒSõ%R4ÛŽCv€W’@“;9ª˜JXñÕü8Åj³——Ê+lüiu˜¥;”Ì9õiÙg)ïÚrÅâvµ“ôPlõYà•˜ÎuŸ÷W\Ž*ŠŽµd>¸ÓV&oê./wõƒ‰¦XÅVA»AÆ$/ŸB÷ëìí ëAÃZ5#±``P÷GW{5ŠÙÁãjgh˜‚Eå¤SW—EÌ•é1K2ú&õQ¥%Ш4$q‹?'öý³5ã¤-‰ƒ àü´ÔÿIþ×àŸµîŒþ³r‚A¢6€âQÉ¥'Å…bS†™’¶ç1_¡:cŒ¸KõéÈLE~ÖêwÔA`5+2X´l¤âì¾cÞEØÔ®ìNõ#Øx5sEJ*/ÍzÖ‡F‰ysro¸knê5SØj/x?ÈÏ5ÅÐ;Iž-»u÷h yò&£¯Ç8x³úB+9u#~)Oý(çUÿ¯ôI|ؼö¸.âu Hõ™°ì·øqB»¬ŽEx=‚ì']lÌÊ:túI¨€÷nâñ¤}ÍÔÞgŽ A—å ÕÚË»Uö˱ +úô7Àjœeh‘¦Ê¿±)¥¤ÁÓ02üùÍê>)´ÛùÔÍr³ RËýQ)X3µ4Ú,ç…-Ù +mÆ—é}S0.š ò‚ì¹ëç,¢:âà+:2¡!œœßûôéõí5d/p Ýú Äz«â–Gˆ<^$Ù0šTú“yBUŒ?JÇG¸r_NžÝÌq˜4ëF«A))èØ·¸ó‡ìVÇ,$A„ŦeÉB0ìÅž¨û‘Ç}]›ŸÔŠºá¡áe*ÇÓûG¦Ú’ÑÞ ÖçªæN×BÍZpʆ1w+§ò0ïÒAß?žY†OÜÝ–è³>qÅ»™€Þˆ eªóÚ +CÜ^´ˆ– +Ös†lÖ”¯4MæÙô‰ÙÉ?¨`ßË+Tú:ÜE÷§*Öí^¶×‚Þék PRñxŸwÐ`“?ÚcxqοúÈL µ/Âwý±\«ªÑÞÊ­F·3ÒõÜ1ïÁŠ27±óa^òž<ŸÉ¤†Üdúl²ëkï 86—FO|óÊëͤ¶­YÝý³Ó=匷M¨àÜîqSw‚ZWº‘r±t +ǤI0ICR××õ;·]9@g7l¤ešb^βɞ`ÀJ£35Ãþi…«Cnì LÝòÍ$0¯<Ž&Äõ7t¨ØÃ~cÕë¡Ò²’}h[Üs·p¾§Ÿb ²Š× UªÛˆØ»Ã­ŽöÔA<Î(œZX+Ñ?£áþ“¦Ô$›ósx<ê„W³¸êJbNd{…É* ÍN«?ûèdÞÝ6Ä®’@ hUL«4µÑq+^ø‚Dļ´Ý Â<,3ßxÐe2[jº}d³5'pHÅmEÞ­Ì,§¥Ï[ƒâо_àŸµB˜ìîp$nnùP¤ãPä´¨šR‰ vÂ0êbOlšiÞ¼ÌrïŒÊ¿|wüeãAJÔHõiU~$ƒg)¼v— ¿F…Ïú*l@i ðYŸE˜ìf ,ý´±ˆØí°Y—\AÁ337Áþà#x³jü¥žÚ+•\:ˆ×ATÒ&vM†‘ö`ö­·'ûk²Ìedz‰?áq £†' ! ¯t6CR õI8d;ɺ€]7MI ǧ„òÖÖ¦D³prnçÈB¡ô“ÆÑv€–6Lr(þ¾RE•mMa“©†¯r¾Ä +)³`!IøA%1t$TwvÒñ-½x‘MÉýƒKþ%5cJäKe¾Û‚]AáU¼Êöþô¶Ó)ÌÓ„->SQô84ïTôU?%!ûE ¡Ucw\Þ0´.“yÑ?u#Mà×}íoƒŒ<-ºÇûÙŒ[¼ªEâ®íØ"‡ÆíÓíž»uN»–‹hï%¾A”d†BfØ€ÅÂ^å}?z¢‡â2Š9^—Ú•RÿþxLZi¯§ønÒùRäCZo¢ì2J$n õe%±.eK#I°ÛóuësÏò|Ió:Ùm,XÂazM€\Ï ¬¦lBÙMôVÆ2M¶EV$<ïgò¨E…-¾Ô +d vG‹jþœöØýo…ÝÈCSþD÷Ð[°-êÕ,Ö{ZÊÏ¢Ú1jèú@û~l´'PC7‘I¤;—Ï žâ‰*ľ¦üùJV;\C,Ò\·Ú*âöq\ÒmÛ:i×¢® ³!Ù—b>Ø_ÓŠJ…Kgsiiä—âj8voŠ ÔC¢>Ó%x¦6ÌkRêÞ }±’-¥žÙhÏ–ÆDAm\ê@ó18I(úZ‹Î¡táÈáVl¿0Ù'š÷A3puˆîÍJŠž7æ !®V·#ïW?Ôkk¦Ã¶`hMŸvÃpíY¾ögXœJS!H^F Ï‘‚\Þè.GR#¯·5‰Ÿ¡J·‘jéhm œýa~Ów D¶[AyB‡lÜôö¢sè­©,ßz xÐÞÄ&t®ærícm\Ú·ÄšÉ%Ÿm°nS·éËÌ3rÈà9 fÎ,úÐËt§Y’ÖdñƾrÝ5YË5ÎO_Z„õ®k!"N°cÈgF…yXÕ”)RHîŽ?æXR'MPÊÝ4J vfÁwé]^ZOÝv& ˆÇ´~®Ü)>w§'ǸÐü5–È¿x‰Q+ Û©íÖ~ÿ¤f#¬b(ßàmNäÑr*Ø®&ü>MÅ–ßHO.‰j§YS­ÿv˹hŽDHx¬5c©ÈX´4Ž< ½˜R1ƒÍÑ7 ¦9K2èÏ´î¬-˜öŸžDÆþ#®*¼]¾OµI&øzU}±:Ñ窜'˃ˆ×OèFwüAgGŽ}K`¹È\ÃL¶ËüÇÏ¡gzõsØÒúé¥`@Ȫë‚ +ÝF¡9B§ŸÞe|ë-£:zéh} ˜ö«W»J“–÷ÕñbìÃ_$±Õ,´+Ž`•ööÖ些¹¦Ñ|ƒÝÊçˆm±Òð”J•†é1Ón2Ëߺ­>]DŒ=¥PÆÛ¿Ô¦Yílnµ¸Â{xŒ”#«›ÞZ¾× ÒG¢9(íGë ûäÿÓÅ|ø6ƒs—_w‡p¥eo¹c +ä¯!8~&ô/*…~… ÜÆÝç¡©½{€DœZjc÷lu§ëäÖu‘”…PS—ã±Êú=ü–彯âÎ|¾³ _ 9V‰¦šD ‡@ylDA"§ƒn¾ NôM#^9\zt"{”Bù”G•%70ŒÔ8 óA†|Ãö‘„ÓªrÇ3S°DG6Ïsîx’’BŸ3y‡ßöNÑŒxEŸ0·IÅ1ëf'”x-jLzæzô¬ÏÍßõÇH´Öðë~nÄÔvy­Å ô{FŠ´Óë5÷(ù”·»Ä€¢5"U |·pDK dÍ2Ò…ó¿ÿGÚtÈæ’ñ'D÷«%bÌe”(ôp×lXЪ¸%ÇÇÀÀY²5Æu;î]ªÀ4äßÐÀAÊj$,Rã +x<±Ï™ª·Š!NÆó…Ï¿`!ó:;(¨tñB$tıŸ^󆯣£‘ˆùtŸ 4´ÿØV-uQá|Ãk¢'_÷ÚÚ¼ná3[)FPçÀ­¦mMvò3uK›éb0nâÀš€¬×n –|›z¿L"÷œF9e +/˜iœ'}¤þ• a›ø6·¹"»jHßÏ)ƾ/Tr®ôÞ¼³xšÀd÷x«×AÂM«ôPWöpmIJÄc° ÊŸ¸‡CK§4ø/Ö½¢‚_{UHpæj§3€O\¸Â +·¶þTÀõPr§wU*Ý+â&¼gù.€²Í›Ï4yeh*³úeJÁ¢c 5¾11A‡÷û‚·z{µ³ÆçëUF·‘y ˆŽýÅ®Ÿë<Æñä §ˆC]³ ¼¤ØU—ˆksOijŽVæÒpÙ¸y‹ÅÕ@ÙƒÓ1˜íM&Ö¦Îÿ¶Ô(;ݘò«èÞ•©›Ð1Žñ>‘kIsMª=‰dÆ?¢Êe‚m2]Q©Î;ƒ·ÄæŒÇC‰uv‹q»LŒ=É`ÍEàÕS£%¹‰ ›¨a!Ÿ¡mQ°¦¥µŸ<ݯÃ\™ê5‹ù3 V…õ(9êzû@x#ÖϬJáa\±d*‚tžyg¸X8,TÔ¡¡ëÍFõQ6îÚ¢—“£ºøµCØÍ8«?ÿëÔUgJëÛ&ÞÎ.£˜GĨ\¾sT´òAfÓ„æÑëvQ[²Ž2(2؉¤˜KB æÊ–¶¼ÏS'+òV˜pË¢QOÖBþ8ž“Ë”Õ"2ˆß3Zg)t!•ø­jÓ8„<\mLk>Ð~VEŸµ¼rìÃýÉõýj-‡U®A{oßüÛ:ω'œ—}{OT¸ äпõFbµÉ¡gqçÉ|üþÏyo^UŸ\‘Ž|ýÝœ›?iüÔ;›Õ[:%Ì‘uÙç6˜íË8ùËñc)à›ó( ++毕ç÷…JÕêαŸ'–ðLv’|—íw' “ù:Vˆ¶læ­v®^2qz'b8ôÛuäÖ¢îs: Õ›ùp¯nǺÂL™~·såp¯ §€ÂøªÛ&Ýbó3P„o”=õ•ã¢ã~ªÕa»}D£ãW§ýÁôì¿ï¹ÝþcÑ·Qxñ“+£N‚¿{r¬u=ºµªP0ÝyéÓeÜj}º®bnOWio„ò¹5× | bŠŒ¯±¸Ãüç8ZK˜ª©:v»õ3BD(x]nMÛïkºL UW;=Öã¨V¸‰ +¿DÇ“¤á× 0AóÝ"€Œ!•·…÷Ðc“>¶§r¯‡öð–ä÷ÆUç©üVbÙLïTigP´óMV—×mÀV.·6´uÈÌ‘„>U ø±¨¬½ÿN 9Î{®+¼:y¾°tÔ %'h¾ê¨)¢±V¸ÁÈÖp&K’–Ãa+äS†PoË¥änDßGö>Ç'6Æi + vBL>îú\ìÛj!§–©º²»ú&qh»ì`>žÇB!É¢ÿB>¦A¶]Ýž<¸{fÿ=€A—Ì‹øå¥I4%s…‡ +,TBœ«(ZO5§Å6>h Sp†6瞈èL a‹^Á0]AÀ•qÂÄ׌¢€ýw/Cý1Ü5|ÇgÕù†¼û¥‡ Å=õÐÓ{ÍdŸ7[‰—IJ±VÕb  %êÙŒÕ߸+ƒú„šcñÍIr¸Ö–ê_{ô F‘ŸQþx8¦ú1Iëz<§´fœáßšL¢-À(ôdåÁmÖ°°̳†àø +‰%ê­)Á‡… íä±]Oö-8»+W([ ¸ŒÝêç·k“Õ:¢,Ê‹õ·Gmï,#„goô“ØZc»c ‰û£—L> —àÉqc©# Q1àHB…ñ‚ŸXÕç;ûÀ˜ð_¦¦Ê½áO›ü¡-Yþˆž`ºG¢'m¸Šsrq7‘ÚAˆÃé±ü\óEÊ0›ß»_`ÁóAöf’³¹íà²Wh"Œ:°8äC=»2²2´@ÌR ƒÆ«\úì”R}\tz¾W;›öÉ+¢O[;Õ¥Ÿ—“ +MÏQa@µùŠA<ꪕ4¢< ÄþE«PéØ×é_}¨ˆCàs|_Ó;œ¾æË±{›€PgÐ4ŽgÕåbœq­zVÕ"Æ%ø©Hí‹­½ö'êýHƈsvû2{e›µâAÄÂ~J@©A=æ”M±™Úi\òލrìžfõö‘ÿ5›9þKÚÏÑvÇ˧RúAùn©#­G˜üÃ?vj¼Áˆ=9hD¢ô*H¬j@í)ªßdÖîC(™„᛿Ÿ†:ÍüÏ +-½Š—UµO<Àë327ʆ®Šî‡…ìÆÁÂÚ)%Äí¸õ“?ŠàV•òG>xdߎë7c,ÇÝ»W(°–ÊÌЗzJ9íá˜ÕnC u4n¯&@¤˜-‚í¾X †Dóà *Qk™…7ÿ’^ÞsC¬œ¬+0AñG]-ñUCÿ þ ×½özs šMzGg×vÊP¾ª4+hb2¢¼Ø©Ì{}{[µÌq­á>¬”gtªveÿ€æ–ofiëâ¹Ö">® p—Œlõø22Tí S)‡Oì#p·»Žk_«½÷±Ê’zܾ!S·_åvw+‰n Iż6›Ÿ^ÿÐgú€Ã¡?ÿ„›_ŽÓ½x.mx±ÛeË7=Â6jÕ X'P-įj ¢Ó^úquTÒ¬2ÖHá ÑΗ( …™ó h?¶È{ÂHdé`¸3Yƒñ'53ÃgfŽ! XÕ äc™6“Ø3Ü¿# +?Šñ†zpÚ¿ºêãèiä,°7®™ô8ß:mØ>½.‰#^†ó_Ÿñ½‡‰à ŒK¹éû;_í+!ÞZµ÷1ºt?Y°-ÊŠÏ´“HÍ&Ÿ]¹F=p¤3;ÈCvDŒÏfg4ÇÃ{ŠJÔ}˜ºZ“.ËÇV*1ÎÈ ¤mU}|ÛT¿£øç>„ÒîÂ}Žjg“í—ÍjZ ¹ÄBôiy±±GvÄ9ͪ¼oÏ-(/ýñT¦(4iêáÑäHϬWm©ôdUíY^ÈðµkÒ¢nS«³•ˇ­áÈÎ M»åŸî?:æNGÕÈ8¥Ôvhïí3bÎǤ€ódŒòÅBò´àÚ†ôÐ8f¬«±Ý¾—È£Z×›MKUzyU['Ãñrý«K~qMnëö àªçÿéဧúL©K|gÛc ÉKg]AX,»ÍƒÑkÎÎ.n µÏôžiBzD~Ì•µéªüX\º?·Ìüð’Õ~pq‘“Bðਗ਼§hT5§í"uDÁ§¡+Šáýíî‘ÞE£Îx×ÿ"±õßïq­&¼tÖ€%Âü¨„ª e9&—±³ŸŽ6‘X>˟“Ö/”‚`ê·Nbæò©IÜý=è–Sqÿ88B“ö¦€?®“ÄgC—û™¸Žˆž1UI’Çv:µ +F\ðGåÅ4+ Ѽ “KÙ‡¼çŽbÜ•f]ÅäÐÊ…0)@TûCä%#Ó pëA«9Hl¡60k¹ÀàÙ°\8rÑÌ0-/a€´eFùð6ד!/&BÛƒ~¶ÏïW߆^7F;fK•ƒµGu×AqcÚÅÁއÀg.ÆÖ±–P`z´ jË7Çe:¦aÐÏŸ6`ÄZÐ6/iád÷KÈÅ%ä{·5ªñÓ¥wY.1¯B´œŒA“oŽ(@2шœXÀÌŸ þt<4kNuÍaÔ\âð'cË©T‡më/»hF¨-ZEã¤H|lʯ'Ïñ’‘>M‡|²t¢ôáˆUùŒôøUä6†¬2ƒ½8ˆbÄŽzòfhÜQò +È î¬N€QdÝ‚Ãa%•óWå82£±øóÜ2Ÿ€±z<ê ~*p™ÓTtܸ°` yQý—óH€ÑýÇe-µ¸€Œm›b)rù´tîóB'N)º?8¶8âÀg½Ý\=Pu+㽔݋£L ±Sþ½F£Þwþ³s5T+êQÕ~N(§6fkÏ˦œˆê¦Ë0ÿòŸã|²®q2ÌŽ„;Bm\¬¹÷Tb™u€¶>\©›ìúݤ¹‰jÔl~®–w”Kã“d•b]ø: n8†H&€è ÇSª<È•Ëì›®ö}Ü"m³VÐÍIQEeSÑ1‘·ôrƼXh¿Ñ[„®(»§µÙzâL!÷²“)…c9PeÑQ,¡W9!1ì;_9V2a4ÕTö#(W'ܶTmnß”2Dsth†)‹ë +°Nˆ€‰HIá«Ô’ät­÷J(@ä…†»¾eÓÞ‘U°9¶¦k+Ó‡îýN›£ýþe‰80·«N›o§<Ôâú¢àõO×0×4P³’£ß29Ô΄ +ñé:6ZÕO ?]y4BÅG3¹ÕS5À ¨ÄA» Œ9|fáa’§Ùox69Öym}ª3\6Es2!¯umÖ8•÷­LlÒ§Œ³Žï©SÃRòµGiÄ>ÇŽ=Øv‚rÇ!1å-0z™&úKêÉã垤’%¥3h¡jþñÀ°‚G(“EJ8Dä.J:Ûú‚˜6"a÷×îóÁÌ\¢6÷Ú¶íOÇÃè¾¶¨¤§Ã| àÙçF](>µªO‘óüµûbÜÏìZ† GDˆ,³^×0ÀNHIë»C äèQûZäCOT°¢ì'©Ú¾,L߸1q¹OƒÌòÚÒÊp˜q¢_„/õ4øîÇ'ä‹ÃÕúRß o!-×&9´Ò{¨¿Þ½íw–ÄÅ©àNëŠp®Nˆ'‹ÆnÉ 'çWƒÇñ‰x\c‚ö.ÕÃ:…~«1¹6­]V'„ª-ñbjoönT·+'ÀÁúùhX9²`JˆåO9Š\[À9[[^}Ÿɦ„´²¾ŸZ šh|EC$ l› ɘ%נﮆÒýwÕæ ‡½lsH!™·%u`ÌzŠ4=¡§;0½ÎýŒß=G“ê¥ÉøØ²:²Ø²§Å˜Žêw¶m‡T¶©E;ÿÑï£o6•Êk2"½ –eò‘[´±Euô Á,› ú"uOÖË¢ó>-«b +&”—0ÜPÈ2šÚ’ç|µMÖ“u•Qé*qkÃõO»Sp¶7PåQÿŠXzH´yÅ£-ò ¨ôê`…ôA­‹:ŠÖ˜\‡õ³p9B˜åâÞ‰WÄðᩘM•ˆ&ë%fªÍ„’ h¾Ý‹÷ƒ¡ùÂû40(ähMa ŽrÓ3=×:d%\6@¶´M(6ƺÔíŸEÜ5…ŽÇpT'C¯<ß6³ÈÃy{RáƒHâû.a§å…Þžwþ‚v÷¸áÅîYÚT‰\æ38ó{Ä=‚› ¤®ªJtu,8¶ý¤ Ž ›(òŒ¥xã…¡t³˜N<¥Ej26þº½p³@ô¨B$"3<2A_·ÅÉ‚c®{á‰r¦!þbkÔtÔ|L?'Dz0“àëe¥Å1©ÔyðÓÒU(!=7$ÂŒÃýæu7QÀùÁ y‘R?¾™æu+~ø#xð[@”5Ån#ú¶­&3*ûy·P¯‹ “’3SÔøbÞ^‰Jñ’*P,}–eñxçÂX·|dC^MA@À`4"©­hçø£xMH ^ & .ÃÅQÄ‹Äþs®ÌR N‹uÌæe>+fø†W“ŽÈdYl ‚î©ðÇ÷ø…ëh…±_;25ðäÎßÖ­·”¬}•4F"Ô? Í½èAp‚µèµbUYk~\óÔ0z1àÇO:pp‰N/ìrîù›‡ƒÔoJ36PŒ`å Q#óà_Þ{%nv‡ºC6ͬ•NVíqœÖ2¥í«qçíxÑþ>LÒ‘>I6œu±m•<-…VâªDDu%~uüðŽQ³·±CÖ @ãÏul¾Ž 7ˆåòö +Öy ]f…Y]~uW.¾KìBLúù£ý:jÒWØZ¹ñ‡ïð“¸gt(öF{^¨vQ™L ÒF„ù(' 1Z‰†Ú 'nY•S*3KÌ’{É_$+˜5HTjð í4»X̵ô¾Ä}ŠZ>–œ°¸–D]T)k t8¤ç²œéRÒùŒ,ª|§T·Äf;Æ*¸¹<¥l›Z[‡.ɪ+¤?§Nê2rj6¿1gØZÄêGýomeCïŽaIœ¼í¯¿ðƒC[€ÊÈf<0ЦήÍý=C³bu¿±$ç/j]u^`ðt›cXîϹuq5HÍ/¡Y3iGÅ%°Þ´.¢ÃÛ=ÁÞ#œZ‰K@joZ!`¾¼ß‰KmN×t6ÔÓ=SöRì5ü»Ó‘|Ï7tˆÅËì%¦LE^›°[k¥—X`Ü·k…fxèùpˆ~?OìÅdXåhcÅ3ú$ä¿Whè|.{ÔýÖ~¤#ãbå $ +žÒ0Œ¨Øª OÔ¾½%r×úª‘¶´<¨É‰Òßïû‰(U-ÜûŽ +ŸàÌ; Ê”Q7ç»ˆÅ Ýø¿ŒfÏÍ‹­ëæM kLd²Y/VyRZ'h˜Ü©öÌ‘ºã4Pv×ì*Æ¿Ãì$´µJSÕßÛ×&96œíÆö{ßõÖjâ vp¥ÂØ“[ýªÁ¬sï"Q9›¥Së—³úäÊŒ†=óü ÿÜ@¨›BÉŸ&i}|¦¬ù…¯àìãGÁA °ó´ÁpÞøx­ò/©´we³ÔZ˜€ŒP%>Q)õ6ûûŠR¬M&ith xx_]P{M¢Õ7W¨¯åªÃDñgl2(§ðÈÃå,T¡Ò®m¥ªm gîŽå†ÇA˜D<~ޝ»ý%ê2‡µŸ›9ß_&«ˆ”]þî¤ú\Ÿœ—b¨{•E|• Æ?Eqn [Úÿ¤Úøêœ€yÔErÕ\´ÄIí )ƒ£×Â"[¸]ê_L÷µÉ!zŒù1m:ŽöL£dPÔ(Ðè»ü^çz,x/týÊì×p×î~›“/ÊË5ÿy†ÒgÌùÀø6ÛYXVÃ`P´§nêâο7?±z÷OççŒØéTþê•ÏùåÄã¹Ár€¬['ú“þ\ŸK¤ib¾A>TëJ(x"+ƒEɯ$×ÔvmAbESú¡ëU†î)xhù6p´6|ÚTEQ;öã3T<2Ò—å8g¹$]…š"Ï{a5]!]øž<š¯¾Aˆ%^èà”KÔêݬ7àù91¥òµîœÃ€Âg‡ËÉÈé0Ë–€˜FJ%ðŽ3V•ͬžÉBo4Ë‚Æð’Õc Pë$=bRtMr7–X0‚ð‚e&–B{V#ȬØá=¹9Òñà\M·îÑàd )ye'L‚W`–>tÿ¯¸ÀŒÞ©Ö³úÕ÷~%ôíá«8Í) 6 +¥ºÞÌP1T½…36ÕY®âÙØ^Ìæ‡:Ú ÙBÒ{ èˆL0 ì~ãûoÐ/DŠï|öm$ÿü?ˆ«gëžÉœÝ¬”Ì,!0a° +š¥±|ï¿ú;í$àþMö(²ìQ!êw[î¼áâîñ„Tk½ŠöMéÞ1ukUžÀx¢ÐÌGßÜ3a4-V—õýѼ¡WTõ p(–Úwd1sMâ§ù6™gà²µÆ + £H\bÑv»TTcš¸Ü“—ªàˆê 3Ee|Å¢ÊÃ{ßÅín †ü‰°¢œÔ­ÒuíÇÿ>ãg3³ÿ%-:?êU.+'ÂÞ ¼×Hé©Ä¾ÉàÙн¿lìûÖ5Kå»{b¡ü2e]€ï„ëÿÞiJ^V£·![VÔ«ÆÅ½;–”Ú}juë®vB†W\2wÒ›²Å} FŽLíp~‰]T~éY,†ÑßFøˆ¿DÁì}¦$Σáýîõ¬]š")Û˜ñ›S' J¤Ó àh°«.‹j³šò`%îT6jÑx¿1OéÑëå¹aJZÈ¢g:x?éEóimD9]‘ΤtžJzÚáœó:³¿@Þª™7ÅÒŸ0¡¢_ÊE¿3MJe‚Ãh·´\InE_š‡ ýøèZîLßwˆR^|ùöÓ8ºÎCÝt¬±À•oÆBï'©//C¥üº¡4¯;ÓÆ6(å9ÅÐ,ÀøúOë"n¤m†ëTäã†Õ™Yª„=#¡\WR6ÍÌÍ#sw`üK6ásÙn Ö0ú$WòôÌœ<“Oö¶øÆáúÃëNUYɉþúÜA}¦Vóêh¹>và3—Ô¢^!ÜG“xŒ‘¨à‡M¦)¶’ÚëÌÚáŹQqÚÉ‹;8&›j9@ï +Rp…~?nŸW$²-þªlqèèÎ Á§‰ÉPiõ+ÅÕŸ;šÖ:}Ù;K?/@Un»',Ba¿tmK á B[¨Öw=\ 0)ÖxD}ñ²'‘¿‰™°ƒâ¦ü§Ç»ÓWmt{DXv1–Ãõ“!%]±‡cÈh[¶á°Õ4@«Ó(ÝJU¡^.œËÀÎ)"|£Šž[¦ØH¥MÞò¬¯Í"4œf"nú7‰ /êÊim«sów°×KÒÿš( )a8Š£3ëÁ?.΀꒡‚7>” 'öæy$v¬NŠX7•ö™®'}é±Êã$Ê¿ŸÐ㦃îÆC€s{a¬±rIØx,à=a˜L:^¢)ä Å×jQN`Rφ' Õ‹G¿g\ò]ß'1I:b\ÆßÉ6ㆪ%{"'e7:website27:http://openspaceproject.come \ No newline at end of file diff --git a/data/scene/osirisrex/osirisrex/osirisrex.data b/data/scene/osirisrex/osirisrex/osirisrex.data new file mode 100644 index 0000000000..f6037ff2d0 --- /dev/null +++ b/data/scene/osirisrex/osirisrex/osirisrex.data @@ -0,0 +1,9 @@ +return { + FileRequest = { + { Identifier = "osirisrex_models", Destination = "models", Version = 1 }, + { Identifier = "osirisrex_textures", Destination = "textures", Version = 1 } + }, + TorrentFiles = { + { File = "OsirisRexKernels.torrent", Destination = "${SPICE}" }, + } +} \ No newline at end of file diff --git a/data/scene/osirisrex/osirisrex/osirisrex.mod b/data/scene/osirisrex/osirisrex/osirisrex.mod index f3e2c214c7..d0c8918d2f 100644 --- a/data/scene/osirisrex/osirisrex/osirisrex.mod +++ b/data/scene/osirisrex/osirisrex/osirisrex.mod @@ -12,7 +12,7 @@ return { Body = "OSIRIS-REX", Geometry = { Type = "MultiModelGeometry", - GeometryFile = "models/osiris_BASE.obj", + GeometryFile = "models/orx_base_resized_12_sep_2016.obj", Magnification = 0, }, Textures = { @@ -29,7 +29,6 @@ return { Translation = { Type = "SpiceEphemeris", Body = "OSIRIS-REX", - Reference = "GALACTIC", Observer = "SUN", }, Rotation = { @@ -38,7 +37,6 @@ return { DestinationFrame = "GALACTIC", }, }, - GuiName = "/Solar/OsirisRex" }, { Name = "ORX_OCAMS_POLYCAM", @@ -48,7 +46,7 @@ return { Body = "OSIRIS-REX", Geometry = { Type = "MultiModelGeometry", - GeometryFile = "models/osiris_POLYCAM.obj", + GeometryFile = "models/orx_polycam_resized_12_sep_2016.obj", Magnification = 0, }, Textures = { @@ -64,7 +62,7 @@ return { Transform = { Translation = { Type = "StaticEphemeris", - Position = {-2.476, 2.710, 3.364}, + Position = {-0.2476, 0.2710, 0.3364}, }, Rotation = { Type = "SpiceRotation", @@ -72,9 +70,7 @@ return { DestinationFrame = "ORX_SPACECRAFT", }, }, - GuiName = "/Solar/ORX_OCAMS_POLYCAM" }, - { Name = "ORX_REXIS", Parent = "OsirisRex", @@ -83,7 +79,7 @@ return { Body = "OSIRIS-REX", Geometry = { Type = "MultiModelGeometry", - GeometryFile = "models/osiris_REXIS.obj", + GeometryFile = "models/orx_rexis_resized_12_sep_2016.obj", Magnification = 0, }, Textures = { @@ -99,18 +95,16 @@ return { Transform = { Translation = { Type = "StaticEphemeris", - Position = {0, 3.371, 2.712}, + Position = {0, 0.3371, 0.2712}, }, Rotation = { Type = "SpiceRotation", SourceFrame = "ORX_REXIS", DestinationFrame = "ORX_SPACECRAFT", - }, }, - - GuiName = "/Solar/ORX_REXIS" + }, + }, }, - - { + { Name = "POLYCAM FOV", Parent = "ORX_OCAMS_POLYCAM", Renderable = { @@ -118,11 +112,6 @@ return { Body = "OSIRIS-REX", Frame = "ORX_OCAMS_POLYCAM", RGB = { 0.8, 0.7, 0.7 }, - Textures = { - Type = "simple", - Color = "textures/glare_blue.png", - -- need to add different texture - }, Instrument = { Name = "ORX_OCAMS_POLYCAM", Method = "ELLIPSOID", @@ -132,10 +121,8 @@ return { BENNU_BODY -- Bennu } }, - GuiName = "/Solar/POLYCAM FOV" }, - - { + { Name = "REXIS FOV", Parent = "ORX_REXIS", Renderable = { @@ -143,11 +130,6 @@ return { Body = "OSIRIS-REX", Frame = "ORX_REXIS", RGB = { 0.8, 0.7, 0.7 }, - Textures = { - Type = "simple", - Color = "textures/glare_blue.png", - -- need to add different texture - }, Instrument = { Name = "ORX_REXIS", Method = "ELLIPSOID", @@ -157,13 +139,12 @@ return { BENNU_BODY -- Bennu } }, - GuiName = "/Solar/REXIS FOV" }, --[[ -- Latest image taken by POLYCAM { Name = "ImagePlaneOsirisRex", - Parent = "OsirisRex", + Parent = "Bennu2", Renderable = { Type = "RenderablePlaneProjection", Frame = "IAU_BENNU", @@ -181,7 +162,7 @@ return { -- POLYCAM FoV square { Name = "FovImagePlane", - Parent = "OsirisRex", + Parent = "Bennu2", Renderable = { Type = "RenderablePlaneProjection", Frame = "IAU_BENNU", @@ -189,7 +170,7 @@ return { Spacecraft = "OSIRIS-REX", Instrument = "ORX_OCAMS_POLYCAM", Moving = true, - Texture = "textures/squarefov.png", + Texture = "textures/defaultProj.png", }, Ephemeris = { Type = "Static", @@ -197,36 +178,11 @@ return { }, }, ]] + + -- Trail relative to Earth { - Name = "OsirisRexTrailLocal", - Parent = "BennuBarycenter", - Renderable = { - Type = "RenderableTrailNew", - -- Spice - Body = "OSIRIS-REX", - Frame = "GALACTIC", - Observer = BENNU_BODY, - -- Optional rendering properties - LineColor = { 0.9, 0.2, 0.9 }, - PointColor = { 0.9, 0.2, 0.9 }, - LineFade = 0.5, -- [0,1] - RenderPart = 0.06, - LineWidth = 2, - ShowTimeStamps = false, - RenderFullTrail = false, - -- Time interval - TimeRange = { - Start = "2016 SEP 8 23:05:00.50", - End = "2023 SEP 24 12:00:00", - }, - SampleDeltaTime = 3600, -- Seconds between each point - SubSamples = 3, - }, - GuiName = "OsirisRexTrailLocal" - }, - { - Name = "OsirisRexTrailGlobal", - Parent = "LodEarth", + Name = "OsirisRexTrailEarth", + Parent = "Earth", Renderable = { Type = "RenderableTrailNew", -- Spice @@ -249,10 +205,11 @@ return { SampleDeltaTime = 60, -- Seconds between each point SubSamples = 59, }, - GuiName = "OsirisRexTrailGlobal" }, + + -- Trail relative to solar system barycenter { - Name = "OsirisRexTrailSolar", + Name = "OsirisRexTrailSolarSystem", Parent = "SolarSystemBarycenter", Renderable = { Type = "RenderableTrailNew", @@ -276,6 +233,35 @@ return { SampleDeltaTime = 3600, -- Seconds between each point SubSamples = 0, }, - GuiName = "OsirisRexTrailSolar" }, + + -- Trail relative to Bennu + { + Name = "OsirisRexTrailBennu", + Parent = "BennuBarycenter", + Renderable = { + Type = "RenderableTrailNew", + -- Spice + Body = "OSIRIS-REX", + Frame = "GALACTIC", + Observer = BENNU_BODY, + -- Optional rendering properties + LineColor = { 0.9, 0.2, 0.9 }, + PointColor = { 0.9, 0.2, 0.9 }, + LineFade = 0.5, -- [0,1] + RenderPart = 0.06, + LineWidth = 2, + ShowTimeStamps = false, + RenderFullTrail = false, + -- Time interval + TimeRange = { + Start = "2016 SEP 8 23:05:00.50", + End = "2023 SEP 24 12:00:00", + }, + SampleDeltaTime = 3600, -- Seconds between each point + SubSamples = 3, + }, + }, + + } diff --git a/data/scene/osirisrex/scheduled_scripts.lua b/data/scene/osirisrex/scheduled_scripts.lua new file mode 100644 index 0000000000..651f64c2dd --- /dev/null +++ b/data/scene/osirisrex/scheduled_scripts.lua @@ -0,0 +1,16 @@ +-- Load the common helper functions +dofile(openspace.absPath('${SCRIPTS}/common.lua')) + +return +{ + helper.scheduledScript.setEnabled("2016 SEP 08 23:05:00", "OsirisRexTrailSolarSystem", false), + helper.scheduledScript.setEnabled("2016 SEP 08 23:05:00", "OsirisRexTrailBennu", false), + + helper.scheduledScript.reversible.setEnabled("2016 SEP 08 23:05:01", "OsirisRexTrailEarth", true), + helper.scheduledScript.reversible.setEnabled("2016 SEP 09 00:00:00", "OsirisRexTrailSolarSystem", true), + helper.scheduledScript.reversible.setEnabled("2016 SEP 09 02:00:00", "OsirisRexTrailEarth", false), + helper.scheduledScript.reversible.setEnabled("2018 OCT 11 00:00:00", "OsirisRexTrailBennu", true), + helper.scheduledScript.reversible.setEnabled("2018 OCT 15 00:00:00", "OsirisRexTrailSolarSystem", false), + helper.scheduledScript.reversible.setEnabled("2019 AUG 01 00:00:00", "OsirisRexTrailSolarSystem", true), + helper.scheduledScript.reversible.setEnabled("2019 AUG 01 00:00:00", "OsirisRexTrailBennu", false), +} \ No newline at end of file diff --git a/data/scene/pluto/pluto.mod b/data/scene/pluto/pluto.mod index 779e78e6e2..e8bdf8b37e 100644 --- a/data/scene/pluto/pluto.mod +++ b/data/scene/pluto/pluto.mod @@ -6,12 +6,8 @@ return { Ephemeris = { Type = "Spice", Body = "PLUTO BARYCENTER", - Reference = "GALACTIC", Observer = "SUN", - Kernels = { - "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp", - -- "${OPENSPACE_DATA}/spice/Pluto/EPHEMERIDES/nh_plu017.bsp" - } + Kernels = "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp", }, }, @@ -41,20 +37,14 @@ return { Ephemeris = { Type = "Spice", Body = "PLUTO", - Reference = "GALACTIC", Observer = "PLUTO BARYCENTER", - Kernels = { - "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp", - -- "${OPENSPACE_DATA}/spice/Pluto/EPHEMERIDES/nh_plu017.bsp" - -- "C:/Users/michal/NewHorizons/SPICE/nh_plu017.bsp" - } + Kernels = "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp", }, Rotation = { Type = "Spice", Frame = "IAU_PLUTO", Reference = "GALACTIC" }, - GuiName = "/Solar/Planets/Pluto" }, { Name = "Charon", @@ -81,20 +71,15 @@ return { Ephemeris = { Type = "Spice", Body = "CHARON", - Reference = "ECLIPJ2000", Observer = "PLUTO BARYCENTER", - Kernels = { - "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" - } + Kernels = "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" }, Rotation = { Type = "Spice", Frame = "IAU_CHARON", Reference = "ECLIPJ2000" }, - GuiName = "/Solar/Planets/Charon" }, - -- CharonTrail module { Name = "CharonTrail", @@ -114,7 +99,6 @@ return { -- need to add different texture }, }, - GuiName = "/Solar/CharonTrail" } --[[ -- PlutoTrail module 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..84af8afce9 100644 --- a/data/scene/rosetta/67P/67P.mod +++ b/data/scene/rosetta/67P/67P.mod @@ -7,33 +7,9 @@ return { Translation = { Type = "SpiceEphemeris", 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", }, { Name = "67P", @@ -50,6 +26,7 @@ return { Textures = { Type = "simple", Color = "textures/gray.jpg", + -- Color = "textures/may9_map.jpg", Project = "textures/defaultProj.png", Default = "textures/defaultProj.png" }, @@ -63,7 +40,8 @@ return { Observer = "ROSETTA", Target = "CHURYUMOV-GERASIMENKO", Aberration = "NONE", - TextureMap = true + TextureMap = true, + ShadowMap = true }, DataInputTranslation = { Instrument = { @@ -98,10 +76,9 @@ return { Method = "ELLIPSOID", Aberration = "NONE", Fovy = 5.00, - Aspect = 1, - Near = 0.01, - Far = 1000000, + Aspect = 1 }, + BoundingSphereRadius = 5000.0 }, Transform = { Rotation = { @@ -110,7 +87,6 @@ return { DestinationFrame = "GALACTIC", }, }, - GuiName = "/Solar/67P", }, -- 67P Trail Module { @@ -138,7 +114,6 @@ return { SampleDeltaTime = 3600, -- Seconds between each point SubSamples = 0, }, - GuiName = "/Solar/67PTrail" }, --[[ { 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..73b8181ecc 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", @@ -61,10 +64,9 @@ return { Translation = { Type = "SpiceEphemeris", Body = "ROSETTA", - Reference = "GALACTIC", Observer = "SUN", Kernels = RosettaKernels - }, + }, Rotation = { Type = "SpiceRotation", SourceFrame = "ROS_SPACECRAFT", @@ -73,8 +75,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 +98,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 +115,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 +132,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 +157,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 +175,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 +193,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 +211,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 +236,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 +261,34 @@ 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", + 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 +303,9 @@ return { Textures = { Type = "simple", Color = "textures/foil_silver_ramp.png" - } + }, + Rotation = { ModelTransform = RotationMatrix } + } }, { @@ -251,7 +321,9 @@ return { Textures = { Type = "simple", Color = "textures/parts2_AO.png" - } + }, + Rotation = { ModelTransform = RotationMatrix } + } }, { @@ -267,7 +339,9 @@ return { Textures = { Type = "simple", Color = "textures/foil_silver_ramp.png" - } + }, + Rotation = { ModelTransform = RotationMatrix } + } }, { @@ -283,55 +357,11 @@ 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 +371,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,24 +381,41 @@ 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, + }, + }, { Name = "NAVCAM", Parent = "Rosetta", - -- Transform = { - -- Rotation = { - -- Type = "SpiceRotation", - -- SourceFrame = "NAVCAM", - -- DestinationFrame = "ROS_SPACECRAFT", - -- }, - -- }, - GuiName = "/Solar/Rosetta_navcam" }, { Name = "NAVCAM FOV", @@ -392,7 +439,6 @@ return { "CHURYUMOV-GERASIMENKO" } }, - GuiName = "/Solar/Rosetta_navcam" }, -- Latest image taken by NAVCAM { diff --git a/data/scene/saturn/saturn.mod b/data/scene/saturn/saturn.mod index aa42c4d4b2..1f7e68170d 100644 --- a/data/scene/saturn/saturn.mod +++ b/data/scene/saturn/saturn.mod @@ -32,11 +32,8 @@ return { Translation = { Type = "SpiceEphemeris", Body = "SATURN BARYCENTER", - Reference = "ECLIPJ2000", Observer = "SUN", - Kernels = { - "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" - } + Kernels = "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" }, Rotation = { Type = "SpiceRotation", @@ -48,7 +45,6 @@ return { Scale = 1, }, }, - GuiName = "/Solar/Planets/Saturn" }, -- SaturnTrail module { @@ -69,6 +65,5 @@ return { -- need to add different texture }, }, - GuiName = "/Solar/SaturnTrail" } } diff --git a/data/scene/stars-denver/stars-denver.mod b/data/scene/stars-denver/stars-denver.mod index 5f9b5c0ec1..0064624bd1 100644 --- a/data/scene/stars-denver/stars-denver.mod +++ b/data/scene/stars-denver/stars-denver.mod @@ -9,8 +9,5 @@ return { Texture = "textures/halo.png", ColorMap = "denver_colorbv.cmap" }, - Ephemeris = { - Type = "Static" - } } } diff --git a/data/scene/stars/stars.mod b/data/scene/stars/stars.mod index e9d48b4901..0cb9ed85cc 100644 --- a/data/scene/stars/stars.mod +++ b/data/scene/stars/stars.mod @@ -9,8 +9,5 @@ return { Texture = "${OPENSPACE_DATA}/scene/stars/textures/halo.png", ColorMap = "${OPENSPACE_DATA}/scene/stars/colorbv.cmap" }, - Ephemeris = { - Type = "Static" - } } } diff --git a/data/scene/sun/sun.mod b/data/scene/sun/sun.mod index 288335bb39..f377c83011 100644 --- a/data/scene/sun/sun.mod +++ b/data/scene/sun/sun.mod @@ -3,9 +3,6 @@ return { { Name = "SolarSystemBarycenter", Parent = "SolarSystem", - Ephemeris = { - Type = "Static", - }, }, -- Sun module @@ -30,11 +27,8 @@ return { Ephemeris = { Type = "Spice", Body = "SUN", - Reference = "GALACTIC", Observer = "SSB", - Kernels = { - "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" - } + Kernels = "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" }, Rotation = { Type = "Spice", @@ -50,17 +44,15 @@ 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", Body = "SUN", - Reference = "GALACTIC", Observer = "SSB", - Kernels = { - "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" - } - }, + Kernels = "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" + }, }, { Name = "SunMarker", @@ -70,7 +62,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/toyvolume/toyvolume.mod b/data/scene/toyvolume/toyvolume.mod index 2a432c2a5b..eed9efd8e4 100644 --- a/data/scene/toyvolume/toyvolume.mod +++ b/data/scene/toyvolume/toyvolume.mod @@ -2,10 +2,6 @@ return { { Name = "ToyVolume 1", Parent = "Sun", - Ephemeris = { - Type = "Static", - Position = {0, 0, 0, 0} - }, Renderable = { Type = "RenderableToyVolume", Color = {1.0, 0.0, 0.0, 0.7}, @@ -13,39 +9,28 @@ return { Rotation = {0.5, 0, 0}, ScalingExponent = 11 }, - GuiName = "/Volumes/ToyVolume1" }, { Name = "ToyVolume 2", Parent = "Earth", - Ephemeris = { - Type = "Static", - Position = {0, 0, 0, 0} - }, Renderable = { Type = "RenderableToyVolume", Color = {1.0, 0.8, 0.0, 0.7}, Translation = {0.0, 0.0, 0.0}, - Scaling = {5.0, 2.5, 5.0}, + Scaling = {5.0, 2.5, 5.0}, ScalingExponent = 6 }, - GuiName = "/Volumes/ToyVolume2" }, { Name = "ToyVolume 3", Parent = "Earth", - Ephemeris = { - Type = "Static", - Translation = {0, 0, 0, 0} - }, Renderable = { Type = "RenderableToyVolume", Scaling = {2.0, 2.0, 2.0}, Rotation = {3.14/2.0, 0, 0}, Color = {1.0, 1.0, 1.0, 0.7}, Translation = {0.0, 0.0, 0.0}, - ScalingExponent = 6 + ScalingExponent = 6 }, - GuiName = "/Volumes/ToyVolume3" } } diff --git a/data/scene/uranus/uranus.mod b/data/scene/uranus/uranus.mod index b31648ea1a..77bac51663 100644 --- a/data/scene/uranus/uranus.mod +++ b/data/scene/uranus/uranus.mod @@ -32,11 +32,8 @@ return { Translation = { Type = "SpiceEphemeris", Body = "URANUS BARYCENTER", - Reference = "ECLIPJ2000", Observer = "SUN", - Kernels = { - "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" - } + Kernels = "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" }, Rotation = { Type = "SpiceRotation", @@ -48,7 +45,6 @@ return { Scale = 1, }, }, - GuiName = "/Solar/Planets/Uranus" }, -- UranusTrail module { @@ -69,6 +65,5 @@ return { -- need to add different texture }, }, - GuiName = "/Solar/UranusTrail" } } diff --git a/data/scene/venus/venus.mod b/data/scene/venus/venus.mod index 753e164b55..6b96b1ca1b 100644 --- a/data/scene/venus/venus.mod +++ b/data/scene/venus/venus.mod @@ -3,9 +3,6 @@ return { { Name = "VenusBarycenter", Parent = "SolarSystemBarycenter", - Ephemeris = { - Type = "Static" - } }, -- Venus module @@ -34,18 +31,14 @@ return { Ephemeris = { Type = "Spice", Body = "VENUS", - Reference = "ECLIPJ2000", Observer = "SUN", - Kernels = { - "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" - } + Kernels = "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" }, Rotation = { Type = "Spice", Frame = "IAU_VENUS", Reference = "ECLIPJ2000" }, - GuiName = "/Solar/Planets/VENUS" }, -- VenusTrail module { @@ -66,6 +59,5 @@ return { -- need to add different texture }, }, - GuiName = "/Solar/VenusTrail" } } diff --git a/data/scene/volumetricmilkyway/volumetricmilkyway.mod b/data/scene/volumetricmilkyway/volumetricmilkyway.mod index 44f857fa41..d30a718d3a 100644 --- a/data/scene/volumetricmilkyway/volumetricmilkyway.mod +++ b/data/scene/volumetricmilkyway/volumetricmilkyway.mod @@ -4,10 +4,6 @@ return { { Name = "Volumetric Milky Way", Parent = "Root", - Ephemeris = { - Type = "Static", - Position = {0, 0, 0, 0} - }, Renderable = { Type = "RenderableGalaxy", Translation = {0, 0, 0}, @@ -21,6 +17,5 @@ return { Scaling = {kiloparsec, kiloparsec, kiloparsec} } }, - GuiName = "/VolumetricMilkyWay" } } 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..515863d546 --- /dev/null +++ b/include/openspace/documentation/documentation.h @@ -0,0 +1,297 @@ +/***************************************************************************************** + * * + * 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 + +// Make the overload for std::to_string available for the Offense::Reason for easier +// error logging + +namespace std { + +std::string to_string(openspace::documentation::TestResult::Offense::Reason reason); + +} // namespace + +#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..d09a386fdc --- /dev/null +++ b/include/openspace/documentation/verifier.h @@ -0,0 +1,943 @@ +/***************************************************************************************** + * * + * 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 +#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::value, + "T cannot be BoolVerifier" + ); + static_assert( + !std::is_base_of::value, + "T cannot be StringVerifier" + ); + static_assert( + !std::is_base_of::value, + "T cannot be TableVerifier" + ); + static_assert( + !std::is_base_of::value, + "T cannot be VectorVerifier" + ); + + using OperatorVerifier>::OperatorVerifier; + + std::string documentation() const; + + using OperatorVerifier>::value; +}; + +/** +* 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::value, + "T cannot be BoolVerifier" + ); + static_assert( + !std::is_base_of::value, + "T cannot be StringVerifier" + ); + static_assert( + !std::is_base_of::value, + "T cannot be TableVerifier" + ); + static_assert( + !std::is_base_of::value, + "T cannot be VectorVerifier" + ); + + using OperatorVerifier>::OperatorVerifier; + + std::string documentation() const override; + + using OperatorVerifier>::value; +}; + +/** +* 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::value, + "T cannot be BoolVerifier" + ); + static_assert( + !std::is_base_of::value, + "T cannot be StringVerifier" + ); + static_assert( + !std::is_base_of::value, + "T cannot be TableVerifier" + ); + static_assert( + !std::is_base_of::value, + "T cannot be VectorVerifier" + ); + + using OperatorVerifier>::OperatorVerifier; + + std::string documentation() const override; + + using OperatorVerifier>::value; +}; + +/** +* 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::value, + "T cannot be BoolVerifier" + ); + static_assert( + !std::is_base_of::value, + "T cannot be StringVerifier" + ); + static_assert( + !std::is_base_of::value, + "T cannot be TableVerifier" + ); + static_assert( + !std::is_base_of::value, + "T cannot be VectorVerifier" + ); + + using OperatorVerifier>::OperatorVerifier; + + std::string documentation() const override; + + using OperatorVerifier>::value; +}; + +/** +* 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::value, "T cannot be TableVerifier"); + + using OperatorVerifier>::OperatorVerifier; + + std::string documentation() const override; + + using OperatorVerifier>::value; +}; + +/** +* 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::value, "T cannot be TableVerifier"); + + using OperatorVerifier>::OperatorVerifier; + + std::string documentation() const override; + + using OperatorVerifier>::value; +}; + +//---------------------------------------------------------------------------------------- +// 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::value, "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::value, "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::value, + "T cannot be BoolVerifier" + ); + static_assert( + !std::is_base_of::value, + "T cannot be StringVerifier" + ); + static_assert( + !std::is_base_of::value, + "T cannot be TableVerifier" + ); + static_assert( + !std::is_base_of::value, + "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::value, + "T cannot be BoolVerifier" + ); + static_assert( + !std::is_base_of::value, + "T cannot be StringVerifier" + ); + static_assert( + !std::is_base_of::value, + "T cannot be TableVerifier" + ); + static_assert( + !std::is_base_of::value, + "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..98ba83a1fa --- /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..06b46babef 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 openspace::Documentation Documentation(); + private: /** * Checks whether the loaded configuration file is complete, that is specifying the diff --git a/include/openspace/engine/openspaceengine.h b/include/openspace/engine/openspaceengine.h index 4240a9a3b0..0b9d8e66c8 100644 --- a/include/openspace/engine/openspaceengine.h +++ b/include/openspace/engine/openspaceengine.h @@ -29,6 +29,7 @@ #include #include +#include #include #include @@ -50,11 +51,11 @@ class LuaConsole; class NetworkEngine; class GUI; class RenderEngine; -class SyncBuffer; class ModuleEngine; class WindowWrapper; class SettingsEngine; class TimeManager; +class SyncEngine; namespace interaction { class InteractionHandler; } namespace gui { class GUI; } @@ -81,6 +82,7 @@ public: interaction::InteractionHandler& interactionHandler(); RenderEngine& renderEngine(); scripting::ScriptEngine& scriptEngine(); + scripting::ScriptScheduler& scriptScheduler(); NetworkEngine& networkEngine(); LuaConsole& console(); ModuleEngine& moduleEngine(); @@ -115,6 +117,9 @@ public: void disableBarrier(); void toggleShutdownMode(); + + bool useBusyWaitForDecode(); + bool logSGCTOutOfOrderErrors(); void runPostInitializationScripts(const std::string& sceneDescription); @@ -140,7 +145,9 @@ private: std::unique_ptr _interactionHandler; std::unique_ptr _renderEngine; std::unique_ptr _scriptEngine; + std::unique_ptr _scriptScheduler; std::unique_ptr _networkEngine; + std::unique_ptr _syncEngine; std::unique_ptr _commandlineParser; std::unique_ptr _console; std::unique_ptr _moduleEngine; @@ -156,7 +163,6 @@ private: // Others std::unique_ptr _globalPropertyNamespace; - std::unique_ptr _syncBuffer; bool _isMaster; double _runTime; diff --git a/include/openspace/engine/settingsengine.h b/include/openspace/engine/settingsengine.h index f1faa111e7..a3a962eac6 100644 --- a/include/openspace/engine/settingsengine.h +++ b/include/openspace/engine/settingsengine.h @@ -43,12 +43,25 @@ public: void setModules(std::vector modules); + bool busyWaitForDecode(); + bool logSGCTOutOfOrderErrors(); + bool useDoubleBuffering(); + private: void initEyeSeparation(); void initSceneFiles(); + void initShowFrameNumber(); + void initBusyWaitForDecode(); + void initLogSGCTOutOfOrderErrors(); + void initUseDoubleBuffering(); properties::FloatProperty _eyeSeparation; properties::OptionProperty _scenes; + properties::BoolProperty _showFrameNumber; + properties::BoolProperty _busyWaitForDecode; + properties::BoolProperty _logSGCTOutOfOrderErrors; + properties::BoolProperty _useDoubleBuffering; + }; } // namespace openspace diff --git a/include/openspace/engine/syncengine.h b/include/openspace/engine/syncengine.h new file mode 100644 index 0000000000..c10a7833d0 --- /dev/null +++ b/include/openspace/engine/syncengine.h @@ -0,0 +1,106 @@ +/***************************************************************************************** + * * + * 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 __SYNCENGINE_H__ +#define __SYNCENGINE_H__ + + +#include +#include + + +namespace openspace { + +class Syncable; +class SyncBuffer; + +/** +* Manages a collection of Syncables and ensures they are synchronized +* over SGCT nodes. Encoding/Decoding order is handles internally. +*/ +class SyncEngine { +public: + + /** + * Dependency injection: a SyncEngine relies on a SyncBuffer to encode the sync data. + */ + SyncEngine(SyncBuffer* syncBuffer); + + + /** + * Encodes all added Syncables in the injected SyncBuffer. + * This method is only called on the SGCT master node + */ + void encodeSyncables(); + + /** + * Decodes the SyncBuffer into the added Syncables. + * This method is only called on the SGCT slave nodes + */ + void decodeSyncables(); + + /** + * Invokes the presync method of all added Syncables + */ + void presync(bool isMaster); + + /** + * Invokes the postsync method of all added Syncables + */ + void postsync(bool isMaster); + + + + /** + * Add a Syncable to be synchronized over the SGCT cluster + */ + void addSyncable(Syncable* syncable); + + /** + * Add multiple Syncables to be synchronized over the SGCT cluster + */ + void addSyncables(const std::vector& syncables); + + /** + * Remove a Syncable from being synchronized over the SGCT cluster + */ + void removeSyncable(Syncable* syncable); + +private: + + /** + * Vector of Syncables. The vectors ensures consistent encode/decode order + */ + std::vector _syncables; + + /** + * Databuffer used in encoding/decoding + */ + std::unique_ptr _syncBuffer; +}; + + +} // namespace openspace + +#endif //#ifndef __SYNCENGINE_H__ diff --git a/include/openspace/engine/wrapper/sgctwindowwrapper.h b/include/openspace/engine/wrapper/sgctwindowwrapper.h index 7a07e2e5b2..da4d291edb 100644 --- a/include/openspace/engine/wrapper/sgctwindowwrapper.h +++ b/include/openspace/engine/wrapper/sgctwindowwrapper.h @@ -53,6 +53,8 @@ public: bool isRegularRendering() const override; bool hasGuiWindow() const override; bool isGuiWindow() const override; + bool isUsingSwapGroups() const override; + bool isSwapGroupMaster() const override; glm::mat4 viewProjectionMatrix() const override; glm::mat4 modelMatrix() const override; @@ -66,7 +68,7 @@ public: bool isSimpleRendering() const override; - void takeScreenshot() const override; + void takeScreenshot(bool applyWarping = false) const override; }; } // namespace openspace diff --git a/include/openspace/engine/wrapper/windowwrapper.h b/include/openspace/engine/wrapper/windowwrapper.h index cb931bc87c..2d3d789dc8 100644 --- a/include/openspace/engine/wrapper/windowwrapper.h +++ b/include/openspace/engine/wrapper/windowwrapper.h @@ -153,6 +153,16 @@ public: */ virtual bool isGuiWindow() const; + /** + * Returns true if the current rendering window is using swap groups. + */ + virtual bool isUsingSwapGroups() const; + + /** + * Returns true if the current rendering window is master of the swap its group. + */ + virtual bool isSwapGroupMaster() const; + /** * Returns the currently employed view-projection matrix. On default, this method will * return the identity matrix. @@ -216,7 +226,7 @@ public: /** * Advises the windowing system to take a screenshot. This method defaults to a no-op. */ - virtual void takeScreenshot() const; + virtual void takeScreenshot(bool applyWarping = false) const; struct WindowWrapperException : public ghoul::RuntimeError { explicit WindowWrapperException(const std::string& msg); diff --git a/include/openspace/interaction/interactionhandler.h b/include/openspace/interaction/interactionhandler.h index 01187de2b8..11ecda27d5 100644 --- a/include/openspace/interaction/interactionhandler.h +++ b/include/openspace/interaction/interactionhandler.h @@ -76,12 +76,8 @@ public: void unlockControls(); //void update(double deltaTime); - - void preSynchronization(double deltaTime); - void postSynchronizationPreDraw(); - - void serialize(SyncBuffer* syncBuffer); - void deserialize(SyncBuffer* syncBuffer); + void updateCamera(); + void updateInputStates(double timeSinceLastUpdate); // Accessors ghoul::Dictionary getCameraStateDictionary(); diff --git a/include/openspace/interaction/interactionmode.h b/include/openspace/interaction/interactionmode.h index 1d248c6f62..0a17cfbfa3 100644 --- a/include/openspace/interaction/interactionmode.h +++ b/include/openspace/interaction/interactionmode.h @@ -97,9 +97,6 @@ public: virtual void updateMouseStatesFromInput(const InputState& inputState, double deltaTime) = 0; virtual void updateCameraStateFromMouseStates(Camera& camera) = 0; - virtual void serialize(SyncBuffer* syncBuffer) = 0; - virtual void deserialize(SyncBuffer* syncBuffer) = 0; - protected: /** Inner class that acts as a smoothing filter to a variable. The filter has a step @@ -170,10 +167,6 @@ public: virtual void updateMouseStatesFromInput(const InputState& inputState, double deltaTime); virtual void updateCameraStateFromMouseStates(Camera& camera); - // Need implementation - - virtual void serialize(SyncBuffer* syncBuffer) {}; - virtual void deserialize(SyncBuffer* syncBuffer) {}; private: std::vector _keyframes; double _currentKeyframeTime; @@ -187,9 +180,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); @@ -206,11 +199,6 @@ public: glm::dvec2 synchedLocalRollMouseVelocity(); glm::dvec2 synchedGlobalRollMouseVelocity(); - void preSynchronization(); - void postSynchronizationPreDraw(); - - void serialize(SyncBuffer* syncBuffer); - void deserialize(SyncBuffer* syncBuffer); private: double _sensitivity; @@ -219,19 +207,6 @@ public: MouseState _truckMovementMouseState; MouseState _localRollMouseState; MouseState _globalRollMouseState; - - // MouseStates have synched variables - glm::dvec2 _sharedGlobalRotationMouseVelocity; - glm::dvec2 _sharedLocalRotationMouseVelocity; - glm::dvec2 _sharedTruckMovementMouseVelocity; - glm::dvec2 _sharedLocalRollMouseVelocity; - glm::dvec2 _sharedGlobalRollMouseVelocity; - - glm::dvec2 _synchedGlobalRotationMouseVelocity; - glm::dvec2 _synchedLocalRotationMouseVelocity; - glm::dvec2 _synchedTruckMovementMouseVelocity; - glm::dvec2 _synchedLocalRollMouseVelocity; - glm::dvec2 _synchedGlobalRollMouseVelocity; }; OrbitalInteractionMode(std::shared_ptr mouseStates); @@ -242,9 +217,6 @@ public: virtual void updateMouseStatesFromInput(const InputState& inputState, double deltaTime); virtual void updateCameraStateFromMouseStates(Camera& camera); - virtual void serialize(SyncBuffer* syncBuffer); - virtual void deserialize(SyncBuffer* syncBuffer); - protected: //void updateCameraStateFromMouseStates(Camera& camera); std::shared_ptr _mouseStates; diff --git a/include/openspace/openspace.h b/include/openspace/openspace.h index 181547f5b4..3fbdcf642e 100644 --- a/include/openspace/openspace.h +++ b/include/openspace/openspace.h @@ -32,10 +32,10 @@ namespace openspace { std::string licenseText(); const int OPENSPACE_VERSION_MAJOR = 0; -const int OPENSPACE_VERSION_MINOR = 4; +const int OPENSPACE_VERSION_MINOR = 5; const int OPENSPACE_VERSION_PATCH = 0; -const std::string OPENSPACE_VERSION_STRING = "prerelease-9 (IPS)"; +const std::string OPENSPACE_VERSION_STRING = "prerelease-10 (Kulturnatten)"; } // namespace openspace 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..de1934821d 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 openspace::Documentation Documentation(); + protected: properties::BoolProperty _enabled; private: + RenderBin _renderBin; PowerScaledScalar boundingSphere_; std::string _startTime; std::string _endTime; diff --git a/include/openspace/rendering/renderengine.h b/include/openspace/rendering/renderengine.h index ee248864d8..26fa01089c 100644 --- a/include/openspace/rendering/renderengine.h +++ b/include/openspace/rendering/renderengine.h @@ -31,6 +31,9 @@ #include #include +#include + + #include namespace ghoul { @@ -49,6 +52,7 @@ namespace openspace { // Forward declare to minimize dependencies class Camera; class SyncBuffer; + class Scene; class Renderer; class RaycasterManager; @@ -94,15 +98,19 @@ public: // sgct wrapped functions bool initializeGL(); - void postSynchronizationPreDraw(); - void preSynchronization(); + + void updateSceneGraph(); + void updateShaderPrograms(); + void updateFade(); + void updateRenderer(); + void updateScreenSpaceRenderables(); void render(const glm::mat4& projectionMatrix, const glm::mat4& viewMatrix); void renderScreenLog(); void renderShutdownInformation(float timer, float fullTime); void postDraw(); - void takeScreenshot(); + void takeScreenshot(bool applyWarping = false); void toggleInfoText(bool b); void toggleFrametimeType(int t); @@ -111,13 +119,10 @@ public: bool doesPerformanceMeasurements() const; performance::PerformanceManager* performanceManager(); - void serialize(SyncBuffer* syncBuffer); - void deserialize(SyncBuffer* syncBuffer); - float globalBlackOutFactor(); void setGlobalBlackOutFactor(float factor); void setNAaSamples(int nAaSamples); - + void setShowFrameNumber(bool enabled); void setDisableRenderingOnMaster(bool enabled); @@ -184,12 +189,17 @@ public: void startFading(int direction, float fadeDuration); void sortScreenspaceRenderables(); + // This is temporary until a proper screenspace solution is found ---abock - struct { + struct OnScreenInformation{ glm::vec2 _position; unsigned int _size; int _node; - } _onScreenInformation; + }; + + SyncData _onScreenInformation; + + std::vector getSyncables(); private: void setRenderer(std::unique_ptr renderer); @@ -214,16 +224,20 @@ private: bool _showInfo; bool _showLog; bool _takeScreenshot; + bool _applyWarping; + bool _showFrameNumber; float _globalBlackOutFactor; float _fadeDuration; float _currentFadeTime; int _fadeDirection; int _nAaSamples; + unsigned int _frameNumber; std::vector _programs; std::vector> _screenSpaceRenderables; + std::shared_ptr _fontBig = nullptr; std::shared_ptr _fontInfo = nullptr; std::shared_ptr _fontDate = nullptr; std::shared_ptr _fontLog = nullptr; 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..ae56fe8569 100644 --- a/include/openspace/scene/ephemeris.h +++ b/include/openspace/scene/ephemeris.h @@ -25,24 +25,25 @@ #ifndef __EPHEMERIS_H__ #define __EPHEMERIS_H__ -#include -#include +#include + +#include #include +#include + namespace openspace { -class Ephemeris { +class Ephemeris : public properties::PropertyOwner { public: static Ephemeris* createFromDictionary(const ghoul::Dictionary& dictionary); - Ephemeris(const ghoul::Dictionary& dictionary); virtual ~Ephemeris(); virtual bool initialize(); - virtual const glm::dvec3& position() const = 0; + virtual glm::dvec3 position() const = 0; virtual void update(const UpdateData& data); -protected: - Ephemeris(); + static openspace::Documentation Documentation(); }; } // namespace openspace diff --git a/include/openspace/scene/rotation.h b/include/openspace/scene/rotation.h index f5f3620382..42e35bd3bd 100644 --- a/include/openspace/scene/rotation.h +++ b/include/openspace/scene/rotation.h @@ -28,6 +28,8 @@ #include #include +#include + namespace openspace { class Rotation { @@ -40,6 +42,8 @@ public: virtual const glm::dmat3& matrix() const = 0; virtual void update(const UpdateData& data); + static openspace::Documentation Documentation(); + protected: Rotation(); }; diff --git a/include/openspace/scene/scale.h b/include/openspace/scene/scale.h index d7f0ce9703..40a694af4a 100644 --- a/include/openspace/scene/scale.h +++ b/include/openspace/scene/scale.h @@ -25,23 +25,25 @@ #ifndef __SCALE_H__ #define __SCALE_H__ -#include +#include + +#include #include +#include + namespace openspace { -class Scale { +class Scale : public properties::PropertyOwner { public: static Scale* createFromDictionary(const ghoul::Dictionary& dictionary); - Scale(const ghoul::Dictionary& dictionary); virtual ~Scale(); virtual bool initialize(); virtual double scaleValue() const = 0; virtual void update(const UpdateData& data); -protected: - Scale(); + static openspace::Documentation Documentation(); }; } // namespace openspace diff --git a/include/openspace/scene/scene.h b/include/openspace/scene/scene.h index 4844d3ac7b..0e748a2f65 100644 --- a/include/openspace/scene/scene.h +++ b/include/openspace/scene/scene.h @@ -31,6 +31,8 @@ #include #include +#include + #include #include #include @@ -117,6 +119,8 @@ public: */ static scripting::LuaLibrary luaLibrary(); + static documentation::Documentation Documentation(); + private: bool loadSceneInternal(const std::string& sceneDescriptionFilePath); diff --git a/include/openspace/scene/scenegraphnode.h b/include/openspace/scene/scenegraphnode.h index 4979eedcf8..a7a3c4cac7 100644 --- a/include/openspace/scene/scenegraphnode.h +++ b/include/openspace/scene/scenegraphnode.h @@ -26,6 +26,8 @@ #define __SCENEGRAPHNODE_H__ // open space includes +#include + #include #include #include @@ -106,6 +108,8 @@ public: _ephemeris = eph; } + static documentation::Documentation Documentation(); + private: bool sphereInsideFrustum(const psc& s_pos, const PowerScaledScalar& s_rad, const Camera* camera); diff --git a/include/openspace/scripting/scriptengine.h b/include/openspace/scripting/scriptengine.h index 624569d027..9e02e117ed 100644 --- a/include/openspace/scripting/scriptengine.h +++ b/include/openspace/scripting/scriptengine.h @@ -26,6 +26,7 @@ #define __SCRIPTENGINE_H__ #include +#include #include @@ -47,7 +48,7 @@ namespace scripting { * openspace namespac prefix in Lua. The same functions can be exposed to * other Lua states by passing them to the #initializeLuaState method. */ -class ScriptEngine { +class ScriptEngine : public Syncable { public: using RemoteScripting = ghoul::Boolean; /** @@ -70,17 +71,14 @@ public: bool runScript(const std::string& script); bool runScriptFile(const std::string& filename); - bool writeDocumentation(const std::string& filename, const std::string& type) const; + void writeDocumentation(const std::string& filename, const std::string& type) const; bool writeLog(const std::string& script); - void serialize(SyncBuffer* syncBuffer); - - void deserialize(SyncBuffer* syncBuffer); - - void postSynchronizationPreDraw(); - - void preSynchronization(); + virtual void presync(bool isMaster); + virtual void encode(SyncBuffer* syncBuffer); + virtual void decode(SyncBuffer* syncBuffer); + virtual void postsync(bool isMaster); void queueScript(const std::string &script, RemoteScripting remoteScripting); diff --git a/include/openspace/scripting/scriptscheduler.h b/include/openspace/scripting/scriptscheduler.h new file mode 100644 index 0000000000..b8b5630c07 --- /dev/null +++ b/include/openspace/scripting/scriptscheduler.h @@ -0,0 +1,136 @@ +/***************************************************************************************** + * * + * 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 __SCRIPTSCHEDULER_H__ +#define __SCRIPTSCHEDULER_H__ + +#include + +#include + +#include +#include + +namespace openspace { + +namespace scripting { + + + +struct ReversibleLuaScript { + std::string forwardScript; + std::string backwardScript; +}; + +struct ScheduledScript { + ScheduledScript() : time(-DBL_MAX) { } + ScheduledScript(const ghoul::Dictionary& dict); + + double time; + ReversibleLuaScript script; + + static bool CompareByTime(const ScheduledScript& s1, const ScheduledScript& s2); +}; + + +/** + * Maintains an ordered list of ScheduledScripts and provides a simple + * interface for retrieveing scheduled scripts + */ +class ScriptScheduler { +public: + + /** + * Load a schedule from a Lua-file + * \param filename Lua file to load + * \param L an optional lua_State defining variables that may be used + * in the Lua-file. + */ + void loadScripts(const std::string& filename, lua_State* L = nullptr); + + /** + * Load a schedule from a ghoul::Dictionary + * \param dict Dictionary to read + */ + void loadScripts(const ghoul::Dictionary& dict); + + + /** + * Rewinds the script scheduler to the first scheduled script. + */ + void rewind(); + + /** + * Removes all scripts for the schedule. + */ + void clearSchedule(); + + /** + * Progresses the script schedulers time and returns all scripts that has been + * scheduled to run between \param newTime and the time provided in the last invocation + * of this method. + * + * \param newTime A j2000 time value specifying the new time stamp that + * the script scheduler should progress to. + * + * \returns the ordered queue of scripts . + */ + std::queue progressTo(double newTime); + + /** + * See progressTo(double newTime). + * + * \param timeStr A string specifying the a new time stamp that the + * scripts scheduler should progress to. + */ + std::queue progressTo(const std::string& timeStr); + + + + /** + * Returns the the j2000 time value that the script scheduler is currently at + */ + double currentTime() const; + + /** + * \returns a vector of all scripts that has been loaded + */ + const std::vector& allScripts() const; + + + static LuaLibrary luaLibrary(); + +private: + + std::vector _scheduledScripts; + + size_t _currentIndex = 0; + double _currentTime; + +}; + +} // namespace scripting +} // namespace openspace + +#endif // __SCRIPTSCHEDULER_H__ diff --git a/include/openspace/util/camera.h b/include/openspace/util/camera.h index 7357ce9c8c..e2de5a6099 100644 --- a/include/openspace/util/camera.h +++ b/include/openspace/util/camera.h @@ -29,9 +29,10 @@ // open space includes #include -#include #include +#include + // glm includes #include #include @@ -118,12 +119,8 @@ namespace openspace { // of the old calls to the function wrong.. const Mat4& combinedViewMatrix() const; - // Synchronization - void postSynchronizationPreDraw(); - void preSynchronization(); - void serialize(SyncBuffer* syncBuffer); - void deserialize(SyncBuffer* syncBuffer); - + void invalidateCache(); + void serialize(std::ostream& os) const; void deserialize(std::istream& is); @@ -177,32 +174,17 @@ namespace openspace { [[deprecated("Replaced by Camera::SgctInternal::viewProjectionMatrix()")]] const glm::mat4& viewProjectionMatrix() const; + + std::vector getSyncables(); + + private: - /** - Class encapsulating data that needs to be synched between SGCT nodes. - Are all three variables (i.e. local, shared, synced) really neccessary? /EB - */ - template - struct SyncData { - SyncData() {} - SyncData(const SyncData& d) - : local(d.local), shared(d.shared), synced(d.synced) {} - void serialize(SyncBuffer* syncBuffer) { syncBuffer->encode(shared); } - void deserialize(SyncBuffer* syncBuffer) { syncBuffer->decode(shared); } - void postSynchronizationPreDraw() { synced = shared; } - void preSynchronization() { shared = local; } - - T local; - T shared; - T synced; - }; - - // State of the camera SyncData _position; SyncData _rotation; SyncData _scaling; + // _focusPosition to be removed Vec3 _focusPosition; float _maxFov; diff --git a/include/openspace/util/factorymanager.h b/include/openspace/util/factorymanager.h index 04903eb82b..acee69b919 100644 --- a/include/openspace/util/factorymanager.h +++ b/include/openspace/util/factorymanager.h @@ -86,9 +86,11 @@ public: /** * Adds the passed \p factory to the FactoryManager. Factories may only be added once. * \param factory The ghoul::TemplateFactory to add to this FactoryManager + * \param name A user-readable name for the registered factory. * \pre \p factory must not be nullptr */ - void addFactory(std::unique_ptr factory); + void addFactory(std::unique_ptr factory, + std::string name = ""); /** * This method provides access to all registered ghoul::TemplateFactory%s through @@ -102,11 +104,25 @@ public: template ghoul::TemplateFactory* factory() const; + /** + * Writes a documentation for the FactoryMananger that contains all of the registered + * factories and for each factory all registered class names. + * \param file The file to which the documentation will be written + * \param type The type of documentation that will be written + * \pre \p file must not be empty + * \pre \p type must not be empty + */ + void writeDocumentation(const std::string& file, const std::string& type); + private: /// Singleton member for the Factory Manager static FactoryManager* _manager; - std::vector> _factories; + struct FactoryInfo { + std::unique_ptr factory; + std::string name; + }; + std::vector _factories; }; } // namespace openspace diff --git a/include/openspace/util/factorymanager.inl b/include/openspace/util/factorymanager.inl index 7f9989f619..dde01bcef5 100644 --- a/include/openspace/util/factorymanager.inl +++ b/include/openspace/util/factorymanager.inl @@ -27,8 +27,8 @@ namespace openspace { template ghoul::TemplateFactory* FactoryManager::factory() const { for (auto& factory : _factories) { - if (factory->baseClassType() == typeid(T)) - return dynamic_cast*>(factory.get()); + if (factory.factory->baseClassType() == typeid(T)) + return dynamic_cast*>(factory.factory.get()); } throw FactoryNotFoundError(typeid(T).name()); diff --git a/include/openspace/util/openspacemodule.h b/include/openspace/util/openspacemodule.h index 350c853f65..2cda76686a 100644 --- a/include/openspace/util/openspacemodule.h +++ b/include/openspace/util/openspacemodule.h @@ -27,6 +27,8 @@ #include +#include + #include #include @@ -64,6 +66,8 @@ public: */ void deinitialize(); + virtual std::vector documentations() const; + protected: /** * Customization point for each derived class. The internalInitialize method is called diff --git a/include/openspace/util/syncdata.h b/include/openspace/util/syncdata.h new file mode 100644 index 0000000000..7eb638dc6c --- /dev/null +++ b/include/openspace/util/syncdata.h @@ -0,0 +1,134 @@ +/***************************************************************************************** + * * + * 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 __SYNC_DATA_H__ +#define __SYNC_DATA_H__ + +#include +#include + +#include +#include + + +namespace openspace { + + +/** +* Interface for synchronizable data +* +* Used by SyncEngine +*/ +class Syncable { +public: + virtual ~Syncable() {}; + +protected: + // Allowing SyncEngine synchronization methods and at the same time hiding them + // from the used of implementations of the interface + friend class SyncEngine; + virtual void presync(bool isMaster) {}; + virtual void encode(SyncBuffer* syncBuffer) = 0; + virtual void decode(SyncBuffer* syncBuffer) = 0; + virtual void postsync(bool isMaster) {}; +}; + +/** +* A double buffered implementation of the Syncable interface. +* Users are encouraged to used this class as a default way to synchronize different +* C++ data types using the SyncEngine +* +* This class aims to handle the synchronization parts and yet act like a regular +* instance of T. Implicit casts are supported, however, when accessing member functions or +* or variables, user may have to do explicit casts. +* +* ((T&) t).method(); +* +*/ +template +class SyncData : public Syncable { +public: + + SyncData() {}; + SyncData(const T& val) : data(val) {}; + SyncData(const SyncData& o) : data(o.data) { + // Should not have to be copied! + }; + + /** + * Allowing assignment of data as if + */ + SyncData& operator=(const T& rhs) { + data = rhs; + return *this; + } + + /** + * Allow implicit cast to referenced T + */ + operator T&() { + return data; + } + + /** + * Allow implicit cast to const referenced T + */ + operator const T&() const { + return data; + } + +protected: + + virtual void encode(SyncBuffer* syncBuffer) { + _mutex.lock(); + syncBuffer->encode(data); + _mutex.unlock(); + } + + virtual void decode(SyncBuffer* syncBuffer) { + _mutex.lock(); + syncBuffer->decode(doubleBufferedData); + _mutex.unlock(); + } + + virtual void postsync(bool isMaster) { + // apply synced update + if (!isMaster) { + _mutex.lock(); + data = doubleBufferedData; + _mutex.unlock(); + } + }; + + + T data; + T doubleBufferedData; + std::mutex _mutex; + +}; + + +} // namespace openspace + +#endif //#ifndef __SYNC_DATA_H__ diff --git a/include/openspace/util/time.h b/include/openspace/util/time.h index 8820bcbcc0..2275c95eec 100644 --- a/include/openspace/util/time.h +++ b/include/openspace/util/time.h @@ -26,6 +26,7 @@ #define __TIME_H__ #include +#include #include #include @@ -40,7 +41,7 @@ namespace openspace { * a valid date string in accordance to the Spice library * (http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/str2et_c.html). The time can * be retrieved as the number of seconds since the J2000 epoch with currentTime() or as a - * UTC string following ISO 8601 with the method currentTimeUTC(). + * UTC string following ISO 8601 with the method UTC(). * * In addition to the time itself, it also stores a delta time value. This value denotes * the number of seconds that pass for each real-time second. This value is set with @@ -102,7 +103,7 @@ public: * time-jump; defaults to true as most calls to set time will require recomputation of * planetary paths etc. */ - void setTime(double value, bool requireJump = true); + void setTime(double j2000Seconds, bool requireJump = true); /** * Sets the current time to the specified value given as a Spice compliant string as @@ -120,16 +121,14 @@ public: * current time is a date before that epoch, the returned value will be negative. * \return The current time as the number of seconds past the J2000 epoch */ - double currentTime() const; - - double unsyncedJ2000Seconds() const; + double j2000Seconds() const; /** * Returns the current time as a formatted date string compliant with ISO 8601 and * thus also compliant with the Spice library. * \return The current time as a formatted date string */ - std::string currentTimeUTC() const; + std::string UTC() const; /** * Returns the current time as a ISO 8601 formatted, i.e YYYY-MM-DDThh:mm:ssZ @@ -182,14 +181,6 @@ public: */ double advanceTime(double tickTime); - void serialize(SyncBuffer* syncBuffer); - - void deserialize(SyncBuffer* syncBuffer); - - void postSynchronizationPreDraw(); - - void preSynchronization(); - bool timeJumped() const; void setTimeJumped(bool jumped); @@ -209,28 +200,16 @@ public: */ static scripting::LuaLibrary luaLibrary(); + std::vector getSyncables(); + private: static Time* _instance; ///< The singleton instance - - //local copies - /// The time stored as the number of seconds past the J2000 epoch - double _time = -1.0; - double _dt = 1.0; - bool _timeJumped = false; - bool _timePaused = false; - bool _jockeHasToFixThisLater; - //shared copies - double _sharedTime = -1.0; - double _sharedDt = 1.0; - bool _sharedTimeJumped = false; + SyncData _time; + SyncData _dt; + SyncData _timeJumped; - //synced copies - double _syncedTime = -1.0; - double _syncedDt = 1.0; - bool _syncedTimeJumped = false; - - std::mutex _syncMutex; + bool _timePaused = false; }; } // namespace openspace diff --git a/include/openspace/util/updatestructures.h b/include/openspace/util/updatestructures.h index 44e8ff25e3..22ed70bef7 100644 --- a/include/openspace/util/updatestructures.h +++ b/include/openspace/util/updatestructures.h @@ -50,12 +50,14 @@ struct UpdateData { bool doPerformanceMeasurement; }; + struct RenderData { const Camera& camera; // psc position to be removed in favor of the double precision position defined in // the translation in transform. psc position; bool doPerformanceMeasurement; + int renderBinMask; TransformData modelTransform; }; diff --git a/modules/base/basemodule.cpp b/modules/base/basemodule.cpp index 196913f848..e1725442fe 100644 --- a/modules/base/basemodule.cpp +++ b/modules/base/basemodule.cpp @@ -65,12 +65,27 @@ BaseModule::BaseModule() {} void BaseModule::internalInitialize() { - FactoryManager::ref().addFactory(std::make_unique>()); - FactoryManager::ref().addFactory(std::make_unique>()); - FactoryManager::ref().addFactory(std::make_unique>()); + FactoryManager::ref().addFactory( + std::make_unique>(), + "PlanetGeometry" + ); + FactoryManager::ref().addFactory( + std::make_unique>(), + "ModelGeometry" + ); + FactoryManager::ref().addFactory( + std::make_unique>(), + "ScreenSpaceRenderable" + ); - FactoryManager::ref().addFactory(std::make_unique>()); - FactoryManager::ref().addFactory(std::make_unique>()); + FactoryManager::ref().addFactory( + std::make_unique>(), + "Rotation" + ); + FactoryManager::ref().addFactory( + std::make_unique>(), + "Scale" + ); auto fScreenSpaceRenderable = FactoryManager::ref().factory(); ghoul_assert(fScreenSpaceRenderable, "ScreenSpaceRenderable factory was not created"); @@ -119,4 +134,12 @@ void BaseModule::internalInitialize() { fModelGeometry->registerClass("MultiModelGeometry"); } +std::vector BaseModule::documentations() const { + return { + StaticScale::Documentation(), + StaticEphemeris::Documentation(), + SpiceEphemeris::Documentation() + }; +} + } // namespace openspace diff --git a/modules/base/basemodule.h b/modules/base/basemodule.h index ffad43acf1..f9838dbe31 100644 --- a/modules/base/basemodule.h +++ b/modules/base/basemodule.h @@ -33,6 +33,8 @@ class BaseModule : public OpenSpaceModule { public: BaseModule(); + std::vector documentations() const override; + protected: void internalInitialize() override; }; diff --git a/modules/base/ephemeris/spiceephemeris.cpp b/modules/base/ephemeris/spiceephemeris.cpp index 36c81ac26a..59d6e6a1b4 100644 --- a/modules/base/ephemeris/spiceephemeris.cpp +++ b/modules/base/ephemeris/spiceephemeris.cpp @@ -27,76 +27,120 @@ #include #include -namespace { - const std::string _loggerCat = "SpiceEphemeris"; - //const std::string keyGhosting = "EphmerisGhosting"; +#include +#include + +namespace { const std::string KeyBody = "Body"; - const std::string KeyOrigin = "Observer"; + const std::string KeyObserver = "Observer"; const std::string KeyKernels = "Kernels"; + + const std::string ReferenceFrame = "GALACTIC"; } namespace openspace { +Documentation SpiceEphemeris::Documentation() { + using namespace openspace::documentation; + + return { + "Spice Translation", + "base_translation_spicetranslation", + { + { + "Type", + new StringEqualVerifier("SpiceEphemeris"), + "", + Optional::No + }, + { + KeyBody, + new StringAnnotationVerifier("A valid SPICE NAIF name or identifier"), + "This is the SPICE NAIF name for the body whose translation is to be " + "computed by the SpiceTranslation. It can either be a fully qualified " + "name (such as 'EARTH') or a NAIF integer id code (such as '399').", + Optional::No + }, + { + KeyObserver, + new StringAnnotationVerifier("A valid SPICE NAIF name or identifier"), + "This is the SPICE NAIF name for the parent of the body whose " + "translation is to be computed by the SpiceTranslation. It can either be " + "a fully qualified name (such as 'SOLAR SYSTEM BARYCENTER') or a NAIF " + "integer id code (such as '0').", + Optional::No + }, + { + KeyKernels, + new OrVerifier( + new TableVerifier({ + { "*", new StringVerifier } + }), + new StringVerifier + ), + "A single kernel or list of kernels that this SpiceTranslation depends " + "on. All provided kernels will be loaded before any other operation is " + "performed.", + Optional::Yes + } + }, + Exhaustive::Yes + }; +} + SpiceEphemeris::SpiceEphemeris(const ghoul::Dictionary& dictionary) - : _targetName("") - , _originName("") - , _position() + : _target("target", "Target", "") + , _origin("origin", "Origin", "") , _kernelsLoadedSuccessfully(true) { - const bool hasBody = dictionary.getValue(KeyBody, _targetName); - if (!hasBody) - LERROR("SpiceEphemeris does not contain the key '" << KeyBody << "'"); + documentation::testSpecificationAndThrow( + Documentation(), + dictionary, + "SpiceEphemeris" + ); - const bool hasObserver = dictionary.getValue(KeyOrigin, _originName); - if (!hasObserver) - LERROR("SpiceEphemeris does not contain the key '" << KeyOrigin << "'"); + _target = dictionary.value(KeyBody); + _origin = dictionary.value(KeyObserver); - //dictionary.getValue(keyGhosting, _ghosting); - - ghoul::Dictionary kernels; - dictionary.getValue(KeyKernels, kernels); - for (size_t i = 1; i <= kernels.size(); ++i) { - std::string kernel; - bool success = kernels.getValue(std::to_string(i), kernel); - if (!success) - LERROR("'" << KeyKernels << "' has to be an array-style table"); + auto loadKernel = [](const std::string& kernel) { + if (!FileSys.fileExists(kernel)) { + throw SpiceManager::SpiceException("Kernel '" + kernel + "' does not exist"); + } try { SpiceManager::ref().loadKernel(kernel); - _kernelsLoadedSuccessfully = true; } - catch (const SpiceManager::SpiceException& e) { - LERROR("Could not load SPICE kernel: " << e.what()); - _kernelsLoadedSuccessfully = false; + catch (const SpiceManager::SpiceException& exception) { + LERRORC("SpiceEphemeris", exception.message); + } + }; + + if (dictionary.hasKey(KeyKernels)) { + // Due to the specification, we can be sure it is either a Dictionary or a string + if (dictionary.hasValue(KeyKernels)) { + std::string kernel = dictionary.value(KeyKernels); + loadKernel(kernel); + } + else { + ghoul::Dictionary kernels = dictionary.value(KeyKernels); + for (size_t i = 1; i <= kernels.size(); ++i) { + std::string kernel = kernels.value(std::to_string(i)); + loadKernel(kernel); + } } } } -const glm::dvec3& SpiceEphemeris::position() const { +glm::dvec3 SpiceEphemeris::position() const { return _position; } void SpiceEphemeris::update(const UpdateData& data) { - if (!_kernelsLoadedSuccessfully) - return; - double lightTime = 0.0; - glm::dvec3 position = SpiceManager::ref().targetPosition( - _targetName, _originName, "GALACTIC", {}, data.time, lightTime); - - //double interval = openspace::ImageSequencer::ref().getIntervalLength(); - //if (_ghosting == "TRUE" && interval > 60){ - // double _time = openspace::ImageSequencer::ref().getNextCaptureTime(); - // SpiceManager::ref().getTargetPosition(_targetName, _originName, - // "GALACTIC", "NONE", _time, position, lightTime); - //} - // - - - //_position = psc::CreatePowerScaledCoordinate(position.x, position.y, position.z); - //_position[3] += 3; - _position = position * glm::pow(10.0, 3.0); + _position = SpiceManager::ref().targetPosition( + _target, _origin, ReferenceFrame, {}, data.time, lightTime + ) * glm::pow(10.0, 3.0); } -} // namespace openspace \ No newline at end of file +} // namespace openspace diff --git a/modules/base/ephemeris/spiceephemeris.h b/modules/base/ephemeris/spiceephemeris.h index 973c388072..92d9991e1e 100644 --- a/modules/base/ephemeris/spiceephemeris.h +++ b/modules/base/ephemeris/spiceephemeris.h @@ -27,23 +27,25 @@ #include -#include +#include +#include namespace openspace { class SpiceEphemeris : public Ephemeris { public: SpiceEphemeris(const ghoul::Dictionary& dictionary); - virtual const glm::dvec3& position() const; + glm::dvec3 position() const; void update(const UpdateData& data) override; + static openspace::Documentation Documentation(); + private: - std::string _targetName; - std::string _originName; + properties::StringProperty _target; + properties::StringProperty _origin; + glm::dvec3 _position; bool _kernelsLoadedSuccessfully; - //std::string _ghosting; - std::string _name; }; } // namespace openspace diff --git a/modules/base/ephemeris/staticephemeris.cpp b/modules/base/ephemeris/staticephemeris.cpp index e95e324546..551da7a05c 100644 --- a/modules/base/ephemeris/staticephemeris.cpp +++ b/modules/base/ephemeris/staticephemeris.cpp @@ -24,27 +24,69 @@ #include +#include + namespace { const std::string KeyPosition = "Position"; } namespace openspace { -StaticEphemeris::StaticEphemeris(const ghoul::Dictionary& dictionary) - : _position(0.0, 0.0, 0.0) +Documentation StaticEphemeris::Documentation() { + using namespace openspace::documentation; + return { + "Static Translation", + "base_transform_translation_static", + { + { + "Type", + new StringEqualVerifier("StaticEphemeris"), + "", + Optional::No + }, + { + KeyPosition, + new DoubleVector3Verifier, + "Specifies the position (in meters) that this scenegraph node is located " + "at relative to its parent", + Optional::No + } + }, + Exhaustive::Yes + }; +} + + +StaticEphemeris::StaticEphemeris() + : _position( + "position", + "Position", + glm::dvec3(0.0), + glm::dvec3(-std::numeric_limits::max()), + glm::dvec3(std::numeric_limits::max()) + ) { - const bool hasPosition = dictionary.hasKeyAndValue(KeyPosition); - if (hasPosition) { - dictionary.getValue(KeyPosition, _position); - } + addProperty(_position); +} + +StaticEphemeris::StaticEphemeris(const ghoul::Dictionary& dictionary) + : StaticEphemeris() +{ + documentation::testSpecificationAndThrow( + Documentation(), + dictionary, + "StaticEphemeris" + ); + + _position = dictionary.value(KeyPosition); } StaticEphemeris::~StaticEphemeris() {} -const glm::dvec3& StaticEphemeris::position() const { +glm::dvec3 StaticEphemeris::position() const { return _position; } void StaticEphemeris::update(const UpdateData&) {} -} // namespace openspace \ No newline at end of file +} // namespace openspace diff --git a/modules/base/ephemeris/staticephemeris.h b/modules/base/ephemeris/staticephemeris.h index 491a872b7a..d85f3eba41 100644 --- a/modules/base/ephemeris/staticephemeris.h +++ b/modules/base/ephemeris/staticephemeris.h @@ -27,17 +27,23 @@ #include +#include +#include + namespace openspace { -class StaticEphemeris: public Ephemeris { +class StaticEphemeris : public Ephemeris { public: - StaticEphemeris(const ghoul::Dictionary& dictionary - = ghoul::Dictionary()); + StaticEphemeris(); + StaticEphemeris(const ghoul::Dictionary& dictionary); virtual ~StaticEphemeris(); - virtual const glm::dvec3& position() const; + virtual glm::dvec3 position() const; virtual void update(const UpdateData& data) override; + + static openspace::Documentation Documentation(); + private: - glm::dvec3 _position; + properties::DVec3Property _position; }; } // namespace openspace diff --git a/modules/base/rendering/modelgeometry.cpp b/modules/base/rendering/modelgeometry.cpp index 507e38ce81..655c883a2e 100644 --- a/modules/base/rendering/modelgeometry.cpp +++ b/modules/base/rendering/modelgeometry.cpp @@ -125,9 +125,9 @@ bool ModelGeometry::initialize(Renderable* parent) { for (auto v: _vertices) { maximumDistanceSquared = glm::max( - glm::pow(v.location[0], 2) + - glm::pow(v.location[1], 2) + - glm::pow(v.location[2], 2), maximumDistanceSquared); + glm::pow(v.location[0], 2.f) + + glm::pow(v.location[1], 2.f) + + glm::pow(v.location[2], 2.f), maximumDistanceSquared); } _parent->setBoundingSphere(PowerScaledScalar(glm::sqrt(maximumDistanceSquared), 0.0)); diff --git a/modules/base/rendering/renderablemodel.cpp b/modules/base/rendering/renderablemodel.cpp index 376fe8cf81..c98e2480c5 100644 --- a/modules/base/rendering/renderablemodel.cpp +++ b/modules/base/rendering/renderablemodel.cpp @@ -178,7 +178,7 @@ void RenderableModel::render(const RenderData& data) { double lt; // Fade away if it does not have spice coverage - double time = openspace::Time::ref().currentTime(); + double time = openspace::Time::ref().j2000Seconds(); bool targetPositionCoverage = openspace::SpiceManager::ref().hasSpkCoverage(_target, time); if (!targetPositionCoverage) { int frame = _frameCount % 180; @@ -211,7 +211,7 @@ void RenderableModel::render(const RenderData& data) { glm::dmat4 modelTransform = glm::translate(glm::dmat4(1.0), data.modelTransform.translation) * // Translation glm::dmat4(data.modelTransform.rotation) * // Spice rotation - glm::dmat4(glm::scale(glm::dmat4(1.0), glm::dvec3(data.modelTransform.scale))); + glm::dmat4(glm::scale(glm::dmat4(_modelTransform), glm::dvec3(data.modelTransform.scale))); debugModelRotation; // debug model rotation controlled from GUI glm::dmat4 modelViewTransform = data.camera.combinedViewMatrix() * modelTransform; diff --git a/modules/base/rendering/renderablepath.cpp b/modules/base/rendering/renderablepath.cpp index 29ced4620b..be5547aefd 100644 --- a/modules/base/rendering/renderablepath.cpp +++ b/modules/base/rendering/renderablepath.cpp @@ -141,7 +141,7 @@ bool RenderablePath::isReady() const { } void RenderablePath::render(const RenderData& data) { - double time = openspace::Time::ref().currentTime(); + double time = openspace::Time::ref().j2000Seconds(); if (_start > time || _stop < time) return; diff --git a/modules/base/rendering/renderableplane.cpp b/modules/base/rendering/renderableplane.cpp index a2e7ff9b08..3d43ee6c66 100644 --- a/modules/base/rendering/renderableplane.cpp +++ b/modules/base/rendering/renderableplane.cpp @@ -60,6 +60,7 @@ RenderablePlane::RenderablePlane(const ghoul::Dictionary& dictionary) , _shader(nullptr) , _textureIsDirty(false) , _texture(nullptr) + , _blendMode(BlendMode::Normal) , _quad(0) , _vertexPositionBuffer(0) { @@ -67,7 +68,7 @@ RenderablePlane::RenderablePlane(const ghoul::Dictionary& dictionary) dictionary.getValue("Size", size); _size = size; - if (dictionary.hasKey("Name")){ + if (dictionary.hasKey("Name")) { dictionary.getValue("Name", _nodeName); } @@ -102,6 +103,13 @@ RenderablePlane::RenderablePlane(const ghoul::Dictionary& dictionary) } } + std::string blendMode; + if (dictionary.getValue("BlendMode", blendMode)) { + if (blendMode == "Additive") { + _blendMode = BlendMode::Additive; + setRenderBin(Renderable::RenderBin::Transparent); + } + } std::string texturePath = ""; bool success = dictionary.getValue("Texture", texturePath); @@ -228,9 +236,30 @@ void RenderablePlane::render(const RenderData& data) { _texture->bind(); _shader->setUniform("texture1", unit); + bool usingFramebufferRenderer = + OsEng.renderEngine().rendererImplementation() == RenderEngine::RendererImplementation::Framebuffer; + + bool usingABufferRenderer = + OsEng.renderEngine().rendererImplementation() == RenderEngine::RendererImplementation::ABuffer; + + if (usingABufferRenderer) { + _shader->setUniform("additiveBlending", _blendMode == BlendMode::Additive); + } + + bool additiveBlending = _blendMode == BlendMode::Additive && usingFramebufferRenderer; + if (additiveBlending) { + glDepthMask(false); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + } + glBindVertexArray(_quad); glDrawArrays(GL_TRIANGLES, 0, 6); + if (additiveBlending) { + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDepthMask(true); + } + _shader->deactivate(); } diff --git a/modules/base/rendering/renderableplane.h b/modules/base/rendering/renderableplane.h index eaa5cf4445..fc4e8f795c 100644 --- a/modules/base/rendering/renderableplane.h +++ b/modules/base/rendering/renderableplane.h @@ -51,6 +51,11 @@ class RenderablePlane : public Renderable { }; public: + enum class BlendMode : int { + Normal = 0, + Additive + }; + RenderablePlane(const ghoul::Dictionary& dictionary); ~RenderablePlane(); @@ -79,6 +84,7 @@ private: std::unique_ptr _shader; bool _textureIsDirty; std::unique_ptr _texture; + BlendMode _blendMode; ghoul::filesystem::File* _textureFile; GLuint _quad; GLuint _vertexPositionBuffer; diff --git a/modules/base/rendering/renderableplanet.cpp b/modules/base/rendering/renderableplanet.cpp index 8cc278a29c..eac80732c3 100644 --- a/modules/base/rendering/renderableplanet.cpp +++ b/modules/base/rendering/renderableplanet.cpp @@ -599,8 +599,7 @@ bool RenderablePlanet::isReady() const { return ready; } -void RenderablePlanet::render(const RenderData& data) -{ +void RenderablePlanet::render(const RenderData& data) { // activate shader _programObject->activate(); diff --git a/modules/base/rendering/renderabletrail.cpp b/modules/base/rendering/renderabletrail.cpp index 3ca3e60ce4..a95cb3054d 100644 --- a/modules/base/rendering/renderabletrail.cpp +++ b/modules/base/rendering/renderabletrail.cpp @@ -124,6 +124,7 @@ bool RenderableTrail::initialize() { "${MODULE_BASE}/shaders/ephemeris_vs.glsl", "${MODULE_BASE}/shaders/ephemeris_fs.glsl"); + setRenderBin(Renderable::RenderBin::Overlay); if (!_programObject) return false; @@ -192,6 +193,14 @@ void RenderableTrail::render(const RenderData& data) { // _programObject->setUniform("forceFade", _distanceFade); //} + bool usingFramebufferRenderer = + OsEng.renderEngine().rendererImplementation() == RenderEngine::RendererImplementation::Framebuffer; + + if (usingFramebufferRenderer) { + glDepthMask(false); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + } + glLineWidth(_lineWidth); glBindVertexArray(_vaoID); @@ -207,6 +216,12 @@ void RenderableTrail::render(const RenderData& data) { glBindVertexArray(0); } + + if (usingFramebufferRenderer) { + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDepthMask(true); + } + _programObject->deactivate(); } diff --git a/modules/base/scale/staticscale.cpp b/modules/base/scale/staticscale.cpp index ff1573e61c..214847d290 100644 --- a/modules/base/scale/staticscale.cpp +++ b/modules/base/scale/staticscale.cpp @@ -24,27 +24,44 @@ #include +#include + namespace { + const std::string _loggerCat = "StaticScale"; const std::string KeyValue = "Scale"; } namespace openspace { -StaticScale::StaticScale(const ghoul::Dictionary& dictionary) - : _scaleValue(1.0) -{ - const bool hasValue = dictionary.hasKeyAndValue(KeyValue); - if (hasValue) { - dictionary.getValue(KeyValue, _scaleValue); - } +Documentation StaticScale::Documentation() { + using namespace openspace::documentation; + return { + "Static Scaling", + {{ + KeyValue, + new DoubleVerifier, + "The scaling factor by which the scenegraph node is scaled." + }} + }; } -StaticScale::~StaticScale() {} +StaticScale::StaticScale() + : _scaleValue("scale", "Scale", 1.0, 1.0, 1000.0) +{ + addProperty(_scaleValue); +} + + +StaticScale::StaticScale(const ghoul::Dictionary& dictionary) + : StaticScale() +{ + documentation::testSpecificationAndThrow(Documentation(), dictionary, "StaticScale"); + + _scaleValue = dictionary.value(KeyValue); +} double StaticScale::scaleValue() const { return _scaleValue; } -void StaticScale::update(const UpdateData&) {} - -} // namespace openspace \ No newline at end of file +} // namespace openspace diff --git a/modules/base/scale/staticscale.h b/modules/base/scale/staticscale.h index 68f2d65c1b..e99e07fd60 100644 --- a/modules/base/scale/staticscale.h +++ b/modules/base/scale/staticscale.h @@ -27,17 +27,20 @@ #include +#include + namespace openspace { -class StaticScale: public Scale { +class StaticScale : public Scale { public: - StaticScale(const ghoul::Dictionary& dictionary - = ghoul::Dictionary()); - virtual ~StaticScale(); - virtual double scaleValue() const; - virtual void update(const UpdateData& data) override; + StaticScale(); + StaticScale(const ghoul::Dictionary& dictionary); + double scaleValue() const; + + static openspace::Documentation Documentation(); + private: - double _scaleValue; + properties::FloatProperty _scaleValue; }; } // namespace openspace diff --git a/modules/base/shaders/ephemeris_fs.glsl b/modules/base/shaders/ephemeris_fs.glsl index 46e46fa916..a77149b371 100644 --- a/modules/base/shaders/ephemeris_fs.glsl +++ b/modules/base/shaders/ephemeris_fs.glsl @@ -32,10 +32,11 @@ in float fade; #include "fragment.glsl" Fragment getFragment() { - vec4 c = vec4(color, fade*forceFade); - + vec4 c = vec4(color * fade * forceFade, 1.0); Fragment frag; frag.color = c; frag.depth = vs_positionScreenSpace.w; + frag.blend = BLEND_MODE_ADDITIVE; + return frag; -} \ No newline at end of file +} diff --git a/modules/base/shaders/plane_fs.glsl b/modules/base/shaders/plane_fs.glsl index a8d20ee5b2..bfabe1ccb9 100644 --- a/modules/base/shaders/plane_fs.glsl +++ b/modules/base/shaders/plane_fs.glsl @@ -24,6 +24,7 @@ uniform float time; uniform sampler2D texture1; +uniform bool additiveBlending; in vec2 vs_st; in vec4 vs_positionScreenSpace; @@ -50,6 +51,10 @@ Fragment getFragment() { Fragment frag; frag.color = diffuse; frag.depth = vs_positionScreenSpace.w; + + if (additiveBlending) { + frag.blend = BLEND_MODE_ADDITIVE; + } return frag; } diff --git a/modules/debugging/rendering/renderabledebugplane.cpp b/modules/debugging/rendering/renderabledebugplane.cpp index da2378fee1..98077c7a7b 100644 --- a/modules/debugging/rendering/renderabledebugplane.cpp +++ b/modules/debugging/rendering/renderabledebugplane.cpp @@ -26,8 +26,6 @@ #include - -#include #include #include diff --git a/modules/globebrowsing/CMakeLists.txt b/modules/globebrowsing/CMakeLists.txt index 69353783a9..e73af3e486 100644 --- a/modules/globebrowsing/CMakeLists.txt +++ b/modules/globebrowsing/CMakeLists.txt @@ -50,10 +50,11 @@ set(HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/tileprovider.h ${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/singleimageprovider.h - ${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/chunkindextileprovider.h + ${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/texttileprovider.h ${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/cachingtileprovider.h ${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/temporaltileprovider.h + ${CMAKE_CURRENT_SOURCE_DIR}/tile/tile.h ${CMAKE_CURRENT_SOURCE_DIR}/tile/tileselector.h ${CMAKE_CURRENT_SOURCE_DIR}/tile/tilediskcache.h ${CMAKE_CURRENT_SOURCE_DIR}/tile/tiledataset.h @@ -62,7 +63,6 @@ set(HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/tile/tileioresult.h ${CMAKE_CURRENT_SOURCE_DIR}/tile/asynctilereader.h ${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovidermanager.h - ${CMAKE_CURRENT_SOURCE_DIR}/tile/tileproviderfactory.h ${CMAKE_CURRENT_SOURCE_DIR}/tile/layeredtextureshaderprovider.h ${CMAKE_CURRENT_SOURCE_DIR}/tile/layeredtextures.h ${CMAKE_CURRENT_SOURCE_DIR}/tile/pixelregion.h @@ -102,11 +102,11 @@ set(SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/tileprovider.cpp ${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/singleimageprovider.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/chunkindextileprovider.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/texttileprovider.cpp ${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/cachingtileprovider.cpp ${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/temporaltileprovider.cpp - + ${CMAKE_CURRENT_SOURCE_DIR}/tile/tile.cpp ${CMAKE_CURRENT_SOURCE_DIR}/tile/tileselector.cpp ${CMAKE_CURRENT_SOURCE_DIR}/tile/tilediskcache.cpp ${CMAKE_CURRENT_SOURCE_DIR}/tile/tiledataset.cpp @@ -114,7 +114,6 @@ set(SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/tile/tileioresult.cpp ${CMAKE_CURRENT_SOURCE_DIR}/tile/asynctilereader.cpp ${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovidermanager.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/tile/tileproviderfactory.cpp ${CMAKE_CURRENT_SOURCE_DIR}/tile/layeredtextureshaderprovider.cpp ${CMAKE_CURRENT_SOURCE_DIR}/tile/layeredtextures.cpp ${CMAKE_CURRENT_SOURCE_DIR}/tile/pixelregion.cpp diff --git a/modules/globebrowsing/Doxyfile b/modules/globebrowsing/Doxyfile new file mode 100644 index 0000000000..7c52cb1206 --- /dev/null +++ b/modules/globebrowsing/Doxyfile @@ -0,0 +1,451 @@ +# Doxyfile 1.7.6.1 + +#--------------------------------------------------------------------------- +# 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 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +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_TESTLIST = NO +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = NO +SHOW_FILES = NO +SHOW_NAMESPACES = YES +LAYOUT_FILE = + +#--------------------------------------------------------------------------- +# 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 +#--------------------------------------------------------------------------- + +INPUT = . + +INPUT_ENCODING = UTF-8 +FILE_PATTERNS = *.c \ + *.cpp \ + *.h \ + *.inl + +RECURSIVE = YES +EXCLUDE = ext/ +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXCLUDE_SYMBOLS = + +#--------------------------------------------------------------------------- +# 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 +#--------------------------------------------------------------------------- + +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 +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 +#--------------------------------------------------------------------------- + +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/modules/globebrowsing/chunk/chunk.cpp b/modules/globebrowsing/chunk/chunk.cpp index 6af4f01ccd..da46d3ac56 100644 --- a/modules/globebrowsing/chunk/chunk.cpp +++ b/modules/globebrowsing/chunk/chunk.cpp @@ -144,31 +144,6 @@ namespace openspace { } } - const TileProviderGroup& heightmapOverlays = tileProviderManager->getTileProviderGroup(LayeredTextures::HeightMapOverlays); - TileAndTransform mostHighResHeightmapOverlay = TileSelector::getHighestResolutionTile(heightmapOverlays, _index); - if (mostHighResHeightmapOverlay.tile.status == Tile::Status::OK) { - auto preprocessData = mostHighResHeightmapOverlay.tile.preprocessData; - if (preprocessData != nullptr && preprocessData->minValues[0] < preprocessData->maxValues[0]) { - if (boundingHeights.available) { - boundingHeights.min = std::min(boundingHeights.min, preprocessData->minValues[0]); - boundingHeights.max = std::max(boundingHeights.max, preprocessData->maxValues[0]); - } - else { - boundingHeights.min = preprocessData->minValues[0]; - boundingHeights.max = preprocessData->maxValues[0]; - boundingHeights.available = true; - - if (preprocessData->hasMissingData[0]) { - boundingHeights.min = std::min(DEFAULT_HEIGHT, preprocessData->minValues[0]); - boundingHeights.max = std::max(DEFAULT_HEIGHT, preprocessData->maxValues[0]); - } - } - } - } - - - - return boundingHeights; } diff --git a/modules/globebrowsing/chunk/chunkedlodglobe.cpp b/modules/globebrowsing/chunk/chunkedlodglobe.cpp index 967bf6bac4..83378d7d6b 100644 --- a/modules/globebrowsing/chunk/chunkedlodglobe.cpp +++ b/modules/globebrowsing/chunk/chunkedlodglobe.cpp @@ -156,7 +156,7 @@ namespace openspace { stats.startNewRecord(); - int j2000s = Time::now().unsyncedJ2000Seconds(); + int j2000s = Time::now().j2000Seconds(); auto duration = std::chrono::system_clock::now().time_since_epoch(); auto millis = std::chrono::duration_cast(duration).count(); @@ -180,7 +180,7 @@ namespace openspace { stats.i["chunks leafs"]++; if (chunk.isVisible()) { stats.i["rendered chunks"]++; - double t0 = Time::now().unsyncedJ2000Seconds(); + double t0 = Time::now().j2000Seconds(); _renderer->renderChunk(chunkNode.getChunk(), data); debugRenderChunk(chunk, mvp); } @@ -214,7 +214,7 @@ namespace openspace { const vec4& clippingSpaceCorner = mvp * modelSpaceCorners[i]; clippingSpaceCorners[i] = clippingSpaceCorner; - vec3 screenSpaceCorner = (1.0f / clippingSpaceCorner.w) * clippingSpaceCorner.xyz(); + vec3 screenSpaceCorner = (1.0f / clippingSpaceCorner.w) * clippingSpaceCorner; screenSpaceBounds.expand(screenSpaceCorner); } diff --git a/modules/globebrowsing/chunk/chunkrenderer.cpp b/modules/globebrowsing/chunk/chunkrenderer.cpp index c8315376b8..7d7cc560fe 100644 --- a/modules/globebrowsing/chunk/chunkrenderer.cpp +++ b/modules/globebrowsing/chunk/chunkrenderer.cpp @@ -95,7 +95,7 @@ namespace openspace { void ChunkRenderer::setDepthTransformUniforms( std::shared_ptr uniformIdHandler, LayeredTextures::TextureCategory textureCategory, - LayeredTextureShaderUniformIdHandler::BlendLayerSuffix blendLayerSuffix, + LayeredTextureShaderUniformIdHandler::BlendLayerSuffixes blendLayerSuffix, size_t layerIndex, const TileDepthTransform& tileDepthTransform) { @@ -120,7 +120,7 @@ namespace openspace { void ChunkRenderer::activateTileAndSetTileUniforms( std::shared_ptr uniformIdHandler, LayeredTextures::TextureCategory textureCategory, - LayeredTextureShaderUniformIdHandler::BlendLayerSuffix blendLayerSuffix, + LayeredTextureShaderUniformIdHandler::BlendLayerSuffixes blendLayerSuffix, size_t layerIndex, ghoul::opengl::TextureUnit& texUnit, const TileAndTransform& tileAndTransform) @@ -244,7 +244,7 @@ namespace openspace { activateTileAndSetTileUniforms( programUniformHandler, LayeredTextures::TextureCategory(category), - LayeredTextureShaderUniformIdHandler::BlendLayerSuffix::none, + LayeredTextureShaderUniformIdHandler::BlendLayerSuffixes::none, i, texUnits[category][i].blendTexture0, tileAndTransform); @@ -258,7 +258,7 @@ namespace openspace { activateTileAndSetTileUniforms( programUniformHandler, LayeredTextures::TextureCategory(category), - LayeredTextureShaderUniformIdHandler::BlendLayerSuffix::Parent1, + LayeredTextureShaderUniformIdHandler::BlendLayerSuffixes::Parent1, i, texUnits[category][i].blendTexture1, tileAndTransformParent1); @@ -270,7 +270,7 @@ namespace openspace { activateTileAndSetTileUniforms( programUniformHandler, LayeredTextures::TextureCategory(category), - LayeredTextureShaderUniformIdHandler::BlendLayerSuffix::Parent2, + LayeredTextureShaderUniformIdHandler::BlendLayerSuffixes::Parent2, i, texUnits[category][i].blendTexture2, tileAndTransformParent2); @@ -300,24 +300,7 @@ namespace openspace { setDepthTransformUniforms( programUniformHandler, LayeredTextures::TextureCategory::HeightMaps, - LayeredTextureShaderUniformIdHandler::BlendLayerSuffix::none, - i, - depthTransform); - i++; - } - - // Go through all the height map overlays and set depth tranforms - i = 0; - it = tileProviders[LayeredTextures::HeightMapOverlays].begin(); - end = tileProviders[LayeredTextures::HeightMapOverlays].end(); - for (; it != end; it++) { - auto tileProvider = *it; - - TileDepthTransform depthTransform = tileProvider->depthTransform(); - setDepthTransformUniforms( - programUniformHandler, - LayeredTextures::TextureCategory::HeightMapOverlays, - LayeredTextureShaderUniformIdHandler::BlendLayerSuffix::none, + LayeredTextureShaderUniformIdHandler::BlendLayerSuffixes::none, i, depthTransform); i++; @@ -383,11 +366,13 @@ namespace openspace { programObject->setUniform("radiiSquared", vec3(ellipsoid.radiiSquared())); if (_tileProviderManager->getTileProviderGroup( - LayeredTextures::NightTextures).getActiveTileProviders().size() > 0) { + LayeredTextures::NightTextures).getActiveTileProviders().size() > 0 || + _tileProviderManager->getTileProviderGroup( + LayeredTextures::WaterMasks).getActiveTileProviders().size() > 0) { glm::vec3 directionToSunWorldSpace = glm::normalize(-data.modelTransform.translation); glm::vec3 directionToSunCameraSpace = - (viewTransform * glm::dvec4(directionToSunWorldSpace, 0)).xyz(); + (viewTransform * glm::dvec4(directionToSunWorldSpace, 0)); data.modelTransform.translation; programObject->setUniform("modelViewTransform", modelViewTransform); programObject->setUniform("lightDirectionCameraSpace", -directionToSunCameraSpace); @@ -460,11 +445,13 @@ namespace openspace { programObject->setUniform("projectionTransform", data.camera.projectionMatrix()); if (_tileProviderManager->getTileProviderGroup( - LayeredTextures::NightTextures).getActiveTileProviders().size() > 0) { + LayeredTextures::NightTextures).getActiveTileProviders().size() > 0 || + _tileProviderManager->getTileProviderGroup( + LayeredTextures::WaterMasks).getActiveTileProviders().size() > 0) { glm::vec3 directionToSunWorldSpace = glm::normalize(-data.modelTransform.translation); glm::vec3 directionToSunCameraSpace = - (viewTransform * glm::dvec4(directionToSunWorldSpace, 0)).xyz(); + (viewTransform * glm::dvec4(directionToSunWorldSpace, 0)); data.modelTransform.translation; programObject->setUniform("lightDirectionCameraSpace", -directionToSunCameraSpace); } diff --git a/modules/globebrowsing/chunk/chunkrenderer.h b/modules/globebrowsing/chunk/chunkrenderer.h index c0b11601f1..cd45c41d2d 100644 --- a/modules/globebrowsing/chunk/chunkrenderer.h +++ b/modules/globebrowsing/chunk/chunkrenderer.h @@ -68,14 +68,14 @@ namespace openspace { void setDepthTransformUniforms( std::shared_ptr uniformIdHandler, LayeredTextures::TextureCategory textureCategory, - LayeredTextureShaderUniformIdHandler::BlendLayerSuffix blendLayerSuffix, + LayeredTextureShaderUniformIdHandler::BlendLayerSuffixes blendLayerSuffix, size_t layerIndex, const TileDepthTransform& tileDepthTransform); void activateTileAndSetTileUniforms( std::shared_ptr uniformIdHandler, LayeredTextures::TextureCategory textureCategory, - LayeredTextureShaderUniformIdHandler::BlendLayerSuffix blendLayerSuffix, + LayeredTextureShaderUniformIdHandler::BlendLayerSuffixes blendLayerSuffix, size_t layerIndex, ghoul::opengl::TextureUnit& texUnit, const TileAndTransform& tileAndTransform); diff --git a/modules/globebrowsing/chunk/culling.cpp b/modules/globebrowsing/chunk/culling.cpp index 88a3d802dd..c281f6d7cb 100644 --- a/modules/globebrowsing/chunk/culling.cpp +++ b/modules/globebrowsing/chunk/culling.cpp @@ -72,7 +72,7 @@ namespace openspace { dvec4 cornerClippingSpace = modelViewProjectionTransform * corners[i]; clippingSpaceCorners[i] = cornerClippingSpace; - dvec3 cornerScreenSpace = (1.0f / glm::abs(cornerClippingSpace.w)) * cornerClippingSpace.xyz(); + dvec3 cornerScreenSpace = (1.0f / glm::abs(cornerClippingSpace.w)) * cornerClippingSpace; bounds.expand(cornerScreenSpace); } diff --git a/modules/globebrowsing/geometry/ellipsoid.cpp b/modules/globebrowsing/geometry/ellipsoid.cpp index 2dc96f427d..b77bd1c9aa 100644 --- a/modules/globebrowsing/geometry/ellipsoid.cpp +++ b/modules/globebrowsing/geometry/ellipsoid.cpp @@ -115,15 +115,20 @@ namespace openspace { sin(geodetic2.lat)); } - Vec3 Ellipsoid::radiiSquared() const { + const Vec3& Ellipsoid::radii() const { + return _radii; + } + + + const Vec3& Ellipsoid::radiiSquared() const { return _cached._radiiSquared; } - Vec3 Ellipsoid::oneOverRadiiSquared() const { + const Vec3& Ellipsoid::oneOverRadiiSquared() const { return _cached._oneOverRadiiSquared; } - Vec3 Ellipsoid::radiiToTheFourth() const { + const Vec3& Ellipsoid::radiiToTheFourth() const { return _cached._radiiToTheFourth; } @@ -139,6 +144,27 @@ namespace openspace { return (_radii.x + _radii.y + _radii.z) / 3.0; } + Scalar Ellipsoid::longitudalDistance(Scalar lat, Scalar lon1, Scalar lon2) const { + Vec2 ellipseRadii = glm::cos(lat) * Vec2(_radii); + // Approximating with the ellipse mean radius + Scalar meanRadius = 0.5 * (ellipseRadii.x + ellipseRadii.y); + return meanRadius * std::abs(lon2 - lon1); + } + + Scalar Ellipsoid::greatCircleDistance(const Geodetic2& p1, const Geodetic2& p2) const{ + // https://en.wikipedia.org/wiki/Meridian_arc + // https://en.wikipedia.org/wiki/Great-circle_distance#Vector_version + + Vec3 n1 = geodeticSurfaceNormal(p1); + Vec3 n2 = geodeticSurfaceNormal(p2); + Scalar centralAngle = glm::atan(glm::length(glm::cross(n1, n2)) / glm::dot(n1, n2)); + + Geodetic2 pMid = (p1 + p2) / 2; + Vec3 centralNormal = cartesianSurfacePosition(pMid); + + return centralAngle * glm::length(centralNormal); + } + Geodetic2 Ellipsoid::cartesianToGeodetic2(const Vec3& p) const { Vec3 normal = geodeticSurfaceNormalForGeocentricallyProjectedPoint(p); diff --git a/modules/globebrowsing/geometry/ellipsoid.h b/modules/globebrowsing/geometry/ellipsoid.h index 041d729ccd..a65c3d00e8 100644 --- a/modules/globebrowsing/geometry/ellipsoid.h +++ b/modules/globebrowsing/geometry/ellipsoid.h @@ -76,14 +76,19 @@ public: Vec3 geodeticSurfaceNormalForGeocentricallyProjectedPoint(const Vec3& p) const; Vec3 geodeticSurfaceNormal(Geodetic2 geodetic2) const; - Vec3 radiiSquared() const; - Vec3 oneOverRadiiSquared() const; - Vec3 radiiToTheFourth() const; + const Vec3& radii() const; + const Vec3& radiiSquared() const; + const Vec3& oneOverRadiiSquared() const; + const Vec3& radiiToTheFourth() const; + Scalar minimumRadius() const; Scalar maximumRadius() const; Scalar averageRadius() const; + Scalar longitudalDistance(Scalar lat, Scalar lon1, Scalar lon2) const; + Scalar greatCircleDistance(const Geodetic2& p1, const Geodetic2& p2) const; + Geodetic2 cartesianToGeodetic2(const Vec3& p) const; Vec3 cartesianSurfacePosition(const Geodetic2& geodetic2) const; Vec3 cartesianPosition(const Geodetic3& geodetic3) const; diff --git a/modules/globebrowsing/globebrowsingmodule.cpp b/modules/globebrowsing/globebrowsingmodule.cpp index c4bdc00a2b..7f511f938b 100644 --- a/modules/globebrowsing/globebrowsingmodule.cpp +++ b/modules/globebrowsing/globebrowsingmodule.cpp @@ -30,8 +30,15 @@ #include #include +#include #include +#include +#include +#include +#include +#include + namespace openspace { @@ -40,28 +47,24 @@ namespace openspace { {} void GlobeBrowsingModule::internalInitialize() { - /* - auto fRenderable = FactoryManager::ref().factory(); - ghoul_assert(fRenderable, "Renderable factory was not created"); - - fRenderable->registerClass("Planet"); - fRenderable->registerClass("RenderableTestPlanet"); - //fRenderable->registerClass("PlanetTestGeometry"); - - auto fPlanetGeometry = FactoryManager::ref().factory(); - ghoul_assert(fPlanetGeometry, "Planet test geometry factory was not created"); - fPlanetGeometry->registerClass("SimpleSphereTest"); - - */ - - - - auto fRenderable = FactoryManager::ref().factory(); ghoul_assert(fRenderable, "Renderable factory was not created"); - fRenderable->registerClass("RenderableGlobe"); + + void addFactory(std::unique_ptr factory); + + // add Tile Provider factory + FactoryManager::ref().addFactory( + std::make_unique>()); + + auto fTileProvider = FactoryManager::ref().factory(); + fTileProvider->registerClass("LRUCaching"); + fTileProvider->registerClass("SingleImage"); + fTileProvider->registerClass("Temporal"); + fTileProvider->registerClass("ChunkIndex"); + fTileProvider->registerClass("SizeReference"); + } } // namespace openspace diff --git a/modules/globebrowsing/globes/renderableglobe.cpp b/modules/globebrowsing/globes/renderableglobe.cpp index d32146008d..52b5f012b0 100644 --- a/modules/globebrowsing/globes/renderableglobe.cpp +++ b/modules/globebrowsing/globes/renderableglobe.cpp @@ -61,13 +61,14 @@ namespace openspace { RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary) - : _isEnabled(properties::BoolProperty(" Enabled", " Enabled", true)) + : _isEnabled(properties::BoolProperty("Enabled", "Enabled", true)) + , _toggleEnabledEveryFrame(properties::BoolProperty("Toggle enabled every frame", "Toggle enabled every frame", false)) , _saveOrThrowCamera(properties::BoolProperty("saveOrThrowCamera", "saveOrThrowCamera")) , _resetTileProviders(properties::BoolProperty("resetTileProviders", "resetTileProviders")) , _cameraMinHeight(properties::FloatProperty("cameraMinHeight", "cameraMinHeight", 100.0f, 0.0f, 1000.0f)) , lodScaleFactor(properties::FloatProperty("lodScaleFactor", "lodScaleFactor", 10.0f, 1.0f, 50.0f)) , debugSelection(ReferencedBoolSelection("Debug", "Debug")) - , atmosphereEnabled(properties::BoolProperty(" Atmosphere", " Atmosphere", false)) + , atmosphereEnabled(properties::BoolProperty("Atmosphere", "Atmosphere", false)) { setName("RenderableGlobe"); @@ -103,6 +104,7 @@ namespace openspace { _distanceSwitch.addSwitchValue(_chunkedLodGlobe, 1e12); addProperty(_isEnabled); + addProperty(_toggleEnabledEveryFrame); // Add debug options - must be after chunkedLodGlobe has been created as it @@ -122,7 +124,7 @@ namespace openspace { // Add all tile layers as being toggleable for each category for (int i = 0; i < LayeredTextures::NUM_TEXTURE_CATEGORIES; i++){ LayeredTextures::TextureCategory category = (LayeredTextures::TextureCategory) i; - std::string categoryName = std::to_string(i+1) + ". " + LayeredTextures::TEXTURE_CATEGORY_NAMES[i]; + std::string categoryName = LayeredTextures::TEXTURE_CATEGORY_NAMES[i]; auto selection = std::make_unique(categoryName, categoryName); auto& categoryProviders = _tileProviderManager->getTileProviderGroup(category); @@ -164,6 +166,9 @@ namespace openspace { } void RenderableGlobe::render(const RenderData& data) { + if (_toggleEnabledEveryFrame.value()) { + _isEnabled.setValue(!_isEnabled.value()); + } if (_isEnabled.value()) { if (_saveOrThrowCamera.value()) { _saveOrThrowCamera.setValue(false); @@ -234,14 +239,14 @@ namespace openspace { // Sample and do linear interpolation (could possibly be moved as a function in ghoul texture) glm::uvec3 dimensions = tile.texture->dimensions(); - glm::vec2 samplePos = transformedUv * glm::vec2(dimensions.xy()); + glm::vec2 samplePos = transformedUv * glm::vec2(dimensions); glm::uvec2 samplePos00 = samplePos; - samplePos00 = glm::clamp(samplePos00, glm::uvec2(0, 0), dimensions.xy() - glm::uvec2(1)); + samplePos00 = glm::clamp(samplePos00, glm::uvec2(0, 0), glm::uvec2(dimensions) - glm::uvec2(1)); glm::vec2 samplePosFract = samplePos - glm::vec2(samplePos00); - glm::uvec2 samplePos10 = glm::min(samplePos00 + glm::uvec2(1, 0), dimensions.xy() - glm::uvec2(1)); - glm::uvec2 samplePos01 = glm::min(samplePos00 + glm::uvec2(0, 1), dimensions.xy() - glm::uvec2(1)); - glm::uvec2 samplePos11 = glm::min(samplePos00 + glm::uvec2(1, 1), dimensions.xy() - glm::uvec2(1)); + glm::uvec2 samplePos10 = glm::min(samplePos00 + glm::uvec2(1, 0), glm::uvec2(dimensions) - glm::uvec2(1)); + glm::uvec2 samplePos01 = glm::min(samplePos00 + glm::uvec2(0, 1), glm::uvec2(dimensions) - glm::uvec2(1)); + glm::uvec2 samplePos11 = glm::min(samplePos00 + glm::uvec2(1, 1), glm::uvec2(dimensions) - glm::uvec2(1)); float sample00 = tile.texture->texelAsFloat(samplePos00).x; float sample10 = tile.texture->texelAsFloat(samplePos10).x; diff --git a/modules/globebrowsing/globes/renderableglobe.h b/modules/globebrowsing/globes/renderableglobe.h index 528c5c2668..f854a94156 100644 --- a/modules/globebrowsing/globes/renderableglobe.h +++ b/modules/globebrowsing/globes/renderableglobe.h @@ -121,6 +121,7 @@ public: // Properties properties::BoolProperty _isEnabled; + properties::BoolProperty _toggleEnabledEveryFrame; properties::FloatProperty lodScaleFactor; std::vector> _categorySelections; properties::BoolProperty atmosphereEnabled; diff --git a/modules/globebrowsing/meshes/basicgrid.h b/modules/globebrowsing/meshes/basicgrid.h index 8bfcf4e263..05097758da 100644 --- a/modules/globebrowsing/meshes/basicgrid.h +++ b/modules/globebrowsing/meshes/basicgrid.h @@ -55,15 +55,14 @@ public: TriangleSoup::Normals useNormals); ~BasicGrid(); - virtual int xSegments() const; virtual int ySegments() const; private: - virtual std::vector CreateElements( int xRes, int yRes); - virtual std::vector CreatePositions( int xRes, int yRes); - virtual std::vector CreateTextureCoordinates( int xRes, int yRes); - virtual std::vector CreateNormals( int xRes, int yRes); + virtual std::vector CreateElements(int xRes, int yRes); + virtual std::vector CreatePositions(int xRes, int yRes); + virtual std::vector CreateTextureCoordinates(int xRes, int yRes); + virtual std::vector CreateNormals(int xRes, int yRes); void validate(int xSegments, int ySegments); diff --git a/modules/globebrowsing/meshes/grid.h b/modules/globebrowsing/meshes/grid.h index 00728991c4..30986a04c6 100644 --- a/modules/globebrowsing/meshes/grid.h +++ b/modules/globebrowsing/meshes/grid.h @@ -34,6 +34,12 @@ namespace openspace { +/** +* Abstract class defining an interface used for geometries with grid structures. +* The class Grid should be extended for use of geometries with a 2D +* structure where the number of segments in x and y direction represents the number +* of vertices + 1 in each direction. +*/ class Grid { public: @@ -48,22 +54,45 @@ public: TriangleSoup& geometry(); /** - Returns the number of grid cells in the x direction. Hence the number of vertices - in the x direction is xResolution + 1. + * Returns the number of grid cells in the x direction. Hence the number of vertices + * in the x direction is xResolution + 1. */ virtual int xSegments() const = 0; /** - Returns the number of grid cells in the y direction. Hence the number of vertices - in the y direction is xResolution + 1. + * Returns the number of grid cells in the y direction. Hence the number of vertices + * in the y direction is xResolution + 1. */ virtual int ySegments() const = 0; protected: - virtual std::vector CreateElements( int xSegments, int ySegments) = 0; - virtual std::vector CreatePositions( int xSegments, int ySegments) = 0; - virtual std::vector CreateTextureCoordinates( int xSegments, int ySegments) = 0; - virtual std::vector CreateNormals( int xSegments, int ySegments) = 0; + /** + * Should return the indices of vertices for a grid with size xSegments * + * ySegments. Where the number of vertices in each direction is the number + * of segments + 1. + */ + virtual std::vector CreateElements(int xSegments, int ySegments) = 0; + + /** + * Should return the positions of vertices for a grid with size xSegments * + * ySegments. Where the number of vertices in each direction is the number + * of segments + 1. + */ + virtual std::vector CreatePositions(int xSegments, int ySegments) = 0; + + /** + * Should return the texture coordinates of vertices for a grid with size + * xSegments * ySegments. Where the number of vertices in + * each direction is the number of segments + 1. + */ + virtual std::vector CreateTextureCoordinates(int xSegments, int ySegments) = 0; + + /** + * Should return the normals of vertices for a grid with size xSegments * + * ySegments. Where the number of vertices in each direction is the number + * of segments + 1. + */ + virtual std::vector CreateNormals(int xSegments, int ySegments) = 0; std::unique_ptr _geometry; diff --git a/modules/globebrowsing/meshes/skirtedgrid.h b/modules/globebrowsing/meshes/skirtedgrid.h index 4f8b5339ea..57669006df 100644 --- a/modules/globebrowsing/meshes/skirtedgrid.h +++ b/modules/globebrowsing/meshes/skirtedgrid.h @@ -34,18 +34,24 @@ namespace openspace { +/** +* This grid is the same as BasicGrid except it has skirts around its edges. +* The areas covered by the skirts have position coordinates and texture coordinates +* that are outside of the range [0, 1]. The width of the skirts is half the size of one +* segment width or a cell. +*/ class SkirtedGrid : public Grid { public: /** - \param xSegments is the number of grid cells in the x direction. - \param ySegments is the number of grid cells in the y direction. - \param usePositions determines whether or not to upload any vertex position data - to the GPU. - \param useTextureCoordinates determines whether or not to upload any vertex texture - coordinate data to the GPU. - \param useNormals determines whether or not to upload any vertex normal data - to the GPU. + * \param xSegments is the number of grid cells in the x direction. + * \param ySegments is the number of grid cells in the y direction. + * \param usePositions determines whether or not to upload any vertex position data + * to the GPU. + * \param useTextureCoordinates determines whether or not to upload any vertex texture + * coordinate data to the GPU. + * \param useNormals determines whether or not to upload any vertex normal data + * to the GPU. */ SkirtedGrid( unsigned int xSegments, @@ -55,7 +61,6 @@ public: TriangleSoup::Normals useNormals); ~SkirtedGrid(); - virtual int xSegments() const; virtual int ySegments() const; diff --git a/modules/globebrowsing/meshes/trianglesoup.cpp b/modules/globebrowsing/meshes/trianglesoup.cpp index adfbad88e8..f50e88601b 100644 --- a/modules/globebrowsing/meshes/trianglesoup.cpp +++ b/modules/globebrowsing/meshes/trianglesoup.cpp @@ -36,9 +36,9 @@ TriangleSoup::TriangleSoup(std::vector elements, : _vaoID(0) ,_vertexBufferID(0) ,_elementBufferID(0) - ,_useVertexPositions(usePositions == Positions::Yes) - ,_useTextureCoordinates(useTextures == TextureCoordinates::Yes) - ,_useVertexNormals(useNormals == Normals::Yes) + ,_useVertexPositions(usePositions) + ,_useTextureCoordinates(useTextures) + ,_useVertexNormals(useNormals) { setElements(elements); } @@ -49,7 +49,6 @@ TriangleSoup::~TriangleSoup() { glDeleteVertexArrays(1, &_vaoID); } - void TriangleSoup::setVertexPositions(std::vector positions) { _useVertexPositions = true; _gpuDataNeedUpdate = true; @@ -63,7 +62,6 @@ void TriangleSoup::setVertexPositions(std::vector positions) { } } - void TriangleSoup::setVertexTextureCoordinates(std::vector textures) { _useTextureCoordinates = true; _gpuDataNeedUpdate = true; @@ -75,7 +73,6 @@ void TriangleSoup::setVertexTextureCoordinates(std::vector textures) } } - void TriangleSoup::setVertexNormals(std::vector normals) { _useVertexNormals = true; _gpuDataNeedUpdate = true; @@ -88,7 +85,6 @@ void TriangleSoup::setVertexNormals(std::vector normals) { } } - void TriangleSoup::setElements(std::vector elements) { _elementData.resize(elements.size()); _gpuDataNeedUpdate = true; @@ -98,7 +94,7 @@ void TriangleSoup::setElements(std::vector elements) { } } -bool TriangleSoup::updateDataInGPU() { +bool TriangleSoup::updateDataOnGPU() { // Create VAO if (_vaoID == 0) glGenVertexArrays(1, &_vaoID); @@ -119,7 +115,6 @@ bool TriangleSoup::updateDataInGPU() { } } - // First VAO setup glBindVertexArray(_vaoID); @@ -167,7 +162,7 @@ bool TriangleSoup::updateDataInGPU() { void TriangleSoup::drawUsingActiveProgram() { if (_gpuDataNeedUpdate) { - updateDataInGPU(); + updateDataOnGPU(); } glBindVertexArray(_vaoID); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _elementBufferID); diff --git a/modules/globebrowsing/meshes/trianglesoup.h b/modules/globebrowsing/meshes/trianglesoup.h index d2291e8a66..c80988c29a 100644 --- a/modules/globebrowsing/meshes/trianglesoup.h +++ b/modules/globebrowsing/meshes/trianglesoup.h @@ -25,6 +25,7 @@ #ifndef __TRIANGLESOUP_H__ #define __TRIANGLESOUP_H__ +#include #include #include @@ -35,21 +36,20 @@ namespace openspace { /** - Class to hold vertex data and handling OpenGL interfacing and rendering. A Geometry - has all data needed such as position buffer and normal buffer but all data is not - necessarily needed for all purpouses so the Geometry can disable use of normals for - example. +* Class to hold vertex data and handling OpenGL interfacing and rendering. +* A TriangleSoup has all data needed such as position buffer and normal +* buffer but all data is not necessarily needed for all purpouses so some vertex buffers +* such as normals can be disabled if not needed. */ - // TODO : Possibly render triangle strips in this class instead of triangles since - // that is faster - +// TODO : Possibly render triangle strips in this class instead of triangles since +// that is faster class TriangleSoup { public: - enum class Positions { Yes, No }; - enum class TextureCoordinates { Yes, No }; - enum class Normals { Yes, No }; + using Positions = ghoul::Boolean; + using TextureCoordinates = ghoul::Boolean; + using Normals = ghoul::Boolean; TriangleSoup( std::vector elements, // At least elements are required @@ -64,8 +64,14 @@ public: void setVertexNormals(std::vector normals); void setElements(std::vector elements); - - + /** + * Calls OpenGL's draw function to draw the triangles defined in the vertex buffers + * using the current bound program object. + * The vertex buffer attribute input locations to the shader program comes in the + * order of positions (0), texture coordinates (1) and normals (2). + * The input locations in the shader program should be specified to match these + * locations. + */ void drawUsingActiveProgram(); protected: @@ -88,7 +94,7 @@ protected: std::vector _elementData; private: - bool updateDataInGPU(); + bool updateDataOnGPU(); // GL handles GLuint _vaoID; diff --git a/modules/globebrowsing/other/statscollector.h b/modules/globebrowsing/other/statscollector.h index e5b07d8920..3bb73728fa 100644 --- a/modules/globebrowsing/other/statscollector.h +++ b/modules/globebrowsing/other/statscollector.h @@ -24,6 +24,7 @@ #ifndef __STATS_TRACKER_H__ #define __STATS_TRACKER_H__ +#include #include #include @@ -143,13 +144,13 @@ namespace openspace { StatsCollector() = delete; - enum class Enabled { Yes, No }; + using Enabled = ghoul::Boolean; StatsCollector(const std::string& filename, int dumpEveryXRecord, Enabled enabled = Enabled::Yes, const std::string& delimiter = ",") : _filename(filename) , _dumpEveryXRecord(dumpEveryXRecord) , _recordsSinceLastDump(0) - , _enabled(enabled == Enabled::Yes) + , _enabled(enabled) , _delimiter(delimiter) , _hasWrittenHeader(false) , i(TemplatedStatsCollector(_enabled, delimiter)) diff --git a/modules/globebrowsing/shaders/texturetilemapping.hglsl b/modules/globebrowsing/shaders/texturetilemapping.hglsl index 06dd98309a..176d861cb6 100644 --- a/modules/globebrowsing/shaders/texturetilemapping.hglsl +++ b/modules/globebrowsing/shaders/texturetilemapping.hglsl @@ -33,11 +33,6 @@ #define USE_HEIGHTMAP #{useHeightMaps} #define HEIGHTMAP_BLENDING_ENABLED #{blendHeightMaps} -// First layer type from LayeredTextureShaderProvider is height map -#define NUMLAYERS_HEIGHTMAP_OVERLAY #{lastLayerIndexHeightMapOverlays} + 1 -#define USE_HEIGHTMAP_OVERLAY #{useHeightMapOverlays} -#define HEIGHTMAP_OVERLAY_BLENDING_ENABLED #{blendHeightMapOverlays} - // Second layer type from LayeredTextureShaderProvider is color texture #define NUMLAYERS_COLORTEXTURE #{lastLayerIndexColorTextures} + 1 #define USE_COLORTEXTURE #{useColorTextures} @@ -131,75 +126,6 @@ float calculateHeight( return height; } - - -float calculateUntransformedHeightOverlay( - float currentHeight, - vec2 uv, - LevelWeights levelWeights, - const Tile heightOverlayTiles[NUMLAYERS_HEIGHTMAP_OVERLAY], - const Tile heightOverlayTilesParent1[NUMLAYERS_HEIGHTMAP_OVERLAY], - const Tile heightOverlayTilesParent2[NUMLAYERS_HEIGHTMAP_OVERLAY]) { - - float height = currentHeight; - - // The shader compiler will remove unused code when variables are multiplied by - // a constant 0 -#if !HEIGHTMAP_OVERLAY_BLENDING_ENABLED - levelWeights = getDefaultLevelWeights(); -#endif // HEIGHTMAP_OVERLAY_BLENDING_ENABLED - - #for i in 0..#{lastLayerIndexHeightMapOverlays} - { - vec4 untransformedHeightSample = - levelWeights.w1 * getTexVal(heightOverlayTiles[#{i}], uv) + - levelWeights.w2 * getTexVal(heightOverlayTilesParent1[#{i}], uv) + - levelWeights.w3 * getTexVal(heightOverlayTilesParent2[#{i}], uv); - - if (untransformedHeightSample.g > 0.5){ - // Float datasets will return un-normalized values, and needs to - // be downscaled in order to be visualized. - float scaleFactor = 0.00005; - height = scaleFactor * untransformedHeightSample.r; - } - } - #endfor - - return height; -} - -float calculateHeightOverlay( - float currentHeight, - vec2 uv, - LevelWeights levelWeights, - const Tile heightOverlayTiles[NUMLAYERS_HEIGHTMAP_OVERLAY], - const Tile heightOverlayTilesParent1[NUMLAYERS_HEIGHTMAP_OVERLAY], - const Tile heightOverlayTilesParent2[NUMLAYERS_HEIGHTMAP_OVERLAY]) { - - float height = currentHeight; - - // The shader compiler will remove unused code when variables are multiplied by - // a constant 0 -#if !HEIGHTMAP_OVERLAY_BLENDING_ENABLED - levelWeights = getDefaultLevelWeights(); -#endif // HEIGHTMAP_OVERLAY_BLENDING_ENABLED - - #for i in 0..#{lastLayerIndexHeightMapOverlays} - { - vec4 untransformedHeightSample = - levelWeights.w1 * getTexVal(heightOverlayTiles[#{i}], uv) + - levelWeights.w2 * getTexVal(heightOverlayTilesParent1[#{i}], uv) + - levelWeights.w3 * getTexVal(heightOverlayTilesParent2[#{i}], uv); - - float heightSample = getTransformedTexVal(heightOverlayTiles[#{i}].depthTransform, untransformedHeightSample.r); - if (heightSample > -100000) - height = heightSample; - } - #endfor - - return height; -} - vec4 calculateColor( const vec2 uv, LevelWeights levelWeights, @@ -281,10 +207,12 @@ vec4 calculateNight( } #endfor - float cosineFactor = clamp(dot(-lightDirectionCameraSpace, ellipsoidNormalCameraSpace) * 3, 0, 1); - + //float cosineFactor = clamp(dot(-lightDirectionCameraSpace, ellipsoidNormalCameraSpace) * 3, 0, 1); + float shadowLight = 0.1; + float cosineFactor = clamp(dot(-lightDirectionCameraSpace, normalize(ellipsoidNormalCameraSpace)) * 3, -shadowLight, 1) + shadowLight; + // Blend night color with base color - vec4 color = vec4(cosineFactor * currentColor.xyz + (1 - cosineFactor) * vec3(nightColor * nightColor * 0.7), currentColor.a); + vec4 color = currentColor * 0.1 + 0.9 * vec4(cosineFactor * currentColor.xyz + (1 - cosineFactor) * vec3(nightColor * nightColor), currentColor.a); return color; } diff --git a/modules/globebrowsing/shaders/tilefragcolor.hglsl b/modules/globebrowsing/shaders/tilefragcolor.hglsl index 884b7b9df0..028e2244a3 100644 --- a/modules/globebrowsing/shaders/tilefragcolor.hglsl +++ b/modules/globebrowsing/shaders/tilefragcolor.hglsl @@ -43,7 +43,6 @@ uniform Tile ColorTexturesParent2[NUMLAYERS_COLORTEXTURE]; uniform Tile NightTextures[NUMLAYERS_NIGHTTEXTURE]; uniform Tile NightTexturesParent1[NUMLAYERS_NIGHTTEXTURE]; uniform Tile NightTexturesParent2[NUMLAYERS_NIGHTTEXTURE]; -uniform vec3 lightDirectionCameraSpace; #endif // USE_NIGHTTEXTURE #if USE_OVERLAY @@ -68,11 +67,14 @@ uniform Tile WaterMasksParent2[NUMLAYERS_WATERMASK]; uniform vec2 vertexResolution; #endif - #if USE_ATMOSPHERE // TODO atmosphere uniforms here #endif // USE_ATMOSPHERE +#if USE_NIGHTTEXTURE || USE_WATERMASK + uniform vec3 lightDirectionCameraSpace; +#endif + in vec4 fs_position; in vec2 fs_uv; in vec3 ellipsoidNormalCameraSpace; @@ -96,12 +98,6 @@ uniform Tile HeightMapsParent1[NUMLAYERS_HEIGHTMAP]; uniform Tile HeightMapsParent2[NUMLAYERS_HEIGHTMAP]; #endif // USE_HEIGHTMAP -#if USE_HEIGHTMAP_OVERLAY -uniform Tile HeightMapOverlays[NUMLAYERS_HEIGHTMAP_OVERLAY]; -uniform Tile HeightMapOverlaysParent1[NUMLAYERS_HEIGHTMAP_OVERLAY]; -uniform Tile HeightMapOverlaysParent2[NUMLAYERS_HEIGHTMAP_OVERLAY]; -#endif // USE_HEIGHTMAP_OVERLAY - float getUntransformedTileVertexHeight(vec2 uv, LevelWeights levelWeights){ float height = CHUNK_DEFAULT_HEIGHT; @@ -115,15 +111,6 @@ float getUntransformedTileVertexHeight(vec2 uv, LevelWeights levelWeights){ #endif // USE_HEIGHTMAP -#if USE_HEIGHTMAP_OVERLAY - height = calculateUntransformedHeightOverlay( - height, - uv, - levelWeights, // Variable to determine which texture to sample from - HeightMapOverlays, HeightMapOverlaysParent1, HeightMapOverlaysParent2); // Three textures to sample from - -#endif // USE_HEIGHTMAP_OVERLAY - return height; } @@ -165,8 +152,6 @@ vec4 getTileFragColor(){ #endif // USE_COLORTEXTURE #if USE_WATERMASK - // TODO: Jonathas magic goes here here - // TODO: This function needs more parameters and should update the fragment color for water color = calculateWater( color, fs_uv, @@ -174,15 +159,13 @@ vec4 getTileFragColor(){ WaterMasks, WaterMasksParent1, WaterMasksParent2, - ellipsoidNormalCameraSpace, - lightDirectionCameraSpace, + normalize(ellipsoidNormalCameraSpace), + lightDirectionCameraSpace, // Should already be normalized positionCameraSpace); #endif // USE_WATERMASK #if USE_NIGHTTEXTURE - // TODO: Jonathas magic goes here here - // TODO: This function needs more parameters and should update the fragment color for night texture color = calculateNight( color, fs_uv, @@ -190,14 +173,27 @@ vec4 getTileFragColor(){ NightTextures, NightTexturesParent1, NightTexturesParent2, - ellipsoidNormalCameraSpace, - lightDirectionCameraSpace); + normalize(ellipsoidNormalCameraSpace), + lightDirectionCameraSpace); // Should already be normalized #endif // USE_NIGHTTEXTURE #if USE_ATMOSPHERE - // TODO: Jonathas magic goes here here - color = color + vec4(0.5,0.5,1,0) * 0.3; // Just to see something for now + // Temporary until the real atmosphere code is here + //color = color + vec4(0.5,0.5,1,0) * 0.3; // Just to see something for now + vec3 n = normalize(ellipsoidNormalCameraSpace); + vec3 l = lightDirectionCameraSpace; + vec3 c = normalize(positionCameraSpace); + float cosFactor = clamp(dot(-n * 0.9, c), 0, 1); + float shadowLight = 0.3; + float cosFactorLight = max(dot(-l, n), -shadowLight) + shadowLight; + float cosFactorScatter = max(dot(l, n) + shadowLight, 0); + //float cosFactorLight = max(dot(-lightDirectionCameraSpace, normalize(ellipsoidNormalCameraSpace)), 0); + vec3 r = reflect(l, n); + float scatteredLight = pow(clamp(dot(-r,c), 0, 1), 20); + vec3 atmosphereColor = vec3(0.2,0.2,1) * (1 - (cosFactorScatter + scatteredLight)) + (cosFactorScatter + scatteredLight) * vec3(1,0.2,0.2); + color = color + vec4(atmosphereColor,0) * (1 - cosFactor) * cosFactorLight * 0.5; + #endif // USE_ATMOSPHERE #if USE_OVERLAY @@ -226,16 +222,11 @@ vec4 getTileFragColor(){ #if SHOW_HEIGHT_RESOLUTION - color += 0.0001*calculateDebugColor(fs_uv, fs_position, vertexResolution); #if USE_HEIGHTMAP color.r = min(color.r, 0.8); color.r += tileResolution(fs_uv, HeightMaps[0]) > 0.9 ? 1 : 0; #endif - #if USE_HEIGHTMAP_OVERLAY - color.g = min(color.g, 0.8); - color.g += tileResolution(fs_uv, HeightMapOverlays[0]) > 0.9 ? 1 : 0; - #endif // USE_HEIGHTMAP_OVERLAY #endif return color; diff --git a/modules/globebrowsing/shaders/tilevertexheight.hglsl b/modules/globebrowsing/shaders/tilevertexheight.hglsl index b39cfc833c..6ea6003dcc 100644 --- a/modules/globebrowsing/shaders/tilevertexheight.hglsl +++ b/modules/globebrowsing/shaders/tilevertexheight.hglsl @@ -36,12 +36,6 @@ uniform Tile HeightMapsParent1[NUMLAYERS_HEIGHTMAP]; uniform Tile HeightMapsParent2[NUMLAYERS_HEIGHTMAP]; #endif // USE_HEIGHTMAP -#if USE_HEIGHTMAP_OVERLAY -uniform Tile HeightMapOverlays[NUMLAYERS_HEIGHTMAP_OVERLAY]; -uniform Tile HeightMapOverlaysParent1[NUMLAYERS_HEIGHTMAP_OVERLAY]; -uniform Tile HeightMapOverlaysParent2[NUMLAYERS_HEIGHTMAP_OVERLAY]; -#endif // USE_HEIGHTMAP_OVERLAY - uniform int xSegments; uniform float skirtLength; @@ -62,15 +56,6 @@ float getUntransformedTileVertexHeight(vec2 uv, LevelWeights levelWeights){ #endif // USE_HEIGHTMAP -#if USE_HEIGHTMAP_OVERLAY - height = calculateUntransformedHeightOverlay( - height, - uv, - levelWeights, // Variable to determine which texture to sample from - HeightMapOverlays, HeightMapOverlaysParent1, HeightMapOverlaysParent2); // Three textures to sample from - -#endif // USE_HEIGHTMAP_OVERLAY - return height; } @@ -88,15 +73,6 @@ float getTileVertexHeight(vec2 uv, LevelWeights levelWeights){ #endif // USE_HEIGHTMAP -#if USE_HEIGHTMAP_OVERLAY - height = calculateHeightOverlay( - height, - uv, - levelWeights, // Variable to determine which texture to sample from - HeightMapOverlays, HeightMapOverlaysParent1, HeightMapOverlaysParent2); // Three textures to sample from - -#endif // USE_HEIGHTMAP_OVERLAY - return height; } diff --git a/modules/globebrowsing/tile/layeredtextures.cpp b/modules/globebrowsing/tile/layeredtextures.cpp index dfac6dab1a..906d23986c 100644 --- a/modules/globebrowsing/tile/layeredtextures.cpp +++ b/modules/globebrowsing/tile/layeredtextures.cpp @@ -44,7 +44,6 @@ namespace openspace { "WaterMasks", "Overlays", "HeightMaps", - "HeightMapOverlays", }; } // namespace openspace diff --git a/modules/globebrowsing/tile/layeredtextures.h b/modules/globebrowsing/tile/layeredtextures.h index 94292a1f26..ab6ca68241 100644 --- a/modules/globebrowsing/tile/layeredtextures.h +++ b/modules/globebrowsing/tile/layeredtextures.h @@ -35,7 +35,7 @@ namespace openspace { public: - static const size_t NUM_TEXTURE_CATEGORIES = 7; + static const size_t NUM_TEXTURE_CATEGORIES = 6; static const size_t MAX_NUM_TEXTURES_PER_CATEGORY = 5; enum TextureCategory { @@ -45,7 +45,6 @@ namespace openspace { WaterMasks, Overlays, HeightMaps, - HeightMapOverlays, }; static const std::string TEXTURE_CATEGORY_NAMES[NUM_TEXTURE_CATEGORIES]; diff --git a/modules/globebrowsing/tile/layeredtextureshaderprovider.cpp b/modules/globebrowsing/tile/layeredtextureshaderprovider.cpp index d64a6b84f4..a7af680705 100644 --- a/modules/globebrowsing/tile/layeredtextureshaderprovider.cpp +++ b/modules/globebrowsing/tile/layeredtextureshaderprovider.cpp @@ -111,21 +111,27 @@ namespace openspace { ghoul::Dictionary shaderDictionary; - // Different texture types can be height maps or color texture for example + // Different texture types can be height maps or color texture for example. // These are used differently within the shaders. auto textureTypes = _preprocessingData.layeredTextureInfo; for (size_t i = 0; i < textureTypes.size(); i++) { // lastLayerIndex must be at least 0 for the shader to compile, - // the layer type is inactivated by setting useThisLayerType to false + // the layer type is inactivated by setting use to false shaderDictionary.setValue( - LayeredTextureInfo::glslKeyPrefixes[LayeredTextureInfo::GlslKeyPrefixes::lastLayerIndex] + - LayeredTextures::TEXTURE_CATEGORY_NAMES[i], glm::max(textureTypes[i].lastLayerIdx, 0)); + LayeredTextureInfo::glslKeyPrefixes[ + LayeredTextureInfo::GlslKeyPrefixes::lastLayerIndex] + + LayeredTextures::TEXTURE_CATEGORY_NAMES[i], + glm::max(textureTypes[i].lastLayerIdx, 0)); shaderDictionary.setValue( - LayeredTextureInfo::glslKeyPrefixes[LayeredTextureInfo::GlslKeyPrefixes::use] + - LayeredTextures::TEXTURE_CATEGORY_NAMES[i], textureTypes[i].lastLayerIdx >= 0); + LayeredTextureInfo::glslKeyPrefixes[ + LayeredTextureInfo::GlslKeyPrefixes::use] + + LayeredTextures::TEXTURE_CATEGORY_NAMES[i], + textureTypes[i].lastLayerIdx >= 0); shaderDictionary.setValue( - LayeredTextureInfo::glslKeyPrefixes[LayeredTextureInfo::GlslKeyPrefixes::blend] + - LayeredTextures::TEXTURE_CATEGORY_NAMES[i], textureTypes[i].layerBlendingEnabled); + LayeredTextureInfo::glslKeyPrefixes[ + LayeredTextureInfo::GlslKeyPrefixes::blend] + + LayeredTextures::TEXTURE_CATEGORY_NAMES[i], + textureTypes[i].layerBlendingEnabled); } // Other settings such as "useAtmosphere" @@ -153,7 +159,8 @@ namespace openspace { } - const std::string LayeredTextureShaderUniformIdHandler::glslTileDataNames[NUM_TILE_DATA_VARIABLES] = + const std::string LayeredTextureShaderUniformIdHandler::glslTileDataNames[ + NUM_TILE_DATA_VARIABLES] = { "textureSampler", "depthTransform.depthScale", @@ -162,7 +169,8 @@ namespace openspace { "uvTransform.uvScale" }; - const std::string LayeredTextureShaderUniformIdHandler::blendLayerSuffixes[NUM_BLEND_TEXTURES] = + const std::string LayeredTextureShaderUniformIdHandler::blendLayerSuffixes[ + NUM_BLEND_TEXTURES] = { "", "Parent1", @@ -176,32 +184,40 @@ namespace openspace { LayeredTextureShaderUniformIdHandler::~LayeredTextureShaderUniformIdHandler() { + } - void LayeredTextureShaderUniformIdHandler::updateIdsIfNecessary(LayeredTextureShaderProvider* shaderProvider) + void LayeredTextureShaderUniformIdHandler::updateIdsIfNecessary( + LayeredTextureShaderProvider* shaderProvider) { if (shaderProvider->updatedOnLastCall()) { _shaderProvider = shaderProvider; - _shaderProvider->_programObject->setIgnoreUniformLocationError(ProgramObject::IgnoreError::Yes); + // Ignore errors since this loops through even uniforms that does not exist. + _shaderProvider->_programObject->setIgnoreUniformLocationError( + ProgramObject::IgnoreError::Yes); for (size_t i = 0; i < LayeredTextures::NUM_TEXTURE_CATEGORIES; i++) { for (size_t j = 0; j < NUM_BLEND_TEXTURES; j++) { - for (size_t k = 0; k < LayeredTextures::MAX_NUM_TEXTURES_PER_CATEGORY; k++) + for (size_t k = 0; k < LayeredTextures::MAX_NUM_TEXTURES_PER_CATEGORY; + k++) { for (size_t l = 0; l < NUM_TILE_DATA_VARIABLES; l++) { - _tileUniformIds[i][j][k][l] = _shaderProvider->_programObject->uniformLocation( - LayeredTextures::TEXTURE_CATEGORY_NAMES[i] + - blendLayerSuffixes[j] + - "[" + std::to_string(k) + "]." + - glslTileDataNames[l]); + _tileUniformIds[i][j][k][l] = + _shaderProvider->_programObject->uniformLocation( + LayeredTextures::TEXTURE_CATEGORY_NAMES[i] + + blendLayerSuffixes[j] + + "[" + std::to_string(k) + "]." + + glslTileDataNames[l]); } } } } - _shaderProvider->_programObject->setIgnoreUniformLocationError(ProgramObject::IgnoreError::No); + // Reset ignore errors + _shaderProvider->_programObject->setIgnoreUniformLocationError( + ProgramObject::IgnoreError::No); } } diff --git a/modules/globebrowsing/tile/layeredtextureshaderprovider.h b/modules/globebrowsing/tile/layeredtextureshaderprovider.h index 4c6ac01561..841afd7ace 100644 --- a/modules/globebrowsing/tile/layeredtextureshaderprovider.h +++ b/modules/globebrowsing/tile/layeredtextureshaderprovider.h @@ -25,15 +25,16 @@ #ifndef __LAYERED_TEXTURE_SHADER_PROVIDER__ #define __LAYERED_TEXTURE_SHADER_PROVIDER__ +#include + +#include "ghoul/opengl/programobject.h" + #include #include #include -#include "ghoul/opengl/programobject.h" - -#include ////////////////////////////////////////////////////////////////////////////////////////// -// LAYERED TEXTURE SHADER PROVIDER // +// LAYERED TEXTURE SHADER PROVIDER // ////////////////////////////////////////////////////////////////////////////////////////// namespace openspace { @@ -41,6 +42,9 @@ namespace openspace { class LayeredTextureShaderUniformIdHandler; + /** + * Settings per texture category that contains shader preprocessing information. + */ struct LayeredTextureInfo { static const size_t NUM_SETTINGS_PER_CATEGORY = 3; @@ -58,13 +62,27 @@ namespace openspace { bool operator==(const LayeredTextureInfo& other) const; }; + /** + * Data needed for shader preprocessing before compiling a layered texture shader + * program. + * + * If a LayeredTexturePreprocessingData is compared with another it can + * be determined wheter or not a LayeredTextureShaderProvider needs to + * recompile its shader program. For each TextureCategory there is + * information about how many layers it has and whether or not to blend the texture + * levels. + */ struct LayeredTexturePreprocessingData { - std::array layeredTextureInfo; + std::array + layeredTextureInfo; std::vector > keyValuePairs; bool operator==(const LayeredTexturePreprocessingData& other) const; }; + /** + * This class has ownership of an updated shader program for rendering tiles. + */ class LayeredTextureShaderProvider { public: @@ -74,6 +92,13 @@ namespace openspace { const std::string& fsPath); ~LayeredTextureShaderProvider(); + /** + * Returns a pointer to a ProgramObject for rendering tiles. + * \param preprocessingData determines wherer or not the shader + * program needs to be re-compiled. If preprocessingData is different + * from the last time this function was called the shader program will be + * recompiled before returned. + */ ProgramObject* getUpdatedShaderProgram( LayeredTexturePreprocessingData preprocessingData); @@ -92,14 +117,36 @@ namespace openspace { bool _updatedOnLastCall; }; + /** + * This class caches OpenGL uniform IDs for LayeredTextureShaderProviders. + */ class LayeredTextureShaderUniformIdHandler { - public: - static const size_t NUM_TILE_DATA_VARIABLES = 5; static const size_t NUM_BLEND_TEXTURES = 3; + /** + * Each texture can have these uniform variables associated with it in the shader + * code. + * + * textureSampler is the actual texture that can be sampled in the + * shader program. The associated GLSL type is sampler2D. + * depthTransform_depthScale specifies the scale part of the depth + * transform. Useful for height maps. The associated GLSL type is + * float. + * depthTransform_depthOffset specifies the offset part of the depth + * transform. Useful for height maps. The associated GLSL type is + * float. + * uvTransform_uvOffset specifies an offset that can be used when + * sampling from the texture. The associated GLSL type is vec2. + * uvTransform_uvScale specifies a scale that can be used when + * sampling from the texture. The associated GLSL type is vec2. + * + * The corresponding struct in GLSL code for storing these data is a + * Tile. The names of the uniforms are the ones specified in + * glslTileDataNames. + */ enum GlslTileDataId { textureSampler, depthTransform_depthScale, @@ -108,7 +155,13 @@ namespace openspace { uvTransform_uvScale, }; - enum BlendLayerSuffix { + /** + * These suffixes are used when naming Tiles in GLSL code. The names + * of the Tiles is one of + * LayeredTextures::TEXTURE_CATEGORY_NAMES followed by the suffixes + * defined in blendLayerSuffixes. + */ + enum BlendLayerSuffixes { none, Parent1, Parent2, @@ -118,6 +171,22 @@ namespace openspace { ~LayeredTextureShaderUniformIdHandler(); void updateIdsIfNecessary(LayeredTextureShaderProvider* shaderProvider); + /** + * \param category can be one of the categories specified in + * LayeredTextures::TextureCategory. + * \param blendLayer can have a value between 0 and + * NUM_BLEND_TEXTURES and specified that it is the uniform of that + * specific blend layer that is requested. + * \param layerIndex should have a value between 0 and + * LayeredTextures::MAX_NUM_TEXTURES_PER_CATEGORY - 1 and will specify + * which of the texture layers that is requested. + * \param tileDataId specifies what variable for the texture that + * should be returned. It can have any of the values specified in + * GlslTileDataId. + * + * \returns an OpenGL uniform ID for the specified arguments. If the uniform does + * not exist in the shader program it returns -1. + */ GLint getId( LayeredTextures::TextureCategory category, size_t blendLayer, @@ -140,9 +209,7 @@ namespace openspace { _tileUniformIds; LayeredTextureShaderProvider* _shaderProvider; - }; - } // namespace openspace #endif // __LAYERED_TEXTURE_SHADER_PROVIDER__ \ No newline at end of file diff --git a/modules/globebrowsing/tile/tileproviderfactory.h b/modules/globebrowsing/tile/tile.cpp similarity index 62% rename from modules/globebrowsing/tile/tileproviderfactory.h rename to modules/globebrowsing/tile/tile.cpp index d963d42f93..a7489dfe60 100644 --- a/modules/globebrowsing/tile/tileproviderfactory.h +++ b/modules/globebrowsing/tile/tile.cpp @@ -22,40 +22,51 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#ifndef __TILE_PROVIDER_FACTORY_H__ -#define __TILE_PROVIDER_FACTORY_H__ +#include +#include -#include - -#include - -#include -#include -#include +namespace { + const std::string _loggerCat = "Tile"; +} namespace openspace { - class TileProviderFactory { - public: + const Tile Tile::TileUnavailable = {nullptr, nullptr, Tile::Status::Unavailable }; + - static std::shared_ptr ref(); + Tile Tile::createPlainTile(const glm::uvec2& size, const glm::uvec4& color) { + using namespace ghoul::opengl; + + // Create pixel data + int numBytes = size.x * size.y * 4 * 1; + char* pixels = new char[numBytes]; + size_t numPixels = size.x * size.y; + size_t i = 0; + for (size_t p = 0; p < numPixels; p++){ + pixels[i++] = color.r; + pixels[i++] = color.g; + pixels[i++] = color.b; + pixels[i++] = color.a; + } - std::shared_ptr create(const std::string& type, const std::string& desc, const TileProviderInitData& initData); + // Create ghoul texture + auto texture = std::make_shared(glm::uvec3(size, 1)); + texture->setDataOwnership(Texture::TakeOwnership::Yes); + texture->setPixelData(pixels); + texture->uploadTexture(); + texture->setFilter(ghoul::opengl::Texture::FilterMode::Linear); - private: + // Create tile + Tile tile; + tile.status = Tile::Status::OK; + tile.preprocessData = nullptr; + tile.texture = texture; - TileProviderFactory(); - void initialize(); + return tile; + } - typedef std::function(const std::string&, const TileProviderInitData&)> ConcreteFactory; - std::unordered_map _factoryMap; - static std::shared_ptr _ref; - }; - - -} // namespace openspace -#endif // __TILE_PROVIDER_FACTORY_H__ \ No newline at end of file +} // namespace openspace diff --git a/modules/globebrowsing/tile/tile.h b/modules/globebrowsing/tile/tile.h new file mode 100644 index 0000000000..159fc855df --- /dev/null +++ b/modules/globebrowsing/tile/tile.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 __TILE_H__ +#define __TILE_H__ + +#include // Texture + +#include // TilePreprocessData + + +namespace openspace { + + using namespace ghoul::opengl; + + /** + * Defines a status and may have a Texture and PreprocessData + */ + struct Tile { + std::shared_ptr texture; + std::shared_ptr preprocessData; + + + /** + * Describe if this Tile is good for usage (OK) or otherwise + * the reason why it is not. + */ + enum class Status { + /** + * E.g when texture data is not currently in memory. + * texture and preprocessData are both null + */ + Unavailable, + + /** + * Can be set by TileProviders if the requested + * ChunkIndex is undefined for that particular + * provider. + * texture and preprocessData are both null + */ + OutOfRange, + + /** + * An IO Error happend + * texture and preprocessData are both null + */ + IOError, + + /** + * The Texture is uploaded to the GPU and good for usage. + * texture is defined. preprocessData may be defined. + */ + OK + } status; + + + /** + * Instantiates a new tile with a single color. + * + * \param size The size of texture to be created + * \param color defined RGBA values in range 0-255. + * + * \returns a Tile with status OK and the a texture + * with the requested size and color + */ + static Tile createPlainTile(const glm::uvec2& size, const glm::uvec4& color); + + /** + * A tile with status unavailable that any user can return to + * indicate that a tile was unavailable. + */ + static const Tile TileUnavailable; + + }; + +} // namespace openspace + + + + +#endif // __TILE_H__ \ No newline at end of file diff --git a/modules/globebrowsing/tile/tiledataset.cpp b/modules/globebrowsing/tile/tiledataset.cpp index 161b37dc9f..4c2d0bc781 100644 --- a/modules/globebrowsing/tile/tiledataset.cpp +++ b/modules/globebrowsing/tile/tiledataset.cpp @@ -611,10 +611,10 @@ namespace openspace { } } - if (depth == 0) { - LDEBUG(indentation << "main rasterIO read: " << io.read.region); - LDEBUG(indentation << "main rasterIO write: " << io.write.region); - } + //if (depth == 0) { + //LDEBUG(indentation << "main rasterIO read: " << io.read.region); + //LDEBUG(indentation << "main rasterIO write: " << io.write.region); + //} else if (worstError > CPLErr::CE_None) { LDEBUG(indentation << "Error reading padding: " << worstError); diff --git a/modules/globebrowsing/tile/tileprovider/cachingtileprovider.cpp b/modules/globebrowsing/tile/tileprovider/cachingtileprovider.cpp index defef66ff3..377d34c924 100644 --- a/modules/globebrowsing/tile/tileprovider/cachingtileprovider.cpp +++ b/modules/globebrowsing/tile/tileprovider/cachingtileprovider.cpp @@ -23,9 +23,7 @@ ****************************************************************************************/ #include - #include - #include #include @@ -34,18 +32,73 @@ #include - - - namespace { - const std::string _loggerCat = "TileProvider"; -} + const std::string _loggerCat = "CachingTileProvider"; + const std::string KeyDoPreProcessing = "DoPreProcessing"; + const std::string KeyMinimumPixelSize = "MinimumPixelSize"; + const std::string KeyFilePath = "FilePath"; + const std::string KeyCacheSize = "CacheSize"; + const std::string KeyFlushInterval = "FlushInterval"; +} namespace openspace { + CachingTileProvider::CachingTileProvider(const ghoul::Dictionary& dictionary) + : _framesSinceLastRequestFlush(0) + { + std::string name = "Name unspecified"; + dictionary.getValue("Name", name); + std::string _loggerCat = "CachingTileProvider : " + name; - CachingTileProvider::CachingTileProvider(std::shared_ptr tileReader, + // 1. Get required Keys + std::string filePath; + if (!dictionary.getValue(KeyFilePath, filePath)) { + throw std::runtime_error("Must define key '" + KeyFilePath + "'"); + } + + // 2. Initialize default values for any optional Keys + TileDataset::Configuration config; + config.doPreProcessing = false; + config.minimumTilePixelSize = 512; + + // getValue does not work for integers + double minimumPixelSize; + double cacheSize = 512; + double framesUntilRequestFlush = 60; + + // 3. Check for used spcified optional keys + if (dictionary.getValue(KeyDoPreProcessing, config.doPreProcessing)) { + LDEBUG("Default doPreProcessing overridden: " << config.doPreProcessing); + } + if (dictionary.getValue(KeyMinimumPixelSize, minimumPixelSize)) { + LDEBUG("Default minimumPixelSize overridden: " << minimumPixelSize); + config.minimumTilePixelSize = static_cast(minimumPixelSize); + } + if (dictionary.getValue(KeyCacheSize, cacheSize)) { + LDEBUG("Default cacheSize overridden: " << cacheSize); + } + if (dictionary.getValue(KeyFlushInterval, framesUntilRequestFlush)) { + LDEBUG("Default framesUntilRequestFlush overridden: " << + framesUntilRequestFlush); + } + + // Initialize instance variables + auto tileDataset = std::make_shared(filePath, config); + + // only one thread per provider supported atm + // (GDAL does not handle multiple threads for a single dataset very well + // currently) + auto threadPool = std::make_shared(1); + + _asyncTextureDataProvider = std::make_shared( + tileDataset, threadPool); + _tileCache = std::make_shared(cacheSize); + _framesUntilRequestFlush = framesUntilRequestFlush; + } + + CachingTileProvider::CachingTileProvider( + std::shared_ptr tileReader, std::shared_ptr tileCache, int framesUntilFlushRequestQueue) : _asyncTextureDataProvider(tileReader) @@ -56,12 +109,10 @@ namespace openspace { } - CachingTileProvider::~CachingTileProvider(){ clearRequestQueue(); } - void CachingTileProvider::update() { initTexturesFromLoadedData(); if (_framesSinceLastRequestFlush++ > _framesUntilRequestFlush) { @@ -81,7 +132,6 @@ namespace openspace { Tile CachingTileProvider::getTile(const ChunkIndex& chunkIndex) { Tile tile = Tile::TileUnavailable; - if (chunkIndex.level > maxLevel()) { tile.status = Tile::Status::OutOfRange; return tile; @@ -106,7 +156,6 @@ namespace openspace { return _defaultTile; } - void CachingTileProvider::initTexturesFromLoadedData() { auto readyTileIOResults = _asyncTextureDataProvider->getTileIOResults(); for(auto tileIOResult : readyTileIOResults){ @@ -136,27 +185,21 @@ namespace openspace { return Tile::Status::Unavailable; } - - Tile CachingTileProvider::getOrStartFetchingTile(ChunkIndex chunkIndex) { - ChunkHashKey hashkey = chunkIndex.hashKey(); - if (_tileCache->exist(hashkey)) { - return _tileCache->get(hashkey); - } - else { - _asyncTextureDataProvider->enqueueTileIO(chunkIndex); - return Tile::TileUnavailable; - } - } - TileDepthTransform CachingTileProvider::depthTransform() { return _asyncTextureDataProvider->getTextureDataProvider()->getDepthTransform(); } - Tile CachingTileProvider::createTile(std::shared_ptr tileIOResult) { + if (tileIOResult->error != CE_None) { + return{ nullptr, nullptr, Tile::Status::IOError }; + } + ChunkHashKey key = tileIOResult->chunkIndex.hashKey(); - TileDataLayout dataLayout = _asyncTextureDataProvider->getTextureDataProvider()->getDataLayout(); - Texture* texturePtr = new Texture( + TileDataLayout dataLayout = + _asyncTextureDataProvider->getTextureDataProvider()->getDataLayout(); + + // The texture should take ownership of the data + std::shared_ptr texture = std::make_shared( tileIOResult->imageData, tileIOResult->dimensions, dataLayout.textureFormat.ghoulFormat, @@ -164,23 +207,19 @@ namespace openspace { dataLayout.glType, Texture::FilterMode::Linear, Texture::WrappingMode::ClampToEdge); - - // The texture should take ownership of the data - std::shared_ptr texture = std::shared_ptr(texturePtr); texture->uploadTexture(); + // AnisotropicMipMap must be set after texture is uploaded. Why?! texture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap); Tile tile = { texture, tileIOResult->preprocessData, - tileIOResult->error == CE_None ? Tile::Status::OK : Tile::Status::IOError + Tile::Status::OK }; return tile; } - - } // namespace openspace diff --git a/modules/globebrowsing/tile/tileprovider/cachingtileprovider.h b/modules/globebrowsing/tile/tileprovider/cachingtileprovider.h index f06c7e774b..47fd735756 100644 --- a/modules/globebrowsing/tile/tileprovider/cachingtileprovider.h +++ b/modules/globebrowsing/tile/tileprovider/cachingtileprovider.h @@ -25,8 +25,6 @@ #ifndef __CACHING_TILE_PROVIDER_H__ #define __CACHING_TILE_PROVIDER_H__ -#include - #include #include // absPath #include @@ -36,21 +34,20 @@ #include #include - ////////////////////////////////////////////////////////////////////////////////////////// -// TILE PROVIDER // +// TILE PROVIDER // ////////////////////////////////////////////////////////////////////////////////////////// - namespace openspace { /** - Provides tiles through GDAL datasets which can be defined with xml files - for example for wms. + * Provides tiles loaded by AsyncTileDataProvider and + * caches them in memory using LRU caching */ class CachingTileProvider : public TileProvider { public: + CachingTileProvider(const ghoul::Dictionary& dictionary); CachingTileProvider( std::shared_ptr tileReader, @@ -59,55 +56,59 @@ namespace openspace { virtual ~CachingTileProvider(); + /** + * \returns a Tile with status OK iff it exists in in-memory + * cache. If not, it may enqueue some IO operations on a + * separate thread. + */ virtual Tile getTile(const ChunkIndex& chunkIndex); + virtual Tile getDefaultTile(); - virtual Tile::Status getTileStatus(const ChunkIndex& index); + virtual Tile::Status getTileStatus(const ChunkIndex& chunkIndex); virtual TileDepthTransform depthTransform(); virtual void update(); virtual void reset(); virtual int maxLevel(); - private: - ////////////////////////////////////////////////////////////////////////////////// // Helper functions // ////////////////////////////////////////////////////////////////////////////////// - - Tile getOrStartFetchingTile(ChunkIndex chunkIndex); - - /** - Creates an OpenGL texture and pushes the data to the GPU. + * Collects all asynchronously downloaded TileIOResult + * and uses createTile to create Tiles, + * which are put in the LRU cache - potentially pushing out outdated + * Tiles. */ - - Tile createTile(std::shared_ptr res); - - void clearRequestQueue(); - void initTexturesFromLoadedData(); + /** + * \returns A tile with Tile::Status::OK if no errors + * occured, a tile with Tile::Status::IOError otherwise + */ + Tile createTile(std::shared_ptr res); + /** + * Deletes all enqueued, but not yet started async downloads of textures. + * Note that this does not cancel any currently ongoing async downloads. + */ + void clearRequestQueue(); ////////////////////////////////////////////////////////////////////////////////// // Member variables // ////////////////////////////////////////////////////////////////////////////////// + std::shared_ptr _asyncTextureDataProvider; std::shared_ptr _tileCache; - Tile _defaultTile; int _framesSinceLastRequestFlush; int _framesUntilRequestFlush; - - std::shared_ptr _asyncTextureDataProvider; + Tile _defaultTile; }; } // namespace openspace - - - #endif // __CACHING_TILE_PROVIDER_H__ \ No newline at end of file diff --git a/modules/globebrowsing/tile/tileprovider/chunkindextileprovider.cpp b/modules/globebrowsing/tile/tileprovider/chunkindextileprovider.cpp deleted file mode 100644 index b734b4e3d7..0000000000 --- a/modules/globebrowsing/tile/tileprovider/chunkindextileprovider.cpp +++ /dev/null @@ -1,154 +0,0 @@ -/***************************************************************************************** -* * -* OpenSpace * -* * -* Copyright (c) 2014-2016 * -* * -* Permission is hereby granted, free of charge, to any person obtaining a copy of this * -* software and associated documentation files (the "Software"), to deal in the Software * -* without restriction, including without limitation the rights to use, copy, modify, * -* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * -* permit persons to whom the Software is furnished to do so, subject to the following * -* conditions: * -* * -* The above copyright notice and this permission notice shall be included in all copies * -* or substantial portions of the Software. * -* * -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * -* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * -* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * -* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * -* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * -* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * -****************************************************************************************/ - -#include - -#include - -#include -#include - -#include -#include - -#include - -#include - - - - -namespace { - const std::string _loggerCat = "TileProvider"; -} - - -namespace openspace { - - ChunkIndexTileProvider::ChunkIndexTileProvider(const glm::uvec2& textureSize, size_t fontSize) - : _tileCache(500) - , _textureSize(textureSize) - , _fontSize(fontSize) - { - using namespace ghoul::fontrendering; - - _font = OsEng.fontManager().font("Mono", _fontSize); - _fontRenderer = std::unique_ptr(FontRenderer::createDefault()); - _fontRenderer->setFramebufferSize(textureSize); - - - glGenFramebuffers(1, &_fbo); - } - - ChunkIndexTileProvider::~ChunkIndexTileProvider() { - glDeleteFramebuffers(1, &_fbo); - } - - Tile ChunkIndexTileProvider::getTile(const ChunkIndex& chunkIndex) { - ChunkHashKey key = chunkIndex.hashKey(); - - if (!_tileCache.exist(key)) { - _tileCache.put(key, createChunkIndexTile(chunkIndex)); - } - - return _tileCache.get(key); - } - - Tile ChunkIndexTileProvider::getDefaultTile() { - return Tile::TileUnavailable; - } - - - Tile::Status ChunkIndexTileProvider::getTileStatus(const ChunkIndex& index) { - return Tile::Status::OK; - } - - TileDepthTransform ChunkIndexTileProvider::depthTransform() { - TileDepthTransform transform; - transform.depthOffset = 0.0f; - transform.depthScale = 1.0f; - return transform; - } - - void ChunkIndexTileProvider::update() { - // nothing to be done - } - - void ChunkIndexTileProvider::reset() { - _tileCache.clear(); - } - - Tile ChunkIndexTileProvider::createChunkIndexTile(const ChunkIndex& chunkIndex) { - glm::uvec4 color = { 0, 0, 0, 0 }; - Tile tile = Tile::createPlainTile(_textureSize, color); - - // Keep track of defaultFBO and viewport to be able to reset state when done - GLint defaultFBO; - GLint viewport[4]; - glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO); - glGetIntegerv(GL_VIEWPORT, viewport); - - // Render to texture - glBindFramebuffer(GL_FRAMEBUFFER, _fbo); - glFramebufferTexture2D( - GL_FRAMEBUFFER, - GL_COLOR_ATTACHMENT0, - GL_TEXTURE_2D, - *(tile.texture), - 0 - ); - - GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - //LDEBUG(status); - - glViewport( - 0, 0, - static_cast(tile.texture->width()), - static_cast(tile.texture->height()) - ); - - _fontRenderer->render( - *_font, - glm::vec2( - _textureSize.x / 4 - (_textureSize.x / 32) * log10(1 << chunkIndex.level), - _textureSize.y / 2 + _fontSize), - glm::vec4(1.0, 0.0, 0.0, 1.0), - "level: %i \nx: %i \ny: %i", - chunkIndex.level, chunkIndex.x, chunkIndex.y - ); - - // Reset state: bind default FBO and set viewport to what it was - glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO); - glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); - - return tile; - } - - - int ChunkIndexTileProvider::maxLevel() { - return 1337; // unlimited - } - - -} // namespace openspace diff --git a/modules/globebrowsing/tile/tileprovider/singleimageprovider.cpp b/modules/globebrowsing/tile/tileprovider/singleimageprovider.cpp index 4642dc7e1c..e88464c5c0 100644 --- a/modules/globebrowsing/tile/tileprovider/singleimageprovider.cpp +++ b/modules/globebrowsing/tile/tileprovider/singleimageprovider.cpp @@ -23,7 +23,6 @@ ****************************************************************************************/ #include - #include #include @@ -31,51 +30,55 @@ #include #include - #include - - namespace { const std::string _loggerCat = "SingleImageProvider"; -} + const std::string KeyFilePath = "FilePath"; +} namespace openspace { + SingleImageProvider::SingleImageProvider(const ghoul::Dictionary& dictionary) { + // Required input + if (!dictionary.getValue(KeyFilePath, _imagePath)) { + throw std::runtime_error("Must define key '" + KeyFilePath + "'"); + } + reset(); + } - SingleImagePrivoder::SingleImagePrivoder(const std::string& imagePath) + SingleImageProvider::SingleImageProvider(const std::string& imagePath) : _imagePath(imagePath) { reset(); } - Tile SingleImagePrivoder::getTile(const ChunkIndex& chunkIndex) { + Tile SingleImageProvider::getTile(const ChunkIndex& chunkIndex) { return _tile; } - Tile SingleImagePrivoder::getDefaultTile() { + Tile SingleImageProvider::getDefaultTile() { return _tile; } - - Tile::Status SingleImagePrivoder::getTileStatus(const ChunkIndex& index) { + Tile::Status SingleImageProvider::getTileStatus(const ChunkIndex& index) { return _tile.status; } - TileDepthTransform SingleImagePrivoder::depthTransform() { + TileDepthTransform SingleImageProvider::depthTransform() { TileDepthTransform transform; transform.depthOffset = 0.0f; transform.depthScale = 1.0f; return transform; } - void SingleImagePrivoder::update() { + void SingleImageProvider::update() { // nothing to be done } - void SingleImagePrivoder::reset() { + void SingleImageProvider::reset() { _tile = Tile(); _tile.texture = std::shared_ptr(ghoul::io::TextureReader::ref().loadTexture(_imagePath).release()); _tile.status = _tile.texture != nullptr ? Tile::Status::OK : Tile::Status::IOError; @@ -85,7 +88,7 @@ namespace openspace { _tile.texture->setFilter(ghoul::opengl::Texture::FilterMode::Linear); } - int SingleImagePrivoder::maxLevel() { + int SingleImageProvider::maxLevel() { return 1337; // unlimited } diff --git a/modules/globebrowsing/tile/tileprovider/singleimageprovider.h b/modules/globebrowsing/tile/tileprovider/singleimageprovider.h index 817562c2fa..b83580712d 100644 --- a/modules/globebrowsing/tile/tileprovider/singleimageprovider.h +++ b/modules/globebrowsing/tile/tileprovider/singleimageprovider.h @@ -25,10 +25,13 @@ #ifndef __SINGLE_IMAGE_PROVIDER_H__ #define __SINGLE_IMAGE_PROVIDER_H__ +#include +#include +#include + #include #include -#include #include #include // absPath @@ -36,23 +39,18 @@ #include #include - -#include -#include -#include - - - +#include namespace openspace { - using namespace ghoul::opengl; - + using namespace ghoul::opengl; - class SingleImagePrivoder : public TileProvider { + class SingleImageProvider : public TileProvider { public: - SingleImagePrivoder(const std::string& imagePath); - virtual ~SingleImagePrivoder() { } + + SingleImageProvider(const ghoul::Dictionary& dictionary); + SingleImageProvider(const std::string& imagePath); + virtual ~SingleImageProvider() { } virtual Tile getTile(const ChunkIndex& chunkIndex); virtual Tile getDefaultTile(); @@ -66,10 +64,6 @@ namespace openspace { std::string _imagePath; }; - } // namespace openspace - - - #endif // __SINGLE_IMAGE_PROVIDER_H__ \ No newline at end of file diff --git a/modules/globebrowsing/tile/tileprovider/temporaltileprovider.cpp b/modules/globebrowsing/tile/tileprovider/temporaltileprovider.cpp index 4adaef4a26..2cdbefd741 100644 --- a/modules/globebrowsing/tile/tileprovider/temporaltileprovider.cpp +++ b/modules/globebrowsing/tile/tileprovider/temporaltileprovider.cpp @@ -25,7 +25,8 @@ #include #include -#include +#include + #include @@ -46,34 +47,53 @@ namespace { const std::string _loggerCat = "TemporalTileProvider"; + + const std::string KeyDoPreProcessing = "DoPreProcessing"; + const std::string KeyMinimumPixelSize = "MinimumPixelSize"; + const std::string KeyFilePath = "FilePath"; + const std::string KeyCacheSize = "CacheSize"; + const std::string KeyFlushInterval = "FlushInterval"; } namespace openspace { - const std::string TemporalTileProvider::TIME_PLACEHOLDER("${OpenSpaceTimeId}"); + const std::string TemporalTileProvider::URL_TIME_PLACEHOLDER("${OpenSpaceTimeId}"); - TemporalTileProvider::TemporalTileProvider(const std::string& datasetFile, - const TileProviderInitData& tileProviderInitData) - : _datasetFile(datasetFile) - , _tileProviderInitData(tileProviderInitData) + const std::string TemporalTileProvider::TemporalXMLTags::TIME_START = "OpenSpaceTimeStart"; + const std::string TemporalTileProvider::TemporalXMLTags::TIME_END = "OpenSpaceTimeEnd"; + const std::string TemporalTileProvider::TemporalXMLTags::TIME_RESOLUTION = "OpenSpaceTimeResolution"; + const std::string TemporalTileProvider::TemporalXMLTags::TIME_FORMAT = "OpenSpaceTimeIdFormat"; + + + TemporalTileProvider::TemporalTileProvider(const ghoul::Dictionary& dictionary) + : _initDict(dictionary) { - std::ifstream in(datasetFile.c_str()); - ghoul_assert(errno == 0, strerror(errno) << std::endl << datasetFile); + + if (!dictionary.getValue(KeyFilePath, _datasetFile)) { + throw std::runtime_error("Must define key '" + KeyFilePath + "'"); + } + + + std::ifstream in(_datasetFile.c_str()); + ghoul_assert(errno == 0, strerror(errno) << std::endl << _datasetFile); // read file - std::string xml( (std::istreambuf_iterator(in)), (std::istreambuf_iterator())); + std::string xml((std::istreambuf_iterator(in)), (std::istreambuf_iterator())); _gdalXmlTemplate = consumeTemporalMetaData(xml); _defaultTile = getTileProvider()->getDefaultTile(); } + + + std::string TemporalTileProvider::consumeTemporalMetaData(const std::string& xml) { CPLXMLNode* node = CPLParseXMLString(xml.c_str()); - std::string timeStart = getXMLValue(node, "OpenSpaceTimeStart", "2000 Jan 1"); - std::string timeResolution = getXMLValue(node, "OpenSpaceTimeResolution", "2d"); - std::string timeEnd = getXMLValue(node, "OpenSpaceTimeEnd", "Now"); - std::string timeIdFormat = getXMLValue(node, "OpenSpaceTimeIdFormat", "YYYY-MM-DDThh:mm:ssZ"); + std::string timeStart = getXMLValue(node, TemporalXMLTags::TIME_START, "2000 Jan 1"); + std::string timeResolution = getXMLValue(node, TemporalXMLTags::TIME_RESOLUTION, "2d"); + std::string timeEnd = getXMLValue(node, TemporalXMLTags::TIME_END, "Now"); + std::string timeIdFormat = getXMLValue(node, TemporalXMLTags::TIME_FORMAT, "YYYY-MM-DDThh:mm:ssZ"); Time start; start.setTime(timeStart); Time end(Time::now()); @@ -155,7 +175,7 @@ namespace openspace { std::shared_ptr TemporalTileProvider::getTileProvider(Time t) { Time tCopy(t); - if (_timeQuantizer.quantize(tCopy)) { + if (_timeQuantizer.quantize(tCopy, true)) { TimeKey timekey = _timeFormat->stringify(tCopy); try { return getTileProvider(timekey); @@ -185,7 +205,8 @@ namespace openspace { std::shared_ptr TemporalTileProvider::initTileProvider(TimeKey timekey) { std::string gdalDatasetXml = getGdalDatasetXML(timekey); - return TileProviderFactory::ref()->create("LRUCaching", gdalDatasetXml, _tileProviderInitData); + _initDict.setValue(KeyFilePath, gdalDatasetXml); + return std::make_shared(_initDict); } std::string TemporalTileProvider::getGdalDatasetXML(Time t) { @@ -195,8 +216,8 @@ namespace openspace { std::string TemporalTileProvider::getGdalDatasetXML(TimeKey timeKey) { std::string xmlTemplate(_gdalXmlTemplate); - size_t pos = xmlTemplate.find(TIME_PLACEHOLDER); - size_t numChars = TIME_PLACEHOLDER.length(); + size_t pos = xmlTemplate.find(URL_TIME_PLACEHOLDER); + size_t numChars = URL_TIME_PLACEHOLDER.length(); ghoul_assert(pos != std::string::npos, "Invalid dataset file"); std::string timeSpecifiedXml = xmlTemplate.replace(pos, numChars, timeKey); return timeSpecifiedXml; @@ -250,8 +271,7 @@ namespace openspace { // Time Quantizer // ////////////////////////////////////////////////////////////////////////////////////// TimeQuantizer::TimeQuantizer(const Time& start, const Time& end, double resolution) - : _start(start.unsyncedJ2000Seconds()) - , _end(end.unsyncedJ2000Seconds()) + : _timerange(start.j2000Seconds(), end.j2000Seconds()) , _resolution(resolution) { @@ -290,17 +310,17 @@ namespace openspace { } } - bool TimeQuantizer::quantize(Time& t) const { - double unquantized = t.unsyncedJ2000Seconds(); - if (_start <= unquantized && unquantized <= _end) { - double quantized = std::floor((unquantized - _start) / _resolution) * _resolution + _start; + bool TimeQuantizer::quantize(Time& t, bool clamp) const { + double unquantized = t.j2000Seconds(); + if (_timerange.includes(unquantized)) { + double quantized = std::floor((unquantized - _timerange.start) / _resolution) * _resolution + _timerange.start; t.setTime(quantized); return true; } - else if (_clampTime) { + else if (clamp) { double clampedTime = unquantized; - clampedTime = std::max(clampedTime, _start); - clampedTime = std::min(clampedTime, _end); + clampedTime = std::max(clampedTime, _timerange.start); + clampedTime = std::min(clampedTime, _timerange.end); t.setTime(clampedTime); return true; } @@ -308,4 +328,5 @@ namespace openspace { return false; } } + } // namespace openspace diff --git a/modules/globebrowsing/tile/tileprovider/temporaltileprovider.h b/modules/globebrowsing/tile/tileprovider/temporaltileprovider.h index 211becda87..eed8e64ed0 100644 --- a/modules/globebrowsing/tile/tileprovider/temporaltileprovider.h +++ b/modules/globebrowsing/tile/tileprovider/temporaltileprovider.h @@ -27,11 +27,13 @@ #include +#include #include #include #include +#include #include @@ -41,7 +43,7 @@ ////////////////////////////////////////////////////////////////////////////////////////// -// TILE PROVIDER // +// TILE PROVIDER // ////////////////////////////////////////////////////////////////////////////////////////// namespace openspace { @@ -50,22 +52,61 @@ namespace openspace { // Time Id Providers // ////////////////////////////////////////////////////////////////////////////////////// + /** + * Interface for stringifying OpenSpace Time instances. + * + * Once OpenSpace has a proper Time format class, this should be + * handled by that instead of here. + */ struct TimeFormat { + /** + * Stringifies a OpenSpace time instance + * \param t The time to be stringifyed + * \returns A string description of the provided time + */ virtual std::string stringify(const Time& t) const = 0; }; + /** + * Stringifies OpenSpace to the format "YYYY-MM-DD". + * Example: 2016-09-08 + */ struct YYYY_MM_DD : public TimeFormat { virtual std::string stringify(const Time& t) const; }; + /** + * Stringifies OpenSpace to the format "YYYY-MM-DDThh:mm:ssZ" + * Example: 2016-09-08T23:05:05Z + */ struct YYYY_MM_DDThh_mm_ssZ : public TimeFormat { virtual std::string stringify(const Time& t) const; }; + /** + * Static factory class for providing different TimeFormats. + * A time format stringifier is retrieved by a name of the format. + * See implementation of init() to see what time + * id formats are supported. + */ struct TimeIdProviderFactory { + /** + * Maps a name of a format to an implementation of a TimeFormat. + * Calling this method will also initialize the TimeIdProviderFactory + * if it hasn't been. + * + * See implementation of init() for supported time formats. + * + * \param format - name of TimeFormat, eg "YYYY-MM-DDThh:mm:ssZ". + * \returns a concrete TimeFormat used to stringify instances of Time + */ static TimeFormat* getProvider(const std::string& format); + + /** + * Registers all supported TimeFormats. + */ static void init(); static std::unordered_map> _timeIdProviderMap; @@ -77,22 +118,43 @@ namespace openspace { ////////////////////////////////////////////////////////////////////////////////////// // Time Quantizer // ////////////////////////////////////////////////////////////////////////////////////// + + /** + * Used to quantize time to descrete values. + */ struct TimeQuantizer { TimeQuantizer() {} TimeQuantizer(const Time& start, const Time& end, double resolution); TimeQuantizer(const Time& start, const Time& end, const std::string& resolutionStr); + /** + * Takes a time resulition string and parses it into a double + * value representing the time resolution as seconds. + * + * Example: parseTimeResolutionStr("1d"); + * + * \param resoltutionStr with the format {number}{unit} + * where supported units are: + * (s)econds, (m)inutes, (h)ours, (d)ays, (y)ears + * + * \returns the time resolution in seconds + */ static double parseTimeResolutionStr(const std::string& resoltutionStr); - - bool quantize(Time& t) const; + /** + * Quantizes a OpenSpace Time into descrete values. + * If the provided Time t is outside the time range, it will + * be clamped to the the time range. + * + * \param t Time instance, which will be quantized + * \param clamp Whether or not time should be clamped if not t is in the time range + * \returns wether or not time was quantized + */ + bool quantize(Time& t, bool clamp) const; private: - double _start; - double _end; + TimeRange _timerange; double _resolution; - - bool _clampTime = true; }; @@ -100,13 +162,26 @@ namespace openspace { // Temporal tile Provider // ////////////////////////////////////////////////////////////////////////////////////// + /** + * Provide Tiles from web map services that have temporal resolution. + * + * TemporalTileProviders are instantiated using a ghoul::Dictionary, + * and must define a filepath to a Openspace Temporal dataset description file. + * This is an xml-file that defines the same meta data as the GDAL wms description + * (http://www.gdal.org/frmt_wms.html), but augmented with some + * extra tags describing the temporal properties of the dataset. See + * TemporalTileProvider::TemporalXMLTags + * + */ class TemporalTileProvider : public TileProvider { public: - TemporalTileProvider(const std::string& datasetFile, const TileProviderInitData& tileProviderInitData); + /** + * Dictionary constructor. Must provide KeyFilePath as defined in .cpp file. + */ + TemporalTileProvider(const ghoul::Dictionary& dictionary); + // These methods implements the TileProvider interface - - // These methods implements TileProvider virtual Tile getTile(const ChunkIndex& chunkIndex); virtual Tile getDefaultTile(); virtual Tile::Status getTileStatus(const ChunkIndex& chunkIndex); @@ -116,8 +191,6 @@ namespace openspace { virtual int maxLevel(); - - typedef std::string TimeKey; std::shared_ptr getTileProvider(Time t = Time::ref()); @@ -125,34 +198,121 @@ namespace openspace { private: - static const std::string TIME_PLACEHOLDER; + /** + * A placeholder string that must be provided in the WMS template url. This + * placeholder will be replaced by quantized date-time strings during run time + * in order to access the datasets for different instances of time. + */ + static const std::string URL_TIME_PLACEHOLDER; + /** + * These are tags that TemporalTileProviders must be able to read from the XML + * file provided in the ghoul::Dictionary used to create this provider. These + * tags describe the temporal properties of the dataset. + */ + static const struct TemporalXMLTags { + /** + * Tag should contain a ISO8601 time specifying the datasets start time + */ + static const std::string TIME_START; - std::string getGdalDatasetXML(Time t); - std::string getGdalDatasetXML(TimeKey key); + /** + * Tag should contain a ISO8601 time specifying the datasets end time + * Example 1: "2016 SEP 08". + * Example 2: "now" - sets the dataset's end time to the current time. + */ + static const std::string TIME_END; + + /** + * Tag should contain the time resolution of the dataset. + * The resolution is defined by a number along with a unit specifying how + * often the dataset is updated temporally. Supported units are: + * (s)econds, (m)inutes, (h)ours, (d)ays, (y)ears. + * + * Example 1: "2d" - dataset updated every other day. + * Example 2: "1h" - dataset is updated every hour. + */ + static const std::string TIME_RESOLUTION; + + /** + * Tag should contain a string specifying the date-time format expected by the + * WMS. + */ + static const std::string TIME_FORMAT; + }; + /** + * Create a GDAL dataset description based on the time t + * \param t Time to generate a GDAL dataset description for + * \returns a GDAL dataset description + */ + std::string getGdalDatasetXML(Time t); + + /** + * Create a GDAL dataset description associated with the provided TimeKey + * \param key The TimeKey specifying time + * \returns a GDAL dataset description + */ + std::string getGdalDatasetXML(TimeKey key); + + /** + * Instantiates a new TileProvder for the temporal dataset at the time + * specified. + * + * This method replaced the URL_TIME_PLACEHOLDER in the template URL + * with the provided timekey, the opens a new GDAL dataset with that URL. + * + * \param timekey time specifying dataset's temporality + * \returns newly instantiated TileProvider + */ std::shared_ptr initTileProvider(TimeKey timekey); + /** + * Takes as input a Openspace Temporal dataset description, extracts the temporal + * metadata provided by reading the TemporalXMLTags, removes the + * read tags from the description, and returns a GDAL template GDAL dataset + * description. The template GDAL dataset description has the a + * URL_TIME_PLACEHOLDER still in it, which needs to be replaced before + * GDAL can open it as a GDALDataset. + * + * \param xml Openspace Temporal dataset description + * \returns a GDAL template data description. + */ std::string consumeTemporalMetaData(const std::string &xml); - std::string getXMLValue(CPLXMLNode*, const std::string& key, const std::string& defaultVal); + /** + * Helper method to read a XML value from a XML tree. + * \param node XML tree to search in + * \param key XML tag to find the value for + * \param defaultVal value to return if key was not found + * \returns the value of the Key, or defaultVal if key was undefined. + */ + std::string getXMLValue(CPLXMLNode* node, const std::string& key, const std::string& defaultVal); + + /** + * Ensures that the TemporalTileProvider is up to date. + */ void ensureUpdated(); ////////////////////////////////////////////////////////////////////////////////// // Members variables // ////////////////////////////////////////////////////////////////////////////////// - const std::string _datasetFile; + std::string _datasetFile; std::string _gdalXmlTemplate; std::unordered_map > _tileProviderMap; - TileProviderInitData _tileProviderInitData; + + // Used for creation of time specific instances of CachingTileProvider + ghoul::Dictionary _initDict; + Tile _defaultTile; std::shared_ptr _currentTileProvider; + TimeFormat * _timeFormat; TimeQuantizer _timeQuantizer; }; diff --git a/modules/globebrowsing/tile/tileprovider/texttileprovider.cpp b/modules/globebrowsing/tile/tileprovider/texttileprovider.cpp new file mode 100644 index 0000000000..39b070b628 --- /dev/null +++ b/modules/globebrowsing/tile/tileprovider/texttileprovider.cpp @@ -0,0 +1,274 @@ +/***************************************************************************************** +* * +* OpenSpace * +* * +* Copyright (c) 2014-2016 * +* * +* Permission is hereby granted, free of charge, to any person obtaining a copy of this * +* software and associated documentation files (the "Software"), to deal in the Software * +* without restriction, including without limitation the rights to use, copy, modify, * +* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * +* permit persons to whom the Software is furnished to do so, subject to the following * +* conditions: * +* * +* The above copyright notice and this permission notice shall be included in all copies * +* or substantial portions of the Software. * +* * +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * +* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * +* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * +* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * +* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * +* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * +****************************************************************************************/ + +#include + +#include + +#include +#include + +#include +#include + +#include + +#include + + + + +namespace { + const std::string _loggerCat = "TextTileProvider"; +} + + +namespace openspace { + + TextTileProvider::TextTileProvider(const glm::uvec2& textureSize, size_t fontSize) + : _tileCache(500) + , _textureSize(textureSize) + , _fontSize(fontSize) + { + + _font = OsEng.fontManager().font("Mono", _fontSize); + + _fontRenderer = std::unique_ptr(FontRenderer::createDefault()); + _fontRenderer->setFramebufferSize(textureSize); + + + glGenFramebuffers(1, &_fbo); + } + + TextTileProvider::~TextTileProvider() { + glDeleteFramebuffers(1, &_fbo); + } + + Tile TextTileProvider::getTile(const ChunkIndex& chunkIndex) { + ChunkHashKey key = chunkIndex.hashKey(); + + if (!_tileCache.exist(key)) { + _tileCache.put(key, createChunkIndexTile(chunkIndex)); + } + + return _tileCache.get(key); + } + + Tile TextTileProvider::getDefaultTile() { + return Tile::TileUnavailable; + } + + + Tile::Status TextTileProvider::getTileStatus(const ChunkIndex& index) { + return Tile::Status::OK; + } + + TileDepthTransform TextTileProvider::depthTransform() { + TileDepthTransform transform; + transform.depthOffset = 0.0f; + transform.depthScale = 1.0f; + return transform; + } + + void TextTileProvider::update() { + // nothing to be done + } + + void TextTileProvider::reset() { + _tileCache.clear(); + } + + Tile TextTileProvider::createChunkIndexTile(const ChunkIndex& chunkIndex) { + Tile tile = backgroundTile(chunkIndex); + + // Keep track of defaultFBO and viewport to be able to reset state when done + GLint defaultFBO; + GLint viewport[4]; + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO); + glGetIntegerv(GL_VIEWPORT, viewport); + + // Render to texture + glBindFramebuffer(GL_FRAMEBUFFER, _fbo); + glFramebufferTexture2D( + GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, + *(tile.texture), + 0 + ); + + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + //LDEBUG(status); + + glViewport( + 0, 0, + static_cast(tile.texture->width()), + static_cast(tile.texture->height()) + ); + + ghoul_assert(_fontRenderer != nullptr, "_fontRenderer must not be null"); + renderText(*_fontRenderer, chunkIndex); + + // Reset state: bind default FBO and set viewport to what it was + glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO); + glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); + + return tile; + } + + int TextTileProvider::maxLevel() { + return 1337; // unlimited + } + + ChunkHashKey TextTileProvider::toHash(const ChunkIndex& chunkIndex) const { + return chunkIndex.hashKey(); + } + + + Tile TextTileProvider::backgroundTile(const ChunkIndex& chunkIndex) const { + glm::uvec4 color = { 0, 0, 0, 0 }; + return Tile::createPlainTile(_textureSize, color); + } + + + ////////////////////////////////////////////////////////////////////////////////////// + // Chunk Index Tile Provider // + ////////////////////////////////////////////////////////////////////////////////////// + + void ChunkIndexTileProvider::renderText(const FontRenderer& fontRenderer, const ChunkIndex& chunkIndex) const { + fontRenderer.render( + *_font, + glm::vec2( + _textureSize.x / 4 - (_textureSize.x / 32) * log10(1 << chunkIndex.level), + _textureSize.y / 2 + _fontSize), + glm::vec4(1.0, 0.0, 0.0, 1.0), + "level: %i \nx: %i \ny: %i", + chunkIndex.level, chunkIndex.x, chunkIndex.y + ); + } + + ////////////////////////////////////////////////////////////////////////////////////// + // Tile Size Reference Tile Provider // + ////////////////////////////////////////////////////////////////////////////////////// + + namespace { + const std::string KeyRadii = "Radii"; + const std::string KeyBackgroundImagePath = "BackgroundImagePath"; + } + + SizeReferenceTileProvider::SizeReferenceTileProvider(const ghoul::Dictionary& dictionary) { + _fontSize = 50; + ghoul::fontrendering::FontManager& fm = OsEng.fontManager(); + _font = fm.font("Mono", _fontSize); + + glm::dvec3 radii(1,1,1); + if (!dictionary.getValue(KeyRadii, radii)) { + throw std::runtime_error("Must define key '" + KeyRadii + "'"); + } + _ellipsoid = Ellipsoid(radii); + + _backgroundTile.status = Tile::Status::Unavailable; + std::string backgroundImagePath; + if (dictionary.getValue(KeyBackgroundImagePath, backgroundImagePath)) { + using namespace ghoul::io; + std::string imgAbsPath = absPath(backgroundImagePath); + _backgroundTile.texture = TextureReader::ref().loadTexture(imgAbsPath); + _backgroundTile.texture->uploadTexture(); + _backgroundTile.texture->setFilter(ghoul::opengl::Texture::FilterMode::Linear); + _backgroundTile.status = Tile::Status::OK; + } + + } + + void SizeReferenceTileProvider::renderText(const FontRenderer& fontRenderer, const ChunkIndex& chunkIndex) const { + GeodeticPatch patch(chunkIndex); + bool aboveEquator = patch.isNorthern(); + + double tileLongitudalLength = roundedLongitudalLength(chunkIndex); + + std::string unit = "m"; + if (tileLongitudalLength > 9999) { + tileLongitudalLength *= 0.001; + unit = "km"; + } + + glm::vec2 textPosition; + textPosition.x = 0; + textPosition.y = aboveEquator ? _fontSize / 2 : _textureSize.y - 3 * _fontSize / 2; + glm::vec4 color(1.0, 1.0, 1.0, 1.0); + + fontRenderer.render( + *_font, + textPosition, + color, + " %.0f %s", + tileLongitudalLength, unit.c_str() + ); + } + + int SizeReferenceTileProvider::roundedLongitudalLength(const ChunkIndex& chunkIndex) const { + GeodeticPatch patch(chunkIndex); + bool aboveEquator = patch.isNorthern(); + double lat = aboveEquator ? patch.minLat() : patch.maxLat(); + double lon1 = patch.minLon(); + double lon2 = patch.maxLon(); + int l = static_cast(_ellipsoid.longitudalDistance(lat, lon1, lon2)); + + bool useKm = l > 9999; + if (useKm) l /= 1000; + l = std::round(l); + if (useKm) l *= 1000; + + return l; + } + + ChunkHashKey SizeReferenceTileProvider::toHash(const ChunkIndex& chunkIndex) const { + int l = roundedLongitudalLength(chunkIndex); + ChunkHashKey key = static_cast(l); + return key; + } + + Tile SizeReferenceTileProvider::backgroundTile(const ChunkIndex& chunkIndex) const { + if (_backgroundTile.status == Tile::Status::OK) { + Tile tile; + auto t = _backgroundTile.texture; + void* pixelData = new char[t->expectedPixelDataSize()]; + memcpy(pixelData, t->pixelData(), t->expectedPixelDataSize()); + tile.texture = std::make_shared( + pixelData, t->dimensions(), t->format(), t->internalFormat(), t->dataType(), t->filter(), t->wrapping()); + tile.texture->uploadTexture(); + tile.texture->setDataOwnership(Texture::TakeOwnership::Yes); + tile.status = Tile::Status::OK; + return tile; + } + else { + // use default background + return TextTileProvider::backgroundTile(chunkIndex); + } + } + + + + +} // namespace openspace diff --git a/modules/globebrowsing/tile/tileprovider/chunkindextileprovider.h b/modules/globebrowsing/tile/tileprovider/texttileprovider.h similarity index 54% rename from modules/globebrowsing/tile/tileprovider/chunkindextileprovider.h rename to modules/globebrowsing/tile/tileprovider/texttileprovider.h index 5e8215d985..a31c8510e3 100644 --- a/modules/globebrowsing/tile/tileprovider/chunkindextileprovider.h +++ b/modules/globebrowsing/tile/tileprovider/texttileprovider.h @@ -22,8 +22,10 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#ifndef __CHUNK_INDEX_TILE_PROVIDER_H__ -#define __CHUNK_INDEX_TILE_PROVIDER_H__ +#ifndef __TEXT_TILE_PROVIDER_H__ +#define __TEXT_TILE_PROVIDER_H__ + +#include #include #include // absPath @@ -37,6 +39,7 @@ #include #include #include +#include ////////////////////////////////////////////////////////////////////////////////////////// @@ -45,12 +48,24 @@ namespace openspace { - - - class ChunkIndexTileProvider : public TileProvider { + using namespace ghoul::fontrendering; + + /** + * Enables a simple way of providing tiles with any type of rendered text. + * Internally it handles setting up a FBO for rendering the text, and defines a new + * interface, consisting of only a single method for subclasses to implement: + * renderText(const FontRenderer&, const ChunkIndex&) const; + */ + class TextTileProvider : public TileProvider { public: - ChunkIndexTileProvider(const glm::uvec2& textureSize = {512, 512}, size_t fontSize = 48); - virtual ~ChunkIndexTileProvider(); + + /** + * Default constructor with default values for texture and font size + */ + TextTileProvider(const glm::uvec2& textureSize = {512, 512}, size_t fontSize = 48); + virtual ~TextTileProvider(); + + // The TileProvider interface below is implemented in this class virtual Tile getTile(const ChunkIndex& chunkIndex); virtual Tile getDefaultTile(); @@ -59,24 +74,79 @@ namespace openspace { virtual void update(); virtual void reset(); virtual int maxLevel(); - private: - Tile createChunkIndexTile(const ChunkIndex& chunkIndex); - std::shared_ptr _font; - std::unique_ptr _fontRenderer; + /** + * Returns the tile which will be used to draw text onto. + * Default implementation returns a tile with a plain transparent texture. + */ + virtual Tile backgroundTile(const ChunkIndex& chunkIndex) const; + + + /** + * Allow overriding of hash function. + * Default is ChunkIndex::hashKey() + * + * \param chunkIndex chunkIndex to hash + * \returns hashkey used for in LRU cache for this tile + */ + virtual ChunkHashKey toHash(const ChunkIndex& chunkIndex) const; - TileCache _tileCache; + /** + * Uses the fontRenderer to render some text onto the tile texture provided in + * backgroundTile(const ChunkIndex& chunkIndex). + * + * \param fontRenderer used for rendering text onto texture + * \param chunkIndex associated with the tile to be rendered onto + */ + virtual void renderText(const FontRenderer& fontRenderer, const ChunkIndex& chunkIndex) const = 0; + + protected: + std::shared_ptr _font; glm::uvec2 _textureSize; size_t _fontSize; - - GLuint _fbo; + private: + Tile createChunkIndexTile(const ChunkIndex& chunkIndex); + std::unique_ptr _fontRenderer; + + TileCache _tileCache; + GLuint _fbo; }; + /** + * Provides Tiles with the chunk index rendered as text onto its tiles. + */ + class ChunkIndexTileProvider : public TextTileProvider { + public: + virtual void renderText(const FontRenderer& fontRenderer, const ChunkIndex& chunkIndex) const; + }; + + /** + * Constructed with an ellipsoid and uses that to render the longitudal length of each + * of each tile. + */ + class SizeReferenceTileProvider : public TextTileProvider { + public: + SizeReferenceTileProvider(const ghoul::Dictionary& dictionary); + + virtual void renderText(const FontRenderer& fontRenderer, const ChunkIndex& chunkIndex) const; + virtual Tile backgroundTile(const ChunkIndex& chunkIndex) const; + + virtual ChunkHashKey toHash(const ChunkIndex& chunkIndex) const; + + + private: + + int roundedLongitudalLength(const ChunkIndex& chunkIndex) const; + + Ellipsoid _ellipsoid; + Tile _backgroundTile; + }; + } // namespace openspace -#endif // __CHUNK_INDEX_TILE_PROVIDER_H__ \ No newline at end of file +#endif // __TEXT_TILE_PROVIDER_H__ \ No newline at end of file diff --git a/modules/globebrowsing/tile/tileprovider/tileprovider.cpp b/modules/globebrowsing/tile/tileprovider/tileprovider.cpp index 387e95d1a5..f47121ec71 100644 --- a/modules/globebrowsing/tile/tileprovider/tileprovider.cpp +++ b/modules/globebrowsing/tile/tileprovider/tileprovider.cpp @@ -22,72 +22,42 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#include - #include -#include +#include -#include - -#include - -#include -#include #include -#include -#include - -#include - -#include - -#include - - namespace { const std::string _loggerCat = "TileProvider"; + + const std::string KeyType = "Type"; } namespace openspace { - const Tile Tile::TileUnavailable = {nullptr, nullptr, Tile::Status::Unavailable }; - - - Tile Tile::createPlainTile(const glm::uvec2& size, const glm::uvec4& color) { - using namespace ghoul::opengl; - - // Create pixel data - int numBytes = size.x * size.y * 4 * 1; - char* pixels = new char[numBytes]; - size_t numPixels = size.x * size.y; - size_t i = 0; - for (size_t p = 0; p < numPixels; p++){ - pixels[i++] = color.r; - pixels[i++] = color.g; - pixels[i++] = color.b; - pixels[i++] = color.a; - } - - // Create ghoul texture - auto texture = std::make_shared(glm::uvec3(size, 1)); - texture->setDataOwnership(Texture::TakeOwnership::Yes); - texture->setPixelData(pixels); - texture->uploadTexture(); - texture->setFilter(ghoul::opengl::Texture::FilterMode::Linear); - - // Create tile - Tile tile; - tile.status = Tile::Status::OK; - tile.preprocessData = nullptr; - tile.texture = texture; - - return tile; +TileProvider* TileProvider::createFromDictionary(const ghoul::Dictionary& dictionary) { + if (!dictionary.hasValue(KeyType)) { + LERROR("TileProvider did not have key '" << KeyType << "'"); + return nullptr; } + std::string type; + dictionary.getValue(KeyType, type); + ghoul::TemplateFactory* factory + = FactoryManager::ref().factory(); + TileProvider* result = factory->create(type, dictionary); + if (result == nullptr) { + LERROR("Failed creating TileProvider of type '" << type << "'"); + return nullptr; + } + + return result; +} + +TileProvider::TileProvider(const ghoul::Dictionary& dictionary) { }; } // namespace openspace diff --git a/modules/globebrowsing/tile/tileprovider/tileprovider.h b/modules/globebrowsing/tile/tileprovider/tileprovider.h index 31a4f5c99e..3e39c7c30d 100644 --- a/modules/globebrowsing/tile/tileprovider/tileprovider.h +++ b/modules/globebrowsing/tile/tileprovider/tileprovider.h @@ -25,68 +25,119 @@ #ifndef __TILE_PROVIDER_H__ #define __TILE_PROVIDER_H__ - -#include -#include - -#include #include // absPath #include -#include -#include +#include #include - -#include - - +#include #include - ////////////////////////////////////////////////////////////////////////////////////////// -// TILE PROVIDER // +// TILE PROVIDER // ////////////////////////////////////////////////////////////////////////////////////////// - namespace openspace { -class TilePreprocessData; - - // TODO: Remove using directive in header file ---abock using namespace ghoul::opengl; - - - struct Tile { - std::shared_ptr texture; - std::shared_ptr preprocessData; - - enum class Status { Unavailable, OutOfRange, IOError, OK } status; - - /** - * Instantiaes a new tile unicolored tile. The texture gets the provided size and - * color in rgba. Color values ranges between 0-255. - */ - static Tile createPlainTile(const glm::uvec2& size, const glm::uvec4& color); - - static const Tile TileUnavailable; - - }; - + /** + * Interface for providing Tiles given a + * ChunkIndex. + */ class TileProvider { public: + + /** + * Factory method for instantiating different implementations of + * TileProviders. The provided dictionary must + * define a key specifying what implementation of TileProvider + * to be instantiated. + */ + static TileProvider* createFromDictionary(const ghoul::Dictionary& dictionary); + + /** + * Empty default constructor + */ + TileProvider() {}; + + /** + * Implementations of the TileProvider interface must implement + * a constructor taking a dictionary as input. The provided + * dictionary must define a key specifying what implementation + * of TileProvider to be instantiated. + */ + TileProvider(const ghoul::Dictionary& dictionary); + + /** + * Virtual destructor that subclasses should override to do + * clean up. + */ virtual ~TileProvider() { } + /** + * Method for querying tiles, given a specified ChunkIndex. + * + * This method is expected to be invoked multiple times per frame, + * and should therefore return quickly, e.g. not perform heavy I/O + * operations. However, invoking this method may spawn separate threads + * to perform such operations. Therefore, programmers shoud + * note that there is no guarantee that the Tile + * status and texture will be consistent over different invocations + * of this method. + * + * \param chunkIndex specifying a region of a map for which + * we want tile data. + * + * \returns The tile corresponding to the ChunkIndex by the time + * the method was invoked. + */ virtual Tile getTile(const ChunkIndex& chunkIndex) = 0; + + /** + * TileProviders must be able to provide a defualt + * Tile which may be used by clients in cases when + * requested tiles were unavailable. + * + * \returns A default tile + */ virtual Tile getDefaultTile() = 0; + + /** + * Returns the status of a Tile. The Tile::Status + * corresponds the Tile that would be returned + * if the function getTile would be invoked with the same + * ChunkIndex argument at this point in time. + */ virtual Tile::Status getTileStatus(const ChunkIndex& index) = 0; + + /** + * Get the associated depth transform for this TileProvider. + * This is necessary for TileProviders serving height map + * data, in order to correcly map pixel values to meters. + */ virtual TileDepthTransform depthTransform() = 0; + + /** + * This method should be called once per frame. Here, TileProviders + * are given the opportunity to update their internal state. + */ virtual void update() = 0; + + /** + * Provides a uniform way of all TileProviders to reload or + * restore all of its internal state. This is mainly useful + * for debugging purposes. + */ virtual void reset() = 0; + + /** + * \returns The maximum level as defined by ChunkIndex + * that this TileProvider is able provide. + */ virtual int maxLevel() = 0; }; - typedef LRUCache TileCache; struct TileProviderInitData { @@ -99,7 +150,4 @@ class TilePreprocessData; } // namespace openspace - - - #endif // __TILE_PROVIDER_H__ \ No newline at end of file diff --git a/modules/globebrowsing/tile/tileproviderfactory.cpp b/modules/globebrowsing/tile/tileproviderfactory.cpp deleted file mode 100644 index c1a88c4d22..0000000000 --- a/modules/globebrowsing/tile/tileproviderfactory.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/***************************************************************************************** -* * -* OpenSpace * -* * -* Copyright (c) 2014-2016 * -* * -* Permission is hereby granted, free of charge, to any person obtaining a copy of this * -* software and associated documentation files (the "Software"), to deal in the Software * -* without restriction, including without limitation the rights to use, copy, modify, * -* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * -* permit persons to whom the Software is furnished to do so, subject to the following * -* conditions: * -* * -* The above copyright notice and this permission notice shall be included in all copies * -* or substantial portions of the Software. * -* * -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * -* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * -* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * -* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * -* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * -* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * -****************************************************************************************/ - -#include -#include - -#include -#include -#include -#include - -#include - -#include "cpl_minixml.h" - - -namespace { - const std::string _loggerCat = "TileProviderFactory"; -} - - -namespace openspace { - - std::shared_ptr TileProviderFactory::_ref = nullptr; - - - TileProviderFactory::TileProviderFactory() { - initialize(); - } - - - std::shared_ptr TileProviderFactory::ref() { - if (_ref == nullptr) { - // Need to explicitly use new here, since constructor is private - TileProviderFactory* ptr = new TileProviderFactory(); - _ref = std::shared_ptr(ptr); - } - return _ref; - } - - std::shared_ptr TileProviderFactory::create(const std::string& type, - const std::string& desc, const TileProviderInitData& initData) - { - auto concreteFactoryIterator = _factoryMap.find(type); - - if (concreteFactoryIterator == _factoryMap.end()) { - LERROR("Unknown type: " << type); - return nullptr; - } - - std::shared_ptr tileProvider; - - try { - tileProvider = concreteFactoryIterator->second(desc, initData); - } - catch (const std::exception& e) { - LERROR(e.what()); - } - catch (...) { - LERROR("Could not open dataset:\n" << desc << "\n"); - } - return tileProvider; - } - - void TileProviderFactory::initialize() { - _factoryMap.insert({"LRUCaching", [](const std::string& desc, const TileProviderInitData& initData) { - TileDataset::Configuration config; - config.doPreProcessing = initData.preprocessTiles; - config.minimumTilePixelSize = initData.minimumPixelSize; - - auto tileDataset = std::make_shared(desc, config); - auto threadPool = std::make_shared(1); - auto tileReader = std::make_shared(tileDataset, threadPool); - auto tileCache = std::make_shared(initData.cacheSize); - auto tileProvider = std::make_shared(tileReader, tileCache, initData.framesUntilRequestQueueFlush); - return tileProvider; - }}); - - _factoryMap.insert({ "Temporal", [](const std::string& file, const TileProviderInitData& initData) { - CPLXMLNode * node = CPLParseXMLFile(file.c_str()); - if (!node) { - throw ghoul::RuntimeError("Unable to parse file:\n" + file); - } - if (std::string(node->pszValue) == "OpenSpaceTemporalGDALDataset") { - auto tileProvider = std::make_shared(file, initData); - return tileProvider; - } - }}); - - _factoryMap.insert({ "SingleImage", [](const std::string& file, const TileProviderInitData& initData) { - auto tileProvider = std::make_shared(file); - return tileProvider; - } }); - - _factoryMap.insert({ "ChunkIndex", [](const std::string& file, const TileProviderInitData& initData) { - auto tileProvider = std::make_shared(); - return tileProvider; - } }); - } - - -} // namespace openspace diff --git a/modules/globebrowsing/tile/tileprovidermanager.cpp b/modules/globebrowsing/tile/tileprovidermanager.cpp index 90faed250b..c395398074 100644 --- a/modules/globebrowsing/tile/tileprovidermanager.cpp +++ b/modules/globebrowsing/tile/tileprovidermanager.cpp @@ -22,9 +22,9 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ +#include + #include -#include -#include #include @@ -91,7 +91,7 @@ namespace openspace { else if (i == LayeredTextures::Overlays) { initData.minimumPixelSize = textureInitDictionary.value("OverlayMinimumSize"); } - else if (i == LayeredTextures::HeightMaps || i == LayeredTextures::HeightMapOverlays) { + else if (i == LayeredTextures::HeightMaps) { initData.minimumPixelSize = textureInitDictionary.value("HeightMapMinimumSize"); } else { @@ -101,9 +101,8 @@ namespace openspace { initData.threads = 1; initData.cacheSize = 5000; initData.framesUntilRequestQueueFlush = 60; - initData.preprocessTiles = - i == LayeredTextures::HeightMaps || - i == LayeredTextures::HeightMapOverlays; // Only preprocess height maps. + // Only preprocess height maps. + initData.preprocessTiles = i == LayeredTextures::HeightMaps; initTexures( _layerCategories[i].tileProviders, @@ -134,16 +133,27 @@ namespace openspace { std::string type = "LRUCaching"; // if type is unspecified texDict.getValue("Type", type); - - std::shared_ptr tileProvider = TileProviderFactory::ref()->create(type, path, initData); + TileProvider* tileProvider; + auto tileProviderFactory = FactoryManager::ref().factory(); + try { + tileProvider = tileProviderFactory->create(type, texDict); + } + catch (const ghoul::RuntimeError& e) { + LERROR(e.what()); + continue; + } + + // Something else went wrong and no exception was thrown if (tileProvider == nullptr) { + LERROR("Unable to create TileProvider '" << name << "' of type '" + << type << "'"); continue; } bool enabled = false; // defaults to false if unspecified texDict.getValue("Enabled", enabled); - dest.push_back({ name, tileProvider, enabled }); + dest.push_back({ name, std::shared_ptr(tileProvider), enabled }); } } diff --git a/modules/iswa/rendering/iswacygnet.h b/modules/iswa/rendering/iswacygnet.h index c123aa5c22..5f140af97f 100644 --- a/modules/iswa/rendering/iswacygnet.h +++ b/modules/iswa/rendering/iswacygnet.h @@ -115,7 +115,7 @@ protected: * this should be the data file. * @return true if update was successfull */ - virtual bool downloadTextureResource(double timestamp = Time::ref().currentTime()) = 0; + virtual bool downloadTextureResource(double timestamp = Time::ref().j2000Seconds()) = 0; virtual bool readyToRender() const = 0; /** * should set all uniforms needed to render diff --git a/modules/iswa/util/iswamanager.h b/modules/iswa/util/iswamanager.h index 9b81fa4646..b96e69dc19 100644 --- a/modules/iswa/util/iswamanager.h +++ b/modules/iswa/util/iswamanager.h @@ -91,7 +91,7 @@ public: std::future fetchImageCygnet(int id, double timestamp); std::future fetchDataCygnet(int id, double timestamp); - std::string iswaUrl(int id, double timestamp = Time::ref().currentTime(), std::string type = "image"); + std::string iswaUrl(int id, double timestamp = Time::ref().j2000Seconds(), std::string type = "image"); std::shared_ptr iswaGroup(std::string name); diff --git a/modules/newhorizons/newhorizonsmodule.cpp b/modules/newhorizons/newhorizonsmodule.cpp index 479afd7e5b..72caa9b844 100644 --- a/modules/newhorizons/newhorizonsmodule.cpp +++ b/modules/newhorizons/newhorizonsmodule.cpp @@ -51,7 +51,10 @@ NewHorizonsModule::NewHorizonsModule() void NewHorizonsModule::internalInitialize() { ImageSequencer::initialize(); - FactoryManager::ref().addFactory(std::make_unique>()); + FactoryManager::ref().addFactory( + std::make_unique>(), + "Decoder" + ); auto fRenderable = FactoryManager::ref().factory(); ghoul_assert(fRenderable, "No renderable factory existed"); diff --git a/modules/newhorizons/rendering/renderablecrawlingline.cpp b/modules/newhorizons/rendering/renderablecrawlingline.cpp index 34f07bd365..4c538c180a 100644 --- a/modules/newhorizons/rendering/renderablecrawlingline.cpp +++ b/modules/newhorizons/rendering/renderablecrawlingline.cpp @@ -24,12 +24,10 @@ #include -#include #include #include #include #include -//#include namespace { const std::string _loggerCat = "RenderableCrawlingLine"; diff --git a/modules/newhorizons/rendering/renderablefov.cpp b/modules/newhorizons/rendering/renderablefov.cpp index a31acd90b7..878d833186 100644 --- a/modules/newhorizons/rendering/renderablefov.cpp +++ b/modules/newhorizons/rendering/renderablefov.cpp @@ -528,7 +528,7 @@ void RenderableFov::computeIntercepts(const RenderData& data) { _interceptTag[_bounds.size()] = _interceptTag[0]; fovSurfaceIntercept(_interceptTag, _bounds); - glm::vec3 aim = (_spacecraftRotation * glm::vec4(_boresight, 1)).xyz(); + glm::vec3 aim = (_spacecraftRotation * glm::vec4(_boresight, 1)); double lt; glm::dvec3 position = SpiceManager::ref().targetPosition( diff --git a/modules/newhorizons/rendering/renderablemodelprojection.cpp b/modules/newhorizons/rendering/renderablemodelprojection.cpp index 1df9adec24..3daadde566 100644 --- a/modules/newhorizons/rendering/renderablemodelprojection.cpp +++ b/modules/newhorizons/rendering/renderablemodelprojection.cpp @@ -40,6 +40,7 @@ namespace { const std::string keyDestination = "Rotation.Destination"; const std::string keyBody = "Body"; const std::string keyGeometry = "Geometry"; + const std::string keyBoundingSphereRadius = "BoundingSphereRadius"; const std::string keyTextureColor = "Textures.Color"; const std::string keyTextureProject = "Textures.Project"; @@ -96,10 +97,10 @@ RenderableModelProjection::RenderableModelProjection(const ghoul::Dictionary& di completeSuccess &= _projectionComponent.initializeProjectionSettings(dictionary); openspace::SpiceManager::ref().addFrame(_target, _source); - - double boundingRadius = _geometry->boundingRadius(); - setBoundingSphere(PowerScaledScalar::CreatePSS(boundingRadius)); + float boundingSphereRadius = 1.0e9; + dictionary.getValue(keyBoundingSphereRadius, boundingSphereRadius); + setBoundingSphere(PowerScaledScalar::CreatePSS(boundingSphereRadius)); Renderable::addProperty(_performShading); Renderable::addProperty(_rotation); @@ -132,9 +133,18 @@ bool RenderableModelProjection::initialize() { ghoul::opengl::ProgramObject::IgnoreError::Yes ); + _depthFboProgramObject = ghoul::opengl::ProgramObject::Build("DepthPass", + "${MODULE_NEWHORIZONS}/shaders/renderableModelDepth_vs.glsl", + "${MODULE_NEWHORIZONS}/shaders/renderableModelDepth_fs.glsl"); + + completeSuccess &= loadTextures(); completeSuccess &= _projectionComponent.initialize(); + + auto bs = getBoundingSphere(); completeSuccess &= _geometry->initialize(this); + setBoundingSphere(bs); // ignore bounding sphere set by geometry. + completeSuccess &= !_source.empty(); completeSuccess &= !_destination.empty(); @@ -164,7 +174,6 @@ void RenderableModelProjection::render(const RenderData& data) { if (_projectionComponent.needsClearProjection()) _projectionComponent.clearAllProjections(); - _camScaling = data.camera.scaling(); _up = data.camera.lookUpVectorCameraSpace(); if (_capture && _projectionComponent.doesPerformProjection()) @@ -221,6 +230,9 @@ void RenderableModelProjection::update(const UpdateData& data) { _projectionComponent.update(); + if (_depthFboProgramObject->isDirty()) + _depthFboProgramObject->rebuildFromFile(); + _time = data.time; if (openspace::ImageSequencer::ref().isReady()) { @@ -252,8 +264,20 @@ void RenderableModelProjection::update(const UpdateData& data) { void RenderableModelProjection::imageProjectGPU( std::shared_ptr projectionTexture) { - _projectionComponent.imageProjectBegin(); + if (_projectionComponent.needsShadowMap()) { + _projectionComponent.depthMapRenderBegin(); + _depthFboProgramObject->activate(); + _depthFboProgramObject->setUniform("ProjectorMatrix", _projectorMatrix); + _depthFboProgramObject->setUniform("ModelTransform", _transform); + _geometry->setUniforms(*_fboProgramObject); + _geometry->render(); + + _depthFboProgramObject->deactivate(); + _projectionComponent.depthMapRenderEnd(); + } + + _projectionComponent.imageProjectBegin(); _fboProgramObject->activate(); ghoul::opengl::TextureUnit unitFbo; @@ -261,9 +285,17 @@ void RenderableModelProjection::imageProjectGPU( projectionTexture->bind(); _fboProgramObject->setUniform("projectionTexture", unitFbo); + _fboProgramObject->setUniform("needShadowMap", _projectionComponent.needsShadowMap()); + + ghoul::opengl::TextureUnit unitDepthFbo; + if (_projectionComponent.needsShadowMap()) { + unitDepthFbo.activate(); + _projectionComponent.depthTexture().bind(); + _fboProgramObject->setUniform("depthTexture", unitDepthFbo); + } + _fboProgramObject->setUniform("ProjectorMatrix", _projectorMatrix); _fboProgramObject->setUniform("ModelTransform", _transform); - _fboProgramObject->setUniform("_scaling", _camScaling); _fboProgramObject->setUniform("boresight", _boresight); _geometry->setUniforms(*_fboProgramObject); @@ -325,19 +357,24 @@ void RenderableModelProjection::attitudeParameters(double time) { time, lightTime); psc position = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); - position[3] += (3 + _camScaling[1]) + 1; + position[3] += 4; glm::vec3 cpos = position.vec3(); + float distance = glm::length(cpos); + float radius = getBoundingSphere().lengthf(); + _projectorMatrix = _projectionComponent.computeProjectorMatrix( cpos, boresight, _up, _instrumentMatrix, _projectionComponent.fieldOfViewY(), _projectionComponent.aspectRatio(), - _projectionComponent.nearPlane(), - _projectionComponent.farPlane(), + distance - radius, + distance + radius, _boresight ); } + + void RenderableModelProjection::project() { for (auto img : _imageTimes) { attitudeParameters(img.timeRange.start); diff --git a/modules/newhorizons/rendering/renderablemodelprojection.h b/modules/newhorizons/rendering/renderablemodelprojection.h index 9f9d0227ab..1a0ef2c259 100644 --- a/modules/newhorizons/rendering/renderablemodelprojection.h +++ b/modules/newhorizons/rendering/renderablemodelprojection.h @@ -74,6 +74,7 @@ private: std::unique_ptr _programObject; std::unique_ptr _fboProgramObject; + std::unique_ptr _depthFboProgramObject; std::unique_ptr _baseTexture; @@ -100,7 +101,6 @@ private: bool _capture; psc _sunPosition; - properties::BoolProperty _performShading; }; diff --git a/modules/newhorizons/rendering/renderableplanetprojection.cpp b/modules/newhorizons/rendering/renderableplanetprojection.cpp index 8f625eb60d..3f892aecb0 100644 --- a/modules/newhorizons/rendering/renderableplanetprojection.cpp +++ b/modules/newhorizons/rendering/renderableplanetprojection.cpp @@ -47,6 +47,7 @@ namespace { const std::string keyFrame = "Frame"; const std::string keyGeometry = "Geometry"; + const std::string keyRadius = "Geometry.Radius"; const std::string keyShading = "PerformShading"; const std::string keyBody = "Body"; const std::string _mainFrame = "GALACTIC"; @@ -101,6 +102,10 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary& if (success) _heightMapTexturePath = absPath(heightMapPath); + glm::vec2 radius = glm::vec2(1.0, 9.0); + dictionary.getValue(keyRadius, radius); + setBoundingSphere(pss(radius)); + addPropertySubOwner(_geometry.get()); addPropertySubOwner(_projectionComponent); @@ -134,7 +139,6 @@ bool RenderablePlanetProjection::initialize() { completeSuccess &= loadTextures(); completeSuccess &= _projectionComponent.initialize(); - completeSuccess &= _geometry->initialize(this); if (completeSuccess) { @@ -285,6 +289,9 @@ void RenderablePlanetProjection::attitudeParameters(double time) { //position[3] += 3; glm::vec3 cpos = position.vec3(); + float distance = glm::length(cpos); + float radius = getBoundingSphere().lengthf(); + _projectorMatrix = _projectionComponent.computeProjectorMatrix( cpos, bs, @@ -292,8 +299,8 @@ void RenderablePlanetProjection::attitudeParameters(double time) { _instrumentMatrix, _projectionComponent.fieldOfViewY(), _projectionComponent.aspectRatio(), - _projectionComponent.nearPlane(), - _projectionComponent.farPlane(), + distance - radius, + distance + radius, _boresight ); } @@ -390,7 +397,7 @@ void RenderablePlanetProjection::update(const UpdateData& data) { _projectionComponent.update(); - _time = Time::ref().currentTime(); + _time = Time::ref().j2000Seconds(); _capture = false; if (openspace::ImageSequencer::ref().isReady()){ diff --git a/modules/newhorizons/shaders/renderableModelDepth_fs.glsl b/modules/newhorizons/shaders/renderableModelDepth_fs.glsl new file mode 100644 index 0000000000..2b7bcfdaec --- /dev/null +++ b/modules/newhorizons/shaders/renderableModelDepth_fs.glsl @@ -0,0 +1,30 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#version __CONTEXT__ + +void main() { + gl_FragColor = vec4(1.0); + //gl_FragDepth = gl_FragCoord.z; +} diff --git a/modules/newhorizons/shaders/renderableModelDepth_vs.glsl b/modules/newhorizons/shaders/renderableModelDepth_vs.glsl new file mode 100644 index 0000000000..574a349ad4 --- /dev/null +++ b/modules/newhorizons/shaders/renderableModelDepth_vs.glsl @@ -0,0 +1,36 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#version __CONTEXT__ + +#include "PowerScaling/powerScaling_vs.hglsl" + +layout(location = 0) in vec4 in_position; + +uniform mat4 ProjectorMatrix; +uniform mat4 ModelTransform; + +void main() { + gl_Position = ProjectorMatrix * ModelTransform * psc_to_meter(in_position, vec2(1.0, 0.0)); +} diff --git a/modules/newhorizons/shaders/renderableModelProjection_fs.glsl b/modules/newhorizons/shaders/renderableModelProjection_fs.glsl index 30d4da79dd..7c69bc65bf 100644 --- a/modules/newhorizons/shaders/renderableModelProjection_fs.glsl +++ b/modules/newhorizons/shaders/renderableModelProjection_fs.glsl @@ -25,9 +25,8 @@ #version __CONTEXT__ in vec4 vs_position; +in vec4 vs_ndc; in vec4 vs_normal; -in vec2 vs_uv; -in vec4 ProjTexCoord; layout (location = 0) out vec4 color; // Even though the stencel texture is only a single channel, we still need to @@ -35,34 +34,53 @@ layout (location = 0) out vec4 color; layout (location = 1) out vec4 stencil; uniform sampler2D projectionTexture; +uniform sampler2D depthTexture; + +uniform bool needShadowMap; uniform mat4 ModelTransform; -uniform vec2 _scaling; uniform vec3 boresight; +uniform vec4 debugColor; bool inRange(float x, float a, float b) { return (x >= a && x <= b); } void main() { - vec2 uv = vec2(0.5,0.5)*vs_uv+vec2(0.5,0.5); - vec3 n = normalize(vs_normal.xyz); - vec4 projected = ProjTexCoord; + vec4 projected = vs_ndc; + vec2 uv = vec2(0.5) * projected.xy + vec2(0.5); - // normalize - projected.x /= projected.w; - projected.y /= projected.w; - // invert gl coordinates - projected.x = 1 - projected.x; + if (needShadowMap) { + float thisDepth = projected.z * 0.5 + 0.5; + float closestDepth = texture(depthTexture, uv).r; + float epsilon = 0.001; - if ((inRange(projected.x, 0, 1) && inRange(projected.y, 0, 1)) && (dot(n, boresight) < 0)) { - color = texture(projectionTexture, projected.xy); - color.a = 1.0; - stencil = vec4(1.0); + if (inRange(uv.x, 0.0, 1.0) && inRange(uv.y, 0.0, 1.0) && + dot(n, boresight) < 0 && thisDepth <= closestDepth + epsilon) + { + // color = texture(projectionTexture, projected.xy); + color = texture(projectionTexture, vec2(1.0) - uv); + color.a = 1.0; + stencil = vec4(1.0); + } + else { + color = vec4(vec3(0.0), 0.0); + stencil = vec4(0.0); + } } else { - color = vec4(vec3(0.0), 1.0); - stencil = vec4(0.0); + if (inRange(uv.x, 0.0, 1.0) && inRange(uv.y, 0.0, 1.0) && + dot(n, boresight) < 0) + { + // color = texture(projectionTexture, projected.xy); + color = texture(projectionTexture, vec2(1.0) - uv); + color.a = 1.0; + stencil = vec4(1.0); + } + else { + color = vec4(vec3(0.0), 0.0); + stencil = vec4(0.0); + } } } diff --git a/modules/newhorizons/shaders/renderableModelProjection_vs.glsl b/modules/newhorizons/shaders/renderableModelProjection_vs.glsl index 20c64bd812..2be32b0119 100644 --- a/modules/newhorizons/shaders/renderableModelProjection_vs.glsl +++ b/modules/newhorizons/shaders/renderableModelProjection_vs.glsl @@ -33,26 +33,20 @@ layout(location = 2) in vec3 in_normal; out vec4 vs_position; out vec4 vs_normal; out vec2 vs_uv; -out vec4 ProjTexCoord; +out vec4 vs_ndc; uniform mat4 ProjectorMatrix; uniform mat4 ModelTransform; -uniform vec2 _scaling; uniform vec3 boresight; void main() { - vs_position = in_position; - - vec4 tmp = in_position; - vec4 position = pscTransform(tmp, ModelTransform); - vs_position = position; - - vec4 raw_pos = psc_to_meter(in_position, _scaling); - ProjTexCoord = ProjectorMatrix * ModelTransform * raw_pos; + vec4 raw_pos = psc_to_meter(in_position, vec2(1.0, 0.0)); + vs_position = ProjectorMatrix * ModelTransform * raw_pos; vs_normal = normalize(ModelTransform * vec4(in_normal,0)); - + vs_ndc = vs_position / vs_position.w; + //match clipping plane vec2 texco = (in_st * 2) - 1; vs_uv = texco; diff --git a/modules/newhorizons/shaders/renderableModel_fs.glsl b/modules/newhorizons/shaders/renderableModel_fs.glsl index 240aba6ea4..efe16cf13c 100644 --- a/modules/newhorizons/shaders/renderableModel_fs.glsl +++ b/modules/newhorizons/shaders/renderableModel_fs.glsl @@ -47,7 +47,7 @@ Fragment getFragment() { textureColor.rgb = mix( textureColor.rgb, projectionColor.rgb, - _projectionFading + _projectionFading * projectionColor.a ); } @@ -84,12 +84,12 @@ Fragment getFragment() { color = diffuseAlbedo; } - float transparency = 1.0; - float alpha = _projectionFading * transparency; + // float transparency = 1.0; + // float alpha = _projectionFading * transparency; Fragment frag; - frag.color = vec4(color, alpha); + frag.color = vec4(color, 1.0); frag.depth = vs_positionScreenSpace.w; return frag; } diff --git a/modules/newhorizons/shaders/renderablePlanetProjection_fs.glsl b/modules/newhorizons/shaders/renderablePlanetProjection_fs.glsl index 7213c6c22f..ff8698c866 100644 --- a/modules/newhorizons/shaders/renderablePlanetProjection_fs.glsl +++ b/modules/newhorizons/shaders/renderablePlanetProjection_fs.glsl @@ -73,6 +73,8 @@ void main() { projected.x /= projected.w; projected.y /= projected.w; + projected = projected * 0.5 + vec4(0.5); + vec3 normal = normalize((ModelTransform*vec4(vertex.xyz,0)).xyz); vec3 v_b = normalize(boresight); @@ -83,7 +85,7 @@ void main() { { // The 1-x is in this texture call because of flipped textures // to be fixed soon ---abock - color = texture(projectionTexture, vec2(projected.x, 1-projected.y)); + color = texture(projectionTexture, vec2(projected.x, projected.y)); stencil = vec4(1.0); } else { diff --git a/modules/newhorizons/util/decoder.cpp b/modules/newhorizons/util/decoder.cpp index 865815035a..74e1c9b87a 100644 --- a/modules/newhorizons/util/decoder.cpp +++ b/modules/newhorizons/util/decoder.cpp @@ -23,8 +23,11 @@ ****************************************************************************************/ #include + #include + #include +#include namespace { const std::string _loggerCat = "Decoder"; @@ -32,29 +35,22 @@ const std::string _loggerCat = "Decoder"; namespace openspace { -Decoder* Decoder::createFromDictionary(const ghoul::Dictionary& dictionary, const std::string& type) +std::unique_ptr Decoder::createFromDictionary( + const ghoul::Dictionary& dictionary, const std::string& type) { ghoul::TemplateFactory* factory = FactoryManager::ref().factory(); Decoder* result = factory->create(type, dictionary); if (result == nullptr) { - LERROR("Failed creating Payload object of type '" << type << "'"); - return nullptr; + throw ghoul::RuntimeError( + "Failed creating payload object of type '" + type + '"', + "Decoder" + ); } - return result; + return std::unique_ptr(result); } -Decoder::Decoder() -{ -} - -Decoder::Decoder(const ghoul::Dictionary& dictionary) -{ -} - -Decoder::~Decoder() -{ -} +Decoder::~Decoder() {} } // namespace openspace \ No newline at end of file diff --git a/modules/newhorizons/util/decoder.h b/modules/newhorizons/util/decoder.h index c4e2c9eb56..700cf06452 100644 --- a/modules/newhorizons/util/decoder.h +++ b/modules/newhorizons/util/decoder.h @@ -26,20 +26,23 @@ #define __DECODER_H__ #include -#include + +#include namespace openspace { class Decoder { public: - static Decoder* createFromDictionary(const ghoul::Dictionary& dictionary, const std::string& type); + static std::unique_ptr createFromDictionary( + const ghoul::Dictionary& dictionary, const std::string& type); - Decoder(const ghoul::Dictionary& dictionary); virtual ~Decoder(); + virtual std::string getDecoderType() = 0; virtual std::vector getTranslation() = 0; + protected: - Decoder(); + Decoder() = default; }; } // namespace openspace diff --git a/modules/newhorizons/util/hongkangparser.cpp b/modules/newhorizons/util/hongkangparser.cpp index 57034403d8..bd8a20b7ac 100644 --- a/modules/newhorizons/util/hongkangparser.cpp +++ b/modules/newhorizons/util/hongkangparser.cpp @@ -75,10 +75,10 @@ HongKangParser::HongKangParser(std::string name, std::string fileName, ghoul::Dictionary decoderDictionary; translationDictionary.getValue(currentKey, decoderDictionary); - Decoder* decoder = Decoder::createFromDictionary(decoderDictionary, decoders[i]); + auto decoder = Decoder::createFromDictionary(decoderDictionary, decoders[i]); //insert decoder to map - this will be used in the parser to determine //behavioral characteristics of each instrument - _fileTranslation[keys[j]] = decoder; + _fileTranslation[keys[j]] = std::move(decoder); } } //Hong's playbook needs _only_ instrument translation though. @@ -201,7 +201,7 @@ bool HongKangParser::create() { if (it->second->getDecoderType() == "SCANNER"){ // SCANNER START scan_start = time; - InstrumentDecoder* scanner = static_cast(it->second); + InstrumentDecoder* scanner = static_cast(it->second.get()); std::string endNominal = scanner->getStopCommand(); // store current position in file diff --git a/modules/newhorizons/util/hongkangparser.h b/modules/newhorizons/util/hongkangparser.h index ef1db0023d..a1959c923e 100644 --- a/modules/newhorizons/util/hongkangparser.h +++ b/modules/newhorizons/util/hongkangparser.h @@ -46,7 +46,6 @@ public: bool create() override; void findPlaybookSpecifiedTarget(std::string line, std::string& target); - virtual std::map getTranslation(){ return _fileTranslation; }; private: double getMetFromET(double et); @@ -70,7 +69,7 @@ private: std::string _name; std::string _fileName; std::string _spacecraft; - std::map _fileTranslation; + std::map> _fileTranslation; std::vector _potentialTargets; }; diff --git a/modules/newhorizons/util/imagesequencer.cpp b/modules/newhorizons/util/imagesequencer.cpp index 1a7eec7fdf..e5e1f5233e 100644 --- a/modules/newhorizons/util/imagesequencer.cpp +++ b/modules/newhorizons/util/imagesequencer.cpp @@ -338,9 +338,9 @@ void ImageSequencer::runSequenceParser(SequenceParser* parser){ bool parserComplete = parser->create(); if (parserComplete){ // get new data - std::map translations = parser->getTranslation(); // in1 + std::map>& translations = parser->getTranslation(); // in1 std::map imageData = parser->getSubsetMap(); // in2 - std::vector> instrumentTimes = parser->getIstrumentTimes(); //in3 + std::vector> instrumentTimes = parser->getInstrumentTimes(); //in3 std::vector> targetTimes = parser->getTargetTimes(); //in4 std::vector captureProgression = parser->getCaptureProgression(); //in5 @@ -349,11 +349,14 @@ void ImageSequencer::runSequenceParser(SequenceParser* parser){ LERROR("Missing sequence data"); return; } - + // append data - _fileTranslation.insert(translations.begin(), translations.end()); - for (auto it : imageData){ + for (auto& it : translations) { + _fileTranslation[it.first] = std::move(it.second); + } + + for (auto& it : imageData){ if (_subsetMap.find(it.first) == _subsetMap.end()) { // if key not exist yet - add sequence data for key (target) _subsetMap.insert(it); @@ -404,7 +407,7 @@ void ImageSequencer::runSequenceParser(SequenceParser* parser){ sortData(); // extract payload from _fileTranslation - for (auto t : _fileTranslation){ + for (auto& t : _fileTranslation){ if (t.second->getDecoderType() == "CAMERA" || t.second->getDecoderType() == "SCANNER"){ std::vector spiceIDs = t.second->getTranslation(); diff --git a/modules/newhorizons/util/imagesequencer.h b/modules/newhorizons/util/imagesequencer.h index 07f981cc9c..4729dab641 100644 --- a/modules/newhorizons/util/imagesequencer.h +++ b/modules/newhorizons/util/imagesequencer.h @@ -152,7 +152,7 @@ private: * \see Decoder * \see (projection mod files) */ - std::map _fileTranslation; + std::map> _fileTranslation; /* * This is the main container of image data. The key is the target name, diff --git a/modules/newhorizons/util/instrumenttimesparser.cpp b/modules/newhorizons/util/instrumenttimesparser.cpp index 2d058e2dee..92765eb190 100644 --- a/modules/newhorizons/util/instrumenttimesparser.cpp +++ b/modules/newhorizons/util/instrumenttimesparser.cpp @@ -65,7 +65,7 @@ InstrumentTimesParser::InstrumentTimesParser( for (const auto& instrumentKey : instruments.keys()) { ghoul::Dictionary instrument = instruments.value(instrumentKey); ghoul::Dictionary files = instrument.value(KeyInstrumentFiles); - _fileTranslation[instrumentKey] = Decoder::createFromDictionary(instrument, KeyInstrument); + _fileTranslation[instrumentKey] = std::move(Decoder::createFromDictionary(instrument, KeyInstrument)); for (int i = 0; i < files.size(); i++) { std::string filename = files.value(std::to_string(i + 1)); _instrumentFiles[instrumentKey].push_back(filename); @@ -96,23 +96,39 @@ bool InstrumentTimesParser::create() { std::string instrumentID = it->first; for (std::string filename: it->second) { std::string filepath = FileSys.pathByAppendingComponent(sequenceDir.path(), filename); + + if (!FileSys.fileExists(filepath)) { + LERROR("Unable to read file " << filepath << ". Skipping file."); + continue; + } // Read file into string - std::ifstream in(filepath); + std::ifstream inFile(filepath); std::string line; std::smatch matches; - TimeRange instrumentActiveTimeRange; - - while (std::getline(in, line)) { + bool successfulRead = true; + while (std::getline(inFile, line)) { if (std::regex_match(line, matches, _pattern)) { - ghoul_assert(matches.size() == 3, "Bad event data formatting. Must have regex 3 matches (source string, start time, stop time)."); - std::string start = matches[1].str(); - std::string stop = matches[2].str(); - + if (matches.size() != 3) { + LERROR("Bad event data formatting. Must \ + have regex 3 matches (source string, start time, stop time)."); + successfulRead = false; + break; + } + TimeRange captureTimeRange; - captureTimeRange.start = SpiceManager::ref().ephemerisTimeFromDate(start); - captureTimeRange.end = SpiceManager::ref().ephemerisTimeFromDate(stop); + try { // parse date strings + std::string start = matches[1].str(); + std::string stop = matches[2].str(); + captureTimeRange.start = SpiceManager::ref().ephemerisTimeFromDate(start); + captureTimeRange.end = SpiceManager::ref().ephemerisTimeFromDate(stop); + } + catch (const SpiceManager::SpiceException& e){ + LERROR(e.what()); + successfulRead = false; + break; + } instrumentActiveTimeRange.include(captureTimeRange); @@ -131,8 +147,10 @@ bool InstrumentTimesParser::create() { _subsetMap[_target]._subset.push_back(image); } } - _subsetMap[_target]._range = instrumentActiveTimeRange; - _instrumentTimes.push_back({ instrumentID, instrumentActiveTimeRange }); + if (successfulRead){ + _subsetMap[_target]._range.include(instrumentActiveTimeRange); + _instrumentTimes.push_back({ instrumentID, instrumentActiveTimeRange }); + } } } diff --git a/modules/newhorizons/util/instrumenttimesparser.h b/modules/newhorizons/util/instrumenttimesparser.h index 4674cc73c3..86f4e6648e 100644 --- a/modules/newhorizons/util/instrumenttimesparser.h +++ b/modules/newhorizons/util/instrumenttimesparser.h @@ -45,13 +45,7 @@ public: bool create() override; - //virtual std::map getTranslation() override; - - // temporary need to figure this out - std::map getTranslation(){ return _fileTranslation; }; - private: - std::regex _pattern; std::map> _instrumentFiles; @@ -59,7 +53,7 @@ private: std::string _name; std::string _fileName; std::string _spacecraft; - std::map _fileTranslation; + //std::map> _fileTranslation; std::vector _specsOfInterest; std::string _target; diff --git a/modules/newhorizons/util/labelparser.cpp b/modules/newhorizons/util/labelparser.cpp index 3ce4c5271b..bccdb49ff6 100644 --- a/modules/newhorizons/util/labelparser.cpp +++ b/modules/newhorizons/util/labelparser.cpp @@ -22,18 +22,23 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#include -#include -#include -#include -#include +#include + #include + +#include +#include + +#include +#include +#include +#include + #include #include #include #include -#include namespace { const std::string _loggerCat = "LabelParser"; @@ -54,24 +59,24 @@ LabelParser::LabelParser(std::string name, std::string fileName, //get the different instrument types const std::vector& decoders = translationDictionary.keys(); //for each decoder (assuming might have more if hong makes changes) - for (int i = 0; i < decoders.size(); i++){ + for (int i = 0; i < decoders.size(); ++i) { ghoul::Dictionary typeDictionary; translationDictionary.getValue(decoders[i], typeDictionary); //create dictionary containing all {playbookKeys , spice IDs} - if (decoders[i] == "Instrument"){ + if (decoders[i] == "Instrument") { //for each playbook call -> create a Decoder object - const std::vector& keys = typeDictionary.keys(); - for (int j = 0; j < keys.size(); j++){ + std::vector keys = typeDictionary.keys(); + for (int j = 0; j < keys.size(); ++j){ std::string currentKey = decoders[i] + "." + keys[j]; - ghoul::Dictionary decoderDictionary; - translationDictionary.getValue(currentKey, decoderDictionary); + ghoul::Dictionary decoderDictionary = + translationDictionary.value(currentKey); - Decoder *decoder = Decoder::createFromDictionary(decoderDictionary, decoders[i]); + auto decoder = Decoder::createFromDictionary(decoderDictionary, decoders[i]); //insert decoder to map - this will be used in the parser to determine //behavioral characteristics of each instrument - _fileTranslation[keys[j]] = decoder; + _fileTranslation[keys[j]] = std::move(decoder); } } if (decoders[i] == "Target"){ @@ -91,17 +96,17 @@ LabelParser::LabelParser(std::string name, std::string fileName, for (int j = 0; j < keys.size(); j++){ ghoul::Dictionary itemDictionary; convertDictionary.getValue(keys[j], itemDictionary); - Decoder *decoder = Decoder::createFromDictionary(itemDictionary, decoders[i]); + auto decoder = Decoder::createFromDictionary(itemDictionary, decoders[i]); //insert decoder to map - this will be used in the parser to determine //behavioral characteristics of each instrument - _fileTranslation[keys[j]] = decoder; + _fileTranslation[keys[j]] = std::move(decoder); }; } } } std::string LabelParser::decode(std::string line){ - for (auto key : _fileTranslation){ + for (auto& key : _fileTranslation){ std::size_t value = line.find(key.first); if (value != std::string::npos){ std::string toTranslate = line.substr(value); @@ -121,7 +126,7 @@ std::string LabelParser::decode(std::string line){ } std::string LabelParser::encode(std::string line) { - for (auto key : _fileTranslation) { + for (auto& key : _fileTranslation) { std::size_t value = line.find(key.first); if (value != std::string::npos) { return line.substr(value); @@ -232,29 +237,31 @@ bool LabelParser::create() { LINFO("Please make sure input data adheres to format https://pds.jpl.nasa.gov/documents/qs/labels.html"); } } - if (count == _specsOfInterest.size()){ - count = 0; - std::string ext = "jpg"; - path.replace(path.begin() + position, path.end(), ext); - bool fileExists = FileSys.fileExists(path); - if (!fileExists) { - ext = "JPG"; - path.replace(path.begin() + position, path.end(), ext); - fileExists = FileSys.fileExists(path); - } - if (fileExists) { - Image image; - std::vector spiceInstrument; - spiceInstrument.push_back(_instrumentID); - createImage(image, startTime, stopTime, spiceInstrument, _target, path); - - _subsetMap[image.target]._subset.push_back(image); - _subsetMap[image.target]._range.include(startTime); + if (count == _specsOfInterest.size()) { + using ghoul::io::TextureReader; + auto extensions = TextureReader::ref().supportedExtensions(); - _captureProgression.push_back(startTime); - std::stable_sort(_captureProgression.begin(), _captureProgression.end()); + count = 0; + + using namespace std::literals; + std::string p = path.substr(0, path.size() - ("lbl"s).size()); + for (const std::string& ext : extensions) { + path = p + ext; + if (FileSys.fileExists(path)) { + Image image; + std::vector spiceInstrument; + spiceInstrument.push_back(_instrumentID); + createImage(image, startTime, stopTime, spiceInstrument, _target, path); + + _subsetMap[image.target]._subset.push_back(image); + _subsetMap[image.target]._range.include(startTime); + + _captureProgression.push_back(startTime); + std::stable_sort(_captureProgression.begin(), _captureProgression.end()); + + break; + } } - } } while (!file.eof()); } diff --git a/modules/newhorizons/util/labelparser.h b/modules/newhorizons/util/labelparser.h index c0cf393ce6..a65eaf1543 100644 --- a/modules/newhorizons/util/labelparser.h +++ b/modules/newhorizons/util/labelparser.h @@ -43,7 +43,7 @@ public: bool create() override; // temporary need to figure this out - std::map getTranslation(){ return _fileTranslation; }; + //std::map getTranslation() { return _fileTranslation; }; private: void createImage(Image& image, @@ -64,7 +64,6 @@ private: std::string _name; std::string _fileName; std::string _spacecraft; - std::map _fileTranslation; std::vector _specsOfInterest; std::string _target; diff --git a/modules/newhorizons/util/projectioncomponent.cpp b/modules/newhorizons/util/projectioncomponent.cpp index 6b92aa5fe1..21a36cbd61 100644 --- a/modules/newhorizons/util/projectioncomponent.cpp +++ b/modules/newhorizons/util/projectioncomponent.cpp @@ -33,6 +33,7 @@ #include #include +#include #include #include @@ -42,8 +43,6 @@ namespace { const std::string keyInstrument = "Instrument.Name"; const std::string keyInstrumentFovy = "Instrument.Fovy"; const std::string keyInstrumentAspect = "Instrument.Aspect"; - const std::string keyInstrumentNear = "Instrument.Near"; - const std::string keyInstrumentFar = "Instrument.Far"; const std::string keyProjObserver = "Projection.Observer"; const std::string keyProjTarget = "Projection.Target"; @@ -54,6 +53,8 @@ namespace { const std::string keyTranslation = "DataInputTranslation"; const std::string keyNeedsTextureMapDilation = "Projection.TextureMap"; + const std::string keyNeedsShadowing = "Projection.ShadowMap"; + const std::string keyTextureMapAspectRatio = "Projection.AspectRatio"; const std::string sequenceTypeImage = "image-sequence"; const std::string sequenceTypePlaybook = "playbook"; @@ -69,25 +70,55 @@ namespace { namespace openspace { using ghoul::Dictionary; +using glm::ivec2; ProjectionComponent::ProjectionComponent() : properties::PropertyOwner() , _performProjection("performProjection", "Perform Projections", true) , _clearAllProjections("clearAllProjections", "Clear Projections", false) , _projectionFading("projectionFading", "Projection Fading", 1.f, 0.f, 1.f) + , _textureSize("textureSize", "Texture Size", ivec2(16), ivec2(16), ivec2(32768)) + , _applyTextureSize("applyTextureSize", "Apply Texture Size") + , _textureSizeDirty(false) , _projectionTexture(nullptr) - , _needsTextureMapDilation(false) { setName("ProjectionComponent"); + _shadowing.isEnabled = false; + _dilation.isEnabled = false; + addProperty(_performProjection); addProperty(_clearAllProjections); addProperty(_projectionFading); + + addProperty(_textureSize); + addProperty(_applyTextureSize); + _applyTextureSize.onChange([this]() { _textureSizeDirty = true; }); } bool ProjectionComponent::initialize() { - bool a = generateProjectionLayerTexture(); - bool b = auxiliaryRendertarget(); + int maxSize = OpenGLCap.max2DTextureSize(); + glm::ivec2 size; + + if (_projectionTextureAspectRatio > 1.f) { + size.x = maxSize; + size.y = static_cast(maxSize / _projectionTextureAspectRatio); + } + else { + size.x = static_cast(maxSize * _projectionTextureAspectRatio); + size.y = maxSize; + } + + _textureSize.setMaxValue(size); + _textureSize = size / 2; + + // We only want to use half the resolution per default: + size /= 2; + + bool success = generateProjectionLayerTexture(size); + success &= generateDepthTexture(size); + success &= auxiliaryRendertarget(); + success &= depthRendertarget(); using std::unique_ptr; using ghoul::opengl::Texture; @@ -103,8 +134,7 @@ bool ProjectionComponent::initialize() { } _placeholderTexture = std::move(texture); - - if (_needsTextureMapDilation) { + if (_dilation.isEnabled) { _dilation.program = ghoul::opengl::ProgramObject::Build( "Dilation", "${MODULE_NEWHORIZONS}/shaders/dilation_vs.glsl", @@ -139,7 +169,7 @@ bool ProjectionComponent::initialize() { glBindVertexArray(0); } - return a && b; + return success; } bool ProjectionComponent::deinitialize() { @@ -147,7 +177,7 @@ bool ProjectionComponent::deinitialize() { glDeleteFramebuffers(1, &_fboID); - if (_needsTextureMapDilation) { + if (_dilation.isEnabled) { glDeleteFramebuffers(1, &_dilation.fbo); glDeleteVertexArrays(1, &_dilation.vao); glDeleteBuffers(1, &_dilation.vbo); @@ -170,8 +200,7 @@ bool ProjectionComponent::initializeProjectionSettings(const Dictionary& diction completeSuccess &= dictionary.getValue(keyProjTarget, _projecteeID); completeSuccess &= dictionary.getValue(keyInstrumentFovy, _fovy); completeSuccess &= dictionary.getValue(keyInstrumentAspect, _aspectRatio); - completeSuccess &= dictionary.getValue(keyInstrumentNear, _nearPlane); - completeSuccess &= dictionary.getValue(keyInstrumentFar, _farPlane); + ghoul_assert(completeSuccess, "All neccessary attributes not found in modfile"); std::string a = "NONE"; @@ -195,7 +224,17 @@ bool ProjectionComponent::initializeProjectionSettings(const Dictionary& diction } if (dictionary.hasKeyAndValue(keyNeedsTextureMapDilation)) { - _needsTextureMapDilation = dictionary.value(keyNeedsTextureMapDilation); + _dilation.isEnabled = dictionary.value(keyNeedsTextureMapDilation); + } + + if (dictionary.hasKeyAndValue(keyNeedsShadowing)) { + _shadowing.isEnabled = dictionary.value(keyNeedsShadowing); + } + + _projectionTextureAspectRatio = 1.f; + if (dictionary.hasKeyAndValue(keyTextureMapAspectRatio)) { + _projectionTextureAspectRatio = + static_cast(dictionary.value(keyTextureMapAspectRatio)); } return completeSuccess; @@ -283,6 +322,190 @@ void ProjectionComponent::imageProjectBegin() { // keep handle to the current bound FBO glGetIntegerv(GL_FRAMEBUFFER_BINDING, &_defaultFBO); + if (_textureSizeDirty) { + LDEBUG("Changing texture size to " << std::to_string(_textureSize)); + + // If the texture size has changed, we have to allocate new memory and copy + // the image texture to the new target + + using ghoul::opengl::Texture; + using ghoul::opengl::FramebufferObject; + + // Make a copy of the old textures + std::unique_ptr oldProjectionTexture = std::move(_projectionTexture); + std::unique_ptr oldDilationStencil = std::move(_dilation.stencilTexture); + std::unique_ptr oldDilationTexture = std::move(_dilation.texture); + std::unique_ptr oldDepthTexture = std::move(_shadowing.texture); + + // Generate the new textures + generateProjectionLayerTexture(_textureSize); + + if (_shadowing.isEnabled) { + generateDepthTexture(_textureSize); + } + + auto copyFramebuffers = [](Texture* src, Texture* dst, const std::string& msg) { + glFramebufferTexture( + GL_READ_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, + *src, + 0 + ); + + GLenum status = glCheckFramebufferStatus(GL_READ_FRAMEBUFFER); + if (!FramebufferObject::errorChecking(status).empty()) { + LERROR( + "Read Buffer (" << msg << "): " << + FramebufferObject::errorChecking(status) + ); + } + + glFramebufferTexture( + GL_DRAW_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, + *dst, + 0 + ); + + status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); + if (!FramebufferObject::errorChecking(status).empty()) { + LERROR( + "Draw Buffer (" << msg << "): " << + FramebufferObject::errorChecking(status) + ); + } + + glBlitFramebuffer( + 0, 0, + src->dimensions().x, src->dimensions().y, + 0, 0, + dst->dimensions().x, dst->dimensions().y, + GL_COLOR_BUFFER_BIT, + GL_LINEAR + ); + }; + + auto copyDepthBuffer = [](Texture* src, Texture* dst, const std::string& msg) { + glFramebufferTexture( + GL_READ_FRAMEBUFFER, + GL_DEPTH_ATTACHMENT, + *src, + 0 + ); + + GLenum status = glCheckFramebufferStatus(GL_READ_FRAMEBUFFER); + if (!FramebufferObject::errorChecking(status).empty()) { + LERROR( + "Read Buffer (" << msg << "): " << + FramebufferObject::errorChecking(status) + ); + } + + glFramebufferTexture( + GL_DRAW_FRAMEBUFFER, + GL_DEPTH_ATTACHMENT, + *dst, + 0 + ); + + status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); + if (!FramebufferObject::errorChecking(status).empty()) { + LERROR( + "Draw Buffer (" << msg << "): " << + FramebufferObject::errorChecking(status) + ); + } + + glBlitFramebuffer( + 0, 0, + src->dimensions().x, src->dimensions().y, + 0, 0, + dst->dimensions().x, dst->dimensions().y, + GL_DEPTH_BUFFER_BIT, + GL_NEAREST + ); + }; + + GLuint fbos[2]; + glGenFramebuffers(2, fbos); + glBindFramebuffer(GL_READ_FRAMEBUFFER, fbos[0]); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbos[1]); + + copyFramebuffers( + oldProjectionTexture.get(), + _projectionTexture.get(), + "Projection" + ); + + if (_dilation.isEnabled) { + copyFramebuffers( + oldDilationStencil.get(), + _dilation.stencilTexture.get(), + "Dilation Stencil" + ); + + copyFramebuffers( + oldDilationTexture.get(), + _dilation.texture.get(), + "Dilation Texture" + ); + } + + if (_shadowing.isEnabled) { + copyDepthBuffer( + oldDepthTexture.get(), + _shadowing.texture.get(), + "Shadowing" + ); + } + + glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + glDeleteFramebuffers(2, fbos); + + glBindFramebuffer(GL_FRAMEBUFFER, _fboID); + glFramebufferTexture2D( + GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, + *_projectionTexture, + 0 + ); + + if (_dilation.isEnabled) { + // We only need the stencil texture if we need to dilate + glFramebufferTexture2D( + GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT1, + GL_TEXTURE_2D, + *_dilation.stencilTexture, + 0 + ); + + glBindFramebuffer(GL_FRAMEBUFFER, _dilation.fbo); + glFramebufferTexture2D( + GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, + *_dilation.texture, + 0 + ); + } + + if (_shadowing.isEnabled) { + glBindFramebuffer(GL_FRAMEBUFFER, _depthFboID); + glFramebufferTexture2D( + GL_FRAMEBUFFER, + GL_DEPTH_ATTACHMENT, + GL_TEXTURE_2D, + *_shadowing.texture, + 0 + ); + } + + _textureSizeDirty = false; + } + glGetIntegerv(GL_VIEWPORT, _viewport); glBindFramebuffer(GL_FRAMEBUFFER, _fboID); @@ -292,14 +515,46 @@ void ProjectionComponent::imageProjectBegin() { static_cast(_projectionTexture->height()) ); - if (_needsTextureMapDilation) { + if (_dilation.isEnabled) { GLenum buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }; glDrawBuffers(2, buffers); } } +bool ProjectionComponent::needsShadowMap() const { + return _shadowing.isEnabled; +} + +ghoul::opengl::Texture& ProjectionComponent::depthTexture() { + return *_shadowing.texture; +} + +void ProjectionComponent::depthMapRenderBegin() { + ghoul_assert(_shadowing.isEnabled, "Shadowing is not enabled"); + + // keep handle to the current bound FBO + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &_defaultFBO); + glGetIntegerv(GL_VIEWPORT, _viewport); + + glBindFramebuffer(GL_FRAMEBUFFER, _depthFboID); + glEnable(GL_DEPTH_TEST); + + glViewport( + 0, 0, + static_cast(_shadowing.texture->width()), + static_cast(_shadowing.texture->height()) + ); + + glClear(GL_DEPTH_BUFFER_BIT); +} + +void ProjectionComponent::depthMapRenderEnd() { + glBindFramebuffer(GL_FRAMEBUFFER, _defaultFBO); + glViewport(_viewport[0], _viewport[1], _viewport[2], _viewport[3]); +} + void ProjectionComponent::imageProjectEnd() { - if (_needsTextureMapDilation) { + if (_dilation.isEnabled) { glBindFramebuffer(GL_FRAMEBUFFER, _dilation.fbo); glDisable(GL_BLEND); @@ -328,13 +583,34 @@ void ProjectionComponent::imageProjectEnd() { } void ProjectionComponent::update() { - if (_needsTextureMapDilation) { - if (_dilation.program->isDirty()) { - _dilation.program->rebuildFromFile(); - } + if (_dilation.isEnabled && _dilation.program->isDirty()) { + _dilation.program->rebuildFromFile(); } } +bool ProjectionComponent::depthRendertarget() { + GLint defaultFBO; + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO); + // setup FBO + glGenFramebuffers(1, &_depthFboID); + glBindFramebuffer(GL_FRAMEBUFFER, _depthFboID); + glFramebufferTexture2D( + GL_FRAMEBUFFER, + GL_DEPTH_ATTACHMENT, + GL_TEXTURE_2D, + *_shadowing.texture, + 0); + + glDrawBuffer(GL_NONE); + + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + if (status != GL_FRAMEBUFFER_COMPLETE) + return false; + + glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO); + return true; +} + bool ProjectionComponent::auxiliaryRendertarget() { bool completeSuccess = true; @@ -359,7 +635,7 @@ bool ProjectionComponent::auxiliaryRendertarget() { } - if (_needsTextureMapDilation) { + if (_dilation.isEnabled) { // We only need the stencil texture if we need to dilate glFramebufferTexture2D( GL_FRAMEBUFFER, @@ -408,32 +684,24 @@ glm::mat4 ProjectionComponent::computeProjectorMatrix(const glm::vec3 loc, glm:: float nearPlane, float farPlane, glm::vec3& boreSight) { + //rotate boresight into correct alignment boreSight = instrumentMatrix*aim; glm::vec3 uptmp(instrumentMatrix*glm::dvec3(up)); // create view matrix - glm::vec3 e3 = glm::normalize(boreSight); + glm::vec3 e3 = glm::normalize(-boreSight); glm::vec3 e1 = glm::normalize(glm::cross(uptmp, e3)); glm::vec3 e2 = glm::normalize(glm::cross(e3, e1)); - glm::mat4 projViewMatrix = glm::mat4( - e1.x, e2.x, e3.x, 0.f, - e1.y, e2.y, e3.y, 0.f, - e1.z, e2.z, e3.z, 0.f, - -glm::dot(e1, loc), -glm::dot(e2, loc), -glm::dot(e3, loc), 1.f - ); + + glm::mat4 projViewMatrix = glm::mat4(e1.x, e2.x, e3.x, 0.f, + e1.y, e2.y, e3.y, 0.f, + e1.z, e2.z, e3.z, 0.f, + glm::dot(e1, -loc), glm::dot(e2, -loc), glm::dot(e3, -loc), 1.f); // create perspective projection matrix - glm::mat4 projProjectionMatrix = glm::perspective( - glm::radians(fieldOfViewY), aspectRatio, nearPlane, farPlane - ); - // bias matrix - glm::mat4 projNormalizationMatrix = glm::mat4( - 0.5f, 0.f, 0.f, 0.f, - 0.f, 0.5f, 0.f, 0.f, - 0.f, 0.f, 0.5f, 0.f, - 0.5f, 0.5f, 0.5f, 1.f - ); - return projNormalizationMatrix * projProjectionMatrix * projViewMatrix; + glm::mat4 projProjectionMatrix = glm::perspective(glm::radians(fieldOfViewY), aspectRatio, nearPlane, farPlane); + + return projProjectionMatrix*projViewMatrix; } bool ProjectionComponent::doesPerformProjection() const { @@ -449,7 +717,7 @@ float ProjectionComponent::projectionFading() const { } ghoul::opengl::Texture& ProjectionComponent::projectionTexture() const { - if (_needsTextureMapDilation) { + if (_dilation.isEnabled) { return *_dilation.texture; } else { @@ -481,14 +749,6 @@ float ProjectionComponent::aspectRatio() const { return _aspectRatio; } -float ProjectionComponent::nearPlane() const { - return _nearPlane; -} - -float ProjectionComponent::farPlane() const { - return _farPlane; -} - void ProjectionComponent::clearAllProjections() { // keep handle to the current bound FBO GLint defaultFBO; @@ -504,7 +764,7 @@ void ProjectionComponent::clearAllProjections() { glClearColor(0.f, 0.f, 0.f, 0.f); glClear(GL_COLOR_BUFFER_BIT); - if (_needsTextureMapDilation) { + if (_dilation.isEnabled) { glBindFramebuffer(GL_FRAMEBUFFER, _dilation.fbo); glClear(GL_COLOR_BUFFER_BIT); } @@ -543,14 +803,12 @@ std::shared_ptr ProjectionComponent::loadProjectionTextu return std::move(texture); } -bool ProjectionComponent::generateProjectionLayerTexture() { - int maxSize = OpenGLCap.max2DTextureSize() / 2; - +bool ProjectionComponent::generateProjectionLayerTexture(const ivec2& size) { LINFO( - "Creating projection texture of size '" << maxSize << ", " << maxSize / 2 << "'" + "Creating projection texture of size '" << size.x << ", " << size.y << "'" ); _projectionTexture = std::make_unique ( - glm::uvec3(maxSize, maxSize / 2, 1), + glm::uvec3(size, 1), ghoul::opengl::Texture::Format::RGBA ); if (_projectionTexture) { @@ -558,9 +816,9 @@ bool ProjectionComponent::generateProjectionLayerTexture() { //_projectionTexture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap); } - if (_needsTextureMapDilation) { + if (_dilation.isEnabled) { _dilation.texture = std::make_unique( - glm::uvec3(maxSize, maxSize / 2, 1), + glm::uvec3(size, 1), ghoul::opengl::Texture::Format::RGBA ); @@ -570,7 +828,7 @@ bool ProjectionComponent::generateProjectionLayerTexture() { } _dilation.stencilTexture = std::make_unique( - glm::uvec3(maxSize, maxSize / 2, 1), + glm::uvec3(size, 1), ghoul::opengl::Texture::Format::Red, ghoul::opengl::Texture::Format::Red ); @@ -586,4 +844,23 @@ bool ProjectionComponent::generateProjectionLayerTexture() { } +bool ProjectionComponent::generateDepthTexture(const ivec2& size) { + LINFO( + "Creating depth texture of size '" << size.x << ", " << size.y << "'" + ); + + _shadowing.texture = std::make_unique( + glm::uvec3(size, 1), + ghoul::opengl::Texture::Format::DepthComponent, + GL_DEPTH_COMPONENT32F + ); + + if (_shadowing.texture) { + _shadowing.texture->uploadTexture(); + } + + return _shadowing.texture != nullptr; + +} + } // namespace openspace diff --git a/modules/newhorizons/util/projectioncomponent.h b/modules/newhorizons/util/projectioncomponent.h index 3386b63a1d..6bae9afa6f 100644 --- a/modules/newhorizons/util/projectioncomponent.h +++ b/modules/newhorizons/util/projectioncomponent.h @@ -27,6 +27,8 @@ #include #include +#include +#include #include #include @@ -54,13 +56,17 @@ public: bool initializeProjectionSettings(const ghoul::Dictionary& dictionary); bool initializeParser(const ghoul::Dictionary& dictionary); + ghoul::opengl::Texture& depthTexture(); void imageProjectBegin(); void imageProjectEnd(); + void depthMapRenderBegin(); + void depthMapRenderEnd(); + void update(); - bool generateProjectionLayerTexture(); bool auxiliaryRendertarget(); + bool depthRendertarget(); std::shared_ptr loadProjectionTexture( const std::string& texturePath, @@ -81,6 +87,8 @@ public: bool needsClearProjection() const; float projectionFading() const; + bool needsShadowMap() const; + void clearAllProjections(); ghoul::opengl::Texture& projectionTexture() const; @@ -92,18 +100,25 @@ public: float fieldOfViewY() const; float aspectRatio() const; - float nearPlane() const; - float farPlane() const; + +private: + bool generateProjectionLayerTexture(const glm::ivec2& size); + bool generateDepthTexture(const glm::ivec2& size); protected: properties::BoolProperty _performProjection; properties::BoolProperty _clearAllProjections; properties::FloatProperty _projectionFading; - std::unique_ptr _projectionTexture; + properties::IVec2Property _textureSize; + properties::TriggerProperty _applyTextureSize; + bool _textureSizeDirty; + std::unique_ptr _projectionTexture; std::shared_ptr _placeholderTexture; + float _projectionTextureAspectRatio; + std::string _instrumentID; std::string _projectorID; std::string _projecteeID; @@ -111,16 +126,20 @@ protected: std::vector _potentialTargets; float _fovy; float _aspectRatio; - float _nearPlane; - float _farPlane; GLuint _fboID; + GLuint _depthFboID; GLint _defaultFBO; GLint _viewport[4]; - bool _needsTextureMapDilation; struct { + bool isEnabled; + std::unique_ptr texture; + } _shadowing; + + struct { + bool isEnabled; GLuint fbo; GLuint vao; GLuint vbo; diff --git a/modules/newhorizons/util/sequenceparser.cpp b/modules/newhorizons/util/sequenceparser.cpp index 340c3bdb62..6e36361fa6 100644 --- a/modules/newhorizons/util/sequenceparser.cpp +++ b/modules/newhorizons/util/sequenceparser.cpp @@ -42,7 +42,7 @@ namespace openspace { std::map SequenceParser::getSubsetMap(){ return _subsetMap; } -std::vector> SequenceParser::getIstrumentTimes(){ +std::vector> SequenceParser::getInstrumentTimes(){ return _instrumentTimes; } std::vector> SequenceParser::getTargetTimes(){ @@ -52,6 +52,9 @@ std::vector SequenceParser::getCaptureProgression(){ return _captureProgression; }; +std::map>& SequenceParser::getTranslation() { + return _fileTranslation; +} template void writeToBuffer(std::vector& buffer, size_t& currentWriteLocation, T value) { diff --git a/modules/newhorizons/util/sequenceparser.h b/modules/newhorizons/util/sequenceparser.h index 18dd755b2c..258a2b566a 100644 --- a/modules/newhorizons/util/sequenceparser.h +++ b/modules/newhorizons/util/sequenceparser.h @@ -28,14 +28,15 @@ #include #include +#include + #include +#include #include #include namespace openspace { -class Decoder; - struct Image { TimeRange timeRange; std::string path; @@ -54,9 +55,9 @@ class SequenceParser { public: virtual bool create() = 0; virtual std::map getSubsetMap() final; - virtual std::vector> getIstrumentTimes() final; + virtual std::vector> getInstrumentTimes() final; virtual std::vector> getTargetTimes() final; - virtual std::map getTranslation() = 0; + std::map>& getTranslation(); virtual std::vector getCaptureProgression() final; protected: @@ -67,6 +68,8 @@ protected: std::vector> _targetTimes; std::vector _captureProgression; + std::map> _fileTranslation; + NetworkEngine::MessageIdentifier _messageIdentifier; }; diff --git a/modules/toyvolume/toyvolumemodule.cpp b/modules/toyvolume/toyvolumemodule.cpp index 77b65bf4ed..f700830085 100644 --- a/modules/toyvolume/toyvolumemodule.cpp +++ b/modules/toyvolume/toyvolumemodule.cpp @@ -24,7 +24,6 @@ #include -#include #include #include diff --git a/openspace.cfg b/openspace.cfg index 61a05dd721..26fb6f447d 100644 --- a/openspace.cfg +++ b/openspace.cfg @@ -27,6 +27,7 @@ return { CONFIG = "${BASE_PATH}/config", CACHE = "${BASE_PATH}/cache", FONTS = "${OPENSPACE_DATA}/fonts", + DOCUMENTATION = "${BASE_PATH}/documentation" }, Fonts = { Mono = "${FONTS}/Droid_Sans_Mono/DroidSansMono.ttf", @@ -34,30 +35,38 @@ return { }, Logging = { LogLevel = "Debug", - ImmediateFlush = true, + ImmediateFlush = false, Logs = { - { Type = "HTML", FileName = "${BASE_PATH}/log.html", Append = false } + { Type = "html", File = "${BASE_PATH}/log.html", Append = false } }, CapabilitiesVerbosity = "Full" }, - LuaDocumentationFile = { - Type = "text", - File = "${BASE_PATH}/LuaScripting.txt" + LuaDocumentation = { + Type = "html", + File = "${DOCUMENTATION}/LuaScripting.html" }, - PropertyDocumentationFile = { - Type = "text", - File = "${BASE_PATH}/Properties.txt" + PropertyDocumentation = { + Type = "html", + File = "${DOCUMENTATION}/Properties.html" }, - ScriptLogFile = { + ScriptLog = { Type = "text", File = "${BASE_PATH}/ScriptLog.txt" }, KeyboardShortcuts = { - Type = "text", - File = "${BASE_PATH}/KeyboardMapping.txt" + Type = "html", + File = "${DOCUMENTATION}/KeyboardMapping.html" + }, + Documentation = { + Type = "html", + File = "${DOCUMENTATION}/Documentation.html" + }, + FactoryDocumentation = { + Type = "html", + File = "${DOCUMENTATION}/FactoryDocumentation.html" }, ShutdownCountdown = 3, - DownloadRequestURL = "http://130.236.132.168/request.cgi", + DownloadRequestURL = "http://data.openspaceproject.com/request.cgi", RenderingMethod = "Framebuffer" --RenderingMethod = "ABuffer" -- alternative: "Framebuffer" diff --git a/run_multiple_nodes.js b/run_multiple_nodes.js deleted file mode 100644 index 6881ba61e4..0000000000 --- a/run_multiple_nodes.js +++ /dev/null @@ -1,97 +0,0 @@ -var fs = require('fs'); -const exec = require('child_process').exec; - - -var path = process.argv[2]; -var confPath = process.argv[3]; -var nNodes = +process.argv[4]; - - -run(); - -function run(){ - if(process.argv.length !== 5){ - console.log("Error! Expected 3 arguments:"); - console.log(" <# nodes to generate>"); - return; - } - if(!path) return new Error("bad path!"); - if(!nNodes) return new Error("bad nNodes!"); - if(!confPath) return new Error("bad confPath!"); - - var s = generateConfigSrcForN_nodes(); - - fs.writeFile(confPath, s, function(err) { - if(err) { - return console.log(err); - } - - console.log("SGCT config generated!"); - execChildProcesses(); - }); -} - -function execChildProcesses(){ - for (var i = 0; i < nNodes; i++) { - - var cmd = path + " -local " + i; - if(i > 0){ - cmd += " --slave"; - } - - console.log(cmd); - exec(cmd, function(err, stdout, stderr){ - if (err) { - console.error(err); - return; - } - console.log(stdout); - console.error(stderr); - }); - } -} - - -function generateConfigSrcForN_nodes(){ - var s = ""; - s += '\ -\n\ -'; - - for (var i = 0; i < nNodes; i++) { - s += generateNode(i); - } - - s += '\n\ - \n\ - \n\ - \n\ -'; - - return s; -} - -function generateNode(i){ - var x = i > 0 ? ((640 + i * 578) % 1920) : 10; - var y = i > 0 ? ((300 + i * 258) % 1080) : 30; - return '\n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - \n\ - '; -} diff --git a/scripts/bind_keys.lua b/scripts/bind_keys.lua index 46571003ac..5bd674031a 100644 --- a/scripts/bind_keys.lua +++ b/scripts/bind_keys.lua @@ -6,10 +6,19 @@ dofile(openspace.absPath('${SCRIPTS}/common.lua')) openspace.clearKeys() helper.setCommonKeys() helper.setDeltaTimeKeys({ - 1, 5, 10, 20, 40, 60, 120, 360, 720, 1440, - 2880, 5760, 11520, 23040, 46080, 92160, 184320, 368640, 737280, 1474560, - 2949120, 5898240, 11796480, 23592960, 47185920, 94371840, 188743680, 377487360 +-- 1 2 3 4 5 6 7 8 9 0 +-------------------------------------------------------------------------------------------------------------------------- +-- 1s 2s 5s 10s 30s 1m 2m 5m 10m 30 min + 1, 2, 5, 10, 30, 60, 120, 300, 600, 1800, + +-- 1h 2h 3h 6h 12h 1d 2d 4d 1w 2w + 3600, 7200, 10800, 21600, 43200, 86400, 172800, 345600, 604800, 1209600, + +-- 1mo 2mo 3mo 6mo 1yr 2y 5y 10y 20y 50y + 2592000, 5184000, 7776000, 15552000, 31536000, 63072000, 157680000, 315360000, 630720000, 1576800000 }) +-- OBS: One month (1mo) is approximated by 30 days. + openspace.bindKey("q", helper.renderable.toggle('SunMarker')) openspace.bindKey("e", helper.renderable.toggle('EarthMarker')) @@ -25,4 +34,4 @@ openspace.bindKey("v", "openspace.time.setTime('2015-03-15T02:00:00.00')"); openspace.bindKeyLocal("h", "openspace.parallel.setAddress('127.0.0.2');openspace.parallel.setPort('25001');openspace.parallel.setPassword('test');openspace.parallel.connect();openspace.parallel.requestHostship('test');") openspace.bindKeyLocal("c", "openspace.parallel.setAddress('127.0.0.3');openspace.parallel.setPort('25001');openspace.parallel.setPassword('test');openspace.parallel.connect();") -openspace.bindKeyLocal("d", "openspace.parallel.setAddress('127.0.0.4');openspace.parallel.setPort('25001');openspace.parallel.setPassword('test');openspace.parallel.connect();") \ No newline at end of file +openspace.bindKeyLocal("d", "openspace.parallel.setAddress('127.0.0.4');openspace.parallel.setPort('25001');openspace.parallel.setPassword('test');openspace.parallel.connect();") diff --git a/scripts/bind_keys_osirisrex.lua b/scripts/bind_keys_osirisrex.lua new file mode 100644 index 0000000000..536a63cd1a --- /dev/null +++ b/scripts/bind_keys_osirisrex.lua @@ -0,0 +1,33 @@ +--[[ OpenSpace keybinding script ]]-- + +-- Load the common helper functions +dofile(openspace.absPath('${SCRIPTS}/common.lua')) + +--openspace.clearKeys() +--helper.setCommonKeys() + +-- Set focuses +openspace.bindKey("o", "openspace.setPropertyValue('Interaction.origin', 'OsirisRex')") +openspace.bindKey("b", "openspace.setPropertyValue('Interaction.origin', 'Bennu2')") + + +-- Quickfix backjumps in Osiris rex +openspace.bindKey("F6" , "openspace.printInfo('Set time: Launch'); openspace.time.setTime('2016 SEP 08 23:05:00');") +openspace.bindKey("F7" , "openspace.printInfo('Set time: Gravity Assist'); openspace.time.setTime('2017 SEP 22 15:00:00');") +openspace.bindKey("F8" , "openspace.printInfo('Set time: Approach'); openspace.time.setTime('2018-SEP-11 21:31:01.183');") +openspace.bindKey("F9" , "openspace.printInfo('Set time: Preliminary Survey'); openspace.time.setTime('2018-NOV-20 01:13:12.183');") +openspace.bindKey("F10", "openspace.printInfo('Set time: Orbital B'); openspace.time.setTime('2019-APR-08 10:35:27.186');") +openspace.bindKey("F11", "openspace.printInfo('Set time: Recon'); openspace.time.setTime('2019-MAY-25 03:50:31.195');") +-- OBS!! Avoid key F12 +-- Pressing F12 triggers a breakpoint on AMNH Windows machine, with with the following stack trace: +-- ntdll.dll!DbgBreakPoint() +-- ntdll.dll!DbgUiRemoteBreakin() +-- kernel32.dll!BaseThreadInitThunk() +-- ntdll.dll!RtUserThreadStart() + +openspace.bindKey("F4", "openspace.scriptScheduler.clear(); openspace.scriptScheduler.load('${OPENSPACE_DATA}/scene/osirisrex/scheduled_scripts.lua');") + +openspace.bindKey("q", helper.property.invert('SunMarker.renderable.enabled')) +openspace.bindKey("e", helper.property.invert('EarthMarker.renderable.enabled')) + +openspace.bindKey("c", "openspace.parallel.setAddress('130.236.142.51');openspace.parallel.setPassword('osiris2016');openspace.parallel.connect();") diff --git a/scripts/bind_keys_rosetta.lua b/scripts/bind_keys_rosetta.lua index d880520069..a81ff43db5 100644 --- a/scripts/bind_keys_rosetta.lua +++ b/scripts/bind_keys_rosetta.lua @@ -22,7 +22,8 @@ openspace.bindKey("F8", "openspace.setPropertyValue('67P.renderable.ProjectionCo openspace.bindKey("i", helper.renderable.toggle('ImagePlaneRosetta')) openspace.bindKey("q", helper.renderable.toggle('SunMarker')) -openspace.bindKey("e", helper.renderable.toggle('EarthMarker')) +openspace.bindKey("e", helper.renderable.toggle('JupiterTrail') .. helper.renderable.toggle('SaturnTrail') .. helper.renderable.toggle('UranusTrail') .. helper.renderable.toggle('NeptuneTrail')) +openspace.bindKey("f", helper.renderable.toggle('PhilaeTrail')) openspace.bindKeyLocal("h", "openspace.parallel.setAddress('127.0.0.1');openspace.parallel.setPort('25001');openspace.parallel.setPassword('test');openspace.parallel.connect();openspace.parallel.requestHostship('test');") openspace.bindKeyLocal("c", "openspace.parallel.setAddress('127.0.0.1');openspace.parallel.setPort('25001');openspace.parallel.setPassword('test');openspace.parallel.connect();") diff --git a/scripts/common.lua b/scripts/common.lua index 617022b16f..17c1ade776 100644 --- a/scripts/common.lua +++ b/scripts/common.lua @@ -4,6 +4,11 @@ helper = {} helper.renderable = {} helper.property = {} +-- These helpers are for scheduling lua scripts +-- See class ScriptScheduler and ScheduledScript for reference +helper.scheduledScript = {} +helper.scheduledScript.reversible = {} + -- Function that sets the most common key bindings that are common to most (all?) -- scenes helper.setCommonKeys = function() @@ -70,3 +75,31 @@ helper.renderable.toggle = function(renderable) return helper.property.invert(renderable .. ".renderable.enabled") end +-- Function that returns the string that sets the enabled property of to +helper.renderable.setEnabled = function(renderable, enabled) + return "openspace.setPropertyValue('" .. renderable .. ".renderable.enabled', " .. (enabled and "true" or "false") .. ");"; +end + +-- Function that returns a lua table specifying a reversible ScheduledScript for +-- setting the enabled property of to at time