mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-02-22 04:49:12 -06:00
Use largest of boudning and interaction sphere for creating camera path (closes #1897)
This commit is contained in:
@@ -74,6 +74,8 @@ public:
|
||||
|
||||
Path::Type defaultPathType() const;
|
||||
double minValidBoundingSphere() const;
|
||||
double findValidBoundingSphere(const SceneGraphNode* node) const;
|
||||
|
||||
const std::vector<SceneGraphNode*>& relevantNodes();
|
||||
|
||||
/**
|
||||
|
||||
@@ -41,8 +41,6 @@ public:
|
||||
Waypoint(const glm::dvec3& pos, const glm::dquat& rot, const std::string& ref);
|
||||
explicit Waypoint(const NavigationState& ns);
|
||||
|
||||
static double findValidBoundingSphere(const SceneGraphNode* node);
|
||||
|
||||
CameraPose pose() const;
|
||||
glm::dvec3 position() const;
|
||||
glm::dquat rotation() const;
|
||||
|
||||
@@ -498,9 +498,10 @@ Waypoint computeWaypointFromNodeInfo(const NodeInfo& info, const Waypoint& start
|
||||
);
|
||||
}
|
||||
else {
|
||||
const double radius = Waypoint::findValidBoundingSphere(targetNode);
|
||||
const double defaultHeight = radius *
|
||||
global::navigationHandler->pathNavigator().arrivalDistanceFactor();
|
||||
const PathNavigator& navigator = global::navigationHandler->pathNavigator();
|
||||
|
||||
const double radius = navigator.findValidBoundingSphere(targetNode);
|
||||
const double defaultHeight = radius * navigator.arrivalDistanceFactor();
|
||||
const double height = info.height.value_or(defaultHeight);
|
||||
const double distanceFromNodeCenter = radius + height;
|
||||
|
||||
|
||||
@@ -343,6 +343,49 @@ double PathNavigator::minValidBoundingSphere() const {
|
||||
return _minValidBoundingSphere;
|
||||
}
|
||||
|
||||
double PathNavigator::findValidBoundingSphere(const SceneGraphNode* node) const {
|
||||
ghoul_assert(node != nullptr, "Node must not be nulltpr");
|
||||
auto sphere = [](const SceneGraphNode* n) {
|
||||
// Use the biggest of the bounding sphere and interaction sphere,
|
||||
// so we don't accidentally choose a bounding sphere that is much smaller
|
||||
// than the interaction sphere of the node
|
||||
double bs = n->boundingSphere();
|
||||
double is = n->interactionSphere();
|
||||
return is > bs ? is : bs;
|
||||
};
|
||||
|
||||
double result = sphere(node);
|
||||
|
||||
if (result < _minValidBoundingSphere) {
|
||||
// If the bs of the target is too small, try to find a good value in a child node.
|
||||
// Only check the closest children, to avoid deep traversal in the scene graph.
|
||||
// Alsp. the chance to find a bounding sphere that represents the visual size of
|
||||
// the target well is higher for these nodes
|
||||
for (SceneGraphNode* child : node->children()) {
|
||||
result = sphere(child);
|
||||
if (result > _minValidBoundingSphere) {
|
||||
LDEBUG(fmt::format(
|
||||
"The scene graph node '{}' has no, or a very small, bounding sphere. "
|
||||
"Using bounding sphere of child node '{}' in computations.",
|
||||
node->identifier(),
|
||||
child->identifier()
|
||||
));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
LDEBUG(fmt::format(
|
||||
"The scene graph node '{}' has no, or a very small, bounding sphere. Using "
|
||||
"minimal value. This might lead to unexpected results.",
|
||||
node->identifier())
|
||||
);
|
||||
|
||||
result = _minValidBoundingSphere;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const std::vector<SceneGraphNode*>& PathNavigator::relevantNodes() {
|
||||
if (!_hasInitializedRelevantNodes) {
|
||||
findRelevantNodes();
|
||||
|
||||
@@ -49,7 +49,9 @@ Waypoint::Waypoint(const glm::dvec3& pos, const glm::dquat& rot, const std::stri
|
||||
LERROR(fmt::format("Could not find node '{}'", _nodeIdentifier));
|
||||
return;
|
||||
}
|
||||
_validBoundingSphere = findValidBoundingSphere(node);
|
||||
|
||||
const PathNavigator& navigator = global::navigationHandler->pathNavigator();
|
||||
_validBoundingSphere = navigator.findValidBoundingSphere(node);
|
||||
}
|
||||
|
||||
Waypoint::Waypoint(const NavigationState& ns) {
|
||||
@@ -61,7 +63,8 @@ Waypoint::Waypoint(const NavigationState& ns) {
|
||||
}
|
||||
|
||||
_nodeIdentifier = ns.anchor;
|
||||
_validBoundingSphere = findValidBoundingSphere(anchorNode);
|
||||
const PathNavigator& navigator = global::navigationHandler->pathNavigator();
|
||||
_validBoundingSphere = navigator.findValidBoundingSphere(anchorNode);
|
||||
_pose = ns.cameraPose();
|
||||
}
|
||||
|
||||
@@ -89,41 +92,4 @@ double Waypoint::validBoundingSphere() const {
|
||||
return _validBoundingSphere;
|
||||
}
|
||||
|
||||
double Waypoint::findValidBoundingSphere(const SceneGraphNode* node) {
|
||||
double bs = node->boundingSphere();
|
||||
|
||||
const double minValidBoundingSphere =
|
||||
global::navigationHandler->pathNavigator().minValidBoundingSphere();
|
||||
|
||||
if (bs < minValidBoundingSphere) {
|
||||
// If the bs of the target is too small, try to find a good value in a child node.
|
||||
// Only check the closest children, to avoid deep traversal in the scene graph.
|
||||
// Alsp. the chance to find a bounding sphere that represents the visual size of
|
||||
// the target well is higher for these nodes
|
||||
for (SceneGraphNode* child : node->children()) {
|
||||
bs = child->boundingSphere();
|
||||
if (bs > minValidBoundingSphere) {
|
||||
LDEBUG(fmt::format(
|
||||
"The scene graph node '{}' has no, or a very small, bounding sphere. "
|
||||
"Using bounding sphere of child node '{}' in computations.",
|
||||
node->identifier(),
|
||||
child->identifier()
|
||||
));
|
||||
|
||||
return bs;
|
||||
}
|
||||
}
|
||||
|
||||
LDEBUG(fmt::format(
|
||||
"The scene graph node '{}' has no, or a very small, bounding sphere. Using "
|
||||
"minimal value. This might lead to unexpected results.",
|
||||
node->identifier())
|
||||
);
|
||||
|
||||
bs = minValidBoundingSphere;
|
||||
}
|
||||
|
||||
return bs;
|
||||
}
|
||||
|
||||
} // namespace openspace::interaction
|
||||
|
||||
Reference in New Issue
Block a user