From 982ec8b87cacbbf68f1debb97f231d8adf765b98 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sun, 4 May 2014 15:28:07 +0200 Subject: [PATCH] Restructured SceneGraphNode code --- include/openspace/rendering/renderable.h | 21 +- .../scenegraph/constantpositioninformation.h | 3 +- include/openspace/scenegraph/scenegraph.h | 39 +- include/openspace/scenegraph/scenegraphnode.h | 13 +- .../openspace/scenegraph/scenegraphnode.inl | 28 -- src/engine/openspaceengine.cpp | 1 + src/main.cpp | 134 +++--- src/scenegraph/scenegraph.cpp | 97 +++-- src/scenegraph/scenegraphnode.cpp | 404 ++++++++++-------- 9 files changed, 391 insertions(+), 349 deletions(-) delete mode 100644 include/openspace/scenegraph/scenegraphnode.inl diff --git a/include/openspace/rendering/renderable.h b/include/openspace/rendering/renderable.h index 5c3e883933..53a982a81a 100644 --- a/include/openspace/rendering/renderable.h +++ b/include/openspace/rendering/renderable.h @@ -36,8 +36,8 @@ namespace openspace { class Renderable : public properties::PropertyOwner { public: - // constructors & destructor - Renderable(const ghoul::Dictionary& dictionary); + // constructors & destructor + Renderable(const ghoul::Dictionary& dictionary); virtual ~Renderable(); void setName(std::string name); @@ -45,22 +45,21 @@ public: virtual bool initialize() = 0; virtual bool deinitialize() = 0; - - void setBoundingSphere(const pss &boundingSphere); - const pss &getBoundingSphere(); - virtual void render(const Camera *camera, const psc &thisPosition) = 0; - virtual void update(); + void setBoundingSphere(const pss& boundingSphere); + const pss& getBoundingSphere(); + + virtual void render(const Camera* camera, const psc& thisPosition) = 0; + virtual void update(); protected: - //Renderable(); + // Renderable(); private: std::string _name; pss boundingSphere_; - }; -} // namespace openspace +} // namespace openspace -#endif // __RENDERABLE_H__ \ No newline at end of file +#endif // __RENDERABLE_H__ diff --git a/include/openspace/scenegraph/constantpositioninformation.h b/include/openspace/scenegraph/constantpositioninformation.h index 6fbc86ca70..6f3154275a 100644 --- a/include/openspace/scenegraph/constantpositioninformation.h +++ b/include/openspace/scenegraph/constantpositioninformation.h @@ -31,7 +31,8 @@ namespace openspace { class ConstantPositionInformation: public PositionInformation { public: - ConstantPositionInformation(const ghoul::Dictionary& dictionary); + ConstantPositionInformation(const ghoul::Dictionary& dictionary + = ghoul::Dictionary()); virtual ~ConstantPositionInformation(); virtual bool initialize(); virtual const psc& position() const; diff --git a/include/openspace/scenegraph/scenegraph.h b/include/openspace/scenegraph/scenegraph.h index 5af588c699..41a3dfb79f 100644 --- a/include/openspace/scenegraph/scenegraph.h +++ b/include/openspace/scenegraph/scenegraph.h @@ -25,36 +25,36 @@ #ifndef SCENEGRAPH_H #define SCENEGRAPH_H -// open space includes -#include - // std includes #include #include +#include + // ghoul includes #include #include namespace openspace { +class SceneGraphNode; + class SceneGraph { public: - - // constructors & destructor - SceneGraph(); - ~SceneGraph(); + // constructors & destructor + SceneGraph(); + ~SceneGraph(); /** * Initalizes the SceneGraph by loading modules from the ${SCENEPATH} directory */ - bool initialize(); - + bool initialize(); + /* * Clean up everything */ bool deinitialize(); - + /* * Load the scenegraph from the provided folder */ @@ -66,17 +66,17 @@ public: /* * Updates all SceneGraphNodes relative positions */ - void update(); - + void update(); + /* * Evaluates if the SceneGraphNodes are visible to the provided camera */ - void evaluate(Camera *camera); - + void evaluate(Camera* camera); + /* * Render visible SceneGraphNodes using the provided camera */ - void render(Camera *camera); + void render(Camera* camera); /* * Prints the SceneGraph tree. For debugging purposes @@ -90,12 +90,11 @@ public: private: std::string _focus, _position; - - // actual scenegraph - SceneGraphNode *_root; - std::vector _nodes; - std::map _allNodes; + // actual scenegraph + SceneGraphNode* _root; + std::vector _nodes; + std::map _allNodes; }; } // namespace openspace diff --git a/include/openspace/scenegraph/scenegraphnode.h b/include/openspace/scenegraph/scenegraphnode.h index a7480ec4e0..8265c6fa97 100644 --- a/include/openspace/scenegraph/scenegraphnode.h +++ b/include/openspace/scenegraph/scenegraphnode.h @@ -29,12 +29,14 @@ #include #include +#include #include // std includes #include -#include +#include #include +#include namespace openspace { @@ -42,8 +44,10 @@ class SceneGraphNode { public: // constructors & destructor - SceneGraphNode(const ghoul::Dictionary& dictionary); + SceneGraphNode(); ~SceneGraphNode(); + + static SceneGraphNode* createFromDictionary(const ghoul::Dictionary& dictionary); bool initialize(); bool deinitialize(); @@ -77,7 +81,6 @@ public: const Renderable * getRenderable() const; private: - // essential std::vector _children; SceneGraphNode* _parent; @@ -98,6 +101,4 @@ private: } // namespace openspace -#include - -#endif \ No newline at end of file +#endif diff --git a/include/openspace/scenegraph/scenegraphnode.inl b/include/openspace/scenegraph/scenegraphnode.inl deleted file mode 100644 index 21abd510c3..0000000000 --- a/include/openspace/scenegraph/scenegraphnode.inl +++ /dev/null @@ -1,28 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014 * - * * - * 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 SCENEGRAPHNODE_INL -#define SCENEGRAPHNODE_INL - -#endif \ No newline at end of file diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index cedf30d118..2a23200c2f 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -252,6 +252,7 @@ bool OpenSpaceEngine::initialize() // Load scenegraph std::shared_ptr sceneGraph(new SceneGraph); + _renderEngine->setSceneGraph(sceneGraph); if (!OsEng.configurationManager().hasValue( configuration::sceneConfigurationKey)) { LFATAL("Configuration needs to point to the scene file"); diff --git a/src/main.cpp b/src/main.cpp index 6fcc949015..759cce831f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -47,121 +47,131 @@ void mainEncodeFun(); void mainDecodeFun(); void mainExternalControlCallback(const char * receivedChars, int size, int clientId); -int main(int argc, char **argv) { - +int main(int argc, char** argv) +{ // create the OpenSpace engine and get arguments for the sgct engine std::vector sgctArguments; openspace::OpenSpaceEngine::create(argc, argv, sgctArguments); // create sgct engine c arguments int newArgc = sgctArguments.size(); - char** newArgv = new char*[newArgc]; + char** newArgv = new char* [newArgc]; for (int i = 0; i < newArgc; ++i) { - //newArgv[i] = new char[sgctArguments.at(i).length()]; - //std::strcpy(newArgv[i], sgctArguments.at(i).c_str()); + // newArgv[i] = new char[sgctArguments.at(i).length()]; + // std::strcpy(newArgv[i], sgctArguments.at(i).c_str()); newArgv[i] = const_cast(sgctArguments.at(i).c_str()); } - - _sgctEngine = new sgct::Engine(newArgc, newArgv); - + + _sgctEngine = new sgct::Engine(newArgc, newArgv); + // deallocate sgct c arguments for (int i = 0; i < newArgc; ++i) { - //delete newArgv[i]; + // delete newArgv[i]; } delete[] newArgv; - + // Bind functions - _sgctEngine->setInitOGLFunction( mainInitFunc ); - _sgctEngine->setPreSyncFunction( mainPreSyncFunc ); - _sgctEngine->setPostSyncPreDrawFunction( mainPostSyncPreDrawFunc ); - _sgctEngine->setDrawFunction( mainRenderFunc ); - _sgctEngine->setPostDrawFunction( mainPostDrawFunc ); - _sgctEngine->setKeyboardCallbackFunction( mainKeyboardCallback ); - _sgctEngine->setMouseButtonCallbackFunction( mainMouseButtonCallback ); - _sgctEngine->setMousePosCallbackFunction( mainMousePosCallback ); - _sgctEngine->setMouseScrollCallbackFunction( mainMouseScrollCallback ); - _sgctEngine->setExternalControlCallback( mainExternalControlCallback ); + _sgctEngine->setInitOGLFunction(mainInitFunc); + _sgctEngine->setPreSyncFunction(mainPreSyncFunc); + _sgctEngine->setPostSyncPreDrawFunction(mainPostSyncPreDrawFunc); + _sgctEngine->setDrawFunction(mainRenderFunc); + _sgctEngine->setPostDrawFunction(mainPostDrawFunc); + _sgctEngine->setKeyboardCallbackFunction(mainKeyboardCallback); + _sgctEngine->setMouseButtonCallbackFunction(mainMouseButtonCallback); + _sgctEngine->setMousePosCallbackFunction(mainMousePosCallback); + _sgctEngine->setMouseScrollCallbackFunction(mainMouseScrollCallback); + _sgctEngine->setExternalControlCallback(mainExternalControlCallback); - // set encode and decode functions - // NOTE: starts synchronizing before init functions - sgct::SharedData::instance()->setEncodeFunction(mainEncodeFun); - sgct::SharedData::instance()->setDecodeFunction(mainDecodeFun); + // set encode and decode functions + // NOTE: starts synchronizing before init functions + sgct::SharedData::instance()->setEncodeFunction(mainEncodeFun); + sgct::SharedData::instance()->setDecodeFunction(mainDecodeFun); - // init the interface which will handle callbacks from an external gui - _interface = new openspace::Interface(&OsEng); + // init the interface which will handle callbacks from an external gui + _interface = new openspace::Interface(&OsEng); - // try to open a window - if( ! _sgctEngine->init(sgct::Engine::OpenGL_4_0_Core_Profile)) { - // could not open a window, deallocates and exits - delete _sgctEngine; + // try to open a window + if (!_sgctEngine->init(sgct::Engine::OpenGL_4_0_Core_Profile)) { + // could not open a window, deallocates and exits + delete _sgctEngine; openspace::OpenSpaceEngine::destroy(); - return EXIT_FAILURE; - } + return EXIT_FAILURE; + } - // Main loop - _sgctEngine->render(); - - // Clean up (de-allocate) - delete _sgctEngine; - - // Exit program - exit( EXIT_SUCCESS ); + // Main loop + _sgctEngine->render(); + + // Clean up (de-allocate) + delete _sgctEngine; + + // Exit program + exit(EXIT_SUCCESS); } -void mainExternalControlCallback(const char * receivedChars, int size, int clientId) { - if (_sgctEngine->isMaster()) - _interface->callback(receivedChars); +void mainExternalControlCallback(const char* receivedChars, int size, int clientId) +{ + if (_sgctEngine->isMaster()) + _interface->callback(receivedChars); } -void mainInitFunc(void) { +void mainInitFunc(void) +{ OsEng.initialize(); OsEng.initializeGL(); } -void mainPreSyncFunc(void) { +void mainPreSyncFunc(void) +{ OsEng.preSynchronization(); } -void mainPostSyncPreDrawFunc(void) { +void mainPostSyncPreDrawFunc(void) +{ OsEng.postSynchronizationPreDraw(); } -void mainRenderFunc(void) { +void mainRenderFunc(void) +{ OsEng.render(); } -void mainPostDrawFunc(void) { +void mainPostDrawFunc(void) +{ OsEng.postDraw(); } -void mainKeyboardCallback(int key, int action) { - if (_sgctEngine->isMaster()) +void mainKeyboardCallback(int key, int action) +{ + if (_sgctEngine->isMaster()) OsEng.keyboardCallback(key, action); } -void mainMouseButtonCallback(int key, int action) { - if (_sgctEngine->isMaster()) +void mainMouseButtonCallback(int key, int action) +{ + if (_sgctEngine->isMaster()) OsEng.mouseButtonCallback(key, action); } -void mainMousePosCallback(double x, double y) { +void mainMousePosCallback(double x, double y) +{ // TODO use float instead - if (_sgctEngine->isMaster()) + if (_sgctEngine->isMaster()) OsEng.mousePositionCallback(static_cast(x), static_cast(y)); } -void mainMouseScrollCallback(double pos, double /*pos2*/) { +void mainMouseScrollCallback(double pos, double /*pos2*/) +{ // TODO use float instead - if (_sgctEngine->isMaster()) + if (_sgctEngine->isMaster()) OsEng.mouseScrollWheelCallback(static_cast(pos)); } -void mainEncodeFun() { - OsEng.encode(); +void mainEncodeFun() +{ + OsEng.encode(); } -void mainDecodeFun() { - OsEng.decode(); +void mainDecodeFun() +{ + OsEng.decode(); } - - diff --git a/src/scenegraph/scenegraph.cpp b/src/scenegraph/scenegraph.cpp index 76c94bf8f9..c4ef331a24 100644 --- a/src/scenegraph/scenegraph.cpp +++ b/src/scenegraph/scenegraph.cpp @@ -49,11 +49,13 @@ namespace { const std::string _loggerCat = "SceneGraph"; const std::string _rootNodeName = "Root"; const std::string _moduleExtension = ".mod"; + namespace configuration { const std::string modulesKey = "Modules"; const std::string cameraKey = "Camera"; -const std::string nameKey = "Name"; -const std::string parentKey = "Parent"; +const std::string focusKey = "Focus"; +const std::string positionKey = "Position"; +const std::string modulePathKey = "ModulePath"; } } @@ -238,10 +240,10 @@ bool SceneGraph::loadScene(const std::string& sceneDescriptionFilePath, // initialize the root node - _root = new SceneGraphNode(Dictionary()); + _root = new SceneGraphNode(); _root->setName(_rootNodeName); _nodes.push_back(_root); - _allNodes.insert(std::make_pair("Root", _root)); + _allNodes.emplace(_rootNodeName, _root); Dictionary dictionary; loadDictionaryFromFile(sceneDescriptionFilePath, dictionary); @@ -263,8 +265,8 @@ bool SceneGraph::loadScene(const std::string& sceneDescriptionFilePath, std::string focus; std::string position; - if (cameraDictionary.hasKey("Focus") - && cameraDictionary.getValue("Focus", focus)) { + if (cameraDictionary.hasKey(configuration::focusKey) + && cameraDictionary.getValue(configuration::focusKey, focus)) { auto focusIterator = _allNodes.find(focus); if (focusIterator != _allNodes.end()) { _focus = focus; @@ -273,8 +275,8 @@ bool SceneGraph::loadScene(const std::string& sceneDescriptionFilePath, else LERROR("Could not find focus object '" << focus << "'"); } - if (cameraDictionary.hasKey("Position") - && cameraDictionary.getValue("Position", position)) { + if (cameraDictionary.hasKey(configuration::positionKey) + && cameraDictionary.getValue(configuration::positionKey, position)) { auto positionIterator = _allNodes.find(position); if (positionIterator != _allNodes.end()) { _position = position; @@ -303,39 +305,54 @@ void SceneGraph::loadModule(const std::string& modulePath) ghoul::lua::loadDictionaryFromFile(fullModule, moduleDictionary); std::vector keys = moduleDictionary.keys(); for (const std::string& key : keys) { - ghoul::Dictionary singleModuleDictionary; - if (moduleDictionary.getValue(key, singleModuleDictionary)) { - std::string moduleName; - if (singleModuleDictionary.getValue(configuration::nameKey, moduleName)) { - std::string parentName; - if (!singleModuleDictionary.getValue(configuration::parentKey, parentName)) { - LWARNING("Could not find 'Parent' key, using 'Root'."); - parentName = "Root"; - } - - auto parentIterator = _allNodes.find(parentName); - if (parentIterator == _allNodes.end()) { - LFATAL("Could not find parent named '" - << parentName << "' for '" << moduleName << "'." - << " Check module definition order. Skipping module."); - continue; - } - - // allocate SceneGraphNode and initialize with Dictionary - singleModuleDictionary.setValue("Path", modulePath); - SceneGraphNode* node = nullptr; - node = new SceneGraphNode(singleModuleDictionary); - if (node != nullptr) { - // add to internal data structures - _allNodes.insert(std::make_pair(moduleName, node)); - _nodes.push_back(node); - - // set child and parent - SceneGraphNode* parentNode = parentIterator->second; - parentNode->addNode(node); - } - } + if (!moduleDictionary.hasValue(key)) { + LERROR("SceneGraphElement '" << key << "' is not a table in module '" + << fullModule << "'"); + continue; } + + ghoul::Dictionary element; + moduleDictionary.getValue(key, element); + + element.setValue(configuration::modulePathKey, modulePath); + + SceneGraphNode* node = SceneGraphNode::createFromDictionary(element); + + _allNodes.emplace(node->nodeName(), node); + _nodes.push_back(node); + + + // std::string moduleName; + // if (element.getValue(configuration::nameKey, moduleName)) { + // std::string parentName; + // if (!element.getValue(configuration::parentKey, parentName)) { + // LWARNING("Could not find 'Parent' key, using 'Root'."); + // parentName = "Root"; + // } + + // auto parentIterator = _allNodes.find(parentName); + // if (parentIterator == _allNodes.end()) { + // LFATAL("Could not find parent named '" + // << parentName << "' for '" << moduleName << "'." + // << " Check module definition order. Skipping module."); + // continue; + // } + + // // allocate SceneGraphNode and initialize with Dictionary + // element.setValue("Path", modulePath); + // SceneGraphNode* node = nullptr; + // node = new SceneGraphNode(element); + // if (node != nullptr) { + // // add to internal data structures + // _allNodes.insert(std::make_pair(moduleName, node)); + // _nodes.push_back(node); + + // // set child and parent + // SceneGraphNode* parentNode = parentIterator->second; + // parentNode->addNode(node); + // } + // } + //} } // Print the tree diff --git a/src/scenegraph/scenegraphnode.cpp b/src/scenegraph/scenegraphnode.cpp index 975bc79e26..57bfb6f29c 100644 --- a/src/scenegraph/scenegraphnode.cpp +++ b/src/scenegraph/scenegraphnode.cpp @@ -25,6 +25,7 @@ // open space includes #include #include +#include // ghoul includes #include @@ -39,27 +40,34 @@ #include namespace { - const std::string _loggerCat = "SceneGraphNode"; +const std::string _loggerCat = "SceneGraphNode"; - const std::string _unnamedSceneGraphNodeName = "Unnamed"; +namespace configuration { +const std::string nameKey = "Name"; +const std::string parentKey = "Parent"; +const std::string modulePathKey = "ModulePath"; +const std::string renderableKey = "Renderable"; +const std::string positionKey = "Position"; +} } namespace openspace { template bool safeCreationWithDictionary(T** object, const std::string& key, - ghoul::Dictionary* dictionary, - const std::string& path = "") { - if (dictionary->hasKey(key)) { + const ghoul::Dictionary& dictionary, + const std::string& path = "") +{ + if (dictionary.hasKey(key)) { ghoul::Dictionary tmpDictionary; - if (dictionary->getValue(key, tmpDictionary)) { + if (dictionary.getValue(key, tmpDictionary)) { if (!tmpDictionary.hasKey("Path") && path != "") { tmpDictionary.setValue("Path", path); } std::string renderableType; if (tmpDictionary.getValue("Type", renderableType)) { ghoul::TemplateFactory* factory - = FactoryManager::ref().factoryByType(); + = FactoryManager::ref().factoryByType(); T* tmp = factory->create(renderableType, tmpDictionary); if (tmp != nullptr) { *object = tmp; @@ -71,45 +79,68 @@ bool safeCreationWithDictionary(T** object, const std::string& key, return false; } +SceneGraphNode* SceneGraphNode::createFromDictionary(const ghoul::Dictionary& dictionary) +{ + SceneGraphNode* result = new SceneGraphNode; -SceneGraphNode::SceneGraphNode(const ghoul::Dictionary& dictionary) + std::string path; + dictionary.getValue(configuration::modulePathKey, path); + + if (!dictionary.hasValue(configuration::nameKey)) { + LERROR("SceneGraphNode in '" << path << "' did not contain a '" + << configuration::nameKey << "' key"); + return nullptr; + } + dictionary.getValue(configuration::nameKey, result->_nodeName); + + + if (dictionary.hasKey(configuration::renderableKey)) { + if (safeCreationWithDictionary( + &result->_renderable, configuration::renderableKey, dictionary, path)) { + LDEBUG(result->_nodeName << ": Successful creation of renderable"); + result->_renderable->setName(result->_nodeName); + } + else { + LDEBUG(result->_nodeName << ": Failed to create renderable"); + } + } + if (dictionary.hasKey(configuration::positionKey)) { + if (safeCreationWithDictionary( + &result->_position, configuration::positionKey, dictionary, path)) { + LDEBUG(result->_nodeName << ": Successful creation of position"); + } + else { + LDEBUG(result->_nodeName << ": Failed to create position"); + } + } + + std::string parentName; + if (!dictionary.getValue(configuration::parentKey, parentName)) { + LWARNING("Could not find 'Parent' key, using 'Root'."); + parentName = "Root"; + } + + SceneGraphNode* parentNode = getSceneGraphNode(parentName); + if (parentNode == nullptr) { + LFATAL("Could not find parent named '" + << parentName << "' for '" << result->_nodeName << "'." + << " Check module definition order. Skipping module."); + } + + parentNode->addNode(result); + + return result; +} + + +SceneGraphNode::SceneGraphNode() : _parent(nullptr) - , _nodeName(_unnamedSceneGraphNodeName) - , _position(nullptr) + , _nodeName("") + , _position(new ConstantPositionInformation) , _renderable(nullptr) , _renderableVisible(false) , _boundingSphereVisible(false) { - ghoul::Dictionary localDictionary = dictionary; - - // set the _nodeName if available - localDictionary.getValue("Name", _nodeName); - - std::string path = ""; - localDictionary.getValue("Path", path); - - if (localDictionary.hasKey("Renderable")) { - if (safeCreationWithDictionary(&_renderable, "Renderable", - &localDictionary, path)) { - LDEBUG(_nodeName << ": Successful creation of renderable!"); - _renderable->setName(_nodeName); - } else { - LDEBUG(_nodeName << ": Failed to create renderable!"); - } - } - if (localDictionary.hasKey("Position")) { - if (safeCreationWithDictionary(&_position, "Position", - &localDictionary, path)) { - LDEBUG(_nodeName << ": Successful creation of position!"); - } else { - LDEBUG(_nodeName << ": Failed to create position!"); - } - } - - if (_position == nullptr) { - _position = new ConstantPositionInformation(ghoul::Dictionary()); - _position->initialize(); - } } SceneGraphNode::~SceneGraphNode() @@ -128,24 +159,25 @@ bool SceneGraphNode::initialize() return true; } -bool SceneGraphNode::deinitialize() { +bool SceneGraphNode::deinitialize() +{ LDEBUG("Deinitialize: " << _nodeName); - - // deallocate the renderable - if(_renderable != nullptr) - delete _renderable; - + + // deallocate the renderable + if (_renderable != nullptr) + delete _renderable; + // deallocate position - if(_position != nullptr) + if (_position != nullptr) delete _position; - - // deallocate the child nodes and delete them, iterate c++11 style - for( auto child: _children) - delete child; - + + // deallocate the child nodes and delete them, iterate c++11 style + for (auto child : _children) + delete child; + // empty the children vector _children.erase(_children.begin(), _children.end()); - + // reset variables _parent = nullptr; _renderable = nullptr; @@ -153,190 +185,199 @@ bool SceneGraphNode::deinitialize() { _nodeName = "Unnamed OpenSpace SceneGraphNode"; _renderableVisible = false; _boundingSphereVisible = false; - _boundingSphere = pss(0.0,0.0); - + _boundingSphere = pss(0.0, 0.0); + return true; } // essential -void SceneGraphNode::update() { +void SceneGraphNode::update() +{ _position->update(); } -void SceneGraphNode::evaluate(const Camera *camera, const psc& parentPosition) { +void SceneGraphNode::evaluate(const Camera* camera, const psc& parentPosition) +{ + const psc thisPosition = parentPosition + _position->position(); + const psc camPos = camera->getPosition(); + const psc toCamera = thisPosition - camPos; - const psc thisPosition = parentPosition + _position->position(); - const psc camPos = camera->getPosition(); - const psc toCamera = thisPosition - camPos; - - // init as not visible - _boundingSphereVisible = false; - _renderableVisible = false; - - // check if camera is outside the node boundingsphere - if(toCamera.length() > _boundingSphere) { - - // check if the boudningsphere is visible before avaluating children - if( ! sphereInsideFrustum(thisPosition, _boundingSphere, camera)) { - // the node is completely outside of the camera view, stop evaluating this node - return; - } - - } - - // inside boudningsphere or parts of the sphere is visible, individual + // init as not visible + _boundingSphereVisible = false; + _renderableVisible = false; + + // check if camera is outside the node boundingsphere + if (toCamera.length() > _boundingSphere) { + // check if the boudningsphere is visible before avaluating children + if (!sphereInsideFrustum(thisPosition, _boundingSphere, camera)) { + // the node is completely outside of the camera view, stop evaluating this + // node + return; + } + } + + // inside boudningsphere or parts of the sphere is visible, individual // children needs to be evaluated - _boundingSphereVisible = true; - - // this node has an renderable - if(_renderable) { + _boundingSphereVisible = true; - // check if the renderable boundingsphere is visible - _renderableVisible = sphereInsideFrustum(thisPosition, _renderable->getBoundingSphere(), camera); - } + // this node has an renderable + if (_renderable) { + // check if the renderable boundingsphere is visible + _renderableVisible = sphereInsideFrustum( + thisPosition, _renderable->getBoundingSphere(), camera); + } - // evaluate all the children, tail-recursive function(?) - for(auto &child: _children) { - child->evaluate(camera,psc()); - } - + // evaluate all the children, tail-recursive function(?) + for (auto& child : _children) { + child->evaluate(camera, psc()); + } } -void SceneGraphNode::render(const Camera *camera, const psc & parentPosition) { +void SceneGraphNode::render(const Camera* camera, const psc& parentPosition) +{ + const psc thisPosition = parentPosition + _position->position(); - const psc thisPosition = parentPosition + _position->position(); - - // check if camera is outside the node boundingsphere - if( ! _boundingSphereVisible) { - return; - } - if(_renderableVisible) { - //LDEBUG("Render"); - _renderable->render(camera,thisPosition); - } + // check if camera is outside the node boundingsphere + if (!_boundingSphereVisible) { + return; + } + if (_renderableVisible) { + // LDEBUG("Render"); + _renderable->render(camera, thisPosition); + } - // evaluate all the children, tail-recursive function(?) - - for(auto &child: _children) { - child->render(camera,thisPosition); - } + // evaluate all the children, tail-recursive function(?) + for (auto& child : _children) { + child->render(camera, thisPosition); + } } // set & get -void SceneGraphNode::addNode(SceneGraphNode *child) { - // add a child node and set this node to be the parent +void SceneGraphNode::addNode(SceneGraphNode* child) +{ + // add a child node and set this node to be the parent child->setParent(this); _children.push_back(child); } -void SceneGraphNode::setName(const std::string &name) { - _nodeName = name; +void SceneGraphNode::setName(const std::string& name) +{ + _nodeName = name; } -void SceneGraphNode::setParent(SceneGraphNode *parent) { - _parent = parent; +void SceneGraphNode::setParent(SceneGraphNode* parent) +{ + _parent = parent; } -const psc &SceneGraphNode::getPosition() const { - return _position->position(); +const psc& SceneGraphNode::getPosition() const +{ + return _position->position(); } -psc SceneGraphNode::getWorldPosition() const { - - // recursive up the hierarchy if there are parents available - if(_parent) { - return _position->position() + _parent->getWorldPosition(); - } else { - return _position->position(); - } +psc SceneGraphNode::getWorldPosition() const +{ + // recursive up the hierarchy if there are parents available + if (_parent) { + return _position->position() + _parent->getWorldPosition(); + } else { + return _position->position(); + } } - -std::string SceneGraphNode::nodeName() const { +std::string SceneGraphNode::nodeName() const +{ return _nodeName; } -SceneGraphNode* SceneGraphNode::parent() const { +SceneGraphNode* SceneGraphNode::parent() const +{ return _parent; } -const std::vector& SceneGraphNode::children() const { +const std::vector& SceneGraphNode::children() const +{ return _children; } // bounding sphere -pss SceneGraphNode::calculateBoundingSphere() { - - // set the vounding sphere to 0.0 - _boundingSphere = 0.0; +pss SceneGraphNode::calculateBoundingSphere() +{ + // set the vounding sphere to 0.0 + _boundingSphere = 0.0; - if(_children.size() > 0) { // node - pss maxChild; + if (_children.size() > 0) { // node + pss maxChild; - // loop though all children and find the one furthest away/with the largest bounding sphere - for(size_t i = 0; i < _children.size(); ++i) { + // loop though all children and find the one furthest away/with the largest + // bounding sphere + for (size_t i = 0; i < _children.size(); ++i) { + // when positions is dynamix, change this part to fins the most distant + // position + pss child = _children.at(i)->getPosition().length() + + _children.at(i)->calculateBoundingSphere(); + if (child > maxChild) { + maxChild = child; + } + } + _boundingSphere += maxChild; + } else { // leaf - // when positions is dynamix, change this part to fins the most distant position - pss child = _children.at(i)->getPosition().length() + - _children.at(i)->calculateBoundingSphere(); - if(child > maxChild) { - maxChild = child; - } - } - _boundingSphere += maxChild; - } else { // leaf + // if has a renderable, use that boundingsphere + if (_renderable) + _boundingSphere += _renderable->getBoundingSphere(); + } - // if has a renderable, use that boundingsphere - if(_renderable) - _boundingSphere += _renderable->getBoundingSphere(); - } - - return _boundingSphere; + return _boundingSphere; } // renderable -void SceneGraphNode::setRenderable(Renderable *renderable) { - _renderable = renderable; - update(); +void SceneGraphNode::setRenderable(Renderable* renderable) +{ + _renderable = renderable; + update(); } -const Renderable * SceneGraphNode::getRenderable() const{ - return _renderable; +const Renderable* SceneGraphNode::getRenderable() const +{ + return _renderable; } // private helper methods -bool SceneGraphNode::sphereInsideFrustum(const psc s_pos, const pss & s_rad, const Camera *camera) { +bool SceneGraphNode::sphereInsideFrustum(const psc s_pos, const pss& s_rad, + const Camera* camera) +{ + // direction the camera is looking at in power scale + psc psc_camdir = psc(camera->getViewDirection()); - // direction the camera is looking at in power scale - psc psc_camdir = psc(camera->getViewDirection()); + // the position of the camera, moved backwards in the view direction to encapsulate + // the sphere radius + psc U = camera->getPosition() - psc_camdir * s_rad * (1.0 / camera->getSinMaxFov()); - // the position of the camera, moved backwards in the view direction to encapsulate the sphere radius - psc U = camera->getPosition() - psc_camdir * s_rad * ( 1.0 / camera->getSinMaxFov()); + // the vector to the object from the new position + psc D = s_pos - U; - // the vector to the object from the new position - psc D = s_pos - U; - const double a = psc_camdir.angle(D); - if ( a < camera->getMaxFov()) - { - // center is inside K'' - D = s_pos - camera->getPosition(); - if ( D.length()* psc_camdir.length() *camera->getSinMaxFov() <= -psc_camdir.dot(D)) { - // center is inside K'' and inside K' - return D.length() <= s_rad; - } else { - // center is inside K'' and outside K' - return true; - } - } else { - // outside the maximum angle - return false; - } - + if (a < camera->getMaxFov()) { + // center is inside K'' + D = s_pos - camera->getPosition(); + if (D.length() * psc_camdir.length() * camera->getSinMaxFov() + <= -psc_camdir.dot(D)) { + // center is inside K'' and inside K' + return D.length() <= s_rad; + } else { + // center is inside K'' and outside K' + return true; + } + } else { + // outside the maximum angle + return false; + } } -SceneGraphNode* SceneGraphNode::get(const std::string& name) { +SceneGraphNode* SceneGraphNode::get(const std::string& name) +{ if (_nodeName == name) return this; else @@ -349,11 +390,12 @@ SceneGraphNode* SceneGraphNode::get(const std::string& name) { return nullptr; } -void SceneGraphNode::print() const { +void SceneGraphNode::print() const +{ std::cout << _nodeName << std::endl; for (auto it : _children) { it->print(); } } - -} // namespace openspace \ No newline at end of file + +} // namespace openspace \ No newline at end of file