Adding methods to add and remove scenegraphnodes from the scenegraph at runtime

This commit is contained in:
Alexander Bock
2016-04-08 13:11:54 +02:00
parent 2acb2cbd92
commit 21276f2cd8
5 changed files with 483 additions and 387 deletions

View File

@@ -25,9 +25,6 @@
#ifndef __SCENEGRAPH_H__
#define __SCENEGRAPH_H__
#include <ghoul/misc/dictionary.h>
#include <unordered_map>
#include <vector>
namespace openspace {

View File

@@ -79,7 +79,7 @@ using namespace ghoul::cmdparser;
namespace {
const std::string _loggerCat = "OpenSpaceEngine";
const std::string _sgctDefaultConfigFile = "${SGCT}/single.xml";
const std::string _defaultCacheLocation = "${BASE_PATH}/cache";
const std::string _defaultCacheLocation = "${BASE_PATH}/cache";
const std::string _sgctConfigArgumentCommand = "-config";
@@ -88,7 +88,7 @@ namespace {
struct {
std::string configurationName;
std::string sgctConfigurationName;
std::string sgctConfigurationName;
std::string sceneName;
} commandlineArgumentPlaceholders;
}
@@ -113,7 +113,7 @@ OpenSpaceEngine::OpenSpaceEngine(std::string programName,
, _parallelConnection(new network::ParallelConnection)
, _windowWrapper(std::move(windowWrapper))
, _globalPropertyNamespace(new properties::PropertyOwner)
, _isMaster(false)
, _isMaster(false)
, _runTime(0.0)
, _syncBuffer(new SyncBuffer(1024))
{
@@ -147,7 +147,7 @@ OpenSpaceEngine::~OpenSpaceEngine() {
_console = nullptr;
_moduleEngine = nullptr;
_gui = nullptr;
_syncBuffer = nullptr;
_syncBuffer = nullptr;
}
OpenSpaceEngine& OpenSpaceEngine::ref() {
@@ -164,18 +164,18 @@ bool OpenSpaceEngine::create(int argc, char** argv,
ghoul::initialize();
// Initialize the LogManager and add the console log as this will be used every time
// and we need a fall back if something goes wrong between here and when we add the
// logs from the configuration file. If the user requested as specific loglevel in the
// configuration file, we will deinitialize this LogManager and reinitialize it later
// with the correct LogLevel
LogManager::initialize(
// Initialize the LogManager and add the console log as this will be used every time
// and we need a fall back if something goes wrong between here and when we add the
// logs from the configuration file. If the user requested as specific loglevel in the
// configuration file, we will deinitialize this LogManager and reinitialize it later
// with the correct LogLevel
LogManager::initialize(
LogManager::LogLevel::Debug,
ghoul::logging::LogManager::ImmediateFlush::Yes
);
LogMgr.addLog(std::make_unique<ConsoleLog>());
LDEBUG("Initialize FileSystem");
LDEBUG("Initialize FileSystem");
#ifdef __APPLE__
ghoul::filesystem::File app(argv[0]);
@@ -184,33 +184,33 @@ bool OpenSpaceEngine::create(int argc, char** argv,
FileSys.setCurrentDirectory(dirName);
#endif
// Sanity check of values
if (argc < 1 || argv == nullptr) {
LFATAL("No arguments were passed to this function");
return false;
}
// Sanity check of values
if (argc < 1 || argv == nullptr) {
LFATAL("No arguments were passed to this function");
return false;
}
// Create other objects
LDEBUG("Creating OpenSpaceEngine");
// Create other objects
LDEBUG("Creating OpenSpaceEngine");
_engine = new OpenSpaceEngine(std::string(argv[0]), std::move(windowWrapper));
// Query modules for commandline arguments
bool gatherSuccess = _engine->gatherCommandlineArguments();
if (!gatherSuccess)
return false;
// Query modules for commandline arguments
bool gatherSuccess = _engine->gatherCommandlineArguments();
if (!gatherSuccess)
return false;
// Parse commandline arguments
// Parse commandline arguments
sgctArguments = *(_engine->_commandlineParser->setCommandLine(argc, argv));
bool showHelp = _engine->_commandlineParser->execute();
bool showHelp = _engine->_commandlineParser->execute();
if (showHelp) {
_engine->_commandlineParser->displayHelp();
return false;
}
// Find configuration
std::string configurationFilePath = commandlineArgumentPlaceholders.configurationName;
if (configurationFilePath.empty()) {
LDEBUG("Finding configuration");
// Find configuration
std::string configurationFilePath = commandlineArgumentPlaceholders.configurationName;
if (configurationFilePath.empty()) {
LDEBUG("Finding configuration");
try {
configurationFilePath =
ConfigurationManager::findConfiguration(configurationFilePath);
@@ -218,12 +218,12 @@ bool OpenSpaceEngine::create(int argc, char** argv,
catch (const ghoul::RuntimeError& e) {
LFATALC(e.component, e.message);
}
}
configurationFilePath = absPath(configurationFilePath);
LINFO("Configuration Path: '" << configurationFilePath << "'");
}
configurationFilePath = absPath(configurationFilePath);
LINFO("Configuration Path: '" << configurationFilePath << "'");
// Loading configuration from disk
LDEBUG("Loading configuration from disk");
// Loading configuration from disk
LDEBUG("Loading configuration from disk");
try {
_engine->configurationManager().loadFromFile(configurationFilePath);
}
@@ -233,55 +233,55 @@ bool OpenSpaceEngine::create(int argc, char** argv,
return false;
}
// Initialize the requested logs from the configuration file
_engine->configureLogging();
// Initialize the requested logs from the configuration file
_engine->configureLogging();
LINFOC("OpenSpace Version",
OPENSPACE_VERSION_MAJOR << "." <<
OPENSPACE_VERSION_MINOR << "." <<
OPENSPACE_VERSION_PATCH << " (" << OPENSPACE_VERSION_STRING << ")");
// Create directories that doesn't exist
auto tokens = FileSys.tokens();
for (const std::string& token : tokens) {
if (!FileSys.directoryExists(token)) {
std::string p = absPath(token);
LDEBUG("Directory '" << p << "' does not exist, creating.");
// Create directories that doesn't exist
auto tokens = FileSys.tokens();
for (const std::string& token : tokens) {
if (!FileSys.directoryExists(token)) {
std::string p = absPath(token);
LDEBUG("Directory '" << p << "' does not exist, creating.");
FileSys.createDirectory(p, ghoul::filesystem::FileSystem::Recursive::Yes);
}
}
}
}
// Register modules
_engine->_moduleEngine->initialize();
// Create the cachemanager
FileSys.createCacheManager(
// Create the cachemanager
FileSys.createCacheManager(
absPath("${" + ConfigurationManager::KeyCache + "}"), CacheVersion
);
_engine->_console->initialize();
_engine->_console->initialize();
// Register the provided shader directories
ghoul::opengl::ShaderPreprocessor::addIncludePath(absPath("${SHADERS}"));
// Register the provided shader directories
ghoul::opengl::ShaderPreprocessor::addIncludePath(absPath("${SHADERS}"));
// Determining SGCT configuration file
LDEBUG("Determining SGCT configuration file");
std::string sgctConfigurationPath = _sgctDefaultConfigFile;
_engine->configurationManager().getValue(
ConfigurationManager::KeyConfigSgct, sgctConfigurationPath);
// Determining SGCT configuration file
LDEBUG("Determining SGCT configuration file");
std::string sgctConfigurationPath = _sgctDefaultConfigFile;
_engine->configurationManager().getValue(
ConfigurationManager::KeyConfigSgct, sgctConfigurationPath);
if (!commandlineArgumentPlaceholders.sgctConfigurationName.empty()) {
LDEBUG("Overwriting SGCT configuration file with commandline argument: " <<
commandlineArgumentPlaceholders.sgctConfigurationName);
sgctConfigurationPath = commandlineArgumentPlaceholders.sgctConfigurationName;
}
if (!commandlineArgumentPlaceholders.sgctConfigurationName.empty()) {
LDEBUG("Overwriting SGCT configuration file with commandline argument: " <<
commandlineArgumentPlaceholders.sgctConfigurationName);
sgctConfigurationPath = commandlineArgumentPlaceholders.sgctConfigurationName;
}
// Prepend the outgoing sgctArguments with the program name
// as well as the configuration file that sgct is supposed to use
sgctArguments.insert(sgctArguments.begin(), argv[0]);
sgctArguments.insert(sgctArguments.begin() + 1, _sgctConfigArgumentCommand);
sgctArguments.insert(sgctArguments.begin() + 2, absPath(sgctConfigurationPath));
// Prepend the outgoing sgctArguments with the program name
// as well as the configuration file that sgct is supposed to use
sgctArguments.insert(sgctArguments.begin(), argv[0]);
sgctArguments.insert(sgctArguments.begin() + 1, _sgctConfigArgumentCommand);
sgctArguments.insert(sgctArguments.begin() + 2, absPath(sgctConfigurationPath));
return true;
return true;
}
void OpenSpaceEngine::destroy() {
@@ -289,30 +289,30 @@ void OpenSpaceEngine::destroy() {
_engine->_console->deinitialize();
_engine->_scriptEngine->deinitialize();
delete _engine;
ghoul::systemcapabilities::SystemCapabilities::deinitialize();
FactoryManager::deinitialize();
Time::deinitialize();
SpiceManager::deinitialize();
delete _engine;
ghoul::systemcapabilities::SystemCapabilities::deinitialize();
FactoryManager::deinitialize();
Time::deinitialize();
SpiceManager::deinitialize();
LogManager::deinitialize();
LogManager::deinitialize();
ghoul::deinitialize();
}
bool OpenSpaceEngine::initialize() {
// clear the screen so the user don't have to see old buffer contents from the
// graphics card
clearAllWindows();
// clear the screen so the user don't have to see old buffer contents from the
// graphics card
clearAllWindows();
// Detect and log OpenCL and OpenGL versions and available devices
// Detect and log OpenCL and OpenGL versions and available devices
SysCap.addComponent(
std::make_unique<ghoul::systemcapabilities::GeneralCapabilitiesComponent>()
);
SysCap.addComponent(
std::make_unique<ghoul::systemcapabilities::OpenGLCapabilitiesComponent>()
);
SysCap.detectCapabilities();
SysCap.detectCapabilities();
using Verbosity = ghoul::systemcapabilities::SystemCapabilitiesComponent::Verbosity;
Verbosity verbosity = Verbosity::Default;
@@ -328,43 +328,43 @@ bool OpenSpaceEngine::initialize() {
if (verbosityMap.find(v) != verbosityMap.end())
verbosity = verbosityMap[v];
}
SysCap.logCapabilities(verbosity);
SysCap.logCapabilities(verbosity);
std::string requestURL = "";
bool success = configurationManager().getValue(ConfigurationManager::KeyDownloadRequestURL, requestURL);
if (success)
DownloadManager::initialize(requestURL, DownloadVersion);
// Load SPICE time kernel
success = loadSpiceKernels();
if (!success)
return false;
// Load SPICE time kernel
success = loadSpiceKernels();
if (!success)
return false;
// Register Lua script functions
LDEBUG("Registering Lua libraries");
_scriptEngine->addLibrary(RenderEngine::luaLibrary());
_scriptEngine->addLibrary(Scene::luaLibrary());
_scriptEngine->addLibrary(Time::luaLibrary());
_scriptEngine->addLibrary(interaction::InteractionHandler::luaLibrary());
_scriptEngine->addLibrary(LuaConsole::luaLibrary());
_scriptEngine->addLibrary(gui::GUI::luaLibrary());
// Register Lua script functions
LDEBUG("Registering Lua libraries");
_scriptEngine->addLibrary(RenderEngine::luaLibrary());
_scriptEngine->addLibrary(Scene::luaLibrary());
_scriptEngine->addLibrary(Time::luaLibrary());
_scriptEngine->addLibrary(interaction::InteractionHandler::luaLibrary());
_scriptEngine->addLibrary(LuaConsole::luaLibrary());
_scriptEngine->addLibrary(gui::GUI::luaLibrary());
_scriptEngine->addLibrary(network::ParallelConnection::luaLibrary());
// TODO: Maybe move all scenegraph and renderengine stuff to initializeGL
scriptEngine().initialize();
// TODO: Maybe move all scenegraph and renderengine stuff to initializeGL
scriptEngine().initialize();
// If a LuaDocumentationFile was specified, generate it now
const bool hasType = configurationManager().hasKey(ConfigurationManager::KeyLuaDocumentationType);
const bool hasFile = configurationManager().hasKey(ConfigurationManager::KeyLuaDocumentationFile);
if (hasType && hasFile) {
std::string luaDocumentationType;
configurationManager().getValue(ConfigurationManager::KeyLuaDocumentationType, luaDocumentationType);
std::string luaDocumentationFile;
configurationManager().getValue(ConfigurationManager::KeyLuaDocumentationFile, luaDocumentationFile);
// If a LuaDocumentationFile was specified, generate it now
const bool hasType = configurationManager().hasKey(ConfigurationManager::KeyLuaDocumentationType);
const bool hasFile = configurationManager().hasKey(ConfigurationManager::KeyLuaDocumentationFile);
if (hasType && hasFile) {
std::string luaDocumentationType;
configurationManager().getValue(ConfigurationManager::KeyLuaDocumentationType, luaDocumentationType);
std::string luaDocumentationFile;
configurationManager().getValue(ConfigurationManager::KeyLuaDocumentationFile, luaDocumentationFile);
luaDocumentationFile = absPath(luaDocumentationFile);
_scriptEngine->writeDocumentation(luaDocumentationFile, luaDocumentationType);
}
luaDocumentationFile = absPath(luaDocumentationFile);
_scriptEngine->writeDocumentation(luaDocumentationFile, luaDocumentationType);
}
bool disableMasterRendering = false;
configurationManager().getValue(
@@ -372,41 +372,41 @@ bool OpenSpaceEngine::initialize() {
_renderEngine->setDisableRenderingOnMaster(disableMasterRendering);
// Load scenegraph
Scene* sceneGraph = new Scene;
_renderEngine->setSceneGraph(sceneGraph);
// Load scenegraph
Scene* sceneGraph = new Scene;
_renderEngine->setSceneGraph(sceneGraph);
// initialize the RenderEngine
// initialize the RenderEngine
_renderEngine->initialize();
sceneGraph->initialize();
sceneGraph->initialize();
std::string sceneDescriptionPath = "";
if (commandlineArgumentPlaceholders.sceneName.empty()) {
success = configurationManager().getValue(
ConfigurationManager::KeyConfigScene, sceneDescriptionPath);
success = configurationManager().getValue(
ConfigurationManager::KeyConfigScene, sceneDescriptionPath);
}
else
sceneDescriptionPath = commandlineArgumentPlaceholders.sceneName;
sceneGraph->scheduleLoadSceneFile(sceneDescriptionPath);
sceneGraph->scheduleLoadSceneFile(sceneDescriptionPath);
_interactionHandler->setKeyboardController(new interaction::KeyboardControllerFixed);
_interactionHandler->setMouseController(new interaction::OrbitalMouseController);
_interactionHandler->setKeyboardController(new interaction::KeyboardControllerFixed);
_interactionHandler->setMouseController(new interaction::OrbitalMouseController);
// Run start up scripts
runStartupScripts();
// Run start up scripts
runStartupScripts();
// Load a light and a monospaced font
// Load a light and a monospaced font
loadFonts();
LINFO("Initializing GUI");
_gui->initialize();
_gui->initialize();
LINFO("Finished initializing");
return true;
return true;
}
bool OpenSpaceEngine::isInitialized() {
return _engine != nullptr;
return _engine != nullptr;
}
void OpenSpaceEngine::clearAllWindows() {
@@ -416,13 +416,13 @@ void OpenSpaceEngine::clearAllWindows() {
bool OpenSpaceEngine::gatherCommandlineArguments() {
// TODO: Get commandline arguments from all modules
commandlineArgumentPlaceholders.configurationName = "";
commandlineArgumentPlaceholders.configurationName = "";
_commandlineParser->addCommand(std::make_unique<SingleCommand<std::string>>(
&commandlineArgumentPlaceholders.configurationName, "-config", "-c",
"Provides the path to the OpenSpace configuration file"
));
commandlineArgumentPlaceholders.sgctConfigurationName = "";
commandlineArgumentPlaceholders.sgctConfigurationName = "";
_commandlineParser->addCommand(std::make_unique<SingleCommand<std::string>>(
&commandlineArgumentPlaceholders.sgctConfigurationName, "-sgct", "-s",
"Provides the path to the SGCT configuration file, overriding the value set in "
@@ -439,27 +439,27 @@ bool OpenSpaceEngine::gatherCommandlineArguments() {
}
bool OpenSpaceEngine::loadSpiceKernels() {
// Load time kernel
std::string timeKernel;
bool success = configurationManager().getValue(ConfigurationManager::KeySpiceTimeKernel, timeKernel);
// Load time kernel
std::string timeKernel;
bool success = configurationManager().getValue(ConfigurationManager::KeySpiceTimeKernel, timeKernel);
// Move this to configurationmanager::completenesscheck ---abock
if (!success) {
LERROR("Configuration file does not contain a '" << ConfigurationManager::KeySpiceTimeKernel << "'");
return false;
}
SpiceManager::KernelHandle id =
SpiceManager::ref().loadKernel(timeKernel);
if (!success) {
LERROR("Configuration file does not contain a '" << ConfigurationManager::KeySpiceTimeKernel << "'");
return false;
}
SpiceManager::KernelHandle id =
SpiceManager::ref().loadKernel(timeKernel);
// Load SPICE leap second kernel
std::string leapSecondKernel;
success = configurationManager().getValue(ConfigurationManager::KeySpiceLeapsecondKernel, leapSecondKernel);
if (!success) {
// Load SPICE leap second kernel
std::string leapSecondKernel;
success = configurationManager().getValue(ConfigurationManager::KeySpiceLeapsecondKernel, leapSecondKernel);
if (!success) {
// Move this to configurationmanager::completenesscheck ---abock
LERROR("Configuration file does not have a '" << ConfigurationManager::KeySpiceLeapsecondKernel << "'");
return false;
}
id = SpiceManager::ref().loadKernel(std::move(leapSecondKernel));
return true;
LERROR("Configuration file does not have a '" << ConfigurationManager::KeySpiceLeapsecondKernel << "'");
return false;
}
id = SpiceManager::ref().loadKernel(std::move(leapSecondKernel));
return true;
}
void OpenSpaceEngine::runScripts(const ghoul::Dictionary& scripts) {
@@ -500,9 +500,9 @@ void OpenSpaceEngine::runScripts(const ghoul::Dictionary& scripts) {
void OpenSpaceEngine::runStartupScripts() {
ghoul::Dictionary scripts;
configurationManager().getValue(
ConfigurationManager::KeyStartupScript, scripts);
ghoul::Dictionary scripts;
configurationManager().getValue(
ConfigurationManager::KeyStartupScript, scripts);
runScripts(scripts);
}
@@ -546,30 +546,30 @@ void OpenSpaceEngine::loadFonts() {
}
void OpenSpaceEngine::configureLogging() {
if (configurationManager().hasKeyAndValue<std::string>(ConfigurationManager::KeyLogLevel)) {
std::string logLevel;
configurationManager().getValue(ConfigurationManager::KeyLogLevel, logLevel);
if (configurationManager().hasKeyAndValue<std::string>(ConfigurationManager::KeyLogLevel)) {
std::string logLevel;
configurationManager().getValue(ConfigurationManager::KeyLogLevel, logLevel);
bool immediateFlush = false;
configurationManager().getValue(ConfigurationManager::KeyLogImmediateFlush, immediateFlush);
bool immediateFlush = false;
configurationManager().getValue(ConfigurationManager::KeyLogImmediateFlush, immediateFlush);
LogManager::LogLevel level = LogManager::levelFromString(logLevel);
LogManager::deinitialize();
LogManager::LogLevel level = LogManager::levelFromString(logLevel);
LogManager::deinitialize();
using ImmediateFlush = ghoul::logging::LogManager::ImmediateFlush;
LogManager::initialize(
level,
immediateFlush ? ImmediateFlush::Yes : ImmediateFlush::No
);
LogMgr.addLog(std::make_unique<ConsoleLog>());
}
LogMgr.addLog(std::make_unique<ConsoleLog>());
}
if (configurationManager().hasKeyAndValue<ghoul::Dictionary>(ConfigurationManager::KeyLogs)) {
ghoul::Dictionary logs;
configurationManager().getValue(ConfigurationManager::KeyLogs, logs);
if (configurationManager().hasKeyAndValue<ghoul::Dictionary>(ConfigurationManager::KeyLogs)) {
ghoul::Dictionary logs;
configurationManager().getValue(ConfigurationManager::KeyLogs, logs);
for (size_t i = 1; i <= logs.size(); ++i) {
ghoul::Dictionary logInfo;
logs.getValue(std::to_string(i), logInfo);
for (size_t i = 1; i <= logs.size(); ++i) {
ghoul::Dictionary logInfo;
logs.getValue(std::to_string(i), logInfo);
try {
LogMgr.addLog(createLog(logInfo));
@@ -577,8 +577,8 @@ void OpenSpaceEngine::configureLogging() {
catch (const ghoul::RuntimeError& e) {
LERRORC(e.component, e.message);
}
}
}
}
}
}
bool OpenSpaceEngine::initializeGL() {
@@ -592,15 +592,15 @@ bool OpenSpaceEngine::initializeGL() {
LERROR(e.what());
}
LINFO("Finished initializing OpenGL");
return success;
return success;
}
bool OpenSpaceEngine::isMaster(){
return _isMaster;
return _isMaster;
}
void OpenSpaceEngine::setMaster(bool master){
_isMaster = master;
_isMaster = master;
}
double OpenSpaceEngine::runTime(){
@@ -612,24 +612,24 @@ void OpenSpaceEngine::setRunTime(double d){
}
void OpenSpaceEngine::preSynchronization() {
FileSys.triggerFilesystemEvents();
FileSys.triggerFilesystemEvents();
if (_isMaster) {
double dt = _windowWrapper->averageDeltaTime();
Time::ref().advanceTime(dt);
Time::ref().preSynchronization();
Time::ref().advanceTime(dt);
Time::ref().preSynchronization();
_interactionHandler->update(dt);
_scriptEngine->preSynchronization();
_scriptEngine->preSynchronization();
_renderEngine->preSynchronization();
_parallelConnection->preSynchronization();
}
}
void OpenSpaceEngine::postSynchronizationPreDraw() {
Time::ref().postSynchronizationPreDraw();
Time::ref().postSynchronizationPreDraw();
_scriptEngine->postSynchronizationPreDraw();
_scriptEngine->postSynchronizationPreDraw();
_renderEngine->postSynchronizationPreDraw();
if (_isMaster && _gui->isEnabled() && _windowWrapper->isRegularRendering()) {
@@ -639,116 +639,116 @@ void OpenSpaceEngine::postSynchronizationPreDraw() {
double dt = _windowWrapper->averageDeltaTime();
_gui->startFrame(static_cast<float>(dt), glm::vec2(drawBufferResolution), mousePosition, mouseButtons);
}
_gui->startFrame(static_cast<float>(dt), glm::vec2(drawBufferResolution), mousePosition, mouseButtons);
}
}
void OpenSpaceEngine::render(const glm::mat4 &projectionMatrix, const glm::mat4 &viewMatrix) {
_renderEngine->render(projectionMatrix, viewMatrix);
if (_isMaster && _windowWrapper->isRegularRendering()) {
if (_isMaster && _windowWrapper->isRegularRendering()) {
if (_console->isVisible())
_console->render();
if (_gui->isEnabled())
_gui->endFrame();
}
_console->render();
if (_gui->isEnabled())
_gui->endFrame();
}
}
void OpenSpaceEngine::postDraw() {
_renderEngine->postDraw();
_renderEngine->postDraw();
}
void OpenSpaceEngine::keyboardCallback(Key key, KeyModifier mod, KeyAction action) {
if (_isMaster) {
if (_gui->isEnabled()) {
bool isConsumed = _gui->keyCallback(key, mod, action);
if (isConsumed)
return;
}
if (_isMaster) {
if (_gui->isEnabled()) {
bool isConsumed = _gui->keyCallback(key, mod, action);
if (isConsumed)
return;
}
if (key == _console->commandInputButton() && (action == KeyAction::Press || action == KeyAction::Repeat))
_console->toggleVisibility();
_console->toggleVisibility();
if (!_console->isVisible()) {
_interactionHandler->keyboardCallback(key, mod, action);
}
else {
_console->keyboardCallback(key, mod, action);
}
}
if (!_console->isVisible()) {
_interactionHandler->keyboardCallback(key, mod, action);
}
else {
_console->keyboardCallback(key, mod, action);
}
}
}
void OpenSpaceEngine::charCallback(unsigned int codepoint, KeyModifier modifier) {
if (_isMaster) {
if (_gui->isEnabled()) {
const bool isConsumed = _gui->charCallback(codepoint, modifier);
if (isConsumed)
return;
}
if (_isMaster) {
if (_gui->isEnabled()) {
const bool isConsumed = _gui->charCallback(codepoint, modifier);
if (isConsumed)
return;
}
if (_console->isVisible()) {
_console->charCallback(codepoint, modifier);
}
}
if (_console->isVisible()) {
_console->charCallback(codepoint, modifier);
}
}
}
void OpenSpaceEngine::mouseButtonCallback(MouseButton button, MouseAction action) {
if (_isMaster) {
if (_gui->isEnabled()) {
const bool isConsumed = _gui->mouseButtonCallback(button, action);
if (_isMaster) {
if (_gui->isEnabled()) {
const bool isConsumed = _gui->mouseButtonCallback(button, action);
if (isConsumed && action != MouseAction::Release)
return;
}
return;
}
_interactionHandler->mouseButtonCallback(button, action);
}
_interactionHandler->mouseButtonCallback(button, action);
}
}
void OpenSpaceEngine::mousePositionCallback(double x, double y) {
if (_isMaster) {
_interactionHandler->mousePositionCallback(x, y);
}
if (_isMaster) {
_interactionHandler->mousePositionCallback(x, y);
}
}
void OpenSpaceEngine::mouseScrollWheelCallback(double pos) {
if (_isMaster) {
if (_gui->isEnabled()) {
const bool isConsumed = _gui->mouseWheelCallback(pos);
if (isConsumed)
return;
}
if (_isMaster) {
if (_gui->isEnabled()) {
const bool isConsumed = _gui->mouseWheelCallback(pos);
if (isConsumed)
return;
}
_interactionHandler->mouseScrollWheelCallback(pos);
}
_interactionHandler->mouseScrollWheelCallback(pos);
}
}
void OpenSpaceEngine::encode() {
if (_syncBuffer) {
Time::ref().serialize(_syncBuffer.get());
_scriptEngine->serialize(_syncBuffer.get());
_renderEngine->serialize(_syncBuffer.get());
_syncBuffer->write();
}
if (_syncBuffer) {
Time::ref().serialize(_syncBuffer.get());
_scriptEngine->serialize(_syncBuffer.get());
_renderEngine->serialize(_syncBuffer.get());
_syncBuffer->write();
}
_networkEngine->publishStatusMessage();
_networkEngine->sendMessages();
}
void OpenSpaceEngine::decode() {
if (_syncBuffer) {
_syncBuffer->read();
if (_syncBuffer) {
_syncBuffer->read();
Time::ref().deserialize(_syncBuffer.get());
_scriptEngine->deserialize(_syncBuffer.get());
_renderEngine->deserialize(_syncBuffer.get());
}
Time::ref().deserialize(_syncBuffer.get());
_scriptEngine->deserialize(_syncBuffer.get());
_renderEngine->deserialize(_syncBuffer.get());
}
}
void OpenSpaceEngine::externalControlCallback(const char* receivedChars, int size,
int clientId)
{
if (size == 0)
return;
if (size == 0)
return;
_networkEngine->handleMessage(std::string(receivedChars, size));
}

View File

@@ -59,8 +59,8 @@
namespace {
const std::string _loggerCat = "Scene";
const std::string _moduleExtension = ".mod";
const std::string _defaultCommonDirectory = "common";
const std::string _commonModuleToken = "${COMMON_MODULE}";
const std::string _defaultCommonDirectory = "common";
const std::string _commonModuleToken = "${COMMON_MODULE}";
const std::string KeyCamera = "Camera";
const std::string KeyFocusObject = "Focus";
@@ -84,28 +84,30 @@ bool Scene::initialize() {
std::unique_ptr<ProgramObject> tmpProgram;
// fboPassthrough program
// fboPassthrough program
tmpProgram = ProgramObject::Build(
"fboPassProgram",
"${SHADERS}/fboPass_vs.glsl",
"${SHADERS}/fboPass_fs.glsl");
if (!tmpProgram)
"${SHADERS}/fboPass_vs.glsl",
"${SHADERS}/fboPass_fs.glsl");
if (!tmpProgram)
return false;
tmpProgram->setIgnoreSubroutineUniformLocationError(ProgramObject::IgnoreError::Yes);
OsEng.configurationManager().setValue("fboPassProgram", tmpProgram.get());
OsEng.configurationManager().setValue("fboPassProgram", tmpProgram.get());
return true;
}
bool Scene::deinitialize() {
clearSceneGraph();
clearSceneGraph();
return true;
}
//bool ONCE = false;
void Scene::update(const UpdateData& data) {
if (!_sceneGraphToLoad.empty()) {
OsEng.renderEngine().scene()->clearSceneGraph();
if (!_sceneGraphToLoad.empty()) {
OsEng.renderEngine().scene()->clearSceneGraph();
try {
bool success = loadSceneInternal(_sceneGraphToLoad);
_sceneGraphToLoad = "";
@@ -114,7 +116,36 @@ void Scene::update(const UpdateData& data) {
LERROR(e.what());
return;
}
}
}
//if (!ONCE) {
// ghoul::Dictionary d = {
// {"Name", std::string("Earth_Pluto")},
// {"Parent", std::string("PlutoBarycenter")},
// {"Renderable", ghoul::Dictionary{
// {"Type", std::string("RenderablePlanet")},
// {"Frame", std::string("IAU_EARTH")},
// {"Body", std::string("EARTH")},
// {"Geometry", ghoul::Dictionary{
// {"Type", std::string("SimpleSphere")},
// {"Radius", glm::vec2(6.3f, 6.0f)},
// {"Segments", 100.0}
// }},
// {"Textures", ghoul::Dictionary{
// {"Type", std::string("simple")},
// { "Color", std::string("C:/alebo68/OpenSpace/data/scene/earth/textures/earth_bluemarble.jpg") },
// { "Night", std::string("C:/alebo68/OpenSpace/data/scene/earth/textures/earth_night.jpg")}
// }}
// }}
// };
// SceneGraphNode* node = SceneGraphNode::createFromDictionary(d);
// node->setParent(sceneGraphNode(d.value<std::string>("Parent")));
// node->initialize();
// _graph.addSceneGraphNode(node);
// ONCE = true;
//}
for (SceneGraphNode* node : _graph.nodes()) {
try {
node->update(data);
@@ -128,7 +159,7 @@ void Scene::update(const UpdateData& data) {
void Scene::evaluate(Camera* camera) {
for (SceneGraphNode* node : _graph.nodes())
node->evaluate(camera);
//_root->evaluate(camera);
//_root->evaluate(camera);
}
void Scene::render(const RenderData& data, RendererTasks& tasks) {
@@ -138,17 +169,17 @@ void Scene::render(const RenderData& data, RendererTasks& tasks) {
}
void Scene::scheduleLoadSceneFile(const std::string& sceneDescriptionFilePath) {
_sceneGraphToLoad = sceneDescriptionFilePath;
_sceneGraphToLoad = sceneDescriptionFilePath;
}
void Scene::clearSceneGraph() {
// deallocate the scene graph. Recursive deallocation will occur
// deallocate the scene graph. Recursive deallocation will occur
_graph.clear();
//if (_root) {
// _root->deinitialize();
// delete _root;
// _root = nullptr;
//}
//if (_root) {
// _root->deinitialize();
// delete _root;
// _root = nullptr;
//}
// _nodes.erase(_nodes.begin(), _nodes.end());
// _allNodes.erase(_allNodes.begin(), _allNodes.end());
@@ -205,9 +236,9 @@ bool Scene::loadSceneInternal(const std::string& sceneDescriptionFilePath) {
}
// update the position of all nodes
// TODO need to check this; unnecessary? (ab)
for (SceneGraphNode* node : _graph.nodes()) {
node->update({ Time::ref().currentTime() });
// TODO need to check this; unnecessary? (ab)
for (SceneGraphNode* node : _graph.nodes()) {
node->update({ Time::ref().currentTime() });
}
for (auto it = _graph.nodes().rbegin(); it != _graph.nodes().rend(); ++it)
@@ -218,7 +249,7 @@ bool Scene::loadSceneInternal(const std::string& sceneDescriptionFilePath) {
//_root->calculateBoundingSphere();
// set the camera position
Camera* c = OsEng.ref().renderEngine().camera();
Camera* c = OsEng.ref().renderEngine().camera();
//auto focusIterator = _allNodes.find(_focus);
auto focusIterator = std::find_if(
_graph.nodes().begin(),
@@ -228,8 +259,8 @@ bool Scene::loadSceneInternal(const std::string& sceneDescriptionFilePath) {
}
);
glm::vec2 cameraScaling(1);
psc cameraPosition(0,0,1,0);
glm::vec2 cameraScaling(1);
psc cameraPosition(0,0,1,0);
//if (_focus->)
if (focusIterator != _graph.nodes().end()) {
@@ -241,26 +272,26 @@ bool Scene::loadSceneInternal(const std::string& sceneDescriptionFilePath) {
// TODO: Set distance and camera direction in some more smart way
// TODO: Set scaling dependent on the position and distance
// set position for camera
const PowerScaledScalar bound = focusNode->calculateBoundingSphere();
const PowerScaledScalar bound = focusNode->calculateBoundingSphere();
// this part is full of magic!
glm::vec2 boundf = bound.vec2();
glm::vec2 boundf = bound.vec2();
//glm::vec2 scaling{1.0f, -boundf[1]};
cameraScaling = glm::vec2(1.f, -boundf[1]);
cameraScaling = glm::vec2(1.f, -boundf[1]);
boundf[0] *= 5.0f;
//psc cameraPosition = focusNode->position();
//psc cameraPosition = focusNode->position();
//cameraPosition += psc(glm::vec4(0.f, 0.f, boundf));
//cameraPosition = psc(glm::vec4(0.f, 0.f, 1.f,0.f));
//cameraPosition = psc(glm::vec4(0.f, 0.f, 1.f,0.f));
cameraPosition = focusNode->position();
cameraPosition += psc(glm::vec4(0.f, 0.f, boundf));
//why this line? (JK)
//cameraPosition = psc(glm::vec4(0.f, 0.f, 1.f, 0.f));
cameraPosition = focusNode->position();
cameraPosition += psc(glm::vec4(0.f, 0.f, boundf));
//why this line? (JK)
//cameraPosition = psc(glm::vec4(0.f, 0.f, 1.f, 0.f));
//c->setPosition(cameraPosition);
//c->setPosition(cameraPosition);
// c->setCameraDirection(glm::vec3(0, 0, -1));
// c->setScaling(scaling);
@@ -270,7 +301,7 @@ bool Scene::loadSceneInternal(const std::string& sceneDescriptionFilePath) {
else
OsEng.interactionHandler().setFocusNode(_graph.rootNode());
glm::vec4 position;
glm::vec4 position;
if (cameraDictionary.hasKeyAndValue<glm::vec4>(KeyPositionObject)) {
try {
position = cameraDictionary.value<glm::vec4>(KeyPositionObject);
@@ -286,32 +317,32 @@ bool Scene::loadSceneInternal(const std::string& sceneDescriptionFilePath) {
catch (const ghoul::Dictionary::DictionaryError& e) {
LERROR("Error loading Camera location: " << e.what());
}
}
}
// the camera position
const SceneGraphNode* fn = OsEng.interactionHandler().focusNode();
// the camera position
const SceneGraphNode* fn = OsEng.interactionHandler().focusNode();
// Check crash for when fn == nullptr
glm::mat4 la = glm::lookAt(cameraPosition.vec3(), fn->worldPosition().vec3(), c->lookUpVector());
glm::mat4 la = glm::lookAt(cameraPosition.vec3(), fn->worldPosition().vec3(), c->lookUpVector());
c->setRotation(la);
c->setPosition(cameraPosition);
c->setScaling(cameraScaling);
c->setRotation(la);
c->setPosition(cameraPosition);
c->setScaling(cameraScaling);
glm::vec3 viewOffset;
if (cameraDictionary.hasKey(KeyViewOffset)
&& cameraDictionary.getValue(KeyViewOffset, viewOffset)) {
glm::quat rot = glm::quat(viewOffset);
c->rotate(rot);
}
glm::vec3 viewOffset;
if (cameraDictionary.hasKey(KeyViewOffset)
&& cameraDictionary.getValue(KeyViewOffset, viewOffset)) {
glm::quat rot = glm::quat(viewOffset);
c->rotate(rot);
}
for (SceneGraphNode* node : _graph.nodes()) {
std::vector<properties::Property*> properties = node->propertiesRecursive();
for (properties::Property* p : properties) {
for (SceneGraphNode* node : _graph.nodes()) {
std::vector<properties::Property*> properties = node->propertiesRecursive();
for (properties::Property* p : properties) {
OsEng.gui()._property.registerProperty(p);
}
}
}
}
// If a LuaDocumentationFile was specified, generate it now
const bool hasType = OsEng.configurationManager().hasKey(ConfigurationManager::KeyPropertyDocumentationType);
@@ -490,7 +521,7 @@ SceneGraphNode* Scene::sceneGraphNode(const std::string& name) const {
}
std::vector<SceneGraphNode*> Scene::allSceneGraphNodes() {
return _graph.nodes();
return _graph.nodes();
}
void Scene::writePropertyDocumentation(const std::string& filename, const std::string& type) {
@@ -521,34 +552,34 @@ void Scene::writePropertyDocumentation(const std::string& filename, const std::s
}
scripting::ScriptEngine::LuaLibrary Scene::luaLibrary() {
return {
"",
{
{
"setPropertyValue",
&luascriptfunctions::property_setValue,
"string, *",
"Sets a property identified by the URI in "
"the first argument. The second argument can be any type, but it has to "
" agree with the type that the property expects",
return {
"",
{
{
"setPropertyValue",
&luascriptfunctions::property_setValue,
"string, *",
"Sets a property identified by the URI in "
"the first argument. The second argument can be any type, but it has to "
" agree with the type that the property expects",
true
},
{
"getPropertyValue",
&luascriptfunctions::property_getValue,
"string",
"Returns the value the property, identified by "
"the provided URI."
},
{
"loadScene",
&luascriptfunctions::loadScene,
"string",
"Loads the scene found at the file passed as an "
"argument. If a scene is already loaded, it is unloaded first"
}
}
};
},
{
"getPropertyValue",
&luascriptfunctions::property_getValue,
"string",
"Returns the value the property, identified by "
"the provided URI."
},
{
"loadScene",
&luascriptfunctions::loadScene,
"string",
"Loads the scene found at the file passed as an "
"argument. If a scene is already loaded, it is unloaded first"
}
}
};
}
} // namespace openspace

View File

@@ -27,12 +27,14 @@
#include <openspace/engine/openspaceengine.h>
#include <openspace/scene/scenegraphnode.h>
#include <openspace/rendering/renderengine.h>
#include <openspace/interaction/interactionhandler.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/lua/lua_helper.h>
#include <stack>
#include <unordered_map>
#ifdef _MSC_VER
#ifdef OPENSPACE_ENABLE_VLD
@@ -43,8 +45,8 @@
namespace {
const std::string _loggerCat = "SceneGraph";
const std::string _moduleExtension = ".mod";
const std::string _defaultCommonDirectory = "common";
const std::string _commonModuleToken = "${COMMON_MODULE}";
const std::string _defaultCommonDirectory = "common";
const std::string _commonModuleToken = "${COMMON_MODULE}";
const std::string KeyPathScene = "ScenePath";
const std::string KeyModules = "Modules";
@@ -352,11 +354,78 @@ bool SceneGraph::sortTopologically() {
}
bool SceneGraph::addSceneGraphNode(SceneGraphNode* node) {
// @TODO rework this ---abock
ghoul_assert(node, "Node must not be nullptr");
SceneGraphNodeInternal* internalNode = new SceneGraphNodeInternal;
internalNode->node = node;
auto it = std::find_if(
_nodes.begin(),
_nodes.end(),
[node](SceneGraphNodeInternal* i) {
return i->node == node->parent();
}
);
if (it == _nodes.end()) {
LERROR("Parent node was not found");
delete internalNode;
return false;
}
(*it)->incomingEdges.push_back(internalNode);
internalNode->outgoingEdges.push_back(*it);
_nodes.push_back(internalNode);
sortTopologically();
return true;
}
bool SceneGraph::removeSceneGraphNode(SceneGraphNode* node) {
// How to handle orphaned nodes? (reparent to root?) --- abock
// @TODO rework this ---abock
ghoul_assert(node, "Node must not be nullptr");
auto it = std::find_if(
_nodes.begin(),
_nodes.end(),
[node](SceneGraphNodeInternal* i) {
return i->node == node;
}
);
if (it == _nodes.end()) {
LERROR("The node '" << node->name() << "' did not exist in the scenegraph");
return false;
}
// Remove internal node from the list of nodes
SceneGraphNodeInternal* internalNode = *it;
_nodes.erase(it);
if (OsEng.interactionHandler().focusNode() == node)
OsEng.interactionHandler().setFocusNode(node->parent());
sortTopologically();
#if 0
SceneGraphNodeInternal* parentInternalNode = nodeByName(node->parent()->name());
ghoul_assert(parentInternalNode, "Could not find internal parent node");
// Reparent its children to its parent
for (SceneGraphNode* c : node->children())
c->setParent(node->parent());
// Reset the dependencies accordingly
// VERY untested ---abock
for (SceneGraphNodeInternal* c : internalNode->incomingEdges) {
parentInternalNode->outgoingEdges.insert(parentInternalNode->outgoingEdges.end(), c->outgoingEdges.begin(), c->outgoingEdges.end());
parentInternalNode->incomingEdges.insert(parentInternalNode->incomingEdges.end(), c->incomingEdges.begin(), c->incomingEdges.end());
}
#endif
return true;
}

View File

@@ -71,7 +71,7 @@ SceneGraphNode* SceneGraphNode::createFromDictionary(const ghoul::Dictionary& di
ghoul::Dictionary renderableDictionary;
dictionary.getValue(KeyRenderable, renderableDictionary);
renderableDictionary.setValue(KeyName, name);
renderableDictionary.setValue(KeyName, name);
result->_renderable = Renderable::createFromDictionary(renderableDictionary);
if (result->_renderable == nullptr) {
@@ -80,7 +80,7 @@ SceneGraphNode* SceneGraphNode::createFromDictionary(const ghoul::Dictionary& di
delete result;
return nullptr;
}
result->addPropertySubOwner(result->_renderable);
result->addPropertySubOwner(result->_renderable);
LDEBUG("Successfully create renderable for '" << result->name() << "'");
}
@@ -95,7 +95,7 @@ SceneGraphNode* SceneGraphNode::createFromDictionary(const ghoul::Dictionary& di
delete result;
return nullptr;
}
//result->addPropertySubOwner(result->_ephemeris);
//result->addPropertySubOwner(result->_ephemeris);
LDEBUG("Successfully create ephemeris for '" << result->name() << "'");
}
@@ -147,18 +147,18 @@ bool SceneGraphNode::deinitialize() {
LDEBUG("Deinitialize: " << name());
if (_renderable) {
_renderable->deinitialize();
_renderable->deinitialize();
delete _renderable;
_renderable = nullptr;
}
_renderable = nullptr;
}
delete _ephemeris;
_ephemeris = nullptr;
// for (SceneGraphNode* child : _children) {
// child->deinitialize();
// delete child;
//}
// child->deinitialize();
// delete child;
//}
_children.clear();
// reset variables
@@ -171,35 +171,35 @@ bool SceneGraphNode::deinitialize() {
}
void SceneGraphNode::update(const UpdateData& data) {
if (_ephemeris) {
if (data.doPerformanceMeasurement) {
glFinish();
if (_ephemeris) {
if (data.doPerformanceMeasurement) {
glFinish();
auto start = std::chrono::high_resolution_clock::now();
_ephemeris->update(data);
_ephemeris->update(data);
glFinish();
auto end = std::chrono::high_resolution_clock::now();
_performanceRecord.updateTimeEphemeris = (end - start).count();
}
else
_ephemeris->update(data);
}
glFinish();
auto end = std::chrono::high_resolution_clock::now();
_performanceRecord.updateTimeEphemeris = (end - start).count();
}
else
_ephemeris->update(data);
}
if (_renderable && _renderable->isReady()) {
if (data.doPerformanceMeasurement) {
glFinish();
auto start = std::chrono::high_resolution_clock::now();
if (_renderable && _renderable->isReady()) {
if (data.doPerformanceMeasurement) {
glFinish();
auto start = std::chrono::high_resolution_clock::now();
_renderable->update(data);
_renderable->update(data);
glFinish();
auto end = std::chrono::high_resolution_clock::now();
_performanceRecord.updateTimeRenderable = (end - start).count();
}
else
_renderable->update(data);
}
glFinish();
auto end = std::chrono::high_resolution_clock::now();
_performanceRecord.updateTimeRenderable = (end - start).count();
}
else
_renderable->update(data);
}
}
void SceneGraphNode::evaluate(const Camera* camera, const psc& parentPosition) {
@@ -222,7 +222,7 @@ void SceneGraphNode::evaluate(const Camera* camera, const psc& parentPosition) {
return;
}
}
*/
*/
#endif
// inside boudningsphere or parts of the sphere is visible, individual
@@ -245,22 +245,22 @@ void SceneGraphNode::evaluate(const Camera* camera, const psc& parentPosition) {
void SceneGraphNode::render(const RenderData& data, RendererTasks& tasks) {
const psc thisPosition = worldPosition();
RenderData newData = {data.camera, thisPosition, data.doPerformanceMeasurement};
RenderData newData = {data.camera, thisPosition, data.doPerformanceMeasurement};
_performanceRecord.renderTime = 0;
_performanceRecord.renderTime = 0;
if (_renderableVisible && _renderable->isVisible() && _renderable->isReady() && _renderable->isEnabled()) {
if (data.doPerformanceMeasurement) {
glFinish();
auto start = std::chrono::high_resolution_clock::now();
if (data.doPerformanceMeasurement) {
glFinish();
auto start = std::chrono::high_resolution_clock::now();
_renderable->render(newData, tasks);
_renderable->render(newData, tasks);
glFinish();
auto end = std::chrono::high_resolution_clock::now();
_performanceRecord.renderTime = (end - start).count();
}
else
_renderable->render(newData, tasks);
glFinish();
auto end = std::chrono::high_resolution_clock::now();
_performanceRecord.renderTime = (end - start).count();
}
else
_renderable->render(newData, tasks);
}
// evaluate all the children, tail-recursive function(?)
@@ -278,8 +278,7 @@ void SceneGraphNode::render(const RenderData& data, RendererTasks& tasks) {
// _children.push_back(child);
//}
void SceneGraphNode::setParent(SceneGraphNode* parent)
{
void SceneGraphNode::setParent(SceneGraphNode* parent) {
_parent = parent;
}
@@ -326,8 +325,8 @@ const std::vector<SceneGraphNode*>& SceneGraphNode::children() const{
// bounding sphere
PowerScaledScalar SceneGraphNode::calculateBoundingSphere(){
// set the bounding sphere to 0.0
_boundingSphere = 0.0;
_boundingSphere = 0.0;
if (!_children.empty()) { // node
PowerScaledScalar maxChild;
@@ -338,7 +337,7 @@ PowerScaledScalar SceneGraphNode::calculateBoundingSphere(){
// position
//PowerScaledScalar child = _children.at(i)->position().length()
// + _children.at(i)->calculateBoundingSphere();
PowerScaledScalar child = _children.at(i)->calculateBoundingSphere();
PowerScaledScalar child = _children.at(i)->calculateBoundingSphere();
if (child > maxChild) {
maxChild = child;
}
@@ -352,8 +351,8 @@ PowerScaledScalar SceneGraphNode::calculateBoundingSphere(){
if(renderableBS > _boundingSphere)
_boundingSphere = renderableBS;
}
//LINFO("Bounding Sphere of '" << name() << "': " << _boundingSphere);
//LINFO("Bounding Sphere of '" << name() << "': " << _boundingSphere);
return _boundingSphere;
}
@@ -372,7 +371,7 @@ const Renderable* SceneGraphNode::renderable() const
}
Renderable* SceneGraphNode::renderable() {
return _renderable;
return _renderable;
}
// private helper methods
@@ -422,21 +421,21 @@ SceneGraphNode* SceneGraphNode::childNode(const std::string& name)
void SceneGraphNode::updateCamera(Camera* camera) const{
psc origin = worldPosition();
//int i = 0;
// the camera position
psc relative = camera->position();
psc focus = camera->focusPosition();
psc relative_focus = relative - focus;
psc origin = worldPosition();
//int i = 0;
// the camera position
psc relative = camera->position();
psc focus = camera->focusPosition();
psc relative_focus = relative - focus;
psc target = origin + relative_focus;
camera->setPosition(target);
camera->setFocusPosition(origin);
psc target = origin + relative_focus;
camera->setPosition(target);
camera->setFocusPosition(origin);
//printf("target: %f, %f, %f, %f\n", target.vec4().x, target.vec4().y, target.vec4().z, target.vec4().w);
//printf("target: %f, %f, %f, %f\n", target.vec4().x, target.vec4().y, target.vec4().z, target.vec4().w);
}
} // namespace openspace