diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp index eb5831e681..fa6dfe77ef 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.cpp @@ -50,12 +50,44 @@ namespace { const char* VALUE_INPUT_FILE_TYPE_CDF = "cdf"; 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 EnableFlowInfo = { + "Enable", "ON/OFF", + "Toggles the rendering of moving particles along the lines. Can e.g. illustrate magnetic flow." + }; + static const openspace::properties::Property::PropertyInfo ReverseFlowInfo = { + "reversed", "Reversed Flow", "Toggle to make the flow move in the opposite direction." + }; + static const openspace::properties::Property::PropertyInfo ParticleSizeInfo = { + "particleSize", "Particle Size", "Size of the particles." + }; + static const openspace::properties::Property::PropertyInfo ParticleSpacingInfo = { + "particleSpacing", "Particle Spacing", "Spacing inbetween particles." + }; + 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." + }; } // namespace namespace openspace { RenderableFieldlinesSequence::RenderableFieldlinesSequence(const ghoul::Dictionary& dictionary) - : Renderable(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" }), + _flowEnabled(EnableFlowInfo, true), + _flowReversed(ReverseFlowInfo, false), + _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)) { if(!extractInfoFromDictionary(dictionary)) { _sourceFileType = INVALID; @@ -92,6 +124,16 @@ void RenderableFieldlinesSequence::initialize() { computeSequenceEndTime(); + // HANDLE PROPERTIES + addProperty(_lineColor); + addPropertySubOwner(_flowGroup); + _flowGroup.addProperty(_flowEnabled); + _flowGroup.addProperty(_flowReversed); + _flowGroup.addProperty(_flowColor); + _flowGroup.addProperty(_flowParticleSize); + _flowGroup.addProperty(_flowParticleSpacing); + _flowGroup.addProperty(_flowSpeed); + // Setup shader program _shaderProgram = OsEng.renderEngine().buildRenderProgram( "FieldlinesSequence", @@ -124,23 +166,32 @@ void RenderableFieldlinesSequence::deinitialize() { } bool RenderableFieldlinesSequence::isReady() const { - return true; + return _sourceFileType != INVALID; } void RenderableFieldlinesSequence::render(const RenderData& data, RendererTasks&) { if (_activeStateIndex != -1) { _shaderProgram->activate(); - const glm::dmat4 ROTATION_TRANSFORM = glm::dmat4(data.modelTransform.rotation); + 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_TRANSFORM = + const glm::dmat4 MODEL_MAT = glm::translate(glm::dmat4(1.0), data.modelTransform.translation) * - ROTATION_TRANSFORM * - glm::dmat4(glm::scale(glm::dmat4(1.0), glm::dvec3(data.modelTransform.scale))); - const glm::dmat4 MODEL_VIEW_TRANSFORM = data.camera.combinedViewMatrix() * MODEL_TRANSFORM; + ROT_MAT * + glm::dmat4(glm::scale(glm::dmat4(1), glm::dvec3(data.modelTransform.scale))); + const glm::dmat4 MODEL_VIEW_MAT = data.camera.combinedViewMatrix() * MODEL_MAT; _shaderProgram->setUniform("modelViewProjection", - data.camera.sgctInternal.projectionMatrix() * glm::mat4(MODEL_VIEW_TRANSFORM)); + data.camera.sgctInternal.projectionMatrix() * glm::mat4(MODEL_VIEW_MAT)); + + _shaderProgram->setUniform("lineColor", _lineColor); + // Flow/Particles + _shaderProgram->setUniform("usingParticles", _flowEnabled); + _shaderProgram->setUniform("flowColor", _flowColor); + _shaderProgram->setUniform("particleSize", _flowParticleSize); + _shaderProgram->setUniform("particleSpeed", _flowSpeed); + _shaderProgram->setUniform("particleSpacing", _flowParticleSpacing); + _shaderProgram->setUniform("time", OsEng.runTime() * (_flowReversed ? -1 : 1)); glBindVertexArray(_vertexArrayObject); glMultiDrawArrays( @@ -216,7 +267,7 @@ void RenderableFieldlinesSequence::updateActiveStateIndex(const double CURRENT_T _activeStateIndex = 0; } } else { - _activeStateIndex = _nStates - 1; + _activeStateIndex = static_cast(_nStates) - 1; } } diff --git a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h index 9f5c44d45a..aeb54134e7 100644 --- a/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h +++ b/modules/fieldlinessequence/rendering/renderablefieldlinessequence.h @@ -27,6 +27,9 @@ #include +#include +#include + #include namespace openspace { @@ -71,6 +74,18 @@ private: // TODO: THIS CAN BE DETERMINED BY ASKING THE SHADER PROGRAM TOO GLuint _vertAttrVertexPos = 0; + // ----------------------------- Properties ----------------------------- + properties::Vec4Property _lineColor; // 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 + + void computeSequenceEndTime(); bool extractInfoFromDictionary(const ghoul::Dictionary& dictionary); inline bool isWithinSequenceInterval(const double CURRENT_TIME); diff --git a/modules/fieldlinessequence/shaders/fieldlinessequence_vs.glsl b/modules/fieldlinessequence/shaders/fieldlinessequence_vs.glsl index cc6f48bc93..906953c7b7 100644 --- a/modules/fieldlinessequence/shaders/fieldlinessequence_vs.glsl +++ b/modules/fieldlinessequence/shaders/fieldlinessequence_vs.glsl @@ -24,7 +24,14 @@ #version __CONTEXT__ -uniform mat4 modelViewProjection; +uniform mat4 modelViewProjection; +uniform bool usingParticles; +uniform double time; +uniform int particleSize; +uniform int particleSpeed; +uniform int particleSpacing; +uniform vec4 flowColor; +uniform vec4 lineColor; layout(location = 0) in vec3 in_position; // in meters @@ -33,8 +40,25 @@ out float vs_depth; #include "PowerScaling/powerScaling_vs.hglsl" +bool isPartOfParticle(const double TIME, const int VERTEX_ID, const int PARTICLE_SIZE, + const int PARTICLE_SPEED, const int PARTICLE_SPACING) { + const int MODULUS_RESULT = int(double(PARTICLE_SPEED) * TIME + VERTEX_ID) % PARTICLE_SPACING; + return MODULUS_RESULT > 0 && MODULUS_RESULT <= PARTICLE_SIZE; +} + void main() { - vs_color = vec4(0.75, 0.5, 0.0, 0.75); + + const bool IS_PARTICLE = usingParticles && isPartOfParticle(time, gl_VertexID, + particleSize, + particleSpeed, + particleSpacing); + + if (IS_PARTICLE) { + vs_color = flowColor; + } else { + vs_color = lineColor; + } + vec4 position_in_meters = vec4(in_position, 1); vec4 positionClipSpace = modelViewProjection * position_in_meters; gl_Position = z_normalization(positionClipSpace);