mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-05-06 03:19:17 -05:00
Merge remote-tracking branch 'origin/NewHorizonsMerge' into feature/timelinegui
Conflicts: src/rendering/renderengine.cpp src/util/imagesequencer2.cpp
This commit is contained in:
@@ -31,6 +31,6 @@
|
||||
</Window>
|
||||
</Node>
|
||||
<User eyeSeparation="0.065">
|
||||
<Pos x="0.0" y="0.0" z="4.0" />
|
||||
<Pos x="0.0" y="0.0" z="2.0" />
|
||||
</User>
|
||||
</Cluster>
|
||||
@@ -2,7 +2,8 @@
|
||||
<Cluster masterAddress="127.0.0.1">
|
||||
<Node address="127.0.0.1" port="20401">
|
||||
<Window fullScreen="false">
|
||||
<Stereo type="none" />
|
||||
<Stereo type="side_by_side" />
|
||||
<!-- <Stereo type="side_by_side_inverted" /> -->
|
||||
<Pos x="200" y="300" />
|
||||
<!-- 16:9 aspect ratio -->
|
||||
<Size x="1280" y="360" />
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#ifndef __CONTROLLER_H__
|
||||
#define __CONTROLLER_H__
|
||||
|
||||
#include <openspace/scenegraph/scenegraphnode.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
|
||||
#include <ghoul/glm.h>
|
||||
#include <glm/gtx/vector_angle.hpp>
|
||||
|
||||
@@ -33,10 +33,10 @@ namespace properties {
|
||||
class Property;
|
||||
}
|
||||
class Renderable;
|
||||
class SceneGraph;
|
||||
class Scene;
|
||||
class SceneGraphNode;
|
||||
|
||||
SceneGraph* sceneGraph();
|
||||
Scene* sceneGraph();
|
||||
SceneGraphNode* sceneGraphNode(const std::string& name);
|
||||
Renderable* renderable(const std::string& name);
|
||||
properties::Property* property(const std::string& uri);
|
||||
|
||||
@@ -37,14 +37,34 @@ class ModelGeometry : public properties::PropertyOwner {
|
||||
public:
|
||||
static ModelGeometry* createFromDictionary(const ghoul::Dictionary& dictionary);
|
||||
|
||||
ModelGeometry();
|
||||
ModelGeometry(const ghoul::Dictionary& dictionary);
|
||||
virtual ~ModelGeometry();
|
||||
virtual bool initialize(RenderableModel* parent);
|
||||
virtual void deinitialize();
|
||||
virtual void render() = 0;
|
||||
void render();
|
||||
virtual bool loadModel(const std::string& filename) = 0;
|
||||
void changeRenderMode(const GLenum mode);
|
||||
|
||||
protected:
|
||||
RenderableModel* _parent;
|
||||
struct Vertex {
|
||||
GLfloat location[4];
|
||||
GLfloat tex[2];
|
||||
GLfloat normal[3];
|
||||
};
|
||||
|
||||
bool loadObj(const std::string& filename);
|
||||
bool loadCachedFile(const std::string& filename);
|
||||
bool saveCachedFile(const std::string& filename);
|
||||
|
||||
GLuint _vaoID;
|
||||
GLuint _vbo;
|
||||
GLuint _ibo;
|
||||
GLenum _mode;
|
||||
|
||||
std::vector<Vertex> _vertices;
|
||||
std::vector<int> _indices;
|
||||
std::string _file;
|
||||
};
|
||||
|
||||
} // namespace modelgeometry
|
||||
|
||||
@@ -57,27 +57,25 @@ protected:
|
||||
|
||||
private:
|
||||
properties::StringProperty _colorTexturePath;
|
||||
properties::StringProperty _bumpTexturePath;
|
||||
|
||||
properties::BoolProperty _performFade;
|
||||
properties::FloatProperty _fading;
|
||||
ghoul::opengl::ProgramObject* _programObject;
|
||||
ghoul::opengl::Texture* _texture;
|
||||
ghoul::opengl::Texture* _bumpMap;
|
||||
|
||||
|
||||
modelgeometry::ModelGeometry* _geometry;
|
||||
|
||||
float _alpha;
|
||||
glm::dmat3 _stateMatrix;
|
||||
|
||||
std::string _source;
|
||||
std::string _destination;
|
||||
std::string _target;
|
||||
|
||||
bool _isGhost;
|
||||
|
||||
psc _sunPosition;
|
||||
|
||||
properties::BoolProperty _performShading;
|
||||
properties::BoolProperty _performFade;
|
||||
|
||||
properties::FloatProperty _fading;
|
||||
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __WAVEFRONTOBJECT_H__
|
||||
#define __WAVEFRONTOBJECT_H__
|
||||
#ifndef __WAVEFRONTGEOMETRY_H__
|
||||
#define __WAVEFRONTGEOMETRY_H__
|
||||
|
||||
#include <openspace/rendering/model/modelgeometry.h>
|
||||
|
||||
@@ -37,28 +37,11 @@ class WavefrontGeometry : public ModelGeometry {
|
||||
public:
|
||||
WavefrontGeometry(const ghoul::Dictionary& dictionary);
|
||||
|
||||
bool initialize(RenderableModel* parent) override;
|
||||
bool initialize(RenderableModel* parent) override;
|
||||
void deinitialize() override;
|
||||
void render() override;
|
||||
|
||||
private:
|
||||
struct Vertex {
|
||||
GLfloat location[4];
|
||||
GLfloat tex[2];
|
||||
GLfloat normal[3];
|
||||
};
|
||||
|
||||
bool loadObj(const std::string& filename);
|
||||
bool loadCachedFile(const std::string& filename);
|
||||
bool saveCachedFile(const std::string& filename);
|
||||
bool loadModel(const std::string& filename);
|
||||
|
||||
GLuint _vaoID;
|
||||
GLuint _vbo;
|
||||
GLuint _ibo;
|
||||
|
||||
std::vector<Vertex> _vertices;
|
||||
std::vector<int> _indices;
|
||||
bool loadModel(const std::string& filename);
|
||||
};
|
||||
|
||||
} // namespace modelgeometry
|
||||
|
||||
@@ -64,13 +64,17 @@ private:
|
||||
properties::StringProperty _colorTexturePath;
|
||||
ghoul::opengl::ProgramObject* _programObject;
|
||||
ghoul::opengl::Texture* _texture;
|
||||
ghoul::opengl::Texture* _nightTexture;
|
||||
planetgeometry::PlanetGeometry* _geometry;
|
||||
properties::BoolProperty _performShading;
|
||||
properties::IntProperty _rotation;
|
||||
float _alpha;
|
||||
|
||||
glm::dmat3 _stateMatrix;
|
||||
|
||||
std::string _nightTexturePath;
|
||||
std::string _frame;
|
||||
std::string _target;
|
||||
bool _hasNightTexture;
|
||||
double _time;
|
||||
};
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
|
||||
// open space includes
|
||||
#include <openspace/rendering/renderable.h>
|
||||
#include <openspace/util/imagesequencer.h>
|
||||
#include <openspace/util/imagesequencer2.h>
|
||||
|
||||
#include <openspace/util/sequenceparser.h>
|
||||
@@ -82,12 +81,14 @@ private:
|
||||
|
||||
properties::StringProperty _colorTexturePath;
|
||||
properties::StringProperty _projectionTexturePath;
|
||||
properties::TriggerProperty _imageTrigger;
|
||||
properties::IntProperty _rotation;
|
||||
properties::FloatProperty _fadeProjection;
|
||||
|
||||
ghoul::opengl::ProgramObject* _programObject;
|
||||
ghoul::opengl::ProgramObject* _fboProgramObject;
|
||||
|
||||
ghoul::opengl::Texture* _texture;
|
||||
ghoul::opengl::Texture* _textureOriginal;
|
||||
ghoul::opengl::Texture* _textureProj;
|
||||
planetgeometryprojection::PlanetGeometryProjection* _geometry;
|
||||
|
||||
@@ -123,12 +124,14 @@ private:
|
||||
double _previousCapture;
|
||||
double lightTime;
|
||||
|
||||
std::vector<std::pair<double, std::string>> _imageTimes;
|
||||
std::vector<Image> _imageTimes;
|
||||
int _sequenceID;
|
||||
|
||||
std::string _target;
|
||||
std::string _frame;
|
||||
std::string _defaultProjImage;
|
||||
std::string _next;
|
||||
|
||||
bool _capture;
|
||||
|
||||
// FBO stuff
|
||||
|
||||
@@ -50,8 +50,10 @@ public:
|
||||
private:
|
||||
void createSphere();
|
||||
|
||||
properties::Vec2Property _radius;
|
||||
glm::vec2 _modRadius;
|
||||
properties::Vec4Property _realRadius;
|
||||
properties::IntProperty _segments;
|
||||
std::string _name;
|
||||
|
||||
PowerScaledSphere* _sphere;
|
||||
};
|
||||
|
||||
@@ -49,9 +49,10 @@ public:
|
||||
private:
|
||||
void createSphere();
|
||||
|
||||
properties::Vec2Property _radius;
|
||||
glm::vec2 _modRadius;
|
||||
properties::Vec4Property _realRadius;
|
||||
properties::IntProperty _segments;
|
||||
|
||||
std::string _name;
|
||||
|
||||
properties::IntProperty _vaoID;
|
||||
properties::IntProperty _vBufferID;
|
||||
|
||||
@@ -69,6 +69,13 @@ public:
|
||||
virtual void update(const UpdateData& data);
|
||||
|
||||
bool isVisible() const;
|
||||
|
||||
bool hasTimeInterval();
|
||||
bool getInterval(double& start, double& end);
|
||||
|
||||
bool hasBody();
|
||||
bool getBody(std::string& body);
|
||||
void setBody(std::string& body);
|
||||
|
||||
protected:
|
||||
std::string findPath(const std::string& path);
|
||||
@@ -79,6 +86,11 @@ private:
|
||||
|
||||
PowerScaledScalar boundingSphere_;
|
||||
std::string _relativePath;
|
||||
std::string _startTime;
|
||||
std::string _endTime;
|
||||
std::string _targetBody;
|
||||
bool _hasBody;
|
||||
bool _hasTimeInterval;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -53,6 +53,7 @@ public:
|
||||
|
||||
private:
|
||||
properties::FloatProperty _lineWidth;
|
||||
properties::BoolProperty _drawSolid;
|
||||
ghoul::opengl::ProgramObject* _programObject;
|
||||
ghoul::opengl::Texture* _texture;
|
||||
openspace::SceneGraphNode* _targetNode;
|
||||
@@ -76,9 +77,9 @@ public:
|
||||
int _nrInserted = 0;
|
||||
int _isteps;
|
||||
bool _rebuild = false;
|
||||
bool _interceptTag[5];
|
||||
bool _interceptTag[9];
|
||||
bool _withinFOV;
|
||||
psc _projectionBounds[4];
|
||||
psc _projectionBounds[8];
|
||||
psc _interceptVector;
|
||||
|
||||
// spice
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2015 *
|
||||
* *
|
||||
* 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 _RENDERABLEPLANEPROJECTION_H_
|
||||
#define _RENDERABLEPLANEPROJECTION_H_
|
||||
|
||||
#include <openspace/rendering/renderable.h>
|
||||
|
||||
#include <openspace/properties/stringproperty.h>
|
||||
#include <openspace/util/imagesequencer2.h>
|
||||
#include <openspace/properties/vectorproperty.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
|
||||
namespace ghoul {
|
||||
namespace filesystem {
|
||||
class File;
|
||||
}
|
||||
namespace opengl {
|
||||
class ProgramObject;
|
||||
class Texture;
|
||||
}
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
struct LinePoint;
|
||||
|
||||
struct target {
|
||||
std::string body;
|
||||
std::string frame;
|
||||
std::string node;
|
||||
};
|
||||
|
||||
class RenderablePlaneProjection : public Renderable {
|
||||
|
||||
|
||||
public:
|
||||
RenderablePlaneProjection(const ghoul::Dictionary& dictionary);
|
||||
~RenderablePlaneProjection();
|
||||
|
||||
bool initialize() override;
|
||||
bool deinitialize() override;
|
||||
|
||||
bool isReady() const override;
|
||||
|
||||
void render(const RenderData& data) override;
|
||||
void update(const UpdateData& data) override;
|
||||
|
||||
private:
|
||||
void loadTexture();
|
||||
void updatePlane(const Image* img, double currentTime);
|
||||
std::string findClosestTarget(double currentTime);
|
||||
void setTarget(std::string body);
|
||||
|
||||
std::string _texturePath;
|
||||
|
||||
bool _planeIsDirty;
|
||||
|
||||
glm::dmat3 _stateMatrix;
|
||||
std::string _frame;
|
||||
|
||||
ghoul::opengl::ProgramObject* _shader;
|
||||
bool _programIsDirty;
|
||||
bool _textureIsDirty;
|
||||
ghoul::opengl::Texture* _texture;
|
||||
ghoul::filesystem::File* _textureFile;
|
||||
GLuint _quad;
|
||||
GLuint _vertexPositionBuffer;
|
||||
std::string _spacecraft;
|
||||
std::string _instrument;
|
||||
|
||||
target _target;
|
||||
std::string _name;
|
||||
bool _moving;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
#endif
|
||||
@@ -63,6 +63,7 @@ private:
|
||||
properties::Vec3Property _lineColor;
|
||||
properties::FloatProperty _lineFade;
|
||||
properties::FloatProperty _lineWidth;
|
||||
properties::BoolProperty _showTimestamps;
|
||||
|
||||
ghoul::opengl::ProgramObject* _programObject;
|
||||
bool _programIsDirty;
|
||||
@@ -86,6 +87,8 @@ private:
|
||||
|
||||
float _increment;
|
||||
float _oldTime = 0;
|
||||
float _time;
|
||||
float _distanceFade;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace openspace {
|
||||
// Forward declare to minimize dependencies
|
||||
class Camera;
|
||||
class SyncBuffer;
|
||||
class SceneGraph;
|
||||
class Scene;
|
||||
class ABuffer;
|
||||
class ABufferVisualizer;
|
||||
class ScreenLog;
|
||||
@@ -53,8 +53,8 @@ public:
|
||||
|
||||
bool initialize();
|
||||
|
||||
void setSceneGraph(SceneGraph* sceneGraph);
|
||||
SceneGraph* sceneGraph();
|
||||
void setSceneGraph(Scene* sceneGraph);
|
||||
Scene* scene();
|
||||
|
||||
Camera* camera() const;
|
||||
ABuffer* abuffer() const;
|
||||
@@ -111,7 +111,7 @@ private:
|
||||
void storePerformanceMeasurements();
|
||||
|
||||
Camera* _mainCamera;
|
||||
SceneGraph* _sceneGraph;
|
||||
Scene* _sceneGraph;
|
||||
ABuffer* _abuffer;
|
||||
ScreenLog* _log;
|
||||
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2015 *
|
||||
* *
|
||||
* 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 __DYNAMICEPHEMERIS_H__
|
||||
#define __DYNAMICEPHEMERIS_H__
|
||||
|
||||
#include "ephemeris.h"
|
||||
|
||||
namespace openspace {
|
||||
|
||||
class DynamicEphemeris: public Ephemeris {
|
||||
public:
|
||||
DynamicEphemeris(const ghoul::Dictionary& dictionary
|
||||
= ghoul::Dictionary());
|
||||
virtual ~DynamicEphemeris();
|
||||
virtual const psc& position() const;
|
||||
virtual void update(const UpdateData& data) override;
|
||||
void setPosition(psc pos);
|
||||
private:
|
||||
psc _position;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __DYNAMICEPHEMERIS_H__
|
||||
@@ -22,8 +22,8 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __SCENEGRAPH_H__
|
||||
#define __SCENEGRAPH_H__
|
||||
#ifndef __SCENE_H__
|
||||
#define __SCENE_H__
|
||||
|
||||
// std includes
|
||||
#include <vector>
|
||||
@@ -34,6 +34,7 @@
|
||||
#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>
|
||||
@@ -45,11 +46,11 @@ class SceneGraphNode;
|
||||
|
||||
// Notifications:
|
||||
// SceneGraphFinishedLoading
|
||||
class SceneGraph {
|
||||
class Scene {
|
||||
public:
|
||||
// constructors & destructor
|
||||
SceneGraph();
|
||||
~SceneGraph();
|
||||
Scene();
|
||||
~Scene();
|
||||
|
||||
/**
|
||||
* Initalizes the SceneGraph by loading modules from the ${SCENEPATH} directory
|
||||
@@ -95,7 +96,7 @@ public:
|
||||
*/
|
||||
SceneGraphNode* sceneGraphNode(const std::string& name) const;
|
||||
|
||||
std::vector<SceneGraphNode*> allSceneGraphNodes() const;
|
||||
std::vector<SceneGraphNode*> allSceneGraphNodes();
|
||||
|
||||
/**
|
||||
* Returns the Lua library that contains all Lua functions available to change the
|
||||
@@ -115,9 +116,10 @@ private:
|
||||
std::string _focus;
|
||||
|
||||
// actual scenegraph
|
||||
SceneGraphNode* _root;
|
||||
std::vector<SceneGraphNode*> _nodes;
|
||||
std::map<std::string, SceneGraphNode*> _allNodes;
|
||||
SceneGraph _graph;
|
||||
//SceneGraphNode* _root;
|
||||
//std::vector<SceneGraphNode*> _nodes;
|
||||
//std::map<std::string, SceneGraphNode*> _allNodes;
|
||||
|
||||
std::string _sceneGraphToLoad;
|
||||
|
||||
@@ -143,4 +145,4 @@ private:
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __SCENEGRAPH_H__
|
||||
#endif // __SCENE_H__
|
||||
@@ -0,0 +1,74 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2015 *
|
||||
* *
|
||||
* 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 __SCENEGRAPH_H__
|
||||
#define __SCENEGRAPH_H__
|
||||
|
||||
#include <ghoul/misc/dictionary.h>
|
||||
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
class SceneGraphNode;
|
||||
|
||||
class SceneGraph {
|
||||
public:
|
||||
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();
|
||||
|
||||
SceneGraphNode* rootNode() const;
|
||||
SceneGraphNode* sceneGraphNode(const std::string& name) const;
|
||||
|
||||
private:
|
||||
struct SceneGraphNodeInternal {
|
||||
SceneGraphNode* node;
|
||||
// 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 sortTopologially();
|
||||
|
||||
SceneGraphNodeInternal* nodeByName(const std::string& name);
|
||||
|
||||
SceneGraphNode* _rootNode;
|
||||
std::vector<SceneGraphNodeInternal*> _nodes;
|
||||
std::vector<SceneGraphNode*> _topologicalSortedNodes;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __SCENEGRAPH_H__
|
||||
+5
-3
@@ -27,10 +27,10 @@
|
||||
|
||||
// open space includes
|
||||
#include <openspace/rendering/renderable.h>
|
||||
#include <openspace/scenegraph/ephemeris.h>
|
||||
#include <openspace/scene/ephemeris.h>
|
||||
#include <openspace/properties/propertyowner.h>
|
||||
|
||||
#include <openspace/scenegraph/scenegraph.h>
|
||||
#include <openspace/scene/scene.h>
|
||||
#include <ghoul/misc/dictionary.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
|
||||
@@ -65,9 +65,11 @@ public:
|
||||
void render(const RenderData& data);
|
||||
void updateCamera(Camera* camera) const;
|
||||
|
||||
void addNode(SceneGraphNode* child);
|
||||
//void addNode(SceneGraphNode* child);
|
||||
|
||||
void setParent(SceneGraphNode* parent);
|
||||
//bool abandonChild(SceneGraphNode* child);
|
||||
|
||||
const psc& position() const;
|
||||
psc worldPosition() const;
|
||||
|
||||
+3
-1
@@ -25,7 +25,7 @@
|
||||
#ifndef __SPICEEPHEMERIS_H__
|
||||
#define __SPICEEPHEMERIS_H__
|
||||
|
||||
#include <openspace/scenegraph/ephemeris.h>
|
||||
#include <openspace/scene/ephemeris.h>
|
||||
|
||||
#include <openspace/util/powerscaledcoordinate.h>
|
||||
|
||||
@@ -42,6 +42,8 @@ private:
|
||||
std::string _originName;
|
||||
psc _position;
|
||||
bool _kernelsLoadedSuccessfully;
|
||||
std::string _ghosting;
|
||||
std::string _name;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
@@ -1,122 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2015 *
|
||||
* *
|
||||
* 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. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <openspace/scenegraph/scenegraph.h>
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/util/time.h>
|
||||
#include <openspace/util/spice.h>
|
||||
#include <openspace/util/factorymanager.h>
|
||||
|
||||
class SceneGraphTest : public testing::Test {
|
||||
protected:
|
||||
SceneGraphTest() {
|
||||
_scenegraph = new openspace::SceneGraph;
|
||||
}
|
||||
|
||||
~SceneGraphTest() {
|
||||
_scenegraph = new openspace::SceneGraph;
|
||||
}
|
||||
|
||||
void reset() {
|
||||
delete _scenegraph;
|
||||
_scenegraph = new openspace::SceneGraph;
|
||||
}
|
||||
|
||||
openspace::SceneGraph* _scenegraph;
|
||||
};
|
||||
|
||||
TEST_F(SceneGraphTest, SceneGraphNode) {
|
||||
|
||||
openspace::SceneGraphNode *node =
|
||||
openspace::SceneGraphNode::createFromDictionary(ghoul::Dictionary());
|
||||
|
||||
// Should not have a renderable and position should be 0,0,0,0 (undefined).
|
||||
EXPECT_EQ(nullptr, node->renderable());
|
||||
EXPECT_EQ(openspace::psc(), node->position());
|
||||
|
||||
delete node;
|
||||
ghoul::Dictionary nodeDictionary;
|
||||
|
||||
ghoul::Dictionary positionDictionary;
|
||||
ghoul::Dictionary positionPositionArrayDictionary;
|
||||
|
||||
ghoul::Dictionary renderableDictionary;
|
||||
|
||||
renderableDictionary.setValue("Type", std::string("RenderablePlanet"));
|
||||
|
||||
positionPositionArrayDictionary.setValue("1", 1.0);
|
||||
positionPositionArrayDictionary.setValue("2", 1.0);
|
||||
positionPositionArrayDictionary.setValue("3", 1.0);
|
||||
positionPositionArrayDictionary.setValue("4", 1.0);
|
||||
|
||||
positionDictionary.setValue("Type", std::string("Static"));
|
||||
positionDictionary.setValue("Position", positionPositionArrayDictionary);
|
||||
|
||||
nodeDictionary.setValue("Position", positionDictionary);
|
||||
nodeDictionary.setValue("Renderable", renderableDictionary);
|
||||
|
||||
node =
|
||||
openspace::SceneGraphNode::createFromDictionary(nodeDictionary);
|
||||
|
||||
// This node should have a renderable (probably no good values but an existing one)
|
||||
EXPECT_TRUE(node->renderable());
|
||||
|
||||
// position should be initialized
|
||||
EXPECT_EQ(openspace::psc(1.0,1.0,1.0,1.0), node->position());
|
||||
|
||||
delete node;
|
||||
}
|
||||
|
||||
TEST_F(SceneGraphTest, Loading) {
|
||||
|
||||
|
||||
// Should not successfully load a non existing scenegraph
|
||||
EXPECT_FALSE(_scenegraph->loadScene(absPath("${TESTDIR}/ScenegraphTestNonExisting"), absPath("${TESTDIR}")));
|
||||
|
||||
// Existing scenegraph should load
|
||||
EXPECT_TRUE(_scenegraph->loadScene(absPath("${TESTDIR}/ScenegraphTest"), absPath("${TESTDIR}")));
|
||||
// TODO need to check for correctness
|
||||
|
||||
// This loading should fail regardless of existing or not since the
|
||||
// scenegraph is already loaded
|
||||
EXPECT_FALSE(_scenegraph->loadScene(absPath("${TESTDIR}/ScenegraphTest"), absPath("${TESTDIR}")));
|
||||
}
|
||||
|
||||
TEST_F(SceneGraphTest, Reinitializing) {
|
||||
|
||||
// Existing scenegraph should load
|
||||
EXPECT_TRUE(_scenegraph->loadScene(absPath("${TESTDIR}/ScenegraphTest"), absPath("${TESTDIR}")));
|
||||
|
||||
_scenegraph->deinitialize();
|
||||
|
||||
// Existing scenegraph should load
|
||||
EXPECT_TRUE(_scenegraph->loadScene(absPath("${TESTDIR}/ScenegraphTest"), absPath("${TESTDIR}")));
|
||||
// TODO need to check for correctness
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -72,6 +72,7 @@ namespace scenegraph {
|
||||
namespace scenegraphnode {
|
||||
const std::string keyName = "Name";
|
||||
const std::string keyParentName = "Parent";
|
||||
const std::string keyDependencies = "Dependencies";
|
||||
const std::string keyRenderable = "Renderable";
|
||||
const std::string keyEphemeris = "Ephemeris";
|
||||
} // namespace scenegraphnode
|
||||
@@ -88,6 +89,15 @@ namespace renderablemodel {
|
||||
const std::string keyGeometry = "Geometry";
|
||||
} // namespace renderablemodel
|
||||
|
||||
namespace renderableplaneprojection {
|
||||
const std::string keySpacecraft = "Spacecraft";
|
||||
const std::string keyInstrument = "Instrument";
|
||||
const std::string keyMoving = "Moving";
|
||||
const std::string keyTexture = "Texture";
|
||||
const std::string keyName = "Name";
|
||||
const std::string galacticFrame = "GALACTIC";
|
||||
} // namespace renderableplaneprojection
|
||||
|
||||
namespace renderablestars {
|
||||
const std::string keyFile = "File";
|
||||
const std::string keyTexture = "Texture";
|
||||
@@ -121,6 +131,10 @@ namespace staticephemeris {
|
||||
const std::string keyPosition = "Position";
|
||||
} // namespace staticephemeris
|
||||
|
||||
namespace dynamicephemeris {
|
||||
const std::string keyPosition = "Position";
|
||||
} // namespace dynamicephemeris
|
||||
|
||||
namespace spiceephemeris {
|
||||
const std::string keyBody = "Body";
|
||||
const std::string keyOrigin = "Observer";
|
||||
|
||||
@@ -36,6 +36,19 @@
|
||||
#include <openspace/util/sequenceparser.h>
|
||||
|
||||
namespace openspace {
|
||||
/**
|
||||
* The ImageSequencer singleton main function is to manage the timekeeping and
|
||||
* distribution of large image data-sets across all openspace renderable instances,
|
||||
* both for past and future unmanned-spacecraft missions. To load the instance with
|
||||
* data the client must provide a parser inherited from the abstract base class
|
||||
* SequenceParser. Hence, there is no restriction imposed on data input, whether its
|
||||
* data in the form of existing images or in the form of a planned observation schedule.
|
||||
* Notably, in order for the sequencer to function the client must provide or write a
|
||||
* parser that fills the ImageSequencers private members.
|
||||
* \see SequenceParser
|
||||
* \see ImageSequencer2::runSequenceParser(SequenceParser* parser)
|
||||
* std::map<std::string, bool>
|
||||
*/
|
||||
class ImageSequencer2 {
|
||||
public:
|
||||
ImageSequencer2();
|
||||
@@ -43,65 +56,145 @@ public:
|
||||
* Singelton instantiation
|
||||
*/
|
||||
static ImageSequencer2* _instance;
|
||||
|
||||
/**
|
||||
* Returns the reference to the singleton ImageSequencer object that must have been
|
||||
* initialized by a call to the initialize method earlier.
|
||||
* \return The ImageSequencer singleton
|
||||
*/
|
||||
static ImageSequencer2& ref();
|
||||
/**
|
||||
* Initializer that initializes the static member.
|
||||
*/
|
||||
static void initialize();
|
||||
/**
|
||||
* Deinitializes that deinitializes the static member.
|
||||
*/
|
||||
static void deinitialize();
|
||||
|
||||
/**
|
||||
* Returns true if sequencer has been loaded with data.
|
||||
*/
|
||||
bool isReady();
|
||||
|
||||
//provides the sequencer with current time
|
||||
/**
|
||||
* Updates sequencer with current <code>time</code>. This is used internally for keeping
|
||||
* track of both current simulation time and the time of the previously rendered frame.
|
||||
*/
|
||||
void updateSequencer(double time);
|
||||
/**
|
||||
* Runs parser and recieves the datastructures filled by it.
|
||||
* \see SequenceParser
|
||||
*/
|
||||
void runSequenceParser(SequenceParser* parser);
|
||||
|
||||
//translates playbook ambiguous namesetting to spice calls, augments each observation with targets and
|
||||
//stores all images in its own subset (see _subsetMap member)
|
||||
bool parsePlaybookFile(const std::string& fileName,
|
||||
std::string spacecraft,
|
||||
std::map<std::string, std::vector<std::string>> acronymDictionary,
|
||||
std::vector<std::string> potentialTargets);
|
||||
|
||||
// returns upcoming target
|
||||
/**
|
||||
* Retrieves the next upcoming target in time.
|
||||
*/
|
||||
std::pair<double, std::string> getNextTarget();
|
||||
// returns next target
|
||||
|
||||
/**
|
||||
* Retrieves the most current target in time.
|
||||
*/
|
||||
std::pair<double, std::string> getCurrentTarget();
|
||||
// returns current target and (in the list) adjacent targets, the number to retrieve is user set
|
||||
|
||||
/**
|
||||
* Retrieves current target and (in the list) adjacent targets, the number to retrieve is user set
|
||||
*/
|
||||
std::pair<double, std::vector<std::string>> getIncidentTargetList(int range = 2);
|
||||
|
||||
/**
|
||||
* Retrieves the next upcoming time of image capture.
|
||||
*/
|
||||
double getNextCaptureTime();
|
||||
|
||||
/**
|
||||
* Retrieves the time interval length between the current time and an upcoming capture.
|
||||
*/
|
||||
double getIntervalLength();
|
||||
std::vector<std::pair<std::string, bool>> getActiveInstruments();
|
||||
bool ImageSequencer2::getImagePaths(std::vector<std::pair<double, std::string>>& captures, std::string projectee, std::string instrumentID);
|
||||
bool ImageSequencer2::getImagePaths(std::vector<std::pair<double, std::string>>& captures, std::string projectee);
|
||||
|
||||
/*
|
||||
* Returns a map with key instrument names whose value indicate whether
|
||||
* an instrument is active or not.
|
||||
*/
|
||||
std::map<std::string, bool> getActiveInstruments();
|
||||
|
||||
/*
|
||||
* Retrieves the relevant data from a specific subset based on the what instance
|
||||
* makes the request. If an instance is not registered in the class then the singleton
|
||||
* returns false and no projections will occur.
|
||||
*/
|
||||
bool ImageSequencer2::getImagePaths(std::vector<Image>& captures,
|
||||
std::string projectee,
|
||||
std::string instrumentID);
|
||||
|
||||
bool ImageSequencer2::getImagePaths(std::vector<Image>& captures,
|
||||
std::string projectee);
|
||||
|
||||
/*
|
||||
* returns true if instrumentID is within a capture range.
|
||||
*/
|
||||
bool instumentActive(std::string instrumentID);
|
||||
|
||||
const Image* findLatestImageInSubset( ImageSubset& subset);
|
||||
/*
|
||||
* returns latest captured image
|
||||
*/
|
||||
const Image* getLatestImageForInstrument(const std::string _instrumentID);
|
||||
private:
|
||||
//default comparison function
|
||||
bool imageComparer(const Image &a, const Image &b);
|
||||
|
||||
//binary find O(log n) always
|
||||
std::vector<Image>::iterator binary_find(std::vector<Image>::iterator begin,
|
||||
std::vector<Image>::iterator end,
|
||||
const Image &val,
|
||||
bool(*imageComparer)(const Image &a, const Image &b));
|
||||
|
||||
//var
|
||||
double _currentTime;
|
||||
double _previousTime;
|
||||
double _intervalLength;
|
||||
double _nextCapture;
|
||||
|
||||
std::string _defaultCaptureImage;
|
||||
std::vector<std::pair<std::string, bool>> _instrumentOnOff;
|
||||
|
||||
std::map<std::string, ImageSubset> _subsetMap;
|
||||
std::vector<std::pair<double, std::string>> _targetTimes;
|
||||
std::vector<std::pair<std::string, TimeRange>> _instrumentTimes;
|
||||
std::vector<double> _captureProgression;
|
||||
void sortData();
|
||||
|
||||
/*
|
||||
* _fileTranslation handles any types of ambiguities between the data and
|
||||
* spice/openspace -calls. This map is composed of a key that is a string in
|
||||
* the data to be translated and a Decoder that holds the corresponding
|
||||
* translation provided through a modfile.
|
||||
* \see Decoder
|
||||
* \see (projection mod files)
|
||||
*/
|
||||
std::map<std::string, Decoder*> _fileTranslation;
|
||||
|
||||
/*
|
||||
* This is the main container of image data. The key is the target name,
|
||||
* the value is a subset of images.
|
||||
* \see SequenceParser
|
||||
*/
|
||||
std::map<std::string, ImageSubset> _subsetMap;
|
||||
|
||||
/*
|
||||
* In order for the simulation to know when to turn on/off any instrument within
|
||||
* all instruments in the spacecraft payload, the key is the data-file given
|
||||
* instrument name.
|
||||
*/
|
||||
std::map<std::string, bool> _switchingMap;
|
||||
|
||||
/*
|
||||
* This datastructure holds the specific times when the spacecraft switches from
|
||||
* observing one inertial body to the next. This happens a lot in such missions
|
||||
* and the coupling of target with specific time is usually therefore not 1:1.
|
||||
*/
|
||||
std::vector<std::pair<double, std::string>> _targetTimes;
|
||||
|
||||
/*
|
||||
* Holds the time ranges of each instruments on and off periods. An instrument
|
||||
* rendering class may ask the ImageSequencer whether or not it
|
||||
*/
|
||||
std::vector<std::pair<std::string, TimeRange>> _instrumentTimes;
|
||||
|
||||
/*
|
||||
* Each consecutive images capture time, for easier traversal.
|
||||
*/
|
||||
std::vector<double> _captureProgression;
|
||||
|
||||
// current simulation time
|
||||
double _currentTime;
|
||||
// simulation time of previous frame
|
||||
double _previousTime;
|
||||
// time between current simulation time and an upcoming capture
|
||||
double _intervalLength;
|
||||
// next consecutive capture in time
|
||||
double _nextCapture;
|
||||
// default capture image
|
||||
std::string _defaultCaptureImage;
|
||||
|
||||
Image* _latestImage;
|
||||
// if no data, no run
|
||||
bool _hasData;
|
||||
};
|
||||
|
||||
|
||||
@@ -36,8 +36,10 @@ public:
|
||||
InstrumentDecoder(const ghoul::Dictionary& dictionary);
|
||||
virtual std::string getDecoderType();
|
||||
virtual std::vector<std::string> getTranslation();
|
||||
std::string getStopCommand();
|
||||
private:
|
||||
std::string _type;
|
||||
std::string _stopCommand;
|
||||
std::vector<std::string> _spiceIDs;
|
||||
};
|
||||
|
||||
|
||||
@@ -33,44 +33,55 @@
|
||||
#include <vector>
|
||||
|
||||
namespace openspace {
|
||||
class LabelParser : public SequenceParser{
|
||||
public:
|
||||
LabelParser();
|
||||
LabelParser(const std::string& fileName,
|
||||
ghoul::Dictionary translationDictionary);
|
||||
virtual void create();
|
||||
virtual std::map<std::string, ImageSubset> getSubsetMap();
|
||||
virtual std::vector<std::pair<std::string, TimeRange>> getIstrumentTimes();
|
||||
virtual std::vector<std::pair<double, std::string>> getTargetTimes();
|
||||
class LabelParser : public SequenceParser{
|
||||
public:
|
||||
LabelParser();
|
||||
LabelParser(const std::string& fileName,
|
||||
ghoul::Dictionary translationDictionary);
|
||||
virtual void create();
|
||||
virtual std::map<std::string, ImageSubset> getSubsetMap();
|
||||
virtual std::vector<std::pair<std::string, TimeRange>> getIstrumentTimes();
|
||||
virtual std::vector<std::pair<double, std::string>> getTargetTimes();
|
||||
|
||||
// temporary need to figure this out
|
||||
std::map<std::string, Decoder*> getTranslation(){ return _fileTranslation; };
|
||||
virtual std::vector<double> getCaptureProgression(){ return _captureProgression; };
|
||||
// temporary need to figure this out
|
||||
std::map<std::string, Decoder*> getTranslation(){ return _fileTranslation; };
|
||||
virtual std::vector<double> getCaptureProgression(){ return _captureProgression; };
|
||||
|
||||
private:
|
||||
void createImage(Image& image,
|
||||
double startTime,
|
||||
double stopTime,
|
||||
std::vector<std::string> instr,
|
||||
std::string targ,
|
||||
std::string pot);
|
||||
private:
|
||||
void createImage(Image& image,
|
||||
double startTime,
|
||||
double stopTime,
|
||||
std::vector<std::string> instr,
|
||||
std::string targ,
|
||||
std::string path);
|
||||
|
||||
bool augmentWithSpice(Image& image,
|
||||
std::string spacecraft,
|
||||
std::vector<std::string> payload,
|
||||
std::vector<std::string> potentialTargets);
|
||||
std::string decode(std::string line);
|
||||
std::string encode(std::string line);
|
||||
|
||||
bool augmentWithSpice(Image& image,
|
||||
std::string spacecraft,
|
||||
std::vector<std::string> payload,
|
||||
std::vector<std::string> potentialTargets);
|
||||
|
||||
std::string _fileName;
|
||||
std::string _spacecraft;
|
||||
std::map<std::string, Decoder*> _fileTranslation;
|
||||
std::vector<std::string> _specsOfInterest;
|
||||
std::string _fileName;
|
||||
std::string _spacecraft;
|
||||
std::map<std::string, Decoder*> _fileTranslation;
|
||||
std::vector<std::string> _specsOfInterest;
|
||||
|
||||
//returnable
|
||||
std::map<std::string, ImageSubset> _subsetMap;
|
||||
std::vector<std::pair<std::string, TimeRange>> _instrumentTimes;
|
||||
std::vector<std::pair<double, std::string>> _targetTimes;
|
||||
std::vector<double> _captureProgression;
|
||||
};
|
||||
//returnable
|
||||
std::map<std::string, ImageSubset> _subsetMap;
|
||||
std::vector<std::pair<std::string, TimeRange>> _instrumentTimes;
|
||||
std::vector<std::pair<double, std::string>> _targetTimes;
|
||||
std::vector<double> _captureProgression;
|
||||
|
||||
|
||||
std::string _target;
|
||||
std::string _instrumentID;
|
||||
std::string _instrumentHostID;
|
||||
std::string _detectorType;
|
||||
std::string _sequenceID;
|
||||
double _startTime;
|
||||
double _stopTime;
|
||||
};
|
||||
}
|
||||
#endif //__LABELPARSER_H__
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <ghoul/opengl/ghoul_gl.h>
|
||||
#include <openspace/util/powerscaledcoordinate.h>
|
||||
#include <openspace/util/powerscaledscalar.h>
|
||||
#include <openspace/properties/vectorproperty.h>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
@@ -37,6 +38,9 @@ public:
|
||||
// initializers
|
||||
PowerScaledSphere(const PowerScaledScalar& radius,
|
||||
int segments = 8);
|
||||
PowerScaledSphere(properties::Vec4Property &radius,
|
||||
int segments, std::string planetName);
|
||||
|
||||
~PowerScaledSphere();
|
||||
PowerScaledSphere(const PowerScaledSphere& cpy);
|
||||
|
||||
|
||||
@@ -35,8 +35,11 @@ public:
|
||||
ScannerDecoder(const ghoul::Dictionary& dictionary);
|
||||
virtual std::string getDecoderType();
|
||||
virtual std::vector<std::string> getSpiceIDs();
|
||||
std::string getStopCommand();
|
||||
void setStopCommand(std::string stopCommand);
|
||||
private:
|
||||
std::string _type;
|
||||
std::string _abort;
|
||||
std::vector<std::string> _spiceIDs;
|
||||
};
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace openspace {
|
||||
double startTime;
|
||||
double stopTime;
|
||||
std::string path;
|
||||
std::vector<std::string> activeInstruments;
|
||||
std::vector<std::string> activeInstruments;
|
||||
std::string target;
|
||||
bool projected;
|
||||
};
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
@@ -76,15 +77,51 @@ public:
|
||||
*/
|
||||
KernelIdentifier loadKernel(const std::string& filePath);
|
||||
|
||||
/**
|
||||
* Function to find and store the intervals covered by a ck file, this is done
|
||||
* by using mainly the <code>ckcov_c</code> and <code>ckobj_c</code> functions.
|
||||
* http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/ckobj_c.html ,
|
||||
* http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/ckcov_c.html
|
||||
* \param filePath The path to the kernel that should be examined
|
||||
* \return true if the operation was successful
|
||||
*/
|
||||
bool findCkCoverage(std::string& path);
|
||||
|
||||
/**
|
||||
* Unloads a SPICE kernel identified by the <code>kernelId</code> which was returned
|
||||
* by the loading call to loadKernel. The unloading is done by calling the
|
||||
* <code>unload_c</code> function.
|
||||
* http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/unload_c.html
|
||||
* \param kernelId The unique identifier that was returned from the call to
|
||||
* loadKernel which loaded the kernel
|
||||
* Function to find and store the intervals covered by a spk file, this is done
|
||||
* by using mainly the <code>spkcov_c</code> and <code>spkobj_c</code> functions.
|
||||
* http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/spkobj_c.html ,
|
||||
* http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/spkcov_c.html
|
||||
* \param filePath The path to the kernel that should be examined
|
||||
* \return true if the operation was successful
|
||||
*/
|
||||
bool findSpkCoverage(std::string& path);
|
||||
|
||||
/**
|
||||
* \return true if SPK kernels have been loaded to cover <code>target</code>
|
||||
* for time <code>et</code>
|
||||
* \param target, the body to be examined
|
||||
* \param et, the time when body is possibly covered
|
||||
*/
|
||||
|
||||
bool hasSpkCoverage(std::string target, double& et) const;
|
||||
|
||||
/**
|
||||
* \return true if CK kernels have been loaded to cover <code>frame</code>
|
||||
* for time <code>et</code>
|
||||
* \param frame, the frame to be examined
|
||||
* \param et, the time when frame is possibly covered
|
||||
*/
|
||||
bool hasCkCoverage(std::string frame, double& et) const;
|
||||
|
||||
/**
|
||||
* Unloads a SPICE kernel identified by the <code>kernelId</code> which was returned
|
||||
* by the loading call to loadKernel. The unloading is done by calling the
|
||||
* <code>unload_c</code> function.
|
||||
* http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/unload_c.html.
|
||||
* \param kernelId The unique identifier that was returned from the call to
|
||||
* loadKernel which loaded the kernel
|
||||
*/
|
||||
void unloadKernel(KernelIdentifier kernelId);
|
||||
|
||||
/**
|
||||
@@ -134,6 +171,19 @@ public:
|
||||
*/
|
||||
bool getNaifId(const std::string& body, int& id) const;
|
||||
|
||||
/**
|
||||
* Returns the NAIF ID for a specific frame using namfrm_c(), see
|
||||
* http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/namfrm_c.html.
|
||||
* The <code>id</code> will only be set if the retrieval was successful,
|
||||
* otherwise it will remain unchanged.
|
||||
* \param frame The frame name that should be retrieved
|
||||
* \param id The ID of the <code>frame</code> will be stored in this variable. The
|
||||
* value will only be changed if the retrieval was successful
|
||||
* \return <code>true</code> if the <code>frame</code> was found, <code>false</code>
|
||||
* otherwise
|
||||
*/
|
||||
bool getFrameId(const std::string& frame, int& id) const;
|
||||
|
||||
/**
|
||||
* Retrieves a single <code>value</code> for a certain <code>body</code>. This method
|
||||
* succeeds iff <code>body</code> is the name of a valid body, <code>value</code>
|
||||
@@ -252,26 +302,8 @@ public:
|
||||
* \return <code>true</code> if the conversion succeeded, <code>false</code> otherwise
|
||||
*/
|
||||
bool getDateFromET(double ephemerisTime, std::string& date,
|
||||
const std::string& format = "YYYY MON DDTHR:MN:SC.### ::RND");
|
||||
const std::string& format = "YYYY MON DDTHR:MN:SC.### ::RND") const;
|
||||
|
||||
/**
|
||||
* This helper method converts a 3 dimensional vector from one reference frame to another.
|
||||
* \param v The vector to be converted
|
||||
* \param from The frame to be converted from
|
||||
* \param to The frame to be converted to
|
||||
* \param ephemerisTime Time at which to get rotational matrix that transforms vector
|
||||
* \return <code>true</code> if the conversion succeeded, <code>false</code> otherwise
|
||||
*/
|
||||
bool frameConversion(glm::dvec3& v, const std::string& from, const std::string& to, double ephemerisTime) const;
|
||||
|
||||
/**
|
||||
* Finds the projection of one vector onto another vector.
|
||||
* All vectors are 3-dimensional.
|
||||
* \param v1 The vector to be projected.
|
||||
* \param v2 The vector onto which v1 is to be projected.
|
||||
* \return The projection of v1 onto v2.
|
||||
*/
|
||||
glm::dvec3 orthogonalProjection(glm::dvec3& v1, glm::dvec3& v2);
|
||||
|
||||
/**
|
||||
* Returns the <code>position</code> of a <code>target</code> body relative to an
|
||||
@@ -313,6 +345,39 @@ public:
|
||||
psc& position,
|
||||
double& lightTime) const;
|
||||
|
||||
/**
|
||||
* If a position is requested for an uncovered time in the SPK kernels,
|
||||
* this function will insert a position in <code>modelPosition</code>.
|
||||
* If the coverage has not yet started, the first position will be retrieved,
|
||||
* If the coverage has ended, the last position will be retrieved
|
||||
* If <code>time</code> is in a coverage gap, the position will be interpolated
|
||||
* \param time, for which an estimated position is desirable
|
||||
* \param target, the body which is missing SPK data for this time
|
||||
* \param origin, the observer, the position will be retrieved in relation to this body
|
||||
* \param modelPosition, the position of the body, passed by reference
|
||||
* \return true if an estimated position is found
|
||||
*/
|
||||
bool getEstimatedPosition(const double time, const std::string target, const std::string origin, psc& modelPosition) const;
|
||||
|
||||
/**
|
||||
* This helper method converts a 3 dimensional vector from one reference frame to another.
|
||||
* \param v The vector to be converted
|
||||
* \param from The frame to be converted from
|
||||
* \param to The frame to be converted to
|
||||
* \param ephemerisTime Time at which to get rotational matrix that transforms vector
|
||||
* \return <code>true</code> if the conversion succeeded, <code>false</code> otherwise
|
||||
*/
|
||||
bool frameConversion(glm::dvec3& v, const std::string& from, const std::string& to, double ephemerisTime) const;
|
||||
|
||||
/**
|
||||
* Finds the projection of one vector onto another vector.
|
||||
* All vectors are 3-dimensional.
|
||||
* \param v1 The vector to be projected.
|
||||
* \param v2 The vector onto which v1 is to be projected.
|
||||
* \return The projection of v1 onto v2.
|
||||
*/
|
||||
glm::dvec3 orthogonalProjection(glm::dvec3& v1, glm::dvec3& v2);
|
||||
|
||||
/**
|
||||
* Given an observer and a direction vector defining a ray, compute
|
||||
* the surface intercept of the ray on a target body at a specified
|
||||
@@ -488,11 +553,21 @@ public:
|
||||
double ephemerisTimeTo,
|
||||
glm::dmat3& transformationMatrix) const;
|
||||
|
||||
/**
|
||||
* If a transform matrix is requested for an uncovered time in the CK kernels,
|
||||
* this function will insert a transform matrix in <code>positionMatrix</code>.
|
||||
* If the coverage has not yet started, the first transform matrix will be retrieved,
|
||||
* If the coverage has ended, the last transform matrix will be retrieved
|
||||
* If <code>time</code> is in a coverage gap, the transform matrix will be interpolated
|
||||
* \param time, for which an estimated transform matrix is desirable
|
||||
* \param fromFrame, the transform matrix will be retrieved in relation to this frame
|
||||
* \param toFrame, the frame missing CK data for this time
|
||||
* \param positionMatrix, the estimated transform matrix of the frame, passed by reference
|
||||
* \return true if an estimated transform matrix is found
|
||||
*/
|
||||
bool getEstimatedTransformMatrix(const double time, const std::string fromFrame, const std::string toFrame, glm::dmat3& positionMatrix) const;
|
||||
|
||||
|
||||
bool getPositionPrimeMeridian(const std::string& sourceFrame,
|
||||
const std::string& destinationFrame,
|
||||
double ephemerisTime,
|
||||
glm::dmat3& transformationMatrix) const;
|
||||
|
||||
/**
|
||||
* Applies the <code>transformationMatrix</code> retrieved from
|
||||
@@ -555,88 +630,22 @@ public:
|
||||
*/
|
||||
bool getFieldOfView(int instrument, std::string& fovShape, std::string& frameName,
|
||||
glm::dvec3& boresightVector, std::vector<glm::dvec3>& bounds) const;
|
||||
|
||||
/**
|
||||
* Converts planeto-centric <code>latitude</code> and <code>longitude</code> of a
|
||||
* surface point on a specified <code>body</code> to rectangular
|
||||
* <code>coordinates</code>. For further details, refer to
|
||||
* http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/srfrec_c.html.
|
||||
* \param body The body on which the <code>longitude</code> and <code>latitude</code>
|
||||
* are defined. This body needs to have a defined radius for this function to work
|
||||
* \param longitude The longitude of the point on the <code>body</code> in radians
|
||||
* \param latitude The latitude of the point on the <code>body</code> in radians
|
||||
* \param coordinates The output containing the rectangular coordinates of the point
|
||||
* defined by <code>longitude</code> and <code>latitude</code> on the
|
||||
* <code>body</code>. If the method fails, the coordinate are unchanged
|
||||
* \return <code>true</code> if the function was successful, <code>false</code>
|
||||
* otherwise
|
||||
*/
|
||||
bool geographicToRectangular(const std::string& body, double longitude,
|
||||
double latitude, glm::dvec3& coordinates) const;
|
||||
|
||||
/**
|
||||
* Converts planeto-centric <code>latitude</code> and <code>longitude</code> of a
|
||||
* surface point on a body with the NAIF ID of <code>id</code> to rectangular
|
||||
* <code>coordinates</code>. For further details, refer to
|
||||
* http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/srfrec_c.html.
|
||||
* \param id The body on which the <code>longitude</code> and <code>latitude</code>
|
||||
* are defined. This body needs to have a defined radius for this function to work
|
||||
* \param longitude The longitude of the point on the <code>body</code> in radians
|
||||
* \param latitude The latitude of the point on the <code>body</code> in radians
|
||||
* \param coordinates The output containing the rectangular coordinates of the point
|
||||
* defined by <code>longitude</code> and <code>latitude</code> on the
|
||||
* <code>body</code>. If the method fails, the coordinate are unchanged
|
||||
* \return <code>true</code> if the function was successful, <code>false</code>
|
||||
* otherwise
|
||||
*/
|
||||
bool geographicToRectangular(int id, double longitude, double latitude,
|
||||
glm::dvec3& coordinates) const;
|
||||
* This function adds a frame to a body
|
||||
* \param body - the name of the body
|
||||
* \param frame - the name of the frame
|
||||
* \return false if the arguments are empty
|
||||
*/
|
||||
bool addFrame(const std::string body, const std::string frame);
|
||||
|
||||
/**
|
||||
* Compute the rectangular coordinates of the sub-observer point of an
|
||||
* <code>observer</code> on a target <code>body</code> at a specified
|
||||
* <code>ephemerisTime</code>, optionally corrected for light time and stellar
|
||||
* aberration. For further details, refer to
|
||||
* http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/subpnt_c.html.
|
||||
* Example: If the sub-observer point on Mars for MRO is requested, the
|
||||
* <code>target</code> would be <code>Mars</code> and the <code>observer</code> would
|
||||
* be <code>MRO</code>.
|
||||
* \param target The name of the target body on which the sub-observer point lies
|
||||
* \param observer The name of the ephemeris object whose sub-observer point should be
|
||||
* retrieved
|
||||
* \param computationMethod The computation method used for the sub-observer point.
|
||||
* Must be one of <code>Near point: ellipsoid</code> or
|
||||
* <code>Intercept: ellipsoid</code> and it determines the interpretation of the
|
||||
* results; see http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/subpnt_c.html
|
||||
* for detailed description on the computation methods
|
||||
* \param bodyFixedFrame The body-fixed, body-centered frame belonging to the
|
||||
* <code>target</code>
|
||||
* \param aberrationCorrection The aberration correction flag out of the list of
|
||||
* values (<code>NONE</code>, <code>LT</code>, <code>LT+S</code>, <code>CN</code>,
|
||||
* <code>CN+S</code> for the reception case or <code>XLT</code>, <code>XLT+S</code>,
|
||||
* <code>XCN</code>, or <code>XCN+S</code> for the transmission case.
|
||||
* \param ephemerisTime The ephemeris time for which the sub-observer point should be
|
||||
* retrieved
|
||||
* \param subObserverPoint The output containing the observer's sub-observer point on
|
||||
* the target body. If the method fails, the value remains unchanged
|
||||
* \param targetEphemerisTime The output containing the target's ephemeris time
|
||||
* accounting for the aberration, if an <code>aberrationCorrection</code> value
|
||||
* different from <code>NONE</code> is chosen. If the method fails, the value remains
|
||||
* unchanged
|
||||
* \param vectorToSurfacePoint The output containing the vector from the observer to
|
||||
* the, potentially aberration corrected, sub-observer point. If the method fails the
|
||||
* value remains unchanged
|
||||
* \return <code>true</code> if the function was successful, <code>false</code>
|
||||
* otherwise
|
||||
*/
|
||||
bool getSubObserverPoint(const std::string& target,
|
||||
const std::string& observer,
|
||||
const std::string& computationMethod,
|
||||
const std::string& bodyFixedFrame,
|
||||
const std::string& aberrationCorrection,
|
||||
double ephemerisTime,
|
||||
glm::dvec3& subObserverPoint,
|
||||
double& targetEphemerisTime,
|
||||
glm::dvec3& vectorToSurfacePoint) const;
|
||||
* This function returns the frame of a body if defined, otherwise it returns
|
||||
* IAU_ + body (most frames are known by the International Astronomical Union)
|
||||
* \param body - the name of the body
|
||||
* \return the frame of the body
|
||||
*/
|
||||
std::string frameFromBody(const std::string body) const;
|
||||
|
||||
/**
|
||||
* This method checks if one of the previous SPICE methods has failed. If it has, the
|
||||
@@ -648,6 +657,19 @@ public:
|
||||
*/
|
||||
static bool checkForError(std::string errorMessage);
|
||||
|
||||
/**
|
||||
* This method uses the SPICE kernels to get the radii of bodies defined as a
|
||||
* triaxial ellipsoid. The benefit of this is to be able to create more accurate
|
||||
* planet shapes, which is desirable when projecting images with SPICE intersection
|
||||
* methods
|
||||
* \param planetName - the name of the body, should be recognizable by SPICE
|
||||
* \param a - equatorial radius 1
|
||||
* \param b - equatorial radius 2
|
||||
* \param c - polar radius
|
||||
* \return <code>true</code> if SPICE reports no errors
|
||||
*/
|
||||
bool getPlanetEllipsoid(std::string planetName, float &a, float &b, float &c);
|
||||
|
||||
private:
|
||||
struct KernelInformation {
|
||||
std::string path; /// The path from which the kernel was loaded
|
||||
@@ -662,6 +684,15 @@ private:
|
||||
|
||||
/// A list of all loaded kernels
|
||||
std::vector<KernelInformation> _loadedKernels;
|
||||
// Map: id, vector of pairs. Pair: Start time, end time;
|
||||
std::map<int, std::vector< std::pair<double, double> > > _ckIntervals;
|
||||
std::map<int, std::vector< std::pair<double, double> > > _spkIntervals;
|
||||
std::map<int, std::set<double> > _ckCoverageTimes;
|
||||
std::map<int, std::set<double> > _spkCoverageTimes;
|
||||
// Vector of pairs: Body, Frame
|
||||
std::vector< std::pair<std::string, std::string> > _frameByBody;
|
||||
|
||||
const static bool _showErrors = false;
|
||||
|
||||
/// The last assigned kernel-id, used to determine the next free kernel id
|
||||
KernelIdentifier _lastAssignedKernel;
|
||||
@@ -671,4 +702,4 @@ private:
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __SPICEMANAGER_H__
|
||||
#endif // __SPICEMANAGER_H__
|
||||
+1
-1
@@ -5,7 +5,7 @@ return {
|
||||
SHADERS = "${BASE_PATH}/shaders",
|
||||
SHADERS_GENERATED = "${SHADERS}/generated",
|
||||
OPENSPACE_DATA = "${BASE_PATH}/openspace-data",
|
||||
TESTDIR = "${BASE_PATH}/src/tests",
|
||||
TESTDIR = "${BASE_PATH}/tests",
|
||||
CONFIG = "${BASE_PATH}/config",
|
||||
CACHE = "${BASE_PATH}/cache",
|
||||
FONTS = "${OPENSPACE_DATA}/fonts",
|
||||
|
||||
@@ -36,5 +36,19 @@ openspace.bindKey("j", "local b = openspace.getPropertyValue('PlutoText.renderab
|
||||
|
||||
openspace.bindKey("l", "local b = openspace.getPropertyValue('Labels.renderable.performFading'); openspace.setPropertyValue('Labels.renderable.performFading', not b)")
|
||||
|
||||
openspace.bindKey("m", "local b = openspace.getPropertyValue('NH_LORRI.renderable.solidDraw'); openspace.setPropertyValue('NH_LORRI.renderable.solidDraw', not b)")
|
||||
openspace.bindKey("m", "local b = openspace.getPropertyValue('NH_RALPH_LEISA.renderable.solidDraw'); openspace.setPropertyValue('NH_RALPH_LEISA.renderable.solidDraw', not b)")
|
||||
openspace.bindKey("m", "local b = openspace.getPropertyValue('NH_RALPH_MVIC_PAN1.renderable.solidDraw'); openspace.setPropertyValue('NH_RALPH_MVIC_PAN1.renderable.solidDraw', not b)")
|
||||
openspace.bindKey("m", "local b = openspace.getPropertyValue('NH_RALPH_MVIC_PAN2.renderable.solidDraw'); openspace.setPropertyValue('NH_RALPH_MVIC_PAN2.renderable.solidDraw', not b)")
|
||||
openspace.bindKey("m", "local b = openspace.getPropertyValue('NH_RALPH_MVIC_RED.renderable.solidDraw'); openspace.setPropertyValue('NH_RALPH_MVIC_RED.renderable.solidDraw', not b)")
|
||||
openspace.bindKey("m", "local b = openspace.getPropertyValue('NH_RALPH_MVIC_BLUE.renderable.solidDraw'); openspace.setPropertyValue('NH_RALPH_MVIC_BLUE.renderable.solidDraw', not b)")
|
||||
openspace.bindKey("m", "local b = openspace.getPropertyValue('NH_RALPH_MVIC_FT.renderable.solidDraw'); openspace.setPropertyValue('NH_RALPH_MVIC_FT.renderable.solidDraw', not b)")
|
||||
openspace.bindKey("m", "local b = openspace.getPropertyValue('NH_RALPH_MVIC_METHANE.renderable.solidDraw'); openspace.setPropertyValue('NH_RALPH_MVIC_METHANE.renderable.solidDraw', not b)")
|
||||
openspace.bindKey("m", "local b = openspace.getPropertyValue('NH_RALPH_MVIC_NIR.renderable.solidDraw'); openspace.setPropertyValue('NH_RALPH_MVIC_NIR.renderable.solidDraw', not b)")
|
||||
openspace.bindKey("m", "local b = openspace.getPropertyValue('NH_ALICE_AIRGLOW.renderable.solidDraw'); openspace.setPropertyValue('NH_ALICE_AIRGLOW.renderable.solidDraw', not b)")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
openspace.bindKey("PAUSE", "openspace.printInfo('F5: Toogle to Sun, F6: Toggle to Jupiter, F7: Toggle to Pluto'); openspace.printInfo('Bookmarks: 1: Jupter, 2-7: Pluto');")
|
||||
|
||||
@@ -7,14 +7,19 @@ openspace.setInvertRoll(true);
|
||||
|
||||
--openspace.time.setTime("2007 FEB 27 16:30:00") -- This is the start time for a Jupiter run of New Horizons
|
||||
|
||||
--openspace.time.setTime("2007 FEB 28 03:45:00") -- Io Capture!
|
||||
|
||||
openspace.time.setDeltaTime(0) -- How many seconds pass per second of realtime, changeable in the GUI
|
||||
|
||||
--openspace.time.setTime("2011 AUG 6 07:15:00") -- Dawn @ Vestaprojection
|
||||
--openspace.time.setTime("2014 AUG 28 03:45:00") -- Rosetta Travels 67p in triangular shape
|
||||
|
||||
openspace.time.setDeltaTime(10) -- How many seconds pass per second of realtime, changeable in the GUI
|
||||
|
||||
dofile(openspace.absPath('${SCRIPTS}/bind_keys.lua')) -- Load the default keybindings
|
||||
|
||||
-- openspace.time.setDeltaTime(50);
|
||||
|
||||
openspace.time.setTime("2015-07-14T10:10:00.00") -- PLUTO
|
||||
openspace.time.setTime("2015-07-14T10:50:00.00") -- PLUTO
|
||||
-- NH takes series of images from visible to dark side (across terminator)
|
||||
-- Sequence lasts ~10 mins, (recommended dt = 10)
|
||||
|
||||
|
||||
+12
-7
@@ -22,15 +22,18 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version 430
|
||||
#version __CONTEXT__
|
||||
|
||||
uniform sampler2D texture1;
|
||||
uniform sampler2D texture2;
|
||||
uniform mat4 ProjectorMatrix;
|
||||
uniform mat4 ModelTransform;
|
||||
uniform vec2 _scaling;
|
||||
uniform vec2 radius;
|
||||
uniform vec4 radius;
|
||||
flat in uint vs_segments;
|
||||
|
||||
uniform float projectionFading;
|
||||
|
||||
in vec4 vs_position;
|
||||
uniform vec3 boresight;
|
||||
|
||||
@@ -38,7 +41,7 @@ out vec4 color;
|
||||
|
||||
#define M_PI 3.14159265358979323846
|
||||
|
||||
vec4 uvToModel( float u, float v, vec2 radius, float segments){
|
||||
vec4 uvToModel( float u, float v, vec4 radius, float segments){
|
||||
const float fj = u * segments;
|
||||
const float fi = v * segments;
|
||||
|
||||
@@ -46,10 +49,10 @@ vec4 uvToModel( float u, float v, vec2 radius, float segments){
|
||||
const float phi = fj * float(M_PI) * 2.0f / segments;
|
||||
|
||||
const float x = radius[0] * sin(phi) * sin(theta); //
|
||||
const float y = radius[0] * cos(theta); // up
|
||||
const float z = radius[0] * cos(phi) * sin(theta); //
|
||||
const float y = radius[1] * cos(theta); // up
|
||||
const float z = radius[2] * cos(phi) * sin(theta); //
|
||||
|
||||
return vec4(x, y, z, radius[1]);
|
||||
return vec4(x, y, z, radius[3]);
|
||||
}
|
||||
|
||||
#include "PowerScaling/powerScaling_vs.hglsl"
|
||||
@@ -78,7 +81,9 @@ void main() {
|
||||
dot(v_b, normal) < 0 ) {
|
||||
color = texture(texture1, projected.xy);
|
||||
}else{
|
||||
color = vec4(1,1,1,0);
|
||||
color = texture(texture2, uv);
|
||||
color.a = projectionFading;
|
||||
}
|
||||
|
||||
// color.a = 0.1f;//1.f - abs(uv.x - 0.55) / (0.6 - 0.5); // blending
|
||||
}
|
||||
@@ -22,7 +22,8 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version 430
|
||||
#version __CONTEXT__
|
||||
|
||||
uniform mat4 ProjectorMatrix;
|
||||
uniform mat4 ModelTransform;
|
||||
uniform vec2 _scaling;
|
||||
|
||||
@@ -31,14 +31,13 @@ uniform vec3 cam_dir; // add this for specular
|
||||
uniform vec3 sun_pos;
|
||||
|
||||
uniform bool _performShading = true;
|
||||
|
||||
uniform float transparency;
|
||||
uniform int shadows;
|
||||
|
||||
uniform float fading;
|
||||
|
||||
uniform float time;
|
||||
uniform sampler2D texture1;
|
||||
uniform sampler2D texture2;
|
||||
|
||||
in vec2 vs_st;
|
||||
in vec4 vs_normal;
|
||||
@@ -55,52 +54,38 @@ void main()
|
||||
float depth = pscDepth(position);
|
||||
vec4 diffuse = texture(texture1, vs_st);
|
||||
|
||||
vec3 normal = normalize(texture2D(texture2, vs_st).rgb * 2.0 - 1.0);
|
||||
|
||||
if (fading > 0 || fading < 1){
|
||||
diffuse.a = fading;
|
||||
}
|
||||
diffuse[3] = fading;
|
||||
|
||||
|
||||
if (_performShading) {
|
||||
vec4 spec = vec4(0.0);
|
||||
|
||||
vec3 n = normalize(vs_normal.xyz);
|
||||
//vec3 n = normalize(normal.xyz);
|
||||
vec3 l_pos = vec3(sun_pos); // sun.
|
||||
vec3 l_dir = normalize(l_pos-objpos.xyz);
|
||||
float intensity = min(max(1*dot(n,l_dir), 0.0), 1);
|
||||
|
||||
float diff = max( dot(l_dir, n), 0.0 );
|
||||
|
||||
float shine = 100;
|
||||
/*if(normal.x > 0 && normal.y > 0 && normal.z > 0){
|
||||
n = normalize(normal.xyz);
|
||||
}*/
|
||||
|
||||
vec4 specular = vec4(1.0);
|
||||
vec4 ambient = diffuse*0.4;//vec4(0.0,0.0,0.0,1);
|
||||
|
||||
if(intensity > 0.0f){
|
||||
float shine = 100;
|
||||
|
||||
vec4 specular = vec4(1.0);
|
||||
vec4 ambient =diffuse*0.4;
|
||||
ambient[3] = transparency;
|
||||
if(intensity > 0.0f){
|
||||
// halfway vector
|
||||
vec3 h = normalize(l_dir + normalize(cam_dir));
|
||||
// specular factor
|
||||
float intSpec = max(dot(n,h),0.0);
|
||||
spec = specular * pow(intSpec, shine);
|
||||
}
|
||||
|
||||
diffuse = vec4(max(intensity * diffuse , ambient).xyz,1) +spec*1.5*diffuse ;
|
||||
|
||||
if (fading > 0 || fading < 1){
|
||||
diffuse.a = fading;
|
||||
}
|
||||
|
||||
|
||||
//diffuse = vec4(1);
|
||||
|
||||
|
||||
diffuse[3] = fading*transparency;
|
||||
|
||||
ABufferStruct_t frag = createGeometryFragment(diffuse, position, depth);
|
||||
addToBuffer(frag);
|
||||
}
|
||||
else {
|
||||
diffuse[3] = fading*transparency;
|
||||
ABufferStruct_t frag = createGeometryFragment(diffuse, position, depth);
|
||||
addToBuffer(frag);
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
uniform float time;
|
||||
uniform sampler2D texture1;
|
||||
|
||||
in vec2 vs_st;
|
||||
in vec4 vs_position;
|
||||
|
||||
#include "ABuffer/abufferStruct.hglsl"
|
||||
#include "ABuffer/abufferAddToBuffer.hglsl"
|
||||
#include "PowerScaling/powerScaling_fs.hglsl"
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 position = vs_position;
|
||||
float depth = pscDepth(position);
|
||||
vec4 diffuse;
|
||||
if (gl_FrontFacing)
|
||||
diffuse = texture(texture1, vs_st);
|
||||
else {
|
||||
diffuse = vec4(0.8);
|
||||
}
|
||||
|
||||
ABufferStruct_t frag = createGeometryFragment(diffuse, position, depth);
|
||||
addToBuffer(frag);
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
uniform mat4 ViewProjection;
|
||||
uniform mat4 ModelTransform;
|
||||
|
||||
layout(location = 0) in vec4 in_position;
|
||||
layout(location = 1) in vec2 in_st;
|
||||
|
||||
out vec2 vs_st;
|
||||
out vec4 vs_position;
|
||||
out float s;
|
||||
|
||||
#include "PowerScaling/powerScaling_vs.hglsl"
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 tmp = in_position;
|
||||
vec4 position = pscTransform(tmp, ModelTransform);
|
||||
|
||||
vs_position = tmp;
|
||||
vs_st = in_st;
|
||||
|
||||
position = ViewProjection * position;
|
||||
gl_Position = z_normalization(position);
|
||||
}
|
||||
@@ -27,6 +27,7 @@
|
||||
in vec4 vs_point_position;
|
||||
in vec4 vs_point_velocity;
|
||||
in float fade;
|
||||
uniform float forceFade;
|
||||
|
||||
uniform vec3 color;
|
||||
|
||||
@@ -38,7 +39,7 @@ void main() {
|
||||
vec4 position = vs_point_position;
|
||||
float depth = pscDepth(position);
|
||||
|
||||
vec4 c = vec4(color, fade);
|
||||
vec4 c = vec4(color, fade*forceFade);
|
||||
ABufferStruct_t frag = createGeometryFragment(c, position, depth);
|
||||
addToBuffer(frag);
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
uniform vec4 campos;
|
||||
uniform vec4 objpos;
|
||||
|
||||
uniform vec3 sun_pos;
|
||||
|
||||
uniform bool _performShading = true;
|
||||
uniform float transparency;
|
||||
uniform int shadows;
|
||||
|
||||
uniform float time;
|
||||
uniform sampler2D texture1;
|
||||
uniform sampler2D nightTex;
|
||||
|
||||
in vec2 vs_st;
|
||||
in vec2 vs_nightTex;
|
||||
in vec4 vs_normal;
|
||||
in vec4 vs_position;
|
||||
|
||||
#include "ABuffer/abufferStruct.hglsl"
|
||||
#include "ABuffer/abufferAddToBuffer.hglsl"
|
||||
#include "PowerScaling/powerScaling_fs.hglsl"
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 position = vs_position;
|
||||
float depth = pscDepth(position);
|
||||
vec4 diffuse = texture(texture1, vs_st);
|
||||
vec4 diffuse2 = texture(nightTex, vs_st);
|
||||
|
||||
if (_performShading) {
|
||||
// directional lighting
|
||||
vec3 origin = vec3(0.0);
|
||||
vec4 spec = vec4(0.0);
|
||||
|
||||
vec3 n = normalize(vs_normal.xyz);
|
||||
//vec3 e = normalize(camdir);
|
||||
vec3 l_pos = vec3(sun_pos); // sun.
|
||||
vec3 l_dir = normalize(l_pos-objpos.xyz);
|
||||
float intensity = min(max(5*dot(n,l_dir), 0.0), 1);
|
||||
float darkSide = min(max(5*dot(n,-l_dir), 0.0), 1);
|
||||
|
||||
float shine = 0.0001;
|
||||
|
||||
vec4 specular = vec4(0.5);
|
||||
vec4 ambient = vec4(0.0,0.0,0.0,transparency);
|
||||
|
||||
vec4 daytex = max(intensity * diffuse, ambient);
|
||||
vec4 mixtex = mix(diffuse, diffuse2, (1+dot(n,-l_dir))/2);
|
||||
|
||||
diffuse = (daytex*2 + mixtex)/3;
|
||||
|
||||
diffuse[3] = transparency;
|
||||
ABufferStruct_t frag = createGeometryFragment(diffuse, position, depth);
|
||||
addToBuffer(frag);
|
||||
}
|
||||
else {
|
||||
diffuse[3] = transparency;
|
||||
ABufferStruct_t frag = createGeometryFragment(diffuse, position, depth);
|
||||
addToBuffer(frag);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
uniform mat4 ViewProjection;
|
||||
uniform mat4 ModelTransform;
|
||||
|
||||
layout(location = 0) in vec4 in_position;
|
||||
layout(location = 1) in vec2 in_st;
|
||||
layout(location = 2) in vec3 in_normal;
|
||||
//layout(location = 3) in vec2 in_nightTex;
|
||||
|
||||
|
||||
out vec2 vs_st;
|
||||
out vec4 vs_normal;
|
||||
out vec4 vs_position;
|
||||
out float s;
|
||||
|
||||
#include "PowerScaling/powerScaling_vs.hglsl"
|
||||
|
||||
void main()
|
||||
{
|
||||
// set variables
|
||||
vs_st = in_st;
|
||||
vs_position = in_position;
|
||||
vec4 tmp = in_position;
|
||||
|
||||
// this is wrong for the normal. The normal transform is the transposed inverse of the model transform
|
||||
vs_normal = normalize(ModelTransform * vec4(in_normal,0));
|
||||
|
||||
vec4 position = pscTransform(tmp, ModelTransform);
|
||||
vs_position = tmp;
|
||||
position = ViewProjection * position;
|
||||
gl_Position = z_normalization(position);
|
||||
}
|
||||
@@ -22,7 +22,7 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version 430
|
||||
#version __CONTEXT__
|
||||
|
||||
uniform vec4 campos;
|
||||
uniform vec4 objpos;
|
||||
@@ -60,7 +60,7 @@ void main()
|
||||
//vec3 e = normalize(camdir);
|
||||
vec3 l_pos = sun_pos; // sun.
|
||||
vec3 l_dir = normalize(l_pos-objpos.xyz);
|
||||
float terminatorBright = 0.4;
|
||||
float terminatorBright = 0.1;
|
||||
float intensity = min(max(5*dot(n,l_dir), terminatorBright), 1);
|
||||
|
||||
float shine = 0.0001;
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version 430
|
||||
#version __CONTEXT__
|
||||
|
||||
uniform mat4 ViewProjection;
|
||||
uniform mat4 ModelTransform;
|
||||
|
||||
@@ -31,7 +31,7 @@ uniform vec4 objpos;
|
||||
uniform vec3 sun_pos;
|
||||
|
||||
uniform bool _performShading = true;
|
||||
|
||||
uniform float transparency;
|
||||
uniform int shadows;
|
||||
|
||||
uniform float time;
|
||||
@@ -66,7 +66,7 @@ void main()
|
||||
float shine = 0.0001;
|
||||
|
||||
vec4 specular = vec4(0.5);
|
||||
vec4 ambient = vec4(0.0,0.0,0.0,1);
|
||||
vec4 ambient = vec4(0.0,0.0,0.0,transparency);
|
||||
/*
|
||||
if(intensity > 0.f){
|
||||
// halfway vector
|
||||
@@ -77,12 +77,13 @@ void main()
|
||||
}
|
||||
*/
|
||||
diffuse = max(intensity * diffuse, ambient);
|
||||
//diffuse = vec4(1);
|
||||
|
||||
|
||||
diffuse[3] = transparency;
|
||||
ABufferStruct_t frag = createGeometryFragment(diffuse, position, depth);
|
||||
addToBuffer(frag);
|
||||
}
|
||||
else {
|
||||
diffuse[3] = transparency;
|
||||
ABufferStruct_t frag = createGeometryFragment(diffuse, position, depth);
|
||||
addToBuffer(frag);
|
||||
}
|
||||
|
||||
+23
-8
@@ -110,11 +110,11 @@ file(GLOB RENDERING_MODEL_HEADER ${HEADER_ROOT_DIR}/openspace/rendering/model/*.
|
||||
set(OPENSPACE_HEADER ${OPENSPACE_HEADER} ${RENDERING_MODEL_HEADER})
|
||||
source_group(Rendering\\Model FILES ${RENDERING_MODEL_SOURCE} ${RENDERING_MODEL_HEADER})
|
||||
|
||||
file(GLOB SCENEGRAPH_SOURCE ${SOURCE_ROOT_DIR}/scenegraph/*.cpp)
|
||||
set(OPENSPACE_SOURCE ${OPENSPACE_SOURCE} ${SCENEGRAPH_SOURCE})
|
||||
file(GLOB SCENEGRAPH_HEADER ${HEADER_ROOT_DIR}/openspace/scenegraph/*.h ${HEADER_ROOT_DIR}/openspace/scenegraph/*.inl)
|
||||
set(OPENSPACE_HEADER ${OPENSPACE_HEADER} ${SCENEGRAPH_HEADER})
|
||||
source_group(SceneGraph FILES ${SCENEGRAPH_SOURCE} ${SCENEGRAPH_HEADER})
|
||||
file(GLOB SCENE_SOURCE ${SOURCE_ROOT_DIR}/scene/*.cpp)
|
||||
set(OPENSPACE_SOURCE ${OPENSPACE_SOURCE} ${SCENE_SOURCE})
|
||||
file(GLOB SCENE_HEADER ${HEADER_ROOT_DIR}/openspace/scene/*.h ${HEADER_ROOT_DIR}/openspace/scene/*.inl)
|
||||
set(OPENSPACE_HEADER ${OPENSPACE_HEADER} ${SCENE_HEADER})
|
||||
source_group(Scene FILES ${SCENE_SOURCE} ${SCENE_HEADER})
|
||||
|
||||
file(GLOB SCRIPTING_SOURCE ${SOURCE_ROOT_DIR}/scripting/*.cpp)
|
||||
set(OPENSPACE_SOURCE ${OPENSPACE_SOURCE} ${SCRIPTING_SOURCE})
|
||||
@@ -156,10 +156,25 @@ include_directories("${HEADER_ROOT_DIR}")
|
||||
add_executable(OpenSpace ${SOURCE_ROOT_DIR}/main.cpp ${OPENSPACE_HEADER} ${OPENSPACE_SOURCE})
|
||||
target_link_libraries(OpenSpace ${DEPENDENT_LIBS})
|
||||
|
||||
option(OPENSPACE_HAVE_TESTS "Activate the OpenSpace unit tests" ON)
|
||||
if (OPENSPACE_HAVE_TESTS)
|
||||
add_definitions(-DOPENSPACE_HAVE_TESTS)
|
||||
|
||||
set(OPENSPACE_TEST_DIR ${OPENSPACE_BASE_DIR}/tests)
|
||||
|
||||
include_directories("${GHOUL_ROOT_DIR}/ext/gtest/include")
|
||||
include_directories("${GHOUL_ROOT_DIR}/include")
|
||||
include_directories("${OPENSPACE_TEST_DIR}")
|
||||
file(GLOB_RECURSE OPENSPACE_TEST_FILES ${OPENSPACE_BASE_DIR}/tests/*.inl)
|
||||
|
||||
source_group(Tests FILES ${OPENSPACE_TEST_FILES})
|
||||
|
||||
add_executable(OpenSpaceTest ${OPENSPACE_BASE_DIR}/tests/main.cpp ${OPENSPACE_TEST_FILES} ${OPENSPACE_HEADER} ${OPENSPACE_SOURCE})
|
||||
target_link_libraries(OpenSpaceTest gtest ${DEPENDENT_LIBS})
|
||||
|
||||
endif (OPENSPACE_HAVE_TESTS)
|
||||
|
||||
#if (NOT UNIX)
|
||||
#cotire(OpenSpace)
|
||||
#endif ()
|
||||
GhoulCopySharedLibraries(OpenSpace)
|
||||
|
||||
add_subdirectory(tests)
|
||||
|
||||
|
||||
@@ -147,12 +147,12 @@ void ABuffer::resolve() {
|
||||
|
||||
// Decrease stepsize in volumes if right click is pressed
|
||||
// TODO: Let the interactionhandler handle this
|
||||
/*int val = sgct::Engine::getMouseButton(0, SGCT_MOUSE_BUTTON_RIGHT);
|
||||
float volumeStepFactor = (val) ? 0.2f: 1.0f;
|
||||
if(volumeStepFactor != _volumeStepFactor) {
|
||||
_volumeStepFactor = volumeStepFactor;
|
||||
_resolveShader->setUniform("volumeStepFactor", _volumeStepFactor);
|
||||
}*/
|
||||
//int val = sgct::Engine::getMouseButton(0, SGCT_MOUSE_BUTTON_RIGHT);
|
||||
//float volumeStepFactor = (val) ? 0.2f: 1.0f;
|
||||
//if(volumeStepFactor != _volumeStepFactor) {
|
||||
// _volumeStepFactor = volumeStepFactor;
|
||||
// _resolveShader->setUniform("volumeStepFactor", _volumeStepFactor);
|
||||
//}
|
||||
|
||||
glBindVertexArray(_screenQuad);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
|
||||
@@ -38,14 +38,13 @@
|
||||
#include <openspace/network/networkengine.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/scripting/scriptengine.h>
|
||||
#include <openspace/scenegraph/scenegraph.h>
|
||||
#include <openspace/scene/scene.h>
|
||||
#include <openspace/util/time.h>
|
||||
#include <openspace/util/spicemanager.h>
|
||||
#include <openspace/util/factorymanager.h>
|
||||
#include <openspace/util/constants.h>
|
||||
#include <openspace/util/spicemanager.h>
|
||||
#include <openspace/util/syncbuffer.h>
|
||||
#include <openspace/util/imagesequencer.h>
|
||||
#include <openspace/util/imagesequencer2.h> // testing
|
||||
|
||||
|
||||
@@ -104,7 +103,6 @@ OpenSpaceEngine::OpenSpaceEngine(std::string programName)
|
||||
{
|
||||
SpiceManager::initialize();
|
||||
Time::initialize();
|
||||
ImageSequencer::initialize();
|
||||
ImageSequencer2::initialize();
|
||||
FactoryManager::initialize();
|
||||
ghoul::systemcapabilities::SystemCapabilities::initialize();
|
||||
@@ -128,7 +126,7 @@ OpenSpaceEngine::~OpenSpaceEngine() {
|
||||
}
|
||||
|
||||
OpenSpaceEngine& OpenSpaceEngine::ref() {
|
||||
assert(_engine);
|
||||
ghoul_assert(_engine, "OpenSpaceEngine not created");
|
||||
return *_engine;
|
||||
}
|
||||
|
||||
@@ -137,7 +135,7 @@ bool OpenSpaceEngine::create(
|
||||
std::vector<std::string>& sgctArguments,
|
||||
std::string& openGlVersion)
|
||||
{
|
||||
assert(_engine == nullptr);
|
||||
ghoul_assert(!_engine, "OpenSpaceEngine was already created");
|
||||
|
||||
// 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
|
||||
@@ -277,7 +275,7 @@ bool OpenSpaceEngine::initialize() {
|
||||
// Register Lua script functions
|
||||
LDEBUG("Registering Lua libraries");
|
||||
_scriptEngine->addLibrary(RenderEngine::luaLibrary());
|
||||
_scriptEngine->addLibrary(SceneGraph::luaLibrary());
|
||||
_scriptEngine->addLibrary(Scene::luaLibrary());
|
||||
_scriptEngine->addLibrary(Time::luaLibrary());
|
||||
_scriptEngine->addLibrary(interaction::InteractionHandler::luaLibrary());
|
||||
_scriptEngine->addLibrary(LuaConsole::luaLibrary());
|
||||
@@ -308,7 +306,7 @@ bool OpenSpaceEngine::initialize() {
|
||||
|
||||
|
||||
// Load scenegraph
|
||||
SceneGraph* sceneGraph = new SceneGraph;
|
||||
Scene* sceneGraph = new Scene;
|
||||
_renderEngine->setSceneGraph(sceneGraph);
|
||||
|
||||
// initialize the RenderEngine
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/scenegraph/scenegraphnode.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/interaction/interactionhandler.h>
|
||||
#include <ghoul/misc/assert.h>
|
||||
#include "imgui.h"
|
||||
@@ -41,7 +41,7 @@ namespace gui {
|
||||
void GuiOriginComponent::render() {
|
||||
const SceneGraphNode* currentFocus = OsEng.interactionHandler()->focusNode();
|
||||
|
||||
std::vector<SceneGraphNode*> nodes = OsEng.renderEngine()->sceneGraph()->allSceneGraphNodes();
|
||||
std::vector<SceneGraphNode*> nodes = OsEng.renderEngine()->scene()->allSceneGraphNodes();
|
||||
std::sort(nodes.begin(), nodes.end(), [](SceneGraphNode* lhs, SceneGraphNode* rhs) { return lhs->name() < rhs->name(); });
|
||||
auto it = std::find(nodes.begin(), nodes.end(), currentFocus);
|
||||
ghoul_assert(it != nodes.end(), "Focus node not found");
|
||||
|
||||
+5
-5
@@ -27,8 +27,8 @@
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/rendering/renderable.h>
|
||||
#include <openspace/scenegraph/scenegraph.h>
|
||||
#include <openspace/scenegraph/scenegraphnode.h>
|
||||
#include <openspace/scene/scene.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
@@ -36,14 +36,14 @@ namespace {
|
||||
const std::string _loggerCat = "Query";
|
||||
}
|
||||
|
||||
SceneGraph* sceneGraph()
|
||||
Scene* sceneGraph()
|
||||
{
|
||||
return OsEng.renderEngine()->sceneGraph();
|
||||
return OsEng.renderEngine()->scene();
|
||||
}
|
||||
|
||||
SceneGraphNode* sceneGraphNode(const std::string& name)
|
||||
{
|
||||
const SceneGraph* graph = sceneGraph();
|
||||
const Scene* graph = sceneGraph();
|
||||
return graph->sceneGraphNode(name);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,19 +25,23 @@
|
||||
#include <openspace/rendering/model/modelgeometry.h>
|
||||
#include <openspace/util/factorymanager.h>
|
||||
#include <openspace/util/constants.h>
|
||||
#include <openspace/util/factorymanager.h>
|
||||
#include <ghoul/filesystem/cachemanager.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <openspace/rendering/model/wavefrontgeometry.h>
|
||||
|
||||
namespace {
|
||||
const std::string _loggerCat = "ModelGeometry";
|
||||
|
||||
const std::string keyObjFile = "ObjFile";
|
||||
const int8_t CurrentCacheVersion = 3;
|
||||
const std::string keyType = "Type";
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
namespace modelgeometry {
|
||||
|
||||
ModelGeometry* ModelGeometry::createFromDictionary(const ghoul::Dictionary& dictionary)
|
||||
{
|
||||
ModelGeometry* ModelGeometry::createFromDictionary(const ghoul::Dictionary& dictionary) {
|
||||
std::string geometryType;
|
||||
const bool success = dictionary.getValue(
|
||||
keyType, geometryType);
|
||||
@@ -58,23 +62,163 @@ ModelGeometry* ModelGeometry::createFromDictionary(const ghoul::Dictionary& dict
|
||||
return result;
|
||||
}
|
||||
|
||||
ModelGeometry::ModelGeometry()
|
||||
ModelGeometry::ModelGeometry(const ghoul::Dictionary& dictionary)
|
||||
: _parent(nullptr)
|
||||
, _mode(GL_TRIANGLES)
|
||||
{
|
||||
setName("ModelGeometry");
|
||||
using constants::scenegraphnode::keyName;
|
||||
|
||||
std::string name;
|
||||
bool success = dictionary.getValue(keyName, name);
|
||||
ghoul_assert(success, "Name tag was not present");
|
||||
|
||||
success = dictionary.getValue(keyObjFile, _file);
|
||||
if (!success) {
|
||||
LERROR("WaveFrontGeometry of '" << name << "' did not provide a key '"
|
||||
<< keyObjFile << "'");
|
||||
}
|
||||
_file = FileSys.absolutePath(_file);
|
||||
|
||||
if (!FileSys.fileExists(_file, true))
|
||||
LERROR("Could not load OBJ file '" << _file << "': File not found");
|
||||
|
||||
}
|
||||
|
||||
ModelGeometry::~ModelGeometry()
|
||||
{
|
||||
ModelGeometry::~ModelGeometry() {
|
||||
}
|
||||
|
||||
bool ModelGeometry::initialize(RenderableModel* parent){
|
||||
void ModelGeometry::render() {
|
||||
glBindVertexArray(_vaoID);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ibo);
|
||||
glDrawElements(_mode, _indices.size(), GL_UNSIGNED_INT, 0);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
void ModelGeometry::changeRenderMode(const GLenum mode){
|
||||
_mode = mode;
|
||||
}
|
||||
|
||||
bool ModelGeometry::initialize(RenderableModel* parent) {
|
||||
_parent = parent;
|
||||
PowerScaledScalar ps = PowerScaledScalar(1.0, 0.0); // will set proper bounding soon.
|
||||
_parent->setBoundingSphere(ps);
|
||||
|
||||
if (_vertices.empty())
|
||||
return false;
|
||||
glGenVertexArrays(1, &_vaoID);
|
||||
glGenBuffers(1, &_vbo);
|
||||
glGenBuffers(1, &_ibo);
|
||||
|
||||
glBindVertexArray(_vaoID);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, _vertices.size() * sizeof(Vertex), _vertices.data(), GL_STATIC_DRAW);
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glEnableVertexAttribArray(1);
|
||||
glEnableVertexAttribArray(2);
|
||||
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex),
|
||||
reinterpret_cast<const GLvoid*>(offsetof(Vertex, location)));
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex),
|
||||
reinterpret_cast<const GLvoid*>(offsetof(Vertex, tex)));
|
||||
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
|
||||
reinterpret_cast<const GLvoid*>(offsetof(Vertex, normal)));
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ibo);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, _indices.size() * sizeof(int), _indices.data(), GL_STATIC_DRAW);
|
||||
|
||||
glBindVertexArray(0);
|
||||
|
||||
return true;
|
||||
}
|
||||
void ModelGeometry::deinitialize()
|
||||
{
|
||||
|
||||
void ModelGeometry::deinitialize() {
|
||||
glDeleteBuffers(1, &_vbo);
|
||||
glDeleteVertexArrays(1, &_vaoID);
|
||||
glDeleteBuffers(1, &_ibo);
|
||||
}
|
||||
|
||||
bool ModelGeometry::loadObj(const std::string& filename){
|
||||
std::string cachedFile = "";
|
||||
FileSys.cacheManager()->getCachedFile(filename, cachedFile, true);
|
||||
|
||||
bool hasCachedFile = FileSys.fileExists(cachedFile);
|
||||
if (hasCachedFile) {
|
||||
LINFO("Cached file '" << cachedFile << "' used for Model file '" << filename << "'");
|
||||
|
||||
bool success = loadCachedFile(cachedFile);
|
||||
if (success)
|
||||
return true;
|
||||
else
|
||||
FileSys.cacheManager()->removeCacheFile(filename);
|
||||
// Intentional fall-through to the 'else' computation to generate the cache
|
||||
// file for the next run
|
||||
}
|
||||
else {
|
||||
LINFO("Cache for Model'" << filename << "' not found");
|
||||
}
|
||||
LINFO("Loading Model file '" << filename << "'");
|
||||
bool success = loadModel(filename);
|
||||
if (!success)
|
||||
//return false;
|
||||
|
||||
LINFO("Saving cache");
|
||||
success = saveCachedFile(cachedFile);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool ModelGeometry::saveCachedFile(const std::string& filename) {
|
||||
std::ofstream fileStream(filename, std::ofstream::binary);
|
||||
if (fileStream.good()) {
|
||||
fileStream.write(reinterpret_cast<const char*>(&CurrentCacheVersion),
|
||||
sizeof(int8_t));
|
||||
|
||||
int64_t vSize = _vertices.size();
|
||||
fileStream.write(reinterpret_cast<const char*>(&vSize), sizeof(int64_t));
|
||||
int64_t iSize = _indices.size();
|
||||
fileStream.write(reinterpret_cast<const char*>(&iSize), sizeof(int64_t));
|
||||
|
||||
fileStream.write(reinterpret_cast<const char*>(_vertices.data()), sizeof(Vertex) * vSize);
|
||||
fileStream.write(reinterpret_cast<const char*>(_indices.data()), sizeof(int) * iSize);
|
||||
|
||||
return fileStream.good();
|
||||
}
|
||||
else {
|
||||
LERROR("Error opening file '" << filename << "' for save cache file");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool ModelGeometry::loadCachedFile(const std::string& filename) {
|
||||
std::ifstream fileStream(filename, std::ifstream::binary);
|
||||
if (fileStream.good()) {
|
||||
int8_t version = 0;
|
||||
fileStream.read(reinterpret_cast<char*>(&version), sizeof(int8_t));
|
||||
if (version != CurrentCacheVersion) {
|
||||
LINFO("The format of the cached file has changed, deleting old cache");
|
||||
fileStream.close();
|
||||
FileSys.deleteFile(filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
int64_t vSize, iSize;
|
||||
fileStream.read(reinterpret_cast<char*>(&vSize), sizeof(int64_t));
|
||||
fileStream.read(reinterpret_cast<char*>(&iSize), sizeof(int64_t));
|
||||
|
||||
_vertices.resize(vSize);
|
||||
_indices.resize(iSize);
|
||||
|
||||
fileStream.read(reinterpret_cast<char*>(_vertices.data()), sizeof(Vertex) * vSize);
|
||||
fileStream.read(reinterpret_cast<char*>(_indices.data()), sizeof(int) * iSize);
|
||||
|
||||
return fileStream.good();
|
||||
}
|
||||
else {
|
||||
LERROR("Error opening file '" << filename << "' for loading cache file");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace modelgeometry
|
||||
} // namespace openspace
|
||||
|
||||
@@ -37,32 +37,37 @@
|
||||
|
||||
#include <openspace/util/time.h>
|
||||
#include <openspace/util/spicemanager.h>
|
||||
#include <openspace/util/imagesequencer2.h>
|
||||
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <sgct.h>
|
||||
#include "imgui.h"
|
||||
|
||||
namespace {
|
||||
const std::string _loggerCat = "RenderableModel";
|
||||
namespace {
|
||||
const std::string _loggerCat = "RenderableModel";
|
||||
const std::string keySource = "Rotation.Source";
|
||||
const std::string keyDestination = "Rotation.Destination";
|
||||
const std::string keyShading = "Shading.PerformShading";
|
||||
const std::string keyFading = "Shading.Fadeable";
|
||||
const std::string keyBody = "Body";
|
||||
const std::string keyStart = "StartTime";
|
||||
const std::string keyEnd = "EndTime";
|
||||
const std::string keyFading = "Shading.Fadeable";
|
||||
const std::string keyGhosting = "Shading.Ghosting";
|
||||
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
|
||||
RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary)
|
||||
: Renderable(dictionary)
|
||||
, _colorTexturePath("colorTexture", "Color Texture")
|
||||
, _bumpTexturePath("bumpTexture", "Bump Texture")
|
||||
, _programObject(nullptr)
|
||||
, _texture(nullptr)
|
||||
, _bumpMap(nullptr)
|
||||
, _geometry(nullptr)
|
||||
, _performShading("performShading", "Perform Shading", true)
|
||||
, _fading("fading", "Fade", 0)
|
||||
, _performFade("performFading", "Perform Fading", false)
|
||||
RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary)
|
||||
: Renderable(dictionary)
|
||||
, _colorTexturePath("colorTexture", "Color Texture")
|
||||
, _programObject(nullptr)
|
||||
, _texture(nullptr)
|
||||
, _geometry(nullptr)
|
||||
, _isGhost(false)
|
||||
, _performShading("performShading", "Perform Shading", true)
|
||||
, _alpha(1.f)
|
||||
, _fading("fading", "Fade", 0)
|
||||
, _performFade("performFading", "Perform Fading", false)
|
||||
{
|
||||
std::string name;
|
||||
bool success = dictionary.getValue(constants::scenegraphnode::keyName, name);
|
||||
@@ -80,53 +85,43 @@ namespace openspace {
|
||||
_geometry = modelgeometry::ModelGeometry::createFromDictionary(geometryDictionary);
|
||||
}
|
||||
|
||||
addPropertySubOwner(_geometry);
|
||||
|
||||
|
||||
std::string texturePath = "";
|
||||
success = dictionary.getValue("Textures.Color", texturePath);
|
||||
if (success)
|
||||
_colorTexturePath = path + "/" + texturePath;
|
||||
|
||||
addPropertySubOwner(_geometry);
|
||||
|
||||
addProperty(_colorTexturePath);
|
||||
_colorTexturePath.onChange(std::bind(&RenderableModel::loadTexture, this));
|
||||
|
||||
std::string bumpPath = "";
|
||||
success = dictionary.getValue("Textures.BumpMap", bumpPath);
|
||||
if (success)
|
||||
_bumpTexturePath = path + "/" + bumpPath;
|
||||
|
||||
addProperty(_bumpTexturePath);
|
||||
_colorTexturePath.onChange(std::bind(&RenderableModel::loadTexture, this));
|
||||
|
||||
dictionary.getValue(keySource, _source);
|
||||
dictionary.getValue(keyDestination, _destination);
|
||||
dictionary.getValue(keyBody, _target);
|
||||
|
||||
openspace::SpiceManager::ref().addFrame(_target, _source);
|
||||
|
||||
setBoundingSphere(pss(1.f, 9.f));
|
||||
|
||||
if (dictionary.hasKeyAndValue<bool>(keyShading)) {
|
||||
bool shading;
|
||||
dictionary.getValue(keyShading, shading);
|
||||
_performShading = shading;
|
||||
}
|
||||
|
||||
addProperty(_performShading);
|
||||
|
||||
if (dictionary.hasKeyAndValue<bool>(keyFading)) {
|
||||
bool fading;
|
||||
dictionary.getValue(keyShading, fading);
|
||||
dictionary.getValue(keyFading, fading);
|
||||
_performFade = fading;
|
||||
}
|
||||
|
||||
addProperty(_performFade);
|
||||
|
||||
if (dictionary.hasKeyAndValue<bool>(keyGhosting)) {
|
||||
bool ghosting;
|
||||
dictionary.getValue(keyGhosting, ghosting);
|
||||
_isGhost = ghosting;
|
||||
}
|
||||
}
|
||||
|
||||
bool RenderableModel::isReady() const {
|
||||
bool ready = true;
|
||||
ready &= (_programObject != nullptr);
|
||||
ready &= (_texture != nullptr);
|
||||
ready &= (_bumpMap != nullptr);
|
||||
|
||||
return ready;
|
||||
}
|
||||
|
||||
@@ -134,12 +129,11 @@ bool RenderableModel::initialize() {
|
||||
bool completeSuccess = true;
|
||||
if (_programObject == nullptr)
|
||||
completeSuccess
|
||||
&= OsEng.ref().configurationManager()->getValue("NewHorizonsShader", _programObject);
|
||||
&= OsEng.ref().configurationManager()->getValue("GenericModelShader", _programObject);
|
||||
|
||||
loadTexture();
|
||||
|
||||
completeSuccess &= (_texture != nullptr);
|
||||
completeSuccess &= (_bumpMap != nullptr);
|
||||
completeSuccess &= _geometry->initialize(this);
|
||||
completeSuccess &= !_source.empty();
|
||||
completeSuccess &= !_destination.empty();
|
||||
@@ -154,17 +148,16 @@ bool RenderableModel::deinitialize() {
|
||||
}
|
||||
if (_texture)
|
||||
delete _texture;
|
||||
if (_bumpMap)
|
||||
delete _bumpMap;
|
||||
|
||||
_geometry = nullptr;
|
||||
_texture = nullptr;
|
||||
_bumpMap = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
void RenderableModel::render(const RenderData& data) {
|
||||
_programObject->activate();
|
||||
|
||||
double lt;
|
||||
glm::mat4 transform = glm::mat4(1);
|
||||
|
||||
glm::mat4 tmp = glm::mat4(1);
|
||||
@@ -173,28 +166,33 @@ void RenderableModel::render(const RenderData& data) {
|
||||
tmp[i][j] = static_cast<float>(_stateMatrix[i][j]);
|
||||
}
|
||||
}
|
||||
|
||||
transform *= tmp;
|
||||
double lt;
|
||||
psc tmppos;
|
||||
|
||||
SpiceManager::ref().getTargetPosition(_source, "SUN", "GALACTIC", "NONE", Time::ref().currentTime(), tmppos, lt);
|
||||
double time = openspace::Time::ref().currentTime();
|
||||
bool targetPositionCoverage = openspace::SpiceManager::ref().hasSpkCoverage(_target, time);
|
||||
if (!targetPositionCoverage){
|
||||
int frame = ImGui::GetFrameCount() % 180;
|
||||
float fadingFactor = sin((frame * pi_c()) / 180);
|
||||
_alpha = 0.5f + fadingFactor*0.5f;
|
||||
//_texture = "";
|
||||
}
|
||||
else
|
||||
_alpha = 1.0f;
|
||||
|
||||
psc tmppos;
|
||||
SpiceManager::ref().getTargetPosition(_target, "SUN", "GALACTIC", "NONE", time, tmppos, lt);
|
||||
glm::vec3 cam_dir = glm::normalize(data.camera.position().vec3() - tmppos.vec3());
|
||||
|
||||
//std::cout << cam_dir << std::endl;
|
||||
_programObject->setUniform("sun_pos", _sunPosition.vec3());
|
||||
_programObject->setUniform("cam_dir", cam_dir);
|
||||
_programObject->setUniform("transparency", _alpha);
|
||||
_programObject->setUniform("sun_pos", _sunPosition.vec3());
|
||||
_programObject->setUniform("ViewProjection", data.camera.viewProjectionMatrix());
|
||||
_programObject->setUniform("ModelTransform", transform);
|
||||
setPscUniforms(_programObject, &data.camera, data.position);
|
||||
|
||||
_programObject->setUniform("_performShading", _performShading);
|
||||
|
||||
|
||||
if (_performFade && _fading > 0.f){
|
||||
_fading = _fading - 0.01f;
|
||||
|
||||
}
|
||||
else if (!_performFade && _fading < 1.f){
|
||||
_fading = _fading + 0.01f;
|
||||
@@ -203,19 +201,12 @@ void RenderableModel::render(const RenderData& data) {
|
||||
|
||||
_programObject->setUniform("fading", _fading);
|
||||
|
||||
|
||||
|
||||
// Bind texture
|
||||
ghoul::opengl::TextureUnit unit;
|
||||
unit.activate();
|
||||
_texture->bind();
|
||||
_programObject->setUniform("texture1", unit);
|
||||
|
||||
ghoul::opengl::TextureUnit unitBump;
|
||||
unitBump.activate();
|
||||
_bumpMap->bind();
|
||||
//_programObject->setUniform("texture2", unitBump);
|
||||
|
||||
_geometry->render();
|
||||
|
||||
// disable shader
|
||||
@@ -223,12 +214,34 @@ void RenderableModel::render(const RenderData& data) {
|
||||
}
|
||||
|
||||
void RenderableModel::update(const UpdateData& data) {
|
||||
double _time = data.time;
|
||||
|
||||
double futureTime;
|
||||
if (_isGhost){
|
||||
futureTime = openspace::ImageSequencer2::ref().getNextCaptureTime();
|
||||
double remaining = openspace::ImageSequencer2::ref().getNextCaptureTime() - data.time;
|
||||
double interval = openspace::ImageSequencer2::ref().getIntervalLength();
|
||||
double t = 1.f - remaining / openspace::ImageSequencer2::ref().getIntervalLength();
|
||||
if (interval > 60){
|
||||
if (t < 0.8){
|
||||
_fading = t;
|
||||
}
|
||||
else if (t >= 0.95f){
|
||||
_fading = _fading - 0.5f;
|
||||
}
|
||||
}
|
||||
else{
|
||||
_fading = 0.0f;
|
||||
}
|
||||
_time = futureTime;
|
||||
}
|
||||
|
||||
// set spice-orientation in accordance to timestamp
|
||||
if (!_source.empty())
|
||||
openspace::SpiceManager::ref().getPositionTransformMatrix(_source, _destination, data.time, _stateMatrix);
|
||||
openspace::SpiceManager::ref().getPositionTransformMatrix(_source, _destination, _time, _stateMatrix);
|
||||
|
||||
double lt;
|
||||
openspace::SpiceManager::ref().getTargetPosition("SUN", _source, "GALACTIC", "NONE", data.time, _sunPosition, lt);
|
||||
openspace::SpiceManager::ref().getTargetPosition("SUN", _target, "GALACTIC", "NONE", _time, _sunPosition, lt);
|
||||
}
|
||||
|
||||
void RenderableModel::loadTexture() {
|
||||
@@ -241,16 +254,6 @@ void RenderableModel::loadTexture() {
|
||||
_texture->uploadTexture();
|
||||
}
|
||||
}
|
||||
|
||||
delete _bumpMap;
|
||||
_bumpMap = nullptr;
|
||||
if (_bumpTexturePath.value() != "") {
|
||||
_bumpMap = ghoul::io::TextureReader::ref().loadTexture(absPath(_bumpTexturePath));
|
||||
if (_bumpMap) {
|
||||
LDEBUG("Loaded texture from '" << absPath(_bumpTexturePath) << "'");
|
||||
_bumpMap->uploadTexture();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -25,20 +25,12 @@
|
||||
#include <openspace/rendering/model/wavefrontgeometry.h>
|
||||
|
||||
#include <openspace/util/constants.h>
|
||||
#include <ghoul/filesystem/cachemanager.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include "ghoul/logging/logmanager.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <numeric>
|
||||
#include <tiny_obj_loader.h>
|
||||
|
||||
namespace {
|
||||
const std::string _loggerCat = "WavefrontGeometry";
|
||||
const std::string keyEnabled = "StartsEnabled";
|
||||
|
||||
const std::string keyObjFile = "ObjFile";
|
||||
|
||||
const int8_t CurrentCacheVersion = 3;
|
||||
}
|
||||
|
||||
@@ -46,104 +38,18 @@ namespace openspace {
|
||||
namespace modelgeometry {
|
||||
|
||||
WavefrontGeometry::WavefrontGeometry(const ghoul::Dictionary& dictionary)
|
||||
: ModelGeometry()
|
||||
: ModelGeometry(dictionary)
|
||||
{
|
||||
using constants::scenegraphnode::keyName;
|
||||
|
||||
std::string name;
|
||||
bool success = dictionary.getValue(keyName, name);
|
||||
ghoul_assert(success, "Name tag was not present");
|
||||
|
||||
std::string file;
|
||||
success = dictionary.getValue(keyObjFile, file);
|
||||
if (!success) {
|
||||
LERROR("WaveFrontGeometry of '" << name << "' did not provide a key '"
|
||||
<< keyObjFile << "'");
|
||||
}
|
||||
file = FileSys.absolutePath(file);
|
||||
|
||||
if (FileSys.fileExists(file, true))
|
||||
loadObj(file);
|
||||
else
|
||||
LERROR("Could not load OBJ file '" << file << "': File not found");
|
||||
}
|
||||
|
||||
bool WavefrontGeometry::loadObj(const std::string& filename){
|
||||
std::string cachedFile = "";
|
||||
|
||||
FileSys.cacheManager()->getCachedFile(filename, cachedFile, true);
|
||||
|
||||
bool hasCachedFile = FileSys.fileExists(cachedFile);
|
||||
if (hasCachedFile) {
|
||||
LINFO("Cached file '" << cachedFile << "' used for Model file '" << filename << "'");
|
||||
|
||||
bool success = loadCachedFile(cachedFile);
|
||||
if (success)
|
||||
return true;
|
||||
else
|
||||
FileSys.cacheManager()->removeCacheFile(filename);
|
||||
// Intentional fall-through to the 'else' computation to generate the cache
|
||||
// file for the next run
|
||||
}
|
||||
else {
|
||||
LINFO("Cache for Model'" << filename << "' not found");
|
||||
}
|
||||
|
||||
LINFO("Loading OBJ file '" << filename << "'");
|
||||
bool success = loadModel(filename);
|
||||
if (!success)
|
||||
return false;
|
||||
|
||||
LINFO("Saving cache");
|
||||
success = saveCachedFile(cachedFile);
|
||||
|
||||
return success;
|
||||
loadObj(_file);
|
||||
}
|
||||
|
||||
bool WavefrontGeometry::initialize(RenderableModel* parent) {
|
||||
bool success = ModelGeometry::initialize(parent);
|
||||
PowerScaledScalar ps = PowerScaledScalar(1.0, 0.0); // will set proper bounding soon.
|
||||
_parent->setBoundingSphere(ps);
|
||||
|
||||
if (_vertices.empty())
|
||||
return false;
|
||||
glGenVertexArrays(1, &_vaoID);
|
||||
glGenBuffers(1, &_vbo);
|
||||
glGenBuffers(1, &_ibo);
|
||||
|
||||
glBindVertexArray(_vaoID);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, _vertices.size() * sizeof(Vertex), _vertices.data(), GL_STATIC_DRAW);
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glEnableVertexAttribArray(1);
|
||||
glEnableVertexAttribArray(2);
|
||||
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex),
|
||||
reinterpret_cast<const GLvoid*>(offsetof(Vertex, location)));
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex),
|
||||
reinterpret_cast<const GLvoid*>(offsetof(Vertex, tex)));
|
||||
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
|
||||
reinterpret_cast<const GLvoid*>(offsetof(Vertex, normal)));
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ibo);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, _indices.size() * sizeof(int), _indices.data(), GL_STATIC_DRAW);
|
||||
|
||||
glBindVertexArray(0);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
void WavefrontGeometry::deinitialize() {
|
||||
glDeleteBuffers(1, &_vbo);
|
||||
glDeleteVertexArrays(1, &_vaoID);
|
||||
glDeleteBuffers(1, &_ibo);
|
||||
}
|
||||
|
||||
void WavefrontGeometry::render() {
|
||||
glBindVertexArray(_vaoID);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ibo);
|
||||
glDrawElements(GL_TRIANGLES, _indices.size(), GL_UNSIGNED_INT, 0);
|
||||
glBindVertexArray(0);
|
||||
ModelGeometry::deinitialize();
|
||||
}
|
||||
|
||||
bool WavefrontGeometry::loadModel(const std::string& filename) {
|
||||
@@ -188,15 +94,16 @@ bool WavefrontGeometry::loadModel(const std::string& filename) {
|
||||
_vertices[j + currentPosition].location[0] = shapes[i].mesh.positions[3 * j + 0];
|
||||
_vertices[j + currentPosition].location[1] = shapes[i].mesh.positions[3 * j + 1];
|
||||
_vertices[j + currentPosition].location[2] = shapes[i].mesh.positions[3 * j + 2];
|
||||
_vertices[j + currentPosition].location[3] = 5;
|
||||
|
||||
_vertices[j + currentPosition].location[3] = 5; // Temp size for the power scale coordinate.
|
||||
// Could be defined per object as a dictionary key.
|
||||
|
||||
_vertices[j + currentPosition].normal[0] = shapes[i].mesh.normals[3 * j + 0];
|
||||
_vertices[j + currentPosition].normal[1] = shapes[i].mesh.normals[3 * j + 1];
|
||||
_vertices[j + currentPosition].normal[2] = shapes[i].mesh.normals[3 * j + 2];
|
||||
|
||||
if (2 * j + 1 < shapes[i].mesh.texcoords.size()) {
|
||||
_vertices[j + currentPosition].tex[0] = shapes[0].mesh.texcoords[2 * j + 0];
|
||||
_vertices[j + currentPosition].tex[1] = shapes[0].mesh.texcoords[2 * j + 1];
|
||||
_vertices[j + currentPosition].tex[0] = shapes[i].mesh.texcoords[2 * j + 0];
|
||||
_vertices[j + currentPosition].tex[1] = shapes[i].mesh.texcoords[2 * j + 1];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -209,94 +116,10 @@ bool WavefrontGeometry::loadModel(const std::string& filename) {
|
||||
);
|
||||
p += shapes[i].mesh.indices.size();
|
||||
}
|
||||
/*
|
||||
std::cout << _vertices.size() << " " << shapes[0].mesh.texcoords.size() << std::endl;
|
||||
|
||||
const size_t face_count = shapes[0].mesh.indices.size() / 3;
|
||||
|
||||
for (size_t f = 0; f < face_count; f++)
|
||||
{
|
||||
int vertex_index_list[3];
|
||||
vertex_index_list[0] = shapes[0].mesh.indices[f * 3 + 0];
|
||||
vertex_index_list[1] = shapes[0].mesh.indices[f * 3 + 1];
|
||||
vertex_index_list[2] = shapes[0].mesh.indices[f * 3 + 2];
|
||||
|
||||
const int face[] = {
|
||||
vertex_index_list[0],
|
||||
vertex_index_list[1],
|
||||
vertex_index_list[2]
|
||||
};
|
||||
|
||||
if (!shapes[0].mesh.texcoords.empty())
|
||||
{
|
||||
for (int k = 0; k < 3; k++)
|
||||
{
|
||||
const int vi = face[k];
|
||||
if (vi*2+1 < shapes[0].mesh.texcoords.size()){
|
||||
|
||||
_vertices[vi].tex[0] = shapes[0].mesh.texcoords[2 * vi + 0];
|
||||
_vertices[vi].tex[1] = shapes[0].mesh.texcoords[2 * vi + 1];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WavefrontGeometry::saveCachedFile(const std::string& filename) {
|
||||
std::ofstream fileStream(filename, std::ofstream::binary);
|
||||
if (fileStream.good()) {
|
||||
fileStream.write(reinterpret_cast<const char*>(&CurrentCacheVersion),
|
||||
sizeof(int8_t));
|
||||
|
||||
int64_t vSize = _vertices.size();
|
||||
fileStream.write(reinterpret_cast<const char*>(&vSize), sizeof(int64_t));
|
||||
int64_t iSize = _indices.size();
|
||||
fileStream.write(reinterpret_cast<const char*>(&iSize), sizeof(int64_t));
|
||||
|
||||
fileStream.write(reinterpret_cast<const char*>(_vertices.data()), sizeof(Vertex) * vSize);
|
||||
fileStream.write(reinterpret_cast<const char*>(_indices.data()), sizeof(int) * iSize);
|
||||
|
||||
return fileStream.good();
|
||||
}
|
||||
else {
|
||||
LERROR("Error opening file '" << filename << "' for save cache file");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool WavefrontGeometry::loadCachedFile(const std::string& filename) {
|
||||
std::ifstream fileStream(filename, std::ifstream::binary);
|
||||
if (fileStream.good()) {
|
||||
int8_t version = 0;
|
||||
fileStream.read(reinterpret_cast<char*>(&version), sizeof(int8_t));
|
||||
if (version != CurrentCacheVersion) {
|
||||
LINFO("The format of the cached file has changed, deleting old cache");
|
||||
fileStream.close();
|
||||
FileSys.deleteFile(filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
int64_t vSize, iSize;
|
||||
fileStream.read(reinterpret_cast<char*>(&vSize), sizeof(int64_t));
|
||||
fileStream.read(reinterpret_cast<char*>(&iSize), sizeof(int64_t));
|
||||
|
||||
_vertices.resize(vSize);
|
||||
_indices.resize(iSize);
|
||||
|
||||
fileStream.read(reinterpret_cast<char*>(_vertices.data()), sizeof(Vertex) * vSize);
|
||||
fileStream.read(reinterpret_cast<char*>(_indices.data()), sizeof(int) * iSize);
|
||||
|
||||
return fileStream.good();
|
||||
}
|
||||
else {
|
||||
LERROR("Error opening file '" << filename << "' for loading cache file");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace modelgeometry
|
||||
} // namespace openspace
|
||||
|
||||
@@ -56,20 +56,25 @@ namespace openspace {
|
||||
RenderablePlanet::RenderablePlanet(const ghoul::Dictionary& dictionary)
|
||||
: Renderable(dictionary)
|
||||
, _colorTexturePath("colorTexture", "Color Texture")
|
||||
, _nightTexturePath("")
|
||||
, _programObject(nullptr)
|
||||
, _texture(nullptr)
|
||||
, _nightTexture(nullptr)
|
||||
, _geometry(nullptr)
|
||||
, _performShading("performShading", "Perform Shading", true)
|
||||
, _rotation("rotation", "Rotation", 0, 0, 360)
|
||||
, _hasNightTexture(false)
|
||||
, _alpha(1.f)
|
||||
{
|
||||
std::string name;
|
||||
bool success = dictionary.getValue(constants::scenegraphnode::keyName, name);
|
||||
ghoul_assert(success,
|
||||
"RenderablePlanet need the '" <<constants::scenegraphnode::keyName<<"' be specified");
|
||||
|
||||
std::string path;
|
||||
success = dictionary.getValue(constants::scenegraph::keyPathModule, path);
|
||||
ghoul_assert(success,
|
||||
"RenderablePlanet need the '"<<constants::scenegraph::keyPathModule<<"' be specified");
|
||||
std::string path;
|
||||
success = dictionary.getValue(constants::scenegraph::keyPathModule, path);
|
||||
//ghoul_assert(success,
|
||||
// "RenderablePlanet need the '"<<constants::scenegraph::keyPathModule<<"' be specified");
|
||||
|
||||
ghoul::Dictionary geometryDictionary;
|
||||
success = dictionary.getValue(keyGeometry, geometryDictionary);
|
||||
@@ -80,9 +85,9 @@ RenderablePlanet::RenderablePlanet(const ghoul::Dictionary& dictionary)
|
||||
}
|
||||
|
||||
dictionary.getValue(keyFrame, _frame);
|
||||
|
||||
dictionary.getValue(keyBody, _target);
|
||||
//assert(b1 == true);
|
||||
if (_target != "")
|
||||
setBody(_target);
|
||||
|
||||
// TODO: textures need to be replaced by a good system similar to the geometry as soon
|
||||
// as the requirements are fixed (ab)
|
||||
@@ -90,7 +95,16 @@ RenderablePlanet::RenderablePlanet(const ghoul::Dictionary& dictionary)
|
||||
success = dictionary.getValue("Textures.Color", texturePath);
|
||||
_colorTexturePath = absPath(texturePath);
|
||||
if (success)
|
||||
_colorTexturePath = path + "/" + texturePath;
|
||||
_colorTexturePath = path + "/" + texturePath;
|
||||
|
||||
std::string nightTexturePath = "";
|
||||
dictionary.getValue("Textures.Night", nightTexturePath);
|
||||
|
||||
if (nightTexturePath != ""){
|
||||
_hasNightTexture = true;
|
||||
_nightTexturePath = absPath(nightTexturePath);
|
||||
_nightTexturePath = path + "/" + nightTexturePath;
|
||||
}
|
||||
|
||||
addPropertySubOwner(_geometry);
|
||||
|
||||
@@ -104,14 +118,18 @@ RenderablePlanet::RenderablePlanet(const ghoul::Dictionary& dictionary)
|
||||
}
|
||||
|
||||
addProperty(_performShading);
|
||||
// Mainly for debugging purposes @AA
|
||||
addProperty(_rotation);
|
||||
}
|
||||
|
||||
RenderablePlanet::~RenderablePlanet() {
|
||||
}
|
||||
|
||||
bool RenderablePlanet::initialize() {
|
||||
if (_programObject == nullptr)
|
||||
OsEng.ref().configurationManager()->getValue("pscShader", _programObject);
|
||||
if (_programObject == nullptr && _hasNightTexture)
|
||||
OsEng.ref().configurationManager()->getValue("nightTextureProgram", _programObject);
|
||||
else if (_programObject == nullptr)
|
||||
OsEng.ref().configurationManager()->getValue("pscShader", _programObject);
|
||||
|
||||
loadTexture();
|
||||
_geometry->initialize(this);
|
||||
@@ -124,11 +142,14 @@ bool RenderablePlanet::deinitialize() {
|
||||
_geometry->deinitialize();
|
||||
delete _geometry;
|
||||
}
|
||||
if(_texture)
|
||||
if (_texture)
|
||||
delete _texture;
|
||||
if (_nightTexture)
|
||||
delete _nightTexture;
|
||||
|
||||
_geometry = nullptr;
|
||||
_texture = nullptr;
|
||||
_nightTexture = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -150,17 +171,15 @@ void RenderablePlanet::render(const RenderData& data)
|
||||
|
||||
//earth needs to be rotated for that to work.
|
||||
glm::mat4 rot = glm::rotate(transform, 90.f, glm::vec3(1, 0, 0));
|
||||
|
||||
glm::mat4 roty = glm::rotate(transform, 90.f, glm::vec3(0, -1, 0));
|
||||
glm::mat4 rotProp = glm::rotate(transform, static_cast<float>(_rotation), glm::vec3(0, 1, 0));
|
||||
|
||||
for (int i = 0; i < 3; i++){
|
||||
for (int j = 0; j < 3; j++){
|
||||
transform[i][j] = static_cast<float>(_stateMatrix[i][j]);
|
||||
}
|
||||
}
|
||||
transform = transform* rot;
|
||||
if (_frame == "IAU_JUPITER"){ //x = 0.935126
|
||||
transform *= glm::scale(glm::mat4(1), glm::vec3(1, 0.93513, 1));
|
||||
}
|
||||
|
||||
transform = transform * rot * roty * rotProp;
|
||||
|
||||
//glm::mat4 modelview = data.camera.viewMatrix()*data.camera.modelMatrix();
|
||||
//glm::vec3 camSpaceEye = (-(modelview*data.position.vec4())).xyz;
|
||||
@@ -171,6 +190,7 @@ void RenderablePlanet::render(const RenderData& data)
|
||||
|
||||
// setup the data to the shader
|
||||
// _programObject->setUniform("camdir", camSpaceEye);
|
||||
_programObject->setUniform("transparency", _alpha);
|
||||
_programObject->setUniform("ViewProjection", data.camera.viewProjectionMatrix());
|
||||
_programObject->setUniform("ModelTransform", transform);
|
||||
setPscUniforms(_programObject, &data.camera, data.position);
|
||||
@@ -178,11 +198,18 @@ void RenderablePlanet::render(const RenderData& data)
|
||||
_programObject->setUniform("_performShading", _performShading);
|
||||
|
||||
// Bind texture
|
||||
ghoul::opengl::TextureUnit unit;
|
||||
unit.activate();
|
||||
ghoul::opengl::TextureUnit dayUnit;
|
||||
dayUnit.activate();
|
||||
_texture->bind();
|
||||
_programObject->setUniform("texture1", unit);
|
||||
_programObject->setUniform("texture1", dayUnit);
|
||||
|
||||
// Bind possible night texture
|
||||
if (_hasNightTexture) {
|
||||
ghoul::opengl::TextureUnit nightUnit;
|
||||
nightUnit.activate();
|
||||
_nightTexture->bind();
|
||||
_programObject->setUniform("nightTex", nightUnit);
|
||||
}
|
||||
// render
|
||||
_geometry->render();
|
||||
|
||||
@@ -199,16 +226,28 @@ void RenderablePlanet::update(const UpdateData& data){
|
||||
void RenderablePlanet::loadTexture() {
|
||||
delete _texture;
|
||||
_texture = nullptr;
|
||||
if (_colorTexturePath.value() != "") {
|
||||
_texture = ghoul::io::TextureReader::ref().loadTexture(absPath(_colorTexturePath));
|
||||
if (_texture) {
|
||||
LDEBUG("Loaded texture from '" << absPath(_colorTexturePath) << "'");
|
||||
if (_colorTexturePath.value() != "") {
|
||||
_texture = ghoul::io::TextureReader::ref().loadTexture(absPath(_colorTexturePath));
|
||||
if (_texture) {
|
||||
LDEBUG("Loaded texture from '" << _colorTexturePath << "'");
|
||||
_texture->uploadTexture();
|
||||
|
||||
// Textures of planets looks much smoother with AnisotropicMipMap rather than linear
|
||||
_texture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap);
|
||||
}
|
||||
}
|
||||
if (_hasNightTexture) {
|
||||
delete _nightTexture;
|
||||
_nightTexture = nullptr;
|
||||
if (_nightTexturePath != "") {
|
||||
_nightTexture = ghoul::io::TextureReader::ref().loadTexture(absPath(_nightTexturePath));
|
||||
if (_nightTexture) {
|
||||
LDEBUG("Loaded texture from '" << _nightTexturePath << "'");
|
||||
_nightTexture->uploadTexture();
|
||||
_nightTexture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -85,14 +85,14 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary&
|
||||
: Renderable(dictionary)
|
||||
, _colorTexturePath("planetTexture", "RGB Texture")
|
||||
, _projectionTexturePath("projectionTexture", "RGB Texture")
|
||||
, _imageTrigger("clearProjections", "Clear Projections")
|
||||
//, _sequencer(nullptr)
|
||||
, _fadeProjection("fadeProjections", "Image Fading Factor", 0.f, 0.f, 1.f)
|
||||
, _programObject(nullptr)
|
||||
, _fboProgramObject(nullptr)
|
||||
, _texture(nullptr)
|
||||
, _textureProj(nullptr)
|
||||
, _textureOriginal(nullptr)
|
||||
, _geometry(nullptr)
|
||||
, _sequenceID(-1)
|
||||
, _rotation("rotation", "Rotation", 0, 0, 360)
|
||||
, _once(false)
|
||||
{
|
||||
std::string name;
|
||||
@@ -114,11 +114,14 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary&
|
||||
_geometry = planetgeometryprojection::PlanetGeometryProjection::createFromDictionary(geometryDictionary);
|
||||
}
|
||||
|
||||
dictionary.getValue(keyFrame, _target);
|
||||
dictionary.getValue(keyFrame, _frame);
|
||||
dictionary.getValue(keyBody, _target);
|
||||
if (_target != "")
|
||||
setBody(_target);
|
||||
|
||||
bool b1 = dictionary.getValue(keyInstrument, _instrumentID);
|
||||
bool b2 = dictionary.getValue(keyProjObserver, _projectorID);
|
||||
bool b3 = dictionary.getValue(keyProjTarget, _projecteeID);
|
||||
bool b1 = dictionary.getValue(keyInstrument, _instrumentID);
|
||||
bool b2 = dictionary.getValue(keyProjObserver, _projectorID);
|
||||
bool b3 = dictionary.getValue(keyProjTarget, _projecteeID);
|
||||
bool b4 = dictionary.getValue(keyProjAberration, _aberration);
|
||||
bool b5 = dictionary.getValue(keyInstrumentFovy, _fovy);
|
||||
bool b6 = dictionary.getValue(keyInstrumentAspect, _aspectRatio);
|
||||
@@ -158,9 +161,8 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary&
|
||||
_projectionTexturePath = path + "/" + texturePath;
|
||||
}
|
||||
addPropertySubOwner(_geometry);
|
||||
|
||||
addProperty(_imageTrigger);
|
||||
_imageTrigger.onChange(std::bind(&RenderablePlanetProjection::loadTexture, this));
|
||||
addProperty(_rotation);
|
||||
addProperty(_fadeProjection);
|
||||
|
||||
addProperty(_colorTexturePath);
|
||||
_colorTexturePath.onChange(std::bind(&RenderablePlanetProjection::loadTexture, this));
|
||||
@@ -181,34 +183,22 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary&
|
||||
//get translation dictionary
|
||||
dictionary.getValue(keyTranslation, translationDictionary);
|
||||
|
||||
|
||||
if (_sequenceType == sequenceTypePlaybook){
|
||||
// eeh to many inputs, bit ugly. beautify later.
|
||||
parser = new HongKangParser(_sequenceSource,
|
||||
"NEW HORIZONS",
|
||||
translationDictionary,
|
||||
_potentialTargets);
|
||||
openspace::ImageSequencer2::ref().runSequenceParser(parser);
|
||||
}
|
||||
/*else if (_sequenceType == sequenceTypeImage){
|
||||
else if (_sequenceType == sequenceTypeImage){
|
||||
parser = new LabelParser(_sequenceSource, translationDictionary);
|
||||
}*/
|
||||
openspace::ImageSequencer2::ref().runSequenceParser(parser);
|
||||
|
||||
}
|
||||
}
|
||||
else{
|
||||
LWARNING("No playbook translation provided, please make sure all spice calls match playbook!");
|
||||
}
|
||||
|
||||
/*if (_sequenceType == sequenceTypeImage) {
|
||||
LWARNING("LOADING STUFF FOR JUPITER!");
|
||||
//openspace::ImageSequencer::ref().loadSequence(_sequenceSource, _sequenceID);
|
||||
// SequenceParser *parser = new LabelParser(_sequenceSource,
|
||||
//"NEW HORIZONS",
|
||||
//_fileTranslation,
|
||||
//_potentialTargets);
|
||||
//openspace::ImageSequencer2::ref().runSequenceParser(parser);
|
||||
}*/
|
||||
/*else*/ if (_sequenceType == sequenceTypePlaybook) {
|
||||
openspace::ImageSequencer2::ref().runSequenceParser(parser);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -311,6 +301,13 @@ void RenderablePlanetProjection::imageProjectGPU(){
|
||||
unitFbo.activate();
|
||||
_textureProj->bind();
|
||||
_fboProgramObject->setUniform("texture1" , unitFbo);
|
||||
|
||||
ghoul::opengl::TextureUnit unitFbo2;
|
||||
unitFbo2.activate();
|
||||
_textureOriginal->bind();
|
||||
_fboProgramObject->setUniform("texture2", unitFbo2);
|
||||
_fboProgramObject->setUniform("projectionFading", _fadeProjection);
|
||||
|
||||
_fboProgramObject->setUniform("ProjectorMatrix", _projectorMatrix);
|
||||
_fboProgramObject->setUniform("ModelTransform" , _transform);
|
||||
_fboProgramObject->setUniform("_scaling" , _camScaling);
|
||||
@@ -318,8 +315,8 @@ void RenderablePlanetProjection::imageProjectGPU(){
|
||||
|
||||
if (_geometry->hasProperty("radius")){
|
||||
boost::any r = _geometry->property("radius")->get();
|
||||
if (glm::vec2* radius = boost::any_cast<glm::vec2>(&r)){
|
||||
_fboProgramObject->setUniform("radius", radius[0]);
|
||||
if (glm::vec4* radius = boost::any_cast<glm::vec4>(&r)){
|
||||
_fboProgramObject->setUniform("radius", radius);
|
||||
}
|
||||
}else{
|
||||
LERROR("Geometry object needs to provide radius");
|
||||
@@ -344,7 +341,7 @@ void RenderablePlanetProjection::imageProjectGPU(){
|
||||
m_viewport[2], m_viewport[3]);
|
||||
|
||||
}
|
||||
#include <math.h>
|
||||
|
||||
glm::mat4 RenderablePlanetProjection::computeProjectorMatrix(const glm::vec3 loc, glm::dvec3 aim, const glm::vec3 up){
|
||||
//rotate boresight into correct alignment
|
||||
_boresight = _instrumentMatrix*aim;
|
||||
@@ -370,21 +367,22 @@ glm::mat4 RenderablePlanetProjection::computeProjectorMatrix(const glm::vec3 loc
|
||||
|
||||
void RenderablePlanetProjection::attitudeParameters(double time){
|
||||
// precomputations for shader
|
||||
openspace::SpiceManager::ref().getPositionTransformMatrix(_target, _mainFrame, time, _stateMatrix);
|
||||
openspace::SpiceManager::ref().getPositionTransformMatrix(_frame, _mainFrame, time, _stateMatrix);
|
||||
openspace::SpiceManager::ref().getPositionTransformMatrix(_instrumentID, _mainFrame, time, _instrumentMatrix);
|
||||
|
||||
_transform = glm::mat4(1);
|
||||
//90 deg rotation w.r.t spice req.
|
||||
glm::mat4 rot = glm::rotate(_transform, 90.f, glm::vec3(1, 0, 0));
|
||||
glm::mat4 roty = glm::rotate(_transform, 90.f, glm::vec3(0, -1, 0));
|
||||
glm::mat4 rotProp = glm::rotate(_transform, static_cast<float>(_rotation), glm::vec3(0, 1, 0));
|
||||
|
||||
for (int i = 0; i < 3; i++){
|
||||
for (int j = 0; j < 3; j++){
|
||||
_transform[i][j] = _stateMatrix[i][j];
|
||||
_transform[i][j] = static_cast<float>(_stateMatrix[i][j]);
|
||||
}
|
||||
}
|
||||
_transform = _transform* rot;
|
||||
if (_target == "IAU_JUPITER"){ // tmp solution scale of jupiterX = 0.935126
|
||||
_transform *= glm::scale(glm::mat4(1), glm::vec3(1, 0.935126, 1));
|
||||
}
|
||||
_transform = _transform * rot * roty * rotProp;
|
||||
|
||||
std::string shape, instrument;
|
||||
std::vector<glm::dvec3> bounds;
|
||||
glm::dvec3 bs;
|
||||
@@ -395,7 +393,6 @@ void RenderablePlanetProjection::attitudeParameters(double time){
|
||||
|
||||
psc position; //observer target
|
||||
found = SpiceManager::ref().getTargetPosition(_projectorID, _projecteeID, _mainFrame, _aberration, time, position, lightTime);
|
||||
//if (!found) LERROR("Could not locate target position");
|
||||
|
||||
//change to KM and add psc camera scaling.
|
||||
position[3] += (3 + _camScaling[1]);
|
||||
@@ -414,9 +411,9 @@ void RenderablePlanetProjection::render(const RenderData& data){
|
||||
|
||||
#ifdef GPU_PROJ
|
||||
if (_capture){
|
||||
for (auto imgSubset : _imageTimes){
|
||||
attitudeParameters(imgSubset.first); // projector viewmatrix
|
||||
_projectionTexturePath = imgSubset.second; // path to current images
|
||||
for (auto img : _imageTimes){
|
||||
attitudeParameters(img.startTime); // compute projector viewmatrix
|
||||
_projectionTexturePath = img.path; // path to current images
|
||||
imageProjectGPU(); //fbopass
|
||||
}
|
||||
_capture = false;
|
||||
@@ -438,7 +435,7 @@ void RenderablePlanetProjection::render(const RenderData& data){
|
||||
_programObject->setUniform("ModelTransform" , _transform);
|
||||
_programObject->setUniform("boresight" , _boresight);
|
||||
setPscUniforms(_programObject, &data.camera, data.position);
|
||||
|
||||
|
||||
// Bind texture
|
||||
ghoul::opengl::TextureUnit unit[2];
|
||||
unit[0].activate();
|
||||
@@ -447,6 +444,7 @@ void RenderablePlanetProjection::render(const RenderData& data){
|
||||
unit[1].activate();
|
||||
_textureProj->bind();
|
||||
_programObject->setUniform("texture2", unit[1]);
|
||||
|
||||
// render geometry
|
||||
_geometry->render();
|
||||
// disable shader
|
||||
@@ -457,13 +455,13 @@ void RenderablePlanetProjection::update(const UpdateData& data){
|
||||
// set spice-orientation in accordance to timestamp
|
||||
_time = data.time;
|
||||
_capture = false;
|
||||
|
||||
|
||||
if (openspace::ImageSequencer2::ref().isReady()){
|
||||
openspace::ImageSequencer2::ref().updateSequencer(_time);
|
||||
_capture = openspace::ImageSequencer2::ref().getImagePaths(_imageTimes, _projecteeID, _instrumentID);
|
||||
}
|
||||
|
||||
//floor fading to decimal
|
||||
//_fadeProjection = floorf(_fadeProjection * 10) / 10;
|
||||
}
|
||||
|
||||
void RenderablePlanetProjection::loadProjectionTexture(){
|
||||
@@ -477,7 +475,6 @@ void RenderablePlanetProjection::loadProjectionTexture(){
|
||||
_textureProj->setWrapping(ghoul::opengl::Texture::WrappingMode::ClampToBorder);
|
||||
}
|
||||
}
|
||||
//_sequencer->sequenceReset();
|
||||
}
|
||||
|
||||
void RenderablePlanetProjection::loadTexture(){
|
||||
@@ -490,5 +487,14 @@ void RenderablePlanetProjection::loadTexture(){
|
||||
_texture->setFilter(ghoul::opengl::Texture::FilterMode::Linear);
|
||||
}
|
||||
}
|
||||
delete _textureOriginal;
|
||||
_textureOriginal = nullptr;
|
||||
if (_colorTexturePath.value() != "") {
|
||||
_textureOriginal = ghoul::io::TextureReader::ref().loadTexture(absPath(_colorTexturePath));
|
||||
if (_textureOriginal) {
|
||||
_textureOriginal->uploadTexture();
|
||||
_textureOriginal->setFilter(ghoul::opengl::Texture::FilterMode::Linear);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace openspace
|
||||
|
||||
@@ -43,8 +43,8 @@ namespace planetgeometry {
|
||||
|
||||
SimpleSphereGeometry::SimpleSphereGeometry(const ghoul::Dictionary& dictionary)
|
||||
: PlanetGeometry()
|
||||
, _radius("radius", "Radius", glm::vec2(1.f, 0.f), glm::vec2(-10.f, -20.f),
|
||||
glm::vec2(10.f, 20.f))
|
||||
, _realRadius("radius", "Radius", glm::vec4(1.f, 1.f, 1.f, 0.f), glm::vec4(-10.f, -10.f, -10.f, -20.f),
|
||||
glm::vec4(10.f, 10.f, 10.f, 20.f))
|
||||
, _segments("segments", "Segments", 20, 1, 50)
|
||||
, _sphere(nullptr)
|
||||
{
|
||||
@@ -53,30 +53,37 @@ SimpleSphereGeometry::SimpleSphereGeometry(const ghoul::Dictionary& dictionary)
|
||||
using constants::simplespheregeometry::keySegments;
|
||||
|
||||
// The name is passed down from the SceneGraphNode
|
||||
std::string name;
|
||||
bool success = dictionary.getValue(keyName, name);
|
||||
bool success = dictionary.getValue(keyName, _name);
|
||||
assert(success);
|
||||
|
||||
glm::vec2 radius;
|
||||
success = dictionary.getValue(keyRadius, radius);
|
||||
|
||||
glm::vec4 radius;
|
||||
success = dictionary.getValue(keyRadius, _modRadius);
|
||||
if (!success) {
|
||||
LERROR("SimpleSphereGeometry of '" << name << "' did not provide a key '"
|
||||
LERROR("SimpleSphereGeometry of '" << _name << "' did not provide a key '"
|
||||
<< keyRadius << "'");
|
||||
}
|
||||
else
|
||||
_radius = radius;
|
||||
else {
|
||||
radius[0] = _modRadius[0];
|
||||
radius[1] = _modRadius[0];
|
||||
radius[2] = _modRadius[0];
|
||||
radius[3] = _modRadius[1];
|
||||
_realRadius = radius; // In case the kernels does not supply a real
|
||||
}
|
||||
|
||||
double segments;
|
||||
success = dictionary.getValue(keySegments, segments);
|
||||
if (!success) {
|
||||
LERROR("SimpleSphereGeometry of '" << name << "' did not provide a key '"
|
||||
LERROR("SimpleSphereGeometry of '" << _name << "' did not provide a key '"
|
||||
<< keySegments << "'");
|
||||
}
|
||||
else
|
||||
_segments = static_cast<int>(segments);
|
||||
|
||||
addProperty(_radius);
|
||||
_radius.onChange(std::bind(&SimpleSphereGeometry::createSphere, this));
|
||||
// The shader need the radii values but they are not changeable runtime
|
||||
// TODO: Possibly add a scaling property @AA
|
||||
addProperty(_realRadius);
|
||||
// Changing the radius/scaling should affect the shader but not the geometry? @AA
|
||||
//_radius.onChange(std::bind(&SimpleSphereGeometry::createSphere, this));
|
||||
addProperty(_segments);
|
||||
_segments.onChange(std::bind(&SimpleSphereGeometry::createSphere, this));
|
||||
}
|
||||
@@ -107,13 +114,13 @@ void SimpleSphereGeometry::render()
|
||||
void SimpleSphereGeometry::createSphere(){
|
||||
//create the power scaled scalar
|
||||
|
||||
PowerScaledScalar planetSize(_radius);
|
||||
PowerScaledScalar planetSize(_modRadius);
|
||||
_parent->setBoundingSphere(planetSize);
|
||||
|
||||
if(_sphere)
|
||||
delete _sphere;
|
||||
|
||||
_sphere = new PowerScaledSphere(planetSize, _segments);
|
||||
//_sphere = new PowerScaledSphere(planetSize, _segments);
|
||||
_sphere = new PowerScaledSphere(_realRadius, _segments, _name);
|
||||
_sphere->initialize();
|
||||
}
|
||||
|
||||
|
||||
@@ -42,8 +42,8 @@ namespace planetgeometryprojection {
|
||||
|
||||
SimpleSphereGeometryProjection::SimpleSphereGeometryProjection(const ghoul::Dictionary& dictionary)
|
||||
: PlanetGeometryProjection()
|
||||
, _radius("radius", "Radius", glm::vec2(1.f, 0.f), glm::vec2(-10.f, -20.f),
|
||||
glm::vec2(10.f, 20.f))
|
||||
, _realRadius("radius", "Radius", glm::vec4(1.f, 1.f, 1.f, 0.f), glm::vec4(-10.f, -10.f, -10.f, -20.f),
|
||||
glm::vec4(10.f, 10.f, 10.f, 20.f))
|
||||
, _segments("segments", "Segments", 20, 1, 1000)
|
||||
, _vaoID("vaoID", "Vao", 1, 1, 1)
|
||||
, _vBufferID("vboID", "Vbo", 1, 1, 1)
|
||||
@@ -55,30 +55,37 @@ SimpleSphereGeometryProjection::SimpleSphereGeometryProjection(const ghoul::Dict
|
||||
using constants::simplespheregeometryprojection::keySegments;
|
||||
|
||||
// The name is passed down from the SceneGraphNode
|
||||
std::string name;
|
||||
bool success = dictionary.getValue(keyName, name);
|
||||
bool success = dictionary.getValue(keyName, _name);
|
||||
assert(success);
|
||||
|
||||
glm::vec2 radius;
|
||||
success = dictionary.getValue(keyRadius, radius);
|
||||
// removing "Projection"-suffix from name for SPICE compability, TODO: better solution @AA
|
||||
if(_name.find("Projection"))
|
||||
_name = _name.substr(0, _name.size() - 10);
|
||||
|
||||
glm::vec4 radius;
|
||||
success = dictionary.getValue(keyRadius, _modRadius);
|
||||
if (!success) {
|
||||
LERROR("SimpleSphereGeometry of '" << name << "' did not provide a key '"
|
||||
LERROR("SimpleSphereGeometry of '" << _name << "' did not provide a key '"
|
||||
<< keyRadius << "'");
|
||||
}
|
||||
else
|
||||
_radius = radius;
|
||||
|
||||
else {
|
||||
radius[0] = _modRadius[0];
|
||||
radius[1] = _modRadius[0];
|
||||
radius[2] = _modRadius[0];
|
||||
radius[3] = _modRadius[1];
|
||||
_realRadius = radius;
|
||||
}
|
||||
double segments;
|
||||
success = dictionary.getValue(keySegments, segments);
|
||||
if (!success) {
|
||||
LERROR("SimpleSphereGeometry of '" << name << "' did not provide a key '"
|
||||
LERROR("SimpleSphereGeometry of '" << _name << "' did not provide a key '"
|
||||
<< keySegments << "'");
|
||||
}
|
||||
else
|
||||
_segments = static_cast<int>(segments);
|
||||
|
||||
addProperty(_radius);
|
||||
_radius.onChange(std::bind(&SimpleSphereGeometryProjection::createSphere, this));
|
||||
addProperty(_realRadius);
|
||||
//_realRadius.onChange(std::bind(&SimpleSphereGeometryProjection::createSphere, this));
|
||||
addProperty(_segments);
|
||||
_segments.onChange(std::bind(&SimpleSphereGeometryProjection::createSphere, this));
|
||||
}
|
||||
@@ -117,12 +124,12 @@ void SimpleSphereGeometryProjection::createSphere()
|
||||
{
|
||||
//create the power scaled scalar
|
||||
|
||||
PowerScaledScalar planetSize(_radius);
|
||||
PowerScaledScalar planetSize(_modRadius);
|
||||
_parent->setBoundingSphere(planetSize);
|
||||
|
||||
delete _planet;
|
||||
_planet = new PowerScaledSphere(planetSize, _segments);
|
||||
_planet->initialize();
|
||||
_planet = new PowerScaledSphere(_realRadius, _segments, _name);
|
||||
_planet->initialize();
|
||||
}
|
||||
|
||||
} // namespace planetgeometry
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <openspace/util/constants.h>
|
||||
#include <openspace/util/factorymanager.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
#include <openspace/util/spicemanager.h>
|
||||
|
||||
// ghoul
|
||||
#include <ghoul/misc/dictionary.h>
|
||||
@@ -36,6 +37,9 @@
|
||||
|
||||
namespace {
|
||||
const std::string _loggerCat = "Renderable";
|
||||
const std::string keyBody = "Body";
|
||||
const std::string keyStart = "StartTime";
|
||||
const std::string keyEnd = "EndTime";
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
@@ -67,7 +71,12 @@ Renderable* Renderable::createFromDictionary(const ghoul::Dictionary& dictionary
|
||||
}
|
||||
|
||||
Renderable::Renderable(const ghoul::Dictionary& dictionary)
|
||||
: _enabled("enabled", "Is Enabled", true)
|
||||
: _enabled("enabled", "Is Enabled", true),
|
||||
_hasTimeInterval(false),
|
||||
_startTime(""),
|
||||
_endTime(""),
|
||||
_targetBody(""),
|
||||
_hasBody(false)
|
||||
{
|
||||
setName("renderable");
|
||||
#ifndef NDEBUG
|
||||
@@ -86,6 +95,12 @@ Renderable::Renderable(const ghoul::Dictionary& dictionary)
|
||||
if (success)
|
||||
_relativePath += ghoul::filesystem::FileSystem::PathSeparator;
|
||||
|
||||
dictionary.getValue(keyStart, _startTime);
|
||||
dictionary.getValue(keyEnd, _endTime);
|
||||
|
||||
if (_startTime != "" && _endTime != "")
|
||||
_hasTimeInterval = true;
|
||||
|
||||
addProperty(_enabled);
|
||||
}
|
||||
|
||||
@@ -135,6 +150,38 @@ bool Renderable::isVisible() const {
|
||||
return _enabled;
|
||||
}
|
||||
|
||||
bool Renderable::hasTimeInterval() {
|
||||
return _hasTimeInterval;
|
||||
}
|
||||
|
||||
bool Renderable::hasBody() {
|
||||
return _hasBody;
|
||||
}
|
||||
|
||||
bool Renderable::getInterval(double& start, double& end) {
|
||||
if (_startTime != "" && _endTime != "") {
|
||||
bool successStart = openspace::SpiceManager::ref().getETfromDate(_startTime, start);
|
||||
bool successEnd = openspace::SpiceManager::ref().getETfromDate(_endTime, end);
|
||||
return successStart && successEnd;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Renderable::getBody(std::string& body) {
|
||||
if (_hasBody) {
|
||||
body = _targetBody;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void Renderable::setBody(std::string& body) {
|
||||
_targetBody = body;
|
||||
_hasBody = true;
|
||||
}
|
||||
|
||||
bool Renderable::isReady() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
#include <openspace/util/constants.h>
|
||||
#include <openspace/util/spicemanager.h>
|
||||
|
||||
#include <openspace/util/imagesequencer.h>
|
||||
#include <openspace/util/imagesequencer2.h> // testing
|
||||
#include <openspace/util/time.h>
|
||||
|
||||
@@ -72,6 +71,7 @@ namespace openspace{
|
||||
, _lineWidth("lineWidth", "Line Width", 1.f, 1.f, 20.f)
|
||||
, _programObject(nullptr)
|
||||
, _texture(nullptr)
|
||||
, _drawSolid("solidDraw", "Draw as Quads", false)
|
||||
, _mode(GL_LINES){
|
||||
|
||||
bool success = dictionary.getValue(keyBody, _spacecraft);
|
||||
@@ -101,6 +101,7 @@ namespace openspace{
|
||||
}
|
||||
|
||||
addProperty(_lineWidth);
|
||||
addProperty(_drawSolid);
|
||||
}
|
||||
|
||||
void RenderableFov::allocateData(){
|
||||
@@ -123,7 +124,7 @@ void RenderableFov::allocateData(){
|
||||
_vtotal[0] = static_cast<int>(_vsize[0] / _stride[0]);
|
||||
|
||||
// allocate second vbo data
|
||||
int cornerPoints = 6;
|
||||
int cornerPoints = 12;
|
||||
_isize[1] = cornerPoints;
|
||||
_iarray1[1] = new int[_isize[1]];
|
||||
for (int i = 0; i < _isize[1]; i++){
|
||||
@@ -293,8 +294,8 @@ void RenderableFov::fovProjection(bool H[], std::vector<glm::dvec3> bounds){
|
||||
glm::dvec3 next;
|
||||
glm::vec4 tmp(1);
|
||||
if (bounds.size() > 1){
|
||||
for (int i = 0; i < 4; i++){
|
||||
int k = (i + 1 > 4 - 1) ? 0 : i + 1;
|
||||
for (int i = 0; i < bounds.size(); i++){
|
||||
int k = (i + 1 > bounds.size() - 1) ? 0 : i + 1;
|
||||
|
||||
current = bounds[i];
|
||||
next = bounds[k];
|
||||
@@ -306,8 +307,6 @@ void RenderableFov::fovProjection(bool H[], std::vector<glm::dvec3> bounds){
|
||||
mid = bisection(current, next, tolerance);
|
||||
for (int j = 1; j <= _isteps; j++){
|
||||
t = ((double)j / _isteps);
|
||||
// TODO: change the interpolate scheme to place points not on a straight line but instead
|
||||
// using either slerp or some other viable method (goal: eliminate checkForIntercept -method)
|
||||
interpolated = interpolate(current, mid, t);
|
||||
_interceptVector = (j < _isteps) ? checkForIntercept(interpolated) : orthogonalProjection(interpolated);
|
||||
insertPoint(_varray2, _interceptVector, col_sq);
|
||||
@@ -334,7 +333,8 @@ void RenderableFov::fovProjection(bool H[], std::vector<glm::dvec3> bounds){
|
||||
}
|
||||
if (_nrInserted == 0){
|
||||
_rebuild = false;
|
||||
}else{
|
||||
}
|
||||
else {
|
||||
_rebuild = true;
|
||||
//update size etc;
|
||||
_vtotal[1] = _nrInserted;
|
||||
@@ -383,7 +383,7 @@ void RenderableFov::computeColors(){
|
||||
c_project = glm::vec4(0.0, 1.0, 0.00,1);
|
||||
col_end = glm::vec4(1.00, 0.29, 0.00, 1);
|
||||
blue = glm::vec4(0, 0.5, 0.7, 1);
|
||||
col_gray = glm::vec4(0.5, 0.5, 0.5, 0.5);
|
||||
col_gray = glm::vec4(0.7);
|
||||
col_start = glm::vec4(1.00, 0.89, 0.00, 1);
|
||||
col_sq = glm::vec4(1.00, 0.29, 0.00, 1);
|
||||
|
||||
@@ -416,18 +416,18 @@ void RenderableFov::render(const RenderData& data){
|
||||
spacecraftRot[i][j] = _stateMatrix[i][j];
|
||||
}
|
||||
}
|
||||
bool drawFOV = false;
|
||||
|
||||
// setup the data to the shader
|
||||
_programObject->setUniform("ViewProjection", data.camera.viewProjectionMatrix());
|
||||
_programObject->setUniform("ModelTransform", transform);
|
||||
setPscUniforms(_programObject, &data.camera, data.position);
|
||||
|
||||
bool drawFOV = false;
|
||||
|
||||
if (openspace::ImageSequencer2::ref().isReady()){
|
||||
drawFOV = ImageSequencer2::ref().instumentActive(_instrumentID);
|
||||
}
|
||||
|
||||
|
||||
if (drawFOV){
|
||||
// update only when time progresses.
|
||||
if (_oldTime != _time){
|
||||
@@ -465,8 +465,9 @@ void RenderableFov::render(const RenderData& data){
|
||||
double targetEpoch;
|
||||
// for each FOV vector
|
||||
for (int i = 0; i <= bounds.size(); i++){
|
||||
// compute surface intercept
|
||||
int r = (i == bounds.size()) ? 0 : i;
|
||||
|
||||
// compute surface intercept
|
||||
openspace::SpiceManager::ref().getSurfaceIntercept(_fovTarget, _spacecraft, _instrumentID,
|
||||
_frame, _method, _aberrationCorrection,
|
||||
_time, targetEpoch, bounds[r], ipoint, ivec, _interceptTag[r]);
|
||||
@@ -513,15 +514,38 @@ void RenderableFov::render(const RenderData& data){
|
||||
}
|
||||
}
|
||||
|
||||
_interceptTag[4] = _interceptTag[0];
|
||||
fovProjection(_interceptTag, bounds);
|
||||
_interceptTag[bounds.size()] = _interceptTag[0];
|
||||
|
||||
|
||||
if (!(_instrumentID == "NH_LORRI")) // image plane replaces fov square
|
||||
fovProjection(_interceptTag, bounds);
|
||||
|
||||
updateData();
|
||||
glm::vec3 aim = (spacecraftRot * glm::vec4(boresight, 1)).xyz;
|
||||
psc position;
|
||||
double lt;
|
||||
SpiceManager::ref().getTargetPosition(_fovTarget,
|
||||
_spacecraft,
|
||||
_frame,
|
||||
_aberrationCorrection,
|
||||
_time,
|
||||
position,
|
||||
lt);
|
||||
|
||||
//if aimed 80 deg away from target, dont draw white square
|
||||
if (glm::dot(glm::normalize(aim), glm::normalize(position.vec3())) < 0.2){
|
||||
drawFOV = false;
|
||||
}
|
||||
|
||||
}
|
||||
_oldTime = _time;
|
||||
|
||||
if (!_drawSolid) _mode = GL_LINES;
|
||||
else _mode = GL_TRIANGLE_STRIP;
|
||||
|
||||
glLineWidth(_lineWidth);
|
||||
glBindVertexArray(_vaoID[0]);
|
||||
glDrawArrays(GL_LINES, 0, _vtotal[0]);
|
||||
glDrawArrays(_mode, 0, _vtotal[0]);
|
||||
glBindVertexArray(0);
|
||||
|
||||
glLineWidth(_lineWidth);
|
||||
@@ -529,7 +553,6 @@ void RenderableFov::render(const RenderData& data){
|
||||
glDrawArrays(GL_LINES, 0, _vtotal[0]);
|
||||
glBindVertexArray(0);
|
||||
|
||||
//second vbo
|
||||
if (drawFOV){
|
||||
glLineWidth(1.f);
|
||||
glBindVertexArray(_vaoID[1]);
|
||||
|
||||
@@ -83,7 +83,7 @@ bool RenderablePath::fullYearSweep(){
|
||||
double lightTime = 0.0;
|
||||
SpiceManager::ref().getETfromDate("2006 jan 20 19:00:00", _time);
|
||||
|
||||
std::cout << _time << std::endl;
|
||||
//std::cout << _time << std::endl;
|
||||
|
||||
// -------------------------------------- ^ this has to be simulation start-time, not passed in here though --
|
||||
//SpiceManager::ref().getETfromDate("2008 apr 01 00:00:00", et2);
|
||||
@@ -100,7 +100,7 @@ bool RenderablePath::fullYearSweep(){
|
||||
|
||||
int indx = 0;
|
||||
for (int i = 0; i < segments + 1; i++){
|
||||
std::cout << i << std::endl;
|
||||
//std::cout << i << std::endl;
|
||||
bool gotData = SpiceManager::ref().getTargetPosition(_target, _observer, _frame, "LT+S", et, _pscpos, lightTime);
|
||||
|
||||
#ifndef NDEBUG
|
||||
@@ -249,7 +249,7 @@ void RenderablePath::update(const UpdateData& data){
|
||||
_time = data.time;
|
||||
_delta = static_cast<int>(data.delta);
|
||||
|
||||
SpiceManager::ref().getTargetState(_target, _observer, _frame, "LT+S", data.time, _pscpos, _pscvel, lightTime);
|
||||
SpiceManager::ref().getTargetPosition(_target, _observer, _frame, "NONE", data.time, _pscpos, lightTime);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/engine/configurationmanager.h>
|
||||
#include <openspace/rendering/renderableplane.h>
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/util/powerscaledcoordinate.h>
|
||||
@@ -125,14 +126,10 @@ bool RenderablePlane::initialize() {
|
||||
glGenBuffers(1, &_vertexPositionBuffer); // generate buffer
|
||||
createPlane();
|
||||
|
||||
// Plane program
|
||||
_shader = ghoul::opengl::ProgramObject::Build("Plane",
|
||||
"${SHADERS}/modules/plane/plane_vs.glsl",
|
||||
"${SHADERS}/modules/plane/plane_fs.glsl");
|
||||
if (!_shader)
|
||||
return false;
|
||||
_shader->setProgramObjectCallback([&](ghoul::opengl::ProgramObject*){ _programIsDirty = true; });
|
||||
|
||||
if (_shader == nullptr)
|
||||
OsEng.ref().configurationManager()->getValue("planeProgram", _shader);
|
||||
|
||||
_shader->setProgramObjectCallback([&](ghoul::opengl::ProgramObject*){ _programIsDirty = true; });
|
||||
loadTexture();
|
||||
|
||||
return isReady();
|
||||
@@ -144,7 +141,6 @@ bool RenderablePlane::deinitialize() {
|
||||
glDeleteBuffers(1, &_vertexPositionBuffer);
|
||||
_vertexPositionBuffer = 0;
|
||||
delete _texture;
|
||||
delete _shader;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,328 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2015 *
|
||||
* *
|
||||
* 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. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/rendering/renderableplaneprojection.h>
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/engine/configurationmanager.h>
|
||||
#include <openspace/util/constants.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/util/spicemanager.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/scene/staticephemeris.h>
|
||||
#include <openspace/scene/dynamicephemeris.h>
|
||||
|
||||
#include <ghoul/filesystem/filesystem>
|
||||
#include <ghoul/io/texture/texturereader.h>
|
||||
#include <ghoul/opengl/programobject.h>
|
||||
#include <ghoul/opengl/texture.h>
|
||||
#include <ghoul/opengl/textureunit.h>
|
||||
#include <openspace/util/time.h>
|
||||
|
||||
namespace {
|
||||
const std::string _loggerCat = "RenderablePlaneProjection";
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
|
||||
using namespace constants::renderableplaneprojection;
|
||||
|
||||
RenderablePlaneProjection::RenderablePlaneProjection(const ghoul::Dictionary& dictionary)
|
||||
: Renderable(dictionary)
|
||||
, _shader(nullptr)
|
||||
, _programIsDirty(false)
|
||||
, _texture(nullptr)
|
||||
, _textureIsDirty(false)
|
||||
, _quad(0)
|
||||
, _vertexPositionBuffer(0)
|
||||
, _name("ImagePlane")
|
||||
, _texturePath("")
|
||||
, _planeIsDirty(false)
|
||||
{
|
||||
|
||||
dictionary.getValue(keySpacecraft, _spacecraft);
|
||||
dictionary.getValue(keyInstrument, _instrument);
|
||||
dictionary.getValue(keyMoving, _moving);
|
||||
dictionary.getValue(keyName, _name);
|
||||
|
||||
std::string texturePath = "";
|
||||
bool success = dictionary.getValue(keyTexture, _texturePath);
|
||||
if (success) {
|
||||
_texturePath = findPath(_texturePath);
|
||||
_textureFile = new ghoul::filesystem::File(_texturePath);
|
||||
}
|
||||
|
||||
loadTexture();
|
||||
}
|
||||
|
||||
RenderablePlaneProjection::~RenderablePlaneProjection() {
|
||||
delete _textureFile;
|
||||
}
|
||||
|
||||
bool RenderablePlaneProjection::isReady() const {
|
||||
bool ready = true;
|
||||
if (!_shader)
|
||||
ready &= false;
|
||||
if (!_texture)
|
||||
ready &= false;
|
||||
return ready;
|
||||
}
|
||||
|
||||
bool RenderablePlaneProjection::initialize() {
|
||||
glGenVertexArrays(1, &_quad); // generate array
|
||||
glGenBuffers(1, &_vertexPositionBuffer); // generate buffer
|
||||
|
||||
// Plane program
|
||||
if (_shader == nullptr)
|
||||
OsEng.ref().configurationManager()->getValue("imagePlaneProgram", _shader);
|
||||
|
||||
setTarget("JUPITER");
|
||||
loadTexture();
|
||||
return isReady();
|
||||
}
|
||||
|
||||
bool RenderablePlaneProjection::deinitialize() {
|
||||
glDeleteVertexArrays(1, &_quad);
|
||||
_quad = 0;
|
||||
glDeleteBuffers(1, &_vertexPositionBuffer);
|
||||
_vertexPositionBuffer = 0;
|
||||
delete _texture;
|
||||
return true;
|
||||
}
|
||||
|
||||
void RenderablePlaneProjection::render(const RenderData& data) {
|
||||
|
||||
glm::mat4 transform = glm::mat4(1.0);
|
||||
|
||||
for (int i = 0; i < 3; i++){
|
||||
for (int j = 0; j < 3; j++){
|
||||
transform[i][j] = static_cast<float>(_stateMatrix[i][j]);
|
||||
}
|
||||
}
|
||||
|
||||
// Activate shader
|
||||
_shader->activate();
|
||||
|
||||
_shader->setUniform("ViewProjection", data.camera.viewProjectionMatrix());
|
||||
_shader->setUniform("ModelTransform", transform);
|
||||
setPscUniforms(_shader, &data.camera, data.position);
|
||||
|
||||
data.position;
|
||||
ghoul::opengl::TextureUnit unit;
|
||||
unit.activate();
|
||||
_texture->bind();
|
||||
_shader->setUniform("texture1", unit);
|
||||
|
||||
glBindVertexArray(_quad);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
|
||||
_shader->deactivate();
|
||||
|
||||
}
|
||||
|
||||
void RenderablePlaneProjection::update(const UpdateData& data) {
|
||||
|
||||
|
||||
double time = data.time;
|
||||
const Image* img = openspace::ImageSequencer2::ref().getLatestImageForInstrument(_instrument);
|
||||
|
||||
openspace::SpiceManager::ref().getPositionTransformMatrix(_target.frame, galacticFrame, time, _stateMatrix);
|
||||
|
||||
std::string tex = _texturePath;
|
||||
|
||||
if (_moving || _planeIsDirty)
|
||||
updatePlane(img, time);
|
||||
|
||||
else if (img != nullptr && img->path != tex) {
|
||||
time = img->startTime;
|
||||
updatePlane(img, time);
|
||||
}
|
||||
|
||||
if (_programIsDirty) {
|
||||
_shader->rebuildFromFile();
|
||||
_programIsDirty = false;
|
||||
}
|
||||
|
||||
if (_textureIsDirty) {
|
||||
loadTexture();
|
||||
_textureIsDirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
void RenderablePlaneProjection::loadTexture() {
|
||||
if (_texturePath != "") {
|
||||
ghoul::opengl::Texture* texture = ghoul::io::TextureReader::ref().loadTexture(absPath(_texturePath));
|
||||
if (texture) {
|
||||
texture->uploadTexture();
|
||||
texture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap);
|
||||
if (_texture)
|
||||
delete _texture;
|
||||
_texture = texture;
|
||||
|
||||
delete _textureFile;
|
||||
_textureFile = new ghoul::filesystem::File(_texturePath);
|
||||
_textureFile->setCallback([&](const ghoul::filesystem::File&) { _textureIsDirty = true; });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RenderablePlaneProjection::updatePlane(const Image* img, double currentTime) {
|
||||
|
||||
std::string shape, frame;
|
||||
std::vector<glm::dvec3> bounds;
|
||||
glm::dvec3 boresight;
|
||||
|
||||
std::string target = "JUPITER"; //default
|
||||
if (!_moving) {
|
||||
// target = findClosestTarget(currentTime);
|
||||
}
|
||||
if (img != nullptr)
|
||||
target = img->target;
|
||||
|
||||
setTarget(target);
|
||||
|
||||
bool found = openspace::SpiceManager::ref().getFieldOfView(_instrument, shape, frame, boresight, bounds);
|
||||
if (!found) {
|
||||
LERROR("Could not locate instrument");
|
||||
return;
|
||||
}
|
||||
|
||||
glm::dvec3 vecToTarget;
|
||||
double lt;
|
||||
psc projection[4];
|
||||
|
||||
SpiceManager::ref().getTargetPosition(_target.body, _spacecraft, galacticFrame, "CN+S", currentTime, vecToTarget, lt);
|
||||
// The apparent position, CN+S, makes image align best with target
|
||||
|
||||
for (int j = 0; j < bounds.size(); ++j) {
|
||||
openspace::SpiceManager::ref().frameConversion(bounds[j], frame, galacticFrame, currentTime);
|
||||
glm::dvec3 cornerPosition = openspace::SpiceManager::ref().orthogonalProjection(vecToTarget, bounds[j]);
|
||||
|
||||
if (!_moving) {
|
||||
cornerPosition -= vecToTarget;
|
||||
}
|
||||
openspace::SpiceManager::ref().frameConversion(cornerPosition, galacticFrame, _target.frame, currentTime);
|
||||
|
||||
projection[j] = PowerScaledCoordinate::CreatePowerScaledCoordinate(cornerPosition[0], cornerPosition[1], cornerPosition[2]);
|
||||
projection[j][3] += 3;
|
||||
}
|
||||
|
||||
if (!_moving) {
|
||||
SceneGraphNode* thisNode = OsEng.renderEngine()->scene()->sceneGraphNode(_name);
|
||||
SceneGraphNode* newParent = OsEng.renderEngine()->scene()->sceneGraphNode(_target.node);
|
||||
if (thisNode != nullptr && newParent != nullptr)
|
||||
thisNode->setParent(newParent);
|
||||
}
|
||||
|
||||
const GLfloat vertex_data[] = { // square of two triangles drawn within fov in target coordinates
|
||||
// x y z w s t
|
||||
projection[1][0], projection[1][1], projection[1][2], projection[1][3], 0, 1, // Lower left 1
|
||||
projection[3][0], projection[3][1], projection[3][2], projection[3][3], 1, 0, // Upper right 2
|
||||
projection[2][0], projection[2][1], projection[2][2], projection[2][3], 0, 0, // Upper left 3
|
||||
projection[1][0], projection[1][1], projection[1][2], projection[1][3], 0, 1, // Lower left 4 = 1
|
||||
projection[0][0], projection[0][1], projection[0][2], projection[0][3], 1, 1, // Lower right 5
|
||||
projection[3][0], projection[3][1], projection[3][2], projection[3][3], 1, 0, // Upper left 6 = 2
|
||||
};
|
||||
|
||||
glBindVertexArray(_quad); // bind array
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vertexPositionBuffer); // bind buffer
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, reinterpret_cast<void*>(0));
|
||||
glEnableVertexAttribArray(1);
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, reinterpret_cast<void*>(sizeof(GLfloat) * 4));
|
||||
|
||||
if (!_moving && img != nullptr) {
|
||||
_texturePath = img->path;
|
||||
loadTexture();
|
||||
}
|
||||
}
|
||||
|
||||
void RenderablePlaneProjection::setTarget(std::string body) {
|
||||
|
||||
if (body == "")
|
||||
return;
|
||||
|
||||
std::vector<SceneGraphNode*> nodes = OsEng.renderEngine()->scene()->allSceneGraphNodes();
|
||||
Renderable* possibleTarget;
|
||||
bool hasBody, found = false;
|
||||
std::string targetBody;
|
||||
|
||||
for (auto node : nodes)
|
||||
{
|
||||
possibleTarget = node->renderable();
|
||||
if (possibleTarget != nullptr) {
|
||||
hasBody = possibleTarget->hasBody();
|
||||
if (hasBody && possibleTarget->getBody(targetBody) && (targetBody == body)) {
|
||||
_target.node = node->name(); // get name from propertyOwner
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
_target.body = body;
|
||||
_target.frame = openspace::SpiceManager::ref().frameFromBody(body);
|
||||
}
|
||||
}
|
||||
|
||||
std::string RenderablePlaneProjection::findClosestTarget(double currentTime) {
|
||||
|
||||
std::vector<std::string> targets;
|
||||
|
||||
std::vector<SceneGraphNode*> nodes = OsEng.renderEngine()->scene()->allSceneGraphNodes();
|
||||
Renderable* possibleTarget;
|
||||
std::string targetBody;
|
||||
bool hasBody, found = false;
|
||||
|
||||
PowerScaledScalar min = PowerScaledScalar::CreatePSS(9999999999999);
|
||||
PowerScaledScalar distance = PowerScaledScalar::CreatePSS(0.0);
|
||||
|
||||
std::string closestTarget = "";
|
||||
|
||||
psc spacecraftPos;
|
||||
double lt;
|
||||
SpiceManager::ref().getTargetPosition(_spacecraft, "SSB", galacticFrame, "NONE", currentTime, spacecraftPos, lt);
|
||||
|
||||
|
||||
for (auto node : nodes)
|
||||
{
|
||||
possibleTarget = node->renderable();
|
||||
if (possibleTarget != nullptr) {
|
||||
hasBody = possibleTarget->hasBody();
|
||||
if (hasBody && possibleTarget->getBody(targetBody)) {
|
||||
openspace::SpiceManager::ref().targetWithinFieldOfView(_instrument, targetBody, _spacecraft, "ELLIPSOID", "NONE", currentTime, found);
|
||||
if (found){
|
||||
targets.push_back(node->name()); // get name from propertyOwner
|
||||
distance = (node->worldPosition() - spacecraftPos).length();
|
||||
if (distance < min)
|
||||
closestTarget = targetBody;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return closestTarget;
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
@@ -30,6 +30,9 @@
|
||||
#include <openspace/util/updatestructures.h>
|
||||
#include <ghoul/opengl/programobject.h>
|
||||
#include <ghoul/misc/highresclock.h>
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/interaction/interactionhandler.h>
|
||||
|
||||
|
||||
/* TODO for this class:
|
||||
* In order to add geometry shader (for pretty-draw),
|
||||
@@ -40,6 +43,7 @@
|
||||
namespace {
|
||||
const std::string _loggerCat = "RenderableTrail";
|
||||
//constants
|
||||
const std::string keyName = "Name";
|
||||
const std::string keyBody = "Body";
|
||||
const std::string keyObserver = "Observer";
|
||||
const std::string keyFrame = "Frame";
|
||||
@@ -48,6 +52,7 @@ namespace {
|
||||
const std::string keyTropicalOrbitPeriod = "TropicalOrbitPeriod";
|
||||
const std::string keyEarthOrbitRatio = "EarthOrbitRatio";
|
||||
const std::string keyDayLength = "DayLength";
|
||||
const std::string keyStamps = "Timestamps";
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
@@ -56,7 +61,7 @@ RenderableTrail::RenderableTrail(const ghoul::Dictionary& dictionary)
|
||||
: Renderable(dictionary)
|
||||
, _lineColor("lineColor", "Line Color")
|
||||
, _lineFade("lineFade", "Line Fade", 0.75f, 0.f, 5.f)
|
||||
, _lineWidth("lineWidth", "Line Width", 1.f, 1.f, 20.f)
|
||||
, _lineWidth("lineWidth", "Line Width", 2.f, 1.f, 20.f)
|
||||
, _programObject(nullptr)
|
||||
, _programIsDirty(true)
|
||||
, _vaoID(0)
|
||||
@@ -64,6 +69,7 @@ RenderableTrail::RenderableTrail(const ghoul::Dictionary& dictionary)
|
||||
, _oldTime(std::numeric_limits<float>::max())
|
||||
, _successfullDictionaryFetch(true)
|
||||
, _needsSweep(true)
|
||||
, _showTimestamps("timestamps", "Show Timestamps", false)
|
||||
{
|
||||
_successfullDictionaryFetch &= dictionary.getValue(keyBody, _target);
|
||||
_successfullDictionaryFetch &= dictionary.getValue(keyObserver, _observer);
|
||||
@@ -80,12 +86,17 @@ RenderableTrail::RenderableTrail(const ghoul::Dictionary& dictionary)
|
||||
dictionary.getValue(keyColor, color);
|
||||
_lineColor = color;
|
||||
|
||||
if (dictionary.hasKeyAndValue<bool>(keyStamps))
|
||||
dictionary.getValue(keyStamps, _showTimestamps);
|
||||
addProperty(_showTimestamps);
|
||||
|
||||
_lineColor.setViewOption(properties::Property::ViewOptions::Color);
|
||||
addProperty(_lineColor);
|
||||
|
||||
addProperty(_lineFade);
|
||||
|
||||
addProperty(_lineWidth);
|
||||
_distanceFade = 1.0;
|
||||
}
|
||||
|
||||
bool RenderableTrail::initialize() {
|
||||
@@ -139,6 +150,19 @@ void RenderableTrail::render(const RenderData& data) {
|
||||
_programObject->setUniform("nVertices", static_cast<unsigned int>(_vertexArray.size()));
|
||||
_programObject->setUniform("lineFade", _lineFade);
|
||||
|
||||
const psc& position = data.camera.position();
|
||||
const psc& origin = openspace::OpenSpaceEngine::ref().interactionHandler()->focusNode()->worldPosition();
|
||||
const PowerScaledScalar& pssl = (position - origin).length();
|
||||
|
||||
if (pssl[0] < 0.000001){
|
||||
if (_distanceFade > 0.0f) _distanceFade -= 0.05f;
|
||||
_programObject->setUniform("forceFade", _distanceFade);
|
||||
}
|
||||
else{
|
||||
if (_distanceFade < 1.0f) _distanceFade += 0.05f;
|
||||
_programObject->setUniform("forceFade", _distanceFade);
|
||||
}
|
||||
|
||||
glLineWidth(_lineWidth);
|
||||
|
||||
glBindVertexArray(_vaoID);
|
||||
@@ -147,11 +171,18 @@ void RenderableTrail::render(const RenderData& data) {
|
||||
|
||||
glLineWidth(1.f);
|
||||
|
||||
if (_showTimestamps){
|
||||
glPointSize(5.f);
|
||||
glBindVertexArray(_vaoID);
|
||||
glDrawArrays(GL_POINTS, 0, _vertexArray.size());
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
_programObject->deactivate();
|
||||
}
|
||||
|
||||
void RenderableTrail::update(const UpdateData& data) {
|
||||
if (data.isTimeJump)
|
||||
if (data.isTimeJump)
|
||||
_needsSweep = true;
|
||||
|
||||
if (_needsSweep) {
|
||||
@@ -166,7 +197,14 @@ void RenderableTrail::update(const UpdateData& data) {
|
||||
_programIsDirty = false;
|
||||
}
|
||||
double lightTime = 0.0;
|
||||
psc pscPos, pscVel;
|
||||
psc pscPos;
|
||||
|
||||
bool intervalSet = hasTimeInterval();
|
||||
double start = DBL_MIN;
|
||||
double end = DBL_MAX;
|
||||
if (intervalSet) {
|
||||
getInterval(start, end);
|
||||
}
|
||||
|
||||
// Points in the vertex array should always have a fixed distance. For this reason we
|
||||
// keep the first entry in the array floating and always pointing to the current date
|
||||
@@ -176,9 +214,13 @@ void RenderableTrail::update(const UpdateData& data) {
|
||||
int nValues = floor(deltaTime / _increment);
|
||||
|
||||
// Update the floating current time
|
||||
// Is 'CN+S' correct? It has to be chosen to be the same as in SpiceEphemeris, but
|
||||
// unsure if it is correct ---abock
|
||||
SpiceManager::ref().getTargetState(_target, _observer, _frame, "NONE", data.time, pscPos, pscVel, lightTime);
|
||||
if (start > data.time)
|
||||
SpiceManager::ref().getTargetPosition(_target, _observer, _frame, "NONE", start, pscPos, lightTime);
|
||||
else if (end < data.time)
|
||||
SpiceManager::ref().getTargetPosition(_target, _observer, _frame, "NONE", end, pscPos, lightTime);
|
||||
else
|
||||
SpiceManager::ref().getTargetPosition(_target, _observer, _frame, "NONE", data.time, pscPos, lightTime);
|
||||
|
||||
pscPos[3] += 3; // KM to M
|
||||
_vertexArray[0] = { pscPos[0], pscPos[1], pscPos[2], pscPos[3] };
|
||||
|
||||
@@ -193,8 +235,12 @@ void RenderableTrail::update(const UpdateData& data) {
|
||||
|
||||
for (int i = nValues; i > 0; --i) {
|
||||
double et = _oldTime + i * _increment;
|
||||
SpiceManager::ref().getTargetState(_target, _observer, _frame, "CN+S", et, pscPos, pscVel, lightTime);
|
||||
pscPos[3] += 3;
|
||||
if (start > et)
|
||||
et = start;
|
||||
else if (end < et)
|
||||
et = end;
|
||||
SpiceManager::ref().getTargetPosition(_target, _observer, _frame, "NONE", et, pscPos, lightTime);
|
||||
pscPos[3] += 3;
|
||||
_vertexArray[i] = { pscPos[0], pscPos[1], pscPos[2], pscPos[3] };
|
||||
}
|
||||
|
||||
@@ -222,15 +268,28 @@ void RenderableTrail::fullYearSweep(double time) {
|
||||
float planetYear = SecondsPerEarthYear * _ratio;
|
||||
int segments = static_cast<int>(_tropic);
|
||||
|
||||
bool intervalSet = hasTimeInterval();
|
||||
double start = DBL_MIN;
|
||||
double end = DBL_MAX;
|
||||
if (intervalSet) {
|
||||
getInterval(start, end);
|
||||
}
|
||||
|
||||
_increment = planetYear / _tropic;
|
||||
|
||||
_oldTime = time;
|
||||
|
||||
psc pscPos, pscVel;
|
||||
psc pscPos;
|
||||
bool validPosition = true;
|
||||
_vertexArray.resize(segments+2);
|
||||
for (int i = 0; i < segments+2; i++){
|
||||
SpiceManager::ref().getTargetState(_target, _observer, _frame, "CN+S", time, pscPos, pscVel, lightTime);
|
||||
pscPos[3] += 3;
|
||||
for (int i = 0; i < segments+2; i++) {
|
||||
if (start > time)
|
||||
time = start;
|
||||
else if (end < time)
|
||||
time = end;
|
||||
|
||||
SpiceManager::ref().getTargetPosition(_target, _observer, _frame, "NONE", time, pscPos, lightTime);
|
||||
pscPos[3] += 3;
|
||||
|
||||
_vertexArray[i] = {pscPos[0], pscPos[1], pscPos[2], pscPos[3]};
|
||||
time -= _increment;
|
||||
|
||||
+333
-182
@@ -22,9 +22,8 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
|
||||
#include <openspace/util/imagesequencer.h>
|
||||
#include <openspace/util/imagesequencer2.h>
|
||||
|
||||
|
||||
@@ -36,7 +35,7 @@
|
||||
#include <openspace/abuffer/abufferdynamic.h>
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/interaction/interactionhandler.h>
|
||||
#include <openspace/scenegraph/scenegraph.h>
|
||||
#include <openspace/scene/scene.h>
|
||||
#include <openspace/util/camera.h>
|
||||
#include <openspace/util/constants.h>
|
||||
#include <openspace/util/time.h>
|
||||
@@ -61,8 +60,8 @@
|
||||
#include <sgct.h>
|
||||
|
||||
// These are temporary ---abock
|
||||
#include <openspace/scenegraph/spiceephemeris.h>
|
||||
#include <openspace/scenegraph/staticephemeris.h>
|
||||
#include <openspace/scene/spiceephemeris.h>
|
||||
#include <openspace/scene/staticephemeris.h>
|
||||
|
||||
// ABuffer defines
|
||||
#define ABUFFER_FRAMEBUFFER 0
|
||||
@@ -433,7 +432,6 @@ namespace openspace {
|
||||
Time::ref().deltaTime(),
|
||||
_doPerformanceMeasurements
|
||||
});
|
||||
ImageSequencer::ref().update(Time::ref().currentTime());
|
||||
_sceneGraph->evaluate(_mainCamera);
|
||||
|
||||
// clear the abuffer before rendering the scene
|
||||
@@ -509,60 +507,6 @@ namespace openspace {
|
||||
sgct::Engine::instance()->getActiveWindowPtr()->getCurrentViewportPixelCoords(x1, y1, xSize, ySize);
|
||||
int startY = ySize - 2 * font_size_mono;
|
||||
|
||||
double currentTime = Time::ref().currentTime();
|
||||
|
||||
double remaining = openspace::ImageSequencer::ref().getNextCaptureTime() - currentTime;
|
||||
double t = 1.f - remaining / openspace::ImageSequencer::ref().getIntervalLength();
|
||||
std::string progress = "|";
|
||||
int g = ((t)* 20) + 1;
|
||||
for (int i = 0; i < g; i++) progress.append("-"); progress.append(">");
|
||||
for (int i = 0; i < 21 - g; i++) progress.append(" ");
|
||||
|
||||
std::string str = "";
|
||||
openspace::SpiceManager::ref().getDateFromET(openspace::ImageSequencer::ref().getNextCaptureTime(), str);
|
||||
|
||||
Freetype::print(font,
|
||||
_onScreenInformation._position.x * xSize,
|
||||
_onScreenInformation._position.y * ySize,
|
||||
"Date: %s",
|
||||
Time::ref().currentTimeUTC().c_str()
|
||||
);
|
||||
|
||||
progress.append("|");
|
||||
if (remaining > 0){
|
||||
glm::vec4 g1(0, t, 0, 1);
|
||||
glm::vec4 g2(1 - t);
|
||||
Freetype::print(font,
|
||||
_onScreenInformation._position.x * xSize,
|
||||
_onScreenInformation._position.y * ySize - font_size_mono * 2,
|
||||
g1 + g2,
|
||||
"Next projection in | %.0f seconds",
|
||||
remaining
|
||||
);
|
||||
Freetype::print(font,
|
||||
_onScreenInformation._position.x * xSize,
|
||||
_onScreenInformation._position.y * ySize - font_size_mono * 2 * 2,
|
||||
g1 + g2,
|
||||
"%s %.1f %%",
|
||||
progress.c_str(), t * 100
|
||||
);
|
||||
|
||||
}
|
||||
/*std::vector<std::string> instrVec = ImageSequencer2::ref().getActiveInstruments();
|
||||
|
||||
std::string active ="";
|
||||
for (int i = 0; i < instrVec.size(); i++){
|
||||
active.append(instrVec[i]);
|
||||
active.append(" ");
|
||||
}
|
||||
Freetype::print(font,
|
||||
_onScreenInformation._position.x * xSize,
|
||||
_onScreenInformation._position.y * ySize - font_size_mono * 3 * 2,
|
||||
glm::vec4(0.3, 0.6, 1, 1),
|
||||
"Active Instrument : %s",
|
||||
active.c_str()
|
||||
);*/
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -593,19 +537,21 @@ namespace openspace {
|
||||
// Using a macro to shorten line length and increase readability
|
||||
|
||||
int i = 0;
|
||||
|
||||
|
||||
PrintText(i++, "Date: %s", Time::ref().currentTimeUTC().c_str());
|
||||
/*
|
||||
|
||||
PrintText(i++, "Avg. Frametime: %.5f", sgct::Engine::instance()->getAvgDt());
|
||||
PrintText(i++, "Drawtime: %.5f", sgct::Engine::instance()->getDrawTime());
|
||||
PrintText(i++, "Frametime: %.5f", sgct::Engine::instance()->getDt());
|
||||
/*
|
||||
PrintText(i++, "Origin: (% .5f, % .5f, % .5f, % .5f)", origin[0], origin[1], origin[2], origin[3]);
|
||||
PrintText(i++, "Cam pos: (% .5f, % .5f, % .5f, % .5f)", position[0], position[1], position[2], position[3]);
|
||||
PrintText(i++, "View dir: (% .5f, % .5f, % .5f)", viewdirection[0], viewdirection[1], viewdirection[2]);
|
||||
PrintText(i++, "Cam->origin: (% .15f, % .4f)", pssl[0], pssl[1]);
|
||||
PrintText(i++, "Scaling: (% .5f, % .5f)", scaling[0], scaling[1]);
|
||||
*/
|
||||
if (openspace::ImageSequencer2::ref().isReady()){
|
||||
|
||||
if (openspace::ImageSequencer2::ref().isReady()) {
|
||||
double remaining = openspace::ImageSequencer2::ref().getNextCaptureTime() - currentTime;
|
||||
double t = 1.f - remaining / openspace::ImageSequencer2::ref().getIntervalLength();
|
||||
std::string progress = "|";
|
||||
@@ -625,75 +571,65 @@ namespace openspace {
|
||||
}
|
||||
glm::vec4 w(1);
|
||||
PrintColorText(i++, "Ucoming capture : %s", 10, w, str.c_str());
|
||||
|
||||
|
||||
std::pair<double, std::string> nextTarget = ImageSequencer2::ref().getNextTarget();
|
||||
std::pair<double, std::string> currentTarget = ImageSequencer2::ref().getCurrentTarget();
|
||||
std::pair<double, std::string> currentTarget = ImageSequencer2::ref().getCurrentTarget();
|
||||
|
||||
if (currentTarget.first > 0.0) {
|
||||
int timeleft = nextTarget.first - currentTime;
|
||||
|
||||
int timeleft = nextTarget.first - currentTime;
|
||||
int hour = timeleft / 3600;
|
||||
int second = timeleft % 3600;
|
||||
int minute = second / 60;
|
||||
second = second % 60;
|
||||
|
||||
int hour = timeleft / 3600;
|
||||
int second = timeleft % 3600;
|
||||
int minute = second / 60;
|
||||
second = second % 60;
|
||||
std::string hh, mm, ss, coundtown;
|
||||
|
||||
std::string hh, mm, ss, coundtown;
|
||||
if (hour < 10) hh.append("0");
|
||||
if (minute < 10) mm.append("0");
|
||||
if (second < 10) ss.append("0");
|
||||
|
||||
if (hour < 10) hh.append("0");
|
||||
if (minute < 10) mm.append("0");
|
||||
if (second < 10) ss.append("0");
|
||||
|
||||
hh.append(std::to_string(hour));
|
||||
mm.append(std::to_string(minute));
|
||||
ss.append(std::to_string(second));
|
||||
hh.append(std::to_string(hour));
|
||||
mm.append(std::to_string(minute));
|
||||
ss.append(std::to_string(second));
|
||||
|
||||
|
||||
glm::vec4 b2(1.00, 0.51, 0.00, 1);
|
||||
PrintColorText(i++, "Switching observation focus in : [%s:%s:%s]", 10, b2, hh.c_str(), mm.c_str(), ss.c_str());
|
||||
|
||||
std::pair<double, std::vector<std::string>> incidentTargets = ImageSequencer2::ref().getIncidentTargetList(2);
|
||||
std::string space;
|
||||
glm::vec4 color;
|
||||
int isize = incidentTargets.second.size();
|
||||
for (int p = 0; p < isize; p++){
|
||||
double t = (double)(p + 1) / (double)(isize + 1);
|
||||
t = (p > isize / 2) ? 1 - t : t;
|
||||
t += 0.3;
|
||||
color = (p == isize / 2) ? glm::vec4(1.00, 0.51, 0.00, 1) : glm::vec4(t, t, t, 1);
|
||||
PrintColorText(i, "%s%s", 10, color, space.c_str(), incidentTargets.second[p].c_str());
|
||||
for (int k = 0; k < 10; k++){ space += " "; }
|
||||
}
|
||||
i++;
|
||||
|
||||
std::vector<std::pair<std::string, bool>> instrVec = ImageSequencer2::ref().getActiveInstruments();
|
||||
|
||||
glm::vec4 active(0.58, 1, 0.00, 1);
|
||||
|
||||
|
||||
glm::vec4 firing(0.58 - t, 1 - t, 1 - t, 1);
|
||||
glm::vec4 notFiring(0.5, 0.5, 0.5, 1);
|
||||
|
||||
|
||||
double reduce = 0.01;
|
||||
|
||||
PrintColorText(i++, "Active Instruments : ", 10, active);
|
||||
for (int k = 0; k < instrVec.size(); k++){
|
||||
|
||||
if (instrVec[k].second == false){
|
||||
PrintColorText(i, "| |", 10, glm::vec4(0.3, 0.3, 0.3, 1));
|
||||
PrintColorText(i++, " %5s", 10, glm::vec4(0.3, 0.3, 0.3, 1), instrVec[k].first.c_str());
|
||||
}
|
||||
else{
|
||||
PrintColorText(i, "|", 10, glm::vec4(0.3, 0.3, 0.3, 1));
|
||||
if (instrVec[k].first == "NH_LORRI"){
|
||||
PrintColorText(i, " + ", 10, firing);
|
||||
}
|
||||
PrintColorText(i, " |", 10, glm::vec4(0.3, 0.3, 0.3, 1));
|
||||
PrintColorText(i++, " %5s", 10, active, instrVec[k].first.c_str());
|
||||
|
||||
}
|
||||
}
|
||||
glm::vec4 b2(1.00, 0.51, 0.00, 1);
|
||||
PrintColorText(i++, "Switching observation focus in : [%s:%s:%s]", 10, b2, hh.c_str(), mm.c_str(), ss.c_str());
|
||||
|
||||
std::pair<double, std::vector<std::string>> incidentTargets = ImageSequencer2::ref().getIncidentTargetList(2);
|
||||
std::string space;
|
||||
glm::vec4 color;
|
||||
int isize = incidentTargets.second.size();
|
||||
for (int p = 0; p < isize; p++){
|
||||
double t = (double)(p + 1) / (double)(isize+1);
|
||||
t = (p > isize / 2) ? 1-t : t;
|
||||
t += 0.3;
|
||||
color = (p == isize / 2) ? glm::vec4(1.00, 0.51, 0.00, 1) : glm::vec4(t, t, t, 1);
|
||||
PrintColorText(i, "%s%s", 10, color, space.c_str(), incidentTargets.second[p].c_str());
|
||||
for (int k = 0; k < 10; k++){ space += " "; }
|
||||
}
|
||||
i++;
|
||||
|
||||
std::map<std::string, bool> activeMap = ImageSequencer2::ref().getActiveInstruments();
|
||||
glm::vec4 active(0.58, 1, 0.00, 1);
|
||||
glm::vec4 firing(0.58-t, 1-t, 1-t, 1);
|
||||
glm::vec4 notFiring(0.5, 0.5, 0.5, 1);
|
||||
PrintColorText(i++, "Active Instruments : ", 10, active);
|
||||
for (auto t : activeMap){
|
||||
if (t.second == false){
|
||||
PrintColorText(i, "| |", 10, glm::vec4(0.3, 0.3, 0.3, 1));
|
||||
PrintColorText(i++, " %5s", 10, glm::vec4(0.3, 0.3, 0.3, 1), t.first.c_str());
|
||||
}
|
||||
else{
|
||||
PrintColorText(i, "|", 10, glm::vec4(0.3, 0.3, 0.3, 1));
|
||||
if (t.first == "NH_LORRI"){
|
||||
PrintColorText(i, " + ", 10, firing);
|
||||
}
|
||||
PrintColorText(i, " |", 10, glm::vec4(0.3, 0.3, 0.3, 1));
|
||||
PrintColorText(i++, " %5s", 10, active, t.first.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -800,14 +736,14 @@ namespace openspace {
|
||||
_showInfo = b;
|
||||
}
|
||||
|
||||
SceneGraph* RenderEngine::sceneGraph()
|
||||
Scene* RenderEngine::scene()
|
||||
{
|
||||
// TODO custom assert (ticket #5)
|
||||
assert(_sceneGraph);
|
||||
return _sceneGraph;
|
||||
}
|
||||
|
||||
void RenderEngine::setSceneGraph(SceneGraph* sceneGraph)
|
||||
void RenderEngine::setSceneGraph(Scene* sceneGraph)
|
||||
{
|
||||
_sceneGraph = sceneGraph;
|
||||
}
|
||||
@@ -984,7 +920,7 @@ namespace openspace {
|
||||
PerformanceLayoutEntry entries[maxValues];
|
||||
};
|
||||
|
||||
const int nNodes = static_cast<int>(sceneGraph()->allSceneGraphNodes().size());
|
||||
const int nNodes = static_cast<int>(scene()->allSceneGraphNodes().size());
|
||||
if (!_performanceMemory) {
|
||||
|
||||
// Compute the total size
|
||||
@@ -1005,7 +941,7 @@ namespace openspace {
|
||||
memset(layout->entries, 0, maxValues * sizeof(PerformanceLayout::PerformanceLayoutEntry));
|
||||
|
||||
for (int i = 0; i < nNodes; ++i) {
|
||||
SceneGraphNode* node = sceneGraph()->allSceneGraphNodes()[i];
|
||||
SceneGraphNode* node = scene()->allSceneGraphNodes()[i];
|
||||
|
||||
memset(layout->entries[i].name, 0, lengthName);
|
||||
strcpy(layout->entries[i].name, node->name().c_str());
|
||||
@@ -1019,7 +955,7 @@ namespace openspace {
|
||||
PerformanceLayout* layout = reinterpret_cast<PerformanceLayout*>(_performanceMemory->pointer());
|
||||
_performanceMemory->acquireLock();
|
||||
for (int i = 0; i < nNodes; ++i) {
|
||||
SceneGraphNode* node = sceneGraph()->allSceneGraphNodes()[i];
|
||||
SceneGraphNode* node = scene()->allSceneGraphNodes()[i];
|
||||
SceneGraphNode::PerformanceRecord r = node->performanceRecord();
|
||||
PerformanceLayout::PerformanceLayoutEntry& entry = layout->entries[i];
|
||||
|
||||
@@ -1036,38 +972,56 @@ namespace openspace {
|
||||
|
||||
// This method is temporary and will be removed once the scalegraph is in effect ---abock
|
||||
void RenderEngine::changeViewPoint(std::string origin) {
|
||||
SceneGraphNode* solarSystemBarycenterNode = sceneGraph()->sceneGraphNode("SolarSystemBarycenter");
|
||||
SceneGraphNode* plutoBarycenterNode = sceneGraph()->sceneGraphNode("PlutoBarycenter");
|
||||
SceneGraphNode* newHorizonsNode = sceneGraph()->sceneGraphNode("NewHorizons");
|
||||
SceneGraphNode* jupiterBarycenterNode = sceneGraph()->sceneGraphNode("JupiterBarycenter");
|
||||
SceneGraphNode* solarSystemBarycenterNode = scene()->sceneGraphNode("SolarSystemBarycenter");
|
||||
SceneGraphNode* plutoBarycenterNode = scene()->sceneGraphNode("PlutoBarycenter");
|
||||
SceneGraphNode* newHorizonsNode = scene()->sceneGraphNode("NewHorizons");
|
||||
SceneGraphNode* newHorizonsTrailNode = scene()->sceneGraphNode("NewHorizonsTrail");
|
||||
|
||||
if (solarSystemBarycenterNode == nullptr || plutoBarycenterNode == nullptr || newHorizonsNode == nullptr || jupiterBarycenterNode == nullptr) {
|
||||
LERROR("WTF");
|
||||
return;
|
||||
SceneGraphNode* jupiterBarycenterNode = scene()->sceneGraphNode("JupiterBarycenter");
|
||||
|
||||
SceneGraphNode* newHorizonsGhostNode = scene()->sceneGraphNode("NewHorizonsGhost");
|
||||
//SceneGraphNode* dawnNode = scene()->sceneGraphNode("Dawn");
|
||||
//SceneGraphNode* vestaNode = scene()->sceneGraphNode("Vesta");
|
||||
|
||||
if (solarSystemBarycenterNode == nullptr || plutoBarycenterNode == nullptr ||
|
||||
newHorizonsNode == nullptr || jupiterBarycenterNode == nullptr
|
||||
//|| dawnNode == nullptr
|
||||
//|| vestaNode == nullptr
|
||||
) {
|
||||
LERROR("Necessary nodes does not exist");
|
||||
return;
|
||||
}
|
||||
|
||||
if (origin == "Pluto") {
|
||||
ghoul::Dictionary solarDictionary =
|
||||
{
|
||||
{ std::string("Type"), std::string("Spice") },
|
||||
{ std::string("Body") , std::string("SUN") },
|
||||
{ std::string("Reference"), std::string("ECLIPJ2000") },
|
||||
{ std::string("Observer") , std::string("PLUTO BARYCENTER") },
|
||||
{ std::string("Kernels") , ghoul::Dictionary() }
|
||||
};
|
||||
plutoBarycenterNode->setParent(scene()->sceneGraphNode("SolarSystem"));
|
||||
plutoBarycenterNode->setEphemeris(new StaticEphemeris);
|
||||
|
||||
solarSystemBarycenterNode->setParent(plutoBarycenterNode);
|
||||
newHorizonsNode->setParent(plutoBarycenterNode);
|
||||
newHorizonsGhostNode->setParent(plutoBarycenterNode);
|
||||
|
||||
//dawnNode->setParent(plutoBarycenterNode);
|
||||
//vestaNode->setParent(plutoBarycenterNode);
|
||||
|
||||
//newHorizonsTrailNode->setParent(plutoBarycenterNode);
|
||||
ghoul::Dictionary solarDictionary =
|
||||
{
|
||||
{ std::string("Type"), std::string("Spice") },
|
||||
{ std::string("Body"), std::string("SUN") },
|
||||
{ std::string("Reference"), std::string("GALACTIC") },
|
||||
{ std::string("Observer"), std::string("PLUTO BARYCENTER") },
|
||||
{ std::string("Kernels"), ghoul::Dictionary() }
|
||||
};
|
||||
|
||||
ghoul::Dictionary jupiterDictionary =
|
||||
{
|
||||
{ std::string("Type"), std::string("Spice") },
|
||||
{ std::string("Body"), std::string("JUPITER BARYCENTER") },
|
||||
{ std::string("Reference"), std::string("ECLIPJ2000") },
|
||||
{ std::string("Observer"), std::string("SUN") },
|
||||
{ std::string("Reference"), std::string("GALACTIC") },
|
||||
{ std::string("Observer"), std::string("PLUTO BARYCENTER") },
|
||||
{ std::string("Kernels"), ghoul::Dictionary() }
|
||||
};
|
||||
|
||||
solarSystemBarycenterNode->setEphemeris(new SpiceEphemeris(solarDictionary));
|
||||
jupiterBarycenterNode->setEphemeris(new SpiceEphemeris(jupiterDictionary));
|
||||
plutoBarycenterNode->setEphemeris(new StaticEphemeris);
|
||||
|
||||
ghoul::Dictionary newHorizonsDictionary =
|
||||
{
|
||||
{ std::string("Type"), std::string("Spice") },
|
||||
@@ -1076,16 +1030,64 @@ void RenderEngine::changeViewPoint(std::string origin) {
|
||||
{ std::string("Observer"), std::string("PLUTO BARYCENTER") },
|
||||
{ std::string("Kernels"), ghoul::Dictionary() }
|
||||
};
|
||||
newHorizonsNode->setEphemeris(new SpiceEphemeris(newHorizonsDictionary));
|
||||
|
||||
solarSystemBarycenterNode->setEphemeris(new SpiceEphemeris(solarDictionary));
|
||||
jupiterBarycenterNode->setEphemeris(new SpiceEphemeris(jupiterDictionary));
|
||||
newHorizonsNode->setEphemeris(new SpiceEphemeris(newHorizonsDictionary));
|
||||
//newHorizonsTrailNode->setEphemeris(new SpiceEphemeris(newHorizonsDictionary));
|
||||
|
||||
|
||||
//ghoul::Dictionary dawnDictionary =
|
||||
//{
|
||||
// { std::string("Type"), std::string("Spice") },
|
||||
// { std::string("Body"), std::string("DAWN") },
|
||||
// { std::string("Reference"), std::string("GALACTIC") },
|
||||
// { std::string("Observer"), std::string("PLUTO BARYCENTER") },
|
||||
// { std::string("Kernels"), ghoul::Dictionary() }
|
||||
//};
|
||||
//dawnNode->setEphemeris(new SpiceEphemeris(dawnDictionary));
|
||||
//
|
||||
//ghoul::Dictionary vestaDictionary =
|
||||
//{
|
||||
// { std::string("Type"), std::string("Spice") },
|
||||
// { std::string("Body"), std::string("VESTA") },
|
||||
// { std::string("Reference"), std::string("GALACTIC") },
|
||||
// { std::string("Observer"), std::string("PLUTO BARYCENTER") },
|
||||
// { std::string("Kernels"), ghoul::Dictionary() }
|
||||
//};
|
||||
//vestaNode->setEphemeris(new SpiceEphemeris(vestaDictionary));
|
||||
|
||||
|
||||
ghoul::Dictionary newHorizonsGhostDictionary =
|
||||
{
|
||||
{ std::string("Type"), std::string("Spice") },
|
||||
{ std::string("Body"), std::string("NEW HORIZONS") },
|
||||
{ std::string("EphmerisGhosting"), std::string("TRUE") },
|
||||
{ std::string("Reference"), std::string("GALACTIC") },
|
||||
{ std::string("Observer"), std::string("PLUTO BARYCENTER") },
|
||||
{ std::string("Kernels"), ghoul::Dictionary() }
|
||||
};
|
||||
newHorizonsGhostNode->setEphemeris(new SpiceEphemeris(newHorizonsGhostDictionary));
|
||||
|
||||
return;
|
||||
}
|
||||
if (origin == "Sun") {
|
||||
solarSystemBarycenterNode->setParent(scene()->sceneGraphNode("SolarSystem"));
|
||||
|
||||
plutoBarycenterNode->setParent(solarSystemBarycenterNode);
|
||||
jupiterBarycenterNode->setParent(solarSystemBarycenterNode);
|
||||
newHorizonsNode->setParent(solarSystemBarycenterNode);
|
||||
newHorizonsGhostNode->setParent(solarSystemBarycenterNode);
|
||||
|
||||
//newHorizonsTrailNode->setParent(solarSystemBarycenterNode);
|
||||
//dawnNode->setParent(solarSystemBarycenterNode);
|
||||
//vestaNode->setParent(solarSystemBarycenterNode);
|
||||
|
||||
ghoul::Dictionary plutoDictionary =
|
||||
{
|
||||
{ std::string("Type"), std::string("Spice") },
|
||||
{ std::string("Body"), std::string("PLUTO BARYCENTER") },
|
||||
{ std::string("Reference"), std::string("ECLIPJ2000") },
|
||||
{ std::string("Reference"), std::string("GALACTIC") },
|
||||
{ std::string("Observer"), std::string("SUN") },
|
||||
{ std::string("Kernels"), ghoul::Dictionary() }
|
||||
};
|
||||
@@ -1093,7 +1095,7 @@ void RenderEngine::changeViewPoint(std::string origin) {
|
||||
{
|
||||
{ std::string("Type"), std::string("Spice") },
|
||||
{ std::string("Body"), std::string("JUPITER BARYCENTER") },
|
||||
{ std::string("Reference"), std::string("ECLIPJ2000") },
|
||||
{ std::string("Reference"), std::string("GALACTIC") },
|
||||
{ std::string("Observer"), std::string("SUN") },
|
||||
{ std::string("Kernels"), ghoul::Dictionary() }
|
||||
};
|
||||
@@ -1107,45 +1109,194 @@ void RenderEngine::changeViewPoint(std::string origin) {
|
||||
{ std::string("Type"), std::string("Spice") },
|
||||
{ std::string("Body"), std::string("NEW HORIZONS") },
|
||||
{ std::string("Reference"), std::string("GALACTIC") },
|
||||
{ std::string("Observer"), std::string("JUPITER BARYCENTER") },
|
||||
{ std::string("Observer"), std::string("SUN") },
|
||||
{ std::string("Kernels"), ghoul::Dictionary() }
|
||||
};
|
||||
newHorizonsNode->setEphemeris(new SpiceEphemeris(newHorizonsDictionary));
|
||||
//newHorizonsTrailNode->setEphemeris(new SpiceEphemeris(newHorizonsDictionary));
|
||||
|
||||
|
||||
//ghoul::Dictionary dawnDictionary =
|
||||
//{
|
||||
// { std::string("Type"), std::string("Spice") },
|
||||
// { std::string("Body"), std::string("DAWN") },
|
||||
// { std::string("Reference"), std::string("GALACTIC") },
|
||||
// { std::string("Observer"), std::string("SUN") },
|
||||
// { std::string("Kernels"), ghoul::Dictionary() }
|
||||
//};
|
||||
//dawnNode->setEphemeris(new SpiceEphemeris(dawnDictionary));
|
||||
//
|
||||
//ghoul::Dictionary vestaDictionary =
|
||||
//{
|
||||
// { std::string("Type"), std::string("Spice") },
|
||||
// { std::string("Body"), std::string("VESTA") },
|
||||
// { std::string("Reference"), std::string("GALACTIC") },
|
||||
// { std::string("Observer"), std::string("SUN") },
|
||||
// { std::string("Kernels"), ghoul::Dictionary() }
|
||||
//};
|
||||
//vestaNode->setEphemeris(new SpiceEphemeris(vestaDictionary));
|
||||
|
||||
|
||||
ghoul::Dictionary newHorizonsGhostDictionary =
|
||||
{
|
||||
{ std::string("Type"), std::string("Spice") },
|
||||
{ std::string("Body"), std::string("NEW HORIZONS") },
|
||||
{ std::string("EphmerisGhosting"), std::string("TRUE") },
|
||||
{ std::string("Reference"), std::string("GALACTIC") },
|
||||
{ std::string("Observer"), std::string("JUPITER BARYCENTER") },
|
||||
{ std::string("Kernels"), ghoul::Dictionary() }
|
||||
};
|
||||
newHorizonsGhostNode->setEphemeris(new SpiceEphemeris(newHorizonsGhostDictionary));
|
||||
|
||||
return;
|
||||
}
|
||||
if (origin == "Jupiter") {
|
||||
ghoul::Dictionary plutoDictionary =
|
||||
{
|
||||
{ std::string("Type"), std::string("Spice") },
|
||||
{ std::string("Body"), std::string("PLUTO BARYCENTER") },
|
||||
{ std::string("Reference"), std::string("ECLIPJ2000") },
|
||||
{ std::string("Observer"), std::string("JUPITER BARYCENTER") },
|
||||
{ std::string("Kernels"), ghoul::Dictionary() }
|
||||
};
|
||||
ghoul::Dictionary solarDictionary =
|
||||
{
|
||||
{ std::string("Type"), std::string("Spice") },
|
||||
{ std::string("Body"), std::string("SUN") },
|
||||
{ std::string("Reference"), std::string("ECLIPJ2000") },
|
||||
{ std::string("Observer"), std::string("JUPITER BARYCENTER") },
|
||||
{ std::string("Kernels"), ghoul::Dictionary() }
|
||||
};
|
||||
|
||||
solarSystemBarycenterNode->setEphemeris(new SpiceEphemeris(solarDictionary));
|
||||
plutoBarycenterNode->setEphemeris(new SpiceEphemeris(plutoDictionary));
|
||||
jupiterBarycenterNode->setEphemeris(new StaticEphemeris);
|
||||
jupiterBarycenterNode->setParent(scene()->sceneGraphNode("SolarSystem"));
|
||||
jupiterBarycenterNode->setEphemeris(new StaticEphemeris);
|
||||
|
||||
ghoul::Dictionary newHorizonsDictionary =
|
||||
{
|
||||
{ std::string("Type"), std::string("Spice") },
|
||||
{ std::string("Body"), std::string("NEW HORIZONS") },
|
||||
{ std::string("Reference"), std::string("GALACTIC") },
|
||||
{ std::string("Observer"), std::string("JUPITER BARYCENTER") },
|
||||
{ std::string("Kernels"), ghoul::Dictionary() }
|
||||
};
|
||||
newHorizonsNode->setEphemeris(new SpiceEphemeris(newHorizonsDictionary));
|
||||
solarSystemBarycenterNode->setParent(jupiterBarycenterNode);
|
||||
newHorizonsNode->setParent(jupiterBarycenterNode);
|
||||
//newHorizonsTrailNode->setParent(jupiterBarycenterNode);
|
||||
|
||||
//dawnNode->setParent(jupiterBarycenterNode);
|
||||
//vestaNode->setParent(jupiterBarycenterNode);
|
||||
|
||||
|
||||
ghoul::Dictionary solarDictionary =
|
||||
{
|
||||
{ std::string("Type"), std::string("Spice") },
|
||||
{ std::string("Body"), std::string("SUN") },
|
||||
{ std::string("Reference"), std::string("GALACTIC") },
|
||||
{ std::string("Observer"), std::string("JUPITER BARYCENTER") },
|
||||
{ std::string("Kernels"), ghoul::Dictionary() }
|
||||
};
|
||||
|
||||
ghoul::Dictionary plutoDictionary =
|
||||
{
|
||||
{ std::string("Type"), std::string("Spice") },
|
||||
{ std::string("Body"), std::string("PlUTO BARYCENTER") },
|
||||
{ std::string("Reference"), std::string("GALACTIC") },
|
||||
{ std::string("Observer"), std::string("JUPITER BARYCENTER") },
|
||||
{ std::string("Kernels"), ghoul::Dictionary() }
|
||||
};
|
||||
|
||||
ghoul::Dictionary newHorizonsDictionary =
|
||||
{
|
||||
{ std::string("Type"), std::string("Spice") },
|
||||
{ std::string("Body"), std::string("NEW HORIZONS") },
|
||||
{ std::string("Reference"), std::string("GALACTIC") },
|
||||
{ std::string("Observer"), std::string("JUPITER BARYCENTER") },
|
||||
{ std::string("Kernels"), ghoul::Dictionary() }
|
||||
};
|
||||
solarSystemBarycenterNode->setEphemeris(new SpiceEphemeris(solarDictionary));
|
||||
plutoBarycenterNode->setEphemeris(new SpiceEphemeris(plutoDictionary));
|
||||
newHorizonsNode->setEphemeris(new SpiceEphemeris(newHorizonsDictionary));
|
||||
newHorizonsGhostNode->setParent(jupiterBarycenterNode);
|
||||
//newHorizonsTrailNode->setEphemeris(new SpiceEphemeris(newHorizonsDictionary));
|
||||
|
||||
|
||||
//ghoul::Dictionary dawnDictionary =
|
||||
//{
|
||||
// { std::string("Type"), std::string("Spice") },
|
||||
// { std::string("Body"), std::string("DAWN") },
|
||||
// { std::string("Reference"), std::string("GALACTIC") },
|
||||
// { std::string("Observer"), std::string("JUPITER BARYCENTER") },
|
||||
// { std::string("Kernels"), ghoul::Dictionary() }
|
||||
//};
|
||||
//dawnNode->setEphemeris(new SpiceEphemeris(dawnDictionary));
|
||||
//
|
||||
//ghoul::Dictionary vestaDictionary =
|
||||
//{
|
||||
// { std::string("Type"), std::string("Spice") },
|
||||
// { std::string("Body"), std::string("VESTA") },
|
||||
// { std::string("Reference"), std::string("GALACTIC") },
|
||||
// { std::string("Observer"), std::string("JUPITER BARYCENTER") },
|
||||
// { std::string("Kernels"), ghoul::Dictionary() }
|
||||
//};
|
||||
//vestaNode->setEphemeris(new SpiceEphemeris(vestaDictionary));
|
||||
|
||||
|
||||
|
||||
ghoul::Dictionary newHorizonsGhostDictionary =
|
||||
{
|
||||
{ std::string("Type"), std::string("Spice") },
|
||||
{ std::string("Body"), std::string("NEW HORIZONS") },
|
||||
{ std::string("EphmerisGhosting"), std::string("TRUE") },
|
||||
{ std::string("Reference"), std::string("GALACTIC") },
|
||||
{ std::string("Observer"), std::string("JUPITER BARYCENTER") },
|
||||
{ std::string("Kernels"), ghoul::Dictionary() }
|
||||
};
|
||||
newHorizonsGhostNode->setEphemeris(new SpiceEphemeris(newHorizonsGhostDictionary));
|
||||
newHorizonsGhostNode->setParent(jupiterBarycenterNode);
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
//if (origin == "Vesta") {
|
||||
//
|
||||
// vestaNode->setParent(scene()->sceneGraphNode("SolarSystem"));
|
||||
// vestaNode->setEphemeris(new StaticEphemeris);
|
||||
//
|
||||
// solarSystemBarycenterNode->setParent(vestaNode);
|
||||
// newHorizonsNode->setParent(vestaNode);
|
||||
//
|
||||
// dawnNode->setParent(vestaNode);
|
||||
// plutoBarycenterNode->setParent(vestaNode);
|
||||
//
|
||||
//
|
||||
// ghoul::Dictionary plutoDictionary =
|
||||
// {
|
||||
// { std::string("Type"), std::string("Spice") },
|
||||
// { std::string("Body"), std::string("PLUTO BARYCENTER") },
|
||||
// { std::string("Reference"), std::string("GALACTIC") },
|
||||
// { std::string("Observer"), std::string("VESTA") },
|
||||
// { std::string("Kernels"), ghoul::Dictionary() }
|
||||
// };
|
||||
// ghoul::Dictionary solarDictionary =
|
||||
// {
|
||||
// { std::string("Type"), std::string("Spice") },
|
||||
// { std::string("Body"), std::string("SUN") },
|
||||
// { std::string("Reference"), std::string("GALACTIC") },
|
||||
// { std::string("Observer"), std::string("VESTA") },
|
||||
// { std::string("Kernels"), ghoul::Dictionary() }
|
||||
// };
|
||||
//
|
||||
// ghoul::Dictionary jupiterDictionary =
|
||||
// {
|
||||
// { std::string("Type"), std::string("Spice") },
|
||||
// { std::string("Body"), std::string("JUPITER BARYCENTER") },
|
||||
// { std::string("Reference"), std::string("GALACTIC") },
|
||||
// { std::string("Observer"), std::string("VESTA") },
|
||||
// { std::string("Kernels"), ghoul::Dictionary() }
|
||||
// };
|
||||
//
|
||||
// solarSystemBarycenterNode->setEphemeris(new SpiceEphemeris(solarDictionary));
|
||||
// plutoBarycenterNode->setEphemeris(new SpiceEphemeris(plutoDictionary));
|
||||
// jupiterBarycenterNode->setEphemeris(new SpiceEphemeris(jupiterDictionary));
|
||||
//
|
||||
// ghoul::Dictionary newHorizonsDictionary =
|
||||
// {
|
||||
// { std::string("Type"), std::string("Spice") },
|
||||
// { std::string("Body"), std::string("NEW HORIZONS") },
|
||||
// { std::string("Reference"), std::string("GALACTIC") },
|
||||
// { std::string("Observer"), std::string("VESTA") },
|
||||
// { std::string("Kernels"), ghoul::Dictionary() }
|
||||
// };
|
||||
// newHorizonsNode->setEphemeris(new SpiceEphemeris(newHorizonsDictionary));
|
||||
//
|
||||
// ghoul::Dictionary dawnDictionary =
|
||||
// {
|
||||
// { std::string("Type"), std::string("Spice") },
|
||||
// { std::string("Body"), std::string("DAWN") },
|
||||
// { std::string("Reference"), std::string("GALACTIC") },
|
||||
// { std::string("Observer"), std::string("VESTA") },
|
||||
// { std::string("Kernels"), ghoul::Dictionary() }
|
||||
// };
|
||||
// dawnNode->setEphemeris(new SpiceEphemeris(dawnDictionary));
|
||||
// vestaNode->setEphemeris(new StaticEphemeris);
|
||||
//
|
||||
// return;
|
||||
//}
|
||||
|
||||
ghoul_assert(false, "This function is being misused");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2015 *
|
||||
* *
|
||||
* 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. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/scene/dynamicephemeris.h>
|
||||
|
||||
#include <openspace/util/constants.h>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
using namespace constants::dynamicephemeris;
|
||||
|
||||
DynamicEphemeris::DynamicEphemeris(const ghoul::Dictionary& dictionary)
|
||||
: _position(0.f, 0.f, 0.f, 0.f)
|
||||
{
|
||||
const bool hasPosition = dictionary.hasKeyAndValue<glm::vec4>(keyPosition);
|
||||
if (hasPosition) {
|
||||
glm::vec4 tmp;
|
||||
dictionary.getValue(keyPosition, tmp);
|
||||
_position = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
DynamicEphemeris::~DynamicEphemeris() {}
|
||||
|
||||
const psc& DynamicEphemeris::position() const {
|
||||
return _position;
|
||||
}
|
||||
|
||||
void DynamicEphemeris::setPosition(psc pos) {
|
||||
_position = pos;
|
||||
}
|
||||
|
||||
void DynamicEphemeris::update(const UpdateData&) {
|
||||
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
@@ -22,7 +22,7 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/scenegraph/ephemeris.h>
|
||||
#include <openspace/scene/ephemeris.h>
|
||||
#include <openspace/util/constants.h>
|
||||
#include <openspace/util/factorymanager.h>
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/scenegraph/scenegraph.h>
|
||||
#include <openspace/scene/scene.h>
|
||||
|
||||
#include <openspace/abuffer/abuffer.h>
|
||||
#include <openspace/engine/configurationmanager.h>
|
||||
@@ -31,12 +31,14 @@
|
||||
#include <openspace/interaction/interactionhandler.h>
|
||||
#include <openspace/query/query.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/scenegraph/scenegraphnode.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/scripting/scriptengine.h>
|
||||
#include <openspace/scripting/script_helper.h>
|
||||
#include <openspace/util/constants.h>
|
||||
#include <openspace/util/time.h>
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include "ghoul/io/texture/texturereader.h"
|
||||
#include <ghoul/misc/dictionary.h>
|
||||
@@ -138,26 +140,23 @@ int loadScene(lua_State* L) {
|
||||
|
||||
std::string sceneFile = luaL_checkstring(L, -1);
|
||||
|
||||
OsEng.renderEngine()->sceneGraph()->scheduleLoadSceneFile(sceneFile);
|
||||
OsEng.renderEngine()->scene()->scheduleLoadSceneFile(sceneFile);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace luascriptfunctions
|
||||
|
||||
SceneGraph::SceneGraph()
|
||||
Scene::Scene()
|
||||
: _focus(SceneGraphNode::RootNodeName)
|
||||
, _root(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
SceneGraph::~SceneGraph()
|
||||
{
|
||||
Scene::~Scene() {
|
||||
deinitialize();
|
||||
}
|
||||
|
||||
bool SceneGraph::initialize()
|
||||
{
|
||||
bool Scene::initialize() {
|
||||
LDEBUG("Initializing SceneGraph");
|
||||
|
||||
using ghoul::opengl::ShaderObject;
|
||||
@@ -184,6 +183,7 @@ bool SceneGraph::initialize()
|
||||
tmpProgram->setProgramObjectCallback(cb);
|
||||
_programs.push_back(tmpProgram);
|
||||
OsEng.ref().configurationManager()->setValue("fboPassProgram", tmpProgram);
|
||||
|
||||
// projection program
|
||||
tmpProgram = ProgramObject::Build("projectiveProgram",
|
||||
"${SHADERS}/projectiveTexture_vs.glsl",
|
||||
@@ -199,21 +199,29 @@ bool SceneGraph::initialize()
|
||||
"${SHADERS}/pscstandard_fs.glsl");
|
||||
if( ! tmpProgram) return false;
|
||||
tmpProgram->setProgramObjectCallback(cb);
|
||||
|
||||
_programs.push_back(tmpProgram);
|
||||
OsEng.ref().configurationManager()->setValue("pscShader", tmpProgram);
|
||||
|
||||
|
||||
// NH shader
|
||||
tmpProgram = ProgramObject::Build("NHProgram",
|
||||
"${SHADERS}/nh_vs.glsl",
|
||||
"${SHADERS}/nh_fs.glsl");
|
||||
tmpProgram = ProgramObject::Build("ModelProgram",
|
||||
"${SHADERS}/model_vs.glsl",
|
||||
"${SHADERS}/model_fs.glsl");
|
||||
if (!tmpProgram) return false;
|
||||
tmpProgram->setProgramObjectCallback(cb);
|
||||
|
||||
_programs.push_back(tmpProgram);
|
||||
OsEng.ref().configurationManager()->setValue("NewHorizonsShader", tmpProgram);
|
||||
OsEng.ref().configurationManager()->setValue("GenericModelShader", tmpProgram);
|
||||
|
||||
// fovProgram
|
||||
// Night texture program
|
||||
tmpProgram = ProgramObject::Build("nightTextureProgram",
|
||||
"${SHADERS}/nighttexture_vs.glsl",
|
||||
"${SHADERS}/nighttexture_fs.glsl");
|
||||
if (!tmpProgram) return false;
|
||||
tmpProgram->setProgramObjectCallback(cb);
|
||||
_programs.push_back(tmpProgram);
|
||||
OsEng.ref().configurationManager()->setValue("nightTextureProgram", tmpProgram);
|
||||
|
||||
// Fov Program
|
||||
tmpProgram = ProgramObject::Build("FovProgram",
|
||||
"${SHADERS}/fov_vs.glsl",
|
||||
"${SHADERS}/fov_fs.glsl");
|
||||
@@ -222,6 +230,24 @@ bool SceneGraph::initialize()
|
||||
_programs.push_back(tmpProgram);
|
||||
OsEng.ref().configurationManager()->setValue("FovProgram", tmpProgram);
|
||||
|
||||
// Plane Program
|
||||
tmpProgram = ProgramObject::Build("planeProgram",
|
||||
"${SHADERS}/modules/plane/plane_vs.glsl",
|
||||
"${SHADERS}/modules/plane/plane_fs.glsl");
|
||||
if (!tmpProgram) return false;
|
||||
tmpProgram->setProgramObjectCallback(cb);
|
||||
_programs.push_back(tmpProgram);
|
||||
OsEng.ref().configurationManager()->setValue("planeProgram", tmpProgram);
|
||||
|
||||
// Image Plane Program
|
||||
tmpProgram = ProgramObject::Build("imagePlaneProgram",
|
||||
"${SHADERS}/modules/imageplane/imageplane_vs.glsl",
|
||||
"${SHADERS}/modules/imageplane/imageplane_fs.glsl");
|
||||
if (!tmpProgram) return false;
|
||||
tmpProgram->setProgramObjectCallback(cb);
|
||||
_programs.push_back(tmpProgram);
|
||||
OsEng.ref().configurationManager()->setValue("imagePlaneProgram", tmpProgram);
|
||||
|
||||
// RaycastProgram
|
||||
tmpProgram = ProgramObject::Build("RaycastProgram",
|
||||
"${SHADERS}/exitpoints.vert",
|
||||
@@ -248,8 +274,7 @@ bool SceneGraph::initialize()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SceneGraph::deinitialize()
|
||||
{
|
||||
bool Scene::deinitialize() {
|
||||
clearSceneGraph();
|
||||
|
||||
// clean up all programs
|
||||
@@ -260,10 +285,9 @@ bool SceneGraph::deinitialize()
|
||||
return true;
|
||||
}
|
||||
|
||||
void SceneGraph::update(const UpdateData& data)
|
||||
{
|
||||
void Scene::update(const UpdateData& data) {
|
||||
if (!_sceneGraphToLoad.empty()) {
|
||||
OsEng.renderEngine()->sceneGraph()->clearSceneGraph();
|
||||
OsEng.renderEngine()->scene()->clearSceneGraph();
|
||||
bool success = loadSceneInternal(_sceneGraphToLoad);
|
||||
_sceneGraphToLoad = "";
|
||||
if (!success)
|
||||
@@ -272,18 +296,17 @@ void SceneGraph::update(const UpdateData& data)
|
||||
OsEng.renderEngine()->abuffer()->invalidateABuffer();
|
||||
#endif
|
||||
}
|
||||
for (SceneGraphNode* node : _nodes)
|
||||
for (SceneGraphNode* node : _graph.nodes())
|
||||
node->update(data);
|
||||
}
|
||||
|
||||
void SceneGraph::evaluate(Camera* camera)
|
||||
{
|
||||
if (_root)
|
||||
_root->evaluate(camera);
|
||||
void Scene::evaluate(Camera* camera) {
|
||||
for (SceneGraphNode* node : _graph.nodes())
|
||||
node->evaluate(camera);
|
||||
//_root->evaluate(camera);
|
||||
}
|
||||
|
||||
void SceneGraph::render(const RenderData& data)
|
||||
{
|
||||
void Scene::render(const RenderData& data) {
|
||||
bool emptyProgramsToUpdate = _programsToUpdate.empty();
|
||||
|
||||
_programUpdateLock.lock();
|
||||
@@ -301,92 +324,106 @@ void SceneGraph::render(const RenderData& data)
|
||||
program->setIgnoreSubroutineUniformLocationError(true);
|
||||
}
|
||||
|
||||
if (_root)
|
||||
_root->render(data);
|
||||
for (SceneGraphNode* node : _graph.nodes())
|
||||
node->render(data);
|
||||
//if (_root)
|
||||
// _root->render(data);
|
||||
}
|
||||
|
||||
void SceneGraph::scheduleLoadSceneFile(const std::string& sceneDescriptionFilePath) {
|
||||
void Scene::scheduleLoadSceneFile(const std::string& sceneDescriptionFilePath) {
|
||||
_sceneGraphToLoad = sceneDescriptionFilePath;
|
||||
}
|
||||
|
||||
void SceneGraph::clearSceneGraph() {
|
||||
void Scene::clearSceneGraph() {
|
||||
// deallocate the scene graph. Recursive deallocation will occur
|
||||
if (_root) {
|
||||
_root->deinitialize();
|
||||
delete _root;
|
||||
_root = nullptr;
|
||||
}
|
||||
_graph.clear();
|
||||
//if (_root) {
|
||||
// _root->deinitialize();
|
||||
// delete _root;
|
||||
// _root = nullptr;
|
||||
//}
|
||||
|
||||
_nodes.erase(_nodes.begin(), _nodes.end());
|
||||
_allNodes.erase(_allNodes.begin(), _allNodes.end());
|
||||
// _nodes.erase(_nodes.begin(), _nodes.end());
|
||||
// _allNodes.erase(_allNodes.begin(), _allNodes.end());
|
||||
|
||||
_focus.clear();
|
||||
}
|
||||
|
||||
bool SceneGraph::loadSceneInternal(const std::string& sceneDescriptionFilePath)
|
||||
{
|
||||
using ghoul::Dictionary;
|
||||
using ghoul::lua::loadDictionaryFromFile;
|
||||
bool Scene::loadSceneInternal(const std::string& sceneDescriptionFilePath) {
|
||||
// using ghoul::Dictionary;
|
||||
// using ghoul::lua::loadDictionaryFromFile;
|
||||
|
||||
if (!FileSys.fileExists(sceneDescriptionFilePath)) {
|
||||
LFATAL("Scene description file '" << sceneDescriptionFilePath << "' not found");
|
||||
return false;
|
||||
}
|
||||
//if (!FileSys.fileExists(sceneDescriptionFilePath)) {
|
||||
// LFATAL("Scene description file '" << sceneDescriptionFilePath << "' not found");
|
||||
// return false;
|
||||
//}
|
||||
|
||||
LDEBUG("Loading scenegraph nodes");
|
||||
if (_root != nullptr) {
|
||||
LFATAL("Scenegraph already loaded");
|
||||
return false;
|
||||
}
|
||||
// LDEBUG("Loading scenegraph nodes");
|
||||
// if (_root != nullptr) {
|
||||
// LFATAL("Scenegraph already loaded");
|
||||
// return false;
|
||||
// }
|
||||
|
||||
OsEng.disableBarrier();
|
||||
// OsEng.disableBarrier();
|
||||
|
||||
// initialize the root node
|
||||
_root = new SceneGraphNode();
|
||||
_root->setName(SceneGraphNode::RootNodeName);
|
||||
_nodes.push_back(_root);
|
||||
_allNodes.emplace(SceneGraphNode::RootNodeName, _root);
|
||||
_focus = SceneGraphNode::RootNodeName;
|
||||
// _root = new SceneGraphNode();
|
||||
// _root->setName(SceneGraphNode::RootNodeName);
|
||||
// _nodes.push_back(_root);
|
||||
// _allNodes.emplace(SceneGraphNode::RootNodeName, _root);
|
||||
// _focus = SceneGraphNode::RootNodeName;
|
||||
|
||||
Dictionary dictionary;
|
||||
//load default.scene
|
||||
loadDictionaryFromFile(sceneDescriptionFilePath, dictionary);
|
||||
// bool success = SceneGraphLoader::load(sceneDescriptionFilePath, _nodes);
|
||||
|
||||
std::string&& sceneDescriptionDirectory =
|
||||
ghoul::filesystem::File(sceneDescriptionFilePath).directoryName();
|
||||
std::string moduleDirectory(".");
|
||||
dictionary.getValue(constants::scenegraph::keyPathScene, moduleDirectory);
|
||||
|
||||
// The scene path could either be an absolute or relative path to the description
|
||||
// paths directory
|
||||
std::string&& relativeCandidate = sceneDescriptionDirectory +
|
||||
ghoul::filesystem::FileSystem::PathSeparator + moduleDirectory;
|
||||
std::string&& absoluteCandidate = absPath(moduleDirectory);
|
||||
ghoul::Dictionary dictionary;
|
||||
////load default.scene
|
||||
ghoul::lua::loadDictionaryFromFile(sceneDescriptionFilePath, dictionary);
|
||||
|
||||
if (FileSys.directoryExists(relativeCandidate))
|
||||
moduleDirectory = relativeCandidate;
|
||||
else if (FileSys.directoryExists(absoluteCandidate))
|
||||
moduleDirectory = absoluteCandidate;
|
||||
else {
|
||||
LFATAL("The '" << constants::scenegraph::keyPathScene << "' pointed to a "
|
||||
"path '" << moduleDirectory << "' that did not exist");
|
||||
OsEng.enableBarrier();
|
||||
return false;
|
||||
}
|
||||
//std::string&& sceneDescriptionDirectory =
|
||||
// ghoul::filesystem::File(sceneDescriptionFilePath).directoryName();
|
||||
//std::string moduleDirectory(".");
|
||||
//dictionary.getValue(constants::scenegraph::keyPathScene, moduleDirectory);
|
||||
|
||||
// Load the modules/scenegraph nodes
|
||||
loadModules(moduleDirectory, dictionary);
|
||||
//// The scene path could either be an absolute or relative path to the description
|
||||
//// paths directory
|
||||
//std::string&& relativeCandidate = sceneDescriptionDirectory +
|
||||
// ghoul::filesystem::FileSystem::PathSeparator + moduleDirectory;
|
||||
//std::string&& absoluteCandidate = absPath(moduleDirectory);
|
||||
|
||||
//if (FileSys.directoryExists(relativeCandidate))
|
||||
// moduleDirectory = relativeCandidate;
|
||||
//else if (FileSys.directoryExists(absoluteCandidate))
|
||||
// moduleDirectory = absoluteCandidate;
|
||||
//else {
|
||||
// LFATAL("The '" << constants::scenegraph::keyPathScene << "' pointed to a "
|
||||
// "path '" << moduleDirectory << "' that did not exist");
|
||||
// OsEng.enableBarrier();
|
||||
// return false;
|
||||
//}
|
||||
|
||||
//// Load the modules/scenegraph nodes
|
||||
//loadModules(moduleDirectory, dictionary);
|
||||
|
||||
_graph.loadFromFile(sceneDescriptionFilePath);
|
||||
|
||||
// TODO: Make it less hard-coded and more flexible when nodes are not found
|
||||
Dictionary cameraDictionary;
|
||||
ghoul::Dictionary cameraDictionary;
|
||||
if (dictionary.getValue(constants::scenegraph::keyCamera, cameraDictionary)) {
|
||||
LDEBUG("Camera dictionary found");
|
||||
std::string focus;
|
||||
|
||||
if (cameraDictionary.hasKey(constants::scenegraph::keyFocusObject)
|
||||
&& cameraDictionary.getValue(constants::scenegraph::keyFocusObject, focus)) {
|
||||
auto focusIterator = _allNodes.find(focus);
|
||||
if (focusIterator != _allNodes.end()) {
|
||||
&& cameraDictionary.getValue(constants::scenegraph::keyFocusObject, focus))
|
||||
{
|
||||
auto focusIterator = std::find_if(
|
||||
_graph.nodes().begin(),
|
||||
_graph.nodes().end(),
|
||||
[focus](SceneGraphNode* node) {
|
||||
return node->name() == focus;
|
||||
}
|
||||
);
|
||||
|
||||
if (focusIterator != _graph.nodes().end()) {
|
||||
_focus = focus;
|
||||
LDEBUG("Setting camera focus to '" << _focus << "'");
|
||||
}
|
||||
@@ -396,7 +433,7 @@ bool SceneGraph::loadSceneInternal(const std::string& sceneDescriptionFilePath)
|
||||
}
|
||||
|
||||
// Initialize all nodes
|
||||
for (SceneGraphNode* node : _nodes) {
|
||||
for (SceneGraphNode* node : _graph.nodes()) {
|
||||
bool success = node->initialize();
|
||||
if (success)
|
||||
LDEBUG(node->name() << " initialized successfully!");
|
||||
@@ -406,24 +443,36 @@ bool SceneGraph::loadSceneInternal(const std::string& sceneDescriptionFilePath)
|
||||
|
||||
// update the position of all nodes
|
||||
// TODO need to check this; unnecessary? (ab)
|
||||
for (SceneGraphNode* node : _nodes)
|
||||
for (SceneGraphNode* node : _graph.nodes()) {
|
||||
node->update({ Time::ref().currentTime() });
|
||||
}
|
||||
|
||||
for (auto it = _graph.nodes().rbegin(); it != _graph.nodes().rend(); ++it)
|
||||
(*it)->calculateBoundingSphere();
|
||||
|
||||
|
||||
// Calculate the bounding sphere for the scenegraph
|
||||
_root->calculateBoundingSphere();
|
||||
//_root->calculateBoundingSphere();
|
||||
|
||||
// set the camera position
|
||||
Camera* c = OsEng.ref().renderEngine()->camera();
|
||||
auto focusIterator = _allNodes.find(_focus);
|
||||
//auto focusIterator = _allNodes.find(_focus);
|
||||
auto focusIterator = std::find_if(
|
||||
_graph.nodes().begin(),
|
||||
_graph.nodes().end(),
|
||||
[&](SceneGraphNode* node) {
|
||||
return node->name() == _focus;
|
||||
}
|
||||
);
|
||||
|
||||
glm::vec2 cameraScaling(1);
|
||||
psc cameraPosition(0,0,1,0);
|
||||
glm::vec3 cameraDirection = glm::vec3(0, 0, -1);
|
||||
|
||||
if (focusIterator != _allNodes.end()) {
|
||||
//if (_focus->)
|
||||
if (focusIterator != _graph.nodes().end()) {
|
||||
LDEBUG("Camera focus is '" << _focus << "'");
|
||||
SceneGraphNode* focusNode = focusIterator->second;
|
||||
SceneGraphNode* focusNode = *focusIterator;
|
||||
//Camera* c = OsEng.interactionHandler().getCamera();
|
||||
|
||||
// TODO: Make distance depend on radius
|
||||
@@ -456,6 +505,8 @@ bool SceneGraph::loadSceneInternal(const std::string& sceneDescriptionFilePath)
|
||||
// Set the focus node for the interactionhandler
|
||||
OsEng.interactionHandler()->setFocusNode(focusNode);
|
||||
}
|
||||
else
|
||||
OsEng.interactionHandler()->setFocusNode(_graph.rootNode());
|
||||
|
||||
glm::vec4 position;
|
||||
if (cameraDictionary.hasKey(constants::scenegraph::keyPositionObject)
|
||||
@@ -490,7 +541,7 @@ bool SceneGraph::loadSceneInternal(const std::string& sceneDescriptionFilePath)
|
||||
}
|
||||
|
||||
|
||||
for (SceneGraphNode* node : _nodes) {
|
||||
for (SceneGraphNode* node : _graph.nodes()) {
|
||||
std::vector<properties::Property*> properties = node->propertiesRecursive();
|
||||
for (properties::Property* p : properties) {
|
||||
OsEng.gui()->_property.registerProperty(p);
|
||||
@@ -520,172 +571,166 @@ bool SceneGraph::loadSceneInternal(const std::string& sceneDescriptionFilePath)
|
||||
return true;
|
||||
}
|
||||
|
||||
void SceneGraph::loadModules(
|
||||
const std::string& directory,
|
||||
const ghoul::Dictionary& dictionary)
|
||||
{
|
||||
// Struct containing dependencies and nodes
|
||||
LoadMaps m;
|
||||
//void Scene::loadModules(
|
||||
// const std::string& directory,
|
||||
// const ghoul::Dictionary& dictionary)
|
||||
//{
|
||||
// // Struct containing dependencies and nodes
|
||||
// LoadMaps m;
|
||||
//
|
||||
// // Get the common directory
|
||||
// std::string commonDirectory(_defaultCommonDirectory);
|
||||
// dictionary.getValue(constants::scenegraph::keyCommonFolder, commonDirectory);
|
||||
// FileSys.registerPathToken(_commonModuleToken, commonDirectory);
|
||||
//
|
||||
// lua_State* state = ghoul::lua::createNewLuaState();
|
||||
// OsEng.scriptEngine()->initializeLuaState(state);
|
||||
//
|
||||
// LDEBUG("Loading common module folder '" << commonDirectory << "'");
|
||||
// // Load common modules into LoadMaps struct
|
||||
// loadModule(m, FileSys.pathByAppendingComponent(directory, commonDirectory), state);
|
||||
//
|
||||
// // Load the rest of the modules into LoadMaps struct
|
||||
// ghoul::Dictionary moduleDictionary;
|
||||
// if (dictionary.getValue(constants::scenegraph::keyModules, moduleDictionary)) {
|
||||
// std::vector<std::string> keys = moduleDictionary.keys();
|
||||
// std::sort(keys.begin(), keys.end());
|
||||
// for (const std::string& key : keys) {
|
||||
// std::string moduleFolder;
|
||||
// if (moduleDictionary.getValue(key, moduleFolder)) {
|
||||
// loadModule(m, FileSys.pathByAppendingComponent(directory, moduleFolder), state);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // Load and construct scenegraphnodes from LoadMaps struct
|
||||
// loadNodes(SceneGraphNode::RootNodeName, m);
|
||||
//
|
||||
// // Remove loaded nodes from dependency list
|
||||
// for(const auto& name: m.loadedNodes) {
|
||||
// m.dependencies.erase(name);
|
||||
// }
|
||||
//
|
||||
// // Check to see what dependencies are not resolved.
|
||||
// for(auto& node: m.dependencies) {
|
||||
// LWARNING(
|
||||
// "'" << node.second << "'' not loaded, parent '"
|
||||
// << node.first << "' not defined!");
|
||||
// }
|
||||
//}
|
||||
|
||||
// Get the common directory
|
||||
std::string commonDirectory(_defaultCommonDirectory);
|
||||
dictionary.getValue(constants::scenegraph::keyCommonFolder, commonDirectory);
|
||||
FileSys.registerPathToken(_commonModuleToken, commonDirectory);
|
||||
//void Scene::loadModule(LoadMaps& m,const std::string& modulePath, lua_State* state) {
|
||||
// auto pos = modulePath.find_last_of(ghoul::filesystem::FileSystem::PathSeparator);
|
||||
// if (pos == modulePath.npos) {
|
||||
// LERROR("Bad format for module path: " << modulePath);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// std::string fullModule = modulePath + modulePath.substr(pos) + _moduleExtension;
|
||||
// LDEBUG("Loading nodes from: " << fullModule);
|
||||
//
|
||||
// ghoul::filesystem::Directory oldDirectory = FileSys.currentDirectory();
|
||||
// FileSys.setCurrentDirectory(modulePath);
|
||||
//
|
||||
// ghoul::Dictionary moduleDictionary;
|
||||
// ghoul::lua::loadDictionaryFromFile(fullModule, moduleDictionary, state);
|
||||
// std::vector<std::string> keys = moduleDictionary.keys();
|
||||
// for (const std::string& key : keys) {
|
||||
// if (!moduleDictionary.hasValue<ghoul::Dictionary>(key)) {
|
||||
// LERROR("SceneGraphElement '" << key << "' is not a table in module '"
|
||||
// << fullModule << "'");
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// ghoul::Dictionary element;
|
||||
// std::string nodeName;
|
||||
// std::string parentName;
|
||||
//
|
||||
// moduleDictionary.getValue(key, element);
|
||||
// element.setValue(constants::scenegraph::keyPathModule, modulePath);
|
||||
//
|
||||
// element.getValue(constants::scenegraphnode::keyName, nodeName);
|
||||
// element.getValue(constants::scenegraphnode::keyParentName, parentName);
|
||||
//
|
||||
// m.nodes[nodeName] = element;
|
||||
// m.dependencies.emplace(parentName,nodeName);
|
||||
// }
|
||||
//
|
||||
// FileSys.setCurrentDirectory(oldDirectory);
|
||||
//}
|
||||
|
||||
lua_State* state = ghoul::lua::createNewLuaState();
|
||||
OsEng.scriptEngine()->initializeLuaState(state);
|
||||
//void Scene::loadNodes(const std::string& parentName, LoadMaps& m) {
|
||||
// auto eqRange = m.dependencies.equal_range(parentName);
|
||||
// for (auto it = eqRange.first; it != eqRange.second; ++it) {
|
||||
// auto node = m.nodes.find((*it).second);
|
||||
// loadNode(node->second);
|
||||
// loadNodes((*it).second, m);
|
||||
// }
|
||||
// m.loadedNodes.emplace_back(parentName);
|
||||
//}
|
||||
//
|
||||
//void Scene::loadNode(const ghoul::Dictionary& dictionary) {
|
||||
// SceneGraphNode* node = SceneGraphNode::createFromDictionary(dictionary);
|
||||
// if(node) {
|
||||
// _allNodes.emplace(node->name(), node);
|
||||
// _nodes.push_back(node);
|
||||
// }
|
||||
//}
|
||||
|
||||
LDEBUG("Loading common module folder '" << commonDirectory << "'");
|
||||
// Load common modules into LoadMaps struct
|
||||
loadModule(m, FileSys.pathByAppendingComponent(directory, commonDirectory), state);
|
||||
//void SceneGraph::loadModule(const std::string& modulePath) {
|
||||
// auto pos = modulePath.find_last_of(ghoul::filesystem::FileSystem::PathSeparator);
|
||||
// if (pos == modulePath.npos) {
|
||||
// LERROR("Bad format for module path: " << modulePath);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// std::string fullModule = modulePath + modulePath.substr(pos) + _moduleExtension;
|
||||
// LDEBUG("Loading modules from: " << fullModule);
|
||||
//
|
||||
// ghoul::filesystem::Directory oldDirectory = FileSys.currentDirectory();
|
||||
// FileSys.setCurrentDirectory(modulePath);
|
||||
//
|
||||
// ghoul::Dictionary moduleDictionary;
|
||||
// ghoul::lua::loadDictionaryFromFile(fullModule, moduleDictionary);
|
||||
// std::vector<std::string> keys = moduleDictionary.keys();
|
||||
// for (const std::string& key : keys) {
|
||||
// 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(constants::scenegraph::keyPathModule, modulePath);
|
||||
//
|
||||
// //each element in this new dictionary becomes a scenegraph node.
|
||||
// SceneGraphNode* node = SceneGraphNode::createFromDictionary(element);
|
||||
//
|
||||
// _allNodes.emplace(node->name(), node);
|
||||
// _nodes.push_back(node);
|
||||
// }
|
||||
//
|
||||
// FileSys.setCurrentDirectory(oldDirectory);
|
||||
//
|
||||
// // Print the tree
|
||||
// //printTree(_root);
|
||||
//}
|
||||
|
||||
// Load the rest of the modules into LoadMaps struct
|
||||
ghoul::Dictionary moduleDictionary;
|
||||
if (dictionary.getValue(constants::scenegraph::keyModules, moduleDictionary)) {
|
||||
std::vector<std::string> keys = moduleDictionary.keys();
|
||||
std::sort(keys.begin(), keys.end());
|
||||
for (const std::string& key : keys) {
|
||||
std::string moduleFolder;
|
||||
if (moduleDictionary.getValue(key, moduleFolder)) {
|
||||
loadModule(m, FileSys.pathByAppendingComponent(directory, moduleFolder), state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Load and construct scenegraphnodes from LoadMaps struct
|
||||
loadNodes(SceneGraphNode::RootNodeName, m);
|
||||
|
||||
// Remove loaded nodes from dependency list
|
||||
for(const auto& name: m.loadedNodes) {
|
||||
m.dependencies.erase(name);
|
||||
}
|
||||
|
||||
// Check to see what dependencies are not resolved.
|
||||
for(auto& node: m.dependencies) {
|
||||
LWARNING(
|
||||
"'" << node.second << "'' not loaded, parent '"
|
||||
<< node.first << "' not defined!");
|
||||
}
|
||||
}
|
||||
|
||||
void SceneGraph::loadModule(LoadMaps& m,const std::string& modulePath, lua_State* state) {
|
||||
auto pos = modulePath.find_last_of(ghoul::filesystem::FileSystem::PathSeparator);
|
||||
if (pos == modulePath.npos) {
|
||||
LERROR("Bad format for module path: " << modulePath);
|
||||
return;
|
||||
}
|
||||
|
||||
std::string fullModule = modulePath + modulePath.substr(pos) + _moduleExtension;
|
||||
LDEBUG("Loading nodes from: " << fullModule);
|
||||
|
||||
ghoul::filesystem::Directory oldDirectory = FileSys.currentDirectory();
|
||||
FileSys.setCurrentDirectory(modulePath);
|
||||
|
||||
ghoul::Dictionary moduleDictionary;
|
||||
ghoul::lua::loadDictionaryFromFile(fullModule, moduleDictionary, state);
|
||||
std::vector<std::string> keys = moduleDictionary.keys();
|
||||
for (const std::string& key : keys) {
|
||||
if (!moduleDictionary.hasValue<ghoul::Dictionary>(key)) {
|
||||
LERROR("SceneGraphElement '" << key << "' is not a table in module '"
|
||||
<< fullModule << "'");
|
||||
continue;
|
||||
}
|
||||
|
||||
ghoul::Dictionary element;
|
||||
std::string nodeName;
|
||||
std::string parentName;
|
||||
|
||||
moduleDictionary.getValue(key, element);
|
||||
element.setValue(constants::scenegraph::keyPathModule, modulePath);
|
||||
|
||||
element.getValue(constants::scenegraphnode::keyName, nodeName);
|
||||
element.getValue(constants::scenegraphnode::keyParentName, parentName);
|
||||
|
||||
m.nodes[nodeName] = element;
|
||||
m.dependencies.emplace(parentName,nodeName);
|
||||
}
|
||||
|
||||
FileSys.setCurrentDirectory(oldDirectory);
|
||||
}
|
||||
|
||||
void SceneGraph::loadNodes(const std::string& parentName, LoadMaps& m) {
|
||||
auto eqRange = m.dependencies.equal_range(parentName);
|
||||
for (auto it = eqRange.first; it != eqRange.second; ++it) {
|
||||
auto node = m.nodes.find((*it).second);
|
||||
loadNode(node->second);
|
||||
loadNodes((*it).second, m);
|
||||
}
|
||||
m.loadedNodes.emplace_back(parentName);
|
||||
}
|
||||
|
||||
void SceneGraph::loadNode(const ghoul::Dictionary& dictionary) {
|
||||
SceneGraphNode* node = SceneGraphNode::createFromDictionary(dictionary);
|
||||
if(node) {
|
||||
_allNodes.emplace(node->name(), node);
|
||||
_nodes.push_back(node);
|
||||
}
|
||||
}
|
||||
|
||||
void SceneGraph::loadModule(const std::string& modulePath)
|
||||
{
|
||||
auto pos = modulePath.find_last_of(ghoul::filesystem::FileSystem::PathSeparator);
|
||||
if (pos == modulePath.npos) {
|
||||
LERROR("Bad format for module path: " << modulePath);
|
||||
return;
|
||||
}
|
||||
|
||||
std::string fullModule = modulePath + modulePath.substr(pos) + _moduleExtension;
|
||||
LDEBUG("Loading modules from: " << fullModule);
|
||||
|
||||
ghoul::filesystem::Directory oldDirectory = FileSys.currentDirectory();
|
||||
FileSys.setCurrentDirectory(modulePath);
|
||||
|
||||
ghoul::Dictionary moduleDictionary;
|
||||
ghoul::lua::loadDictionaryFromFile(fullModule, moduleDictionary);
|
||||
std::vector<std::string> keys = moduleDictionary.keys();
|
||||
for (const std::string& key : keys) {
|
||||
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(constants::scenegraph::keyPathModule, modulePath);
|
||||
|
||||
//each element in this new dictionary becomes a scenegraph node.
|
||||
SceneGraphNode* node = SceneGraphNode::createFromDictionary(element);
|
||||
|
||||
_allNodes.emplace(node->name(), node);
|
||||
_nodes.push_back(node);
|
||||
}
|
||||
|
||||
FileSys.setCurrentDirectory(oldDirectory);
|
||||
|
||||
// Print the tree
|
||||
//printTree(_root);
|
||||
}
|
||||
|
||||
SceneGraphNode* SceneGraph::root() const
|
||||
{
|
||||
return _root;
|
||||
SceneGraphNode* Scene::root() const {
|
||||
return _graph.rootNode();
|
||||
}
|
||||
|
||||
SceneGraphNode* SceneGraph::sceneGraphNode(const std::string& name) const {
|
||||
auto it = _allNodes.find(name);
|
||||
if (it == _allNodes.end())
|
||||
return nullptr;
|
||||
else
|
||||
return it->second;
|
||||
SceneGraphNode* Scene::sceneGraphNode(const std::string& name) const {
|
||||
return _graph.sceneGraphNode(name);
|
||||
}
|
||||
|
||||
std::vector<SceneGraphNode*> SceneGraph::allSceneGraphNodes() const {
|
||||
return _nodes;
|
||||
std::vector<SceneGraphNode*> Scene::allSceneGraphNodes() {
|
||||
return _graph.nodes();
|
||||
}
|
||||
|
||||
void SceneGraph::writePropertyDocumentation(const std::string& filename, const std::string& type) {
|
||||
void Scene::writePropertyDocumentation(const std::string& filename, const std::string& type) {
|
||||
if (type == "text") {
|
||||
LDEBUG("Writing documentation for properties");
|
||||
std::ofstream file(filename);
|
||||
@@ -695,7 +740,7 @@ void SceneGraph::writePropertyDocumentation(const std::string& filename, const s
|
||||
}
|
||||
|
||||
using properties::Property;
|
||||
for (SceneGraphNode* node : _nodes) {
|
||||
for (SceneGraphNode* node : _graph.nodes()) {
|
||||
std::vector<Property*> properties = node->propertiesRecursive();
|
||||
if (!properties.empty()) {
|
||||
file << node->name() << std::endl;
|
||||
@@ -712,7 +757,7 @@ void SceneGraph::writePropertyDocumentation(const std::string& filename, const s
|
||||
LERROR("Undefined type '" << type << "' for Property documentation");
|
||||
}
|
||||
|
||||
scripting::ScriptEngine::LuaLibrary SceneGraph::luaLibrary() {
|
||||
scripting::ScriptEngine::LuaLibrary Scene::luaLibrary() {
|
||||
return {
|
||||
"",
|
||||
{
|
||||
@@ -0,0 +1,367 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2015 *
|
||||
* *
|
||||
* 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. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/scene/scenegraph.h>
|
||||
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/util/constants.h>
|
||||
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/lua/lua_helper.h>
|
||||
|
||||
#include <stack>
|
||||
|
||||
namespace {
|
||||
const std::string _loggerCat = "SceneGraph";
|
||||
const std::string _moduleExtension = ".mod";
|
||||
const std::string _defaultCommonDirectory = "common";
|
||||
const std::string _commonModuleToken = "${COMMON_MODULE}";
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
|
||||
SceneGraph::SceneGraph() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
void SceneGraph::clear() {
|
||||
// Untested ---abock
|
||||
for (SceneGraphNodeInternal* n : _nodes) {
|
||||
delete n->node;
|
||||
delete n;
|
||||
}
|
||||
|
||||
_nodes.clear();
|
||||
}
|
||||
|
||||
bool SceneGraph::loadFromFile(const std::string& sceneDescription) {
|
||||
clear(); // Move this to a later stage to retain a proper scenegraph when the loading fails ---abock
|
||||
|
||||
std::string absSceneFile = absPath(sceneDescription);
|
||||
|
||||
// See if scene file exists
|
||||
if (!FileSys.fileExists(absSceneFile, true)) {
|
||||
LERROR("Could not load scene file '" << absSceneFile << "'. " <<
|
||||
"File not found");
|
||||
return false;
|
||||
}
|
||||
LINFO("Loading SceneGraph from file '" << absSceneFile << "'");
|
||||
|
||||
// Load dictionary
|
||||
ghoul::Dictionary sceneDictionary;
|
||||
bool success = ghoul::lua::loadDictionaryFromFile(absSceneFile, sceneDictionary);
|
||||
if (!success)
|
||||
return false;
|
||||
|
||||
std::string sceneDescriptionDirectory =
|
||||
ghoul::filesystem::File(absSceneFile, true).directoryName();
|
||||
std::string sceneDirectory(".");
|
||||
sceneDictionary.getValue(constants::scenegraph::keyPathScene, sceneDirectory);
|
||||
|
||||
// The scene path could either be an absolute or relative path to the description
|
||||
// paths directory
|
||||
std::string relativeCandidate = sceneDescriptionDirectory +
|
||||
ghoul::filesystem::FileSystem::PathSeparator + sceneDirectory;
|
||||
std::string absoluteCandidate = absPath(sceneDirectory);
|
||||
|
||||
if (FileSys.directoryExists(relativeCandidate))
|
||||
sceneDirectory = relativeCandidate;
|
||||
else if (FileSys.directoryExists(absoluteCandidate))
|
||||
sceneDirectory = absoluteCandidate;
|
||||
else {
|
||||
LERROR("The '" << constants::scenegraph::keyPathScene << "' pointed to a "
|
||||
"path '" << sceneDirectory << "' that did not exist");
|
||||
return false;
|
||||
}
|
||||
|
||||
using constants::scenegraph::keyModules;
|
||||
ghoul::Dictionary moduleDictionary;
|
||||
success = sceneDictionary.getValue(keyModules, moduleDictionary);
|
||||
if (!success)
|
||||
// There are no modules that are loaded
|
||||
return true;
|
||||
|
||||
lua_State* state = ghoul::lua::createNewLuaState();
|
||||
OsEng.scriptEngine()->initializeLuaState(state);
|
||||
|
||||
// Get the common directory
|
||||
using constants::scenegraph::keyCommonFolder;
|
||||
bool commonFolderSpecified = sceneDictionary.hasKey(keyCommonFolder);
|
||||
bool commonFolderCorrectType = sceneDictionary.hasKeyAndValue<std::string>(keyCommonFolder);
|
||||
|
||||
if (commonFolderSpecified) {
|
||||
if (commonFolderCorrectType) {
|
||||
std::string commonFolder = sceneDictionary.value<std::string>(keyCommonFolder);
|
||||
std::string fullCommonFolder = FileSys.pathByAppendingComponent(
|
||||
sceneDirectory,
|
||||
commonFolder
|
||||
);
|
||||
if (!FileSys.directoryExists(fullCommonFolder))
|
||||
LERROR("Specified common folder '" << fullCommonFolder << "' did not exist");
|
||||
else {
|
||||
if (!commonFolder.empty()) {
|
||||
FileSys.registerPathToken(_commonModuleToken, commonFolder);
|
||||
size_t nKeys = moduleDictionary.size();
|
||||
moduleDictionary.setValue(std::to_string(nKeys + 1), commonFolder);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
LERROR("Specification for 'common' folder has invalid type");
|
||||
}
|
||||
|
||||
std::vector<std::string> keys = moduleDictionary.keys();
|
||||
|
||||
std::map<std::string, std::vector<std::string>> dependencies;
|
||||
std::map<std::string, std::string> parents;
|
||||
|
||||
_rootNode = new SceneGraphNode;
|
||||
_rootNode->setName(SceneGraphNode::RootNodeName);
|
||||
SceneGraphNodeInternal* internalRoot = new SceneGraphNodeInternal;
|
||||
internalRoot->node = _rootNode;
|
||||
_nodes.push_back(internalRoot);
|
||||
|
||||
std::sort(keys.begin(), keys.end());
|
||||
ghoul::filesystem::Directory oldDirectory = FileSys.currentDirectory();
|
||||
for (const std::string& key : keys) {
|
||||
std::string moduleName = moduleDictionary.value<std::string>(key);
|
||||
std::string modulePath = FileSys.pathByAppendingComponent(sceneDirectory, moduleName);
|
||||
|
||||
if (!FileSys.directoryExists(modulePath)) {
|
||||
LERROR("Could not load module '" << moduleName << "'. Directory did not exist");
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string moduleFile = FileSys.pathByAppendingComponent(
|
||||
modulePath,
|
||||
moduleName + _moduleExtension
|
||||
);
|
||||
|
||||
if (!FileSys.fileExists(moduleFile)) {
|
||||
LERROR("Could not load module file '" << moduleFile << "'. File did not exist");
|
||||
continue;
|
||||
}
|
||||
|
||||
ghoul::Dictionary moduleDictionary;
|
||||
bool s = ghoul::lua::loadDictionaryFromFile(moduleFile, moduleDictionary, state);
|
||||
if (!s)
|
||||
continue;
|
||||
|
||||
std::vector<std::string> keys = moduleDictionary.keys();
|
||||
for (const std::string& key : keys) {
|
||||
if (!moduleDictionary.hasValue<ghoul::Dictionary>(key)) {
|
||||
LERROR("SceneGraphNode '" << key << "' is not a table in module '"
|
||||
<< moduleFile << "'");
|
||||
continue;
|
||||
}
|
||||
|
||||
ghoul::Dictionary element;
|
||||
std::string nodeName;
|
||||
std::string parentName;
|
||||
|
||||
moduleDictionary.getValue(key, element);
|
||||
element.setValue(constants::scenegraph::keyPathModule, modulePath);
|
||||
|
||||
element.getValue(constants::scenegraphnode::keyName, nodeName);
|
||||
element.getValue(constants::scenegraphnode::keyParentName, parentName);
|
||||
|
||||
FileSys.setCurrentDirectory(modulePath);
|
||||
SceneGraphNode* node = SceneGraphNode::createFromDictionary(element);
|
||||
if (node == nullptr) {
|
||||
LERROR("Error loading SceneGraphNode '" << nodeName << "' in module '" << moduleName << "'");
|
||||
clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
dependencies[nodeName].push_back(parentName);
|
||||
parents[nodeName] = parentName;
|
||||
// Also include loaded dependencies
|
||||
|
||||
using constants::scenegraphnode::keyDependencies;
|
||||
if (element.hasKey(keyDependencies)) {
|
||||
if (element.hasValue<ghoul::Dictionary>(keyDependencies)) {
|
||||
ghoul::Dictionary nodeDependencies;
|
||||
element.getValue(constants::scenegraphnode::keyDependencies, nodeDependencies);
|
||||
|
||||
std::vector<std::string> keys = nodeDependencies.keys();
|
||||
for (const std::string& key : keys) {
|
||||
std::string value = nodeDependencies.value<std::string>(key);
|
||||
dependencies[nodeName].push_back(value);
|
||||
}
|
||||
}
|
||||
else {
|
||||
LERROR("Dependencies did not have the corrent type");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SceneGraphNodeInternal* internalNode = new SceneGraphNodeInternal;
|
||||
internalNode->node = node;
|
||||
_nodes.push_back(internalNode);
|
||||
}
|
||||
}
|
||||
FileSys.setCurrentDirectory(oldDirectory);
|
||||
|
||||
for (SceneGraphNodeInternal* node : _nodes) {
|
||||
if (node->node == _rootNode)
|
||||
continue;
|
||||
std::string parent = parents[node->node->name()];
|
||||
SceneGraphNode* parentNode = sceneGraphNode(parent);
|
||||
if (parentNode == nullptr) {
|
||||
LERROR("Could not find parent '" << parent << "' for '" << node->node->name() << "'");
|
||||
}
|
||||
|
||||
node->node->setParent(parentNode);
|
||||
}
|
||||
|
||||
// Setup dependencies
|
||||
for (SceneGraphNodeInternal* node : _nodes) {
|
||||
std::vector<std::string> nodeDependencies = dependencies[node->node->name()];
|
||||
|
||||
for (const std::string& dep : nodeDependencies) {
|
||||
SceneGraphNodeInternal* n = nodeByName(dep);
|
||||
if (n == nullptr) {
|
||||
LERROR("Dependent node '" << dep << "' was not loaded for '" <<node->node->name() << "'");
|
||||
continue;
|
||||
}
|
||||
node->outgoingEdges.push_back(n);
|
||||
n->incomingEdges.push_back(node);
|
||||
}
|
||||
}
|
||||
|
||||
for (SceneGraphNodeInternal* node : _nodes) {
|
||||
if (!nodeIsDependentOnRoot(node)) {
|
||||
LERROR("Node '" << node->node->name() << "' has no direct connection to Root.");
|
||||
//clear();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool s = sortTopologially();
|
||||
if (!s) {
|
||||
LERROR("Topological sort failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SceneGraph::nodeIsDependentOnRoot(SceneGraphNodeInternal* node) {
|
||||
if (node->node->name() == SceneGraphNode::RootNodeName)
|
||||
return true;
|
||||
else {
|
||||
for (SceneGraphNodeInternal* n : node->outgoingEdges) {
|
||||
bool dep = nodeIsDependentOnRoot(n);
|
||||
if (dep)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool SceneGraph::sortTopologially() {
|
||||
if (_nodes.empty())
|
||||
return true;
|
||||
|
||||
// Only the Root node can have an in-degree of 0
|
||||
SceneGraphNodeInternal* root = nodeByName(SceneGraphNode::RootNodeName);
|
||||
ghoul_assert(root != nullptr, "Could not find Root node");
|
||||
|
||||
std::stack<SceneGraphNodeInternal*> zeroInDegreeNodes;
|
||||
zeroInDegreeNodes.push(root);
|
||||
|
||||
std::unordered_map<SceneGraphNodeInternal*, size_t> inDegrees;
|
||||
for (SceneGraphNodeInternal* node : _nodes)
|
||||
inDegrees[node] = node->outgoingEdges.size();
|
||||
//inDegrees[node] = node->incomingEdges.size();
|
||||
|
||||
_topologicalSortedNodes.clear();
|
||||
_topologicalSortedNodes.reserve(_nodes.size());
|
||||
while (!zeroInDegreeNodes.empty()) {
|
||||
SceneGraphNodeInternal* node = zeroInDegreeNodes.top();
|
||||
|
||||
_topologicalSortedNodes.push_back(node->node);
|
||||
zeroInDegreeNodes.pop();
|
||||
|
||||
//for (SceneGraphNodeInternal* n : node->outgoingEdges) {
|
||||
for (SceneGraphNodeInternal* n : node->incomingEdges) {
|
||||
inDegrees[n] -= 1;
|
||||
if (inDegrees[n] == 0)
|
||||
zeroInDegreeNodes.push(n);
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SceneGraph::addSceneGraphNode(SceneGraphNode* node) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SceneGraph::removeSceneGraphNode(SceneGraphNode* node) {
|
||||
// How to handle orphaned nodes? (reparent to root?) --- abock
|
||||
return true;
|
||||
}
|
||||
|
||||
SceneGraph::SceneGraphNodeInternal* SceneGraph::nodeByName(const std::string& name) {
|
||||
auto it = std::find_if(
|
||||
_nodes.begin(),
|
||||
_nodes.end(),
|
||||
[name](SceneGraphNodeInternal* node) {
|
||||
return node->node->name() == name;
|
||||
}
|
||||
);
|
||||
|
||||
if (it == _nodes.end())
|
||||
return nullptr;
|
||||
else
|
||||
return *it;
|
||||
}
|
||||
|
||||
const std::vector<SceneGraphNode*>& SceneGraph::nodes() {
|
||||
return _topologicalSortedNodes;
|
||||
}
|
||||
|
||||
SceneGraphNode* SceneGraph::rootNode() const {
|
||||
return _rootNode;
|
||||
}
|
||||
|
||||
SceneGraphNode* SceneGraph::sceneGraphNode(const std::string& name) const {
|
||||
auto it = std::find_if(
|
||||
_nodes.begin(),
|
||||
_nodes.end(),
|
||||
[name](SceneGraphNodeInternal* node) {
|
||||
return node->node->name() == name;
|
||||
}
|
||||
);
|
||||
if (it != _nodes.end())
|
||||
return (*it)->node;
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
@@ -23,7 +23,7 @@
|
||||
****************************************************************************************/
|
||||
|
||||
// open space includes
|
||||
#include <openspace/scenegraph/scenegraphnode.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/query/query.h>
|
||||
#include <openspace/util/constants.h>
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
#include <ghoul/opengl/shaderobject.h>
|
||||
#include <ghoul/misc/highresclock.h>
|
||||
|
||||
#include <openspace/scenegraph/staticephemeris.h>
|
||||
#include <openspace/scene/staticephemeris.h>
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/util/factorymanager.h>
|
||||
|
||||
@@ -109,14 +109,14 @@ SceneGraphNode* SceneGraphNode::createFromDictionary(const ghoul::Dictionary& di
|
||||
parentName = "Root";
|
||||
}
|
||||
|
||||
SceneGraphNode* parentNode = sceneGraphNode(parentName);
|
||||
if (parentNode == nullptr) {
|
||||
LFATAL("Could not find parent named '"
|
||||
<< parentName << "' for '" << result->name() << "'."
|
||||
<< " Check module definition order. Skipping module.");
|
||||
}
|
||||
//SceneGraphNode* parentNode = sceneGraphNode(parentName);
|
||||
//if (parentNode == nullptr) {
|
||||
// LFATAL("Could not find parent named '"
|
||||
// << parentName << "' for '" << result->name() << "'."
|
||||
// << " Check module definition order. Skipping module.");
|
||||
//}
|
||||
|
||||
parentNode->addNode(result);
|
||||
//parentNode->addNode(result);
|
||||
|
||||
LDEBUG("Successfully created SceneGraphNode '"
|
||||
<< result->name() << "'");
|
||||
@@ -247,12 +247,12 @@ void SceneGraphNode::evaluate(const Camera* camera, const psc& parentPosition) {
|
||||
}
|
||||
|
||||
// evaluate all the children, tail-recursive function(?)
|
||||
for (SceneGraphNode* child : _children)
|
||||
child->evaluate(camera, psc());
|
||||
//for (SceneGraphNode* child : _children)
|
||||
// child->evaluate(camera, psc());
|
||||
}
|
||||
|
||||
void SceneGraphNode::render(const RenderData& data) {
|
||||
const psc thisPosition = data.position + _ephemeris->position();
|
||||
const psc thisPosition = worldPosition();
|
||||
|
||||
RenderData newData = {data.camera, thisPosition, data.doPerformanceMeasurement};
|
||||
|
||||
@@ -274,23 +274,35 @@ void SceneGraphNode::render(const RenderData& data) {
|
||||
|
||||
// evaluate all the children, tail-recursive function(?)
|
||||
|
||||
for (SceneGraphNode* child : _children)
|
||||
child->render(newData);
|
||||
//for (SceneGraphNode* child : _children)
|
||||
// child->render(newData);
|
||||
}
|
||||
|
||||
// set & get
|
||||
void SceneGraphNode::addNode(SceneGraphNode* child)
|
||||
{
|
||||
// add a child node and set this node to be the parent
|
||||
child->setParent(this);
|
||||
_children.push_back(child);
|
||||
}
|
||||
// not used anymore @AA
|
||||
//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::setParent(SceneGraphNode* parent)
|
||||
{
|
||||
_parent = parent;
|
||||
}
|
||||
|
||||
//not used anymore @AA
|
||||
//bool SceneGraphNode::abandonChild(SceneGraphNode* child) {
|
||||
// std::vector < SceneGraphNode* >::iterator it = std::find(_children.begin(), _children.end(), child);
|
||||
//
|
||||
// if (it != _children.end()){
|
||||
// _children.erase(it);
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// return false;
|
||||
//}
|
||||
|
||||
const psc& SceneGraphNode::position() const
|
||||
{
|
||||
return _ephemeris->position();
|
||||
@@ -22,14 +22,16 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/scenegraph/spiceephemeris.h>
|
||||
#include <openspace/scene/spiceephemeris.h>
|
||||
|
||||
#include <openspace/util/constants.h>
|
||||
#include <openspace/util/spicemanager.h>
|
||||
#include <openspace/util/time.h>
|
||||
#include <openspace/util/imagesequencer2.h>
|
||||
|
||||
namespace {
|
||||
const std::string _loggerCat = "SpiceEphemeris";
|
||||
const std::string keyGhosting = "EphmerisGhosting";
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
@@ -50,6 +52,8 @@ SpiceEphemeris::SpiceEphemeris(const ghoul::Dictionary& dictionary)
|
||||
if (!hasObserver)
|
||||
LERROR("SpiceEphemeris does not contain the key '" << keyOrigin << "'");
|
||||
|
||||
dictionary.getValue(keyGhosting, _ghosting);
|
||||
|
||||
ghoul::Dictionary kernels;
|
||||
dictionary.getValue(keyKernels, kernels);
|
||||
for (size_t i = 1; i <= kernels.size(); ++i) {
|
||||
@@ -73,15 +77,14 @@ void SpiceEphemeris::update(const UpdateData& data) {
|
||||
|
||||
glm::dvec3 position(0,0,0);
|
||||
double lightTime = 0.0;
|
||||
|
||||
SpiceManager::ref().getTargetPosition(_targetName, _originName,
|
||||
"GALACTIC", "NONE", data.time, position, lightTime);
|
||||
|
||||
if (_targetName == "NEW HORIZONS"){
|
||||
// In order to properly draw the viewfrustrum, the craft might have to be
|
||||
// positioned using the X-variations of aberration methods (ongoing investigation).
|
||||
|
||||
double interval = openspace::ImageSequencer2::ref().getIntervalLength();
|
||||
if (_ghosting == "TRUE" && interval > 60){
|
||||
double _time = openspace::ImageSequencer2::ref().getNextCaptureTime();
|
||||
SpiceManager::ref().getTargetPosition(_targetName, _originName,
|
||||
"GALACTIC", "NONE", data.time, position, lightTime);
|
||||
"GALACTIC", "NONE", _time, position, lightTime);
|
||||
}
|
||||
|
||||
_position = psc::CreatePowerScaledCoordinate(position.x, position.y, position.z);
|
||||
@@ -22,7 +22,7 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/scenegraph/staticephemeris.h>
|
||||
#include <openspace/scene/staticephemeris.h>
|
||||
|
||||
#include <openspace/util/constants.h>
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
-- Solar System module
|
||||
{
|
||||
Name = "SolarSystem",
|
||||
Parent = "Root",
|
||||
Position = {
|
||||
Type = "static",
|
||||
Position = { 0, 0, 0, 0}
|
||||
}
|
||||
},
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
|
||||
|
||||
{
|
||||
Camera = {
|
||||
Focus = "Earth",
|
||||
Position = "Earth"
|
||||
},
|
||||
Modules = {
|
||||
"common",
|
||||
"earth"
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
{
|
||||
-- Earth barycenter module
|
||||
{
|
||||
Name = "EarthBarycenter",
|
||||
Parent = "SolarSystem",
|
||||
Static = "true",
|
||||
Position = {
|
||||
Type = "Kepler",
|
||||
Inclination = 0.00041,
|
||||
AscendingNode = 349.2,
|
||||
Perihelion = 102.8517,
|
||||
SemiMajorAxis = 1.00002,
|
||||
DailyMotion = 0.9855796,
|
||||
Eccentricity = 0.0166967,
|
||||
MeanLongitude = 328.40353
|
||||
}
|
||||
},
|
||||
|
||||
-- dummy earth module
|
||||
--[[
|
||||
{
|
||||
Name = "DummyEarth",
|
||||
Parent = "Root",
|
||||
Renderable = {
|
||||
Type = "RenderablePlanet",
|
||||
Geometry = {
|
||||
Type = "SimpleSphere",
|
||||
--Radius = { 1.0, 1 } -- not sure if correct; supposed 6371km in meters in pss
|
||||
Radius = { 1.0, 1} -- not sure if correct; supposed 6371km in meters in pss
|
||||
},
|
||||
Textures = {
|
||||
Type = "simple",
|
||||
Color = "textures/earth_nasa_lowres.png",
|
||||
Depth = "textures/earth_depth.png"
|
||||
},
|
||||
},
|
||||
Position = {
|
||||
Type = "Static",
|
||||
Position = { 0, 0, -1, 1}
|
||||
}
|
||||
},
|
||||
]]--
|
||||
|
||||
-- Earth module
|
||||
{
|
||||
Name = "Earth",
|
||||
Parent = "EarthBarycenter",
|
||||
Renderable = {
|
||||
Type = "RenderablePlanet",
|
||||
Geometry = {
|
||||
Type = "SimpleSphere",
|
||||
--Radius = { 6.371, 6 },
|
||||
Radius = { 1.0, 1},
|
||||
Segments = 10
|
||||
},
|
||||
Textures = {
|
||||
Type = "simple",
|
||||
Color = "textures/earth_nasa_lowres.png",
|
||||
Depth = "textures/earth_depth.png"
|
||||
},
|
||||
Atmosphere = {
|
||||
Type = "Nishita", -- for example, values missing etc etc
|
||||
MieFactor = 1.0,
|
||||
MieColor = {1.0, 1.0, 1.0}
|
||||
}
|
||||
},
|
||||
Position = {
|
||||
Type = "Spice",
|
||||
Body = "EARTH",
|
||||
Reference = "ECLIPJ2000",
|
||||
Observer = "EARTH BARYCENTER",
|
||||
Kernels = {
|
||||
"kernels/earth.bsp"
|
||||
}
|
||||
},
|
||||
Rotation = {
|
||||
Type = "Spice",
|
||||
Frame = "IAU_EARTH",
|
||||
Reference = "ECLIPJ2000"
|
||||
},
|
||||
GuiName = "/Solar/Planets/Earth"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 145 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 734 KiB |
@@ -37,14 +37,16 @@
|
||||
#include <openspace/rendering/planets/renderableplanet.h>
|
||||
#include <openspace/rendering/planets/simplespheregeometry.h>
|
||||
#include <openspace/rendering/renderableplane.h>
|
||||
#include <openspace/rendering/renderableplaneprojection.h>
|
||||
#include <openspace/rendering/renderablevolumegl.h>
|
||||
#include <openspace/rendering/planets/simplespheregeometry.h>
|
||||
#include <openspace/rendering/model/modelgeometry.h>
|
||||
#include <openspace/rendering/model/wavefrontgeometry.h>
|
||||
|
||||
// positioninformation
|
||||
#include <openspace/scenegraph/staticephemeris.h>
|
||||
#include <openspace/scenegraph/spiceephemeris.h>
|
||||
#include <openspace/scene/staticephemeris.h>
|
||||
#include <openspace/scene/dynamicephemeris.h>
|
||||
#include <openspace/scene/spiceephemeris.h>
|
||||
|
||||
// projection
|
||||
#include <openspace/rendering/planets/renderableplanetprojection.h>
|
||||
@@ -93,6 +95,8 @@ void FactoryManager::initialize()
|
||||
"RenderableModel");
|
||||
_manager->factory<Renderable>()->registerClass<RenderablePlane>(
|
||||
"RenderablePlane");
|
||||
_manager->factory<Renderable>()->registerClass<RenderablePlaneProjection>(
|
||||
"RenderablePlaneProjection");
|
||||
_manager->factory<Renderable>()->registerClass<RenderableVolumeGL>(
|
||||
"RenderableVolumeGL");
|
||||
_manager->factory<Renderable>()->registerClass<RenderableFieldlines>(
|
||||
@@ -101,6 +105,7 @@ void FactoryManager::initialize()
|
||||
// Add Ephimerides
|
||||
_manager->addFactory(new ghoul::TemplateFactory<Ephemeris>);
|
||||
_manager->factory<Ephemeris>()->registerClass<StaticEphemeris>("Static");
|
||||
_manager->factory<Ephemeris>()->registerClass<StaticEphemeris>("Dynamic");
|
||||
_manager->factory<Ephemeris>()->registerClass<SpiceEphemeris>("Spice");
|
||||
|
||||
_manager->addFactory(new ghoul::TemplateFactory<Decoder>);
|
||||
|
||||
+56
-15
@@ -34,8 +34,9 @@
|
||||
#include <iterator>
|
||||
#include <iomanip>
|
||||
#include <limits>
|
||||
|
||||
#include <openspace/util/hongkangparser.h>
|
||||
#include <openspace/util/instrumentdecoder.h>
|
||||
|
||||
|
||||
namespace {
|
||||
const std::string _loggerCat = "HongKangParser";
|
||||
@@ -65,9 +66,10 @@ namespace openspace {
|
||||
translationDictionary.getValue(decoders[i], typeDictionary);
|
||||
//for each playbook call -> create a Decoder object
|
||||
const std::vector<std::string>& keys = typeDictionary.keys();
|
||||
//std::string abort = decoders[i] + "." + keyStopCommand;
|
||||
for (int j = 0; j < keys.size(); j++){
|
||||
std::string currentKey = decoders[i] + "." + keys[j];
|
||||
|
||||
|
||||
ghoul::Dictionary decoderDictionary;
|
||||
translationDictionary.getValue(currentKey, decoderDictionary);
|
||||
|
||||
@@ -105,7 +107,7 @@ void HongKangParser::create(){
|
||||
|
||||
if (extension == "txt"){// Hong Kang. pre-parsed playbook
|
||||
LINFO("Using Preparsed Playbook V9H");
|
||||
std::ifstream file(_fileName);
|
||||
std::ifstream file(_fileName , std::ios::binary);
|
||||
if (!file.good()) LERROR("Failed to open txt file '" << _fileName << "'");
|
||||
|
||||
std::string line = "";
|
||||
@@ -130,18 +132,22 @@ void HongKangParser::create(){
|
||||
|
||||
std::string cameraTarget = "VOID";
|
||||
std::string scannerTarget = "VOID";
|
||||
do{
|
||||
std::getline(file, line);
|
||||
int counter = 0;
|
||||
|
||||
|
||||
while (!file.eof()){//only while inte do, FIX
|
||||
std::getline(file, line);
|
||||
|
||||
std::string event = line.substr(0, line.find_first_of(" "));
|
||||
|
||||
auto it = _fileTranslation.find(event);
|
||||
bool foundEvent = (it != _fileTranslation.end());
|
||||
|
||||
|
||||
std::string met = line.substr(25, 9);
|
||||
double time = getETfromMet(met);
|
||||
|
||||
Image image;
|
||||
|
||||
|
||||
if (foundEvent){
|
||||
//store the time, this is used for getNextCaptureTime()
|
||||
_captureProgression.push_back(time);
|
||||
@@ -171,13 +177,48 @@ void HongKangParser::create(){
|
||||
//compute and store the range for each subset
|
||||
_subsetMap[image.target]._range.setRange(time);
|
||||
}
|
||||
if (scan_start == -1 && it->second->getDecoderType() == "SCANNER"){
|
||||
//scanner works like state-machine -only store start time now
|
||||
if (it->second->getDecoderType() == "SCANNER"){ // SCANNER START
|
||||
scan_start = time;
|
||||
|
||||
InstrumentDecoder* scanner = static_cast<InstrumentDecoder*>(it->second);
|
||||
std::string endNominal = scanner->getStopCommand();
|
||||
|
||||
// store current position in file
|
||||
int len = file.tellg();
|
||||
std::string linePeek;
|
||||
bool foundstop = false;
|
||||
while (!file.eof() && !foundstop){
|
||||
//continue grabbing next line until we find what we need
|
||||
getline(file, linePeek);
|
||||
if (linePeek.find(endNominal) != std::string::npos){
|
||||
foundstop = true;
|
||||
|
||||
met = linePeek.substr(25, 9);
|
||||
scan_stop = getETfromMet(met);
|
||||
findPlaybookSpecifiedTarget(line, scannerTarget);
|
||||
scannerSpiceID = it->second->getTranslation();
|
||||
|
||||
scanRange._min = scan_start;
|
||||
scanRange._max = scan_stop;
|
||||
_instrumentTimes.push_back(std::make_pair(it->first, scanRange));
|
||||
|
||||
|
||||
//store individual image
|
||||
createImage(image, scan_start, scan_stop, scannerSpiceID, scannerTarget, _defaultCaptureImage);
|
||||
|
||||
_subsetMap[image.target]._subset.push_back(image);
|
||||
_subsetMap[image.target]._range.setRange(scan_start);
|
||||
}
|
||||
}
|
||||
//go back to stored position in file
|
||||
file.seekg(len, std::ios_base::beg);
|
||||
|
||||
/*//scanner works like state-machine -only store start time now
|
||||
scan_start = time;
|
||||
previousScanner = it->first;
|
||||
//store scanning instrument - store image once stopTime is found!
|
||||
findPlaybookSpecifiedTarget(line, scannerTarget);
|
||||
scannerSpiceID = it->second->getTranslation();
|
||||
scannerSpiceID = it->second->getTranslation();*/
|
||||
}
|
||||
}
|
||||
else{ // we have reached the end of a scan or consecutive capture sequence!
|
||||
@@ -190,7 +231,7 @@ void HongKangParser::create(){
|
||||
|
||||
capture_start = -1;
|
||||
}
|
||||
if (line.find("END_NOM") != std::string::npos){
|
||||
/*if (line.find("END_NOM") != std::string::npos){
|
||||
assert(scan_start != -1, "SCAN end occured before SCAN call!");
|
||||
//end of scan, store end time of this scan + store the scan image
|
||||
scan_stop = time;
|
||||
@@ -205,9 +246,9 @@ void HongKangParser::create(){
|
||||
_subsetMap[image.target]._range.setRange(scan_start);
|
||||
|
||||
scan_start = -1;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
} while (!file.eof());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -279,10 +320,10 @@ bool HongKangParser::augmentWithSpice(Image& image,
|
||||
return false;
|
||||
}
|
||||
|
||||
void HongKangParser::createImage(Image& image, double startTime, double stopTime, std::vector<std::string> instr, std::string targ, std::string pot) {
|
||||
void HongKangParser::createImage(Image& image, double startTime, double stopTime, std::vector<std::string> instr, std::string targ, std::string path) {
|
||||
image.startTime = startTime;
|
||||
image.stopTime = stopTime;
|
||||
image.path = pot;
|
||||
image.path = path;
|
||||
for (int i = 0; i < instr.size(); i++){
|
||||
image.activeInstruments.push_back(instr[i]);
|
||||
}
|
||||
|
||||
+123
-74
@@ -46,10 +46,10 @@ ImageSequencer2* ImageSequencer2::_instance = nullptr;
|
||||
|
||||
ImageSequencer2::ImageSequencer2() :
|
||||
_hasData(false),
|
||||
_latestImage(nullptr),
|
||||
_defaultCaptureImage(absPath("${OPENSPACE_DATA}/scene/common/textures/placeholder_blank.png"))
|
||||
{}
|
||||
|
||||
|
||||
ImageSequencer2& ImageSequencer2::ref() {
|
||||
assert(_instance != nullptr);
|
||||
return *_instance;
|
||||
@@ -68,22 +68,6 @@ bool ImageSequencer2::isReady(){
|
||||
return _hasData;
|
||||
}
|
||||
|
||||
bool ImageSequencer2::imageComparer(const Image &a, const Image &b){
|
||||
return a.startTime < b.startTime;
|
||||
};
|
||||
|
||||
std::vector<Image>::iterator ImageSequencer2::binary_find(std::vector<Image>::iterator begin,
|
||||
std::vector<Image>::iterator end,
|
||||
const Image &val,
|
||||
bool(*compareFunc)(const Image &a, const Image &b)){
|
||||
// Finds the lower bound in at most log(last - first) + 1 comparisons
|
||||
std::vector<Image>::iterator it = std::lower_bound(begin, end, val, compareFunc);
|
||||
if (it != begin && it != end){
|
||||
return it;
|
||||
}
|
||||
return end;
|
||||
}
|
||||
|
||||
void ImageSequencer2::updateSequencer(double time){
|
||||
if (_currentTime != time){
|
||||
_previousTime = _currentTime;
|
||||
@@ -92,7 +76,6 @@ void ImageSequencer2::updateSequencer(double time){
|
||||
}
|
||||
|
||||
std::pair<double, std::string> ImageSequencer2::getNextTarget(){
|
||||
// make into template func
|
||||
auto compareTime = [](const std::pair<double, std::string> &a,
|
||||
const std::pair<double, std::string> &b)->bool{
|
||||
return a.first < b.first;
|
||||
@@ -101,15 +84,14 @@ std::pair<double, std::string> ImageSequencer2::getNextTarget(){
|
||||
findEqualToThis.first = _currentTime;
|
||||
auto it = std::lower_bound(_targetTimes.begin(), _targetTimes.end(), findEqualToThis, compareTime);
|
||||
|
||||
if (it != _targetTimes.end()){
|
||||
if (it != _targetTimes.end() && it != _targetTimes.begin()){
|
||||
return (*it);
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<double, std::string> ImageSequencer2::getCurrentTarget(){
|
||||
// make into template func
|
||||
auto compareTime = [](const std::pair<double, std::string> &a,
|
||||
const std::pair<double, std::string> &b)->bool{
|
||||
const std::pair<double, std::string> &b)->bool{
|
||||
return a.first < b.first;
|
||||
};
|
||||
std::pair<double, std::string> findEqualToThis;
|
||||
@@ -127,21 +109,26 @@ std::pair<double, std::vector<std::string>> ImageSequencer2::getIncidentTargetLi
|
||||
std::pair<double, std::vector<std::string>> incidentTargets;
|
||||
|
||||
auto compareTime = [](const std::pair<double, std::string> &a,
|
||||
const std::pair<double, std::string> &b)->bool{
|
||||
return a.first < b.first;
|
||||
const std::pair<double, std::string> &b)->bool{
|
||||
return a.first < b.first;
|
||||
};
|
||||
// what to look for
|
||||
std::pair<double, std::string> findEqualToThis;
|
||||
findEqualToThis.first = _currentTime;
|
||||
auto it = std::lower_bound(_targetTimes.begin(), _targetTimes.end(), findEqualToThis, compareTime);
|
||||
|
||||
std::advance(it, -(range+1));
|
||||
if (it != _targetTimes.end() && it != _targetTimes.begin()){
|
||||
// move the iterator to the first element of the range
|
||||
std::advance(it, -(range + 1));
|
||||
|
||||
for (int i = 0; i < 2*range+1; i++){
|
||||
incidentTargets.first = it->first;
|
||||
incidentTargets.second.push_back(it->second);
|
||||
it++;
|
||||
if (it == _targetTimes.end())
|
||||
break;
|
||||
// now extract incident range
|
||||
for (int i = 0; i < 2 * range + 1; i++){
|
||||
incidentTargets.first = it->first;
|
||||
incidentTargets.second.push_back(it->second);
|
||||
it++;
|
||||
if (it == _targetTimes.end())
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return incidentTargets;
|
||||
@@ -167,30 +154,41 @@ double ImageSequencer2::getNextCaptureTime(){
|
||||
|
||||
return nextCaptureTime;
|
||||
}
|
||||
const Image* ImageSequencer2::getLatestImageForInstrument(const std::string _instrumentID){
|
||||
|
||||
std::vector<std::pair<std::string, bool>> ImageSequencer2::getActiveInstruments(){
|
||||
for (int i = 0; i < _instrumentOnOff.size(); i++){
|
||||
_instrumentOnOff[i].second = false;
|
||||
}
|
||||
return _latestImage;
|
||||
}
|
||||
|
||||
std::map<std::string, bool> ImageSequencer2::getActiveInstruments(){
|
||||
// first set all instruments to off
|
||||
for (auto i : _switchingMap)
|
||||
_switchingMap[i.first] = false;
|
||||
// go over the filetranslation map
|
||||
for (auto key : _fileTranslation){
|
||||
// for each spice-instrument
|
||||
for (auto instrumentID : key.second->getTranslation()){
|
||||
// check if the spice-instrument is active
|
||||
if (instumentActive(instrumentID)){
|
||||
for (int i = 0; i < _instrumentOnOff.size(); i++){
|
||||
if (instrumentID == _instrumentOnOff[i].first){
|
||||
_instrumentOnOff[i].second = true;
|
||||
// go over switching map
|
||||
for (auto instrument : _switchingMap){
|
||||
// if instrument is present in switching map
|
||||
if (instrumentID == instrument.first){
|
||||
// set as active
|
||||
_switchingMap[instrumentID] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return _instrumentOnOff;
|
||||
// return entire map, seen in GUI.
|
||||
return _switchingMap;
|
||||
}
|
||||
bool ImageSequencer2::instumentActive(std::string instrumentID){
|
||||
bool ImageSequencer2::instumentActive(std::string instrumentID){
|
||||
for (auto i : _instrumentTimes){
|
||||
//check if this instrument is in range
|
||||
if (i.second.inRange(_currentTime)){
|
||||
//if so, then get the corresponding spiceIDs
|
||||
std::vector < std::string> spiceIDs = _fileTranslation[i.first]->getTranslation();
|
||||
if (i.second.inRange(_currentTime)){
|
||||
//if so, then get the corresponding spiceID
|
||||
std::vector<std::string> spiceIDs = _fileTranslation[i.first]->getTranslation();
|
||||
//check which specific subinstrument is firing
|
||||
for (auto s : spiceIDs){
|
||||
if (s == instrumentID){
|
||||
@@ -201,65 +199,116 @@ bool ImageSequencer2::instumentActive(std::string instrumentID){
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool ImageSequencer2::getImagePaths(std::vector<std::pair<double, std::string>>& captures, std::string projectee, std::string instrumentID){
|
||||
bool ImageSequencer2::getImagePaths(std::vector<Image>& captures,
|
||||
std::string projectee,
|
||||
std::string instrumentID){
|
||||
|
||||
if (!instumentActive(instrumentID) && !Time::ref().timeJumped()) return false;
|
||||
return (instrumentID == "NH_LORRI") ? getImagePaths(captures, projectee) : false;
|
||||
// dev. note: this is only due to LORRI being the only instrument implemented so far.
|
||||
return getImagePaths(captures, projectee);
|
||||
}
|
||||
|
||||
bool ImageSequencer2::getImagePaths(std::vector<std::pair<double, std::string>>& captures,
|
||||
bool ImageSequencer2::getImagePaths(std::vector<Image>& captures,
|
||||
std::string projectee){
|
||||
|
||||
// check if this instance is either in range or
|
||||
// a valid candidate to recieve data
|
||||
|
||||
//if (!Time::ref().timeJumped() && projectee == getCurrentTarget().second)
|
||||
if (_subsetMap[projectee]._range.inRange(_currentTime) ||
|
||||
_subsetMap[projectee]._range.inRange(_previousTime)){
|
||||
auto compareTime = [](const Image &a,
|
||||
const Image &b)->bool{
|
||||
const Image &b)->bool{
|
||||
return a.startTime < b.startTime;
|
||||
};
|
||||
|
||||
auto begin = _subsetMap[projectee]._subset.begin();
|
||||
auto end = _subsetMap[projectee]._subset.end();
|
||||
|
||||
std::vector<std::pair<double, std::string>> captureTimes;
|
||||
Image findPrevious;
|
||||
|
||||
// for readability we store the iterators
|
||||
auto begin = _subsetMap[projectee]._subset.begin();
|
||||
auto end = _subsetMap[projectee]._subset.end();
|
||||
|
||||
// create temporary storage
|
||||
std::vector<Image> captureTimes;
|
||||
// what to look for
|
||||
Image findPrevious, findCurrent;
|
||||
findPrevious.startTime = _previousTime;
|
||||
Image findCurrent;
|
||||
findCurrent.startTime = _currentTime;
|
||||
findCurrent.startTime = _currentTime;
|
||||
|
||||
// find the two iterators that correspond to the latest time jump
|
||||
auto curr = std::lower_bound(begin, end, findCurrent, compareTime);
|
||||
auto prev = std::lower_bound(begin, end, findPrevious, compareTime);
|
||||
|
||||
if (curr != begin && curr != end && prev != begin && prev != end && prev < curr){
|
||||
std::transform(prev, curr, std::back_inserter(captureTimes),
|
||||
[](const Image& i) {
|
||||
return std::make_pair(i.startTime, i.path);
|
||||
});
|
||||
std::reverse(captureTimes.begin(), captureTimes.end());
|
||||
captures = captureTimes;
|
||||
return true;
|
||||
if (curr->startTime >= prev->startTime){
|
||||
std::transform(prev, curr, std::back_inserter(captureTimes),
|
||||
[](const Image& i) {
|
||||
return i;
|
||||
});
|
||||
std::reverse(captureTimes.begin(), captureTimes.end());
|
||||
captures = captureTimes;
|
||||
if (!captures.empty())
|
||||
_latestImage = &captures.back();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void ImageSequencer2::sortData(){
|
||||
auto targetComparer = [](const std::pair<double, std::string> &a,
|
||||
const std::pair<double, std::string> &b)->bool{
|
||||
return a.first < b.first;
|
||||
};
|
||||
auto imageComparer = [](const Image &a, const Image &b)->bool{
|
||||
return a.startTime < b.startTime;
|
||||
};
|
||||
|
||||
std::sort(_targetTimes.begin(), _targetTimes.end(), targetComparer);
|
||||
std::stable_sort(_captureProgression.begin(), _captureProgression.end());
|
||||
|
||||
for (auto sub : _subsetMap){
|
||||
std::sort(_subsetMap[sub.first]._subset.begin(),
|
||||
_subsetMap[sub.first]._subset.end(), imageComparer);
|
||||
}
|
||||
}
|
||||
|
||||
void ImageSequencer2::runSequenceParser(SequenceParser* parser){
|
||||
parser->create();
|
||||
_fileTranslation = parser->getTranslation(); // should perhaps be named 'instrumentTranslation'
|
||||
_subsetMap = parser->getSubsetMap();
|
||||
_instrumentTimes = parser->getIstrumentTimes();
|
||||
_targetTimes = parser->getTargetTimes();
|
||||
_captureProgression = parser->getCaptureProgression();
|
||||
// get new data
|
||||
std::map<std::string, Decoder*> in1 = parser->getTranslation();
|
||||
std::map<std::string, ImageSubset> in2 = parser->getSubsetMap();
|
||||
std::vector<std::pair<std::string, TimeRange>> in3 = parser->getIstrumentTimes();
|
||||
std::vector<std::pair<double, std::string>> in4 = parser->getTargetTimes();
|
||||
std::vector<double> in5 = parser->getCaptureProgression();
|
||||
|
||||
// check for sanity
|
||||
assert(in1.size() > 0, "Sequencer failed to load Translation" );
|
||||
assert(in2.size() > 0, "Sequencer failed to load Image data" );
|
||||
assert(in3.size() > 0, "Sequencer failed to load Instrument Switching schedule");
|
||||
assert(in4.size() > 0, "Sequencer failed to load Target Switching schedule" );
|
||||
assert(in5.size() > 0, "Sequencer failed to load Capture progression" );
|
||||
|
||||
//copy payload from _fileTranslation
|
||||
|
||||
// append data
|
||||
_fileTranslation.insert ( in1.begin(), in1.end());
|
||||
_subsetMap.insert ( in2.begin(), in2.end());
|
||||
_instrumentTimes.insert ( _instrumentTimes.end(), in3.begin(), in3.end());
|
||||
_targetTimes.insert ( _targetTimes.end(), in4.begin(), in4.end());
|
||||
_captureProgression.insert(_captureProgression.end(), in5.begin(), in5.end());
|
||||
|
||||
// sorting of data _not_ optional
|
||||
sortData();
|
||||
|
||||
// extract payload from _fileTranslation
|
||||
for (auto t : _fileTranslation){
|
||||
std::vector<std::string> spiceIDs = t.second->getTranslation();
|
||||
for (auto id : spiceIDs){
|
||||
_instrumentOnOff.push_back(std::make_pair(id, false));
|
||||
if (t.second->getDecoderType() == "CAMERA" ||
|
||||
t.second->getDecoderType() == "SCANNER" ){
|
||||
std::vector<std::string> spiceIDs = t.second->getTranslation();
|
||||
for (auto id : spiceIDs){
|
||||
_switchingMap[id] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
_instrumentOnOff.erase(std::unique(_instrumentOnOff.begin(),
|
||||
_instrumentOnOff.end()),
|
||||
_instrumentOnOff.end());
|
||||
_hasData = true;
|
||||
|
||||
}
|
||||
} // namespace openspace
|
||||
|
||||
@@ -28,6 +28,7 @@ namespace {
|
||||
const std::string _loggerCat = "InstrumentDecoder";
|
||||
const std::string keyDetector = "DetectorType";
|
||||
const std::string keySpice = "Spice";
|
||||
const std::string keyStopCommand = "StopCommand";
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
@@ -38,6 +39,12 @@ InstrumentDecoder::InstrumentDecoder(const ghoul::Dictionary& dictionary)
|
||||
ghoul_assert(success, "Instrument has not provided detector type");
|
||||
for_each(_type.begin(), _type.end(), [](char& in){ in = ::toupper(in); });
|
||||
|
||||
if (!dictionary.hasKeyAndValue<std::string>(keyStopCommand) && _type == "SCANNER"){
|
||||
LWARNING("Scanner must provide stop command, please check mod file.");
|
||||
}else{
|
||||
dictionary.getValue(keyStopCommand, _stopCommand);
|
||||
}
|
||||
|
||||
std::vector<std::string> spice;
|
||||
ghoul::Dictionary spiceDictionary;
|
||||
success = dictionary.getValue(keySpice, spiceDictionary);
|
||||
@@ -52,6 +59,10 @@ InstrumentDecoder::InstrumentDecoder(const ghoul::Dictionary& dictionary)
|
||||
}
|
||||
}
|
||||
|
||||
std::string InstrumentDecoder::getStopCommand(){
|
||||
return _stopCommand;
|
||||
}
|
||||
|
||||
std::string InstrumentDecoder::getDecoderType(){
|
||||
return _type;
|
||||
}
|
||||
|
||||
+149
-36
@@ -45,9 +45,7 @@ namespace openspace {
|
||||
LabelParser::LabelParser(const std::string& fileName,
|
||||
ghoul::Dictionary translationDictionary)
|
||||
{
|
||||
_fileName = fileName;
|
||||
//_fileTranslation = fileTranslation;
|
||||
|
||||
_fileName = fileName;
|
||||
//get the different instrument types
|
||||
const std::vector<std::string>& decoders = translationDictionary.keys();
|
||||
//for each decoder (assuming might have more if hong makes changes)
|
||||
@@ -76,10 +74,10 @@ LabelParser::LabelParser(const std::string& fileName,
|
||||
typeDictionary.getValue(keySpecs, specsOfInterestDictionary);
|
||||
|
||||
_specsOfInterest.resize(specsOfInterestDictionary.size());
|
||||
for (int i = 0; i < _specsOfInterest.size(); ++i) {
|
||||
for (int n = 0; n < _specsOfInterest.size(); ++n) {
|
||||
std::string readMe;
|
||||
specsOfInterestDictionary.getValue(std::to_string(i + 1), readMe);
|
||||
_specsOfInterest[i] = readMe;
|
||||
specsOfInterestDictionary.getValue(std::to_string(n + 1), readMe);
|
||||
_specsOfInterest[n] = readMe;
|
||||
}
|
||||
ghoul::Dictionary convertDictionary;
|
||||
typeDictionary.getValue(keyConvert, convertDictionary);
|
||||
@@ -95,70 +93,185 @@ LabelParser::LabelParser(const std::string& fileName,
|
||||
};
|
||||
}
|
||||
}
|
||||
for (auto t : _fileTranslation){
|
||||
std::cout << t.first << std::endl;
|
||||
for (auto b : t.second->getTranslation()){
|
||||
std::cout << " " << b << std::endl;
|
||||
}
|
||||
|
||||
std::string LabelParser::decode(std::string line){
|
||||
for (auto key : _fileTranslation){
|
||||
std::size_t value = line.find(key.first);
|
||||
if (value != std::string::npos){
|
||||
std::string toTranslate = line.substr(value);
|
||||
return _fileTranslation[toTranslate]->getTranslation()[0]; //lbls always 1:1 -> single value return.
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string LabelParser::encode(std::string line) {
|
||||
for (auto key : _fileTranslation) {
|
||||
std::size_t value = line.find(key.first);
|
||||
if (value != std::string::npos) {
|
||||
//std::cout << line.substr(value) << std::endl;
|
||||
return line.substr(value);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
void LabelParser::create(){
|
||||
|
||||
std::vector<Image> tmp;
|
||||
|
||||
auto imageComparer = [](const Image &a, const Image &b)->bool{
|
||||
return a.startTime < b.startTime;
|
||||
};
|
||||
auto targetComparer = [](const std::pair<double, std::string> &a,
|
||||
const std::pair<double, std::string> &b)->bool{
|
||||
return a.first < b.first;
|
||||
};
|
||||
std::string previousTarget;
|
||||
std::string lblName = "";
|
||||
|
||||
ghoul::filesystem::Directory sequenceDir(_fileName, true);
|
||||
std::vector<std::string> sequencePaths = sequenceDir.read(true, false); // check inputs
|
||||
for (auto path : sequencePaths){
|
||||
//std::cout << path << std::endl;
|
||||
if (size_t position = path.find_last_of(".") + 1){
|
||||
if (position != std::string::npos){
|
||||
ghoul::filesystem::File currentFile(path);
|
||||
std::string extension = currentFile.fileExtension();
|
||||
|
||||
if (extension == "lbl"){ // discovered header file
|
||||
if (extension == "lbl" || extension == "LBL"){ // discovered header file
|
||||
std::ifstream file(currentFile.path());
|
||||
|
||||
if (!file.good()) LERROR("Failed to open label file '" << currentFile.path() << "'");
|
||||
|
||||
int count = 0;
|
||||
|
||||
// open up label files
|
||||
std::string line = "";
|
||||
double timestamp = 0.0;
|
||||
bool found = false;
|
||||
std::string previousSequence;
|
||||
TimeRange instrumentRange;
|
||||
|
||||
do {
|
||||
std::getline(file, line);
|
||||
for (auto spec : _specsOfInterest){
|
||||
auto pos = line.find(spec);
|
||||
if (pos != std::string::npos){
|
||||
if (line.substr(0, line.find_first_of(" ")) == "TARGET_NAME"){
|
||||
/* std::string target = line.substr(line.find("=") + 2, line.find(" "));
|
||||
target.erase(std::remove(target.begin(), target.end(), '"'), target.end());
|
||||
for (auto t : _fileTranslation[target]->getTranslation()){
|
||||
std::cout << t << std::endl;
|
||||
}*/
|
||||
|
||||
}
|
||||
std::string read = line.substr(0, line.find_first_of(" "));
|
||||
|
||||
line.erase(std::remove(line.begin(), line.end(), '"'), line.end());
|
||||
line.erase(std::remove(line.begin(), line.end(), ' '), line.end());
|
||||
|
||||
/* Add more */
|
||||
if (read == "TARGET_NAME"){
|
||||
_target = decode(line);
|
||||
count++;
|
||||
}
|
||||
if (read == "INSTRUMENT_HOST_NAME"){
|
||||
_instrumentHostID = decode(line);
|
||||
count++;
|
||||
}
|
||||
if (read == "INSTRUMENT_ID"){
|
||||
_instrumentID = decode(line);
|
||||
lblName = encode(line);
|
||||
count++;
|
||||
}
|
||||
if (read == "DETECTOR_TYPE"){
|
||||
_detectorType = decode(line);
|
||||
count++;
|
||||
}
|
||||
if (read == "START_TIME"){
|
||||
std::string start = line.substr(line.find("=") + 2);
|
||||
start.erase(std::remove(start.begin(), start.end(), ' '), start.end());
|
||||
openspace::SpiceManager::ref().getETfromDate(start, _startTime);
|
||||
count++;
|
||||
|
||||
getline(file, line);
|
||||
read = line.substr(0, line.find_first_of(" "));
|
||||
if (read == "STOP_TIME"){
|
||||
std::string stop = line.substr(line.find("=") + 2);
|
||||
stop.erase(std::remove(stop.begin(), stop.end(), ' '), stop.end());
|
||||
openspace::SpiceManager::ref().getETfromDate(stop, _stopTime);
|
||||
count++;
|
||||
}
|
||||
/*if (timestamp != 0.0){
|
||||
found = true;
|
||||
else{
|
||||
LERROR("Label file " + _fileName + " deviates from generic standard!");
|
||||
LINFO("Please make sure input data adheres to format https://pds.jpl.nasa.gov/documents/qs/labels.html");
|
||||
}
|
||||
}
|
||||
if (count == _specsOfInterest.size()){
|
||||
count = 0;
|
||||
std::string ext = "jpg";
|
||||
path.replace(path.begin() + position, path.end(), ext);
|
||||
bool fileExists = FileSys.fileExists(path);
|
||||
if (fileExists) {
|
||||
// createImage(tmp, timestamp, "NH_LORRI", "", path); /// fix active instrument!
|
||||
// std::sort(tmp.begin(), tmp.end(), imageComparer);
|
||||
if (!fileExists) {
|
||||
ext = "JPG";
|
||||
path.replace(path.begin() + position, path.end(), ext);
|
||||
fileExists = FileSys.fileExists(path);
|
||||
}
|
||||
}*/
|
||||
if (fileExists) {
|
||||
Image image;
|
||||
std::vector<std::string> spiceInstrument;
|
||||
spiceInstrument.push_back(_instrumentID);
|
||||
createImage(image, _startTime, _startTime, spiceInstrument, _target, path);
|
||||
|
||||
_subsetMap[image.target]._subset.push_back(image);
|
||||
_subsetMap[image.target]._range.setRange(_startTime);
|
||||
|
||||
_captureProgression.push_back(_startTime);
|
||||
std::stable_sort(_captureProgression.begin(), _captureProgression.end());
|
||||
}
|
||||
|
||||
}
|
||||
} while (!file.eof() && found == false);
|
||||
} while (!file.eof());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
int pause;
|
||||
std::cin >> pause;
|
||||
|
||||
std::vector<Image> tmp;
|
||||
for (auto key : _subsetMap){
|
||||
for (auto image : key.second._subset){
|
||||
tmp.push_back(image);
|
||||
}
|
||||
}
|
||||
std::sort(tmp.begin(), tmp.end(), imageComparer);
|
||||
|
||||
for (auto image : tmp){
|
||||
if (previousTarget != image.target){
|
||||
previousTarget = image.target;
|
||||
std::pair<double, std::string> v_target = std::make_pair(image.startTime, image.target);
|
||||
_targetTimes.push_back(v_target);
|
||||
std::sort(_targetTimes.begin(), _targetTimes.end(), targetComparer);
|
||||
}
|
||||
}
|
||||
|
||||
std::ofstream myfile;
|
||||
myfile.open("LabelFileOutput.txt");
|
||||
|
||||
//print all
|
||||
for (auto target : _subsetMap){
|
||||
_instrumentTimes.push_back(std::make_pair(lblName, _subsetMap[target.first]._range));
|
||||
std::string min, max;
|
||||
SpiceManager::ref().getDateFromET(target.second._range._min, min);
|
||||
SpiceManager::ref().getDateFromET(target.second._range._max, max);
|
||||
|
||||
myfile << std::endl;
|
||||
for (auto image : target.second._subset){
|
||||
std::string time_beg;
|
||||
std::string time_end;
|
||||
SpiceManager::ref().getDateFromET(image.startTime, time_beg);
|
||||
SpiceManager::ref().getDateFromET(image.stopTime, time_end);
|
||||
|
||||
myfile << std::fixed
|
||||
<< " " << time_beg
|
||||
<< "-->" << time_end
|
||||
<< " [ " << image.startTime
|
||||
<< " ] " << image.target << std::setw(10);
|
||||
for (auto instrument : image.activeInstruments){
|
||||
myfile << " " << instrument;
|
||||
}
|
||||
myfile << std::endl;
|
||||
}
|
||||
}
|
||||
myfile.close();
|
||||
|
||||
|
||||
}
|
||||
|
||||
void LabelParser::createImage(Image& image, double startTime, double stopTime, std::vector<std::string> instr, std::string targ, std::string pot) {
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
// open space includes
|
||||
#include <openspace/util/powerscaledsphere.h>
|
||||
|
||||
#include <openspace/util/spicemanager.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
|
||||
#define _USE_MATH_DEFINES
|
||||
@@ -125,6 +125,103 @@ PowerScaledSphere::PowerScaledSphere(const PowerScaledScalar& radius, int segmen
|
||||
}
|
||||
}
|
||||
|
||||
// Alternative Constructor for using accurate triaxial ellipsoid
|
||||
PowerScaledSphere::PowerScaledSphere(properties::Vec4Property &radius, int segments, std::string planetName)
|
||||
: _vaoID(0)
|
||||
, _vBufferID(0)
|
||||
, _iBufferID(0)
|
||||
, _isize(6 * segments * segments)
|
||||
, _vsize((segments + 1) * (segments + 1))
|
||||
, _varray(new Vertex[_vsize])
|
||||
, _iarray(new int[_isize])
|
||||
{
|
||||
static_assert(sizeof(Vertex) == 64,
|
||||
"The size of the Vertex needs to be 64 for performance");
|
||||
|
||||
float a, b, c, powerscale;
|
||||
bool accutareRadius = SpiceManager::ref().getPlanetEllipsoid(planetName, a, b, c);
|
||||
|
||||
if (accutareRadius) {
|
||||
PowerScaledCoordinate powerScaledRadii = psc::CreatePowerScaledCoordinate(a, b, c);
|
||||
powerScaledRadii[3] += 3; // SPICE returns radii in km
|
||||
|
||||
std::swap(powerScaledRadii[1], powerScaledRadii[2]); // c is equivalent to y in our coordinate system
|
||||
radius.set(powerScaledRadii.vec4());
|
||||
a = powerScaledRadii[0];
|
||||
b = powerScaledRadii[1];
|
||||
c = powerScaledRadii[2];
|
||||
powerscale = powerScaledRadii[3];
|
||||
}
|
||||
else {
|
||||
boost::any r = radius.get();
|
||||
glm::vec4 modRadius = boost::any_cast<glm::vec4>(r);
|
||||
a = modRadius[0];
|
||||
b = modRadius[1];
|
||||
c = modRadius[2];
|
||||
powerscale = modRadius[3];
|
||||
}
|
||||
|
||||
int nr = 0;
|
||||
const float fsegments = static_cast<float>(segments);
|
||||
|
||||
for (int i = 0; i <= segments; i++) {
|
||||
// define an extra vertex around the y-axis due to texture mapping
|
||||
for (int j = 0; j <= segments; j++) {
|
||||
const float fi = static_cast<float>(i);
|
||||
const float fj = static_cast<float>(j);
|
||||
// inclination angle (north to south)
|
||||
const float theta = fi * float(M_PI) / fsegments; // 0 -> PI
|
||||
// azimuth angle (east to west)
|
||||
const float phi = fj * float(M_PI) * 2.0f / fsegments; // 0 -> 2*PI
|
||||
|
||||
const float x = a * sin(phi) * sin(theta); //
|
||||
const float y = b * cos(theta); // up
|
||||
const float z = c * cos(phi) * sin(theta); //
|
||||
|
||||
_varray[nr].location[0] = x;
|
||||
_varray[nr].location[1] = y;
|
||||
_varray[nr].location[2] = z;
|
||||
_varray[nr].location[3] = powerscale;
|
||||
|
||||
glm::vec3 normal = glm::vec3(x, y, z);
|
||||
if (!(x == 0.f && y == 0.f && z == 0.f))
|
||||
normal = glm::normalize(normal);
|
||||
|
||||
_varray[nr].normal[0] = normal[0];
|
||||
_varray[nr].normal[1] = normal[1];
|
||||
_varray[nr].normal[2] = normal[2];
|
||||
|
||||
const float t1 = fj / fsegments;
|
||||
const float t2 = fi / fsegments;
|
||||
|
||||
_varray[nr].tex[0] = t1;
|
||||
_varray[nr].tex[1] = t2;
|
||||
++nr;
|
||||
}
|
||||
}
|
||||
|
||||
nr = 0;
|
||||
// define indices for all triangles
|
||||
for (int i = 1; i <= segments; ++i) {
|
||||
for (int j = 0; j < segments; ++j) {
|
||||
const int t = segments + 1;
|
||||
_iarray[nr] = t * (i - 1) + j + 0; //1
|
||||
++nr;
|
||||
_iarray[nr] = t * (i + 0) + j + 0; //2
|
||||
++nr;
|
||||
_iarray[nr] = t * (i + 0) + j + 1; //3
|
||||
++nr;
|
||||
|
||||
_iarray[nr] = t * (i - 1) + j + 0; //4
|
||||
++nr;
|
||||
_iarray[nr] = t * (i + 0) + j + 1; //5
|
||||
++nr;
|
||||
_iarray[nr] = t * (i - 1) + j + 1; //6
|
||||
++nr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PowerScaledSphere::PowerScaledSphere(const PowerScaledSphere& cpy)
|
||||
: _vaoID(cpy._vaoID)
|
||||
, _vBufferID(cpy._vBufferID)
|
||||
|
||||
@@ -46,4 +46,8 @@ std::vector<std::string> ScannerDecoder::getSpiceIDs(){
|
||||
return _spiceIDs;
|
||||
}
|
||||
|
||||
void ScannerDecoder::setStopCommand(std::string stopCommand){
|
||||
_abort = stopCommand;
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
+399
-159
@@ -31,6 +31,8 @@
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#define MAXOBJ 1000
|
||||
#define WINSIZ 10000
|
||||
|
||||
namespace {
|
||||
const std::string _loggerCat = "SpiceManager";
|
||||
@@ -75,6 +77,7 @@ SpiceManager::KernelIdentifier SpiceManager::loadKernel(const std::string& fileP
|
||||
}
|
||||
|
||||
std::string&& path = absPath(filePath);
|
||||
|
||||
if (!FileSys.fileExists(path)) {
|
||||
LERROR("Kernel file '" << path << "' does not exist");
|
||||
return KernelFailed;
|
||||
@@ -112,7 +115,16 @@ SpiceManager::KernelIdentifier SpiceManager::loadKernel(const std::string& fileP
|
||||
LINFO("Loading SPICE kernel '" << path << "'");
|
||||
// Load the kernel
|
||||
furnsh_c(path.c_str());
|
||||
|
||||
|
||||
std::string fileExtension = path.substr(path.size() - 3);
|
||||
if (fileExtension == ".bc" || fileExtension == ".BC") { // binary ck kernel
|
||||
findCkCoverage(path);
|
||||
}
|
||||
else if (fileExtension == "bsp" || fileExtension == "BSP") { // binary spk kernel
|
||||
findSpkCoverage(path);
|
||||
}
|
||||
|
||||
|
||||
// Reset the current directory to the previous one
|
||||
FileSys.setCurrentDirectory(currentDirectory);
|
||||
int failed = failed_c();
|
||||
@@ -135,6 +147,111 @@ SpiceManager::KernelIdentifier SpiceManager::loadKernel(const std::string& fileP
|
||||
}
|
||||
}
|
||||
|
||||
bool SpiceManager::findCkCoverage(std::string& path) {
|
||||
SpiceInt frame, numberOfIntervals;
|
||||
SpiceDouble b, e;
|
||||
std::pair <double, double> tempInterval;
|
||||
SPICEINT_CELL(ids, MAXOBJ);
|
||||
SPICEDOUBLE_CELL(cover, WINSIZ);
|
||||
|
||||
ckobj_c(path.c_str(), &ids);
|
||||
|
||||
for (SpiceInt i = 0; i < card_c(&ids); ++i) {
|
||||
frame = SPICE_CELL_ELEM_I(&ids, i);
|
||||
|
||||
scard_c(0, &cover);
|
||||
ckcov_c(path.c_str(), frame, SPICEFALSE, "SEGMENT", 0.0, "TDB", &cover);
|
||||
|
||||
//Get the number of intervals in the coverage window.
|
||||
numberOfIntervals = wncard_c(&cover);
|
||||
|
||||
for (SpiceInt j = 0; j < numberOfIntervals; ++j) {
|
||||
//Get the endpoints of the jth interval.
|
||||
wnfetd_c(&cover, j, &b, &e);
|
||||
tempInterval = std::make_pair(b, e);
|
||||
|
||||
_ckCoverageTimes[frame].insert(e);
|
||||
_ckCoverageTimes[frame].insert(b);
|
||||
_ckIntervals[frame].push_back(tempInterval);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SpiceManager::findSpkCoverage(std::string& path) {
|
||||
SpiceInt obj, numberOfIntervals;
|
||||
SpiceDouble b, e;
|
||||
std::pair <double, double> tempInterval;
|
||||
SPICEINT_CELL(ids, MAXOBJ);
|
||||
SPICEDOUBLE_CELL(cover, WINSIZ);
|
||||
|
||||
spkobj_c(path.c_str(), &ids);
|
||||
|
||||
for (SpiceInt i = 0; i < card_c(&ids); ++i) {
|
||||
obj = SPICE_CELL_ELEM_I(&ids, i);
|
||||
|
||||
scard_c(0, &cover);
|
||||
spkcov_c(path.c_str(), obj, &cover);
|
||||
//Get the number of intervals in the coverage window.
|
||||
numberOfIntervals = wncard_c(&cover);
|
||||
|
||||
for (SpiceInt j = 0; j < numberOfIntervals; ++j) {
|
||||
//Get the endpoints of the jth interval.
|
||||
wnfetd_c(&cover, j, &b, &e);
|
||||
tempInterval = std::make_pair(b, e);
|
||||
//insert all into coverage time set, the windows could be merged @AA
|
||||
_spkCoverageTimes[obj].insert(e);
|
||||
_spkCoverageTimes[obj].insert(b);
|
||||
_spkIntervals[obj].push_back(tempInterval);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SpiceManager::hasSpkCoverage(std::string target, double& et) const
|
||||
{
|
||||
int id;
|
||||
bool idSuccess = getNaifId(target, id);
|
||||
bool hasCoverage = false;
|
||||
|
||||
std::vector< std::pair<double, double> > intervalVector;
|
||||
if (_spkIntervals.find(id) == _spkIntervals.end())
|
||||
return false;
|
||||
else
|
||||
intervalVector = _spkIntervals.find(id)->second;
|
||||
|
||||
for (auto vecElement : intervalVector) {
|
||||
if (vecElement.first < et && vecElement.second > et) {
|
||||
hasCoverage = true;
|
||||
return idSuccess && hasCoverage;
|
||||
}
|
||||
}
|
||||
|
||||
return idSuccess && hasCoverage;
|
||||
}
|
||||
|
||||
bool SpiceManager::hasCkCoverage(std::string frame, double& et) const
|
||||
{
|
||||
int id;
|
||||
bool idSuccess = getFrameId(frame, id);
|
||||
bool hasCoverage = false;
|
||||
|
||||
std::vector< std::pair<double, double> > intervalVector;
|
||||
if (_ckIntervals.find(id) == _ckIntervals.end())
|
||||
return false;
|
||||
else
|
||||
intervalVector = _ckIntervals.find(id)->second;
|
||||
|
||||
for (auto vecElement : intervalVector) {
|
||||
if (vecElement.first < et && vecElement.second > et) {
|
||||
hasCoverage = true;
|
||||
return idSuccess && hasCoverage;
|
||||
}
|
||||
}
|
||||
|
||||
return idSuccess && hasCoverage;
|
||||
}
|
||||
|
||||
void SpiceManager::unloadKernel(KernelIdentifier kernelId) {
|
||||
auto it = std::find_if(_loadedKernels.begin(), _loadedKernels.end(),
|
||||
[&kernelId](const KernelInformation& info) { return info.id == kernelId ; });
|
||||
@@ -209,6 +326,20 @@ bool SpiceManager::getNaifId(const std::string& body, int& id) const {
|
||||
}
|
||||
}
|
||||
|
||||
bool SpiceManager::getFrameId(const std::string& frame, int& id) const {
|
||||
if (frame.empty()) {
|
||||
LERROR("No frame was provided");
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
SpiceInt sid = id;
|
||||
namfrm_c(frame.c_str(), &sid);
|
||||
id = sid;
|
||||
bool hasError = SpiceManager::checkForError("Error getting id for frame '" + frame + "'");
|
||||
return !hasError;
|
||||
}
|
||||
}
|
||||
|
||||
bool getValueInternal(const std::string& body, const std::string& value, int S,
|
||||
double* v)
|
||||
{
|
||||
@@ -294,7 +425,7 @@ bool SpiceManager::getETfromDate(const std::string& timeString,
|
||||
}
|
||||
|
||||
bool SpiceManager::getDateFromET(double ephemerisTime, std::string& date,
|
||||
const std::string& format)
|
||||
const std::string& format) const
|
||||
{
|
||||
static const int BufferSize = 256;
|
||||
|
||||
@@ -322,15 +453,32 @@ bool SpiceManager::getTargetPosition(const std::string& target,
|
||||
glm::dvec3& position,
|
||||
double& lightTime) const
|
||||
{
|
||||
spkpos_c(target.c_str(), ephemerisTime, referenceFrame.c_str(),
|
||||
aberrationCorrection.c_str(), observer.c_str(), glm::value_ptr(position),
|
||||
&lightTime);
|
||||
psc pscPosition = PowerScaledCoordinate::CreatePowerScaledCoordinate(position[0], position[1], position[2]);
|
||||
|
||||
bool hasError = checkForError("Error retrieving position of target '" + target + "'" +
|
||||
" viewed from observer '" + observer + "' in reference"+
|
||||
" frame '" + referenceFrame + "' at time '" +
|
||||
std::to_string(ephemerisTime) + "'");
|
||||
return !hasError;
|
||||
bool targetHasCoverage = hasSpkCoverage(target, ephemerisTime);
|
||||
bool observerHasCoverage = hasSpkCoverage(observer, ephemerisTime);
|
||||
if (!targetHasCoverage && !observerHasCoverage){
|
||||
return false;
|
||||
}
|
||||
else if (targetHasCoverage && observerHasCoverage){
|
||||
spkpos_c(target.c_str(), ephemerisTime, referenceFrame.c_str(),
|
||||
aberrationCorrection.c_str(), observer.c_str(), glm::value_ptr(position),
|
||||
&lightTime);
|
||||
}
|
||||
else if (targetHasCoverage) {// observer has no coverage
|
||||
getEstimatedPosition(ephemerisTime, observer, target, pscPosition);
|
||||
pscPosition = pscPosition*(-1.f); // inverse estimated position because the observer is "target" argument in funciton
|
||||
position = pscPosition.vec3();
|
||||
}
|
||||
else { // target has no coverage
|
||||
getEstimatedPosition(ephemerisTime, target, observer, pscPosition);
|
||||
position = pscPosition.vec3();
|
||||
}
|
||||
|
||||
if (position[0] == 0.0 || position[1] == 0.0 || position[2] == 0.0)
|
||||
return false;
|
||||
|
||||
return targetHasCoverage && observerHasCoverage;
|
||||
}
|
||||
|
||||
bool SpiceManager::getTargetPosition(const std::string& target,
|
||||
@@ -343,22 +491,103 @@ bool SpiceManager::getTargetPosition(const std::string& target,
|
||||
{
|
||||
double pos[3] = { 0.0, 0.0, 0.0};
|
||||
|
||||
spkpos_c(target.c_str(), ephemerisTime, referenceFrame.c_str(),
|
||||
aberrationCorrection.c_str(), observer.c_str(), pos, &lightTime);
|
||||
|
||||
if (pos[0] == 0.0 || pos[1] == 0.0|| pos[2] == 0.0)
|
||||
bool targetHasCoverage = hasSpkCoverage(target, ephemerisTime);
|
||||
bool observerHasCoverage = hasSpkCoverage(observer, ephemerisTime);
|
||||
if (!targetHasCoverage && !observerHasCoverage){
|
||||
position = PowerScaledCoordinate::CreatePowerScaledCoordinate(pos[0], pos[1], pos[2]);
|
||||
return false;
|
||||
}
|
||||
else if (targetHasCoverage && observerHasCoverage){
|
||||
spkpos_c(target.c_str(), ephemerisTime, referenceFrame.c_str(),
|
||||
aberrationCorrection.c_str(), observer.c_str(), pos, &lightTime);
|
||||
position = PowerScaledCoordinate::CreatePowerScaledCoordinate(pos[0], pos[1], pos[2]);
|
||||
}
|
||||
else if (targetHasCoverage) {// observer has no coverage
|
||||
getEstimatedPosition(ephemerisTime, observer, target, position);
|
||||
position = position*(-1.f); // inverse estimated position because the observer is "target" argument in funciton
|
||||
}
|
||||
else {// target has no coverage
|
||||
getEstimatedPosition(ephemerisTime, target, observer, position);
|
||||
}
|
||||
|
||||
position = PowerScaledCoordinate::CreatePowerScaledCoordinate(pos[0], pos[1], pos[2]);
|
||||
return targetHasCoverage && observerHasCoverage;
|
||||
}
|
||||
|
||||
return true;
|
||||
bool SpiceManager::getEstimatedPosition(const double time, const std::string target,
|
||||
const std::string observer, psc& targetPosition) const
|
||||
{
|
||||
|
||||
int idTarget, idObserver;
|
||||
bool targetFound = getNaifId(target, idTarget);
|
||||
if (idTarget == 0) { //SOLAR SYSTEM BARYCENTER special case, no def. in kernels
|
||||
targetPosition[0] = 0.f;
|
||||
targetPosition[1] = 0.f;
|
||||
targetPosition[2] = 0.f;
|
||||
targetPosition[3] = 0.f;
|
||||
return true;
|
||||
}
|
||||
|
||||
double pos[3] = { 0.0, 0.0, 0.0 };
|
||||
|
||||
bool observerFound = getNaifId(observer, idObserver);
|
||||
if (!targetFound || !observerFound || (idTarget == idObserver)) {
|
||||
return false;
|
||||
}
|
||||
double lt, earlier, later, difference, quote;
|
||||
double pos_earlier[3] = { 0.0, 0.0, 0.0 };
|
||||
double pos_later[3] = { 0.0, 0.0, 0.0 };
|
||||
if (_spkCoverageTimes.find(idTarget) == _spkCoverageTimes.end()){ // no coverage
|
||||
LWARNING("No position for " + target + " at any time, was the correct SPK Kernels loaded?");
|
||||
targetPosition = PowerScaledCoordinate::CreatePowerScaledCoordinate(pos[0], pos[1], pos[2]);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::set<double> coveredTimes = _spkCoverageTimes.find(idTarget)->second;
|
||||
|
||||
std::set<double>::iterator first = coveredTimes.begin();
|
||||
std::set<double>::iterator last = coveredTimes.end();
|
||||
|
||||
if (coveredTimes.lower_bound(time) == first) { // coverage later, fetch first position
|
||||
spkpos_c(target.c_str(), (*first), "GALACTIC",
|
||||
"NONE", observer.c_str(), pos, <);
|
||||
}
|
||||
else if (coveredTimes.upper_bound(time) == last) { // coverage earlier, fetch last position
|
||||
spkpos_c(target.c_str(), *(coveredTimes.rbegin()), "GALACTIC",
|
||||
"NONE", observer.c_str(), pos, <);
|
||||
|
||||
}
|
||||
else { // coverage both earlier and later, interpolate these positions
|
||||
earlier = *std::prev((coveredTimes.lower_bound(time)));
|
||||
later = *(coveredTimes.upper_bound(time));
|
||||
|
||||
spkpos_c(target.c_str(), earlier, "GALACTIC",
|
||||
"NONE", observer.c_str(), pos_earlier, <);
|
||||
spkpos_c(target.c_str(), later, "GALACTIC",
|
||||
"NONE", observer.c_str(), pos_later, <);
|
||||
|
||||
//linear interpolation
|
||||
difference = later - earlier;
|
||||
quote = (time - earlier) / difference;
|
||||
pos[0] = (pos_earlier[0]*(1-quote) + pos_later[0]*quote);
|
||||
pos[1] = (pos_earlier[1]*(1-quote) + pos_later[1]*quote);
|
||||
pos[2] = (pos_earlier[2]*(1-quote) + pos_later[2]*quote);
|
||||
}
|
||||
|
||||
|
||||
targetPosition = PowerScaledCoordinate::CreatePowerScaledCoordinate(pos[0], pos[1], pos[2]);
|
||||
checkForError("Error estimating positin for target: " + target + ", or observer: " + observer);
|
||||
|
||||
return targetFound && observerFound;
|
||||
}
|
||||
|
||||
// do NOT remove this method.
|
||||
bool SpiceManager::frameConversion(glm::dvec3& v, const std::string& from, const std::string& to, double ephemerisTime) const{
|
||||
glm::dmat3 transform;
|
||||
if (from == to)
|
||||
return true;
|
||||
// get rotation matrix from frame A - frame B
|
||||
pxform_c(from.c_str(), to.c_str(), ephemerisTime, (double(*)[3])glm::value_ptr(transform));
|
||||
|
||||
bool hasError = checkForError("Error converting from frame '" + from +
|
||||
"' to frame '" + to + "' at time " + std::to_string(ephemerisTime));
|
||||
if (hasError)
|
||||
@@ -384,7 +613,6 @@ bool SpiceManager::targetWithinFieldOfView(const std::string& instrument,
|
||||
bool& isVisible
|
||||
) const
|
||||
{
|
||||
|
||||
int visible;
|
||||
fovtrg_c(instrument.c_str(),
|
||||
target.c_str(),
|
||||
@@ -413,13 +641,12 @@ bool SpiceManager::targetWithinFieldOfView(const std::string& instrument,
|
||||
|
||||
int visible;
|
||||
|
||||
std::string bodyfixed = "IAU_";
|
||||
bodyfixed += target;
|
||||
std::string frame = frameFromBody(target);
|
||||
|
||||
fovtrg_c(instrument.c_str(),
|
||||
target.c_str(),
|
||||
method.c_str(),
|
||||
bodyfixed.c_str(),
|
||||
frame.c_str(),
|
||||
aberrationCorrection.c_str(),
|
||||
observer.c_str(),
|
||||
&targetEpoch,
|
||||
@@ -460,9 +687,9 @@ bool SpiceManager::getSurfaceIntercept(const std::string& target,
|
||||
// allow client specify non-inertial frame.
|
||||
std::string bodyfixed = "IAU_";
|
||||
convert = (referenceFrame.find(bodyfixed) == std::string::npos);
|
||||
if (convert){
|
||||
bodyfixed += target;
|
||||
}else{
|
||||
if (convert) {
|
||||
bodyfixed = frameFromBody(target);
|
||||
} else {
|
||||
bodyfixed = referenceFrame;
|
||||
}
|
||||
|
||||
@@ -500,6 +727,7 @@ bool SpiceManager::getSurfaceIntercept(const std::string& target,
|
||||
return true;
|
||||
}
|
||||
|
||||
// Not called at the moment @AA
|
||||
bool SpiceManager::getTargetState(const std::string& target,
|
||||
const std::string& observer,
|
||||
const std::string& referenceFrame,
|
||||
@@ -525,6 +753,7 @@ bool SpiceManager::getTargetState(const std::string& target,
|
||||
return !hasError;
|
||||
}
|
||||
|
||||
// Not called at the moment @AA
|
||||
bool SpiceManager::getTargetState(const std::string& target,
|
||||
const std::string& observer,
|
||||
const std::string& referenceFrame,
|
||||
@@ -540,12 +769,25 @@ bool SpiceManager::getTargetState(const std::string& target,
|
||||
spkezr_c(target.c_str(), ephemerisTime, referenceFrame.c_str(),
|
||||
aberrationCorrection.c_str(), observer.c_str(), state, &lightTime);
|
||||
|
||||
position = PowerScaledCoordinate::CreatePowerScaledCoordinate(state[0], state[1], state[2]);
|
||||
velocity = PowerScaledCoordinate::CreatePowerScaledCoordinate(state[3], state[4], state[5]);
|
||||
bool hasError = checkForError("Error retrieving state of target '" + target + "'" +
|
||||
"viewed from observer '" + observer + "' in " +
|
||||
"reference frame '" + referenceFrame + "' at time '" +
|
||||
std::to_string(ephemerisTime) + "'");
|
||||
|
||||
return true;
|
||||
if (!hasError) {
|
||||
position = PowerScaledCoordinate::CreatePowerScaledCoordinate(state[0], state[1], state[2]);
|
||||
velocity = PowerScaledCoordinate::CreatePowerScaledCoordinate(state[3], state[4], state[5]);
|
||||
}
|
||||
else
|
||||
{
|
||||
position = PowerScaledCoordinate::CreatePowerScaledCoordinate(0.0, 0.0, 0.0);
|
||||
velocity = PowerScaledCoordinate::CreatePowerScaledCoordinate(0, 0, 0);
|
||||
}
|
||||
|
||||
return !hasError;
|
||||
}
|
||||
|
||||
// Not called at the moment @AA
|
||||
bool SpiceManager::getStateTransformMatrix(const std::string& fromFrame,
|
||||
const std::string& toFrame,
|
||||
double ephemerisTime,
|
||||
@@ -560,58 +802,105 @@ bool SpiceManager::getStateTransformMatrix(const std::string& fromFrame,
|
||||
return !hasError;
|
||||
}
|
||||
|
||||
// I honestly dont even think we need this, deprecatable relic from previous crunch time.
|
||||
bool SpiceManager::getPositionPrimeMeridian(const std::string& fromFrame,
|
||||
const std::string& body,
|
||||
double ephemerisTime,
|
||||
glm::dmat3& positionMatrix) const{
|
||||
|
||||
int id;
|
||||
getNaifId(body, id);
|
||||
tipbod_c(fromFrame.c_str(), id, ephemerisTime, (double(*)[3])glm::value_ptr(positionMatrix));
|
||||
|
||||
bool hasError = checkForError("Error retrieving position transform matrix from "
|
||||
"frame '" + fromFrame + "' to frame '" + body +
|
||||
"at time '" + std::to_string(ephemerisTime) + "' for prime meridian");
|
||||
positionMatrix = glm::transpose(positionMatrix);
|
||||
|
||||
return !hasError;
|
||||
}
|
||||
|
||||
bool SpiceManager::getPositionTransformMatrix(const std::string& fromFrame,
|
||||
const std::string& toFrame,
|
||||
double ephemerisTime,
|
||||
glm::dmat3& positionMatrix) const{
|
||||
glm::dmat3& positionMatrix) const
|
||||
{
|
||||
bool success = false, estimated = false;
|
||||
pxform_c(fromFrame.c_str(), toFrame.c_str(),
|
||||
ephemerisTime, (double(*)[3])glm::value_ptr(positionMatrix));
|
||||
|
||||
bool hasError = checkForError("Error retrieving position transform matrix from "
|
||||
"frame '" + fromFrame + "' to frame '" + toFrame +
|
||||
"' at time '" + std::to_string(ephemerisTime) + "'");
|
||||
ephemerisTime, (double(*)[3])glm::value_ptr(positionMatrix));
|
||||
|
||||
success = !(failed_c());
|
||||
if (!success) {
|
||||
reset_c();
|
||||
estimated = getEstimatedTransformMatrix(ephemerisTime, fromFrame, toFrame, positionMatrix);
|
||||
}
|
||||
if (_showErrors) {
|
||||
bool hasError = checkForError("Error retrieving position transform matrix from "
|
||||
"frame '" + fromFrame + "' to frame '" + toFrame +
|
||||
"' at time '" + std::to_string(ephemerisTime));
|
||||
}
|
||||
|
||||
positionMatrix = glm::transpose(positionMatrix);
|
||||
|
||||
return !hasError;
|
||||
return estimated || success;
|
||||
}
|
||||
|
||||
|
||||
// Not called at the moment @AA
|
||||
bool SpiceManager::getPositionTransformMatrix(const std::string& fromFrame,
|
||||
const std::string& toFrame,
|
||||
double ephemerisTimeFrom,
|
||||
double ephemerisTimeTo,
|
||||
glm::dmat3& positionMatrix) const{
|
||||
const std::string& toFrame,
|
||||
double ephemerisTimeFrom,
|
||||
double ephemerisTimeTo,
|
||||
glm::dmat3& positionMatrix) const{
|
||||
|
||||
pxfrm2_c(fromFrame.c_str(), toFrame.c_str(), ephemerisTimeFrom, ephemerisTimeTo, (double(*)[3])glm::value_ptr(positionMatrix));
|
||||
|
||||
bool hasError = checkForError("Error retrieving position transform matrix from "
|
||||
"frame '" + fromFrame + "' to frame '" + toFrame +
|
||||
"' from time '" + std::to_string(ephemerisTimeFrom) + " to time '"
|
||||
+ std::to_string(ephemerisTimeTo) + "'");
|
||||
+ std::to_string(ephemerisTimeTo) + "'");
|
||||
positionMatrix = glm::transpose(positionMatrix);
|
||||
|
||||
return !hasError;
|
||||
}
|
||||
|
||||
|
||||
bool SpiceManager::getEstimatedTransformMatrix(const double time, const std::string fromFrame,
|
||||
const std::string toFrame, glm::dmat3& positionMatrix) const
|
||||
{
|
||||
int idFrame;
|
||||
|
||||
bool frameFound = getFrameId(fromFrame, idFrame);
|
||||
if (!frameFound) {
|
||||
return false;
|
||||
}
|
||||
if (_ckCoverageTimes.find(idFrame) == _ckCoverageTimes.end()){ // no coverage
|
||||
return false;
|
||||
}
|
||||
|
||||
double earlier, later, difference, quote;
|
||||
|
||||
std::set<double> coveredTimes = _ckCoverageTimes.find(idFrame)->second;
|
||||
|
||||
std::set<double>::iterator first = coveredTimes.begin();
|
||||
std::set<double>::iterator last = coveredTimes.end();
|
||||
|
||||
if (coveredTimes.lower_bound(time) == first) { // coverage later, fetch first transform
|
||||
pxform_c(fromFrame.c_str(), toFrame.c_str(),
|
||||
*first, (double(*)[3])glm::value_ptr(positionMatrix));
|
||||
}
|
||||
else if (coveredTimes.upper_bound(time) == last) { // coverage earlier, fetch last transform
|
||||
pxform_c(fromFrame.c_str(), toFrame.c_str(),
|
||||
*(coveredTimes.rbegin()), (double(*)[3])glm::value_ptr(positionMatrix));
|
||||
}
|
||||
else { // coverage both earlier and later, interpolate these transformations
|
||||
earlier = *std::prev((coveredTimes.lower_bound(time)));
|
||||
later = *(coveredTimes.upper_bound(time));
|
||||
|
||||
glm::dmat3 earlierTransform, laterTransform;
|
||||
|
||||
pxform_c(fromFrame.c_str(), toFrame.c_str(),
|
||||
earlier, (double(*)[3])glm::value_ptr(earlierTransform));
|
||||
pxform_c(fromFrame.c_str(), toFrame.c_str(),
|
||||
later, (double(*)[3])glm::value_ptr(laterTransform));
|
||||
|
||||
difference = later - earlier;
|
||||
quote = (time - earlier) / difference;
|
||||
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
for (int j = 0; j < 3; ++j) {
|
||||
positionMatrix[i][j] = (earlierTransform[i][j] * (1 - quote) + laterTransform[i][j] * quote);
|
||||
}
|
||||
}
|
||||
}
|
||||
bool hasError = checkForError("Error estimating transform matrix from frame: "
|
||||
+ fromFrame + ", to frame: " + toFrame);
|
||||
|
||||
return !hasError;
|
||||
}
|
||||
|
||||
|
||||
bool SpiceManager::getFieldOfView(const std::string& instrument, std::string& fovShape,
|
||||
std::string& frameName, glm::dvec3& boresightVector,
|
||||
std::vector<glm::dvec3>& bounds) const
|
||||
@@ -649,6 +938,7 @@ bool SpiceManager::getFieldOfView(int instrument,
|
||||
&nrReturned, // the number of array values returned for the bounds
|
||||
(double(*)[3])boundsArr // the bounds
|
||||
);
|
||||
|
||||
bool hasError = checkForError("Error getting Field-of-View parameters for "
|
||||
"instrument '" + std::to_string(instrument) + "'");
|
||||
if (hasError)
|
||||
@@ -667,127 +957,77 @@ bool SpiceManager::getFieldOfView(int instrument,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SpiceManager::geographicToRectangular(const std::string& body,
|
||||
double longitude,
|
||||
double latitude,
|
||||
glm::dvec3& coordinates) const
|
||||
{
|
||||
int id;
|
||||
bool success = getNaifId(body, id);
|
||||
if (!success)
|
||||
return false;
|
||||
std::string SpiceManager::frameFromBody(const std::string body) const {
|
||||
|
||||
for (auto pair : _frameByBody) {
|
||||
if (pair.first == body) {
|
||||
return pair.second;
|
||||
}
|
||||
}
|
||||
|
||||
std::string unionPrefix = "IAU_";
|
||||
std::string frame = "";
|
||||
|
||||
if (body.find(unionPrefix) == std::string::npos)
|
||||
frame = unionPrefix + body;
|
||||
else
|
||||
return geographicToRectangular(id, longitude, latitude, coordinates);
|
||||
frame = body;
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
bool SpiceManager::geographicToRectangular(int id, double longitude, double latitude,
|
||||
glm::dvec3& coordinates) const
|
||||
{
|
||||
srfrec_c(id, longitude*rpd_c(), latitude*rpd_c(), glm::value_ptr(coordinates));
|
||||
bool hasError = checkForError("Error transforming geographic coordinates for '" +
|
||||
std::to_string(id) + "'");
|
||||
return !hasError;
|
||||
}
|
||||
|
||||
bool SpiceManager::getSubObserverPoint(const std::string& target,
|
||||
const std::string& observer,
|
||||
const std::string& computationMethod,
|
||||
const std::string& bodyFixedFrame,
|
||||
const std::string& aberrationCorrection,
|
||||
double ephemerisTime,
|
||||
glm::dvec3& subObserverPoint,
|
||||
double& targetEphemerisTime,
|
||||
glm::dvec3& vectorToSurfacePoint) const
|
||||
{
|
||||
if (target.empty()) {
|
||||
LERROR("No target was provided");
|
||||
bool SpiceManager::addFrame(const std::string body, const std::string frame) {
|
||||
if (body == "" || frame == "")
|
||||
return false;
|
||||
else {
|
||||
_frameByBody.push_back(std::make_pair(body, frame));
|
||||
return true;
|
||||
}
|
||||
if (observer.empty()) {
|
||||
LERROR("No observer was provided");
|
||||
return false;
|
||||
}
|
||||
if (computationMethod.empty()) {
|
||||
LERROR("No computation method was provided");
|
||||
return false;
|
||||
}
|
||||
if (bodyFixedFrame.empty()) {
|
||||
LERROR("No body fixed frame was provided");
|
||||
return false;
|
||||
}
|
||||
if (aberrationCorrection.empty()) {
|
||||
LERROR("No aberration correction was provided");
|
||||
return false;
|
||||
}
|
||||
|
||||
subpnt_c(computationMethod.c_str(),
|
||||
target.c_str(),
|
||||
ephemerisTime,
|
||||
bodyFixedFrame.c_str(),
|
||||
aberrationCorrection.c_str(),
|
||||
observer.c_str(),
|
||||
glm::value_ptr(subObserverPoint),
|
||||
&targetEphemerisTime,
|
||||
glm::value_ptr(vectorToSurfacePoint)
|
||||
);
|
||||
|
||||
bool hasError = checkForError("Error retrieving subobserver point on target '" +
|
||||
target + "' of observer '" + observer + "' for computation method '" +
|
||||
computationMethod + "' and body fixed frame '" + bodyFixedFrame + "'");
|
||||
return !hasError;
|
||||
}
|
||||
|
||||
void SpiceManager::applyTransformationMatrix(glm::dvec3& position,
|
||||
glm::dvec3& velocity,
|
||||
const TransformMatrix& transformationMatrix)
|
||||
{
|
||||
double input[6];
|
||||
double output[6];
|
||||
memmove(input, glm::value_ptr(position), 3 * sizeof(glm::dvec3::value_type));
|
||||
memmove(input + 3, glm::value_ptr(velocity), 3 * sizeof(glm::dvec3::value_type));
|
||||
mxvg_c(transformationMatrix.data(), input, 6, 6, output);
|
||||
memmove(glm::value_ptr(position), output, 3 * sizeof(glm::dvec3::value_type));
|
||||
memmove(glm::value_ptr(velocity), output + 3, 3 * sizeof(glm::dvec3::value_type));
|
||||
}
|
||||
|
||||
bool SpiceManager::checkForError(std::string errorMessage) {
|
||||
|
||||
int failed = failed_c();
|
||||
if (failed) {
|
||||
if (failed && _showErrors) {
|
||||
static char msg[1024];
|
||||
if (!errorMessage.empty()) {
|
||||
getmsg_c("LONG", 1024, msg);
|
||||
LERROR(errorMessage);
|
||||
LERROR("Spice reported: " + std::string(msg));
|
||||
LWARNING(errorMessage);
|
||||
LWARNING("Spice reported: " + std::string(msg));
|
||||
}
|
||||
reset_c();
|
||||
return true;
|
||||
}
|
||||
else if (failed) {
|
||||
reset_c();
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
//bool SpiceManager::getSubSolarPoint(std::string computationMethod,
|
||||
// std::string target,
|
||||
// double ephemeris,
|
||||
// std::string bodyFixedFrame,
|
||||
// std::string aberrationCorrection,
|
||||
// std::string observer,
|
||||
// glm::dvec3& subSolarPoint,
|
||||
// double& targetEpoch,
|
||||
// glm::dvec3& vectorToSurfacePoint) const{
|
||||
// double subPoint[3], vecToSurf[3];
|
||||
//
|
||||
// subslr_c(computationMethod.c_str(),
|
||||
// target.c_str(),
|
||||
// ephemeris,
|
||||
// bodyFixedFrame.c_str(),
|
||||
// aberrationCorrection.c_str(),
|
||||
// observer.c_str(), subPoint, &targetEpoch, vecToSurf);
|
||||
//
|
||||
// memcpy(&subSolarPoint, subPoint, sizeof(double)* 3);
|
||||
// memcpy(&vectorToSurfacePoint, vecToSurf, sizeof(double)* 3);
|
||||
//
|
||||
// return true;
|
||||
//}
|
||||
bool SpiceManager::getPlanetEllipsoid(std::string planetName, float &a, float &b, float &c) {
|
||||
|
||||
SpiceDouble radii[3];
|
||||
SpiceInt n;
|
||||
int id;
|
||||
|
||||
getNaifId(planetName, id);
|
||||
if (bodfnd_c(id, "RADII")) {
|
||||
bodvrd_c(planetName.c_str(), "RADII", 3, &n, radii);
|
||||
a = static_cast<float>(radii[0]);
|
||||
b = static_cast<float>(radii[1]);
|
||||
c = static_cast<float>(radii[2]);
|
||||
}
|
||||
else {
|
||||
LWARNING("Could not find SPICE data for the shape of " + planetName + ", using modfile value");
|
||||
a = 1.f;
|
||||
b = 1.f;
|
||||
c = 1.f;
|
||||
}
|
||||
|
||||
bool hasError = checkForError("Error retrieving planet radii of " + planetName);
|
||||
return !hasError;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -28,11 +28,13 @@ if (OPENSPACE_HAVE_TESTS)
|
||||
|
||||
include_directories("${GHOUL_ROOT_DIR}/ext/gtest/include")
|
||||
include_directories("${GHOUL_ROOT_DIR}/include")
|
||||
file(GLOB_RECURSE OPENSPACE_TEST_FILES ${HEADER_ROOT_DIR}/openspace/tests/*.inl)
|
||||
include_directories("${OPENSPACE_BASE_DIR}/tests")
|
||||
include_directories("${OPENSPACE_BASE_DIR}/include")
|
||||
file(GLOB_RECURSE OPENSPACE_TEST_FILES ${OPENSPACE_BASE_DIR}/tests/*.inl)
|
||||
|
||||
source_group(OpenSpaceSource FILES ${OPENSPACE_SOURCE} ${OPENSPACE_HEADER})
|
||||
source_group(Tests FILES ${OPENSPACE_TEST_FILES})
|
||||
|
||||
add_executable(OpenSpaceTest ${SOURCE_ROOT_DIR}/tests/main.cpp ${OPENSPACE_TEST_FILES} ${OPENSPACE_HEADER} ${OPENSPACE_SOURCE})
|
||||
add_executable(OpenSpaceTest ${OPENSPACE_BASE_DIR}/tests/main.cpp ${OPENSPACE_TEST_FILES} ${OPENSPACE_HEADER} ${OPENSPACE_SOURCE})
|
||||
target_link_libraries(OpenSpaceTest gtest ${DEPENDENT_LIBS})
|
||||
|
||||
endif (OPENSPACE_HAVE_TESTS)
|
||||
@@ -0,0 +1,10 @@
|
||||
return {
|
||||
{
|
||||
Name = "CircularDependency1",
|
||||
Parent = "CircularDependency2"
|
||||
},
|
||||
{
|
||||
Name = "CircularDependency2",
|
||||
Parent = "CircularDependency1"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
return {
|
||||
{
|
||||
Name = "CommonDependency",
|
||||
Parent = "Common"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
return {
|
||||
{
|
||||
Name = "Common",
|
||||
Parent = "Root",
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
return {
|
||||
{
|
||||
Name = "DirectDependency",
|
||||
Parent = "NoDependency"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
-- Malformed script
|
||||
a
|
||||
@@ -0,0 +1,8 @@
|
||||
-- Malformed script
|
||||
return {
|
||||
ScenePath = "foobar",
|
||||
CommonFolder = "",
|
||||
Modules = {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
-- Malformed script
|
||||
return {
|
||||
ScenePath = ".",
|
||||
Modules = {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
-- Malformed script
|
||||
return {
|
||||
ScenePath = ".",
|
||||
CommonFolder = "nonexisting",
|
||||
Modules = {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
-- Malformed script
|
||||
return {
|
||||
ScenePath = ".",
|
||||
CommonFolder = 2,
|
||||
Modules = {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
return {
|
||||
{
|
||||
Name = "MultipleDependencies",
|
||||
Parent = "NoDependency",
|
||||
Dependency = {
|
||||
"DirectDependency"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
return {
|
||||
{
|
||||
Name = "NoDependency",
|
||||
Parent = "Root"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
return {
|
||||
{
|
||||
Name = "CommonDependency",
|
||||
Parent = "Common"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
return {
|
||||
{
|
||||
Name = "Common",
|
||||
Parent = "Root",
|
||||
},
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user