Merge pull request #19719 from Rexbas/navicube-accumulative-animation

Gui: Accumulate orientation for NaviCube flat button animations
This commit is contained in:
Chris Hennes
2025-02-24 17:15:45 +00:00
committed by GitHub
7 changed files with 62 additions and 41 deletions

View File

@@ -54,6 +54,7 @@
#include "Command.h"
#include "Action.h"
#include "MainWindow.h"
#include "Navigation/NavigationAnimation.h"
#include "View3DInventorViewer.h"
#include "View3DInventor.h"
#include "ViewParams.h"
@@ -63,10 +64,6 @@ using namespace Eigen;
using namespace std;
using namespace Gui;
class NaviCubeImplementation {
public:
explicit NaviCubeImplementation(Gui::View3DInventorViewer*);
@@ -206,6 +203,9 @@ private:
map<PickId, LabelTexture> m_LabelTextures;
QMenu* m_Menu;
std::shared_ptr<NavigationAnimation> m_flatButtonAnimation;
SbRotation m_flatButtonTargetOrientation;
};
int NaviCubeImplementation::m_CubeWidgetSize = 132;
@@ -1102,7 +1102,17 @@ bool NaviCubeImplementation::mouseReleased(short x, short y)
else {
rotation.scaleAngle(rotStepAngle);
}
m_View3DInventorViewer->setCameraOrientation(rotation * m_View3DInventorViewer->getCameraOrientation());
// If the previous flat button animation is still active then apply the rotation to the
// previous target orientation, otherwise apply the rotation to the current camera orientation
if (m_flatButtonAnimation != nullptr && m_flatButtonAnimation->state() == QAbstractAnimation::Running) {
m_flatButtonTargetOrientation = rotation * m_flatButtonTargetOrientation;
}
else {
m_flatButtonTargetOrientation = rotation * m_View3DInventorViewer->getCameraOrientation();
}
m_flatButtonAnimation = m_View3DInventorViewer->setCameraOrientation(m_flatButtonTargetOrientation);
}
else {
return false;

View File

@@ -33,7 +33,7 @@ NavigationAnimation::NavigationAnimation(NavigationStyle* navigation)
void NavigationAnimation::updateCurrentValue(const QVariant& value)
{
if (state() == QAbstractAnimation::State::Stopped) {
if (state() != QAbstractAnimation::State::Running) {
return;
}
update(value);

View File

@@ -37,6 +37,7 @@ class GuiExport NavigationAnimation : protected QVariantAnimation
Q_OBJECT
public:
explicit NavigationAnimation(NavigationStyle* navigation);
using QVariantAnimation::state;
Q_SIGNALS:
void interrupted();

View File

@@ -386,15 +386,15 @@ SoCamera* NavigationStyle::getCamera() const
return this->viewer->getCamera();
}
void NavigationStyle::setCameraOrientation(const SbRotation& orientation, SbBool moveToCenter)
std::shared_ptr<NavigationAnimation> NavigationStyle::setCameraOrientation(const SbRotation& orientation, const SbBool moveToCenter) const
{
SoCamera* camera = getCamera();
if (!camera)
return;
return {};
animator->stop();
SbVec3f focalPoint = getFocalPoint();
const SbVec3f focalPoint = getFocalPoint();
SbVec3f translation(0, 0, 0);
if (moveToCenter) {
@@ -406,42 +406,48 @@ void NavigationStyle::setCameraOrientation(const SbRotation& orientation, SbBool
}
}
// Start an animation or set the pose directly
// Start an animation and return it
if (isAnimationEnabled()) {
viewer->startAnimation(orientation, focalPoint, translation);
return viewer->startAnimation(orientation, focalPoint, translation);
}
else {
// Distance from rotation center to camera position in camera coordinate system
SbVec3f rotationCenterDistanceCam = camera->focalDistance.getValue() * SbVec3f(0, 0, 1);
// Set to the given orientation
camera->orientation = orientation;
// or set the pose directly
// Distance from rotation center to camera position in camera coordinate system
const SbVec3f rotationCenterDistanceCam = camera->focalDistance.getValue() * SbVec3f(0, 0, 1);
// Distance from rotation center to new camera position in global coordinate system
SbVec3f newRotationCenterDistance;
camera->orientation.getValue().multVec(rotationCenterDistanceCam, newRotationCenterDistance);
// Set to the given orientation
camera->orientation = orientation;
// Reposition camera so the rotation center stays in the same place
// Optionally add translation to move to center
camera->position = focalPoint + newRotationCenterDistance + translation;
}
// Distance from rotation center to new camera position in global coordinate system
SbVec3f newRotationCenterDistance;
camera->orientation.getValue().multVec(rotationCenterDistanceCam, newRotationCenterDistance);
// Reposition camera so the rotation center stays in the same place
// Optionally add translation to move to center
camera->position = focalPoint + newRotationCenterDistance + translation;
return {};
}
void NavigationStyle::translateCamera(const SbVec3f& translation)
std::shared_ptr<NavigationAnimation> NavigationStyle::translateCamera(const SbVec3f& translation) const
{
SoCamera* camera = getCamera();
if (!camera)
return;
return {};
animator->stop();
// Start an animation or set the pose directly
// Start an animation and return it
if (isAnimationEnabled()) {
viewer->startAnimation(camera->orientation.getValue(), SbVec3f(0, 0, 0), translation);
}
else {
camera->position = camera->position.getValue() + translation;
return viewer->startAnimation(camera->orientation.getValue(), SbVec3f(0, 0, 0), translation);
}
// or set the pose directly
camera->position = camera->position.getValue() + translation;
return {};
}
void NavigationStyle::boxZoom(const SbBox2s& box)

View File

@@ -150,8 +150,8 @@ public:
SbVec3f getFocalPoint() const;
SoCamera* getCamera() const;
void setCameraOrientation(const SbRotation& orientation, SbBool moveToCenter = false);
void translateCamera(const SbVec3f& translation);
std::shared_ptr<NavigationAnimation> setCameraOrientation(const SbRotation& orientation, SbBool moveToCenter = false) const;
std::shared_ptr<NavigationAnimation> translateCamera(const SbVec3f& translation) const;
#if (COIN_MAJOR_VERSION * 100 + COIN_MINOR_VERSION * 10 + COIN_MICRO_VERSION < 403)
void findBoundingSphere();

View File

@@ -3216,9 +3216,9 @@ void View3DInventorViewer::pubSeekToPoint(const SbVec3f& pos)
this->seekToPoint(pos);
}
void View3DInventorViewer::setCameraOrientation(const SbRotation& orientation, bool moveToCenter)
std::shared_ptr<NavigationAnimation> View3DInventorViewer::setCameraOrientation(const SbRotation& orientation, const bool moveToCenter) const
{
navigation->setCameraOrientation(orientation, moveToCenter);
return navigation->setCameraOrientation(orientation, moveToCenter);
}
void View3DInventorViewer::setCameraType(SoType type)
@@ -3629,12 +3629,14 @@ bool View3DInventorViewer::isSpinning() const
* @param translation An additional translation on top of the translation caused by the rotation around the rotation center
* @param duration The duration in milliseconds
* @param wait When false, start the animation and continue (asynchronous). When true, start the animation and wait for the animation to finish (synchronous)
*
* @return The started @class NavigationAnimation
*/
void View3DInventorViewer::startAnimation(const SbRotation& orientation,
std::shared_ptr<NavigationAnimation> View3DInventorViewer::startAnimation(const SbRotation& orientation,
const SbVec3f& rotationCenter,
const SbVec3f& translation,
int duration,
bool wait)
const bool wait) const
{
// Currently starts a FixedTimeAnimation. If there is going to be an additional animation like
// FixedVelocityAnimation, check the animation type from a parameter and start the right animation
@@ -3654,6 +3656,8 @@ void View3DInventorViewer::startAnimation(const SbRotation& orientation,
navigation, orientation, rotationCenter, translation, duration, easingCurve);
navigation->startAnimating(animation, wait);
return animation;
}
/**

View File

@@ -75,7 +75,7 @@ namespace Base {
}
namespace Gui {
class NavigationAnimation;
class ViewProvider;
class SoFCBackgroundGradient;
class NavigationStyle;
@@ -165,8 +165,8 @@ public:
bool isSpinningAnimationEnabled() const;
bool isAnimating() const;
bool isSpinning() const;
void startAnimation(const SbRotation& orientation, const SbVec3f& rotationCenter,
const SbVec3f& translation, int duration = -1, bool wait = false);
std::shared_ptr<NavigationAnimation> startAnimation(const SbRotation& orientation, const SbVec3f& rotationCenter,
const SbVec3f& translation, int duration = -1, bool wait = false) const;
void startSpinningAnimation(const SbVec3f& axis, float velocity);
void stopAnimating();
@@ -386,10 +386,10 @@ public:
/**
* Set the camera's orientation. If isAnimationEnabled() returns
* \a true the reorientation is animated, otherwise its directly
* \a true the reorientation is animated and the animation is returned, otherwise its directly
* set.
*/
void setCameraOrientation(const SbRotation& orientation, bool moveToCenter = false);
std::shared_ptr<NavigationAnimation> setCameraOrientation(const SbRotation& orientation, bool moveToCenter = false) const;
void setCameraType(SoType type) override;
void moveCameraTo(const SbRotation& orientation, const SbVec3f& position, int duration = -1);
/**