Cancel follow anchor node rotation interpolation when the anchor is changed

This commit is contained in:
Emil Axelsson
2019-08-13 18:35:22 +02:00
parent 4ab094e681
commit e06993332c
5 changed files with 49 additions and 29 deletions
+1 -1
View File
@@ -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();
+1 -1
View File
@@ -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();
+43 -22
View File
@@ -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
+1 -1
View File
@@ -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();