mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-05-06 19:39:56 -05:00
Add functionality for coloring lines by different quantities
This commit is contained in:
@@ -29,9 +29,9 @@
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
|
||||
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/opengl/programobject.h>
|
||||
#include <ghoul/opengl/textureunit.h>
|
||||
|
||||
using std::string;
|
||||
|
||||
@@ -44,6 +44,8 @@ namespace {
|
||||
const char* KEY_SOURCE_FOLDER = "SourceFolder"; // [STRING]
|
||||
|
||||
// ---------------------------- OPTIONAL MODFILE KEYS ---------------------------- //
|
||||
const char* KEY_COLOR_TABLE_PATHS = "ColorTablePaths"; // [STRING ARRAY] Values should be paths to .txt files
|
||||
const char* KEY_COLOR_TABLE_RANGES = "ColorTableRanges";// [VEC2 ARRAY] Values should be paths to .txt files
|
||||
const char* KEY_OSLFS_LOAD_AT_RUNTIME = "LoadAtRuntime"; // [BOOLEAN] If value False => Load in initializing step and store in RAM
|
||||
|
||||
// ------------- POSSIBLE STRING VALUES FOR CORRESPONDING MODFILE KEY ------------- //
|
||||
@@ -51,8 +53,26 @@ namespace {
|
||||
const char* VALUE_INPUT_FILE_TYPE_JSON = "json";
|
||||
const char* VALUE_INPUT_FILE_TYPE_OSFLS = "osfls";
|
||||
|
||||
static const openspace::properties::Property::PropertyInfo LineColorInfo = {
|
||||
"lineColor", "Line Color", "Color of lines."
|
||||
static const openspace::properties::Property::PropertyInfo ColorMethodInfo = {
|
||||
"colorMethod", "Color Method", "Color lines uniformly or using color tables based on extra variables like e.g. temperature or particle density."
|
||||
};
|
||||
static const openspace::properties::Property::PropertyInfo ColorQuantityInfo = {
|
||||
"colorQuantity", "Quantity to Color By", "Quantity/variable used to color lines if the \"By Quantity\" color method is selected."
|
||||
};
|
||||
static const openspace::properties::Property::PropertyInfo ColorQuantityMinInfo = {
|
||||
"colorQuantityMin", "ColorTable Min Value", "Value to map to the lowest end of the color table."
|
||||
};
|
||||
static const openspace::properties::Property::PropertyInfo ColorQuantityMaxInfo = {
|
||||
"colorQuantityMax", "ColorTable Max Value", "Value to map to the highest end of the color table."
|
||||
};
|
||||
static const openspace::properties::Property::PropertyInfo ColorTablePathInfo = {
|
||||
"colorTablePath", "Path to Color Table", "Color Table/Transfer Function to use for \"By Quantity\" coloring."
|
||||
};
|
||||
static const openspace::properties::Property::PropertyInfo ColorUniformInfo = {
|
||||
"uniform", "Uniform Line Color", "The uniform color of lines shown when \"Color Method\" is set to \"Uniform\"."
|
||||
};
|
||||
static const openspace::properties::Property::PropertyInfo FlowColorInfo = {
|
||||
"color", "Color", "Color of particles."
|
||||
};
|
||||
static const openspace::properties::Property::PropertyInfo EnableFlowInfo = {
|
||||
"Enable", "ON/OFF",
|
||||
@@ -70,29 +90,37 @@ namespace {
|
||||
static const openspace::properties::Property::PropertyInfo FlowSpeedInfo = {
|
||||
"speed", "Speed", "Speed of the flow."
|
||||
};
|
||||
static const openspace::properties::Property::PropertyInfo FlowColorInfo = {
|
||||
"color", "Color", "Color of particles."
|
||||
};
|
||||
|
||||
enum ColorMethod { UNIFORM = 0, BY_QUANTITY };
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
|
||||
RenderableFieldlinesSequence::RenderableFieldlinesSequence(const ghoul::Dictionary& dictionary)
|
||||
: Renderable(dictionary),
|
||||
_lineColor(LineColorInfo, glm::vec4(0.75f, 0.5f, 0.0f, 0.5f), glm::vec4(0.f), glm::vec4(1.f)),
|
||||
_flowGroup({ "Flow" }),
|
||||
_colorGroup({ "Color" }),
|
||||
_colorMethod(ColorMethodInfo, properties::OptionProperty::DisplayType::Radio),
|
||||
_colorQuantity(ColorQuantityInfo, properties::OptionProperty::DisplayType::Dropdown),
|
||||
_colorQuantityMin(ColorQuantityMinInfo),
|
||||
_colorQuantityMax(ColorQuantityMaxInfo),
|
||||
_colorTablePath(ColorTablePathInfo),
|
||||
_colorUniform(ColorUniformInfo, glm::vec4(0.75f, 0.5f, 0.0f, 0.5f),
|
||||
glm::vec4(0.f), glm::vec4(1.f)),
|
||||
_flowColor(FlowColorInfo, glm::vec4(0.8f, 0.7f, 0.0f, 0.6f),
|
||||
glm::vec4(0.f), glm::vec4(1.f)),
|
||||
_flowEnabled(EnableFlowInfo, true),
|
||||
_flowReversed(ReverseFlowInfo, false),
|
||||
_flowGroup({ "Flow" }),
|
||||
_flowParticleSize(ParticleSizeInfo, 5, 0, 500),
|
||||
_flowParticleSpacing(ParticleSpacingInfo, 60, 0, 500),
|
||||
_flowSpeed(FlowSpeedInfo, 20, 0, 1000),
|
||||
_flowColor(FlowColorInfo, glm::vec4(0.8f, 0.7f, 0.0f, 0.6f),
|
||||
glm::vec4(0.f), glm::vec4(1.f)) {
|
||||
_flowReversed(ReverseFlowInfo, false),
|
||||
_flowSpeed(FlowSpeedInfo, 20, 0, 1000) {
|
||||
|
||||
// Set the default color table, just in case user defined paths are corrupt!
|
||||
_transferFunction = std::make_shared<TransferFunction>(absPath(_colorTablePaths[0]));
|
||||
|
||||
if(!extractInfoFromDictionary(dictionary)) {
|
||||
_sourceFileType = INVALID;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void RenderableFieldlinesSequence::initialize() {
|
||||
@@ -133,16 +161,27 @@ void RenderableFieldlinesSequence::initialize() {
|
||||
break;
|
||||
}
|
||||
|
||||
// No need to store source paths in memory if their states are already in RAM!
|
||||
// At this point there's at least one state loaded into memory!
|
||||
// No need to store source paths in memory if they are already in RAM!
|
||||
if (!_isLoadingStatesAtRuntime) {
|
||||
_sourceFiles.clear();
|
||||
}
|
||||
|
||||
computeSequenceEndTime();
|
||||
|
||||
// HANDLE PROPERTIES
|
||||
addProperty(_lineColor);
|
||||
// --------------------- HANDLE PROPERTIES --------------------- //
|
||||
// Add Property Groups
|
||||
addPropertySubOwner(_colorGroup);
|
||||
addPropertySubOwner(_flowGroup);
|
||||
|
||||
// Add Properties to the groups
|
||||
_colorGroup.addProperty(_colorMethod);
|
||||
_colorGroup.addProperty(_colorQuantity);
|
||||
_colorGroup.addProperty(_colorQuantityMin);
|
||||
_colorGroup.addProperty(_colorQuantityMax);
|
||||
_colorGroup.addProperty(_colorTablePath);
|
||||
_colorGroup.addProperty(_colorUniform);
|
||||
|
||||
_flowGroup.addProperty(_flowEnabled);
|
||||
_flowGroup.addProperty(_flowReversed);
|
||||
_flowGroup.addProperty(_flowColor);
|
||||
@@ -150,6 +189,52 @@ void RenderableFieldlinesSequence::initialize() {
|
||||
_flowGroup.addProperty(_flowParticleSpacing);
|
||||
_flowGroup.addProperty(_flowSpeed);
|
||||
|
||||
// Add Options to OptionProperties
|
||||
_colorMethod.addOption(ColorMethod::UNIFORM, "Uniform");
|
||||
_colorMethod.addOption(ColorMethod::BY_QUANTITY, "By Quantity");
|
||||
|
||||
// Add option for each extra quantity. We assume that there are just as many names to
|
||||
// extra variables as there are extra variables. We also assume that all states in the
|
||||
// given sequence have the same extra variables!
|
||||
const size_t N_EXTRA_QUANTITIES = _states[0].nExtraVariables();
|
||||
auto EXTRA_VARIABLE_NAMES_VEC = _states[0].extraVariableNames();
|
||||
for (size_t i = 0; i < N_EXTRA_QUANTITIES; ++i) {
|
||||
_colorQuantity.addOption(i, EXTRA_VARIABLE_NAMES_VEC[i]);
|
||||
}
|
||||
// Each quantity should have its own color table and color table range, no more, no less
|
||||
_colorTablePaths.resize(N_EXTRA_QUANTITIES, _colorTablePaths.back());
|
||||
_colorTableRanges.resize(N_EXTRA_QUANTITIES, _colorTableRanges.back());
|
||||
|
||||
// Add Property Callback Functions
|
||||
_colorQuantity.onChange([this] {
|
||||
LDEBUG("CHANGED COLORING QUANTITY");
|
||||
_shouldUpdateColorBuffer = true;
|
||||
_colorQuantityMin = std::to_string(_colorTableRanges[_colorQuantity].x);
|
||||
_colorQuantityMax = std::to_string(_colorTableRanges[_colorQuantity].y);
|
||||
_activeColorTable = &_colorTablePaths[_colorQuantity];
|
||||
_colorTablePath = *_activeColorTable;
|
||||
});
|
||||
|
||||
_colorTablePath.onChange([this] {
|
||||
// TOGGLE ACTIVE SHADER PROGRAM
|
||||
_transferFunction->setPath(_colorTablePath);
|
||||
*_activeColorTable = _colorTablePath;
|
||||
});
|
||||
|
||||
_colorQuantityMin.onChange([this] {
|
||||
LDEBUG("CHANGED MIN VALUE");
|
||||
// TODO CHECK IF VALID NUMBER!
|
||||
// _updateTransferFunctionMin = true;
|
||||
_colorTableRanges[_colorQuantity].x = std::stof(_colorQuantityMin);
|
||||
});
|
||||
|
||||
_colorQuantityMax.onChange([this] {
|
||||
LDEBUG("CHANGED MAX VALUE");
|
||||
// TODO CHECK IF VALID NUMBER!
|
||||
// _updateTransferFunctionMin = true;
|
||||
_colorTableRanges[_colorQuantity].y = std::stof(_colorQuantityMax);
|
||||
});
|
||||
|
||||
// Setup shader program
|
||||
_shaderProgram = OsEng.renderEngine().buildRenderProgram(
|
||||
"FieldlinesSequence",
|
||||
@@ -165,6 +250,7 @@ void RenderableFieldlinesSequence::initialize() {
|
||||
//------------------ Initialize OpenGL VBOs and VAOs-------------------------------//
|
||||
glGenVertexArrays(1, &_vertexArrayObject);
|
||||
glGenBuffers(1, &_vertexPositionBuffer);
|
||||
glGenBuffers(1, &_vertexColorBuffer);
|
||||
}
|
||||
|
||||
void RenderableFieldlinesSequence::deinitialize() {
|
||||
@@ -194,6 +280,7 @@ void RenderableFieldlinesSequence::render(const RenderData& data, RendererTasks&
|
||||
if (_activeTriggerTimeIndex != -1) {
|
||||
_shaderProgram->activate();
|
||||
|
||||
// Calculate Model View MatrixProjection
|
||||
const glm::dmat4 ROT_MAT = glm::dmat4(data.modelTransform.rotation);
|
||||
// const glm::mat4 SCALE_TRANSFORM = glm::mat4(1.0); // TODO remove if no use
|
||||
const glm::dmat4 MODEL_MAT =
|
||||
@@ -205,7 +292,19 @@ void RenderableFieldlinesSequence::render(const RenderData& data, RendererTasks&
|
||||
_shaderProgram->setUniform("modelViewProjection",
|
||||
data.camera.sgctInternal.projectionMatrix() * glm::mat4(MODEL_VIEW_MAT));
|
||||
|
||||
_shaderProgram->setUniform("lineColor", _lineColor);
|
||||
|
||||
_shaderProgram->setUniform("colorMethod", _colorMethod);
|
||||
_shaderProgram->setUniform("lineColor", _colorUniform);
|
||||
|
||||
if (_colorMethod == ColorMethod::BY_QUANTITY) {
|
||||
ghoul::opengl::TextureUnit textureUnit;
|
||||
textureUnit.activate();
|
||||
_transferFunction->bind(); // Calls update internally
|
||||
_shaderProgram->setUniform("colorTable", textureUnit);
|
||||
_shaderProgram->setUniform("colorTableRange",
|
||||
_colorTableRanges[_colorQuantity]);
|
||||
}
|
||||
|
||||
// Flow/Particles
|
||||
_shaderProgram->setUniform("usingParticles", _flowEnabled);
|
||||
_shaderProgram->setUniform("flowColor", _flowColor);
|
||||
@@ -238,8 +337,8 @@ void RenderableFieldlinesSequence::update(const UpdateData& data) {
|
||||
// Check if current time in OpenSpace is within sequence interval
|
||||
if (isWithinSequenceInterval(CURRENT_TIME)) {
|
||||
const int NEXT_IDX = _activeTriggerTimeIndex + 1;
|
||||
if (_activeTriggerTimeIndex < 0 // true => Previous frame was not within the sequence interval
|
||||
|| CURRENT_TIME < _startTimes[_activeTriggerTimeIndex] // true => OpenSpace has stepped back to a time represented by another state
|
||||
if (_activeTriggerTimeIndex < 0 // true => Previous frame was not within the sequence interval
|
||||
|| CURRENT_TIME < _startTimes[_activeTriggerTimeIndex] // true => OpenSpace has stepped back to a time represented by another state
|
||||
|| (NEXT_IDX < _nStates && CURRENT_TIME >= _startTimes[NEXT_IDX])) { // true => OpenSpace has stepped forward to a time represented by another state
|
||||
|
||||
updateActiveTriggerTimeIndex(CURRENT_TIME);
|
||||
@@ -275,30 +374,27 @@ void RenderableFieldlinesSequence::update(const UpdateData& data) {
|
||||
_states[0] = std::move(_newState);
|
||||
}
|
||||
|
||||
glBindVertexArray(_vertexArrayObject);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vertexPositionBuffer);
|
||||
updateVertexPositionBuffer();
|
||||
|
||||
const std::vector<glm::vec3>& VERTEX_POS_VEC =
|
||||
_states[_activeStateIndex].vertexPositions();
|
||||
|
||||
glBufferData(GL_ARRAY_BUFFER, VERTEX_POS_VEC.size() * sizeof(glm::vec3),
|
||||
&VERTEX_POS_VEC.front(), GL_STATIC_DRAW);
|
||||
|
||||
glEnableVertexAttribArray(_vertAttrVertexPos);
|
||||
glVertexAttribPointer(_vertAttrVertexPos, 3, GL_FLOAT, GL_FALSE, 0, 0);
|
||||
|
||||
// UNBIND
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
if (_states[_activeStateIndex].nExtraVariables() > 0) {
|
||||
_shouldUpdateColorBuffer = true;
|
||||
} else {
|
||||
_colorMethod = ColorMethod::UNIFORM;
|
||||
}
|
||||
|
||||
// Everything is set and ready for rendering!
|
||||
_needsUpdate = false;
|
||||
_needsUpdate = false;
|
||||
_newStateIsReady = false;
|
||||
}
|
||||
|
||||
if (_shouldUpdateColorBuffer) {
|
||||
updateVertexColorBuffer();
|
||||
_shouldUpdateColorBuffer = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline bool RenderableFieldlinesSequence::isWithinSequenceInterval(const double CURRENT_TIME) {
|
||||
inline bool RenderableFieldlinesSequence::isWithinSequenceInterval(const double CURRENT_TIME) const {
|
||||
return (CURRENT_TIME >= _startTimes[0]) && (CURRENT_TIME < _sequenceEndTime);
|
||||
}
|
||||
|
||||
@@ -327,6 +423,47 @@ void RenderableFieldlinesSequence::readNewState(const std::string& FILEPATH) {
|
||||
_isLoadingStateFromDisk = false;
|
||||
}
|
||||
|
||||
// Unbind buffers and arrays
|
||||
inline void unbindGL() {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
void RenderableFieldlinesSequence::updateVertexPositionBuffer() {
|
||||
glBindVertexArray(_vertexArrayObject);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vertexPositionBuffer);
|
||||
|
||||
const std::vector<glm::vec3>& VERTEX_POS_VEC =
|
||||
_states[_activeStateIndex].vertexPositions();
|
||||
|
||||
glBufferData(GL_ARRAY_BUFFER, VERTEX_POS_VEC.size() * sizeof(glm::vec3),
|
||||
&VERTEX_POS_VEC.front(), GL_STATIC_DRAW);
|
||||
|
||||
glEnableVertexAttribArray(_VA_POSITION);
|
||||
glVertexAttribPointer(_VA_POSITION, 3, GL_FLOAT, GL_FALSE, 0, 0);
|
||||
|
||||
unbindGL();
|
||||
}
|
||||
|
||||
void RenderableFieldlinesSequence::updateVertexColorBuffer() {
|
||||
glBindVertexArray(_vertexArrayObject);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vertexColorBuffer);
|
||||
|
||||
bool isSuccessful;
|
||||
const std::vector<float>& QUANTITY_VEC =
|
||||
_states[_activeStateIndex].extraVariable(_colorQuantity, isSuccessful);
|
||||
|
||||
if (isSuccessful) {
|
||||
glBufferData(GL_ARRAY_BUFFER, QUANTITY_VEC.size() * sizeof(float),
|
||||
&QUANTITY_VEC.front(), GL_STATIC_DRAW);
|
||||
|
||||
glEnableVertexAttribArray(_VA_COLOR);
|
||||
glVertexAttribPointer(_VA_COLOR, 1, GL_FLOAT, GL_FALSE, 0, 0);
|
||||
|
||||
unbindGL();
|
||||
}
|
||||
}
|
||||
|
||||
bool RenderableFieldlinesSequence::extractInfoFromDictionary(
|
||||
const ghoul::Dictionary& dictionary) {
|
||||
|
||||
@@ -390,6 +527,32 @@ bool RenderableFieldlinesSequence::extractInfoFromDictionary(
|
||||
return false;
|
||||
}
|
||||
|
||||
// Extract optional info from modfile
|
||||
ghoul::Dictionary colorTablesPathsDictionary;
|
||||
if (dictionary.getValue(KEY_COLOR_TABLE_PATHS, colorTablesPathsDictionary)) {
|
||||
const size_t N_PROVIDED_PATHS = colorTablesPathsDictionary.size();
|
||||
if (N_PROVIDED_PATHS > 0) {
|
||||
// Clear the default! It is already specified in the transferFunction
|
||||
_colorTablePaths.clear();
|
||||
for (size_t i = 1; i <= N_PROVIDED_PATHS; ++i) {
|
||||
_colorTablePaths.push_back(
|
||||
colorTablesPathsDictionary.value<std::string>( std::to_string(i) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ghoul::Dictionary colorTablesRangesDictionary;
|
||||
if (dictionary.getValue(KEY_COLOR_TABLE_RANGES, colorTablesRangesDictionary)) {
|
||||
const size_t N_PROVIDED_RANGES = colorTablesRangesDictionary.size();
|
||||
for (size_t i = 1; i <= N_PROVIDED_RANGES; ++i) {
|
||||
_colorTableRanges.push_back(
|
||||
colorTablesRangesDictionary.value<glm::vec2>( std::to_string(i) ) );
|
||||
}
|
||||
} else {
|
||||
_colorTableRanges.push_back(glm::vec2(0, 1));
|
||||
}
|
||||
|
||||
// Extract info specific to each inputType
|
||||
switch (_sourceFileType) {
|
||||
case CDF:
|
||||
LERROR(name << "CDF NOT YET IMPLEMENTED!");
|
||||
|
||||
@@ -27,8 +27,12 @@
|
||||
|
||||
#include <openspace/rendering/renderable.h>
|
||||
|
||||
#include <openspace/properties/optionproperty.h>
|
||||
#include <openspace/properties/scalar/intproperty.h>
|
||||
#include <openspace/properties/stringproperty.h>
|
||||
#include <openspace/properties/vector/vec4property.h>
|
||||
#include <openspace/rendering/transferfunction.h>
|
||||
|
||||
|
||||
#include <modules/fieldlinessequence/util/fieldlinesstate.h>
|
||||
|
||||
@@ -59,8 +63,9 @@ private:
|
||||
int _activeStateIndex = -1;
|
||||
int _activeTriggerTimeIndex = -1;
|
||||
bool _isLoadingStatesAtRuntime = true; // False => loading osfls at runtime
|
||||
bool _mustLoadNewStateFromDisk = false; // If still in same state as previous frame == false
|
||||
bool _mustLoadNewStateFromDisk = false;
|
||||
bool _needsUpdate = false; // If still in same state as previous frame == false
|
||||
bool _shouldUpdateColorBuffer = false;
|
||||
FieldlinesState _newState;
|
||||
size_t _nStates = 0;
|
||||
double _sequenceEndTime;
|
||||
@@ -69,39 +74,53 @@ private:
|
||||
std::atomic<bool> _isLoadingStateFromDisk{false};
|
||||
std::atomic<bool> _newStateIsReady{false};
|
||||
|
||||
|
||||
std::shared_ptr<TransferFunction> _transferFunction; // Transfer funtion (tf)
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _shaderProgram;
|
||||
|
||||
std::string* _activeColorTable;
|
||||
std::vector<std::string> _colorTablePaths {"${OPENSPACE_DATA}/colortables/kroyw.txt"}; // Default in case user doesn't specify otherwise
|
||||
std::vector<std::string> _sourceFiles; // Stored in RAM if files are loaded at runtime, else emptied after initialization
|
||||
std::vector<double> _startTimes;
|
||||
std::vector<FieldlinesState> _states;
|
||||
std::vector<std::string> _sourceFiles; // Stored in RAM if files are loaded at runtime, else emptied after initialization
|
||||
std::vector<glm::vec2> _colorTableRanges; // Values represents min & max values represented in the color table
|
||||
|
||||
GLuint _vertexArrayObject = 0;
|
||||
GLuint _vertexPositionBuffer = 0;
|
||||
GLuint _vertexColorBuffer = 0;
|
||||
|
||||
// THESE MUST CORRESPOND TO THE SHADER PROGRAM
|
||||
// TODO: THIS CAN BE DETERMINED BY ASKING THE SHADER PROGRAM TOO
|
||||
GLuint _vertAttrVertexPos = 0;
|
||||
const GLuint _VA_POSITION = 0;
|
||||
const GLuint _VA_COLOR = 1;
|
||||
|
||||
// ----------------------------- Properties -----------------------------
|
||||
properties::Vec4Property _lineColor; // Uniform Field Line Color
|
||||
properties::PropertyOwner _colorGroup; // Group to hold the color properties
|
||||
properties::OptionProperty _colorMethod; // Uniform/transfer function/topology?
|
||||
properties::OptionProperty _colorQuantity; // Index of the extra variable to color lines by
|
||||
properties::StringProperty _colorQuantityMin; // Color table/transfer function min
|
||||
properties::StringProperty _colorQuantityMax; // Color table/transfer function max
|
||||
properties::StringProperty _colorTablePath; // Color table/transfer function for "By Quantity" coloring
|
||||
properties::Vec4Property _colorUniform; // Uniform Field Line Color
|
||||
|
||||
properties::PropertyOwner _flowGroup;
|
||||
properties::BoolProperty _flowEnabled; // Toggle flow [ON/OFF]
|
||||
properties::BoolProperty _flowReversed; // Toggle flow direction [FORWARDS/BACKWARDS]
|
||||
properties::IntProperty _flowParticleSize; // Size of simulated flow particles
|
||||
properties::IntProperty _flowParticleSpacing; // Size of simulated flow particles
|
||||
properties::IntProperty _flowSpeed; // Speed of simulated flow
|
||||
properties::Vec4Property _flowColor; // Simulated particles' color
|
||||
properties::Vec4Property _flowColor; // Simulated particles' color
|
||||
properties::BoolProperty _flowEnabled; // Toggle flow [ON/OFF]
|
||||
properties::PropertyOwner _flowGroup; // Gropu to hold the flow/particle properties
|
||||
properties::IntProperty _flowParticleSize; // Size of simulated flow particles
|
||||
properties::IntProperty _flowParticleSpacing; // Size of simulated flow particles
|
||||
properties::BoolProperty _flowReversed; // Toggle flow direction [FORWARDS/BACKWARDS]
|
||||
properties::IntProperty _flowSpeed; // Speed of simulated flow
|
||||
|
||||
|
||||
void computeSequenceEndTime();
|
||||
bool extractInfoFromDictionary(const ghoul::Dictionary& dictionary);
|
||||
void extractTriggerTimesFromFileNames();
|
||||
void readNewState(const std::string& FILEPATH);
|
||||
void computeSequenceEndTime();
|
||||
bool extractInfoFromDictionary(const ghoul::Dictionary& dictionary);
|
||||
void extractTriggerTimesFromFileNames();
|
||||
void readNewState(const std::string& FILEPATH);
|
||||
|
||||
inline bool isWithinSequenceInterval(const double CURRENT_TIME);
|
||||
inline void updateActiveTriggerTimeIndex(const double CURRENT_TIME);
|
||||
inline bool isWithinSequenceInterval(const double CURRENT_TIME) const;
|
||||
|
||||
void updateActiveTriggerTimeIndex(const double CURRENT_TIME);
|
||||
void updateVertexPositionBuffer();
|
||||
void updateVertexColorBuffer();
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -24,21 +24,42 @@
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
uniform mat4 modelViewProjection;
|
||||
uniform bool usingParticles;
|
||||
uniform double time;
|
||||
uniform int particleSize;
|
||||
uniform int particleSpeed;
|
||||
uniform int particleSpacing;
|
||||
uniform vec4 flowColor;
|
||||
uniform vec4 lineColor;
|
||||
#include "PowerScaling/powerScaling_vs.hglsl"
|
||||
|
||||
layout(location = 0) in vec3 in_position; // in meters
|
||||
// General Uniforms that's always needed
|
||||
uniform vec4 lineColor;
|
||||
uniform mat4 modelViewProjection;
|
||||
|
||||
// Uniforms needed to color by quantity
|
||||
uniform int colorMethod;
|
||||
uniform sampler1D colorTable;
|
||||
uniform vec2 colorTableRange;
|
||||
|
||||
// Uniforms needed for Particle Flow
|
||||
uniform vec4 flowColor;
|
||||
uniform int particleSize;
|
||||
uniform int particleSpeed;
|
||||
uniform int particleSpacing;
|
||||
uniform double time;
|
||||
uniform bool usingParticles;
|
||||
|
||||
layout(location = 0) in vec3 in_position; // Should be provided in meters
|
||||
layout(location = 1) in float in_color_scalar; // The extra value used to color lines. Location must correspond to _VA_COLOR in renderablefieldlinessequence.h
|
||||
|
||||
// These should correspond to the enum 'ColorMethod' in renderablefieldlinesequence.cpp
|
||||
const int UNIFORM_COLOR = 0;
|
||||
const int COLOR_BY_QUANTITY = 1;
|
||||
|
||||
out vec4 vs_color;
|
||||
out float vs_depth;
|
||||
|
||||
#include "PowerScaling/powerScaling_vs.hglsl"
|
||||
|
||||
vec4 getTransferFunctionColor() {
|
||||
// Remap the color scalar to a [0,1] range
|
||||
const float LOOK_UP_VAL = (in_color_scalar - colorTableRange.x) /
|
||||
(colorTableRange.y - colorTableRange.x);
|
||||
return texture(colorTable, LOOK_UP_VAL);
|
||||
}
|
||||
|
||||
bool isPartOfParticle(const double TIME, const int VERTEX_ID, const int PARTICLE_SIZE,
|
||||
const int PARTICLE_SPEED, const int PARTICLE_SPACING) {
|
||||
@@ -59,6 +80,11 @@ void main() {
|
||||
vs_color = lineColor;
|
||||
}
|
||||
|
||||
if (colorMethod == COLOR_BY_QUANTITY) {
|
||||
const vec4 QUANTITY_COLOR = getTransferFunctionColor();
|
||||
vs_color = vec4(QUANTITY_COLOR.xyz, vs_color.a * QUANTITY_COLOR.a);
|
||||
}
|
||||
|
||||
vec4 position_in_meters = vec4(in_position, 1);
|
||||
vec4 positionClipSpace = modelViewProjection * position_in_meters;
|
||||
gl_Position = z_normalization(positionClipSpace);
|
||||
|
||||
@@ -108,4 +108,17 @@ bool FieldlinesState::loadStateFromOsfls(const std::string& PATH_TO_OSFLS_FILE)
|
||||
return true;
|
||||
}
|
||||
|
||||
// Returns one of the extra variable vectors, _extraVariables[INDEX].
|
||||
// If INDEX is out of scope an empty vector is returned and the referenced bool will be false.
|
||||
const vector<float>& FieldlinesState::extraVariable(const size_t INDEX,
|
||||
bool& isSuccessful) const {
|
||||
if (INDEX < _extraVariables.size()) {
|
||||
isSuccessful = true;
|
||||
return _extraVariables[INDEX];
|
||||
}
|
||||
isSuccessful = false;
|
||||
// return empty vector which goes out of scope hence unusable!
|
||||
return std::vector<float>();
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
using std::vector;
|
||||
|
||||
namespace openspace {
|
||||
|
||||
class FieldlinesState {
|
||||
@@ -46,23 +48,29 @@ public:
|
||||
|
||||
bool loadStateFromOsfls(const std::string& PATH_TO_OSFLS_FILE);
|
||||
|
||||
// Getters
|
||||
double triggerTime() { return _triggerTime; }
|
||||
Model model() { return _model; }
|
||||
const std::vector<glm::vec3>& vertexPositions() { return _vertexPositions; }
|
||||
const std::vector<GLint>& lineStart() { return _lineStart; }
|
||||
const std::vector<GLsizei>& lineCount() { return _lineCount; }
|
||||
// ------------------------------GETTERS-----------------------------------------//
|
||||
const vector<vector<float>>& extraVariables() const { return _extraVariables; }
|
||||
const vector<std::string>& extraVariableNames() const { return _extraVariableNames; }
|
||||
const vector<GLsizei>& lineCount() const { return _lineCount; }
|
||||
const vector<GLint>& lineStart() const { return _lineStart; }
|
||||
size_t nExtraVariables() const { return _extraVariables.size(); }
|
||||
Model model() const { return _model; }
|
||||
double triggerTime() const { return _triggerTime; }
|
||||
const vector<glm::vec3>& vertexPositions() const { return _vertexPositions; }
|
||||
|
||||
// Special getter. Returns extraVariables[INDEX].
|
||||
const vector<float>& extraVariable(const size_t INDEX, bool& isSuccesful) const;
|
||||
|
||||
private:
|
||||
bool _isMorphable = false;
|
||||
double _triggerTime = -1.0;
|
||||
Model _model;
|
||||
|
||||
std::vector<glm::vec3> _vertexPositions;
|
||||
std::vector<GLint> _lineStart;
|
||||
std::vector<GLsizei> _lineCount;
|
||||
std::vector<std::vector<float>> _extraVariables;
|
||||
std::vector<std::string> _extraVariableNames;
|
||||
vector<glm::vec3> _vertexPositions;
|
||||
vector<GLint> _lineStart;
|
||||
vector<GLsizei> _lineCount;
|
||||
vector<vector<float>> _extraVariables;
|
||||
vector<std::string> _extraVariableNames;
|
||||
// TODO: Maybe introduce a vector containing seed point indices
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user