diff --git a/src/Gui/CMakeLists.txt b/src/Gui/CMakeLists.txt index 16169537f8..248ea7ac4e 100644 --- a/src/Gui/CMakeLists.txt +++ b/src/Gui/CMakeLists.txt @@ -833,8 +833,6 @@ SET(View3D_CPP_SRCS View3DPy.cpp View3DViewerPy.cpp NaviCube.cpp - NavigationAnimator.cpp - NavigationAnimation.cpp ) SET(View3D_SRCS ${View3D_CPP_SRCS} @@ -857,8 +855,6 @@ SET(View3D_SRCS CoinRiftWidget.h View3DViewerPy.h NaviCube.h - NavigationAnimator.h - NavigationAnimation.h ) SOURCE_GROUP("View3D" FILES ${View3D_SRCS}) diff --git a/src/Gui/DemoMode.cpp b/src/Gui/DemoMode.cpp index dab35bc98a..5dadc25a0c 100644 --- a/src/Gui/DemoMode.cpp +++ b/src/Gui/DemoMode.cpp @@ -91,7 +91,7 @@ void DemoMode::reset() view->getViewer()->stopAnimating(); ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath ("User parameter:BaseApp/Preferences/View"); - hGrp->Notify("UseNavigationAnimations"); + hGrp->Notify("UseAutoRotation"); } void DemoMode::accept() @@ -273,9 +273,8 @@ void DemoMode::startAnimation(Gui::View3DInventor* view) { if (!view->getViewer()->isAnimationEnabled()) view->getViewer()->setAnimationEnabled(true); - - view->getViewer()->startSpinningAnimation(getDirection(view), - getSpeed(ui->speedSlider->value())); + view->getViewer()->startAnimating(getDirection(view), + getSpeed(ui->speedSlider->value())); } void DemoMode::onTimerCheckToggled(bool on) diff --git a/src/Gui/NavigationAnimation.cpp b/src/Gui/NavigationAnimation.cpp deleted file mode 100644 index 5f62366054..0000000000 --- a/src/Gui/NavigationAnimation.cpp +++ /dev/null @@ -1,145 +0,0 @@ -// SPDX-License-Identifier: LGPL-2.1-or-later -/**************************************************************************** - * * - * Copyright (c) 2023 Bas Ruigrok (Rexbas) * - * * - * This file is part of FreeCAD. * - * * - * FreeCAD is free software: you can redistribute it and/or modify it * - * under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 2.1 of the * - * License, or (at your option) any later version. * - * * - * FreeCAD is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public * - * License along with FreeCAD. If not, see * - * . * - * * - ***************************************************************************/ - -#include "PreCompiled.h" -#include "NavigationAnimation.h" -#include - -using namespace Gui; - -NavigationAnimation::NavigationAnimation(NavigationStyle* navigation) - : navigation(navigation), started(false) -{} - -void NavigationAnimation::startAnimation(QAbstractAnimation::DeletionPolicy policy) -{ - started = true; - QAbstractAnimation::start(policy); -} - -void NavigationAnimation::updateCurrentValue(const QVariant& value) -{ - if (!started) { - return; - } - update(value); -} - -void NavigationAnimation::stopAnimation() -{ - QAbstractAnimation::stop(); -} - -FixedTimeAnimation::FixedTimeAnimation(NavigationStyle* navigation, const SbRotation& orientation, - const SbVec3f& rotationCenter, const SbVec3f& translation, - int duration) - : NavigationAnimation(navigation) - , targetOrientation(orientation) - , targetTranslation(translation) - , rotationCenter(rotationCenter) -{ - setDuration(duration); - setStartValue(0.0); - setEndValue(duration * 1.0); -} - -void FixedTimeAnimation::initialize() -{ - prevAngle = 0; - prevTranslation = SbVec3f(0, 0, 0); - - // Find an axis and angle to rotate from the camera orientation to the target orientation using post-multiplication - SbVec3f rotationAxisPost; - float angle; - SbRotation(navigation->getCamera()->orientation.getValue().inverse() * targetOrientation).getValue(rotationAxisPost, angle); - if (angle > M_PI) { - angle -= 2 * M_PI; - } - - // Convert post-multiplication axis to a pre-multiplication axis - navigation->getCamera()->orientation.getValue().inverse().multVec(rotationAxisPost, rotationAxis); - - angularVelocity = angle / duration(); - linearVelocity = targetTranslation / duration(); -} - -/** - * @param value The elapsed time - */ -void FixedTimeAnimation::update(const QVariant& value) -{ - float angle = value.toFloat() * angularVelocity; - SbVec3f translation = value.toFloat() * linearVelocity; - - SbRotation rotation(rotationAxis, angle - prevAngle); - - navigation->reorientCamera(navigation->getCamera(), rotation, rotationCenter); - navigation->getCamera()->position = navigation->getCamera()->position.getValue() + translation - prevTranslation; - - prevAngle = angle; - prevTranslation = translation; -} - -/** - * @param navigation The navigation style - * @param axis The rotation axis in screen coordinates - * @param velocity The angular velocity in radians per second - */ -SpinningAnimation::SpinningAnimation(NavigationStyle* navigation, const SbVec3f& axis, - float velocity) - : NavigationAnimation(navigation) - , rotationAxis(axis) -{ - setDuration((2 * M_PI / velocity) * 1000.0); - setStartValue(0.0); - setEndValue(2 * M_PI); - setLoopCount(-1); -} - -void SpinningAnimation::initialize() -{ - prevAngle = 0; - - navigation->setViewing(true); - navigation->setViewingMode(NavigationStyle::SPINNING); -} - -/** - * @param value The angle in radians - */ -void SpinningAnimation::update(const QVariant& value) -{ - SbRotation deltaRotation = SbRotation(rotationAxis, value.toFloat() - prevAngle); - navigation->reorientCamera(navigation->getCamera(), deltaRotation); - - prevAngle = value.toFloat(); -} - -void SpinningAnimation::stopAnimation() -{ - NavigationAnimation::stopAnimation(); - if (navigation->getViewingMode() != NavigationStyle::SPINNING) { - return; - } - navigation->setViewingMode(navigation->isViewing() ? NavigationStyle::IDLE : NavigationStyle::INTERACT); -} diff --git a/src/Gui/NavigationAnimation.h b/src/Gui/NavigationAnimation.h deleted file mode 100644 index 0488db5ed6..0000000000 --- a/src/Gui/NavigationAnimation.h +++ /dev/null @@ -1,96 +0,0 @@ -// SPDX-License-Identifier: LGPL-2.1-or-later -/**************************************************************************** - * * - * Copyright (c) 2023 Bas Ruigrok (Rexbas) * - * * - * This file is part of FreeCAD. * - * * - * FreeCAD is free software: you can redistribute it and/or modify it * - * under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 2.1 of the * - * License, or (at your option) any later version. * - * * - * FreeCAD is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public * - * License along with FreeCAD. If not, see * - * . * - * * - ***************************************************************************/ - -#ifndef GUI_NAVIGATIONANIMATION_H -#define GUI_NAVIGATIONANIMATION_H - -#include "NavigationStyle.h" -#include -#include -#include - -namespace Gui -{ - -class GuiExport NavigationAnimation : protected QVariantAnimation -{ -public: - explicit NavigationAnimation(NavigationStyle* navigation); - -protected: - NavigationStyle* navigation; - - virtual void initialize() = 0; - virtual void update(const QVariant& value) = 0; - virtual void stopAnimation(); - -private: - bool started; - - void startAnimation(QAbstractAnimation::DeletionPolicy policy = KeepWhenStopped); - void updateCurrentValue(const QVariant& value) override; - - friend class NavigationAnimator; -}; - -class GuiExport FixedTimeAnimation : public NavigationAnimation -{ -public: - explicit FixedTimeAnimation(NavigationStyle* navigation, const SbRotation& orientation, - const SbVec3f& rotationCenter, const SbVec3f& translation, - int duration); - -private: - float angularVelocity; // [rad/ms] - SbVec3f linearVelocity; // [/ms] - - SbRotation targetOrientation; - SbVec3f targetTranslation; - - float prevAngle; - SbVec3f prevTranslation; - - SbVec3f rotationCenter; - SbVec3f rotationAxis; - - void initialize() override; - void update(const QVariant& value) override; -}; - -class GuiExport SpinningAnimation : public NavigationAnimation -{ -public: - explicit SpinningAnimation(NavigationStyle* navigation, const SbVec3f& axis, float velocity); - -private: - SbVec3f rotationAxis; - float prevAngle; - - void initialize() override; - void update(const QVariant& value) override; - void stopAnimation() override; -}; - -} // namespace Gui - -#endif // GUI_NAVIGATIONANIMATION_H diff --git a/src/Gui/NavigationAnimator.cpp b/src/Gui/NavigationAnimator.cpp deleted file mode 100644 index 0060952746..0000000000 --- a/src/Gui/NavigationAnimator.cpp +++ /dev/null @@ -1,99 +0,0 @@ -// SPDX-License-Identifier: LGPL-2.1-or-later -/**************************************************************************** - * * - * Copyright (c) 2023 Bas Ruigrok (Rexbas) * - * * - * This file is part of FreeCAD. * - * * - * FreeCAD is free software: you can redistribute it and/or modify it * - * under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 2.1 of the * - * License, or (at your option) any later version. * - * * - * FreeCAD is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public * - * License along with FreeCAD. If not, see * - * . * - * * - ***************************************************************************/ - -#include "PreCompiled.h" -#include "NavigationAnimator.h" -#include "NavigationAnimation.h" -#include - -using namespace Gui; - -NavigationAnimator::NavigationAnimator() - : activeAnimation(nullptr) -{} - -NavigationAnimator::~NavigationAnimator() -{ - stop(); -} - -/** - * @brief Start an animation - * - * @param animation The animation to start - */ -void NavigationAnimator::start(const std::shared_ptr& animation) -{ - stop(); - activeAnimation = animation; - activeAnimation->initialize(); - - connect(activeAnimation.get(), &NavigationAnimation::finished, this, &NavigationAnimator::reset); - activeAnimation->startAnimation(); -} - -/** - * @brief Start an animation and wait for it to finish - * - * @param animation The animation to start - * @return True if the animation finished, false if interrupted - */ -bool NavigationAnimator::startAndWait(const std::shared_ptr& animation) -{ - stop(); - bool finished = true; - QEventLoop loop; - loop.connect(animation.get(), &NavigationAnimation::finished, - [&loop, &finished, &animation]() { // clazy:exclude=lambda-in-connect - if (animation->state() == QAbstractAnimation::State::Running) { - finished = false; - } - - loop.quit(); - }); - start(animation); - loop.exec(); - return finished; -} - -/** - * @brief Stops an active animation - */ -void NavigationAnimator::stop() -{ - if (activeAnimation != nullptr && activeAnimation->state() != QAbstractAnimation::State::Stopped) { - Q_EMIT activeAnimation->finished(); - } -} - -/** - * @brief Stops the animation and releases ownership of the animation - * - * Is called when the animation finished() signal is received which is triggered when the animation - * is finished or when the animation is interrupted by NavigationAnimator::stop() - */ -void NavigationAnimator::reset() { - activeAnimation->started = false; - activeAnimation->stopAnimation(); - activeAnimation.reset(); -} diff --git a/src/Gui/NavigationAnimator.h b/src/Gui/NavigationAnimator.h deleted file mode 100644 index d3d654560f..0000000000 --- a/src/Gui/NavigationAnimator.h +++ /dev/null @@ -1,55 +0,0 @@ -// SPDX-License-Identifier: LGPL-2.1-or-later -/**************************************************************************** - * * - * Copyright (c) 2023 Bas Ruigrok (Rexbas) * - * * - * This file is part of FreeCAD. * - * * - * FreeCAD is free software: you can redistribute it and/or modify it * - * under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation, either version 2.1 of the * - * License, or (at your option) any later version. * - * * - * FreeCAD is distributed in the hope that it will be useful, but * - * WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public * - * License along with FreeCAD. If not, see * - * . * - * * - ***************************************************************************/ - -#ifndef GUI_NAVIGATIONANIMATOR_H -#define GUI_NAVIGATIONANIMATOR_H - -#include "NavigationStyle.h" -#include -#include - -namespace Gui -{ - -class NavigationAnimation; - -class GuiExport NavigationAnimator : public QObject -{ - Q_OBJECT -public: - NavigationAnimator(); - ~NavigationAnimator(); - void start(const std::shared_ptr& animation); - bool startAndWait(const std::shared_ptr& animation); - void stop(); - -private Q_SLOTS: - void reset(); - -private: - std::shared_ptr activeAnimation; -}; - -} // namespace Gui - -#endif // GUI_NAVIGATIONANIMATOR_H diff --git a/src/Gui/NavigationStyle.cpp b/src/Gui/NavigationStyle.cpp index 54e799ae0b..e3490ead43 100644 --- a/src/Gui/NavigationStyle.cpp +++ b/src/Gui/NavigationStyle.cpp @@ -45,13 +45,40 @@ #include "Application.h" #include "MenuManager.h" #include "MouseSelection.h" -#include "NavigationAnimator.h" -#include "NavigationAnimation.h" #include "SoMouseWheelEvent.h" #include "View3DInventorViewer.h" + using namespace Gui; +namespace Gui { +struct NavigationStyleP { + int animationsteps; + int animationdelta; + SbVec3f focal1, focal2; + SbVec3f rotationCenter; + SbBool rotationCenterFound; + NavigationStyle::RotationCenterModes rotationCenterMode; + SbRotation endRotation; + SoTimerSensor * animsensor; + float sensitivity; + SbBool resetcursorpos; + + NavigationStyleP() + { + this->animationsteps = 0; + this->animationdelta = 0; + this->animsensor = nullptr; + this->sensitivity = 2.0f; + this->resetcursorpos = false; + this->rotationCenterFound = false; + this->rotationCenterMode = NavigationStyle::RotationCenterMode::ScenePointAtCursor | + NavigationStyle::RotationCenterMode::FocalPointAtCursor; + } + static void viewAnimationCB(void * data, SoSensor * sensor); +}; +} + class FCSphereSheetProjector : public SbSphereSheetProjector { using inherited = SbSphereSheetProjector; @@ -157,19 +184,25 @@ const Base::Type& NavigationStyleEvent::style() const return t; } +#define PRIVATE(ptr) (ptr->pimpl) +#define PUBLIC(ptr) (ptr->pub) + TYPESYSTEM_SOURCE_ABSTRACT(Gui::NavigationStyle,Base::BaseClass) NavigationStyle::NavigationStyle() : viewer(nullptr), mouseSelection(nullptr) { - this->rotationCenterMode = NavigationStyle::RotationCenterMode::ScenePointAtCursor - | NavigationStyle::RotationCenterMode::FocalPointAtCursor; + PRIVATE(this) = new NavigationStyleP(); + PRIVATE(this)->animsensor = new SoTimerSensor(NavigationStyleP::viewAnimationCB, this); initialize(); } NavigationStyle::~NavigationStyle() { finalize(); - delete this->animator; + if (PRIVATE(this)->animsensor->isScheduled()) + PRIVATE(this)->animsensor->unschedule(); + delete PRIVATE(this)->animsensor; + delete PRIVATE(this); } NavigationStyle& NavigationStyle::operator = (const NavigationStyle& ns) @@ -189,15 +222,12 @@ void NavigationStyle::setViewer(View3DInventorViewer* view) void NavigationStyle::initialize() { - this->animator = new NavigationAnimator(); - - this->sensitivity = 2.0f; - this->resetcursorpos = false; this->currentmode = NavigationStyle::IDLE; + this->prevRedrawTime = SbTime::getTimeOfDay(); this->spinanimatingallowed = true; this->spinsamplecounter = 0; this->spinincrement = SbRotation::identity(); - this->rotationCenterFound = false; + this->spinRotation.setValue(SbVec3f(0, 0, -1), 0); // FIXME: use a smaller sphere than the default one to have a larger // area close to the borders that gives us "z-axis rotation"? @@ -323,71 +353,171 @@ SbBool NavigationStyle::lookAtPoint(const SbVec2s screenpos) SbVec3f hitpoint; hitpoint = picked->getPoint(); - this->rotationCenterFound = false; - translateCamera(hitpoint - getFocalPoint()); + lookAtPoint(hitpoint); return true; } -SoCamera* NavigationStyle::getCamera() const +void NavigationStyle::lookAtPoint(const SbVec3f& pos) { - return this->viewer->getCamera(); + SoCamera* cam = viewer->getSoRenderManager()->getCamera(); + if (!cam) + return; + PRIVATE(this)->rotationCenterFound = false; + + // Find global coordinates of focal point. + SbVec3f direction; + cam->orientation.getValue().multVec(SbVec3f(0, 0, -1), direction); + PRIVATE(this)->focal1 = cam->position.getValue() + + cam->focalDistance.getValue() * direction; + PRIVATE(this)->focal2 = pos; + + // avoid to interfere with spinning (fixes #3101462) + if (this->isAnimating()) + this->stopAnimating(); + + if (PRIVATE(this)->animsensor->isScheduled()) { + PRIVATE(this)->animsensor->unschedule(); + this->interactiveCountDec(); + } + + if (isAnimationEnabled()) { + SbRotation cam_rot = cam->orientation.getValue(); + // get the amount of movement + SbVec3f dir1 = direction, dir2; + dir2 = pos - cam->position.getValue(); + dir2.normalize(); + SbRotation rot(dir1, dir2); + float val = 0.5f*(1.0f + dir1.dot(dir2)); // value in range [0,1] + int div = (int)(val * 20.0f); + int steps = 20-div; // do it with max. 20 steps + + // check whether a movement is required + if (steps > 0) { + PRIVATE(this)->endRotation = cam_rot; + this->spinRotation = cam_rot; + PRIVATE(this)->animationsteps = 5; + PRIVATE(this)->animationdelta = std::max(100/steps, 5); + PRIVATE(this)->animsensor->setBaseTime(SbTime::getTimeOfDay()); + PRIVATE(this)->animsensor->schedule(); + this->interactiveCountInc(); + } + else { + // set to the given position + SbVec3f direction; + cam->orientation.getValue().multVec(SbVec3f(0, 0, -1), direction); + cam->position = pos - cam->focalDistance.getValue() * direction; + } + } + else { + // set to the given position + SbVec3f direction; + cam->orientation.getValue().multVec(SbVec3f(0, 0, -1), direction); + cam->position = pos - cam->focalDistance.getValue() * direction; + } } -void NavigationStyle::setCameraOrientation(const SbRotation& orientation, SbBool moveToCenter) +void NavigationStyle::setCameraOrientation(const SbRotation& rot, SbBool moveToCenter) { - SoCamera* camera = getCamera(); - if (!camera) + SoCamera* cam = viewer->getSoRenderManager()->getCamera(); + if (!cam) return; - animator->stop(); - - SbVec3f focalPoint = getFocalPoint(); - SbVec3f translation(0, 0, 0); - + // Find global coordinates of focal point. + SbVec3f direction; + cam->orientation.getValue().multVec(SbVec3f(0, 0, -1), direction); + PRIVATE(this)->focal1 = cam->position.getValue() + + cam->focalDistance.getValue() * direction; + PRIVATE(this)->focal2 = PRIVATE(this)->focal1; if (moveToCenter) { SoGetBoundingBoxAction action(viewer->getSoRenderManager()->getViewportRegion()); action.apply(viewer->getSceneGraph()); SbBox3f box = action.getBoundingBox(); if (!box.isEmpty()) { - translation = box.getCenter() - focalPoint; + rot.multVec(SbVec3f(0, 0, -1), direction); + //float s = (this->focal1 - box.getCenter()).dot(direction); + //this->focal2 = box.getCenter() + s * direction; + // setting the center of the overall bounding box as the future focal point + // seems to be a satisfactory solution + PRIVATE(this)->focal2 = box.getCenter(); } } - // Start an animation or set the pose directly + // avoid to interfere with spinning (fixes #3101462) + if (this->isAnimating()) + this->stopAnimating(); + + if (PRIVATE(this)->animsensor->isScheduled()) { + PRIVATE(this)->animsensor->unschedule(); + this->interactiveCountDec(); + } + if (isAnimationEnabled()) { - viewer->startAnimation(orientation, focalPoint, translation); + // get the amount of movement + SbVec3f dir1, dir2; + SbRotation cam_rot = cam->orientation.getValue(); + cam_rot.multVec(SbVec3f(0, 0, -1), dir1); + rot.multVec(SbVec3f(0, 0, -1), dir2); + float val = 0.5f*(1.0f + dir1.dot(dir2)); // value in range [0,1] + int div = (int)(val * 20.0f); + int steps = 20-div; // do it with max. 20 steps + + // check whether a movement is required + if (steps > 0) { + PRIVATE(this)->endRotation = rot; // this is the final camera orientation + this->spinRotation = cam_rot; + PRIVATE(this)->animationsteps = 5; + PRIVATE(this)->animationdelta = std::max(100/steps, 5); + PRIVATE(this)->animsensor->setBaseTime(SbTime::getTimeOfDay()); + PRIVATE(this)->animsensor->schedule(); + this->interactiveCountInc(); + } + else { + // due to possible round-off errors make sure that the + // exact orientation is set + cam->orientation.setValue(rot); + cam->position = PRIVATE(this)->focal2 - cam->focalDistance.getValue() * direction; + } } 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; - - // 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; + // set to the given rotation + cam->orientation.setValue(rot); + cam->orientation.getValue().multVec(SbVec3f(0, 0, -1), direction); + cam->position = PRIVATE(this)->focal2 - cam->focalDistance.getValue() * direction; } } -void NavigationStyle::translateCamera(const SbVec3f& translation) +void NavigationStyleP::viewAnimationCB(void * data, SoSensor * sensor) { - SoCamera* camera = getCamera(); - if (!camera) - return; + Q_UNUSED(sensor); + auto that = static_cast(data); + if (PRIVATE(that)->animationsteps > 0) { + // here the camera rotates from the current rotation to a given + // rotation (e.g. the standard views). To get this movement animated + // we calculate an interpolated rotation and update the view after + // each step + float step = std::min((float)PRIVATE(that)->animationsteps/100.0f, 1.0f); + SbRotation slerp = SbRotation::slerp(that->spinRotation, PRIVATE(that)->endRotation, step); + SbVec3f focalpoint = (1.0f-step)*PRIVATE(that)->focal1 + step*PRIVATE(that)->focal2; + SoCamera* cam = that->viewer->getSoRenderManager()->getCamera(); + if (!cam) // no camera + return; - animator->stop(); + SbVec3f direction; + cam->orientation.setValue(slerp); + cam->orientation.getValue().multVec(SbVec3f(0, 0, -1), direction); + cam->position = focalpoint - cam->focalDistance.getValue() * direction; - // Start an animation or set the pose directly - if (isAnimationEnabled()) { - viewer->startAnimation(camera->orientation.getValue(), SbVec3f(0, 0, 0), translation); - } - else { - camera->position = camera->position.getValue() + translation; + PRIVATE(that)->animationsteps += PRIVATE(that)->animationdelta; + if (PRIVATE(that)->animationsteps > 100) { + // now we have reached the end of the movement + PRIVATE(that)->animationsteps=0; + PRIVATE(that)->animsensor->unschedule(); + that->interactiveCountDec(); + // set to the actual given rotation + cam->orientation.setValue(PRIVATE(that)->endRotation); + cam->orientation.getValue().multVec(SbVec3f(0, 0, -1), direction); + cam->position = PRIVATE(that)->focal2 - cam->focalDistance.getValue() * direction; + } } } @@ -474,41 +604,29 @@ void NavigationStyle::viewAll() } } -/** Rotate the camera by the given amount, then reposition it so we're still pointing at the same - * focal point +/** Rotate the camera by the given amount, then reposition it so we're + * still pointing at the same focal point. */ -void NavigationStyle::reorientCamera(SoCamera* camera, const SbRotation& rotation) +void NavigationStyle::reorientCamera(SoCamera * cam, const SbRotation & rot) { - reorientCamera(camera, rotation, getFocalPoint()); -} - -/** Rotate the camera by the given amount, then reposition it so the rotation center stays in the - * same place - */ -void NavigationStyle::reorientCamera(SoCamera* camera, const SbRotation& rotation, const SbVec3f& rotationCenter) -{ - if (!camera) { + if (!cam) return; - } - // Distance from rotation center to camera position in camera coordinate system - SbVec3f rotationCenterDistanceCam; - camera->orientation.getValue().inverse().multVec(camera->position.getValue() - rotationCenter, rotationCenterDistanceCam); - - // Set new orientation value by accumulating the new rotation - camera->orientation = rotation * camera->orientation.getValue(); + // Find global coordinates of focal point. + SbVec3f direction; + cam->orientation.getValue().multVec(SbVec3f(0, 0, -1), direction); + SbVec3f focalpoint = cam->position.getValue() + + cam->focalDistance.getValue() * direction; + // Set new orientation value by accumulating the new rotation. + cam->orientation = rot * cam->orientation.getValue(); // Fix issue with near clipping in orthogonal view - if (camera->getTypeId().isDerivedFrom(SoOrthographicCamera::getClassTypeId())) { - camera->focalDistance = static_cast(camera)->height; + if (cam->getTypeId().isDerivedFrom(SoOrthographicCamera::getClassTypeId())) { + cam->focalDistance = static_cast(cam)->height; } - - // 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 - camera->position = rotationCenter + newRotationCenterDistance; + // Reposition camera so we are still pointing at the same old focal point. + cam->orientation.getValue().multVec(SbVec3f(0, 0, -1), direction); + cam->position = focalpoint - cam->focalDistance.getValue() * direction; } void NavigationStyle::panCamera(SoCamera * cam, float aspectratio, const SbPlane & panplane, @@ -566,7 +684,7 @@ void NavigationStyle::panToCenter(const SbPlane & pplane, const SbVec2f & currpo const SbViewportRegion & vp = viewer->getSoRenderManager()->getViewportRegion(); float ratio = vp.getViewportAspectRatio(); panCamera(viewer->getSoRenderManager()->getCamera(), ratio, pplane, SbVec2f(0.5,0.5), currpos); - this->rotationCenterFound = false; + PRIVATE(this)->rotationCenterFound = false; } /** Dependent on the camera type this will either shrink or expand the @@ -577,9 +695,6 @@ void NavigationStyle::zoom(SoCamera * cam, float diffvalue) { if (!cam) // can happen for empty scenegraph return; - - animator->stop(); - SoType t = cam->getTypeId(); SbName tname = t.getName(); @@ -747,14 +862,14 @@ void NavigationStyle::doRotate(SoCamera * camera, float angle, const SbVec2f& po SbVec3f NavigationStyle::getRotationCenter(SbBool& found) const { - found = this->rotationCenterFound; - return this->rotationCenter; + found = PRIVATE(this)->rotationCenterFound; + return PRIVATE(this)->rotationCenter; } void NavigationStyle::setRotationCenter(const SbVec3f& cnt) { - this->rotationCenter = cnt; - this->rotationCenterFound = true; + PRIVATE(this)->rotationCenter = cnt; + PRIVATE(this)->rotationCenterFound = true; } SbVec3f NavigationStyle::getFocalPoint() const @@ -786,8 +901,8 @@ void NavigationStyle::spin(const SbVec2f & pointerpos) lastpos[0] = float(this->log.position[1][0]) / float(std::max((int)(glsize[0]-1), 1)); lastpos[1] = float(this->log.position[1][1]) / float(std::max((int)(glsize[1]-1), 1)); - if (this->rotationCenterMode && this->rotationCenterFound) { - SbVec3f hitpoint = this->rotationCenter; + if (PRIVATE(this)->rotationCenterMode && PRIVATE(this)->rotationCenterFound) { + SbVec3f hitpoint = PRIVATE(this)->rotationCenter; // set to the given position SbVec3f direction; @@ -814,7 +929,7 @@ void NavigationStyle::spin(const SbVec2f & pointerpos) r.invert(); this->reorientCamera(viewer->getSoRenderManager()->getCamera(), r); - if (this->rotationCenterMode && this->rotationCenterFound) { + if (PRIVATE(this)->rotationCenterMode && PRIVATE(this)->rotationCenterFound) { float ratio = vp.getViewportAspectRatio(); SbViewVolume vv = viewer->getSoRenderManager()->getCamera()->getViewVolume(vp.getViewportAspectRatio()); SbPlane panplane = vv.getPlane(viewer->getSoRenderManager()->getCamera()->focalDistance.getValue()); @@ -900,7 +1015,7 @@ SbBool NavigationStyle::doSpin() float radians; rot.getValue(axis, radians); if ((radians > 0.01f) && (deltatime < 0.300)) { - viewer->startSpinningAnimation(axis, radians * 5); + this->spinRotation = rot; return true; } } @@ -915,14 +1030,14 @@ void NavigationStyle::saveCursorPosition(const SoEvent * const ev) this->localPos = ev->getPosition(); // mode is WindowCenter - if (!this->rotationCenterMode) { + if (!PRIVATE(this)->rotationCenterMode) { setRotationCenter(getFocalPoint()); } //Option to get point on model (slow) or always on focal plane (fast) // // mode is ScenePointAtCursor to get exact point if possible - if (this->rotationCenterMode & NavigationStyle::RotationCenterMode::ScenePointAtCursor) { + if (PRIVATE(this)->rotationCenterMode & NavigationStyle::RotationCenterMode::ScenePointAtCursor) { SoRayPickAction rpaction(viewer->getSoRenderManager()->getViewportRegion()); rpaction.setPoint(this->localPos); rpaction.setRadius(viewer->getPickRadius()); @@ -936,7 +1051,7 @@ void NavigationStyle::saveCursorPosition(const SoEvent * const ev) } // mode is FocalPointAtCursor or a ScenePointAtCursor failed - if (this->rotationCenterMode & NavigationStyle::RotationCenterMode::FocalPointAtCursor) { + if (PRIVATE(this)->rotationCenterMode & NavigationStyle::RotationCenterMode::FocalPointAtCursor) { // get the intersection point of the ray and the focal plane const SbViewportRegion & vp = viewer->getSoRenderManager()->getViewportRegion(); float ratio = vp.getViewportAspectRatio(); @@ -957,7 +1072,7 @@ void NavigationStyle::saveCursorPosition(const SoEvent * const ev) } // mode is BoundingBoxCenter or a ScenePointAtCursor failed - if (this->rotationCenterMode & NavigationStyle::RotationCenterMode::BoundingBoxCenter) { + if (PRIVATE(this)->rotationCenterMode & NavigationStyle::RotationCenterMode::BoundingBoxCenter) { const SbViewportRegion & vp = viewer->getSoRenderManager()->getViewportRegion(); float ratio = vp.getViewportAspectRatio(); @@ -1013,6 +1128,20 @@ void NavigationStyle::moveCursorPosition() } } +void NavigationStyle::updateAnimation() +{ + SbTime now = SbTime::getTimeOfDay(); + double secs = now.getValue() - prevRedrawTime.getValue(); + this->prevRedrawTime = now; + + if (this->isAnimating()) { + // here the camera rotates around a fix axis + SbRotation deltaRotation = this->spinRotation; + deltaRotation.scaleAngle(secs * 5.0); + this->reorientCamera(viewer->getSoRenderManager()->getCamera(), deltaRotation); + } +} + void NavigationStyle::redraw() { if (mouseSelection) @@ -1039,7 +1168,7 @@ void NavigationStyle::setAnimationEnabled(const SbBool enable) { this->spinanimatingallowed = enable; - if (!enable && this->isAnimating()) { animator->stop(); } + if (!enable && this->isAnimating()) { this->stopAnimating(); } } /*! @@ -1062,29 +1191,52 @@ SbBool NavigationStyle::isAnimating() const return this->currentmode == NavigationStyle::SPINNING; } -NavigationAnimator* NavigationStyle::getAnimator() const +/*! + * Starts programmatically the viewer in animation mode. The given axis direction + * is always in screen coordinates, not in world coordinates. + */ +void NavigationStyle::startAnimating(const SbVec3f& axis, float velocity) { - return this->animator; + if (!isAnimationEnabled()) + return; + + this->prevRedrawTime = SbTime::getTimeOfDay(); + this->spinincrement = SbRotation::identity(); + SbRotation rot; + rot.setValue(axis, velocity); + + this->setViewing(true); + this->setViewingMode(NavigationStyle::SPINNING); + this->spinRotation = rot; +} + +void NavigationStyle::stopAnimating() +{ + if (this->currentmode != NavigationStyle::SPINNING) { + return; + } + this->setViewingMode(this->isViewing() ? + NavigationStyle::IDLE : NavigationStyle::INTERACT); } void NavigationStyle::setSensitivity(float val) { - this->sensitivity = val; + PRIVATE(this)->sensitivity = val; } float NavigationStyle::getSensitivity() const { - return this->sensitivity; + return PRIVATE(this)->sensitivity; } void NavigationStyle::setResetCursorPosition(SbBool on) { - this->resetcursorpos = on; + PRIVATE(this)->resetcursorpos = on; } SbBool NavigationStyle::isResetCursorPosition() const { - return this->resetcursorpos; + return PRIVATE(this)->resetcursorpos; } void NavigationStyle::setZoomInverted(SbBool on) @@ -1114,12 +1266,12 @@ SbBool NavigationStyle::isZoomAtCursor() const void NavigationStyle::setRotationCenterMode(NavigationStyle::RotationCenterModes mode) { - this->rotationCenterMode = mode; + PRIVATE(this)->rotationCenterMode = mode; } NavigationStyle::RotationCenterModes NavigationStyle::getRotationCenterMode() const { - return this->rotationCenterMode; + return PRIVATE(this)->rotationCenterMode; } void NavigationStyle::startSelection(AbstractMouseSelection* mouse) @@ -1263,7 +1415,6 @@ void NavigationStyle::setViewingMode(const ViewerMode newmode) case DRAGGING: // Set up initial projection point for the projector object when // first starting a drag operation. - animator->stop(); viewer->showRotationCenter(true); this->spinprojector->project(this->lastmouseposition); this->interactiveCountInc(); @@ -1277,18 +1428,15 @@ void NavigationStyle::setViewingMode(const ViewerMode newmode) break; case PANNING: - animator->stop(); pan(viewer->getSoRenderManager()->getCamera()); this->interactiveCountInc(); break; case ZOOMING: - animator->stop(); this->interactiveCountInc(); break; case BOXZOOM: - animator->stop(); this->interactiveCountInc(); break; diff --git a/src/Gui/NavigationStyle.h b/src/Gui/NavigationStyle.h index 1bcdef2854..cbc6204a9a 100644 --- a/src/Gui/NavigationStyle.h +++ b/src/Gui/NavigationStyle.h @@ -52,7 +52,6 @@ class SbSphereSheetProjector; namespace Gui { class View3DInventorViewer; -class NavigationAnimator; class AbstractMouseSelection; /** @@ -123,8 +122,9 @@ public: void setAnimationEnabled(const SbBool enable); SbBool isAnimationEnabled() const; + void startAnimating(const SbVec3f& axis, float velocity); + void stopAnimating(); SbBool isAnimating() const; - NavigationAnimator* getAnimator() const; void setSensitivity(float); float getSensitivity() const; @@ -144,14 +144,11 @@ public: void setRotationCenter(const SbVec3f& cnt); SbVec3f getFocalPoint() const; + void updateAnimation(); void redraw(); - SoCamera* getCamera() const; - void setCameraOrientation(const SbRotation& orientation, SbBool moveToCenter = false); - void translateCamera(const SbVec3f& translation); - void reorientCamera(SoCamera* camera, const SbRotation& rotation); - void reorientCamera(SoCamera* camera, const SbRotation& rotation, const SbVec3f& rotationCenter); - + void setCameraOrientation(const SbRotation& rot, SbBool moveTocenter=false); + void lookAtPoint(const SbVec3f&); void boxZoom(const SbBox2s& box); virtual void viewAll(); @@ -176,9 +173,6 @@ public: void setOrbitStyle(OrbitStyle style); OrbitStyle getOrbitStyle() const; - SbBool isViewing() const; - void setViewing(SbBool); - SbVec3f getRotationCenter(SbBool&) const; protected: @@ -189,12 +183,15 @@ protected: void interactiveCountDec(); int getInteractiveCount() const; + SbBool isViewing() const; + void setViewing(SbBool); SbBool isSeekMode() const; void setSeekMode(SbBool enable); SbBool seekToPoint(const SbVec2s screenpos); void seekToPoint(const SbVec3f& scenepos); SbBool lookAtPoint(const SbVec2s screenpos); + void reorientCamera(SoCamera * camera, const SbRotation & rot); void panCamera(SoCamera * camera, float vpaspect, const SbPlane & panplane, @@ -236,13 +233,13 @@ protected: } log; View3DInventorViewer* viewer{nullptr}; - NavigationAnimator* animator; ViewerMode currentmode; SoMouseButtonEvent mouseDownConsumedEvent; SbVec2f lastmouseposition; SbVec2s globalPos; SbVec2s localPos; SbPlane panningplane; + SbTime prevRedrawTime; SbTime centerTime; SbBool lockrecenter; SbBool menuenabled; @@ -264,17 +261,13 @@ protected: SbBool spinanimatingallowed; int spinsamplecounter; SbRotation spinincrement; + SbRotation spinRotation; SbSphereSheetProjector * spinprojector; //@} private: - friend class NavigationAnimator; - - SbVec3f rotationCenter; - SbBool rotationCenterFound; - NavigationStyle::RotationCenterModes rotationCenterMode; - float sensitivity; - SbBool resetcursorpos; + struct NavigationStyleP* pimpl; + friend struct NavigationStyleP; }; /** Sub-classes of this class appear in the preference dialog where users can diff --git a/src/Gui/PreferencePackTemplates/View.cfg b/src/Gui/PreferencePackTemplates/View.cfg index 708b9b9498..6ad815c14c 100644 --- a/src/Gui/PreferencePackTemplates/View.cfg +++ b/src/Gui/PreferencePackTemplates/View.cfg @@ -32,8 +32,7 @@ - - + diff --git a/src/Gui/PreferencePages/DlgSettingsNavigation.cpp b/src/Gui/PreferencePages/DlgSettingsNavigation.cpp index 9e307a8816..55ff7a0a66 100644 --- a/src/Gui/PreferencePages/DlgSettingsNavigation.cpp +++ b/src/Gui/PreferencePages/DlgSettingsNavigation.cpp @@ -88,8 +88,7 @@ void DlgSettingsNavigation::saveSettings() ui->rotationCenterSize->onSave(); ui->rotationCenterColor->onSave(); ui->spinBoxZoomStep->onSave(); - ui->checkBoxNavigationAnimations->onSave(); - ui->spinBoxAnimationDuration->onSave(); + ui->checkBoxUseAutoRotation->onSave(); ui->qspinNewDocScale->onSave(); ui->prefStepByTurn->onSave(); ui->naviCubeCorner->onSave(); @@ -116,7 +115,7 @@ void DlgSettingsNavigation::saveSettings() hGrp = App::GetApplication().GetParameterGroupByPath( "User parameter:BaseApp/Preferences/NaviCube"); if (ui->naviCubeFontName->currentIndex()) { - hGrp->SetASCII("FontString", ui->naviCubeFontName->currentText().toLatin1()); + hGrp->SetASCII("FontString", ui->naviCubeFontName->currentText().toLatin1()); } else { hGrp->RemoveASCII("FontString"); } @@ -130,8 +129,7 @@ void DlgSettingsNavigation::loadSettings() ui->rotationCenterSize->onRestore(); ui->rotationCenterColor->onRestore(); ui->spinBoxZoomStep->onRestore(); - ui->checkBoxNavigationAnimations->onRestore(); - ui->spinBoxAnimationDuration->onRestore(); + ui->checkBoxUseAutoRotation->onRestore(); ui->qspinNewDocScale->onRestore(); ui->prefStepByTurn->onRestore(); ui->naviCubeCorner->onRestore(); @@ -193,7 +191,7 @@ void DlgSettingsNavigation::loadSettings() QStringList familyNames = QFontDatabase::families(QFontDatabase::Any); #endif ui->naviCubeFontName->addItems(familyNames); - + hGrp = App::GetApplication().GetParameterGroupByPath( "User parameter:BaseApp/Preferences/NaviCube"); int indexFamilyNames = familyNames.indexOf( diff --git a/src/Gui/PreferencePages/DlgSettingsNavigation.ui b/src/Gui/PreferencePages/DlgSettingsNavigation.ui index 2e7879bdd9..6ccab19a45 100644 --- a/src/Gui/PreferencePages/DlgSettingsNavigation.ui +++ b/src/Gui/PreferencePages/DlgSettingsNavigation.ui @@ -566,91 +566,27 @@ The value is the diameter of the sphere to fit on the screen. - + true - Enable navigation animations + Enable animated rotations - Enable navigation animations + Enable animation - true + false - UseNavigationAnimations + UseAutoRotation View - - - - Duration of navigation animations that have a fixed duration - - - Animation duration - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - 60 - 16777215 - - - - The duration of navigation animations in milliseconds - - - 100 - - - 10000 - - - 50 - - - 250 - - - AnimationDuration - - - View - - - - - - - Qt::Horizontal - - - QSizePolicy::MinimumExpanding - - - - 10 - 20 - - - - - - @@ -673,7 +609,7 @@ The value is the diameter of the sphere to fit on the screen. - Zoom step + Zoom step Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter diff --git a/src/Gui/View3DInventorViewer.cpp b/src/Gui/View3DInventorViewer.cpp index 4ca6a20fb9..ee2a800766 100644 --- a/src/Gui/View3DInventorViewer.cpp +++ b/src/Gui/View3DInventorViewer.cpp @@ -118,8 +118,6 @@ #include "ViewProvider.h" #include "ViewProviderDocumentObject.h" #include "ViewProviderLink.h" -#include "NavigationAnimator.h" -#include "NavigationAnimation.h" FC_LOG_LEVEL_INIT("3DViewer",true,true) @@ -204,8 +202,8 @@ while the progress bar is running. class Gui::ViewerEventFilter : public QObject { public: - ViewerEventFilter() {} - ~ViewerEventFilter() override {} + ViewerEventFilter() = default; + ~ViewerEventFilter() override = default; bool eventFilter(QObject* obj, QEvent* event) override { // Bug #0000607: Some mice also support horizontal scrolling which however might @@ -247,8 +245,8 @@ public: class SpaceNavigatorDevice : public Quarter::InputDevice { public: - SpaceNavigatorDevice() {} - ~SpaceNavigatorDevice() override {} + SpaceNavigatorDevice() = default; + ~SpaceNavigatorDevice() override = default; const SoEvent* translateEvent(QEvent* event) override { if (event->type() == Spaceball::MotionEvent::MotionEventType) { @@ -2248,6 +2246,8 @@ void View3DInventorViewer::renderScene() drawSingleBackground(col); glra->apply(this->backgroundroot); + navigation->updateAnimation(); + if (!this->shading) { state->push(); SoLightModelElement::set(state, selectionRoot, SoLightModelElement::BASE_COLOR); @@ -2765,9 +2765,9 @@ void View3DInventorViewer::pubSeekToPoint(const SbVec3f& pos) this->seekToPoint(pos); } -void View3DInventorViewer::setCameraOrientation(const SbRotation& orientation, SbBool moveToCenter) +void View3DInventorViewer::setCameraOrientation(const SbRotation& rot, SbBool moveTocenter) { - navigation->setCameraOrientation(orientation, moveToCenter); + navigation->setCameraOrientation(rot, moveTocenter); } void View3DInventorViewer::setCameraType(SoType t) @@ -2788,19 +2788,54 @@ void View3DInventorViewer::setCameraType(SoType t) } } -void View3DInventorViewer::moveCameraTo(const SbRotation& orientation, const SbVec3f& position) +namespace Gui { + class CameraAnimation : public QVariantAnimation + { + SoCamera* camera; + SbRotation startRot, endRot; + SbVec3f startPos, endPos; + + public: + CameraAnimation(SoCamera* camera, const SbRotation& rot, const SbVec3f& pos) + : camera(camera), endRot(rot), endPos(pos) + { + startPos = camera->position.getValue(); + startRot = camera->orientation.getValue(); + } + ~CameraAnimation() override = default; + protected: + void updateCurrentValue(const QVariant & value) override + { + int steps = endValue().toInt(); + int curr = value.toInt(); + + float s = static_cast(curr)/static_cast(steps); + SbVec3f curpos = startPos * (1.0f-s) + endPos * s; + SbRotation currot = SbRotation::slerp(startRot, endRot, s); + camera->orientation.setValue(currot); + camera->position.setValue(curpos); + } + }; +} + +void View3DInventorViewer::moveCameraTo(const SbRotation& rot, const SbVec3f& pos, int steps, int ms) { - SoCamera* camera = getCamera(); - if (!camera) + SoCamera* cam = this->getSoRenderManager()->getCamera(); + if (!cam) return; - if (isAnimationEnabled()) { - startAnimation( - orientation, camera->position.getValue(), position - camera->position.getValue(), true); - } + CameraAnimation anim(cam, rot, pos); + anim.setDuration(Base::clamp(ms,0,5000)); + anim.setStartValue(static_cast(0)); + anim.setEndValue(steps); - camera->orientation.setValue(orientation); - camera->position.setValue(position); + QEventLoop loop; + QObject::connect(&anim, &CameraAnimation::finished, &loop, &QEventLoop::quit); + anim.start(); + loop.exec(QEventLoop::ExcludeUserInputEvents); + + cam->orientation.setValue(rot); + cam->position.setValue(pos); } void View3DInventorViewer::animatedViewAll(int steps, int ms) @@ -3082,49 +3117,18 @@ SbBool View3DInventorViewer::isAnimating() const return navigation->isAnimating(); } -/** - * @brief Change the camera pose with an animation - * - * @param orientation The new orientation - * @param rotationCenter The rotation center - * @param translation An additional translation on top of the translation caused by the rotation around the rotation center +/*! + * Starts programmatically the viewer in animation mode. The given axis direction + * is always in screen coordinates, not in world coordinates. */ -void View3DInventorViewer::startAnimation(const SbRotation& orientation, - const SbVec3f& rotationCenter, const SbVec3f& translation, bool wait) +void View3DInventorViewer::startAnimating(const SbVec3f& axis, float velocity) { - // 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 - - int duration = App::GetApplication() - .GetParameterGroupByPath("User parameter:BaseApp/Preferences/View") - ->GetInt("AnimationDuration", 250); - - auto animation = std::make_shared( - navigation, orientation, rotationCenter, translation, duration); - - if (wait) { - navigation->getAnimator()->startAndWait(animation); - } - else { - navigation->getAnimator()->start(animation); - } -} - -/** - * @brief Start an infinite spin animation - * - * @param axis The rotation axis in screen coordinates - * @param velocity The angular velocity in radians per second - */ -void View3DInventorViewer::startSpinningAnimation(const SbVec3f& axis, float velocity) -{ - auto animation = std::make_shared(navigation, axis, velocity); - navigation->getAnimator()->start(animation); + navigation->startAnimating(axis, velocity); } void View3DInventorViewer::stopAnimating() { - navigation->getAnimator()->stop(); + navigation->stopAnimating(); } void View3DInventorViewer::setPopupMenuEnabled(const SbBool on) diff --git a/src/Gui/View3DInventorViewer.h b/src/Gui/View3DInventorViewer.h index 85441f11b8..0f0edfb429 100644 --- a/src/Gui/View3DInventorViewer.h +++ b/src/Gui/View3DInventorViewer.h @@ -164,9 +164,7 @@ public: void setPopupMenuEnabled(const SbBool on); SbBool isPopupMenuEnabled() const; - void startAnimation(const SbRotation& orientation, const SbVec3f& rotationCenter, - const SbVec3f& translation, bool wait = false); - void startSpinningAnimation(const SbVec3f& axis, float velocity); + void startAnimating(const SbVec3f& axis, float velocity); void stopAnimating(); SbBool isAnimating() const; @@ -375,9 +373,9 @@ public: * \a true the reorientation is animated, otherwise its directly * set. */ - void setCameraOrientation(const SbRotation& orientation, SbBool moveToCenter = false); + void setCameraOrientation(const SbRotation& rot, SbBool moveTocenter=false); void setCameraType(SoType t) override; - void moveCameraTo(const SbRotation& orientation, const SbVec3f& position); + void moveCameraTo(const SbRotation& rot, const SbVec3f& pos, int steps, int ms); /** * Zooms the viewport to the size of the bounding box. */ diff --git a/src/Gui/View3DPy.cpp b/src/Gui/View3DPy.cpp index 7e36f8b4a3..92f407bbab 100644 --- a/src/Gui/View3DPy.cpp +++ b/src/Gui/View3DPy.cpp @@ -777,8 +777,10 @@ Py::Object View3DInventorPy::getCameraOrientation() Py::Object View3DInventorPy::viewPosition(const Py::Tuple& args) { - PyObject* p = nullptr; - if (!PyArg_ParseTuple(args.ptr(), "|O!", &Base::PlacementPy::Type, &p)) + PyObject* p=nullptr; + int steps = 20; + int ms = 30; + if (!PyArg_ParseTuple(args.ptr(), "|O!ii",&Base::PlacementPy::Type,&p,&steps,&ms)) throw Py::Exception(); if (p) { @@ -789,7 +791,7 @@ Py::Object View3DInventorPy::viewPosition(const Py::Tuple& args) rot.getValue(q0,q1,q2,q3); getView3DIventorPtr()->getViewer()->moveCameraTo( SbRotation((float)q0, (float)q1, (float)q2, (float)q3), - SbVec3f((float)pos.x, (float)pos.y, (float)pos.z)); + SbVec3f((float)pos.x, (float)pos.y, (float)pos.z), steps, ms); } SoCamera* cam = getView3DIventorPtr()->getViewer()->getSoRenderManager()->getCamera(); @@ -808,11 +810,11 @@ Py::Object View3DInventorPy::viewPosition(const Py::Tuple& args) Py::Object View3DInventorPy::startAnimating(const Py::Tuple& args) { - float x, y, z; + float x,y,z; float velocity; - if (!PyArg_ParseTuple(args.ptr(), "ffff", &x, &y, &z, &velocity)) + if (!PyArg_ParseTuple(args.ptr(), "ffff", &x,&y,&z,&velocity)) throw Py::Exception(); - getView3DIventorPtr()->getViewer()->startSpinningAnimation(SbVec3f(x, y, z), velocity); + getView3DIventorPtr()->getViewer()->startAnimating(SbVec3f(x,y,z),velocity); return Py::None(); } diff --git a/src/Gui/View3DSettings.cpp b/src/Gui/View3DSettings.cpp index 449302fffb..f16e5e5acb 100644 --- a/src/Gui/View3DSettings.cpp +++ b/src/Gui/View3DSettings.cpp @@ -74,7 +74,7 @@ void View3DSettings::applySettings() OnChange(*hGrp,"CornerCoordSystem"); OnChange(*hGrp,"CornerCoordSystemSize"); OnChange(*hGrp,"ShowAxisCross"); - OnChange(*hGrp,"UseNavigationAnimations"); + OnChange(*hGrp,"UseAutoRotation"); OnChange(*hGrp,"Gradient"); OnChange(*hGrp,"RadialGradient"); OnChange(*hGrp,"BackgroundColor"); @@ -287,9 +287,9 @@ void View3DSettings::OnChange(ParameterGrp::SubjectType &rCaller,ParameterGrp::M _viewer->setAxisCross(rGrp.GetBool("ShowAxisCross", false)); } } - else if (strcmp(Reason,"UseNavigationAnimations") == 0) { + else if (strcmp(Reason,"UseAutoRotation") == 0) { for (auto _viewer : _viewers) { - _viewer->setAnimationEnabled(rGrp.GetBool("UseNavigationAnimations", true)); + _viewer->setAnimationEnabled(rGrp.GetBool("UseAutoRotation", false)); } } else if (strcmp(Reason,"Gradient") == 0 || strcmp(Reason,"RadialGradient") == 0) {