Salome HOME
2c03bee21d208da75198e514603ae942edd42133
[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     qint64 delta = (myLog.myTime[LastIdx] - myLog.myTime[PrevIdx]);
63     if (aStopTime < (qint64)100 && delta < (qint64)100) {
64       OCCViewer_ViewWindow *aWnd = dynamic_cast<OCCViewer_ViewWindow*>(myWindow);
65       if (aWnd) {
66         OCCViewer_ViewPort3d* aViewPort = aWnd->getViewPort();
67         if (aViewPort) {
68           Handle(V3d_View) aView = aViewPort->getView();
69           if ( !aView.IsNull() ) {
70             Standard_Real rx, ry;
71             aView->Size(rx, ry);
72
73             Standard_Real dx=0., dy=0., dz=0.;
74             dx = (Standard_Real(this->myLog.myPosition[LastIdx].x()) - this->myLog.myPosition[PrevIdx].x()) * M_PI / rx;
75             dy = (this->myLog.myPosition[PrevIdx].y() - Standard_Real(this->myLog.myPosition[LastIdx].y())) * M_PI / ry;
76             dz = atan2(Standard_Real(this->myLog.myPosition[LastIdx].x())-rx/2., ry/2.-Standard_Real(this->myLog.myPosition[LastIdx].y()))
77                - atan2(this->myLog.myPosition[PrevIdx].x()-rx/2.,ry/2.-this->myLog.myPosition[PrevIdx].y());
78
79             Handle(Graphic3d_Camera) aCamera = aView->Camera();
80             gp_Pnt aRCenter = aView->GravityPoint();
81             gp_Dir aZAxis (aCamera->Direction().Reversed());
82             gp_Dir aYAxis (aCamera->Up());
83             gp_Dir aXAxis (aYAxis.Crossed (aZAxis)); 
84
85             gp_Trsf aRot[3], aTrsf;
86             aRot[0].SetRotation (gp_Ax1 (aRCenter, aYAxis), -dx);
87             aRot[1].SetRotation (gp_Ax1 (aRCenter, aXAxis), dy);
88             aRot[2].SetRotation (gp_Ax1 (aRCenter, aZAxis), dz);
89             aTrsf.Multiply (aRot[0]);
90             aTrsf.Multiply (aRot[1]);
91             aTrsf.Multiply (aRot[2]);
92
93             gp_Quaternion quat = aTrsf.GetRotation();
94             gp_Vec aAxis;
95             Standard_Real anAngle=0., aScale=1.;
96             quat.GetVectorAndAngle(aAxis, anAngle);
97             aScale = aView->Scale();
98             // std::cout << "Axis=[" << aAxis.X() << " , " << aAxis.Y() << " , " << aAxis.Z()
99             //           << "]   Angle=" << anAngle * 180. / M_PI 
100             //           << " deg   z-Angle=" << dz * 180. / M_PI << " deg   Scale=" << aScale << std::endl;
101             if (anAngle != 0.)
102               aViewPort->setRotationAxis(aAxis, anAngle*3./aScale, dz*3./aScale);
103           }
104         }
105         return true;
106       }
107     }
108   }
109
110   return false;
111 }
112
113
114 bool OCCViewer_AutoRotate::stopAnimation()
115 {
116   OCCViewer_ViewWindow *aWnd = dynamic_cast<OCCViewer_ViewWindow*>(myWindow);
117   if (aWnd) {
118     OCCViewer_ViewPort3d* aViewPort = aWnd->getViewPort();
119     if (aViewPort) {
120       aViewPort->stopRotation();
121       return true;
122     }
123   }
124   return false;
125 }