Merge branch 'develop' of openspace.itn.liu.se:/openspace into develop

Conflicts:
	src/scenegraph/scenegraph.cpp
This commit is contained in:
Jonas Strandstedt
2014-12-02 11:19:51 +01:00
51 changed files with 1155 additions and 955 deletions

1
.gitignore vendored
View File

@@ -27,3 +27,4 @@ html/
latex/
shaders/ABuffer/constants.hglsl
*.OpenSpaceGenerated.glsl
LuaScripting.txt

View File

@@ -37,7 +37,7 @@ enum class KeyAction {
};
enum class KeyModifier {
None = 0,
NoModifier = 0,
Shift = GLFW_MOD_SHIFT,
Control = GLFW_MOD_CONTROL,
Alt = GLFW_MOD_ALT,

View File

@@ -40,14 +40,14 @@ enum class MouseButton {
Left = SGCT_MOUSE_BUTTON_LEFT,
Right = SGCT_MOUSE_BUTTON_RIGHT,
Middle = SGCT_MOUSE_BUTTON_MIDDLE,
Button1 = SGCT_MOUSE_BUTTON_1,
Button2 = SGCT_MOUSE_BUTTON_2,
Button3 = SGCT_MOUSE_BUTTON_3,
Button4 = SGCT_MOUSE_BUTTON_4,
Button5 = SGCT_MOUSE_BUTTON_5,
Button6 = SGCT_MOUSE_BUTTON_6,
Button7 = SGCT_MOUSE_BUTTON_7,
Button8 = SGCT_MOUSE_BUTTON_8,
//Button1 = SGCT_MOUSE_BUTTON_1,
//Button2 = SGCT_MOUSE_BUTTON_2,
//Button3 = SGCT_MOUSE_BUTTON_3,
//Button4 = SGCT_MOUSE_BUTTON_4,
//Button5 = SGCT_MOUSE_BUTTON_5,
//Button6 = SGCT_MOUSE_BUTTON_6,
//Button7 = SGCT_MOUSE_BUTTON_7,
//Button8 = SGCT_MOUSE_BUTTON_8,
ButtonLast = SGCT_MOUSE_BUTTON_LAST,
};

View File

@@ -0,0 +1,97 @@
/*****************************************************************************************
* *
* 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 __OPTIONPROPERTY_H__
#define __OPTIONPROPERTY_H__
#include <openspace/properties/scalarproperty.h>
#include <vector>
namespace openspace {
namespace properties {
/**
* The OptionProperty is a property that provides a number of predefined (using the
* addOption method) options consisting of a <code>description</code> and a
* <code>value</code>. The available options can be queried using the options method.
* Only values representing valid options can be used to set this property, or an error
* will be logged
*/
class OptionProperty : public IntProperty {
public:
/**
* The struct storing a single option consisting of an integer <code>value</code> and
* a <code>string</code> description.
*/
struct Option {
int value;
std::string description;
};
/**
* The constructor delegating the <code>identifier</code> and the <code>guiName</code>
* to its super class.
* \param identifier A unique identifier for this property
* \param guiName The GUI name that should be used to represent this property
*/
OptionProperty(std::string identifier, std::string guiName);
/**
* Returns the name of the class for reflection purposes.
* \return The name of this class for reflection purposes
*/
std::string className() const override;
using IntProperty::operator=;
/**
* Adds the passed option to the list of available options. The <code>value</code> of
* the <code>option</code> must not have been registered previously, or a warning will
* be logged.
* \param option The option that will be added to the list of available options
*/
void addOption(Option option);
/**
* Returns the list of available options.
* /return The list of available options
*/
const std::vector<Option>& options() const;
/**
* The overritten TemplateProperty::setValue method that checks if the provided value
* represents a valid Option
* \param value The value of the Option that should be set
*/
void setValue(int value) override;
private:
/// The list of options which have been registered with this OptionProperty
std::vector<Option> _options;
};
} // namespace properties
} // namespace openspace
#endif // __STRINGPROPERTY_H__

View File

@@ -158,7 +158,7 @@ public:
* <code>T</code>. If the value are different, the listeners are notified.
* \param val The new value for this TemplateProperty
*/
void setValue(T val);
virtual void setValue(T val);
/**
* Returns the currently stored value.

View File

@@ -49,6 +49,8 @@ public:
bool initialize() override;
bool deinitialize() override;
bool isReady() const override;
void render(const RenderData& data) override;
void update(const UpdateData& data) override;

View File

@@ -48,6 +48,7 @@ public:
bool initialize() override;
bool deinitialize() override;
bool isReady() const override;
void render(const RenderData& data) override;
void update(const UpdateData& data) override;

View File

@@ -55,6 +55,8 @@ public:
virtual bool initialize() = 0;
virtual bool deinitialize() = 0;
virtual bool isReady() const = 0;
void setBoundingSphere(const PowerScaledScalar& boundingSphere);
const PowerScaledScalar& getBoundingSphere();

View File

@@ -43,6 +43,8 @@ public:
bool initialize() override;
bool deinitialize() override;
bool isReady() const override;
void render(const RenderData& data) override;
void update(const UpdateData& data) override;

View File

@@ -27,11 +27,9 @@
// open space includes
#include <openspace/rendering/renderable.h>
#include <openspace/util/updatestructures.h>
// ghoul includes
#include <ghoul/opengl/programobject.h>
#include <ghoul/filesystem/file.h>
namespace openspace {
struct LinePoint;
@@ -44,8 +42,9 @@ public:
bool initialize();
bool deinitialize();
bool isReady() const override;
void render(const RenderData& data) override;
void update(const UpdateData& data) override;
private:
std::vector<std::vector<LinePoint> > getFieldlinesData(std::string filename, ghoul::Dictionary hintsDictionary);
@@ -54,18 +53,11 @@ private:
std::vector<std::string> _filenames;
std::vector<glm::vec3> _seedPoints;
ghoul::opengl::ProgramObject *_fieldlinesProgram;
GLuint _VAO, _seedpointVAO;
ghoul::filesystem::File* _vertexSourceFile;
ghoul::filesystem::File* _fragmentSourceFile;
ghoul::opengl::ProgramObject* _shader;
GLuint _fieldlineVAO;
std::vector<GLint> _lineStart;
std::vector<GLsizei> _lineCount;
bool _programUpdateOnSave;
bool _update;
void safeShaderCompilation();
};
} // namespace openspace

View File

@@ -44,6 +44,8 @@ public:
bool initialize() override;
bool deinitialize() override;
bool isReady() const override;
void render(const RenderData& data) override;
void update(const UpdateData& data) override;
private:

View File

@@ -44,6 +44,8 @@ namespace openspace {
bool initialize() override;
bool deinitialize() override;
bool isReady() const override;
void render(const RenderData& data) override;
void update(const UpdateData& data) override;
private:

View File

@@ -47,8 +47,10 @@ public:
RenderablePlane(const ghoul::Dictionary& dictionary);
~RenderablePlane();
bool initialize();
bool deinitialize();
bool initialize() override;
bool deinitialize() override;
bool isReady() const override;
void render(const RenderData& data) override;
void update(const UpdateData& data) override;

View File

@@ -44,6 +44,8 @@ public:
bool initialize() override;
bool deinitialize() override;
bool isReady() const override;
void render(const RenderData& data) override;
void update(const UpdateData& data) override;
private:

View File

@@ -44,6 +44,8 @@ public:
bool initialize() override;
bool deinitialize() override;
bool isReady() const override;
void render(const RenderData& data) override;
void update(const UpdateData& data) override;
private:

View File

@@ -46,8 +46,10 @@ public:
RenderableVolumeGL(const ghoul::Dictionary& dictionary);
~RenderableVolumeGL();
bool initialize();
bool deinitialize();
bool initialize() override;
bool deinitialize() override;
bool isReady() const override;
virtual void render(const RenderData& data) override;
virtual void update(const UpdateData& data) override;

View File

@@ -25,54 +25,61 @@
#ifndef __RENDERABLESTARS_H__
#define __RENDERABLESTARS_H__
// open space includes
#include <openspace/rendering/renderable.h>
#include <openspace/properties/stringproperty.h>
#include <openspace/properties/optionproperty.h>
// ghoul includes
#include <ghoul/opengl/programobject.h>
#include <ghoul/opengl/texture.h>
namespace openspace {
namespace openspace{
class RenderableStars : public Renderable{
class RenderableStars : public Renderable {
public:
RenderableStars(const ghoul::Dictionary& dictionary);
~RenderableStars();
bool initialize() override;
bool initialize() override;
bool deinitialize() override;
bool isReady() const override;
void render(const RenderData& data) override;
void update(const UpdateData& data) override;
protected:
void loadTexture();
private:
std::ifstream& skipToLine(std::ifstream& file, unsigned int num);
bool readSpeckFile(const std::string& path);
void generateBufferObjects(const void* data);
enum ColorOption {
Color = 0,
Velocity = 1,
Speed = 2
};
void createDataSlice(ColorOption option);
bool loadData();
bool readSpeckFile();
bool loadCachedFile(const std::string& file);
bool saveCachedFile(const std::string& file) const;
properties::StringProperty _colorTexturePath;
ghoul::opengl::ProgramObject* _haloProgram;
ghoul::opengl::ProgramObject* _pointProgram;
ghoul::opengl::Texture* _texture;
bool _textureIsDirty;
std::string _speckPath;
properties::OptionProperty _colorOption;
bool _dataIsDirty;
//GLint vertsToDraw;
properties::FloatProperty _spriteSize;
GLuint _vboID;
GLuint _vaoID;
GLint positionAttrib;
GLint brightnessDataAttrib;
int v_size;
int v_stride;
int v_total;
ghoul::opengl::ProgramObject* _program;
bool _programIsDirty;
std::string _speckFile;
std::vector<float> _slicedData;
std::vector<float> _fullData;
int _nValuesPerStar;
GLuint _vao;
GLuint _vbo;
};
} // namespace openspace

View File

@@ -57,12 +57,13 @@ public:
void initializeLuaState(lua_State* state);
void addLibrary(const LuaLibrary& library);
void addLibrary(LuaLibrary library);
bool hasLibrary(const std::string& name);
bool runScript(const std::string& script);
bool runScriptFile(const std::string& filename);
bool writeDocumentation(const std::string& filename, const std::string& type) const;
private:
bool registerLuaLibrary(lua_State* state, const LuaLibrary& library);

View File

@@ -47,7 +47,7 @@ protected:
#define SRCLEN 128
const int nrMetaKernels = 9;
int which, handle, count = 0;
SpiceInt which, handle, count = 0;
char file[FILLEN], filtyp[TYPLEN], source[SRCLEN];
double abs_error = 0.00001;
@@ -353,8 +353,8 @@ TEST_F(SpiceManagerTest, getPositionTransformMatrix){
TEST_F(SpiceManagerTest, getFieldOfView){
loadMetaKernel();
int n;
int cassini_ID;
SpiceInt n;
SpiceInt cassini_ID;
double et;
glm::dvec3 boresight;
double bounds_ref[5][3];
@@ -395,7 +395,7 @@ TEST_F(SpiceManagerTest, planetocentricToRectangular){
double lat = -35.0; //initial values
double lon = 100.0;
double rectangular_ref[3];
int naifId;
SpiceInt naifId;
SpiceBoolean foundSpice;
bodn2c_c("EARTH", &naifId, &foundSpice);

View File

@@ -42,6 +42,8 @@ namespace configurationmanager {
const std::string keyCachePath = keyPaths + "." + keyCache;
const std::string keyFonts = "Fonts";
const std::string keyConfigSgct = "SGCTConfig";
const std::string keyLuaDocumentationType = "LuaDocumentationFile.Type";
const std::string keyLuaDocumentationFile = "LuaDocumentationFile.File";
const std::string keyConfigScene = "Scene";
const std::string keyStartupScript = "StartupScripts";
const std::string keySpiceTimeKernel = "SpiceKernel.Time";
@@ -88,8 +90,8 @@ namespace modelgeometry {
} // namespace modelgeometry
namespace renderablestars {
const std::string keySpeckFile = "SpeckFile";
const std::string keyPathModule = "ModulePath";
const std::string keyFile = "File";
const std::string keyTexture = "Texture";
} // namespace renderablestars
namespace renderablevolumegl {

View File

@@ -26,5 +26,9 @@ return {
Scene = "${OPENSPACE_DATA}/scene/default.scene",
StartupScripts = {
"${SCRIPTS}/default_startup.lua"
},
LuaDocumentationFile = {
Type = "text",
File = "${BASE_PATH}/LuaScripting.txt"
}
}

42
shaders/fieldline_fs.glsl Normal file
View File

@@ -0,0 +1,42 @@
/*****************************************************************************************
* *
* 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__
in vec4 gs_color;
in vec4 gs_position;
in vec3 gs_normal;
#include "ABuffer/abufferStruct.hglsl"
#include "ABuffer/abufferAddToBuffer.hglsl"
#include "PowerScaling/powerScaling_fs.hglsl"
void main() {
float alpha = 1-length(gs_normal)*length(gs_normal);
vec4 fragColor = vec4(gs_color.rgb, alpha);
float depth = pscDepth(gs_position);
ABufferStruct_t frag = createGeometryFragment(fragColor, gs_position, depth);
addToBuffer(frag);
}

99
shaders/fieldline_gs.glsl Normal file
View File

@@ -0,0 +1,99 @@
/*****************************************************************************************
* *
* 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 modelViewProjection;
uniform mat4 modelTransform;
uniform vec3 cameraViewDir;
in vec4 vs_color[];
out vec4 gs_color;
out vec4 gs_position;
out vec3 gs_normal;
#include "PowerScaling/powerScaling_vs.hglsl"
layout(lines_adjacency) in;
layout(triangle_strip, max_vertices = 4) out;
vec4 prismoid[4];
// Calculate the correct powerscaled position and depth for the ABuffer
void ABufferEmitVertex(vec4 pos) {
// calculate psc position
vec4 tmp = pos;
vec4 position = pscTransform(tmp, modelTransform);
gs_position = tmp;
// project the position to view space
position = modelViewProjection*position;
gl_Position = position;
EmitVertex();
}
// Original code from http://prideout.net/blog/?p=61
void main() {
gs_color = vs_color[0];
// Get the current and adjacent vertex positions and calculate help vectors u and v
vec3 p0, p1, p2, p3;
p0 = gl_in[0].gl_Position.xyz; p1 = gl_in[1].gl_Position.xyz;
p2 = gl_in[2].gl_Position.xyz; p3 = gl_in[3].gl_Position.xyz;
vec3 n0 = normalize(p1-p0);
vec3 n1 = normalize(p2-p1);
vec3 n2 = normalize(p3-p2);
vec3 u = normalize(n0+n1);
vec3 v = normalize(n1+n2);
float EARTH_RADIUS = 6371000.0;
float width = 0.1*EARTH_RADIUS;
// Calculate normals for all 4 new vertices
vec3 normals[4];
normals[0] = normalize(cross(cameraViewDir,u));
normals[1] = -normals[0];
normals[3] = normalize(cross(cameraViewDir,v));
normals[2] = -normals[3];
// Calculate positions for the new vertices
prismoid[0] = vec4(p1 + normals[0]*width, 0);
prismoid[1] = vec4(p1 + normals[1]*width, 0);
prismoid[2] = vec4(p2 + normals[2]*width, 0);
prismoid[3] = vec4(p2 + normals[3]*width, 0);
// Send normals and verticies to fragment shader
gs_normal = normals[0];
ABufferEmitVertex(prismoid[0]);
gs_normal = normals[1];
ABufferEmitVertex(prismoid[1]);
gs_normal = normals[3];
ABufferEmitVertex(prismoid[3]);
gs_normal = normals[2];
ABufferEmitVertex(prismoid[2]);
EndPrimitive();
}

40
shaders/fieldline_vs.glsl Normal file
View File

@@ -0,0 +1,40 @@
/*****************************************************************************************
* *
* 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 modelViewProjection;
uniform mat4 modelTransform;
layout(location = 0) in vec3 in_position;
layout(location = 1) in vec4 in_color;
out vec4 vs_color;
#include "PowerScaling/powerScaling_vs.hglsl"
void main() {
vs_color = in_color;
gl_Position = vec4(in_position, 0);
}

View File

@@ -24,13 +24,22 @@
#version __CONTEXT__
// keep in sync with renderablestars.h:ColorOption enum
const int COLOROPTION_COLOR = 0;
const int COLOROPTION_VELOCITY = 1;
const int COLOROPTION_SPEED = 2;
uniform sampler2D texture1;
uniform vec3 Color;
in vec4 vs_position;
in vec2 texCoord;
uniform int colorOption;
layout(location = 0) in vec4 vs_position;
layout(location = 1) in vec3 ge_brightness;
layout(location = 2) in vec3 ge_velocity;
layout(location = 3) in float ge_speed;
layout(location = 4) in vec2 texCoord;
layout(location = 2) in vec3 ge_brightness;
#include "ABuffer/abufferStruct.hglsl"
@@ -40,7 +49,7 @@ layout(location = 2) in vec3 ge_brightness;
//---------------------------------------------------------------------------
vec4 bv2rgb(float bv) // RGB <0,1> <- BV <-0.4,+2.0> [-]
{
float t;
float t = 0.0;
vec4 c;
// TODO CHECK: Isn't t uninitialized here?
@@ -63,16 +72,30 @@ vec4 bv2rgb(float bv) // RGB <0,1> <- BV <-0.4,+2.0> [-]
void main(void)
{
// Something in the color calculations need to be changed because before it was dependent
// on the gl blend functions since the abuffer was not involved
//glDisable(GL_DEPTH_TEST);
//glEnable(GL_BLEND);
//glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ONE);
vec4 color = bv2rgb(ge_brightness[0])/1.1;
vec4 color = vec4(0.0);
switch (colorOption) {
case COLOROPTION_COLOR:
color = bv2rgb(ge_brightness[0])/1.1;
break;
case COLOROPTION_VELOCITY:
color = vec4(abs(ge_velocity), 0.5);
break;
case COLOROPTION_SPEED:
// @TODO Include a transfer function here ---abock
color = vec4(vec3(ge_speed), 0.5);
break;
}
// color.rgb = 1/ color.rgb;
// color.a = 1-color.a;
framebuffer_output_color = texture(texture1, texCoord)*color;
//framebuffer_output_color = vec4(1.0, 0.0, 0.0, 1.0);
// framebuffer_output_color = vec4(ge_velocity, 1.0);
//diffuse = vec4(1,1,0,1);
///diffuse = vec4(Color, 1.0);
@@ -80,7 +103,6 @@ void main(void)
vec4 position = vs_position;
float depth = pscDepth(position);
gl_FragDepth = depth;
//gl_FragDepth = 10.0;
//ABufferStruct_t frag = createGeometryFragment(vec4(1,0,0,1), position, depth);
//ABufferStruct_t frag = createGeometryFragment(diffuse, position, depth);

View File

@@ -1,144 +0,0 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#version __CONTEXT__
uniform sampler2D texture1;
uniform vec3 Color;
in vec4 vs_position;
in vec2 texCoord;
layout(location = 2) in vec3 ge_brightness;
out vec4 diffuse;
in float scale;
const float k = 10.0;
//---------------------------------------------------------------------------
vec4 bv2rgb(float bv) // RGB <0,1> <- BV <-0.4,+2.0> [-]
{
float t;
vec4 c;
if (t<-0.4) t=-0.4; if (t> 2.0) t= 2.0;
if ((bv>=-0.40)&&(bv<0.00)) { t=(bv+0.40)/(0.00+0.40); c.r=0.61+(0.11*t)+(0.1*t*t); }
else if ((bv>= 0.00)&&(bv<0.40)) { t=(bv-0.00)/(0.40-0.00); c.r=0.83+(0.17*t) ; }
else if ((bv>= 0.40)&&(bv<2.10)) { t=(bv-0.40)/(2.10-0.40); c.r=1.00 ; }
if ((bv>=-0.40)&&(bv<0.00)) { t=(bv+0.40)/(0.00+0.40); c.g=0.70+(0.07*t)+(0.1*t*t); }
else if ((bv>= 0.00)&&(bv<0.40)) { t=(bv-0.00)/(0.40-0.00); c.g=0.87+(0.11*t) ; }
else if ((bv>= 0.40)&&(bv<1.60)) { t=(bv-0.40)/(1.60-0.40); c.g=0.98-(0.16*t) ; }
else if ((bv>= 1.60)&&(bv<2.00)) { t=(bv-1.60)/(2.00-1.60); c.g=0.82 -(0.5*t*t); }
if ((bv>=-0.40)&&(bv<0.40)) { t=(bv+0.40)/(0.40+0.40); c.b=1.00 ; }
else if ((bv>= 0.40)&&(bv<1.50)) { t=(bv-0.40)/(1.50-0.40); c.b=1.00-(0.47*t)+(0.1*t*t); }
else if ((bv>= 1.50)&&(bv<1.94)) { t=(bv-1.50)/(1.94-1.50); c.b=0.63 -(0.6*t*t); }
return c;
}
//---------------------------------------------------------------------------
vec4 psc_normlization(vec4 invec) {
float xymax = max(invec.x,invec.y);
if(invec.z > 0.0f || invec.z < 0.0f) {
return invec / abs(invec.z);
} else if (xymax != 0.0f) {
return invec / xymax;
} else {
return invec / -.0;
}
}
void main(void)
{
// Observable universe is 10^27m, setting the far value to extremely high, aka 30!! ERMAHGERD!
float s_far = 27.0; //= gl_DepthRange.far; // 40
float s_farcutoff = 12.0;
float s_nearcutoff = 7.0;
float s_near = 0.0f;// gl_DepthRange.near; // 0.1
float depth;
// the value can be normalized to 1
vec4 p = vs_position;
if(vs_position.w <= 0.5) {
//depth = abs(vs_position.z * pow(10, vs_position.w)) / pow(k,s_far);
depth = (vs_position.w+log(abs(vs_position.z)))/pow(k, vs_position.w);
} else if(vs_position.w < 3.0) {
depth = vs_position.w+log(abs(vs_position.z))/pow(k, vs_position.w);
} else {
depth = vs_position.w+log(abs(vs_position.z));
}
// DEBUG
float depth_orig = depth;
float x = 0.0f;
float cutoffs = 0.0;
float orig_z = vs_position.z;
// calculate a normalized depth [0.0 1.0]
if((depth > s_near && depth <= s_nearcutoff) || (depth > s_farcutoff && depth < s_far)) {
// completely linear interpolation [s_near .. depth .. s_far]
depth = (depth - s_near) / (s_far - s_near);
} else if(depth > s_nearcutoff && depth < s_farcutoff) {
// DEBUG
cutoffs = 1.0;
// interpolate [10^s_nearcutoff .. 10^depth .. 10^s_farcutoff]
// calculate between 0..1 where the depth is
x = (pow(10,depth) - pow(10, s_nearcutoff)) / (pow(10,s_farcutoff) - pow(10, s_nearcutoff));
// remap the depth to the 0..1 depth buffer
depth = s_nearcutoff + x * (s_farcutoff - s_nearcutoff);
depth = (depth - s_near) / (s_far - s_near);
} else {
// where am I?
// do I need to be discarded?
// discard;
}
// set the depth
gl_FragDepth = depth;
//float a = ge_brightness[2]/500;
float b = scale;
vec4 color = bv2rgb(ge_brightness[0]*b)/250;
//color*=b;
// GL_SMOOTH_POINTS decrepated in core profile.
if(dot(gl_PointCoord-0.5,gl_PointCoord-0.5)>0.25)
discard;
else
//diffuse = vec4(color.xyz, 1);//*b;
diffuse = vec4(1)*b;
//diffuse = vec4(Color, 1.0);
}

View File

@@ -33,29 +33,35 @@ const vec2 corners[4] = vec2[4](
#include "PowerScaling/powerScalingMath.hglsl"
in vec4 psc_position[];
in vec4 cam_position[];
layout(points) in;
//layout(points, max_vertices = 1) out;
layout(location = 2) in vec3 vs_brightness[];
layout(location = 2) out vec3 ge_brightness;
layout(triangle_strip, max_vertices = 4) out;
out vec2 texCoord;
out vec4 vs_position;
layout(location = 0) in vec4 psc_position[];
layout(location = 1) in vec3 vs_brightness[];
layout(location = 2) in vec3 vs_velocity[];
layout(location = 3) in float vs_speed[];
layout(location = 4) in vec4 cam_position[];
layout(location = 0) out vec4 vs_position;
layout(location = 1) out vec3 ge_brightness;
layout(location = 2) out vec3 ge_velocity;
layout(location = 3) out float ge_speed;
layout(location = 4) out vec2 texCoord;
uniform mat4 projection; // we do this after distance computation.
float spriteSize = 0.0000005f; // set here for now.
uniform float spriteSize;
void main(){
ge_brightness = vs_brightness[0]; // pass on to fragment shader.
void main() {
ge_brightness = vs_brightness[0];
ge_velocity = vs_velocity[0];
ge_speed = vs_speed[0];
/// --- distance modulus --- NOT OPTIMIZED YET.
// float M = vs_brightness[0][0]; // get ABSOLUTE magnitude (x param)
float M = vs_brightness[0][2]; // if NOT running test-target.
float M = vs_brightness[0].z; // if NOT running test-target.
vec4 cam = vec4(-cam_position[0].xyz, cam_position[0].w); // get negative camera position
vec4 pos = psc_position[0]; // get OK star position
@@ -65,9 +71,10 @@ void main(){
y = result[1];
z = result[2];
w = result[3];
// I dont trust the legnth function at this point
vec2 pc = vec2(sqrt(x*x +y*y + z*z), result[3]); // form vec2
vec2 pc = vec2(length(result.xyz), result[3]);
// @Check conversion is also done in the cpp file ---abock
pc[0] *= 0.324077929f; // convert meters -> parsecs
pc[1] += -18.0f;
@@ -79,16 +86,16 @@ void main(){
float weight = 0.00001f; // otherwise this takes over.
float depth = pc[0] * pow(10, pc[1]);
depth *= pow(apparent,3);
//if(round(apparent) > 10)
spriteSize += (depth*weight);
float modifiedSpriteSize = spriteSize + (depth*weight);
// EMIT QUAD
for(int i = 0; i < 4; i++){
vec4 p1 = P;
p1.xy += spriteSize *(corners[i] - vec2(0.5));
p1.xy += modifiedSpriteSize *(corners[i] - vec2(0.5));
vs_position = p1;
gl_Position = projection * p1;
// gl_Position = z_normalization(projection * p1); // projection here
// gl_Position = z_normalization(projection * p1);
texCoord = corners[i];
EmitVertex();
}

View File

@@ -1,101 +0,0 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#version __CONTEXT__
layout(points) in;
layout(points, max_vertices = 1) out; // Draw points
//layout(triangle_strip, max_vertices = 4) out; // Draw quads
layout(location = 2) in vec3 vs_brightness[];
layout(location = 2) out vec3 ge_brightness[];
float spriteSize = 0.1; // set here for now.
out vec2 texCoord;
out float scale;
in vec4 psc_position[];
in vec4 campos[];
float k = 10.f;
vec4 psc_addition(vec4 v1, vec4 v2) {
float ds = v2.w - v1.w;
if(ds >= 0) {
float p = pow(k,-ds);
return vec4(v1.x*p + v2.x, v1.y*p + v2.y, v1.z*p + v2.z, v2.w);
} else {
float p = pow(k,ds);
return vec4(v1.x + v2.x*p, v1.y + v2.y*p, v1.z + v2.z*p, v1.w);
}
}
float log10( float x ){ return log(x) / log(10); }
void main(){
ge_brightness[0] = vs_brightness[0];
float distToPoint = 1;
float radius = 2f;
// EMIT POINT
gl_Position = gl_in[0].gl_Position;
// right now only threshing with absolute magnitude.
float absMag = 1.0f;
if(vs_brightness[0].x < 0.0) absMag = 3;
if(vs_brightness[0].x < -3.0) absMag = 6;
if(vs_brightness[0].x < -6.0) absMag = 9;
// float M = vs_brightness[0][0]; // get ABSOLUTE magnitude (x param)
float M = vs_brightness[0][2]; // if NOT running test-target.
vec4 cam = vec4(-campos[0].xyz, campos[0].w); // get negative camera position
// does swizzle work?? FFS! do it manually:
vec4 pos = psc_position[0]; // get OK star position
vec4 result = psc_addition(pos, cam); // compute vec from camera to position
float x, y, z, w;
x = result[0];
y = result[1];
z = result[2];
w = result[3];
// I dont trust the legnth function at this point
vec2 pc = vec2(sqrt(x*x +y*y + z*z), result[3]); // form vec2
pc[0] *= 0.324077929; // convert meters -> parsecs
pc[1] += -18;
float pc_psc = pc[0] * pow(10, pc[1]); // psc scale out
float apparent = (M - 5.0f * (1.f - log10(pc_psc))); // formula, get appMagnitude.
vec4 P = gl_in[0].gl_Position;
float weight = 0.1f; // otherwise this takes over.
float depth = -P.z;
//depth *= pow(apparent,6);
//if(round(apparent) > 10)
scale = -apparent*weight;
gl_PointSize = -apparent*0.3;
EmitVertex();
EndPrimitive();
}

View File

@@ -24,36 +24,35 @@
#version __CONTEXT__
uniform mat4 ViewProjection;
uniform mat4 ModelTransform;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
uniform sampler2D texture1;
layout(location = 0) in vec4 in_position;
layout(location = 2) in vec3 in_brightness;
layout(location = 1) in vec3 in_brightness;
layout(location = 2) in vec3 in_velocity;
layout(location = 3) in float in_speed;
out vec3 vs_brightness;
out vec4 psc_position;
out vec4 cam_position;
layout(location = 0) out vec4 psc_position;
layout(location = 1) out vec3 vs_brightness;
layout(location = 2) out vec3 vs_velocity;
layout(location = 3) out float vs_speed;
layout(location = 4) out vec4 cam_position;
#include "PowerScaling/powerScaling_vs.hglsl"
void main(){
vs_brightness = in_brightness;
void main() {
psc_position = in_position;
vs_brightness = in_brightness;
vs_velocity = in_velocity;
vs_speed = in_speed;
cam_position = campos;
vec4 tmp = in_position;
vec4 position = pscTransform(tmp, ModelTransform);
vec4 position = pscTransform(tmp, mat4(1.0));
// psc_position = tmp;
position = view * model * position;
position = model * view * position;
// position = ViewProjection * ModelTransform * position;
// gl_Position = z_normalization(position);
gl_Position = position;
}

View File

@@ -1,108 +0,0 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#version __CONTEXT__
uniform mat4 ViewProjection;
uniform mat4 ModelTransform;
uniform vec4 campos;
uniform mat4 camrot;
//uniform vec2 scaling;
uniform vec4 objpos;
uniform sampler2D texture1;
layout(location = 0) in vec4 in_position;
layout(location = 2) in vec3 in_brightness;
out vec4 vs_position;
out vec3 vs_brightness;
out vec4 psc_position;
out vec4 cam_position;
const float k = 10.0;
const float dgr_to_rad = 0.0174532925;
vec4 psc_addition(vec4 v1, vec4 v2) {
float ds = v2.w - v1.w;
if(ds >= 0) {
float p = pow(k,-ds);
return vec4(v1.x*p + v2.x, v1.y*p + v2.y, v1.z*p + v2.z, v2.w);
} else {
float p = pow(k,ds);
return vec4(v1.x + v2.x*p, v1.y + v2.y*p, v1.z + v2.z*p, v1.w);
}
}
vec4 psc_to_meter(vec4 v1, vec2 v2) {
float factor = v2.x * pow(k,v2.y + v1.w);
return vec4(v1.xyz * factor, 1.0);
}
vec4 psc_scaling(vec4 v1, vec2 v2) {
float ds = v2.y - v1.w;
if(ds >= 0) {
return vec4(v1.xyz * v2.x * pow(k,v1.w), v2.y);
} else {
return vec4(v1.xyz * v2.x * pow(k,v2.y), v1.w);
}
}
void main()
{
vs_brightness = in_brightness;
psc_position = in_position;
cam_position = campos;
// rotate and scale vertex with model transform and add the translation
vec3 local_vertex_pos = mat3(ModelTransform) * in_position.xyz;
//vec4 lvp = ModelTransform * in_position;
// PSC addition; local vertex position and the object power scaled world position
vs_position = psc_addition(vec4(local_vertex_pos,in_position.w),objpos);
//vs_position = psc_addition(lvp,objpos);
// PSC addition; rotated and viewscaled vertex and the cmaeras negative position
vs_position = psc_addition(vs_position,vec4(-campos.xyz,campos.w));
// rotate the camera
local_vertex_pos = mat3(camrot) * vs_position.xyz;
vs_position = vec4(local_vertex_pos, vs_position.w);
//vs_position = camrot * vs_position;
vec2 scaling = vec2(1.0, -in_position.w);
// project using the rescaled coordinates,
//vec4 vs_position_rescaled = psc_scaling(vs_position, scaling);
vec4 vs_position_rescaled = psc_to_meter(vs_position, scaling);
//vs_position = vs_position_rescaled;
// project the position to view space
gl_Position = ViewProjection * vs_position_rescaled;
//gl_Position = view * model * vs_position_rescaled;
//distanceToStar = psc_subtraction(gl_Position, campos);
}

View File

@@ -129,7 +129,7 @@ source_group(Interface FILES ${INTERFACE_SOURCE} ${INTERFACE_HEADER})
include_directories(${HEADER_ROOT_DIR})
# hack:
set(OPENSPACE_SOURCE ${OPENSPACE_SOURCE} ${OPENSPACE_EXT_DIR}/tinythread.cpp)
#set(OPENSPACE_SOURCE ${OPENSPACE_SOURCE} ${OPENSPACE_EXT_DIR}/tinythread.cpp)
include_directories(${GHOUL_ROOT_DIR}/ext/boost)
find_package(OpenCL REQUIRED)

View File

@@ -344,6 +344,22 @@ bool OpenSpaceEngine::initialize() {
// TODO: Maybe move all scenegraph and renderengine stuff to initializeGL
scriptEngine().initialize();
// If a LuaDocumentationFile was specified, generate it now
using constants::configurationmanager::keyLuaDocumentationType;
using constants::configurationmanager::keyLuaDocumentationFile;
const bool hasType = configurationManager().hasKey(keyLuaDocumentationType);
const bool hasFile = configurationManager().hasKey(keyLuaDocumentationFile);
if (hasType && hasFile) {
std::string luaDocumentationType;
configurationManager().getValue(keyLuaDocumentationType, luaDocumentationType);
std::string luaDocumentationFile;
configurationManager().getValue(keyLuaDocumentationFile, luaDocumentationFile);
luaDocumentationFile = absPath(luaDocumentationFile);
_scriptEngine.writeDocumentation(luaDocumentationFile, luaDocumentationType);
}
// Load scenegraph
SceneGraph* sceneGraph = new SceneGraph;
_renderEngine.setSceneGraph(sceneGraph);

View File

@@ -0,0 +1,73 @@
/*****************************************************************************************
* *
* 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 <openspace/properties/optionproperty.h>
namespace {
const std::string _loggerCat = "OptionProperty";
}
namespace openspace {
namespace properties {
OptionProperty::OptionProperty(std::string identifier, std::string guiName)
: IntProperty(std::move(identifier), std::move(guiName))
{}
std::string OptionProperty::className() const {
return "OptionProperty";
}
const std::vector<OptionProperty::Option>& OptionProperty::options() const {
return _options;
}
void OptionProperty::addOption(Option option) {
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));
}
void OptionProperty::setValue(int value) {
// Check if the passed value belongs to any option
for (auto o : _options) {
if (o.value == value) {
// If it does, set it by calling the superclasses setValue method
NumericalProperty::setValue(value);
return;
}
}
// Otherwise, log an error
LERROR("Could not find an option for value '" << value << "' in OptionProperty");
}
} // namespace properties
} // namespace openspace

View File

@@ -94,6 +94,10 @@ RenderableModel::~RenderableModel(){
deinitialize();
}
bool RenderableModel::isReady() const {
return _programObject != nullptr;
}
bool RenderableModel::initialize(){
bool completeSuccess = true;
if (_programObject == nullptr)
@@ -176,4 +180,5 @@ void RenderableModel::loadTexture()
}
}
}
} // namespace openspace

View File

@@ -82,11 +82,9 @@ RenderablePlanet::RenderablePlanet(const ghoul::Dictionary& dictionary)
_colorTexturePath.onChange(std::bind(&RenderablePlanet::loadTexture, this));
}
RenderablePlanet::~RenderablePlanet(){
deinitialize();
}
RenderablePlanet::~RenderablePlanet() {}
bool RenderablePlanet::initialize(){
bool RenderablePlanet::initialize() {
bool completeSuccess = true;
if (_programObject == nullptr)
completeSuccess
@@ -99,7 +97,7 @@ bool RenderablePlanet::initialize(){
return completeSuccess;
}
bool RenderablePlanet::deinitialize(){
bool RenderablePlanet::deinitialize() {
_geometry->deinitialize();
delete _geometry;
_geometry = nullptr;
@@ -108,6 +106,10 @@ bool RenderablePlanet::deinitialize(){
return true;
}
bool RenderablePlanet::isReady() const {
return (_geometry != nullptr);
}
void RenderablePlanet::render(const RenderData& data)
{
if (!_programObject) return;

View File

@@ -118,4 +118,8 @@ bool Renderable::isVisible() const {
return _enabled;
}
bool Renderable::isReady() const {
return true;
}
} // namespace openspace

View File

@@ -128,6 +128,10 @@ RenderableEphemeris::~RenderableEphemeris(){
deinitialize();
}
bool RenderableEphemeris::isReady() const {
return _programObject != nullptr;
}
bool RenderableEphemeris::initialize(){
bool completeSuccess = true;
if (_programObject == nullptr)
@@ -312,4 +316,5 @@ void RenderableEphemeris::loadTexture()
}
}
}

View File

@@ -26,32 +26,30 @@
#include <openspace/engine/openspaceengine.h>
#include <openspace/util/powerscaledcoordinate.h>
#include <openspace/util/kameleonwrapper.h>
#include <openspace/util/constants.h>
#include <ghoul/filesystem/file.h>
namespace {
const std::string _loggerCat = "RenderableFieldlines";
const std::string keyFieldlines = "Fieldlines";
const std::string keyFilename = "File";
const std::string keyHints = "Hints";
const std::string keyShaders = "Shaders";
const std::string keyVertexShader = "VertexShader";
const std::string keyFragmentShader = "FragmentShader";
}
namespace openspace {
RenderableFieldlines::RenderableFieldlines(const ghoul::Dictionary& dictionary)
: Renderable(dictionary)
, _VAO(0)
, _programUpdateOnSave(false)
, _update(false)
, _fieldlineVAO(0)
, _shader(nullptr)
{
std::string name;
bool success = dictionary.getValue(constants::scenegraphnode::keyName, name);
assert(success);
// Read fieldlines module into dictionary
ghoul::Dictionary fieldlines;
success = dictionary.getValue(keyFieldlines, fieldlines);
if (!success) {
@@ -84,75 +82,42 @@ RenderableFieldlines::RenderableFieldlines(const ghoul::Dictionary& dictionary)
}
}
ghoul::Dictionary shaderDictionary;
success = dictionary.getValue(keyShaders, shaderDictionary);
if (!success) {
LERROR("RenderableFieldlines '" << name << "' does not contain a '" <<
keyShaders << "' table");
return;
}
std::string vshaderpath;
success = shaderDictionary.getValue(keyVertexShader, vshaderpath);
if (!success) {
LERROR("RenderableFieldlines '" << name << "' does not have a '" <<
keyVertexShader << "'");
return;
}
vshaderpath = findPath(vshaderpath);
std::string fshaderpath;
success = shaderDictionary.getValue(keyFragmentShader, fshaderpath);
if (!success) {
LERROR("RenderableFieldlines '" << name << "' does not have a '" <<
keyFragmentShader << "'");
return;
}
fshaderpath = findPath(fshaderpath);
_vertexSourceFile = new ghoul::filesystem::File(vshaderpath, false);
_fragmentSourceFile = new ghoul::filesystem::File(fshaderpath, false);
_fieldlinesProgram = ghoul::opengl::ProgramObject::Build("FieldlinesProgram", vshaderpath, fshaderpath);
dictionary.getValue("UpdateOnSave", _programUpdateOnSave);
setBoundingSphere(PowerScaledScalar::CreatePSS(5)); // FIXME a non-magic number perhaps
setBoundingSphere(PowerScaledScalar::CreatePSS(250.f*6371000.f)); // FIXME a non-magic number perhaps
}
RenderableFieldlines::~RenderableFieldlines() {
}
bool RenderableFieldlines::isReady() const {
return _shader != nullptr;
}
bool RenderableFieldlines::initialize() {
assert(_filenames.size() != 0);
assert(_hintsDictionaries.size() != 0);
int prevEnd = 0;
std::vector<LinePoint> vertexData, seedPointsData;
std::vector<LinePoint> vertexData;
std::vector<std::vector<LinePoint> > fieldlinesData;
glm::vec4 seedPointsColor = glm::vec4(1.0, 0.5, 0.0, 1.0);
// Read data from fieldlines dictionary
for (int i = 0; i < _filenames.size(); ++i) {
fieldlinesData = getFieldlinesData(_filenames[i], _hintsDictionaries[i]);
// Arrange data for glMultiDrawArrays
for (int j = 0; j < fieldlinesData.size(); ++j) {
_lineStart.push_back(prevEnd);
_lineCount.push_back(fieldlinesData[j].size());
prevEnd = prevEnd + fieldlinesData[j].size();
vertexData.insert( vertexData.end(), fieldlinesData[j].begin(), fieldlinesData[j].end());
}
// Give seedpoints a color for visualizing as GL_POINTS
for (glm::vec3 seedPoint : _seedPoints) {
seedPointsData.push_back(LinePoint(seedPoint, seedPointsColor));
}
}
LDEBUG("Number of vertices : " << vertexData.size());
// ------ FIELDLINES -----------------
GLuint vertexPositionBuffer;
glGenVertexArrays(1, &_VAO); // generate array
glBindVertexArray(_VAO); // bind array
glGenVertexArrays(1, &_fieldlineVAO); // generate array
glBindVertexArray(_fieldlineVAO); // bind array
glGenBuffers(1, &vertexPositionBuffer); // generate buffer
glBindBuffer(GL_ARRAY_BUFFER, vertexPositionBuffer); // bind buffer
glBufferData(GL_ARRAY_BUFFER, vertexData.size()*sizeof(LinePoint), &vertexData.front(), GL_STATIC_DRAW);
@@ -162,46 +127,16 @@ bool RenderableFieldlines::initialize() {
glEnableVertexAttribArray(vertexLocation);
glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, sizeof(LinePoint), reinterpret_cast<void*>(0));
// Texture coordinates
GLuint texcoordLocation = 1;
glEnableVertexAttribArray(texcoordLocation);
glVertexAttribPointer(texcoordLocation, 4, GL_FLOAT, GL_FALSE, sizeof(LinePoint), (void*)(sizeof(glm::vec3)));
// Vertex colors
GLuint colorLocation = 1;
glEnableVertexAttribArray(colorLocation);
glVertexAttribPointer(colorLocation, 4, GL_FLOAT, GL_FALSE, sizeof(LinePoint), (void*)(sizeof(glm::vec3)));
glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind buffer
glBindVertexArray(0); //unbind array
// ------ SEEDPOINTS -----------------
GLuint seedpointPositionBuffer;
glGenVertexArrays(1, &_seedpointVAO); // generate array
glBindVertexArray(_seedpointVAO); // bind array
glGenBuffers(1, &seedpointPositionBuffer); // generate buffer
glBindBuffer(GL_ARRAY_BUFFER, seedpointPositionBuffer); // bind buffer
glBufferData(GL_ARRAY_BUFFER, seedPointsData.size()*sizeof(LinePoint), &seedPointsData.front(), GL_STATIC_DRAW);
// Vertex positions
glEnableVertexAttribArray(vertexLocation);
glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, sizeof(LinePoint), reinterpret_cast<void*>(0));
// Texture coordinates
glEnableVertexAttribArray(texcoordLocation);
glVertexAttribPointer(texcoordLocation, 4, GL_FLOAT, GL_FALSE, sizeof(LinePoint), (void*)(3*sizeof(float)));
glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind buffer
glBindVertexArray(0); //unbind array
glPointSize(5); // size of seedpoints
// ------ SETUP SHADERS -----------------
auto privateCallback = [this](const ghoul::filesystem::File& file) {
_update = true;
};
if(_programUpdateOnSave) {
_vertexSourceFile->setCallback(privateCallback);
_fragmentSourceFile->setCallback(privateCallback);
}
_fieldlinesProgram->compileShaderObjects();
_fieldlinesProgram->linkProgramObject();
OsEng.ref().configurationManager().getValue("FieldlineProgram", _shader);
assert(_shader);
return true;
}
@@ -211,57 +146,30 @@ bool RenderableFieldlines::deinitialize() {
}
void RenderableFieldlines::render(const RenderData& data) {
if(_update) {
_update = false;
safeShaderCompilation();
}
if (!_shader)
return;
_shader->activate();
_shader->setUniform("modelViewProjection", data.camera.viewProjectionMatrix());
_shader->setUniform("modelTransform", glm::mat4(1.0));
_shader->setUniform("cameraViewDir", data.camera.viewDirection());
setPscUniforms(_shader, &data.camera, data.position);
glm::mat4 transform = data.camera.viewProjectionMatrix();
glm::mat4 camTransform = data.camera.viewRotationMatrix();
//psc relative = data.position - data.camera.position();
// ------ DRAW FIELDLINES -----------------
glBindVertexArray(_fieldlineVAO);
glMultiDrawArrays(GL_LINE_STRIP_ADJACENCY, &_lineStart[0], &_lineCount[0], _lineStart.size());
transform = transform*camTransform;
transform = glm::mat4(1.0);
transform = glm::scale(transform, glm::vec3(0.01));
// Activate shader
_fieldlinesProgram->activate();
_fieldlinesProgram->setUniform("modelViewProjection", data.camera.viewProjectionMatrix());
_fieldlinesProgram->setUniform("modelTransform", transform);
setPscUniforms(_fieldlinesProgram, &data.camera, data.position);
// ------ FIELDLINES -----------------
glBindVertexArray(_VAO);
glMultiDrawArrays(GL_LINE_STRIP, &_lineStart[0], &_lineCount[0], _lineStart.size());
// // ------ SEEDPOINTS -----------------
// glBindVertexArray(_seedpointVAO);
// glMultiDrawArrays(GL_POINTS, &_lineStart[0], &_lineCount[0], _seedPoints.size());
glBindVertexArray(0);
// Deactivate shader
_fieldlinesProgram->deactivate();
}
void RenderableFieldlines::update(const UpdateData& data) {
}
void RenderableFieldlines::safeShaderCompilation() {
_fieldlinesProgram->rebuildFromFile();
_fieldlinesProgram->compileShaderObjects();
_fieldlinesProgram->linkProgramObject();
_shader->deactivate();
}
std::vector<std::vector<LinePoint> > RenderableFieldlines::getFieldlinesData(std::string filename, ghoul::Dictionary hintsDictionary) {
std::string modelString;
float stepSize = 0.5; // default if no stepsize is specified in hints
std::string xVariable, yVariable, zVariable;
std::string modelString, xVariable, yVariable, zVariable;
KameleonWrapper::Model model;
std::vector<std::vector<LinePoint> > fieldlinesData;
bool classification = false, lorentz = false;
glm::vec4 fieldlineColor = glm::vec4(1.0, 1.0, 1.0, 1.0); // default color if no color or classification is specified
float stepSize = 0.5; // default if no stepsize is specified in hints
if (hintsDictionary.hasKey("Model") && hintsDictionary.getValue("Model", modelString)) {
// ------ MODEL -----------------

View File

@@ -95,6 +95,10 @@ RenderableFov::~RenderableFov(){
deinitialize();
}
bool RenderableFov::isReady() const {
return _programObject != nullptr;
}
void RenderableFov::sendToGPU(){
// Initialize and upload to graphics card
glGenVertexArrays(1, &_vaoID);

View File

@@ -139,6 +139,11 @@ RenderablePath::~RenderablePath(){
deinitialize();
}
bool RenderablePath::isReady() const {
return _programObject != nullptr;
}
bool RenderablePath::initialize(){
bool completeSuccess = true;
if (_programObject == nullptr)

View File

@@ -90,6 +90,10 @@ RenderablePlane::RenderablePlane(const ghoul::Dictionary& dictionary)
RenderablePlane::~RenderablePlane() {
}
bool RenderablePlane::isReady() const {
return _shader != nullptr;
}
bool RenderablePlane::initialize() {
// ============================
@@ -121,12 +125,12 @@ bool RenderablePlane::initialize() {
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, reinterpret_cast<void*>(sizeof(GLfloat) * 4));
OsEng.ref().configurationManager().getValue("PlaneProgram", _shader);
assert(_shader);
if (!_shader)
return false;
loadTexture();
return true;
}

View File

@@ -131,6 +131,10 @@ RenderableSphericalGrid::~RenderableSphericalGrid(){
deinitialize();
}
bool RenderableSphericalGrid::isReady() const {
return _gridProgram != nullptr;
}
bool RenderableSphericalGrid::deinitialize(){
return true;
}

View File

@@ -151,6 +151,10 @@ RenderableTrail::~RenderableTrail(){
deinitialize();
}
bool RenderableTrail::isReady() const {
return _programObject != nullptr;
}
void RenderableTrail::sendToGPU(){
// Initialize and upload to graphics card
glGenVertexArrays(1, &_vaoID);

View File

@@ -167,6 +167,11 @@ RenderableVolumeGL::~RenderableVolumeGL() {
delete _transferFunction;
}
bool RenderableVolumeGL::isReady() const {
// @TODO needs a proper isReady definition --abock
return true;
}
bool RenderableVolumeGL::initialize() {
// TODO: fix volume an transferfunction names
if(_filename != "") {

View File

@@ -22,359 +22,504 @@
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
//standard includes
#include <iostream>
#include <fstream>
#include <limits>
#include <vector>
#include <iomanip>
#include <iterator>
// openspace includes
#include <openspace/rendering/stars/renderablestars.h>
#include <openspace/util/constants.h>
#include <openspace/util/spicemanager.h>
#include <openspace/util/constants.h>
#include <ghoul/filesystem/filesystem>
#include <ghoul/misc/templatefactory.h>
#include <ghoul/opengl/texturereader.h>
#include <ghoul/opengl/textureunit.h>
#include <ghoul/filesystem/filesystem.h>
#include <openspace/engine/openspaceengine.h>
#include <sgct.h>
#define _USE_MATH_DEFINES
#include <math.h>
#define GLSPRITES
//#define GLPOINTS
#include <array>
#include <fstream>
#include <stdint.h>
namespace {
const std::string _loggerCat = "RenderableStars";
const int8_t CurrentCacheVersion = 1;
struct ColorVBOLayout {
std::array<float, 4> position; // (x,y,z,e)
float bvColor; // B-V color value
float luminance;
float absoluteMagnitude;
};
struct VelocityVBOLayout {
std::array<float, 4> position; // (x,y,z,e)
float bvColor; // B-V color value
float luminance;
float absoluteMagnitude;
float vx; // v_x
float vy; // v_y
float vz; // v_z
};
struct SpeedVBOLayout {
std::array<float, 4> position; // (x,y,z,e)
float bvColor; // B-V color value
float luminance;
float absoluteMagnitude;
float speed;
};
}
namespace openspace {
RenderableStars::RenderableStars(const ghoul::Dictionary& dictionary)
: Renderable(dictionary)
, _colorTexturePath("colorTexture", "Color Texture")
, _haloProgram(nullptr)
, _pointProgram(nullptr)
, _texture(nullptr)
, _textureIsDirty(true)
, _colorOption("colorOption", "Color Option")
, _dataIsDirty(true)
, _spriteSize("spriteSize", "Sprite Size", 0.0000005f, 0.f, 1.f)
, _program(nullptr)
, _programIsDirty(false)
, _speckFile("")
, _nValuesPerStar(0)
, _vao(0)
, _vbo(0)
{
std::string path;
dictionary.getValue(constants::renderablestars::keyPathModule, path);
std::string texturePath = "";
if (dictionary.hasKey("Textures.Color")) {
dictionary.getValue("Textures.Color", texturePath);
_colorTexturePath = path + "/" + texturePath;
if (dictionary.hasKey(constants::renderablestars::keyTexture)) {
dictionary.getValue(constants::renderablestars::keyTexture, texturePath);
_colorTexturePath = absPath(texturePath);
}
dictionary.getValue(constants::renderablestars::keySpeckFile, path);
_speckPath = FileSys.absolutePath(path);
bool success = dictionary.getValue(constants::renderablestars::keyFile, _speckFile);
if (!success) {
LERROR("SpeckDataSource did not contain key '" <<
constants::renderablestars::keyFile << "'");
return;
}
_speckFile = absPath(_speckFile);
_colorOption.addOption({ColorOption::Color, "Color"});
_colorOption.addOption({ColorOption::Velocity, "Velocity"});
_colorOption.addOption({ColorOption::Speed, "Speed"});
addProperty(_colorOption);
_colorOption.onChange([&]{ _dataIsDirty = true;});
addProperty(_spriteSize);
addProperty(_colorTexturePath);
_colorTexturePath.onChange(std::bind(&RenderableStars::loadTexture, this));
_colorTexturePath.onChange([&]{ _textureIsDirty = true;});
}
RenderableStars::~RenderableStars(){
glDeleteBuffers(1, &_vboID);
glDeleteVertexArrays(1, &_vaoID);
deinitialize();
bool RenderableStars::isReady() const {
return (_program != nullptr) && (_fullData.size() > 0);
}
std::ifstream& RenderableStars::skipToLine(std::ifstream& file, unsigned int num){
file.seekg(std::ios::beg);
for (size_t i = 0; i < num - 1; ++i){
file.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
return file;
}
//#define ROTATESTARS
bool RenderableStars::readSpeckFile(const std::string& path){
bool readCache = false;
std::ifstream file;
std::string str, starDescription, datastr;
std::vector<std::string> strvec;
std::vector<float> starcluster;
std::vector<float> floatingPointData;
int count = 0;
const std::string absPath = FileSys.absolutePath(path);
std::string::size_type last
= absPath.find_last_of(ghoul::filesystem::FileSystem::PathSeparator);
if (last == std::string::npos) return false;
std::string cacheName = absPath.substr(last + 1, absPath.size() - absPath.rfind('.') - 1);
std::string basePath = absPath.substr(0, last);
cacheName = basePath + "\\" + cacheName + ".bin";
//if (!FileSys.fileExists(cacheName)){
if (!readCache){ // dumb boolean for now.
std::ofstream cache;
cache.open(cacheName, std::ios::binary);
file.open(absPath);
if (!file.is_open()){
LERROR("Failed to open spec file for : '" << path << "'");
return false;
}
// count metadata lines to skip.
do{
getline(file, str);
count++;
} while (str[0] != ' ');
// set seek pointer to first line with actual data
skipToLine(file, count);
count = 0;
do{
getline(file, str);
if (file.eof()) break;
// split the line on pound symbol. we only want data.
std::size_t mid = str.find('#');
if (mid != std::string::npos){
datastr = str.substr(0, mid);
std::size_t end = str.find('\n');
if (end == std::string::npos)
starDescription = str.substr(mid, end);
}
// split data string on whitespace -> push to to vector
std::istringstream ss(datastr);
std::copy(std::istream_iterator<std::string>(ss),
std::istream_iterator<std::string>(),
std::back_inserter<std::vector<std::string> >(strvec));
ss.clear();
// conv. string vector to doubles
floatingPointData.reserve(strvec.size());
transform(strvec.begin(), strvec.end(), back_inserter(floatingPointData),
[](std::string const& val) {return std::stod(val); });
// store data concerning apparent luminocity, brigthness etc.
// convert to powerscaled coordinate
psc powerscaled = PowerScaledCoordinate::CreatePowerScaledCoordinate(floatingPointData[0],
floatingPointData[1],
floatingPointData[2]);
// Convert parsecs -> meter
// Could convert floatingPointData instead ??
// (possible as 3.4 × 10^38 is max rep nr of float)
PowerScaledScalar parsecsToMetersFactor = glm::vec2(0.308567758, 17);
powerscaled[0] *= parsecsToMetersFactor[0];
powerscaled[1] *= parsecsToMetersFactor[0];
powerscaled[2] *= parsecsToMetersFactor[0];
powerscaled[3] += parsecsToMetersFactor[1];
#ifdef ROTATESTARS
glm::mat4 transform = glm::mat4(1);
glm::dmat3 stateMatrix;
double initTime = 0;
openspace::SpiceManager::ref().getPositionTransformMatrixGLM("GALACTIC", "IAU_EARTH", 0, stateMatrix);
for (int i = 0; i < 3; i++){
for (int j = 0; j < 3; j++){
transform[i][j] = stateMatrix[i][j];
}
}
glm::vec4 tmp(powerscaled[0], powerscaled[1], powerscaled[2], powerscaled[3] );
tmp = transform*tmp;
powerscaled[0] = tmp[0];
powerscaled[1] = tmp[1];
powerscaled[2] = tmp[2];
powerscaled[3] = tmp[3];
#endif
// We use std::vector to store data
// needs no preallocation and has tightly packed arr.
for (int i = 0; i < 4; i++){
starcluster.push_back(powerscaled[i]);
cache << ' ' << powerscaled[i];
}
// will need more elegant solution here.
starcluster.push_back(floatingPointData[3]);
starcluster.push_back(floatingPointData[4]);
starcluster.push_back(floatingPointData[5]);
strvec.clear();
floatingPointData.clear();
count++;
} while (file.good());
}else{
LINFO("Found cached data, loading");
file.open(cacheName, std::ios::binary);
while (file.good()){
if (file.eof()) break;
count++;
float cachedValue;
file >> cachedValue;
starcluster.push_back(cachedValue);
}
}
v_stride = 7; // stride in VBO, set manually for now.
v_size = static_cast<int>(starcluster.size()); // size of VBO
v_total = v_size / v_stride; // total number of vertecies
// create vao and interleaved vbo from vectors internal array
generateBufferObjects(&starcluster[0]);
return true;
}
void RenderableStars::generateBufferObjects(const void* data){
// generate and buffer data
glGenVertexArrays(1, &_vaoID);
glGenBuffers(1, &_vboID);
glBindVertexArray(_vaoID);
glBindBuffer(GL_ARRAY_BUFFER, _vboID);
glBufferData(GL_ARRAY_BUFFER, v_size*sizeof(GLfloat), data, GL_STATIC_DRAW); // order : x, y, z, lum, appmag, absmag
positionAttrib = _haloProgram->attributeLocation( "in_position" );
brightnessDataAttrib = _haloProgram->attributeLocation( "in_brightness" );
GLint postest = _pointProgram->attributeLocation("in_position");
GLint britest = _pointProgram->attributeLocation("in_brightness");
assert(postest == positionAttrib); // assume pointer locations same for both programs.
assert(britest == brightnessDataAttrib);
GLsizei stride = sizeof(GLfloat) * v_stride;
glBindVertexArray(_vaoID); // vao holds ref. to vbo
glBindBuffer(GL_ARRAY_BUFFER, _vboID); // bind vbo
glEnableVertexAttribArray(positionAttrib); // enable acess attribute in_position
glEnableVertexAttribArray(brightnessDataAttrib); // enable acess attribute in_brigthness
glVertexAttribPointer(positionAttrib, 4, GL_FLOAT, GL_FALSE, stride, (void*)0); // psc coordinates
glVertexAttribPointer(brightnessDataAttrib, 3, GL_FLOAT, GL_FALSE, stride, (void*)(4 * sizeof(GLfloat))); // brigthness properties
glBindBuffer(GL_ARRAY_BUFFER, 0); // unbind
glBindVertexArray(0);
}
bool RenderableStars::initialize(){
bool RenderableStars::initialize() {
bool completeSuccess = true;
// 1. StarProgram - Generates quads with png image of halo
if (_haloProgram == nullptr)
completeSuccess &= OsEng.ref().configurationManager().getValue("StarProgram", _haloProgram);
_program = ghoul::opengl::ProgramObject::Build("Star",
"${SHADERS}/star_vs.glsl",
"${SHADERS}/star_fs.glsl",
"${SHADERS}/star_ge.glsl",
[&](ghoul::opengl::ProgramObject*){ _programIsDirty = true;});
// 2. PointProgram - Generates gl_Points in geom shader.
if (_pointProgram == nullptr)
completeSuccess &= OsEng.ref().configurationManager().getValue("PointProgram", _pointProgram);
// Run read star-datafile routine.
if (!readSpeckFile(_speckPath))
LERROR("Failed to read speck file for path : '" << _speckPath << "'");
loadTexture();
completeSuccess = (_program != nullptr);
completeSuccess &= loadData();
completeSuccess &= (_texture != nullptr);
return completeSuccess;
}
bool RenderableStars::deinitialize(){
bool RenderableStars::deinitialize() {
glDeleteBuffers(1, &_vbo);
_vbo = 0;
glDeleteVertexArrays(1, &_vao);
_vao = 0;
delete _texture;
_texture = nullptr;
delete _program;
_program = nullptr;
return true;
}
//#define TMAT
void RenderableStars::render(const RenderData& data){
if(!_haloProgram)
return;
if(!_texture)
return;
assert(_haloProgram);
//printOpenGLError();
// activate shader
_haloProgram->activate();
void RenderableStars::render(const RenderData& data) {
_program->activate();
// fetch data
//scaling = glm::vec2(1, -22);
// @Check overwriting the scaling from the camera; error as parsec->meter conversion
// is done twice? ---abock
glm::vec2 scaling = glm::vec2(1, -19);
#ifdef TMAT
transform = glm::rotate(transform,
1.1f * static_cast<float>(sgct::Engine::instance()->getTime()),
glm::vec3(0.0f, 1.0f, 0.0f));
#endif
// disable depth test, enable additative blending
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ONE);
#ifdef GLSPRITES
glm::mat4 modelMatrix = data.camera.modelMatrix();
glm::mat4 viewMatrix = data.camera.viewMatrix();
glm::mat4 projectionMatrix = data.camera.projectionMatrix();
// ---------------------- RENDER HALOS -----------------------------
_haloProgram->setUniform("model", modelMatrix);
_haloProgram->setUniform("view", viewMatrix);
_haloProgram->setUniform("projection", projectionMatrix);
_program->setUniform("model", modelMatrix);
_program->setUniform("view", viewMatrix);
_program->setUniform("projection", projectionMatrix);
//_haloProgram->setUniform("ViewProjection", camera->viewProjectionMatrix());
_haloProgram->setUniform("ModelTransform", glm::mat4(1));
setPscUniforms(_haloProgram, &data.camera, data.position);
_haloProgram->setUniform("scaling", scaling);
_program->setUniform("colorOption", _colorOption);
setPscUniforms(_program, &data.camera, data.position);
_program->setUniform("scaling", scaling);
_program->setUniform("spriteSize", _spriteSize);
// Bind texure
ghoul::opengl::TextureUnit unit;
unit.activate();
_texture->bind();
_haloProgram->setUniform("texture1", unit);
_program->setIgnoreUniformLocationError(true);
_program->setUniform("texture1", unit);
_program->setIgnoreUniformLocationError(false);
// activate the VBO.
glBindVertexArray(_vaoID);
glDrawArrays(GL_POINTS, 0, v_total);
glBindVertexArray(_vao);
const GLsizei nStars = static_cast<GLsizei>(_fullData.size() / _nValuesPerStar);
glDrawArrays(GL_POINTS, 0, nStars);
glBindVertexArray(0);
#endif
_haloProgram->deactivate();
#ifdef GLPOINTS
// ---------------------- RENDER POINTS -----------------------------
_pointProgram->activate();
_pointProgram->setUniform("ViewProjection", data.camera.viewProjectionMatrix);
_pointProgram->setUniform("ModelTransform", transform);
_pointProgram->setUniform("campos", campos.vec4());
_pointProgram->setUniform("objpos", currentPosition.vec4());
_pointProgram->setUniform("camrot", camrot);
//_pointProgram->setUniform("scaling", scaling.vec2());
glEnable(GL_PROGRAM_POINT_SIZE_EXT); // Allows shader to determine pointsize.
//glEnable(GL_POINT_SMOOTH); // decrepated in core profile, workaround in frag.
glBindVertexArray(_vaoID);
glDrawArrays(GL_POINTS, 0, v_total*7);
glBindVertexArray(0);
glDisable(GL_BLEND);
_pointProgram->deactivate();
glEnable(GL_DEPTH_TEST);
#endif
glDisable(GL_BLEND);
_program->deactivate();
}
void RenderableStars::loadTexture(){
delete _texture;
_texture = nullptr;
if (_colorTexturePath.value() != "") {
_texture = ghoul::opengl::loadTexture(absPath(_colorTexturePath));
if (_texture) {
LDEBUG("Loaded texture from '" << absPath(_colorTexturePath) << "'");
_texture->uploadTexture();
void RenderableStars::update(const UpdateData& data) {
if (_programIsDirty) {
_program->rebuildFromFile();
_dataIsDirty = true;
_programIsDirty = false;
}
if (_dataIsDirty) {
const int value = _colorOption;
LDEBUG("Regenerating data");
createDataSlice(ColorOption(value));
int size = static_cast<int>(_slicedData.size());
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,
size*sizeof(GLfloat),
&_slicedData[0],
GL_STATIC_DRAW);
GLint positionAttrib = _program->attributeLocation("in_position");
GLint brightnessDataAttrib = _program->attributeLocation("in_brightness");
const size_t nStars = _fullData.size() / _nValuesPerStar;
const size_t nValues = _slicedData.size() / nStars;
GLsizei stride = static_cast<GLsizei>(sizeof(GLfloat) * nValues);
glEnableVertexAttribArray(positionAttrib);
glEnableVertexAttribArray(brightnessDataAttrib);
const int colorOption = _colorOption;
switch (colorOption) {
case ColorOption::Color:
glVertexAttribPointer(positionAttrib, 4, GL_FLOAT, GL_FALSE, stride,
reinterpret_cast<void*>(offsetof(ColorVBOLayout, position)));
glVertexAttribPointer(brightnessDataAttrib, 3, GL_FLOAT, GL_FALSE, stride,
reinterpret_cast<void*>(offsetof(ColorVBOLayout, bvColor)));
break;
case ColorOption::Velocity:
{
glVertexAttribPointer(positionAttrib, 4, GL_FLOAT, GL_FALSE, stride,
reinterpret_cast<void*>(offsetof(VelocityVBOLayout, position)));
glVertexAttribPointer(brightnessDataAttrib, 3, GL_FLOAT, GL_FALSE, stride,
reinterpret_cast<void*>(offsetof(VelocityVBOLayout, bvColor)));
GLint velocityAttrib = _program->attributeLocation("in_velocity");
glEnableVertexAttribArray(velocityAttrib);
glVertexAttribPointer(velocityAttrib, 3, GL_FLOAT, GL_TRUE, stride,
reinterpret_cast<void*>(offsetof(VelocityVBOLayout, vx)));
break;
}
case ColorOption::Speed:
{
glVertexAttribPointer(positionAttrib, 4, GL_FLOAT, GL_FALSE, stride,
reinterpret_cast<void*>(offsetof(SpeedVBOLayout, position)));
glVertexAttribPointer(brightnessDataAttrib, 3, GL_FLOAT, GL_FALSE, stride,
reinterpret_cast<void*>(offsetof(SpeedVBOLayout, bvColor)));
GLint speedAttrib = _program->attributeLocation("in_speed");
glEnableVertexAttribArray(speedAttrib);
glVertexAttribPointer(speedAttrib, 1, GL_FLOAT, GL_TRUE, stride,
reinterpret_cast<void*>(offsetof(SpeedVBOLayout, speed)));
}
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
_dataIsDirty = false;
}
if (_textureIsDirty) {
LDEBUG("Reloading texture");
delete _texture;
_texture = nullptr;
if (_colorTexturePath.value() != "") {
_texture = ghoul::opengl::loadTexture(absPath(_colorTexturePath));
if (_texture) {
LDEBUG("Loaded texture from '" << absPath(_colorTexturePath) << "'");
_texture->uploadTexture();
}
}
_textureIsDirty = false;
}
}
bool RenderableStars::loadData() {
std::string _file = _speckFile;
std::string cachedFile = "";
FileSys.cacheManager()->getCachedFile(_file, cachedFile, true);
bool hasCachedFile = FileSys.fileExists(cachedFile);
if (hasCachedFile) {
LINFO("Cached file '" << cachedFile << "' used for Speck file '" << _file << "'");
bool success = loadCachedFile(cachedFile);
if (success)
return true;
else
FileSys.cacheManager()->removeCacheFile(_file);
// Intentional fall-through to the 'else' computation to generate the cache
// file for the next run
}
else {
LINFO("Cache for Speck file '" << _file << "' not found");
}
LINFO("Loading Speck file '" << _file << "'");
bool success = readSpeckFile();
if (!success)
return false;
LINFO("Saving cache");
success = saveCachedFile(cachedFile);
return success;
}
bool RenderableStars::readSpeckFile() {
std::string _file = _speckFile;
std::ifstream file(_file);
if (!file.good()) {
LERROR("Failed to open Speck file '" << _file << "'");
return false;
}
_nValuesPerStar = 0;
// The beginning of the speck file has a header that either contains comments
// (signaled by a preceding '#') or information about the structure of the file
// (signaled by the keywords 'datavar', 'texturevar', and 'texture')
std::string line = "";
while (true) {
std::ifstream::streampos position = file.tellg();
std::getline(file, line);
if (line[0] == '#')
continue;
if (line.substr(0, 7) != "datavar" &&
line.substr(0, 10) != "texturevar" &&
line.substr(0, 7) != "texture")
{
// we read a line that doesn't belong to the header, so we have to jump back
// before the beginning of the current line
file.seekg(position);
break;
}
if (line.substr(0, 7) == "datavar") {
// datavar lines are structured as follows:
// datavar # description
// where # is the index of the data variable; so if we repeatedly overwrite
// the 'nValues' variable with the latest index, we will end up with the total
// number of values (+3 since X Y Z are not counted in the Speck file index)
std::stringstream str(line);
std::string dummy;
str >> dummy;
str >> _nValuesPerStar;
_nValuesPerStar += 1; // We want the number, but the index is 0 based
}
}
_nValuesPerStar += 3; // X Y Z are not counted in the Speck file indices
do {
std::vector<float> values(_nValuesPerStar);
std::getline(file, line);
std::stringstream str(line);
for (int i = 0; i < _nValuesPerStar; ++i)
str >> values[i];
_fullData.insert(_fullData.end(), values.begin(), values.end());
} while (!file.eof());
return true;
}
bool RenderableStars::loadCachedFile(const std::string& file) {
std::ifstream fileStream(file, 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, deleted old cache");
fileStream.close();
FileSys.deleteFile(file);
return false;
}
int32_t nValues = 0;
fileStream.read(reinterpret_cast<char*>(&nValues), sizeof(int32_t));
fileStream.read(reinterpret_cast<char*>(&_nValuesPerStar), sizeof(int32_t));
_fullData.resize(nValues);
fileStream.read(reinterpret_cast<char*>(&_fullData[0]),
nValues * sizeof(_fullData[0]));
bool success = fileStream.good();
return success;
}
else {
LERROR("Error opening file '" << file << "' for loading cache file");
return false;
}
}
bool RenderableStars::saveCachedFile(const std::string& file) const {
std::ofstream fileStream(file, std::ofstream::binary);
if (fileStream.good()) {
fileStream.write(reinterpret_cast<const char*>(&CurrentCacheVersion),
sizeof(int8_t));
int32_t nValues = static_cast<int32_t>(_fullData.size());
if (nValues == 0) {
LERROR("Error writing cache: No values were loaded");
return false;
}
fileStream.write(reinterpret_cast<const char*>(&nValues), sizeof(int32_t));
int32_t nValuesPerStar = static_cast<int32_t>(_nValuesPerStar);
fileStream.write(reinterpret_cast<const char*>(&nValuesPerStar), sizeof(int32_t));
size_t nBytes = nValues * sizeof(_fullData[0]);
fileStream.write(reinterpret_cast<const char*>(&_fullData[0]), nBytes);
bool success = fileStream.good();
return success;
}
else {
LERROR("Error opening file '" << file << "' for save cache file");
return false;
}
}
void RenderableStars::createDataSlice(ColorOption option) {
_slicedData.clear();
for (size_t i = 0; i < _fullData.size(); i+=_nValuesPerStar) {
psc position = PowerScaledCoordinate::CreatePowerScaledCoordinate(
_fullData[i + 0],
_fullData[i + 1],
_fullData[i + 2]
);
// Convert parsecs -> meter
PowerScaledScalar parsecsToMetersFactor = PowerScaledScalar(0.308567758f, 17.f);
position[0] *= parsecsToMetersFactor[0];
position[1] *= parsecsToMetersFactor[0];
position[2] *= parsecsToMetersFactor[0];
position[3] += parsecsToMetersFactor[1];
switch (option) {
case ColorOption::Color:
{
union {
ColorVBOLayout value;
std::array<float, sizeof(ColorVBOLayout)> data;
} layout;
layout.value.position = { {
position[0], position[1], position[2], position[3]
} };
layout.value.bvColor = _fullData[i + 3];
layout.value.luminance = _fullData[i + 4];
layout.value.absoluteMagnitude = _fullData[i + 5];
_slicedData.insert(_slicedData.end(),
layout.data.begin(),
layout.data.end());
break;
}
case ColorOption::Velocity:
{
union {
VelocityVBOLayout value;
std::array<float, sizeof(VelocityVBOLayout)> data;
} layout;
layout.value.position = { {
position[0], position[1], position[2], position[3]
} };
layout.value.bvColor = _fullData[i + 3];
layout.value.luminance = _fullData[i + 4];
layout.value.absoluteMagnitude = _fullData[i + 5];
layout.value.vx = _fullData[i + 12];
layout.value.vy = _fullData[i + 13];
layout.value.vz = _fullData[i + 14];
_slicedData.insert(_slicedData.end(),
layout.data.begin(),
layout.data.end());
break;
}
case ColorOption::Speed:
{
union {
SpeedVBOLayout value;
std::array<float, sizeof(SpeedVBOLayout)> data;
} layout;
layout.value.position = { {
position[0], position[1], position[2], position[3]
} };
layout.value.bvColor = _fullData[i + 3];
layout.value.luminance = _fullData[i + 4];
layout.value.absoluteMagnitude = _fullData[i + 5];
layout.value.speed = _fullData[i + 15];
_slicedData.insert(_slicedData.end(),
layout.data.begin(),
layout.data.end());
break;
}
}
}
}
void RenderableStars::update(const UpdateData& data)
{
}
}
} // namespace openspace

View File

@@ -192,26 +192,6 @@ bool SceneGraph::initialize()
_programs.push_back(tmpProgram);
OsEng.ref().configurationManager().setValue("RaycastProgram", tmpProgram);
// Star program
tmpProgram = ProgramObject::Build("Star",
"${SHADERS}/star_vs.glsl",
"${SHADERS}/star_fs.glsl",
"${SHADERS}/star_ge.glsl",
cb);
if (!tmpProgram) return false;
_programs.push_back(tmpProgram);
OsEng.ref().configurationManager().setValue("StarProgram", tmpProgram);
// Point program
tmpProgram = ProgramObject::Build("Point",
"${SHADERS}/star_vs.glsl",
"${SHADERS}/star_fs.glsl",
"${SHADERS}/star_ge.glsl",
cb);
if (!tmpProgram) return false;
_programs.push_back(tmpProgram);
OsEng.ref().configurationManager().setValue("PointProgram", tmpProgram);
// Grid program
tmpProgram = ProgramObject::Build("Grid",
"${SHADERS}/grid_vs.glsl",
@@ -230,32 +210,15 @@ bool SceneGraph::initialize()
_programs.push_back(tmpProgram);
OsEng.ref().configurationManager().setValue("PlaneProgram", tmpProgram);
// pscColorToTexture program
tmpProgram = ProgramObject::Build("pscColorToTexture",
"${SHADERS}/pscColorToTexture_vs.glsl",
"${SHADERS}/pscColorToTexture_fs.glsl",
// Fieldline program
tmpProgram = ProgramObject::Build("Fieldline",
"${SHADERS}/fieldline_vs.glsl",
"${SHADERS}/fieldline_fs.glsl",
"${SHADERS}/fieldline_gs.glsl",
cb);
if (!tmpProgram) return false;
_programs.push_back(tmpProgram);
OsEng.ref().configurationManager().setValue("pscColorToTexture", tmpProgram);
// pscTextureToABuffer program
tmpProgram = ProgramObject::Build("pscTextureToABuffer",
"${SHADERS}/pscTextureToABuffer_vs.glsl",
"${SHADERS}/pscTextureToABuffer_fs.glsl",
cb);
if (!tmpProgram) return false;
_programs.push_back(tmpProgram);
OsEng.ref().configurationManager().setValue("pscTextureToABuffer", tmpProgram);
// pscColorPassthrough program
tmpProgram = ProgramObject::Build("pscColorPassthrough",
"${SHADERS}/pscColorPassthrough_vs.glsl",
"${SHADERS}/pscColorPassthrough_fs.glsl",
cb);
if (!tmpProgram) return false;
_programs.push_back(tmpProgram);
OsEng.ref().configurationManager().setValue("pscColorPassthrough", tmpProgram);
OsEng.ref().configurationManager().setValue("FieldlineProgram", tmpProgram);
// Done building shaders
double elapsed = std::chrono::duration_cast<second_>(clock_::now()-beginning).count();
@@ -329,7 +292,10 @@ void SceneGraph::scheduleLoadSceneFile(const std::string& sceneDescriptionFilePa
}
void SceneGraph::clearSceneGraph() {
// deallocate the scene graph. Recursive deallocation will occur
for (auto node : _nodes)
node->deinitialize();
// deallocate the scene graph. Recursive deallocation will occur
delete _root;
_root = nullptr;

View File

@@ -175,7 +175,7 @@ void SceneGraphNode::update(const UpdateData& data)
{
if (_ephemeris)
_ephemeris->update(data);
if (_renderable)
if (_renderable && _renderable->isReady())
_renderable->update(data);
}
@@ -232,7 +232,7 @@ void SceneGraphNode::render(const RenderData& data)
return;
}*/
if (_renderableVisible && _renderable->isVisible()) {
if (_renderableVisible && _renderable->isVisible() && _renderable->isReady()) {
// LDEBUG("Render");
_renderable->render(newData);
}

View File

@@ -29,6 +29,7 @@
#include <ghoul/lua/lua_helper.h>
#include <fstream>
#include <iomanip>
namespace openspace {
@@ -208,14 +209,21 @@ void ScriptEngine::deinitialize() {
_state = nullptr;
}
void ScriptEngine::addLibrary(const ScriptEngine::LuaLibrary& library) {
void ScriptEngine::addLibrary(LuaLibrary library) {
auto sortFunc = [](const LuaLibrary::Function& lhs, const LuaLibrary::Function& rhs)
{
return lhs.name < rhs.name;
};
// do we have a library with the same name as the incoming one
auto it = std::find_if(_registeredLibraries.begin(), _registeredLibraries.end(),
[&library](const LuaLibrary& lib) { return lib.name == library.name; });
if (it == _registeredLibraries.end())
// If not, we can add it
_registeredLibraries.insert(library);
if (it == _registeredLibraries.end()) {
// If not, we can add it after we sorted it
std::sort(library.functions.begin(), library.functions.end(), sortFunc);
_registeredLibraries.insert(std::move(library));
}
else {
// otherwise, we merge the libraries
@@ -235,7 +243,10 @@ void ScriptEngine::addLibrary(const ScriptEngine::LuaLibrary& library) {
}
_registeredLibraries.erase(it);
_registeredLibraries.insert(merged);
// Sort the merged library before inserting it
std::sort(merged.functions.begin(), merged.functions.end(), sortFunc);
_registeredLibraries.insert(std::move(merged));
}
}
@@ -475,6 +486,55 @@ bool ScriptEngine::registerLuaLibrary(lua_State* state, const LuaLibrary& librar
return true;
}
bool ScriptEngine::writeDocumentation(const std::string& filename, const std::string& type) const {
if (type == "text") {
// The additional space between the longest function name and the descriptions
const size_t AdditionalSpace = 5;
LDEBUG("Writing Lua documentation of type '" << type <<
"' to file '" << filename << "'");
std::ofstream file(filename);
if (file.good()) {
auto concatenate = [](std::string library, std::string function) {
std::string total = "openspace.";
if (!library.empty())
total += std::move(library) + ".";
total += std::move(function);
return std::move(total);
};
// First iterate over all libraries and functions to find the longest
// combination so that can be used as the 'width' parameter for the output
// stream
size_t maxLength = 0;
for (auto library : _registeredLibraries) {
for (auto function : library.functions) {
std::string functionName = concatenate(library.name, function.name);
maxLength = std::max(maxLength, functionName.size());
}
}
maxLength += AdditionalSpace;
// Now write out the functions
for (auto library : _registeredLibraries) {
for (auto function : library.functions) {
std::string functionName = concatenate(library.name, function.name);
file << std::setw(maxLength) << std::left << functionName;
file << std::setw(0) << function.helpText << std::endl;
}
}
return true;
}
else {
LERROR("Could not open file '" << filename << "' for writing documentation");
return false;
}
}
else {
LERROR("Undefined type '" << type << "' for Lua documentation");
return false;
}
}
} // namespace scripting
} // namespace openspace

View File

@@ -46,6 +46,7 @@
namespace openspace {
std::string _loggerCat = "KameleonWrapper";
const float RE_TO_METER = 6371000;
KameleonWrapper::KameleonWrapper()
: _kameleon(nullptr)
@@ -400,15 +401,16 @@ KameleonWrapper::Fieldlines KameleonWrapper::getClassifiedFieldLines(
fLine = traceCartesianFieldline(xVar, yVar, zVar, seedPoint, stepSize, TraceDirection::FORWARD, forwardEnd);
bLine = traceCartesianFieldline(xVar, yVar, zVar, seedPoint, stepSize, TraceDirection::BACK, backEnd);
bLine.erase(bLine.begin());
bLine.insert(bLine.begin(), fLine.rbegin(), fLine.rend());
// classify
color = classifyFieldline(forwardEnd, backEnd);
// write colors
// write colors and convert positions to meter
std::vector<LinePoint> line;
for (glm::vec3 position : bLine) {
line.push_back(LinePoint(position, color));
line.push_back(LinePoint(RE_TO_METER*position, color));
}
fieldLines.push_back(line);
@@ -440,12 +442,13 @@ KameleonWrapper::Fieldlines KameleonWrapper::getFieldLines(
fLine = traceCartesianFieldline(xVar, yVar, zVar, seedPoint, stepSize, TraceDirection::FORWARD, forwardEnd);
bLine = traceCartesianFieldline(xVar, yVar, zVar, seedPoint, stepSize, TraceDirection::BACK, backEnd);
bLine.insert(bLine.begin(), fLine.rbegin(), fLine.rend());
bLine.erase(bLine.begin());
bLine.insert(bLine.begin(), fLine.rbegin(), fLine.rend());
// write colors
// write colors and convert positions to meter
std::vector<LinePoint> line;
for (glm::vec3 position : bLine) {
line.push_back(LinePoint(position, color));
line.push_back(LinePoint(RE_TO_METER*position, color));
}
fieldLines.push_back(line);
@@ -471,12 +474,17 @@ KameleonWrapper::Fieldlines KameleonWrapper::getLorentzTrajectories(
plusTraj = traceLorentzTrajectory(seedPoint, stepsize, 1.0);
minusTraj = traceLorentzTrajectory(seedPoint, stepsize, -1.0);
//minusTraj.erase(minusTraj.begin());
int plusNum = plusTraj.size();
minusTraj.insert(minusTraj.begin(), plusTraj.rbegin(), plusTraj.rend());
// write colors
// write colors and convert positions to meter
std::vector<LinePoint> trajectory;
for (glm::vec3 position : minusTraj) {
trajectory.push_back(LinePoint(position, color));
for (glm::vec3 position : minusTraj) {
if (trajectory.size() < plusNum) // set positive trajectory to pink
trajectory.push_back(LinePoint(RE_TO_METER*position, glm::vec4(1, 0, 1, 1)));
else // set negative trajectory to cyan
trajectory.push_back(LinePoint(RE_TO_METER*position, glm::vec4(0, 1, 1, 1)));
}
trajectories.push_back(trajectory);
}

View File

@@ -165,13 +165,15 @@ bool SpiceManager::hasValue(const std::string& body, const std::string& item) co
}
bool SpiceManager::getNaifId(const std::string& body, int& id) const {
SpiceInt s_id = id;
if (body.empty()) {
LERROR("No body was provided");
return false;
}
else {
SpiceBoolean success;
bods2c_c(body.c_str(), &id, &success);
bods2c_c(body.c_str(), &s_id, &success);
if (success == SPICEFALSE)
LERROR("Could not find NAIF ID of body '" + body + "'");
return (success == SPICETRUE);
@@ -190,8 +192,9 @@ bool getValueInternal(const std::string& body, const std::string& value, int S,
return false;
}
int n;
bodvrd_c(body.c_str(), value.c_str(), S, &n, v);
SpiceInt n;
SpiceInt _s = S;
bodvrd_c(body.c_str(), value.c_str(), _s, &n, v);
bool hasError = SpiceManager::checkForError("Error getting value '" + value +
"' for body '" + body + "'");
@@ -232,7 +235,7 @@ bool SpiceManager::getValue(const std::string& body, const std::string& value,
return false;
}
int n;
SpiceInt n;
bodvrd_c(body.c_str(), value.c_str(), static_cast<SpiceInt>(v.size()), &n, &v[0]);
bool hasError = checkForError("Error getting value '" + value + "' for body '" +
@@ -433,7 +436,7 @@ bool SpiceManager::getFieldOfView(int instrument,
static char fovShapeBuffer[bufferSize];
static char frameNameBuffer[bufferSize];
int nrReturned;
SpiceInt nrReturned;
double boundsArr[maxBoundsSize][3];
getfov_c(instrument, // instrument id