mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-02-27 15:29:26 -06:00
Merge branch 'master' into feature/milkyway-galaxy
This commit is contained in:
6
.gitmodules
vendored
6
.gitmodules
vendored
@@ -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
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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
|
||||
|
||||
1
apps/OpenSpace-MinVR/ext/glfw
Submodule
1
apps/OpenSpace-MinVR/ext/glfw
Submodule
Submodule apps/OpenSpace-MinVR/ext/glfw added at 7ef34eb06d
@@ -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 {
|
||||
|
||||
Submodule apps/OpenSpace/ext/sgct updated: 99e5595539...25c8d30bde
@@ -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) {
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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 ()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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 ()
|
||||
|
||||
@@ -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)
|
||||
|
||||
10
data/assets/examples/screenspacebrowser.asset
Normal file
10
data/assets/examples/screenspacebrowser.asset
Normal 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 })
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -14,6 +14,7 @@ local Apollo17Lem = {
|
||||
Globe = moonAsset.Moon.Identifier,
|
||||
Longitude = -329.22833,
|
||||
Latitude = 20.19092,
|
||||
UseHeightmap = true
|
||||
},
|
||||
},
|
||||
GUI = {
|
||||
|
||||
@@ -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
@@ -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)
|
||||
@@ -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)
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
})
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ local carpoGroup = {
|
||||
{
|
||||
Identifier = "Carpo",
|
||||
Parent = {
|
||||
Name = parentIdentifier,
|
||||
Identifier = parentIdentifier,
|
||||
Spice = parentSpice
|
||||
},
|
||||
Spice = "CARPO",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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)
|
||||
|
||||
18
data/assets/util/ipac.asset
Normal file
18
data/assets/util/ipac.asset
Normal 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)
|
||||
21
data/assets/util/static_server.asset
Normal file
21
data/assets/util/static_server.asset
Normal 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)
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
Submodule ext/ghoul updated: cf5b311dda...526b27cb65
22555
ext/json/json.hpp
22555
ext/json/json.hpp
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
54
include/openspace/interaction/scriptcamerastates.h
Normal file
54
include/openspace/interaction/scriptcamerastates.h
Normal 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__
|
||||
@@ -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;
|
||||
|
||||
117
include/openspace/interaction/websocketcamerastates.h
Normal file
117
include/openspace/interaction/websocketcamerastates.h
Normal 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__
|
||||
125
include/openspace/interaction/websocketinputstate.h
Normal file
125
include/openspace/interaction/websocketinputstate.h
Normal 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__
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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})
|
||||
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 };
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
118
modules/base/rotation/timelinerotation.cpp
Normal file
118
modules/base/rotation/timelinerotation.cpp
Normal 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
|
||||
49
modules/base/rotation/timelinerotation.h
Normal file
49
modules/base/rotation/timelinerotation.h
Normal 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__
|
||||
@@ -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;
|
||||
|
||||
|
||||
114
modules/base/translation/timelinetranslation.cpp
Normal file
114
modules/base/translation/timelinetranslation.cpp
Normal 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
|
||||
@@ -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__
|
||||
@@ -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();
|
||||
});
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -771,7 +771,7 @@ void RenderableFieldlinesSequence::definePropertyCallbackFunctions() {
|
||||
});
|
||||
|
||||
_pJumpToStartBtn.onChange([this] {
|
||||
global::timeManager.setTimeNextFrame(_startTimes[0]);
|
||||
global::timeManager.setTimeNextFrame(Time(_startTimes[0]));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <ghoul/fmt.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
|
||||
namespace {
|
||||
constexpr const char* _loggerCat = "FieldlinesState";
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>());
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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>(
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user