mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-07 04:00:37 -06:00
Merged master.
This commit is contained in:
@@ -101,7 +101,7 @@ local Keybindings = {
|
||||
},
|
||||
{
|
||||
Key = "l",
|
||||
Command = propertyHelper.invert('Scene.Labels.renderable.Enabled'),
|
||||
Command = propertyHelper.fadeInOut('Scene.Labels.renderable.Opacity', 2.0),
|
||||
Documentation = "Toggles the visibility of the labels for the New Horizons instruments.",
|
||||
Local = false
|
||||
},
|
||||
|
||||
@@ -33,6 +33,7 @@ local Moon = {
|
||||
-- Utah based servers
|
||||
{
|
||||
Identifier = "ClemUvvis",
|
||||
Name = "Clem Uvvis",
|
||||
FilePath = mapServiceConfigs .. "/Utah/ClemUvvis.wms"
|
||||
},
|
||||
{
|
||||
@@ -55,6 +56,7 @@ local Moon = {
|
||||
-- Utah based servers
|
||||
{
|
||||
Identifier = "LolaDem",
|
||||
Name = "WAC [Utah]",
|
||||
FilePath = mapServiceConfigs .. "/Utah/LolaDem.wms",
|
||||
Enabled = true,
|
||||
TilePixelSize = 64,
|
||||
|
||||
@@ -16,7 +16,8 @@ local EarthBarycenter = {
|
||||
},
|
||||
GUI = {
|
||||
Name = "Earth Barycenter",
|
||||
Path = "/Solar System/Planets/Earth"
|
||||
Path = "/Solar System/Planets/Earth",
|
||||
Hidden = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +34,8 @@ local EarthInertial = {
|
||||
},
|
||||
GUI = {
|
||||
Name = "Earth Inertial",
|
||||
Path = "/Solar System/Planets/Earth"
|
||||
Path = "/Solar System/Planets/Earth",
|
||||
Hidden = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +51,8 @@ local EarthIAU = {
|
||||
},
|
||||
GUI = {
|
||||
Name = "Earth IAU",
|
||||
Path = "/Solar System/Planets/Earth"
|
||||
Path = "/Solar System/Planets/Earth",
|
||||
Hidden = true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,8 @@ local JupiterBarycenter = {
|
||||
},
|
||||
GUI = {
|
||||
Name = "Jupiter Barycenter",
|
||||
Path = "/Solar System/Planets/Jupiter"
|
||||
Path = "/Solar System/Planets/Jupiter",
|
||||
Hidden = true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,8 @@ local MarsBarycenter = {
|
||||
},
|
||||
GUI = {
|
||||
Name = "Mars Barycenter",
|
||||
Path = "/Solar System/Planets/Mars"
|
||||
Path = "/Solar System/Planets/Mars",
|
||||
Hidden = true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,8 @@ local MercuryBarycenter = {
|
||||
},
|
||||
GUI = {
|
||||
Name = "Mercury Barycenter",
|
||||
Path = "/Solar System/Planets/Mercury"
|
||||
Path = "/Solar System/Planets/Mercury",
|
||||
Hidden = true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,8 @@ local NeptuneBarycenter = {
|
||||
},
|
||||
GUI = {
|
||||
Name = "Neptune Barycenter",
|
||||
Path = "/Solar System/Planets/Neptune"
|
||||
Path = "/Solar System/Planets/Neptune",
|
||||
Hidden = true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ local kernels081 = asset.require('./nep081').Kernels
|
||||
local Triton = {
|
||||
Identifier = "Triton",
|
||||
Parent = {
|
||||
Name = transforms.NeptuneBarycenter.Identifier,
|
||||
Identifier = transforms.NeptuneBarycenter.Identifier,
|
||||
Spice = "NEPTUNE BARYCENTER"
|
||||
},
|
||||
Spice = "TRITON",
|
||||
|
||||
@@ -16,7 +16,8 @@ local SaturnBarycenter = {
|
||||
},
|
||||
GUI = {
|
||||
Name = "Saturn Barycenter",
|
||||
Path = "/Solar System/Planets/Saturn"
|
||||
Path = "/Solar System/Planets/Saturn",
|
||||
Hidden = true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,8 @@ local UranusBarycenter = {
|
||||
},
|
||||
GUI = {
|
||||
Name = "Uranus Barycenter",
|
||||
Path = "/Solar System/Planets/Uranus"
|
||||
Path = "/Solar System/Planets/Uranus",
|
||||
Hidden = true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,8 @@ local VenusTrail = {
|
||||
Tag = { "planetTrail_solarSystem", "planetTrail_terrestrial" },
|
||||
GUI = {
|
||||
Name = "Venus Trail",
|
||||
Path = "/Solar System/Planets/Venus"
|
||||
Path = "/Solar System/Planets/Venus",
|
||||
Hidden = true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,12 @@ asset.require("spice/base")
|
||||
|
||||
-- Barycenter of the solar system, expressed in the Galactic frame
|
||||
local SolarSystemBarycenter = {
|
||||
Identifier = "SolarSystemBarycenter"
|
||||
Identifier = "SolarSystemBarycenter",
|
||||
GUI = {
|
||||
Name = "Solar System Barycenter",
|
||||
Path = "/Solar System",
|
||||
Hidden = true
|
||||
}
|
||||
-- No parent; this node is attached to the scene graph root
|
||||
}
|
||||
|
||||
@@ -27,7 +32,8 @@ local SunIAU = {
|
||||
},
|
||||
GUI = {
|
||||
Name = "SUN IAU",
|
||||
Path = "/Solar System/Sun"
|
||||
Path = "/Solar System/Sun",
|
||||
Hidden = true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,35 @@ local decrement = function(prop, value)
|
||||
return increment(prop, -value)
|
||||
end
|
||||
|
||||
local fade = function(prop, value, duration)
|
||||
assert(type(prop) == "string", "prop must be a number")
|
||||
assert(type(duration) == "number", "duration must be a number")
|
||||
|
||||
local escaped_property = "'" .. prop .. "'"
|
||||
return "openspace.setPropertyValue(" .. escaped_property ..", " .. tostring(value) .. ", " .. tostring(duration) .. ")"
|
||||
end
|
||||
|
||||
local fadeOut = function(prop, duration)
|
||||
return fade(prop, 0.0, duration)
|
||||
end
|
||||
|
||||
local fadeIn = function(prop, duration)
|
||||
return fade(prop, 1.0, duration)
|
||||
end
|
||||
|
||||
local fadeInOut = function(prop, duration)
|
||||
assert(type(prop) == "string", "prop must be a number")
|
||||
assert(type(duration) == "number", "duration must be a number")
|
||||
|
||||
local escaped_property = "'" .. prop .. "'"
|
||||
-- If the value is > 0.5 fade out, otherwise fade in
|
||||
return "local v = openspace.getPropertyValue(" .. escaped_property .. "); if v <= 0.5 then " .. fadeIn(prop, duration) .. " else " .. fadeOut(prop, duration) .. " end"
|
||||
end
|
||||
|
||||
asset.export('invert', invert)
|
||||
asset.export('increment', increment)
|
||||
asset.export('decrement', decrement)
|
||||
asset.export('fade', fade)
|
||||
asset.export('fadeIn', fadeIn)
|
||||
asset.export('fadeOut', fadeOut)
|
||||
asset.export('fadeInOut', fadeInOut)
|
||||
|
||||
@@ -137,6 +137,7 @@ public:
|
||||
Renderable* renderable();
|
||||
|
||||
const std::string& guiPath() const;
|
||||
bool hasGuiHintHidden() const;
|
||||
|
||||
static documentation::Documentation Documentation();
|
||||
|
||||
@@ -152,6 +153,10 @@ private:
|
||||
std::vector<SceneGraphNode*> _dependentNodes;
|
||||
Scene* _scene;
|
||||
|
||||
// If this value is 'true' GUIs are asked to hide this node from collections, as it
|
||||
// might be a node that is not very interesting (for example barycenters)
|
||||
bool _guiHintHidden = false;
|
||||
|
||||
PerformanceRecord _performanceRecord;
|
||||
|
||||
std::unique_ptr<Renderable> _renderable;
|
||||
|
||||
@@ -77,6 +77,7 @@ protected:
|
||||
|
||||
properties::BoolProperty _useTreeLayout;
|
||||
properties::StringListProperty _treeOrdering;
|
||||
properties::BoolProperty _ignoreHiddenHint;
|
||||
};
|
||||
|
||||
} // namespace openspace::gui
|
||||
|
||||
@@ -53,6 +53,14 @@ namespace {
|
||||
"elements not listed."
|
||||
};
|
||||
|
||||
static const openspace::properties::Property::PropertyInfo IgnoreHiddenInfo = {
|
||||
"IgnoreHidden",
|
||||
"Ignore Hidden Hint",
|
||||
"If this value is 'true', all 'Hidden' hints passed into the SceneGraphNodes are "
|
||||
"ignored and thus all SceneGraphNodes are displayed. If this value is 'false', "
|
||||
"the hidden hints are followed."
|
||||
};
|
||||
|
||||
int nVisibleProperties(const std::vector<openspace::properties::Property*>& props,
|
||||
openspace::properties::Property::Visibility visibility)
|
||||
{
|
||||
@@ -166,9 +174,11 @@ GuiPropertyComponent::GuiPropertyComponent(std::string identifier, std::string g
|
||||
: GuiComponent(std::move(identifier), std::move(guiName))
|
||||
, _useTreeLayout(UseTreeInfo, useTree)
|
||||
, _treeOrdering(OrderingInfo)
|
||||
, _ignoreHiddenHint(IgnoreHiddenInfo)
|
||||
{
|
||||
addProperty(_useTreeLayout);
|
||||
addProperty(_treeOrdering);
|
||||
addProperty(_ignoreHiddenHint);
|
||||
}
|
||||
|
||||
void GuiPropertyComponent::setSource(SourceFunction function) {
|
||||
@@ -378,6 +388,25 @@ void GuiPropertyComponent::render() {
|
||||
};
|
||||
|
||||
if (!_useTreeLayout || noGuiGroups) {
|
||||
if (!_ignoreHiddenHint) {
|
||||
// Remove all of the nodes that we want hidden first
|
||||
owners.erase(
|
||||
std::remove_if(
|
||||
owners.begin(),
|
||||
owners.end(),
|
||||
[](properties::PropertyOwner* p) {
|
||||
SceneGraphNode* s = dynamic_cast<SceneGraphNode*>(p);
|
||||
if (s && s->hasGuiHintHidden()) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
),
|
||||
owners.end()
|
||||
);
|
||||
}
|
||||
std::for_each(owners.begin(), owners.end(), renderProp);
|
||||
}
|
||||
else { // _useTreeLayout && gui groups exist
|
||||
@@ -386,6 +415,9 @@ void GuiPropertyComponent::render() {
|
||||
for (properties::PropertyOwner* pOwner : owners) {
|
||||
// We checked above that pOwner is a SceneGraphNode
|
||||
SceneGraphNode* nOwner = static_cast<SceneGraphNode*>(pOwner);
|
||||
if (!_ignoreHiddenHint && nOwner->hasGuiHintHidden()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (nOwner->guiPath().empty()) {
|
||||
// We know that we are done now since we stable_sort:ed them above
|
||||
|
||||
@@ -56,7 +56,7 @@ properties::PropertyOwner* findPropertyOwnerWithMatchingGroupTag(T* prop,
|
||||
return tagMatchOwner;
|
||||
}
|
||||
|
||||
void applyRegularExpression(lua_State* L, std::regex regex,
|
||||
void applyRegularExpression(lua_State* L, const std::string& regex,
|
||||
std::vector<properties::Property*> properties,
|
||||
double interpolationDuration,
|
||||
const std::string& groupName,
|
||||
@@ -68,11 +68,15 @@ void applyRegularExpression(lua_State* L, std::regex regex,
|
||||
|
||||
const int type = lua_type(L, -1);
|
||||
|
||||
// Stores whether we found at least one matching property. If this is false at the end
|
||||
// of the loop, the property name regex was probably misspelled.
|
||||
bool foundMatching = false;
|
||||
std::regex r(regex);
|
||||
for (properties::Property* prop : properties) {
|
||||
// Check the regular expression for all properties
|
||||
std::string id = prop->fullyQualifiedIdentifier();
|
||||
|
||||
if (std::regex_match(id, regex)) {
|
||||
if (std::regex_match(id, r)) {
|
||||
// If the fully qualified id matches the regular expression, we queue the
|
||||
// value change if the types agree
|
||||
if (isGroupMode) {
|
||||
@@ -99,6 +103,8 @@ void applyRegularExpression(lua_State* L, std::regex regex,
|
||||
)
|
||||
);
|
||||
} else {
|
||||
foundMatching = true;
|
||||
|
||||
if (interpolationDuration == 0.0) {
|
||||
OsEng.renderEngine().scene()->removeInterpolation(prop);
|
||||
prop->setLuaValue(L);
|
||||
@@ -114,6 +120,17 @@ void applyRegularExpression(lua_State* L, std::regex regex,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundMatching) {
|
||||
LERRORC(
|
||||
"property_setValue",
|
||||
fmt::format(
|
||||
"{}: No property matched the requested URI '{}'",
|
||||
errorLocation(L),
|
||||
regex
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Checks to see if URI contains a group tag (with { } around the first term). If so,
|
||||
@@ -270,7 +287,7 @@ int property_setValue(lua_State* L) {
|
||||
try {
|
||||
applyRegularExpression(
|
||||
L,
|
||||
std::regex(uriOrRegex),
|
||||
uriOrRegex,
|
||||
allProperties(),
|
||||
interpolationDuration,
|
||||
groupName,
|
||||
@@ -291,7 +308,7 @@ int property_setValue(lua_State* L) {
|
||||
try {
|
||||
applyRegularExpression(
|
||||
L,
|
||||
std::regex(uriOrRegex),
|
||||
uriOrRegex,
|
||||
allProperties(),
|
||||
interpolationDuration,
|
||||
"",
|
||||
|
||||
@@ -56,8 +56,9 @@
|
||||
namespace {
|
||||
constexpr const char* _loggerCat = "SceneGraphNode";
|
||||
constexpr const char* KeyRenderable = "Renderable";
|
||||
constexpr const char* KeyName = "GUI.Name";
|
||||
constexpr const char* KeyGuiName = "GUI.Name";
|
||||
constexpr const char* KeyGuiPath = "GUI.Path";
|
||||
constexpr const char* KeyGuiHidden = "GUI.Hidden";
|
||||
|
||||
constexpr const char* keyTransformTranslation = "Transform.Translation";
|
||||
constexpr const char* keyTransformRotation = "Transform.Rotation";
|
||||
@@ -80,8 +81,12 @@ std::unique_ptr<SceneGraphNode> SceneGraphNode::createFromDictionary(
|
||||
std::string identifier = dictionary.value<std::string>(KeyIdentifier);
|
||||
result->setIdentifier(std::move(identifier));
|
||||
|
||||
if (dictionary.hasKey(KeyName)) {
|
||||
result->setGuiName(dictionary.value<std::string>(KeyName));
|
||||
if (dictionary.hasKey(KeyGuiName)) {
|
||||
result->setGuiName(dictionary.value<std::string>(KeyGuiName));
|
||||
}
|
||||
|
||||
if (dictionary.hasKey(KeyGuiHidden)) {
|
||||
result->_guiHintHidden = dictionary.value<bool>(KeyGuiHidden);
|
||||
}
|
||||
|
||||
if (dictionary.hasKey(keyTransformTranslation)) {
|
||||
@@ -573,6 +578,10 @@ const std::string& SceneGraphNode::guiPath() const {
|
||||
return _guiPath;
|
||||
}
|
||||
|
||||
bool SceneGraphNode::hasGuiHintHidden() const {
|
||||
return _guiHintHidden;
|
||||
}
|
||||
|
||||
glm::dvec3 SceneGraphNode::calculateWorldPosition() const {
|
||||
// recursive up the hierarchy if there are parents available
|
||||
if (_parent) {
|
||||
|
||||
@@ -43,13 +43,6 @@ documentation::Documentation SceneGraphNode::Documentation() {
|
||||
"detected the loading of the node will fail, as will all childing that "
|
||||
"depend on the node. The identifier must not contain any whitespaces or '.'."
|
||||
},
|
||||
{
|
||||
"Name",
|
||||
new StringVerifier,
|
||||
Optional::Yes,
|
||||
"An optional user-facing name for this SceneGraphNode, which does not have "
|
||||
"to be unique, though it is recommended, and can contain any characters."
|
||||
},
|
||||
{
|
||||
"Parent",
|
||||
new StringAnnotationVerifier(
|
||||
@@ -106,13 +99,39 @@ documentation::Documentation SceneGraphNode::Documentation() {
|
||||
"corresponding to a 'Translation', a 'Rotation', and a 'Scale'."
|
||||
},
|
||||
{
|
||||
"GuiPath",
|
||||
new StringVerifier,
|
||||
"GUI",
|
||||
new TableVerifier({
|
||||
{
|
||||
"Name",
|
||||
new StringVerifier,
|
||||
Optional::Yes,
|
||||
"An optional user-facing name for this SceneGraphNode, which does "
|
||||
"not have to be unique, though it is recommended, and can contain "
|
||||
"any characters."
|
||||
},
|
||||
{
|
||||
"Path",
|
||||
new StringVerifier,
|
||||
Optional::Yes,
|
||||
"If this value is specified, this '/' separated URI specifies the "
|
||||
"location of this scenegraph node in a GUI representation, for "
|
||||
"instance '/SolarSystem/Earth/Moon'."
|
||||
},
|
||||
{
|
||||
"Hidden",
|
||||
new BoolVerifier,
|
||||
Optional::Yes,
|
||||
"If this value is specified, GUI applications are incouraged to "
|
||||
"ignore this scenegraph node. This is most useful to trim collective "
|
||||
"lists of nodes and not display, for example, barycenters."
|
||||
}
|
||||
}),
|
||||
Optional::Yes,
|
||||
"If this value is specified, this '/' separated URI specifies the location "
|
||||
"of this scenegraph node in a GUI representation, for instance "
|
||||
"'/SolarSystem/Earth/Moon'."
|
||||
}
|
||||
"Additional information that is passed to GUI applications. These are all "
|
||||
"hints and do not have any impact on the actual function of the scenegraph "
|
||||
"node."
|
||||
},
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user