From 21276f2cd819c4ef1b1e33c0d8deb4640a9216db Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Fri, 8 Apr 2016 13:11:54 +0200 Subject: [PATCH] Adding methods to add and remove scenegraphnodes from the scenegraph at runtime --- include/openspace/scene/scenegraph.h | 3 - src/engine/openspaceengine.cpp | 464 +++++++++++++-------------- src/scene/scene.cpp | 197 +++++++----- src/scene/scenegraph.cpp | 75 ++++- src/scene/scenegraphnode.cpp | 131 ++++---- 5 files changed, 483 insertions(+), 387 deletions(-) diff --git a/include/openspace/scene/scenegraph.h b/include/openspace/scene/scenegraph.h index d5251bdf65..4afe13e291 100644 --- a/include/openspace/scene/scenegraph.h +++ b/include/openspace/scene/scenegraph.h @@ -25,9 +25,6 @@ #ifndef __SCENEGRAPH_H__ #define __SCENEGRAPH_H__ -#include - -#include #include namespace openspace { diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index c924357c9e..d99b5485f6 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -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()); - 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() ); SysCap.addComponent( std::make_unique() ); - 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>( &commandlineArgumentPlaceholders.configurationName, "-config", "-c", "Provides the path to the OpenSpace configuration file" )); - commandlineArgumentPlaceholders.sgctConfigurationName = ""; + commandlineArgumentPlaceholders.sgctConfigurationName = ""; _commandlineParser->addCommand(std::make_unique>( &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(ConfigurationManager::KeyLogLevel)) { - std::string logLevel; - configurationManager().getValue(ConfigurationManager::KeyLogLevel, logLevel); + if (configurationManager().hasKeyAndValue(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()); - } + LogMgr.addLog(std::make_unique()); + } - if (configurationManager().hasKeyAndValue(ConfigurationManager::KeyLogs)) { - ghoul::Dictionary logs; - configurationManager().getValue(ConfigurationManager::KeyLogs, logs); + if (configurationManager().hasKeyAndValue(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(dt), glm::vec2(drawBufferResolution), mousePosition, mouseButtons); - } + _gui->startFrame(static_cast(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)); } diff --git a/src/scene/scene.cpp b/src/scene/scene.cpp index d1724f5b50..43fa99613b 100644 --- a/src/scene/scene.cpp +++ b/src/scene/scene.cpp @@ -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 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("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(KeyPositionObject)) { try { position = cameraDictionary.value(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 = node->propertiesRecursive(); - for (properties::Property* p : properties) { + for (SceneGraphNode* node : _graph.nodes()) { + std::vector 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 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 diff --git a/src/scene/scenegraph.cpp b/src/scene/scenegraph.cpp index 00975b8485..ed741c4b10 100644 --- a/src/scene/scenegraph.cpp +++ b/src/scene/scenegraph.cpp @@ -27,12 +27,14 @@ #include #include #include +#include #include #include #include #include +#include #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; } diff --git a/src/scene/scenegraphnode.cpp b/src/scene/scenegraphnode.cpp index 5f88de541d..5a8c27a09f 100644 --- a/src/scene/scenegraphnode.cpp +++ b/src/scene/scenegraphnode.cpp @@ -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::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