Refactor scene graph: Move scene loading to separate class.

This commit is contained in:
Emil Axelsson
2016-12-15 10:06:30 +01:00
parent 0ad004bdc9
commit 4751ce36c4
66 changed files with 1551 additions and 2209 deletions
+48 -46
View File
@@ -35,8 +35,6 @@
#include <openspace/util/camera.h>
#include <openspace/util/updatestructures.h>
#include <openspace/scripting/scriptengine.h>
#include <openspace/scene/scenegraph.h>
#include <ghoul/opengl/programobject.h>
#include <ghoul/misc/dictionary.h>
@@ -48,28 +46,48 @@ class SceneGraphNode;
// SceneGraphFinishedLoading
class Scene {
public:
using UpdateDependencies = ghoul::Boolean;
struct InvalidSceneError : ghoul::RuntimeError {
/**
* \param message The reason that caused this exception to be thrown
* \param component The optional compoment that caused this exception to be thrown
* \pre message may not be empty
*/
explicit InvalidSceneError(const std::string& message, const std::string& component = "");
};
// constructors & destructor
Scene();
~Scene();
/**
* Initalizes the SceneGraph by loading modules from the ${SCENEPATH} directory
* Initalizes the SceneGraph
*/
bool initialize();
/*
* Clean up everything
*/
bool deinitialize();
void initialize();
/*
* Load the scenegraph from the provided folder
*/
void scheduleLoadSceneFile(const std::string& sceneDescriptionFilePath);
void clearSceneGraph();
//void scheduleLoadSceneFile(const std::string& sceneDescriptionFilePath);
void clear();
void loadModule(const std::string& modulePath);
/*
* Set the root node of the scene
*/
void setRoot(std::unique_ptr<SceneGraphNode> root);
/*
* Set the root node of the scene
*/
void setCamera(std::unique_ptr<Camera> camera);
/**
* Return the camera
*/
Camera* camera() const;
/*
* Updates all SceneGraphNodes relative positions
*/
@@ -96,13 +114,20 @@ public:
*/
SceneGraphNode* sceneGraphNode(const std::string& name) const;
std::vector<SceneGraphNode*> allSceneGraphNodes() const;
void addNode(SceneGraphNode* node, UpdateDependencies updateDeps = UpdateDependencies::Yes);
SceneGraph& sceneGraph();
void removeNode(SceneGraphNode* node, UpdateDependencies updateDeps = UpdateDependencies::Yes);
void updateDependencies();
void sortTopologically();
const std::vector<SceneGraphNode*>& allSceneGraphNodes() const;
const std::map<std::string, SceneGraphNode*>& nodesByName() const;
void writePropertyDocumentation(const std::string& filename, const std::string& type, const std::string& sceneFilename);
void addSceneGraphNode(SceneGraphNode* node){
_graph.addSceneGraphNode(node);
}
/**
* Returns the Lua library that contains all Lua functions available to change the
* scene graph. The functions contained are
@@ -115,39 +140,16 @@ public:
static documentation::Documentation Documentation();
private:
bool loadSceneInternal(const std::string& sceneDescriptionFilePath);
void writePropertyDocumentation(const std::string& filename, const std::string& type, const std::string& sceneFilename);
std::string _focus;
// actual scenegraph
SceneGraph _graph;
//SceneGraphNode* _root;
//std::vector<SceneGraphNode*> _nodes;
//std::map<std::string, SceneGraphNode*> _allNodes;
std::string _sceneGraphToLoad;
private:
std::unique_ptr<SceneGraphNode> _root;
std::unique_ptr<Camera> _camera;
std::vector<SceneGraphNode*> _topologicallySortedNodes;
std::vector<SceneGraphNode*> _circularNodes;
std::map<std::string, SceneGraphNode*> _nodesByName;
std::mutex _programUpdateLock;
std::set<ghoul::opengl::ProgramObject*> _programsToUpdate;
std::vector<std::unique_ptr<ghoul::opengl::ProgramObject>> _programs;
typedef std::map<std::string, ghoul::Dictionary> NodeMap;
typedef std::multimap<std::string, std::string> DependencyMap;
typedef std::vector<std::string> LoadedList;
struct LoadMaps {
NodeMap nodes;
DependencyMap dependencies;
LoadedList loadedNodes;
};
void loadModules(const std::string& directory, const ghoul::Dictionary& dictionary);
void loadModule(LoadMaps& m,const std::string& modulePath, lua_State* state);
void loadNodes(const std::string& parentName, LoadMaps& m);
void loadNode(const ghoul::Dictionary& dictionary);
};
} // namespace openspace
+24 -9
View File
@@ -48,6 +48,8 @@ namespace openspace {
class SceneGraphNode : public properties::PropertyOwner {
public:
using UpdateScene = ghoul::Boolean;
struct PerformanceRecord {
long long renderTime; // time in ns
long long updateTimeRenderable; // time in ns
@@ -64,21 +66,33 @@ public:
SceneGraphNode();
~SceneGraphNode();
static SceneGraphNode* createFromDictionary(const ghoul::Dictionary& dictionary);
static std::unique_ptr<SceneGraphNode> createFromDictionary(const ghoul::Dictionary& dictionary);
bool initialize();
bool deinitialize();
void traversePreOrder(std::function<void(SceneGraphNode*)> fn);
void traversePostOrder(std::function<void(SceneGraphNode*)> fn);
void update(const UpdateData& data);
void evaluate(const Camera* camera, const psc& parentPosition = psc());
void render(const RenderData& data, RendererTasks& tasks);
void updateCamera(Camera* camera) const;
//void addNode(SceneGraphNode* child);
void attachChild(std::unique_ptr<SceneGraphNode> child, UpdateScene updateScene = UpdateScene::Yes);
std::unique_ptr<SceneGraphNode> detachChild(SceneGraphNode& child, UpdateScene updateScene = UpdateScene::Yes);
void setParent(SceneGraphNode& parent, UpdateScene updateScene = UpdateScene::Yes);
void addChild(SceneGraphNode* child);
void setParent(SceneGraphNode* parent);
//bool abandonChild(SceneGraphNode* child);
void addDependency(SceneGraphNode& dependency, UpdateScene updateScene = UpdateScene::Yes);
void removeDependency(SceneGraphNode& dependency, UpdateScene updateScene = UpdateScene::Yes);
void clearDependencies(UpdateScene updateScene = UpdateScene::Yes);
void setDependencies(const std::vector<SceneGraphNode*>& dependencies, UpdateScene updateScene = UpdateScene::Yes);
const std::vector<SceneGraphNode*>& dependencies() const;
const std::vector<SceneGraphNode*>& dependentNodes() const;
Scene* scene();
void setScene(Scene* scene);
glm::dvec3 position() const;
const glm::dmat3& rotationMatrix() const;
@@ -89,7 +103,7 @@ public:
double worldScale() const;
SceneGraphNode* parent() const;
const std::vector<SceneGraphNode*>& children() const;
std::vector<SceneGraphNode*> children() const;
PowerScaledScalar calculateBoundingSphere();
PowerScaledScalar boundingSphere() const;
@@ -105,14 +119,15 @@ public:
static documentation::Documentation Documentation();
private:
bool sphereInsideFrustum(const psc& s_pos, const PowerScaledScalar& s_rad, const Camera* camera);
glm::dvec3 calculateWorldPosition() const;
glm::dmat3 calculateWorldRotation() const;
double calculateWorldScale() const;
std::vector<SceneGraphNode*> _children;
std::vector<std::unique_ptr<SceneGraphNode>> _children;
SceneGraphNode* _parent;
std::vector<SceneGraphNode*> _dependencies;
std::vector<SceneGraphNode*> _dependentNodes;
Scene* _scene;
PerformanceRecord _performanceRecord;
+92
View File
@@ -0,0 +1,92 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#ifndef __OPENSPACE_CORE___SCENELOADER___H__
#define __OPENSPACE_CORE___SCENELOADER___H__
#include <memory>
#include <string>
#include <ghoul/misc/dictionary.h>
#include <ghoul/lua/ghoul_lua.h>
#include <openspace/scene/scenegraphnode.h>
#include <openspace/util/camera.h>
namespace openspace {
class Scene;
class SceneLoader {
public:
struct LoadedNode {
LoadedNode(
const std::string& nodeName,
const std::string& parentName,
const std::vector<std::string>& deps,
std::unique_ptr<SceneGraphNode> n)
{
name = nodeName;
parent = parentName;
dependencies = deps;
node = std::move(n);
}
std::string name;
std::string parent;
std::vector<std::string> dependencies;
std::unique_ptr<SceneGraphNode> node;
};
struct LoadedCamera {
LoadedCamera(
const std::string& parentName,
std::unique_ptr<Camera> c)
{
parent = parentName;
camera = std::move(c);
}
std::string parent;
std::unique_ptr<Camera> camera;
};
SceneLoader() = default;
~SceneLoader() = default;
std::unique_ptr<Scene> loadScene(const std::string& path);
std::vector<SceneGraphNode*> importDirectory(Scene& scene, const std::string& directory);
SceneGraphNode* importNodeDictionary(Scene& scene, const ghoul::Dictionary& dictionary);
private:
SceneLoader::LoadedNode loadNode(const ghoul::Dictionary& dictionary);
std::vector<SceneLoader::LoadedNode> loadModule(const std::string& path, lua_State* luaState);
std::vector<SceneLoader::LoadedNode> loadDirectory(const std::string& path, lua_State* luaState);
SceneLoader::LoadedCamera loadCamera(const ghoul::Dictionary& dictionary);
std::vector<SceneGraphNode*> addLoadedNodes(Scene& scene, std::vector<SceneLoader::LoadedNode> nodes);
};
}
#endif // __OPENSPACE_CORE___SCENELOADER___H__
@@ -21,55 +21,27 @@
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#ifndef __OPENSPACE_CORE___SCENEGRAPH___H__
#define __OPENSPACE_CORE___SCENEGRAPH___H__
#ifndef __OPENSPACE_CORE___SCENEMANAGER___H__
#define __OPENSPACE_CORE___SCENEMANAGER___H__
#include <vector>
#include <string>
#include <memory>
namespace openspace {
class SceneGraphNode;
class Scene;
class SceneGraph {
class SceneManager {
public:
SceneGraph();
~SceneGraph();
void clear();
bool loadFromFile(const std::string& sceneDescription);
// Returns if addition was successful
bool addSceneGraphNode(SceneGraphNode* node);
bool removeSceneGraphNode(SceneGraphNode* node);
const std::vector<SceneGraphNode*>& nodes() const;
SceneGraphNode* rootNode() const;
SceneGraphNode* sceneGraphNode(const std::string& name) const;
SceneManager() = default;
~SceneManager() = default;
Scene* loadScene(const std::string& path);
void unloadScene(Scene& scene);
private:
struct SceneGraphNodeInternal {
~SceneGraphNodeInternal();
SceneGraphNode* node = nullptr;
// From nodes that are dependent on this one
std::vector<SceneGraphNodeInternal*> incomingEdges;
// To nodes that this node depends on
std::vector<SceneGraphNodeInternal*> outgoingEdges;
};
bool nodeIsDependentOnRoot(SceneGraphNodeInternal* node);
bool sortTopologically();
SceneGraphNodeInternal* nodeByName(const std::string& name);
SceneGraphNode* _rootNode;
std::vector<SceneGraphNodeInternal*> _nodes;
std::vector<SceneGraphNode*> _topologicalSortedNodes;
std::vector<std::unique_ptr<Scene>> _scenes;
};
} // namespace openspace
}
#endif // __OPENSPACE_CORE___SCENEGRAPH___H__
#endif // __OPENSPACE_CORE___SCENEMANAGER___H__