40 using ScalarType = Scalar;
51 using MotionType = vcl::TrackBall<Scalar>::MotionType;
54 static constexpr double DISCRETE_TRANSLATION_STEP = 0.1;
55 static constexpr double DISCRETE_ROTATION_STEP =
M_PI_4 / 3.0;
63 float mDefaultTrackBallRadius = 1.0;
66 KeyModifiers mCurrentKeyModifiers = {KeyModifier::NO_MODIFIER};
69 MouseButton::Enum mCurrentMouseButton = MouseButton::NO_BUTTON;
71 std::map<std::pair<MouseButton::Enum, KeyModifiers>, MotionType>
74 {{MouseButton::LEFT, {KeyModifier::NO_MODIFIER}},
76 {{MouseButton::LEFT, {KeyModifier::CONTROL}}, TrackBallType::PAN },
77 {{MouseButton::LEFT, {KeyModifier::ALT}}, TrackBallType::ZMOVE},
78 {{MouseButton::LEFT, {KeyModifier::SHIFT}}, TrackBallType::SCALE},
79 {{MouseButton::MIDDLE, {KeyModifier::NO_MODIFIER}},
81 {{MouseButton::MIDDLE, {KeyModifier::CONTROL}},
82 TrackBallType::ROLL },
83 {{MouseButton::LEFT, {KeyModifier::SHIFT, KeyModifier::CONTROL}},
84 TrackBallType::DIR_LIGHT_ARC },
88 using Axis =
unsigned char;
89 std::map<std::pair<KeyModifiers, Axis>, MotionType> mScrollAtomicMap = {
90 {{{KeyModifier::NO_MODIFIER}, 1}, TrackBallType::SCALE},
91 {{{KeyModifier::CONTROL}, 1}, TrackBallType::ROLL },
92 {{{KeyModifier::SHIFT}, 1}, TrackBallType::FOV },
94 {{{KeyModifier::SHIFT}, 0}, TrackBallType::FOV },
99 std::pair<Key::Enum, KeyModifiers>,
102 {{Key::R, {KeyModifier::NO_MODIFIER}},
105 mDefaultTrackBallCenter, 1.5 / mDefaultTrackBallRadius);
107 {{Key::R, {KeyModifier::CONTROL, KeyModifier::SHIFT}},
109 t.resetDirectionalLight();
113 {{Key::NP_2, {KeyModifier::NO_MODIFIER}},
115 rotate(t, UNIT_X, DISCRETE_ROTATION_STEP);
117 {{Key::NP_4, {KeyModifier::NO_MODIFIER}},
119 rotate(t, UNIT_Y, -DISCRETE_ROTATION_STEP);
121 {{Key::NP_6, {KeyModifier::NO_MODIFIER}},
123 rotate(t, UNIT_Y, DISCRETE_ROTATION_STEP);
125 {{Key::NP_8, {KeyModifier::NO_MODIFIER}},
127 rotate(t, UNIT_X, -DISCRETE_ROTATION_STEP);
131 {{Key::UP, {KeyModifier::NO_MODIFIER}},
133 translate(t, UNIT_Y * DISCRETE_TRANSLATION_STEP);
135 {{Key::DOWN, {KeyModifier::NO_MODIFIER}},
137 translate(t, -UNIT_Y * DISCRETE_TRANSLATION_STEP);
139 {{Key::LEFT, {KeyModifier::NO_MODIFIER}},
141 translate(t, -UNIT_X * DISCRETE_TRANSLATION_STEP);
143 {{Key::RIGHT, {KeyModifier::NO_MODIFIER}},
145 translate(t, UNIT_X * DISCRETE_TRANSLATION_STEP);
149 {{Key::NP_1, {KeyModifier::NO_MODIFIER}},
153 {{Key::NP_7, {KeyModifier::NO_MODIFIER}},
156 rotate(t, UNIT_X,
M_PI_2);
158 {{Key::NP_3, {KeyModifier::NO_MODIFIER}},
161 rotate(t, UNIT_Y, -
M_PI_2);
163 {{Key::NP_1, {KeyModifier::CONTROL}},
166 rotate(t, UNIT_Y,
M_PI);
168 {{Key::NP_7, {KeyModifier::CONTROL}},
171 rotate(t, UNIT_X, -
M_PI_2);
173 {{Key::NP_3, {KeyModifier::CONTROL}},
176 rotate(t, UNIT_Y,
M_PI_2);
179 {{Key::NP_5, {KeyModifier::NO_MODIFIER}},
182 t.projectionMode() ==
186 t.setProjectionMode(v);
190 {{Key::NP_2, {KeyModifier::CONTROL, KeyModifier::SHIFT}},
192 rotateLight(t, UNIT_X, DISCRETE_ROTATION_STEP);
194 {{Key::NP_4, {KeyModifier::CONTROL, KeyModifier::SHIFT}},
196 rotateLight(t, UNIT_Y, -DISCRETE_ROTATION_STEP);
198 {{Key::NP_6, {KeyModifier::CONTROL, KeyModifier::SHIFT}},
200 rotateLight(t, UNIT_Y, DISCRETE_ROTATION_STEP);
202 {{Key::NP_8, {KeyModifier::CONTROL, KeyModifier::SHIFT}},
204 rotateLight(t, UNIT_X, -DISCRETE_ROTATION_STEP);
212 resizeViewer(width, height);
219 return mTrackball.projectionMatrix();
225 mDefaultTrackBallCenter, 1.5 / mDefaultTrackBallRadius);
230 mTrackball.applyAtomicMotion(TrackBallType::FOCUS, center);
235 mDefaultTrackBallCenter = center;
236 mDefaultTrackBallRadius = radius;
243 mTrackball.adaptCurrentViewToCenter(center);
254 return mTrackball.lightGizmoMatrix();
261 void onResize(
unsigned int width,
unsigned int height)
override
263 resizeViewer(width, height);
314 bool isDragging()
const {
return mTrackball.isDragging(); }
316 MotionType currentMotion()
const {
return mTrackball.currentMotion(); }
323 mTrackball.setScreenSize(w,
h);
326 void setKeyModifiers(
KeyModifiers keys) { mCurrentKeyModifiers = keys; }
328 void moveMouse(
int x,
int y)
331 auto it = mDragMotionMap.find(
332 std::make_pair(mCurrentMouseButton, mCurrentKeyModifiers));
333 if (
it != mDragMotionMap.end()) {
334 mTrackball.beginDragMotion(
it->second);
336 mTrackball.setMousePosition(x, y);
340 void pressMouse(MouseButton::Enum
button)
343 if (mTrackball.isDragging()) {
347 mCurrentMouseButton =
button;
350 mDragMotionMap.find(std::make_pair(
button, mCurrentKeyModifiers));
351 if (
it != mDragMotionMap.end()) {
352 mTrackball.beginDragMotion(
it->second);
359 void releaseMouse(MouseButton::Enum
button)
362 if (mTrackball.isDragging() && mCurrentMouseButton ==
button) {
363 mCurrentMouseButton = MouseButton::NO_BUTTON;
367 mDragMotionMap.find(std::make_pair(
button, mCurrentKeyModifiers));
368 if (
it != mDragMotionMap.end()) {
369 mTrackball.endDragMotion(
it->second);
381 auto it = mScrollAtomicMap.find({mCurrentKeyModifiers, Axis(0)});
382 if (
it != mScrollAtomicMap.end()) {
388 auto it = mScrollAtomicMap.find({mCurrentKeyModifiers, Axis(1)});
389 if (
it != mScrollAtomicMap.end()) {
395 void keyPress(Key::Enum key)
398 auto atomicOp = mKeyAtomicMap.find({key, mCurrentKeyModifiers});
399 if (
atomicOp != mKeyAtomicMap.end()) {
404 auto it = mDragMotionMap.find(
405 std::make_pair(mCurrentMouseButton, mCurrentKeyModifiers));
406 if (
it != mDragMotionMap.end()) {
407 mTrackball.beginDragMotion(
it->second);
410 mTrackball.endDragMotion(currentMotion());
415 void keyRelease(Key::Enum key)
418 if (!mTrackball.isDragging())
422 auto it = mDragMotionMap.find(
423 std::make_pair(mCurrentMouseButton, mCurrentKeyModifiers));
424 if (
it != mDragMotionMap.end()) {
425 mTrackball.beginDragMotion(
it->second);
428 mTrackball.endDragMotion(currentMotion());
436 Scalar angle =
M_PI / 6)
438 using Args =
typename TrackBallType::TransformArgs;
439 t.applyAtomicMotion(TrackBallType::ARC, Args(axis, angle));
442 static void rotateLight(
445 Scalar angle =
M_PI / 6)
447 using Args =
typename TrackBallType::TransformArgs;
448 t.applyAtomicMotion(TrackBallType::DIR_LIGHT_ARC, Args(axis, angle));
453 t.applyAtomicMotion(TrackBallType::PAN,
translation);