Restructured SceneGraphNode code

This commit is contained in:
Alexander Bock
2014-05-04 15:28:07 +02:00
parent 2bf71ad9b6
commit 982ec8b87c
9 changed files with 391 additions and 349 deletions

View File

@@ -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__
#endif // __RENDERABLE_H__

View File

@@ -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;

View File

@@ -25,36 +25,36 @@
#ifndef SCENEGRAPH_H
#define SCENEGRAPH_H
// open space includes
#include <openspace/scenegraph/scenegraphnode.h>
// std includes
#include <vector>
#include <map>
#include <openspace/util/camera.h>
// ghoul includes
#include <ghoul/opengl/programobject.h>
#include <ghoul/misc/dictionary.h>
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<SceneGraphNode*> _nodes;
std::map<std::string, SceneGraphNode*> _allNodes;
// actual scenegraph
SceneGraphNode* _root;
std::vector<SceneGraphNode*> _nodes;
std::map<std::string, SceneGraphNode*> _allNodes;
};
} // namespace openspace

View File

@@ -29,12 +29,14 @@
#include <openspace/rendering/renderable.h>
#include <openspace/scenegraph/positioninformation.h>
#include <openspace/scenegraph/scenegraph.h>
#include <ghoul/misc/dictionary.h>
// std includes
#include <iostream>
#include <vector>
#include <memory>
#include <string>
#include <vector>
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<SceneGraphNode*> _children;
SceneGraphNode* _parent;
@@ -98,6 +101,4 @@ private:
} // namespace openspace
#include <openspace/scenegraph/scenegraphnode.inl>
#endif
#endif

View File

@@ -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

View File

@@ -252,6 +252,7 @@ bool OpenSpaceEngine::initialize()
// Load scenegraph
std::shared_ptr<SceneGraph> sceneGraph(new SceneGraph);
_renderEngine->setSceneGraph(sceneGraph);
if (!OsEng.configurationManager().hasValue<std::string>(
configuration::sceneConfigurationKey)) {
LFATAL("Configuration needs to point to the scene file");

View File

@@ -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<std::string> 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<char*>(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<int>(x), static_cast<int>(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<int>(pos));
}
void mainEncodeFun() {
OsEng.encode();
void mainEncodeFun()
{
OsEng.encode();
}
void mainDecodeFun() {
OsEng.decode();
void mainDecodeFun()
{
OsEng.decode();
}

View File

@@ -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<std::string> 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<ghoul::Dictionary>(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

View File

@@ -25,6 +25,7 @@
// open space includes
#include <openspace/scenegraph/scenegraphnode.h>
#include <openspace/util/spice.h>
#include <openspace/query/query.h>
// ghoul includes
#include <ghoul/logging/logmanager.h>
@@ -39,27 +40,34 @@
#include <openspace/util/factorymanager.h>
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 <class T>
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<T>* factory
= FactoryManager::ref().factoryByType<T>();
= FactoryManager::ref().factoryByType<T>();
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<std::string>(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<Renderable>(
&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<PositionInformation>(
&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, "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<PositionInformation>(&_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*>& SceneGraphNode::children() const {
const std::vector<SceneGraphNode*>& 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
} // namespace openspace