1 // Copyright (C) 2007-2023 CEA, EDF, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #include "OCCViewer_AutoRotate.h"
24 #include "OCCViewer_ViewWindow.h"
25 #include "OCCViewer_ViewPort3d.h"
27 #include <SUIT_ViewWindow.h>
29 #include <gp_Quaternion.hxx>
33 #include <QMouseEvent>
38 OCCViewer_AutoRotate::OCCViewer_AutoRotate(SUIT_ViewWindow* theWindow)
39 : SUIT_AutoRotate(theWindow)
44 OCCViewer_AutoRotate::~OCCViewer_AutoRotate()
46 OCCViewer_ViewWindow *aWnd = dynamic_cast<OCCViewer_ViewWindow*>(myWindow);
48 OCCViewer_ViewPort3d* aViewPort = aWnd->getViewPort();
50 aViewPort->stopRotation();
56 bool OCCViewer_AutoRotate::startAnimation()
58 const int LastIdx = 4;
59 const int PrevIdx = 10;
60 if (myLog.myHistorySize > PrevIdx) {
61 qint64 aStopTime = (QDateTime::currentMSecsSinceEpoch() - myLog.myTime[LastIdx]);
62 // Compute the maximum time spent between two distinct mouse move events until we consider the
63 // mouse being move at the time, the manual rotation action stops (mouse button released).
64 // If the mouse was moving, then we trigger the continuous view animation.
65 qint64 maxTime = qint64((myLog.myTime[LastIdx] - myLog.myTime[PrevIdx]) * 1.2);
66 if (aStopTime < (qint64)maxTime) {
67 OCCViewer_ViewWindow *aWnd = dynamic_cast<OCCViewer_ViewWindow*>(myWindow);
69 OCCViewer_ViewPort3d* aViewPort = aWnd->getViewPort();
71 Handle(V3d_View) aView = aViewPort->getView();
72 if ( !aView.IsNull() ) {
76 Standard_Real dx=0., dy=0., dz=0.;
77 dx = (Standard_Real(this->myLog.myPosition[LastIdx].x()) - this->myLog.myPosition[PrevIdx].x()) * M_PI / rx;
78 dy = (this->myLog.myPosition[PrevIdx].y() - Standard_Real(this->myLog.myPosition[LastIdx].y())) * M_PI / ry;
79 dz = atan2(Standard_Real(this->myLog.myPosition[LastIdx].x())-rx/2., ry/2.-Standard_Real(this->myLog.myPosition[LastIdx].y()))
80 - atan2(Standard_Real(this->myLog.myPosition[PrevIdx].x())-rx/2., ry/2.-Standard_Real(this->myLog.myPosition[PrevIdx].y()));
82 Handle(Graphic3d_Camera) aCamera = aView->Camera();
83 gp_Pnt aRCenter = aView->GravityPoint();
84 gp_Dir aZAxis (aCamera->Direction().Reversed());
85 gp_Dir aYAxis (aCamera->Up());
86 gp_Dir aXAxis (aYAxis.Crossed (aZAxis));
88 gp_Trsf aRot[3], aTrsf;
89 aRot[0].SetRotation (gp_Ax1 (aRCenter, aYAxis), -dx);
90 aRot[1].SetRotation (gp_Ax1 (aRCenter, aXAxis), dy);
91 aRot[2].SetRotation (gp_Ax1 (aRCenter, aZAxis), dz);
92 aTrsf.Multiply (aRot[0]);
93 aTrsf.Multiply (aRot[1]);
94 aTrsf.Multiply (aRot[2]);
96 gp_Quaternion quat = aTrsf.GetRotation();
98 Standard_Real anAngle=0., aScale=1.;
99 quat.GetVectorAndAngle(aAxis, anAngle);
100 aScale = aView->Scale();
101 // std::cout << "Axis=[" << aAxis.X() << " , " << aAxis.Y() << " , " << aAxis.Z()
102 // << "] Angle=" << anAngle * 180. * 3./aScale / M_PI
103 // << " deg z-Angle=" << dz * 180. * 12./aScale / M_PI << " deg Scale=" << aScale << std::endl;
105 aViewPort->setRotationAxis(aAxis, anAngle*3./aScale, dz*12./aScale);
117 bool OCCViewer_AutoRotate::stopAnimation()
119 OCCViewer_ViewWindow *aWnd = dynamic_cast<OCCViewer_ViewWindow*>(myWindow);
121 OCCViewer_ViewPort3d* aViewPort = aWnd->getViewPort();
123 aViewPort->stopRotation();