mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-09 21:21:19 -06:00
Merge branch 'feature/fieldlines' into feature/ABuffer
Conflicts: src/rendering/renderablevolumegl.cpp
This commit is contained in:
@@ -52,9 +52,10 @@ public:
|
||||
virtual void update();
|
||||
|
||||
protected:
|
||||
// Renderable();
|
||||
std::string findPath(const std::string& path);
|
||||
private:
|
||||
PowerScaledScalar boundingSphere_;
|
||||
std::string _relativePath;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
77
include/openspace/rendering/renderablefieldlines.h
Normal file
77
include/openspace/rendering/renderablefieldlines.h
Normal file
@@ -0,0 +1,77 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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 RENDERABLEFIELDLINES_H_
|
||||
#define RENDERABLEFIELDLINES_H_
|
||||
|
||||
// open space includes
|
||||
#include <openspace/rendering/renderable.h>
|
||||
|
||||
// ghoul includes
|
||||
#include <ghoul/opengl/programobject.h>
|
||||
#include <ghoul/filesystem/file.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <memory>
|
||||
#else
|
||||
#include <mutex>
|
||||
#endif
|
||||
|
||||
namespace openspace {
|
||||
|
||||
class RenderableFieldlines : public Renderable {
|
||||
public:
|
||||
RenderableFieldlines(const ghoul::Dictionary& dictionary);
|
||||
~RenderableFieldlines();
|
||||
|
||||
bool initialize();
|
||||
bool deinitialize();
|
||||
|
||||
virtual void render(const Camera *camera, const psc& thisPosition);
|
||||
virtual void update();
|
||||
|
||||
private:
|
||||
ghoul::Dictionary _hintsDictionary;
|
||||
std::string _filename;
|
||||
std::vector<glm::vec3> _seedPoints;
|
||||
|
||||
ghoul::opengl::ProgramObject* _fieldlinesProgram;
|
||||
GLuint _VAO;
|
||||
|
||||
std::mutex* _shaderMutex;
|
||||
|
||||
ghoul::filesystem::File* _vertexSourceFile;
|
||||
ghoul::filesystem::File* _fragmentSourceFile;
|
||||
|
||||
std::vector<GLint> _lineStart;
|
||||
std::vector<GLsizei> _lineCount;
|
||||
|
||||
bool _programUpdateOnSave;
|
||||
void safeShaderCompilation();
|
||||
|
||||
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
#endif // RENDERABLEFIELDLINES_H_
|
||||
@@ -29,7 +29,6 @@
|
||||
#include <openspace/rendering/renderable.h>
|
||||
|
||||
// ghoul includes
|
||||
#include <ghoul/opengl/programobject.h>
|
||||
#include <ghoul/opengl/texture.h>
|
||||
#include <ghoul/io/rawvolumereader.h>
|
||||
|
||||
@@ -37,23 +36,18 @@ namespace openspace {
|
||||
|
||||
class RenderableVolume: public Renderable {
|
||||
public:
|
||||
|
||||
// constructors & destructor
|
||||
RenderableVolume(const ghoul::Dictionary& dictionary);
|
||||
~RenderableVolume();
|
||||
|
||||
protected:
|
||||
std::string findPath(const std::string& path);
|
||||
ghoul::opengl::Texture* loadVolume(const std::string& filepath, const ghoul::Dictionary& hintsDictionary);
|
||||
ghoul::RawVolumeReader::ReadHints readHints(const ghoul::Dictionary& dictionary);
|
||||
ghoul::opengl::Texture* loadTransferFunction(const std::string& filepath);
|
||||
|
||||
private:
|
||||
|
||||
// relative path
|
||||
std::string _relativePath;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#ifndef KAMELEONWRAPPER_H_
|
||||
#define KAMELEONWRAPPER_H_
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
//#include <glm/glm.hpp>
|
||||
#include <glm/gtx/std_based_type.hpp>
|
||||
|
||||
namespace ccmc {
|
||||
@@ -43,14 +43,42 @@ public:
|
||||
BATSRUS // Magnetosphere
|
||||
};
|
||||
|
||||
enum TraceDirection {
|
||||
FORWARD = 1,
|
||||
BACK = -1
|
||||
};
|
||||
|
||||
KameleonWrapper(const std::string& filename, Model model);
|
||||
~KameleonWrapper();
|
||||
float* getUniformSampledValues(const std::string& var, glm::size3_t outDimensions);
|
||||
float* getUniformSampledVectorValues(const std::string& xVar, const std::string& yVar,
|
||||
const std::string& zVar, glm::size3_t outDimensions);
|
||||
|
||||
float* getVolumeFieldLines(const std::string& xVar, const std::string& yVar,
|
||||
const std::string& zVar, glm::size3_t outDimensions, std::vector<glm::vec3> seedPoints);
|
||||
|
||||
std::vector<std::vector<glm::vec3> > getFieldLines(const std::string& xVar,
|
||||
const std::string& yVar, const std::string& zVar,
|
||||
std::vector<glm::vec3> seedPoints);
|
||||
|
||||
private:
|
||||
std::vector<glm::vec3> traceCartesianFieldline(const std::string& xVar,
|
||||
const std::string& yVar, const std::string& zVar,
|
||||
glm::vec3 seedPoint, TraceDirection direction);
|
||||
|
||||
void getGridVariables(std::string& x, std::string& y, std::string& z);
|
||||
void progressBar(int current, int end);
|
||||
|
||||
ccmc::Model* _model;
|
||||
Model _type;
|
||||
ccmc::Interpolator* _interpolator;
|
||||
|
||||
// Model parameters
|
||||
float _xMin, _xMax, _yMin, _yMax, _zMin, _zMax;
|
||||
std::string _xCoordVar, _yCoordVar, _zCoordVar;
|
||||
|
||||
// For progressbar
|
||||
int _lastiProgress;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
Submodule openspace-data updated: 42865a2858...840edd3a81
@@ -118,9 +118,9 @@ vec4 calculate_final_color(uint frag_count) {
|
||||
// final_color = blend(final_color, _col_(endFrag));
|
||||
|
||||
}
|
||||
|
||||
//int id =2;
|
||||
//if(id < frag_count)final_color = blend(final_color, _col_(fragments[id]));
|
||||
// final_color = vec4(0);
|
||||
// int id =0;
|
||||
// if(id < frag_count)final_color = blend(final_color, _col_(fragments[id]));
|
||||
|
||||
return final_color;
|
||||
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
#include <openspace/util/constants.h>
|
||||
#include <openspace/util/factorymanager.h>
|
||||
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
|
||||
namespace {
|
||||
const std::string _loggerCat = "Renderable";
|
||||
}
|
||||
@@ -63,6 +65,13 @@ Renderable::Renderable(const ghoul::Dictionary& dictionary)
|
||||
std::string name;
|
||||
dictionary.getValue(constants::scenegraphnode::keyName, name);
|
||||
setName(name);
|
||||
|
||||
// get path if available
|
||||
_relativePath = "";
|
||||
if(dictionary.hasKey(constants::scenegraph::keyPathModule)) {
|
||||
dictionary.getValue(constants::scenegraph::keyPathModule, _relativePath);
|
||||
_relativePath += "/";
|
||||
}
|
||||
}
|
||||
|
||||
Renderable::~Renderable()
|
||||
@@ -83,4 +92,18 @@ void Renderable::update()
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
std::string Renderable::findPath(const std::string& path) {
|
||||
std::string tmp = absPath(path);
|
||||
if(FileSys.fileExists(tmp))
|
||||
return tmp;
|
||||
|
||||
tmp = absPath(_relativePath + path);
|
||||
if(FileSys.fileExists(tmp))
|
||||
return tmp;
|
||||
|
||||
LERROR("Could not find file '" << path << "'");
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
215
src/rendering/renderablefieldlines.cpp
Normal file
215
src/rendering/renderablefieldlines.cpp
Normal file
@@ -0,0 +1,215 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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/rendering/renderablefieldlines.h>
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/util/powerscaledcoordinate.h>
|
||||
#include <openspace/util/kameleonwrapper.h>
|
||||
|
||||
namespace {
|
||||
std::string _loggerCat = "RenderableFieldlines";
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
|
||||
RenderableFieldlines::RenderableFieldlines(const ghoul::Dictionary& dictionary) :
|
||||
Renderable(dictionary), _VAO(0), _programUpdateOnSave(false) {
|
||||
_shaderMutex = new std::mutex;
|
||||
|
||||
if(dictionary.hasKey("Fieldlines")) {
|
||||
ghoul::Dictionary fieldlines;
|
||||
if(dictionary.getValue("Fieldlines", fieldlines)) {
|
||||
for(auto key: fieldlines.keys()) {
|
||||
ghoul::Dictionary fieldline;
|
||||
if(fieldlines.getValue(key, fieldline)) {
|
||||
if (fieldline.hasKey("File")) {
|
||||
std::string file = "";
|
||||
if (fieldline.getValue("File", file)) {
|
||||
file = findPath(file);
|
||||
if (file != "") {
|
||||
|
||||
// parse hints
|
||||
ghoul::Dictionary hintsDictionary;
|
||||
if(fieldline.hasKey("Hints"))
|
||||
fieldline.getValue("Hints", hintsDictionary);
|
||||
|
||||
// TODO Vectors of filenames and dictionaries
|
||||
_filename = file;
|
||||
_hintsDictionary = hintsDictionary;
|
||||
|
||||
ghoul::Dictionary seedpointsDictionary;
|
||||
if (fieldline.hasKey("Seedpoints") && fieldline.getValue("Seedpoints", seedpointsDictionary)) {
|
||||
glm::vec3 tmpVal;
|
||||
for (int i = 0; i < seedpointsDictionary.keys().size(); ++i) {
|
||||
fieldline.getValue("Seedpoints."+std::to_string(i+1), tmpVal);
|
||||
_seedPoints.push_back(tmpVal);
|
||||
}
|
||||
}
|
||||
} else
|
||||
LERROR("File not found!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string vshaderpath = "";
|
||||
std::string fshaderpath = "";
|
||||
|
||||
if (dictionary.hasKey("Shaders")) {
|
||||
ghoul::Dictionary shaderDictionary;
|
||||
if(dictionary.getValue("Shaders", shaderDictionary)) {
|
||||
if (shaderDictionary.hasKey("VertexShader")) {
|
||||
shaderDictionary.getValue("VertexShader", vshaderpath);
|
||||
}
|
||||
if (shaderDictionary.hasKey("FragmentShader")) {
|
||||
shaderDictionary.getValue("FragmentShader", fshaderpath);
|
||||
}
|
||||
|
||||
vshaderpath = findPath(vshaderpath);
|
||||
fshaderpath = findPath(fshaderpath);
|
||||
|
||||
_vertexSourceFile = new ghoul::filesystem::File(vshaderpath, false);
|
||||
_fragmentSourceFile = new ghoul::filesystem::File(fshaderpath, false);
|
||||
|
||||
_fieldlinesProgram = new ghoul::opengl::ProgramObject("FieldlinesProgram");
|
||||
ghoul::opengl::ShaderObject* vertexShader = new ghoul::opengl::ShaderObject(ghoul::opengl::ShaderObject::ShaderTypeVertex,vshaderpath);
|
||||
ghoul::opengl::ShaderObject* fragmentShader = new ghoul::opengl::ShaderObject(ghoul::opengl::ShaderObject::ShaderTypeFragment,fshaderpath);
|
||||
_fieldlinesProgram->attachObject(vertexShader);
|
||||
_fieldlinesProgram->attachObject(fragmentShader);
|
||||
}
|
||||
}
|
||||
|
||||
if(dictionary.hasKey("UpdateOnSave")) {
|
||||
dictionary.getValue("UpdateOnSave", _programUpdateOnSave);
|
||||
}
|
||||
|
||||
setBoundingSphere(PowerScaledScalar::CreatePSS(5));
|
||||
}
|
||||
|
||||
RenderableFieldlines::~RenderableFieldlines() {
|
||||
|
||||
}
|
||||
|
||||
bool RenderableFieldlines::initialize() {
|
||||
assert(_filename != "");
|
||||
|
||||
// std::vector<glm::vec3> seedPoints;
|
||||
// for (int x = -6; x <= 6; x+=3) {
|
||||
// for (int y = -6; y <= 6; y+=3) {
|
||||
// for (int z = -6; z <= 6; z+=3) {
|
||||
// seedPoints.push_back(glm::vec3((float)x, (float)y, (float)z));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
KameleonWrapper kameleon(_filename, KameleonWrapper::Model::BATSRUS);
|
||||
std::vector<std::vector<glm::vec3> > fieldlines = kameleon.getFieldLines("bx", "by", "bz", _seedPoints);
|
||||
|
||||
std::vector<glm::vec3> vertexData;
|
||||
int prevEnd = 0;
|
||||
|
||||
int vertexSum = 0;
|
||||
|
||||
for (int i = 0; i < fieldlines.size(); i++) {
|
||||
_lineStart.push_back(prevEnd);
|
||||
_lineCount.push_back(fieldlines[i].size());
|
||||
prevEnd = prevEnd + fieldlines[i].size();
|
||||
vertexSum += fieldlines[i].size();
|
||||
|
||||
vertexData.insert( vertexData.end(), fieldlines[i].begin(), fieldlines[i].end());
|
||||
}
|
||||
|
||||
LDEBUG("Vertex size: " << vertexSum);
|
||||
LDEBUG("Line average : " << (float)vertexSum/(float)fieldlines.size());
|
||||
|
||||
GLuint vertexPositionBuffer;
|
||||
glGenVertexArrays(1, &_VAO); // generate array
|
||||
glBindVertexArray(_VAO); // bind array
|
||||
glGenBuffers(1, &vertexPositionBuffer); // generate buffer
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertexPositionBuffer); // bind buffer
|
||||
glBufferData(GL_ARRAY_BUFFER, vertexData.size()*sizeof(glm::vec3), &vertexData.front(), GL_STATIC_DRAW);
|
||||
|
||||
// Vertex positions
|
||||
GLuint vertexLocation = 0;
|
||||
glEnableVertexAttribArray(vertexLocation);
|
||||
glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, 3*sizeof(GLfloat), reinterpret_cast<void*>(0));
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind buffer
|
||||
glBindVertexArray(0); //unbind array
|
||||
|
||||
// ------ SETUP SHADERS -----------------
|
||||
auto privateCallback = [this](const ghoul::filesystem::File& file) {
|
||||
safeShaderCompilation();
|
||||
};
|
||||
if(_programUpdateOnSave) {
|
||||
_vertexSourceFile->setCallback(privateCallback);
|
||||
_fragmentSourceFile->setCallback(privateCallback);
|
||||
}
|
||||
|
||||
_fieldlinesProgram->compileShaderObjects();
|
||||
_fieldlinesProgram->linkProgramObject();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RenderableFieldlines::deinitialize() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void RenderableFieldlines::render(const Camera* camera, const psc& thisPosition) {
|
||||
glm::mat4 transform = camera->viewProjectionMatrix();
|
||||
glm::mat4 camTransform = camera->viewRotationMatrix();
|
||||
psc relative = thisPosition-camera->position();
|
||||
|
||||
transform = transform*camTransform;
|
||||
transform = glm::translate(transform, relative.vec3());
|
||||
transform = glm::scale(transform, glm::vec3(0.1));
|
||||
|
||||
_shaderMutex->lock();
|
||||
_fieldlinesProgram->activate();
|
||||
_fieldlinesProgram->setUniform("modelViewProjection", transform);
|
||||
|
||||
|
||||
glBindVertexArray(_VAO);
|
||||
glMultiDrawArrays(GL_LINE_STRIP, &_lineStart[0], &_lineCount[0], _lineStart.size());
|
||||
glBindVertexArray(0);
|
||||
|
||||
_fieldlinesProgram->deactivate();
|
||||
_shaderMutex->unlock();
|
||||
}
|
||||
|
||||
void RenderableFieldlines::update() {
|
||||
}
|
||||
|
||||
void RenderableFieldlines::safeShaderCompilation() {
|
||||
_shaderMutex->lock();
|
||||
_fieldlinesProgram->rebuildFromFile();
|
||||
_fieldlinesProgram->compileShaderObjects();
|
||||
_fieldlinesProgram->linkProgramObject();
|
||||
_shaderMutex->unlock();
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
@@ -24,15 +24,13 @@
|
||||
|
||||
// open space includes
|
||||
#include <openspace/rendering/renderablevolume.h>
|
||||
|
||||
#include <ghoul/opengl/texturereader.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
#include <openspace/util/kameleonwrapper.h>
|
||||
#include <openspace/util/constants.h>
|
||||
|
||||
#include <sgct.h>
|
||||
// ghoul includes
|
||||
#include <ghoul/opengl/texturereader.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
@@ -73,92 +71,104 @@ namespace {
|
||||
|
||||
namespace openspace {
|
||||
|
||||
RenderableVolume::RenderableVolume(const ghoul::Dictionary& dictionary)
|
||||
: Renderable(dictionary)
|
||||
{
|
||||
// get path if available
|
||||
_relativePath = "";
|
||||
if(dictionary.hasKey(constants::scenegraph::keyPathModule)) {
|
||||
dictionary.getValue(constants::scenegraph::keyPathModule, _relativePath);
|
||||
_relativePath += "/";
|
||||
}
|
||||
RenderableVolume::RenderableVolume(const ghoul::Dictionary& dictionary) : Renderable(dictionary) {
|
||||
}
|
||||
|
||||
RenderableVolume::~RenderableVolume() {
|
||||
}
|
||||
|
||||
std::string RenderableVolume::findPath(const std::string& path) {
|
||||
std::string tmp = absPath(path);
|
||||
if(FileSys.fileExists(tmp))
|
||||
return tmp;
|
||||
|
||||
tmp = absPath(_relativePath + path);
|
||||
if(FileSys.fileExists(tmp))
|
||||
return tmp;
|
||||
|
||||
LERROR("Could not find file '" << path << "'");
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
ghoul::opengl::Texture* RenderableVolume::loadVolume(const std::string& filepath, const ghoul::Dictionary& hintsDictionary) {
|
||||
if( ! FileSys.fileExists(filepath)) {
|
||||
LWARNING("Could not load volume, could not find '" << filepath << "'");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if(hasExtension(filepath, "raw")) {
|
||||
ghoul::RawVolumeReader::ReadHints hints = readHints(hintsDictionary);
|
||||
ghoul::RawVolumeReader rawReader(hints);
|
||||
return rawReader.read(filepath);
|
||||
} else if(hasExtension(filepath, "cdf")) {
|
||||
|
||||
std::string modelString;
|
||||
if (hintsDictionary.hasKey("Model") && hintsDictionary.getValue("Model", modelString)) {
|
||||
KameleonWrapper::Model model;
|
||||
if (modelString == "BATSRUS") {
|
||||
model = KameleonWrapper::Model::BATSRUS;
|
||||
} else if (modelString == "ENLIL") {
|
||||
model = KameleonWrapper::Model::ENLIL;
|
||||
} else {
|
||||
LWARNING("Hints does not specify a valid 'Model'");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::string variableString;
|
||||
if (hintsDictionary.hasKey("Variable") && hintsDictionary.getValue("Variable", variableString)) {
|
||||
glm::size3_t dimensions(1,1,1);
|
||||
double tempValue;
|
||||
if (hintsDictionary.hasKey("Dimensions.1") && hintsDictionary.getValue("Dimensions.1", tempValue)) {
|
||||
int intVal = static_cast<int>(tempValue);
|
||||
if(intVal > 0)
|
||||
dimensions[0] = intVal;
|
||||
}
|
||||
if (hintsDictionary.hasKey("Dimensions.2") && hintsDictionary.getValue("Dimensions.2", tempValue)) {
|
||||
int intVal = static_cast<int>(tempValue);
|
||||
if(intVal > 0)
|
||||
dimensions[1] = intVal;
|
||||
}
|
||||
if (hintsDictionary.hasKey("Dimensions.3") && hintsDictionary.getValue("Dimensions.3", tempValue)) {
|
||||
int intVal = static_cast<int>(tempValue);
|
||||
if(intVal > 0)
|
||||
dimensions[2] = intVal;
|
||||
}
|
||||
|
||||
KameleonWrapper kw(filepath, model);
|
||||
float* data = kw.getUniformSampledValues(variableString, dimensions);
|
||||
return new ghoul::opengl::Texture(data, dimensions, ghoul::opengl::Texture::Format::Red, GL_RED, GL_FLOAT);
|
||||
} else {
|
||||
LWARNING("Hints does not specify a 'Variable'");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
LWARNING("Hints does not specify a 'Model'");
|
||||
} else {
|
||||
LWARNING("No valid file extension.");
|
||||
}
|
||||
return nullptr;
|
||||
if( ! FileSys.fileExists(filepath)) {
|
||||
LWARNING("Could not load volume, could not find '" << filepath << "'");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if(hasExtension(filepath, "raw")) {
|
||||
ghoul::RawVolumeReader::ReadHints hints = readHints(hintsDictionary);
|
||||
ghoul::RawVolumeReader rawReader(hints);
|
||||
return rawReader.read(filepath);
|
||||
} else if(hasExtension(filepath, "cdf")) {
|
||||
|
||||
std::string modelString;
|
||||
if (hintsDictionary.hasKey("Model") && hintsDictionary.getValue("Model", modelString)) {
|
||||
KameleonWrapper::Model model;
|
||||
if (modelString == "BATSRUS") {
|
||||
model = KameleonWrapper::Model::BATSRUS;
|
||||
} else if (modelString == "ENLIL") {
|
||||
model = KameleonWrapper::Model::ENLIL;
|
||||
} else {
|
||||
LWARNING("Hints does not specify a valid 'Model'");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
glm::size3_t dimensions(1,1,1);
|
||||
double tempValue;
|
||||
if (hintsDictionary.hasKey("Dimensions.1") && hintsDictionary.getValue("Dimensions.1", tempValue)) {
|
||||
int intVal = static_cast<int>(tempValue);
|
||||
if(intVal > 0)
|
||||
dimensions[0] = intVal;
|
||||
}
|
||||
if (hintsDictionary.hasKey("Dimensions.2") && hintsDictionary.getValue("Dimensions.2", tempValue)) {
|
||||
int intVal = static_cast<int>(tempValue);
|
||||
if(intVal > 0)
|
||||
dimensions[1] = intVal;
|
||||
}
|
||||
if (hintsDictionary.hasKey("Dimensions.3") && hintsDictionary.getValue("Dimensions.3", tempValue)) {
|
||||
int intVal = static_cast<int>(tempValue);
|
||||
if(intVal > 0)
|
||||
dimensions[2] = intVal;
|
||||
}
|
||||
|
||||
KameleonWrapper kw(filepath, model);
|
||||
|
||||
std::string variableString;
|
||||
if (hintsDictionary.hasKey("Variable") && hintsDictionary.getValue("Variable", variableString)) {
|
||||
float* data = kw.getUniformSampledValues(variableString, dimensions);
|
||||
return new ghoul::opengl::Texture(data, dimensions, ghoul::opengl::Texture::Format::Red, GL_RED, GL_FLOAT);
|
||||
|
||||
} else if (hintsDictionary.hasKey("Variables")) {
|
||||
std::string xVariable, yVariable, zVariable;
|
||||
bool xVar, yVar, zVar;
|
||||
xVar = hintsDictionary.getValue("Variables.1", xVariable);
|
||||
yVar = hintsDictionary.getValue("Variables.2", yVariable);
|
||||
zVar = hintsDictionary.getValue("Variables.3", zVariable);
|
||||
|
||||
if (!xVar || !yVar || !zVar) {
|
||||
LERROR("Error reading variables! Must be 3 and must exist in CDF data");
|
||||
} else {
|
||||
|
||||
// Seed 'em all
|
||||
std::vector<glm::vec3> seedPoints;
|
||||
// seedPoints.push_back(glm::vec3(5.0, 0.0, 0.0));
|
||||
for (int z = -5; z <= 5; z+=5) {
|
||||
for (int y = -5; y <= 5; y+=5)
|
||||
seedPoints.push_back(glm::vec3(5.0, (float)y, (float)z));
|
||||
}
|
||||
|
||||
float* fieldlinesData = kw.getVolumeFieldLines(xVariable, yVariable, zVariable, dimensions, seedPoints);
|
||||
// float* rhoData = kw.getUniformSampledValues("rho", dimensions);
|
||||
//
|
||||
// // Combine fieldlines with rhoData, clamp to [0,1]
|
||||
// float* data = new float[dimensions.x*dimensions.y*dimensions.z];
|
||||
// for (int i = 0; i < dimensions.x*dimensions.y*dimensions.z; ++i)
|
||||
// data[i] = std::min(fieldlinesData[i]+rhoData[i], 1.0f);
|
||||
//
|
||||
// delete fieldlinesData;
|
||||
// delete rhoData;
|
||||
|
||||
return new ghoul::opengl::Texture(fieldlinesData, dimensions, ghoul::opengl::Texture::Format::Red, GL_RED, GL_FLOAT);
|
||||
}
|
||||
|
||||
} else {
|
||||
LWARNING("Hints does not specify a 'Variable' or 'Variables'");
|
||||
}
|
||||
|
||||
}
|
||||
LWARNING("Hints does not specify a 'Model'");
|
||||
} else {
|
||||
LWARNING("No valid file extension.");
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ghoul::RawVolumeReader::ReadHints RenderableVolume::readHints(const ghoul::Dictionary& dictionary) {
|
||||
|
||||
@@ -210,7 +210,7 @@ RenderableVolumeExpert::RenderableVolumeExpert(const ghoul::Dictionary& dictiona
|
||||
}
|
||||
}
|
||||
|
||||
setBoundingSphere(PowerScaledScalar::CreatePSS(_boxScaling.length()));
|
||||
setBoundingSphere(PowerScaledScalar::CreatePSS(glm::length(_boxScaling)));
|
||||
}
|
||||
|
||||
RenderableVolumeExpert::~RenderableVolumeExpert() {
|
||||
@@ -253,9 +253,11 @@ bool RenderableVolumeExpert::initialize() {
|
||||
|
||||
LDEBUG("Creating CL texture from GL texture with path '" << _volumePaths.at(i) << "'");
|
||||
cl_mem volumeTexture = _context.createTextureFromGLTexture(CL_MEM_READ_ONLY, *volume);
|
||||
|
||||
|
||||
_volumes.push_back(volume);
|
||||
_clVolumes.push_back(volumeTexture);
|
||||
} else {
|
||||
LERROR("Invalid volume");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -194,9 +194,6 @@ void RenderableVolumeGL::render(const Camera *camera, const psc &thisPosition) {
|
||||
_colorBoxRenderer->render(camera->viewProjectionMatrix(), transform);
|
||||
/*
|
||||
// Draw screenquad
|
||||
glClearColor(0.2f, 0.2f, 0.2f, 0);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
_shaderMutex->lock();
|
||||
_twopassProgram->activate();
|
||||
_twopassProgram->setUniform("stepSize", _stepSize);
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <cassert>
|
||||
|
||||
// renderables
|
||||
#include <openspace/rendering/renderablefieldlines.h>
|
||||
#include <openspace/rendering/planets/renderableplanet.h>
|
||||
#include <openspace/rendering/renderablevolumeexpert.h>
|
||||
#include <openspace/rendering/renderablevolumecl.h>
|
||||
@@ -62,6 +63,7 @@ void FactoryManager::initialize()
|
||||
_manager->factory<Renderable>()->registerClass<RenderableVolumeExpert>(
|
||||
"RenderableVolumeExpert");
|
||||
_manager->factory<Renderable>()->registerClass<Flare>("RenderableFlare");
|
||||
_manager->factory<Renderable>()->registerClass<RenderableFieldlines>("RenderableFieldlines");
|
||||
|
||||
// Add Ephimerides
|
||||
_manager->addFactory(new ghoul::TemplateFactory<Ephemeris>);
|
||||
@@ -102,4 +104,4 @@ void FactoryManager::addFactory(ghoul::TemplateFactoryBase* factory) {
|
||||
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
} // namespace openspace
|
||||
|
||||
@@ -31,7 +31,8 @@
|
||||
#include <ccmc/ENLIL.h>
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <math.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <iomanip>
|
||||
|
||||
namespace openspace {
|
||||
@@ -42,23 +43,42 @@ KameleonWrapper::KameleonWrapper(const std::string& filename, Model model): _typ
|
||||
switch (_type) {
|
||||
case Model::BATSRUS:
|
||||
_model = new ccmc::BATSRUS();
|
||||
if(!_model) LERROR("BATSRUS:Failed to create model instance");
|
||||
if(!_model) LERROR("BATSRUS:Failed to create BATSRUS model instance");
|
||||
if (_model->open(filename) != ccmc::FileReader::OK)
|
||||
LERROR("BATSRUS:Failed to open "+filename);
|
||||
_interpolator = _model->createNewInterpolator();
|
||||
if (!_interpolator) LERROR("BATSRUS:Failed to create interpolator");
|
||||
if (!_interpolator) LERROR("BATSRUS:Failed to create BATSRUS interpolator");
|
||||
break;
|
||||
case Model::ENLIL:
|
||||
_model = new ccmc::ENLIL();
|
||||
if(!_model) LERROR("Failed to create model instance");
|
||||
if(!_model) LERROR("Failed to create ENLIL model instance");
|
||||
if (_model->open(filename) != ccmc::FileReader::OK)
|
||||
LERROR("Failed to open "+filename);
|
||||
_interpolator = _model->createNewInterpolator();
|
||||
if (!_interpolator) LERROR("Failed to create interpolator");
|
||||
if (!_interpolator) LERROR("Failed to create ENLIL interpolator");
|
||||
break;
|
||||
default:
|
||||
LERROR("No valid model type provided!");
|
||||
}
|
||||
|
||||
getGridVariables(_xCoordVar, _yCoordVar, _zCoordVar);
|
||||
LDEBUG("Using coordinate system variables: " << _xCoordVar << ", " << _yCoordVar << ", " << _zCoordVar);
|
||||
|
||||
_xMin = _model->getVariableAttribute(_xCoordVar, "actual_min").getAttributeFloat();
|
||||
_xMax = _model->getVariableAttribute(_xCoordVar, "actual_max").getAttributeFloat();
|
||||
_yMin = _model->getVariableAttribute(_yCoordVar, "actual_min").getAttributeFloat();
|
||||
_yMax = _model->getVariableAttribute(_yCoordVar, "actual_max").getAttributeFloat();
|
||||
_zMin = _model->getVariableAttribute(_zCoordVar, "actual_min").getAttributeFloat();
|
||||
_zMax = _model->getVariableAttribute(_zCoordVar, "actual_max").getAttributeFloat();
|
||||
|
||||
LDEBUG(_xCoordVar << "Min: " << _xMin);
|
||||
LDEBUG(_xCoordVar << "Max: " << _xMax);
|
||||
LDEBUG(_yCoordVar << "Min: " << _yMin);
|
||||
LDEBUG(_yCoordVar << "Max: " << _yMax);
|
||||
LDEBUG(_zCoordVar << "Min: " << _zMin);
|
||||
LDEBUG(_zCoordVar << "Max: " << _zMax);
|
||||
|
||||
_lastiProgress = -1; // For progressbar
|
||||
}
|
||||
|
||||
KameleonWrapper::~KameleonWrapper() {
|
||||
@@ -70,93 +90,23 @@ float* KameleonWrapper::getUniformSampledValues(const std::string& var, glm::siz
|
||||
assert(_model && _interpolator);
|
||||
assert(outDimensions.x > 0 && outDimensions.y > 0 && outDimensions.z > 0);
|
||||
assert(_type == Model::ENLIL || _type == Model::BATSRUS);
|
||||
LINFO("Loading CDF data");
|
||||
LINFO("Loading variable " << var << " from CDF data with a uniform sampling");
|
||||
|
||||
int size = outDimensions.x*outDimensions.y*outDimensions.z;
|
||||
float* data = new float[size];
|
||||
|
||||
// get the grid system string
|
||||
std::string gridSystem = _model->getGlobalAttribute("grid_system_1").getAttributeString();
|
||||
|
||||
// remove leading and trailing brackets
|
||||
gridSystem = gridSystem.substr(1,gridSystem.length()-2);
|
||||
|
||||
// remove all whitespaces
|
||||
gridSystem.erase(remove_if(gridSystem.begin(), gridSystem.end(), isspace), gridSystem.end());
|
||||
|
||||
// replace all comma signs with whitespaces
|
||||
std::replace( gridSystem.begin(), gridSystem.end(), ',', ' ');
|
||||
|
||||
// tokenize
|
||||
std::istringstream iss(gridSystem);
|
||||
std::vector<std::string> tokens{std::istream_iterator<std::string>{iss},std::istream_iterator<std::string>{}};
|
||||
|
||||
// validate
|
||||
if (tokens.size() != 3) {
|
||||
LERROR("Something went wrong");
|
||||
delete[] data;
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string v_x = tokens.at(0), v_y = tokens.at(1), v_z = tokens.at(2);
|
||||
/*
|
||||
for(auto t: tokens)
|
||||
LDEBUG("t: " << t);
|
||||
*/
|
||||
/*
|
||||
LERROR("getVariableAttributeNames");
|
||||
std::vector<std::string> attributeNames = _model->getVariableAttributeNames();
|
||||
for(auto name : attributeNames)
|
||||
LDEBUG(name);
|
||||
*/
|
||||
//_model->getVa
|
||||
|
||||
//auto fan = std::find(attributeNames.begin(), attributeNames.end(), "");
|
||||
|
||||
|
||||
//KameleonWrapper (Debug) grid_system_1
|
||||
//KameleonWrapper (Debug) grid_1_type
|
||||
|
||||
LDEBUG("Using coordinate system: " << v_x << ", " << v_y << ", " << v_z);
|
||||
|
||||
float xMin = _model->getVariableAttribute(v_x, "actual_min").getAttributeFloat();
|
||||
float xMax = _model->getVariableAttribute(v_x, "actual_max").getAttributeFloat();
|
||||
float yMin = _model->getVariableAttribute(v_y, "actual_min").getAttributeFloat();
|
||||
float yMax = _model->getVariableAttribute(v_y, "actual_max").getAttributeFloat();
|
||||
float zMin = _model->getVariableAttribute(v_z, "actual_min").getAttributeFloat();
|
||||
float zMax = _model->getVariableAttribute(v_z, "actual_max").getAttributeFloat();
|
||||
float varMin = _model->getVariableAttribute(var, "actual_min").getAttributeFloat();
|
||||
float varMax = _model->getVariableAttribute(var, "actual_max").getAttributeFloat();
|
||||
|
||||
float stepX = (xMax-xMin)/(static_cast<float>(outDimensions.x));
|
||||
float stepY = (yMax-yMin)/(static_cast<float>(outDimensions.y));
|
||||
float stepZ = (zMax-zMin)/(static_cast<float>(outDimensions.z));
|
||||
float stepX = (_xMax-_xMin)/(static_cast<float>(outDimensions.x));
|
||||
float stepY = (_yMax-_yMin)/(static_cast<float>(outDimensions.y));
|
||||
float stepZ = (_zMax-_zMin)/(static_cast<float>(outDimensions.z));
|
||||
|
||||
|
||||
LDEBUG(v_x << "Min: " << xMin);
|
||||
LDEBUG(v_x << "Max: " << xMax);
|
||||
LDEBUG(v_y << "Min: " << yMin);
|
||||
LDEBUG(v_y << "Max: " << yMax);
|
||||
LDEBUG(v_z << "Min: " << zMin);
|
||||
LDEBUG(v_z << "Max: " << zMax);
|
||||
LDEBUG(var << "Min: " << varMin);
|
||||
LDEBUG(var << "Max: " << varMax);
|
||||
|
||||
int barWidth = 70;
|
||||
int lastiProgress = -1;
|
||||
for (int x = 0; x < outDimensions.x; ++x) {
|
||||
float progress = static_cast<float>(x) / static_cast<float>(outDimensions.x-1);
|
||||
int iprogress = static_cast<int>(progress*100.0f);
|
||||
if (iprogress != lastiProgress) {
|
||||
|
||||
int pos = barWidth * progress;
|
||||
int eqWidth = pos+1;
|
||||
int spWidth = barWidth - pos + 2;
|
||||
std::cout << "[" << std::setfill('=') << std::setw(eqWidth)
|
||||
<< ">" << std::setfill(' ') << std::setw(spWidth)
|
||||
<< "] " << iprogress << " % \r" << std::flush;
|
||||
}
|
||||
lastiProgress = iprogress;
|
||||
progressBar(x, outDimensions.x);
|
||||
|
||||
for (int y = 0; y < outDimensions.y; ++y) {
|
||||
for (int z = 0; z < outDimensions.z; ++z) {
|
||||
@@ -164,9 +114,9 @@ float* KameleonWrapper::getUniformSampledValues(const std::string& var, glm::siz
|
||||
int index = x + y*outDimensions.x + z*outDimensions.x*outDimensions.y;
|
||||
|
||||
if(_type == Model::BATSRUS) {
|
||||
float xPos = xMin + stepX*x;
|
||||
float yPos = yMin + stepY*y;
|
||||
float zPos = zMin + stepZ*z;
|
||||
float xPos = _xMin + stepX*x;
|
||||
float yPos = _yMin + stepY*y;
|
||||
float zPos = _zMin + stepZ*z;
|
||||
|
||||
// get interpolated data value for (xPos, yPos, zPos)
|
||||
float value = _interpolator->interpolate(var, xPos, yPos, zPos);
|
||||
@@ -174,10 +124,6 @@ float* KameleonWrapper::getUniformSampledValues(const std::string& var, glm::siz
|
||||
// scale to [0,1]
|
||||
data[index] = (value-varMin)/(varMax-varMin);
|
||||
} else if (_type == Model::ENLIL) {
|
||||
//LDEBUG("data: " << theval);
|
||||
|
||||
// Calculate array index
|
||||
//unsigned int index = r + theta*xDim_ + phi*xDim_*yDim_;
|
||||
|
||||
// Put r in the [0..sqrt(3)] range
|
||||
float rNorm = sqrt(3.0)*(float)x/(float)(outDimensions.x-1);
|
||||
@@ -189,21 +135,18 @@ float* KameleonWrapper::getUniformSampledValues(const std::string& var, glm::siz
|
||||
float phiNorm = 2.0*M_PI*(float)z/(float)(outDimensions.z-1);
|
||||
|
||||
// Go to physical coordinates before sampling
|
||||
float rPh = xMin + rNorm*(xMax-xMin);
|
||||
float rPh = _xMin + rNorm*(_xMax-_xMin);
|
||||
float thetaPh = thetaNorm;
|
||||
//phi range needs to be mapped to the slightly different
|
||||
// model range to avoid gaps in the data
|
||||
// Subtract a small term to avoid rounding errors when comparing
|
||||
// to phiMax.
|
||||
float phiPh = zMin + phiNorm/(2.0*M_PI)*(zMax-zMin-0.000001);
|
||||
// phi range needs to be mapped to the slightly different model
|
||||
// range to avoid gaps in the data Subtract a small term to
|
||||
// avoid rounding errors when comparing to phiMax.
|
||||
float phiPh = _zMin + phiNorm/(2.0*M_PI)*(_zMax-_zMin-0.000001);
|
||||
|
||||
// Hardcoded variables (rho or rho - rho_back)
|
||||
// TODO Don't hardcode, make more flexible
|
||||
float varValue = 0.f;//, rho_back = 0.f, diff = 0.f;
|
||||
float varValue = 0.f;
|
||||
// See if sample point is inside domain
|
||||
if (rPh < xMin || rPh > xMax || thetaPh < yMin ||
|
||||
thetaPh > yMax || phiPh < zMin || phiPh > zMax) {
|
||||
if (phiPh > zMax) {
|
||||
if (rPh < _xMin || rPh > _xMax || thetaPh < _yMin ||
|
||||
thetaPh > _yMax || phiPh < _zMin || phiPh > _zMax) {
|
||||
if (phiPh > _zMax) {
|
||||
std::cout << "Warning: There might be a gap in the data\n";
|
||||
}
|
||||
// Leave values at zero if outside domain
|
||||
@@ -218,22 +161,9 @@ float* KameleonWrapper::getUniformSampledValues(const std::string& var, glm::siz
|
||||
phiPh = phiPh*180.f/M_PI;
|
||||
// Sample
|
||||
varValue = _interpolator->interpolate(var, rPh, thetaPh, phiPh);
|
||||
//rho_back = _interpolator->interpolate("rho-back",rPh,thetaPh,phiPh);
|
||||
|
||||
// Calculate difference (or just rho)
|
||||
//diff = rho;
|
||||
//diff = rho - rho_back;
|
||||
|
||||
// Clamp to 0
|
||||
//if (diff < 0.f) diff = 0.f;
|
||||
}
|
||||
//if(var < 0.0f) var = 0.0f;
|
||||
//data[index] = var;
|
||||
|
||||
data[index] = (varValue-varMin)/(varMax-varMin);
|
||||
//LDEBUG("varValue:" << varValue);
|
||||
//LDEBUG("data[index]:" << data[index]);
|
||||
//data[index] = var;
|
||||
//data[index] = diff;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -244,5 +174,221 @@ float* KameleonWrapper::getUniformSampledValues(const std::string& var, glm::siz
|
||||
return data;
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
float* KameleonWrapper::getUniformSampledVectorValues(const std::string& xVar, const std::string& yVar, const std::string& zVar, glm::size3_t outDimensions) {
|
||||
assert(_model && _interpolator);
|
||||
assert(outDimensions.x > 0 && outDimensions.y > 0 && outDimensions.z > 0);
|
||||
assert(_type == Model::ENLIL || _type == Model::BATSRUS);
|
||||
LINFO("Loading variables " << xVar << " " << yVar << " " << zVar << " from CDF data with a uniform sampling");
|
||||
|
||||
int channels = 4;
|
||||
int size = channels*outDimensions.x*outDimensions.y*outDimensions.z;
|
||||
float* data = new float[size];
|
||||
|
||||
float varXMin = _model->getVariableAttribute(xVar, "actual_min").getAttributeFloat();
|
||||
float varXMax = _model->getVariableAttribute(xVar, "actual_max").getAttributeFloat();
|
||||
float varYMin = _model->getVariableAttribute(yVar, "actual_min").getAttributeFloat();
|
||||
float varYMax = _model->getVariableAttribute(yVar, "actual_max").getAttributeFloat();
|
||||
float varZMin = _model->getVariableAttribute(zVar, "actual_min").getAttributeFloat();
|
||||
float varZMax = _model->getVariableAttribute(zVar, "actual_max").getAttributeFloat();
|
||||
|
||||
float stepX = (_xMax-_xMin)/(static_cast<float>(outDimensions.x));
|
||||
float stepY = (_yMax-_yMin)/(static_cast<float>(outDimensions.y));
|
||||
float stepZ = (_zMax-_zMin)/(static_cast<float>(outDimensions.z));
|
||||
|
||||
LDEBUG(xVar << "Min: " << varXMin);
|
||||
LDEBUG(xVar << "Max: " << varXMax);
|
||||
LDEBUG(yVar << "Min: " << varYMin);
|
||||
LDEBUG(yVar << "Max: " << varYMax);
|
||||
LDEBUG(zVar << "Min: " << varZMin);
|
||||
LDEBUG(zVar << "Max: " << varZMax);
|
||||
|
||||
for (int x = 0; x < outDimensions.x; ++x) {
|
||||
progressBar(x, outDimensions.x);
|
||||
|
||||
for (int y = 0; y < outDimensions.y; ++y) {
|
||||
for (int z = 0; z < outDimensions.z; ++z) {
|
||||
|
||||
int index = x*channels + y*channels*outDimensions.x + z*channels*outDimensions.x*outDimensions.y;
|
||||
|
||||
if(_type == Model::BATSRUS) {
|
||||
float xPos = _xMin + stepX*x;
|
||||
float yPos = _yMin + stepY*y;
|
||||
float zPos = _zMin + stepZ*z;
|
||||
|
||||
// get interpolated data value for (xPos, yPos, zPos)
|
||||
float xValue = _interpolator->interpolate(xVar, xPos, yPos, zPos);
|
||||
float yValue = _interpolator->interpolate(yVar, xPos, yPos, zPos);
|
||||
float zValue = _interpolator->interpolate(zVar, xPos, yPos, zPos);
|
||||
|
||||
// scale to [0,1]
|
||||
data[index] = (xValue-varXMin)/(varXMax-varXMin); // R
|
||||
data[index + 1] = (yValue-varYMin)/(varYMax-varYMin); // G
|
||||
data[index + 2] = (zValue-varZMin)/(varZMax-varZMin); // B
|
||||
data[index + 3] = 1.0; // GL_RGB refuses to work. Workaround by doing a GL_RGBA with hardcoded alpha
|
||||
} else {
|
||||
LERROR("Only BATSRUS supported for getUniformSampledVectorValues (for now)");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
std::cout << std::endl;
|
||||
LINFO("Done!");
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
float* KameleonWrapper::getVolumeFieldLines(const std::string& xVar,
|
||||
const std::string& yVar, const std::string& zVar,
|
||||
glm::size3_t outDimensions, std::vector<glm::vec3> seedPoints) {
|
||||
assert(_model && _interpolator);
|
||||
assert(outDimensions.x > 0 && outDimensions.y > 0 && outDimensions.z > 0);
|
||||
assert(_type == Model::ENLIL || _type == Model::BATSRUS);
|
||||
LINFO("Creating " << seedPoints.size() << " fieldlines from variables " << xVar << " " << yVar << " " << zVar);
|
||||
|
||||
int size = outDimensions.x*outDimensions.y*outDimensions.z;
|
||||
float* data = new float[size];
|
||||
std::vector<glm::vec3> line;
|
||||
|
||||
if (_type == Model::BATSRUS) {
|
||||
for (glm::vec3 seedPoint : seedPoints) {
|
||||
line = traceCartesianFieldline(xVar, yVar, zVar, seedPoint, TraceDirection::FORWARD);
|
||||
for (glm::vec3 point : line) {
|
||||
int vPosX = std::floor(outDimensions.x*(point.x-_xMin)/(_xMax-_xMin));
|
||||
int vPosY = std::floor(outDimensions.y*(point.y-_yMin)/(_yMax-_yMin));
|
||||
int vPosZ = std::floor(outDimensions.z*(point.z-_zMin)/(_zMax-_zMin));
|
||||
int index = vPosX + vPosY*outDimensions.x + vPosZ*outDimensions.x*outDimensions.y;
|
||||
data[index] = 1.0;
|
||||
}
|
||||
|
||||
line = traceCartesianFieldline(xVar, yVar, zVar, seedPoint, TraceDirection::BACK);
|
||||
for (glm::vec3 point : line) {
|
||||
int vPosX = std::floor(outDimensions.x*(point.x-_xMin)/(_xMax-_xMin));
|
||||
int vPosY = std::floor(outDimensions.y*(point.y-_yMin)/(_yMax-_yMin));
|
||||
int vPosZ = std::floor(outDimensions.z*(point.z-_zMin)/(_zMax-_zMin));
|
||||
int index = vPosX + vPosY*outDimensions.x + vPosZ*outDimensions.x*outDimensions.y;
|
||||
data[index] = 1.0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LERROR("Fieldlines are only supported for BATSRUS model");
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
std::vector<std::vector<glm::vec3> > KameleonWrapper::getFieldLines(
|
||||
const std::string& xVar, const std::string& yVar,
|
||||
const std::string& zVar, std::vector<glm::vec3> seedPoints) {
|
||||
assert(_model && _interpolator);
|
||||
assert(_type == Model::ENLIL || _type == Model::BATSRUS);
|
||||
LINFO("Creating " << seedPoints.size() << " fieldlines from variables " << xVar << " " << yVar << " " << zVar);
|
||||
|
||||
std::vector<glm::vec3> fLine, bLine;
|
||||
std::vector<std::vector<glm::vec3> > fieldLines;
|
||||
|
||||
if (_type == Model::BATSRUS) {
|
||||
for (glm::vec3 seedPoint : seedPoints) {
|
||||
fLine = traceCartesianFieldline(xVar, yVar, zVar, seedPoint, TraceDirection::FORWARD);
|
||||
bLine = traceCartesianFieldline(xVar, yVar, zVar, seedPoint, TraceDirection::BACK);
|
||||
bLine.insert(bLine.begin(), fLine.rbegin(), fLine.rend());
|
||||
fieldLines.push_back(bLine);
|
||||
}
|
||||
} else {
|
||||
LERROR("Fieldlines are only supported for BATSRUS model");
|
||||
}
|
||||
|
||||
return fieldLines;
|
||||
}
|
||||
|
||||
std::vector<glm::vec3> KameleonWrapper::traceCartesianFieldline(
|
||||
const std::string& xVar, const std::string& yVar,
|
||||
const std::string& zVar, glm::vec3 seedPoint, TraceDirection direction) {
|
||||
|
||||
glm::vec3 pos, k1, k2, k3, k4;
|
||||
std::vector<glm::vec3> line;
|
||||
|
||||
float stepX = 0.5, stepY = 0.5, stepZ = 0.5;
|
||||
|
||||
int numSteps = 0;
|
||||
int maxSteps = 1000;
|
||||
pos = seedPoint;
|
||||
|
||||
// While we are inside the models boundries and not inside earth
|
||||
while ((pos.x < _xMax && pos.x > _xMin && pos.y < _yMax && pos.y > _yMin &&
|
||||
pos.z < _zMax && pos.z > _zMin) && !(pos.x < 1.0 && pos.x > -1.0 &&
|
||||
pos.y < 1.0 && pos.y > -1.0 && pos.z < 1.0 && pos.z > -1.0)) {
|
||||
|
||||
// Save position
|
||||
line.push_back(pos);
|
||||
|
||||
// Calculate new position with Runge-Kutta 4th order
|
||||
k1.x = _interpolator->interpolate(xVar, pos.x, pos.y, pos.z);
|
||||
k1.y = _interpolator->interpolate(yVar, pos.x, pos.y, pos.z);
|
||||
k1.z = _interpolator->interpolate(zVar, pos.x, pos.y, pos.z);
|
||||
k1 = (float)direction*glm::normalize(k1);
|
||||
k2.x = _interpolator->interpolate(xVar, pos.x+(stepX/2.0)*k1.x, pos.y+(stepY/2.0)*k1.y, pos.z+(stepZ/2.0)*k1.z);
|
||||
k2.y = _interpolator->interpolate(yVar, pos.x+(stepX/2.0)*k1.x, pos.y+(stepY/2.0)*k1.y, pos.z+(stepZ/2.0)*k1.z);
|
||||
k2.z = _interpolator->interpolate(zVar, pos.x+(stepX/2.0)*k1.x, pos.y+(stepY/2.0)*k1.y, pos.z+(stepZ/2.0)*k1.z);
|
||||
k2 = (float)direction*glm::normalize(k2);
|
||||
k3.x = _interpolator->interpolate(xVar, pos.x+(stepX/2.0)*k2.x, pos.y+(stepY/2.0)*k2.y, pos.z+(stepZ/2.0)*k2.z);
|
||||
k3.y = _interpolator->interpolate(yVar, pos.x+(stepX/2.0)*k2.x, pos.y+(stepY/2.0)*k2.y, pos.z+(stepZ/2.0)*k2.z);
|
||||
k3.z = _interpolator->interpolate(zVar, pos.x+(stepX/2.0)*k2.x, pos.y+(stepY/2.0)*k2.y, pos.z+(stepZ/2.0)*k2.z);
|
||||
k3 = (float)direction*glm::normalize(k3);
|
||||
k4.x = _interpolator->interpolate(xVar, pos.x+stepX*k3.x, pos.y+stepY*k3.y, pos.z+stepZ*k3.z);
|
||||
k4.y = _interpolator->interpolate(yVar, pos.x+stepX*k3.x, pos.y+stepY*k3.y, pos.z+stepZ*k3.z);
|
||||
k4.z = _interpolator->interpolate(zVar, pos.x+stepX*k3.x, pos.y+stepY*k3.y, pos.z+stepZ*k3.z);
|
||||
k4 = (float)direction*glm::normalize(k4);
|
||||
pos.x = pos.x + (stepX/6.0)*(k1.x + 2.0*k2.x + 2.0*k3.x + k4.x);
|
||||
pos.y = pos.y + (stepY/6.0)*(k1.y + 2.0*k2.y + 2.0*k3.y + k4.y);
|
||||
pos.z = pos.z + (stepZ/6.0)*(k1.z + 2.0*k2.z + 2.0*k3.z + k4.z);
|
||||
|
||||
++numSteps;
|
||||
if (numSteps > maxSteps) {
|
||||
LDEBUG("Max number of steps taken");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
void KameleonWrapper::getGridVariables(std::string& x, std::string& y, std::string& z) {
|
||||
// get the grid system string
|
||||
std::string gridSystem = _model->getGlobalAttribute("grid_system_1").getAttributeString();
|
||||
|
||||
// remove leading and trailing brackets
|
||||
gridSystem = gridSystem.substr(1,gridSystem.length()-2);
|
||||
|
||||
// remove all whitespaces
|
||||
gridSystem.erase(remove_if(gridSystem.begin(), gridSystem.end(), isspace), gridSystem.end());
|
||||
|
||||
// replace all comma signs with whitespaces
|
||||
std::replace( gridSystem.begin(), gridSystem.end(), ',', ' ');
|
||||
|
||||
// tokenize
|
||||
std::istringstream iss(gridSystem);
|
||||
std::vector<std::string> tokens{std::istream_iterator<std::string>{iss},std::istream_iterator<std::string>{}};
|
||||
|
||||
// validate
|
||||
if (tokens.size() != 3) LERROR("Something went wrong");
|
||||
|
||||
x = tokens.at(0);
|
||||
y = tokens.at(1);
|
||||
z = tokens.at(2);
|
||||
}
|
||||
|
||||
void KameleonWrapper::progressBar(int current, int end) {
|
||||
float progress = static_cast<float>(current) / static_cast<float>(end-1);
|
||||
int iprogress = static_cast<int>(progress*100.0f);
|
||||
int barWidth = 70;
|
||||
if (iprogress != _lastiProgress) {
|
||||
int pos = barWidth * progress;
|
||||
int eqWidth = pos+1;
|
||||
int spWidth = barWidth - pos + 2;
|
||||
std::cout << "[" << std::setfill('=') << std::setw(eqWidth)
|
||||
<< ">" << std::setfill(' ') << std::setw(spWidth)
|
||||
<< "] " << iprogress << " % \r" << std::flush;
|
||||
}
|
||||
_lastiProgress = iprogress;
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
Reference in New Issue
Block a user