mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-02-09 04:59:56 -06:00
Add smooth transition when resetting camera direction.
This commit is contained in:
@@ -710,30 +710,7 @@ void InteractionHandler::setCamera(Camera* camera) {
|
||||
|
||||
void InteractionHandler::resetCameraDirection() {
|
||||
LINFO("Setting camera direction to point at focus node.");
|
||||
|
||||
glm::dquat rotation = _camera->rotationQuaternion();
|
||||
glm::dvec3 focusPosition = focusNode()->worldPosition();
|
||||
glm::dvec3 cameraPosition = _camera->positionVec3();
|
||||
glm::dvec3 lookUpVector = _camera->lookUpVectorWorldSpace();
|
||||
|
||||
glm::dvec3 directionToFocusNode = glm::normalize(focusPosition - cameraPosition);
|
||||
|
||||
// To make sure the lookAt function won't fail
|
||||
static const double epsilon = 0.000001;
|
||||
if (glm::dot(lookUpVector, directionToFocusNode) > 1.0 - epsilon) {
|
||||
// Change the look up vector a little bit
|
||||
lookUpVector = glm::normalize(lookUpVector + glm::dvec3(epsilon));
|
||||
}
|
||||
|
||||
// Create the rotation to look at focus node
|
||||
glm::dmat4 lookAtMat = glm::lookAt(
|
||||
glm::dvec3(0, 0, 0),
|
||||
directionToFocusNode,
|
||||
lookUpVector);
|
||||
glm::dquat rotationLookAtFocusNode = normalize(quat_cast(inverse(lookAtMat)));
|
||||
|
||||
// Update camera Rotation
|
||||
_camera->setRotation(rotationLookAtFocusNode);
|
||||
_currentInteractionMode->rotateToFocusNodeInterpolator().start();
|
||||
}
|
||||
|
||||
void InteractionHandler::setInteractionMode(std::shared_ptr<InteractionMode> interactionMode) {
|
||||
|
||||
@@ -153,7 +153,10 @@ namespace interaction {
|
||||
|
||||
|
||||
|
||||
InteractionMode::InteractionMode() {
|
||||
InteractionMode::InteractionMode()
|
||||
: _rotateToFocusNodeInterpolator(Interpolator<double>([](double t){
|
||||
return pow(t, 2);
|
||||
})) {
|
||||
}
|
||||
|
||||
|
||||
@@ -174,6 +177,11 @@ SceneGraphNode* InteractionMode::focusNode() {
|
||||
return _focusNode;
|
||||
}
|
||||
|
||||
Interpolator<double>& InteractionMode::rotateToFocusNodeInterpolator() {
|
||||
return _rotateToFocusNodeInterpolator;
|
||||
};
|
||||
|
||||
|
||||
// KeyframeInteractionMode
|
||||
KeyframeInteractionMode::KeyframeInteractionMode(){
|
||||
|
||||
@@ -319,10 +327,11 @@ glm::dvec2 OrbitalInteractionMode::MouseStates::synchedGlobalRollMouseVelocity()
|
||||
return _globalRollMouseState.velocity.get();
|
||||
}
|
||||
|
||||
OrbitalInteractionMode::OrbitalInteractionMode(std::shared_ptr<MouseStates> mouseStates)
|
||||
OrbitalInteractionMode::OrbitalInteractionMode(
|
||||
std::shared_ptr<MouseStates> mouseStates)
|
||||
: InteractionMode()
|
||||
, _mouseStates(mouseStates){
|
||||
|
||||
, _mouseStates(mouseStates) {
|
||||
|
||||
}
|
||||
|
||||
OrbitalInteractionMode::~OrbitalInteractionMode() {
|
||||
@@ -367,12 +376,23 @@ void OrbitalInteractionMode::updateCameraStateFromMouseStates(Camera& camera) {
|
||||
glm::angleAxis(_mouseStates->synchedLocalRollMouseVelocity().x, dvec3(0, 0, 1));
|
||||
localCameraRotation = localCameraRotation * cameraRollRotation;
|
||||
}
|
||||
if (!_rotateToFocusNodeInterpolator.isInterpolating())
|
||||
{ // Do local rotation
|
||||
dvec3 eulerAngles(_mouseStates->synchedLocalRotationMouseVelocity().y, _mouseStates->synchedLocalRotationMouseVelocity().x, 0);
|
||||
dquat rotationDiff = dquat(eulerAngles);
|
||||
|
||||
localCameraRotation = localCameraRotation * rotationDiff;
|
||||
}
|
||||
else
|
||||
{ // Interpolate local rotation to focus node
|
||||
double t = _rotateToFocusNodeInterpolator.value();
|
||||
localCameraRotation = slerp(localCameraRotation, dquat(dvec3(0.0)), t);
|
||||
_rotateToFocusNodeInterpolator.step(0.002); // Should probably depend on dt
|
||||
// This is a fast but ugly solution to slow regaining of control...
|
||||
if (t > 0.18) {
|
||||
_rotateToFocusNodeInterpolator.end();
|
||||
}
|
||||
}
|
||||
{ // Do global rotation
|
||||
dvec2 smoothMouseVelocity = _mouseStates->synchedGlobalRotationMouseVelocity();
|
||||
dvec3 eulerAngles(-smoothMouseVelocity.y, -smoothMouseVelocity.x, 0);
|
||||
@@ -519,12 +539,23 @@ void GlobeBrowsingInteractionMode::updateCameraStateFromMouseStates(Camera& came
|
||||
glm::angleAxis(_mouseStates->synchedLocalRollMouseVelocity().x, dvec3(0, 0, 1));
|
||||
localCameraRotation = localCameraRotation * cameraRollRotation;
|
||||
}
|
||||
if(!_rotateToFocusNodeInterpolator.isInterpolating())
|
||||
{ // Do local rotation
|
||||
glm::dvec3 eulerAngles(_mouseStates->synchedLocalRotationMouseVelocity().y, _mouseStates->synchedLocalRotationMouseVelocity().x, 0);
|
||||
glm::dquat rotationDiff = glm::dquat(eulerAngles);
|
||||
|
||||
localCameraRotation = localCameraRotation * rotationDiff;
|
||||
}
|
||||
else
|
||||
{ // Interpolate local rotation to focus node
|
||||
double t = _rotateToFocusNodeInterpolator.value();
|
||||
localCameraRotation = slerp(localCameraRotation, dquat(dvec3(0.0)), t);
|
||||
_rotateToFocusNodeInterpolator.step(0.002); // Should probably depend on dt
|
||||
// This is a fast but ugly solution to slow regaining of control...
|
||||
if (t > 0.2) {
|
||||
_rotateToFocusNodeInterpolator.end();
|
||||
}
|
||||
}
|
||||
{ // Do global rotation (horizontal movement)
|
||||
glm::dvec3 eulerAngles = glm::dvec3(
|
||||
-_mouseStates->synchedGlobalRotationMouseVelocity().y,
|
||||
|
||||
Reference in New Issue
Block a user