39 using ScalarType = Scalar;
47 using MotionType = vcl::TrackBall<Scalar>::MotionType;
50 static constexpr double DISCRETE_TRANSLATION_STEP = 0.1;
51 static constexpr double DISCRETE_ROTATION_STEP =
M_PI_4 / 3.0;
59 float mDefaultTrackBallRadius = 1.0;
62 KeyModifiers mCurrentKeyModifiers = {KeyModifier::NO_MODIFIER};
65 MouseButton::Enum mCurrentMouseButton = MouseButton::NO_BUTTON;
67 std::map<std::pair<MouseButton::Enum, KeyModifiers>, MotionType>
70 {{MouseButton::LEFT, {KeyModifier::NO_MODIFIER}},
72 {{MouseButton::LEFT, {KeyModifier::CONTROL}}, TrackBallType::PAN },
73 {{MouseButton::LEFT, {KeyModifier::ALT}}, TrackBallType::ZMOVE},
74 {{MouseButton::LEFT, {KeyModifier::SHIFT}}, TrackBallType::SCALE},
75 {{MouseButton::MIDDLE, {KeyModifier::NO_MODIFIER}},
77 {{MouseButton::MIDDLE, {KeyModifier::CONTROL}},
78 TrackBallType::ROLL },
79 {{MouseButton::LEFT, {KeyModifier::SHIFT, KeyModifier::CONTROL}},
80 TrackBallType::DIR_LIGHT_ARC },
84 using Axis =
unsigned char;
85 std::map<std::pair<KeyModifiers, Axis>, MotionType> mScrollAtomicMap = {
86 {{{KeyModifier::NO_MODIFIER}, 1}, TrackBallType::SCALE},
87 {{{KeyModifier::CONTROL}, 1}, TrackBallType::ROLL },
88 {{{KeyModifier::SHIFT}, 1}, TrackBallType::FOV },
90 {{{KeyModifier::SHIFT}, 0}, TrackBallType::FOV },
95 std::pair<Key::Enum, KeyModifiers>,
98 {{Key::R, {KeyModifier::NO_MODIFIER}},
101 mDefaultTrackBallCenter, 1.5 / mDefaultTrackBallRadius);
103 {{Key::R, {KeyModifier::CONTROL, KeyModifier::SHIFT}},
105 t.resetDirectionalLight();
109 {{Key::NP_2, {KeyModifier::NO_MODIFIER}},
111 rotate(t, UNIT_X, DISCRETE_ROTATION_STEP);
113 {{Key::NP_4, {KeyModifier::NO_MODIFIER}},
115 rotate(t, UNIT_Y, -DISCRETE_ROTATION_STEP);
117 {{Key::NP_6, {KeyModifier::NO_MODIFIER}},
119 rotate(t, UNIT_Y, DISCRETE_ROTATION_STEP);
121 {{Key::NP_8, {KeyModifier::NO_MODIFIER}},
123 rotate(t, UNIT_X, -DISCRETE_ROTATION_STEP);
127 {{Key::UP, {KeyModifier::NO_MODIFIER}},
129 translate(t, UNIT_Y * DISCRETE_TRANSLATION_STEP);
131 {{Key::DOWN, {KeyModifier::NO_MODIFIER}},
133 translate(t, -UNIT_Y * DISCRETE_TRANSLATION_STEP);
135 {{Key::LEFT, {KeyModifier::NO_MODIFIER}},
137 translate(t, -UNIT_X * DISCRETE_TRANSLATION_STEP);
139 {{Key::RIGHT, {KeyModifier::NO_MODIFIER}},
141 translate(t, UNIT_X * DISCRETE_TRANSLATION_STEP);
145 {{Key::NP_1, {KeyModifier::NO_MODIFIER}},
149 {{Key::NP_7, {KeyModifier::NO_MODIFIER}},
152 rotate(t, UNIT_X,
M_PI_2);
154 {{Key::NP_3, {KeyModifier::NO_MODIFIER}},
157 rotate(t, UNIT_Y, -
M_PI_2);
159 {{Key::NP_1, {KeyModifier::CONTROL}},
162 rotate(t, UNIT_Y,
M_PI);
164 {{Key::NP_7, {KeyModifier::CONTROL}},
167 rotate(t, UNIT_X, -
M_PI_2);
169 {{Key::NP_3, {KeyModifier::CONTROL}},
172 rotate(t, UNIT_Y,
M_PI_2);
175 {{Key::NP_5, {KeyModifier::NO_MODIFIER}},
178 t.projectionMode() ==
182 t.setProjectionMode(v);
186 {{Key::NP_2, {KeyModifier::CONTROL, KeyModifier::SHIFT}},
188 rotateLight(t, UNIT_X, DISCRETE_ROTATION_STEP);
190 {{Key::NP_4, {KeyModifier::CONTROL, KeyModifier::SHIFT}},
192 rotateLight(t, UNIT_Y, -DISCRETE_ROTATION_STEP);
194 {{Key::NP_6, {KeyModifier::CONTROL, KeyModifier::SHIFT}},
196 rotateLight(t, UNIT_Y, DISCRETE_ROTATION_STEP);
198 {{Key::NP_8, {KeyModifier::CONTROL, KeyModifier::SHIFT}},
200 rotateLight(t, UNIT_X, -DISCRETE_ROTATION_STEP);
207 resizeViewer(width, height);
210 bool isDragging()
const {
return mTrackball.isDragging(); }
212 MotionType currentMotion()
const {
return mTrackball.currentMotion(); }
216 const Camera<Scalar>& camera()
const {
return mTrackball.camera(); }
222 return mTrackball.lightGizmoMatrix();
229 return mTrackball.projectionMatrix();
232 void resetTrackBall()
235 mDefaultTrackBallCenter, 1.5 / mDefaultTrackBallRadius);
240 mDefaultTrackBallCenter = center;
241 mDefaultTrackBallRadius = radius;
248 mTrackball.applyAtomicMotion(TrackBallType::FOCUS, center);
255 mTrackball.setScreenSize(w,
h);
258 void setKeyModifiers(
KeyModifiers keys) { mCurrentKeyModifiers = keys; }
260 void moveMouse(
int x,
int y)
263 auto it = mDragMotionMap.find(
264 std::make_pair(mCurrentMouseButton, mCurrentKeyModifiers));
265 if (
it != mDragMotionMap.end()) {
266 mTrackball.beginDragMotion(
it->second);
268 mTrackball.setMousePosition(x, y);
272 void pressMouse(MouseButton::Enum
button)
275 if (mTrackball.isDragging()) {
279 mCurrentMouseButton =
button;
282 mDragMotionMap.find(std::make_pair(
button, mCurrentKeyModifiers));
283 if (
it != mDragMotionMap.end()) {
284 mTrackball.beginDragMotion(
it->second);
291 void releaseMouse(MouseButton::Enum
button)
294 if (mTrackball.isDragging() && mCurrentMouseButton ==
button) {
295 mCurrentMouseButton = MouseButton::NO_BUTTON;
299 mDragMotionMap.find(std::make_pair(
button, mCurrentKeyModifiers));
300 if (
it != mDragMotionMap.end()) {
301 mTrackball.endDragMotion(
it->second);
313 auto it = mScrollAtomicMap.find({mCurrentKeyModifiers, Axis(0)});
314 if (
it != mScrollAtomicMap.end()) {
320 auto it = mScrollAtomicMap.find({mCurrentKeyModifiers, Axis(1)});
321 if (
it != mScrollAtomicMap.end()) {
327 void keyPress(Key::Enum key)
330 auto atomicOp = mKeyAtomicMap.find({key, mCurrentKeyModifiers});
331 if (
atomicOp != mKeyAtomicMap.end()) {
336 auto it = mDragMotionMap.find(
337 std::make_pair(mCurrentMouseButton, mCurrentKeyModifiers));
338 if (
it != mDragMotionMap.end()) {
339 mTrackball.beginDragMotion(
it->second);
342 mTrackball.endDragMotion(currentMotion());
347 void keyRelease(Key::Enum key)
350 if (!mTrackball.isDragging())
354 auto it = mDragMotionMap.find(
355 std::make_pair(mCurrentMouseButton, mCurrentKeyModifiers));
356 if (
it != mDragMotionMap.end()) {
357 mTrackball.beginDragMotion(
it->second);
360 mTrackball.endDragMotion(currentMotion());
369 Scalar angle =
M_PI / 6)
371 using Args =
typename TrackBallType::TransformArgs;
372 t.applyAtomicMotion(TrackBallType::ARC, Args(axis, angle));
375 static void rotateLight(
378 Scalar angle =
M_PI / 6)
380 using Args =
typename TrackBallType::TransformArgs;
381 t.applyAtomicMotion(TrackBallType::DIR_LIGHT_ARC, Args(axis, angle));
386 t.applyAtomicMotion(TrackBallType::PAN,
translation);