diff --git a/include/openspace/properties/optionproperty.h b/include/openspace/properties/optionproperty.h
index ae7f36125e..7cd3ca2443 100644
--- a/include/openspace/properties/optionproperty.h
+++ b/include/openspace/properties/optionproperty.h
@@ -31,7 +31,7 @@
namespace openspace {
namespace properties {
-
+
/**
* The OptionProperty is a property that provides a number of predefined (using the
* addOption method) options consisting of a description and a
diff --git a/include/openspace/properties/selectionproperty.h b/include/openspace/properties/selectionproperty.h
new file mode 100644
index 0000000000..59f2f6eb17
--- /dev/null
+++ b/include/openspace/properties/selectionproperty.h
@@ -0,0 +1,74 @@
+/*****************************************************************************************
+* *
+* OpenSpace *
+* *
+* Copyright (c) 2014 *
+* *
+* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
+* software and associated documentation files (the "Software"), to deal in the Software *
+* without restriction, including without limitation the rights to use, copy, modify, *
+* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
+* permit persons to whom the Software is furnished to do so, subject to the following *
+* conditions: *
+* *
+* The above copyright notice and this permission notice shall be included in all copies *
+* or substantial portions of the Software. *
+* *
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
+* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
+* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
+* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
+* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
+* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
+****************************************************************************************/
+
+#ifndef __SELECTIONPROPERTY_H__
+#define __SELECTIONPROPERTY_H__
+
+#include
+
+#include
+
+namespace openspace {
+namespace properties {
+
+//REGISTER_TEMPLATEPROPERTY_HEADER(SelectionProperty, std::vector);
+
+class SelectionProperty : public TemplateProperty> {
+public:
+ struct Option {
+ int value;
+ std::string description;
+ };
+
+ SelectionProperty(std::string identifier, std::string guiName);
+
+ void addOption(Option option);
+ const std::vector& options() const;
+
+ void setValue(std::vector value) override;
+
+private:
+ /// The list of options which have been registered with this OptionProperty
+ std::vector _options;
+ std::vector _values;
+};
+
+template <>
+std::string PropertyDelegate>>::className();
+
+template <>
+template <>
+std::vector PropertyDelegate>>::fromLuaValue(lua_State* state, bool& success);
+
+template <>
+template <>
+bool PropertyDelegate>>::toLuaValue(lua_State* state, std::vector value);
+
+template <>
+int PropertyDelegate>>::typeLua();
+
+} // namespace properties
+} // namespace openspace
+
+#endif // __SELECTIONPROPERTY_H__
\ No newline at end of file
diff --git a/include/openspace/rendering/stars/renderableconstellationbounds.h b/include/openspace/rendering/stars/renderableconstellationbounds.h
new file mode 100644
index 0000000000..1735e627f8
--- /dev/null
+++ b/include/openspace/rendering/stars/renderableconstellationbounds.h
@@ -0,0 +1,129 @@
+/*****************************************************************************************
+* *
+* OpenSpace *
+* *
+* Copyright (c) 2014 *
+* *
+* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
+* software and associated documentation files (the "Software"), to deal in the Software *
+* without restriction, including without limitation the rights to use, copy, modify, *
+* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
+* permit persons to whom the Software is furnished to do so, subject to the following *
+* conditions: *
+* *
+* The above copyright notice and this permission notice shall be included in all copies *
+* or substantial portions of the Software. *
+* *
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
+* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
+* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
+* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
+* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
+* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
+****************************************************************************************/
+
+#ifndef __RENDERABLECONSTELLATIONBOUNDS_H__
+#define __RENDERABLECONSTELLATIONBOUNDS_H__
+
+#include
+#include
+#include
+#include
+#include
+
+namespace openspace {
+
+/**
+ * This class renders the constellation bounds as defined in
+ * http://cdsarc.u-strasbg.fr/viz-bin/Cat?cat=VI%2F49. It contains the bounds on the
+ * celestial sky for the different constellations and is used to determine in which region
+ * of the sky a specific object is located.
+ * The bounds are drawn as lines on a sphere with variable radius, set by the
+ * _distance property. Currently, all constellation bounds are lines, which
+ * leads to artifacts if the radius is very small.
+ * Renderable configuration attributes:
+ * File [string] (required): The file that contains the bounds and the
+ * abbreviations for the different constellations
+ * ConstellationFile [string]: The file that contains the mapping between
+ * abbreviations and full names. If the file is omitted, the abbreviations are used as the
+ * full names.
+ * ReferenceFrame [string]: The reference frame in which the points contained
+ * in the File are stored in. Defaults to J2000
+ */
+class RenderableConstellationBounds : public Renderable {
+public:
+ RenderableConstellationBounds(const ghoul::Dictionary& dictionary);
+
+ bool initialize() override;
+ bool deinitialize() override;
+
+ bool isReady() const override;
+
+ void render(const RenderData& data) override;
+ void update(const UpdateData& data) override;
+
+private:
+ /// Stores the constellation bounds
+ struct ConstellationBound {
+ std::string constellationAbbreviation; ///< The abbreviation of the constellation
+ std::string constellationFullName;
+ bool isEnabled;
+ size_t startIndex; ///< The index of the first vertex describing the bounds
+ size_t nVertices; ///< The number of vertices describing the bounds
+ };
+
+ /**
+ * Loads the file specified in _vertexFilename and fills the
+ * _constellationBounds variable, as well as the
+ * _vertexValues list. If this method fails, the content of either
+ * destination is undefined.
+ * \return true if the loading succeeded, false otherwise
+ */
+ bool loadVertexFile();
+
+ /**
+ * Loads the file specified in _constellationFilename that contains the
+ * mapping between abbreviations and full names of constellations.
+ * \return true if the loading succeeded, false otherwise
+ */
+ bool loadConstellationFile();
+
+ /// Fills the _constellationSelection property with all constellations
+ void fillSelectionProperty();
+
+ /**
+ * Callback method that gets triggered when _constellationSelection
+ * changes.
+ */
+ void selectionPropertyHasChanged();
+
+ std::string _vertexFilename; ///< The filename containing the constellation bounds
+ std::string _constellationFilename; ///< The file containing constellation names
+
+ ghoul::opengl::ProgramObject* _program;
+ bool _programIsDirty;
+
+ /// The list of all loaded constellation bounds
+ std::vector _constellationBounds;
+
+ typedef std::array Vertex;
+ std::vector _vertexValues; ///< A list of all vertices of all bounds
+
+ /// The radius of the celestial sphere onto which the bounds are drawn
+ properties::FloatProperty _distance;
+
+ /// The property that stores all indices of constellations that should be drawn
+ properties::SelectionProperty _constellationSelection;
+
+ std::string _originReferenceFrame; ///< Reference frame in which bounds are defined
+
+ /// Used to translate between the origin reference frame and the target frame
+ glm::dmat3 _stateMatrix;
+
+ GLuint _vao;
+ GLuint _vbo;
+};
+
+} // namespace openspace
+
+#endif // __RENDERABLECONSTELLATIONBOUNDS_H__
diff --git a/openspace-data b/openspace-data
index 48daa03562..07ef85b86b 160000
--- a/openspace-data
+++ b/openspace-data
@@ -1 +1 @@
-Subproject commit 48daa03562e2bdc42a9088c724792ac57832ab92
+Subproject commit 07ef85b86b2a65dbce718055f56ddb23a588da3c
diff --git a/shaders/constellationbounds_fs.glsl b/shaders/constellationbounds_fs.glsl
new file mode 100644
index 0000000000..803e0bd79b
--- /dev/null
+++ b/shaders/constellationbounds_fs.glsl
@@ -0,0 +1,45 @@
+/*****************************************************************************************
+ * *
+ * 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 camdir; // add this for specular
+
+in vec4 vs_position;
+
+#include "ABuffer/abufferStruct.hglsl"
+#include "ABuffer/abufferAddToBuffer.hglsl"
+#include "PowerScaling/powerScaling_fs.hglsl"
+
+//#include "PowerScaling/powerScaling_vs.hglsl"
+void main()
+{
+ vec4 position = vs_position;
+ float depth = pscDepth(position);
+
+ ABufferStruct_t frag = createGeometryFragment(vec4(1.0, 0.0, 0.0, 1.0), position, depth);
+ addToBuffer(frag);
+}
\ No newline at end of file
diff --git a/shaders/constellationbounds_vs.glsl b/shaders/constellationbounds_vs.glsl
new file mode 100644
index 0000000000..f78b55555d
--- /dev/null
+++ b/shaders/constellationbounds_vs.glsl
@@ -0,0 +1,46 @@
+/*****************************************************************************************
+ * *
+ * 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;
+
+uniform float exponent;
+
+layout(location = 0) in vec3 in_position;
+out vec4 vs_position;
+
+#include "PowerScaling/powerScaling_vs.hglsl"
+
+void main()
+{
+ vec4 tmp = vec4(in_position, exponent);
+ vs_position = tmp;
+
+ vec4 position = pscTransform(tmp, ModelTransform);
+ vs_position = tmp;
+ position = ViewProjection * position;
+ gl_Position = z_normalization(position);
+}
\ No newline at end of file
diff --git a/src/properties/selectionproperty.cpp b/src/properties/selectionproperty.cpp
new file mode 100644
index 0000000000..447396ca24
--- /dev/null
+++ b/src/properties/selectionproperty.cpp
@@ -0,0 +1,161 @@
+/*****************************************************************************************
+* *
+* 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. *
+****************************************************************************************/
+
+#include
+
+namespace {
+ const std::string _loggerCat = "SelectionProperty";
+}
+
+namespace openspace {
+namespace properties {
+
+SelectionProperty::SelectionProperty(std::string identifier, std::string guiName)
+ : TemplateProperty(std::move(identifier), std::move(guiName), std::vector())
+{}
+
+void SelectionProperty::addOption(Option option) {
+ // @COPY-N-PASTE from optionproperty.cpp, possible refactoring? ---abock
+ for (auto o : _options) {
+ if (o.value == option.value) {
+ LWARNING("The value of option {" << o.value << " -> " << o.description <<
+ "} was already registered when trying to add option {" << option.value <<
+ " -> " << option.description << "}");
+ return;
+ }
+ }
+ _options.push_back(std::move(option));
+}
+
+const std::vector& SelectionProperty::options() const {
+ return _options;
+}
+
+void SelectionProperty::setValue(std::vector value) {
+ _values = std::move(value);
+}
+
+template <>
+std::string PropertyDelegate>>::className() {
+ return "SelectionProperty";
+}
+
+template <>
+template <>
+std::vector PropertyDelegate>>::fromLuaValue(lua_State* state, bool& success) {
+ static const int KEY = -2;
+ static const int VAL = -1;
+
+ std::vector result;
+
+ if (!lua_istable(state, -1)) {
+ LERROR("Parameter passed to the property is not a table");
+ success = false;
+ return result;
+ }
+
+ lua_pushnil(state);
+ while (lua_next(state, -2) != 0) {
+ int valueType = lua_type(state, VAL);
+
+ if (lua_isnumber(state, VAL)) {
+ int number = static_cast(lua_tonumber(state, VAL));
+ result.push_back(number);
+ }
+ else {
+ success = false;
+ return std::vector();
+ }
+
+ lua_pop(state, 1);
+ }
+
+ success = true;
+ return result;
+}
+
+template <>
+template <>
+bool PropertyDelegate>>::toLuaValue(lua_State* state, std::vector value) {
+ //@NOTE Untested ---abock
+ lua_newtable(state);
+ for (int i = 0; i < value.size(); ++i) {
+ int v = value[i];
+ lua_pushinteger(state, v);
+ lua_setfield(state, -2, std::to_string(i).c_str());
+ }
+ return true;
+}
+
+template <>
+int PropertyDelegate>>::typeLua() {
+ return LUA_TTABLE;
+}
+
+//REGISTER_TEMPLATEPROPERTY_SOURCE(SelectionProperty, std::vector, std::vector(),
+// [](lua_State* state, bool& success) -> std::vector {
+// static const int KEY = -2;
+// static const int VAL = -1;
+//
+// std::vector result;
+//
+// if (!lua_istable(state, -1)) {
+// LERROR("Parameter passed to the property is not a table");
+// success = false;
+// return result;
+// }
+//
+// lua_pushnil(state);
+// while (lua_next(state, -2) != 0) {
+// int valueType = lua_type(state, VAL);
+//
+// if (lua_isnumber(state, VAL)) {
+// int number = static_cast(lua_tonumber(state, VAL));
+// result.push_back(number);
+// }
+// else {
+// success = false;
+// return std::vector();
+// }
+//
+// lua_pop(state, 1);
+// }
+//
+// success = true;
+// return result;
+// },
+// [](lua_State* state, const std::vector& value) -> bool {
+// //@NOTE Untested ---abock
+// lua_newtable(state);
+// for (int i = 0; i < value.size(); ++i) {
+// int v = value[i];
+// lua_pushinteger(state, v);
+// lua_setfield(state, -2, std::to_string(i).c_str());
+// }
+// return true;
+// }, LUA_TTABLE
+//);
+
+} // namespace properties
+} // namespace openspace
diff --git a/src/rendering/stars/renderableconstellationbounds.cpp b/src/rendering/stars/renderableconstellationbounds.cpp
new file mode 100644
index 0000000000..7b96544164
--- /dev/null
+++ b/src/rendering/stars/renderableconstellationbounds.cpp
@@ -0,0 +1,343 @@
+/*****************************************************************************************
+* *
+* 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. *
+****************************************************************************************/
+
+#include
+
+#include
+#include
+#include
+#define _USE_MATH_DEFINES
+#include
+
+namespace {
+ const std::string _loggerCat = "RenderableConstellationBounds";
+
+ const std::string keyVertexFile = "File";
+ const std::string keyConstellationFile = "ConstellationFile";
+ const std::string keyReferenceFrame = "ReferenceFrame";
+
+ const std::string defaultReferenceFrame = "J2000";
+
+ float deg2rad(float deg) {
+ return static_cast((deg / 360.f) * 2.f * M_PI);
+ }
+ float convertHrsToRadians(float rightAscension) {
+ // 360 degrees / 24h = 15 degrees/h
+ return deg2rad(rightAscension * 15);
+ }
+}
+
+namespace openspace {
+
+RenderableConstellationBounds::RenderableConstellationBounds(
+ const ghoul::Dictionary& dictionary)
+ : Renderable(dictionary)
+ , _vertexFilename("")
+ , _constellationFilename("")
+ , _programIsDirty(false)
+ , _distance("distance", "Distance to the celestial Sphere", 15.f, 0.f, 30.f)
+ , _constellationSelection("constellationSelection", "Constellation Selection")
+ , _originReferenceFrame("")
+ , _vao(0)
+ , _vbo(0)
+{
+ bool success = dictionary.getValue(keyVertexFile, _vertexFilename);
+ if (!success) {
+ LERROR("RenderableConstellationBounds did not contain a key '" <<
+ keyVertexFile << "'");
+ }
+
+ dictionary.getValue(keyConstellationFile, _constellationFilename);
+
+ success = dictionary.getValue(keyReferenceFrame, _originReferenceFrame);
+ if (!success) {
+ _originReferenceFrame = defaultReferenceFrame;
+ }
+
+ addProperty(_distance);
+ addProperty(_constellationSelection);
+ _constellationSelection.onChange(
+ std::bind(&RenderableConstellationBounds::selectionPropertyHasChanged, this)
+ );
+}
+
+bool RenderableConstellationBounds::initialize() {
+ _program = ghoul::opengl::ProgramObject::Build("ConstellationBounds",
+ "${SHADERS}/constellationbounds_vs.glsl",
+ "${SHADERS}/constellationbounds_fs.glsl");
+ if (!_program)
+ return false;
+ _program->setProgramObjectCallback([&](ghoul::opengl::ProgramObject*){ this->_programIsDirty = true; });
+
+ bool loadSuccess = loadVertexFile();
+ if (!loadSuccess)
+ return false;
+ loadSuccess = loadConstellationFile();
+ if (!loadSuccess)
+ return false;
+
+ fillSelectionProperty();
+
+ if (_vao == 0) {
+ glGenVertexArrays(1, &_vao);
+ LDEBUG("Generating Vertex Array id '" << _vao << "'");
+ }
+ if (_vbo == 0) {
+ glGenBuffers(1, &_vbo);
+ LDEBUG("Generating Vertex Buffer Object id '" << _vbo << "'");
+ }
+
+ glBindVertexArray(_vao);
+ glBindBuffer(GL_ARRAY_BUFFER, _vbo);
+ glBufferData(GL_ARRAY_BUFFER,
+ _vertexValues.size() * 3 * sizeof(float),
+ &_vertexValues[0],
+ GL_STATIC_DRAW
+ );
+
+ GLint positionAttrib = _program->attributeLocation("in_position");
+ glEnableVertexAttribArray(positionAttrib);
+ glVertexAttribPointer(positionAttrib, 3, GL_FLOAT, GL_FALSE, 0, 0);
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glBindVertexArray(0);
+
+ return true;
+}
+
+bool RenderableConstellationBounds::deinitialize() {
+ glDeleteBuffers(1, &_vbo);
+ _vbo = 0;
+ glDeleteVertexArrays(1, &_vao);
+ _vao = 0;
+
+ delete _program;
+ _program = nullptr;
+ return true;
+}
+
+bool RenderableConstellationBounds::isReady() const {
+ return (_vao != 0) && (_vbo != 0);
+}
+
+void RenderableConstellationBounds::render(const RenderData& data) {
+ _program->activate();
+
+ glm::mat4 modelMatrix = data.camera.modelMatrix();
+ glm::mat4 viewMatrix = data.camera.viewMatrix();
+ glm::mat4 projectionMatrix = data.camera.projectionMatrix();
+
+ setPscUniforms(_program, &data.camera, data.position);
+
+ _program->setUniform("exponent", _distance);
+ _program->setUniform("ViewProjection", data.camera.viewProjectionMatrix());
+ _program->setUniform("ModelTransform", glm::mat4(glm::dmat4(_stateMatrix)));
+
+ glBindVertexArray(_vao);
+ for (auto bound : _constellationBounds)
+ if (bound.isEnabled) {
+ glDrawArrays(
+ //GL_LINE_STRIP,
+ GL_LINE_LOOP,
+ static_cast(bound.startIndex),
+ static_cast(bound.nVertices)
+ );
+ }
+ glBindVertexArray(0);
+ _program->deactivate();
+}
+
+void RenderableConstellationBounds::update(const UpdateData& data) {
+ if (_programIsDirty) {
+ _program->rebuildFromFile();
+ _programIsDirty = false;
+ }
+
+ SpiceManager::ref().getPositionTransformMatrix(
+ _originReferenceFrame,
+ "GALACTIC",
+ data.time,
+ _stateMatrix
+ );
+}
+
+bool RenderableConstellationBounds::loadVertexFile() {
+ if (_vertexFilename.empty())
+ return false;
+
+ std::string fileName = absPath(_vertexFilename);
+ std::ifstream file(fileName);
+ if (!file.good()) {
+ LERROR("Could not open file '" << fileName << "' for reading");
+ return false;
+ }
+
+ ConstellationBound currentBound;
+ currentBound.constellationAbbreviation = "";
+
+ std::string currentLine;
+ int currentLineNumber = 1;
+
+ float ra;
+ float dec;
+ std::string constellationName;
+ SpiceDouble rectangularValues[3];
+
+ // Overview of the reading algorithm:
+ // We keep an active ConstellationBound (currentBound) and update it until we read
+ // a new constellation name, at which point the currentBound is stored away, a new,
+ // empty ConstellationBound is created and set at the currentBound
+ while (file.good()) {
+ std::getline(file, currentLine);
+ if (currentLine.empty())
+ continue;
+
+ // @CHECK: Is this the best way of doing this? ---abock
+ std::stringstream s(currentLine);
+ s >> ra;
+ s >> dec;
+ s >> constellationName;
+
+ if (!s.good()) {
+ // If this evaluates to true, the stream was not completely filled, which
+ // means that the line was incomplete, so there was an error
+ LERROR("Error reading file '" << fileName << "' at line #" << currentLineNumber);
+ break;
+ }
+
+ // Did we arrive at a new constellation?
+ if (constellationName != currentBound.constellationAbbreviation) {
+ // Store how many vertices we read during the active time of the constellation
+ currentBound.nVertices = (_vertexValues.size() - currentBound.startIndex);
+ // Store the constellation and start a new one
+ _constellationBounds.push_back(currentBound);
+ currentBound = ConstellationBound();
+ currentBound.isEnabled = true;
+ currentBound.constellationAbbreviation = constellationName;
+ currentBound.constellationFullName = constellationName;
+ currentBound.startIndex = _vertexValues.size();
+ }
+
+ // The file format stores the right ascension in hours, while SPICE expects them
+ // to be in radians
+ ra = convertHrsToRadians(ra);
+
+ // Likewise, the declination is stored in degrees and needs to be converted
+ dec = deg2rad(dec);
+
+ // Convert the (right ascension, declination) to rectangular coordinates)
+ // The 1.0 is the distance of the celestial sphere, we will scale that in the
+ // render function
+ radrec_c(1.0, ra, dec, rectangularValues);
+
+ // Add the new vertex to our list of vertices
+ _vertexValues.push_back({{
+ static_cast(rectangularValues[0]),
+ static_cast(rectangularValues[1]),
+ static_cast(rectangularValues[2])
+ }});
+ ++currentLineNumber;
+ }
+
+ // Due to the way we read the file, the first (empty) constellation bounds will not
+ // contain any valid values. So we have to remove it
+ _constellationBounds.erase(_constellationBounds.begin());
+
+ // And we still have the one value that was left when we exited the loop
+ currentBound.nVertices = (_vertexValues.size() - currentBound.startIndex);
+ _constellationBounds.push_back(currentBound);
+
+ return true;
+}
+
+bool RenderableConstellationBounds::loadConstellationFile() {
+ if (_constellationFilename.empty())
+ return true;
+
+ std::string fileName = absPath(_constellationFilename);
+ std::ifstream file(fileName);
+ if (!file.good()) {
+ LERROR("Could not open file '" << fileName << "' for reading");
+ return false;
+ }
+
+ std::string line;
+ int index = 0;
+ while (file.good()) {
+ std::getline(file, line);
+ if (line.empty())
+ continue;
+
+ std::string abbreviation;
+ std::stringstream s(line);
+ s >> abbreviation;
+
+ auto it = std::find_if(_constellationBounds.begin(), _constellationBounds.end(),
+ [abbreviation](const ConstellationBound& bound) {
+ return bound.constellationAbbreviation == abbreviation;
+ });
+ if (it == _constellationBounds.end()) {
+ LERROR("Could not find constellation '" << abbreviation << "' in list");
+ return false;
+ }
+
+ // Update the constellations full name
+ s >> it->constellationFullName;
+
+ ++index;
+ }
+
+ return true;
+}
+
+void RenderableConstellationBounds::fillSelectionProperty() {
+ // Each constellation is associated with its position in the array as this is unique
+ // and will be constant during the runtime
+ for (int i = 0 ; i < _constellationBounds.size(); ++i) {
+ const ConstellationBound& bound = _constellationBounds[i];
+ _constellationSelection.addOption( { i, bound.constellationFullName } );
+
+ }
+}
+
+void RenderableConstellationBounds::selectionPropertyHasChanged() {
+ const std::vector& values = _constellationSelection;
+ // If no values are selected (the default), we want to show all constellations
+ if (values.size() == 0) {
+ for (ConstellationBound& b : _constellationBounds)
+ b.isEnabled = true;
+ }
+ else {
+ // In the worst case, this algorithm runs with 2 * nConstellations, which is
+ // acceptable as the number of constellations is < 100
+ // First disable all constellations
+ for (ConstellationBound& b : _constellationBounds)
+ b.isEnabled = false;
+ // then re-enable the ones for which we have indices
+ for (int value : values)
+ _constellationBounds[value].isEnabled = true;
+ }
+}
+
+} // namespace openspace
diff --git a/src/util/factorymanager.cpp b/src/util/factorymanager.cpp
index f169fa226c..72e99876e7 100644
--- a/src/util/factorymanager.cpp
+++ b/src/util/factorymanager.cpp
@@ -26,6 +26,7 @@
// renderables
#include
+#include
#include
#include
#include
@@ -62,10 +63,10 @@ void FactoryManager::initialize()
// TODO: This has to be moved into a sort of module structure (ab)
// Add Renderables
_manager->addFactory(new ghoul::TemplateFactory);
- _manager->factory()->registerClass(
- "RenderablePlanet");
- _manager->factory()->registerClass(
- "RenderableStars");
+ _manager->factory()->registerClass("RenderablePlanet");
+ _manager->factory()->registerClass("RenderableStars");
+ _manager->factory()->registerClass
+ ("RenderableConstellationBounds");
_manager->factory()->registerClass(
"RenderableEphemeris");
//will replace ephemeris class soon...
diff --git a/support/cloc/glslLangDef b/support/cloc/glslLangDef
index ccc4f70900..d4f8610ae6 100644
--- a/support/cloc/glslLangDef
+++ b/support/cloc/glslLangDef
@@ -4,4 +4,3 @@ GLSL
filter remove_inline //.*$
extension glsl
3rd_gen_scale 5
- end_of_line_continuation \\$
\ No newline at end of file