ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
GamepadInput.cpp
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
8 #include "GamepadInput.h"
9 
10 // Qt
11 #include <ecvDisplayTools.h>
12 
13 #include <QGamepadManager>
14 #include <QMainWindow>
15 
16 // system
17 #include <assert.h>
18 
19 GamepadInput::GamepadInput(QObject* parent /*=nullptr*/)
20  : QGamepad(0, parent),
21  m_hasPanning(false),
22  m_hasRotation(false),
23  m_zoom(0) {
24  connect(&m_timer, &QTimer::timeout, this,
25  &GamepadInput::updateInternalState);
26 }
27 
29 
30 void GamepadInput::start() { m_timer.start(0); }
31 
32 void GamepadInput::stop() { m_timer.stop(); }
33 
34 void GamepadInput::update(QMainWindow* win) {
35  if (!win) {
36  assert(false);
37  return;
38  }
39 
40  // rotation
41  if (m_hasRotation) {
43  }
44 
45  const ecvViewportParameters& viewParams =
47 
48  // panning
49  if (m_hasPanning) {
50  double screenWidth3D = viewParams.computeWidthAtFocalDist();
51  if (!viewParams.objectCenteredView) {
52  screenWidth3D = -screenWidth3D;
53  }
54  CCVector3d v(-m_panning.x * screenWidth3D, -m_panning.y * screenWidth3D,
55  0);
56  ecvDisplayTools::MoveCamera(static_cast<float>(v.x),
57  static_cast<float>(v.y),
58  static_cast<float>(v.z));
59  }
60 
61  // zoom
62  if (m_hasTranslation) {
63  double X = m_translation.x;
64  // double Y = m_translation.y; //always 0
65  double Z = m_translation.z;
66 
67  if (cloudViewer::GreaterThanEpsilon(std::abs(X)) ||
68  cloudViewer::GreaterThanEpsilon(std::abs(Z))) {
69  if (viewParams.perspectiveView) {
72  }
73  double screenWidth3D = viewParams.computeWidthAtFocalDist();
74  if (!viewParams.objectCenteredView) {
75  screenWidth3D = -screenWidth3D;
76  }
77  CCVector3d v(-X * screenWidth3D, 0, -Z * screenWidth3D);
78  ecvDisplayTools::MoveCamera(static_cast<float>(v.x),
79  static_cast<float>(v.y),
80  static_cast<float>(v.z));
81  }
82  }
83 
85 }
86 
87 static double s_gamepadSpeed = 0.005;
88 static double s_gamepadRotSpeed = 0.02;
89 
90 void GamepadInput::updateInternalState() {
91  // reset
92  m_panning = CCVector3(0, 0, 0);
93  m_hasPanning = false;
94  m_translation = CCVector3(0, 0, 0);
95  m_hasTranslation = false;
96  m_rotation.toIdentity();
97  m_hasRotation = false;
98  m_zoom = 0;
99 
100  // rotation
101  {
102  CCVector3d u(axisRightX() * s_gamepadRotSpeed,
103  -axisRightY() * s_gamepadRotSpeed, 1);
104  u.normalize();
105 
106  if (u.z != 1.0) {
107  m_rotation = ccGLMatrixd::FromToRotation(CCVector3d(0, 0, 1), u);
108  m_hasRotation = true;
109  }
110 
111  if (buttonL2() || buttonR2()) {
112  double angle_deg = buttonL2() ? 20 * s_gamepadRotSpeed
113  : -20 * s_gamepadRotSpeed;
114  ccGLMatrixd rot;
116  CCVector3d(0, 0, 1), CCVector3d(0, 0, 0));
117  m_rotation = rot * m_rotation;
118  m_hasRotation = true;
119  }
120  }
121 
122  // panning
123  {
124  if (buttonLeft()) {
125  m_panning.x = -s_gamepadSpeed;
126  m_hasPanning = true;
127  } else if (buttonRight()) {
128  m_panning.x = s_gamepadSpeed;
129  m_hasPanning = true;
130  }
131  if (buttonUp()) {
132  m_panning.y = s_gamepadSpeed;
133  m_hasPanning = true;
134  } else if (buttonDown()) {
135  m_panning.y = -s_gamepadSpeed;
136  m_hasPanning = true;
137  }
138  }
139 
140  // translation
141  {
142  double x = axisLeftX();
143  double z = axisLeftY();
144  if (x != 0 || z != 0) {
145  m_translation =
147  m_hasTranslation = true;
148  }
149  }
150 
151  // zoom
152  { m_zoom = -axisLeftY() * s_gamepadSpeed; }
153 
154  if (m_hasRotation || m_hasPanning || m_hasTranslation || m_zoom != 0) {
155  Q_EMIT updated();
156  }
157 }
Vector3Tpl< double > CCVector3d
Double 3D Vector.
Definition: CVGeom.h:804
Vector3Tpl< PointCoordinateType > CCVector3
Default 3D Vector.
Definition: CVGeom.h:798
static double s_gamepadRotSpeed
static double s_gamepadSpeed
void * X
Definition: SmallVector.cpp:45
virtual ~GamepadInput()
Destructor.
void updated()
void update(QMainWindow *win)
Updates a window with the current gamepad state.
GamepadInput(QObject *parent=nullptr)
Default constructor.
Type y
Definition: CVGeom.h:137
Type x
Definition: CVGeom.h:137
Type z
Definition: CVGeom.h:137
void normalize()
Sets vector norm to unity.
Definition: CVGeom.h:428
static ccGLMatrixTpl< double > FromToRotation(const Vector3Tpl< double > &from, const Vector3Tpl< double > &to)
Creates a transformation matrix that rotates a vector to another.
void initFromParameters(T alpha_rad, const Vector3Tpl< T > &axis3D, const Vector3Tpl< T > &t3D)
Inits transformation from a rotation axis, an angle and a translation.
virtual void toIdentity()
Sets matrix to identity.
Double version of ccGLMatrixTpl.
Definition: ecvGLMatrix.h:56
static void RedrawDisplay(bool only2D=false, bool forceRedraw=true)
static void MoveCamera(float dx, float dy, float dz)
Displaces camera.
static const ecvViewportParameters & GetViewportParameters()
static void RotateBaseViewMat(const ccGLMatrixd &rotMat)
Rotates the base view matrix.
Standard parameters for GL displays/viewports.
bool perspectiveView
Perspective view state.
double computeWidthAtFocalDist() const
Computes the object 'width' at the 'focal' distance.
double computeDistanceToHalfWidthRatio() const
Computes the ratio 'distance to half width' (based on the current FOV)
normal_z x
normal_z z
bool GreaterThanEpsilon(float x)
Test a floating point number against our epsilon (a very small number).
Definition: CVMath.h:37
float DegreesToRadians(int degrees)
Convert degrees to radians.
Definition: CVMath.h:98