mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-03-03 02:48:32 -06:00
Merge branch 'master' into feature/jwst
This commit is contained in:
Submodule apps/OpenSpace/ext/sgct updated: 669fbc16a9...2a3ef78f72
19
data/assets/util/add_marker.asset
Normal file
19
data/assets/util/add_marker.asset
Normal file
@@ -0,0 +1,19 @@
|
||||
local icons = asset.syncedResource({
|
||||
Name = "Icons",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "icons",
|
||||
Version = 1
|
||||
})
|
||||
|
||||
asset.onInitialize(function()
|
||||
openspace.addScreenSpaceRenderable({
|
||||
Identifier = "target-marker",
|
||||
Name = "Target Marker",
|
||||
Type = "ScreenSpaceImageLocal",
|
||||
TexturePath = icons .. '/target.png'
|
||||
})
|
||||
end)
|
||||
|
||||
asset.onDeinitialize(function()
|
||||
openspace.removeScreenSpaceRenderable('target-marker');
|
||||
end)
|
||||
@@ -104,11 +104,12 @@ protected:
|
||||
properties::Vec3Property _localRotation;
|
||||
|
||||
properties::FloatProperty _scale;
|
||||
properties::Vec3Property _multiplyColor;
|
||||
properties::FloatProperty _opacity;
|
||||
properties::TriggerProperty _delete;
|
||||
|
||||
glm::ivec2 _objectSize = glm::ivec2(0);
|
||||
UniformCache(alpha, modelTransform, viewProj, texture) _uniformCache;
|
||||
UniformCache(color, alpha, modelTransform, viewProj, texture) _uniformCache;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _shader;
|
||||
};
|
||||
|
||||
|
||||
@@ -113,7 +113,7 @@ namespace {
|
||||
constexpr const char* GlslDeferredcastVsPath =
|
||||
"${MODULES}/atmosphere/shaders/atmosphere_deferred_vs.glsl";
|
||||
|
||||
constexpr const float ATM_EPS = 2.f;
|
||||
constexpr const float ATM_EPS = 2000.f;
|
||||
constexpr const float KM_TO_M = 1000.f;
|
||||
|
||||
|
||||
@@ -213,7 +213,7 @@ void AtmosphereDeferredcaster::preRaycast(const RenderData& renderData,
|
||||
renderData.camera.sgctInternal.projectionMatrix()
|
||||
) * renderData.camera.combinedViewMatrix();
|
||||
|
||||
const float totalAtmosphere = (_atmosphereRadius + ATM_EPS)* KM_TO_M;
|
||||
const float totalAtmosphere = (scaledRadius + ATM_EPS);
|
||||
if (!isAtmosphereInFrustum(MV, tPlanetPosWorld, totalAtmosphere)) {
|
||||
program.setUniform(_uniformCache.cullAtmosphere, 1);
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ namespace {
|
||||
// [[codegen::verbatim(BlendModeInfo.description)]]
|
||||
std::optional<BlendMode> blendMode;
|
||||
|
||||
// [[codegen::verbatim(BlendModeInfo.description)]]
|
||||
// [[codegen::verbatim(MultiplyColorInfo.description)]]
|
||||
std::optional<glm::vec3> multiplyColor [[codegen::color()]];
|
||||
};
|
||||
#include "renderableplane_codegen.cpp"
|
||||
@@ -275,6 +275,7 @@ void RenderablePlane::render(const RenderData& data, RendererTasks&) {
|
||||
|
||||
glBindVertexArray(_quad);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
glBindVertexArray(0);
|
||||
|
||||
if (additiveBlending) {
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
@@ -327,6 +328,7 @@ void RenderablePlane::createPlane() {
|
||||
sizeof(GLfloat) * 6,
|
||||
reinterpret_cast<void*>(sizeof(GLfloat) * 4)
|
||||
);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -75,8 +75,6 @@ RenderablePlaneImageOnline::RenderablePlaneImageOnline(
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
_texturePath.onChange([this]() { _textureIsDirty = true; });
|
||||
addProperty(_texturePath);
|
||||
|
||||
_texturePath = p.url;
|
||||
addProperty(_texturePath);
|
||||
}
|
||||
|
||||
@@ -81,8 +81,8 @@ ScreenSpaceImageOnline::ScreenSpaceImageOnline(const ghoul::Dictionary& dictiona
|
||||
setIdentifier(std::move(identifier));
|
||||
|
||||
_texturePath.onChange([this]() { _textureIsDirty = true; });
|
||||
addProperty(_texturePath);
|
||||
_texturePath = p.url.value_or(_texturePath);
|
||||
addProperty(_texturePath);
|
||||
}
|
||||
|
||||
ScreenSpaceImageOnline::~ScreenSpaceImageOnline() {} // NOLINT
|
||||
|
||||
@@ -29,13 +29,13 @@ in vec2 vs_st;
|
||||
in vec4 vs_position;
|
||||
|
||||
uniform sampler2D texture1;
|
||||
uniform float Alpha;
|
||||
uniform vec3 MultiplyColor = vec3(1.0, 1.0, 1.0);
|
||||
uniform float Alpha = 1.0;
|
||||
|
||||
Fragment getFragment() {
|
||||
Fragment frag;
|
||||
|
||||
frag.color = texture(texture1, vs_st);
|
||||
frag.color.a = Alpha * frag.color.a;
|
||||
frag.color = texture(texture1, vs_st) * vec4(MultiplyColor, Alpha);
|
||||
if (frag.color.a == 0.0) {
|
||||
discard;
|
||||
}
|
||||
|
||||
@@ -34,34 +34,50 @@
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/misc/dictionary.h>
|
||||
#include <charconv>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
|
||||
namespace {
|
||||
constexpr const char* KeyInputDataFile = "InputDataFile";
|
||||
constexpr const char* KeyInputSpeck = "InputSPECK";
|
||||
constexpr const char* KeyOutputBin = "OutputBIN";
|
||||
constexpr const char* KeyOutputLut = "OutputLUT";
|
||||
constexpr const char* KeyTeffToBv = "TeffToBvFile";
|
||||
|
||||
constexpr const char* _loggerCat = "ExoplanetsDataPreparationTask";
|
||||
|
||||
struct [[codegen::Dictionary(ExoplanetsDataPreparationTask)]] Parameters {
|
||||
// The csv file to extract data from
|
||||
std::filesystem::path inputDataFile;
|
||||
|
||||
// The speck file with star locations
|
||||
std::filesystem::path inputSPECK;
|
||||
|
||||
// The bin file to export data into
|
||||
std::string outputBIN [[codegen::annotation("A valid filepath")]];
|
||||
|
||||
// The txt file to write look-up table into
|
||||
std::string outputLUT [[codegen::annotation("A valid filepath")]];
|
||||
|
||||
// The path to a teff to bv conversion file. Should be a txt file where each line
|
||||
// has the format 'teff,bv'
|
||||
std::filesystem::path teffToBvFile;
|
||||
};
|
||||
#include "exoplanetsdatapreparationtask_codegen.cpp"
|
||||
} // namespace
|
||||
|
||||
namespace openspace::exoplanets {
|
||||
|
||||
documentation::Documentation ExoplanetsDataPreparationTask::documentation() {
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "exoplanets_data_preparation_task";
|
||||
return doc;
|
||||
}
|
||||
|
||||
ExoplanetsDataPreparationTask::ExoplanetsDataPreparationTask(
|
||||
const ghoul::Dictionary& dictionary)
|
||||
{
|
||||
openspace::documentation::testSpecificationAndThrow(
|
||||
documentation(),
|
||||
dictionary,
|
||||
"ExoplanetsDataPreparationTask"
|
||||
);
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
_inputDataPath = absPath(dictionary.value<std::string>(KeyInputDataFile));
|
||||
_inputSpeckPath = absPath(dictionary.value<std::string>(KeyInputSpeck));
|
||||
_outputBinPath = absPath(dictionary.value<std::string>(KeyOutputBin));
|
||||
_outputLutPath = absPath(dictionary.value<std::string>(KeyOutputLut));
|
||||
_teffToBvFilePath = absPath(dictionary.value<std::string>(KeyTeffToBv));
|
||||
_inputDataPath = absPath(p.inputDataFile.string());
|
||||
_inputSpeckPath = absPath(p.inputSPECK.string());
|
||||
_outputBinPath = absPath(p.outputBIN);
|
||||
_outputLutPath = absPath(p.outputLUT);
|
||||
_teffToBvFilePath = absPath(p.teffToBvFile.string());
|
||||
}
|
||||
|
||||
std::string ExoplanetsDataPreparationTask::description() {
|
||||
@@ -441,45 +457,4 @@ float ExoplanetsDataPreparationTask::bvFromTeff(float teff) {
|
||||
return bv;
|
||||
}
|
||||
|
||||
documentation::Documentation ExoplanetsDataPreparationTask::documentation() {
|
||||
using namespace documentation;
|
||||
return {
|
||||
"ExoplanetsDataPreparationTask",
|
||||
"exoplanets_data_preparation_task",
|
||||
{
|
||||
{
|
||||
KeyInputDataFile,
|
||||
new FileVerifier,
|
||||
Optional::No,
|
||||
"The csv file to extract data from"
|
||||
},
|
||||
{
|
||||
KeyInputSpeck,
|
||||
new FileVerifier,
|
||||
Optional::No,
|
||||
"The speck file with star locations"
|
||||
},
|
||||
{
|
||||
KeyOutputBin,
|
||||
new StringAnnotationVerifier("A valid filepath"),
|
||||
Optional::No,
|
||||
"The bin file to export data into"
|
||||
},
|
||||
{
|
||||
KeyOutputLut,
|
||||
new StringAnnotationVerifier("A valid filepath"),
|
||||
Optional::No,
|
||||
"The txt file to write look-up table into"
|
||||
},
|
||||
{
|
||||
KeyTeffToBv,
|
||||
new FileVerifier,
|
||||
Optional::No,
|
||||
"The path to a teff to bv conversion file. Should be a txt file where "
|
||||
"each line has the format 'teff,bv'"
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace openspace::exoplanets
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/documentation/verifier.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/interaction/sessionrecording.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/scene/scene.h>
|
||||
@@ -107,62 +108,57 @@ namespace {
|
||||
constexpr openspace::properties::Property::PropertyInfo ShowChunkEdgeInfo = {
|
||||
"ShowChunkEdges",
|
||||
"Show chunk edges",
|
||||
"" // @TODO Missing documentation
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo ShowChunkBoundsInfo = {
|
||||
"ShowChunkBounds",
|
||||
"Show chunk bounds",
|
||||
"" // @TODO Missing documentation
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo HeightResolutionInfo = {
|
||||
"ShowHeightResolution",
|
||||
"Show height resolution",
|
||||
"" // @TODO Missing documentation
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo HeightIntensityInfo = {
|
||||
"ShowHeightIntensities",
|
||||
"Show height intensities",
|
||||
"" // @TODO Missing documentation
|
||||
"If this value is set to 'true', the borders between chunks are shown using a "
|
||||
"red highlight"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo LevelProjectedAreaInfo = {
|
||||
"LevelByProjectedAreaElseDistance",
|
||||
"Level by projected area (else distance)",
|
||||
"" // @TODO Missing documentation
|
||||
"If this value is set to 'true', the tile level is determined by the area "
|
||||
"projected on screen. If it is 'false', the distance to the center of the tile "
|
||||
"is used instead."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo ResetTileProviderInfo = {
|
||||
"ResetTileProviders",
|
||||
"Reset tile providers",
|
||||
"" // @TODO Missing documentation
|
||||
"If this property is triggered, all tile provides for the globe are reset and "
|
||||
"data is reloaded from scratch."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo ModelSpaceRenderingInfo = {
|
||||
"ModelSpaceRenderingCutoffLevel",
|
||||
"Model Space Rendering Cutoff Level",
|
||||
"" // @TODO Missing documentation
|
||||
"This value determines the tile level that is used as the cut off between "
|
||||
"rendering tiles using the globe model rendering vs the flat in-game rendering "
|
||||
"method. This value is a tradeoff between not having precision errors in the "
|
||||
"rendering and represting a tile as flat or curved."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo DynamicLodIterationCountInfo =
|
||||
{
|
||||
"DynamicLodIterationCount",
|
||||
"Data availability checks before LOD factor impact",
|
||||
"" // @TODO Missing documentation
|
||||
"The number of checks that have to fail/succeed in a row before the dynamic "
|
||||
"level-of-detail adjusts the actual level-of-detail up or down during a session "
|
||||
"recording"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo PerformShadingInfo = {
|
||||
"PerformShading",
|
||||
"Perform shading",
|
||||
"" // @TODO Missing documentation
|
||||
"This value determines whether there should be lighting applied to the surface "
|
||||
"of the globe. Note that if there is an atmosphere attached to the planet, there "
|
||||
"is a separate setting to control the shadowing induced by the atmosphere part."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo AccurateNormalsInfo = {
|
||||
"UseAccurateNormals",
|
||||
"Use Accurate Normals",
|
||||
"" // @TODO Missing documentation
|
||||
"This value determines whether higher-accuracy normals should be used in the "
|
||||
"rendering. These normals are calculated based on the height field information "
|
||||
"and are thus only available if the planet has a height map"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo EclipseInfo = {
|
||||
@@ -200,25 +196,22 @@ namespace {
|
||||
constexpr openspace::properties::Property::PropertyInfo TargetLodScaleFactorInfo = {
|
||||
"TargetLodScaleFactor",
|
||||
"Target Level of Detail Scale Factor",
|
||||
"" // @TODO Missing documentation
|
||||
"Determines the targeted level-of-detail of the tiles for this globe. A higher "
|
||||
"value means that the tiles rendered are a higher resolution for the same "
|
||||
"distance of the camera to the planet."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo CurrentLodScaleFactorInfo = {
|
||||
"CurrentLodScaleFactor",
|
||||
"Current Level of Detail Scale Factor (Read Only)",
|
||||
"" // @TODO Missing documentation
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo CameraMinHeightInfo = {
|
||||
"CameraMinHeight",
|
||||
"Camera Minimum Height",
|
||||
"" // @TODO Missing documentation
|
||||
"The currently used scale factor whose target value is deteremined by "
|
||||
"'TargetLodScaleFactor'."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo OrenNayarRoughnessInfo = {
|
||||
"OrenNayarRoughness",
|
||||
"orenNayarRoughness",
|
||||
"" // @TODO Missing documentation
|
||||
"The roughness factor that is used for the Oren-Nayar lighting mode"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo NActiveLayersInfo = {
|
||||
@@ -506,9 +499,6 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary)
|
||||
: Renderable(dictionary)
|
||||
, _debugProperties({
|
||||
BoolProperty(ShowChunkEdgeInfo, false),
|
||||
BoolProperty(ShowChunkBoundsInfo, false),
|
||||
BoolProperty(HeightResolutionInfo, false),
|
||||
BoolProperty(HeightIntensityInfo, false),
|
||||
BoolProperty(LevelProjectedAreaInfo, true),
|
||||
BoolProperty(ResetTileProviderInfo, false),
|
||||
IntProperty(ModelSpaceRenderingInfo, 14, 1, 22),
|
||||
@@ -524,7 +514,6 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary)
|
||||
IntProperty(NumberShadowSamplesInfo, 5, 1, 7),
|
||||
FloatProperty(TargetLodScaleFactorInfo, 15.f, 1.f, 50.f),
|
||||
FloatProperty(CurrentLodScaleFactorInfo, 15.f, 1.f, 50.f),
|
||||
FloatProperty(CameraMinHeightInfo, 100.f, 0.f, 1000.f),
|
||||
FloatProperty(OrenNayarRoughnessInfo, 0.f, 0.f, 1.f),
|
||||
IntProperty(NActiveLayersInfo, 0, 0, OpenGLCap.maxTextureUnits() / 3)
|
||||
})
|
||||
@@ -605,16 +594,11 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary)
|
||||
});
|
||||
addProperty(_generalProperties.targetLodScaleFactor);
|
||||
addProperty(_generalProperties.currentLodScaleFactor);
|
||||
addProperty(_generalProperties.cameraMinHeight);
|
||||
addProperty(_generalProperties.orenNayarRoughness);
|
||||
_generalProperties.nActiveLayers.setReadOnly(true);
|
||||
addProperty(_generalProperties.nActiveLayers);
|
||||
|
||||
_debugPropertyOwner.addProperty(_debugProperties.showChunkEdges);
|
||||
//_debugPropertyOwner.addProperty(_debugProperties.showChunkBounds);
|
||||
//_debugPropertyOwner.addProperty(_debugProperties.showChunkAABB);
|
||||
//_debugPropertyOwner.addProperty(_debugProperties.showHeightResolution);
|
||||
//_debugPropertyOwner.addProperty(_debugProperties.showHeightIntensities);
|
||||
_debugPropertyOwner.addProperty(_debugProperties.levelByProjectedAreaElseDistance);
|
||||
_debugPropertyOwner.addProperty(_debugProperties.resetTileProviders);
|
||||
_debugPropertyOwner.addProperty(_debugProperties.modelSpaceRenderingCutoffLevel);
|
||||
@@ -628,8 +612,6 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary)
|
||||
_generalProperties.eclipseHardShadows.onChange(notifyShaderRecompilation);
|
||||
_generalProperties.performShading.onChange(notifyShaderRecompilation);
|
||||
_debugProperties.showChunkEdges.onChange(notifyShaderRecompilation);
|
||||
_debugProperties.showHeightResolution.onChange(notifyShaderRecompilation);
|
||||
_debugProperties.showHeightIntensities.onChange(notifyShaderRecompilation);
|
||||
|
||||
_layerManager.onChange([&](Layer* l) {
|
||||
_shadersNeedRecompilation = true;
|
||||
@@ -808,13 +790,6 @@ void RenderableGlobe::update(const UpdateData& data) {
|
||||
|
||||
_localRenderer.program->setUniform("xSegments", _grid.xSegments);
|
||||
|
||||
if (_debugProperties.showHeightResolution) {
|
||||
_localRenderer.program->setUniform(
|
||||
"vertexResolution",
|
||||
glm::vec2(_grid.xSegments, _grid.ySegments)
|
||||
);
|
||||
}
|
||||
|
||||
ghoul::opengl::updateUniformLocations(
|
||||
*_localRenderer.program,
|
||||
_localRenderer.uniformCache,
|
||||
@@ -827,12 +802,6 @@ void RenderableGlobe::update(const UpdateData& data) {
|
||||
|
||||
_globalRenderer.program->setUniform("xSegments", _grid.xSegments);
|
||||
|
||||
if (_debugProperties.showHeightResolution) {
|
||||
_globalRenderer.program->setUniform(
|
||||
"vertexResolution",
|
||||
glm::vec2(_grid.xSegments, _grid.ySegments)
|
||||
);
|
||||
}
|
||||
// Ellipsoid Radius (Model Space)
|
||||
_globalRenderer.program->setUniform(
|
||||
"radiiSquared",
|
||||
@@ -1220,48 +1189,32 @@ void RenderableGlobe::renderChunks(const RenderData& data, RendererTasks&,
|
||||
}
|
||||
_localRenderer.program->deactivate();
|
||||
|
||||
if (_debugProperties.showChunkBounds) {
|
||||
for (int i = 0; i < globalCount; ++i) {
|
||||
debugRenderChunk(
|
||||
*_globalChunkBuffer[i],
|
||||
mvp,
|
||||
_debugProperties.showChunkBounds
|
||||
);
|
||||
if (global::sessionRecording->isSavingFramesDuringPlayback()) {
|
||||
// If our tile cache is very full, we assume we need to adjust the level of detail
|
||||
// dynamically to not keep rendering frames with unavailable data
|
||||
// After certain number of iterations(_debugProperties.dynamicLodIterationCount) of
|
||||
// unavailable/available data in a row, we assume that a change could be made.
|
||||
const int iterCount = _debugProperties.dynamicLodIterationCount;
|
||||
const bool exceededIterations =
|
||||
static_cast<int>(_iterationsOfUnavailableData) > iterCount;
|
||||
const float clf = _generalProperties.currentLodScaleFactor;
|
||||
const float clfMin = _generalProperties.currentLodScaleFactor.minValue();
|
||||
const float targetLod = _generalProperties.targetLodScaleFactor;
|
||||
const bool validLodFactor = clf > clfMin;
|
||||
if (exceededIterations && validLodFactor) {
|
||||
_generalProperties.currentLodScaleFactor =
|
||||
_generalProperties.currentLodScaleFactor - 0.1f;
|
||||
_iterationsOfUnavailableData = 0;
|
||||
_lodScaleFactorDirty = true;
|
||||
} // Make 2 times the iterations with available data to move it up again
|
||||
else if (static_cast<int>(_iterationsOfAvailableData) >
|
||||
(iterCount * 2) && clf < targetLod)
|
||||
{
|
||||
_generalProperties.currentLodScaleFactor =
|
||||
_generalProperties.currentLodScaleFactor + 0.1f;
|
||||
_iterationsOfAvailableData = 0;
|
||||
_lodScaleFactorDirty = true;
|
||||
}
|
||||
|
||||
for (int i = 0; i < localCount; ++i) {
|
||||
debugRenderChunk(
|
||||
*_localChunkBuffer[i],
|
||||
mvp,
|
||||
_debugProperties.showChunkBounds
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// If our tile cache is very full, we assume we need to adjust the level of detail
|
||||
// dynamically to not keep rendering frames with unavailable data
|
||||
// After certain number of iterations(_debugProperties.dynamicLodIterationCount) of
|
||||
// unavailable/available data in a row, we assume that a change could be made.
|
||||
const int iterCount = _debugProperties.dynamicLodIterationCount;
|
||||
const bool exceededIterations =
|
||||
static_cast<int>(_iterationsOfUnavailableData) > iterCount;
|
||||
const float clf = _generalProperties.currentLodScaleFactor;
|
||||
const float clfMin = _generalProperties.currentLodScaleFactor.minValue();
|
||||
const float targetLod = _generalProperties.targetLodScaleFactor;
|
||||
const bool validLodFactor = clf > clfMin;
|
||||
if (exceededIterations && validLodFactor) {
|
||||
_generalProperties.currentLodScaleFactor =
|
||||
_generalProperties.currentLodScaleFactor - 0.1f;
|
||||
_iterationsOfUnavailableData = 0;
|
||||
_lodScaleFactorDirty = true;
|
||||
} // Make 2 times the iterations with available data to move it up again
|
||||
else if (static_cast<int>(_iterationsOfAvailableData) >
|
||||
(iterCount * 2) && clf < targetLod)
|
||||
{
|
||||
_generalProperties.currentLodScaleFactor =
|
||||
_generalProperties.currentLodScaleFactor + 0.1f;
|
||||
_iterationsOfAvailableData = 0;
|
||||
_lodScaleFactorDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1658,12 +1611,8 @@ void RenderableGlobe::recompileShaders() {
|
||||
std::to_string(_generalProperties.shadowMapping)
|
||||
);
|
||||
pairs.emplace_back("showChunkEdges", std::to_string(_debugProperties.showChunkEdges));
|
||||
pairs.emplace_back("showHeightResolution",
|
||||
std::to_string(_debugProperties.showHeightResolution)
|
||||
);
|
||||
pairs.emplace_back("showHeightIntensities",
|
||||
std::to_string(_debugProperties.showHeightIntensities)
|
||||
);
|
||||
pairs.emplace_back("showHeightResolution", "0");
|
||||
pairs.emplace_back("showHeightIntensities", "0");
|
||||
pairs.emplace_back("defaultHeight", std::to_string(DefaultHeight));
|
||||
|
||||
|
||||
@@ -1771,13 +1720,6 @@ void RenderableGlobe::recompileShaders() {
|
||||
|
||||
_localRenderer.program->setUniform("xSegments", _grid.xSegments);
|
||||
|
||||
if (_debugProperties.showHeightResolution) {
|
||||
_localRenderer.program->setUniform(
|
||||
"vertexResolution",
|
||||
glm::vec2(_grid.xSegments, _grid.ySegments)
|
||||
);
|
||||
}
|
||||
|
||||
ghoul::opengl::updateUniformLocations(
|
||||
*_localRenderer.program,
|
||||
_localRenderer.uniformCache,
|
||||
@@ -1799,12 +1741,6 @@ void RenderableGlobe::recompileShaders() {
|
||||
|
||||
_globalRenderer.program->setUniform("xSegments", _grid.xSegments);
|
||||
|
||||
if (_debugProperties.showHeightResolution) {
|
||||
_globalRenderer.program->setUniform(
|
||||
"vertexResolution",
|
||||
glm::vec2(_grid.xSegments, _grid.ySegments)
|
||||
);
|
||||
}
|
||||
// Ellipsoid Radius (Model Space)
|
||||
_globalRenderer.program->setUniform(
|
||||
"radiiSquared",
|
||||
|
||||
@@ -123,9 +123,6 @@ private:
|
||||
|
||||
struct {
|
||||
properties::BoolProperty showChunkEdges;
|
||||
properties::BoolProperty showChunkBounds;
|
||||
properties::BoolProperty showHeightResolution;
|
||||
properties::BoolProperty showHeightIntensities;
|
||||
properties::BoolProperty levelByProjectedAreaElseDistance;
|
||||
properties::BoolProperty resetTileProviders;
|
||||
properties::IntProperty modelSpaceRenderingCutoffLevel;
|
||||
@@ -142,7 +139,6 @@ private:
|
||||
properties::IntProperty nShadowSamples;
|
||||
properties::FloatProperty targetLodScaleFactor;
|
||||
properties::FloatProperty currentLodScaleFactor;
|
||||
properties::FloatProperty cameraMinHeight;
|
||||
properties::FloatProperty orenNayarRoughness;
|
||||
properties::IntProperty nActiveLayers;
|
||||
} _generalProperties;
|
||||
|
||||
@@ -148,6 +148,21 @@ namespace temporal {
|
||||
"This is the path to the XML configuration file that describes the temporal tile "
|
||||
"information."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo UseFixedTimeInfo = {
|
||||
"UseFixedTime",
|
||||
"Use Fixed Time",
|
||||
"If this value is enabled, the time-varying timevarying dataset will always use "
|
||||
"the time that is specified in the 'FixedTime' property, rather than using the "
|
||||
"actual time from OpenSpace"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo FixedTimeInfo = {
|
||||
"FixedTime",
|
||||
"Fixed Time",
|
||||
"If the 'UseFixedTime' is enabled, this time will be used instead of the actual "
|
||||
"time taken from OpenSpace for the displayed tiles."
|
||||
};
|
||||
} // namespace temporal
|
||||
|
||||
|
||||
@@ -375,18 +390,29 @@ TileProvider* getTileProvider(TemporalTileProvider& t, std::string_view timekey)
|
||||
TileProvider* getTileProvider(TemporalTileProvider& t, const Time& time) {
|
||||
ZoneScoped
|
||||
|
||||
Time tCopy(time);
|
||||
if (t.timeQuantizer.quantize(tCopy, true)) {
|
||||
char Buffer[22];
|
||||
const int size = timeStringify(t.timeFormat, tCopy, Buffer);
|
||||
if (t.useFixedTime && !t.fixedTime.value().empty()) {
|
||||
try {
|
||||
return getTileProvider(t, std::string_view(Buffer, size));
|
||||
return getTileProvider(t, t.fixedTime.value());
|
||||
}
|
||||
catch (const ghoul::RuntimeError& e) {
|
||||
LERRORC("TemporalTileProvider", e.message);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Time tCopy(time);
|
||||
if (t.timeQuantizer.quantize(tCopy, true)) {
|
||||
char Buffer[22];
|
||||
const int size = timeStringify(t.timeFormat, tCopy, Buffer);
|
||||
try {
|
||||
return getTileProvider(t, std::string_view(Buffer, size));
|
||||
}
|
||||
catch (const ghoul::RuntimeError& e) {
|
||||
LERRORC("TemporalTileProvider", e.message);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -831,6 +857,8 @@ TileProviderByLevel::TileProviderByLevel(const ghoul::Dictionary& dictionary) {
|
||||
TemporalTileProvider::TemporalTileProvider(const ghoul::Dictionary& dictionary)
|
||||
: initDict(dictionary)
|
||||
, filePath(temporal::FilePathInfo)
|
||||
, useFixedTime(temporal::UseFixedTimeInfo, false)
|
||||
, fixedTime(temporal::FixedTimeInfo)
|
||||
{
|
||||
ZoneScoped
|
||||
|
||||
@@ -839,6 +867,16 @@ TemporalTileProvider::TemporalTileProvider(const ghoul::Dictionary& dictionary)
|
||||
filePath = dictionary.value<std::string>(KeyFilePath);
|
||||
addProperty(filePath);
|
||||
|
||||
if (dictionary.hasValue<bool>(temporal::UseFixedTimeInfo.identifier)) {
|
||||
useFixedTime = dictionary.value<bool>(temporal::UseFixedTimeInfo.identifier);
|
||||
}
|
||||
addProperty(useFixedTime);
|
||||
|
||||
if (dictionary.hasValue<std::string>(temporal::FixedTimeInfo.identifier)) {
|
||||
fixedTime = dictionary.value<std::string>(temporal::FixedTimeInfo.identifier);
|
||||
}
|
||||
addProperty(fixedTime);
|
||||
|
||||
successfulInitialization = readFilePath(*this);
|
||||
|
||||
if (!successfulInitialization) {
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <modules/globebrowsing/src/tiletextureinitdata.h>
|
||||
#include <modules/globebrowsing/src/timequantizer.h>
|
||||
#include <openspace/properties/stringproperty.h>
|
||||
#include <openspace/properties/scalar/boolproperty.h>
|
||||
#include <openspace/properties/scalar/intproperty.h>
|
||||
#include <unordered_map>
|
||||
|
||||
@@ -174,6 +175,8 @@ struct TemporalTileProvider : public TileProvider {
|
||||
|
||||
ghoul::Dictionary initDict;
|
||||
properties::StringProperty filePath;
|
||||
properties::BoolProperty useFixedTime;
|
||||
properties::StringProperty fixedTime;
|
||||
std::string gdalXmlTemplate;
|
||||
|
||||
std::unordered_map<TimeKey, std::unique_ptr<TileProvider>> tileProviderMap;
|
||||
|
||||
@@ -29,30 +29,39 @@
|
||||
#include <openspace/documentation/verifier.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/misc/dictionaryjsonformatter.h>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
|
||||
namespace {
|
||||
constexpr const char* KeyInput = "Input";
|
||||
constexpr const char* KeyOutput = "Output";
|
||||
constexpr const char* MainTemplateFilename = "${WEB}/kameleondocumentation/main.hbs";
|
||||
constexpr const char* HandlebarsFilename = "${WEB}/common/handlebars-v4.0.5.js";
|
||||
constexpr const char* JsFilename = "${WEB}/kameleondocumentation/script.js";
|
||||
constexpr const char* BootstrapFilename = "${WEB}/common/bootstrap.min.css";
|
||||
constexpr const char* CssFilename = "${WEB}/common/style.css";
|
||||
|
||||
struct [[codegen::Dictionary(KameleonDocumentationTask)]] Parameters {
|
||||
// The CDF file to extract data from
|
||||
std::filesystem::path input;
|
||||
|
||||
// The HTML file to write documentation to
|
||||
std::string output [[codegen::annotation("A valid filepath")]];
|
||||
};
|
||||
#include "kameleondocumentationtask_codegen.cpp"
|
||||
} // namespace
|
||||
|
||||
namespace openspace::kameleonvolume {
|
||||
|
||||
documentation::Documentation KameleonDocumentationTask::documentation() {
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "kameleon_documentation_task";
|
||||
return doc;
|
||||
}
|
||||
|
||||
KameleonDocumentationTask::KameleonDocumentationTask(const ghoul::Dictionary& dictionary)
|
||||
{
|
||||
openspace::documentation::testSpecificationAndThrow(
|
||||
documentation(),
|
||||
dictionary,
|
||||
"KameleonDocumentationTask"
|
||||
);
|
||||
|
||||
_inputPath = absPath(dictionary.value<std::string>(KeyInput));
|
||||
_outputPath = absPath(dictionary.value<std::string>(KeyOutput));
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
_inputPath = absPath(p.input.string());
|
||||
_outputPath = absPath(p.output);
|
||||
}
|
||||
|
||||
std::string KameleonDocumentationTask::description() {
|
||||
@@ -146,26 +155,4 @@ void KameleonDocumentationTask::perform(const Task::ProgressCallback & progressC
|
||||
progressCallback(1.0f);
|
||||
}
|
||||
|
||||
documentation::Documentation KameleonDocumentationTask::documentation() {
|
||||
using namespace documentation;
|
||||
return {
|
||||
"KameleonDocumentationTask",
|
||||
"kameleon_documentation_task",
|
||||
{
|
||||
{
|
||||
KeyInput,
|
||||
new StringAnnotationVerifier("A file path to a cdf file"),
|
||||
Optional::No,
|
||||
"The cdf file to extract data from"
|
||||
},
|
||||
{
|
||||
KeyOutput,
|
||||
new StringAnnotationVerifier("A valid filepath"),
|
||||
Optional::No,
|
||||
"The html file to write documentation to"
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace openspace::kameleonvolume
|
||||
|
||||
@@ -29,26 +29,34 @@
|
||||
#include <ghoul/fmt.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/misc/dictionaryjsonformatter.h>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
|
||||
namespace {
|
||||
constexpr const char* KeyInput = "Input";
|
||||
constexpr const char* KeyOutput = "Output";
|
||||
struct [[codegen::Dictionary(KameleonMetadataToJsonTask)]] Parameters {
|
||||
// The CDF file to extract data from
|
||||
std::filesystem::path input;
|
||||
|
||||
// The JSON file to export data into
|
||||
std::string output [[codegen::annotation("A valid filepath")]];
|
||||
};
|
||||
#include "kameleonmetadatatojsontask_codegen.cpp"
|
||||
} // namespace
|
||||
|
||||
namespace openspace::kameleonvolume {
|
||||
|
||||
documentation::Documentation KameleonMetadataToJsonTask::documentation() {
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "kameleon_metadata_to_json_task";
|
||||
return doc;
|
||||
}
|
||||
|
||||
KameleonMetadataToJsonTask::KameleonMetadataToJsonTask(
|
||||
const ghoul::Dictionary& dictionary)
|
||||
{
|
||||
openspace::documentation::testSpecificationAndThrow(
|
||||
documentation(),
|
||||
dictionary,
|
||||
"KameleonMetadataToJsonTask"
|
||||
);
|
||||
|
||||
_inputPath = absPath(dictionary.value<std::string>(KeyInput));
|
||||
_outputPath = absPath(dictionary.value<std::string>(KeyOutput));
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
_inputPath = absPath(p.input.string());
|
||||
_outputPath = absPath(p.output);
|
||||
}
|
||||
|
||||
std::string KameleonMetadataToJsonTask::description() {
|
||||
@@ -69,26 +77,4 @@ void KameleonMetadataToJsonTask::perform(const Task::ProgressCallback& progressC
|
||||
progressCallback(1.0f);
|
||||
}
|
||||
|
||||
documentation::Documentation KameleonMetadataToJsonTask::documentation() {
|
||||
using namespace documentation;
|
||||
return {
|
||||
"KameleonMetadataToJsonTask",
|
||||
"kameleon_metadata_to_json_task",
|
||||
{
|
||||
{
|
||||
KeyInput,
|
||||
new StringAnnotationVerifier("A file path to a cdf file"),
|
||||
Optional::No,
|
||||
"The cdf file to extract data from"
|
||||
},
|
||||
{
|
||||
KeyOutput,
|
||||
new StringAnnotationVerifier("A valid filepath"),
|
||||
Optional::No,
|
||||
"The JSON file to export data into"
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace openspace::kameleonvolume
|
||||
|
||||
@@ -31,13 +31,11 @@
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/misc/dictionaryluaformatter.h>
|
||||
#include <array>
|
||||
#include <filesystem>
|
||||
#include <optional>
|
||||
|
||||
namespace {
|
||||
constexpr const char* KeyInput = "Input";
|
||||
constexpr const char* KeyRawVolumeOutput = "RawVolumeOutput";
|
||||
constexpr const char* KeyDictionaryOutput = "DictionaryOutput";
|
||||
constexpr const char* KeyDimensions = "Dimensions";
|
||||
constexpr const char* KeyVariable = "Variable";
|
||||
constexpr const char* KeyTime = "Time";
|
||||
constexpr const char* KeyLowerDomainBound = "LowerDomainBound";
|
||||
constexpr const char* KeyUpperDomainBound = "UpperDomainBound";
|
||||
@@ -46,92 +44,64 @@ namespace {
|
||||
constexpr const char* KeyMaxValue = "MaxValue";
|
||||
|
||||
constexpr const char* KeyVisUnit = "VisUnit";
|
||||
|
||||
struct [[codegen::Dictionary(KameleonVolumeToRawTask)]] Parameters {
|
||||
// The cdf file to extract data from
|
||||
std::filesystem::path input;
|
||||
|
||||
// The raw volume file to export data to
|
||||
std::string rawVolumeOutput [[codegen::annotation("A valid filepath")]];
|
||||
|
||||
// The Lua dictionary file to export metadata to
|
||||
std::string dictionaryOutput [[codegen::annotation("A valid filepath")]];
|
||||
|
||||
// The variable name to read from the kameleon dataset
|
||||
std::string variable [[codegen::annotation("A valid kameleon variable")]];
|
||||
|
||||
// A vector representing the number of cells in each dimension
|
||||
glm::ivec3 dimensions;
|
||||
|
||||
// A vector representing the lower bound of the domain, in the native kameleon
|
||||
// grid units
|
||||
std::optional<glm::vec3> lowerDomainBound;
|
||||
|
||||
// A vector representing the lower bound of the domain, in the native kameleon
|
||||
// grid units
|
||||
std::optional<glm::vec3> upperDomainBound;
|
||||
|
||||
// The unit of the data
|
||||
std::optional<std::string> visUnit
|
||||
[[codegen::annotation("A valid kameleon unit")]];
|
||||
};
|
||||
#include "kameleonvolumetorawtask_codegen.cpp"
|
||||
} // namespace
|
||||
|
||||
namespace openspace::kameleonvolume {
|
||||
|
||||
documentation::Documentation KameleonVolumeToRawTask::documentation() {
|
||||
using namespace documentation;
|
||||
return {
|
||||
"KameleonVolumeToRawTask",
|
||||
"kameleon_metadata_to_json_task",
|
||||
{
|
||||
{
|
||||
KeyInput,
|
||||
new StringAnnotationVerifier("A file path to a cdf file"),
|
||||
Optional::No,
|
||||
"The cdf file to extract data from",
|
||||
},
|
||||
{
|
||||
KeyRawVolumeOutput,
|
||||
new StringAnnotationVerifier("A valid filepath"),
|
||||
Optional::No,
|
||||
"The raw volume file to export data to",
|
||||
},
|
||||
{
|
||||
KeyDictionaryOutput,
|
||||
new StringAnnotationVerifier("A valid filepath"),
|
||||
Optional::No,
|
||||
"The lua dictionary file to export metadata to",
|
||||
},
|
||||
{
|
||||
KeyVariable,
|
||||
new StringAnnotationVerifier("A valid kameleon variable"),
|
||||
Optional::No,
|
||||
"The variable name to read from the kameleon dataset",
|
||||
},
|
||||
{
|
||||
KeyDimensions,
|
||||
new DoubleVector3Verifier,
|
||||
Optional::No,
|
||||
"A vector representing the number of cells in each dimension",
|
||||
},
|
||||
{
|
||||
KeyLowerDomainBound,
|
||||
new DoubleVector3Verifier,
|
||||
Optional::Yes,
|
||||
"A vector representing the lower bound of the domain, "
|
||||
"in the native kameleon grid units",
|
||||
},
|
||||
{
|
||||
KeyUpperDomainBound,
|
||||
new DoubleVector3Verifier,
|
||||
Optional::Yes,
|
||||
"A vector representing the lower bound of the domain, "
|
||||
"in the native kameleon grid units"
|
||||
},
|
||||
{
|
||||
KeyVisUnit,
|
||||
new StringAnnotationVerifier("A valid kameleon unit"),
|
||||
Optional::Yes,
|
||||
"The unit of the data",
|
||||
}
|
||||
}
|
||||
};
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "kameleon_metadata_to_json_task";
|
||||
return doc;
|
||||
}
|
||||
|
||||
|
||||
KameleonVolumeToRawTask::KameleonVolumeToRawTask(const ghoul::Dictionary& dictionary) {
|
||||
openspace::documentation::testSpecificationAndThrow(
|
||||
documentation(),
|
||||
dictionary,
|
||||
"KameleonVolumeToRawTask"
|
||||
);
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
_inputPath = absPath(dictionary.value<std::string>(KeyInput));
|
||||
_rawVolumeOutputPath = absPath(dictionary.value<std::string>(KeyRawVolumeOutput));
|
||||
_dictionaryOutputPath = absPath(dictionary.value<std::string>(KeyDictionaryOutput));
|
||||
_variable = dictionary.value<std::string>(KeyVariable);
|
||||
_dimensions = glm::uvec3(dictionary.value<glm::dvec3>(KeyDimensions));
|
||||
_inputPath = absPath(p.input.string());
|
||||
_rawVolumeOutputPath = absPath(p.rawVolumeOutput);
|
||||
_dictionaryOutputPath = absPath(p.dictionaryOutput);
|
||||
_variable = p.variable;
|
||||
_dimensions = p.dimensions;
|
||||
|
||||
if (dictionary.hasKey(KeyLowerDomainBound)) {
|
||||
_lowerDomainBound = dictionary.value<glm::dvec3>(KeyLowerDomainBound);
|
||||
if (p.lowerDomainBound.has_value()) {
|
||||
_lowerDomainBound = *p.lowerDomainBound;
|
||||
}
|
||||
else {
|
||||
_autoDomainBounds = true;
|
||||
}
|
||||
if (dictionary.hasKey(KeyUpperDomainBound)) {
|
||||
_upperDomainBound = dictionary.value<glm::dvec3>(KeyUpperDomainBound);
|
||||
|
||||
if (p.upperDomainBound.has_value()) {
|
||||
_upperDomainBound = *p.upperDomainBound;
|
||||
}
|
||||
else {
|
||||
_autoDomainBounds = true;
|
||||
|
||||
@@ -29,12 +29,11 @@
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/documentation/verifier.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <optional>
|
||||
|
||||
namespace {
|
||||
constexpr const char* LoggerCat = "ScreenSpaceSpout";
|
||||
|
||||
constexpr const char* KeyName = "Name";
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo NameInfo = {
|
||||
"SpoutName",
|
||||
"Spout Sender Name",
|
||||
@@ -56,30 +55,20 @@ namespace {
|
||||
"If this property is trigged, the 'SpoutSelection' options will be refreshed."
|
||||
};
|
||||
|
||||
struct [[codegen::Dictionary(RenderablePlaneSpout)]] Parameters {
|
||||
// [[codegen::verbatim(NameInfo.description)]]
|
||||
std::optional<std::string> spoutName;
|
||||
};
|
||||
#include "renderableplanespout_codegen.cpp"
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation RenderablePlaneSpout::Documentation() {
|
||||
using namespace openspace::documentation;
|
||||
return {
|
||||
"ScreenSpace Spout",
|
||||
"spout_screenspace_spout",
|
||||
{
|
||||
{
|
||||
KeyName,
|
||||
new StringVerifier,
|
||||
Optional::Yes,
|
||||
"Specifies the GUI name of the ScreenspaceSpout"
|
||||
},
|
||||
{
|
||||
NameInfo.identifier,
|
||||
new StringVerifier,
|
||||
Optional::Yes,
|
||||
NameInfo.description
|
||||
}
|
||||
}
|
||||
};
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "spout_screenspace_spout";
|
||||
return doc;
|
||||
}
|
||||
|
||||
RenderablePlaneSpout::RenderablePlaneSpout(const ghoul::Dictionary& dictionary)
|
||||
@@ -89,11 +78,7 @@ RenderablePlaneSpout::RenderablePlaneSpout(const ghoul::Dictionary& dictionary)
|
||||
, _updateSelection(UpdateInfo)
|
||||
, _receiver(GetSpout())
|
||||
{
|
||||
documentation::testSpecificationAndThrow(
|
||||
Documentation(),
|
||||
dictionary,
|
||||
"RenderablePlaneSpout"
|
||||
);
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
int iIdentifier = 0;
|
||||
if (_identifier.empty()) {
|
||||
@@ -114,10 +99,7 @@ RenderablePlaneSpout::RenderablePlaneSpout(const ghoul::Dictionary& dictionary)
|
||||
setGuiName("RenderablePlaneSpout " + std::to_string(iIdentifier));
|
||||
}
|
||||
|
||||
if (dictionary.hasKey(NameInfo.identifier)) {
|
||||
_spoutName = dictionary.value<std::string>(NameInfo.identifier);
|
||||
}
|
||||
|
||||
_spoutName = p.spoutName.value_or(_spoutName);
|
||||
_spoutName.onChange([this]() {
|
||||
_isSpoutDirty = true;
|
||||
_isErrorMessageDisplayed = false;
|
||||
|
||||
@@ -29,10 +29,9 @@
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/documentation/verifier.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <optional>
|
||||
|
||||
namespace {
|
||||
constexpr const char* KeyName = "Name";
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo NameInfo = {
|
||||
"SpoutName",
|
||||
"Spout Sender Name",
|
||||
@@ -54,30 +53,20 @@ namespace {
|
||||
"If this property is trigged, the 'SpoutSelection' options will be refreshed."
|
||||
};
|
||||
|
||||
struct [[codegen::Dictionary(ScreenSpaceSpout)]] Parameters {
|
||||
// [[codegen::verbatim(NameInfo.description)]]
|
||||
std::optional<std::string> spoutName;
|
||||
};
|
||||
#include "screenspacespout_codegen.cpp"
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation ScreenSpaceSpout::Documentation() {
|
||||
using namespace openspace::documentation;
|
||||
return {
|
||||
"ScreenSpace Spout",
|
||||
"spout_screenspace_spout",
|
||||
{
|
||||
{
|
||||
KeyName,
|
||||
new StringVerifier,
|
||||
Optional::Yes,
|
||||
"Specifies the GUI name of the ScreenspaceSpout"
|
||||
},
|
||||
{
|
||||
NameInfo.identifier,
|
||||
new StringVerifier,
|
||||
Optional::Yes,
|
||||
NameInfo.description
|
||||
}
|
||||
}
|
||||
};
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "spout_screenspace_spout";
|
||||
return doc;
|
||||
}
|
||||
|
||||
ScreenSpaceSpout::ScreenSpaceSpout(const ghoul::Dictionary& dictionary)
|
||||
@@ -87,11 +76,7 @@ ScreenSpaceSpout::ScreenSpaceSpout(const ghoul::Dictionary& dictionary)
|
||||
, _updateSelection(UpdateInfo)
|
||||
, _receiver(GetSpout())
|
||||
{
|
||||
documentation::testSpecificationAndThrow(
|
||||
Documentation(),
|
||||
dictionary,
|
||||
"ScreenSpaceSpout"
|
||||
);
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
std::string identifier;
|
||||
if (dictionary.hasValue<std::string>(KeyIdentifier)) {
|
||||
@@ -103,10 +88,7 @@ ScreenSpaceSpout::ScreenSpaceSpout(const ghoul::Dictionary& dictionary)
|
||||
identifier = makeUniqueIdentifier(identifier);
|
||||
setIdentifier(std::move(identifier));
|
||||
|
||||
if (dictionary.hasKey(NameInfo.identifier)) {
|
||||
_spoutName = dictionary.value<std::string>(NameInfo.identifier);
|
||||
}
|
||||
|
||||
_spoutName = p.spoutName.value_or(_spoutName);
|
||||
_spoutName.onChange([this]() {
|
||||
_isSpoutDirty = true;
|
||||
_isErrorMessageDisplayed = false;
|
||||
|
||||
@@ -37,43 +37,34 @@
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/lua/luastate.h>
|
||||
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <chrono>
|
||||
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
|
||||
namespace {
|
||||
constexpr const char* KeyAsset = "Asset";
|
||||
constexpr std::chrono::milliseconds ProgressPollInterval(200);
|
||||
|
||||
struct [[codegen::Dictionary(SyncAssetTask)]] Parameters {
|
||||
// The asset file to sync
|
||||
std::filesystem::path asset;
|
||||
};
|
||||
#include "syncassettask_codegen.cpp"
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation SyncAssetTask::documentation() {
|
||||
using namespace documentation;
|
||||
return {
|
||||
"SyncAssetTask",
|
||||
"sync_asset_task",
|
||||
{
|
||||
{
|
||||
KeyAsset,
|
||||
new StringAnnotationVerifier("A file path to an asset"),
|
||||
Optional::No,
|
||||
"The asset file to sync"
|
||||
}
|
||||
}
|
||||
};
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "sync_asset_task";
|
||||
return doc;
|
||||
}
|
||||
|
||||
SyncAssetTask::SyncAssetTask(const ghoul::Dictionary& dictionary) {
|
||||
documentation::testSpecificationAndThrow(
|
||||
documentation(),
|
||||
dictionary,
|
||||
"SyncAssetTask"
|
||||
);
|
||||
|
||||
_asset = dictionary.value<std::string>(KeyAsset);
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
_asset = p.asset.string();
|
||||
}
|
||||
|
||||
std::string SyncAssetTask::description() {
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/opengl/texture.h>
|
||||
#include <optional>
|
||||
|
||||
namespace {
|
||||
constexpr const char* _loggerCat = "RenderableTimeVaryingVolume";
|
||||
@@ -54,11 +55,6 @@ namespace {
|
||||
const char* KeyStepSize = "StepSize";
|
||||
const char* KeyGridType = "GridType";
|
||||
const char* KeyTransferFunction = "TransferFunction";
|
||||
const char* KeySourceDirectory = "SourceDirectory";
|
||||
|
||||
const char* KeyClipPlanes = "ClipPlanes";
|
||||
const char* KeySecondsBefore = "SecondsBefore";
|
||||
const char* KeySecondsAfter = "SecondsAfter";
|
||||
|
||||
const float SecondsInOneDay = 60 * 60 * 24;
|
||||
constexpr const float VolumeMaxOpacity = 500;
|
||||
@@ -129,44 +125,33 @@ namespace {
|
||||
"Radius upper bound",
|
||||
"" // @TODO Missing documentation
|
||||
};
|
||||
|
||||
struct [[codegen::Dictionary(RenderableTimeVaryingVolume)]] Parameters {
|
||||
// Specifies the path to load timesteps from
|
||||
std::string sourceDirectory;
|
||||
|
||||
// Specifies the transfer function file path
|
||||
std::string transferFunction;
|
||||
|
||||
// Specifies the number of seconds to show the the first timestep before its
|
||||
// actual time. The default value is 0
|
||||
std::optional<float> secondsBefore;
|
||||
|
||||
// Specifies the number of seconds to show the the last timestep after its
|
||||
// actual time
|
||||
float secondsAfter;
|
||||
|
||||
std::optional<ghoul::Dictionary> clipPlanes;
|
||||
};
|
||||
#include "renderabletimevaryingvolume_codegen.cpp"
|
||||
} // namespace
|
||||
|
||||
namespace openspace::volume {
|
||||
|
||||
documentation::Documentation RenderableTimeVaryingVolume::Documentation() {
|
||||
using namespace documentation;
|
||||
return {
|
||||
"RenderableTimevaryingVolume",
|
||||
"volume_renderable_timevaryingvolume",
|
||||
{
|
||||
{
|
||||
KeySourceDirectory,
|
||||
new StringVerifier,
|
||||
Optional::No,
|
||||
"Specifies the path to load timesteps from"
|
||||
},
|
||||
{
|
||||
KeyTransferFunction,
|
||||
new StringVerifier,
|
||||
Optional::No,
|
||||
"Specifies the transfer function file path"
|
||||
},
|
||||
{
|
||||
KeySecondsBefore,
|
||||
new DoubleVerifier,
|
||||
Optional::Yes,
|
||||
"Specifies the number of seconds to show the the first timestep before "
|
||||
"its actual time. The default value is 0."
|
||||
},
|
||||
{
|
||||
KeySecondsAfter,
|
||||
new DoubleVerifier,
|
||||
Optional::No,
|
||||
"Specifies the number of seconds to show the the last timestep after its "
|
||||
"actual time"
|
||||
}
|
||||
}
|
||||
};
|
||||
documentation::Documentation RenderableTimeVaryingVolume::Documentation() {
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "volume_renderable_timevaryingvolume";
|
||||
return doc;
|
||||
}
|
||||
|
||||
RenderableTimeVaryingVolume::RenderableTimeVaryingVolume(
|
||||
@@ -184,14 +169,10 @@ RenderableTimeVaryingVolume::RenderableTimeVaryingVolume(
|
||||
, _jumpToTimestep(JumpToTimestepInfo, 0, 0, 256)
|
||||
, _currentTimestep(CurrentTimeStepInfo, 0, 0, 256)
|
||||
{
|
||||
documentation::testSpecificationAndThrow(
|
||||
Documentation(),
|
||||
dictionary,
|
||||
"RenderableTimeVaryingVolume"
|
||||
);
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
_sourceDirectory = absPath(dictionary.value<std::string>(KeySourceDirectory));
|
||||
_transferFunctionPath = absPath(dictionary.value<std::string>(KeyTransferFunction));
|
||||
_sourceDirectory = absPath(p.sourceDirectory);
|
||||
_transferFunctionPath = absPath(p.transferFunction);
|
||||
_transferFunction = std::make_shared<openspace::TransferFunction>(
|
||||
_transferFunctionPath,
|
||||
[](const openspace::TransferFunction&) {}
|
||||
@@ -207,15 +188,10 @@ RenderableTimeVaryingVolume::RenderableTimeVaryingVolume(
|
||||
_stepSize = static_cast<float>(dictionary.value<double>(KeyStepSize));
|
||||
}
|
||||
|
||||
if (dictionary.hasValue<double>(KeySecondsBefore)) {
|
||||
_secondsBefore = static_cast<float>(dictionary.value<double>(KeySecondsBefore));
|
||||
}
|
||||
_secondsAfter = static_cast<float>(dictionary.value<double>(KeySecondsAfter));
|
||||
_secondsBefore = p.secondsBefore.value_or(_secondsBefore);
|
||||
_secondsAfter = p.secondsAfter;
|
||||
|
||||
ghoul::Dictionary clipPlanesDictionary;
|
||||
if (dictionary.hasValue<ghoul::Dictionary>(KeyClipPlanes)) {
|
||||
clipPlanesDictionary.value<ghoul::Dictionary>(KeyClipPlanes);
|
||||
}
|
||||
ghoul::Dictionary clipPlanesDictionary = p.clipPlanes.value_or(ghoul::Dictionary());
|
||||
_clipPlanes = std::make_shared<volume::VolumeClipPlanes>(clipPlanesDictionary);
|
||||
_clipPlanes->setIdentifier("clipPlanes");
|
||||
_clipPlanes->setGuiName("Clip Planes");
|
||||
|
||||
@@ -234,6 +234,8 @@ OpenGLDebugContext = {
|
||||
{ Type = "Other", Source = "API", Identifier = 131185 },
|
||||
-- API_ID_RECOMPILE_FRAGMENT_SHADER performance warning has been generated. Fragment shader recompiled due to state change
|
||||
{ Type = "Performance", Source = "API", Identifier = 2 },
|
||||
-- Pixel-path performance warning: Pixel transfer is synchronized with 3D rendering
|
||||
{ Type = "Performance", Source = "API", Identifier = 131154 },
|
||||
-- Buffer performance warning: "copied/moved from VIDEO memory to HOST memory"
|
||||
{ Type = "Performance", Source = "API", Identifier = 131186 },
|
||||
-- API_ID_LINE_WIDTH deprecated behavior warning has been generated
|
||||
|
||||
@@ -42,8 +42,8 @@
|
||||
#include <variant>
|
||||
|
||||
namespace {
|
||||
constexpr const std::array<const char*, 4> UniformNames = {
|
||||
"Alpha", "ModelTransform", "ViewProjectionMatrix", "texture1"
|
||||
constexpr const std::array<const char*, 5> UniformNames = {
|
||||
"MultiplyColor", "Alpha", "ModelTransform", "ViewProjectionMatrix", "texture1"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo EnabledInfo = {
|
||||
@@ -100,6 +100,12 @@ namespace {
|
||||
"An euler rotation (x, y, z) to apply to the plane."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo MultiplyColorInfo = {
|
||||
"MultiplyColor",
|
||||
"Multiply Color",
|
||||
"If set, the plane's texture is multiplied with this color. "
|
||||
"Useful for applying a color grayscale images."
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo OpacityInfo = {
|
||||
"Opacity",
|
||||
@@ -245,6 +251,9 @@ namespace {
|
||||
// [[codegen::verbatim(UsePerspectiveProjectionInfo.description)]]
|
||||
std::optional<bool> usePerspectiveProjection;
|
||||
|
||||
// [[codegen::verbatim(MultiplyColorInfo.description)]]
|
||||
std::optional<glm::vec3> multiplyColor [[codegen::color()]];
|
||||
|
||||
// [codegen::verbatim(OpacityInfo.description)]]
|
||||
std::optional<float> opacity [[codegen::inrange(0.f, 1.f)]];
|
||||
|
||||
@@ -324,6 +333,7 @@ ScreenSpaceRenderable::ScreenSpaceRenderable(const ghoul::Dictionary& dictionary
|
||||
glm::vec3(glm::pi<float>())
|
||||
)
|
||||
, _scale(ScaleInfo, 0.25f, 0.f, 2.f)
|
||||
, _multiplyColor(MultiplyColorInfo, glm::vec3(1.f), glm::vec3(0.f), glm::vec3(1.f))
|
||||
, _opacity(OpacityInfo, 1.f, 0.f, 1.f)
|
||||
, _delete(DeleteInfo)
|
||||
{
|
||||
@@ -355,9 +365,14 @@ ScreenSpaceRenderable::ScreenSpaceRenderable(const ghoul::Dictionary& dictionary
|
||||
});
|
||||
|
||||
addProperty(_scale);
|
||||
addProperty(_multiplyColor);
|
||||
addProperty(_opacity);
|
||||
addProperty(_localRotation);
|
||||
|
||||
|
||||
_multiplyColor = p.multiplyColor.value_or(_multiplyColor);
|
||||
_multiplyColor.setViewOption(properties::Property::ViewOptions::Color);
|
||||
|
||||
_enabled = p.enabled.value_or(_enabled);
|
||||
_useRadiusAzimuthElevation =
|
||||
p.useRadiusAzimuthElevation.value_or(_useRadiusAzimuthElevation);
|
||||
@@ -554,6 +569,7 @@ void ScreenSpaceRenderable::draw(glm::mat4 modelTransform) {
|
||||
|
||||
_shader->activate();
|
||||
|
||||
_shader->setUniform(_uniformCache.color, _multiplyColor);
|
||||
_shader->setUniform(_uniformCache.alpha, _opacity);
|
||||
_shader->setUniform(_uniformCache.modelTransform, modelTransform);
|
||||
|
||||
@@ -576,8 +592,6 @@ void ScreenSpaceRenderable::draw(glm::mat4 modelTransform) {
|
||||
unbindTexture();
|
||||
}
|
||||
|
||||
void ScreenSpaceRenderable::unbindTexture() {
|
||||
}
|
||||
|
||||
void ScreenSpaceRenderable::unbindTexture() {}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -35,41 +35,31 @@
|
||||
#include <ghoul/misc/templatefactory.h>
|
||||
|
||||
namespace {
|
||||
constexpr const char* KeyType = "Type";
|
||||
struct [[codegen::Dictionary(Scale)]] Parameters {
|
||||
// The type of the scaling that is described in this element. The available types
|
||||
// of scaling depend on the configuration of the application and can be written to
|
||||
// disk on application startup into the FactoryDocumentation
|
||||
std::string type [[codegen::annotation("Must name a valid Scale type")]];
|
||||
};
|
||||
#include "scale_codegen.cpp"
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation Scale::Documentation() {
|
||||
using namespace openspace::documentation;
|
||||
|
||||
return {
|
||||
"Transformation Scaling",
|
||||
"core_transform_scaling",
|
||||
{
|
||||
{
|
||||
KeyType,
|
||||
new StringAnnotationVerifier("Must name a valid Scale type"),
|
||||
Optional::No,
|
||||
"The type of the scaling that is described in this element. "
|
||||
"The available types of scaling depend on the configuration "
|
||||
"of the application and can be written to disk on "
|
||||
"application startup into the FactoryDocumentation."
|
||||
}
|
||||
}
|
||||
};
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "core_transform_scaling";
|
||||
return doc;
|
||||
}
|
||||
|
||||
ghoul::mm_unique_ptr<Scale> Scale::createFromDictionary(
|
||||
const ghoul::Dictionary& dictionary)
|
||||
{
|
||||
documentation::testSpecificationAndThrow(Documentation(), dictionary, "Scale");
|
||||
|
||||
std::string scaleType = dictionary.value<std::string>(KeyType);
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
auto factory = FactoryManager::ref().factory<Scale>();
|
||||
Scale* result = factory->create(
|
||||
scaleType,
|
||||
p.type,
|
||||
dictionary,
|
||||
&global::memoryManager->PersistentMemory
|
||||
);
|
||||
|
||||
@@ -306,7 +306,6 @@ ghoul::mm_unique_ptr<SceneGraphNode> SceneGraphNode::createFromDictionary(
|
||||
LDEBUG(fmt::format(
|
||||
"Successfully created ephemeris for '{}'", result->identifier()
|
||||
));
|
||||
result->addPropertySubOwner(result->_transform.translation.get());
|
||||
}
|
||||
|
||||
if (p.transform->rotation.has_value()) {
|
||||
@@ -326,7 +325,6 @@ ghoul::mm_unique_ptr<SceneGraphNode> SceneGraphNode::createFromDictionary(
|
||||
LDEBUG(fmt::format(
|
||||
"Successfully created rotation for '{}'", result->identifier()
|
||||
));
|
||||
result->addPropertySubOwner(result->_transform.rotation.get());
|
||||
}
|
||||
|
||||
if (p.transform->scale.has_value()) {
|
||||
@@ -344,9 +342,12 @@ ghoul::mm_unique_ptr<SceneGraphNode> SceneGraphNode::createFromDictionary(
|
||||
LDEBUG(fmt::format(
|
||||
"Successfully created scale for '{}'", result->identifier()
|
||||
));
|
||||
result->addPropertySubOwner(result->_transform.scale.get());
|
||||
}
|
||||
}
|
||||
result->addPropertySubOwner(result->_transform.translation.get());
|
||||
result->addPropertySubOwner(result->_transform.rotation.get());
|
||||
result->addPropertySubOwner(result->_transform.scale.get());
|
||||
|
||||
|
||||
if (p.timeFrame.has_value()) {
|
||||
result->_timeFrame = TimeFrame::createFromDictionary(*p.timeFrame);
|
||||
|
||||
@@ -35,44 +35,30 @@
|
||||
#include <ghoul/misc/templatefactory.h>
|
||||
|
||||
namespace {
|
||||
constexpr const char* KeyType = "Type";
|
||||
struct [[codegen::Dictionary(TimeFrame)]] Parameters {
|
||||
// The type of the time frame that is described in this element. The available
|
||||
// types of scaling depend on the configuration of the application and can be
|
||||
// written to disk on application startup into the FactoryDocumentation
|
||||
std::string type [[codegen::annotation("Must name a valid TimeFrame type")]];
|
||||
};
|
||||
#include "timeframe_codegen.cpp"
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation TimeFrame::Documentation() {
|
||||
using namespace openspace::documentation;
|
||||
|
||||
return {
|
||||
"Time Frame",
|
||||
"core_time_frame",
|
||||
{
|
||||
{
|
||||
KeyType,
|
||||
new StringAnnotationVerifier("Must name a valid TimeFrame type"),
|
||||
Optional::No,
|
||||
"The type of the time frame that is described in this element. "
|
||||
"The available types of scaling depend on the configuration "
|
||||
"of the application and can be written to disk on "
|
||||
"application startup into the FactoryDocumentation."
|
||||
}
|
||||
}
|
||||
};
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "core_time_frame";
|
||||
return doc;
|
||||
}
|
||||
|
||||
ghoul::mm_unique_ptr<TimeFrame> TimeFrame::createFromDictionary(
|
||||
const ghoul::Dictionary& dictionary)
|
||||
{
|
||||
documentation::testSpecificationAndThrow(Documentation(), dictionary, "TimeFrame");
|
||||
|
||||
const std::string timeFrameType = dictionary.value<std::string>(KeyType);
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
auto factory = FactoryManager::ref().factory<TimeFrame>();
|
||||
TimeFrame* result = factory->create(
|
||||
timeFrameType,
|
||||
dictionary/*,
|
||||
&global::memoryManager.PersistentMemory*/
|
||||
);
|
||||
TimeFrame* result = factory->create(p.type, dictionary);
|
||||
result->setIdentifier("TimeFrame");
|
||||
return ghoul::mm_unique_ptr<TimeFrame>(result);
|
||||
}
|
||||
|
||||
@@ -30,38 +30,29 @@
|
||||
#include <ghoul/misc/dictionary.h>
|
||||
#include <ghoul/misc/templatefactory.h>
|
||||
|
||||
namespace {
|
||||
struct [[codegen::Dictionary(Task)]] Parameters {
|
||||
// This key specifies the type of Task that gets created. It has to be one of the
|
||||
// valid Tasks that are available for creation (see the FactoryDocumentation for a
|
||||
// list of possible Tasks), which depends on the configration of the application
|
||||
std::string type [[codegen::annotation("A valid Task created by a factory")]];
|
||||
};
|
||||
#include "task_codegen.cpp"
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation Task::documentation() {
|
||||
using namespace documentation;
|
||||
return {
|
||||
"Task",
|
||||
"core_task",
|
||||
{
|
||||
{
|
||||
"Type",
|
||||
new StringAnnotationVerifier("A valid Task created by a factory"),
|
||||
Optional::No,
|
||||
"This key specifies the type of Task that gets created. It has to be one"
|
||||
"of the valid Tasks that are available for creation (see the "
|
||||
"FactoryDocumentation for a list of possible Tasks), which depends on "
|
||||
"the configration of the application"
|
||||
}
|
||||
}
|
||||
};
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "core_task";
|
||||
return doc;
|
||||
}
|
||||
|
||||
std::unique_ptr<Task> Task::createFromDictionary(const ghoul::Dictionary& dictionary) {
|
||||
openspace::documentation::testSpecificationAndThrow(
|
||||
documentation::Documentation(),
|
||||
dictionary,
|
||||
"Task"
|
||||
);
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
std::string taskType = dictionary.value<std::string>("Type");
|
||||
auto factory = FactoryManager::ref().factory<Task>();
|
||||
|
||||
Task* task = factory->create(taskType, dictionary);
|
||||
Task* task = factory->create(p.type, dictionary);
|
||||
return std::unique_ptr<Task>(task);
|
||||
}
|
||||
|
||||
|
||||
@@ -31,32 +31,22 @@
|
||||
#include <ghoul/misc/dictionary.h>
|
||||
|
||||
namespace {
|
||||
constexpr const char* KeyStart = "Start";
|
||||
constexpr const char* KeyEnd = "End";
|
||||
struct [[codegen::Dictionary(TimeRange)]] Parameters {
|
||||
// The start date of the time range
|
||||
std::string start [[codegen::annotation("A string representing a valid date")]];
|
||||
|
||||
// The end date of the time range
|
||||
std::string end [[codegen::annotation("A string representing a valid date")]];
|
||||
};
|
||||
#include "timerange_codegen.cpp"
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation TimeRange::Documentation() {
|
||||
using namespace documentation;
|
||||
return {
|
||||
"Time Range",
|
||||
"core_util_timerange",
|
||||
{
|
||||
{
|
||||
KeyStart,
|
||||
new StringAnnotationVerifier("A string representing a valid date"),
|
||||
Optional::No,
|
||||
"The start date of the time range"
|
||||
},
|
||||
{
|
||||
KeyEnd,
|
||||
new StringAnnotationVerifier("A string representing a valid date"),
|
||||
Optional::No,
|
||||
"The end date of the time range"
|
||||
}
|
||||
}
|
||||
};
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "core_util_timerange";
|
||||
return doc;
|
||||
}
|
||||
|
||||
TimeRange::TimeRange(double startTime, double endTime)
|
||||
@@ -73,19 +63,10 @@ TimeRange::TimeRange(const ghoul::Dictionary& dict) {
|
||||
bool TimeRange::initializeFromDictionary(const ghoul::Dictionary& dict,
|
||||
TimeRange& timeRange)
|
||||
{
|
||||
if (dict.hasValue<std::string>(KeyStart) && dict.hasValue<std::string>(KeyEnd)) {
|
||||
std::string startTimeStr = dict.value<std::string>(KeyStart);
|
||||
std::string endTimeStr = dict.value<std::string>(KeyEnd);
|
||||
// Parse to date.
|
||||
// @TODO converting string to time stamp should not rely on Spice
|
||||
timeRange.start = SpiceManager::ref().ephemerisTimeFromDate(startTimeStr);
|
||||
timeRange.end = SpiceManager::ref().ephemerisTimeFromDate(endTimeStr);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
// Could not read TimeRange from Dict
|
||||
return false;
|
||||
}
|
||||
const Parameters p = codegen::bake<Parameters>(dict);
|
||||
timeRange.start = SpiceManager::ref().ephemerisTimeFromDate(p.start);
|
||||
timeRange.end = SpiceManager::ref().ephemerisTimeFromDate(p.end);
|
||||
return true;
|
||||
}
|
||||
|
||||
void TimeRange::include(double val) {
|
||||
|
||||
Submodule support/coding/codegen updated: 4b06f1ad45...481f12fd98
Reference in New Issue
Block a user