more pr comments fixed

This commit is contained in:
ElonOlsson
2021-09-10 17:11:44 -04:00
parent cd4ebd7532
commit 505215964a
21 changed files with 693 additions and 852 deletions

View File

@@ -39,12 +39,10 @@ local fieldlines = {
Type = "RenderableFieldlinesSequence",
SourceFolder = fieldlinesDirectory,
AlphaBlendlingEnabled = false,
InputFileType = "osfls",
InputFileType = "Osfls",
ColorTablePaths = {
asset.localResource("transferfunctions/density-fieldlines.txt"),
asset.localResource("transferfunctions/velocity-fieldlines.txt")
--masDensityColorTable,
--masVelocityColorTable,
},
ColorTableMinMax = {
{ 0, 1000000 },

View File

@@ -1,12 +1,6 @@
local assetHelper = asset.require('util/asset_helper')
local heliosphereTransforms = asset.require('scene/solarsystem/sun/transforms_heliosphere')
--local transferFunctions = asset.localResource("transferfunctions")
local fluxnodeColorTable = asset.localResource("transferfunctions/flux-nodes.txt")
local fluxnodeColorTableCMR = asset.localResource("transferfunctions/CMR.txt")
local fluxnodeColorTableEarth = asset.localResource("transferfunctions/flux-nodes-grey-scale.txt")
local fluxnodeColorTableFlow = asset.localResource("transferfunctions/flux-nodes-flow.txt")
local fluxnodesBinaries = asset.syncedResource({
Name = "Bastille day Flux nodes binaries",
Type = "HttpSynchronization",
@@ -39,18 +33,14 @@ local Fluxnodes = {
Type = "RenderableFluxNodes",
SourceFolder = fluxnodesBinaries,
ColorTablePaths = {
--Standard = fluxnodeColorTable,
Standard = asset.localResource("transferfunctions/flux-nodes.txt"),
--CMR = fluxnodeColorTableCMR,
CMR = asset.localResource("transferfunctions/CMR.txt"),
--Earth = fluxnodeColorTableEarth,
Earth = asset.localResource("transferfunctions/flux-nodes-grey-scale.txt"),
--Flow = fluxnodeColorTableFlow,
Flow = asset.localResource("transferfunctions/flux-nodes-flow.txt")
},
LoadAtRuntime = true,
ScaleToMeters = 1.0,
--ScaleToMeters = 1.0,
SecondsBefore = 24*60*60,
SecondsAfter = 24*60*60,
Enabled = true

View File

@@ -18,7 +18,7 @@ local earthMagnetosphere = {
SourceFolder = fieldlinesDirectory,
LineWidth = 1.0,
AlphaBlendlingEnabled = false,
InputFileType = "osfls", -- openspace Field lines Sequence
InputFileType = "Osfls", -- openspace Field lines Sequence
MaskingEnabled = true,
MaskingQuantity = 5, -- corresponds to "topology"
MaskingRanges = {{-0, 0}},

View File

@@ -34,7 +34,6 @@
#include <openspace/util/updatestructures.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/io/texture/texturereader.h>
#include <ghoul/logging/logmanager.h>
#include <optional>
@@ -112,7 +111,7 @@ RenderablePlaneTimeVaryingImage::RenderablePlaneTimeVaryingImage(
}
addProperty(_texturePath);
_texturePath.onChange([this]() {loadTexture(); });
_texturePath.onChange([this]() { _texture = loadTexture(); });
if (p.renderType.has_value()) {
switch (*p.renderType) {
@@ -178,7 +177,7 @@ void RenderablePlaneTimeVaryingImage::initializeGL() {
_textureFiles[i]->purgeFromRAM();
}
if (!_isLoadingLazily) {
loadTexture();
_texture = loadTexture();
}
}
@@ -226,7 +225,7 @@ void RenderablePlaneTimeVaryingImage::update(const UpdateData& data) {
ZoneScoped
RenderablePlane::update(data);
if (!_enabled || _startTimes.size() == 0) {
if (!_enabled || _startTimes.empty()) {
return;
}
bool needsUpdate = false;
@@ -241,7 +240,7 @@ void RenderablePlaneTimeVaryingImage::update(const UpdateData& data) {
// true => We stepped forward to a time represented by another state
(nextIdx < _sourceFiles.size() && currentTime >= _startTimes[nextIdx]))
{
updateActiveTriggerTimeIndex(currentTime);
_activeTriggerTimeIndex = updateActiveTriggerTimeIndex(currentTime);
needsUpdate = true;
} // else we're still in same state as previous frame (no changes needed)
@@ -253,13 +252,16 @@ void RenderablePlaneTimeVaryingImage::update(const UpdateData& data) {
}
if (needsUpdate || _textureIsDirty) {
loadTexture();
_texture = loadTexture();
_textureIsDirty = false;
}
}
void RenderablePlaneTimeVaryingImage::render(const RenderData& data, RendererTasks& t) {
if (data.time.j2000Seconds() < _sequenceEndTime) {
if (!_startTimes.empty() &&
data.time.j2000Seconds() < _sequenceEndTime &&
data.time.j2000Seconds() > _startTimes[0])
{
glDisable(GL_CULL_FACE);
RenderablePlane::render(data, t);
}
@@ -282,20 +284,24 @@ void RenderablePlaneTimeVaryingImage::extractTriggerTimesFromFileNames() {
}
}
void RenderablePlaneTimeVaryingImage::updateActiveTriggerTimeIndex(double currentTime) {
int RenderablePlaneTimeVaryingImage::updateActiveTriggerTimeIndex(double currentTime)
const
{
int activeIndex = 0;
auto iter = std::upper_bound(_startTimes.begin(), _startTimes.end(), currentTime);
if (iter != _startTimes.end()) {
if (iter != _startTimes.begin()) {
std::ptrdiff_t idx = std::distance(_startTimes.begin(), iter);
_activeTriggerTimeIndex = static_cast<int>(idx) - 1;
activeIndex = static_cast<int>(idx) - 1;
}
else {
_activeTriggerTimeIndex = 0;
activeIndex = 0;
}
}
else {
_activeTriggerTimeIndex = static_cast<int>(_sourceFiles.size() - 1);
activeIndex = static_cast<int>(_sourceFiles.size() - 1);
}
return activeIndex;
}
void RenderablePlaneTimeVaryingImage::computeSequenceEndTime() {
@@ -308,9 +314,11 @@ void RenderablePlaneTimeVaryingImage::computeSequenceEndTime() {
}
}
void RenderablePlaneTimeVaryingImage::loadTexture() {
ghoul::opengl::Texture* RenderablePlaneTimeVaryingImage::loadTexture() const{
ghoul::opengl::Texture* texture = nullptr;
if (_activeTriggerTimeIndex != -1) {
_texture = _textureFiles[_activeTriggerTimeIndex].get();
texture = _textureFiles[_activeTriggerTimeIndex].get();
}
return texture;
}
} // namespace openspace

View File

@@ -54,10 +54,10 @@ protected:
virtual void bindTexture() override;
private:
void loadTexture();
ghoul::opengl::Texture* loadTexture() const;
void extractTriggerTimesFromFileNames();
bool extractMandatoryInfoFromDictionary();
void updateActiveTriggerTimeIndex(double currenttime);
int updateActiveTriggerTimeIndex(double currenttime) const;
void computeSequenceEndTime();
// If there's just one state it should never disappear

View File

@@ -118,9 +118,11 @@ namespace {
constexpr openspace::properties::Property::PropertyInfo BackgroundInfo = {
"Background",
"Render as Background",
"Enables/Disables background rendering."
"If this value is set, the sphere is rendered in the background rendering bin, "
"causing it to be rendered before most other scene graph nodes"
};
struct [[codegen::Dictionary(RenerableTimeVaryingSphere)]] Parameters {
// [[codegen::verbatim(SizeInfo.description)]]
float size;
@@ -163,6 +165,8 @@ namespace {
namespace openspace {
double extractTriggerTimeFromFileName(const std::string& filePath);
documentation::Documentation RenderableTimeVaryingSphere::Documentation() {
return codegen::doc<Parameters>("base_renderable_time_varying_sphere");
}
@@ -226,9 +230,6 @@ RenderableTimeVaryingSphere::RenderableTimeVaryingSphere(
addProperty(_segments);
_segments.onChange([this]() { _sphereIsDirty = true; });
addProperty(_textureSourcePath);
_textureSourcePath.onChange([this]() { loadTexture(); });
addProperty(_mirrorTexture);
addProperty(_useAdditiveBlending);
addProperty(_fadeOutThreshold);
@@ -276,13 +277,12 @@ void RenderableTimeVaryingSphere::initializeGL() {
);
}
);
_shader->setIgnoreUniformLocationError(
ghoul::opengl::ProgramObject::IgnoreError::Yes
);
ghoul::opengl::updateUniformLocations(*_shader, _uniformCache, UniformNames);
bool success = extractMandatoryInfoFromDictionary();
if (!success) {
return;
}
extractMandatoryInfoFromSourceFolder();
computeSequenceEndTime();
loadTexture();
}
@@ -308,12 +308,9 @@ void RenderableTimeVaryingSphere::render(const RenderData& data, RendererTasks&)
glm::dmat4(data.modelTransform.rotation) *
glm::scale(glm::dmat4(1.0), glm::dvec3(data.modelTransform.scale));
glm::dmat3 modelRotation = glm::dmat3(data.modelTransform.rotation);
glm::dmat3 modelRotation = data.modelTransform.rotation;
// Activate shader
using IgnoreError = ghoul::opengl::ProgramObject::IgnoreError;
_shader->activate();
_shader->setIgnoreUniformLocationError(IgnoreError::Yes);
glm::mat4 modelViewProjection = data.camera.projectionMatrix() *
glm::mat4(data.camera.combinedViewMatrix() * modelTransform);
@@ -335,7 +332,8 @@ void RenderableTimeVaryingSphere::render(const RenderData& data, RendererTasks&)
const float stopLogFadeDistance = startLogFadeDistance + 1.f;
if (logDistCamera > startLogFadeDistance &&
logDistCamera < stopLogFadeDistance) {
logDistCamera < stopLogFadeDistance)
{
const float fadeFactor = glm::clamp(
(logDistCamera - startLogFadeDistance) /
(stopLogFadeDistance - startLogFadeDistance),
@@ -357,7 +355,8 @@ void RenderableTimeVaryingSphere::render(const RenderData& data, RendererTasks&)
const float stopLogFadeDistance = startLogFadeDistance + 1.f;
if (logDistCamera > startLogFadeDistance &&
logDistCamera < stopLogFadeDistance) {
logDistCamera < stopLogFadeDistance)
{
const float fadeFactor = glm::clamp(
(logDistCamera - startLogFadeDistance) /
(stopLogFadeDistance - startLogFadeDistance),
@@ -377,7 +376,7 @@ void RenderableTimeVaryingSphere::render(const RenderData& data, RendererTasks&)
}
_shader->setUniform(_uniformCache.opacity, adjustedOpacity);
_shader->setUniform(_uniformCache._mirrorTexture, _mirrorTexture.value());
_shader->setUniform(_uniformCache._mirrorTexture, _mirrorTexture);
ghoul::opengl::TextureUnit unit;
unit.activate();
@@ -408,7 +407,7 @@ void RenderableTimeVaryingSphere::render(const RenderData& data, RendererTasks&)
glDepthMask(true);
}
_shader->setIgnoreUniformLocationError(IgnoreError::No);
_shader->setIgnoreUniformLocationError(ghoul::opengl::ProgramObject::IgnoreError::No);
_shader->deactivate();
if (orientation == Orientation::Inside) {
@@ -418,61 +417,51 @@ void RenderableTimeVaryingSphere::render(const RenderData& data, RendererTasks&)
glEnable(GL_CULL_FACE);
}
glDisable(GL_CULL_FACE);
}
bool RenderableTimeVaryingSphere::extractMandatoryInfoFromDictionary()
{
void RenderableTimeVaryingSphere::extractMandatoryInfoFromSourceFolder() {
// Ensure that the source folder exists and then extract
// the files with the same extension as <inputFileTypeString>
namespace fs = std::filesystem;
fs::path sourceFolder = absPath(_textureSourcePath);
if (std::filesystem::is_directory(sourceFolder)) {
// Extract all file paths from the provided folder
_files.clear();
//_sourceFiles.clear();
namespace fs = std::filesystem;
for (const fs::directory_entry& e : fs::directory_iterator(sourceFolder)) {
if (e.is_regular_file()) {
std::string filePath = e.path().string();
double time = extractTriggerTimeFromFileName(filePath);
std::unique_ptr<ghoul::opengl::Texture> t =
ghoul::io::TextureReader::ref().loadTexture(filePath);
t->setInternalFormat(GL_COMPRESSED_RGBA);
t->uploadTexture();
t->setFilter(ghoul::opengl::Texture::FilterMode::Linear);
t->purgeFromRAM();
_files.push_back({ filePath, time, std::move(t) });
}
}
std::sort(
_files.begin(), _files.end(),
[](const FileData& a, const FileData& b) {
return a.time < b.time;
}
if (!std::filesystem::is_directory(sourceFolder)) {
throw ghoul::RuntimeError(
"Source folder for timevaryingsphere is not a valid directory"
);
// Ensure that there are available and valid source files left
if (_files.empty()) {
LERROR(fmt::format(
"{}: {} contains no {} files",
_identifier, _textureSourcePath, "extension"
));
return false;
}
// Extract all file paths from the provided folder
_files.clear();
//_sourceFiles.clear();
namespace fs = std::filesystem;
for (const fs::directory_entry& e : fs::directory_iterator(sourceFolder)) {
if (e.is_regular_file()) {
std::string filePath = e.path().string();
double time = extractTriggerTimeFromFileName(filePath);
std::unique_ptr<ghoul::opengl::Texture> t =
ghoul::io::TextureReader::ref().loadTexture(filePath);
t->setInternalFormat(GL_COMPRESSED_RGBA);
t->uploadTexture();
t->setFilter(ghoul::opengl::Texture::FilterMode::Linear);
t->purgeFromRAM();
_files.push_back({ filePath, time, std::move(t) });
}
}
else {
LERROR(fmt::format(
"{}: FieldlinesSequence {} is not a valid directory",
_identifier, _textureSourcePath
));
return false;
}
LDEBUG("returning true in extractMandatoryInfoFromDictionary");
return true;
std::sort(
_files.begin(), _files.end(),
[](const FileData& a, const FileData& b) {
return a.time < b.time;
}
);
// Ensure that there are available and valid source files left
if (_files.empty()) {
throw ghoul::RuntimeError(
"Source folder for timevaryingsphere contains no files"
);
}
}
void RenderableTimeVaryingSphere::update(const UpdateData& data) {
@@ -495,29 +484,24 @@ void RenderableTimeVaryingSphere::update(const UpdateData& data) {
(nextIdx < _files.size() && currentTime >= _files[nextIdx].time))
{
updateActiveTriggerTimeIndex(currentTime);
// _mustLoadNewStateFromDisk = true;
_needsUpdate = true;
_sphereIsDirty = true;
} // else {we're still in same state as previous frame (no changes needed)}
}
else {
// not in interval => set everything to false
_activeTriggerTimeIndex = 0;
_needsUpdate = false;
}
if ((_needsUpdate || _sphereIsDirty) && !_isLoadingTexture) {
if (_sphereIsDirty) {
_sphere = std::make_unique<Sphere>(_size, _segments);
_sphere->initialize();
_isLoadingTexture = true;
loadTexture();
_sphereIsDirty = false;
}
}
// Extract J2000 time from file names
// Requires files to be named as such: 'YYYY-MM-DDTHH-MM-SS-XXX.png'
double RenderableTimeVaryingSphere::extractTriggerTimeFromFileName(
const std::string& filePath) {
double extractTriggerTimeFromFileName(const std::string& filePath) {
// Extract the filename from the path (without extension)
std::string timeString = std::filesystem::path(filePath).stem().string();
@@ -540,9 +524,8 @@ void RenderableTimeVaryingSphere::updateActiveTriggerTimeIndex(double currentTim
);
if (iter != _files.end()) {
if (iter != _files.begin()) {
_activeTriggerTimeIndex = static_cast<int>(
std::distance(_files.begin(), iter)
) - 1;
ptrdiff_t idx = std::distance(_files.begin(), iter);
_activeTriggerTimeIndex = static_cast<int>(idx - 1);
}
else {
_activeTriggerTimeIndex = 0;
@@ -561,17 +544,11 @@ void RenderableTimeVaryingSphere::computeSequenceEndTime() {
(static_cast<double>(_files.size()) - 1.0);
_sequenceEndTime = lastTriggerTime + averageStateDuration;
}
else {
// If there's just one state it should never disappear!
_sequenceEndTime = std::numeric_limits<double>::max();
}
}
void RenderableTimeVaryingSphere::loadTexture() {
if (_activeTriggerTimeIndex != -1) {
_texture = _files[_activeTriggerTimeIndex].texture.get();
_isLoadingTexture = false;
}
}
} // namespace openspace

View File

@@ -44,12 +44,6 @@ class Sphere;
struct RenderData;
struct UpdateData;
struct FileData {
std::string path;
double time;
std::unique_ptr<ghoul::opengl::Texture> texture;
};
namespace documentation { struct Documentation; }
class RenderableTimeVaryingSphere : public Renderable {
@@ -67,19 +61,20 @@ public:
static documentation::Documentation Documentation();
private:
struct FileData {
std::string path;
double time;
std::unique_ptr<ghoul::opengl::Texture> texture;
};
void loadTexture();
double extractTriggerTimeFromFileName(const std::string& filePath);
bool extractMandatoryInfoFromDictionary();
void extractMandatoryInfoFromSourceFolder();
void updateActiveTriggerTimeIndex(double currenttime);
void computeSequenceEndTime();
// Estimated end of sequence.
double _sequenceEndTime;
bool _needsUpdate = false;
// If there's just one state it should never disappear!
double _sequenceEndTime = std::numeric_limits<double>::max();
std::vector<FileData> _files;
int _activeTriggerTimeIndex = 0;
// Number of states in the sequence
bool _isLoadingTexture = false;
properties::StringProperty _textureSourcePath;
properties::OptionProperty _orientation;
@@ -97,7 +92,6 @@ private:
ghoul::opengl::ProgramObject* _shader = nullptr;
ghoul::opengl::Texture* _texture = nullptr;
std::unique_ptr<ghoul::filesystem::File> _textureFile;
std::unique_ptr<Sphere> _sphere;
UniformCache(opacity, modelViewProjection, modelViewRotation, colorTexture,

View File

@@ -41,8 +41,8 @@ Fragment getFragment() {
frag.color = texture(texture1, vs_st);
}
else {
if (mirrorBackside){
frag.color = texture(texture1, vec2(1 - vs_st.s, vs_st.t));
if (mirrorBackside) {
frag.color = texture(texture1, vec2(1.0 - vs_st.s, vs_st.t));
}
else {
frag.color = texture(texture1, vs_st);

View File

@@ -47,11 +47,6 @@
namespace {
constexpr const char* _loggerCat = "RenderableFieldlinesSequence";
constexpr const GLuint VaPosition = 0; // MUST CORRESPOND TO THE SHADER PROGRAM
constexpr const GLuint VaColor = 1; // MUST CORRESPOND TO THE SHADER PROGRAM
constexpr const GLuint VaMasking = 2; // MUST CORRESPOND TO THE SHADER PROGRAM
// --------------------------------- Property Info -------------------------------- //
constexpr openspace::properties::Property::PropertyInfo ColorMethodInfo = {
"ColorMethod",
"Color Method",
@@ -170,12 +165,12 @@ namespace {
};
struct [[codegen::Dictionary(RenderableFieldlinesSequence)]] Parameters {
// osfls, cdf or json
enum class SourceFileType {
cdf,
json,
osfls
Cdf,
Json,
Osfls
};
// Input file type. Should be cdf, json or osfls
SourceFileType inputFileType;
// Should be path to folder containing the input files
@@ -186,7 +181,10 @@ namespace {
std::optional<std::filesystem::path> seedPointDirectory [[codegen::directory()]];
// Currently supports: batsrus, enlil & pfss
std::optional<std::string> simluationModel;
std::optional<std::string> simulationModel;
//sim mod
//std::optional<openspace::fls::Model> model;
// Extra variables such as rho, p or t
std::optional<std::vector<std::string>> extraVariables;
@@ -195,8 +193,8 @@ namespace {
std::optional<std::string> tracingVariable;
// 1.f is default, assuming meters as input.
// In setup it is used to scale JSON coordinates.
// During runtime it is used to scale domain limits.
// Convert the models distance unit, ex. AU for Enlil, to meters.
// Can be used during runtime to scale domain limits.
std::optional<float> scaleToMeters;
// If False (default) => Load in initializing step and store in RAM
@@ -221,7 +219,7 @@ namespace {
std::optional<bool> maskingEnabled;
// [[codegen::verbatim(MaskingQuantityInfo.description)]]
std::optional<int> MaskingQuantity;
std::optional<int> maskingQuantity;
// Values should be entered as {{X, Y},{X, Y}} where X & Y are numbers
std::optional<std::vector<glm::vec2>> maskingRanges;
@@ -243,6 +241,11 @@ namespace {
} // namespace
namespace openspace {
fls::Model stringToModel(std::string str);
std::unordered_map<std::string, std::vector<glm::vec3>>
extractSeedPointsFromFiles(std::filesystem::path);
std::vector<std::string>
extractMagnitudeVarsFromStrings(std::vector<std::string> extrVars);
documentation::Documentation RenderableFieldlinesSequence::Documentation() {
return codegen::doc<Parameters>("fieldlinessequence_renderablefieldlinessequence");
@@ -255,7 +258,10 @@ RenderableFieldlinesSequence::RenderableFieldlinesSequence(
, _colorMethod(ColorMethodInfo, properties::OptionProperty::DisplayType::Radio)
, _colorQuantity(ColorQuantityInfo, properties::OptionProperty::DisplayType::Dropdown)
, _colorQuantityMinMax(
ColorMinMaxInfo, glm::vec2(-0, 100), glm::vec2(-5000), glm::vec2(5000)
ColorMinMaxInfo,
glm::vec2(-0.f, 100.f),
glm::vec2(-5000.f),
glm::vec2(5000.f)
)
, _colorTablePath(ColorTablePathInfo)
, _colorUniform(
@@ -286,10 +292,14 @@ RenderableFieldlinesSequence::RenderableFieldlinesSequence(
, _maskingEnabled(MaskingEnabledInfo, false)
, _maskingGroup({ "Masking" })
, _maskingMinMax(
MaskingMinMaxInfo, glm::vec2(0,100), glm::vec2(-5000), glm::vec2(5000)
MaskingMinMaxInfo,
glm::vec2(0.f, 100.f),
glm::vec2(-5000.f),
glm::vec2(5000.f)
)
, _maskingQuantity(
MaskingQuantityInfo, properties::OptionProperty::DisplayType::Dropdown
MaskingQuantityInfo,
properties::OptionProperty::DisplayType::Dropdown
)
, _lineWidth(LineWidthInfo, 1.f, 1.f, 20.f)
, _jumpToStartBtn(TimeJumpButtonInfo)
@@ -300,25 +310,24 @@ RenderableFieldlinesSequence::RenderableFieldlinesSequence(
// is mandatory for the class to function;
std::string fileTypeString;
switch (p.inputFileType) {
case Parameters::SourceFileType::cdf:
case Parameters::SourceFileType::Cdf:
_inputFileType = SourceFileType::Cdf;
fileTypeString = "cdf";
if( p.tracingVariable.has_value()) {
if (p.tracingVariable.has_value()) {
_tracingVariable = *p.tracingVariable;
}
else {
_tracingVariable = "b"; // Magnetic field variable as default
LWARNING(fmt::format(
"No tracing variable, using default '{}'",
_tracingVariable
"No tracing variable, using default '{}'", _tracingVariable
));
}
break;
case Parameters::SourceFileType::json:
case Parameters::SourceFileType::Json:
_inputFileType = SourceFileType::Json;
fileTypeString = "json";
break;
case Parameters::SourceFileType::osfls:
case Parameters::SourceFileType::Osfls:
_inputFileType = SourceFileType::Osfls;
fileTypeString = "osfls";
break;
@@ -335,7 +344,6 @@ RenderableFieldlinesSequence::RenderableFieldlinesSequence(
}
// Extract all file paths from the provided folder
_sourceFiles.clear();
namespace fs = std::filesystem;
for (const fs::directory_entry& e : fs::directory_iterator(sourcePath)) {
if (e.is_regular_file()) {
@@ -376,10 +384,11 @@ RenderableFieldlinesSequence::RenderableFieldlinesSequence(
_flowEnabled = p.flowEnabled.value_or(_flowEnabled);
_lineWidth = p.lineWidth.value_or(_lineWidth);
_manualTimeOffset = p.manualTimeOffset.value_or(_manualTimeOffset);
_modelStr = p.simluationModel.value_or(_modelStr);
_modelStr = p.simulationModel.value_or(_modelStr);
//thismodel = p.model.value_or(thismodel);
_seedPointDirectory = p.seedPointDirectory.value_or(_seedPointDirectory);
_maskingEnabled = p.maskingEnabled.value_or(_maskingEnabled);
_maskingQuantityTemp = p.MaskingQuantity.value_or(_maskingQuantityTemp);
_maskingQuantityTemp = p.maskingQuantity.value_or(_maskingQuantityTemp);
_colorTablePaths = p.colorTablePaths.value_or(_colorTablePaths);
_colorMethod.addOption(static_cast<int>(ColorMethod::Uniform), "Uniform");
@@ -398,7 +407,7 @@ RenderableFieldlinesSequence::RenderableFieldlinesSequence(
if (p.colorQuantity.has_value()) {
_colorMethod = static_cast<int>(ColorMethod::ByQuantity);
_colorQuantityTemp = p.colorQuantity.value_or(_colorQuantityTemp);
_colorQuantityTemp = *p.colorQuantity;
}
if (p.colorTableRanges.has_value()) {
@@ -409,7 +418,7 @@ RenderableFieldlinesSequence::RenderableFieldlinesSequence(
}
_loadingStatesDynamically = p.loadAtRuntime.value_or(_loadingStatesDynamically);
if (_loadingStatesDynamically && _inputFileType != SourceFileType::Osfls ) {
if (_loadingStatesDynamically && _inputFileType != SourceFileType::Osfls) {
LWARNING("Load at run time is only supported for osfls file type");
_loadingStatesDynamically = false;
}
@@ -418,15 +427,14 @@ RenderableFieldlinesSequence::RenderableFieldlinesSequence(
_maskingRanges = *p.maskingRanges;
}
else {
_maskingRanges.push_back(glm::vec2(-100000, 100000)); // Just some default values
_maskingRanges.push_back(glm::vec2(-100000.f, 100000.f)); // some default values
}
_outputFolderPath = p.outputFolder.value_or(_outputFolderPath);
if (!_outputFolderPath.empty() && !std::filesystem::is_directory(_outputFolderPath)) {
_outputFolderPath.clear();
LERROR(fmt::format(
"The specified output path: '{}', does not exist",
_outputFolderPath
"The specified output path: '{}', does not exist", _outputFolderPath
));
}
@@ -441,8 +449,8 @@ void RenderableFieldlinesSequence::initialize() {
absPath(_colorTablePaths[0]).string()
);
// EXTRACT SOURCE FILE TYPE SPECIFIC INFOMRATION FROM DICTIONARY & GET STATES FROM
// SOURCE
// Extract source file type specific information from dictionary
// & get states from source
switch (_inputFileType) {
case SourceFileType::Cdf:
if (!getStatesFromCdfFiles()) {
@@ -486,7 +494,6 @@ void RenderableFieldlinesSequence::initialize() {
}
void RenderableFieldlinesSequence::initializeGL() {
// Setup shader program
_shaderProgram = global::renderEngine->buildRenderProgram(
"FieldlinesSequence",
@@ -494,7 +501,6 @@ void RenderableFieldlinesSequence::initializeGL() {
absPath("${MODULE_FIELDLINESSEQUENCE}/shaders/fieldlinessequence_fs.glsl")
);
//------------------ Initialize OpenGL VBOs and VAOs-------------------------------//
glGenVertexArrays(1, &_vertexArrayObject);
glGenBuffers(1, &_vertexPositionBuffer);
glGenBuffers(1, &_vertexColorBuffer);
@@ -505,19 +511,17 @@ void RenderableFieldlinesSequence::initializeGL() {
}
/**
* Returns false if it fails to extract mandatory information!
* Returns fls::Model::Invalid if it fails to extract mandatory information!
*/
fls::Model RenderableFieldlinesSequence::extractJsonInfoFromDictionary() {
//fls::Model model;
if (!_modelStr.empty()) {
fls::Model stringToModel(std::string str) {
if (!str.empty()) {
std::transform(
_modelStr.begin(),
_modelStr.end(),
_modelStr.begin(),
str.begin(),
str.end(),
str.begin(),
[](char c) { return static_cast<char>(::tolower(c)); }
);
return fls::stringToModel(_modelStr);
return fls::stringToModel(str);
}
else {
LERROR("Must specify model");
@@ -526,7 +530,8 @@ fls::Model RenderableFieldlinesSequence::extractJsonInfoFromDictionary() {
}
bool RenderableFieldlinesSequence::loadJsonStatesIntoRAM() {
fls::Model model = extractJsonInfoFromDictionary();
fls::Model model = stringToModel(_modelStr);
//fls::Model model = thismodel;
if (model == fls::Model::Invalid) {
return false;
}
@@ -582,7 +587,7 @@ void RenderableFieldlinesSequence::loadOsflsStatesIntoRAM() {
void RenderableFieldlinesSequence::setupProperties() {
bool hasExtras = (_states[0].nExtraQuantities() > 0);
// -------------- Add non-grouped properties (enablers and buttons) -------------- //
// Add non-grouped properties (enablers and buttons)
addProperty(_colorABlendEnabled);
addProperty(_domainEnabled);
addProperty(_flowEnabled);
@@ -592,7 +597,7 @@ void RenderableFieldlinesSequence::setupProperties() {
addProperty(_lineWidth);
addProperty(_jumpToStartBtn);
// ----------------------------- Add Property Groups ----------------------------- //
// Add Property Groups
addPropertySubOwner(_colorGroup);
addPropertySubOwner(_domainGroup);
addPropertySubOwner(_flowGroup);
@@ -600,7 +605,7 @@ void RenderableFieldlinesSequence::setupProperties() {
addPropertySubOwner(_maskingGroup);
}
// ------------------------- Add Properties to the groups ------------------------- //
// Add Properties to the groups
_colorGroup.addProperty(_colorUniform);
_domainGroup.addProperty(_domainX);
_domainGroup.addProperty(_domainY);
@@ -614,14 +619,15 @@ void RenderableFieldlinesSequence::setupProperties() {
if (hasExtras) {
_colorGroup.addProperty(_colorMethod);
_colorGroup.addProperty(_colorQuantity);
_colorQuantityMinMax.setViewOption(properties::Property::ViewOptions::MinMaxRange);
_colorQuantityMinMax.setViewOption(
properties::Property::ViewOptions::MinMaxRange
);
_colorGroup.addProperty(_colorQuantityMinMax);
_colorGroup.addProperty(_colorTablePath);
_maskingGroup.addProperty(_maskingQuantity);
_maskingMinMax.setViewOption(properties::Property::ViewOptions::MinMaxRange);
_maskingGroup.addProperty(_maskingMinMax);
// --------------------- Add Options to OptionProperties --------------------- //
// Add option for each extra quantity. Assumes there are just as many names to
// extra quantities as there are extra quantities. Also assume that all states in
// the given sequence have the same extra quantities! */
@@ -655,32 +661,32 @@ void RenderableFieldlinesSequence::definePropertyCallbackFunctions() {
// Add Property Callback Functions
bool hasExtras = (_states[0].nExtraQuantities() > 0);
if (hasExtras) {
_colorQuantity.onChange([this] {
_colorQuantity.onChange([this]() {
_shouldUpdateColorBuffer = true;
_colorQuantityMinMax = _colorTableRanges[_colorQuantity];
_colorTablePath = _colorTablePaths[_colorQuantity];
});
_colorTablePath.onChange([this] {
_colorTablePath.onChange([this]() {
_transferFunction->setPath(_colorTablePath);
_colorTablePaths[_colorQuantity] = _colorTablePath;
});
_colorQuantityMinMax.onChange([this] {
_colorQuantityMinMax.onChange([this]() {
_colorTableRanges[_colorQuantity] = _colorQuantityMinMax;
});
_maskingQuantity.onChange([this] {
_maskingQuantity.onChange([this]() {
_shouldUpdateMaskingBuffer = true;
_maskingMinMax = _maskingRanges[_maskingQuantity];
});
_maskingMinMax.onChange([this] {
_maskingMinMax.onChange([this]() {
_maskingRanges[_maskingQuantity] = _maskingMinMax;
});
}
_jumpToStartBtn.onChange([this] {
_jumpToStartBtn.onChange([this]() {
global::timeManager->setTimeNextFrame(Time(_startTimes[0]));
});
}
@@ -694,10 +700,6 @@ void RenderableFieldlinesSequence::computeSequenceEndTime() {
(static_cast<double>(_nStates) - 1.0);
_sequenceEndTime = lastTriggerTime + averageStateDuration;
}
else {
// If there's just one state it should never disappear!
_sequenceEndTime = DBL_MAX;
}
}
void RenderableFieldlinesSequence::setModelDependentConstants() {
@@ -706,16 +708,16 @@ void RenderableFieldlinesSequence::setModelDependentConstants() {
switch (simulationModel) {
case fls::Model::Batsrus:
_scalingFactor = fls::ReToMeter;
limit = 300; // Should include a long magnetotail
limit = 300.f; // Should include a long magnetotail
break;
case fls::Model::Enlil:
_flowReversed = true;
_scalingFactor = fls::AuToMeter;
limit = 50; // Should include Plutos furthest distance from the Sun
limit = 50.f; // Should include Plutos furthest distance from the Sun
break;
case fls::Model::Pfss:
_scalingFactor = fls::RsToMeter;
limit = 100; // Just a default value far away from the solar surface
limit = 100.f; // Just a default value far away from the solar surface
break;
default:
break;
@@ -731,13 +733,13 @@ void RenderableFieldlinesSequence::setModelDependentConstants() {
// Radial should range from 0 out to a corner of the cartesian box:
// sqrt(3) = 1.732..., 1.75 is a nice and round number
_domainR.setMinValue(glm::vec2(0));
_domainR.setMinValue(glm::vec2(0.f));
_domainR.setMaxValue(glm::vec2(limit * 1.75f));
_domainX = glm::vec2(-limit, limit);
_domainY = glm::vec2(-limit, limit);
_domainZ = glm::vec2(-limit, limit);
_domainR = glm::vec2(0, limit * 1.5f);
_domainR = glm::vec2(0.f, limit * 1.5f);
}
// Extract J2000 time from file names
@@ -773,11 +775,10 @@ void RenderableFieldlinesSequence::addStateToSequence(FieldlinesState& state) {
}
bool RenderableFieldlinesSequence::getStatesFromCdfFiles() {
std::vector<std::string> extraMagVars = extractMagnitudeVarsFromStrings();
std::vector<std::string> extraMagVars = extractMagnitudeVarsFromStrings(_extraVars);
std::unordered_map<std::string, std::vector<glm::vec3>> seedsPerFiles =
extractSeedPointsFromFiles();
extractSeedPointsFromFiles(_seedPointDirectory);
if (seedsPerFiles.empty()) {
LERROR("No seed files found");
return false;
@@ -807,24 +808,24 @@ bool RenderableFieldlinesSequence::getStatesFromCdfFiles() {
}
std::unordered_map<std::string, std::vector<glm::vec3>>
RenderableFieldlinesSequence::extractSeedPointsFromFiles()
extractSeedPointsFromFiles(std::filesystem::path filePath)
{
std::vector<std::string> files;
std::unordered_map<std::string, std::vector<glm::vec3>> outMap;
if (!std::filesystem::is_directory(_seedPointDirectory)){
if (!std::filesystem::is_directory(filePath)) {
LERROR(fmt::format(
"The specified seed point directory: '{}' does not exist",
_seedPointDirectory
"The specified seed point directory: '{}' does not exist", filePath
));
return outMap;
}
namespace fs = std::filesystem;
for (const fs::directory_entry& spFile : fs::directory_iterator(_seedPointDirectory)){
for (const fs::directory_entry& spFile : fs::directory_iterator(filePath)) {
std::string seedFilePath = spFile.path().string();
if (!spFile.is_regular_file() ||
seedFilePath.substr(seedFilePath.find_last_of('.')+1) != "txt") {
seedFilePath.substr(seedFilePath.find_last_of('.')+1) != "txt")
{
continue;
}
@@ -847,7 +848,7 @@ RenderableFieldlinesSequence::extractSeedPointsFromFiles()
outVec.push_back(std::move(point));
}
if (outVec.size() == 0) {
if (outVec.empty()) {
LERROR(fmt::format("Found no seed points in: {}", seedFilePath));
outMap.clear();
return {};
@@ -866,10 +867,12 @@ RenderableFieldlinesSequence::extractSeedPointsFromFiles()
return outMap;
}
std::vector<std::string> RenderableFieldlinesSequence::extractMagnitudeVarsFromStrings() {
std::vector<std::string>
extractMagnitudeVarsFromStrings(std::vector<std::string> extrVars)
{
std::vector<std::string> extraMagVars;
for (int i = 0; i < static_cast<int>(_extraVars.size()); i++) {
const std::string& str = _extraVars[i];
for (int i = 0; i < static_cast<int>(extrVars.size()); i++) {
const std::string& str = extrVars[i];
// Check if string is in the format specified for magnitude variables
if (str.substr(0, 2) == "|(" && str.substr(str.size() - 2, 2) == ")|") {
std::istringstream ss(str.substr(2, str.size() - 4));
@@ -893,7 +896,7 @@ std::vector<std::string> RenderableFieldlinesSequence::extractMagnitudeVarsFromS
if (counter != 3 && counter > 0) {
extraMagVars.erase(extraMagVars.end() - counter, extraMagVars.end());
}
_extraVars.erase(_extraVars.begin() + i);
extrVars.erase(extrVars.begin() + i);
i--;
}
}
@@ -934,82 +937,85 @@ bool RenderableFieldlinesSequence::isReady() const {
}
void RenderableFieldlinesSequence::render(const RenderData& data, RendererTasks&) {
if (_activeTriggerTimeIndex != -1) {
_shaderProgram->activate();
if (_activeTriggerTimeIndex == -1) {
return;
}
_shaderProgram->activate();
// Calculate Model View MatrixProjection
const glm::dmat4 rotMat = glm::dmat4(data.modelTransform.rotation);
const glm::dmat4 modelMat =
glm::translate(glm::dmat4(1.0), data.modelTransform.translation) *
rotMat *
glm::dmat4(glm::scale(glm::dmat4(1), glm::dvec3(data.modelTransform.scale)));
const glm::dmat4 modelViewMat = data.camera.combinedViewMatrix() * modelMat;
// Calculate Model View MatrixProjection
const glm::dmat4 rotMat = glm::dmat4(data.modelTransform.rotation);
const glm::dmat4 modelMat =
glm::translate(glm::dmat4(1.0), data.modelTransform.translation) *
rotMat *
glm::dmat4(glm::scale(glm::dmat4(1), glm::dvec3(data.modelTransform.scale)));
const glm::dmat4 modelViewMat = data.camera.combinedViewMatrix() * modelMat;
_shaderProgram->setUniform("modelViewProjection",
data.camera.sgctInternal.projectionMatrix() * glm::mat4(modelViewMat));
_shaderProgram->setUniform("modelViewProjection",
data.camera.sgctInternal.projectionMatrix() * glm::mat4(modelViewMat));
_shaderProgram->setUniform("colorMethod", _colorMethod);
_shaderProgram->setUniform("lineColor", _colorUniform);
_shaderProgram->setUniform("usingDomain", _domainEnabled);
_shaderProgram->setUniform("usingMasking", _maskingEnabled);
_shaderProgram->setUniform("colorMethod", _colorMethod);
_shaderProgram->setUniform("lineColor", _colorUniform);
_shaderProgram->setUniform("usingDomain", _domainEnabled);
_shaderProgram->setUniform("usingMasking", _maskingEnabled);
if (_colorMethod == static_cast<int>(ColorMethod::ByQuantity)) {
ghoul::opengl::TextureUnit textureUnit;
textureUnit.activate();
_transferFunction->bind(); // Calls update internally
_shaderProgram->setUniform("colorTable", textureUnit);
_shaderProgram->setUniform("colorTableRange",
_colorTableRanges[_colorQuantity]);
}
if (_maskingEnabled) {
_shaderProgram->setUniform("maskingRange", _maskingRanges[_maskingQuantity]);
}
_shaderProgram->setUniform("domainLimR", _domainR.value() * _scalingFactor);
_shaderProgram->setUniform("domainLimX", _domainX.value() * _scalingFactor);
_shaderProgram->setUniform("domainLimY", _domainY.value() * _scalingFactor);
_shaderProgram->setUniform("domainLimZ", _domainZ.value() * _scalingFactor);
// Flow/Particles
_shaderProgram->setUniform("flowColor", _flowColor);
_shaderProgram->setUniform("usingParticles", _flowEnabled);
_shaderProgram->setUniform("particleSize", _flowParticleSize);
_shaderProgram->setUniform("particleSpacing", _flowParticleSpacing);
_shaderProgram->setUniform("particleSpeed", _flowSpeed);
if (_colorMethod == static_cast<int>(ColorMethod::ByQuantity)) {
ghoul::opengl::TextureUnit textureUnit;
textureUnit.activate();
_transferFunction->bind(); // Calls update internally
_shaderProgram->setUniform("colorTable", textureUnit);
_shaderProgram->setUniform(
"time",
global::windowDelegate->applicationTime() * (_flowReversed ? -1 : 1)
"colorTableRange",
_colorTableRanges[_colorQuantity]
);
}
bool additiveBlending = false;
if (_colorABlendEnabled) {
additiveBlending = true;
glDepthMask(false);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
}
if (_maskingEnabled) {
_shaderProgram->setUniform("maskingRange", _maskingRanges[_maskingQuantity]);
}
glBindVertexArray(_vertexArrayObject);
_shaderProgram->setUniform("domainLimR", _domainR.value() * _scalingFactor);
_shaderProgram->setUniform("domainLimX", _domainX.value() * _scalingFactor);
_shaderProgram->setUniform("domainLimY", _domainY.value() * _scalingFactor);
_shaderProgram->setUniform("domainLimZ", _domainZ.value() * _scalingFactor);
// Flow/Particles
_shaderProgram->setUniform("flowColor", _flowColor);
_shaderProgram->setUniform("usingParticles", _flowEnabled);
_shaderProgram->setUniform("particleSize", _flowParticleSize);
_shaderProgram->setUniform("particleSpacing", _flowParticleSpacing);
_shaderProgram->setUniform("particleSpeed", _flowSpeed);
_shaderProgram->setUniform(
"time",
global::windowDelegate->deltaTime() * (_flowReversed ? -1 : 1)
);
bool additiveBlending = false;
if (_colorABlendEnabled) {
additiveBlending = true;
glDepthMask(false);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
}
glBindVertexArray(_vertexArrayObject);
#ifndef __APPLE__
glLineWidth(_lineWidth);
glLineWidth(_lineWidth);
#else
glLineWidth(1.f);
glLineWidth(1.f);
#endif
glMultiDrawArrays(
GL_LINE_STRIP, //_drawingOutputType,
_states[_activeStateIndex].lineStart().data(),
_states[_activeStateIndex].lineCount().data(),
static_cast<GLsizei>(_states[_activeStateIndex].lineStart().size())
);
glMultiDrawArrays(
GL_LINE_STRIP, //_drawingOutputType,
_states[_activeStateIndex].lineStart().data(),
_states[_activeStateIndex].lineCount().data(),
static_cast<GLsizei>(_states[_activeStateIndex].lineStart().size())
);
glBindVertexArray(0);
_shaderProgram->deactivate();
glBindVertexArray(0);
_shaderProgram->deactivate();
if (additiveBlending) {
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDepthMask(true);
}
if (additiveBlending) {
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDepthMask(true);
}
}
@@ -1017,7 +1023,12 @@ void RenderableFieldlinesSequence::update(const UpdateData& data) {
if (_shaderProgram->isDirty()) {
_shaderProgram->rebuildFromFile();
}
// True if new 'runtime-state' must be loaded from disk.
// False => the previous frame's state should still be shown
bool mustLoadNewStateFromDisk = false;
// True if new 'in-RAM-state' must be loaded.
// False => the previous frame's state should still be shown
bool needUpdate = false;
const double currentTime = data.time.j2000Seconds();
const bool isInInterval = (currentTime >= _startTimes[0]) &&
(currentTime < _sequenceEndTime);
@@ -1036,10 +1047,10 @@ void RenderableFieldlinesSequence::update(const UpdateData& data) {
updateActiveTriggerTimeIndex(currentTime);
if (_loadingStatesDynamically) {
_mustLoadNewStateFromDisk = true;
mustLoadNewStateFromDisk = true;
}
else {
_needsUpdate = true;
needUpdate = true;
_activeStateIndex = _activeTriggerTimeIndex;
}
} // else {we're still in same state as previous frame (no changes needed)}
@@ -1047,14 +1058,14 @@ void RenderableFieldlinesSequence::update(const UpdateData& data) {
else {
// Not in interval => set everything to false
_activeTriggerTimeIndex = -1;
_mustLoadNewStateFromDisk = false;
_needsUpdate = false;
mustLoadNewStateFromDisk = false;
needUpdate = false;
}
if (_mustLoadNewStateFromDisk) {
if (mustLoadNewStateFromDisk) {
if (!_isLoadingStateFromDisk && !_newStateIsReady) {
_isLoadingStateFromDisk = true;
_mustLoadNewStateFromDisk = false;
mustLoadNewStateFromDisk = false;
std::string filePath = _sourceFiles[_activeTriggerTimeIndex];
std::thread readBinaryThread([this, f = std::move(filePath)] {
readNewState(f);
@@ -1063,7 +1074,7 @@ void RenderableFieldlinesSequence::update(const UpdateData& data) {
}
}
if (_needsUpdate || _newStateIsReady) {
if (needUpdate || _newStateIsReady) {
if (_loadingStatesDynamically) {
_states[0] = std::move(*_newState);
}
@@ -1076,7 +1087,7 @@ void RenderableFieldlinesSequence::update(const UpdateData& data) {
}
// Everything is set and ready for rendering!
_needsUpdate = false;
needUpdate = false;
_newStateIsReady = false;
}
@@ -1137,8 +1148,8 @@ void RenderableFieldlinesSequence::updateVertexPositionBuffer() {
GL_STATIC_DRAW
);
glEnableVertexAttribArray(VaPosition);
glVertexAttribPointer(VaPosition, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
unbindGL();
}
@@ -1161,8 +1172,8 @@ void RenderableFieldlinesSequence::updateVertexColorBuffer() {
GL_STATIC_DRAW
);
glEnableVertexAttribArray(VaColor);
glVertexAttribPointer(VaColor, 1, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, 0, 0);
unbindGL();
}
@@ -1186,8 +1197,8 @@ void RenderableFieldlinesSequence::updateVertexMaskingBuffer() {
GL_STATIC_DRAW
);
glEnableVertexAttribArray(VaMasking);
glVertexAttribPointer(VaMasking, 1, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, 0, 0);
unbindGL();
}

View File

@@ -54,7 +54,23 @@ public:
static documentation::Documentation Documentation();
private:
// ------------------------------------- ENUMS -------------------------------------//
void addStateToSequence(FieldlinesState& STATE);
void computeSequenceEndTime();
void definePropertyCallbackFunctions();
void extractTriggerTimesFromFileNames();
bool loadJsonStatesIntoRAM();
void loadOsflsStatesIntoRAM();
bool getStatesFromCdfFiles();
void setModelDependentConstants();
void setupProperties();
bool prepareForOsflsStreaming();
void readNewState(const std::string& filePath);
void updateActiveTriggerTimeIndex(double currentTime);
void updateVertexPositionBuffer();
void updateVertexColorBuffer();
void updateVertexMaskingBuffer();
// Used to determine if lines should be colored UNIFORMLY or by an extraQuantity
enum class ColorMethod {
Uniform = 0,
@@ -66,8 +82,6 @@ private:
Osfls = 2
};
// ------------------------------------ STRINGS ------------------------------------//
std::string _identifier; // Name of the Node!
// cdf, osfls or json
SourceFileType _inputFileType;
// Output folder path in case of file conversion
@@ -78,19 +92,14 @@ private:
std::filesystem::path _seedPointDirectory;
// optional except when using json input
std::string _modelStr;
// ------------------------------------- FLAGS -------------------------------------//
fls::Model thismodel;
// Used for 'runtime-states'. True when loading a new state from disk on another
// thread.
std::atomic_bool _isLoadingStateFromDisk = false;
// False => states are stored in RAM (using 'in-RAM-states'), True => states are
// loaded from disk during runtime (using 'runtime-states')
bool _loadingStatesDynamically = false;
// Used for 'runtime-states': True if new 'runtime-state' must be loaded from disk.
// False => the previous frame's state should still be shown
bool _mustLoadNewStateFromDisk = false;
// Used for 'in-RAM-states' : True if new 'in-RAM-state' must be loaded.
// False => the previous frame's state should still be shown
bool _needsUpdate = false;
// Used for 'runtime-states'. True when finished loading a new state from disk on
// another thread.
std::atomic_bool _newStateIsReady = false;
@@ -100,7 +109,6 @@ private:
// line segments
bool _shouldUpdateMaskingBuffer = false;
// --------------------------------- NUMERICALS ----------------------------------- //
// Active index of _states. If(==-1)=>no state available for current time. Always the
// same as _activeTriggerTimeIndex if(_loadingStatesDynamically==true), else
// always = 0
@@ -115,7 +123,8 @@ private:
// domain limits.
float _scalingFactor = 1.f;
// Estimated end of sequence.
double _sequenceEndTime;
// If there's just one state it should never disappear
double _sequenceEndTime = std::numeric_limits<double>::max();
// OpenGL Vertex Array Object
GLuint _vertexArrayObject = 0;
// OpenGL Vertex Buffer Object containing the extraQuantity values used for coloring
@@ -127,7 +136,6 @@ private:
// OpenGL Vertex Buffer Object containing the vertex positions
GLuint _vertexPositionBuffer = 0;
// ----------------------------------- POINTERS ------------------------------------//
// The Lua-Modfile-Dictionary used during initialization
// Used for 'runtime-states' when switching out current state to a new state
std::unique_ptr<FieldlinesState> _newState;
@@ -135,7 +143,6 @@ private:
// Transfer function used to color lines when _pColorMethod is set to BY_QUANTITY
std::unique_ptr<TransferFunction> _transferFunction;
// ------------------------------------ VECTORS ----------------------------------- //
// Paths to color tables. One for each 'extraQuantity'
std::vector<std::string> _colorTablePaths;
// Values represents min & max values represented in the color table
@@ -152,7 +159,6 @@ private:
// Stores the FieldlineStates
std::vector<FieldlinesState> _states;
// ---------------------------------- Properties ---------------------------------- //
// Group to hold the color properties
properties::PropertyOwner _colorGroup;
// Uniform/transfer function/topology?
@@ -170,7 +176,7 @@ private:
// Whether or not to use additive blending
properties::BoolProperty _colorABlendEnabled;
// Whether or not to use Domain
// Whether or not to use Domain
properties::BoolProperty _domainEnabled;
// Group to hold the Domain properties
properties::PropertyOwner _domainGroup;
@@ -183,7 +189,7 @@ private:
// Domain Limits radially
properties::Vec2Property _domainR;
// Simulated particles' color
// Simulated particles' color
properties::Vec4Property _flowColor;
// Toggle flow [ON/OFF]
properties::BoolProperty _flowEnabled;
@@ -209,34 +215,10 @@ private:
// used to save property for later initialization
int _maskingQuantityTemp = 0;
/// Line width for the line rendering part
// Line width for the line rendering part
properties::FloatProperty _lineWidth;
// Button which executes a time jump to start of sequence
properties::TriggerProperty _jumpToStartBtn;
// --------------------- FUNCTIONS USED DURING INITIALIZATION --------------------- //
void addStateToSequence(FieldlinesState& STATE);
void computeSequenceEndTime();
void definePropertyCallbackFunctions();
//bool extractCdfInfoFromDictionary();
fls::Model extractJsonInfoFromDictionary();
std::vector<std::string> extractMagnitudeVarsFromStrings();
//bool extractMandatoryInfoFromDictionary(std::string sourceFolderPath);
std::unordered_map<std::string, std::vector<glm::vec3>> extractSeedPointsFromFiles();
void extractTriggerTimesFromFileNames();
bool loadJsonStatesIntoRAM();
void loadOsflsStatesIntoRAM();
bool getStatesFromCdfFiles();
void setModelDependentConstants();
void setupProperties();
bool prepareForOsflsStreaming();
// ------------------------- FUNCTIONS USED DURING RUNTIME ------------------------ //
void readNewState(const std::string& filePath);
void updateActiveTriggerTimeIndex(double currentTime);
void updateVertexPositionBuffer();
void updateVertexColorBuffer();
void updateVertexMaskingBuffer();
};
} // namespace openspace

View File

@@ -89,12 +89,12 @@ namespace openspace::fls {
* vector at each line vertex
*/
bool convertCdfToFieldlinesState(FieldlinesState& state, const std::string& cdfPath,
const std::unordered_map<std::string,
std::vector<glm::vec3>>& seedMap,
double manualTimeOffset,
const std::string& tracingVar,
std::vector<std::string>& extraVars,
std::vector<std::string>& extraMagVars)
const std::unordered_map<std::string,
std::vector<glm::vec3>>& seedMap,
double manualTimeOffset,
const std::string& tracingVar,
std::vector<std::string>& extraVars,
std::vector<std::string>& extraMagVars)
{
#ifndef OPENSPACE_MODULE_KAMELEON_ENABLED
LERROR("CDF inputs provided but Kameleon module is deactivated");
@@ -109,10 +109,10 @@ bool convertCdfToFieldlinesState(FieldlinesState& state, const std::string& cdfP
double cdfDoubleTime = kameleonHelper::getTime(kameleon.get(), manualTimeOffset);
state.setTriggerTime(cdfDoubleTime);
//get time as string.
// get time as string.
std::string cdfStringTime = SpiceManager::ref().dateFromEphemerisTime(
cdfDoubleTime, "YYYYMMDDHRMNSC::RND"
); //YYYY MM DD HOUR MIN SEC ROUNDED
);
// use time as string for picking seedpoints from seedm
std::vector<glm::vec3> seedPoints = seedMap.at(cdfStringTime);

View File

@@ -76,90 +76,90 @@ double getTime(ccmc::Kameleon* kameleon, double manualOffset) {
// As a new version of Kameleon is included in OpenSpace this function may prove to be
// redundant!
std::string seqStartStr;
if (kameleon->doesAttributeExist("start_time")){
seqStartStr =
kameleon->getGlobalAttribute("start_time").getAttributeString();
}
else if (kameleon->doesAttributeExist("tim_rundate_cal")) {
seqStartStr =
kameleon->getGlobalAttribute("tim_rundate_cal").getAttributeString();
const size_t N_CHARS = seqStartStr.length();
if (N_CHARS < 19) {
// Fall through to add the required characters
switch (N_CHARS) {
case 10: // YYYY-MM-DD => YYYY-MM-DDTHH
seqStartStr += "T00";
[[fallthrough]];
case 13: // YYYY-MM-DDTHH => YYYY-MM-DDTHH:
seqStartStr += ":";
[[fallthrough]];
case 14: // YYYY-MM-DDTHH: => YYYY-MM-DDTHH:MM
seqStartStr += "00";
[[fallthrough]];
case 16: // YYYY-MM-DDTHH:MM => YYYY-MM-DDTHH:MM:
seqStartStr += ":";
[[fallthrough]];
case 17: // YYYY-MM-DDTHH:MM: => YYYY-MM-DDTHH:MM:SS
seqStartStr += "00";
[[fallthrough]];
// case 19 : // YYYY-MM-DDTHH:MM:SS => YYYY-MM-DDTHH:MM:SS.000
// seqStartStr += ".000";
// case 23 : // YYYY-MM-DDTHH:MM:SS. => YYYY-MM-DDTHH:MM:SS.000Z
// seqStartStr += "Z";
default:
break;
}
std::string seqStartStr;
if (kameleon->doesAttributeExist("start_time")){
seqStartStr =
kameleon->getGlobalAttribute("start_time").getAttributeString();
}
else if (kameleon->doesAttributeExist("tim_rundate_cal")) {
seqStartStr =
kameleon->getGlobalAttribute("tim_rundate_cal").getAttributeString();
const size_t N_CHARS = seqStartStr.length();
if (N_CHARS < 19) {
// Fall through to add the required characters
switch (N_CHARS) {
case 10: // YYYY-MM-DD => YYYY-MM-DDTHH
seqStartStr += "T00";
[[fallthrough]];
case 13: // YYYY-MM-DDTHH => YYYY-MM-DDTHH:
seqStartStr += ":";
[[fallthrough]];
case 14: // YYYY-MM-DDTHH: => YYYY-MM-DDTHH:MM
seqStartStr += "00";
[[fallthrough]];
case 16: // YYYY-MM-DDTHH:MM => YYYY-MM-DDTHH:MM:
seqStartStr += ":";
[[fallthrough]];
case 17: // YYYY-MM-DDTHH:MM: => YYYY-MM-DDTHH:MM:SS
seqStartStr += "00";
[[fallthrough]];
// case 19 : // YYYY-MM-DDTHH:MM:SS => YYYY-MM-DDTHH:MM:SS.000
// seqStartStr += ".000";
// case 23 : // YYYY-MM-DDTHH:MM:SS. => YYYY-MM-DDTHH:MM:SS.000Z
// seqStartStr += "Z";
default:
break;
}
}
else if (kameleon->doesAttributeExist("tim_obsdate_cal")) {
seqStartStr =
kameleon->getGlobalAttribute("tim_obsdate_cal").getAttributeString();
}
else if (kameleon->doesAttributeExist("tim_crstart_cal")) {
seqStartStr =
kameleon->getGlobalAttribute("tim_crstart_cal").getAttributeString();
}
else {
LWARNING(
"No starting time attribute could be found in the .cdf file. Starting "
"time is set to 01.JAN.2000 12:00."
);
}
}
else if (kameleon->doesAttributeExist("tim_obsdate_cal")) {
seqStartStr =
kameleon->getGlobalAttribute("tim_obsdate_cal").getAttributeString();
}
else if (kameleon->doesAttributeExist("tim_crstart_cal")) {
seqStartStr =
kameleon->getGlobalAttribute("tim_crstart_cal").getAttributeString();
}
else {
LWARNING(
"No starting time attribute could be found in the .cdf file. Starting "
"time is set to 01.JAN.2000 12:00."
);
}
if (seqStartStr.length() == 19) {
seqStartStr += ".000Z";
}
if (seqStartStr.length() == 19) {
seqStartStr += ".000Z";
}
double seqStartDbl;
if (seqStartStr.length() == 24) {
seqStartDbl = Time::convertTime(
seqStartStr.substr(0, seqStartStr.length() - 2)
);
}
else {
LWARNING("No starting time attribute could be found in the .cdf file."
"Starting time is set to 01.JAN.2000 12:00.");
seqStartDbl = 0.0;
}
double seqStartDbl;
if (seqStartStr.length() == 24) {
seqStartDbl = Time::convertTime(
seqStartStr.substr(0, seqStartStr.length() - 2)
);
}
else {
LWARNING("No starting time attribute could be found in the .cdf file."
"Starting time is set to 01.JAN.2000 12:00.");
seqStartDbl = 0.0;
}
double stateStartOffset;
double stateStartOffset;
if (kameleon->doesAttributeExist("elapsed_time_in_seconds")) {
ccmc::Attribute att = kameleon->getGlobalAttribute("elapsed_time_in_seconds");
stateStartOffset = static_cast<double>(att.getAttributeFloat());
}
else if (kameleon->doesAttributeExist("time_physical_time")) {
ccmc::Attribute att = kameleon->getGlobalAttribute("time_physical_time");
stateStartOffset = static_cast<double>(att.getAttributeFloat());
}
else {
stateStartOffset = 0.0;
LWARNING("No time offset attribute could be found in the .cdf file."
"The current state starts the same time as the sequence!");
}
if (kameleon->doesAttributeExist("elapsed_time_in_seconds")) {
ccmc::Attribute att = kameleon->getGlobalAttribute("elapsed_time_in_seconds");
stateStartOffset = static_cast<double>(att.getAttributeFloat());
}
else if (kameleon->doesAttributeExist("time_physical_time")) {
ccmc::Attribute att = kameleon->getGlobalAttribute("time_physical_time");
stateStartOffset = static_cast<double>(att.getAttributeFloat());
}
else {
stateStartOffset = 0.0;
LWARNING("No time offset attribute could be found in the .cdf file."
"The current state starts the same time as the sequence!");
}
return seqStartDbl + stateStartOffset + manualOffset;
return seqStartDbl + stateStartOffset + manualOffset;
}
} // namespace openspace::kameleonHelper {

View File

@@ -51,11 +51,6 @@ namespace {
// log category
constexpr const char* _loggerCat = "RenderableFluxNodes";
// GL variables for shaders, probably needed some of them atleast
constexpr const GLuint VaPosition = 0; // MUST CORRESPOND TO THE SHADER PROGRAM
constexpr const GLuint VaColor = 1; // MUST CORRESPOND TO THE SHADER PROGRAM
constexpr const GLuint VaFiltering = 2; // MUST CORRESPOND TO THE SHADER PROGRAM
constexpr int8_t CurrentCacheVersion = 2;
//streamColor, nodeSize, nodeSizeLargerFlux, thresholdFlux,
@@ -68,24 +63,24 @@ namespace {
"enhanceMethod", "flowColor", "usingParticles",
"particleSize", "particleSpacing", "particleSpeed"
};
constexpr const std::array<const char*, 14> UniformNames2 = {
constexpr const std::array<const char*, 13> UniformNames2 = {
"time", "flowColoring", "maxNodeDistanceSize", "usingCameraPerspective",
"drawCircles", "drawHollow", "useGaussian", "usingRadiusPerspective",
"perspectiveDistanceFactor", "maxNodeSize", "minNodeSize", "usingPulse",
"perspectiveDistanceFactor", "minMaxNodeSize", "usingPulse",
"usingGaussianPulse", "pulsatingAlways"
};
// --------------------------------- Property Info -------------------------------- //
constexpr openspace::properties::Property::PropertyInfo GoesEnergyBinsInfo = {
"GoesEnergy",
"Goes Energy",
"Select which energy bin you want to show. Emin01 is values > 10 Mev,"
"GOES Energy",
"Select which energy bin you want to show. GOES = Geostationary Operational "
"Environmental Satellites Emin01 is values > 10 Mev, "
"Default is Emin03 where values > 100 Mev."
};
constexpr openspace::properties::Property::PropertyInfo ColorModeInfo = {
"ColorMode",
"Color Mode",
"Color lines uniformly or using color tables based on specific values on nodes,"
"Color lines uniformly or using color tables based on specific values on nodes, "
"for examples flux values."
};
constexpr openspace::properties::Property::PropertyInfo ColorTablePathInfo = {
@@ -108,12 +103,6 @@ namespace {
"Size of nodes for larger flux",
"Change the size of the nodes when flux is larger than flux threshold value"
};
constexpr openspace::properties::Property::PropertyInfo LineWidthInfo = {
"LineWidth",
"Line Width",
"This value specifies the line width of the field lines if the "
"selected render method includes lines."
};
constexpr openspace::properties::Property::PropertyInfo ThresholdFluxInfo = {
"ThresholdFlux",
"Threshold flux value",
@@ -204,7 +193,7 @@ namespace {
constexpr openspace::properties::Property::PropertyInfo MisalignedIndexInfo = {
"MisalignedIndex",
"Index to shift sequence number",
"The misalignement number for sequence for fluxnodes vs Fieldlines"
"The misalignment number for sequence for fluxnodes vs Fieldlines"
};
constexpr openspace::properties::Property::PropertyInfo FlowColorInfo = {
"Flowcolor",
@@ -242,11 +231,6 @@ namespace {
"Color either by Flowcolor or Flow colortable",
"If set to true the flow will be colored by Flowcolor."
};
constexpr openspace::properties::Property::PropertyInfo TempInfo1 = {
"Temp1",
"temp",
"Temp"
};
constexpr openspace::properties::Property::PropertyInfo MaxNodeDistanceSizeInfo = {
"MaxNodeDistanceSize",
"Max Node Distance Size",
@@ -261,7 +245,7 @@ namespace {
CameraPerspectiveEnabledInfo = {
"CameraPerspectiveEnabled",
"Use Camera perspective",
"Camera perspective changes the size of the nodes dependent on "
"Camera perspective changes the size of the nodes dependent on the "
"distance from camera."
};
constexpr openspace::properties::Property::PropertyInfo DrawingCirclesInfo = {
@@ -294,15 +278,10 @@ namespace {
"This value decides how far away the camera must be to start "
"impacting the node size."
};
constexpr openspace::properties::Property::PropertyInfo MinNodeSizeInfo = {
"MinNodeSize",
"Minimum node size",
"The minimum node size."
};
constexpr openspace::properties::Property::PropertyInfo MaxNodeSizeInfo = {
"MaxNodeSize",
"Maximum node size",
"The minimum node size."
constexpr openspace::properties::Property::PropertyInfo MinMaxNodeSizeInfo = {
"MinMaxNodeSize",
"Min & Max node size",
"The minimum and maximum node size."
};
constexpr openspace::properties::Property::PropertyInfo AlwaysPulseInfo = {
"AlwaysPulsate",
@@ -337,7 +316,7 @@ namespace {
struct [[codegen::Dictionary(RenderableFluxNodes)]] Parameters {
// path to source folder with the 3 binary files in it
std::filesystem::path sourceFolder [[codegen::directory()]];
//
struct TransferFunctions {
std::string standard;
std::string flow;
@@ -346,8 +325,6 @@ namespace {
};
// [[codegen::verbatim(ColorTablePathInfo.description)]]
TransferFunctions colorTablePaths;
// [[codegen::verbatim(LineWidthInfo.description)]]
//float lineWidth;
// [[codegen::verbatim(GoesEnergyBinsInfo.description)]]
std::optional<int> energyBin;
};
@@ -362,26 +339,25 @@ documentation::Documentation RenderableFluxNodes::Documentation() {
}
RenderableFluxNodes::RenderableFluxNodes(const ghoul::Dictionary& dictionary)
: Renderable(dictionary)
, _goesEnergyBins(GoesEnergyBinsInfo, properties::OptionProperty::DisplayType::Radio)
, _colorGroup({ "Color" })
, _colorMode(ColorModeInfo, properties::OptionProperty::DisplayType::Radio)
, _scalingmethod(ScalingmethodInfo, properties::OptionProperty::DisplayType::Radio)
, _scalingMethod(ScalingmethodInfo, properties::OptionProperty::DisplayType::Radio)
, _nodeskipMethod(NodeskipMethodInfo, properties::OptionProperty::DisplayType::Radio)
, _enhancemethod(EnhanceMethodInfo, properties::OptionProperty::DisplayType::Dropdown)
, _colorTablePath(ColorTablePathInfo)
, _streamColor(StreamColorInfo,
, _streamColor(
StreamColorInfo,
glm::vec4(0.96f, 0.88f, 0.8f, 1.f),
glm::vec4(0.f),
glm::vec4(1.f))
, _streamGroup({ "Streams" })
, _nodesamountGroup({ "NodeGroup" })
, _nodesAmountGroup({ "NodeGroup" })
, _nodeSize(NodeSizeInfo, 2.f, 1.f, 10.f)
, _nodeSizeLargerFlux(NodeSizeLargerFluxInfo, 2.f, 1.f, 10.f)
, _lineWidth(LineWidthInfo, 4.f, 1.f, 20.f)
, _colorTableRange(colorTableRangeInfo)
, _domainZ(DomainZInfo)
, _colorTableRange(colorTableRangeInfo, { -2.f, 4.f }, { -8.f, -8.f }, { 8.f, 8.f })
, _domainZ(DomainZInfo, { -2.5f, 2.5f }, { -2.5f, -2.5f }, { 2.5f, 2.5f})
, _fluxColorAlpha(FluxColorAlphaInfo, 0.f, 0.f, 1.f)
, _fluxColorAlphaIlluminance(FluxColorAlphaIlluminanceInfo, 1.f, 0.f, 1.f)
, _thresholdFlux(ThresholdFluxInfo, -1.5f, -50.f, 10.f)
@@ -394,7 +370,6 @@ RenderableFluxNodes::RenderableFluxNodes(const ghoul::Dictionary& dictionary)
, _radiusNodeSkipThreshold(RadiusNodeSkipThresholdInfo, 0.f, 0.f, 5.f)
, _earthdistGroup({ "Earthfocus" })
, _distanceThreshold(DistanceThresholdInfo, 0.0f, 0.0f, 1.0f)
, _misalignedIndex(MisalignedIndexInfo, 0, -5, 20)
, _flowColor(
FlowColorInfo,
glm::vec4(0.96f, 0.88f, 0.8f, 0.5f),
@@ -408,7 +383,6 @@ RenderableFluxNodes::RenderableFluxNodes(const ghoul::Dictionary& dictionary)
, _flowParticleSpacing(FlowParticleSpacingInfo, 60, 0, 500)
, _flowSpeed(FlowSpeedInfo, 20, 0, 1000)
, _useFlowColor(UseFlowColorInfo, false)
, _scaleFactor(TempInfo1, 150.f, 1.f, 500.f)
, _maxNodeDistanceSize(MaxNodeDistanceSizeInfo, 1.f, 1.f, 10.f)
, _nodeDistanceThreshold(NodeDistanceThresholdInfo, 0.f, 0.f, 40.f)
, _cameraPerspectiveEnabled(CameraPerspectiveEnabledInfo, false)
@@ -418,33 +392,27 @@ RenderableFluxNodes::RenderableFluxNodes(const ghoul::Dictionary& dictionary)
, _gaussianAlphaFilter(GaussiandAlphaFilterInfo, false)
, _radiusPerspectiveEnabled(RadiusPerspectiveEnabledInfo, true)
, _perspectiveDistanceFactor(PerspectiveDistanceFactorInfo, 2.67f, 1.f, 20.f)
, _maxNodeSize(MaxNodeSizeInfo, 30.f, 1.f, 200.f)
, _minNodeSize(MinNodeSizeInfo, 2.f, 1.f, 10.f)
, _minMaxNodeSize(MinMaxNodeSizeInfo, {2.f, 30.f}, {1.f, 1.f}, {10.f, 200.f})
, _pulseEnabled(pulseEnabledInfo, false)
, _gaussianPulseEnabled(gaussianPulseEnabledInfo, false)
, _pulseAlways(AlwaysPulseInfo, false)
{
const Parameters p = codegen::bake<Parameters>(dictionary);
_transferFunction =
std::make_unique<TransferFunction>(p.colorTablePaths.standard);
_transferFunctionCMR =
std::make_unique<TransferFunction>(p.colorTablePaths.cmr);
_transferFunctionEarth =
std::make_unique<TransferFunction>(p.colorTablePaths.earth);
_transferFunctionFlow =
std::make_unique<TransferFunction>(p.colorTablePaths.flow);
_transferFunction = std::make_unique<TransferFunction>(p.colorTablePaths.standard);
_transferFunctionCMR = std::make_unique<TransferFunction>(p.colorTablePaths.cmr);
_transferFunctionEarth = std::make_unique<TransferFunction>(p.colorTablePaths.earth);
_transferFunctionFlow = std::make_unique<TransferFunction>(p.colorTablePaths.flow);
_colorTablePath = p.colorTablePaths.standard;
_binarySourceFolderPath = p.sourceFolder;
if (std::filesystem::is_directory(_binarySourceFolderPath)) {
// Extract all file paths from the provided folder
_binarySourceFiles.clear();
namespace fs = std::filesystem;
for (const fs::directory_entry& e : fs::directory_iterator(
_binarySourceFolderPath)) {
for (const fs::directory_entry& e :
fs::directory_iterator(_binarySourceFolderPath))
{
if (e.is_regular_file()) {
_binarySourceFiles.push_back(e.path().string());
}
@@ -453,45 +421,41 @@ RenderableFluxNodes::RenderableFluxNodes(const ghoul::Dictionary& dictionary)
// Ensure that there are available and valid source files left
if (_binarySourceFiles.empty()) {
LERROR(fmt::format(
"{} contains no files", _binarySourceFolderPath
));
LERROR(fmt::format("{} contains no files", _binarySourceFolderPath));
}
}
else {
LERROR(fmt::format(
"Source folder {} is not a valid directory",
LERROR(fmt::format("Source folder {} is not a valid directory",
_binarySourceFolderPath
));
}
// --------------------- Add Options to OptionProperties --------------------- //
_goesEnergyBins.addOption(static_cast<int>(GoesEnergyBins::Emin01), "Emin01");
_goesEnergyBins.addOption(static_cast<int>(GoesEnergyBins::Emin03), "Emin03");
_colorMode.addOption(static_cast<int>(ColorMethod::ByFluxValue), "By Flux Value");
_colorMode.addOption(static_cast<int>(ColorMethod::Uniform), "Uniform");
_scalingmethod.addOption(static_cast<int>(ScalingMethod::Flux), "Flux");
_scalingmethod.addOption(static_cast<int>(ScalingMethod::RFlux), "Radius * Flux");
_scalingmethod.addOption(static_cast<int>(ScalingMethod::R2Flux), "Radius^2 * Flux");
_scalingmethod.addOption(
static_cast<int>(ScalingMethod::log10RFlux), "log10(r) * Flux");
_scalingmethod.addOption(static_cast<int>(ScalingMethod::lnRFlux), "ln(r) * Flux");
_scalingMethod.addOption(static_cast<int>(ScalingMethod::Flux), "Flux");
_scalingMethod.addOption(static_cast<int>(ScalingMethod::RFlux), "Radius * Flux");
_scalingMethod.addOption(static_cast<int>(ScalingMethod::R2Flux), "Radius^2 * Flux");
_scalingMethod.addOption(
static_cast<int>(ScalingMethod::Log10RFlux), "log10(r) * Flux"
);
_scalingMethod.addOption(static_cast<int>(ScalingMethod::LnRFlux), "ln(r) * Flux");
_nodeskipMethod.addOption(static_cast<int>(NodeSkipMethod::Uniform), "Uniform");
_nodeskipMethod.addOption(static_cast<int>(NodeSkipMethod::Flux), "Flux");
_nodeskipMethod.addOption(static_cast<int>(NodeSkipMethod::Radius), "Radius");
_nodeskipMethod.addOption(
static_cast<int>(NodeSkipMethod::Streamnumber), "Streamnumber");
static_cast<int>(NodeSkipMethod::Streamnumber), "Streamnumber"
);
_enhancemethod.addOption(static_cast<int>(EnhanceMethod::SizeScaling), "SizeScaling");
_enhancemethod.addOption(static_cast<int>(EnhanceMethod::ColorTables), "ColorTables");
_enhancemethod.addOption(
static_cast<int>(EnhanceMethod::Sizescaling), "SizeScaling");
_enhancemethod.addOption(
static_cast<int>(EnhanceMethod::Colortables), "ColorTables");
_enhancemethod.addOption(
static_cast<int>(EnhanceMethod::Sizeandcolor), "Sizescaling and colortables");
_enhancemethod.addOption(
static_cast<int>(EnhanceMethod::Illuminance), "Illuminance");
static_cast<int>(EnhanceMethod::SizeAndColor), "Sizescaling and colortables"
);
_enhancemethod.addOption(static_cast<int>(EnhanceMethod::Illuminance), "Illuminance");
if (p.energyBin.has_value()) {
_goesEnergyBins.setValue(p.energyBin.value());
@@ -503,12 +467,8 @@ RenderableFluxNodes::RenderableFluxNodes(const ghoul::Dictionary& dictionary)
}
void RenderableFluxNodes::initialize() {
setModelDependentConstants();
populateStartTimes();
loadNodeData(_goesEnergyBins.option().value);
computeSequenceEndTime();
}
@@ -523,7 +483,7 @@ void RenderableFluxNodes::initializeGL() {
_uniformCache.streamColor = _shaderProgram->uniformLocation("streamColor");
_uniformCache.nodeSize = _shaderProgram->uniformLocation("nodeSize");
_uniformCache.nodeSizeLargerFlux =
_shaderProgram->uniformLocation("nodeSizeLargerFlux");
_shaderProgram->uniformLocation("nodeSizeLargerFlux");
_uniformCache.thresholdFlux = _shaderProgram->uniformLocation("thresholdFlux");
ghoul::opengl::updateUniformLocations(*_shaderProgram, _uniformCache, UniformNames);
@@ -551,21 +511,6 @@ void RenderableFluxNodes::definePropertyCallbackFunctions() {
});
}
void RenderableFluxNodes::setModelDependentConstants() {
// Just used as a default value.
float limit = 8.f;
_colorTableRange.setMinValue(glm::vec2(-limit));
_colorTableRange.setMaxValue(glm::vec2(limit));
_colorTableRange = glm::vec2(-2.f, 4.f);
float limitZMin = -2.5f;
float limitZMax = 2.5f;
_domainZ.setMinValue(glm::vec2(limitZMin));
_domainZ.setMaxValue(glm::vec2(limitZMax));
_domainZ = glm::vec2(limitZMin, limitZMax);
}
void RenderableFluxNodes::loadNodeData(int energybinOption) {
LDEBUG("Loading in binary files directly from sync folder");
@@ -573,10 +518,10 @@ void RenderableFluxNodes::loadNodeData(int energybinOption) {
switch (energybinOption) {
case 0:
energybin = "_emin01";
break;
break;
case 1:
energybin = "_emin03";
break;
break;
}
std::string file = _binarySourceFolderPath.string() + "\\positions" + energybin;
@@ -600,8 +545,10 @@ void RenderableFluxNodes::loadNodeData(int energybinOption) {
_nStates = nTimeSteps;
if (_nStates != _startTimes.size()) {
LERROR("Number of states, _nStates, and number of start times, _startTimes, "
"do not match");
LERROR(
"Number of states, _nStates, and number of start times, _startTimes, "
"do not match"
);
return;
}
@@ -639,23 +586,17 @@ void RenderableFluxNodes::loadNodeData(int energybinOption) {
}
void RenderableFluxNodes::setupProperties() {
// -------------- Add non-grouped properties (enablers and buttons) -------------- //
addProperty(_goesEnergyBins);
addProperty(_lineWidth);
addProperty(_misalignedIndex);
addProperty(_scaleFactor);
// ----------------------------- Add Property Groups ----------------------------- //
addPropertySubOwner(_colorGroup);
addPropertySubOwner(_streamGroup);
addPropertySubOwner(_nodesamountGroup);
addPropertySubOwner(_nodesAmountGroup);
addPropertySubOwner(_earthdistGroup);
addPropertySubOwner(_cameraPerspectiveGroup);
_earthdistGroup.addPropertySubOwner(_flowGroup);
// ------------------------- Add Properties to the groups ------------------------ //
_colorGroup.addProperty(_colorMode);
_colorGroup.addProperty(_scalingmethod);
_colorGroup.addProperty(_scalingMethod);
_colorGroup.addProperty(_colorTableRange);
_colorGroup.addProperty(_colorTablePath);
_colorGroup.addProperty(_streamColor);
@@ -667,16 +608,16 @@ void RenderableFluxNodes::setupProperties() {
_streamGroup.addProperty(_filteringUpper);
_streamGroup.addProperty(_domainZ);
_nodesamountGroup.addProperty(_nodeskipMethod);
_nodesamountGroup.addProperty(_amountofNodes);
_nodesamountGroup.addProperty(_defaultNodeSkip);
_nodesamountGroup.addProperty(_earthNodeSkip);
_nodesamountGroup.addProperty(_nodeSize);
_nodesamountGroup.addProperty(_nodeSizeLargerFlux);
_nodesamountGroup.addProperty(_fluxNodeskipThreshold);
_nodesamountGroup.addProperty(_radiusNodeSkipThreshold);
_nodesamountGroup.addProperty(_maxNodeDistanceSize);
_nodesamountGroup.addProperty(_nodeDistanceThreshold);
_nodesAmountGroup.addProperty(_nodeskipMethod);
_nodesAmountGroup.addProperty(_amountofNodes);
_nodesAmountGroup.addProperty(_defaultNodeSkip);
_nodesAmountGroup.addProperty(_earthNodeSkip);
_nodesAmountGroup.addProperty(_nodeSize);
_nodesAmountGroup.addProperty(_nodeSizeLargerFlux);
_nodesAmountGroup.addProperty(_fluxNodeskipThreshold);
_nodesAmountGroup.addProperty(_radiusNodeSkipThreshold);
_nodesAmountGroup.addProperty(_maxNodeDistanceSize);
_nodesAmountGroup.addProperty(_nodeDistanceThreshold);
_earthdistGroup.addProperty(_distanceThreshold);
_earthdistGroup.addProperty(_enhancemethod);
@@ -695,8 +636,8 @@ void RenderableFluxNodes::setupProperties() {
_cameraPerspectiveGroup.addProperty(_drawingHollow);
_cameraPerspectiveGroup.addProperty(_gaussianAlphaFilter);
_cameraPerspectiveGroup.addProperty(_radiusPerspectiveEnabled);
_cameraPerspectiveGroup.addProperty(_maxNodeSize);
_cameraPerspectiveGroup.addProperty(_minNodeSize);
_minMaxNodeSize.setViewOption(properties::Property::ViewOptions::MinMaxRange);
_cameraPerspectiveGroup.addProperty(_minMaxNodeSize);
_cameraPerspectiveGroup.addProperty(_pulseEnabled);
_cameraPerspectiveGroup.addProperty(_gaussianPulseEnabled);
_cameraPerspectiveGroup.addProperty(_pulseAlways);
@@ -737,7 +678,7 @@ void RenderableFluxNodes::populateStartTimes() {
for (const std::string& filePath : _binarySourceFiles) {
timeFile = filePath;
if (filePath.substr(filePath.find_last_of(".") + 1) == "csv" ) {
if (filePath.substr(filePath.find_last_of(".") + 1) == "csv") {
fileType = "csv";
break;
}
@@ -751,11 +692,12 @@ void RenderableFluxNodes::populateStartTimes() {
}
//if no file extention but word "time" in file name
else if (filePath.find("time") != std::string::npos &&
filePath.find(".") == std::string::npos) {
filePath.find(".") == std::string::npos)
{
break;
}
else {
LERROR(fmt::format("Error in file type or nameing of file '{}'. ",
LERROR(fmt::format("Error in file type or naming of file '{}'. ",
"Time meta file supports csv, dat, txt or without file extention ",
"(but then have to include 'time' in filename)", filePath
));
@@ -764,30 +706,33 @@ void RenderableFluxNodes::populateStartTimes() {
}
if (timeFile.empty()) {
LERROR("Could not find a metadata file with time steps,"
" such as a csv, dat, txt or no file extention with 'time' in filename");
LERROR(
"Could not find a metadata file with time steps, "
"such as a csv, dat, txt or no file extention with 'time' in filename"
);
}
// time filestream
std::ifstream tfs(timeFile);
if (!tfs.is_open()) {
throw std::runtime_error("Could not open file");
throw ghoul::RuntimeError("Could not open file");
}
std::string line;
std::getline(tfs, line); //gets only first line
// gets only first line to "remove" header
std::getline(tfs, line);
std::stringstream s;
s << line;
int nColumns = 0;
std::string columnName;
//loops through the names/columns in first line/header
// loops through the names/columns in first line/header
while (s >> columnName) {
++nColumns;
}
while (std::getline(tfs, line)) { //for each line of data
while (std::getline(tfs, line)) { // for each line of data
std::istringstream iss(line);
for (int i = 0; i < nColumns; ++i) { //for each column in line
for (int i = 0; i < nColumns; ++i) { // for each column in line
std::string columnValue;
iss >> columnValue;
if (i != nColumns - 1) { // last column
@@ -801,7 +746,6 @@ void RenderableFluxNodes::populateStartTimes() {
columnValue.replace(16, 1, ":");
columnValue.replace(19, 1, ".");
const double triggerTime = Time::convertTime(columnValue);
LDEBUG("timestring " + columnValue);
_startTimes.push_back(triggerTime);
}
else {
@@ -809,7 +753,6 @@ void RenderableFluxNodes::populateStartTimes() {
"file '{}' is not on UTC ISO8601 format", timeFile
));
}
}
}
}
@@ -818,9 +761,8 @@ void RenderableFluxNodes::updateActiveTriggerTimeIndex(double currentTime) {
auto iter = std::upper_bound(_startTimes.begin(), _startTimes.end(), currentTime);
if (iter != _startTimes.end()) {
if (iter != _startTimes.begin()) {
_activeTriggerTimeIndex = static_cast<int>(
std::distance(_startTimes.begin(), iter)
) - 1;
std::ptrdiff_t idx = std::distance(_startTimes.begin(), iter);
_activeTriggerTimeIndex = static_cast<int>(idx) - 1;
}
else {
_activeTriggerTimeIndex = 0;
@@ -831,141 +773,137 @@ void RenderableFluxNodes::updateActiveTriggerTimeIndex(double currentTime) {
}
}
void RenderableFluxNodes::render(const RenderData& data, RendererTasks&) {
if (_activeTriggerTimeIndex != -1) {
_shaderProgram->activate();
// Calculate Model View MatrixProjection
const glm::dmat4 rotMat = glm::dmat4(data.modelTransform.rotation);
const glm::dmat4 modelMat =
glm::translate(glm::dmat4(1.0), data.modelTransform.translation) *
rotMat *
glm::dmat4(glm::scale(
glm::dmat4(1.0), glm::dvec3(data.modelTransform.scale)
));
const glm::dmat4 modelViewMat = data.camera.combinedViewMatrix() * modelMat;
//not in use atm.
_shaderProgram->setUniform("modelViewProjection",
data.camera.sgctInternal.projectionMatrix() * glm::mat4(modelViewMat)
);
SceneGraphNode* earthNode = sceneGraphNode("Earth");
if (!earthNode) {
LWARNING("Could not find scene graph node 'Earth'.");
}
glm::vec3 earthPos = earthNode->worldPosition() * data.modelTransform.rotation;
_shaderProgram->setUniform(_uniformCache.streamColor, _streamColor);
_shaderProgram->setUniform(_uniformCache.nodeSize, _nodeSize);
_shaderProgram->setUniform(
_uniformCache.nodeSizeLargerFlux,
_nodeSizeLargerFlux
);
_shaderProgram->setUniform(_uniformCache.thresholdFlux, _thresholdFlux);
_shaderProgram->setUniform(_uniformCache.colorMode, _colorMode);
_shaderProgram->setUniform(_uniformCache.filterLower, _filteringLower);
_shaderProgram->setUniform(_uniformCache.filterUpper, _filteringUpper);
_shaderProgram->setUniform(_uniformCache.scalingMode, _scalingmethod);
_shaderProgram->setUniform(
_uniformCache.colorTableRange,
_colorTableRange.value()
);
_shaderProgram->setUniform(_uniformCache.domainLimZ, _domainZ.value());
_shaderProgram->setUniform(_uniformCache.nodeSkip, _amountofNodes);
_shaderProgram->setUniform(_uniformCache.nodeSkipDefault, _defaultNodeSkip);
_shaderProgram->setUniform(_uniformCache.nodeSkipEarth, _earthNodeSkip);
_shaderProgram->setUniform(_uniformCache.nodeSkipMethod, _nodeskipMethod);
_shaderProgram->setUniform(
_uniformCache.nodeSkipFluxThreshold,
_fluxNodeskipThreshold
);
_shaderProgram->setUniform(
_uniformCache.nodeSkipRadiusThreshold,
_radiusNodeSkipThreshold
);
_shaderProgram->setUniform(_uniformCache.fluxColorAlpha, _fluxColorAlpha);
_shaderProgram->setUniform(
_uniformCache.fluxColorAlphaIlluminance,
_fluxColorAlphaIlluminance
);
_shaderProgram->setUniform(_uniformCache.earthPos, earthPos);
_shaderProgram->setUniform(_uniformCache.distanceThreshold, _distanceThreshold);
_shaderProgram->setUniform(_uniformCache.enhanceMethod, _enhancemethod);
_shaderProgram->setUniform(_uniformCache.flowColor, _flowColor);
_shaderProgram->setUniform(_uniformCache.usingParticles, _flowEnabled);
_shaderProgram->setUniform(_uniformCache.particleSize, _flowParticleSize);
_shaderProgram->setUniform(_uniformCache.particleSpacing, _flowParticleSpacing);
_shaderProgram->setUniform(_uniformCache.particleSpeed, _flowSpeed);
_shaderProgram->setUniform(
_uniformCache2.time,
global::windowDelegate->applicationTime() * -1
);
_shaderProgram->setUniform(_uniformCache2.flowColoring, _useFlowColor);
_shaderProgram->setUniform(
_uniformCache2.maxNodeDistanceSize,
_maxNodeDistanceSize
);
_shaderProgram->setUniform(
_uniformCache2.usingCameraPerspective,
_cameraPerspectiveEnabled
);
_shaderProgram->setUniform(_uniformCache2.drawCircles, _drawingCircles);
_shaderProgram->setUniform(_uniformCache2.drawHollow, _drawingHollow);
_shaderProgram->setUniform(_uniformCache2.useGaussian, _gaussianAlphaFilter);
_shaderProgram->setUniform(
_uniformCache2.usingRadiusPerspective,
_radiusPerspectiveEnabled
);
_shaderProgram->setUniform(
_uniformCache2.perspectiveDistanceFactor,
_perspectiveDistanceFactor
);
_shaderProgram->setUniform(_uniformCache2.maxNodeSize, _maxNodeSize);
_shaderProgram->setUniform(_uniformCache2.minNodeSize, _minNodeSize);
_shaderProgram->setUniform(_uniformCache2.usingPulse, _pulseEnabled);
_shaderProgram->setUniform(
_uniformCache2.usingGaussianPulse,
_gaussianPulseEnabled
);
_shaderProgram->setUniform(_uniformCache2.pulsatingAlways, _pulseAlways);
glm::vec3 cameraPos = data.camera.positionVec3() * data.modelTransform.rotation;
_shaderProgram->setUniform("cameraPos", cameraPos);
ghoul::opengl::TextureUnit textureUnit;
ghoul::opengl::TextureUnit textureUnitCMR;
ghoul::opengl::TextureUnit textureUnitEarth;
ghoul::opengl::TextureUnit textureUnitFlow;
if (_colorMode == static_cast<int>(ColorMethod::ByFluxValue)) {
textureUnit.activate();
_transferFunction->bind(); // Calls update internally
_shaderProgram->setUniform("colorTable", textureUnit);
textureUnitCMR.activate();
_transferFunctionCMR->bind(); // Calls update internally
_shaderProgram->setUniform("colorTableCMR", textureUnitCMR);
textureUnitEarth.activate();
_transferFunctionEarth->bind(); // Calls update internally
_shaderProgram->setUniform("colorTableEarth", textureUnitEarth);
textureUnitFlow.activate();
_transferFunctionFlow->bind(); // Calls update internally
_shaderProgram->setUniform("colorTableFlow", textureUnitFlow);
}
glBindVertexArray(_vertexArrayObject);
glDrawArrays(
GL_POINTS,
0,
static_cast<GLsizei>(_vertexPositions.size())
);
glBindVertexArray(0);
_shaderProgram->deactivate();
if (_activeTriggerTimeIndex == -1) {
return;
}
_shaderProgram->activate();
// Calculate Model View MatrixProjection
const glm::dmat4 rotMat = glm::dmat4(data.modelTransform.rotation);
const glm::dmat4 modelMat =
glm::translate(glm::dmat4(1.0), data.modelTransform.translation) *
rotMat *
glm::dmat4(glm::scale(
glm::dmat4(1.0), data.modelTransform.scale
));
const glm::dmat4 modelViewMat = data.camera.combinedViewMatrix() * modelMat;
_shaderProgram->setUniform("modelViewProjection",
data.camera.sgctInternal.projectionMatrix() * glm::mat4(modelViewMat)
);
SceneGraphNode* earthNode = sceneGraphNode("Earth");
if (!earthNode) {
LWARNING("Could not find scene graph node 'Earth'");
}
glm::vec3 earthPos = earthNode->worldPosition() * data.modelTransform.rotation;
_shaderProgram->setUniform(_uniformCache.streamColor, _streamColor);
_shaderProgram->setUniform(_uniformCache.nodeSize, _nodeSize);
_shaderProgram->setUniform(
_uniformCache.nodeSizeLargerFlux,
_nodeSizeLargerFlux
);
_shaderProgram->setUniform(_uniformCache.thresholdFlux, _thresholdFlux);
_shaderProgram->setUniform(_uniformCache.colorMode, _colorMode);
_shaderProgram->setUniform(_uniformCache.filterLower, _filteringLower);
_shaderProgram->setUniform(_uniformCache.filterUpper, _filteringUpper);
_shaderProgram->setUniform(_uniformCache.scalingMode, _scalingMethod);
_shaderProgram->setUniform(_uniformCache.colorTableRange, _colorTableRange);
_shaderProgram->setUniform(_uniformCache.domainLimZ, _domainZ);
_shaderProgram->setUniform(_uniformCache.nodeSkip, _amountofNodes);
_shaderProgram->setUniform(_uniformCache.nodeSkipDefault, _defaultNodeSkip);
_shaderProgram->setUniform(_uniformCache.nodeSkipEarth, _earthNodeSkip);
_shaderProgram->setUniform(_uniformCache.nodeSkipMethod, _nodeskipMethod);
_shaderProgram->setUniform(
_uniformCache.nodeSkipFluxThreshold,
_fluxNodeskipThreshold
);
_shaderProgram->setUniform(
_uniformCache.nodeSkipRadiusThreshold,
_radiusNodeSkipThreshold
);
_shaderProgram->setUniform(_uniformCache.fluxColorAlpha, _fluxColorAlpha);
_shaderProgram->setUniform(
_uniformCache.fluxColorAlphaIlluminance,
_fluxColorAlphaIlluminance
);
_shaderProgram->setUniform(_uniformCache.earthPos, earthPos);
_shaderProgram->setUniform(_uniformCache.distanceThreshold, _distanceThreshold);
_shaderProgram->setUniform(_uniformCache.enhanceMethod, _enhancemethod);
_shaderProgram->setUniform(_uniformCache.flowColor, _flowColor);
_shaderProgram->setUniform(_uniformCache.usingParticles, _flowEnabled);
_shaderProgram->setUniform(_uniformCache.particleSize, _flowParticleSize);
_shaderProgram->setUniform(_uniformCache.particleSpacing, _flowParticleSpacing);
_shaderProgram->setUniform(_uniformCache.particleSpeed, _flowSpeed);
_shaderProgram->setUniform(
_uniformCache2.time,
global::windowDelegate->applicationTime() * -1
);
_shaderProgram->setUniform(_uniformCache2.flowColoring, _useFlowColor);
_shaderProgram->setUniform(
_uniformCache2.maxNodeDistanceSize,
_maxNodeDistanceSize
);
_shaderProgram->setUniform(
_uniformCache2.usingCameraPerspective,
_cameraPerspectiveEnabled
);
_shaderProgram->setUniform(_uniformCache2.drawCircles, _drawingCircles);
_shaderProgram->setUniform(_uniformCache2.drawHollow, _drawingHollow);
_shaderProgram->setUniform(_uniformCache2.useGaussian, _gaussianAlphaFilter);
_shaderProgram->setUniform(
_uniformCache2.usingRadiusPerspective,
_radiusPerspectiveEnabled
);
_shaderProgram->setUniform(
_uniformCache2.perspectiveDistanceFactor,
_perspectiveDistanceFactor
);
_shaderProgram->setUniform(_uniformCache2.minMaxNodeSize, _minMaxNodeSize);
_shaderProgram->setUniform(_uniformCache2.usingPulse, _pulseEnabled);
_shaderProgram->setUniform(
_uniformCache2.usingGaussianPulse,
_gaussianPulseEnabled
);
_shaderProgram->setUniform(_uniformCache2.pulsatingAlways, _pulseAlways);
glm::vec3 cameraPos = data.camera.positionVec3() * data.modelTransform.rotation;
_shaderProgram->setUniform("cameraPos", cameraPos);
ghoul::opengl::TextureUnit textureUnit;
ghoul::opengl::TextureUnit textureUnitCMR;
ghoul::opengl::TextureUnit textureUnitEarth;
ghoul::opengl::TextureUnit textureUnitFlow;
if (_colorMode == static_cast<int>(ColorMethod::ByFluxValue)) {
textureUnit.activate();
_transferFunction->bind(); // Calls update internally
_shaderProgram->setUniform("colorTable", textureUnit);
textureUnitCMR.activate();
_transferFunctionCMR->bind(); // Calls update internally
_shaderProgram->setUniform("colorTableCMR", textureUnitCMR);
textureUnitEarth.activate();
_transferFunctionEarth->bind(); // Calls update internally
_shaderProgram->setUniform("colorTableEarth", textureUnitEarth);
textureUnitFlow.activate();
_transferFunctionFlow->bind(); // Calls update internally
_shaderProgram->setUniform("colorTableFlow", textureUnitFlow);
}
glBindVertexArray(_vertexArrayObject);
glDrawArrays(
GL_POINTS,
0,
static_cast<GLsizei>(_vertexPositions.size())
);
glBindVertexArray(0);
_shaderProgram->deactivate();
}
void RenderableFluxNodes::computeSequenceEndTime() {
@@ -1007,7 +945,6 @@ void RenderableFluxNodes::update(const UpdateData& data) {
(nextIdx < _nStates && currentTime >= _startTimes[nextIdx]))
{
updateActiveTriggerTimeIndex(currentTime);
needsUpdate = true;
} // else {we're still in same state as previous frame (no changes needed)}
}
else {
@@ -1015,19 +952,14 @@ void RenderableFluxNodes::update(const UpdateData& data) {
needsUpdate = false;
}
if (needsUpdate) {
if (!_statesPos[_activeTriggerTimeIndex].empty()) {
//if (_activeTriggerTimeIndex > _pMisalignedIndex) {
// _activeTriggerTimeIndex += -_pMisalignedIndex;
//}
_vertexPositions = _statesPos[_activeTriggerTimeIndex];//TODO urgent.
_vertexColor = _statesColor[_activeTriggerTimeIndex]; //access violation
_vertexRadius = _statesRadius[_activeTriggerTimeIndex];
needsUpdate = false;
updatePositionBuffer();
updateVertexColorBuffer();
updateVertexFilteringBuffer();
}
if (needsUpdate && !_statesPos[_activeTriggerTimeIndex].empty()) {
_vertexPositions = _statesPos[_activeTriggerTimeIndex];
_vertexColor = _statesColor[_activeTriggerTimeIndex];
_vertexRadius = _statesRadius[_activeTriggerTimeIndex];
needsUpdate = false;
updatePositionBuffer();
updateVertexColorBuffer();
updateVertexFilteringBuffer();
}
if (_shaderProgram->isDirty()) {
@@ -1049,56 +981,52 @@ void RenderableFluxNodes::updatePositionBuffer() {
glBindVertexArray(_vertexArrayObject);
glBindBuffer(GL_ARRAY_BUFFER, _vertexPositionBuffer);
const std::vector<glm::vec3>& vertPos = _vertexPositions;
glBufferData(
GL_ARRAY_BUFFER,
vertPos.size() * sizeof(glm::vec3),
vertPos.data(),
_vertexPositions.size() * sizeof(glm::vec3),
_vertexPositions.data(),
GL_STATIC_DRAW
);
glEnableVertexAttribArray(VaPosition);
glEnableVertexAttribArray(0);
glEnable(GL_PROGRAM_POINT_SIZE);
glVertexAttribPointer(VaPosition, 3, GL_FLOAT, GL_FALSE, 0, 0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
void RenderableFluxNodes::updateVertexColorBuffer() {
glBindVertexArray(_vertexArrayObject);
glBindBuffer(GL_ARRAY_BUFFER, _vertexColorBuffer);
const std::vector<float>& vertColor = _vertexColor;
glBufferData(
GL_ARRAY_BUFFER,
vertColor.size() * sizeof(float),
vertColor.data(),
_vertexColor.size() * sizeof(float),
_vertexColor.data(),
GL_STATIC_DRAW
);
glEnableVertexAttribArray(VaColor);
glVertexAttribPointer(VaColor, 1, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
void RenderableFluxNodes::updateVertexFilteringBuffer() {
glBindVertexArray(_vertexArrayObject);
glBindBuffer(GL_ARRAY_BUFFER, _vertexFilteringBuffer);
const std::vector<float>& vertexRadius = _vertexRadius;
glBufferData(
GL_ARRAY_BUFFER,
vertexRadius.size() * sizeof(float),
vertexRadius.data(),
_vertexRadius.size() * sizeof(float),
_vertexRadius.data(),
GL_STATIC_DRAW
);
glEnableVertexAttribArray(VaFiltering);
glVertexAttribPointer(VaFiltering, 1, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);

View File

@@ -52,9 +52,19 @@ public:
static documentation::Documentation Documentation();
private:
void definePropertyCallbackFunctions();
void populateStartTimes();
void computeSequenceEndTime();
void setupProperties();
void updateActiveTriggerTimeIndex(double currentTime);
void loadNodeData(int energybinOption);
void updatePositionBuffer();
void updateVertexColorBuffer();
void updateVertexFilteringBuffer();
std::vector<GLsizei> _lineCount;
std::vector<GLint> _lineStart;
// ------------------------------------- ENUMS -------------------------------------//
// Used to determine if lines should be colored UNIFORMLY or by Flux Value
enum class ColorMethod {
ByFluxValue = 0,
@@ -68,8 +78,8 @@ private:
Flux = 0,
RFlux = 1,
R2Flux = 2,
log10RFlux = 3,
lnRFlux = 4
Log10RFlux = 3,
LnRFlux = 4
};
enum class NodeSkipMethod {
Uniform = 0,
@@ -78,9 +88,9 @@ private:
Streamnumber = 3
};
enum class EnhanceMethod {
Sizescaling = 0,
Colortables = 1,
Sizeandcolor = 2,
SizeScaling = 0,
ColorTables = 1,
SizeAndColor = 2,
Illuminance = 3,
};
@@ -93,15 +103,12 @@ private:
_uniformCache;
UniformCache(time, flowColoring, maxNodeDistanceSize, usingCameraPerspective,
drawCircles, drawHollow, useGaussian, usingRadiusPerspective,
perspectiveDistanceFactor, maxNodeSize, minNodeSize, usingPulse,
perspectiveDistanceFactor, minMaxNodeSize, usingPulse,
usingGaussianPulse, pulsatingAlways)
_uniformCache2;
// ------------------------------------ STRINGS ------------------------------------//
std::filesystem::path _binarySourceFolderPath;
// --------------------------------- NUMERICALS ----------------------------------- //
// Active index of _startTimes
int _activeTriggerTimeIndex = -1;
// Number of states in the sequence
@@ -121,8 +128,6 @@ private:
// OpenGL Vertex Buffer Object containing the index of nodes
GLuint _vertexindexBuffer = 0;
// ----------------------------------- POINTERS ------------------------------------//
// The Lua-Modfile-Dictionary used during initialization
std::unique_ptr<ghoul::opengl::ProgramObject> _shaderProgram;
// Transfer function used to color lines when _pColorMethod is set to BY_FLUX_VALUE
@@ -134,7 +139,7 @@ private:
// Transfer function used to color line flow
std::unique_ptr<TransferFunction> _transferFunctionFlow;
// ------------------------------------ VECTORS ----------------------------------- //
std::vector<std::string> _binarySourceFiles;
// Contains the _triggerTimes for all streams in the sequence
std::vector<double> _startTimes;
// Contains vertexPositions
@@ -150,11 +155,10 @@ private:
// Stores the states radius
std::vector<std::vector<float>> _statesRadius;
// ---------------------------------- Properties ---------------------------------- //
// Group to hold properties regarding distance to earth
properties::PropertyOwner _earthdistGroup;
//Property to show different energybins
// Property to show different energybins
properties::OptionProperty _goesEnergyBins;
// Group to hold the color properties
properties::PropertyOwner _colorGroup;
@@ -175,17 +179,15 @@ private:
// Group to hold the particle properties
properties::PropertyOwner _streamGroup;
// Scaling options
properties::OptionProperty _scalingmethod;
properties::OptionProperty _scalingMethod;
// Group for how many nodes to render dependent on radius and flux
properties::PropertyOwner _nodesamountGroup;
properties::PropertyOwner _nodesAmountGroup;
// Size of simulated node particles
properties::FloatProperty _nodeSize;
// Size of nodes for larger flux
properties::FloatProperty _nodeSizeLargerFlux;
// Threshold from earth to decide the distance for which the nodeSize gets larger
properties::FloatProperty _distanceThreshold;
// Minimum size of nodes at a certin distance
//properties::FloatProperty _pMinNodeDistanceSize;
// Maximum size of nodes at a certin distance
properties::FloatProperty _maxNodeDistanceSize;
// Threshold for where to interpolate between the max and min node distance
@@ -193,10 +195,10 @@ private:
// Toggle selected streams [ON/OFF]
properties::BoolProperty _interestingStreamsEnabled;
properties::FloatProperty _maxNodeSize;
properties::FloatProperty _minNodeSize;
/// Line width for the line rendering part
properties::FloatProperty _lineWidth;
//properties::FloatProperty _maxNodeSize;
//properties::FloatProperty _minNodeSize;
properties::Vec2Property _minMaxNodeSize;
// Valid range along the Z-axis
properties::Vec2Property _domainZ;
// Threshold flux value
@@ -219,8 +221,6 @@ private:
// The Radius threshold to decide the line between
//_pDefaultNodeSkip and _pAmountofNodes
properties::FloatProperty _radiusNodeSkipThreshold;
//Misaligned index for fieldlines vs Fluxnodes
properties::IntProperty _misalignedIndex;
// Flow Properties
// Simulated particles' color
@@ -239,7 +239,6 @@ private:
properties::IntProperty _flowSpeed;
//Either use flowcolortable or FlowColor.
properties::BoolProperty _useFlowColor;
properties::PropertyOwner _cameraPerspectiveGroup;
properties::BoolProperty _cameraPerspectiveEnabled;
properties::BoolProperty _drawingCircles;
@@ -250,23 +249,5 @@ private:
properties::BoolProperty _pulseEnabled;
properties::BoolProperty _gaussianPulseEnabled;
properties::BoolProperty _pulseAlways;
properties::FloatProperty _scaleFactor;
// initialization
std::vector<std::string> _binarySourceFiles;
// --------------------- FUNCTIONS USED DURING INITIALIZATION --------------------- //
void definePropertyCallbackFunctions();
void populateStartTimes();
void computeSequenceEndTime();
void setModelDependentConstants();
void setupProperties();
void updateActiveTriggerTimeIndex(double currentTime);
void loadNodeData(int energybinOption);
// ------------------------- FUNCTIONS USED DURING RUNTIME ------------------------ //
void updatePositionBuffer();
void updateVertexColorBuffer();
void updateVertexFilteringBuffer();
};
} // namespace openspace

View File

@@ -34,15 +34,12 @@
#include <openspace/util/timemanager.h>
#include <openspace/util/updatestructures.h>
#include <ghoul/filesystem/filesystem.h>
#include <optional>
namespace {
constexpr const char* _loggerCat = "renderableTravelSpeed";
constexpr const std::array<const char*, 2> UniformNames = {
"lineColor", "opacity"
};
constexpr const std::array<const char*, 2> UniformNames = {"lineColor", "opacity"};
constexpr openspace::properties::Property::PropertyInfo SpeedInfo = {
"TravelSpeed",
@@ -130,7 +127,7 @@ RenderableTravelSpeed::RenderableTravelSpeed(const ghoul::Dictionary& dictionary
, _indicatorLength(IndicatorLengthInfo, 1, 1, 360)
, _fadeLength(FadeLengthInfo, 1, 0, 360)
, _lineColor(LineColorInfo, glm::vec3(1.f), glm::vec3(0.f), glm::vec3(1.f))
, _opacity(LineOpacityInfo, 1.0, 0.0, 1.0)
, _opacity(LineOpacityInfo, 1.f, 0.f, 1.f)
, _lineWidth(LineWidthInfo, 2.f, 1.f, 20.f)
{
const Parameters p = codegen::bake<Parameters>(dictionary);
@@ -174,8 +171,10 @@ RenderableTravelSpeed::RenderableTravelSpeed(const ghoul::Dictionary& dictionary
}
void RenderableTravelSpeed::initialize() {
_initiationTime = -1;
_targetNode = sceneGraphNode(_targetName);
if (_targetNode == nullptr) {
throw ghoul::RuntimeError("Could not find targetNode");
}
}
void RenderableTravelSpeed::initializeGL() {
@@ -209,8 +208,7 @@ void RenderableTravelSpeed::deinitializeGL() {
double RenderableTravelSpeed::calculateLightTravelTime(glm::dvec3 startPosition,
glm::dvec3 targetPosition) {
return glm::distance(targetPosition, startPosition) /
_travelSpeed;
return glm::distance(targetPosition, startPosition) / _travelSpeed;
}
void RenderableTravelSpeed::calculateDirectionVector() {
@@ -219,26 +217,24 @@ void RenderableTravelSpeed::calculateDirectionVector() {
void RenderableTravelSpeed::calculateVerticesPositions() {
// 3: start of light, 2: start of fade, 1: end of fade
_verticesPositions[2] = _travelSpeed * _timeSinceStart * _directionVector;
_vertexPositions.headOfLight = _travelSpeed * _timeSinceStart * _directionVector;
// This if statment is there to not start the line from behind the source node
if (_timeSinceStart < _indicatorLength) {
_verticesPositions[1] = glm::vec3(0.0, 0.0, 0.0); // = source node
_vertexPositions.betweenLightAndFade = glm::vec3(0.0, 0.0, 0.0); // = source node
}
else {
_verticesPositions[1] =
_vertexPositions.betweenLightAndFade =
_travelSpeed * (_timeSinceStart - _indicatorLength) * _directionVector;
}
// This if statment is there to not start the line from behind the source node
if (_timeSinceStart < (_indicatorLength + _fadeLength)) {
_verticesPositions[0] = glm::vec3(0.0, 0.0, 0.0); // = source node
_vertexPositions.endOfFade = glm::vec3(0.0, 0.0, 0.0); // = source node
}
else {
_verticesPositions[0] =
_travelSpeed *
(_timeSinceStart - _indicatorLength - _fadeLength) *
_directionVector;
_vertexPositions.endOfFade = _travelSpeed *
(_timeSinceStart - _indicatorLength - _fadeLength) * _directionVector;
}
}
@@ -249,12 +245,12 @@ void RenderableTravelSpeed::updateVertexData() {
glBindBuffer(GL_ARRAY_BUFFER, _vBufferId);
glBufferData(
GL_ARRAY_BUFFER,
sizeof(_verticesPositions),
_verticesPositions,
sizeof(VertexPositions),
&_vertexPositions,
GL_DYNAMIC_DRAW
);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), nullptr);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), nullptr);
glBindVertexArray(0);
}
@@ -268,9 +264,8 @@ bool RenderableTravelSpeed::isReady() const{
}
void RenderableTravelSpeed::update(const UpdateData& data) {
if (_initiationTime == -1) {
if (_initiationTime == -1.0) {
_initiationTime = data.time.j2000Seconds();
std::string_view temp = data.time.ISO8601();
_arrivalTime = _initiationTime + _lightTravelTime;
}
@@ -308,7 +303,7 @@ void RenderableTravelSpeed::render(const RenderData& data, RendererTasks& ) {
const glm::dmat4 modelTransform =
glm::translate(glm::dmat4(1.0), data.modelTransform.translation) *
glm::dmat4(data.modelTransform.rotation) *
glm::scale(glm::dmat4(1.0), glm::dvec3(data.modelTransform.scale));
glm::scale(glm::dmat4(1.0), data.modelTransform.scale);
const glm::dmat4 modelViewTransform = data.camera.combinedViewMatrix() *
modelTransform;
@@ -323,11 +318,7 @@ void RenderableTravelSpeed::render(const RenderData& data, RendererTasks& ) {
#endif
glBindVertexArray(_vaoId);
glBindBuffer(GL_ARRAY_BUFFER, _vBufferId);
glDrawArrays(
GL_LINE_STRIP,
0,
3
);
glDrawArrays(GL_LINE_STRIP, 0, 3);
glBindVertexArray(0);
_shaderProgram->deactivate();

View File

@@ -68,16 +68,18 @@ private:
properties::FloatProperty _opacity;
properties::Vec3Property _lineColor;
//0 at parent, 1 at end of fade, 2 between light and fade,
//3 at head of light, 4 at target
glm::vec3 _verticesPositions[3];
struct VertexPositions {
glm::vec3 endOfFade;
glm::vec3 betweenLightAndFade;
glm::vec3 headOfLight;
};
VertexPositions _vertexPositions;
glm::dvec3 _sourcePosition;
glm::dvec3 _targetPosition;
double _lightTravelTime;
glm::dvec3 _directionVector;
double _initiationTime;
double _initiationTime = -1.0;
double _arrivalTime;
double _timeSinceStart = -1.0;
@@ -87,6 +89,7 @@ private:
GLuint _vaoId = 0;
GLuint _vBufferId = 0;
};
} // namespace openspace
#endif //__OPENSPACE_MODULE_SPACE___RENDERABLETRAVELSPEED___H__

View File

@@ -36,7 +36,6 @@ uniform bool drawCircles;
uniform bool drawHollow;
uniform bool useGaussian;
uniform bool usingCameraPerspective;
//uniform float testChange;
uniform bool pulsatingAlways;
uniform bool usingPulse;
uniform bool usingGaussianPulse;
@@ -49,44 +48,36 @@ Fragment getFragment() {
discard;
}
vec2 pos = vec2(0.5)-vs_st;
vec2 pos = vec2(0.5) - vs_st;
float r = length(pos)*2.0;
float a = atan(pos.y,pos.x);
float f = cos(a*3.0);
float r = length(pos) * 2.0;
float a = atan(pos.y, pos.x);
float f = cos(a * 3.0);
vec3 color = vec3(0.0);
color = vec3(1.-smoothstep(f,f, r));
color = vec3(1.0 - smoothstep(f, f, r));
//fragColor = vec4(color, 1.0);
Fragment frag;
frag.depth = vs_depth;
frag.color = fragColor;
vec2 coord = gl_PointCoord - vec2(0.5);
if (drawCircles) {
if (length(coord) > 0.5) {
discard;
}
if (drawCircles && length(coord) > 0.5) {
discard;
}
if (drawHollow &&
length(coord) < 0.4 &&
(vs_closeToEarth > 0.5 || distance(cameraPos, vec3(0)) < 500000000000.0f))
(vs_closeToEarth > 0.5 || distance(cameraPos, vec3(0.0)) < 500000000000.0))
{
//frag.color.xyz = streamColor.xyz;
if (usingGaussianPulse &&
usingCameraPerspective &&
vs_closeToEarth > 0.5)
{
if (length(coord) < 0.3 &&
(pulsatingAlways || camera_IsCloseEnough > 0.5))
{
if (length(coord) < 0.3 && (pulsatingAlways || camera_IsCloseEnough > 0.5)) {
float e = 2.718055;
float y = 1.0 *
pow(
e, - (pow(length(coord), 2.0)) /( 2.0 * pow(0.2, 2.0))
);
float y = 1.0 *
pow(e, - (pow(length(coord), 2.0)) /( 2.0 * pow(0.2, 2.0)));
if (y < 0.05) {
discard;
}

View File

@@ -38,8 +38,8 @@ layout(location = 1) in float fluxValue;
layout(location = 2) in float rValue;
// These should correspond to the enum 'ColorMode' in renderablefluxnodes.cpp
const int colorByFluxValue = 0;
const int uniformColor = 1;
const int colorByFluxValue = 0;
const int uniformColor = 1;
const int uniformskip = 0;
const int fluxSkip = 1;
@@ -89,7 +89,6 @@ uniform bool usingMasking;
uniform vec2 maskingRange;
// Domain Uniforms
uniform bool usingDomain;
uniform vec2 domainLimX;
uniform vec2 domainLimY;
uniform vec2 domainLimZ;
@@ -126,8 +125,7 @@ uniform bool usingCameraPerspective;
uniform bool usingRadiusPerspective;
uniform float perspectiveDistanceFactor;
uniform float maxNodeSize;
uniform float minNodeSize;
uniform vec2 minMaxNodeSize;
uniform bool usingPulse;
vec4 getTransferFunctionColor(sampler1D inColorTable) {
@@ -156,7 +154,7 @@ vec4 getTransferFunctionColor(sampler1D inColorTable) {
return texture(inColorTable, lookUpVal);
}
bool CheckvertexIndex() {
bool checkIfSkipVertex() {
int nodeIndex = gl_VertexID;
if (nodeSkipMethod == uniformskip) {
@@ -189,7 +187,7 @@ bool isParticle() {
}
//function for showing nodes different depending on distance to earth
void DecidehowtoshowClosetoEarth() {
void decideHowToShowCloseToEarth() {
// SizeScaling
if (enhanceMethod == sizeScaling || enhanceMethod == illuminance) {
vec4 fluxColor = getTransferFunctionColor(colorTableCMR);
@@ -213,7 +211,7 @@ void DecidehowtoshowClosetoEarth() {
}
}
void CheckdistanceMethod() {
void checkdistanceMethod() {
//Enhance by distance to Earth
float maxdist = 10000000000.0 * perspectiveDistanceFactor;
float distancevec = distance(earthPos, in_position.xyz);
@@ -226,18 +224,17 @@ void CheckdistanceMethod() {
vec4 fluxColor = getTransferFunctionColor(colorTable);
vs_color = vec4(fluxColor.xyz, fluxColorAlpha);
}
if (enhanceMethod == colorTables || enhanceMethod == sizeAndColor) {
vec4 fluxColor2 = getTransferFunctionColor(colorTableEarth);
vs_color = vec4(fluxColor2.xyz, fluxColorAlpha);
vec4 fluxColor = getTransferFunctionColor(colorTableEarth);
vs_color = vec4(fluxColor.xyz, fluxColorAlpha);
}
if (enhanceMethod == illuminance) {
vec4 fluxColor = getTransferFunctionColor(colorTableCMR);
vs_color = vec4(fluxColor.xyz, fluxColorAlpha);
if (enhanceMethod == illuminance) {
vec4 fluxColor = getTransferFunctionColor(colorTableCMR);
vs_color = vec4(fluxColor.xyz, fluxColorAlpha);
}
if (distance(earthPos, in_position) < AUtoMeter * distanceThreshold) {
if (mod(gl_VertexID, nodeSkipEarth) == 0) {
DecidehowtoshowClosetoEarth();
decideHowToShowCloseToEarth();
}
else {
vs_color = vec4(0.0);
@@ -257,20 +254,18 @@ void CheckdistanceMethod() {
void main() {
// Default gl_PointSize if it is not set anywhere else.
gl_PointSize = 2;
// Checking if we should render the vertex dependent on the vertexindex,
// by using modulus.
if (CheckvertexIndex() ||
if (checkIfSkipVertex() ||
distance(earthPos, in_position) < (distanceThreshold * AUtoMeter) &&
rValue/AUtoMeter > filterLower &&
rValue/AUtoMeter < filterUpper &&
in_position.z > (domainLimZ.x * AUtoMeter) &&
in_position.z < (domainLimZ.y * AUtoMeter))
{
// We should color it by flux
if (colorMode == 0) {
//vec4 fluxColor = getTransferFunctionColor(colorTable);
vec4 fluxColor = getTransferFunctionColor(colorTableCMR);
if (fluxValue > thresholdFlux) {
vs_color = vec4(fluxColor.xyz, fluxColor.a);
@@ -285,7 +280,7 @@ void main() {
//Uniform coloring
vs_color = streamColor;
}
CheckdistanceMethod();
checkdistanceMethod();
}
else {
vs_color = vec4(0.0);
@@ -293,7 +288,7 @@ void main() {
if (usingParticles && isParticle() && rValue > 0.0) {
int modulusResult = int(double(particleSpeed) * time + gl_VertexID)
% particleSpacing;
% particleSpacing;
if (modulusResult >= particleSize - 30) {
if (flowColoring) {
@@ -311,21 +306,15 @@ void main() {
}
if (usingCameraPerspective) {
float rtemp = 1.0;
if (rValue > 1.0) {
rtemp = 1.0;
}
else {
rtemp = rValue;
}
float rtemp = min(rValue, 1,0);
float maxDistance = 100000000000.0 * perspectiveDistanceFactor;
float distanceVec = distance(cameraPos, in_position.xyz);
if(distanceVec < maxDistance){
if (distanceVec < maxDistance) {
camera_IsCloseEnough = 0.0;
}
else{
else {
camera_IsCloseEnough = 1.0;
}
@@ -341,20 +330,19 @@ void main() {
gl_PointSize = factorS * maxNodeDistanceSize * 0.8;
}
if (gl_PointSize > maxNodeSize) {
gl_PointSize = maxNodeSize;
if (gl_PointSize > minMaxNodeSize.y) {
gl_PointSize = minMaxNodeSize.y;
}
if (gl_PointSize < minNodeSize) {
gl_PointSize = minNodeSize;
if (gl_PointSize < minMaxNodeSize.x) {
gl_PointSize = minMaxNodeSize.x;
}
}
vs_time = time;
vec4 position_in_meters = vec4(in_position, 1);
vec4 position_in_meters = vec4(in_position, 1.0);
vec4 positionClipSpace = modelViewProjection * position_in_meters;
//vs_gPosition = vec4(modelViewTransform * dvec4(in_point_position, 1));
gl_Position = vec4(positionClipSpace.xy, 0, positionClipSpace.w);
gl_Position = vec4(positionClipSpace.xy, 0.0, positionClipSpace.w);
vs_depth = gl_Position.w;
}

View File

@@ -49,7 +49,7 @@ void main() {
else if (gl_VertexID == 1) {
finalColor = vec4(lineColor, opacity);
}
else if (gl_VertexID == 2 ) {
else if (gl_VertexID == 2) {
finalColor = vec4(lineColor, opacity);
}
// should never hit else

View File

@@ -83,9 +83,6 @@ std::unique_ptr<RawVolume<VoxelType>> RawVolumeReader<VoxelType>::read(bool inve
std::unique_ptr<RawVolume<VoxelType>> volume = std::make_unique<RawVolume<VoxelType>>(
dims
);
std::unique_ptr<RawVolume<VoxelType>> newVolume = std::make_unique<RawVolume<VoxelType>>(
dims
);
std::ifstream file(_path, std::ios::binary);
char* buffer = reinterpret_cast<char*>(volume->data());
@@ -106,6 +103,9 @@ std::unique_ptr<RawVolume<VoxelType>> RawVolumeReader<VoxelType>::read(bool inve
}
if (invertZ) {
std::unique_ptr<RawVolume<VoxelType>> newVolume =
std::make_unique<RawVolume<VoxelType>>(dims);
for (int i = 0; i < volume->nCells(); ++i) {
const glm::uvec3& coords = volume->indexToCoords(i);
glm::uvec3 newcoords = glm::uvec3(coords.x, coords.y, dims.z - coords.z - 1);
@@ -115,12 +115,11 @@ std::unique_ptr<RawVolume<VoxelType>> RawVolumeReader<VoxelType>::read(bool inve
newVolume->set(newcoords, volume->get(coords));
}
return newVolume;
}
else {
return volume;
}
return newVolume;
}
} // namespace openspace::volume

View File

@@ -164,7 +164,7 @@ RenderableTimeVaryingVolume::RenderableTimeVaryingVolume(
: Renderable(dictionary)
, _gridType(GridTypeInfo, properties::OptionProperty::DisplayType::Dropdown)
, _stepSize(StepSizeInfo, 0.02f, 0.001f, 0.1f)
, _opacity(OpacityInfo, 10.0f, 0.f, VolumeMaxOpacity)
, _opacity(OpacityInfo, 10.f, 0.f, VolumeMaxOpacity)
, _rNormalization(rNormalizationInfo, 0.f, 0.f, 2.f)
, _rUpperBound(rUpperBoundInfo, 1.f, 0.f, 2.f)
, _secondsBefore(SecondsBeforeInfo, 0.f, 0.01f, SecondsInOneDay)