mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-03 10:09:40 -06:00
more pr comments fixed
This commit is contained in:
@@ -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 },
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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}},
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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__
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user