mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-05-01 08:19:51 -05:00
Cancel follow anchor node rotation interpolation when the anchor is changed
This commit is contained in:
@@ -116,7 +116,7 @@ datamessagestructures::CameraKeyframe ExternInteraction::generateCameraKeyframe(
|
||||
//kf._position = global::navigationHandler.camera()->positionVec3();
|
||||
kf._position = navHandler.orbitalNavigator().anchorNodeToCameraVector();
|
||||
|
||||
kf._followNodeRotation = navHandler.orbitalNavigator().followingNodeRotation();
|
||||
kf._followNodeRotation = navHandler.orbitalNavigator().followingAnchorRotation();
|
||||
if (kf._followNodeRotation) {
|
||||
kf._position = glm::inverse(focusNode->worldRotationMatrix()) * kf._position;
|
||||
kf._rotation = navHandler.orbitalNavigator().anchorNodeToCameraRotation();
|
||||
|
||||
@@ -376,7 +376,7 @@ NavigationHandler::NavigationState NavigationHandler::navigationState(
|
||||
void NavigationHandler::saveNavigationState(const std::string& filepath,
|
||||
const std::string& referenceFrameIdentifier)
|
||||
{
|
||||
const SceneGraphNode* referenceFrame = _orbitalNavigator.followingNodeRotation() ?
|
||||
const SceneGraphNode* referenceFrame = _orbitalNavigator.followingAnchorRotation() ?
|
||||
_orbitalNavigator.anchorNode() :
|
||||
sceneGraph()->root();
|
||||
|
||||
|
||||
@@ -368,6 +368,13 @@ void OrbitalNavigator::resetVelocities() {
|
||||
_joystickStates.resetVelocities();
|
||||
_websocketStates.resetVelocities();
|
||||
_scriptStates.resetVelocities();
|
||||
|
||||
if (shouldFollowAnchorRotation()) {
|
||||
_followRotationInterpolator.end();
|
||||
}
|
||||
else {
|
||||
_followRotationInterpolator.start();
|
||||
}
|
||||
}
|
||||
|
||||
void OrbitalNavigator::updateStatesFromInput(const InputState& inputState,
|
||||
@@ -452,10 +459,7 @@ void OrbitalNavigator::updateCameraStateFromStates(double deltaTime) {
|
||||
anchorNodeRotationDiff = interpolateRotationDifferential(
|
||||
deltaTime,
|
||||
_followRotationInterpolationTime,
|
||||
anchorNodeRotationDiff,
|
||||
anchorPos,
|
||||
pose.position,
|
||||
posHandle
|
||||
anchorNodeRotationDiff
|
||||
);
|
||||
|
||||
// Update local rotation based on user input
|
||||
@@ -588,12 +592,16 @@ void OrbitalNavigator::setAnchorNode(const SceneGraphNode* anchorNode) {
|
||||
if (!_anchorNode) {
|
||||
_directlySetStereoDistance = true;
|
||||
}
|
||||
if (_anchorNode != anchorNode) {
|
||||
|
||||
const bool changedAnchor = _anchorNode != anchorNode;
|
||||
_anchorNode = anchorNode;
|
||||
|
||||
// Need to reset velocities after the actual switch in anchor node,
|
||||
// since the reset behavior depends on the anchor node.
|
||||
if (changedAnchor) {
|
||||
resetVelocities();
|
||||
}
|
||||
|
||||
_anchorNode = anchorNode;
|
||||
|
||||
if (_anchorNode) {
|
||||
_previousAnchorNodePosition = _anchorNode->worldPosition();
|
||||
_previousAnchorNodeRotation = glm::quat_cast(_anchorNode->worldRotationMatrix());
|
||||
@@ -693,7 +701,32 @@ void OrbitalNavigator::setRetargetInterpolationTime(float durationInSeconds) {
|
||||
_retargetInterpolationTime = durationInSeconds;
|
||||
}
|
||||
|
||||
bool OrbitalNavigator::followingNodeRotation() const {
|
||||
bool OrbitalNavigator::shouldFollowAnchorRotation() const
|
||||
{
|
||||
if (!_anchorNode) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const glm::dmat4 modelTransform = _anchorNode->modelTransform();
|
||||
const glm::dmat4 inverseModelTransform = _anchorNode->inverseModelTransform();
|
||||
const glm::dvec3 cameraPositionModelSpace = glm::dvec3(inverseModelTransform *
|
||||
glm::dvec4(_camera->positionVec3(), 1.0));
|
||||
|
||||
const SurfacePositionHandle positionHandle =
|
||||
_anchorNode->calculateSurfacePositionHandle(cameraPositionModelSpace);
|
||||
|
||||
const double maximumDistanceForRotation = glm::length(
|
||||
glm::dmat3(modelTransform) * positionHandle.centerToReferenceSurface
|
||||
) * _followAnchorNodeRotationDistance;
|
||||
|
||||
const double distanceToCamera =
|
||||
glm::distance(_camera->positionVec3(), _anchorNode->worldPosition());
|
||||
|
||||
return distanceToCamera < maximumDistanceForRotation;
|
||||
}
|
||||
|
||||
|
||||
bool OrbitalNavigator::followingAnchorRotation() const {
|
||||
if (_aimNode != nullptr && _aimNode != _anchorNode) {
|
||||
return false;
|
||||
}
|
||||
@@ -1245,22 +1278,10 @@ glm::dvec3 OrbitalNavigator::pushToSurface(double minHeightAboveGround,
|
||||
|
||||
glm::dquat OrbitalNavigator::interpolateRotationDifferential(double deltaTime,
|
||||
double interpolationTime,
|
||||
const glm::dquat& rotationDiff,
|
||||
const glm::dvec3& objectPosition,
|
||||
const glm::dvec3& cameraPosition,
|
||||
const SurfacePositionHandle& positionHandle)
|
||||
const glm::dquat& rotationDiff)
|
||||
{
|
||||
const glm::dmat4 modelTransform = _anchorNode->modelTransform();
|
||||
|
||||
const double maximumDistanceForRotation = glm::length(
|
||||
glm::dmat3(modelTransform) * positionHandle.centerToReferenceSurface
|
||||
) * _followAnchorNodeRotationDistance;
|
||||
const double distanceToCamera = glm::distance(cameraPosition, objectPosition);
|
||||
|
||||
// Interpolate with a negative delta time if distance is too large to follow
|
||||
const double interpolationSign = glm::sign(
|
||||
maximumDistanceForRotation - distanceToCamera
|
||||
);
|
||||
const double interpolationSign = shouldFollowAnchorRotation() ? 1.0 : -1.0;
|
||||
|
||||
_followRotationInterpolator.setInterpolationTime(static_cast<float>(
|
||||
interpolationTime
|
||||
|
||||
@@ -597,7 +597,7 @@ void ParallelPeer::sendCameraKeyframe() {
|
||||
datamessagestructures::CameraKeyframe kf;
|
||||
kf._position = navHandler.orbitalNavigator().anchorNodeToCameraVector();
|
||||
|
||||
kf._followNodeRotation = navHandler.orbitalNavigator().followingNodeRotation();
|
||||
kf._followNodeRotation = navHandler.orbitalNavigator().followingAnchorRotation();
|
||||
if (kf._followNodeRotation) {
|
||||
kf._position = glm::inverse(focusNode->worldRotationMatrix()) * kf._position;
|
||||
kf._rotation = navHandler.orbitalNavigator().anchorNodeToCameraRotation();
|
||||
|
||||
Reference in New Issue
Block a user