added fading functionalities for the labels

This commit is contained in:
Lovisa Hassler
2018-12-18 14:59:15 -05:00
parent bed63c8e4e
commit 9a6d79ce8c
3 changed files with 234 additions and 98 deletions

View File

@@ -6,12 +6,17 @@ local OuterSpaceLabels = {
Renderable = {
Type = "RenderableLabel",
Enabled = true,
--ScaleFactor = 1.0,
ScaleFactor = 9.0,
LabelIdentifierMap = spacecrafts.labelMapVoyagers,
TextColor = { 1.0, 0.6, 0.2, 1.0 },
DrawLabels = true,
--LabelSize = 6.5,
LabelSizeRange = {5.8, 6.3},
LabelSizeRange = {5.5, 6.0},
SizeDistanceRange = {2, 100000000},
SizeDistanceUnit = "km",
FadeOutDistanceRange = {2, 0.1},
FadeOutDistanceUnit = "km",
FadeInDistanceRange = {2,1},
FadeInDistanceUnit = "lightdays",
},
GUI = {
Name = "Outer Space Labels",
@@ -29,7 +34,13 @@ local MarsLabels = {
TextColor = { 0.4, 0.4, 0.4, 1.0 },
DrawLabels = true,
--LabelSize = 6.5,
LabelSizeRange = {5.8, 6.3},
LabelSizeRange = {5.8, 6.0},
SizeDistanceRange = {2, 1000},
SizeDistanceUnit = "kilometer",
FadeOutDistanceRange = {0.01, 0.5},
FadeOutDistanceUnit = "meter",
FadeInDistanceRange = {0.9, 1.0},
FadeInDistanceUnit = "lightminutes",
},
GUI = {
Name = "Mars Labels",

View File

@@ -39,6 +39,9 @@
namespace {
constexpr const char* _loggerCat = "RenderableLabel";
constexpr const char* ProgramObjectName = "RenderableLabel";
constexpr const char* KeyUnitOut = "FadeOutDistanceUnit";
constexpr const char* KeyUnitIn = "FadeInDistanceUnit";
constexpr const char* KeyUnitSize = "SizeDistanceUnit";
constexpr openspace::properties::Property::PropertyInfo LabelIdentifierMapInfo = {
"LabelIdentifierMap",
@@ -47,23 +50,25 @@ namespace {
"instead of reading positions from file. "
};
/* This toggles the distance from the camera of the projection plane that the label is rendered on.
* Necessary to combat precision errors for labels on astronomical objects that are far out in space */
constexpr openspace::properties::Property::PropertyInfo ScaleFactorInfo = {
"ScaleFactor",
"Scale Factor",
"This value is used as a multiplicative factor that is applied to the apparent "
"size of each point."
"This value is used as a multiplicative factor that toggles the distance of "
"the label from the camera. "
};
constexpr openspace::properties::Property::PropertyInfo TextColorInfo = {
"TextColor",
"Text Color",
"The text color for the astronomical object."
"The text color for the label of the astronomical object."
};
constexpr openspace::properties::Property::PropertyInfo LabelSizeInfo = {
"LabelSize",
"Label Size",
"The static label size if no LabelSizeRange interval are set "
"The static label size if no LabelSizeRange interval are set. "
};
//constexpr openspace::properties::Property::PropertyInfo TextMinSizeInfo = {
@@ -83,22 +88,30 @@ namespace {
"LabelSizeRange",
"Label Size Range",
"These values determine the min and max size of this label when it is "
"scaled depending on distance"
"scaled depending on distance. Also need to specify the distance range from "
"the astronomical object the rescaling occurs. "
};
constexpr openspace::properties::Property::PropertyInfo TextMinSizeInfo = {
"TextMinSize",
"Text Min Size",
"The minimal size (in pixels) of the text for the labels for the astronomical "
"objects being rendered."
constexpr openspace::properties::Property::PropertyInfo SizeDistanceRangeInfo = {
"SizeDistanceRange",
"Size Distance Range",
"The distance range where rescaling from min label size to max label size occurs. "
};
constexpr openspace::properties::Property::PropertyInfo TextMaxSizeInfo = {
"TextMaxSize",
"Text Max Size",
"The maximum size (in pixels) of the text for the labels for the astronomical "
"objects being rendered."
};
//constexpr openspace::properties::Property::PropertyInfo TextMinSizeInfo = {
// "TextMinSize",
// "Text Min Size",
// "The minimal size (in pixels) of the text for the labels for the astronomical "
// "objects being rendered."
//};
//constexpr openspace::properties::Property::PropertyInfo TextMaxSizeInfo = {
// "TextMaxSize",
// "Text Max Size",
// "The maximum size (in pixels) of the text for the labels for the astronomical "
// "objects being rendered."
//};
constexpr openspace::properties::Property::PropertyInfo DrawLabelInfo = {
"DrawLabels",
@@ -118,18 +131,24 @@ namespace {
"Debug option for rendering of billboards and texts."
};
constexpr openspace::properties::Property::PropertyInfo FadeInDistancesInfo = {
"FadeInDistances",
"Fade-In Start and End Distances",
"These values determine the initial and final distances from the center of "
"our galaxy from which the astronomical object will start and end "
"fading-in."
constexpr openspace::properties::Property::PropertyInfo FadeInDistanceRangeInfo = {
"FadeInDistanceRange",
"Fade-In Distance Range",
"These values determine the start and end of the fade expressed in a distance "
"from the astronomical object. {start, end}"
};
constexpr openspace::properties::Property::PropertyInfo DisableFadeInInfo = {
"DisableFadeIn",
"Disable Fade-in effect",
"Enables/Disables the Fade-in effect."
constexpr openspace::properties::Property::PropertyInfo FadeOutDistanceRangeInfo = {
"FadeOutDistanceRange",
"Fade-Out Distance Range",
"These values determine the start and end of the fade expressed in a distance "
"from the astronomical object. {start, end}"
};
constexpr openspace::properties::Property::PropertyInfo DisableFadeDistancesInfo = {
"DisableFadeDistances",
"Disable Fade-in and Fade-out effects",
"Enables/Disables the Fade effects."
};
} // namespace
@@ -178,28 +197,34 @@ namespace openspace {
LabelSizeInfo.description
},
{
TextMinSizeInfo.identifier,
new DoubleVerifier,
Optional::Yes,
TextMinSizeInfo.description
},
{
TextMaxSizeInfo.identifier,
new DoubleVerifier,
Optional::Yes,
TextMaxSizeInfo.description
},
{
FadeInDistancesInfo.identifier,
SizeDistanceRangeInfo.identifier,
new Vector2Verifier<double>,
Optional::Yes,
FadeInDistancesInfo.description
SizeDistanceRangeInfo.description
},
//{
// TextMinSizeInfo.identifier,
// new DoubleVerifier,
// Optional::Yes,
// TextMinSizeInfo.description
//},
//{
// TextMaxSizeInfo.identifier,
// new DoubleVerifier,
// Optional::Yes,
// TextMaxSizeInfo.description
//},
{
FadeInDistanceRangeInfo.identifier,
new Vector2Verifier<double>,
Optional::Yes,
FadeInDistanceRangeInfo.description
},
{
DisableFadeInInfo.identifier,
DisableFadeDistancesInfo.identifier,
new BoolVerifier,
Optional::Yes,
DisableFadeInInfo.description
DisableFadeDistancesInfo.description
},
{
TransformationMatrixInfo.identifier,
@@ -213,7 +238,7 @@ namespace openspace {
RenderableLabel::RenderableLabel(const ghoul::Dictionary& dictionary)
: Renderable(dictionary)
, _scaleFactor(ScaleFactorInfo, 5.0f, 1.f, 100.f)
, _scaleFactor(ScaleFactorInfo, 1.0f, 0.f, 10.f)
, _textColor(
TextColorInfo,
glm::vec4(1.0f, 1.0, 1.0f, 1.f),
@@ -227,16 +252,28 @@ namespace openspace {
glm::vec2(0.0),
glm::vec2(100.0)
)
// , _textMinSize(TextMinSizeInfo, 5.f, 0.0f, 100.f)
// , _textMaxSize(TextMaxSizeInfo, 50.f, 0.0f, 100.f)
, _drawLabels(DrawLabelInfo, false)
, _fadeInDistance(
FadeInDistancesInfo,
glm::vec2(0.0f),
, _sizeDistanceRange(
SizeDistanceRangeInfo,
glm::vec2(0, 100.0f),
glm::vec2(0.0),
glm::vec2(100.0)
)
, _disableFadeInDistance(DisableFadeInInfo, true)
// , _textMinSize(TextMinSizeInfo, 5.f, 0.0f, 100.f)
// , _textMaxSize(TextMaxSizeInfo, 50.f, 0.0f, 100.f)
, _drawLabels(DrawLabelInfo, false)
, _fadeOutDistance(
FadeOutDistanceRangeInfo,
glm::vec2(0.01f, 1.0f),
glm::vec2(0.0),
glm::vec2(10.0)
)
, _fadeInDistance(
FadeInDistanceRangeInfo,
glm::vec2(0.01f, 1.0f),
glm::vec2(0.0),
glm::vec2(10.0)
)
, _disableFadeDistances(DisableFadeDistancesInfo, false)
, _renderOption(RenderOptionInfo, properties::OptionProperty::DisplayType::Dropdown)
{
documentation::testSpecificationAndThrow(
@@ -289,11 +326,25 @@ namespace openspace {
addProperty(_labelSize);
_hasStaticLabelSize = true;
}else if(dictionary.hasKey(LabelSizeRangeInfo.identifier))
}else if(dictionary.hasKey(LabelSizeRangeInfo.identifier) && dictionary.hasKey(SizeDistanceRangeInfo.identifier))
{
glm::vec2 labelsizeRange = dictionary.value<glm::vec2>(LabelSizeRangeInfo.identifier);
_labelSizeRange.set(labelsizeRange);
addProperty(_labelSizeRange);
if (dictionary.hasKey(KeyUnitSize)) {
std::string unit = dictionary.value<std::string>(KeyUnitOut);
_sizeDistanceUnit = getUnitFactor(unit);
}
glm::vec2 sizeDistanceRange = dictionary.value<glm::vec2>(SizeDistanceRangeInfo.identifier);
_sizeDistanceRange.set(sizeDistanceRange);
addProperty(_sizeDistanceRange);
}
else {
LERROR(fmt::format("Need to specify either a static '{}' or a scalable range '{}' with a distance range '{}'",
LabelSizeInfo.identifier, LabelSizeRangeInfo.identifier, SizeDistanceRangeInfo.identifier));
}
//if (dictionary.hasKey(TextMinSizeInfo.identifier)) {
@@ -318,15 +369,34 @@ namespace openspace {
);
}
if (dictionary.hasKey(FadeInDistancesInfo.identifier)) {
if (dictionary.hasKey(FadeInDistanceRangeInfo.identifier) && dictionary.hasKey(FadeOutDistanceRangeInfo.identifier)) {
glm::vec2 fadeInValue = dictionary.value<glm::vec2>(
FadeInDistancesInfo.identifier
FadeInDistanceRangeInfo.identifier
);
_fadeInDistance.set(fadeInValue);
_disableFadeInDistance.set(false);
if (dictionary.hasKey(KeyUnitIn)) {
std::string unit = dictionary.value<std::string>(KeyUnitIn);
_fadeInDistanceUnit = getUnitFactor(unit);
}
glm::vec2 fadeOutValue = dictionary.value<glm::vec2>(
FadeOutDistanceRangeInfo.identifier
);
_fadeOutDistance.set(fadeOutValue);
if (dictionary.hasKey(KeyUnitOut)) {
std::string unit = dictionary.value<std::string>(KeyUnitOut);
_fadeOutDistanceUnit = getUnitFactor(unit);
}
_disableFadeDistances.set(false);
addProperty(_fadeInDistance);
addProperty(_fadeOutDistance);
addProperty(_disableFadeDistances);
}
addProperty(_fadeInDistance);
addProperty(_disableFadeInDistance);
}
bool RenderableLabel::isReady() const {
@@ -369,20 +439,6 @@ namespace openspace {
loadLabelDataFromId();
}
glm::vec4 textColor = _textColor;
//float fadeInVariable = 1.f;
//if (!_disableFadeInDistance) {
// float distCamera = static_cast<float>(glm::length(data.camera.positionVec3()));
// const glm::vec2 fadeRange = _fadeInDistance;
// const float a = 1.f / (fadeRange.y - fadeRange.x);
// const float b = -(fadeRange.x / (fadeRange.y - fadeRange.x));
// const float funcValue = a * distCamera + b;
// fadeInVariable *= funcValue > 1.f ? 1.f : funcValue;
// if (funcValue < 0.01f) {
// return;
// }
//}
for (const std::pair<glm::dvec3, std::string>& pair : _labelData) {
@@ -390,25 +446,41 @@ namespace openspace {
glm::dvec3 nodePos = pair.first;
std::string labelText = pair.second;
// The distance from the camera to the SceneGraphNode of the label
double distCamera = glm::distance(data.camera.positionVec3(), nodePos);
if (!_disableFadeDistances) {
// fade in when when we are close enough
const glm::vec2 fadeInRange = _fadeInDistance;
double fadeIn = maxMinNormalize(distCamera, glm::dvec2(1.0, 0.0), glm::dvec2(_fadeInDistanceUnit*fadeInRange.x, _fadeInDistanceUnit*fadeInRange.y));
// fade out again when we get really close
const glm::vec2 fadeOutRange = _fadeOutDistance;
double fadeOut = maxMinNormalize(distCamera, glm::dvec2(0.0, 1.0), glm::dvec2(_fadeOutDistanceUnit*fadeOutRange.x, _fadeOutDistanceUnit*fadeOutRange.y));
textColor.a *= glm::min(fadeIn, fadeOut);
}
double textSize = 0.0;
if (!_hasStaticLabelSize) {
const glm::vec2 labelSizeRange = _labelSizeRange;
const glm::vec2 sizeRange = _sizeDistanceRange;
// Pass in the labelSizeRanges in opposite order (max,min) since we want the largest value
// when the distance is the smallest
textSize = maxMinNormalize(distCamera, glm::dvec2(labelSizeRange.y, labelSizeRange.x), glm::dvec2(20000.0, _maxDistanceUnit));
textSize = maxMinNormalize(distCamera, glm::dvec2(labelSizeRange.y, labelSizeRange.x), glm::dvec2(_sizeDistanceUnit*sizeRange.x, _sizeDistanceUnit*sizeRange.y));
}
else {
textSize = _labelSize;
}
double labelPosLength = (1.0 / _scaleFactor) * _maxDistanceUnit;
double labelPosLength = pow(10, _scaleFactor);//(1.0 / _scaleFactor) * 1E10;// length(nodePos) / _fadeInDistanceUnit;// _fadeInDistanceUnit;
// The direction vector from the camera to the SceneGraphNode
glm::dvec3 nodeDir = normalize(data.camera.positionVec3() - nodePos);
// The new label position vector, calculated from the camera
glm::dvec3 labelPos = data.camera.positionVec3() - (nodeDir * labelPosLength);
//textColor.a *= fadeInVariable;
double textScale = pow(10, textSize);
ghoul::fontrendering::FontRenderer::defaultProjectionRenderer().render(
@@ -429,25 +501,6 @@ namespace openspace {
}
}
double RenderableLabel::maxMinNormalize(double value, glm::dvec2 newRange, glm::dvec2 oldRange)
{
double newMax = newRange.y;
double newMin = newRange.x;
double oldMax = oldRange.y;
double oldMin = oldRange.x;
if (value >= oldMax)
return newMax;
double nominator = (newMax - newMin) * (value - oldMax);
double denominator = oldMax - oldMin;
double newValue = nominator / denominator + newMax;
return newValue;
}
void RenderableLabel::render(const RenderData& data, RendererTasks&) {
glm::dmat4 modelMatrix =
@@ -528,4 +581,70 @@ namespace openspace {
return true;
}
double RenderableLabel::maxMinNormalize(double value, glm::dvec2 newRange, glm::dvec2 oldRange)
{
double newMax = newRange.y;
double newMin = newRange.x;
double oldMax = glm::max(oldRange.y,oldRange.x);
double oldMin = glm::min(oldRange.y, oldRange.x);
if (value >= oldMax)
return newMax;
if (value <= oldMin)
return newMin;
double nominator = (newMax - newMin) * (value - oldMax);
double denominator = oldMax - oldMin;
double newValue = nominator / denominator + newMax;
return newValue;
}
double RenderableLabel::getUnitFactor(std::string unitString)
{
double unit = 0.0;
//2.998e+8
std::transform(unitString.begin(), unitString.end(), unitString.begin(), ::tolower);
// Units expressed in meters
if (unitString == "meter" ||
unitString == "meters" ||
unitString == "m") {
unit = 1.0;
}
else if (unitString == "kilometer" ||
unitString == "kilometers" ||
unitString == "km") {
unit = 1E3;
}
else if (unitString == "lightsecond" ||
unitString == "lightseconds") {
unit = 2.998E8;
}
else if (unitString == "lightminute" ||
unitString == "lightminutes") {
unit = 1.799E10;
}
else if (unitString == "lighthour" ||
unitString == "lighthours") {
unit = 1.079E12;
}
else if (unitString == "lightday" ||
unitString == "lightdays") {
unit = 2.59E13;
}
else {
LWARNING(
fmt::format("{} is not a specified unit. Using meters as units.", unitString)
);
unit = 1.0;
}
return unit;
}
} // namespace openspace

View File

@@ -57,7 +57,9 @@ namespace openspace {
private:
const double _maxDistanceUnit = 1E10;
double _fadeInDistanceUnit = 1E10;
double _fadeOutDistanceUnit = 2E3;
double _sizeDistanceUnit = 1.0;
void renderLabels(const RenderData& data, const glm::dmat4& modelViewProjectionMatrix,
const glm::dvec3& orthoRight, const glm::dvec3& orthoUp);
@@ -76,11 +78,13 @@ namespace openspace {
properties::Vec4Property _textColor;
properties::FloatProperty _labelSize;
properties::Vec2Property _labelSizeRange;
properties::Vec2Property _sizeDistanceRange;
//properties::FloatProperty _textMinSize;
//properties::FloatProperty _textMaxSize;
properties::BoolProperty _drawLabels;
properties::Vec2Property _fadeInDistance;
properties::BoolProperty _disableFadeInDistance;
properties::Vec2Property _fadeOutDistance;
properties::BoolProperty _disableFadeDistances;
// DEBUG:
properties::OptionProperty _renderOption;
@@ -90,6 +94,8 @@ namespace openspace {
std::vector<std::pair<glm::dvec3, std::string>> _labelData;
glm::dmat4 _transformationMatrix = glm::dmat4(1.0);
double getUnitFactor(std::string unitString);
/*The minimal size(in pixels) of the text for the labels
for the astronomical objects being rendered.*/
double _textMinSize = 1.0;