mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-05-12 06:19:57 -05:00
Merge remote-tracking branch 'origin/master' into feature/video-module
# Conflicts: # modules/globebrowsing/src/tileprovider/tileprovider.cpp
This commit is contained in:
@@ -252,7 +252,7 @@ AtmosphereDeferredcaster::AtmosphereDeferredcaster(float textureScale,
|
||||
}
|
||||
|
||||
void AtmosphereDeferredcaster::initialize() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
_transmittanceTableTexture = createTexture(_transmittanceTableSize, "Transmittance");
|
||||
_irradianceTableTexture = createTexture(_irradianceTableSize, "Irradiance");
|
||||
@@ -261,7 +261,7 @@ void AtmosphereDeferredcaster::initialize() {
|
||||
}
|
||||
|
||||
void AtmosphereDeferredcaster::deinitialize() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
glDeleteTextures(1, &_transmittanceTableTexture);
|
||||
glDeleteTextures(1, &_irradianceTableTexture);
|
||||
@@ -273,7 +273,7 @@ void AtmosphereDeferredcaster::update(const UpdateData&) {}
|
||||
void AtmosphereDeferredcaster::preRaycast(const RenderData& data, const DeferredcastData&,
|
||||
ghoul::opengl::ProgramObject& prg)
|
||||
{
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
// Atmosphere Frustum Culling
|
||||
glm::dvec3 tPlanetPos = glm::dvec3(_modelTransform * glm::dvec4(0.0, 0.0, 0.0, 1.0));
|
||||
@@ -473,7 +473,7 @@ void AtmosphereDeferredcaster::preRaycast(const RenderData& data, const Deferred
|
||||
void AtmosphereDeferredcaster::postRaycast(const RenderData&, const DeferredcastData&,
|
||||
ghoul::opengl::ProgramObject&)
|
||||
{
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
// Deactivate the texture units
|
||||
_transmittanceTableTextureUnit.deactivate();
|
||||
@@ -537,7 +537,7 @@ void AtmosphereDeferredcaster::setHardShadows(bool enabled) {
|
||||
}
|
||||
|
||||
void AtmosphereDeferredcaster::calculateTransmittance() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
glFramebufferTexture(
|
||||
GL_FRAMEBUFFER,
|
||||
@@ -574,7 +574,7 @@ void AtmosphereDeferredcaster::calculateTransmittance() {
|
||||
}
|
||||
|
||||
GLuint AtmosphereDeferredcaster::calculateDeltaE() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
GLuint deltaE = createTexture(_deltaETableSize, "DeltaE");
|
||||
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, deltaE, 0);
|
||||
@@ -603,7 +603,7 @@ GLuint AtmosphereDeferredcaster::calculateDeltaE() {
|
||||
}
|
||||
|
||||
std::pair<GLuint, GLuint> AtmosphereDeferredcaster::calculateDeltaS() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
GLuint deltaSRayleigh = createTexture(_textureSize, "DeltaS Rayleigh", 3);
|
||||
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, deltaSRayleigh, 0);
|
||||
@@ -657,7 +657,7 @@ std::pair<GLuint, GLuint> AtmosphereDeferredcaster::calculateDeltaS() {
|
||||
}
|
||||
|
||||
void AtmosphereDeferredcaster::calculateIrradiance() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
glFramebufferTexture(
|
||||
GL_FRAMEBUFFER,
|
||||
@@ -686,7 +686,7 @@ void AtmosphereDeferredcaster::calculateIrradiance() {
|
||||
void AtmosphereDeferredcaster::calculateInscattering(GLuint deltaSRayleigh,
|
||||
GLuint deltaSMie)
|
||||
{
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
glFramebufferTexture(
|
||||
GL_FRAMEBUFFER,
|
||||
@@ -734,7 +734,7 @@ void AtmosphereDeferredcaster::calculateDeltaJ(int scatteringOrder,
|
||||
GLuint deltaJ, GLuint deltaE,
|
||||
GLuint deltaSRayleigh, GLuint deltaSMie)
|
||||
{
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, deltaJ, 0);
|
||||
glViewport(0, 0, _textureSize.x, _textureSize.y);
|
||||
@@ -792,7 +792,7 @@ void AtmosphereDeferredcaster::calculateDeltaE(int scatteringOrder,
|
||||
GLuint deltaE, GLuint deltaSRayleigh,
|
||||
GLuint deltaSMie)
|
||||
{
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, deltaE, 0);
|
||||
glViewport(0, 0, _deltaETableSize.x, _deltaETableSize.y);
|
||||
@@ -831,7 +831,7 @@ void AtmosphereDeferredcaster::calculateDeltaS(int scatteringOrder,
|
||||
ghoul::opengl::ProgramObject& program,
|
||||
GLuint deltaSRayleigh, GLuint deltaJ)
|
||||
{
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, deltaSRayleigh, 0);
|
||||
glViewport(0, 0, _textureSize.x, _textureSize.y);
|
||||
@@ -871,7 +871,7 @@ void AtmosphereDeferredcaster::calculateIrradiance(int scatteringOrder,
|
||||
ghoul::opengl::ProgramObject& program,
|
||||
GLuint deltaE)
|
||||
{
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
glFramebufferTexture(
|
||||
GL_FRAMEBUFFER,
|
||||
@@ -903,7 +903,7 @@ void AtmosphereDeferredcaster::calculateInscattering(int scatteringOrder,
|
||||
GLuint deltaSRayleigh)
|
||||
|
||||
{
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
glFramebufferTexture(
|
||||
GL_FRAMEBUFFER,
|
||||
@@ -936,7 +936,7 @@ void AtmosphereDeferredcaster::calculateInscattering(int scatteringOrder,
|
||||
}
|
||||
|
||||
void AtmosphereDeferredcaster::calculateAtmosphereParameters() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
using ProgramObject = ghoul::opengl::ProgramObject;
|
||||
std::unique_ptr<ProgramObject> deltaJProgram = ProgramObject::Build(
|
||||
|
||||
@@ -428,7 +428,7 @@ glm::dmat4 RenderableAtmosphere::computeModelTransformMatrix(const TransformData
|
||||
}
|
||||
|
||||
void RenderableAtmosphere::render(const RenderData& data, RendererTasks& renderTask) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
DeferredcasterTask task{ _deferredcaster.get(), data };
|
||||
renderTask.deferredcasterTasks.push_back(task);
|
||||
|
||||
@@ -279,7 +279,7 @@ std::pair<glm::dvec3, std::string> DashboardItemAngle::positionAndLabel(
|
||||
}
|
||||
|
||||
void DashboardItemAngle::render(glm::vec2& penPosition) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
std::pair<glm::dvec3, std::string> sourceInfo = positionAndLabel(_source);
|
||||
std::pair<glm::dvec3, std::string> referenceInfo = positionAndLabel(_reference);
|
||||
@@ -316,7 +316,7 @@ void DashboardItemAngle::render(glm::vec2& penPosition) {
|
||||
}
|
||||
|
||||
glm::vec2 DashboardItemAngle::size() const {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
constexpr double Angle = 120;
|
||||
return _font->boundingBox("Angle: " + std::to_string(Angle));
|
||||
|
||||
@@ -83,7 +83,7 @@ DashboardItemDate::DashboardItemDate(const ghoul::Dictionary& dictionary)
|
||||
}
|
||||
|
||||
void DashboardItemDate::render(glm::vec2& penPosition) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
std::string time = SpiceManager::ref().dateFromEphemerisTime(
|
||||
global::timeManager->time().j2000Seconds(),
|
||||
@@ -104,7 +104,7 @@ void DashboardItemDate::render(glm::vec2& penPosition) {
|
||||
}
|
||||
|
||||
glm::vec2 DashboardItemDate::size() const {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
std::string_view time = global::timeManager->time().UTC();
|
||||
return _font->boundingBox(fmt::format(fmt::runtime(_formatString.value()), time));
|
||||
|
||||
@@ -335,7 +335,7 @@ std::pair<glm::dvec3, std::string> DashboardItemDistance::positionAndLabel(
|
||||
}
|
||||
|
||||
void DashboardItemDistance::render(glm::vec2& penPosition) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
std::pair<glm::dvec3, std::string> sourceInfo = positionAndLabel(
|
||||
_source,
|
||||
@@ -375,7 +375,7 @@ void DashboardItemDistance::render(glm::vec2& penPosition) {
|
||||
}
|
||||
|
||||
glm::vec2 DashboardItemDistance::size() const {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
const double d = glm::length(1e20);
|
||||
std::pair<double, std::string_view> dist;
|
||||
|
||||
@@ -132,7 +132,7 @@ DashboardItemElapsedTime::DashboardItemElapsedTime(const ghoul::Dictionary& dict
|
||||
}
|
||||
|
||||
void DashboardItemElapsedTime::render(glm::vec2& penPosition) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
double delta = global::timeManager->time().j2000Seconds() - _referenceJ2000;
|
||||
|
||||
@@ -175,7 +175,7 @@ void DashboardItemElapsedTime::render(glm::vec2& penPosition) {
|
||||
}
|
||||
|
||||
glm::vec2 DashboardItemElapsedTime::size() const {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
const double delta = global::timeManager->time().j2000Seconds() - _referenceJ2000;
|
||||
return _font->boundingBox(fmt::format(fmt::runtime(_formatString.value()), delta));
|
||||
|
||||
@@ -203,7 +203,7 @@ DashboardItemFramerate::DashboardItemFramerate(const ghoul::Dictionary& dictiona
|
||||
}
|
||||
|
||||
void DashboardItemFramerate::render(glm::vec2& penPosition) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
if (_shouldClearCache) {
|
||||
_minDeltaTimeCache = 1.0;
|
||||
@@ -243,7 +243,7 @@ void DashboardItemFramerate::render(glm::vec2& penPosition) {
|
||||
}
|
||||
|
||||
glm::vec2 DashboardItemFramerate::size() const {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
const FrametimeType t = FrametimeType(_frametimeType.value());
|
||||
char* end = format(_buffer, t, _minDeltaTimeCache, _maxDeltaTimeCache);
|
||||
|
||||
@@ -119,7 +119,7 @@ DashboardItemInputState::DashboardItemInputState(const ghoul::Dictionary& dictio
|
||||
}
|
||||
|
||||
void DashboardItemInputState::render(glm::vec2& penPosition) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
std::vector<std::string> text;
|
||||
if (_showKeyboard) {
|
||||
@@ -169,7 +169,7 @@ void DashboardItemInputState::render(glm::vec2& penPosition) {
|
||||
}
|
||||
|
||||
glm::vec2 DashboardItemInputState::size() const {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
std::vector<std::string> text;
|
||||
if (_showKeyboard) {
|
||||
|
||||
@@ -67,7 +67,7 @@ DashboardItemMission::DashboardItemMission(const ghoul::Dictionary& dictionary)
|
||||
{}
|
||||
|
||||
void DashboardItemMission::render(glm::vec2& penPosition) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
if (!global::missionManager->hasCurrentMission()) {
|
||||
return;
|
||||
@@ -184,7 +184,7 @@ void DashboardItemMission::render(glm::vec2& penPosition) {
|
||||
}
|
||||
|
||||
glm::vec2 DashboardItemMission::size() const {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
// @TODO fix this up ---abock
|
||||
return { 0.f, 0.f };
|
||||
|
||||
@@ -51,7 +51,7 @@ DashboardItemParallelConnection::DashboardItemParallelConnection(
|
||||
{}
|
||||
|
||||
void DashboardItemParallelConnection::render(glm::vec2& penPosition) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
const ParallelConnection::Status status = global::parallelPeer->status();
|
||||
const size_t nConnections = global::parallelPeer->nConnections();
|
||||
@@ -106,7 +106,7 @@ void DashboardItemParallelConnection::render(glm::vec2& penPosition) {
|
||||
}
|
||||
|
||||
glm::vec2 DashboardItemParallelConnection::size() const {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
ParallelConnection::Status status = global::parallelPeer->status();
|
||||
size_t nConnections = global::parallelPeer->nConnections();
|
||||
|
||||
@@ -85,7 +85,7 @@ DashboardItemPropertyValue::DashboardItemPropertyValue(
|
||||
}
|
||||
|
||||
void DashboardItemPropertyValue::render(glm::vec2& penPosition) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
if (_propertyIsDirty) {
|
||||
_property = openspace::property(_propertyUri);
|
||||
@@ -104,7 +104,7 @@ void DashboardItemPropertyValue::render(glm::vec2& penPosition) {
|
||||
}
|
||||
|
||||
glm::vec2 DashboardItemPropertyValue::size() const {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
return _font->boundingBox(_displayString.value());
|
||||
}
|
||||
|
||||
@@ -151,7 +151,7 @@ DashboardItemSimulationIncrement::DashboardItemSimulationIncrement(
|
||||
}
|
||||
|
||||
void DashboardItemSimulationIncrement::render(glm::vec2& penPosition) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
const double targetDt = global::timeManager->targetDeltaTime();
|
||||
const double currentDt = global::timeManager->deltaTime();
|
||||
@@ -215,7 +215,7 @@ void DashboardItemSimulationIncrement::render(glm::vec2& penPosition) {
|
||||
}
|
||||
|
||||
glm::vec2 DashboardItemSimulationIncrement::size() const {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
double t = global::timeManager->targetDeltaTime();
|
||||
std::pair<double, std::string> deltaTime;
|
||||
|
||||
@@ -66,14 +66,14 @@ DashboardItemText::DashboardItemText(const ghoul::Dictionary& dictionary)
|
||||
}
|
||||
|
||||
void DashboardItemText::render(glm::vec2& penPosition) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
RenderFont(*_font, penPosition, _text.value());
|
||||
penPosition.y -= _font->height();
|
||||
}
|
||||
|
||||
glm::vec2 DashboardItemText::size() const {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
return _font->boundingBox(_text.value());
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ DashboardItemVelocity::DashboardItemVelocity(const ghoul::Dictionary& dictionary
|
||||
}
|
||||
|
||||
void DashboardItemVelocity::render(glm::vec2& penPosition) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
const glm::dvec3 currentPos = global::renderEngine->scene()->camera()->positionVec3();
|
||||
const glm::dvec3 dt = currentPos - _prevPosition;
|
||||
@@ -153,7 +153,7 @@ void DashboardItemVelocity::render(glm::vec2& penPosition) {
|
||||
}
|
||||
|
||||
glm::vec2 DashboardItemVelocity::size() const {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
const double d = glm::length(1e20);
|
||||
std::pair<double, std::string_view> dist;
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace {
|
||||
std::optional<float> intensity;
|
||||
|
||||
// [[codegen::verbatim(NodeInfo.description)]]
|
||||
std::string node;
|
||||
std::string node [[codegen::identifier()]];
|
||||
};
|
||||
#include "scenegraphlightsource_codegen.cpp"
|
||||
} // namespace
|
||||
@@ -83,7 +83,7 @@ SceneGraphLightSource::SceneGraphLightSource(const ghoul::Dictionary& dictionary
|
||||
}
|
||||
|
||||
bool SceneGraphLightSource::initialize() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
_sceneGraphNode =
|
||||
global::renderEngine->scene()->sceneGraphNode(_sceneGraphNodeReference);
|
||||
|
||||
@@ -362,7 +362,7 @@ bool RenderableLabel::isReady() const {
|
||||
}
|
||||
|
||||
void RenderableLabel::initialize() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
setRenderBin(Renderable::RenderBin::PreDeferredTransparent);
|
||||
}
|
||||
|
||||
@@ -490,7 +490,7 @@ bool RenderableModel::isReady() const {
|
||||
}
|
||||
|
||||
void RenderableModel::initialize() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
if (_geometry->hasAnimation() && _enableAnimation && _animationStart.empty()) {
|
||||
LWARNING("Model with animation not given any start time");
|
||||
@@ -507,7 +507,7 @@ void RenderableModel::initialize() {
|
||||
}
|
||||
|
||||
void RenderableModel::initializeGL() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
std::string program = std::string(ProgramName);
|
||||
if (!_vertexShaderPath.empty()) {
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
#include <ghoul/opengl/programobject.h>
|
||||
|
||||
namespace {
|
||||
constexpr std::string_view _loggerCat = "RenderableNodeLine";
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo StartNodeInfo = {
|
||||
"StartNode",
|
||||
"Start Node",
|
||||
@@ -65,6 +67,33 @@ namespace {
|
||||
"This value specifies the line width"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo StartOffsetInfo = {
|
||||
"StartOffset",
|
||||
"Offset to Start Node",
|
||||
"A distance from the start node at which the rendered line should begin. "
|
||||
"By default it takes a value in meters, but if 'UseRelativeOffsets' is set "
|
||||
"to true it is read as a multiplier times the bounding sphere of the node.",
|
||||
openspace::properties::Property::Visibility::AdvancedUser
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo EndOffsetInfo = {
|
||||
"EndOffset",
|
||||
"Offset to End Node",
|
||||
"A distance to the end node at which the rendered line should end. "
|
||||
"By default it takes a value in meters, but if 'UseRelativeOffsets' is set "
|
||||
"to true it is read as a multiplier times the bounding sphere of the node.",
|
||||
openspace::properties::Property::Visibility::AdvancedUser
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo RelativeOffsetsInfo = {
|
||||
"UseRelativeOffsets",
|
||||
"Use Relative Offsets",
|
||||
"If true, the offset values are interpreted as relative values to be multiplied "
|
||||
"with the bounding sphere of the start/end node. If false, the value is "
|
||||
"interpreted as a distance in meters.",
|
||||
openspace::properties::Property::Visibility::AdvancedUser
|
||||
};
|
||||
|
||||
// Returns a position that is relative to the current anchor node. This is a method to
|
||||
// handle precision problems that occur when approaching a line end point
|
||||
glm::dvec3 coordinatePosFromAnchorNode(const glm::dvec3& worldPos) {
|
||||
@@ -83,16 +112,25 @@ namespace {
|
||||
|
||||
struct [[codegen::Dictionary(RenderableNodeLine)]] Parameters {
|
||||
// [[codegen::verbatim(StartNodeInfo.description)]]
|
||||
std::optional<std::string> startNode;
|
||||
std::optional<std::string> startNode [[codegen::identifier()]];
|
||||
|
||||
// [[codegen::verbatim(EndNodeInfo.description)]]
|
||||
std::optional<std::string> endNode;
|
||||
std::optional<std::string> endNode [[codegen::identifier()]];
|
||||
|
||||
// [[codegen::verbatim(LineColorInfo.description)]]
|
||||
std::optional<glm::vec3> color [[codegen::color()]];
|
||||
|
||||
// [[codegen::verbatim(LineWidthInfo.description)]]
|
||||
std::optional<float> lineWidth;
|
||||
|
||||
// [[codegen::verbatim(StartOffsetInfo.description)]]
|
||||
std::optional<float> startOffset;
|
||||
|
||||
// [[codegen::verbatim(EndOffsetInfo.description)]]
|
||||
std::optional<float> endOffset;
|
||||
|
||||
// [[codegen::verbatim(RelativeOffsetsInfo.description)]]
|
||||
std::optional<bool> useRelativeOffsets;
|
||||
};
|
||||
#include "renderablenodeline_codegen.cpp"
|
||||
} // namespace
|
||||
@@ -109,14 +147,13 @@ RenderableNodeLine::RenderableNodeLine(const ghoul::Dictionary& dictionary)
|
||||
, _end(EndNodeInfo, "Root")
|
||||
, _lineColor(LineColorInfo, glm::vec3(1.f), glm::vec3(0.f), glm::vec3(1.f))
|
||||
, _lineWidth(LineWidthInfo, 2.f, 1.f, 20.f)
|
||||
, _startOffset(StartOffsetInfo, 0.f, 0.f, 1e13f)
|
||||
, _endOffset(EndOffsetInfo, 0.f, 0.f, 1e13f)
|
||||
, _useRelativeOffsets(RelativeOffsetsInfo, true)
|
||||
{
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
_start = p.startNode.value_or(_start);
|
||||
addProperty(_start);
|
||||
|
||||
_end = p.endNode.value_or(_end);
|
||||
addProperty(_end);
|
||||
addProperty(_opacity);
|
||||
|
||||
_lineColor = p.color.value_or(_lineColor);
|
||||
_lineColor.setViewOption(properties::Property::ViewOptions::Color);
|
||||
@@ -125,7 +162,82 @@ RenderableNodeLine::RenderableNodeLine(const ghoul::Dictionary& dictionary)
|
||||
_lineWidth = p.lineWidth.value_or(_lineWidth);
|
||||
addProperty(_lineWidth);
|
||||
|
||||
addProperty(_opacity);
|
||||
_start = p.startNode.value_or(_start);
|
||||
addProperty(_start);
|
||||
|
||||
_end = p.endNode.value_or(_end);
|
||||
addProperty(_end);
|
||||
|
||||
addProperty(_startOffset);
|
||||
_startOffset.setExponent(7.f);
|
||||
_startOffset.onChange([&] {
|
||||
if (_useRelativeOffsets) {
|
||||
SceneGraphNode* node = global::renderEngine->scene()->sceneGraphNode(_start);
|
||||
if (!node || node->boundingSphere() > 0.0) {
|
||||
return;
|
||||
}
|
||||
LWARNING(fmt::format(
|
||||
"Setting StartOffset for node line '{}': "
|
||||
"Trying to use relative offsets for start node '{}' that has no "
|
||||
"bounding sphere. This will result in no offset. Use direct "
|
||||
"values by setting UseRelativeOffsets to false",
|
||||
_parent->identifier(), _start
|
||||
));
|
||||
}
|
||||
});
|
||||
|
||||
addProperty(_endOffset);
|
||||
_endOffset.setExponent(7.f);
|
||||
_endOffset.onChange([&] {
|
||||
if (_useRelativeOffsets) {
|
||||
SceneGraphNode* node = global::renderEngine->scene()->sceneGraphNode(_end);
|
||||
if (!node || node->boundingSphere() > 0.0) {
|
||||
return;
|
||||
}
|
||||
LWARNING(fmt::format(
|
||||
"Setting EndOffset for node line '{}': "
|
||||
"Trying to use relative offsets for end node '{}' that has no "
|
||||
"bounding sphere. This will result in no offset. Use direct "
|
||||
"values by setting UseRelativeOffsets to false",
|
||||
_parent->identifier(), _end
|
||||
));
|
||||
}
|
||||
});
|
||||
|
||||
addProperty(_useRelativeOffsets);
|
||||
_useRelativeOffsets.onChange([&]() {
|
||||
SceneGraphNode* startNode = global::renderEngine->scene()->sceneGraphNode(_start);
|
||||
SceneGraphNode* endNode = global::renderEngine->scene()->sceneGraphNode(_end);
|
||||
|
||||
if (!startNode) {
|
||||
LERROR(fmt::format(
|
||||
"Error when recomputing node line offsets for scene graph node '{}'. "
|
||||
"Could not find start node '{}'", _parent->identifier(), _start.value()
|
||||
));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!endNode) {
|
||||
LERROR(fmt::format(
|
||||
"Error when recomputing node line offsets for scene graph node '{}'. "
|
||||
"Could not find end node '{}'", _parent->identifier(), _end.value()
|
||||
));
|
||||
return;
|
||||
}
|
||||
|
||||
if (_useRelativeOffsets) {
|
||||
// Recompute previous offsets to relative values
|
||||
double startBs = startNode->boundingSphere();
|
||||
double endBs = endNode->boundingSphere();
|
||||
_startOffset = startBs > 0.0 ? _startOffset / startBs : 0.0;
|
||||
_endOffset = endBs > 0.0 ? _endOffset / startBs : 0.0;
|
||||
}
|
||||
else {
|
||||
// Recompute relative values to meters
|
||||
_startOffset = _startOffset * startNode->boundingSphere();
|
||||
_endOffset = _endOffset * endNode->boundingSphere();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
double RenderableNodeLine::distance() const {
|
||||
@@ -200,15 +312,13 @@ void RenderableNodeLine::updateVertexData() {
|
||||
SceneGraphNode* startNode = global::renderEngine->scene()->sceneGraphNode(_start);
|
||||
SceneGraphNode* endNode = global::renderEngine->scene()->sceneGraphNode(_end);
|
||||
|
||||
if (!startNode || !endNode) {
|
||||
LERRORC(
|
||||
"RenderableNodeLine",
|
||||
fmt::format(
|
||||
"Could not find starting '{}' or ending '{}'",
|
||||
_start.value(), _end.value()
|
||||
)
|
||||
);
|
||||
if (!startNode) {
|
||||
LERROR(fmt::format("Could not find start node '{}'", _start.value()));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!endNode) {
|
||||
LERROR(fmt::format("Could not find end node '{}'", _end.value()));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -218,13 +328,26 @@ void RenderableNodeLine::updateVertexData() {
|
||||
_startPos = coordinatePosFromAnchorNode(startNode->worldPosition());
|
||||
_endPos = coordinatePosFromAnchorNode(endNode->worldPosition());
|
||||
|
||||
_vertexArray.push_back(static_cast<float>(_startPos.x));
|
||||
_vertexArray.push_back(static_cast<float>(_startPos.y));
|
||||
_vertexArray.push_back(static_cast<float>(_startPos.z));
|
||||
// Handle relative values
|
||||
double startOffset = static_cast<double>(_startOffset);
|
||||
double endOffset = static_cast<double>(_endOffset);
|
||||
if (_useRelativeOffsets) {
|
||||
startOffset *= startNode->boundingSphere();
|
||||
endOffset *= endNode->boundingSphere();
|
||||
}
|
||||
|
||||
_vertexArray.push_back(static_cast<float>(_endPos.x));
|
||||
_vertexArray.push_back(static_cast<float>(_endPos.y));
|
||||
_vertexArray.push_back(static_cast<float>(_endPos.z));
|
||||
// Compute line positions
|
||||
glm::dvec3 dir = glm::normalize(_endPos - _startPos);
|
||||
glm::dvec3 startPos = _startPos + startOffset * dir;
|
||||
glm::dvec3 endPos = _endPos - endOffset * dir;
|
||||
|
||||
_vertexArray.push_back(static_cast<float>(startPos.x));
|
||||
_vertexArray.push_back(static_cast<float>(startPos.y));
|
||||
_vertexArray.push_back(static_cast<float>(startPos.z));
|
||||
|
||||
_vertexArray.push_back(static_cast<float>(endPos.x));
|
||||
_vertexArray.push_back(static_cast<float>(endPos.y));
|
||||
_vertexArray.push_back(static_cast<float>(endPos.z));
|
||||
|
||||
bindGL();
|
||||
glBufferData(
|
||||
|
||||
@@ -83,6 +83,9 @@ private:
|
||||
properties::StringProperty _end;
|
||||
properties::Vec3Property _lineColor;
|
||||
properties::FloatProperty _lineWidth;
|
||||
properties::FloatProperty _startOffset;
|
||||
properties::FloatProperty _endOffset;
|
||||
properties::BoolProperty _useRelativeOffsets;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -175,7 +175,7 @@ bool RenderablePlane::isReady() const {
|
||||
}
|
||||
|
||||
void RenderablePlane::initializeGL() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
glGenVertexArrays(1, &_quad); // generate array
|
||||
glGenBuffers(1, &_vertexPositionBuffer); // generate buffer
|
||||
@@ -194,7 +194,7 @@ void RenderablePlane::initializeGL() {
|
||||
}
|
||||
|
||||
void RenderablePlane::deinitializeGL() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
glDeleteVertexArrays(1, &_quad);
|
||||
_quad = 0;
|
||||
@@ -212,7 +212,7 @@ void RenderablePlane::deinitializeGL() {
|
||||
}
|
||||
|
||||
void RenderablePlane::render(const RenderData& data, RendererTasks&) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
_shader->activate();
|
||||
_shader->setUniform("opacity", opacity());
|
||||
@@ -287,7 +287,7 @@ void RenderablePlane::bindTexture() {}
|
||||
void RenderablePlane::unbindTexture() {}
|
||||
|
||||
void RenderablePlane::update(const UpdateData&) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
if (_shader->isDirty()) {
|
||||
_shader->rebuildFromFile();
|
||||
|
||||
@@ -119,7 +119,7 @@ void RenderablePlaneImageLocal::bindTexture() {
|
||||
}
|
||||
|
||||
void RenderablePlaneImageLocal::update(const UpdateData& data) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
RenderablePlane::update(data);
|
||||
|
||||
@@ -130,7 +130,7 @@ void RenderablePlaneImageLocal::update(const UpdateData& data) {
|
||||
}
|
||||
|
||||
void RenderablePlaneImageLocal::loadTexture() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
if (!_texturePath.value().empty()) {
|
||||
ghoul::opengl::Texture* t = _texture;
|
||||
|
||||
@@ -195,7 +195,7 @@ void RenderablePlaneTimeVaryingImage::bindTexture() {
|
||||
}
|
||||
|
||||
void RenderablePlaneTimeVaryingImage::update(const UpdateData& data) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
RenderablePlane::update(data);
|
||||
|
||||
if (!_enabled || _startTimes.empty()) {
|
||||
|
||||
@@ -88,21 +88,24 @@ namespace {
|
||||
constexpr openspace::properties::Property::PropertyInfo FadeOutThresholdInfo = {
|
||||
"FadeOutThreshold",
|
||||
"Fade-Out Threshold",
|
||||
"This value determines percentage of the sphere is visible before starting "
|
||||
"fading-out it"
|
||||
"This value determines percentage of the sphere that is visible before starting "
|
||||
"to fade it out. A negative or zero value means no fading out will happen. This "
|
||||
"is also the default"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo FadeInThresholdInfo = {
|
||||
"FadeInThreshold",
|
||||
"Fade-In Threshold",
|
||||
"Distance from center of MilkyWay from where the astronomical object starts to "
|
||||
"fade in"
|
||||
"This value determines the distance from center of MilkyWay from where the "
|
||||
"astronomical object starts to fade in, given as a percentage of the size of "
|
||||
"the object. A negative or zero value means no fading in will happen. This is "
|
||||
"also the default"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo DisableFadeInOutInfo = {
|
||||
"DisableFadeInOut",
|
||||
"Disable Fade-In/Fade-Out effects",
|
||||
"Enables/Disables the Fade-In/Out effects"
|
||||
"Enables/Disables the fade in and out effects"
|
||||
};
|
||||
|
||||
struct [[codegen::Dictionary(RenderableSphere)]] Parameters {
|
||||
@@ -152,9 +155,9 @@ RenderableSphere::RenderableSphere(const ghoul::Dictionary& dictionary)
|
||||
, _size(SizeInfo, 1.f, 0.f, 1e25f)
|
||||
, _segments(SegmentsInfo, 8, 4, 1000)
|
||||
, _mirrorTexture(MirrorTextureInfo, false)
|
||||
, _disableFadeInDistance(DisableFadeInOutInfo, true)
|
||||
, _fadeInThreshold(FadeInThresholdInfo, -1.f, 0.f, 1.f)
|
||||
, _fadeOutThreshold(FadeOutThresholdInfo, -1.f, 0.f, 1.f)
|
||||
, _disableFadeInDistance(DisableFadeInOutInfo, false)
|
||||
, _fadeInThreshold(FadeInThresholdInfo, -1.f, -0.1f, 1.f, 0.001f)
|
||||
, _fadeOutThreshold(FadeOutThresholdInfo, -1.f, -0.1f, 1.f, 0.001f)
|
||||
{
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
@@ -192,26 +195,17 @@ RenderableSphere::RenderableSphere(const ghoul::Dictionary& dictionary)
|
||||
addProperty(_texturePath);
|
||||
_texturePath.onChange([this]() { loadTexture(); });
|
||||
|
||||
_mirrorTexture = p.mirrorTexture.value_or(_mirrorTexture);
|
||||
addProperty(_mirrorTexture);
|
||||
|
||||
_mirrorTexture = p.mirrorTexture.value_or(_mirrorTexture);
|
||||
_fadeOutThreshold = p.fadeOutThreshold.value_or(_fadeOutThreshold);
|
||||
addProperty(_fadeOutThreshold);
|
||||
|
||||
bool hasGivenFadeOut = p.fadeOutThreshold.has_value();
|
||||
if (hasGivenFadeOut) {
|
||||
_fadeOutThreshold = *p.fadeOutThreshold;
|
||||
addProperty(_fadeOutThreshold);
|
||||
}
|
||||
_fadeInThreshold = p.fadeInThreshold.value_or(_fadeInThreshold);
|
||||
addProperty(_fadeInThreshold);
|
||||
|
||||
bool hasGivenFadeIn = p.fadeInThreshold.has_value();
|
||||
if (hasGivenFadeIn) {
|
||||
_fadeInThreshold = *p.fadeInThreshold;
|
||||
addProperty(_fadeInThreshold);
|
||||
}
|
||||
|
||||
if (hasGivenFadeIn || hasGivenFadeOut) {
|
||||
_disableFadeInDistance = false;
|
||||
addProperty(_disableFadeInDistance);
|
||||
}
|
||||
_disableFadeInDistance = p.disableFadeInOut.value_or(_disableFadeInDistance);
|
||||
addProperty(_disableFadeInDistance);
|
||||
|
||||
setBoundingSphere(_size);
|
||||
setRenderBinFromOpacity();
|
||||
@@ -281,7 +275,7 @@ void RenderableSphere::render(const RenderData& data, RendererTasks&) {
|
||||
float adjustedOpacity = opacity();
|
||||
|
||||
if (!_disableFadeInDistance) {
|
||||
if (_fadeInThreshold > -1.0) {
|
||||
if (_fadeInThreshold > 0.f) {
|
||||
const double d = glm::distance(
|
||||
data.camera.positionVec3(),
|
||||
data.modelTransform.translation
|
||||
@@ -308,7 +302,7 @@ void RenderableSphere::render(const RenderData& data, RendererTasks&) {
|
||||
}
|
||||
}
|
||||
|
||||
if (_fadeOutThreshold > -1.0) {
|
||||
if (_fadeOutThreshold > 0.f) {
|
||||
const double d = glm::distance(
|
||||
data.camera.positionVec3(),
|
||||
data.modelTransform.translation
|
||||
|
||||
@@ -68,13 +68,6 @@ namespace {
|
||||
{ "Points+Lines", RenderingModeLinesPoints }
|
||||
};
|
||||
|
||||
static const openspace::properties::PropertyOwner::PropertyOwnerInfo AppearanceInfo =
|
||||
{
|
||||
"Appearance",
|
||||
"Appearance",
|
||||
"The appearance of the trail"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo LineColorInfo = {
|
||||
"Color",
|
||||
"Color",
|
||||
@@ -162,7 +155,11 @@ documentation::Documentation RenderableTrail::Documentation() {
|
||||
}
|
||||
|
||||
RenderableTrail::Appearance::Appearance()
|
||||
: properties::PropertyOwner(AppearanceInfo)
|
||||
: properties::PropertyOwner({
|
||||
"Appearance",
|
||||
"Appearance",
|
||||
"The appearance of the trail"
|
||||
})
|
||||
, lineColor(LineColorInfo, glm::vec3(1.f), glm::vec3(0.f), glm::vec3(1.f))
|
||||
, useLineFade(EnableFadeInfo, true)
|
||||
, lineFade(FadeInfo, 1.f, 0.f, 30.f)
|
||||
@@ -230,7 +227,7 @@ RenderableTrail::RenderableTrail(const ghoul::Dictionary& dictionary)
|
||||
}
|
||||
|
||||
void RenderableTrail::initializeGL() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
#ifdef __APPLE__
|
||||
_programObject = BaseModule::ProgramObjectManager.request(
|
||||
@@ -278,7 +275,7 @@ void RenderableTrail::internalRender(bool renderLines, bool renderPoints,
|
||||
const glm::dmat4& modelTransform,
|
||||
RenderInformation& info, int nVertices, int offset)
|
||||
{
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
// We pass in the model view transformation matrix as double in order to maintain
|
||||
// high precision for vertices; especially for the trails, a high vertex precision
|
||||
@@ -378,7 +375,7 @@ void RenderableTrail::internalRender(bool renderLines, bool renderPoints,
|
||||
}
|
||||
|
||||
void RenderableTrail::render(const RenderData& data, RendererTasks&) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
_programObject->activate();
|
||||
_programObject->setUniform(_uniformCache.opacity, opacity());
|
||||
|
||||
@@ -61,7 +61,7 @@ class Translation;
|
||||
*
|
||||
* Trails can be rendered either as lines, as points, or a combination of both with
|
||||
* varying colors, line thicknesses, or fading settings. If trails are rendered as points,
|
||||
* the RenderInformation's \c stride parameter determines the number of points between
|
||||
* the RenderInformation's `stride` parameter determines the number of points between
|
||||
* larger points. A potential use case for this is showing the passage of time along a
|
||||
* trail by using a point separation of one hour and a subsampling of 4, you would get a
|
||||
* point every 15 minutes with every hourly point being bigger.
|
||||
@@ -100,8 +100,8 @@ struct Appearance : properties::PropertyOwner {
|
||||
|
||||
/**
|
||||
* The render method will set up the shader information and then render first the
|
||||
* information contained in the the \c _primaryRenderInformation, then the optional
|
||||
* \c _floatingRenderInformation using the provided \p data
|
||||
* information contained in the the `_primaryRenderInformation`, then the optional
|
||||
* `_floatingRenderInformation` using the provided \p data
|
||||
* \param data The data that is necessary to render this Renderable
|
||||
*/
|
||||
void render(const RenderData& data, RendererTasks& rendererTask) override;
|
||||
|
||||
@@ -67,10 +67,10 @@ private:
|
||||
struct UpdateReport {
|
||||
static constexpr int All = 0; ///< The entire array was touched in the update
|
||||
|
||||
/// If \c true the floating point needs to be updated
|
||||
/// If `true` the floating point needs to be updated
|
||||
bool floatingPointNeedsUpdate;
|
||||
|
||||
/// If \c true at least one of their permanent point were touched
|
||||
/// If `true` at least one of their permanent point were touched
|
||||
bool permanentPointsNeedUpdate;
|
||||
|
||||
/// Returns the number of fixed points that were touched in the update method
|
||||
|
||||
@@ -83,6 +83,14 @@ namespace {
|
||||
"'false', only the trail until the current time in the application will be shown"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo SweepChunkSizeInfo = {
|
||||
"SweepChunkSize",
|
||||
"Sweep Chunk Size",
|
||||
"The number of vertices that will be calculated each frame whenever the trail "
|
||||
"needs to be recalculated. "
|
||||
"A greater value will result in more calculations per frame."
|
||||
};
|
||||
|
||||
struct [[codegen::Dictionary(RenderableTrailTrajectory)]] Parameters {
|
||||
// [[codegen::verbatim(StartTimeInfo.description)]]
|
||||
std::string startTime [[codegen::annotation("A valid date in ISO 8601 format")]];
|
||||
@@ -98,6 +106,9 @@ namespace {
|
||||
|
||||
// [[codegen::verbatim(RenderFullPathInfo.description)]]
|
||||
std::optional<bool> showFullTrail;
|
||||
|
||||
// [[codegen::verbatim(SweepChunkSizeInfo.description)]]
|
||||
std::optional<int> sweepChunkSize;
|
||||
};
|
||||
#include "renderabletrailtrajectory_codegen.cpp"
|
||||
} // namespace
|
||||
@@ -118,21 +129,23 @@ RenderableTrailTrajectory::RenderableTrailTrajectory(const ghoul::Dictionary& di
|
||||
, _sampleInterval(SampleIntervalInfo, 2.0, 2.0, 1e6)
|
||||
, _timeStampSubsamplingFactor(TimeSubSampleInfo, 1, 1, 1000000000)
|
||||
, _renderFullTrail(RenderFullPathInfo, false)
|
||||
, _maxVertex(glm::vec3(-std::numeric_limits<float>::max()))
|
||||
, _minVertex(glm::vec3(std::numeric_limits<float>::max()))
|
||||
{
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
_translation->onParameterChange([this]() { _needsFullSweep = true; });
|
||||
_translation->onParameterChange([this]() { reset(); });
|
||||
|
||||
_startTime = p.startTime;
|
||||
_startTime.onChange([this] { _needsFullSweep = true; });
|
||||
_startTime.onChange([this] { reset(); });
|
||||
addProperty(_startTime);
|
||||
|
||||
_endTime = p.endTime;
|
||||
_endTime.onChange([this] { _needsFullSweep = true; });
|
||||
_endTime.onChange([this] { reset(); });
|
||||
addProperty(_endTime);
|
||||
|
||||
_sampleInterval = p.sampleInterval;
|
||||
_sampleInterval.onChange([this] { _needsFullSweep = true; });
|
||||
_sampleInterval.onChange([this] { reset(); });
|
||||
addProperty(_sampleInterval);
|
||||
|
||||
_timeStampSubsamplingFactor =
|
||||
@@ -143,6 +156,8 @@ RenderableTrailTrajectory::RenderableTrailTrajectory(const ghoul::Dictionary& di
|
||||
_renderFullTrail = p.showFullTrail.value_or(_renderFullTrail);
|
||||
addProperty(_renderFullTrail);
|
||||
|
||||
_sweepChunkSize = p.sweepChunkSize.value_or(_sweepChunkSize);
|
||||
|
||||
// We store the vertices with ascending temporal order
|
||||
_primaryRenderInformation.sorting = RenderInformation::VertexSorting::OldestFirst;
|
||||
}
|
||||
@@ -171,32 +186,76 @@ void RenderableTrailTrajectory::deinitializeGL() {
|
||||
RenderableTrail::deinitializeGL();
|
||||
}
|
||||
|
||||
void RenderableTrailTrajectory::reset() {
|
||||
_needsFullSweep = true;
|
||||
_sweepIteration = 0;
|
||||
_maxVertex = glm::vec3(-std::numeric_limits<float>::max());
|
||||
_minVertex = glm::vec3(std::numeric_limits<float>::max());
|
||||
}
|
||||
|
||||
void RenderableTrailTrajectory::update(const UpdateData& data) {
|
||||
if (_needsFullSweep) {
|
||||
// Convert the start and end time from string representations to J2000 seconds
|
||||
_start = SpiceManager::ref().ephemerisTimeFromDate(_startTime);
|
||||
_end = SpiceManager::ref().ephemerisTimeFromDate(_endTime);
|
||||
|
||||
const double totalSampleInterval = _sampleInterval / _timeStampSubsamplingFactor;
|
||||
// How many values do we need to compute given the distance between the start and
|
||||
// end date and the desired sample interval
|
||||
const int nValues = static_cast<int>((_end - _start) / totalSampleInterval);
|
||||
if (_sweepIteration == 0) {
|
||||
// Max number of vertices
|
||||
constexpr unsigned int maxNumberOfVertices = 1000000;
|
||||
|
||||
// Make space for the vertices
|
||||
_vertexArray.clear();
|
||||
_vertexArray.resize(nValues);
|
||||
// Convert the start and end time from string representations to J2000 seconds
|
||||
_start = SpiceManager::ref().ephemerisTimeFromDate(_startTime);
|
||||
_end = SpiceManager::ref().ephemerisTimeFromDate(_endTime);
|
||||
double timespan = _end - _start;
|
||||
|
||||
// ... fill all of the values
|
||||
for (int i = 0; i < nValues; ++i) {
|
||||
_totalSampleInterval = _sampleInterval / _timeStampSubsamplingFactor;
|
||||
|
||||
// Cap _numberOfVertices in order to prevent overflow and extreme performance
|
||||
// degredation/RAM usage
|
||||
_numberOfVertices = std::min(
|
||||
static_cast<unsigned int>(timespan / _totalSampleInterval),
|
||||
maxNumberOfVertices
|
||||
);
|
||||
|
||||
// We need to recalcuate the _totalSampleInterval if _numberOfVertices eqals
|
||||
// maxNumberOfVertices. If we don't do this the position for each vertex
|
||||
// will not be correct for the number of vertices we are doing along the trail.
|
||||
_totalSampleInterval = (_numberOfVertices == maxNumberOfVertices) ?
|
||||
(timespan / _numberOfVertices) : _totalSampleInterval;
|
||||
|
||||
// Make space for the vertices
|
||||
_vertexArray.clear();
|
||||
_vertexArray.resize(_numberOfVertices);
|
||||
}
|
||||
|
||||
// Calculate sweeping range for this iteration
|
||||
unsigned int startIndex = _sweepIteration * _sweepChunkSize;
|
||||
unsigned int nextIndex = (_sweepIteration + 1) * _sweepChunkSize;
|
||||
unsigned int stopIndex = std::min(nextIndex, _numberOfVertices);
|
||||
|
||||
// Calculate all vertex positions
|
||||
for (int i = startIndex; i < stopIndex; ++i) {
|
||||
const glm::vec3 p = _translation->position({
|
||||
{},
|
||||
Time(_start + i * totalSampleInterval),
|
||||
Time(_start + i * _totalSampleInterval),
|
||||
Time(0.0)
|
||||
});
|
||||
_vertexArray[i] = { p.x, p.y, p.z };
|
||||
}
|
||||
|
||||
// ... and upload them to the GPU
|
||||
// Set max and min vertex for bounding sphere calculations
|
||||
_maxVertex = glm::max(_maxVertex, p);
|
||||
_minVertex = glm::min(_minVertex, p);
|
||||
}
|
||||
++_sweepIteration;
|
||||
|
||||
if (stopIndex == _numberOfVertices) {
|
||||
_sweepIteration = 0;
|
||||
setBoundingSphere(glm::distance(_maxVertex, _minVertex) / 2.f);
|
||||
}
|
||||
else {
|
||||
// Early return as we don't need to render if we are still
|
||||
// doing full sweep calculations
|
||||
return;
|
||||
}
|
||||
|
||||
// Upload vertices to the GPU
|
||||
glBindVertexArray(_primaryRenderInformation._vaoID);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _primaryRenderInformation._vBufferID);
|
||||
glBufferData(
|
||||
@@ -299,24 +358,6 @@ void RenderableTrailTrajectory::update(const UpdateData& data) {
|
||||
|
||||
glBindVertexArray(0);
|
||||
|
||||
// Updating bounding sphere
|
||||
glm::vec3 maxVertex(-std::numeric_limits<float>::max());
|
||||
glm::vec3 minVertex(std::numeric_limits<float>::max());
|
||||
|
||||
auto setMax = [&maxVertex, &minVertex](const TrailVBOLayout& vertexData) {
|
||||
maxVertex.x = std::max(maxVertex.x, vertexData.x);
|
||||
maxVertex.y = std::max(maxVertex.y, vertexData.y);
|
||||
maxVertex.z = std::max(maxVertex.z, vertexData.z);
|
||||
|
||||
minVertex.x = std::min(minVertex.x, vertexData.x);
|
||||
minVertex.y = std::min(minVertex.y, vertexData.y);
|
||||
minVertex.z = std::min(minVertex.z, vertexData.z);
|
||||
};
|
||||
|
||||
std::for_each(_vertexArray.begin(), _vertexArray.end(), setMax);
|
||||
|
||||
setBoundingSphere(glm::distance(maxVertex, minVertex) / 2.f);
|
||||
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -60,6 +60,13 @@ public:
|
||||
static documentation::Documentation Documentation();
|
||||
|
||||
private:
|
||||
|
||||
/// Reset some variables to default state
|
||||
void reset();
|
||||
|
||||
/// The number of vertices that we calculate during each frame of the full sweep pass
|
||||
unsigned int _sweepChunkSize = 200;
|
||||
|
||||
/// The start time of the trail
|
||||
properties::StringProperty _startTime;
|
||||
/// The end time of the trail
|
||||
@@ -84,6 +91,19 @@ private:
|
||||
double _start = 0.0;
|
||||
/// The conversion of the _endTime into the internal time format
|
||||
double _end = 0.0;
|
||||
|
||||
/// Tracks sweep iteration, is used to calculate which vertices to work on per frame
|
||||
int _sweepIteration = 0;
|
||||
|
||||
/// How many points do we need to compute given the distance between the
|
||||
/// start and end date and the desired sample interval
|
||||
unsigned int _numberOfVertices = 0;
|
||||
|
||||
double _totalSampleInterval = 0.0;
|
||||
|
||||
/// Max and min vertex used to calculate the bounding sphere
|
||||
glm::vec3 _maxVertex;
|
||||
glm::vec3 _minVertex;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -390,7 +390,7 @@ FixedRotation::FixedRotation(const ghoul::Dictionary& dictionary)
|
||||
}
|
||||
|
||||
bool FixedRotation::initialize() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
// We have already checked this before, but still
|
||||
const Parameters p = codegen::bake<Parameters>(_constructorDictionary);
|
||||
|
||||
@@ -87,7 +87,7 @@ CefWebGuiModule::CefWebGuiModule()
|
||||
}
|
||||
|
||||
void CefWebGuiModule::startOrStopGui() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
WebBrowserModule* webBrowserModule = global::moduleEngine->module<WebBrowserModule>();
|
||||
|
||||
@@ -127,7 +127,7 @@ void CefWebGuiModule::startOrStopGui() {
|
||||
}
|
||||
|
||||
void CefWebGuiModule::internalInitialize(const ghoul::Dictionary& configuration) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
WebBrowserModule* webBrowserModule =
|
||||
global::moduleEngine->module<WebBrowserModule>();
|
||||
@@ -139,13 +139,13 @@ void CefWebGuiModule::internalInitialize(const ghoul::Dictionary& configuration)
|
||||
}
|
||||
|
||||
_enabled.onChange([this]() {
|
||||
ZoneScopedN("CefWebGuiModule::enabled")
|
||||
ZoneScopedN("CefWebGuiModule::enabled");
|
||||
|
||||
startOrStopGui();
|
||||
});
|
||||
|
||||
_url.onChange([this]() {
|
||||
ZoneScopedN("CefWebGuiModule::url")
|
||||
ZoneScopedN("CefWebGuiModule::url");
|
||||
|
||||
if (_instance) {
|
||||
_instance->loadUrl(_url);
|
||||
@@ -153,7 +153,7 @@ void CefWebGuiModule::internalInitialize(const ghoul::Dictionary& configuration)
|
||||
});
|
||||
|
||||
_reload.onChange([this]() {
|
||||
ZoneScopedN("CefWebGuiModule::reload")
|
||||
ZoneScopedN("CefWebGuiModule::reload");
|
||||
|
||||
if (_instance) {
|
||||
_instance->reloadBrowser();
|
||||
@@ -161,7 +161,7 @@ void CefWebGuiModule::internalInitialize(const ghoul::Dictionary& configuration)
|
||||
});
|
||||
|
||||
_guiScale.onChange([this]() {
|
||||
ZoneScopedN("CefWebGuiModule::guiScale")
|
||||
ZoneScopedN("CefWebGuiModule::guiScale");
|
||||
|
||||
if (_instance) {
|
||||
_instance->setZoom(_guiScale);
|
||||
@@ -169,7 +169,7 @@ void CefWebGuiModule::internalInitialize(const ghoul::Dictionary& configuration)
|
||||
});
|
||||
|
||||
_visible.onChange([this, webBrowserModule]() {
|
||||
ZoneScopedN("CefWebGuiModule::visible")
|
||||
ZoneScopedN("CefWebGuiModule::visible");
|
||||
|
||||
if (_visible && _instance) {
|
||||
webBrowserModule->attachEventHandler(_instance.get());
|
||||
@@ -189,7 +189,7 @@ void CefWebGuiModule::internalInitialize(const ghoul::Dictionary& configuration)
|
||||
|
||||
_endpointCallback = webGuiModule->addEndpointChangeCallback(
|
||||
[this](const std::string& endpoint, bool exists) {
|
||||
ZoneScopedN("CefWebGuiModule::endpointCallback")
|
||||
ZoneScopedN("CefWebGuiModule::endpointCallback");
|
||||
if (exists && endpoint == "frontend" && _instance) {
|
||||
_instance->reloadBrowser();
|
||||
}
|
||||
@@ -213,7 +213,7 @@ void CefWebGuiModule::internalInitialize(const ghoul::Dictionary& configuration)
|
||||
});
|
||||
|
||||
global::callback::draw2D->emplace_back([this](){
|
||||
ZoneScopedN("CefWebGuiModule")
|
||||
ZoneScopedN("CefWebGuiModule");
|
||||
|
||||
const bool isGuiWindow =
|
||||
global::windowDelegate->hasGuiWindow() ?
|
||||
@@ -236,7 +236,7 @@ void CefWebGuiModule::internalInitialize(const ghoul::Dictionary& configuration)
|
||||
});
|
||||
|
||||
global::callback::deinitializeGL->emplace_back([this]() {
|
||||
ZoneScopedN("CefWebGuiModule")
|
||||
ZoneScopedN("CefWebGuiModule");
|
||||
|
||||
if (_endpointCallback != -1) {
|
||||
WebGuiModule* m = global::moduleEngine->module<WebGuiModule>();
|
||||
|
||||
@@ -511,7 +511,7 @@ bool RenderableBillboardsCloud::isReady() const {
|
||||
}
|
||||
|
||||
void RenderableBillboardsCloud::initialize() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
if (_hasSpeckFile) {
|
||||
_dataset = speck::data::loadFileWithCache(_speckFile);
|
||||
@@ -536,7 +536,7 @@ void RenderableBillboardsCloud::initialize() {
|
||||
}
|
||||
|
||||
void RenderableBillboardsCloud::initializeGL() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
_program = DigitalUniverseModule::ProgramObjectManager.request(
|
||||
"RenderableBillboardsCloud",
|
||||
@@ -727,11 +727,11 @@ void RenderableBillboardsCloud::render(const RenderData& data, RendererTasks&) {
|
||||
}
|
||||
|
||||
void RenderableBillboardsCloud::update(const UpdateData&) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
if (_dataIsDirty && _hasSpeckFile) {
|
||||
ZoneScopedN("Data dirty")
|
||||
TracyGpuZone("Data dirty")
|
||||
ZoneScopedN("Data dirty");
|
||||
TracyGpuZone("Data dirty");
|
||||
LDEBUG("Regenerating data");
|
||||
|
||||
std::vector<float> slice = createDataSlice();
|
||||
@@ -848,8 +848,8 @@ void RenderableBillboardsCloud::update(const UpdateData&) {
|
||||
|
||||
if (_hasSpriteTexture && _spriteTextureIsDirty && !_spriteTexturePath.value().empty())
|
||||
{
|
||||
ZoneScopedN("Sprite texture")
|
||||
TracyGpuZone("Sprite texture")
|
||||
ZoneScopedN("Sprite texture");
|
||||
TracyGpuZone("Sprite texture");
|
||||
|
||||
ghoul::opengl::Texture* texture = _spriteTexture;
|
||||
|
||||
@@ -875,7 +875,7 @@ void RenderableBillboardsCloud::update(const UpdateData&) {
|
||||
}
|
||||
|
||||
std::vector<float> RenderableBillboardsCloud::createDataSlice() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
if (_dataset.entries.empty()) {
|
||||
return std::vector<float>();
|
||||
@@ -1045,7 +1045,7 @@ std::vector<float> RenderableBillboardsCloud::createDataSlice() {
|
||||
}
|
||||
|
||||
void RenderableBillboardsCloud::createPolygonTexture() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
LDEBUG("Creating Polygon Texture");
|
||||
|
||||
|
||||
@@ -305,7 +305,7 @@ bool RenderablePlanesCloud::isReady() const {
|
||||
}
|
||||
|
||||
void RenderablePlanesCloud::initialize() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
if (_hasSpeckFile && std::filesystem::is_regular_file(_speckFile)) {
|
||||
_dataset = speck::data::loadFileWithCache(_speckFile);
|
||||
@@ -321,7 +321,7 @@ void RenderablePlanesCloud::initialize() {
|
||||
}
|
||||
|
||||
void RenderablePlanesCloud::initializeGL() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
_program = DigitalUniverseModule::ProgramObjectManager.request(
|
||||
"RenderablePlanesCloud",
|
||||
|
||||
@@ -172,7 +172,7 @@ bool RenderablePoints::isReady() const {
|
||||
}
|
||||
|
||||
void RenderablePoints::initialize() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
_dataset = speck::data::loadFileWithCache(_speckFile);
|
||||
|
||||
@@ -182,7 +182,7 @@ void RenderablePoints::initialize() {
|
||||
}
|
||||
|
||||
void RenderablePoints::initializeGL() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
if (_hasSpriteTexture) {
|
||||
_program = DigitalUniverseModule::ProgramObjectManager.request(
|
||||
|
||||
@@ -99,6 +99,22 @@ void ExoplanetsDataPreparationTask::perform(
|
||||
std::ofstream binFile(_outputBinPath, std::ios::out | std::ios::binary);
|
||||
std::ofstream lutFile(_outputLutPath);
|
||||
|
||||
if (!binFile.good()) {
|
||||
LERROR(fmt::format("Error when writing to {}",_outputBinPath));
|
||||
if (!std::filesystem::is_directory(_outputBinPath.parent_path())) {
|
||||
LERROR("Output directory does not exist");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!lutFile.good()) {
|
||||
LERROR(fmt::format("Error when writing to {}", _outputLutPath));
|
||||
if (!std::filesystem::is_directory(_outputLutPath.parent_path())) {
|
||||
LERROR("Output directory does not exist");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int version = 1;
|
||||
binFile.write(reinterpret_cast<char*>(&version), sizeof(int));
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ public:
|
||||
|
||||
/**
|
||||
* Read specified table columns from fits file.
|
||||
* If <code>readAll</code> is set to true the entire table will be read before the
|
||||
* If `readAll` is set to true the entire table will be read before the
|
||||
* selected columns, which makes the function take a lot longer if it's a big file.
|
||||
* If no HDU index is given the current Extension HDU will be read from.
|
||||
*/
|
||||
@@ -85,8 +85,8 @@ public:
|
||||
|
||||
/**
|
||||
* Reads a single FITS file with pre-defined columns (defined for Viennas TGAS-file).
|
||||
* Returns a vector with all read stars with <code>nValuesPerStar</code>.
|
||||
* If additional columns are given by <code>filterColumnNames</code>, they will be
|
||||
* Returns a vector with all read stars with `nValuesPerStar`.
|
||||
* If additional columns are given by `filterColumnNames`, they will be
|
||||
* read but it will slow doen the reading tremendously.
|
||||
*/
|
||||
std::vector<float> readFitsFile(std::filesystem::path filePath, int& nValuesPerStar,
|
||||
@@ -94,7 +94,7 @@ public:
|
||||
int multiplier = 1);
|
||||
|
||||
/**
|
||||
* Reads a single SPECK file and returns a vector with <code>nRenderValues</code>
|
||||
* Reads a single SPECK file and returns a vector with `nRenderValues`
|
||||
* per star. Reads data in pre-defined order based on AMNH's star data files.
|
||||
*/
|
||||
std::vector<float> readSpeckFile(const std::filesystem::path& filePath,
|
||||
|
||||
@@ -81,21 +81,21 @@ public:
|
||||
|
||||
/**
|
||||
* Inserts star values in correct position in Octree. Makes use of a recursive
|
||||
* traversal strategy. Internally calls <code>insertInNode()</code>
|
||||
* traversal strategy. Internally calls `insertInNode()`
|
||||
*/
|
||||
void insert(const std::vector<float>& starValues);
|
||||
|
||||
/**
|
||||
* Slices LOD data so only the MAX_STARS_PER_NODE brightest stars are stored in inner
|
||||
* nodes. If \p branchIndex is defined then only that branch will be sliced.
|
||||
* Calls <code>sliceNodeLodCache()</code> internally.
|
||||
* Calls `sliceNodeLodCache()` internally.
|
||||
*/
|
||||
void sliceLodData(size_t branchIndex = 8);
|
||||
|
||||
/**
|
||||
* Prints the whole tree structure, including number of stars per node, number of
|
||||
* nodes, tree depth and if node is a leaf.
|
||||
* Calls <code>printStarsPerNode(node, prefix)</code> internally.
|
||||
* Calls `printStarsPerNode(node, prefix)` internally.
|
||||
*/
|
||||
void printStarsPerNode() const;
|
||||
|
||||
@@ -104,8 +104,7 @@ public:
|
||||
* unloaded. If entire dataset fits in RAM then the whole dataset will be loaded
|
||||
* asynchronously. Otherwise only nodes close to the camera will be fetched.
|
||||
* When RAM stars to fill up least-recently used nodes will start to unload.
|
||||
* Calls <code>findAndFetchNeighborNode()</code> and
|
||||
* <code>removeNodesFromRam()</code> internally.
|
||||
* Calls `findAndFetchNeighborNode()` and `removeNodesFromRam()` internally.
|
||||
*/
|
||||
void fetchSurroundingNodes(const glm::dvec3& cameraPos, size_t chunkSizeInBytes,
|
||||
const glm::ivec2& additionalNodes);
|
||||
@@ -114,7 +113,7 @@ public:
|
||||
* Builds render data structure by traversing the Octree and checking for intersection
|
||||
* with view frustum. Every vector in map contains data for one node.
|
||||
* The corresponding integer key is the index where chunk should be inserted into
|
||||
* streaming buffer. Calls <code>checkNodeIntersection()</code> for every branch.
|
||||
* streaming buffer. Calls `checkNodeIntersection()` for every branch.
|
||||
* \pdeltaStars keeps track of how many stars that were added/removed this render
|
||||
* call.
|
||||
*/
|
||||
@@ -136,7 +135,7 @@ public:
|
||||
/**
|
||||
* Write entire Octree structure to a binary file. \param writeData defines if data
|
||||
* should be included or if only structure should be written to the file.
|
||||
* Calls <code>writeNodeToFile()</code> which recursively writes all nodes.
|
||||
* Calls `writeNodeToFile()` which recursively writes all nodes.
|
||||
*/
|
||||
void writeToFile(std::ofstream& outFileStream, bool writeData);
|
||||
|
||||
@@ -145,7 +144,7 @@ public:
|
||||
* stars read.
|
||||
*
|
||||
* \param readData defines if full data or only structure should be read.
|
||||
* Calls <code>readNodeFromFile()</code> which recursively reads all nodes.
|
||||
* Calls `readNodeFromFile()` which recursively reads all nodes.
|
||||
*/
|
||||
int readFromFile(std::ifstream& inFileStream, bool readData,
|
||||
const std::string& folderPath = std::string());
|
||||
@@ -154,7 +153,7 @@ public:
|
||||
* Write specified part of Octree to multiple files, including all data.
|
||||
* \param branchIndex defines which branch to write.
|
||||
* Clears specified branch after writing is done.
|
||||
* Calls <code>writeNodeToMultipleFiles()</code> for the specified branch.
|
||||
* Calls `writeNodeToMultipleFiles()` for the specified branch.
|
||||
*/
|
||||
void writeToMultipleFiles(const std::string& outFolderPath, size_t branchIndex);
|
||||
|
||||
@@ -206,7 +205,7 @@ private:
|
||||
float origY = 0.f, float origZ = 0.f);
|
||||
|
||||
/**
|
||||
* Private help function for <code>insert()</code>. Inserts star into node if leaf and
|
||||
* Private help function for `insert()`. Inserts star into node if leaf and
|
||||
* numStars < MAX_STARS_PER_NODE. If a leaf goes above the threshold it is subdivided
|
||||
* into 8 new nodes.
|
||||
* If node is an inner node, then star is stores in LOD cache if it is among the
|
||||
@@ -223,20 +222,21 @@ private:
|
||||
void sliceNodeLodCache(OctreeNode& node);
|
||||
|
||||
/**
|
||||
* Private help function for <code>insertInNode()</code>. Stores star data in node and
|
||||
* Private help function for `insertInNode()`. Stores star data in node and
|
||||
* keeps track of the brightest stars all children.
|
||||
*/
|
||||
void storeStarData(OctreeNode& node, const std::vector<float>& starValues);
|
||||
|
||||
/**
|
||||
* Private help function for <code>printStarsPerNode()</code>. \returns an accumulated
|
||||
* string containing all descendant nodes.
|
||||
* Private help function for `printStarsPerNode()`.
|
||||
*
|
||||
* \return an accumulated string containing all descendant nodes.
|
||||
*/
|
||||
std::string printStarsPerNode(const OctreeNode& node,
|
||||
const std::string& prefix) const;
|
||||
|
||||
/**
|
||||
* Private help function for <code>traverseData()</code>. Recursively checks which
|
||||
* Private help function for `traverseData()`. Recursively checks which
|
||||
* nodes intersect with the view frustum (interpreted as an AABB) and decides if data
|
||||
* should be optimized away or not. Keeps track of which nodes that are visible and
|
||||
* loaded (if streaming). \param deltaStars keeps track of how many stars that were
|
||||
@@ -324,7 +324,7 @@ private:
|
||||
* \param additionalLevelsToFetch determines how many levels of descendants to fetch.
|
||||
* If it is set to 0 no additional level will be fetched.
|
||||
* If it is set to a negative value then all descendants will be fetched recursively.
|
||||
* Calls <code>fetchNodeDataFromFile()</code> for every child that passes the tests.
|
||||
* Calls `fetchNodeDataFromFile()` for every child that passes the tests.
|
||||
*/
|
||||
void fetchChildrenNodes(OctreeNode& parentNode, int additionalLevelsToFetch);
|
||||
|
||||
@@ -337,8 +337,8 @@ private:
|
||||
|
||||
/**
|
||||
* Loops though all nodes in \param nodesToRemove and clears them from RAM.
|
||||
* Also checks if any ancestor should change the <code>hasLoadedDescendant</code> flag
|
||||
* by calling <code>propagateUnloadedNodes()</code> with all ancestors.
|
||||
* Also checks if any ancestor should change the `hasLoadedDescendant` flag
|
||||
* by calling `propagateUnloadedNodes()` with all ancestors.
|
||||
*/
|
||||
void removeNodesFromRam(const std::vector<unsigned long long>& nodesToRemove);
|
||||
|
||||
@@ -350,7 +350,7 @@ private:
|
||||
|
||||
/**
|
||||
* Loops through \param ancestorNodes backwards and checks if parent node has any
|
||||
* loaded descendants left. If not, then flag <code>hasLoadedDescendant</code> will be
|
||||
* loaded descendants left. If not, then flag `hasLoadedDescendant` will be
|
||||
* set to false for that parent node and next parent in line will be checked.
|
||||
*/
|
||||
void propagateUnloadedNodes(std::vector<std::shared_ptr<OctreeNode>> ancestorNodes);
|
||||
|
||||
@@ -986,6 +986,13 @@ void RenderableGaiaStars::render(const RenderData& data, RendererTasks&) {
|
||||
|
||||
// Update vector with accumulated indices.
|
||||
for (const auto& [offset, subData] : updateData) {
|
||||
if (offset >= _accumulatedIndices.size() - 1) {
|
||||
// @TODO(2023-03-08, alebo) We want to redo the whole rendering pipeline
|
||||
// anyway, so right now we just bail out early if we get an invalid index
|
||||
// that would trigger a crash
|
||||
continue;
|
||||
}
|
||||
|
||||
int newValue = static_cast<int>(subData.size() / _nRenderValuesPerStar) +
|
||||
_accumulatedIndices[offset];
|
||||
int changeInValue = newValue - _accumulatedIndices[offset + 1];
|
||||
|
||||
@@ -65,9 +65,11 @@ private:
|
||||
|
||||
/**
|
||||
* Checks all defined filter ranges and \returns true if any of the corresponding
|
||||
* <code>filterValues</code> are outside of the defined range.
|
||||
* \returns false if value should be inserted into Octree.
|
||||
* `filterValues` are outside of the defined range.
|
||||
*
|
||||
* \param filterValues are all read filter values in binary file.
|
||||
*
|
||||
* \returns false if value should be inserted into Octree.
|
||||
*/
|
||||
bool checkAllFilters(const std::vector<float>& filterValues);
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ GalaxyRaycaster::GalaxyRaycaster(ghoul::opengl::Texture& texture)
|
||||
{}
|
||||
|
||||
void GalaxyRaycaster::initialize() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
_boundingBox.initialize();
|
||||
}
|
||||
|
||||
@@ -326,7 +326,7 @@ RenderableGalaxy::RenderableGalaxy(const ghoul::Dictionary& dictionary)
|
||||
}
|
||||
|
||||
void RenderableGalaxy::initialize() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
// Aspect is currently hardcoded to cubic voxels.
|
||||
glm::vec3 d = _volumeDimensions;
|
||||
@@ -383,7 +383,7 @@ void RenderableGalaxy::initialize() {
|
||||
}
|
||||
|
||||
void RenderableGalaxy::initializeGL() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
_texture = std::make_unique<ghoul::opengl::Texture>(
|
||||
_volumeDimensions,
|
||||
|
||||
@@ -249,7 +249,7 @@ void GlobeBrowsingModule::internalInitialize(const ghoul::Dictionary& dict) {
|
||||
|
||||
// Initialize
|
||||
global::callback::initializeGL->emplace_back([&]() {
|
||||
ZoneScopedN("GlobeBrowsingModule")
|
||||
ZoneScopedN("GlobeBrowsingModule");
|
||||
|
||||
_tileCache = std::make_unique<cache::MemoryAwareTileCache>(_tileCacheSizeMB);
|
||||
addPropertySubOwner(_tileCache.get());
|
||||
@@ -265,21 +265,21 @@ void GlobeBrowsingModule::internalInitialize(const ghoul::Dictionary& dict) {
|
||||
});
|
||||
|
||||
global::callback::deinitializeGL->emplace_back([]() {
|
||||
ZoneScopedN("GlobeBrowsingModule")
|
||||
ZoneScopedN("GlobeBrowsingModule");
|
||||
|
||||
TileProvider::deinitializeDefaultTile();
|
||||
});
|
||||
|
||||
// Render
|
||||
global::callback::render->emplace_back([&]() {
|
||||
ZoneScopedN("GlobeBrowsingModule")
|
||||
ZoneScopedN("GlobeBrowsingModule");
|
||||
|
||||
_tileCache->update();
|
||||
});
|
||||
|
||||
// Deinitialize
|
||||
global::callback::deinitialize->emplace_back([&]() {
|
||||
ZoneScopedN("GlobeBrowsingModule")
|
||||
ZoneScopedN("GlobeBrowsingModule");
|
||||
|
||||
GdalWrapper::destroy();
|
||||
});
|
||||
|
||||
@@ -45,7 +45,7 @@ AsyncTileDataProvider::AsyncTileDataProvider(std::string name,
|
||||
, _rawTileDataReader(std::move(rawTileDataReader))
|
||||
, _concurrentJobManager(LRUThreadPool<TileIndex::TileHashKey>(1, 10))
|
||||
{
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
performReset(ResetRawTileDataReader::No);
|
||||
}
|
||||
@@ -55,7 +55,7 @@ const RawTileDataReader& AsyncTileDataProvider::rawTileDataReader() const {
|
||||
}
|
||||
|
||||
bool AsyncTileDataProvider::enqueueTileIO(const TileIndex& tileIndex) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
if (_resetMode == ResetMode::ShouldNotReset && satisfiesEnqueueCriteria(tileIndex)) {
|
||||
auto job = std::make_unique<TileLoadJob>(*_rawTileDataReader, tileIndex);
|
||||
@@ -95,7 +95,7 @@ std::optional<RawTile> AsyncTileDataProvider::popFinishedRawTile() {
|
||||
}
|
||||
|
||||
bool AsyncTileDataProvider::satisfiesEnqueueCriteria(const TileIndex& tileIndex) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
// Only satisfies if it is not already enqueued. Also bumps the request to the top.
|
||||
const bool alreadyEnqueued = _concurrentJobManager.touch(tileIndex.hashKey());
|
||||
@@ -185,7 +185,7 @@ bool AsyncTileDataProvider::shouldBeDeleted() {
|
||||
}
|
||||
|
||||
void AsyncTileDataProvider::performReset(ResetRawTileDataReader resetRawTileDataReader) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
ghoul_assert(_enqueuedTileRequests.empty(), "No enqueued requests left");
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ struct RawTile;
|
||||
|
||||
/**
|
||||
* The responsibility of this class is to enqueue tile requests and fetching finished
|
||||
* <code>RawTile</code>s that has been asynchronously loaded.
|
||||
* `RawTile`s that has been asynchronously loaded.
|
||||
*/
|
||||
class AsyncTileDataProvider {
|
||||
public:
|
||||
@@ -80,7 +80,7 @@ protected:
|
||||
};
|
||||
|
||||
/**
|
||||
* \returns true if tile of index <code>tileIndex</code> is not already enqueued.
|
||||
* \returns true if tile of index `tileIndex` is not already enqueued.
|
||||
*/
|
||||
bool satisfiesEnqueueCriteria(const TileIndex& tileIndex);
|
||||
|
||||
|
||||
@@ -125,9 +125,8 @@ public:
|
||||
Unavailable,
|
||||
|
||||
/**
|
||||
* Can be set by <code>TileProvider</code>s if the requested
|
||||
* <code>TileIndex</code> is undefined for that particular
|
||||
* provider.
|
||||
* Can be set by `TileProvider`s if the requested `TileIndex` is undefined for
|
||||
* that particular provider.
|
||||
* texture and metaData are both null
|
||||
*/
|
||||
OutOfRange,
|
||||
|
||||
@@ -138,7 +138,7 @@ DashboardItemGlobeLocation::DashboardItemGlobeLocation(
|
||||
}
|
||||
|
||||
void DashboardItemGlobeLocation::render(glm::vec2& penPosition) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
GlobeBrowsingModule* module = global::moduleEngine->module<GlobeBrowsingModule>();
|
||||
|
||||
@@ -200,7 +200,7 @@ void DashboardItemGlobeLocation::render(glm::vec2& penPosition) {
|
||||
}
|
||||
|
||||
glm::vec2 DashboardItemGlobeLocation::size() const {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
return _font->boundingBox(
|
||||
fmt::format("Position: {}, {} Altitude: {}", 1.f, 1.f, 1.f)
|
||||
|
||||
@@ -89,7 +89,7 @@ bool GdalWrapper::logGdalErrors() const {
|
||||
}
|
||||
|
||||
GdalWrapper::GdalWrapper(size_t maximumCacheSize, size_t maximumMaximumCacheSize)
|
||||
: PropertyOwner({ "GdalWrapper" })
|
||||
: PropertyOwner({ "GdalWrapper", "Gdal Wrapper" })
|
||||
, _logGdalErrors(LogGdalErrorInfo, false)
|
||||
, _gdalMaximumCacheSize(
|
||||
GdalMaximumCacheInfo,
|
||||
@@ -99,7 +99,7 @@ GdalWrapper::GdalWrapper(size_t maximumCacheSize, size_t maximumMaximumCacheSize
|
||||
1 // Step: One MB
|
||||
)
|
||||
{
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
addProperty(_logGdalErrors);
|
||||
addProperty(_gdalMaximumCacheSize);
|
||||
|
||||
@@ -51,7 +51,7 @@ public:
|
||||
double edgeLatitudeNearestEquator() const;
|
||||
|
||||
/**
|
||||
* Returns \c true if the center above the equator
|
||||
* Returns `true` if the center above the equator
|
||||
*/
|
||||
double isNorthern() const;
|
||||
|
||||
@@ -63,7 +63,7 @@ public:
|
||||
double maxLon() const;
|
||||
|
||||
/**
|
||||
* Returns \c true if the specified coordinate is contained within the patch
|
||||
* Returns `true` if the specified coordinate is contained within the patch
|
||||
*/
|
||||
bool contains(const Geodetic2& p) const;
|
||||
|
||||
|
||||
@@ -249,7 +249,7 @@ GlobeLabelsComponent::GlobeLabelsComponent()
|
||||
void GlobeLabelsComponent::initialize(const ghoul::Dictionary& dictionary,
|
||||
globebrowsing::RenderableGlobe* globe)
|
||||
{
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
_globe = globe;
|
||||
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace openspace::globebrowsing {
|
||||
void GPULayerGroup::setValue(ghoul::opengl::ProgramObject& program,
|
||||
const LayerGroup& layerGroup, const TileIndex& tileIndex)
|
||||
{
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
ghoul_assert(
|
||||
layerGroup.activeLayers().size() == _gpuActiveLayers.size(),
|
||||
|
||||
@@ -45,27 +45,26 @@ struct LayerGroup;
|
||||
struct TileIndex;
|
||||
|
||||
/**
|
||||
* Manages a GPU representation of a <code>LayerGroup</code>
|
||||
* Manages a GPU representation of a `LayerGroup`
|
||||
*/
|
||||
class GPULayerGroup {
|
||||
public:
|
||||
/**
|
||||
* Sets the value of <code>LayerGroup</code> to its corresponding
|
||||
* GPU struct. OBS! Users must ensure bind has been
|
||||
* called before setting using this method.
|
||||
* Sets the value of `LayerGroup` to its corresponding GPU struct. OBS! Users must
|
||||
* ensure bind has been called before setting using this method.
|
||||
*/
|
||||
void setValue(ghoul::opengl::ProgramObject& programObject,
|
||||
const LayerGroup& layerGroup, const TileIndex& tileIndex);
|
||||
|
||||
/**
|
||||
* Binds this object with GLSL variables with identifiers starting
|
||||
* with nameBase within the provided shader program.
|
||||
* After this method has been called, users may invoke setValue.
|
||||
* Binds this object with GLSL variables with identifiers starting with nameBase
|
||||
* within the provided shader program. After this method has been called, users may
|
||||
* invoke setValue.
|
||||
*/
|
||||
void bind(ghoul::opengl::ProgramObject& programObject, const LayerGroup& layerGroup);
|
||||
|
||||
/**
|
||||
* Deactivates any <code>TextureUnit</code>s assigned by this object.
|
||||
* Deactivates any `TextureUnit`s assigned by this object.
|
||||
* This method should be called after the OpenGL draw call.
|
||||
*/
|
||||
void deactivate();
|
||||
|
||||
@@ -96,8 +96,8 @@ namespace {
|
||||
};
|
||||
|
||||
struct [[codegen::Dictionary(Layer), codegen::noexhaustive()]] Parameters {
|
||||
// The unique identifier for this layer. May not contain '.' or spaces
|
||||
std::string identifier;
|
||||
// The unique identifier for this layer.
|
||||
std::string identifier [[codegen::identifier()]];
|
||||
|
||||
// A human-readable name for the user interface. If this is omitted, the
|
||||
// identifier is used instead
|
||||
@@ -366,7 +366,7 @@ Layer::Layer(layers::Group::ID id, const ghoul::Dictionary& layerDict, LayerGrou
|
||||
}
|
||||
|
||||
void Layer::initialize() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
if (_tileProvider) {
|
||||
_tileProvider->initialize();
|
||||
@@ -380,7 +380,7 @@ void Layer::deinitialize() {
|
||||
}
|
||||
|
||||
ChunkTilePile Layer::chunkTilePile(const TileIndex& tileIndex, int pileSize) const {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
if (_tileProvider) {
|
||||
return _tileProvider->chunkTilePile(tileIndex, pileSize);
|
||||
@@ -446,7 +446,7 @@ void Layer::onChange(std::function<void(Layer*)> callback) {
|
||||
}
|
||||
|
||||
void Layer::update() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
if (_tileProvider) {
|
||||
_tileProvider->update();
|
||||
|
||||
@@ -69,7 +69,7 @@ void LayerGroup::setLayersFromDict(const ghoul::Dictionary& dict) {
|
||||
}
|
||||
|
||||
void LayerGroup::initialize() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
for (const std::unique_ptr<Layer>& l : _layers) {
|
||||
l->initialize();
|
||||
@@ -77,7 +77,7 @@ void LayerGroup::initialize() {
|
||||
}
|
||||
|
||||
void LayerGroup::deinitialize() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
for (const std::unique_ptr<Layer>& l : _layers) {
|
||||
l->deinitialize();
|
||||
@@ -85,7 +85,7 @@ void LayerGroup::deinitialize() {
|
||||
}
|
||||
|
||||
void LayerGroup::update() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
_activeLayers.clear();
|
||||
|
||||
@@ -98,7 +98,7 @@ void LayerGroup::update() {
|
||||
}
|
||||
|
||||
Layer* LayerGroup::addLayer(const ghoul::Dictionary& layerDict) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
documentation::TestResult res = documentation::testSpecification(
|
||||
Layer::Documentation(),
|
||||
|
||||
@@ -36,7 +36,7 @@ class Layer;
|
||||
struct TileProvider;
|
||||
|
||||
/**
|
||||
* Convenience class for dealing with multiple <code>Layer</code>s.
|
||||
* Convenience class for dealing with multiple `Layer`s.
|
||||
*/
|
||||
struct LayerGroup : public properties::PropertyOwner {
|
||||
LayerGroup(layers::Group group);
|
||||
|
||||
@@ -54,7 +54,7 @@ documentation::Documentation LayerManager::Documentation() {
|
||||
LayerManager::LayerManager() : properties::PropertyOwner({ "Layers" }) {}
|
||||
|
||||
void LayerManager::initialize(const ghoul::Dictionary& layerGroupsDict) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
// First create empty layer groups in case not all are specified
|
||||
for (size_t i = 0; i < _layerGroups.size(); ++i) {
|
||||
@@ -91,7 +91,7 @@ void LayerManager::deinitialize() {
|
||||
}
|
||||
|
||||
Layer* LayerManager::addLayer(layers::Group::ID id, const ghoul::Dictionary& layerDict) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
ghoul_assert(id != layers::Group::ID::Unknown, "Layer group ID must be known");
|
||||
|
||||
@@ -109,7 +109,7 @@ Layer* LayerManager::addLayer(layers::Group::ID id, const ghoul::Dictionary& lay
|
||||
}
|
||||
|
||||
void LayerManager::deleteLayer(layers::Group::ID id, const std::string& layerName) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
ghoul_assert(id != layers::Group::ID::Unknown, "Layer group ID must be known");
|
||||
_layerGroups[static_cast<size_t>(id)]->deleteLayer(layerName);
|
||||
@@ -124,7 +124,7 @@ const LayerGroup& LayerManager::layerGroup(layers::Group::ID groupId) const {
|
||||
}
|
||||
|
||||
bool LayerManager::hasAnyBlendingLayersEnabled() const {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
return std::any_of(
|
||||
_layerGroups.begin(),
|
||||
@@ -136,7 +136,7 @@ bool LayerManager::hasAnyBlendingLayersEnabled() const {
|
||||
}
|
||||
|
||||
std::array<LayerGroup*, LayerManager::NumLayerGroups> LayerManager::layerGroups() const {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
std::array<LayerGroup*, NumLayerGroups> res = {};
|
||||
for (size_t i = 0; i < NumLayerGroups; ++i) {
|
||||
@@ -146,7 +146,7 @@ std::array<LayerGroup*, LayerManager::NumLayerGroups> LayerManager::layerGroups(
|
||||
}
|
||||
|
||||
void LayerManager::update() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
for (std::unique_ptr<LayerGroup>& layerGroup : _layerGroups) {
|
||||
layerGroup->update();
|
||||
@@ -154,7 +154,7 @@ void LayerManager::update() {
|
||||
}
|
||||
|
||||
void LayerManager::reset(bool includeDisabled) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
for (std::unique_ptr<LayerGroup>& layerGroup : _layerGroups) {
|
||||
for (Layer* layer : layerGroup->layers()) {
|
||||
@@ -166,7 +166,7 @@ void LayerManager::reset(bool includeDisabled) {
|
||||
}
|
||||
|
||||
void LayerManager::onChange(std::function<void(Layer*)> callback) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
for (std::unique_ptr<LayerGroup>& layerGroup : _layerGroups) {
|
||||
layerGroup->onChange(callback);
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace openspace::globebrowsing::cache {
|
||||
|
||||
/**
|
||||
* Templated class implementing a Least-Recently-Used Cache.
|
||||
* <code>KeyType</code> needs to be an enumerable type.
|
||||
* `KeyType` needs to be an enumerable type.
|
||||
*/
|
||||
template <typename KeyType, typename ValueType, typename HasherType>
|
||||
class LRUCache {
|
||||
|
||||
@@ -59,7 +59,7 @@ bool LRUCache<KeyType, ValueType, HasherType>::exist(const KeyType& key) const {
|
||||
|
||||
template<typename KeyType, typename ValueType, typename HasherType>
|
||||
bool LRUCache<KeyType, ValueType, HasherType>::touch(const KeyType& key) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
const auto it = _itemMap.find(key);
|
||||
if (it != _itemMap.end()) {
|
||||
|
||||
@@ -49,7 +49,7 @@ private:
|
||||
};
|
||||
|
||||
/**
|
||||
* The <code>LRUThreadPool</code> will only enqueue a certain number of tasks. The most
|
||||
* The `LRUThreadPool` will only enqueue a certain number of tasks. The most
|
||||
* recently enqueued task is the one that will be executed first. This class is templated
|
||||
* on a key type which used as an identifier to determine wheter or not a task with the
|
||||
* given key has been enqueued or not. This means that a task can be enqueued several
|
||||
|
||||
@@ -195,14 +195,14 @@ MemoryAwareTileCache::TextureContainer::TextureContainer(TileTextureInitData ini
|
||||
: _initData(std::move(initData))
|
||||
, _numTextures(numTextures)
|
||||
{
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
_textures.reserve(_numTextures);
|
||||
reset();
|
||||
}
|
||||
|
||||
void MemoryAwareTileCache::TextureContainer::reset() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
_textures.clear();
|
||||
_freeTexture = 0;
|
||||
@@ -228,7 +228,7 @@ void MemoryAwareTileCache::TextureContainer::reset() {
|
||||
}
|
||||
|
||||
void MemoryAwareTileCache::TextureContainer::reset(size_t numTextures) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
_numTextures = numTextures;
|
||||
reset();
|
||||
@@ -260,7 +260,7 @@ size_t MemoryAwareTileCache::TextureContainer::size() const {
|
||||
//
|
||||
|
||||
MemoryAwareTileCache::MemoryAwareTileCache(int tileCacheSize)
|
||||
: PropertyOwner({ "TileCache" })
|
||||
: PropertyOwner({ "TileCache", "Tile Cache" })
|
||||
, _numTextureBytesAllocatedOnCPU(0)
|
||||
, _cpuAllocatedTileData(CpuAllocatedDataInfo, tileCacheSize, 128, 16384, 1)
|
||||
, _gpuAllocatedTileData(GpuAllocatedDataInfo, tileCacheSize, 128, 16384, 1)
|
||||
@@ -268,7 +268,7 @@ MemoryAwareTileCache::MemoryAwareTileCache(int tileCacheSize)
|
||||
, _applyTileCacheSize(ApplyTileCacheInfo)
|
||||
, _clearTileCache(ClearTileCacheInfo)
|
||||
{
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
createDefaultTextureContainers();
|
||||
|
||||
@@ -313,7 +313,7 @@ void MemoryAwareTileCache::clear() {
|
||||
}
|
||||
|
||||
void MemoryAwareTileCache::createDefaultTextureContainers() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
for (const layers::Group& gi : layers::Groups) {
|
||||
TileTextureInitData initData = tileTextureInitData(gi.id, true);
|
||||
@@ -324,7 +324,7 @@ void MemoryAwareTileCache::createDefaultTextureContainers() {
|
||||
void MemoryAwareTileCache::assureTextureContainerExists(
|
||||
const TileTextureInitData& initData)
|
||||
{
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
TileTextureInitData::HashKey initDataKey = initData.hashKey;
|
||||
if (_textureContainerMap.find(initDataKey) == _textureContainerMap.end()) {
|
||||
@@ -339,7 +339,7 @@ void MemoryAwareTileCache::assureTextureContainerExists(
|
||||
}
|
||||
|
||||
void MemoryAwareTileCache::setSizeEstimated(size_t estimatedSize) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
ghoul_assert(!_textureContainerMap.empty(), "Texture containers must exist");
|
||||
|
||||
LDEBUG("Resetting tile cache size");
|
||||
@@ -366,7 +366,7 @@ void MemoryAwareTileCache::setSizeEstimated(size_t estimatedSize) {
|
||||
}
|
||||
|
||||
void MemoryAwareTileCache::resetTextureContainerSize(size_t numTexturesPerTextureType) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
_numTextureBytesAllocatedOnCPU = 0;
|
||||
for (std::pair<const TileTextureInitData::HashKey,
|
||||
@@ -391,7 +391,7 @@ bool MemoryAwareTileCache::exist(const ProviderTileKey& key) const {
|
||||
}
|
||||
|
||||
Tile MemoryAwareTileCache::get(const ProviderTileKey& key) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
const TextureContainerMap::const_iterator it = std::find_if(
|
||||
_textureContainerMap.cbegin(),
|
||||
|
||||
@@ -60,7 +60,7 @@ public:
|
||||
std::vector<KeyType> keysToEnqueuedJobs();
|
||||
|
||||
/**
|
||||
* Bumps the job identified with <code>key</code> to the beginning of the queue.
|
||||
* Bumps the job identified with `key` to the beginning of the queue.
|
||||
* In case the job was not already enqueued the function simply returns false and
|
||||
* no state is changed.
|
||||
* \param key is the identifier of the job to bump.
|
||||
|
||||
@@ -426,7 +426,7 @@ RawTileDataReader::RawTileDataReader(std::string filePath,
|
||||
, _initData(std::move(initData))
|
||||
, _preprocess(preprocess)
|
||||
{
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
initialize();
|
||||
}
|
||||
@@ -440,7 +440,7 @@ RawTileDataReader::~RawTileDataReader() {
|
||||
}
|
||||
|
||||
void RawTileDataReader::initialize() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
if (_datasetFilePath.empty()) {
|
||||
throw ghoul::RuntimeError("File path must not be empty");
|
||||
@@ -450,7 +450,7 @@ void RawTileDataReader::initialize() {
|
||||
|
||||
std::string content = _datasetFilePath;
|
||||
if (module.isWMSCachingEnabled()) {
|
||||
ZoneScopedN("WMS Caching")
|
||||
ZoneScopedN("WMS Caching");
|
||||
std::string c;
|
||||
if (std::filesystem::is_regular_file(_datasetFilePath)) {
|
||||
// Only replace the 'content' if the dataset is an XML file and we want to do
|
||||
@@ -520,7 +520,7 @@ void RawTileDataReader::initialize() {
|
||||
}
|
||||
|
||||
{
|
||||
ZoneScopedN("GDALOpen")
|
||||
ZoneScopedN("GDALOpen");
|
||||
_dataset = static_cast<GDALDataset*>(GDALOpen(content.c_str(), GA_ReadOnly));
|
||||
if (!_dataset) {
|
||||
throw ghoul::RuntimeError(fmt::format(
|
||||
|
||||
@@ -64,6 +64,8 @@ namespace std {
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
constexpr std::string_view _loggerCat = "RenderableGlobe";
|
||||
|
||||
// Global flags to modify the RenderableGlobe
|
||||
constexpr bool LimitLevelByAvailableData = true;
|
||||
constexpr bool PerformFrustumCulling = true;
|
||||
@@ -318,7 +320,7 @@ using ChunkTileVector =
|
||||
ChunkTileVector tilesAndSettingsUnsorted(const LayerGroup& layerGroup,
|
||||
const TileIndex& tileIndex)
|
||||
{
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
#if defined(__APPLE__) || (defined(__linux__) && defined(__clang__))
|
||||
ChunkTileVector tilesAndSettings;
|
||||
@@ -338,7 +340,7 @@ ChunkTileVector tilesAndSettingsUnsorted(const LayerGroup& layerGroup,
|
||||
}
|
||||
|
||||
BoundingHeights boundingHeightsForChunk(const Chunk& chunk, const LayerManager& lm) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
using ChunkTileSettingsPair = std::pair<ChunkTile, const LayerRenderSettings*>;
|
||||
|
||||
@@ -403,7 +405,7 @@ BoundingHeights boundingHeightsForChunk(const Chunk& chunk, const LayerManager&
|
||||
}
|
||||
|
||||
bool colorAvailableForChunk(const Chunk& chunk, const LayerManager& lm) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
const LayerGroup& colorLayers = lm.layerGroup(layers::Group::ID::ColorLayers);
|
||||
for (Layer* lyr : colorLayers.activeLayers()) {
|
||||
@@ -422,7 +424,7 @@ std::array<glm::dvec4, 8> boundingCornersForChunk(const Chunk& chunk,
|
||||
const Ellipsoid& ellipsoid,
|
||||
const BoundingHeights& heights)
|
||||
{
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
// assume worst case
|
||||
const double patchCenterRadius = ellipsoid.maximumRadius();
|
||||
@@ -664,6 +666,10 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary)
|
||||
_generalProperties.shadowMapping = true;
|
||||
}
|
||||
_generalProperties.shadowMapping.onChange(notifyShaderRecompilation);
|
||||
|
||||
// Use a secondary renderbin for labels, and other things that we want to be able to
|
||||
// render with transparency, on top of the globe, after the atmosphere step
|
||||
_secondaryRenderBin = RenderBin::PostDeferredTransparent;
|
||||
}
|
||||
|
||||
void RenderableGlobe::initializeGL() {
|
||||
@@ -735,9 +741,6 @@ void RenderableGlobe::render(const RenderData& data, RendererTasks& rendererTask
|
||||
|
||||
if ((distanceToCamera < distance) || (_generalProperties.renderAtDistance)) {
|
||||
try {
|
||||
// Before Shadows
|
||||
_globeLabelsComponent.draw(data);
|
||||
|
||||
if (_hasShadows && _shadowComponent.isEnabled()) {
|
||||
// Set matrices and other GL states
|
||||
RenderData lightRenderData(_shadowComponent.begin(data));
|
||||
@@ -806,8 +809,17 @@ void RenderableGlobe::render(const RenderData& data, RendererTasks& rendererTask
|
||||
_lastChangedLayer = nullptr;
|
||||
}
|
||||
|
||||
void RenderableGlobe::renderSecondary(const RenderData& data, RendererTasks&) {
|
||||
try {
|
||||
_globeLabelsComponent.draw(data);
|
||||
}
|
||||
catch (const ghoul::opengl::TextureUnit::TextureUnitError& e) {
|
||||
LERROR(fmt::format("Error on drawing globe labels: '{}'", e.message));
|
||||
}
|
||||
}
|
||||
|
||||
void RenderableGlobe::update(const UpdateData& data) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
if (_localRenderer.program && _localRenderer.program->isDirty()) {
|
||||
_localRenderer.program->rebuildFromFile();
|
||||
@@ -914,7 +926,7 @@ void RenderableGlobe::renderChunks(const RenderData& data, RendererTasks&,
|
||||
const ShadowComponent::ShadowMapData& shadowData,
|
||||
bool renderGeomOnly)
|
||||
{
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
|
||||
if (_layerManagerDirty) {
|
||||
@@ -1147,7 +1159,7 @@ void RenderableGlobe::renderChunks(const RenderData& data, RendererTasks&,
|
||||
int& iGlobal, std::vector<const Chunk*>& local, int& iLocal, int cutoff,
|
||||
std::vector<const Chunk*>& traversalMemory)
|
||||
{
|
||||
ZoneScopedN("traversal")
|
||||
ZoneScopedN("traversal");
|
||||
|
||||
traversalMemory.clear();
|
||||
|
||||
@@ -1244,8 +1256,8 @@ void RenderableGlobe::renderChunkGlobally(const Chunk& chunk, const RenderData&
|
||||
const ShadowComponent::ShadowMapData& shadowData,
|
||||
bool renderGeomOnly)
|
||||
{
|
||||
ZoneScoped
|
||||
TracyGpuZone("renderChunkGlobally")
|
||||
ZoneScoped;
|
||||
TracyGpuZone("renderChunkGlobally");
|
||||
|
||||
const TileIndex& tileIndex = chunk.tileIndex;
|
||||
ghoul::opengl::ProgramObject& program = *_globalRenderer.program;
|
||||
@@ -1335,8 +1347,8 @@ void RenderableGlobe::renderChunkLocally(const Chunk& chunk, const RenderData& d
|
||||
const ShadowComponent::ShadowMapData& shadowData,
|
||||
bool renderGeomOnly)
|
||||
{
|
||||
ZoneScoped
|
||||
TracyGpuZone("renderChunkLocally")
|
||||
ZoneScoped;
|
||||
TracyGpuZone("renderChunkLocally");
|
||||
|
||||
//PerfMeasure("locally");
|
||||
const TileIndex& tileIndex = chunk.tileIndex;
|
||||
@@ -1473,7 +1485,7 @@ void RenderableGlobe::renderChunkLocally(const Chunk& chunk, const RenderData& d
|
||||
void RenderableGlobe::debugRenderChunk(const Chunk& chunk, const glm::dmat4& mvp,
|
||||
bool renderBounds) const
|
||||
{
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
const std::array<glm::dvec4, 8>& modelSpaceCorners = chunk.corners;
|
||||
|
||||
@@ -1511,7 +1523,7 @@ void RenderableGlobe::setCommonUniforms(ghoul::opengl::ProgramObject& programObj
|
||||
{
|
||||
using namespace layers;
|
||||
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
if (_generalProperties.useAccurateNormals &&
|
||||
!_layerManager.layerGroup(Group::ID::HeightLayers).activeLayers().empty())
|
||||
@@ -1559,7 +1571,7 @@ void RenderableGlobe::setCommonUniforms(ghoul::opengl::ProgramObject& programObj
|
||||
}
|
||||
|
||||
void RenderableGlobe::recompileShaders() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
struct LayerShaderPreprocessingData {
|
||||
struct LayerGroupPreprocessingData {
|
||||
@@ -1787,7 +1799,7 @@ void RenderableGlobe::recompileShaders() {
|
||||
SurfacePositionHandle RenderableGlobe::calculateSurfacePositionHandle(
|
||||
const glm::dvec3& targetModelSpace) const
|
||||
{
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
glm::dvec3 centerToEllipsoidSurface =
|
||||
_ellipsoid.geodeticSurfaceProjection(targetModelSpace);
|
||||
@@ -1820,7 +1832,7 @@ bool RenderableGlobe::testIfCullable(const Chunk& chunk,
|
||||
const BoundingHeights& heights,
|
||||
const glm::dmat4& mvp) const
|
||||
{
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
return (PreformHorizonCulling && isCullableByHorizon(chunk, renderData, heights)) ||
|
||||
(PerformFrustumCulling && isCullableByFrustum(chunk, renderData, mvp));
|
||||
@@ -1829,7 +1841,7 @@ bool RenderableGlobe::testIfCullable(const Chunk& chunk,
|
||||
int RenderableGlobe::desiredLevel(const Chunk& chunk, const RenderData& renderData,
|
||||
const BoundingHeights& heights) const
|
||||
{
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
const int desiredLevel = _debugProperties.levelByProjectedAreaElseDistance ?
|
||||
desiredLevelByProjectedArea(chunk, renderData, heights) :
|
||||
@@ -1846,7 +1858,7 @@ int RenderableGlobe::desiredLevel(const Chunk& chunk, const RenderData& renderDa
|
||||
}
|
||||
|
||||
float RenderableGlobe::getHeight(const glm::dvec3& position) const {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
float height = 0;
|
||||
|
||||
@@ -1996,7 +2008,7 @@ float RenderableGlobe::getHeight(const glm::dvec3& position) const {
|
||||
void RenderableGlobe::calculateEclipseShadows(ghoul::opengl::ProgramObject& programObject,
|
||||
const RenderData& data, ShadowCompType stype)
|
||||
{
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
constexpr double KM_TO_M = 1000.0;
|
||||
|
||||
@@ -2159,7 +2171,7 @@ int RenderableGlobe::desiredLevelByDistance(const Chunk& chunk,
|
||||
const RenderData& data,
|
||||
const BoundingHeights& heights) const
|
||||
{
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
// Calculations are done in the reference frame of the globe
|
||||
// (model space). Hence, the camera position needs to be transformed
|
||||
@@ -2195,7 +2207,7 @@ int RenderableGlobe::desiredLevelByProjectedArea(const Chunk& chunk,
|
||||
const RenderData& data,
|
||||
const BoundingHeights& heights) const
|
||||
{
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
// Calculations are done in the reference frame of the globe
|
||||
// (model space). Hence, the camera position needs to be transformed
|
||||
@@ -2277,7 +2289,7 @@ int RenderableGlobe::desiredLevelByProjectedArea(const Chunk& chunk,
|
||||
}
|
||||
|
||||
int RenderableGlobe::desiredLevelByAvailableTileData(const Chunk& chunk) const {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
const int currLevel = chunk.tileIndex.level;
|
||||
|
||||
@@ -2302,7 +2314,7 @@ bool RenderableGlobe::isCullableByFrustum(const Chunk& chunk,
|
||||
const RenderData&,
|
||||
const glm::dmat4& mvp) const
|
||||
{
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
const std::array<glm::dvec4, 8>& corners = chunk.corners;
|
||||
|
||||
@@ -2323,7 +2335,7 @@ bool RenderableGlobe::isCullableByHorizon(const Chunk& chunk,
|
||||
const RenderData& renderData,
|
||||
const BoundingHeights& heights) const
|
||||
{
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
// Calculations are done in the reference frame of the globe. Hence, the camera
|
||||
// position needs to be transformed with the inverse model matrix
|
||||
@@ -2394,7 +2406,7 @@ bool RenderableGlobe::isCullableByHorizon(const Chunk& chunk,
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void RenderableGlobe::splitChunkNode(Chunk& cn, int depth) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
if (depth > 0 && isLeaf(cn)) {
|
||||
std::vector<void*> memory = _chunkPool.allocate(
|
||||
@@ -2424,7 +2436,7 @@ void RenderableGlobe::splitChunkNode(Chunk& cn, int depth) {
|
||||
}
|
||||
|
||||
void RenderableGlobe::freeChunkNode(Chunk* n) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
_chunkPool.free(n);
|
||||
for (Chunk* c : n->children) {
|
||||
@@ -2436,7 +2448,7 @@ void RenderableGlobe::freeChunkNode(Chunk* n) {
|
||||
}
|
||||
|
||||
void RenderableGlobe::mergeChunkNode(Chunk& cn) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
for (Chunk* child : cn.children) {
|
||||
if (child) {
|
||||
@@ -2450,7 +2462,7 @@ void RenderableGlobe::mergeChunkNode(Chunk& cn) {
|
||||
bool RenderableGlobe::updateChunkTree(Chunk& cn, const RenderData& data,
|
||||
const glm::dmat4& mvp)
|
||||
{
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
// abock: I tried turning this into a queue and use iteration, rather than recursion
|
||||
// but that made the code harder to understand as the breadth-first traversal
|
||||
@@ -2458,7 +2470,7 @@ bool RenderableGlobe::updateChunkTree(Chunk& cn, const RenderData& data,
|
||||
// children and then again it self to be processed after the children finish).
|
||||
// In addition, this didn't even improve performance --- 2018-10-04
|
||||
if (isLeaf(cn)) {
|
||||
ZoneScopedN("leaf")
|
||||
ZoneScopedN("leaf");
|
||||
updateChunk(cn, data, mvp);
|
||||
|
||||
if (cn.status == Chunk::Status::WantSplit) {
|
||||
@@ -2472,7 +2484,7 @@ bool RenderableGlobe::updateChunkTree(Chunk& cn, const RenderData& data,
|
||||
return cn.status == Chunk::Status::WantMerge;
|
||||
}
|
||||
else {
|
||||
ZoneScopedN("!leaf")
|
||||
ZoneScopedN("!leaf");
|
||||
char requestedMergeMask = 0;
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
if (updateChunkTree(*cn.children[i], data, mvp)) {
|
||||
@@ -2500,7 +2512,7 @@ bool RenderableGlobe::updateChunkTree(Chunk& cn, const RenderData& data,
|
||||
void RenderableGlobe::updateChunk(Chunk& chunk, const RenderData& data,
|
||||
const glm::dmat4& mvp) const
|
||||
{
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
const BoundingHeights& heights = boundingHeightsForChunk(chunk, _layerManager);
|
||||
chunk.heightTileOK = heights.tileOK;
|
||||
|
||||
@@ -103,6 +103,7 @@ public:
|
||||
bool isReady() const override;
|
||||
|
||||
void render(const RenderData& data, RendererTasks& rendererTask) override;
|
||||
void renderSecondary(const RenderData& data, RendererTasks&) override;
|
||||
void update(const UpdateData& data) override;
|
||||
|
||||
SurfacePositionHandle calculateSurfacePositionHandle(
|
||||
@@ -153,8 +154,8 @@ private:
|
||||
* Test if a specific chunk can safely be culled without affecting the rendered
|
||||
* image.
|
||||
*
|
||||
* Goes through all available <code>ChunkCuller</code>s and check if any of them
|
||||
* allows culling of the <code>Chunk</code>s in question.
|
||||
* Goes through all available `ChunkCuller`s and check if any of them
|
||||
* allows culling of the `Chunk`s in question.
|
||||
*/
|
||||
bool testIfCullable(const Chunk& chunk, const RenderData& renderData,
|
||||
const BoundingHeights& heights, const glm::dmat4& mvp) const;
|
||||
@@ -163,10 +164,10 @@ private:
|
||||
* Gets the desired level which can be used to determine if a chunk should split
|
||||
* or merge.
|
||||
*
|
||||
* Using <code>ChunkLevelEvaluator</code>s, the desired level can be higher or
|
||||
* lower than the current level of the <code>Chunks</code>s
|
||||
* <code>TileIndex</code>. If the desired level is higher than that of the
|
||||
* <code>Chunk</code>, it wants to split. If it is lower, it wants to merge with
|
||||
* Using `ChunkLevelEvaluator`s, the desired level can be higher or
|
||||
* lower than the current level of the `Chunks`s
|
||||
* `TileIndex`. If the desired level is higher than that of the
|
||||
* `Chunk`, it wants to split. If it is lower, it wants to merge with
|
||||
* its siblings.
|
||||
*/
|
||||
int desiredLevel(const Chunk& chunk, const RenderData& renderData,
|
||||
@@ -178,8 +179,8 @@ private:
|
||||
*
|
||||
* The height can be negative if the height map contains negative values.
|
||||
*
|
||||
* \param <code>position</code> is the position of a point that gets geodetically
|
||||
* projected on the reference ellipsoid. <code>position</code> must be in
|
||||
* \param `position` is the position of a point that gets geodetically
|
||||
* projected on the reference ellipsoid. `position` must be in
|
||||
* cartesian model space.
|
||||
* \returns the height from the reference ellipsoid to the globe surface.
|
||||
*/
|
||||
|
||||
@@ -241,7 +241,7 @@ RingsComponent::RingsComponent(const ghoul::Dictionary& dictionary)
|
||||
}
|
||||
|
||||
void RingsComponent::initialize() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
using ghoul::filesystem::File;
|
||||
|
||||
@@ -328,7 +328,7 @@ bool RingsComponent::isReady() const {
|
||||
}
|
||||
|
||||
void RingsComponent::initializeGL() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
loadTexture();
|
||||
compileShadowShader();
|
||||
@@ -582,7 +582,7 @@ void RingsComponent::draw(const RenderData& data, RenderPass renderPass,
|
||||
}
|
||||
|
||||
void RingsComponent::update(const UpdateData& data) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
if (_shader && _shader->isDirty()) {
|
||||
compileShadowShader();
|
||||
|
||||
@@ -204,7 +204,7 @@ bool ShadowComponent::isReady() const {
|
||||
}
|
||||
|
||||
void ShadowComponent::initializeGL() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
createDepthTexture();
|
||||
createShadowFBO();
|
||||
@@ -353,7 +353,7 @@ void ShadowComponent::end() {
|
||||
}
|
||||
|
||||
void ShadowComponent::update(const UpdateData&) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
SceneGraphNode* sun = global::renderEngine->scene()->sceneGraphNode("Sun");
|
||||
if (sun) {
|
||||
|
||||
@@ -36,8 +36,8 @@ class RawTileDataReader;
|
||||
|
||||
struct TileLoadJob : public Job<RawTile> {
|
||||
/**
|
||||
* Allocates enough data for one tile. When calling <code>product()</code>, the
|
||||
* ownership of this data will be released. If <code>product()</code> has not been
|
||||
* Allocates enough data for one tile. When calling `product()`, the
|
||||
* ownership of this data will be released. If `product()` has not been
|
||||
* called before the TileLoadJob is finished, the data will be deleted as it has not
|
||||
* been exposed outside of this object.
|
||||
*/
|
||||
|
||||
@@ -84,7 +84,7 @@ DefaultTileProvider::DefaultTileProvider(const ghoul::Dictionary& dictionary)
|
||||
: _filePath(FilePathInfo, "")
|
||||
, _tilePixelSize(TilePixelSizeInfo, 32, 32, 2048)
|
||||
{
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
@@ -116,7 +116,7 @@ DefaultTileProvider::DefaultTileProvider(const ghoul::Dictionary& dictionary)
|
||||
}
|
||||
|
||||
void DefaultTileProvider::initAsyncTileDataReader(TileTextureInitData initData) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
_asyncTextureDataProvider = std::make_unique<AsyncTileDataProvider>(
|
||||
name,
|
||||
@@ -129,7 +129,7 @@ void DefaultTileProvider::initAsyncTileDataReader(TileTextureInitData initData)
|
||||
}
|
||||
|
||||
Tile DefaultTileProvider::tile(const TileIndex& tileIndex) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
ghoul_assert(_asyncTextureDataProvider, "No data provider");
|
||||
if (tileIndex.level > maxLevel()) {
|
||||
|
||||
@@ -71,7 +71,7 @@ ImageSequenceTileProvider::ImageSequenceTileProvider(const ghoul::Dictionary& di
|
||||
, _folderPath(FolderPathInfo)
|
||||
, _initDict(dictionary)
|
||||
{
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
@@ -90,7 +90,7 @@ ImageSequenceTileProvider::ImageSequenceTileProvider(const ghoul::Dictionary& di
|
||||
}
|
||||
|
||||
Tile ImageSequenceTileProvider::tile(const TileIndex& tileIndex) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
return _currentTileProvider ? _currentTileProvider->tile(tileIndex) : Tile();
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ documentation::Documentation SingleImageProvider::Documentation() {
|
||||
SingleImageProvider::SingleImageProvider(const ghoul::Dictionary& dictionary)
|
||||
: _filePath(FilePathInfo)
|
||||
{
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
@@ -62,7 +62,7 @@ SingleImageProvider::SingleImageProvider(const ghoul::Dictionary& dictionary)
|
||||
}
|
||||
|
||||
Tile SingleImageProvider::tile(const TileIndex&) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
return _tile;
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ documentation::Documentation SizeReferenceTileProvider::Documentation() {
|
||||
SizeReferenceTileProvider::SizeReferenceTileProvider(const ghoul::Dictionary& dictionary)
|
||||
: TextTileProvider(tileTextureInitData(layers::Group::ID::ColorLayers, false))
|
||||
{
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
@@ -65,7 +65,7 @@ SizeReferenceTileProvider::SizeReferenceTileProvider(const ghoul::Dictionary& di
|
||||
}
|
||||
|
||||
Tile SizeReferenceTileProvider::tile(const TileIndex& tileIndex) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
const GeodeticPatch patch(tileIndex);
|
||||
const bool aboveEquator = patch.isNorthern();
|
||||
|
||||
@@ -52,7 +52,7 @@ documentation::Documentation SpoutImageProvider::Documentation() {
|
||||
SpoutImageProvider::SpoutImageProvider(
|
||||
[[maybe_unused]] const ghoul::Dictionary& dictionary)
|
||||
{
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
#ifdef OPENSPACE_HAS_SPOUT
|
||||
spoutReceiver = std::make_unique<spout::SpoutReceiverPropertyProxy>(
|
||||
@@ -159,7 +159,7 @@ SpoutImageProvider::SpoutImageProvider(
|
||||
}
|
||||
|
||||
void SpoutImageProvider::internalInitialize() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
#ifdef OPENSPACE_HAS_SPOUT
|
||||
spoutReceiver->updateReceiver();
|
||||
@@ -173,7 +173,7 @@ void SpoutImageProvider::internalDeinitialize() {
|
||||
}
|
||||
|
||||
Tile SpoutImageProvider::tile(const TileIndex& tileIndex) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
spoutUpdate = true;
|
||||
return tiles[tileIndex.x];
|
||||
|
||||
@@ -132,7 +132,7 @@ namespace {
|
||||
#include "temporaltileprovider_codegen.cpp"
|
||||
|
||||
std::string_view timeStringify(const std::string& format, const openspace::Time& t) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
constexpr int BufferSize = 64;
|
||||
ghoul_assert(format.size() < BufferSize, "Format string too long");
|
||||
@@ -165,7 +165,7 @@ TemporalTileProvider::TemporalTileProvider(const ghoul::Dictionary& dictionary)
|
||||
, _useFixedTime(UseFixedTimeInfo, false)
|
||||
, _fixedTime(FixedTimeInfo)
|
||||
{
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
@@ -314,7 +314,7 @@ TemporalTileProvider::TemporalTileProvider(const ghoul::Dictionary& dictionary)
|
||||
}
|
||||
|
||||
Tile TemporalTileProvider::tile(const TileIndex& tileIndex) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
if (!_currentTileProvider) {
|
||||
update();
|
||||
}
|
||||
@@ -389,7 +389,7 @@ float TemporalTileProvider::noDataValueAsFloat() {
|
||||
DefaultTileProvider TemporalTileProvider::createTileProvider(
|
||||
std::string_view timekey) const
|
||||
{
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
std::string value;
|
||||
switch (_mode) {
|
||||
@@ -425,7 +425,7 @@ DefaultTileProvider TemporalTileProvider::createTileProvider(
|
||||
}
|
||||
|
||||
DefaultTileProvider* TemporalTileProvider::retrieveTileProvider(const Time& t) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
const double time = t.j2000Seconds();
|
||||
if (const auto it = _tileProviderMap.find(time); it != _tileProviderMap.end()) {
|
||||
@@ -665,7 +665,7 @@ TileProvider* TemporalTileProvider::tileProvider(const Time& time) {
|
||||
TemporalTileProvider::InterpolateTileProvider::InterpolateTileProvider(
|
||||
const ghoul::Dictionary&)
|
||||
{
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
glGenFramebuffers(1, &fbo);
|
||||
glGenVertexArrays(1, &vaoQuad);
|
||||
@@ -712,7 +712,7 @@ TemporalTileProvider::InterpolateTileProvider::~InterpolateTileProvider() {
|
||||
}
|
||||
|
||||
Tile TemporalTileProvider::InterpolateTileProvider::tile(const TileIndex& tileIndex) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
TracyGpuZone("tile");
|
||||
|
||||
// prev and next are the two tiles to interpolate between
|
||||
|
||||
@@ -33,14 +33,14 @@
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
/**
|
||||
* Provide <code>Tile</code>s from web map services that have temporal resolution.
|
||||
* Provide `Tile`s from web map services that have temporal resolution.
|
||||
*
|
||||
* TemporalTileProviders are instantiated using a ghoul::Dictionary, and must define a
|
||||
* filepath to a Openspace Temporal dataset description file. This is an xml-file that
|
||||
* defines the same meta data as the GDAL wms description
|
||||
* (http://www.gdal.org/frmt_wms.html), but augmented with some extra tags describing the
|
||||
* temporal properties of the dataset. See
|
||||
* <code>TemporalTileProvider::TemporalXMLTags</code>
|
||||
* `TemporalTileProvider::TemporalXMLTags`
|
||||
*/
|
||||
class TemporalTileProvider : public TileProvider {
|
||||
public:
|
||||
|
||||
@@ -39,7 +39,7 @@ TextTileProvider::TextTileProvider(TileTextureInitData initData_, size_t fontSiz
|
||||
: initData(std::move(initData_))
|
||||
, fontSize(fontSize_)
|
||||
{
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
tileCache = global::moduleEngine->module<GlobeBrowsingModule>()->tileCache();
|
||||
}
|
||||
@@ -47,7 +47,7 @@ TextTileProvider::TextTileProvider(TileTextureInitData initData_, size_t fontSiz
|
||||
TextTileProvider::~TextTileProvider() {}
|
||||
|
||||
void TextTileProvider::internalInitialize() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
font = global::fontManager->font("Mono", static_cast<float>(fontSize));
|
||||
fontRenderer = ghoul::fontrendering::FontRenderer::createDefault();
|
||||
@@ -62,8 +62,8 @@ void TextTileProvider::internalDeinitialize() {
|
||||
Tile TextTileProvider::renderTile(const TileIndex& tileIndex, const std::string& text,
|
||||
const glm::vec2& position, const glm::vec4& color)
|
||||
{
|
||||
ZoneScoped
|
||||
TracyGpuZone("tile")
|
||||
ZoneScoped;
|
||||
TracyGpuZone("tile");
|
||||
|
||||
cache::ProviderTileKey key = { tileIndex, uniqueIdentifier };
|
||||
Tile tile = tileCache->get(key);
|
||||
@@ -101,7 +101,7 @@ Tile TextTileProvider::renderTile(const TileIndex& tileIndex, const std::string&
|
||||
}
|
||||
|
||||
void TextTileProvider::reset() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
tileCache->clear();
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ TileIndexTileProvider::TileIndexTileProvider(const ghoul::Dictionary&)
|
||||
{}
|
||||
|
||||
Tile TileIndexTileProvider::tile(const TileIndex& tileIndex) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
std::string text = fmt::format(
|
||||
"level: {}\nx: {}\ny: {}", tileIndex.level, tileIndex.x, tileIndex.y
|
||||
);
|
||||
|
||||
@@ -73,7 +73,7 @@ std::unique_ptr<TileProvider> TileProvider::createFromDictionary(
|
||||
layers::Layer::ID layerTypeID,
|
||||
const ghoul::Dictionary& dictionary)
|
||||
{
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
std::string_view type = layers::Layers[static_cast<int>(layerTypeID)].identifier;
|
||||
|
||||
@@ -86,7 +86,7 @@ std::unique_ptr<TileProvider> TileProvider::createFromDictionary(
|
||||
}
|
||||
|
||||
void TileProvider::initializeDefaultTile() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
ghoul_assert(!DefaultTile.texture, "Default tile should not have been created");
|
||||
using namespace ghoul::opengl;
|
||||
@@ -118,10 +118,12 @@ void TileProvider::deinitializeDefaultTile() {
|
||||
DefaultTileTexture = nullptr;
|
||||
}
|
||||
|
||||
TileProvider::TileProvider() : properties::PropertyOwner({ "TileProvider" }) {}
|
||||
TileProvider::TileProvider() :
|
||||
properties::PropertyOwner({ "TileProvider", "Tile Provider" })
|
||||
{}
|
||||
|
||||
void TileProvider::initialize() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
ghoul_assert(!isInitialized, "TileProvider can only be initialized once");
|
||||
|
||||
@@ -145,7 +147,7 @@ void TileProvider::initialize() {
|
||||
}
|
||||
|
||||
void TileProvider::deinitialize() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
internalDeinitialize();
|
||||
}
|
||||
@@ -192,7 +194,7 @@ void TileProvider::internalInitialize() {}
|
||||
void TileProvider::internalDeinitialize() {}
|
||||
|
||||
ChunkTile TileProvider::chunkTile(TileIndex tileIndex, int parents, int maxParents) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
ghoul_assert(isInitialized, "TileProvider was not initialized");
|
||||
|
||||
@@ -216,7 +218,7 @@ ChunkTile TileProvider::chunkTile(TileIndex tileIndex, int parents, int maxParen
|
||||
}
|
||||
|
||||
ChunkTilePile TileProvider::chunkTilePile(TileIndex tileIndex, int pileSize) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
ghoul_assert(isInitialized, "TileProvider was not initialized");
|
||||
ghoul_assert(pileSize >= 0, "pileSize must be positive");
|
||||
|
||||
@@ -91,10 +91,9 @@ struct TileProvider : public properties::PropertyOwner {
|
||||
virtual Tile tile(const TileIndex& tileIndex) = 0;
|
||||
|
||||
/**
|
||||
* Returns the status of a <code>Tile</code>. The <code>Tile::Status</code>
|
||||
* corresponds the <code>Tile</code> that would be returned if the function
|
||||
* <code>tile</code> would be invoked with the same <code>TileIndex</code> argument at
|
||||
* this point in time.
|
||||
* Returns the status of a `Tile`. The `Tile::Status` corresponds the `Tile` that
|
||||
* would be returned if the function `tile` would be invoked with the same `TileIndex`
|
||||
* argument at this point in time.
|
||||
*/
|
||||
virtual Tile::Status tileStatus(const TileIndex& index) = 0;
|
||||
|
||||
@@ -118,13 +117,13 @@ struct TileProvider : public properties::PropertyOwner {
|
||||
virtual void reset() = 0;
|
||||
|
||||
/**
|
||||
* \return The minimum level as defined by the <code>TileIndex</code> that this
|
||||
* \return The minimum level as defined by the `TileIndex` that this
|
||||
* TileProvider is capable of providing.
|
||||
*/
|
||||
virtual int minLevel() = 0;
|
||||
|
||||
/**
|
||||
* \return The maximum level as defined by <code>TileIndex</code> that this
|
||||
* \return The maximum level as defined by `TileIndex` that this
|
||||
* TileProvider is able provide.
|
||||
*/
|
||||
virtual int maxLevel() = 0;
|
||||
|
||||
@@ -65,7 +65,7 @@ documentation::Documentation TileProviderByIndex::Documentation() {
|
||||
}
|
||||
|
||||
TileProviderByIndex::TileProviderByIndex(const ghoul::Dictionary& dictionary) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
@@ -108,7 +108,7 @@ TileProviderByIndex::TileProviderByIndex(const ghoul::Dictionary& dictionary) {
|
||||
}
|
||||
|
||||
Tile TileProviderByIndex::tile(const TileIndex& tileIndex) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
const auto it = _providers.find(tileIndex.hashKey());
|
||||
const bool hasProvider = it != _providers.end();
|
||||
return hasProvider ? it->second->tile(tileIndex) : Tile();
|
||||
|
||||
@@ -46,7 +46,7 @@ documentation::Documentation TileProviderByLevel::Documentation() {
|
||||
}
|
||||
|
||||
TileProviderByLevel::TileProviderByLevel(const ghoul::Dictionary& dictionary) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
@@ -107,7 +107,7 @@ void TileProviderByLevel::internalDeinitialize() {
|
||||
}
|
||||
|
||||
Tile TileProviderByLevel::tile(const TileIndex& tileIndex) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
TileProvider* provider = levelProvider(tileIndex.level);
|
||||
if (provider) {
|
||||
@@ -124,7 +124,7 @@ Tile::Status TileProviderByLevel::tileStatus(const TileIndex& index) {
|
||||
}
|
||||
|
||||
TileProvider* TileProviderByLevel::levelProvider(int level) const {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
if (!_levelTileProviders.empty()) {
|
||||
int clampedLevel = glm::clamp(
|
||||
|
||||
@@ -479,7 +479,7 @@ double TimeQuantizer::computeSecondsFromResolution(const int valueIn, const char
|
||||
}
|
||||
|
||||
bool TimeQuantizer::quantize(Time& t, bool clamp) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
constexpr const char Format[] = "YYYY-MM-DDTHR:MN:SC.###";
|
||||
constexpr int BufferSize = sizeof(Format);
|
||||
@@ -551,7 +551,7 @@ bool TimeQuantizer::quantize(Time& t, bool clamp) {
|
||||
void TimeQuantizer::doFirstApproximation(DateTime& quantized, DateTime& unQ, double value,
|
||||
char unit)
|
||||
{
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
switch (unit) {
|
||||
case 'y':
|
||||
|
||||
@@ -126,7 +126,7 @@ ImGUIModule::ImGUIModule()
|
||||
}
|
||||
|
||||
global::callback::draw2D->emplace_back([&]() {
|
||||
ZoneScopedN("ImGUI")
|
||||
ZoneScopedN("ImGUI");
|
||||
|
||||
if (!_isEnabled) {
|
||||
return;
|
||||
@@ -156,7 +156,7 @@ ImGUIModule::ImGUIModule()
|
||||
[&](Key key, KeyModifier mod, KeyAction action,
|
||||
IsGuiWindow isGuiWindow) -> bool
|
||||
{
|
||||
ZoneScopedN("ImGUI")
|
||||
ZoneScopedN("ImGUI");
|
||||
|
||||
if (!isGuiWindow || !_isEnabled) {
|
||||
return false;
|
||||
@@ -169,7 +169,7 @@ ImGUIModule::ImGUIModule()
|
||||
[&](unsigned int codepoint, KeyModifier modifier,
|
||||
IsGuiWindow isGuiWindow) -> bool
|
||||
{
|
||||
ZoneScopedN("ImGUI")
|
||||
ZoneScopedN("ImGUI");
|
||||
|
||||
if (!isGuiWindow || !_isEnabled) {
|
||||
return false;
|
||||
@@ -191,7 +191,7 @@ ImGUIModule::ImGUIModule()
|
||||
[&](MouseButton button, MouseAction action, KeyModifier,
|
||||
IsGuiWindow isGuiWindow) -> bool
|
||||
{
|
||||
ZoneScopedN("ImGUI")
|
||||
ZoneScopedN("ImGUI");
|
||||
|
||||
if (!isGuiWindow) {
|
||||
return false;
|
||||
@@ -210,7 +210,7 @@ ImGUIModule::ImGUIModule()
|
||||
|
||||
global::callback::mouseScrollWheel->emplace_back(
|
||||
[&](double, double posY, IsGuiWindow isGuiWindow) -> bool {
|
||||
ZoneScopedN("ImGUI")
|
||||
ZoneScopedN("ImGUI");
|
||||
|
||||
if (!isGuiWindow || !_isEnabled) {
|
||||
return false;
|
||||
|
||||
@@ -44,7 +44,7 @@ public:
|
||||
* Returns if this component is enabled, that is, if it is currently active and
|
||||
* visible on the screen.
|
||||
*
|
||||
* \return \c true if this component is enabled, \c false otherwise
|
||||
* \return `true` if this component is enabled, `false` otherwise
|
||||
*/
|
||||
bool isEnabled() const;
|
||||
|
||||
@@ -75,10 +75,10 @@ public:
|
||||
void setShowHelpTooltipDelay(double delay);
|
||||
|
||||
protected:
|
||||
/// \c true if this component is enabled and visible on the screen
|
||||
/// `true` if this component is enabled and visible on the screen
|
||||
properties::BoolProperty _isEnabled;
|
||||
|
||||
/// if \c true this window is currently collapsed. This setting mirrors the ImGui
|
||||
/// if `true` this window is currently collapsed. This setting mirrors the ImGui
|
||||
/// internal state of the window
|
||||
properties::BoolProperty _isCollapsed;
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace openspace {
|
||||
|
||||
IswaModule::IswaModule() : OpenSpaceModule(Name) {
|
||||
global::callback::initialize->push_back([]() {
|
||||
ZoneScopedN("IswaModule")
|
||||
ZoneScopedN("IswaModule");
|
||||
IswaManager::initialize();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ protected:
|
||||
/**
|
||||
* Should create a new texture and populate the _textures vector.
|
||||
*
|
||||
* \return \c true if update was successful
|
||||
* \return `true` if update was successful
|
||||
*/
|
||||
virtual bool updateTexture() = 0;
|
||||
|
||||
@@ -98,7 +98,7 @@ protected:
|
||||
* Is called before updateTexture. For IswaCygnets getting data from a HTTP request,
|
||||
* this function should get the dataFile from the future object.
|
||||
*
|
||||
* \return \c true if update was successful
|
||||
* \return `true` if update was successful
|
||||
*/
|
||||
virtual bool updateTextureResource() = 0;
|
||||
|
||||
@@ -107,7 +107,7 @@ protected:
|
||||
* Texture cygnets, this should be an image. For DataCygnets, this should be the data
|
||||
* file.
|
||||
*
|
||||
* \return \c true if update was successful
|
||||
* \return `true` if update was successful
|
||||
*/
|
||||
virtual bool downloadTextureResource(double timestamp) = 0;
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ namespace openspace {
|
||||
IswaManager* IswaManager::_instance = nullptr;
|
||||
|
||||
IswaManager::IswaManager()
|
||||
: properties::PropertyOwner({ "IswaManager" })
|
||||
: properties::PropertyOwner({ "IswaManager", "Iswa Manager" })
|
||||
, _baseUrl("https://iswa-demo-server.herokuapp.com/")
|
||||
{
|
||||
_type[CygnetType::Texture] = "Texture";
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace openspace::kameleonHelper {
|
||||
* Opens a ccmc::Kameleon object from the provided path to a .cdf file. Path should be
|
||||
* absolute.
|
||||
*
|
||||
* \return \c nullptr if the file fails to open
|
||||
* \return `nullptr` if the file fails to open
|
||||
*/
|
||||
std::unique_ptr<ccmc::Kameleon> createKameleonObject(const std::string& cdfFilePath);
|
||||
double getTime(ccmc::Kameleon* kameleon, double manualOffset);
|
||||
|
||||
@@ -88,7 +88,7 @@ int ServerModule::skyBrowserUpdateTime() const {
|
||||
|
||||
void ServerModule::internalInitialize(const ghoul::Dictionary& configuration) {
|
||||
global::callback::preSync->emplace_back([this]() {
|
||||
ZoneScopedN("ServerModule")
|
||||
ZoneScopedN("ServerModule");
|
||||
|
||||
preSync();
|
||||
});
|
||||
@@ -113,10 +113,7 @@ void ServerModule::internalInitialize(const ghoul::Dictionary& configuration) {
|
||||
std::unique_ptr<ServerInterface> serverInterface =
|
||||
ServerInterface::createFromDictionary(interfaceDictionary);
|
||||
|
||||
|
||||
if (global::windowDelegate->isMaster()) {
|
||||
serverInterface->initialize();
|
||||
}
|
||||
serverInterface->initialize();
|
||||
|
||||
_interfaceOwner.addPropertySubOwner(serverInterface.get());
|
||||
|
||||
@@ -132,10 +129,6 @@ void ServerModule::internalInitialize(const ghoul::Dictionary& configuration) {
|
||||
}
|
||||
|
||||
void ServerModule::preSync() {
|
||||
if (!global::windowDelegate->isMaster()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Set up new connections.
|
||||
for (std::unique_ptr<ServerInterface>& serverInterface : _interfaces) {
|
||||
if (!serverInterface->isEnabled()) {
|
||||
@@ -180,7 +173,7 @@ void ServerModule::preSync() {
|
||||
}
|
||||
|
||||
void ServerModule::cleanUpFinishedThreads() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
for (ConnectionData& connectionData : _connections) {
|
||||
Connection& connection = *connectionData.connection;
|
||||
@@ -201,12 +194,10 @@ void ServerModule::cleanUpFinishedThreads() {
|
||||
}
|
||||
|
||||
void ServerModule::disconnectAll() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
for (std::unique_ptr<ServerInterface>& serverInterface : _interfaces) {
|
||||
if (global::windowDelegate->isMaster()) {
|
||||
serverInterface->deinitialize();
|
||||
}
|
||||
serverInterface->deinitialize();
|
||||
}
|
||||
|
||||
for (ConnectionData& connectionData : _connections) {
|
||||
@@ -220,7 +211,7 @@ void ServerModule::disconnectAll() {
|
||||
}
|
||||
|
||||
void ServerModule::handleConnection(std::shared_ptr<Connection> connection) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
std::string messageString;
|
||||
messageString.reserve(256);
|
||||
@@ -231,7 +222,7 @@ void ServerModule::handleConnection(std::shared_ptr<Connection> connection) {
|
||||
}
|
||||
|
||||
void ServerModule::consumeMessages() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
std::lock_guard lock(_messageQueueMutex);
|
||||
while (!_messageQueue.empty()) {
|
||||
|
||||
@@ -99,7 +99,7 @@ Connection::Connection(std::unique_ptr<ghoul::io::Socket> s, std::string address
|
||||
}
|
||||
|
||||
void Connection::handleMessage(const std::string& message) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
try {
|
||||
nlohmann::json j = nlohmann::json::parse(message.c_str());
|
||||
@@ -140,7 +140,7 @@ void Connection::handleMessage(const std::string& message) {
|
||||
}
|
||||
|
||||
void Connection::handleJson(const nlohmann::json& json) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
auto topicJson = json.find(MessageKeyTopic);
|
||||
auto payloadJson = json.find(MessageKeyPayload);
|
||||
@@ -196,13 +196,13 @@ void Connection::handleJson(const nlohmann::json& json) {
|
||||
}
|
||||
|
||||
void Connection::sendMessage(const std::string& message) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
_socket->putMessage(message);
|
||||
}
|
||||
|
||||
void Connection::sendJson(const nlohmann::json& json) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
sendMessage(json.dump());
|
||||
}
|
||||
|
||||
@@ -133,7 +133,7 @@ const json TimeTopic::getNextPrevDeltaTimeStepJson() {
|
||||
}
|
||||
|
||||
void TimeTopic::sendCurrentTime() {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
const json timeJson = {
|
||||
{ "time", global::timeManager->time().ISO8601() }
|
||||
|
||||
@@ -36,7 +36,7 @@ void Topic::initialize(std::shared_ptr<Connection> connection, size_t topicId) {
|
||||
}
|
||||
|
||||
nlohmann::json Topic::wrappedPayload(const nlohmann::json& payload) const {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
// TODO: add message time
|
||||
nlohmann::json j = {
|
||||
@@ -47,7 +47,7 @@ nlohmann::json Topic::wrappedPayload(const nlohmann::json& payload) const {
|
||||
}
|
||||
|
||||
nlohmann::json Topic::wrappedError(std::string message, int code) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
|
||||
nlohmann::json j = {
|
||||
{ "topic", _topicId },
|
||||
|
||||
@@ -49,11 +49,13 @@ public:
|
||||
float opacity() const;
|
||||
glm::dvec2 fineTuneVector(const glm::dvec2& drag);
|
||||
bool isInitialized() const;
|
||||
bool isPointingSpacecraft() const;
|
||||
|
||||
double setVerticalFovWithScroll(float scroll);
|
||||
void setOpacity(float opacity);
|
||||
void setIdInBrowser() const;
|
||||
void setIsInitialized(bool isInitialized);
|
||||
void setPointSpaceCraft(bool shouldPoint);
|
||||
|
||||
void updateTextureResolution();
|
||||
|
||||
@@ -69,6 +71,7 @@ private:
|
||||
static constexpr int RadiusTimeOut = 25;
|
||||
properties::FloatProperty _textureQuality;
|
||||
properties::BoolProperty _isHidden;
|
||||
properties::BoolProperty _isPointingSpacecraft;
|
||||
std::vector<std::unique_ptr<properties::Vec3Property>> _displayCopies;
|
||||
std::vector<std::unique_ptr<properties::BoolProperty>> _showDisplayCopies;
|
||||
|
||||
|
||||
@@ -75,6 +75,7 @@ public:
|
||||
void setBrowserRatio(float ratio);
|
||||
void setVerticalFovWithScroll(float scroll);
|
||||
void setImageCollectionIsLoaded(bool isLoaded);
|
||||
void setPointSpaceCraft(bool shouldPoint);
|
||||
void applyRoll();
|
||||
|
||||
double verticalFov() const;
|
||||
@@ -85,6 +86,7 @@ public:
|
||||
std::string browserId() const;
|
||||
std::string targetRenderableId() const;
|
||||
std::string targetNodeId() const;
|
||||
bool pointSpaceCraft() const;
|
||||
|
||||
ScreenSpaceSkyBrowser* browser() const;
|
||||
std::vector<std::string> selectedImages() const;
|
||||
|
||||
@@ -540,7 +540,6 @@ scripting::LuaLibrary SkyBrowserModule::luaLibrary() const {
|
||||
codegen::lua::ScrollOverBrowser,
|
||||
codegen::lua::LoadingImageCollectionComplete,
|
||||
codegen::lua::ShowAllTargetsAndBrowsers,
|
||||
codegen::lua::PointSpaceCraft,
|
||||
codegen::lua::GetWwtImageCollectionUrl,
|
||||
codegen::lua::StopAnimations,
|
||||
codegen::lua::SetBorderRadius,
|
||||
|
||||
@@ -35,10 +35,34 @@
|
||||
#include <openspace/scripting/scriptengine.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <scn/scn.h>
|
||||
|
||||
namespace {
|
||||
constexpr std::string_view _loggerCat = "SkyBrowserModule";
|
||||
constexpr std::string_view _loggerCat = "SkyBrowserModule";
|
||||
|
||||
bool browserBelongsToCurrentNode(std::string identifier) {
|
||||
size_t found = identifier.find('_');
|
||||
std::string errorMessage = "The Sky Browser encountered a problem when it tried to "
|
||||
"initialize the browser";
|
||||
if (found == std::string::npos) {
|
||||
throw ghoul::RuntimeError(errorMessage);
|
||||
}
|
||||
else {
|
||||
std::string res = identifier.substr(found + 1, identifier.size());
|
||||
if (res.empty()) {
|
||||
throw ghoul::RuntimeError(errorMessage);
|
||||
}
|
||||
// Convert the last char to an int
|
||||
int nodeId = std::stoi(res);
|
||||
return nodeId == openspace::global::windowDelegate->currentNode();
|
||||
}
|
||||
}
|
||||
|
||||
std::string prunedIdentifier(std::string identifier) {
|
||||
// Removes the node number at the end of the identifier
|
||||
std::string res = identifier.substr(0, identifier.find('_'));
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reloads the sky browser display copy for the node index that is sent in.
|
||||
@@ -116,6 +140,14 @@ namespace {
|
||||
);
|
||||
module->startRotatingCamera(dir);
|
||||
}
|
||||
|
||||
if (selected->pointSpaceCraft()) {
|
||||
global::eventEngine->publishEvent<events::EventPointSpacecraft>(
|
||||
image.equatorialSpherical.x,
|
||||
image.equatorialSpherical.y,
|
||||
module->spaceCraftAnimationTime()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -178,13 +210,17 @@ namespace {
|
||||
[[codegen::luawrap]] void loadImagesToWWT(std::string identifier) {
|
||||
using namespace openspace;
|
||||
|
||||
if (!browserBelongsToCurrentNode(identifier)) {
|
||||
return;
|
||||
}
|
||||
std::string prunedId = prunedIdentifier(identifier);
|
||||
// Load images from url
|
||||
LINFO("Connection established to WorldWide Telescope application in " + identifier);
|
||||
LINFO("Loading image collections to " + identifier);
|
||||
LINFO("Connection established to WorldWide Telescope application in " + prunedId);
|
||||
LINFO("Loading image collections to " + prunedId);
|
||||
|
||||
// Load the collections here because we know that the browser can execute javascript
|
||||
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
|
||||
TargetBrowserPair* pair = module->pair(identifier);
|
||||
TargetBrowserPair* pair = module->pair(prunedId);
|
||||
if (pair) {
|
||||
pair->hideChromeInterface();
|
||||
pair->browser()->loadImageCollection(module->wwtImageCollectionUrl());
|
||||
@@ -216,12 +252,11 @@ namespace {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// To ensure each node in a cluster calls its own instance of the wwt application
|
||||
// Do not send this script to the other nodes
|
||||
global::scriptEngine->queueScript(
|
||||
"openspace.skybrowser.sendOutIdsToBrowsers()",
|
||||
scripting::ScriptEngine::RemoteScripting::No
|
||||
scripting::ScriptEngine::RemoteScripting::Yes
|
||||
);
|
||||
}
|
||||
|
||||
@@ -250,9 +285,14 @@ namespace {
|
||||
using namespace openspace;
|
||||
|
||||
// Initialize browser with ID and its corresponding target
|
||||
LINFO("Initializing sky browser " + identifier);
|
||||
if (!browserBelongsToCurrentNode(identifier)) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string prunedId = prunedIdentifier(identifier);
|
||||
LINFO("Initializing sky browser " + prunedId);
|
||||
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
|
||||
TargetBrowserPair* pair = module->pair(identifier);
|
||||
TargetBrowserPair* pair = module->pair(prunedId);
|
||||
if (pair) {
|
||||
pair->initialize();
|
||||
}
|
||||
@@ -317,6 +357,7 @@ namespace {
|
||||
image.setValue("cartesianDirection", img.equatorialCartesian);
|
||||
image.setValue("hasCelestialCoords", img.hasCelestialCoords);
|
||||
image.setValue("credits", img.credits);
|
||||
image.setValue("collection", img.collection);
|
||||
image.setValue("creditsUrl", img.creditsUrl);
|
||||
image.setValue("identifier", img.identifier);
|
||||
|
||||
@@ -471,7 +512,7 @@ namespace {
|
||||
glm::vec3 positionTarget = glm::vec3(0.9f, 0.4f, -2.1f);
|
||||
glm::dvec3 galacticTarget = skybrowser::localCameraToGalactic(positionTarget);
|
||||
if (glm::any(glm::isnan(galacticTarget))) {
|
||||
galacticTarget = glm::dvec3 (0.0, 0.0, skybrowser::CelestialSphereRadius);
|
||||
galacticTarget = glm::dvec3(0.0, 0.0, skybrowser::CelestialSphereRadius);
|
||||
}
|
||||
std::string guiPath = "/Sky Browser";
|
||||
std::string url = "http://wwt.openspaceproject.com/1/openspace/";
|
||||
@@ -769,10 +810,15 @@ namespace {
|
||||
[[codegen::luawrap]] void loadingImageCollectionComplete(std::string identifier) {
|
||||
using namespace openspace;
|
||||
|
||||
if (!browserBelongsToCurrentNode(identifier)) {
|
||||
return;
|
||||
}
|
||||
std::string prunedId = prunedIdentifier(identifier);
|
||||
|
||||
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
|
||||
TargetBrowserPair* pair = module->pair(identifier);
|
||||
TargetBrowserPair* pair = module->pair(prunedId);
|
||||
if (pair) {
|
||||
LINFO("Image collection is loaded in Screen Space Sky Browser " + identifier);
|
||||
LINFO("Image collection is loaded in Screen Space Sky Browser " + prunedId);
|
||||
pair->setImageCollectionIsLoaded(true);
|
||||
// Add all selected images to WorldWide Telescope
|
||||
const std::vector<std::string>& images = pair->selectedImages();
|
||||
@@ -800,22 +846,6 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Point spacecraft to the equatorial coordinates the target points to. Takes an
|
||||
* identifier to a sky browser.
|
||||
*/
|
||||
[[codegen::luawrap]] void pointSpaceCraft(std::string identifier) {
|
||||
using namespace openspace;
|
||||
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
|
||||
TargetBrowserPair* pair = module->pair(identifier);
|
||||
glm::dvec2 equatorial = pair->targetDirectionEquatorial();
|
||||
global::eventEngine->publishEvent<events::EventPointSpacecraft>(
|
||||
equatorial.x,
|
||||
equatorial.y,
|
||||
module->spaceCraftAnimationTime()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop animations. Takes an identifier to a sky browser.
|
||||
*/
|
||||
|
||||
@@ -185,7 +185,7 @@ void RenderableSkyTarget::applyRoll() {
|
||||
}
|
||||
|
||||
void RenderableSkyTarget::render(const RenderData& data, RendererTasks&) {
|
||||
ZoneScoped
|
||||
ZoneScoped;
|
||||
const bool showRectangle = _verticalFov > _showRectangleThreshold;
|
||||
|
||||
glm::vec4 color = glm::vec4(glm::vec3(_borderColor) / 255.f, 1.0);
|
||||
|
||||
@@ -70,12 +70,22 @@ namespace {
|
||||
"be"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo PointSpacecraftInfo = {
|
||||
"PointSpacecraft",
|
||||
"Point Spacecraft",
|
||||
"If checked, spacecrafts will point towards the coordinate of an image upon "
|
||||
"selection."
|
||||
};
|
||||
|
||||
struct [[codegen::Dictionary(ScreenSpaceSkyBrowser)]] Parameters {
|
||||
// [[codegen::verbatim(TextureQualityInfo.description)]]
|
||||
std::optional<float> textureQuality;
|
||||
|
||||
// [[codegen::verbatim(IsHiddenInfo.description)]]
|
||||
std::optional<bool> isHidden;
|
||||
|
||||
// [[codegen::verbatim(PointSpacecraftInfo.description)]]
|
||||
std::optional<bool> pointSpacecraft;
|
||||
};
|
||||
|
||||
#include "screenspaceskybrowser_codegen.cpp"
|
||||
@@ -107,6 +117,7 @@ ScreenSpaceSkyBrowser::ScreenSpaceSkyBrowser(const ghoul::Dictionary& dictionary
|
||||
, WwtCommunicator(dictionary)
|
||||
, _textureQuality(TextureQualityInfo, 1.f, 0.25f, 1.f)
|
||||
, _isHidden(IsHiddenInfo, true)
|
||||
, _isPointingSpacecraft(PointSpacecraftInfo, false)
|
||||
{
|
||||
_identifier = makeUniqueIdentifier(_identifier);
|
||||
|
||||
@@ -114,6 +125,7 @@ ScreenSpaceSkyBrowser::ScreenSpaceSkyBrowser(const ghoul::Dictionary& dictionary
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
_textureQuality = p.textureQuality.value_or(_textureQuality);
|
||||
_isHidden = p.isHidden.value_or(_isHidden);
|
||||
_isPointingSpacecraft = p.pointSpacecraft.value_or(_isPointingSpacecraft);
|
||||
|
||||
addProperty(_isHidden);
|
||||
addProperty(_url);
|
||||
@@ -121,6 +133,7 @@ ScreenSpaceSkyBrowser::ScreenSpaceSkyBrowser(const ghoul::Dictionary& dictionary
|
||||
addProperty(_reload);
|
||||
addProperty(_textureQuality);
|
||||
addProperty(_verticalFov);
|
||||
addProperty(_isPointingSpacecraft);
|
||||
|
||||
_textureQuality.onChange([this]() { _isDimensionsDirty = true; });
|
||||
|
||||
@@ -177,14 +190,23 @@ bool ScreenSpaceSkyBrowser::isInitialized() const {
|
||||
return _isInitialized;
|
||||
}
|
||||
|
||||
bool ScreenSpaceSkyBrowser::isPointingSpacecraft() const {
|
||||
return _isPointingSpacecraft;
|
||||
}
|
||||
|
||||
void ScreenSpaceSkyBrowser::setIdInBrowser() const {
|
||||
WwtCommunicator::setIdInBrowser(identifier());
|
||||
int currentNode = global::windowDelegate->currentNode();
|
||||
WwtCommunicator::setIdInBrowser(fmt::format("{}_{}", identifier(), currentNode));
|
||||
}
|
||||
|
||||
void ScreenSpaceSkyBrowser::setIsInitialized(bool isInitialized) {
|
||||
_isInitialized = isInitialized;
|
||||
}
|
||||
|
||||
void ScreenSpaceSkyBrowser::setPointSpaceCraft(bool shouldPoint) {
|
||||
_isPointingSpacecraft = shouldPoint;
|
||||
}
|
||||
|
||||
void ScreenSpaceSkyBrowser::updateTextureResolution() {
|
||||
// Check if texture quality has changed. If it has, adjust accordingly
|
||||
if (std::abs(_textureQuality.value() - _lastTextureQuality) > glm::epsilon<float>()) {
|
||||
|
||||
@@ -147,6 +147,10 @@ std::string TargetBrowserPair::targetNodeId() const {
|
||||
return _targetNode->identifier();
|
||||
}
|
||||
|
||||
bool TargetBrowserPair::pointSpaceCraft() const {
|
||||
return _browser->isPointingSpacecraft();
|
||||
}
|
||||
|
||||
double TargetBrowserPair::verticalFov() const {
|
||||
return _browser->verticalFov();
|
||||
}
|
||||
@@ -283,6 +287,10 @@ void TargetBrowserPair::applyRoll() {
|
||||
_targetRenderable->applyRoll();
|
||||
}
|
||||
|
||||
void TargetBrowserPair::setPointSpaceCraft(bool shouldPoint) {
|
||||
_browser->setPointSpaceCraft(shouldPoint);
|
||||
}
|
||||
|
||||
void TargetBrowserPair::incrementallyAnimateToCoordinate() {
|
||||
// Animate the target before the field of view starts to animate
|
||||
if (_targetAnimation.isAnimating()) {
|
||||
|
||||
@@ -39,7 +39,7 @@ using json = nlohmann::json;
|
||||
namespace {
|
||||
constexpr std::string_view _loggerCat = "HorizonsFile";
|
||||
constexpr std::string_view ApiSource = "NASA/JPL Horizons API";
|
||||
constexpr std::string_view CurrentVersion = "1.1";
|
||||
constexpr std::string_view CurrentMajorVersion = "1";
|
||||
|
||||
// Values needed to construct the url for the http request to JPL Horizons API
|
||||
constexpr std::string_view VectorUrl = "https://ssd.jpl.nasa.gov/api/horizons.api?"
|
||||
@@ -61,12 +61,12 @@ HorizonsFile::HorizonsFile(std::filesystem::path file)
|
||||
: _file(std::move(file))
|
||||
{}
|
||||
|
||||
HorizonsFile::HorizonsFile(std::filesystem::path filePath, const std::string& result) {
|
||||
HorizonsFile::HorizonsFile(std::filesystem::path filePath, std::string result)
|
||||
: _file(std::move(filePath))
|
||||
{
|
||||
// Write the response into a new file and save it
|
||||
std::ofstream file(filePath);
|
||||
file << ghoul::replaceAll(result, "\\n", "\n") << std::endl;
|
||||
file.close();
|
||||
_file = std::move(filePath);
|
||||
std::ofstream file(_file);
|
||||
file << ghoul::replaceAll(std::move(result), "\\n", "\n") << std::endl;
|
||||
}
|
||||
|
||||
void HorizonsFile::setFile(std::filesystem::path file) {
|
||||
@@ -77,10 +77,6 @@ const std::filesystem::path& HorizonsFile::file() const {
|
||||
return _file;
|
||||
}
|
||||
|
||||
std::filesystem::path& HorizonsFile::file() {
|
||||
return _file;
|
||||
}
|
||||
|
||||
std::string constructHorizonsUrl(HorizonsType type, const std::string& target,
|
||||
const std::string& observer,
|
||||
const std::string& startTime,
|
||||
@@ -88,7 +84,7 @@ std::string constructHorizonsUrl(HorizonsType type, const std::string& target,
|
||||
const std::string& unit)
|
||||
{
|
||||
// Construct url for request
|
||||
std::string url = "";
|
||||
std::string url;
|
||||
switch (type) {
|
||||
case HorizonsType::Vector:
|
||||
url = VectorUrl;
|
||||
@@ -100,10 +96,13 @@ std::string constructHorizonsUrl(HorizonsType type, const std::string& target,
|
||||
throw ghoul::MissingCaseException();
|
||||
}
|
||||
|
||||
url += fmt::format("{}'{}'", Command, ghoul::encodeUrl(target));
|
||||
url += fmt::format("{}'{}'", Center, ghoul::encodeUrl(observer));
|
||||
url += fmt::format("{}'{}'", StartTime, ghoul::encodeUrl(startTime));
|
||||
url += fmt::format("{}'{}'", StopTime, ghoul::encodeUrl(stopTime));
|
||||
url += fmt::format(
|
||||
"{}'{}'{}'{}'{}'{}'{}'{}'",
|
||||
Command, ghoul::encodeUrl(target),
|
||||
Center, ghoul::encodeUrl(observer),
|
||||
StartTime, ghoul::encodeUrl(startTime),
|
||||
StopTime, ghoul::encodeUrl(stopTime)
|
||||
);
|
||||
|
||||
if (unit.empty()) {
|
||||
url += fmt::format("{}'{}'", StepSize, ghoul::encodeUrl(stepSize));
|
||||
@@ -162,7 +161,6 @@ nlohmann::json convertHorizonsDownloadToJson(std::filesystem::path filePath) {
|
||||
HorizonsResultCode isValidHorizonsAnswer(const json& answer) {
|
||||
// Signature, source and version
|
||||
if (auto signature = answer.find("signature"); signature != answer.end()) {
|
||||
|
||||
if (auto source = signature->find("source"); source != signature->end()) {
|
||||
if (*source != static_cast<std::string>(ApiSource)) {
|
||||
LWARNING(fmt::format("Horizons answer from unkown source '{}'", *source));
|
||||
@@ -173,10 +171,14 @@ HorizonsResultCode isValidHorizonsAnswer(const json& answer) {
|
||||
}
|
||||
|
||||
if (auto version = signature->find("version"); version != signature->end()) {
|
||||
if (*version != static_cast<std::string>(CurrentVersion)) {
|
||||
// Extract the major version from the version string
|
||||
std::string v = *version;
|
||||
v = v.substr(0, v.find('.'));
|
||||
|
||||
if (v != CurrentMajorVersion) {
|
||||
LWARNING(fmt::format(
|
||||
"Unknown Horizons version '{}' found. The currently supported "
|
||||
"version is {}", *version, CurrentVersion
|
||||
"Unknown Horizons major version '{}' found. The currently supported "
|
||||
"major version is {}", *version, CurrentMajorVersion
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -191,7 +193,7 @@ HorizonsResultCode isValidHorizonsAnswer(const json& answer) {
|
||||
}
|
||||
|
||||
// Errors
|
||||
if (auto it = answer.find("error"); it != answer.end()) {
|
||||
if (auto it = answer.find("error"); it != answer.end()) {
|
||||
// There was an error
|
||||
std::string errorMsg = *it;
|
||||
|
||||
@@ -273,13 +275,11 @@ HorizonsResultCode isValidHorizonsFile(std::filesystem::path file) {
|
||||
while (fileStream.good() && line.find("$$SOE") == std::string::npos) {
|
||||
// Selected time range too big and step size too small?
|
||||
if (line.find("change step-size") != std::string::npos) {
|
||||
fileStream.close();
|
||||
return HorizonsResultCode::ErrorSize;
|
||||
}
|
||||
|
||||
// Selected time range too big for avalable time span?
|
||||
if (line.find("STEP_SIZE too big") != std::string::npos) {
|
||||
fileStream.close();
|
||||
return HorizonsResultCode::ErrorSpan;
|
||||
}
|
||||
|
||||
@@ -287,7 +287,6 @@ HorizonsResultCode isValidHorizonsFile(std::filesystem::path file) {
|
||||
if (line.find("No ephemeris for target") != std::string::npos) {
|
||||
// Available time range is located several lines before this in the file
|
||||
// The avalable time range is persed later
|
||||
fileStream.close();
|
||||
return HorizonsResultCode::ErrorTimeRange;
|
||||
}
|
||||
|
||||
@@ -295,19 +294,16 @@ HorizonsResultCode isValidHorizonsFile(std::filesystem::path file) {
|
||||
if (line.find("No site matches") != std::string::npos ||
|
||||
line.find("Cannot find central body") != std::string::npos)
|
||||
{
|
||||
fileStream.close();
|
||||
return HorizonsResultCode::ErrorNoObserver;
|
||||
}
|
||||
|
||||
// Are observer and target the same?
|
||||
if (line.find("disallowed") != std::string::npos) {
|
||||
fileStream.close();
|
||||
return HorizonsResultCode::ErrorObserverTargetSame;
|
||||
}
|
||||
|
||||
// Enough data?
|
||||
if (line.find("Insufficient ephemeris data") != std::string::npos) {
|
||||
fileStream.close();
|
||||
return HorizonsResultCode::ErrorNoData;
|
||||
}
|
||||
|
||||
@@ -337,7 +333,6 @@ HorizonsResultCode isValidHorizonsFile(std::filesystem::path file) {
|
||||
|
||||
// No Target?
|
||||
if (line.find("No matches found") != std::string::npos) {
|
||||
fileStream.close();
|
||||
return HorizonsResultCode::ErrorNoTarget;
|
||||
}
|
||||
|
||||
@@ -345,18 +340,15 @@ HorizonsResultCode isValidHorizonsFile(std::filesystem::path file) {
|
||||
}
|
||||
|
||||
if (result != HorizonsResultCode::UnknownError) {
|
||||
fileStream.close();
|
||||
return result;
|
||||
}
|
||||
|
||||
// If we reached end of file before we found the start of data then it is
|
||||
// not a valid file
|
||||
if (fileStream.good()) {
|
||||
fileStream.close();
|
||||
return HorizonsResultCode::Valid;
|
||||
}
|
||||
else {
|
||||
fileStream.close();
|
||||
return HorizonsResultCode::UnknownError;
|
||||
}
|
||||
}
|
||||
@@ -365,7 +357,7 @@ bool HorizonsFile::hasFile() const {
|
||||
return std::filesystem::is_regular_file(_file);
|
||||
}
|
||||
|
||||
void HorizonsFile::displayErrorMessage(const HorizonsResultCode code) const {
|
||||
void HorizonsFile::displayErrorMessage(HorizonsResultCode code) const {
|
||||
switch (code) {
|
||||
case HorizonsResultCode::Valid:
|
||||
return;
|
||||
@@ -395,8 +387,8 @@ void HorizonsFile::displayErrorMessage(const HorizonsResultCode code) const {
|
||||
}
|
||||
|
||||
LINFO(fmt::format(
|
||||
"Valid time range is '{}' to '{}'", validTimeRange.first,
|
||||
validTimeRange.second
|
||||
"Valid time range is '{}' to '{}'",
|
||||
validTimeRange.first, validTimeRange.second
|
||||
));
|
||||
break;
|
||||
}
|
||||
@@ -533,7 +525,7 @@ HorizonsResult readHorizonsVectorFile(std::filesystem::path file) {
|
||||
|
||||
std::ifstream fileStream(file);
|
||||
if (!fileStream.good()) {
|
||||
LERROR(fmt::format("Failed to open Horizons text file '{}'", file));
|
||||
LERROR(fmt::format("Failed to open Horizons text file {}", file));
|
||||
return HorizonsResult();
|
||||
}
|
||||
|
||||
@@ -589,7 +581,6 @@ HorizonsResult readHorizonsVectorFile(std::filesystem::path file) {
|
||||
|
||||
std::getline(fileStream, line);
|
||||
}
|
||||
fileStream.close();
|
||||
|
||||
result.data = data;
|
||||
return result;
|
||||
@@ -654,8 +645,6 @@ HorizonsResult readHorizonsObserverFile(std::filesystem::path file) {
|
||||
std::getline(fileStream, line);
|
||||
}
|
||||
|
||||
fileStream.close();
|
||||
|
||||
LWARNING(
|
||||
"Observer table data from Horizons might not align with SPICE data well. "
|
||||
"We recommend using Vector table data from Horizons instead"
|
||||
@@ -757,7 +746,6 @@ std::pair<std::string, std::string> HorizonsFile::parseValidTimeRange(
|
||||
std::ifstream fileStream(_file);
|
||||
|
||||
if (!fileStream.good()) {
|
||||
fileStream.close();
|
||||
return { "", "" };
|
||||
}
|
||||
|
||||
@@ -782,7 +770,6 @@ std::pair<std::string, std::string> HorizonsFile::parseValidTimeRange(
|
||||
}
|
||||
|
||||
if (!fileStream.good()) {
|
||||
fileStream.close();
|
||||
return { "", "" };
|
||||
}
|
||||
|
||||
@@ -823,7 +810,6 @@ std::pair<std::string, std::string> HorizonsFile::parseValidTimeRange(
|
||||
}
|
||||
}
|
||||
if (startTime.empty() || endTime.empty()) {
|
||||
fileStream.close();
|
||||
return { "", "" };
|
||||
}
|
||||
|
||||
@@ -831,7 +817,6 @@ std::pair<std::string, std::string> HorizonsFile::parseValidTimeRange(
|
||||
// Get the end time from the last trajectery
|
||||
while (fileStream.good()) {
|
||||
if (line.find(endPhrase) != std::string::npos || line.empty() || line == " ") {
|
||||
fileStream.close();
|
||||
return { startTime, endTime };
|
||||
}
|
||||
|
||||
@@ -861,7 +846,6 @@ std::pair<std::string, std::string> HorizonsFile::parseValidTimeRange(
|
||||
std::getline(fileStream, line);
|
||||
}
|
||||
|
||||
fileStream.close();
|
||||
return { "", "" };
|
||||
}
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ enum class HorizonsResultCode {
|
||||
Valid,
|
||||
Empty,
|
||||
|
||||
// Erros caught by the error field in the json output
|
||||
// Errors caught by the error field in the json output
|
||||
ErrorSize,
|
||||
ErrorSpan,
|
||||
ErrorTimeRange,
|
||||
@@ -73,7 +73,7 @@ enum class HorizonsResultCode {
|
||||
ErrorNoData,
|
||||
MultipleObserverStations,
|
||||
|
||||
// Erros/problems NOT caught by the error field in the json output
|
||||
// Errors/problems NOT caught by the error field in the json output
|
||||
MultipleObserver,
|
||||
ErrorNoTarget,
|
||||
MultipleTarget,
|
||||
@@ -95,21 +95,20 @@ struct HorizonsKeyframe {
|
||||
struct HorizonsResult {
|
||||
HorizonsType type = HorizonsType::Invalid;
|
||||
HorizonsResultCode errorCode = HorizonsResultCode::UnknownError;
|
||||
std::vector<HorizonsKeyframe> data = std::vector<HorizonsKeyframe>();
|
||||
std::vector<HorizonsKeyframe> data;
|
||||
};
|
||||
|
||||
class HorizonsFile {
|
||||
public:
|
||||
HorizonsFile() = default;
|
||||
HorizonsFile(std::filesystem::path file);
|
||||
HorizonsFile(std::filesystem::path filePath, const std::string& result);
|
||||
HorizonsFile(std::filesystem::path filePath, std::string result);
|
||||
|
||||
void setFile(std::filesystem::path file);
|
||||
const std::filesystem::path& file() const;
|
||||
std::filesystem::path& file();
|
||||
|
||||
bool hasFile() const;
|
||||
void displayErrorMessage(const HorizonsResultCode code) const;
|
||||
void displayErrorMessage(HorizonsResultCode code) const;
|
||||
|
||||
|
||||
std::vector<std::string> parseMatches(const std::string& startPhrase,
|
||||
|
||||
@@ -205,7 +205,11 @@ namespace {
|
||||
// 00-56 correspond to 2000-2056. We'll see each other again in 2057!
|
||||
|
||||
// 1,2. Get the full year and days
|
||||
auto [res, year, daysInYear] = scn::scan_tuple<int, double>(epoch, "{:2}{}");
|
||||
std::string e = epoch;
|
||||
if (e.find('.') == std::string::npos) {
|
||||
e += ".0";
|
||||
}
|
||||
auto [res, year, daysInYear] = scn::scan_tuple<int, double>(e, "{:2}{}");
|
||||
if (!res) {
|
||||
throw ghoul::RuntimeError(fmt::format("Error parsing epoch '{}'", epoch));
|
||||
}
|
||||
@@ -248,9 +252,14 @@ namespace {
|
||||
// 5. Adjust for the fact the epoch starts on 1st January at 12:00:00, not
|
||||
// midnight
|
||||
|
||||
std::string e = epoch;
|
||||
if (e.find('.') == std::string::npos) {
|
||||
// No . was found so the epoch was provided as an integer number (see #2551)
|
||||
e += ".0";
|
||||
}
|
||||
// 1, 2
|
||||
auto [res, year, monthNum, dayOfMonthNum, fractionOfDay] =
|
||||
scn::scan_tuple<int, int, int, double>(epoch, "{:4}{:2}{:2}{}");
|
||||
scn::scan_tuple<int, int, int, double>(e, "{:4}{:2}{:2}{}");
|
||||
if (!res) {
|
||||
throw ghoul::RuntimeError(fmt::format("Error parsing epoch '{}'", epoch));
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ std::vector<Parameters> readOmmFile(std::filesystem::path file);
|
||||
std::vector<Parameters> readSbdbFile(std::filesystem::path file);
|
||||
|
||||
/**
|
||||
* The different formats that the #readFile function is capable of loading
|
||||
* The different formats that the readFile function is capable of loading
|
||||
*/
|
||||
enum class Format {
|
||||
TLE,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user