]> SALOME platform Git repositories - modules/gui.git/blob - src/OCCViewer/OCCViewer_AutoRotate.cxx
Salome HOME
Merge branch 'V9_12_BR'
[modules/gui.git] / src / OCCViewer / OCCViewer_AutoRotate.cxx
1 // Copyright (C) 2007-2023  CEA, EDF, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
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.
10 //
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.
15 //
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
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 #include "OCCViewer_AutoRotate.h"
24 #include "OCCViewer_ViewWindow.h"
25 #include "OCCViewer_ViewPort3d.h"
26
27 #include <SUIT_ViewWindow.h>
28
29 #include <gp_Quaternion.hxx>
30
31 #include <QtGlobal>
32 #include <QDateTime>
33 #include <QMouseEvent>
34 #include <QPoint>
35
36
37
38 OCCViewer_AutoRotate::OCCViewer_AutoRotate(SUIT_ViewWindow* theWindow)
39   : SUIT_AutoRotate(theWindow)
40 {
41 }
42
43
44 OCCViewer_AutoRotate::~OCCViewer_AutoRotate()
45 {
46   OCCViewer_ViewWindow *aWnd = dynamic_cast<OCCViewer_ViewWindow*>(myWindow);
47   if (aWnd) {
48     OCCViewer_ViewPort3d* aViewPort = aWnd->getViewPort();
49     if (aViewPort) {
50       aViewPort->stopRotation();
51     }
52   }
53 }
54
55
56 bool OCCViewer_AutoRotate::startAnimation()
57 {
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);
68       if (aWnd) {
69         OCCViewer_ViewPort3d* aViewPort = aWnd->getViewPort();
70         if (aViewPort) {
71           Handle(V3d_View) aView = aViewPort->getView();
72           if ( !aView.IsNull() ) {
73             Standard_Real rx, ry;
74             aView->Size(rx, ry);
75
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()));
81
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)); 
87
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]);
95
96             gp_Quaternion quat = aTrsf.GetRotation();
97             gp_Vec aAxis;
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;
104             if (anAngle != 0.)
105               aViewPort->setRotationAxis(aAxis, anAngle*3./aScale, dz*12./aScale);
106           }
107         }
108         return true;
109       }
110     }
111   }
112
113   return false;
114 }
115
116
117 bool OCCViewer_AutoRotate::stopAnimation()
118 {
119   OCCViewer_ViewWindow *aWnd = dynamic_cast<OCCViewer_ViewWindow*>(myWindow);
120   if (aWnd) {
121     OCCViewer_ViewPort3d* aViewPort = aWnd->getViewPort();
122     if (aViewPort) {
123       aViewPort->stopRotation();
124       return true;
125     }
126   }
127   return false;
128 }