mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-05-02 08:49:20 -05:00
Moving more documentation to use codegen (#1549)
- Make use of more codegen in more classes - Fix verifier for Color4Verifier
This commit is contained in:
@@ -62,36 +62,25 @@ namespace {
|
||||
"Determines the number of significant digits that are shown in the location text."
|
||||
};
|
||||
|
||||
struct [[codegen::Dictionary(DashboardItemGlobeLocation)]] Parameters {
|
||||
// [[codegen::verbatim(FontNameInfo.description)]]
|
||||
std::optional<std::string> fontName;
|
||||
|
||||
// [[codegen::verbatim(FontSizeInfo.description)]]
|
||||
std::optional<float> fontSize;
|
||||
|
||||
// [[codegen::verbatim(SignificantDigitsInfo.description)]]
|
||||
std::optional<int> significantDigits;
|
||||
};
|
||||
#include "dashboarditemglobelocation_codegen.cpp"
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation DashboardItemGlobeLocation::Documentation() {
|
||||
using namespace documentation;
|
||||
return {
|
||||
"DashboardItem Globe Location",
|
||||
"globebrowsing_dashboarditem_globelocation",
|
||||
{
|
||||
{
|
||||
FontNameInfo.identifier,
|
||||
new StringVerifier,
|
||||
Optional::Yes,
|
||||
FontNameInfo.description
|
||||
},
|
||||
{
|
||||
FontSizeInfo.identifier,
|
||||
new IntVerifier,
|
||||
Optional::Yes,
|
||||
FontSizeInfo.description
|
||||
},
|
||||
{
|
||||
SignificantDigitsInfo.identifier,
|
||||
new IntVerifier,
|
||||
Optional::Yes,
|
||||
SignificantDigitsInfo.description
|
||||
}
|
||||
}
|
||||
};
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "globebrowsing_dashboarditem_globelocation";
|
||||
return doc;
|
||||
}
|
||||
|
||||
DashboardItemGlobeLocation::DashboardItemGlobeLocation(
|
||||
@@ -102,30 +91,15 @@ DashboardItemGlobeLocation::DashboardItemGlobeLocation(
|
||||
, _significantDigits(SignificantDigitsInfo, 4, 1, 12)
|
||||
, _font(global::fontManager->font(KeyFontMono, 10))
|
||||
{
|
||||
documentation::testSpecificationAndThrow(
|
||||
Documentation(),
|
||||
dictionary,
|
||||
"DashboardItemGlobeLocation"
|
||||
);
|
||||
|
||||
if (dictionary.hasKey(FontNameInfo.identifier)) {
|
||||
_fontName = dictionary.value<std::string>(FontNameInfo.identifier);
|
||||
}
|
||||
if (dictionary.hasKey(FontSizeInfo.identifier)) {
|
||||
_fontSize = static_cast<float>(dictionary.value<double>(FontSizeInfo.identifier));
|
||||
}
|
||||
if (dictionary.hasKey(SignificantDigitsInfo.identifier)) {
|
||||
_significantDigits = static_cast<int>(
|
||||
dictionary.value<double>(SignificantDigitsInfo.identifier)
|
||||
);
|
||||
}
|
||||
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
_fontName = p.fontName.value_or(_fontName);
|
||||
_fontName.onChange([this]() {
|
||||
_font = global::fontManager->font(_fontName, _fontSize);
|
||||
});
|
||||
addProperty(_fontName);
|
||||
|
||||
_fontSize = p.fontSize.value_or(_fontSize);
|
||||
_fontSize.onChange([this]() {
|
||||
_font = global::fontManager->font(_fontName, _fontSize);
|
||||
});
|
||||
@@ -139,6 +113,7 @@ DashboardItemGlobeLocation::DashboardItemGlobeLocation(
|
||||
_significantDigits.value()
|
||||
);
|
||||
};
|
||||
_significantDigits = p.significantDigits.value_or(_significantDigits);
|
||||
_significantDigits.onChange(updateFormatString);
|
||||
addProperty(_significantDigits);
|
||||
updateFormatString();
|
||||
|
||||
@@ -42,14 +42,14 @@
|
||||
#include <ghoul/misc/profiling.h>
|
||||
#include <ghoul/opengl/programobject.h>
|
||||
#include <cstdlib>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <locale>
|
||||
#include <optional>
|
||||
|
||||
namespace {
|
||||
constexpr const char* _loggerCat = "GlobeLabels";
|
||||
|
||||
constexpr const char* KeyLabelsFileName = "FileName";
|
||||
|
||||
constexpr const double LabelFadeOutLimitAltitudeMeters = 25000.0;
|
||||
constexpr const double RangeAngularCoefConst = 0.8;
|
||||
constexpr const float MinOpacityValueConst = 0.009f;
|
||||
@@ -163,114 +163,72 @@ namespace {
|
||||
"Label Alignment Option",
|
||||
"Labels are aligned horizontally or circularly related to the planet."
|
||||
};
|
||||
|
||||
struct [[codegen::Dictionary(GlobeLabelsComponent)]] Parameters {
|
||||
// The path to the labels file
|
||||
std::optional<std::filesystem::path> fileName;
|
||||
|
||||
// [[codegen::verbatim(LabelsInfo.description)]]
|
||||
std::optional<bool> labels;
|
||||
|
||||
// [[codegen::verbatim(LabelsEnableInfo.description)]]
|
||||
std::optional<bool> enable;
|
||||
|
||||
// [[codegen::verbatim(LabelsFontSizeInfo.description)]]
|
||||
std::optional<float> labelsFontSize;
|
||||
|
||||
// [[codegen::verbatim(LabelsMinSizeInfo.description)]]
|
||||
std::optional<int> labelsMinSize;
|
||||
|
||||
// [[codegen::verbatim(LabelsMaxSizeInfo.description)]]
|
||||
std::optional<int> labelsMaxSize;
|
||||
|
||||
// [[codegen::verbatim(LabelsSizeInfo.description)]]
|
||||
std::optional<float> labelsSize;
|
||||
|
||||
// [[codegen::verbatim(LabelsMinHeightInfo.description)]]
|
||||
std::optional<float> labelsMinHeight;
|
||||
|
||||
// [[codegen::verbatim(LabelsColorInfo.description)]]
|
||||
std::optional<glm::vec3> labelsColor [[codegen::color()]];
|
||||
|
||||
// [[codegen::verbatim(LabelsOpacityInfo.description)]]
|
||||
std::optional<float> labelsOpacity [[codegen::inrange(0.f, 1.0)]];
|
||||
|
||||
// [[codegen::verbatim(LabelsFadeInStartingDistanceInfo.description)]]
|
||||
std::optional<float> fadeInStartingDistance;
|
||||
|
||||
// [[codegen::verbatim(LabelsFadeOutStartingDistanceInfo.description)]]
|
||||
std::optional<float> fadeOutStartingDistance;
|
||||
|
||||
// [[codegen::verbatim(LabelsFadeInEnabledInfo.description)]]
|
||||
std::optional<bool> labelsFadeInEnabled;
|
||||
|
||||
// [[codegen::verbatim(LabelsFadeOutEnabledInfo.description)]]
|
||||
std::optional<bool> labelsFadeOutEnabled;
|
||||
|
||||
// [[codegen::verbatim(LabelsDisableCullingEnabledInfo.description)]]
|
||||
std::optional<bool> labelsDisableCullingEnabled;
|
||||
|
||||
// [[codegen::verbatim(LabelsDistanceEPSInfo.description)]]
|
||||
std::optional<float> labelsDistanceEPS;
|
||||
|
||||
enum class Alignment {
|
||||
Horizontally,
|
||||
Circularly
|
||||
};
|
||||
// [[codegen::verbatim(LabelAlignmentOptionInfo.description)]]
|
||||
std::optional<Alignment> labelAlignmentOption;
|
||||
};
|
||||
#include "globelabelscomponent_codegen.cpp"
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation GlobeLabelsComponent::Documentation() {
|
||||
using namespace documentation;
|
||||
return {
|
||||
"GlobeLabels Component",
|
||||
"globebrowsing_globelabelscomponent",
|
||||
{
|
||||
{
|
||||
LabelsInfo.identifier,
|
||||
new BoolVerifier,
|
||||
Optional::Yes,
|
||||
LabelsInfo.description
|
||||
},
|
||||
{
|
||||
LabelsEnableInfo.identifier,
|
||||
new BoolVerifier,
|
||||
Optional::Yes,
|
||||
LabelsEnableInfo.description
|
||||
},
|
||||
{
|
||||
LabelsFontSizeInfo.identifier,
|
||||
new DoubleVerifier,
|
||||
Optional::Yes,
|
||||
LabelsFontSizeInfo.description
|
||||
},
|
||||
{
|
||||
LabelsMaxSizeInfo.identifier,
|
||||
new DoubleVerifier,
|
||||
Optional::Yes,
|
||||
LabelsMaxSizeInfo.description
|
||||
},
|
||||
{
|
||||
LabelsMinSizeInfo.identifier,
|
||||
new DoubleVerifier,
|
||||
Optional::Yes,
|
||||
LabelsMinSizeInfo.description
|
||||
},
|
||||
{
|
||||
LabelsSizeInfo.identifier,
|
||||
new DoubleVerifier,
|
||||
Optional::Yes,
|
||||
LabelsSizeInfo.description
|
||||
},
|
||||
{
|
||||
LabelsMinHeightInfo.identifier,
|
||||
new DoubleVerifier,
|
||||
Optional::Yes,
|
||||
LabelsMinHeightInfo.description
|
||||
},
|
||||
{
|
||||
LabelsColorInfo.identifier,
|
||||
new Color3Verifier,
|
||||
Optional::Yes,
|
||||
LabelsColorInfo.description
|
||||
},
|
||||
{
|
||||
LabelsOpacityInfo.identifier,
|
||||
new DoubleVerifier,
|
||||
Optional::Yes,
|
||||
LabelsOpacityInfo.description
|
||||
},
|
||||
{
|
||||
LabelsFadeInStartingDistanceInfo.identifier,
|
||||
new DoubleVerifier,
|
||||
Optional::Yes,
|
||||
LabelsFadeInStartingDistanceInfo.description
|
||||
},
|
||||
{
|
||||
LabelsFadeOutStartingDistanceInfo.identifier,
|
||||
new DoubleVerifier,
|
||||
Optional::Yes,
|
||||
LabelsFadeOutStartingDistanceInfo.description
|
||||
},
|
||||
{
|
||||
LabelsFadeInEnabledInfo.identifier,
|
||||
new BoolVerifier,
|
||||
Optional::Yes,
|
||||
LabelsFadeInEnabledInfo.description
|
||||
},
|
||||
{
|
||||
LabelsFadeOutEnabledInfo.identifier,
|
||||
new BoolVerifier,
|
||||
Optional::Yes,
|
||||
LabelsFadeOutEnabledInfo.description
|
||||
},
|
||||
{
|
||||
LabelsDisableCullingEnabledInfo.identifier,
|
||||
new BoolVerifier,
|
||||
Optional::Yes,
|
||||
LabelsDisableCullingEnabledInfo.description
|
||||
},
|
||||
{
|
||||
LabelsDistanceEPSInfo.identifier,
|
||||
new DoubleVerifier,
|
||||
Optional::Yes,
|
||||
LabelsDistanceEPSInfo.description
|
||||
},
|
||||
{
|
||||
LabelAlignmentOptionInfo.identifier,
|
||||
new StringVerifier,
|
||||
Optional::Yes,
|
||||
LabelAlignmentOptionInfo.description
|
||||
},
|
||||
}
|
||||
};
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "globebrowsing_globelabelscomponent";
|
||||
return doc;
|
||||
}
|
||||
|
||||
GlobeLabelsComponent::GlobeLabelsComponent()
|
||||
@@ -293,7 +251,7 @@ GlobeLabelsComponent::GlobeLabelsComponent()
|
||||
, _labelsFadeInEnabled(LabelsFadeInEnabledInfo, false)
|
||||
, _labelsFadeOutEnabled(LabelsFadeOutEnabledInfo, false)
|
||||
, _labelsDisableCullingEnabled(LabelsDisableCullingEnabledInfo, false)
|
||||
, _labelsDistaneEPS(LabelsDistanceEPSInfo, 100000.f, 1000.f, 10000000.f)
|
||||
, _labelsDistanceEPS(LabelsDistanceEPSInfo, 100000.f, 1000.f, 10000000.f)
|
||||
, _labelAlignmentOption(
|
||||
LabelAlignmentOptionInfo,
|
||||
properties::OptionProperty::DisplayType::Dropdown
|
||||
@@ -312,7 +270,7 @@ GlobeLabelsComponent::GlobeLabelsComponent()
|
||||
addProperty(_labelsFadeInEnabled);
|
||||
addProperty(_labelsFadeOutEnabled);
|
||||
addProperty(_labelsDisableCullingEnabled);
|
||||
addProperty(_labelsDistaneEPS);
|
||||
addProperty(_labelsDistanceEPS);
|
||||
|
||||
_labelAlignmentOption.addOption(Horizontally, "Horizontally");
|
||||
_labelAlignmentOption.addOption(Circularly, "Circularly");
|
||||
@@ -324,125 +282,45 @@ void GlobeLabelsComponent::initialize(const ghoul::Dictionary& dictionary,
|
||||
globebrowsing::RenderableGlobe* globe)
|
||||
{
|
||||
ZoneScoped
|
||||
|
||||
documentation::testSpecificationAndThrow(
|
||||
Documentation(),
|
||||
dictionary,
|
||||
"GlobeLabelsComponent"
|
||||
);
|
||||
|
||||
_globe = globe;
|
||||
|
||||
// Reads labels' file and build cache file if necessary
|
||||
if (dictionary.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (!dictionary.hasValue<std::string>(KeyLabelsFileName)) {
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
if (!p.fileName.has_value()) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string labelsFile = dictionary.value<std::string>(KeyLabelsFileName);
|
||||
bool loadSuccess = loadLabelsData(absPath(labelsFile));
|
||||
const bool loadSuccess = loadLabelsData(absPath(p.fileName->string()));
|
||||
if (!loadSuccess) {
|
||||
return;
|
||||
}
|
||||
if (dictionary.hasKey(LabelsEnableInfo.identifier)) {
|
||||
// In case of the label's dic is present but is disabled
|
||||
_labelsEnabled = dictionary.value<bool>(LabelsEnableInfo.identifier);
|
||||
}
|
||||
else {
|
||||
// Is the labels dic is enable in the configuration file,
|
||||
// enables the label automatically.
|
||||
_labelsEnabled = true;
|
||||
}
|
||||
|
||||
if (dictionary.hasKey(LabelsFontSizeInfo.identifier)) {
|
||||
_labelsFontSize = static_cast<float>(
|
||||
dictionary.value<double>(LabelsFontSizeInfo.identifier)
|
||||
);
|
||||
_labelsFontSize.onChange([this]() { initializeFonts(); });
|
||||
}
|
||||
_labelsEnabled = p.enable.value_or(true);
|
||||
_labelsFontSize = p.labelsFontSize.value_or(_labelsFontSize);
|
||||
_labelsFontSize.onChange([this]() { initializeFonts(); });
|
||||
_labelsSize = p.labelsSize.value_or(_labelsSize);
|
||||
_labelsMinHeight = p.labelsMinHeight.value_or(_labelsMinHeight);
|
||||
_labelsColor = p.labelsColor.value_or(_labelsColor);
|
||||
_labelsOpacity = p.labelsOpacity.value_or(_labelsOpacity);
|
||||
_labelsFadeInEnabled = p.labelsFadeInEnabled.value_or(_labelsFadeInEnabled);
|
||||
_labelsFadeInDist = p.fadeInStartingDistance.value_or(_labelsFadeInDist);
|
||||
_labelsFadeOutEnabled = p.labelsFadeOutEnabled.value_or(_labelsFadeOutEnabled);
|
||||
_labelsFadeOutDist = p.fadeOutStartingDistance.value_or(_labelsFadeOutDist);
|
||||
_labelsMinSize = p.labelsMinSize.value_or(_labelsMinSize);
|
||||
_labelsMaxSize = p.labelsMaxSize.value_or(_labelsMaxSize);
|
||||
_labelsDisableCullingEnabled =
|
||||
p.labelsDisableCullingEnabled.value_or(_labelsDisableCullingEnabled);
|
||||
_labelsDistanceEPS = p.labelsDistanceEPS.value_or(_labelsDistanceEPS);
|
||||
|
||||
if (dictionary.hasKey(LabelsSizeInfo.identifier)) {
|
||||
_labelsSize = static_cast<float>(
|
||||
dictionary.value<double>(LabelsSizeInfo.identifier)
|
||||
);
|
||||
}
|
||||
|
||||
if (dictionary.hasKey(LabelsMinHeightInfo.identifier)) {
|
||||
_labelsMinHeight = static_cast<float>(
|
||||
dictionary.value<double>(LabelsMinHeightInfo.identifier)
|
||||
);
|
||||
}
|
||||
|
||||
if (dictionary.hasKey(LabelsColorInfo.identifier)) {
|
||||
_labelsColor = dictionary.value<glm::dvec3>(LabelsColorInfo.identifier);
|
||||
}
|
||||
|
||||
if (dictionary.hasKey(LabelsOpacityInfo.identifier)) {
|
||||
_labelsOpacity = static_cast<float>(
|
||||
dictionary.value<double>(LabelsOpacityInfo.identifier)
|
||||
);
|
||||
}
|
||||
|
||||
if (dictionary.hasKey(LabelsFadeInEnabledInfo.identifier)) {
|
||||
_labelsFadeInEnabled = dictionary.value<bool>(LabelsFadeInEnabledInfo.identifier);
|
||||
}
|
||||
|
||||
if (dictionary.hasKey(LabelsFadeInStartingDistanceInfo.identifier)) {
|
||||
_labelsFadeInDist = static_cast<float>(
|
||||
dictionary.value<double>(LabelsFadeInStartingDistanceInfo.identifier)
|
||||
);
|
||||
}
|
||||
|
||||
if (dictionary.hasKey(LabelsFadeOutEnabledInfo.identifier)) {
|
||||
_labelsFadeOutEnabled = dictionary.value<bool>(
|
||||
LabelsFadeOutEnabledInfo.identifier
|
||||
);
|
||||
}
|
||||
|
||||
if (dictionary.hasKey(LabelsFadeOutStartingDistanceInfo.identifier)) {
|
||||
_labelsFadeOutDist = static_cast<float>(
|
||||
dictionary.value<double>(LabelsFadeOutStartingDistanceInfo.identifier)
|
||||
);
|
||||
}
|
||||
|
||||
if (dictionary.hasKey(LabelsMinSizeInfo.identifier)) {
|
||||
_labelsMinSize = static_cast<int>(
|
||||
dictionary.value<double>(LabelsMinSizeInfo.identifier)
|
||||
);
|
||||
}
|
||||
|
||||
if (dictionary.hasKey(LabelsMaxSizeInfo.identifier)) {
|
||||
_labelsMaxSize = static_cast<int>(
|
||||
dictionary.value<double>(LabelsMaxSizeInfo.identifier)
|
||||
);
|
||||
}
|
||||
|
||||
if (dictionary.hasKey(LabelsDisableCullingEnabledInfo.identifier)) {
|
||||
bool disabled = dictionary.value<bool>(
|
||||
LabelsDisableCullingEnabledInfo.identifier
|
||||
);
|
||||
_labelsDisableCullingEnabled = disabled;
|
||||
}
|
||||
|
||||
if (dictionary.hasKey(LabelsDistanceEPSInfo.identifier)) {
|
||||
_labelsDistaneEPS = static_cast<float>(
|
||||
dictionary.value<double>(LabelsDistanceEPSInfo.identifier)
|
||||
);
|
||||
}
|
||||
|
||||
if (dictionary.hasKey(LabelAlignmentOptionInfo.identifier)) {
|
||||
std::string alignment =
|
||||
dictionary.value<std::string>(LabelAlignmentOptionInfo.identifier);
|
||||
if (alignment == "Horizontally") {
|
||||
_labelAlignmentOption = Horizontally;
|
||||
}
|
||||
else if (alignment == "Circularly" ) {
|
||||
_labelAlignmentOption = Circularly;
|
||||
}
|
||||
else {
|
||||
LERROR("Unknown alignment option: " + alignment);
|
||||
if (p.labelAlignmentOption.has_value()) {
|
||||
switch (*p.labelAlignmentOption) {
|
||||
case Parameters::Alignment::Horizontally:
|
||||
_labelAlignmentOption = Horizontally;
|
||||
break;
|
||||
case Parameters::Alignment::Circularly:
|
||||
_labelAlignmentOption = Circularly;
|
||||
break;
|
||||
default:
|
||||
throw ghoul::MissingCaseException();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -732,7 +610,7 @@ void GlobeLabelsComponent::renderLabels(const RenderData& data,
|
||||
glm::length(locationPositionWorld - data.camera.positionVec3());
|
||||
|
||||
if (_labelsDisableCullingEnabled ||
|
||||
((distToCamera > (distanceCameraToLabelWorld + _labelsDistaneEPS)) &&
|
||||
((distToCamera > (distanceCameraToLabelWorld + _labelsDistanceEPS)) &&
|
||||
isLabelInFrustum(VP, locationPositionWorld)))
|
||||
{
|
||||
if (_labelAlignmentOption == Circularly) {
|
||||
|
||||
@@ -96,7 +96,7 @@ private:
|
||||
properties::BoolProperty _labelsFadeInEnabled;
|
||||
properties::BoolProperty _labelsFadeOutEnabled;
|
||||
properties::BoolProperty _labelsDisableCullingEnabled;
|
||||
properties::FloatProperty _labelsDistaneEPS;
|
||||
properties::FloatProperty _labelsDistanceEPS;
|
||||
properties::OptionProperty _labelAlignmentOption;
|
||||
|
||||
private:
|
||||
|
||||
@@ -74,51 +74,33 @@ namespace {
|
||||
"as an offset from the heightmap. Otherwise, it will be an offset from the "
|
||||
"globe's reference ellipsoid. The default value is 'false'."
|
||||
};
|
||||
|
||||
struct [[codegen::Dictionary(GlobeTranslation)]] Parameters {
|
||||
// [[codegen::verbatim(GlobeInfo.description)]]
|
||||
std::string globe
|
||||
[[codegen::annotation("A valid scene graph node with a RenderableGlobe")]];
|
||||
|
||||
// [[codegen::verbatim(LongitudeInfo.description)]]
|
||||
std::optional<double> longitude;
|
||||
|
||||
// [[codegen::verbatim(LatitudeInfo.description)]]
|
||||
std::optional<double> latitude;
|
||||
|
||||
// [[codegen::verbatim(AltitudeInfo.description)]]
|
||||
std::optional<double> altitude;
|
||||
|
||||
// [[codegen::verbatim(UseHeightmapInfo.description)]]
|
||||
std::optional<bool> useHeightmap;
|
||||
};
|
||||
#include "globetranslation_codegen.cpp"
|
||||
} // namespace
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
documentation::Documentation GlobeTranslation::Documentation() {
|
||||
using namespace openspace::documentation;
|
||||
|
||||
return {
|
||||
"Globe Translation",
|
||||
"space_translation_globetranslation",
|
||||
{
|
||||
{
|
||||
GlobeInfo.identifier,
|
||||
new StringAnnotationVerifier(
|
||||
"A valid scene graph node with a RenderableGlobe"
|
||||
),
|
||||
Optional::No,
|
||||
GlobeInfo.description
|
||||
},
|
||||
{
|
||||
LongitudeInfo.identifier,
|
||||
new DoubleVerifier,
|
||||
Optional::Yes,
|
||||
LongitudeInfo.description
|
||||
},
|
||||
{
|
||||
LatitudeInfo.identifier,
|
||||
new DoubleVerifier,
|
||||
Optional::Yes,
|
||||
LatitudeInfo.description,
|
||||
},
|
||||
{
|
||||
AltitudeInfo.identifier,
|
||||
new DoubleVerifier,
|
||||
Optional::Yes,
|
||||
AltitudeInfo.description
|
||||
},
|
||||
{
|
||||
UseHeightmapInfo.identifier,
|
||||
new BoolVerifier,
|
||||
Optional::Yes,
|
||||
UseHeightmapInfo.description
|
||||
}
|
||||
}
|
||||
};
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "space_translation_globetranslation";
|
||||
return doc;
|
||||
}
|
||||
|
||||
GlobeTranslation::GlobeTranslation(const ghoul::Dictionary& dictionary)
|
||||
@@ -128,39 +110,28 @@ GlobeTranslation::GlobeTranslation(const ghoul::Dictionary& dictionary)
|
||||
, _altitude(AltitudeInfo, 0.0, 0.0, 1e12)
|
||||
, _useHeightmap(UseHeightmapInfo, false)
|
||||
{
|
||||
documentation::testSpecificationAndThrow(
|
||||
Documentation(),
|
||||
dictionary,
|
||||
"GlobeTranslation"
|
||||
);
|
||||
|
||||
_globe = dictionary.value<std::string>(GlobeInfo.identifier);
|
||||
if (dictionary.hasKey(LongitudeInfo.identifier)) {
|
||||
_longitude = dictionary.value<double>(LongitudeInfo.identifier);
|
||||
}
|
||||
if (dictionary.hasKey(LatitudeInfo.identifier)) {
|
||||
_latitude = dictionary.value<double>(LatitudeInfo.identifier);
|
||||
}
|
||||
if (dictionary.hasKey(AltitudeInfo.identifier)) {
|
||||
_altitude = dictionary.value<double>(AltitudeInfo.identifier);
|
||||
}
|
||||
if (dictionary.hasKey(UseHeightmapInfo.identifier)) {
|
||||
_useHeightmap = dictionary.value<bool>(UseHeightmapInfo.identifier);
|
||||
}
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
_globe = p.globe;
|
||||
_globe.onChange([this]() {
|
||||
fillAttachedNode();
|
||||
_positionIsDirty = true;
|
||||
});
|
||||
|
||||
_longitude = p.longitude.value_or(_longitude);
|
||||
_longitude.onChange([this]() { _positionIsDirty = true; });
|
||||
_latitude.onChange([this]() { _positionIsDirty = true; });
|
||||
_altitude.onChange([this]() { _positionIsDirty = true; });
|
||||
_useHeightmap.onChange([this]() { _positionIsDirty = true; });
|
||||
|
||||
addProperty(_longitude);
|
||||
|
||||
_latitude = p.latitude.value_or(_latitude);
|
||||
_latitude.onChange([this]() { _positionIsDirty = true; });
|
||||
addProperty(_latitude);
|
||||
|
||||
_altitude = p.altitude.value_or(_altitude);
|
||||
_altitude.onChange([this]() { _positionIsDirty = true; });
|
||||
addProperty(_altitude);
|
||||
|
||||
_useHeightmap = p.useHeightmap.value_or(_useHeightmap);
|
||||
_useHeightmap.onChange([this]() { _positionIsDirty = true; });
|
||||
addProperty(_useHeightmap);
|
||||
}
|
||||
|
||||
|
||||
@@ -26,12 +26,9 @@
|
||||
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/documentation/verifier.h>
|
||||
#include <optional>
|
||||
|
||||
namespace {
|
||||
constexpr const char* KeyType = "Type";
|
||||
constexpr const char* KeyChromaKeyColor = "ChromaKeyColor";
|
||||
constexpr const char* KeyChromaKeyTolerance = "ChromaKeyTolerance";
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo ChromaKeyColorInfo = {
|
||||
"ChromaKeyColor",
|
||||
"Chroma Key Color",
|
||||
@@ -50,37 +47,32 @@ namespace {
|
||||
"Type",
|
||||
"The type of layer adjustment that is applied to the underlying layer."
|
||||
};
|
||||
|
||||
struct [[codegen::Dictionary(LayerAdjustment)]] Parameters {
|
||||
enum class Type {
|
||||
None,
|
||||
ChromaKey,
|
||||
TransferFunction
|
||||
};
|
||||
// Specifies the type of the adjustment that is applied
|
||||
std::optional<Type> type;
|
||||
|
||||
// Specifies the chroma key used when selecting 'ChromaKey' for the 'Type'
|
||||
std::optional<glm::vec3> chromaKeyColor [[codegen::color()]];
|
||||
|
||||
// Specifies the tolerance to match the color to the chroma key when the
|
||||
// 'ChromaKey' type is selected for the 'Type'
|
||||
std::optional<float> chromaKeyTolerance;
|
||||
};
|
||||
#include "layeradjustment_codegen.cpp"
|
||||
} // namespace
|
||||
|
||||
namespace openspace::globebrowsing {
|
||||
|
||||
documentation::Documentation LayerAdjustment::Documentation() {
|
||||
using namespace documentation;
|
||||
return {
|
||||
"LayerAdjustment",
|
||||
"globebrowsing_layeradjustment",
|
||||
{
|
||||
{
|
||||
KeyType,
|
||||
new StringInListVerifier({ "None", "ChromaKey", "TransferFunction" }),
|
||||
Optional::Yes,
|
||||
"Specifies the type of the adjustment that is applied"
|
||||
},
|
||||
{
|
||||
KeyChromaKeyColor,
|
||||
new Color3Verifier,
|
||||
Optional::Yes,
|
||||
"Specifies the chroma key used when selecting 'ChromaKey' for the 'Type'."
|
||||
},
|
||||
{
|
||||
KeyChromaKeyTolerance,
|
||||
new DoubleVerifier,
|
||||
Optional::Yes,
|
||||
"Specifies the tolerance to match the color to the chroma key when the "
|
||||
"'ChromaKey' type is selected for the 'Type'."
|
||||
}
|
||||
}
|
||||
};
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "globebrowsing_layeradjustment";
|
||||
return doc;
|
||||
}
|
||||
|
||||
LayerAdjustment::LayerAdjustment()
|
||||
@@ -121,31 +113,27 @@ LayerAdjustment::LayerAdjustment()
|
||||
}
|
||||
|
||||
void LayerAdjustment::setValuesFromDictionary(const ghoul::Dictionary& adjustmentDict) {
|
||||
documentation::testSpecificationAndThrow(
|
||||
Documentation(),
|
||||
adjustmentDict,
|
||||
"LayerAdjustment"
|
||||
);
|
||||
const Parameters p = codegen::bake<Parameters>(adjustmentDict);
|
||||
|
||||
if (adjustmentDict.hasValue<std::string>(KeyType)) {
|
||||
std::string dictType = adjustmentDict.value<std::string>(KeyType);
|
||||
_typeOption = static_cast<int>(
|
||||
ghoul::from_string<layergroupid::AdjustmentTypeID>(dictType)
|
||||
);
|
||||
if (p.type.has_value()) {
|
||||
switch (*p.type) {
|
||||
case Parameters::Type::None:
|
||||
_typeOption = static_cast<int>(layergroupid::AdjustmentTypeID::None);
|
||||
break;
|
||||
case Parameters::Type::ChromaKey:
|
||||
_typeOption = static_cast<int>(layergroupid::AdjustmentTypeID::ChromaKey);
|
||||
break;
|
||||
case Parameters::Type::TransferFunction:
|
||||
_typeOption =
|
||||
static_cast<int>(layergroupid::AdjustmentTypeID::TransferFunction);
|
||||
break;
|
||||
default:
|
||||
throw ghoul::MissingCaseException();
|
||||
}
|
||||
}
|
||||
|
||||
if (adjustmentDict.hasValue<glm::dvec3>(KeyChromaKeyColor)) {
|
||||
glm::vec3 dictChromaKeyColor =
|
||||
adjustmentDict.value<glm::dvec3>(KeyChromaKeyColor);
|
||||
_chromaKeyColor = std::move(dictChromaKeyColor);
|
||||
}
|
||||
|
||||
if (adjustmentDict.hasValue<double>(KeyChromaKeyTolerance)) {
|
||||
float dictChromaKeyTolerance = static_cast<float>(
|
||||
adjustmentDict.value<double>(KeyChromaKeyTolerance)
|
||||
);
|
||||
_chromaKeyTolerance = dictChromaKeyTolerance;
|
||||
}
|
||||
_chromaKeyColor = p.chromaKeyColor.value_or(_chromaKeyColor);
|
||||
_chromaKeyTolerance = p.chromaKeyTolerance.value_or(_chromaKeyTolerance);
|
||||
}
|
||||
|
||||
layergroupid::AdjustmentTypeID LayerAdjustment::type() const {
|
||||
|
||||
@@ -79,11 +79,6 @@ namespace {
|
||||
bool isShadowing = false;
|
||||
};
|
||||
|
||||
constexpr const char* KeyRadii = "Radii";
|
||||
constexpr const char* KeyLayers = "Layers";
|
||||
constexpr const char* KeyShadowGroup = "ShadowGroup";
|
||||
constexpr const char* KeyLabels = "Labels";
|
||||
|
||||
const openspace::globebrowsing::AABB3 CullingFrustum{
|
||||
glm::vec3(-1.f, -1.f, 0.f),
|
||||
glm::vec3( 1.f, 1.f, 1e35)
|
||||
@@ -232,6 +227,47 @@ namespace {
|
||||
"This is the number of currently active layers, if this value reaches the "
|
||||
"maximum, bad things will happen."
|
||||
};
|
||||
|
||||
struct [[codegen::Dictionary(RenderableGlobe)]] Parameters {
|
||||
// Specifies the radii for this planet. If the Double version of this is used, all
|
||||
// three radii are assumed to be equal
|
||||
std::optional<std::variant<glm::dvec3, double>> radii;
|
||||
|
||||
// Specifies whether the planet should be shaded by the primary light source or
|
||||
// not. If it is disabled, all parts of the planet are illuminated
|
||||
std::optional<bool> performShading;
|
||||
|
||||
// A list of all the layers that should be added
|
||||
std::map<std::string, ghoul::Dictionary> layers
|
||||
[[codegen::reference("globebrowsing_layermanager")]];
|
||||
|
||||
// Specifies information about planetary labels that can be rendered on the
|
||||
// object's surface
|
||||
std::optional<ghoul::Dictionary> labels
|
||||
[[codegen::reference("globebrowsing_globelabelscomponent")]];
|
||||
|
||||
struct ShadowGroup {
|
||||
struct Source {
|
||||
std::string name;
|
||||
double radius;
|
||||
};
|
||||
std::vector<Source> sources;
|
||||
|
||||
struct Caster {
|
||||
std::string name;
|
||||
double radius;
|
||||
};
|
||||
std::vector<Caster> casters;
|
||||
};
|
||||
std::optional<ShadowGroup> shadowGroup;
|
||||
|
||||
std::optional<ghoul::Dictionary> rings
|
||||
[[codegen::reference("globebrowsing_rings_component")]];
|
||||
|
||||
std::optional<ghoul::Dictionary> shadows
|
||||
[[codegen::reference("globebrowsing_shadows_component")]];
|
||||
};
|
||||
#include "renderableglobe_codegen.cpp"
|
||||
} // namespace
|
||||
|
||||
using namespace openspace::properties;
|
||||
@@ -461,48 +497,9 @@ Chunk::Chunk(const TileIndex& ti)
|
||||
{}
|
||||
|
||||
documentation::Documentation RenderableGlobe::Documentation() {
|
||||
using namespace documentation;
|
||||
return {
|
||||
"RenderableGlobe",
|
||||
"globebrowsing_renderableglobe",
|
||||
{
|
||||
{
|
||||
KeyRadii,
|
||||
new OrVerifier({ new DoubleVector3Verifier, new DoubleVerifier }),
|
||||
Optional::Yes,
|
||||
"Specifies the radii for this planet. If the Double version of this is "
|
||||
"used, all three radii are assumed to be equal."
|
||||
},
|
||||
{
|
||||
"PerformShading",
|
||||
new BoolVerifier,
|
||||
Optional::Yes,
|
||||
"Specifies whether the planet should be shaded by the primary light "
|
||||
"source or not. If it is disabled, all parts of the planet are "
|
||||
"illuminated."
|
||||
},
|
||||
{
|
||||
KeyLayers,
|
||||
new TableVerifier({
|
||||
{
|
||||
"*",
|
||||
new ReferencingVerifier("globebrowsing_layermanager"),
|
||||
Optional::Yes,
|
||||
"Descriptions of the individual layer groups"
|
||||
}
|
||||
}),
|
||||
Optional::Yes,
|
||||
"A list of all the layers that should be added"
|
||||
},
|
||||
{
|
||||
KeyLabels,
|
||||
new ReferencingVerifier("globebrowsing_globelabelscomponent"),
|
||||
Optional::Yes,
|
||||
"Specifies information about planetary labels that can be rendered on "
|
||||
"the object's surface."
|
||||
}
|
||||
}
|
||||
};
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "globebrowsing_renderableglobe";
|
||||
return doc;
|
||||
}
|
||||
|
||||
RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary)
|
||||
@@ -539,75 +536,52 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary)
|
||||
, _ringsComponent(dictionary)
|
||||
, _shadowComponent(dictionary)
|
||||
{
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
_generalProperties.currentLodScaleFactor.setReadOnly(true);
|
||||
|
||||
// Read the radii in to its own dictionary
|
||||
if (dictionary.hasValue<glm::dvec3>(KeyRadii)) {
|
||||
_ellipsoid = Ellipsoid(dictionary.value<glm::dvec3>(KeyRadii));
|
||||
setBoundingSphere(static_cast<float>(_ellipsoid.maximumRadius()));
|
||||
}
|
||||
else if (dictionary.hasValue<double>(KeyRadii)) {
|
||||
const double radius = dictionary.value<double>(KeyRadii);
|
||||
_ellipsoid = Ellipsoid({ radius, radius, radius });
|
||||
setBoundingSphere(static_cast<float>(_ellipsoid.maximumRadius()));
|
||||
if (p.radii.has_value()) {
|
||||
if (std::holds_alternative<glm::dvec3>(*p.radii)) {
|
||||
_ellipsoid = Ellipsoid(std::get<glm::dvec3>(*p.radii));
|
||||
setBoundingSphere(static_cast<float>(_ellipsoid.maximumRadius()));
|
||||
}
|
||||
else if (std::holds_alternative<double>(*p.radii)) {
|
||||
const double radius = std::get<double>(*p.radii);
|
||||
_ellipsoid = Ellipsoid({ radius, radius, radius });
|
||||
setBoundingSphere(static_cast<float>(_ellipsoid.maximumRadius()));
|
||||
}
|
||||
else {
|
||||
throw ghoul::MissingCaseException();
|
||||
}
|
||||
}
|
||||
|
||||
if (dictionary.hasKey("PerformShading")) {
|
||||
_generalProperties.performShading = dictionary.value<bool>("PerformShading");
|
||||
}
|
||||
_generalProperties.performShading =
|
||||
p.performShading.value_or(_generalProperties.performShading);
|
||||
|
||||
|
||||
// Init layer manager
|
||||
ghoul::Dictionary layersDictionary;
|
||||
if (!dictionary.hasValue<ghoul::Dictionary>(KeyLayers)) {
|
||||
throw ghoul::RuntimeError(std::string(KeyLayers) + " must be specified");
|
||||
}
|
||||
layersDictionary = dictionary.value<ghoul::Dictionary>(KeyLayers);
|
||||
|
||||
// @TODO (abock, 2021-03-25) The layermanager should be changed to take a
|
||||
// std::map<std::string, ghoul::Dictionary> instead and then we don't need to get it
|
||||
// as a bare dictionary anymore and can use the value from the struct directly
|
||||
ghoul::Dictionary layersDictionary = dictionary.value<ghoul::Dictionary>("Layers");
|
||||
_layerManager.initialize(layersDictionary);
|
||||
|
||||
addProperty(_generalProperties.performShading);
|
||||
addProperty(_generalProperties.useAccurateNormals);
|
||||
|
||||
// ================================================================
|
||||
// ======== Reads Shadow (Eclipses) Entries in asset file =========
|
||||
// ================================================================
|
||||
if (dictionary.hasValue<ghoul::Dictionary>(KeyShadowGroup)) {
|
||||
ghoul::Dictionary shadowDictionary =
|
||||
dictionary.value<ghoul::Dictionary>(KeyShadowGroup);
|
||||
|
||||
std::vector<std::pair<std::string, double>> sourceArray;
|
||||
ghoul::Dictionary sources = shadowDictionary.value<ghoul::Dictionary>("Sources");
|
||||
for (std::string_view k : sources.keys()) {
|
||||
ghoul::Dictionary source = sources.value<ghoul::Dictionary>(k);
|
||||
|
||||
std::string name = source.value<std::string>("Name");
|
||||
double radius = source.value<double>("Radius");
|
||||
sourceArray.emplace_back(name, radius);
|
||||
}
|
||||
|
||||
std::vector<std::pair<std::string, double>> casterArray;
|
||||
ghoul::Dictionary casters = shadowDictionary.value<ghoul::Dictionary>("Casters");
|
||||
for (std::string_view k : casters.keys()) {
|
||||
ghoul::Dictionary caster = casters.value<ghoul::Dictionary>(k);
|
||||
|
||||
std::string name = caster.value<std::string>("Name");
|
||||
double radius = caster.value<double>("Radius");
|
||||
casterArray.emplace_back(name, radius);
|
||||
}
|
||||
|
||||
if (p.shadowGroup.has_value()) {
|
||||
std::vector<Ellipsoid::ShadowConfiguration> shadowConfArray;
|
||||
for (const std::pair<std::string, double>& source : sourceArray) {
|
||||
for (const std::pair<std::string, double>& caster : casterArray) {
|
||||
for (const Parameters::ShadowGroup::Source& source : p.shadowGroup->sources) {
|
||||
for (const Parameters::ShadowGroup::Caster& caster : p.shadowGroup->casters) {
|
||||
Ellipsoid::ShadowConfiguration sc;
|
||||
sc.source = source;
|
||||
sc.caster = caster;
|
||||
sc.source = std::pair<std::string, double>(source.name, source.radius);
|
||||
sc.caster = std::pair<std::string, double>(source.name, source.radius);
|
||||
shadowConfArray.push_back(sc);
|
||||
}
|
||||
}
|
||||
_ellipsoid.setShadowConfigurationArray(shadowConfArray);
|
||||
}
|
||||
|
||||
if (!_ellipsoid.shadowConfigurationArray().empty()) {
|
||||
addProperty(_generalProperties.eclipseShadowsEnabled);
|
||||
addProperty(_generalProperties.eclipseHardShadows);
|
||||
}
|
||||
@@ -667,22 +641,20 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary)
|
||||
_localChunkBuffer.resize(2048);
|
||||
_traversalMemory.resize(512);
|
||||
|
||||
// Labels Dictionary
|
||||
if (dictionary.hasValue<ghoul::Dictionary>(KeyLabels)) {
|
||||
_labelsDictionary = dictionary.value<ghoul::Dictionary>(KeyLabels);
|
||||
}
|
||||
_labelsDictionary = p.labels.value_or(_labelsDictionary);
|
||||
|
||||
|
||||
// Components
|
||||
if (dictionary.hasValue<ghoul::Dictionary>("Rings")) {
|
||||
_hasRings = p.rings.has_value();
|
||||
if (_hasRings) {
|
||||
_ringsComponent.initialize();
|
||||
addPropertySubOwner(_ringsComponent);
|
||||
_hasRings = true;
|
||||
}
|
||||
|
||||
if (dictionary.hasKey("Shadows")) {
|
||||
_hasShadows = p.shadows.has_value();
|
||||
if (_hasShadows) {
|
||||
_shadowComponent.initialize();
|
||||
addPropertySubOwner(_shadowComponent);
|
||||
_hasShadows = true;
|
||||
_generalProperties.shadowMapping = true;
|
||||
}
|
||||
_generalProperties.shadowMapping.onChange(notifyShaderRecompilation);
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
#include <ghoul/opengl/texture.h>
|
||||
#include <ghoul/opengl/textureunit.h>
|
||||
#include <ghoul/io/texture/texturereader.h>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <cstdlib>
|
||||
#include <locale>
|
||||
@@ -155,90 +156,53 @@ namespace {
|
||||
"The number of samples used during shadow mapping calculation "
|
||||
"(Percentage Closer Filtering)."
|
||||
};
|
||||
|
||||
struct [[codegen::Dictionary(RingsComponent)]] Parameters {
|
||||
// [[codegen::verbatim(TextureInfo.description)]]
|
||||
std::optional<std::filesystem::path> texture;
|
||||
|
||||
// [[codegen::verbatim(TextureFwrdInfo.description)]]
|
||||
std::optional<std::filesystem::path> textureFwrd;
|
||||
|
||||
// [[codegen::verbatim(TextureBckwrdInfo.description)]]
|
||||
std::optional<std::filesystem::path> textureBckwrd;
|
||||
|
||||
// [[codegen::verbatim(TextureUnlitInfo.description)]]
|
||||
std::optional<std::filesystem::path> textureUnlit;
|
||||
|
||||
// [[codegen::verbatim(TextureColorInfo.description)]]
|
||||
std::optional<std::filesystem::path> textureColor;
|
||||
|
||||
// [[codegen::verbatim(TextureTransparencyInfo.description)]]
|
||||
std::optional<std::filesystem::path> textureTransparency;
|
||||
|
||||
// [[codegen::verbatim(SizeInfo.description)]]
|
||||
std::optional<float> size;
|
||||
|
||||
// [[codegen::verbatim(OffsetInfo.description)]]
|
||||
std::optional<glm::vec2> offset;
|
||||
|
||||
// [[codegen::verbatim(NightFactorInfo.description)]]
|
||||
std::optional<float> nightFactor;
|
||||
|
||||
// [[codegen::verbatim(ColorFilterInfo.description)]]
|
||||
std::optional<float> colorFilter;
|
||||
|
||||
// [[codegen::verbatim(ZFightingPercentageInfo.description)]]
|
||||
std::optional<float> zFightingPercentage;
|
||||
|
||||
// [[codegen::verbatim(NumberShadowSamplesInfo.description)]]
|
||||
std::optional<int> numberShadowSamples;
|
||||
};
|
||||
#include "ringscomponent_codegen.cpp"
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation RingsComponent::Documentation() {
|
||||
using namespace documentation;
|
||||
return {
|
||||
"Rings Component",
|
||||
"globebrowsing_rings_component",
|
||||
{
|
||||
{
|
||||
TextureInfo.identifier,
|
||||
new StringVerifier,
|
||||
Optional::Yes,
|
||||
TextureInfo.description
|
||||
},
|
||||
{
|
||||
TextureFwrdInfo.identifier,
|
||||
new StringVerifier,
|
||||
Optional::Yes,
|
||||
TextureFwrdInfo.description
|
||||
},
|
||||
{
|
||||
TextureBckwrdInfo.identifier,
|
||||
new StringVerifier,
|
||||
Optional::Yes,
|
||||
TextureBckwrdInfo.description
|
||||
},
|
||||
{
|
||||
TextureUnlitInfo.identifier,
|
||||
new StringVerifier,
|
||||
Optional::Yes,
|
||||
TextureUnlitInfo.description
|
||||
},
|
||||
{
|
||||
TextureColorInfo.identifier,
|
||||
new StringVerifier,
|
||||
Optional::Yes,
|
||||
TextureColorInfo.description
|
||||
},
|
||||
{
|
||||
TextureTransparencyInfo.identifier,
|
||||
new StringVerifier,
|
||||
Optional::Yes,
|
||||
TextureTransparencyInfo.description
|
||||
},
|
||||
{
|
||||
SizeInfo.identifier,
|
||||
new DoubleVerifier,
|
||||
Optional::Yes,
|
||||
SizeInfo.description
|
||||
},
|
||||
{
|
||||
OffsetInfo.identifier,
|
||||
new DoubleVector2Verifier,
|
||||
Optional::Yes,
|
||||
OffsetInfo.description
|
||||
},
|
||||
{
|
||||
NightFactorInfo.identifier,
|
||||
new DoubleVerifier,
|
||||
Optional::Yes,
|
||||
NightFactorInfo.description
|
||||
},
|
||||
{
|
||||
ColorFilterInfo.identifier,
|
||||
new DoubleVerifier,
|
||||
Optional::Yes,
|
||||
ColorFilterInfo.description
|
||||
},
|
||||
{
|
||||
ZFightingPercentageInfo.identifier,
|
||||
new DoubleVerifier,
|
||||
Optional::Yes,
|
||||
ZFightingPercentageInfo.description
|
||||
},
|
||||
{
|
||||
NumberShadowSamplesInfo.identifier,
|
||||
new IntVerifier,
|
||||
Optional::Yes,
|
||||
NumberShadowSamplesInfo.description
|
||||
}
|
||||
}
|
||||
};
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "globebrowsing_rings_component";
|
||||
return doc;
|
||||
}
|
||||
|
||||
RingsComponent::RingsComponent(const ghoul::Dictionary& dictionary)
|
||||
@@ -265,14 +229,17 @@ RingsComponent::RingsComponent(const ghoul::Dictionary& dictionary)
|
||||
// term and rather extract the values directly here. This would require a bit of
|
||||
// a rewrite in the RenderableGlobe class to not create the RingsComponent in the
|
||||
// class-initializer list though
|
||||
// @TODO (abock, 2021-03-25) Righto! The RenderableGlobe passes this dictionary
|
||||
// in as-is so it would be easy to just pass it directly to the initialize method
|
||||
// instead
|
||||
_ringsDictionary = dictionary.value<ghoul::Dictionary>("Rings");
|
||||
}
|
||||
|
||||
documentation::testSpecificationAndThrow(
|
||||
Documentation(),
|
||||
_ringsDictionary,
|
||||
"RingsComponent"
|
||||
);
|
||||
documentation::testSpecificationAndThrow(
|
||||
Documentation(),
|
||||
_ringsDictionary,
|
||||
"RingsComponent"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void RingsComponent::initialize() {
|
||||
@@ -280,106 +247,78 @@ void RingsComponent::initialize() {
|
||||
|
||||
using ghoul::filesystem::File;
|
||||
|
||||
const Parameters p = codegen::bake<Parameters>(_ringsDictionary);
|
||||
|
||||
addProperty(_enabled);
|
||||
|
||||
_size = static_cast<float>(_ringsDictionary.value<double>(SizeInfo.identifier));
|
||||
//setBoundingSphere(_size);
|
||||
_size = p.size.value_or(_size);
|
||||
_size.onChange([&]() { _planeIsDirty = true; });
|
||||
addProperty(_size);
|
||||
|
||||
if (_ringsDictionary.hasKey(TextureInfo.identifier)) {
|
||||
_texturePath = absPath(
|
||||
_ringsDictionary.value<std::string>(TextureInfo.identifier)
|
||||
);
|
||||
if (p.texture.has_value()) {
|
||||
_texturePath = absPath(p.texture->string());
|
||||
_textureFile = std::make_unique<File>(_texturePath);
|
||||
_texturePath.onChange([&]() { loadTexture(); });
|
||||
addProperty(_texturePath);
|
||||
_textureFile->setCallback([&](const File&) { _textureIsDirty = true; });
|
||||
}
|
||||
|
||||
if (_ringsDictionary.hasKey(TextureFwrdInfo.identifier)) {
|
||||
_textureFwrdPath = absPath(
|
||||
_ringsDictionary.value<std::string>(TextureFwrdInfo.identifier)
|
||||
);
|
||||
|
||||
if (p.textureFwrd.has_value()) {
|
||||
_textureFwrdPath = absPath(p.textureFwrd->string());
|
||||
_textureFileForwards = std::make_unique<File>(_textureFwrdPath);
|
||||
_textureFwrdPath.onChange([&]() { loadTexture(); });
|
||||
addProperty(_textureFwrdPath);
|
||||
_textureFileForwards->setCallback([&](const File&) { _textureIsDirty = true; });
|
||||
}
|
||||
|
||||
if (_ringsDictionary.hasKey(TextureBckwrdInfo.identifier)) {
|
||||
_textureBckwrdPath = absPath(
|
||||
_ringsDictionary.value<std::string>(TextureBckwrdInfo.identifier)
|
||||
);
|
||||
if (p.textureBckwrd.has_value()) {
|
||||
_textureBckwrdPath = absPath(p.textureBckwrd->string());
|
||||
_textureFileBackwards = std::make_unique<File>(_textureBckwrdPath);
|
||||
_textureBckwrdPath.onChange([&]() { loadTexture(); });
|
||||
addProperty(_textureBckwrdPath);
|
||||
_textureFileBackwards->setCallback([&](const File&) { _textureIsDirty = true; });
|
||||
}
|
||||
|
||||
if (_ringsDictionary.hasKey(TextureUnlitInfo.identifier)) {
|
||||
_textureUnlitPath = absPath(
|
||||
_ringsDictionary.value<std::string>(TextureUnlitInfo.identifier)
|
||||
);
|
||||
if (p.textureUnlit.has_value()) {
|
||||
_textureUnlitPath = absPath(p.textureUnlit->string());
|
||||
_textureFileUnlit = std::make_unique<File>(_textureUnlitPath);
|
||||
_textureUnlitPath.onChange([&]() { loadTexture(); });
|
||||
addProperty(_textureUnlitPath);
|
||||
_textureFileUnlit->setCallback([&](const File&) { _textureIsDirty = true; });
|
||||
}
|
||||
|
||||
if (_ringsDictionary.hasKey(TextureColorInfo.identifier)) {
|
||||
_textureColorPath = absPath(
|
||||
_ringsDictionary.value<std::string>(TextureColorInfo.identifier)
|
||||
);
|
||||
if (p.textureColor.has_value()) {
|
||||
_textureColorPath = absPath(p.textureColor->string());
|
||||
_textureFileColor = std::make_unique<File>(_textureColorPath);
|
||||
_textureColorPath.onChange([&]() { loadTexture(); });
|
||||
addProperty(_textureColorPath);
|
||||
_textureFileColor->setCallback([&](const File&) { _textureIsDirty = true; });
|
||||
}
|
||||
|
||||
if (_ringsDictionary.hasKey(TextureTransparencyInfo.identifier)) {
|
||||
_textureTransparencyPath = absPath(
|
||||
_ringsDictionary.value<std::string>(TextureTransparencyInfo.identifier)
|
||||
);
|
||||
if (p.textureTransparency.has_value()) {
|
||||
_textureTransparencyPath = absPath(p.textureTransparency->string());
|
||||
_textureFileTransparency = std::make_unique<File>(_textureTransparencyPath);
|
||||
_textureTransparencyPath.onChange([&]() { loadTexture(); });
|
||||
addProperty(_textureTransparencyPath);
|
||||
_textureFileTransparency->setCallback([&](const File&) { _textureIsDirty = true; });
|
||||
}
|
||||
|
||||
if (_ringsDictionary.hasValue<glm::dvec2>(OffsetInfo.identifier)) {
|
||||
_offset = _ringsDictionary.value<glm::dvec2>(OffsetInfo.identifier);
|
||||
}
|
||||
_offset = p.offset.value_or(_offset);
|
||||
addProperty(_offset);
|
||||
|
||||
if (_ringsDictionary.hasValue<double>(NightFactorInfo.identifier)) {
|
||||
_nightFactor = static_cast<float>(
|
||||
_ringsDictionary.value<double>(NightFactorInfo.identifier)
|
||||
);
|
||||
}
|
||||
_nightFactor = p.nightFactor.value_or(_nightFactor);
|
||||
addProperty(_nightFactor);
|
||||
|
||||
if (_ringsDictionary.hasValue<double>(ColorFilterInfo.identifier)) {
|
||||
_colorFilter = static_cast<float>(
|
||||
_ringsDictionary.value<double>(ColorFilterInfo.identifier)
|
||||
);
|
||||
}
|
||||
_colorFilter = p.colorFilter.value_or(_colorFilter);
|
||||
addProperty(_colorFilter);
|
||||
|
||||
// Shadow Mapping Quality Controls
|
||||
if (_ringsDictionary.hasKey(ZFightingPercentageInfo.identifier)) {
|
||||
_zFightingPercentage = static_cast<float>(
|
||||
_ringsDictionary.value<double>(ZFightingPercentageInfo.identifier)
|
||||
);
|
||||
}
|
||||
_zFightingPercentage = p.zFightingPercentage.value_or(_zFightingPercentage);
|
||||
addProperty(_zFightingPercentage);
|
||||
|
||||
if (_ringsDictionary.hasKey(NumberShadowSamplesInfo.identifier)) {
|
||||
_nShadowSamples = _ringsDictionary.value<int>(NumberShadowSamplesInfo.identifier);
|
||||
}
|
||||
_nShadowSamples = p.numberShadowSamples.value_or(_nShadowSamples);
|
||||
_nShadowSamples.onChange([this]() { compileShadowShader(); });
|
||||
addProperty(_nShadowSamples);
|
||||
|
||||
addProperty(_colorFilter);
|
||||
}
|
||||
|
||||
bool RingsComponent::isReady() const {
|
||||
|
||||
@@ -141,30 +141,23 @@ namespace {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct [[codegen::Dictionary(ShadowComponent)]] Parameters {
|
||||
// [[codegen::verbatim(DistanceFractionInfo.description)]]
|
||||
std::optional<int> distanceFraction;
|
||||
|
||||
// [[codegen::verbatim(DepthMapSizeInfo.description)]]
|
||||
std::optional<glm::ivec2> depthMapSize;
|
||||
};
|
||||
#include "shadowcomponent_codegen.cpp"
|
||||
} // namespace
|
||||
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation ShadowComponent::Documentation() {
|
||||
using namespace documentation;
|
||||
return {
|
||||
"ShadowsRing Component",
|
||||
"globebrowsing_shadows_component",
|
||||
{
|
||||
{
|
||||
DistanceFractionInfo.identifier,
|
||||
new DoubleVerifier,
|
||||
Optional::Yes,
|
||||
DistanceFractionInfo.description
|
||||
},
|
||||
{
|
||||
DepthMapSizeInfo.identifier,
|
||||
new Vector2ListVerifier<double>,
|
||||
Optional::Yes,
|
||||
DepthMapSizeInfo.description
|
||||
}
|
||||
}
|
||||
};
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "globebrowsing_shadows_component";
|
||||
return doc;
|
||||
}
|
||||
|
||||
ShadowComponent::ShadowComponent(const ghoul::Dictionary& dictionary)
|
||||
@@ -172,37 +165,30 @@ ShadowComponent::ShadowComponent(const ghoul::Dictionary& dictionary)
|
||||
, _saveDepthTexture(SaveDepthTextureInfo)
|
||||
, _distanceFraction(DistanceFractionInfo, 20, 1, 10000)
|
||||
, _enabled({ "Enabled", "Enabled", "Enable/Disable Shadows" }, true)
|
||||
, _shadowMapDictionary(dictionary)
|
||||
{
|
||||
using ghoul::filesystem::File;
|
||||
|
||||
if (dictionary.hasValue<ghoul::Dictionary>("Shadows")) {
|
||||
// @TODO (abock, 2019-12-16) It would be better to not store the dictionary long
|
||||
// term and rather extract the values directly here. This would require a bit of
|
||||
// a rewrite in the RenderableGlobe class to not create the ShadowComponent in the
|
||||
// class-initializer list though
|
||||
_shadowMapDictionary = dictionary.value<ghoul::Dictionary>("Shadows");
|
||||
// @TODO (abock, 2021-03-25) This is not really a nice solution as this key name is
|
||||
// coded into the RenderableGlobe. Instead, the parent should unpack the dictionary
|
||||
// and pass the unpacked dictionary in here; Or maybe we don't want a dictionary at
|
||||
// this state anyway?
|
||||
if (!dictionary.hasValue<ghoul::Dictionary>("Shadows")) {
|
||||
return;
|
||||
}
|
||||
ghoul::Dictionary d = dictionary.value<ghoul::Dictionary>("Shadows");
|
||||
|
||||
const Parameters p = codegen::bake<Parameters>(d);
|
||||
|
||||
documentation::testSpecificationAndThrow(
|
||||
Documentation(),
|
||||
_shadowMapDictionary,
|
||||
"ShadowComponent"
|
||||
);
|
||||
addProperty(_enabled);
|
||||
|
||||
_distanceFraction = p.distanceFraction.value_or(_distanceFraction);
|
||||
addProperty(_distanceFraction);
|
||||
|
||||
if (_shadowMapDictionary.hasKey(DistanceFractionInfo.identifier)) {
|
||||
_distanceFraction = static_cast<int>(
|
||||
_shadowMapDictionary.value<double>(DistanceFractionInfo.identifier)
|
||||
);
|
||||
}
|
||||
_saveDepthTexture.onChange([&]() { _executeDepthTextureSave = true; });
|
||||
|
||||
|
||||
if (_shadowMapDictionary.hasKey(DepthMapSizeInfo.identifier)) {
|
||||
glm::dvec2 depthMapSize =
|
||||
_shadowMapDictionary.value<glm::dvec2>(DepthMapSizeInfo.identifier);
|
||||
_shadowDepthTextureWidth = static_cast<int>(depthMapSize.x);
|
||||
_shadowDepthTextureHeight = static_cast<int>(depthMapSize.y);
|
||||
if (p.depthMapSize.has_value()) {
|
||||
_shadowDepthTextureWidth = p.depthMapSize->x;
|
||||
_shadowDepthTextureHeight = p.depthMapSize->y;
|
||||
_dynamicDepthTextureRes = false;
|
||||
}
|
||||
else {
|
||||
@@ -212,13 +198,7 @@ ShadowComponent::ShadowComponent(const ghoul::Dictionary& dictionary)
|
||||
_dynamicDepthTextureRes = true;
|
||||
}
|
||||
|
||||
_saveDepthTexture.onChange([&]() { _executeDepthTextureSave = true; });
|
||||
|
||||
_viewDepthMap = false;
|
||||
|
||||
addProperty(_enabled);
|
||||
addProperty(_saveDepthTexture);
|
||||
addProperty(_distanceFraction);
|
||||
}
|
||||
|
||||
void ShadowComponent::initialize() {
|
||||
|
||||
@@ -105,8 +105,6 @@ private:
|
||||
properties::IntProperty _distanceFraction;
|
||||
properties::BoolProperty _enabled;
|
||||
|
||||
ghoul::Dictionary _shadowMapDictionary;
|
||||
|
||||
int _shadowDepthTextureHeight = 4096;
|
||||
int _shadowDepthTextureWidth = 4096;
|
||||
bool _dynamicDepthTextureRes = true;
|
||||
|
||||
Reference in New Issue
Block a user