Merge branch 'master' into feature/milkyway-galaxy

This commit is contained in:
eriksunden
2019-08-05 12:09:13 +02:00
162 changed files with 22970 additions and 9041 deletions

6
.gitmodules vendored
View File

@@ -10,9 +10,6 @@
[submodule "modules/touch/ext/libTUIO11"]
path = modules/touch/ext/libTUIO11
url = https://github.com/mkalten/TUIO11_CPP
[submodule "modules/sync/ext/libtorrent"]
path = modules/sync/ext/libtorrent
url = https://github.com/OpenSpace/libtorrent.git
[submodule "apps/OpenSpace-MinVR/ext/minvr"]
path = apps/OpenSpace-MinVR/ext/minvr
url = https://github.com/OpenSpace/minvr
@@ -26,3 +23,6 @@
[submodule "modules/fitsfilereader/ext/cfitsio"]
path = modules/fitsfilereader/ext/cfitsio
url = https://github.com/OpenSpace/cfitsio.git
[submodule "apps/OpenSpace-MinVR/ext/glfw"]
path = apps/OpenSpace-MinVR/ext/glfw
url = https://github.com/opensgct/glfw

View File

@@ -285,6 +285,11 @@ if (OPENSPACE_WITH_ABUFFER_RENDERER)
target_compile_definitions(openspace-core PUBLIC "OPENSPACE_WITH_ABUFFER_RENDERER")
endif ()
option(OPENSPACE_WITH_INSTRUMENTATION "Add instrumentation options" OFF)
if (OPENSPACE_WITH_INSTRUMENTATION)
target_compile_definitions(openspace-core PUBLIC "OPENSPACE_WITH_INSTRUMENTATION")
endif ()
# Just in case, create the bin directory
add_custom_command(

View File

@@ -50,7 +50,7 @@ target_include_directories(OpenSpace-MinVR PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/ex
target_include_directories(OpenSpace-MinVR PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/ext/minvr/external/GLFW/src/include)
target_link_libraries(OpenSpace-MinVR libOpenSpace MinVR)
target_link_libraries(OpenSpace-MinVR openspace-core MinVR)
# Web Browser and Web gui
# Why not put these in the module's path? Because they do not have access to the

View File

@@ -200,7 +200,14 @@ void Handler::onVREvent(const VRDataIndex& eventData) {
if (button == MouseButton::Right && action == MouseAction::Press) {
windowingGlobals.mouseButtons |= 1 << 2;
}
global::openSpaceEngine.mouseButtonCallback(button, action);
using KM = KeyModifier;
KM mod = KM::NoModifier;
mod |= keyboardState.modifierShift ? KM::Shift : KM::NoModifier;
mod |= keyboardState.modifierCtrl ? KM::Control : KM::NoModifier;
mod |= keyboardState.modifierAlt ? KM::Alt : KM::NoModifier;
global::openSpaceEngine.mouseButtonCallback(button, action, mod);
}
}
@@ -341,6 +348,14 @@ int main(int argc, char** argv) {
ghoul::initialize();
// Register the path of the executable,
// to make it possible to find other files in the same directory.
FileSys.registerPathToken(
"${BIN}",
ghoul::filesystem::File(absPath(argv[0])).directoryName(),
ghoul::filesystem::FileSystem::Override::Yes
);
// Create the OpenSpace engine and get arguments for the SGCT engine
std::string windowConfiguration;
try {

View File

@@ -76,6 +76,8 @@ constexpr const bool EnableDetailedVtune = false;
#include "nvToolsExt.h"
#endif // OPENSPACE_HAS_NVTOOLS
using namespace openspace;
namespace {
constexpr const char* _loggerCat = "main";
@@ -157,9 +159,9 @@ LONG WINAPI generateMiniDump(EXCEPTION_POINTERS* exceptionPointers) {
std::string dumpFile = fmt::format(
"OpenSpace_{}_{}_{}-{}-{}-{}-{}-{}-{}--{}--{}.dmp",
openspace::OPENSPACE_VERSION_MAJOR,
openspace::OPENSPACE_VERSION_MINOR,
openspace::OPENSPACE_VERSION_PATCH,
OPENSPACE_VERSION_MAJOR,
OPENSPACE_VERSION_MINOR,
OPENSPACE_VERSION_PATCH,
stLocalTime.wYear,
stLocalTime.wMonth,
stLocalTime.wDay,
@@ -260,7 +262,7 @@ void mainInitFunc() {
LTRACE("main::mainInitFunc(begin)");
LDEBUG("Initializing OpenSpace Engine started");
openspace::global::openSpaceEngine.initialize();
global::openSpaceEngine.initialize();
LDEBUG("Initializing OpenSpace Engine finished");
{
@@ -287,7 +289,7 @@ void mainInitFunc() {
LDEBUG("Initializing OpenGL in OpenSpace Engine started");
openspace::global::openSpaceEngine.initializeGL();
global::openSpaceEngine.initializeGL();
LDEBUG("Initializing OpenGL in OpenSpace Engine finished");
@@ -366,7 +368,7 @@ void mainInitFunc() {
//
std::string screenshotPath = "${SCREENSHOTS}";
if (openspace::global::configuration.shouldUseScreenshotDate) {
if (global::configuration.shouldUseScreenshotDate) {
std::time_t now = std::time(nullptr);
std::tm* nowTime = std::localtime(&now);
char mbstr[128];
@@ -412,13 +414,13 @@ void mainPreSyncFunc() {
#endif // OPENSPACE_HAS_VTUNE
LTRACE("main::mainPreSyncFunc(begin)");
openspace::global::openSpaceEngine.preSynchronization();
global::openSpaceEngine.preSynchronization();
// Query joystick status
using namespace openspace::interaction;
using namespace interaction;
for (int i = GLFW_JOYSTICK_1; i <= GLFW_JOYSTICK_LAST; ++i) {
JoystickInputState& state = openspace::global::joystickInputStates[i];
JoystickInputState& state = global::joystickInputStates[i];
int present = glfwJoystickPresent(i);
if (present == GLFW_FALSE) {
@@ -511,7 +513,7 @@ void mainPostSyncPreDrawFunc() {
#endif // OPENSPACE_HAS_NVTOOLS
LTRACE("main::postSynchronizationPreDraw(begin)");
openspace::global::openSpaceEngine.postSynchronizationPreDraw();
global::openSpaceEngine.postSynchronizationPreDraw();
#ifdef OPENVR_SUPPORT
if (FirstOpenVRWindow) {
@@ -559,7 +561,7 @@ void mainRenderFunc() {
#endif
try {
openspace::global::openSpaceEngine.render(
global::openSpaceEngine.render(
SgctEngine->getModelMatrix(),
viewMatrix,
projectionMatrix
@@ -591,7 +593,7 @@ void mainDraw2DFunc() {
LTRACE("main::mainDraw2DFunc(begin)");
try {
openspace::global::openSpaceEngine.drawOverlays();
global::openSpaceEngine.drawOverlays();
}
catch (const ghoul::RuntimeError& e) {
LERRORC(e.component, e.message);
@@ -627,7 +629,7 @@ void mainPostDrawFunc() {
}
#endif // OPENVR_SUPPORT
openspace::global::openSpaceEngine.postDraw();
global::openSpaceEngine.postDraw();
#ifdef OPENSPACE_HAS_SPOUT
for (const SpoutWindow& w : SpoutWindows) {
@@ -667,7 +669,7 @@ void mainPostDrawFunc() {
void mainKeyboardCallback(int key, int, int action, int mods) {
void mainKeyboardCallback(int key, int, int action, int modifiers) {
#ifdef OPENSPACE_HAS_VTUNE
if (EnableDetailedVtune) {
__itt_frame_begin_v3(_vTune.keyboard, nullptr);
@@ -675,11 +677,10 @@ void mainKeyboardCallback(int key, int, int action, int mods) {
#endif // OPENSPACE_HAS_VTUNE
LTRACE("main::mainKeyboardCallback(begin)");
openspace::global::openSpaceEngine.keyboardCallback(
openspace::Key(key),
openspace::KeyModifier(mods),
openspace::KeyAction(action)
);
const Key k = Key(key);
const KeyModifier m = KeyModifier(modifiers);
const KeyAction a = KeyAction(action);
global::openSpaceEngine.keyboardCallback(k, m, a);
LTRACE("main::mainKeyboardCallback(begin)");
#ifdef OPENSPACE_HAS_VTUNE
@@ -699,11 +700,10 @@ void mainMouseButtonCallback(int key, int action, int modifiers) {
#endif // OPENSPACE_HAS_VTUNE
LTRACE("main::mainMouseButtonCallback(begin)");
openspace::global::openSpaceEngine.mouseButtonCallback(
openspace::MouseButton(key),
openspace::MouseAction(action),
openspace::KeyModifier(modifiers)
);
const MouseButton k = MouseButton(key);
const MouseAction a = MouseAction(action);
const KeyModifier m = KeyModifier(modifiers);
global::openSpaceEngine.mouseButtonCallback(k, a, m);
LTRACE("main::mainMouseButtonCallback(end)");
#ifdef OPENSPACE_HAS_VTUNE
@@ -722,7 +722,7 @@ void mainMousePosCallback(double x, double y) {
}
#endif // OPENSPACE_HAS_VTUNE
openspace::global::openSpaceEngine.mousePositionCallback(x, y);
global::openSpaceEngine.mousePositionCallback(x, y);
#ifdef OPENSPACE_HAS_VTUNE
if (EnableDetailedVtune) {
@@ -741,7 +741,7 @@ void mainMouseScrollCallback(double posX, double posY) {
#endif // OPENSPACE_HAS_VTUNE
LTRACE("main::mainMouseScrollCallback(begin");
openspace::global::openSpaceEngine.mouseScrollWheelCallback(posX, posY);
global::openSpaceEngine.mouseScrollWheelCallback(posX, posY);
LTRACE("main::mainMouseScrollCallback(end)");
#ifdef OPENSPACE_HAS_VTUNE
@@ -753,17 +753,15 @@ void mainMouseScrollCallback(double posX, double posY) {
void mainCharCallback(unsigned int codepoint, int mods) {
void mainCharCallback(unsigned int codepoint, int modifiers) {
#ifdef OPENSPACE_HAS_VTUNE
if (EnableDetailedVtune) {
__itt_frame_begin_v3(_vTune.character, nullptr);
}
#endif // OPENSPACE_HAS_VTUNE
openspace::global::openSpaceEngine.charCallback(
codepoint,
openspace::KeyModifier(mods)
);
const KeyModifier m = KeyModifier(modifiers);
global::openSpaceEngine.charCallback(codepoint, m);
#ifdef OPENSPACE_HAS_VTUNE
if (EnableDetailedVtune) {
@@ -782,7 +780,7 @@ void mainEncodeFun() {
#endif // OPENSPACE_HAS_VTUNE
LTRACE("main::mainEncodeFun(begin)");
std::vector<char> data = openspace::global::openSpaceEngine.encode();
std::vector<char> data = global::openSpaceEngine.encode();
_synchronizationBuffer.setVal(std::move(data));
sgct::SharedData::instance()->writeVector(&_synchronizationBuffer);
@@ -806,7 +804,7 @@ void mainDecodeFun() {
sgct::SharedData::instance()->readVector(&_synchronizationBuffer);
std::vector<char> data = _synchronizationBuffer.getVal();
openspace::global::openSpaceEngine.decode(std::move(data));
global::openSpaceEngine.decode(std::move(data));
LTRACE("main::mainDecodeFun(end)");
#ifdef OPENSPACE_HAS_VTUNE
@@ -833,7 +831,7 @@ void mainLogCallback(const char* msg) {
void setSgctDelegateFunctions() {
openspace::WindowDelegate& sgctDelegate = openspace::global::windowDelegate;
WindowDelegate& sgctDelegate = global::windowDelegate;
sgctDelegate.terminate = []() { sgct::Engine::instance()->terminate(); };
sgctDelegate.setBarrier = [](bool enabled) {
sgct::SGCTWindow::setBarrier(enabled);
@@ -1101,7 +1099,7 @@ int main(int argc, char** argv) {
ghoul::cmdparser::CommandlineParser::AllowUnknownCommands::Yes
);
openspace::CommandlineArguments commandlineArguments;
CommandlineArguments commandlineArguments;
parser.addCommand(std::make_unique<ghoul::cmdparser::SingleCommand<std::string>>(
commandlineArguments.configurationName, "--file", "-f",
"Provides the path to the OpenSpace configuration file. Only the '${TEMPORARY}' "
@@ -1141,8 +1139,6 @@ int main(int argc, char** argv) {
// Create the OpenSpace engine and get arguments for the SGCT engine
std::string windowConfiguration;
try {
using namespace openspace;
// Find configuration
std::string configurationFilePath = commandlineArguments.configurationName;
if (commandlineArguments.configurationName.empty()) {
@@ -1178,16 +1174,17 @@ int main(int argc, char** argv) {
// Determining SGCT configuration file
LDEBUG("SGCT Configuration file: " + global::configuration.windowConfiguration);
windowConfiguration = openspace::global::configuration.windowConfiguration;
windowConfiguration = global::configuration.windowConfiguration;
}
catch (const openspace::documentation::SpecificationError& e) {
catch (const documentation::SpecificationError& e) {
LFATALC("main", "Loading of configuration file failed");
for (const openspace::documentation::TestResult::Offense& o : e.result.offenses) {
for (const documentation::TestResult::Offense& o : e.result.offenses) {
LERRORC(o.offender, ghoul::to_string(o.reason));
}
for (const openspace::documentation::TestResult::Warning& w : e.result.warnings) {
for (const documentation::TestResult::Warning& w : e.result.warnings) {
LWARNINGC(w.offender, ghoul::to_string(w.reason));
}
ghoul::deinitialize();
exit(EXIT_FAILURE);
}
catch (const ghoul::RuntimeError& e) {
@@ -1196,10 +1193,11 @@ int main(int argc, char** argv) {
if (ghoul::logging::LogManager::isInitialized()) {
LogMgr.flushLogs();
}
ghoul::deinitialize();
return EXIT_FAILURE;
}
openspace::global::openSpaceEngine.registerPathTokens();
global::openSpaceEngine.registerPathTokens();
// Prepend the outgoing sgctArguments with the program name
// as well as the configuration file that sgct is supposed to use
@@ -1293,8 +1291,8 @@ int main(int argc, char** argv) {
auto cleanup = [&](bool isInitialized) {
if (isInitialized) {
openspace::global::openSpaceEngine.deinitializeGL();
openspace::global::openSpaceEngine.deinitialize();
global::openSpaceEngine.deinitializeGL();
global::openSpaceEngine.deinitialize();
}
// Clear function bindings to avoid crash after destroying the OpenSpace Engine
@@ -1321,6 +1319,8 @@ int main(int argc, char** argv) {
}
}
#endif // OPENSPACE_HAS_SPOUT
ghoul::deinitialize();
};
if (!initSuccess) {

View File

@@ -22,43 +22,26 @@
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#include <ghoul/opengl/ghoul_gl.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/filesystem/directory.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/logging/consolelog.h>
#include <ghoul/ghoul.h>
#include <openspace/network/parallelserver.h>
#include <ghoul/fmt.h>
#include <ghoul/cmdparser/commandlineparser.h>
#include <ghoul/cmdparser/singlecommand.h>
#include <openspace/engine/windowdelegate.h>
#include <openspace/scripting/scriptengine.h>
#include <openspace/rendering/renderable.h>
#include <openspace/network/parallelserver.h>
#include <iostream>
#include <string>
#include <ghoul/glm.h>
#include <functional>
#include <sstream>
#include <ghoul/logging/logmanager.h>
#include <iomanip>
#include <ios>
namespace {
const std::string _loggerCat = "Wormhole";
}
constexpr const char*_loggerCat = "Wormhole";
} // namespace
int main(int argc, char** argv) {
using namespace openspace;
using namespace ghoul::cmdparser;
std::vector<std::string> arguments(argv, argv + argc);
ghoul::cmdparser::CommandlineParser commandlineParser(
CommandlineParser commandlineParser(
"Wormhole",
ghoul::cmdparser::CommandlineParser::AllowUnknownCommands::Yes
CommandlineParser::AllowUnknownCommands::Yes
);
std::stringstream defaultPassword;
@@ -73,43 +56,43 @@ int main(int argc, char** argv) {
std::chrono::system_clock::now().time_since_epoch().count() + 1
) % 0xffffff);
std::string portString = "";
std::string portString;
commandlineParser.addCommand(
std::make_unique<ghoul::cmdparser::SingleCommand<std::string>>(
portString,
"--port",
"-p",
"Sets the port to listen on"
)
)
);
std::string password = "";
std::string password;
commandlineParser.addCommand(
std::make_unique<ghoul::cmdparser::SingleCommand<std::string>>(
password,
"--password",
"-l",
"Sets the password to use"
)
)
);
std::string changeHostPassword = "";
std::string changeHostPassword;
commandlineParser.addCommand(
std::make_unique<ghoul::cmdparser::SingleCommand<std::string>>(
changeHostPassword,
"--hostpassword",
"-h",
"Sets the host password to use"
)
)
);
commandlineParser.setCommandLine(arguments);
commandlineParser.execute();
if (password == "") {
if (password.empty()) {
password = defaultPassword.str();
}
if (changeHostPassword == "") {
if (changeHostPassword.empty()) {
changeHostPassword = defaultChangeHostPassword.str();
}
@@ -118,11 +101,11 @@ int main(int argc, char** argv) {
int port = 25001;
if (portString != "") {
if (!portString.empty()) {
try {
port = std::stoi(portString);
}
catch (...) {
catch (const std::invalid_argument&) {
LERROR(fmt::format("Invalid port: {}", portString));
}
}
@@ -132,7 +115,9 @@ int main(int argc, char** argv) {
server.setDefaultHostAddress("127.0.0.1");
LINFO(fmt::format("Server listening to port {}", port));
while (std::cin.get() != 'q') {}
while (std::cin.get() != 'q') {
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
server.stop();
LINFO("Server stopped");

View File

@@ -12,14 +12,19 @@ local Keybindings = {
{
Key = "E",
Command = "openspace.time.setPause(true);" ..
"openspace.setPropertyValue('*Trail.Renderable.Enabled', false)"..
"openspace.setPropertyValue('Scene.Apollo8LaunchTrail.Renderable.Enabled', false)"..
"openspace.sessionRecording.startPlayback('apollo8')",
"openspace.time.setDeltaTime(1);" ..
"openspace.time.setTime('1968 DEC 24 16:37:31');" ..
"openspace.navigation.setNavigationState({" ..
" Anchor = 'Apollo8'," ..
" Position = { 1.494592E1, 3.236777E1, -4.171296E1 }," ..
" ReferenceFrame = 'Root'," ..
" Up = { 0.960608E0, -0.212013E0, 0.179675E0 }" ..
"});" ..
"openspace.setPropertyValue('*Trail.Renderable.Enabled', false)",
Documentation = "Jump to right before the earthrise photo",
Name = "Set Earthrise time",
GuiPath = "/Missions/Apollo/8",
Local = false
},
{
Key = "U",
@@ -115,13 +120,7 @@ asset.onInitialize(function ()
openspace.setPropertyValueSingle('NavigationHandler.OrbitalNavigator.MinimumAllowedDistance', 0.000000);
openspace.setPropertyValueSingle('Scene.Moon.Renderable.LodScaleFactor', 24.0);
openspace.navigation.setCameraState({
Anchor = earthAsset.Earth.Identifier,
Position = { 0, 0, 0 },
Rotation = { 0.758797, 0.221490, -0.605693, -0.091135 },
})
openspace.globebrowsing.goToGeo(20, -60, 15000000)
openspace.globebrowsing.goToGeo(earthAsset.Earth.Identifier, 20, -60, 15000000)
end)
asset.onDeinitialize(function ()

View File

@@ -2,15 +2,15 @@ asset.require('./base')
--moonrocks.scene
local sceneHelper = asset.require('util/scene_helper')
-- local station2 = asset.require('scene/solarsystem/missions/apollo/bouldersstation2')
-- local station6 = asset.require('scene/solarsystem/missions/apollo/bouldersstation6')
-- local station7 = asset.require('scene/solarsystem/missions/apollo/bouldersstation7')
asset.require('scene/solarsystem/missions/apollo/apollo8')
asset.require('scene/solarsystem/missions/apollo/apollo11')
asset.require('scene/solarsystem/missions/apollo/a11_lem')
asset.require('scene/solarsystem/missions/apollo/a17_lem')
asset.require('scene/solarsystem/missions/apollo/apollo_globebrowsing')
asset.require('scene/solarsystem/missions/apollo/apollo_11_lem_flipbook')
asset.require('scene/solarsystem/missions/apollo/insignias_map')
local Keybindings = {
{
@@ -37,11 +37,11 @@ local Keybindings = {
},
{
Key = "F11",
Command = "openspace.time.setTime('1969 JUL 20 20:17:40');" ..
Command = "openspace.time.setTime('1969 JUL 20 20:17:40');" ..
"openspace.setPropertyValueSingle('Scene.Moon.Renderable.Layers.HeightLayers.LRO_NAC_Apollo_11.Enabled', true);" ..
"openspace.setPropertyValueSingle('Scene.Moon.Renderable.Layers.ColorLayers.A11_M177481212_p_longlat.Enabled', true);" ..
"openspace.setPropertyValueSingle('Scene.Moon.Renderable.LodScaleFactor', 20.11);" ..
"openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Anchor', 'Apollo11LemModel');" ..
"openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Anchor', 'Apollo11LemPosition');" ..
"openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.RetargetAnchor', nil);" ..
"openspace.setPropertyValueSingle('Scene.Apollo11MoonTrail.Renderable.Enabled', true);" ..
"openspace.setPropertyValueSingle('Scene.Apollo11LemTrail.Renderable.Enabled', true);",
@@ -82,10 +82,14 @@ asset.onInitialize(function ()
sceneHelper.bindKeys(Keybindings)
openspace.markInterestingNodes({ "Moon", "Apollo11LemModel", "Apollo17LemModel", "Apollo11", "Apollo11LunarLander" })
openspace.markInterestingNodes({
"Moon", "Apollo11LemModel", "Apollo17LemModel",
"Apollo11", "Apollo11LunarLander",
-- "Station_2_Boulder2", "Station_6_Fragment1"
})
openspace.setPropertyValueSingle('Scene.Moon.Renderable.Layers.ColorLayers.A17_travmap.BlendMode', 0);
-- To enable both sites by default, uncomment these lines
-- openspace.setPropertyValueSingle('Scene.Moon.Renderable.Layers.ColorLayers.A17_travmap.BlendMode', 0.000000);
-- openspace.setPropertyValueSingle('Scene.Moon.Renderable.Layers.ColorLayers.A17_travmap.Enabled', true);
-- openspace.setPropertyValueSingle('Scene.Moon.Renderable.Layers.HeightLayers.LRO_NAC_Apollo_17.Enabled', true);
-- openspace.setPropertyValueSingle('Scene.Moon.Renderable.Layers.ColorLayers.A17_LEM.Enabled', true);
@@ -95,17 +99,19 @@ asset.onInitialize(function ()
-- openspace.setPropertyValueSingle('Scene.Moon.Renderable.Layers.ColorLayers.A17_station7.BlendMode', 0.000000);
-- openspace.setPropertyValueSingle('Scene.Moon.Renderable.Layers.HeightLayers.LRO_NAC_Apollo_11.Enabled', true);
-- openspace.setPropertyValueSingle('Scene.Moon.Renderable.Layers.ColorLayers.A11_M177481212_p_longlat.Enabled', true);
openspace.navigation.setCameraState({
Anchor = moonAsset.Moon.Identifier,
Position = { 0, 0, 0 },
Rotation = { 0, 0, 0, 0 },
})
openspace.globebrowsing.goToGeo(20, -60, 15000000)
openspace.setPropertyValueSingle('Scene.Apollo11LemDescentModel.Renderable.RotationVector', { 273.205475,6.904110,308.712311 });
openspace.setPropertyValueSingle('Scene.Apollo11LemLandedModel.Renderable.RotationVector', { 273.205475,6.904110,308.712311 });
openspace.globebrowsing.goToGeo(moonAsset.Moon.Identifier, 20, -60, 15000000)
openspace.setPropertyValueSingle("Scene.Moon.Renderable.PerformShading", false)
end)
asset.onDeinitialize(function ()
openspace.removeInterestingNodes({ "Moon", "Apollo11Lem", "Apollo17Lem", "Apollo11", "Apollo11LunarLander" })
openspace.removeInterestingNodes({
"Moon", "Apollo11Lem", "Apollo17Lem",
"Apollo11", "Apollo11LemPosition",
-- "Station_6_Fragment1", "Station_6_Fragments_2_3"
})
end)

View File

@@ -10,10 +10,9 @@ asset.onInitialize(function ()
openspace.markInterestingNodes({ "Dawn", "Ceres", "Vesta" })
openspace.navigation.setCameraState({
openspace.navigation.setNavigationState({
Anchor = DawnAsset.Dawn.Identifier,
Position = { 526781518487.171326, 257168309890.072144, -1381125204152.817383 },
Rotation = { -0.106166, 0.981574, -0.084545, 0.134513 },
})
end)

View File

@@ -1,20 +1,15 @@
asset.require('./base')
local earthAsset = asset.require('scene/solarsystem/planets/earth/earth')
asset.onInitialize(function ()
local now = openspace.time.currentWallTime()
-- Jump back one day to show a complete planet
-- Jump back one day to be able to show complete weather data on Earth.
openspace.time.setTime(openspace.time.advancedTime(now, "-1d"))
openspace.globebrowsing.goToGeo("Earth", 58.5877, 16.1924, 20000000)
openspace.markInterestingNodes({ "Earth", "Mars", "Moon", "Sun" })
openspace.navigation.setCameraState({
Anchor = earthAsset.Earth.Identifier,
Position = { 0, 0, 0 },
Rotation = { 0.758797, 0.221490, -0.605693, -0.091135 },
})
openspace.globebrowsing.goToGeo(58.5877, 16.1924, 20000000)
end)
asset.onDeinitialize(function ()

View File

@@ -1,8 +1,9 @@
local assetHelper = asset.require('util/asset_helper')
local sceneHelper = asset.require('util/scene_helper')
local propertyHelper = asset.require('util/property_helper')
local debugHelper = asset.require('util/debug_helper')
-- At this point, a sceene needs basic spice data to load.
-- At this point, a scene needs basic spice data to load.
asset.require('spice/base')
asset.require('util/default_keybindings')
@@ -12,10 +13,15 @@ asset.require('util/default_joystick')
asset.require('util/webgui')
local spheres = asset.require('examples/spheres')
debugHelper.registerCartesianAxes(asset, {
Parent = "Root",
Scale = 10
})
asset.onInitialize(function ()
openspace.navigation.setCameraState({
Anchor = spheres.ExampleSphere1.Identifier,
Position = { 20, 0, 0 },
Rotation = { 0.758797, 0.221490, -0.605693, -0.091135 }
openspace.navigation.setNavigationState({
Anchor = "Root",
Position = { 20, 20, 20 },
Up = {0, 1, 0},
})
end)

View File

@@ -0,0 +1,10 @@
local assetHelper = asset.require('util/asset_helper')
local spec = {
Type = "ScreenSpaceBrowser",
Identifier = "ScreenSpaceBrowserExample",
Name = "Screen Space Browser Example",
Url = "https://www.openspaceproject.com/"
};
assetHelper.registerScreenSpaceRenderables(asset, { spec })

View File

@@ -35,10 +35,9 @@ asset.onInitialize(function ()
openspace.markInterestingNodes({ "Gaia" })
openspace.navigation.setCameraState({
openspace.navigation.setNavigationState({
Anchor = earthAsset.Earth.Identifier,
Position = { 1000000000000.0, 1000000000000.0, 1000000000000.0 },
Rotation = { 0.683224, -0.765934, -0.601234, -0.418073 },
})
end)

View File

@@ -60,10 +60,11 @@ asset.onInitialize(function ()
openspace.markInterestingNodes({ "Insight" })
openspace.navigation.setCameraState({
openspace.navigation.setNavigationState({
Anchor = insightAsset.Insight.Identifier,
Position = { 0, 0, 0 },
Rotation = { 0.758797, 0.221490, -0.605693, -0.091135 },
Position = { 8.430115E0, -1.791710E1, 2.813660E0 },
ReferenceFrame = "Root",
Up = { 0.494659E0,0.357162E0,0.792306E0 },
})
end)

View File

@@ -18,10 +18,11 @@ asset.onInitialize(function ()
28800, 57600, 115200, 230400, 460800, 921600, 1843200, 3686400, 7372800, 14745600
})
openspace.navigation.setCameraState({
openspace.navigation.setNavigationState({
Anchor = junoAsset.Juno.Identifier,
Position = { 1837386367.601345, -389860693812.834839, 714830404470.398926 },
Rotation = { -0.336540, 0.711402, -0.099212, 0.608937 },
Position = { 1.243398E8, 7.176068E7, -1.519733E7 },
ReferenceFrame = "Root",
Up = { -0.377400E0, 0.764573E0, 0.522492E0 },
})
end)

View File

@@ -33,10 +33,11 @@ asset.onInitialize(function ()
28800, 57600, 115200, 230400, 460800, 921600, 1843200, 3686400, 7372800, 14745600
})
openspace.navigation.setCameraState({
openspace.navigation.setNavigationState({
Anchor = "Mercury",
Position = { 526781518487.171326, 257168309890.072144, -1381125204152.817383 },
Rotation = {0.180662, 0.021334, 0.979084, 0.091111},
Position = { 2.423690E11, 1.979038E11, -2.241483E10 },
ReferenceFrame = "Root",
Up = { -0.492046E0, 0.666088E0, 0.560551E0 }
})
end)

View File

@@ -255,10 +255,11 @@ asset.onInitialize(function ()
openspace.setPropertyValueSingle('Scene.Charon.Renderable.Enabled', false)
openspace.setPropertyValueSingle("Scene.PlutoBarycenterTrail.Renderable.Enabled", false)
openspace.navigation.setCameraState({
Anchor = NewHorizonsAsset.NewHorizons.Identifier,
Position = { 4662120063743.592773, 1263245003503.724854, -955413856565.788086 },
Rotation = { 0.683224, -0.165934, 0.701234, 0.118073 },
openspace.navigation.setNavigationState({
Anchor = "NewHorizons",
ReferenceFrame = "Root",
Position = { -6.572656E1, -7.239404E1, -2.111890E1 },
Up = { 0.102164, -0.362945, 0.926193 }
})
end)

View File

@@ -134,10 +134,9 @@ asset.onInitialize(function ()
openspace.markInterestingNodes({ "OsirisRex", "BennuBarycenter", "Earth" })
openspace.navigation.setCameraState({
openspace.navigation.setNavigationState({
Anchor = OsirisRexAsset.OsirisRex.Identifier,
Position = { 26974590199.661884, 76314608558.908020, -127086452897.101791 },
Rotation = { 0.729548, -0.126024, 0.416827, 0.527382 },
Position = { 26974590199.661884, 76314608558.908020, -127086452897.101791 }
})
end)

View File

@@ -134,10 +134,11 @@ asset.onInitialize(function ()
28800, 57600, 115200, 230400, 460800, 921600, 1843200, 3686400, 7372800, 14745600
})
openspace.navigation.setCameraState({
openspace.navigation.setNavigationState({
Anchor = Comet67PAsset.Comet67P.Identifier,
Position = { 526781518487.171326, 257168309890.072144, -1381125204152.817383 },
Rotation = { -0.106166, 0.981574, -0.084545, 0.134513 },
ReferenceFrame = "Root",
Position = { -7.294781E5 , -6.657894E5, 2.509047E6 },
Up = { 0.146529E0, 0.944727E0, 0.293290E0 }
})
openspace.setPropertyValue('Scene.67P.Renderable.PerformShading', false);

View File

@@ -1,19 +1,30 @@
-- Download a dataset of 618 million stars (28 GB), already preprocessed and stored in a binary octree.
-- The octree was generated from the full DR2 by filtering away all stars with a parallax error higher than 0.5
-- Max Star Per Node = 50,000 and max distance = 500kpc
asset.syncedResource({
local gaia618Destination = asset.syncedResource({
Name = "Gaia DR2 618M Octree",
Type = "HttpSynchronization",
Identifier = "gaia_stars_618M_octree",
Version = 1
})
local gaia618DestinationExtracted = gaia618Destination + '/data';
-- Download the full DR2 dataset with 24 values per star (preprocessed with theReadFitsTask (gaia_read.task) into 8 binary files).
-- From these files new subsets can be created with the ConstructOctreeTask (gaia_octree.task).
-- Total size of download is 151 GB.
asset.syncedResource({
local gaiaFull = asset.syncedResource({
Name = "Gaia DR2 Full Raw",
Type = "HttpSynchronization",
Identifier = "gaia_stars_dr2_raw",
Version = 1
})
asset.onInitialize(function()
if not openspace.directoryExists(gaia618DestinationExtracted) then
openspace.printInfo("Extracted Gaia dataset")
openspace.unzipFile(gaia618Destination .. '/DR2_full_Octree[50kSPN,500dist]_50,50.zip', gaia618DestinationExtracted, true)
end
end)
asset.export('GaiaDR2_618M', gaia618DestinationExtracted)
asset.export('GaiaFullDataset', gaiaFull)

View File

@@ -20,7 +20,8 @@ local OumuamuaTrail = {
Color = { 0.9, 0.9, 0.0 },
StartTime = "2014 JAN 01 00:00:00",
EndTime = "2023 JAN 01 00:00:00",
SampleInterval = 60
SampleInterval = 7000,
TimeStampSubsampleFactor = 1
},
GUI = {
Name = "'Oumuamua Trail",

View File

@@ -15,8 +15,8 @@ local Apollo11Lem = {
Globe = moonAsset.Moon.Identifier,
Longitude = -360+23.47306,
Latitude = 0.67402,
FixedAltitude = -1927.65,
UseFixedAltitude = true
Altitude = -1927.65,
UseHeightMap = false
},
},
GUI = {

View File

@@ -14,6 +14,7 @@ local Apollo17Lem = {
Globe = moonAsset.Moon.Identifier,
Longitude = -329.22833,
Latitude = 20.19092,
UseHeightmap = true
},
},
GUI = {

View File

@@ -1,5 +1,8 @@
local assetHelper = asset.require('util/asset_helper')
local sunTransforms = asset.require('scene/solarsystem/sun/transforms')
local descentKeyframes = asset.require('./apollo11_lem_descent.asset')
local descentRotationKeyframes = asset.require('./apollo11_lem_descent_rotation.asset')
local model = asset.require('scene/solarsystem/missions/apollo/lem_model')
asset.require('spice/base')
@@ -11,7 +14,7 @@ local kernelsFolder = asset.syncedResource({
})
local modelFolder = asset.syncedResource({
Name = "Apollo Kernels",
Name = "Apollo Models",
Type = "HttpSynchronization",
Identifier = "apollo_11_models",
Version = 1
@@ -24,7 +27,7 @@ local kernels = {
kernelsFolder .. '/apollo11_orbits_full9km.bsp',
kernelsFolder .. '/apollo11_orbits_lm9km.bsp',
}
--landing - 1969-07-20T20:17:40
local apolloSpiceId = "-911"
local apolloLemSpiceId = "-911500"
@@ -107,81 +110,44 @@ local Apollo11MoonTrail = {
}
}
-- Uncomment if you want to follow the mock decent
-- local Apollo11LemPosition = {
-- Identifier = "Apollo11LemPosition",
-- Parent = "Moon",
-- TimeFrame = {
-- Type = "TimeFrameInterval",
-- Start = "1969 JUL 20 19:10:25.183",
-- End = "1969 JUL 20 20:17:46.183"
-- },
-- Transform = {
-- Translation = {
-- Type = "SpiceTranslation",
-- Target = apolloLemSpiceId,
-- Observer = "MOON",
-- Frame = "MOON_ME",
-- Kernels = kernels
-- },
-- },
-- GUI = {
-- Hidden = true,
-- Name = "Apollo 11 Lunar Lander Position",
-- Path = "/Solar System/Missions/Apollo/11"
-- }
-- }
-- local Apollo11LunarLanderModel = {
-- Identifier = "Apollo11LunarLander",
-- Parent = Apollo11LemPosition.Identifier,
-- Transform = {
-- Rotation = {
-- Type = "StaticRotation",
-- Rotation = {0.0, 0.0, -3.1415/2}
-- },
-- Scale = {
-- Type = "StaticScale",
-- Scale = 100.0
-- }
-- },
-- TimeFrame = {
-- Type = "TimeFrameInterval",
-- Start = "1969 JUL 20 19:10:25.183",
-- End = "1969 JUL 20 20:17:46.183"
-- },
-- Renderable = {
-- Type = "RenderableModel",
-- Geometry = {
-- Type = "MultiModelGeometry",
-- GeometryFile = modelFolder .. "/lem_nasa.obj"
-- },
-- ColorTexture = modelFolder .. "/gray.png",
-- LightSources = assetHelper.getDefaultLightSources(sunTransforms.SolarSystemBarycenter.Identifier)
-- },
-- GUI = {
-- Hidden = false,
-- Name = "Apollo 11 Lunar Lander",
-- Path = "/Solar System/Missions/Apollo/11"
-- }
-- }
local Apollo11LemTrail = {
Identifier = "Apollo11LemTrail",
Parent = "Moon",
Renderable = {
Type = "RenderableTrailTrajectory",
Translation = {
local lemTranslation = {
Type = "TimelineTranslation",
Keyframes = {
-- 20:14:30 is an arbitrary cutoff, but last 4 minutes data in descentKeyframes
-- begins at 20.14.40. Due to linear interpolation, we will get
-- a 10s linear transition to the location where the descentKeyframes start.
['1969 JUL 20 20:14:30'] = {
Type = "SpiceTranslation",
Target = apolloLemSpiceId,
Observer = "MOON",
Frame = "IAU_MOON",
Kernels = kernels
},
Color = {0.780000,0.940000,0.340000 },
['1969 JUL 20 20:14:40'] = {
Type = "TimelineTranslation",
Keyframes = descentKeyframes.keyframes
}
}
}
local lemRotation = {
Type = "TimelineRotation",
Keyframes = descentRotationKeyframes.keyframes
}
local Apollo11LemTrail = {
Identifier = "Apollo11LemTrail",
Parent = "Moon",
Renderable = {
Type = "RenderableTrailTrajectory",
Translation = lemTranslation,
Color = { 0.780000,0.940000,0.340000 },
StartTime = "1969 JUL 20 19:10:25.183",
EndTime = "1969 JUL 20 20:17:46.183",
SampleInterval = 60,
SampleInterval = 2,
EnableFade = false,
Enabled = false,
},
@@ -191,11 +157,91 @@ local Apollo11LemTrail = {
}
}
local Apollo11LemPosition = {
Identifier = "Apollo11LemPosition",
Parent = "Moon",
TimeFrame = {
Type = "TimeFrameInterval",
Start = "1969 JUL 20 19:10:25.183"
},
Transform = {
Translation = lemTranslation,
Rotation = lemRotation
},
GUI = {
Hidden = false,
Name = "Apollo 11 Lunar Lander Position",
Path = "/Solar System/Missions/Apollo/11"
}
}
--landing - 1969-07-20T20:17:40
local Apollo11LemDescentModel = {
Identifier = "Apollo11LemDescentModel",
Parent = Apollo11LemPosition.Identifier,
TimeFrame = {
Type = "TimeFrameInterval",
Start = "1969 JUL 19 19:38:29.183",
End = "1969 JUL 20 20:17:40.0"
},
Transform = {
Scale = {
Type = "StaticScale",
Scale = 0.24
}
},
Renderable = {
Type = "RenderableModel",
Geometry = {
Type = "MultiModelGeometry",
GeometryFile = model.modelFolder .. "/lmremoved.obj"
},
ColorTexture = model.modelFolder .. "/LM-2_ver2clean_u1_v1.jpeg",
LightSources = assetHelper.getDefaultLightSources(sunTransforms.SolarSystemBarycenter.Identifier)
},
GUI = {
Hidden = false,
Name = "Apollo 11 Descent Lem",
Path = "/Solar System/Missions/Apollo/11"
}
}
local Apollo11LemLandedModel = {
Identifier = "Apollo11LemLandedModel",
Parent = Apollo11LemPosition.Identifier,
TimeFrame = {
Type = "TimeFrameInterval",
Start = "1969 JUL 20 20:17:40.0"
},
Transform = {
Scale = {
Type = "StaticScale",
Scale = 0.24
}
},
Renderable = {
Type = "RenderableModel",
Geometry = {
Type = "MultiModelGeometry",
GeometryFile = model.modelFolder .. "/LM-2_ver2clean.obj"
},
ColorTexture = model.modelFolder .. "/LM-2_ver2clean_u1_v1.jpeg",
LightSources = assetHelper.getDefaultLightSources(sunTransforms.SolarSystemBarycenter.Identifier)
},
GUI = {
Hidden = false,
Name = "Apollo 11 Landed Lem",
Path = "/Solar System/Missions/Apollo/11"
}
}
local exportList = {
Apollo11Position,
-- Apollo11LemPosition,
Apollo11Position,
Apollo11LemPosition,
Apollo11Model,
-- Apollo11LunarLanderModel,
Apollo11LemDescentModel,
Apollo11LemLandedModel,
Apollo11MoonTrail,
Apollo11LemTrail,
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,74 @@
local assetHelper = asset.require('util/asset_helper')
local sunTransforms = asset.require('scene/solarsystem/sun/transforms')
local kernelsFolder = asset.syncedResource({
Name = "Apollo Kernels",
Type = "HttpSynchronization",
Identifier = "apollo_spice",
Version = 1
})
local kernels = {
kernelsFolder .. "/moon_080317.tf",
kernelsFolder .. "/apollo8.tf",
kernelsFolder .. "/moon_pa_de421_1900-2050.bpc",
kernelsFolder .. '/apollo8.tsc',
kernelsFolder .. '/apollo8.bsp',
kernelsFolder .. '/apollo8_earthrise.bc',
}
local apolloSpiceId = "-908"
local Apollo8LaunchTrail = {
Identifier = "Apollo8LaunchTrail",
Parent = "Earth",
Renderable = {
Type = "RenderableTrailTrajectory",
Translation = {
Type = "SpiceTranslation",
Target = apolloSpiceId,
Observer = "EARTH",
Frame = "IAU_EARTH",
Kernels = kernels
},
Color = { 0.70, 0.50, 0.20 },
StartTime = "1968 DEC 21 12:51:00",
EndTime = "1968 DEC 21 23:23:22",
SampleInterval = 30
},
GUI = {
Name = "Apollo 8 Launch Trail",
Path = "/Solar System/Missions/Apollo"
}
}
local Apollo8EarthBarycenterTrail = {
Identifier = "Apollo8EarthBarycenterTrail",
Parent = "EarthBarycenter",
Renderable = {
Type = "RenderableTrailTrajectory",
Translation = {
Type = "SpiceTranslation",
Target = apolloSpiceId,
Observer = "EARTH BARYCENTER",
Frame = "GALACTIC",
Kernels = kernels
},
Color = { 1, 0.0, 0.0 },
StartTime = "1968 DEC 21",
EndTime = "1968 DEC 28",
SampleInterval = 30,
Enabled = false,
},
GUI = {
Name = "Apollo 8 Earth Barycenter Trail",
Path = "/Solar System/Missions/Apollo"
}
}
local exportList = {
Apollo8LaunchTrail,
Apollo8EarthBarycenterTrail,
}
assetHelper.registerSceneGraphNodesAndExport(asset, exportList)

View File

@@ -2,36 +2,36 @@
local heightmaps = asset.syncedResource({
Name = "Apollo Globebrowsing",
Name = "Apollo Globebrowsing Heightmaps",
Type = "HttpSynchronization",
Identifier = "apollo_globebrowsing_heightmaps",
Version = 1
})
local basemaps = asset.syncedResource({
Name = "Apollo Globebrowsing",
Name = "Apollo Globebrowsing Basemaps",
Type = "HttpSynchronization",
Identifier = "apollo_globebrowsing_basemaps",
Version = 1
})
local naclighting = asset.syncedResource({
Name = "Apollo Globebrowsing",
Name = "Apollo Globebrowsing NAC Lighting",
Type = "HttpSynchronization",
Identifier = "apollo_globebrowsing_naclighting",
Version = 1
})
local stations = asset.syncedResource({
Name = "Apollo 17 Globebrowsing",
Name = "Apollo 17 Globebrowsing Stations",
Type = "HttpSynchronization",
Identifier = "apollo_17_stations",
Version = 1
})
asset.onInitialize(function ()
openspace.globebrowsing.addBlendingLayersFromDirectory(heightmaps,"Moon")
openspace.globebrowsing.addBlendingLayersFromDirectory(basemaps,"Moon")
openspace.globebrowsing.addBlendingLayersFromDirectory(naclighting,"Moon")
openspace.globebrowsing.addBlendingLayersFromDirectory(stations,"Moon")
openspace.globebrowsing.addBlendingLayersFromDirectory(heightmaps, "Moon")
openspace.globebrowsing.addBlendingLayersFromDirectory(basemaps, "Moon")
openspace.globebrowsing.addBlendingLayersFromDirectory(naclighting, "Moon")
openspace.globebrowsing.addBlendingLayersFromDirectory(stations, "Moon")
end)

View File

@@ -33,8 +33,8 @@ local Station2Boulder1Holder = {
Globe = moonAsset.Moon.Identifier,
Longitude = -360+30.5294692,
Latitude = 20.098824,
FixedAltitude = -2442.8,
UseFixedAltitude = true
Altitude = -2442.8,
UseHeightMap = false
}
},
GUI = {
@@ -78,8 +78,8 @@ local Station2Boulder2Holder = {
Globe = moonAsset.Moon.Identifier,
Longitude = -360+30.5287892,
Latitude = 20.098240,
FixedAltitude = -2434.6,
UseFixedAltitude = true
Altitude = -2434.6,
UseHeightMap = false
}
},
GUI = {
@@ -123,8 +123,8 @@ local Station2Boulder3Holder = {
Globe = moonAsset.Moon.Identifier,
Longitude = -360+30.5294692,
Latitude = 20.098610,
FixedAltitude = -2441.55,
UseFixedAltitude = true
Altitude = -2441.55,
UseHeightMap = false
}
},
GUI = {

View File

@@ -37,6 +37,8 @@ local Station6Frag1Holder = {
Globe = moonAsset.Moon.Identifier,
Longitude = -360+30.80068,
Latitude = 20.2903,
Altitude = -2562.6,
UseHeightmap = false
}
},
GUI = {
@@ -54,6 +56,8 @@ local Station6Frag1Model = {
Globe = moonAsset.Moon.Identifier,
Longitude = -360+30.8007,
Latitude = 20.2903,
Altitude = -2562.6,
UseHeightmap = false
}
},
Transform = {
@@ -104,8 +108,8 @@ local Station6Frag2Model = {
Globe = moonAsset.Moon.Identifier,
Longitude = -360+30.80055,
Latitude = 20.289808,
FixedAltitude = -2566.5,
UseFixedAltitude = true
Altitude = -2566.5,
UseHeightmap = false
}
},
Renderable = {
@@ -140,8 +144,8 @@ local Station6Frag3Model = {
Globe = moonAsset.Moon.Identifier,
Longitude = -360+30.80053,
Latitude = 20.29030,
FixedAltitude = -2563.0,
UseFixedAltitude = true
Altitude = -2563.0,
UseHeightMap = false
}
},
Renderable = {

View File

@@ -34,8 +34,8 @@ local Station7BoulderHolder = {
Globe = moonAsset.Moon.Identifier,
Longitude = -360+30.8165882,
Latitude = 20.2908556,
FixedAltitude = -2593.5,
UseFixedAltitude = true
Altitude = -2593.5,
UseHeightMap = true
}
},
GUI = {

View File

@@ -0,0 +1,120 @@
-- Apollo mission insignias on their locations on the Lunar surface.
-- The insignias are invisible by default, but can be enabled using shown or hidden using
-- the exported functions `showInsignias(interpolationDuration)` and `hideInsignias(interpolationDuration)`.
local assetHelper = asset.require('util/asset_helper')
local insigniasPath = asset.syncedResource({
Name = "Apollo Insignias",
Type = "HttpSynchronization",
Identifier = "apollo_insignias",
Version = 1
})
local moon = asset.require('scene/solarsystem/planets/earth/moon/moon')
local landingData = {
{
Identifier = "Apollo11",
Name = "Apollo 11",
Name = "Apollo 11",
Texture = "apollo11.png",
LunarModule = {0.67409, 23.47298, 0.0},
},
{
Identifier = "Apollo12",
Name = "Apollo 12",
Texture = "apollo12.png",
LunarModule = {-3.01381, -23.41930, 0.0}
},
{
Identifier = "Apollo14",
Name = "Apollo 14",
Texture = "apollo14.png",
LunarModule = {-3.64544, -17.47139, 0.0}
},
{
Identifier = "Apollo15",
Name = "Apollo 15",
Texture = "apollo15.png",
LunarModule = {26.13224, 3.63400, 0.0}
},
{
Identifier = "Apollo16",
Name = "Apollo 16",
Texture = "apollo16.png",
LunarModule = {-8.97341, 15.49859, 0.0}
},
{
Identifier = "Apollo17",
Name = "Apollo 17",
Texture = "apollo17.png",
LunarModule = {20.18809, 30.77475, 0.0}
}
}
local nodes = {}
local size = 100000;
for i = 1, #landingData do
local entry = landingData[i]
nodes[i] = {
Identifier = entry.Identifier .. "Insignia",
Parent = moon.Moon.Identifier,
Transform = {
Translation = {
Type = "GlobeTranslation",
Globe = moon.Moon.Identifier,
Latitude = entry.LunarModule[1],
Longitude = entry.LunarModule[2],
Altitude = entry.LunarModule[3] + size * 1.1,
UseHeightmap = false
},
},
Renderable = {
Type = "RenderablePlaneImageLocal",
Size = size,
Origin = "Center",
Billboard = true,
Texture = insigniasPath .. "/" .. entry.Texture,
Opacity = 0.0
},
GUI = {
Path = "/Other/Labels",
Name = entry.Name .. " Insignia"
}
}
end
asset.onInitialize(function ()
openspace.bindShortcut(
'Show Apollo Landing Labels',
'openspace.setPropertyValue("Scene.Apollo*Insignia.Renderable.Opacity", 1, 0.5)',
'Show patches of the Apollo missions on their respective landing sites',
'/Missions/Apollo'
)
openspace.bindShortcut(
'Hide Apollo Landing Labels',
'openspace.setPropertyValue("Scene.Apollo*Insignia.Renderable.Opacity", 0, 0.5)',
'Hide patches of the Apollo missions on their respective landing sites',
'/Missions/Apollo'
)
end)
asset.export('showInsignia', function (missinNumber, interpolationDuration)
openspace.setPropertyValue("Scene.Apollo" .. missionNumber .. "Insignia.Renderable.Opacity", 1, interpolationDuration)
end)
asset.export('hideInsignia', function (missinNumber, interpolationDuration)
openspace.setPropertyValue("Scene.Apollo" .. missionNumber .. "Insignia.Renderable.Opacity", 0, interpolationDuration)
end)
asset.export('showInsignias', function (interpolationDuration)
openspace.setPropertyValue("Scene.Apollo*Insignia.Renderable.Opacity", 1, interpolationDuration)
end)
asset.export('hideInsignias', function (interpolationDuration)
openspace.setPropertyValue("Scene.Apollo*Insignia.Renderable.Opacity", 0, interpolationDuration)
end)
assetHelper.registerSceneGraphNodesAndExport(asset, nodes)

View File

@@ -2,7 +2,7 @@ local modelFolder = asset.syncedResource({
Name = "Apollo Lem Models",
Type = "HttpSynchronization",
Identifier = "apollo_lem_model",
Version = 2
Version = 3
})
asset.export('modelFolder', modelFolder)

View File

@@ -20,7 +20,7 @@ local images = asset.syncedResource({
local models = asset.syncedResource({
Name = "Vesta Models",
Type = "HttpSynchronization",
Identifier = "vesta_comet",
Identifier = "vesta_model",
Version = 1
})

View File

@@ -14,7 +14,7 @@ local carpoGroup = {
{
Identifier = "Carpo",
Parent = {
Name = parentIdentifier,
Identifier = parentIdentifier,
Spice = parentSpice
},
Spice = "CARPO",

View File

@@ -25,6 +25,7 @@ local color_layers = {
FilePath = mapServiceConfigs .. "/Utah/Mars_Color.wms",
Enabled = true,
Fallback = {
Identifier = "Mars_Texture",
Name = "Mars Texture",
FilePath = textures .. "/mars.jpg",
Enabled = true
@@ -35,6 +36,7 @@ local color_layers = {
Name = "MOC WA Color [Sweden]",
FilePath = mapServiceConfigs .. "/LiU/Color.wms",
Fallback = {
Identifier = "Mars_Texture",
Name = "Mars Texture",
FilePath = textures .. "/mars.jpg",
Enabled = true

View File

@@ -20,7 +20,8 @@ local TeslaRoadsterTrail = {
Color = { 0.9, 0.9, 0.0 },
StartTime = "2018 FEB 8 00:00:00",
EndTime = "2022 FEB 7 00:00:00",
SampleInterval = 60
SampleInterval = 3000,
TimeStampSubsampleFactor = 1
},
GUI = {
Name = "Tesla Roadster Trail",

View File

@@ -42,6 +42,29 @@ local registerSceneGraphNodes = function (sceneAsset, nodes, override)
end)
end
local registerScreenSpaceRenderables = function (sceneAsset, renderables, override)
override = override or false
if not override then
if tableLength(renderables) == 0 then
openspace.printWarning(sceneAsset.filePath .. ": Register function was called with an empty node list. Pass 'true' as third argument to silence this warning.")
return
end
end
sceneAsset.onInitialize(function ()
for i, node in ipairs(renderables) do
openspace.addScreenSpaceRenderable(node)
end
end)
sceneAsset.onDeinitialize(function ()
for i = #renderables, 1, -1 do
renderable = renderables[i]
openspace.removeScreenSpaceRenderable(renderable.Identifier)
end
end)
end
local registerDashboardItems = function (dashboardAsset, items)
dashboardAsset.onInitialize(
function ()
@@ -176,6 +199,7 @@ end
asset.export("registerSceneGraphNodes", registerSceneGraphNodes)
asset.export("registerSceneGraphNodesAndExport", registerSceneGraphNodesAndExport)
asset.export("registerScreenSpaceRenderables", registerScreenSpaceRenderables)
asset.export("registerSpiceKernels", registerSpiceKernels)
asset.export("registerDashboardItems", registerDashboardItems)
asset.export("requireAll", requireAll)

View File

@@ -0,0 +1,18 @@
asset.onInitialize(function()
openspace.clearKeys()
openspace.bindKey("RIGHT", "openspace.navigation.addGlobalRotation(-5.0, 0.0)");
openspace.bindKey("LEFT", "openspace.navigation.addGlobalRotation(5.0, 0.0)");
openspace.bindKey("UP", "openspace.navigation.addGlobalRotation(0.0, 5.0)");
openspace.bindKey("DOWN", "openspace.navigation.addGlobalRotation(0.0, -5.0)");
openspace.bindKey("CTRL+RIGHT", "openspace.navigation.addLocalRotation(-5.0, 0.0)");
openspace.bindKey("CTRL+LEFT", "openspace.navigation.addLocalRotation(5.0, 0.0)");
openspace.bindKey("CTRL+UP", "openspace.navigation.addLocalRotation(0.0, 5.0)");
openspace.bindKey("CTRL+DOWN", "openspace.navigation.addLocalRotation(0.0, -5.0)");
openspace.bindKey("ALT+UP", "openspace.navigation.addTruckMovement(0.0, 5.0)");
openspace.bindKey("ALT+DOWN", "openspace.navigation.addTruckMovement(0.0, -5.0)");
openspace.bindKey("SPACE", "openspace.setPropertyValueSingle('NavigationHandler.OrbitalNavigator.Aim', '');openspace.setPropertyValueSingle('NavigationHandler.OrbitalNavigator.Anchor', 'Moon');openspace.setPropertyValueSingle('NavigationHandler.OrbitalNavigator.RetargetAnchor', nil);")
openspace.bindKey("Z", "openspace.setPropertyValueSingle('NavigationHandler.OrbitalNavigator.Aim', '');openspace.setPropertyValueSingle('NavigationHandler.OrbitalNavigator.Anchor', 'Earth');openspace.setPropertyValueSingle('NavigationHandler.OrbitalNavigator.RetargetAnchor', nil);")
end)

View File

@@ -0,0 +1,21 @@
local backendHash = "7ca0a34e9c4c065b7bfad0623db0e322bf3e0af9"
local dataProvider = "data.openspaceproject.com/files/webgui"
local backend = asset.syncedResource({
Identifier = "WebGuiBackend",
Name = "Web Gui Backend",
Type = "UrlSynchronization",
Url = dataProvider .. "/backend/" .. backendHash .. "/backend.zip"
})
asset.onInitialize(function ()
-- Unzip the server bundle
dest = backend .. "/backend"
if not openspace.directoryExists(dest) then
openspace.unzipFile(backend .. "/backend.zip", dest, true)
end
openspace.setPropertyValueSingle(
"Modules.WebGui.ServerProcessEntryPoint", backend .. "/backend/backend.js"
)
end)

View File

@@ -1,18 +1,11 @@
asset.require('./static_server')
local guiCustomization = asset.require('customization/gui')
-- Select which commit hashes to use for the frontend and backend
local frontendHash = "c603ad07d1407a7d3def43f1e203244cee1c06f6"
local backendHash = "84737f9785f12efbb12d2de9d511154c6215fe9c"
local frontendHash = "2d1bb8d8d8478b6ed025ccc6f1e0ceacf04b6114"
local dataProvider = "data.openspaceproject.com/files/webgui"
local backend = asset.syncedResource({
Identifier = "WebGuiBackend",
Name = "Web Gui Backend",
Type = "UrlSynchronization",
Url = dataProvider .. "/backend/" .. backendHash .. "/backend.zip"
})
local frontend = asset.syncedResource({
Identifier = "WebGuiFrontend",
Name = "Web Gui Frontend",
@@ -27,22 +20,21 @@ asset.onInitialize(function ()
openspace.unzipFile(frontend .. "/frontend.zip", dest, true)
end
-- Unzip the frontend bundle
dest = backend .. "/backend"
if not openspace.directoryExists(dest) then
openspace.unzipFile(backend .. "/backend.zip", dest, true)
end
-- Serve the production GUI:
local directories = openspace.getPropertyValue("Modules.WebGui.Directories")
directories[#directories + 1] = "frontend"
directories[#directories + 1] = frontend .. '/frontend'
openspace.setPropertyValueSingle("Modules.WebGui.Directories", directories)
openspace.setPropertyValueSingle("Modules.WebGui.DefaultEndpoint", "frontend")
-- Do not serve the files if we are in webgui development mode.
-- In that case, you have to serve the webgui manually, using `npm start`.
if not guiCustomization.webguiDevelopmentMode then
if guiCustomization.webguiDevelopmentMode then
-- Route CEF to the deveopment version of the GUI.
-- This must be manually served using `npm start`
-- in the OpenSpace-WebGuiFrontend repository.
openspace.setPropertyValueSingle(
"Modules.WebGui.ServerProcessEntryPoint", backend .. "/backend/backend.js"
"Modules.CefWebGui.GuiUrl",
"http://127.0.0.1:4690/frontend/#/onscreen"
)
openspace.setPropertyValueSingle(
"Modules.WebGui.WebDirectory", frontend .. "/frontend"
)
openspace.setPropertyValueSingle("Modules.WebGui.ServerProcessEnabled", true)
end
-- The GUI contains date and simulation increment,
@@ -54,5 +46,17 @@ asset.onInitialize(function ()
end)
asset.onDeinitialize(function ()
openspace.setPropertyValueSingle("Modules.WebGui.ServerProcessEnabled", false)
-- Remove the frontend endpoint
local directories = openspace.getPropertyValue("Modules.WebGui.Directories")
local newDirectories;
openspace.setPropertyValueSingle("Modules.WebGui.DefaultEndpoint", "")
for i = 0, #directories, 2 do
if (string.find(directories[i], "frontend") == nil) then
newDirectories[#newDirectories + 1] = directories[i]
newDirectories[#newDirectories + 1] = directories[i + 1]
end
end
openspace.setPropertyValueSingle("Modules.WebGui.Directories", newDirectories)
end)

View File

@@ -47,10 +47,10 @@ asset.onInitialize(function ()
"Earth", "Voyager 1", "Voyager 2", "Jupiter", "Saturn", "Uranus", "Neptune"
})
openspace.navigation.setCameraState({
openspace.navigation.setNavigationState({
Anchor = VoyagerAsset.Voyager_1.Identifier,
Position = { 526781518487.171326, 257168309890.072144, -1381125204152.817383 },
Rotation = { -0.106166, 0.981574, -0.084545, 0.134513 },
ReferenceFrame = "Root",
Position = { 526781518487.171326, 257168309890.072144, -1381125204152.817383 }
})
end)

File diff suppressed because it is too large Load Diff

View File

@@ -57,7 +57,6 @@ struct TestResult {
*/
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 ///< The identifier for a ReferencingVerifier did not exist

View File

@@ -52,6 +52,7 @@ struct WindowDelegate;
namespace configuration { struct Configuration; }
namespace interaction {
struct JoystickInputStates;
struct WebsocketInputStates;
class KeybindingManager;
class NavigationHandler;
class SessionRecording;
@@ -87,6 +88,7 @@ VirtualPropertyManager& gVirtualPropertyManager();
WindowDelegate& gWindowDelegate();
configuration::Configuration& gConfiguration();
interaction::JoystickInputStates& gJoystickInputStates();
interaction::WebsocketInputStates& gWebsocketInputStates();
interaction::KeybindingManager& gKeybindingManager();
interaction::NavigationHandler& gNavigationHandler();
interaction::SessionRecording& gSessionRecording();
@@ -120,6 +122,8 @@ static WindowDelegate& windowDelegate = detail::gWindowDelegate();
static configuration::Configuration& configuration = detail::gConfiguration();
static interaction::JoystickInputStates& joystickInputStates =
detail::gJoystickInputStates();
static interaction::WebsocketInputStates& websocketInputStates =
detail::gWebsocketInputStates();
static interaction::KeybindingManager& keybindingManager = detail::gKeybindingManager();
static interaction::NavigationHandler& navigationHandler = detail::gNavigationHandler();
static interaction::SessionRecording& sessionRecording = detail::gSessionRecording();

View File

@@ -109,6 +109,7 @@ private:
std::unique_ptr<Scene> _scene;
std::unique_ptr<AssetManager> _assetManager;
bool _shouldAbortLoading = false;
std::unique_ptr<LoadingScreen> _loadingScreen;
std::unique_ptr<VersionChecker> _versionChecker;

View File

@@ -25,6 +25,7 @@
#ifndef __OPENSPACE_CORE___INPUTSTATE___H__
#define __OPENSPACE_CORE___INPUTSTATE___H__
#include <openspace/interaction/websocketinputstate.h>
#include <openspace/util/keys.h>
#include <openspace/util/mouse.h>
#include <ghoul/glm.h>
@@ -33,6 +34,7 @@
namespace openspace::interaction {
struct JoystickInputStates;
struct WebsocketInputStates;
// This class represents the global input state of interaction devices
class InputState {
@@ -56,6 +58,12 @@ public:
float joystickAxis(int i) const;
bool joystickButton(int i) const;
WebsocketInputStates& websocketInputStates();
float websocketAxis(int i) const;
bool websocketButton(int i) const;
bool hasWebsocketStates() const;
void resetWebsockets();
private:
// Input from keyboard
std::vector<std::pair<Key, KeyModifier>> _keysDown;

View File

@@ -51,7 +51,7 @@ public:
private:
std::function<T(float)> _transferFunction;
float _t = 0.f;
float _t = 1.f;
float _interpolationTime = 1.f;
float _scaledDeltaTime = 0.f;
};

View File

@@ -25,13 +25,18 @@
#ifndef __OPENSPACE_CORE___NAVIGATIONHANDLER___H__
#define __OPENSPACE_CORE___NAVIGATIONHANDLER___H__
#include <openspace/properties/propertyowner.h>
#include <openspace/documentation/documentation.h>
#include <openspace/interaction/inputstate.h>
#include <openspace/interaction/joystickcamerastates.h>
#include <openspace/interaction/orbitalnavigator.h>
#include <openspace/interaction/keyframenavigator.h>
#include <openspace/properties/propertyowner.h>
#include <openspace/interaction/websocketcamerastates.h>
#include <openspace/properties/stringproperty.h>
#include <openspace/properties/scalar/boolproperty.h>
#include <openspace/util/mouse.h>
#include <openspace/util/keys.h>
#include <optional>
namespace openspace {
class Camera;
@@ -43,11 +48,31 @@ namespace openspace::scripting { struct LuaLibrary; }
namespace openspace::interaction {
struct JoystickInputStates;
struct WebsocketInputStates;
class KeyframeNavigator;
class OrbitalNavigator;
class NavigationHandler : public properties::PropertyOwner {
public:
struct NavigationState {
NavigationState() = default;
NavigationState(const ghoul::Dictionary& dictionary);
NavigationState(std::string anchor, std::string aim, std::string referenceFrame,
glm::dvec3 position, std::optional<glm::dvec3> up = std::nullopt,
double yaw = 0.0, double pitch = 0.0);
ghoul::Dictionary dictionary() const;
static documentation::Documentation Documentation();
std::string anchor;
std::string aim;
std::string referenceFrame;
glm::dvec3 position;
std::optional<glm::dvec3> up;
double yaw = 0.0;
double pitch = 0.0;
};
NavigationHandler();
~NavigationHandler();
@@ -55,10 +80,10 @@ public:
void deinitialize();
// Mutators
void setNavigationStateNextFame(NavigationState state);
void setCamera(Camera* camera);
void setInterpolationTime(float durationInSeconds);
void setCameraStateFromDictionary(const ghoul::Dictionary& cameraDict);
void updateCamera(double deltaTime);
void setEnableKeyFrameInteraction();
void setDisableKeyFrameInteraction();
@@ -66,12 +91,11 @@ public:
void stopPlayback();
// Accessors
ghoul::Dictionary cameraStateDictionary();
Camera* camera() const;
const InputState& inputState() const;
const OrbitalNavigator& orbitalNavigator() const;
OrbitalNavigator& orbitalNavigator();
KeyframeNavigator& keyframeNavigator() const;
KeyframeNavigator& keyframeNavigator();
bool isKeyFrameInteractionEnabled() const;
float interpolationTime() const;
@@ -100,10 +124,21 @@ public:
void clearJoystickButtonCommand(int button);
std::vector<std::string> joystickButtonCommand(int button) const;
// Websockets
void setWebsocketAxisMapping(int axis, WebsocketCameraStates::AxisType mapping,
WebsocketCameraStates::AxisInvert shouldInvert =
WebsocketCameraStates::AxisInvert::No,
WebsocketCameraStates::AxisNormalize shouldNormalize =
WebsocketCameraStates::AxisNormalize::No);
NavigationState navigationState(const SceneGraphNode& referenceFrame) const;
void saveNavigationState(const std::string& filepath,
const std::string& referenceFrameIdentifier);
void saveCameraStateToFile(const std::string& filepath);
void restoreCameraStateFromFile(const std::string& filepath);
void loadNavigationState(const std::string& filepath);
void setNavigationStateNextFrame(NavigationState state);
/**
* \return The Lua library that contains all Lua functions available to affect the
@@ -112,15 +147,18 @@ public:
static scripting::LuaLibrary luaLibrary();
private:
bool _cameraUpdatedFromScript = false;
void applyNavigationState(const NavigationHandler::NavigationState& ns);
bool _playbackModeEnabled = false;
std::unique_ptr<InputState> _inputState;
InputState _inputState;
Camera* _camera = nullptr;
std::function<void()> _playbackEndCallback;
std::unique_ptr<OrbitalNavigator> _orbitalNavigator;
std::unique_ptr<KeyframeNavigator> _keyframeNavigator;
OrbitalNavigator _orbitalNavigator;
KeyframeNavigator _keyframeNavigator;
std::optional<NavigationState> _pendingNavigationState;
properties::BoolProperty _useKeyFrameInteraction;
};

View File

@@ -31,6 +31,8 @@
#include <openspace/interaction/interpolator.h>
#include <openspace/interaction/joystickcamerastates.h>
#include <openspace/interaction/mousecamerastates.h>
#include <openspace/interaction/scriptcamerastates.h>
#include <openspace/interaction/websocketcamerastates.h>
#include <openspace/properties/stringproperty.h>
#include <openspace/properties/scalar/boolproperty.h>
#include <openspace/properties/scalar/floatproperty.h>
@@ -38,6 +40,8 @@
#include <ghoul/glm.h>
#include <glm/gtx/quaternion.hpp>
#include <optional>
namespace openspace {
class SceneGraphNode;
class Camera;
@@ -58,6 +62,7 @@ public:
Camera* camera() const;
void setCamera(Camera* camera);
void clearPreviousState();
void setFocusNode(const std::string& focusNode);
void setAnchorNode(const std::string& anchorNode);
@@ -70,6 +75,13 @@ public:
void resetNodeMovements();
JoystickCameraStates& joystickStates();
const JoystickCameraStates& joystickStates() const;
WebsocketCameraStates& websocketStates();
const WebsocketCameraStates& websocketStates() const;
ScriptCameraStates& scriptStates();
const ScriptCameraStates& scriptStates() const;
bool followingNodeRotation() const;
const SceneGraphNode* anchorNode() const;
@@ -131,6 +143,7 @@ private:
properties::FloatProperty _mouseSensitivity;
properties::FloatProperty _joystickSensitivity;
properties::FloatProperty _websocketSensitivity;
properties::BoolProperty _useAdaptiveStereoscopicDepth;
properties::FloatProperty _stereoscopicDepthOfFocusSurface;
@@ -142,14 +155,15 @@ private:
MouseCameraStates _mouseStates;
JoystickCameraStates _joystickStates;
WebsocketCameraStates _websocketStates;
ScriptCameraStates _scriptStates;
const SceneGraphNode* _anchorNode = nullptr;
const SceneGraphNode* _aimNode = nullptr;
glm::dvec3 _previousAnchorNodePosition;
glm::dquat _previousAnchorNodeRotation;
glm::dvec3 _previousAimNodePosition;
std::optional<glm::dvec3>_previousAnchorNodePosition;
std::optional<glm::dquat> _previousAnchorNodeRotation;
std::optional<glm::dvec3> _previousAimNodePosition;
double _currentCameraToSurfaceDistance = 0.0;
bool _directlySetStereoDistance = false;

View File

@@ -0,0 +1,54 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2019 *
* *
* 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 __OPENSPACE_CORE___SCRIPTCAMERASTATES___H__
#define __OPENSPACE_CORE___SCRIPTCAMERASTATES___H__
#include <openspace/interaction/camerainteractionstates.h>
namespace openspace::interaction {
class ScriptCameraStates : public CameraInteractionStates {
public:
ScriptCameraStates();
void updateStateFromInput(const InputState& inputState, double deltaTime) override;
void addLocalRotation(const glm::dvec2& delta);
void addGlobalRotation(const glm::dvec2& delta);
void addTruckMovement(const glm::dvec2& delta);
void addLocalRoll(const glm::dvec2& delta);
void addGlobalRoll(const glm::dvec2& delta);
private:
glm::dvec2 _localRotation;
glm::dvec2 _globalRotation;
glm::dvec2 _truckMovement;
glm::dvec2 _localRoll;
glm::dvec2 _globalRoll;
};
} // namespace openspace::interaction
#endif // __OPENSPACE_CORE___SCRIPTCAMERASTATES___H__

View File

@@ -221,7 +221,6 @@ private:
double timestamp;
};
ExternInteraction _externInteract;
bool _isRecording = false;
double _timestampRecordStarted = 0.0;
double _timestampPlaybackStarted_application = 0.0;
double _timestampPlaybackStarted_simulation = 0.0;

View File

@@ -0,0 +1,117 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2019 *
* *
* 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 __OPENSPACE_CORE___WEBSOCKETCAMERASTATES___H__
#define __OPENSPACE_CORE___WEBSOCKETCAMERASTATES___H__
#include <openspace/interaction/camerainteractionstates.h>
#include <openspace/interaction/websocketinputstate.h>
#include <ghoul/misc/boolean.h>
#include <ghoul/misc/stringconversion.h>
#include <map>
#include <vector>
namespace openspace::interaction {
class WebsocketCameraStates : public CameraInteractionStates {
public:
enum class AxisType {
None = 0,
OrbitX,
OrbitY,
ZoomIn,
ZoomOut,
LocalRollX,
LocalRollY,
GlobalRollX,
GlobalRollY,
PanX,
PanY
};
BooleanType(AxisInvert);
BooleanType(AxisNormalize);
BooleanType(ButtonCommandRemote);
struct AxisInformation {
AxisType type = AxisType::None;
AxisInvert invert = AxisInvert::No;
AxisNormalize normalize = AxisNormalize::No;
float deadzone = 0.f;
};
WebsocketCameraStates(double sensitivity, double velocityScaleFactor);
void updateStateFromInput(const InputState& inputState, double deltaTime) override;
void setAxisMapping(int axis, AxisType mapping,
AxisInvert shouldInvert = AxisInvert::No,
AxisNormalize shouldNormalize = AxisNormalize::No
);
AxisInformation axisMapping(int axis) const;
void setDeadzone(int axis, float deadzone);
float deadzone(int axis) const;
void bindButtonCommand(int button, std::string command, WebsocketAction action,
ButtonCommandRemote remote, std::string documentation);
void clearButtonCommand(int button);
std::vector<std::string> buttonCommand(int button) const;
private:
// We use an array for the axes and a map for the buttons since the axis are going to
// be accessed much more often and thus have to be more efficient. And storing a few
// extra AxisInformation that are not used will not matter that much; finding an axis
// location in a potential map each frame, however, would
std::array<AxisInformation, WebsocketInputState::MaxAxes> _axisMapping;
struct ButtonInformation {
std::string command;
WebsocketAction action;
ButtonCommandRemote synchronization;
std::string documentation;
};
std::multimap<int, ButtonInformation> _buttonMapping;
};
} // namespace openspace::interaction
namespace ghoul {
template <>
std::string to_string(const openspace::interaction::WebsocketCameraStates::AxisType& type);
template <>
openspace::interaction::WebsocketCameraStates::AxisType
from_string(const std::string& string);
} // namespace ghoul
#endif // __OPENSPACE_CORE___WEBSOCKETCAMERASTATES___H__

View File

@@ -0,0 +1,125 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2019 *
* *
* 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 __OPENSPACE_CORE___WEBSOCKETINPUTSTATE___H__
#define __OPENSPACE_CORE___WEBSOCKETINPUTSTATE___H__
#include <ghoul/misc/stringconversion.h>
#include <array>
#include <memory>
#include <unordered_map>
#include <string>
namespace openspace::interaction {
/**
* Actions that any button of a websocket can have. Each button must be in one of these
* states
*/
enum class WebsocketAction : uint8_t {
/// Idle state if the button is unpressed and has been unpressed since last frame
Idle = 0,
/// If the button has been pressed since the last frame
Press,
/// If the button has been pressed since longer than last frame
Repeat,
/// If the button was released since the last frame
Release
};
/**
* The input state of a single websocket.
*/
struct WebsocketInputState {
/// The maximum number of supported axes
static constexpr const int MaxAxes = 10;
/// The maximum number of supported buttons
static constexpr const int MaxButtons = 32;
/// Marks whether this websocket is connected. If this value is \c false, all other
/// members of this struct are undefined
bool isConnected = false;
/// The name of this websocket
std::string name;
/// The number of axes that this websocket supports
int nAxes = 0;
/// The values for each axis. Each value is in the range [-1, 1]. Only the first
/// \c nAxes values are defined values, the rest are undefined
std::array<float, MaxAxes> axes;
/// The number of buttons that this websocket possesses
int nButtons = 0;
/// The status of each button. Only the first \c nButtons values are defined, the rest
/// are undefined
std::array<WebsocketAction, MaxButtons> buttons;
};
/// The maximum number of websockets that are supported by this system. This number is
/// derived from the available GLFW constants
constexpr const int MaxWebsockets = 16;
//struct WebsocketInputStates : public std::array<WebsocketInputState, MaxWebsockets> {
struct WebsocketInputStates : public std::unordered_map<size_t, WebsocketInputState*> {
/**
* This function adds the contributions of all connected websockets for the provided
* \p axis. After adding each websockets contribution, the result is clamped to [-1,1].
* If a websocket does not possess a particular axis, it's does not contribute to the
* sum.
*
* \param axis The numerical axis for which the values are added
* \return The summed axis values of all connected websockets
*
* \pre \p axis must be 0 or positive
*/
float axis(int axis) const;
/**
* This functions checks whether any connected websocket has its \p button in the
* passed \p action. Any websocket that does not posses the \p button, it will be
* ignored.
*
* \param button The button that is to be checked
* \param action The action which is checked for each button
* \return \c true if there is at least one websocket whose \param button is in the
* \p action state
*
* \pre \p button must be 0 or positive
*/
bool button(int button, WebsocketAction action) const;
};
} // namespace openspace::interaction
namespace ghoul {
template <>
std::string to_string(const openspace::interaction::WebsocketAction& action);
template <>
openspace::interaction::WebsocketAction from_string(const std::string& str);
} // namespace ghoul
#endif // __OPENSPACE_CORE___WEBSOCKETINPUTSTATE___H__

View File

@@ -303,7 +303,6 @@ protected:
/// The description for this PropertyOwner
std::string _description;
private:
/// The owner of this PropertyOwner
PropertyOwner* _owner = nullptr;
/// A list of all registered Property's

View File

@@ -86,8 +86,8 @@ public:
struct ProgressInfo {
float progress = 0.f;
int currentSize = -1;
int totalSize = -1;
int64_t currentSize = -1;
int64_t totalSize = -1;
};
void updateItem(const std::string& itemIdentifier, const std::string& itemName,

View File

@@ -187,7 +187,21 @@ private:
properties::TriggerProperty _takeScreenshot;
bool _shouldTakeScreenshot = false;
properties::BoolProperty _applyWarping;
properties::BoolProperty _showFrameNumber;
properties::BoolProperty _showFrameInformation;
#ifdef OPENSPACE_WITH_INSTRUMENTATION
struct FrameInfo {
uint64_t iFrame;
double deltaTime;
double avgDeltaTime;
};
struct {
std::vector<FrameInfo> frames;
uint64_t lastSavedFrame = 0;
uint16_t saveEveryNthFrame = 2048;
} _frameInfo;
properties::BoolProperty _saveFrameInformation;
#endif // OPENSPACE_WITH_INSTRUMENTATION
properties::BoolProperty _disableMasterRendering;
properties::FloatProperty _globalBlackOutFactor;
@@ -205,7 +219,7 @@ private:
std::vector<ghoul::opengl::ProgramObject*> _programs;
std::shared_ptr<ghoul::fontrendering::Font> _fontBig;
std::shared_ptr<ghoul::fontrendering::Font> _fontFrameInfo;
std::shared_ptr<ghoul::fontrendering::Font> _fontInfo;
std::shared_ptr<ghoul::fontrendering::Font> _fontDate;
std::shared_ptr<ghoul::fontrendering::Font> _fontLog;

View File

@@ -82,7 +82,7 @@ protected:
void draw(glm::mat4 modelTransform);
virtual void bindTexture();
virtual void bindTexture() = 0;
virtual void unbindTexture();
properties::BoolProperty _enabled;
@@ -106,10 +106,8 @@ protected:
properties::TriggerProperty _delete;
glm::ivec2 _objectSize;
UniformCache(occlusionDepth, alpha, modelTransform, viewProj, texture) _uniformCache;
UniformCache(alpha, modelTransform, viewProj, texture) _uniformCache;
std::unique_ptr<ghoul::opengl::ProgramObject> _shader;
glm::vec2 _originalViewportSize;
};
} // namespace openspace

View File

@@ -65,7 +65,7 @@ public:
*/
static double convertTime(const std::string& time);
Time(double secondsJ2000 = -1);
explicit Time(double secondsJ2000 = -1);
Time(const Time& other) = default;
/**

View File

@@ -44,7 +44,12 @@ struct KeyframeBase {
*/
template <typename T>
struct Keyframe : public KeyframeBase {
Keyframe(size_t i, double t, T p);
Keyframe(size_t i, double t, T d);
Keyframe(Keyframe const&) = default;
Keyframe(Keyframe&&) = default;
Keyframe& operator=(Keyframe&&) = default;
Keyframe& operator=(Keyframe const&) = default;
T data;
};
@@ -56,7 +61,8 @@ class Timeline {
public:
virtual ~Timeline() = default;
void addKeyframe(double time, T data);
void addKeyframe(double time, const T& data);
void addKeyframe(double time, T&& data);
void clearKeyframes();
void removeKeyframe(size_t id);
void removeKeyframesBefore(double timestamp, bool inclusive = false);
@@ -66,6 +72,7 @@ public:
size_t nKeyframes() const;
const Keyframe<T>* firstKeyframeAfter(double timestamp, bool inclusive = false) const;
const Keyframe<T>* lastKeyframeBefore(double timestamp, bool inclusive = false) const;
const std::deque<Keyframe<T>>& keyframes() const;
private:

View File

@@ -25,13 +25,25 @@
namespace openspace {
template <typename T>
Keyframe<T>::Keyframe(size_t i, double t, T p)
Keyframe<T>::Keyframe(size_t i, double t, T d)
: KeyframeBase{ i, t }
, data(p)
, data(std::move(d))
{}
template <typename T>
void Timeline<T>::addKeyframe(double timestamp, T data) {
void Timeline<T>::addKeyframe(double timestamp, T&& data) {
Keyframe<T> keyframe(++_nextKeyframeId, timestamp, std::move(data));
const auto iter = std::upper_bound(
_keyframes.cbegin(),
_keyframes.cend(),
keyframe,
&compareKeyframeTimes
);
_keyframes.insert(iter, std::move(keyframe));
}
template <typename T>
void Timeline<T>::addKeyframe(double timestamp, const T& data) {
Keyframe<T> keyframe(++_nextKeyframeId, timestamp, data);
const auto iter = std::upper_bound(
_keyframes.cbegin(),
@@ -39,7 +51,7 @@ void Timeline<T>::addKeyframe(double timestamp, T data) {
keyframe,
&compareKeyframeTimes
);
_keyframes.insert(iter, keyframe);
_keyframes.insert(iter, std::move(keyframe));
}
template <typename T>
@@ -143,7 +155,7 @@ void Timeline<T>::removeKeyframe(size_t id) {
std::remove_if(
_keyframes.begin(),
_keyframes.end(),
[id] (Keyframe<T> keyframe) { return keyframe.id == id; }
[id] (const Keyframe<T>& keyframe) { return keyframe.id == id; }
),
_keyframes.end()
);
@@ -209,7 +221,7 @@ const Keyframe<T>* Timeline<T>::lastKeyframeBefore(double timestamp, bool inclus
return &(*it);
}
template<typename T>
template <typename T>
const std::deque<Keyframe<T>>& Timeline<T>::keyframes() const {
return _keyframes;
}

View File

@@ -261,8 +261,8 @@ void AtmosphereDeferredcaster::preRaycast(const RenderData& renderData,
program.setUniform(_uniformCache2.dModelTransformMatrix, _modelTransform);
// Eye Space in SGCT to Eye Space in OS (SGCT View to OS Camera Rig)
glm::dmat4 dSgctEye2OSEye = glm::inverse(
glm::dmat4(renderData.camera.viewMatrix()));
// glm::dmat4 dSgctEye2OSEye = glm::inverse(
// glm::dmat4(renderData.camera.viewMatrix()));
glm::dmat4 dSGCTViewToWorldMatrix = glm::inverse(
renderData.camera.combinedViewMatrix()
@@ -1508,7 +1508,7 @@ bool AtmosphereDeferredcaster::isAtmosphereInFrustum(const glm::dmat4& MVMatrix,
double bottomDistance = MVMatrix[3][3] + MVMatrix[3][1];
double topDistance = MVMatrix[3][3] - MVMatrix[3][1];
double nearDistance = MVMatrix[3][3] + MVMatrix[3][2];
double farDistance = MVMatrix[3][3] - MVMatrix[3][2];
// double farDistance = MVMatrix[3][3] - MVMatrix[3][2];
// Normalize Planes
double invMag = 1.0 / glm::length(leftNormal);
@@ -1533,7 +1533,7 @@ bool AtmosphereDeferredcaster::isAtmosphereInFrustum(const glm::dmat4& MVMatrix,
invMag = 1.0 / glm::length(farNormal);
farNormal *= invMag;
farDistance *= invMag;
// farDistance *= invMag;
if ((glm::dot(leftNormal, position) + leftDistance) < -radius) {
return false;

View File

@@ -54,8 +54,7 @@ set(HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/rendering/screenspaceframebuffer.h
${CMAKE_CURRENT_SOURCE_DIR}/rendering/screenspaceimagelocal.h
${CMAKE_CURRENT_SOURCE_DIR}/rendering/screenspaceimageonline.h
${CMAKE_CURRENT_SOURCE_DIR}/translation/luatranslation.h
${CMAKE_CURRENT_SOURCE_DIR}/translation/statictranslation.h
${CMAKE_CURRENT_SOURCE_DIR}/rotation/timelinerotation.h
${CMAKE_CURRENT_SOURCE_DIR}/rotation/constantrotation.h
${CMAKE_CURRENT_SOURCE_DIR}/rotation/fixedrotation.h
${CMAKE_CURRENT_SOURCE_DIR}/rotation/luarotation.h
@@ -65,6 +64,10 @@ set(HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/scale/timedependentscale.h
${CMAKE_CURRENT_SOURCE_DIR}/timeframe/timeframeinterval.h
${CMAKE_CURRENT_SOURCE_DIR}/timeframe/timeframeunion.h
${CMAKE_CURRENT_SOURCE_DIR}/translation/luatranslation.h
${CMAKE_CURRENT_SOURCE_DIR}/translation/statictranslation.h
${CMAKE_CURRENT_SOURCE_DIR}/translation/timelinetranslation.h
)
source_group("Header Files" FILES ${HEADER_FILES})
@@ -98,8 +101,7 @@ set(SOURCE_FILES
${CMAKE_CURRENT_SOURCE_DIR}/rendering/screenspaceframebuffer.cpp
${CMAKE_CURRENT_SOURCE_DIR}/rendering/screenspaceimagelocal.cpp
${CMAKE_CURRENT_SOURCE_DIR}/rendering/screenspaceimageonline.cpp
${CMAKE_CURRENT_SOURCE_DIR}/translation/luatranslation.cpp
${CMAKE_CURRENT_SOURCE_DIR}/translation/statictranslation.cpp
${CMAKE_CURRENT_SOURCE_DIR}/rotation/timelinerotation.cpp
${CMAKE_CURRENT_SOURCE_DIR}/rotation/constantrotation.cpp
${CMAKE_CURRENT_SOURCE_DIR}/rotation/fixedrotation.cpp
${CMAKE_CURRENT_SOURCE_DIR}/rotation/luarotation.cpp
@@ -109,6 +111,9 @@ set(SOURCE_FILES
${CMAKE_CURRENT_SOURCE_DIR}/scale/timedependentscale.cpp
${CMAKE_CURRENT_SOURCE_DIR}/timeframe/timeframeinterval.cpp
${CMAKE_CURRENT_SOURCE_DIR}/timeframe/timeframeunion.cpp
${CMAKE_CURRENT_SOURCE_DIR}/translation/luatranslation.cpp
${CMAKE_CURRENT_SOURCE_DIR}/translation/statictranslation.cpp
${CMAKE_CURRENT_SOURCE_DIR}/translation/timelinetranslation.cpp
)
source_group("Source Files" FILES ${SOURCE_FILES})

View File

@@ -55,9 +55,11 @@
#include <modules/base/rotation/fixedrotation.h>
#include <modules/base/rotation/luarotation.h>
#include <modules/base/rotation/staticrotation.h>
#include <modules/base/rotation/timelinerotation.h>
#include <modules/base/scale/luascale.h>
#include <modules/base/scale/staticscale.h>
#include <modules/base/scale/timedependentscale.h>
#include <modules/base/translation/timelinetranslation.h>
#include <modules/base/translation/luatranslation.h>
#include <modules/base/translation/statictranslation.h>
#include <modules/base/timeframe/timeframeinterval.h>
@@ -131,6 +133,7 @@ void BaseModule::internalInitialize(const ghoul::Dictionary&) {
auto fTranslation = FactoryManager::ref().factory<Translation>();
ghoul_assert(fTranslation, "Ephemeris factory was not created");
fTranslation->registerClass<TimelineTranslation>("TimelineTranslation");
fTranslation->registerClass<LuaTranslation>("LuaTranslation");
fTranslation->registerClass<StaticTranslation>("StaticTranslation");
@@ -141,6 +144,8 @@ void BaseModule::internalInitialize(const ghoul::Dictionary&) {
fRotation->registerClass<FixedRotation>("FixedRotation");
fRotation->registerClass<LuaRotation>("LuaRotation");
fRotation->registerClass<StaticRotation>("StaticRotation");
fRotation->registerClass<TimelineRotation>("TimelineRotation");
auto fScale = FactoryManager::ref().factory<Scale>();
ghoul_assert(fScale, "Scale factory was not created");
@@ -198,6 +203,7 @@ std::vector<documentation::Documentation> BaseModule::documentations() const {
FixedRotation::Documentation(),
LuaRotation::Documentation(),
StaticRotation::Documentation(),
TimelineRotation::Documentation(),
LuaScale::Documentation(),
StaticScale::Documentation(),
@@ -205,6 +211,7 @@ std::vector<documentation::Documentation> BaseModule::documentations() const {
LuaTranslation::Documentation(),
StaticTranslation::Documentation(),
TimelineTranslation::Documentation(),
TimeFrameInterval::Documentation(),
TimeFrameUnion::Documentation(),

View File

@@ -289,7 +289,7 @@ void DashboardItemFramerate::render(glm::vec2& penPosition) {
);
int nLines = output.empty() ? 0 :
(std::count(output.begin(), output.end(), '\n') + 1);
static_cast<int>((std::count(output.begin(), output.end(), '\n') + 1));
penPosition.y -= _font->height() * static_cast<float>(nLines);

View File

@@ -233,8 +233,8 @@ void RenderableTrailOrbit::update(const UpdateData& data) {
// Write the current location into the floating position
const glm::vec3 p = _translation->position({
{},
data.time.j2000Seconds(),
0.0,
data.time,
Time(0.0),
false
});
_vertexArray[_primaryRenderInformation.first] = { p.x, p.y, p.z };
@@ -412,8 +412,8 @@ RenderableTrailOrbit::UpdateReport RenderableTrailOrbit::updateTrails(
// location
const glm::vec3 p = _translation->position({
{},
_lastPointTime,
0.0,
Time(_lastPointTime),
Time(0.0),
false
});
_vertexArray[_primaryRenderInformation.first] = { p.x, p.y, p.z };
@@ -452,8 +452,8 @@ RenderableTrailOrbit::UpdateReport RenderableTrailOrbit::updateTrails(
// location
const glm::vec3 p = _translation->position({
{},
_firstPointTime,
0.0,
Time(_firstPointTime),
Time(0.0),
false
});
_vertexArray[_primaryRenderInformation.first] = { p.x, p.y, p.z };
@@ -496,7 +496,7 @@ void RenderableTrailOrbit::fullSweep(double time) {
const double secondsPerPoint = _period / (_resolution - 1);
// starting at 1 because the first position is a floating current one
for (int i = 1; i < _resolution; ++i) {
const glm::vec3 p = _translation->position({ {}, time, 0.0, false });
const glm::vec3 p = _translation->position({ {}, Time(time), Time(0.0), false });
_vertexArray[i] = { p.x, p.y, p.z };
time -= secondsPerPoint;

View File

@@ -226,8 +226,8 @@ void RenderableTrailTrajectory::update(const UpdateData& data) {
for (int i = 0; i < nValues; ++i) {
const glm::vec3 p = _translation->position({
{},
_start + i * totalSampleInterval,
0.0,
Time(_start + i * totalSampleInterval),
Time(0.0),
false
});
_vertexArray[i] = { p.x, p.y, p.z };

View File

@@ -212,7 +212,6 @@ void ScreenSpaceDashboard::update() {
if (global::windowDelegate.windowHasResized()) {
const glm::ivec2 size = global::windowDelegate.currentWindowResolution();
_size = { 0.f, 0.f, size.x, size.y };
_originalViewportSize = size;
createFramebuffer();
}
}

View File

@@ -106,15 +106,15 @@ void ScreenSpaceFramebuffer::render() {
const glm::vec2& resolution = global::windowDelegate.currentWindowResolution();
const glm::vec4& size = _size.value();
const float xratio = _originalViewportSize.x / (size.z - size.x);
const float yratio = _originalViewportSize.y / (size.w - size.y);;
const float xratio = resolution.x / (size.z - size.x);
const float yratio = resolution.y / (size.w - size.y);;
if (!_renderFunctions.empty()) {
glViewport(
static_cast<GLint>(-size.x * xratio),
static_cast<GLint>(-size.y * yratio),
static_cast<GLsizei>(_originalViewportSize.x * xratio),
static_cast<GLsizei>(_originalViewportSize.y * yratio)
static_cast<GLsizei>(resolution.x * xratio),
static_cast<GLsizei>(resolution.y * yratio)
);
GLint defaultFBO = _framebuffer->getActiveObject();
_framebuffer->activate();
@@ -170,14 +170,16 @@ void ScreenSpaceFramebuffer::removeAllRenderFunctions() {
}
void ScreenSpaceFramebuffer::createFramebuffer() {
glm::vec2 resolution = global::windowDelegate.currentWindowResolution();
_framebuffer = std::make_unique<ghoul::opengl::FramebufferObject>();
_framebuffer->activate();
_texture = std::make_unique<ghoul::opengl::Texture>(glm::uvec3(
_originalViewportSize.x,
_originalViewportSize.y,
resolution.x,
resolution.y,
1
));
_objectSize = glm::ivec2(_originalViewportSize);
_objectSize = glm::ivec2(resolution);
_texture->uploadTexture();
_texture->setFilter(ghoul::opengl::Texture::FilterMode::LinearMipMap);

View File

@@ -28,6 +28,7 @@
#include <openspace/documentation/verifier.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/io/texture/texturereader.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/opengl/programobject.h>
#include <ghoul/opengl/texture.h>
#include <ghoul/opengl/textureconversion.h>
@@ -96,11 +97,30 @@ ScreenSpaceImageLocal::ScreenSpaceImageLocal(const ghoul::Dictionary& dictionary
setGuiName("ScreenSpaceImageLocal " + std::to_string(iIdentifier));
}
_texturePath.onChange([this]() { _textureIsDirty = true; });
_texturePath.onChange([this]() {
if (!FileSys.fileExists(FileSys.absolutePath(_texturePath))) {
LWARNINGC(
"ScreenSpaceImageLocal",
fmt::format("Image {} did not exist for {}", _texturePath, _identifier)
);
}
else {
_textureIsDirty = true;
}
});
addProperty(_texturePath);
if (dictionary.hasKey(TexturePathInfo.identifier)) {
_texturePath = dictionary.value<std::string>(TexturePathInfo.identifier);
std::string path = dictionary.value<std::string>(TexturePathInfo.identifier);
if (!FileSys.fileExists(FileSys.absolutePath(path))) {
LWARNINGC(
"ScreenSpaceImageLocal",
fmt::format("Image {} did not exist for {}", path, _identifier)
);
}
else {
_texturePath = path;
}
}
}
@@ -130,12 +150,13 @@ void ScreenSpaceImageLocal::update() {
_objectSize = _texture->dimensions();
_textureIsDirty = false;
}
}
}
void ScreenSpaceImageLocal::bindTexture() {
_texture->bind();
if (_texture) {
_texture->bind();
}
}
} // namespace openspace

View File

@@ -0,0 +1,118 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2019 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#include <modules/base/rotation/timelinerotation.h>
#include <openspace/documentation/documentation.h>
#include <openspace/documentation/verifier.h>
#include <openspace/util/updatestructures.h>
#include <openspace/util/time.h>
namespace {
constexpr const char* KeyType = "Type";
constexpr const char* KeyKeyframes = "Keyframes";
} // namespace
namespace openspace {
documentation::Documentation TimelineRotation::Documentation() {
using namespace documentation;
return {
"Timeline Rotation",
"base_transform_rotation_keyframe",
{
{
KeyType,
new StringEqualVerifier("TimelineRotation"),
Optional::No
},
{
KeyKeyframes,
new TableVerifier({
{ "*", new TableVerifier(), Optional::No, "Any translation object" }
}),
Optional::No,
"A table of keyframes, with keys formatted as YYYY-MM-DDTHH:MM:SS"
"and values that are valid Rotation objects."
}
}
};
}
TimelineRotation::TimelineRotation(const ghoul::Dictionary& dictionary) {
documentation::testSpecificationAndThrow(
Documentation(),
dictionary,
"TimelineTranslation"
);
const ghoul::Dictionary& keyframes =
dictionary.value<ghoul::Dictionary>(KeyKeyframes);
std::vector<std::string> timeStrings = keyframes.keys();
for (const std::string& timeString : timeStrings) {
const double t = Time::convertTime(timeString);
std::unique_ptr<Rotation> rotation =
Rotation::createFromDictionary(
keyframes.value<ghoul::Dictionary>(timeString)
);
if (rotation) {
_timeline.addKeyframe(t, std::move(rotation));
}
}
}
glm::dmat3 TimelineRotation::matrix(const UpdateData& data) const {
const double now = data.time.j2000Seconds();
using KeyframePointer = const Keyframe<std::unique_ptr<Rotation>>*;
KeyframePointer prev = _timeline.lastKeyframeBefore(now, true);
KeyframePointer next = _timeline.firstKeyframeAfter(now, true);
if (!prev && !next) {
return glm::dmat3(0.0);
}
if (!prev) {
prev = next;
}
if (!next) {
next = prev;
}
const double prevTime = prev->timestamp;
const double nextTime = next->timestamp;
double t = 0.0;
if (nextTime - prevTime > 0.0) {
t = (now - prevTime) / (nextTime - prevTime);
}
const glm::dquat nextRot = glm::quat_cast(next->data->matrix(data));
const glm::dquat prevRot = glm::quat_cast(prev->data->matrix(data));
return glm::dmat3(glm::slerp(prevRot, nextRot, t));
}
} // namespace openspace

View File

@@ -0,0 +1,49 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2019 *
* *
* 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 __OPENSPACE_MODULE_BASE___TIMELINEROTATION___H__
#define __OPENSPACE_MODULE_BASE___TIMELINEROTATION___H__
#include <openspace/scene/rotation.h>
#include <openspace/util/timeline.h>
namespace openspace {
struct UpdateData;
namespace documentation { struct Documentation; }
class TimelineRotation : public Rotation {
public:
TimelineRotation(const ghoul::Dictionary& dictionary);
glm::dmat3 matrix(const UpdateData& data) const override;
static documentation::Documentation Documentation();
private:
Timeline<std::unique_ptr<Rotation>> _timeline;
};
} // namespace openspace
#endif // __OPENSPACE_MODULE_BASE___TIMELINEROTATION___H__

View File

@@ -29,10 +29,8 @@ in vec2 vs_st;
in vec4 vs_position;
uniform sampler2D texture1;
uniform float OcclusionDepth;
uniform float Alpha;
Fragment getFragment() {
Fragment frag;

View File

@@ -0,0 +1,114 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2019 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#include <modules/base/translation/timelinetranslation.h>
#include <openspace/documentation/documentation.h>
#include <openspace/documentation/verifier.h>
#include <openspace/util/updatestructures.h>
#include <openspace/util/time.h>
namespace {
constexpr const char* KeyType = "Type";
constexpr const char* KeyKeyframes = "Keyframes";
} // namespace
namespace openspace {
documentation::Documentation TimelineTranslation::Documentation() {
using namespace documentation;
return {
"Timeline Translation",
"base_transform_translation_keyframe",
{
{
KeyType,
new StringEqualVerifier("TimelineTranslation"),
Optional::No
},
{
KeyKeyframes,
new TableVerifier({
{ "*", new TableVerifier(), Optional::No, "Any translation object" }
}),
Optional::No,
"A table of keyframes, with keys formatted as YYYY-MM-DDTHH:MM:SS"
"and values that are valid Translation objects."
}
}
};
}
TimelineTranslation::TimelineTranslation(const ghoul::Dictionary& dictionary) {
documentation::testSpecificationAndThrow(
Documentation(),
dictionary,
"TimelineTranslation"
);
const ghoul::Dictionary& keyframes =
dictionary.value<ghoul::Dictionary>(KeyKeyframes);
std::vector<std::string> timeStrings = keyframes.keys();
for (const std::string& timeString : timeStrings) {
const double t = Time::convertTime(timeString);
std::unique_ptr<Translation> translation =
Translation::createFromDictionary(
keyframes.value<ghoul::Dictionary>(timeString)
);
if (translation) {
_timeline.addKeyframe(t, std::move(translation));
}
}
}
glm::dvec3 TimelineTranslation::position(const UpdateData& data) const {
const double now = data.time.j2000Seconds();
using KeyframePointer = const Keyframe<std::unique_ptr<Translation>>*;
KeyframePointer prev = _timeline.lastKeyframeBefore(now, true);
KeyframePointer next = _timeline.firstKeyframeAfter(now, true);
if (!prev && !next) {
return glm::dvec3(0.0);
}
if (!prev) {
prev = next;
}
if (!next) {
next = prev;
}
const double prevTime = prev->timestamp;
const double nextTime = next->timestamp;
double t = 0.0;
if (nextTime - prevTime > 0.0) {
t = (now - prevTime) / (nextTime - prevTime);
}
return t * next->data->position(data) + (1.0 - t) * prev->data->position(data);
}
} // namespace openspace

View File

@@ -22,56 +22,29 @@
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#ifndef __OPENSPACE_MODULE_SYNC___TORRENTSYNCHRONIZATION___H__
#define __OPENSPACE_MODULE_SYNC___TORRENTSYNCHRONIZATION___H__
#ifndef __OPENSPACE_MODULE_BASE___TIMELINETRANSLATION___H__
#define __OPENSPACE_MODULE_BASE___TIMELINETRANSLATION___H__
#ifdef SYNC_USE_LIBTORRENT
#include <openspace/util/resourcesynchronization.h>
#include <modules/sync/torrentclient.h>
#include <openspace/scene/translation.h>
#include <openspace/util/timeline.h>
namespace openspace {
class TorrentSynchronizationJob;
struct UpdateData;
class TorrentSynchronization : public ResourceSynchronization {
namespace documentation { struct Documentation; }
class TimelineTranslation : public Translation {
public:
TorrentSynchronization(const ghoul::Dictionary& dict, std::string synchronizationRoot,
TorrentClient& client);
virtual ~TorrentSynchronization();
std::string directory() override;
void start() override;
void cancel() override;
void clear() override;
size_t nSynchronizedBytes() override;
size_t nTotalBytes() override;
bool nTotalBytesIsKnown() override;
TimelineTranslation(const ghoul::Dictionary& dictionary);
glm::dvec3 position(const UpdateData& data) const override;
static documentation::Documentation Documentation();
private:
void updateTorrentProgress(TorrentClient::TorrentProgress p);
std::string uniformResourceName() const;
bool hasSyncFile();
void createSyncFile();
std::atomic_bool _enabled = false;
TorrentClient::TorrentId _torrentId = 0;
TorrentClient::TorrentProgress _progress;
std::mutex _progressMutex;
std::string _identifier;
std::string _magnetLink;
std::string _synchronizationRoot;
TorrentClient& _torrentClient;
Timeline<std::unique_ptr<Translation>> _timeline;
};
} // namespace openspace
#endif // SYNC_USE_LIBTORRENT
#endif // __OPENSPACE_MODULE_SYNC___TORRENTSYNCHRONIZATION___H__
#endif // __OPENSPACE_MODULE_BASE___TIMELINETRANSLATION___H__

View File

@@ -25,7 +25,6 @@
#include <modules/cefwebgui/cefwebguimodule.h>
#include <modules/webbrowser/webbrowsermodule.h>
#include <modules/webgui/webguimodule.h>
#include <modules/cefwebgui/include/guirenderhandler.h>
#include <modules/cefwebgui/include/guikeyboardhandler.h>
#include <modules/webbrowser/include/browserinstance.h>
@@ -166,7 +165,15 @@ void CefWebGuiModule::internalInitialize(const ghoul::Dictionary& configuration)
} else {
WebGuiModule* webGuiModule = global::moduleEngine.module<WebGuiModule>();
_url = "http://127.0.0.1:" +
std::to_string(webGuiModule->port()) + "/#/onscreen";
std::to_string(webGuiModule->port()) + "/frontend/#/onscreen";
_endpointCallback = webGuiModule->addEndpointChangeCallback(
[this](const std::string& endpoint, bool exists) {
if (exists && endpoint == "frontend" && _instance) {
_instance->reloadBrowser();
}
}
);
}
if (configuration.hasValue<float>(GuiScaleInfo.identifier)) {
@@ -204,6 +211,11 @@ void CefWebGuiModule::internalInitialize(const ghoul::Dictionary& configuration)
});
global::callback::deinitializeGL.emplace_back([this]() {
if (_endpointCallback != -1) {
WebGuiModule* webGuiModule = global::moduleEngine.module<WebGuiModule>();
webGuiModule->removeEndpointChangeCallback(_endpointCallback);
_endpointCallback = -1;
}
_enabled = false;
startOrStopGui();
});

View File

@@ -27,6 +27,8 @@
#include <openspace/util/openspacemodule.h>
#include <modules/webgui/webguimodule.h>
#include <openspace/properties/scalar/boolproperty.h>
#include <openspace/properties/scalar/floatproperty.h>
#include <openspace/properties/triggerproperty.h>
@@ -53,6 +55,8 @@ private:
properties::StringProperty _url;
properties::FloatProperty _guiScale;
std::unique_ptr<BrowserInstance> _instance;
WebGuiModule::CallbackHandle _endpointCallback = -1;
};
} // namespace openspace

View File

@@ -39,8 +39,8 @@ public:
GUIRenderHandler();
virtual ~GUIRenderHandler();
void draw();
void render();
void draw() override;
void render() override;
private:
std::unique_ptr<ghoul::opengl::ProgramObject> _programObject;

View File

@@ -31,8 +31,7 @@ uniform mat4 ortho;
out vec2 Texcoord;
void main() {
Texcoord = vec2(position.x + 1.0f, position.y - 1.0f) * 0.5;
Texcoord.y *= -1.0f;
Texcoord = vec2(position.x + 1.0f, position.y + 1.0f) * 0.5;
gl_Position = vec4(position, 0.0, 1.0);
}

View File

@@ -750,7 +750,6 @@ void RenderableBillboardsCloud::renderBillboards(const RenderData& data,
_program->activate();
const glm::dmat4 projMatrix = glm::dmat4(data.camera.projectionMatrix());
_program->setUniform(
"screenSize",
glm::vec2(global::renderEngine.renderingResolution())

View File

@@ -77,19 +77,6 @@ namespace {
"all point."
};
//constexpr openspace::properties::Property::PropertyInfo ScaleFactorInfo = {
// "ScaleFactor",
// "Scale Factor",
// "This value is used as a multiplicative factor that is applied to the apparent "
// "size of each point."
//};
constexpr openspace::properties::Property::PropertyInfo ColorInfo = {
"Color",
"Color",
"This value is used to define the color of the astronomical object."
};
constexpr openspace::properties::Property::PropertyInfo TextColorInfo = {
"TextColor",
"Text Color",
@@ -427,7 +414,7 @@ void RenderableDUMeshes::initializeGL() {
}
void RenderableDUMeshes::deinitializeGL() {
for (const std::pair<int, RenderingMesh>& pair : _renderingMeshesMap) {
for (const std::pair<const int, RenderingMesh>& pair : _renderingMeshesMap) {
for (int i = 0; i < pair.second.numU; ++i) {
glDeleteVertexArrays(1, &pair.second.vaoArray[i]);
glDeleteBuffers(1, &pair.second.vboArray[i]);
@@ -483,7 +470,7 @@ void RenderableDUMeshes::renderMeshes(const RenderData&,
_program->setUniform(_uniformCache.alphaValue, _alphaValue);
//_program->setUniform(_uniformCache.scaleFactor, _scaleFactor);
for (const std::pair<int, RenderingMesh>& pair : _renderingMeshesMap) {
for (const std::pair<const int, RenderingMesh>& pair : _renderingMeshesMap) {
_program->setUniform(_uniformCache.color, _meshColorMap[pair.second.colorIndex]);
for (size_t i = 0; i < pair.second.vaoArray.size(); ++i) {
glBindVertexArray(pair.second.vaoArray[i]);

View File

@@ -844,7 +844,7 @@ bool RenderablePlanesCloud::loadData() {
bool RenderablePlanesCloud::loadTextures() {
if (!_textureFileMap.empty()) {
for (const std::pair<int, std::string>& pair : _textureFileMap) {
for (const std::pair<const int, std::string>& pair : _textureFileMap) {
const auto& p = _textureMap.insert(std::make_pair(
pair.first,
ghoul::io::TextureReader::ref().loadTexture(pair.second)

View File

@@ -771,7 +771,7 @@ void RenderableFieldlinesSequence::definePropertyCallbackFunctions() {
});
_pJumpToStartBtn.onChange([this] {
global::timeManager.setTimeNextFrame(_startTimes[0]);
global::timeManager.setTimeNextFrame(Time(_startTimes[0]));
});
}

View File

@@ -29,6 +29,7 @@
#include <ghoul/fmt.h>
#include <ghoul/logging/logmanager.h>
#include <fstream>
#include <iomanip>
namespace {
constexpr const char* _loggerCat = "FieldlinesState";

View File

@@ -109,6 +109,11 @@ create_new_module(
${HEADER_FILES} ${SOURCE_FILES} ${SHADER_FILES}
)
option(OPENSPACE_MODULE_GLOBEBROWSING_INSTRUMENTATION "Instrumentation for GlobeBrowsing Performance" OFF)
if (OPENSPACE_MODULE_GLOBEBROWSING_INSTRUMENTATION)
target_compile_definitions(openspace-module-globebrowsing INTERFACE "OPENSPACE_MODULE_GLOBEBROWSING_INSTRUMENTATION")
endif ()
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/gdal_data DESTINATION modules/globebrowsing)
if (WIN32)

View File

@@ -28,7 +28,11 @@
#include <modules/globebrowsing/src/dashboarditemglobelocation.h>
#include <modules/globebrowsing/src/gdalwrapper.h>
#include <modules/globebrowsing/src/geodeticpatch.h>
#include <modules/globebrowsing/src/globelabelscomponent.h>
#include <modules/globebrowsing/src/globetranslation.h>
#include <modules/globebrowsing/src/layer.h>
#include <modules/globebrowsing/src/layeradjustment.h>
#include <modules/globebrowsing/src/layermanager.h>
#include <modules/globebrowsing/src/memoryawaretilecache.h>
#include <modules/globebrowsing/src/tileprovider.h>
#include <openspace/interaction/navigationhandler.h>
@@ -38,6 +42,7 @@
#include <openspace/util/factorymanager.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/fmt.h>
#include <ghoul/misc/templatefactory.h>
#include <ghoul/misc/assert.h>
#include <ghoul/systemcapabilities/generalcapabilitiescomponent.h>
@@ -100,6 +105,14 @@ namespace {
"The maximum size of the MemoryAwareTileCache, on the CPU and GPU."
};
#ifdef OPENSPACE_MODULE_GLOBEBROWSING_INSTRUMENTATION
constexpr const openspace::properties::Property::PropertyInfo InstrumentationInfo = {
"SaveInstrumentationInfo",
"Save Instrumentation Info",
"If enabled, the instrumentation data is saved to disk at the end of the frame."
};
#endif // OPENSPACE_MODULE_GLOBEBROWSING_INSTRUMENTATION
openspace::GlobeBrowsingModule::Capabilities
parseSubDatasets(char** subDatasets, int nSubdatasets)
@@ -162,12 +175,24 @@ GlobeBrowsingModule::GlobeBrowsingModule()
, _wmsCacheLocation(WMSCacheLocationInfo, "${BASE}/cache_gdal")
, _wmsCacheSizeMB(WMSCacheSizeInfo, 1024)
, _tileCacheSizeMB(TileCacheSizeInfo, 1024)
#ifdef OPENSPACE_MODULE_GLOBEBROWSING_INSTRUMENTATION
, _saveInstrumentation(InstrumentationInfo, false)
#endif // OPENSPACE_MODULE_GLOBEBROWSING_INSTRUMENTATION
{
addProperty(_wmsCacheEnabled);
addProperty(_offlineMode);
addProperty(_wmsCacheLocation);
addProperty(_wmsCacheSizeMB);
addProperty(_tileCacheSizeMB);
#ifdef OPENSPACE_MODULE_GLOBEBROWSING_INSTRUMENTATION
_saveInstrumentation.onChange([&]() {
if (_saveInstrumentation) {
_frameInfo.lastSavedFrame = global::renderEngine.frameNumber();
}
});
addProperty(_saveInstrumentation);
#endif // OPENSPACE_MODULE_GLOBEBROWSING_INSTRUMENTATION
}
void GlobeBrowsingModule::internalInitialize(const ghoul::Dictionary& dict) {
@@ -234,6 +259,43 @@ void GlobeBrowsingModule::internalInitialize(const ghoul::Dictionary& dict) {
// Render
global::callback::render.emplace_back([&]() { _tileCache->update(); });
// Postdraw
#ifdef OPENSPACE_MODULE_GLOBEBROWSING_INSTRUMENTATION
global::callback::postDraw.emplace_back([&]() {
// >= as we might have multiple frames per postDraw call (stereo rendering,
// fisheye, etc)
const uint16_t next = _frameInfo.lastSavedFrame + _frameInfo.saveEveryNthFrame;
const bool shouldSave = _saveInstrumentation &&
global::renderEngine.frameNumber() >= next;
if (shouldSave) {
using K = const globebrowsing::RenderableGlobe*;
using V = std::vector<FrameInfo>;
for (const std::pair<K, V>& i : _frameInfo.frames) {
std::string filename = fmt::format(
"_inst_globebrowsing_{}_{}_{}.txt",
i.first->owner()->identifier(), // Owner of the renderable has a name
_frameInfo.lastSavedFrame,
_frameInfo.saveEveryNthFrame
);
std::ofstream file(absPath("${BIN}/" + filename));
for (const FrameInfo& f : i.second) {
std::string line = fmt::format(
"{}\t{}\t{}\t{}",
f.iFrame,
f.nTilesRenderedLocal,
f.nTilesRenderedGlobal,
f.nTilesUploaded
);
file << line << '\n';
}
}
_frameInfo.frames.clear();
_frameInfo.lastSavedFrame = global::renderEngine.frameNumber();
}
});
#endif // OPENSPACE_MODULE_GLOBEBROWSING_INSTRUMENTATION
// Deinitialize
global::callback::deinitialize.emplace_back([&]() { GdalWrapper::destroy(); });
@@ -327,6 +389,27 @@ scripting::LuaLibrary GlobeBrowsingModule::luaLibrary() const {
"any of " + listLayerGroups + ". The third argument is the dictionary"
"defining the layer."
},
{
"getLayers",
&globebrowsing::luascriptfunctions::getLayers,
{},
"string, string",
"Returns the list of layers for the scene graph node specified in the first "
"parameter. The second parameter specifies which layer type should be "
"queried."
},
{
"moveLayer",
&globebrowsing::luascriptfunctions::moveLayer,
{},
"string, string, number, number",
"Rearranges the order of a single layer in a scene graph node. The first "
"parameter specifies the scene graph node, the second parameter specifies "
"the name of the layer group, the third parameter is the original position "
"of the layer that should be moved and the last parameter is the new "
"position. The new position may be -1 to place the layer at the top or any "
"large number bigger than the number of layers to place it at the bottom."
},
{
"goToChunk",
&globebrowsing::luascriptfunctions::goToChunk,
@@ -338,16 +421,24 @@ scripting::LuaLibrary GlobeBrowsingModule::luaLibrary() const {
"goToGeo",
&globebrowsing::luascriptfunctions::goToGeo,
{},
"number, number, number",
"Go to geographic coordinates latitude and longitude"
"[string], number, number, [number]",
"Go to geographic coordinates of a globe. The first (optional) argument is "
"the identifier of a scene graph node that has a RenderableGlobe attached. "
"If no globe is passed in, the current anchor will be used. "
"The second argument is latitude and the third is longitude (degrees). "
"North and East are expressed as positive angles, while South and West are "
"negative. The optional fourh argument is the altitude in meters. If no "
"altitude is provided, the altitude will be kept as the current distance to "
"the surface of the specified globe."
},
{
"getGeoPosition",
&globebrowsing::luascriptfunctions::getGeoPosition,
{},
"name, latitude, longitude, altitude",
"Returns the specified surface position on the globe as three floating point "
"values"
"string, number, number, number",
"Returns the specified surface position on the globe identified by the first "
"argument, as three floating point values - latitude, longitude and altitude "
"(degrees and meters)."
},
{
"getGeoPositionForCamera",
@@ -355,7 +446,7 @@ scripting::LuaLibrary GlobeBrowsingModule::luaLibrary() const {
{},
"void",
"Get geographic coordinates of the camera poosition in latitude, "
"longitude, and altitude"
"longitude, and altitude (degrees and meters)."
},
{
"loadWMSCapabilities",
@@ -395,29 +486,38 @@ scripting::LuaLibrary GlobeBrowsingModule::luaLibrary() const {
return res;
}
void GlobeBrowsingModule::goToChunk(int x, int y, int level) {
Camera* cam = global::navigationHandler.camera();
goToChunk(*cam, globebrowsing::TileIndex(x,y,level), glm::vec2(0.5f, 0.5f), true);
std::vector<documentation::Documentation> GlobeBrowsingModule::documentations() const {
return {
globebrowsing::Layer::Documentation(),
globebrowsing::LayerAdjustment::Documentation(),
globebrowsing::LayerManager::Documentation(),
GlobeLabelsComponent::Documentation()
};
}
void GlobeBrowsingModule::goToGeo(double latitude, double longitude) {
void GlobeBrowsingModule::goToChunk(const globebrowsing::RenderableGlobe& globe,
int x, int y, int level)
{
goToChunk(globe, globebrowsing::TileIndex(x, y, level), glm::vec2(0.5f, 0.5f), true);
}
void GlobeBrowsingModule::goToGeo(const globebrowsing::RenderableGlobe& globe,
double latitude, double longitude)
{
using namespace globebrowsing;
Camera* cam = global::navigationHandler.camera();
goToGeodetic2(
*cam,
globe,
Geodetic2{ glm::radians(latitude), glm::radians(longitude) },
true
);
}
void GlobeBrowsingModule::goToGeo(double latitude, double longitude,
double altitude)
void GlobeBrowsingModule::goToGeo(const globebrowsing::RenderableGlobe& globe,
double latitude, double longitude, double altitude)
{
using namespace globebrowsing;
Camera* cam = global::navigationHandler.camera();
goToGeodetic3(
*cam,
globe,
{
Geodetic2{ glm::radians(latitude), glm::radians(longitude) },
altitude
@@ -437,32 +537,15 @@ glm::vec3 GlobeBrowsingModule::cartesianCoordinatesFromGeo(
altitude
};
const glm::dvec3 positionModelSpace = globe.ellipsoid().cartesianPosition(pos);
//glm::dmat4 modelTransform = globe.modelTransform();
//glm::dvec3 positionWorldSpace = glm::dvec3(modelTransform *
//glm::dvec4(positionModelSpace, 1.0));
return glm::vec3(positionModelSpace);
return glm::vec3(globe.ellipsoid().cartesianPosition(pos));
}
void GlobeBrowsingModule::goToChunk(Camera& camera, const globebrowsing::TileIndex& ti,
void GlobeBrowsingModule::goToChunk(const globebrowsing::RenderableGlobe& globe,
const globebrowsing::TileIndex& ti,
glm::vec2 uv, bool doResetCameraDirection)
{
using namespace globebrowsing;
const RenderableGlobe* globe = castFocusNodeRenderableToGlobe();
if (!globe) {
LERROR("Focus node must have a RenderableGlobe renderable.");
return;
}
// Camera position in model space
const glm::dvec3 camPos = camera.positionVec3();
const glm::dmat4 inverseModelTransform = glm::inverse(globe->modelTransform());
const glm::dvec3 cameraPositionModelSpace = glm::dvec3(
inverseModelTransform * glm::dvec4(camPos, 1)
);
const GeodeticPatch patch(ti);
const Geodetic2 corner = patch.corner(SOUTH_WEST);
Geodetic2 positionOnPatch = patch.size();
@@ -473,32 +556,50 @@ void GlobeBrowsingModule::goToChunk(Camera& camera, const globebrowsing::TileInd
corner.lon + positionOnPatch.lon
};
const glm::dvec3 positionOnEllipsoid = globe->ellipsoid().geodeticSurfaceProjection(
// Compute altitude
const glm::dvec3 cameraPosition = global::navigationHandler.camera()->positionVec3();
SceneGraphNode* globeSceneGraphNode = dynamic_cast<SceneGraphNode*>(globe.owner());
if (!globeSceneGraphNode) {
LERROR(
"Cannot go to chunk. The renderable is not attached to a scene graph node."
);
return;
}
const glm::dmat4 inverseModelTransform = globeSceneGraphNode->inverseModelTransform();
const glm::dvec3 cameraPositionModelSpace =
glm::dvec3(inverseModelTransform * glm::dvec4(cameraPosition, 1.0));
const SurfacePositionHandle posHandle = globe.calculateSurfacePositionHandle(
cameraPositionModelSpace
);
const double altitude = glm::length(cameraPositionModelSpace - positionOnEllipsoid);
goToGeodetic3(camera, {pointPosition, altitude}, doResetCameraDirection);
const Geodetic2 geo2 = globe.ellipsoid().cartesianToGeodetic2(
posHandle.centerToReferenceSurface
);
const double altitude = glm::length(
cameraPositionModelSpace - posHandle.centerToReferenceSurface
);
goToGeodetic3(globe, { pointPosition, altitude }, doResetCameraDirection);
}
void GlobeBrowsingModule::goToGeodetic2(Camera& camera, globebrowsing::Geodetic2 geo2,
void GlobeBrowsingModule::goToGeodetic2(const globebrowsing::RenderableGlobe& globe,
globebrowsing::Geodetic2 geo2,
bool doResetCameraDirection)
{
using namespace globebrowsing;
const RenderableGlobe* globe = castFocusNodeRenderableToGlobe();
if (!globe) {
LERROR("Focus node must have a RenderableGlobe renderable.");
return;
const glm::dvec3 cameraPosition = global::navigationHandler.camera()->positionVec3();
SceneGraphNode* globeSceneGraphNode = dynamic_cast<SceneGraphNode*>(globe.owner());
if (!globeSceneGraphNode) {
LERROR("Error when going to Geodetic2");
}
interaction::NavigationHandler& nav = global::navigationHandler;
const glm::dvec3 cameraPosition = nav.camera()->positionVec3();
const glm::dmat4 inverseModelTransform =
nav.orbitalNavigator().anchorNode()->inverseModelTransform();
const glm::dmat4 inverseModelTransform = globeSceneGraphNode->inverseModelTransform();
const glm::dvec3 cameraPositionModelSpace =
glm::dvec3(inverseModelTransform * glm::dvec4(cameraPosition, 1.0));
const SurfacePositionHandle posHandle = globe->calculateSurfacePositionHandle(
const SurfacePositionHandle posHandle = globe.calculateSurfacePositionHandle(
cameraPositionModelSpace
);
@@ -506,71 +607,58 @@ void GlobeBrowsingModule::goToGeodetic2(Camera& camera, globebrowsing::Geodetic2
posHandle.referenceSurfaceOutDirection * posHandle.heightToSurface;
const double altitude = glm::length(cameraPositionModelSpace - centerToActualSurface);
goToGeodetic3(camera, { geo2, altitude }, doResetCameraDirection);
goToGeodetic3(globe, { geo2, altitude }, doResetCameraDirection);
}
void GlobeBrowsingModule::goToGeodetic3(Camera& camera, globebrowsing::Geodetic3 geo3,
void GlobeBrowsingModule::goToGeodetic3(const globebrowsing::RenderableGlobe& globe,
globebrowsing::Geodetic3 geo3,
bool doResetCameraDirection)
{
using namespace globebrowsing;
const glm::dvec3 positionModelSpace = globe.ellipsoid().cartesianPosition(geo3);
const RenderableGlobe* globe = castFocusNodeRenderableToGlobe();
if (!globe) {
LERROR("Focus node must have a RenderableGlobe renderable.");
return;
}
const glm::dvec3 positionModelSpace = globe->ellipsoid().cartesianPosition(geo3);
const glm::dmat4 modelTransform = globe->modelTransform();
const glm::dvec3 positionWorldSpace = glm::dvec3(modelTransform *
glm::dvec4(positionModelSpace, 1.0));
camera.setPositionVec3(positionWorldSpace);
const glm::dvec3 slightlyNorth = globe.ellipsoid().cartesianSurfacePosition(
Geodetic2{ geo3.geodetic2.lat + 0.001, geo3.geodetic2.lon }
);
if (doResetCameraDirection) {
resetCameraDirection(camera, geo3.geodetic2);
}
interaction::NavigationHandler::NavigationState state;
state.anchor = globe.owner()->identifier();
state.referenceFrame = globe.owner()->identifier();
state.position = positionModelSpace;
state.up = slightlyNorth;
global::navigationHandler.setNavigationStateNextFrame(state);
}
void GlobeBrowsingModule::resetCameraDirection(Camera& camera,
globebrowsing::Geodetic2 geo2)
glm::dquat GlobeBrowsingModule::lookDownCameraRotation(
const globebrowsing::RenderableGlobe& globe,
glm::dvec3 cameraModelSpace,
globebrowsing::Geodetic2 geo2)
{
using namespace globebrowsing;
const RenderableGlobe* globe = castFocusNodeRenderableToGlobe();
if (!globe) {
LERROR("Focus node must have a RenderableGlobe renderable.");
return;
}
// Camera is described in world space
const glm::dmat4 modelTransform = globe->modelTransform();
const glm::dmat4 modelTransform = globe.modelTransform();
// Lookup vector
const glm::dvec3 positionModelSpace = globe->ellipsoid().cartesianSurfacePosition(
const glm::dvec3 positionModelSpace = globe.ellipsoid().cartesianSurfacePosition(
geo2
);
const glm::dvec3 slightlyNorth = globe->ellipsoid().cartesianSurfacePosition(
const glm::dvec3 slightlyNorth = globe.ellipsoid().cartesianSurfacePosition(
Geodetic2{ geo2.lat + 0.001, geo2.lon }
);
const glm::dvec3 lookUpModelSpace = glm::normalize(
slightlyNorth - positionModelSpace
);
const glm::dvec3 lookUpWorldSpace = glm::dmat3(modelTransform) * lookUpModelSpace;
// Lookat vector
const glm::dvec3 lookAtWorldSpace = glm::dvec3(
modelTransform * glm::dvec4(positionModelSpace, 1.0)
);
// Eye position
const glm::dvec3 eye = camera.positionVec3();
// Matrix
const glm::dmat4 lookAtMatrix = glm::lookAt(eye, lookAtWorldSpace, lookUpWorldSpace);
const glm::dmat4 lookAtMatrix =
glm::lookAt(cameraModelSpace, positionModelSpace, lookUpModelSpace);
// Set rotation
const glm::dquat rotation = glm::quat_cast(inverse(lookAtMatrix));
camera.setRotation(rotation);
return rotation;
}
const globebrowsing::RenderableGlobe*
@@ -732,5 +820,27 @@ uint64_t GlobeBrowsingModule::wmsCacheSize() const {
return size * 1024 * 1024;
}
#ifdef OPENSPACE_MODULE_GLOBEBROWSING_INSTRUMENTATION
void GlobeBrowsingModule::addFrameInfo(globebrowsing::RenderableGlobe* globe,
uint32_t nTilesRenderedLocal,
uint32_t nTilesRenderedGlobal,
uint32_t nTilesUploaded)
{
auto it = _frameInfo.frames.find(globe);
if (it == _frameInfo.frames.end()) {
_frameInfo.frames[globe] = std::vector<FrameInfo>();
_frameInfo.frames[globe].reserve(_frameInfo.saveEveryNthFrame);
}
else {
it->second.push_back({
global::renderEngine.frameNumber(),
nTilesRenderedLocal,
nTilesRenderedGlobal,
nTilesUploaded
});
}
}
#endif // OPENSPACE_MODULE_GLOBEBROWSING_INSTRUMENTATION
} // namespace openspace

View File

@@ -53,15 +53,20 @@ public:
GlobeBrowsingModule();
void goToChunk(int x, int y, int level);
void goToGeo(double latitude, double longitude);
void goToGeo(double latitude, double longitude, double altitude);
void goToChunk(const globebrowsing::RenderableGlobe& globe, int x, int y, int level);
void goToGeo(const globebrowsing::RenderableGlobe& globe,
double latitude, double longitude);
void goToGeo(const globebrowsing::RenderableGlobe& globe,
double latitude, double longitude, double altitude);
glm::vec3 cartesianCoordinatesFromGeo(const globebrowsing::RenderableGlobe& globe,
double latitude, double longitude, double altitude);
globebrowsing::cache::MemoryAwareTileCache* tileCache();
scripting::LuaLibrary luaLibrary() const override;
std::vector<documentation::Documentation> documentations() const override;
const globebrowsing::RenderableGlobe* castFocusNodeRenderableToGlobe();
struct Layer {
@@ -90,17 +95,26 @@ public:
std::string wmsCacheLocation() const;
uint64_t wmsCacheSize() const; // bytes
#ifdef OPENSPACE_MODULE_GLOBEBROWSING_INSTRUMENTATION
void addFrameInfo(globebrowsing::RenderableGlobe* globe, uint32_t nTilesRenderedLocal,
uint32_t nTilesRenderedGlobal, uint32_t nTilesUploaded);
#endif // OPENSPACE_MODULE_GLOBEBROWSING_INSTRUMENTATION
protected:
void internalInitialize(const ghoul::Dictionary&) override;
private:
void goToChunk(Camera& camera, const globebrowsing::TileIndex& ti, glm::vec2 uv,
bool doResetCameraDirection);
void goToGeodetic2(Camera& camera, globebrowsing::Geodetic2 geo2,
bool doResetCameraDirection);
void goToGeodetic3(Camera& camera, globebrowsing::Geodetic3 geo3,
bool doResetCameraDirection);
void resetCameraDirection(Camera& camera, globebrowsing::Geodetic2 geo2);
void goToChunk(const globebrowsing::RenderableGlobe& globe,
const globebrowsing::TileIndex& ti, glm::vec2 uv, bool doResetCameraDirection);
void goToGeodetic2(const globebrowsing::RenderableGlobe& globe,
globebrowsing::Geodetic2 geo2, bool doResetCameraDirection);
void goToGeodetic3(const globebrowsing::RenderableGlobe& globe,
globebrowsing::Geodetic3 geo3, bool doResetCameraDirection);
glm::dquat lookDownCameraRotation(const globebrowsing::RenderableGlobe& globe,
glm::dvec3 cameraPositionModelSpace, globebrowsing::Geodetic2 geo2);
/**
\return a comma separated list of layer group names.
@@ -127,6 +141,26 @@ private:
std::map<std::string, Capabilities> _capabilitiesMap;
std::multimap<std::string, UrlInfo> _urlList;
#ifdef OPENSPACE_MODULE_GLOBEBROWSING_INSTRUMENTATION
struct FrameInfo {
uint64_t iFrame = 0;
uint32_t nTilesRenderedLocal = 0;
uint32_t nTilesRenderedGlobal = 0;
uint32_t nTilesUploaded = 0;
};
struct {
std::unordered_map<
globebrowsing::RenderableGlobe*,
std::vector<FrameInfo>
> frames;
uint64_t lastSavedFrame = 0;
const uint16_t saveEveryNthFrame = 2048;
} _frameInfo;
properties::BoolProperty _saveInstrumentation;
#endif // OPENSPACE_MODULE_GLOBEBROWSING_INSTRUMENTATION
};
} // namespace openspace

View File

@@ -25,6 +25,7 @@
#include <modules/globebrowsing/src/renderableglobe.h>
#include <modules/globebrowsing/src/layer.h>
#include <modules/globebrowsing/src/layergroup.h>
#include <modules/globebrowsing/src/layermanager.h>
#include <openspace/engine/globals.h>
#include <openspace/engine/moduleengine.h>
@@ -127,32 +128,151 @@ int deleteLayer(lua_State* L) {
return 0;
}
int getLayers(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 2, "lua::getLayers");
const std::string& globeIdentifier = ghoul::lua::value<std::string>(L, 1);
const std::string& layer = ghoul::lua::value<std::string>(L, 2);
lua_pop(L, 2);
SceneGraphNode* n = sceneGraphNode(globeIdentifier);
if (!n) {
return ghoul::lua::luaError(L, "Unknown globe name: " + globeIdentifier);
}
const RenderableGlobe* globe = dynamic_cast<const RenderableGlobe*>(n->renderable());
if (!globe) {
return ghoul::lua::luaError(L, "Identifier must be a RenderableGlobe");
}
globebrowsing::layergroupid::GroupID group =
ghoul::from_string<globebrowsing::layergroupid::GroupID>(layer);
if (group == globebrowsing::layergroupid::GroupID::Unknown) {
return ghoul::lua::luaError(L, "Unknown layer groupd: " + layer);
}
const globebrowsing::LayerGroup& lg = globe->layerManager().layerGroup(group);
std::vector<globebrowsing::Layer*> layers = lg.layers();
lua_newtable(L);
int key = 1;
for (globebrowsing::Layer* l : layers) {
ghoul::lua::push(L, key, l->identifier());
lua_settable(L, -3);
key++;
}
return 1;
}
int moveLayer(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 4, "lua::moveLayer");
const std::string& globeIdentifier = ghoul::lua::value<std::string>(L, 1);
const std::string& layer = ghoul::lua::value<std::string>(L, 2);
int oldPosition = ghoul::lua::value<int>(L, 3);
int newPosition = ghoul::lua::value<int>(L, 4);
lua_pop(L, 4);
if (oldPosition == newPosition) {
return 0;
}
SceneGraphNode* n = sceneGraphNode(globeIdentifier);
if (!n) {
return ghoul::lua::luaError(L, "Unknown globe name: " + globeIdentifier);
}
RenderableGlobe* globe = dynamic_cast<RenderableGlobe*>(n->renderable());
if (!globe) {
return ghoul::lua::luaError(L, "Identifier must be a RenderableGlobe");
}
globebrowsing::layergroupid::GroupID group =
ghoul::from_string<globebrowsing::layergroupid::GroupID>(layer);
if (group == globebrowsing::layergroupid::GroupID::Unknown) {
return ghoul::lua::luaError(L, "Unknown layer groupd: " + layer);
}
globebrowsing::LayerGroup& lg = globe->layerManager().layerGroup(group);
lg.moveLayers(oldPosition, newPosition);
return 0;
}
int goToChunk(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 3, "lua::goToChunk");
ghoul::lua::checkArgumentsAndThrow(L, 4, "lua::goToChunk");
const int x = ghoul::lua::value<int>(L, 1);
const int y = ghoul::lua::value<int>(L, 2);
const int level = ghoul::lua::value<int>(L, 3);
lua_pop(L, 3);
const std::string& globeIdentifier = ghoul::lua::value<std::string>(L, 1);
const int x = ghoul::lua::value<int>(L, 2);
const int y = ghoul::lua::value<int>(L, 3);
const int level = ghoul::lua::value<int>(L, 4);
lua_pop(L, 4);
global::moduleEngine.module<GlobeBrowsingModule>()->goToChunk(x, y, level);
SceneGraphNode* n = sceneGraphNode(globeIdentifier);
if (!n) {
return ghoul::lua::luaError(L, "Unknown globe name: " + globeIdentifier);
}
const RenderableGlobe* globe = dynamic_cast<const RenderableGlobe*>(n->renderable());
if (!globe) {
return ghoul::lua::luaError(L, "Identifier must be a RenderableGlobe");
}
global::moduleEngine.module<GlobeBrowsingModule>()->goToChunk(*globe, x, y, level);
ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack");
return 0;
}
int goToGeo(lua_State* L) {
const int nArguments = ghoul::lua::checkArgumentsAndThrow(L, 2, 3, "lua::goToGeo");
int nArguments = ghoul::lua::checkArgumentsAndThrow(L, { 2, 4 }, "lua::goToGeo");
const double latitude = ghoul::lua::value<double>(L, 1);
const double longitude = ghoul::lua::value<double>(L, 2);
// Check if the user provided a Scene graph node identifier as the first argument.
// lua_isstring returns true for both numbers and strings, so better use !lua_isnumber
const bool providedGlobeIdentifier = !lua_isnumber(L, 1);
const int parameterOffset = providedGlobeIdentifier ? 1 : 0;
if (nArguments == 2) {
global::moduleEngine.module<GlobeBrowsingModule>()->goToGeo(latitude, longitude);
const SceneGraphNode* n;
if (providedGlobeIdentifier) {
const std::string& globeIdentifier = ghoul::lua::value<std::string>(L, 1);
n = sceneGraphNode(globeIdentifier);
if (!n) {
return ghoul::lua::luaError(L, "Unknown globe name: " + globeIdentifier);
}
}
else if (nArguments == 3) {
const double altitude = ghoul::lua::value<double>(L, 3);
else {
n = global::navigationHandler.orbitalNavigator().anchorNode();
if (!n) {
return ghoul::lua::luaError(L, "No anchor node is set.");
}
}
const double latitude = ghoul::lua::value<double>(L, parameterOffset + 1);
const double longitude = ghoul::lua::value<double>(L, parameterOffset + 2);
const RenderableGlobe* globe = dynamic_cast<const RenderableGlobe*>(n->renderable());
if (!globe) {
if (providedGlobeIdentifier) {
return ghoul::lua::luaError(L, "Identifier must be a RenderableGlobe");
}
else {
return ghoul::lua::luaError(L,
"Current anchor node is not a RenderableGlobe. "
"Either change the anchor to a globe, or specify a globe identifier "
"as the first argument"
);
}
}
if (nArguments == parameterOffset + 2) {
global::moduleEngine.module<GlobeBrowsingModule>()->goToGeo(
*globe, latitude, longitude
);
}
else if (nArguments == parameterOffset + 3) {
const double altitude = ghoul::lua::value<double>(L, parameterOffset + 3);
global::moduleEngine.module<GlobeBrowsingModule>()->goToGeo(
*globe,
latitude,
longitude,
altitude
@@ -168,19 +288,19 @@ int goToGeo(lua_State* L) {
int getGeoPosition(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 4, "lua::getGeoPosition");
const std::string& name = ghoul::lua::value<std::string>(L, 1);
const std::string& globeIdentifier = ghoul::lua::value<std::string>(L, 1);
const double latitude = ghoul::lua::value<double>(L, 2);
const double longitude = ghoul::lua::value<double>(L, 3);
const double altitude = ghoul::lua::value<double>(L, 4);
lua_pop(L, 4);
SceneGraphNode* n = sceneGraphNode(name);
SceneGraphNode* n = sceneGraphNode(globeIdentifier);
if (!n) {
return ghoul::lua::luaError(L, "Unknown globe name: " + name);
return ghoul::lua::luaError(L, "Unknown globe identifier: " + globeIdentifier);
}
const RenderableGlobe* globe = dynamic_cast<const RenderableGlobe*>(n->renderable());
if (!globe) {
return ghoul::lua::luaError(L, "Name must be a RenderableGlobe");
return ghoul::lua::luaError(L, "Identifier must be a RenderableGlobe");
}
GlobeBrowsingModule& mod = *(global::moduleEngine.module<GlobeBrowsingModule>());

View File

@@ -173,9 +173,16 @@ void DashboardItemGlobeLocation::render(glm::vec2& penPosition) {
bool isEast = lon > 0.0;
lon = std::abs(lon);
const double altitude = glm::length(
double altitude = glm::length(
cameraPositionModelSpace - posHandle.centerToReferenceSurface
);
if (glm::length(cameraPositionModelSpace) <
glm::length(posHandle.centerToReferenceSurface))
{
altitude = -altitude;
}
std::pair<double, std::string> dist = simplifyDistance(altitude);
penPosition.y -= _font->height();

View File

@@ -45,11 +45,10 @@
#include <locale>
namespace {
constexpr const char* KeyLabels = "Labels";
constexpr const char* KeyLabelsFileName = "FileName";
constexpr const char* _loggerCat = "GlobeLabels";
constexpr const char* KeyLabelsFileName = "FileName";
constexpr const double LabelFadeRangeConst = 1500.0;
constexpr const double RangeAngularCoefConst = 0.8;
constexpr const float MinTransparencyValueConst = 0.009f;
@@ -671,19 +670,10 @@ void GlobeLabelsComponent::renderLabels(const RenderData& data,
float distToCamera,
float fadeInVariable
) {
constexpr double DIST_EPS = 6000.0;
constexpr double SIN_EPS = 0.001;
glm::vec4 textColor = _labelsColor;
textColor.a *= fadeInVariable;
glm::dmat4 invMP = glm::inverse(_globe->modelTransform());
glm::dmat4 invCombinedView = glm::inverse(data.camera.combinedViewMatrix());
glm::dvec4 cameraPosWorld = invCombinedView * glm::dvec4(0.0, 0.0, 0.0, 1.0);
glm::dvec3 cameraPosObj = glm::dvec3(invMP * cameraPosWorld);
glm::dvec4 cameraUpVecWorld = glm::dvec4(data.camera.lookUpVectorWorldSpace(), 0.0);
glm::dvec3 cameraLookUpObj = glm::dvec3(invMP * cameraUpVecWorld);
glm::dmat4 VP = glm::dmat4(data.camera.sgctInternal.projectionMatrix()) *
data.camera.combinedViewMatrix();
@@ -799,7 +789,7 @@ bool GlobeLabelsComponent::isLabelInFrustum(const glm::dmat4& MVMatrix,
double bottomDistance = MVMatrix[3][3] + MVMatrix[3][1];
double topDistance = MVMatrix[3][3] - MVMatrix[3][1];
double nearDistance = MVMatrix[3][3] + MVMatrix[3][2];
double farDistance = MVMatrix[3][3] - MVMatrix[3][2];
// double farDistance = MVMatrix[3][3] - MVMatrix[3][2];
// Normalize Planes
const double invMagLeft = 1.0 / glm::length(leftNormal);
@@ -824,7 +814,7 @@ bool GlobeLabelsComponent::isLabelInFrustum(const glm::dmat4& MVMatrix,
const double invMagFar = 1.0 / glm::length(farNormal);
farNormal *= invMagFar;
farDistance *= invMagFar;
// farDistance *= invMagFar;
constexpr const float Radius = 1.0;

View File

@@ -58,20 +58,21 @@ namespace {
"globe. The default value is 0.0"
};
constexpr openspace::properties::Property::PropertyInfo FixedAltitudeInfo = {
"FixedAltitude",
"Fixed Altitude",
"The altitude in meters of the location on the globe's surface. This value is "
"used if the 'UseFixedAltitude' property is 'true'. The default value is 10000km."
constexpr openspace::properties::Property::PropertyInfo AltitudeInfo = {
"Altitude",
"Altitude",
"The altitude in meters. "
"If the 'UseHeightmap' property is 'true', this is an offset from the actual "
"surface of the globe. If not, this is an offset from the reference ellipsoid."
"The default value is 0.0"
};
constexpr openspace::properties::Property::PropertyInfo UseFixedAltitudeInfo = {
"UseFixedAltitude",
"Use Fixed Altitude",
"If this value is 'true', the altitude specified in 'FixedAltitude' is used for "
"this translation. If it is 'false', the altitude will be computed based on the "
"height information that is available about the globe to which this translation "
"is attached. The default value is 'true'."
constexpr openspace::properties::Property::PropertyInfo UseHeightmapInfo = {
"UseHeightmap",
"Use Heightmap",
"If this value is 'true', the altitude specified in 'Altitude' will be treated "
"as an offset from the heightmap. Otherwise, it will be an offset from the "
"globe's reference ellipsoid. The default value is 'false'."
};
} // namespace
@@ -81,8 +82,8 @@ documentation::Documentation GlobeTranslation::Documentation() {
using namespace openspace::documentation;
return {
"Spice Translation",
"space_translation_spicetranslation",
"Globe Translation",
"space_translation_globetranslation",
{
{
"Type",
@@ -110,16 +111,16 @@ documentation::Documentation GlobeTranslation::Documentation() {
LatitudeInfo.description,
},
{
FixedAltitudeInfo.identifier,
AltitudeInfo.identifier,
new DoubleVerifier,
Optional::Yes,
FixedAltitudeInfo.description
AltitudeInfo.description
},
{
UseFixedAltitudeInfo.identifier,
UseHeightmapInfo.identifier,
new BoolVerifier,
Optional::Yes,
UseFixedAltitudeInfo.description
UseHeightmapInfo.description
}
}
};
@@ -129,8 +130,8 @@ GlobeTranslation::GlobeTranslation(const ghoul::Dictionary& dictionary)
: _globe(GlobeInfo)
, _longitude(LongitudeInfo, 0.0, -180.0, 180.0)
, _latitude(LatitudeInfo, 0.0, -90.0, 90.0)
, _fixedAltitude(FixedAltitudeInfo, 1e8, 0.0, 1e12)
, _useFixedAltitude(UseFixedAltitudeInfo, false)
, _altitude(AltitudeInfo, 0.0, 0.0, 1e12)
, _useHeightmap(UseHeightmapInfo, false)
{
documentation::testSpecificationAndThrow(
Documentation(),
@@ -145,11 +146,11 @@ GlobeTranslation::GlobeTranslation(const ghoul::Dictionary& dictionary)
if (dictionary.hasKey(LatitudeInfo.identifier)) {
_latitude = dictionary.value<double>(LatitudeInfo.identifier);
}
if (dictionary.hasKey(FixedAltitudeInfo.identifier)) {
_fixedAltitude = dictionary.value<double>(FixedAltitudeInfo.identifier);
if (dictionary.hasKey(AltitudeInfo.identifier)) {
_altitude = dictionary.value<double>(AltitudeInfo.identifier);
}
if (dictionary.hasKey(UseFixedAltitudeInfo.identifier)) {
_useFixedAltitude = dictionary.value<bool>(UseFixedAltitudeInfo.identifier);
if (dictionary.hasKey(UseHeightmapInfo.identifier)) {
_useHeightmap = dictionary.value<bool>(UseHeightmapInfo.identifier);
}
_globe.onChange([this]() {
@@ -159,8 +160,13 @@ GlobeTranslation::GlobeTranslation(const ghoul::Dictionary& dictionary)
_longitude.onChange([this]() { _positionIsDirty = true; });
_latitude.onChange([this]() { _positionIsDirty = true; });
_fixedAltitude.onChange([this]() { _positionIsDirty = true; });
_useFixedAltitude.onChange([this]() { _positionIsDirty = true; });
_altitude.onChange([this]() { _positionIsDirty = true; });
_useHeightmap.onChange([this]() { _positionIsDirty = true; });
addProperty(_longitude);
addProperty(_latitude);
addProperty(_altitude);
addProperty(_useHeightmap);
}
void GlobeTranslation::fillAttachedNode() {
@@ -173,8 +179,10 @@ void GlobeTranslation::fillAttachedNode() {
"GlobeTranslation",
"Could not set attached node as it does not have a RenderableGlobe"
);
// Reset the globe name to it's previous name
_globe = _attachedNode->identifier();
if (_attachedNode) {
// Reset the globe name to it's previous name
_globe = _attachedNode->identifier();
}
}
}
@@ -188,8 +196,8 @@ glm::dvec3 GlobeTranslation::position(const UpdateData&) const {
_positionIsDirty = true;
}
if (!_useFixedAltitude) {
// If we don't use the fixed altitude, we have to compute the height every frame
if (_useHeightmap) {
// If we use the heightmap, we have to compute the height every frame
_positionIsDirty = true;
}
@@ -197,33 +205,35 @@ glm::dvec3 GlobeTranslation::position(const UpdateData&) const {
return _position;
}
GlobeBrowsingModule& mod = *(global::moduleEngine.module<GlobeBrowsingModule>());
glm::vec3 pos = mod.cartesianCoordinatesFromGeo(
*_attachedNode,
_latitude,
_longitude,
_fixedAltitude
);
if (_useFixedAltitude) {
_position = glm::dvec3(pos);
_positionIsDirty = true;
return _position;
}
else {
SurfacePositionHandle h = _attachedNode->calculateSurfacePositionHandle(pos);
pos = mod.cartesianCoordinatesFromGeo(
if (_useHeightmap) {
glm::vec3 groundPos = mod.cartesianCoordinatesFromGeo(
*_attachedNode,
_latitude,
_longitude,
h.heightToSurface
0.0
);
_position = glm::dvec3(pos);
SurfacePositionHandle h =
_attachedNode->calculateSurfacePositionHandle(groundPos);
_position = mod.cartesianCoordinatesFromGeo(
*_attachedNode,
_latitude,
_longitude,
h.heightToSurface + _altitude
);
return _position;
}
else {
_position = mod.cartesianCoordinatesFromGeo(
*_attachedNode,
_latitude,
_longitude,
_altitude
);
_positionIsDirty = false;
return _position;
}
}

View File

@@ -49,8 +49,8 @@ private:
properties::StringProperty _globe;
properties::DoubleProperty _longitude;
properties::DoubleProperty _latitude;
properties::DoubleProperty _fixedAltitude;
properties::BoolProperty _useFixedAltitude;
properties::DoubleProperty _altitude;
properties::BoolProperty _useHeightmap;
RenderableGlobe* _attachedNode = nullptr;

View File

@@ -24,6 +24,8 @@
#include <modules/globebrowsing/src/layer.h>
#include <openspace/documentation/documentation.h>
#include <openspace/documentation/verifier.h>
#include <modules/globebrowsing/src/layergroup.h>
#include <modules/globebrowsing/src/layermanager.h>
#include <modules/globebrowsing/src/tileindex.h>
@@ -93,6 +95,114 @@ namespace {
};
} // namespace
documentation::Documentation Layer::Documentation() {
using namespace documentation;
return {
"Layer",
"globebrowsing_layer",
{
{
KeyIdentifier,
new StringVerifier,
Optional::No,
"The unique identifier for this layer. May not contain '.' or spaces."
},
{
KeyName,
new StringVerifier,
Optional::Yes,
"A human-readable name for the user interface. If this is omitted, the "
"identifier is used instead."
},
{
KeyDesc,
new StringVerifier,
Optional::Yes,
"A human-readable description of the layer to be used in informational "
"texts presented to the user."
},
{
"Type",
new StringInListVerifier({
"DefaultTileLayer", "SingleImageTileLayer", "SizeReferenceTileLayer",
"TemporalTileLayer", "TileIndexTileLayer", "ByIndexTileLayer",
"ByLevelTileLayer", "SolidColor"
}),
Optional::Yes,
"Specifies the type of layer that is to be added. If this value is not "
"specified, the layer is a DefaultTileLayer."
},
{
EnabledInfo.identifier,
new BoolVerifier,
Optional::Yes,
"Determine whether the layer is enabled or not. If this value is not "
"specified, the layer is disabled."
},
{
KeyPadTiles,
new BoolVerifier,
Optional::Yes,
"Determines whether the downloaded tiles should have a padding added to "
"the borders."
},
{
KeySettings,
new TableVerifier({
{
KeyOpacity,
new DoubleInRangeVerifier(0.0, 1.0),
Optional::Yes,
"The opacity value of the layer."
},
{
KeyGamma,
new DoubleVerifier,
Optional::Yes,
"The gamma value that is applied to each pixel of the layer."
},
{
KeyMultiplier,
new DoubleVerifier,
Optional::Yes,
"The multiplicative factor that is applied to each pixel of the "
"layer."
},
{
KeyOffset,
new DoubleVerifier,
Optional::Yes,
"An additive offset that is applied to each pixel of the layer."
}
}),
Optional::Yes,
"Specifies the render settings that should be applied to this layer."
},
{
KeyAdjustment,
new ReferencingVerifier("globebrowsing_layeradjustment"),
Optional::Yes,
""
},
{
BlendModeInfo.identifier,
new StringInListVerifier({
"Normal", "Multiply", "Add", "Subtract", "Color"
}),
Optional::Yes,
"Sets the blend mode of this layer to determine how it interacts with "
"other layers on top of this."
},
{
"Fallback",
new ReferencingVerifier("globebrowsing_layer"),
Optional::Yes,
"If the primary layer creation fails, this layer is used as a fallback"
}
}
};
}
Layer::Layer(layergroupid::GroupID id, const ghoul::Dictionary& layerDict,
LayerGroup& parent)
: properties::PropertyOwner({
@@ -109,13 +219,15 @@ Layer::Layer(layergroupid::GroupID id, const ghoul::Dictionary& layerDict,
, _solidColor(ColorInfo, glm::vec3(1.f), glm::vec3(0.f), glm::vec3(1.f))
, _layerGroupId(id)
{
documentation::testSpecificationAndThrow(Documentation(), layerDict, "Layer");
layergroupid::TypeID typeID;
if (layerDict.hasKeyAndValue<std::string>("Type")) {
const std::string& typeString = layerDict.value<std::string>("Type");
typeID = ghoul::from_string<layergroupid::TypeID>(typeString);
}
else {
typeID = layergroupid::TypeID::DefaultTileLayer;
typeID = layergroupid::TypeID::DefaultTileLayer;
}
if (typeID == layergroupid::TypeID::Unknown) {
throw ghoul::RuntimeError("Unknown layer type!");
@@ -341,9 +453,12 @@ void Layer::onChange(std::function<void(Layer*)> callback) {
_onChangeCallback = std::move(callback);
}
void Layer::update() {
int Layer::update() {
if (_tileProvider) {
tileprovider::update(*_tileProvider);
return tileprovider::update(*_tileProvider);
}
else {
return 0;
}
}

View File

@@ -34,6 +34,8 @@
#include <openspace/properties/optionproperty.h>
#include <openspace/properties/scalar/boolproperty.h>
namespace openspace::documentation { struct Documentation; }
namespace openspace::globebrowsing {
struct LayerGroup;
@@ -64,13 +66,16 @@ public:
void onChange(std::function<void(Layer*)> callback);
void update();
// Return: number of tiles that were updated
int update();
glm::ivec2 tilePixelStartOffset() const;
glm::ivec2 tilePixelSizeDifference() const;
glm::vec2 tileUvToTextureSamplePosition(const TileUvTransform& uvTransform,
const glm::vec2& tileUV, const glm::uvec2& resolution);
static documentation::Documentation Documentation();
private:
void initializeBasedOnType(layergroupid::TypeID typeId, ghoul::Dictionary initDict);
void addVisibleProperties();

View File

@@ -24,6 +24,9 @@
#include <modules/globebrowsing/src/layeradjustment.h>
#include <openspace/documentation/documentation.h>
#include <openspace/documentation/verifier.h>
namespace {
constexpr const char* KeyType = "Type";
constexpr const char* KeyChromaKeyColor = "ChromaKeyColor";
@@ -51,6 +54,35 @@ namespace {
namespace openspace::globebrowsing {
documentation::Documentation LayerAdjustment::Documentation() {
using namespace documentation;
return {
"LayerAdjustment",
"globebrowsing_layeradjustment",
{
{
KeyType,
new StringInListVerifier({ "None", "ChromaKey", "TransferFunction" }),
Optional::Yes,
"Specifies the type of the adjustment that is applied"
},
{
KeyChromaKeyColor,
new DoubleVector3Verifier,
Optional::Yes,
"Specifies the chroma key used when selecting 'ChromaKey' for the 'Type'."
},
{
KeyChromaKeyTolerance,
new DoubleVerifier,
Optional::Yes,
"Specifies the tolerance to match the color to the chroma key when the "
"'ChromaKey' type is selected for the 'Type'."
}
}
};
}
LayerAdjustment::LayerAdjustment()
: properties::PropertyOwner({ "adjustment" })
, _chromaKeyColor(ChromaKeyColorInfo, glm::vec3(0.f), glm::vec3(0.f), glm::vec3(1.f))
@@ -89,6 +121,12 @@ LayerAdjustment::LayerAdjustment()
}
void LayerAdjustment::setValuesFromDictionary(const ghoul::Dictionary& adjustmentDict) {
documentation::testSpecificationAndThrow(
Documentation(),
adjustmentDict,
"LayerAdjustment"
);
if (adjustmentDict.hasKeyAndValue<std::string>(KeyType)) {
std::string dictType = adjustmentDict.value<std::string>(KeyType);
_typeOption = static_cast<int>(

View File

@@ -32,6 +32,8 @@
#include <openspace/properties/scalar/floatproperty.h>
#include <openspace/properties/vector/vec3property.h>
namespace openspace::documentation { struct Documentation; }
namespace openspace::globebrowsing {
namespace tileprovider { struct TileProvider; }
@@ -50,6 +52,8 @@ public:
void onChange(std::function<void(void)> callback);
static documentation::Documentation Documentation();
private:
void addVisibleProperties();

View File

@@ -25,6 +25,7 @@
#include <modules/globebrowsing/src/layergroup.h>
#include <modules/globebrowsing/src/layer.h>
#include <openspace/documentation/documentation.h>
#include <ghoul/logging/logmanager.h>
namespace {
@@ -91,18 +92,29 @@ void LayerGroup::deinitialize() {
}
}
void LayerGroup::update() {
int LayerGroup::update() {
int res = 0;
_activeLayers.clear();
for (const std::unique_ptr<Layer>& layer : _layers) {
if (layer->enabled()) {
layer->update();
res += layer->update();
_activeLayers.push_back(layer.get());
}
}
return res;
}
Layer* LayerGroup::addLayer(const ghoul::Dictionary& layerDict) {
documentation::TestResult res = documentation::testSpecification(
Layer::Documentation(),
layerDict
);
if (!res.success) {
LERROR("Error adding layer. " + ghoul::to_string(res));
}
if (!layerDict.hasKeyAndValue<std::string>("Identifier")) {
LERROR("'Identifier' must be specified for layer.");
return nullptr;
@@ -152,6 +164,33 @@ void LayerGroup::deleteLayer(const std::string& layerName) {
LERROR("Could not find layer " + layerName);
}
void LayerGroup::moveLayers(int oldPosition, int newPosition) {
oldPosition = std::max(0, oldPosition);
newPosition = std::min(newPosition, static_cast<int>(_layers.size()));
// We need to adjust the new position as we first delete the old position, if this
// position is before the new position we have reduced the size of the vector by 1 and
// need to adapt where we want to put the value in
if (oldPosition < newPosition) {
newPosition -= 1;
}
// There are two synchronous vectors that we have to update here. The _layers vector
// is used to determine the order while rendering, the _subowners is the order in
// which the layers are shown in the UI
auto oldPosLayers = _layers.begin() + oldPosition;
std::unique_ptr<Layer> v = std::move(*oldPosLayers);
_layers.erase(oldPosLayers);
auto newPosLayers = _layers.begin() + newPosition;
_layers.insert(newPosLayers, std::move(v));
auto oldPosOwner = _subOwners.begin() + oldPosition;
PropertyOwner* owner = std::move(*oldPosOwner);
_subOwners.erase(oldPosOwner);
auto newPosOwner = _subOwners.begin() + newPosition;
_subOwners.insert(newPosOwner, std::move(owner));
}
std::vector<Layer*> LayerGroup::layers() const {
std::vector<Layer*> res;
res.reserve(_layers.size());

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