iMSTK
Interactive Medical Simulation Toolkit
imstkMouseSceneControl.cpp
1 /*
2 ** This file is part of the Interactive Medical Simulation Toolkit (iMSTK)
3 ** iMSTK is distributed under the Apache License, Version 2.0.
4 ** See accompanying NOTICE for details.
5 */
6 
7 #include "imstkMouseSceneControl.h"
8 #include "imstkCamera.h"
9 #include "imstkLogger.h"
10 #include "imstkMouseDeviceClient.h"
11 #include "imstkScene.h"
12 #include "imstkSceneManager.h"
13 
14 namespace imstk
15 {
16 void
18 {
19  LOG(INFO) << "Mouse Scene Controls: Only usable in debug mode";
20  LOG(INFO) << "----------------------------------------------------------------------";
21  LOG(INFO) << " | Left click drag - rotate view";
22  LOG(INFO) << " | Middle click drag - pan view";
23  LOG(INFO) << " | Scroll - zoom in/out";
24  LOG(INFO) << "----------------------------------------------------------------------";
25 }
26 
27 void
29 {
30  if (m_mode == Mode::None)
31  {
32  // Set the mode
33  if (key == LEFT_BUTTON)
34  {
35  m_mode = Mode::Rotate;
36  }
37  else if (key == MIDDLE_BUTTON)
38  {
39  m_mode = Mode::Pan;
40  }
41  }
42 }
43 
44 void
45 MouseSceneControl::OnButtonRelease(const int key)
46 {
47  if (key == LEFT_BUTTON && m_mode == Mode::Rotate)
48  {
49  m_mode = Mode::None;
50  }
51  else if (key == MIDDLE_BUTTON && m_mode == Mode::Pan)
52  {
53  m_mode = Mode::None;
54  }
55 }
56 
57 void
58 MouseSceneControl::OnScroll(const double dx)
59 {
60  if (!getEnabled())
61  {
62  return;
63  }
64 
65  std::shared_ptr<Camera> cam = m_sceneManager->getActiveScene()->getActiveCamera();
66  const Vec3d& focalPt = cam->getFocalPoint();
67  const Vec3d& camPos = cam->getPosition();
68  const Vec3d diff = camPos - focalPt;
69 
70  // Linear zoom function
71  Vec3d newDiff;
72  if (dx > 0.0)
73  {
74  newDiff = diff * 1.1 * m_zoomSpeed * m_zoomFactor;
75  }
76  else
77  {
78  newDiff = diff * 0.9 * m_zoomSpeed * m_zoomFactor;
79  }
80  const Vec3d newPos = focalPt + newDiff;
81  cam->setPosition(newPos);
82  cam->update();
83 }
84 
85 void
86 MouseSceneControl::OnMouseMove(const Vec2d& pos)
87 {
88  if (!getEnabled())
89  {
90  return;
91  }
92 
93  std::shared_ptr<Camera> cam = m_sceneManager->getActiveScene()->getActiveCamera();
94 
95  // Push back the position
96  m_prevPos = m_pos;
97  m_pos = pos;
98 
99  if (m_mode == Mode::Rotate)
100  {
101  // Map mouse deltas to theta, phi rotations on a sphere
102  const Vec2d dx = (m_pos - m_prevPos) * (m_rotateSpeed * m_rotateFactor);
103  const double dTheta = dx[1]; // Elevation
104  const double dPhi = -dx[0]; // Azimuth
105 
106  const Vec3d& focalPt = cam->getFocalPoint();
107  const Vec3d& camPos = cam->getPosition();
108  Vec3d localCamPos = camPos - focalPt;
109 
110  // Get the rotation axes
111  const Mat4d& view = cam->getView();
112  const Vec3d up = Vec3d(view(1, 0), view(1, 1), view(1, 2));
113  const Vec3d right = Vec3d(view(0, 0), view(0, 1), view(0, 2));
114  // Rotate around each
115  localCamPos = Rotd(dPhi, up).toRotationMatrix() * localCamPos;
116  localCamPos = Rotd(dTheta, right).toRotationMatrix() * localCamPos;
117 
118  // Set the new cam pos and up, then compute lookat
119  const Vec3d newPos = localCamPos + focalPt;
120  cam->setPosition(newPos);
121  cam->setViewUp(Vec3d(view(1, 0), view(1, 1), view(1, 2)));
122  cam->update();
123  }
124  else if (m_mode == Mode::Pan)
125  {
126  // Move camera along up and right
127  const Vec2d dx = m_pos - m_prevPos;
128 
129  const Vec3d& focalPt = cam->getFocalPoint();
130  const Vec3d& camPos = cam->getPosition();
131 
132  Mat4d& view = cam->getView();
133  const Vec3d up = Vec3d(view(1, 0), view(1, 1), view(1, 2));
134  const Vec3d right = Vec3d(view(0, 0), view(0, 1), view(0, 2));
135 
136  // scale pan by zoom as well
137  const double dist = (focalPt - camPos).norm();
138  const Vec3d dPos = (up * dx[1] + right * dx[0]) * -(m_panSpeed * m_panFactor * dist);
139  cam->setFocalPoint(focalPt + dPos);
140  cam->setPosition(camPos + dPos);
141  cam->update();
142  }
143 }
144 
145 void
147 {
148  m_enabled = enable;
149 }
150 
151 bool
153 {
154  return (m_sceneManager->getMode() == SceneManager::Mode::Debug) || m_enabled;
155 }
156 } // namespace imstk
void OnButtonPress(const int key) override
On the mouse scene control button press.
void setEnabled(bool enable)
Enable the mouse control, independent of the debug mode.
Compound Geometry.
void printControls() override
Prints the controls.