PeriDyno 1.0.0
Loading...
Searching...
No Matches
vGizmo.h
Go to the documentation of this file.
1//------------------------------------------------------------------------------
2// Copyright (c) 2018-2020 Michele Morrone
3// All rights reserved.
4//
5// https://michelemorrone.eu - https://BrutPitt.com
6//
7// twitter: https://twitter.com/BrutPitt - github: https://github.com/BrutPitt
8//
9// mailto:brutpitt@gmail.com - mailto:me@michelemorrone.eu
10//
11// This software is distributed under the terms of the BSD 2-Clause license
12//------------------------------------------------------------------------------
13#pragma once
14
15#define VGIZMO_H_FILE
16#include "vgMath.h"
17
18#ifdef VGM_USES_TEMPLATE
19 #define VGIZMO_BASE_CLASS virtualGizmoBaseClass<T>
20 #define imGuIZMO_BASE_CLASS virtualGizmoBaseClass<float>
21#else
22 #define VGIZMO_BASE_CLASS virtualGizmoBaseClass
23 #define imGuIZMO_BASE_CLASS VGIZMO_BASE_CLASS
24 #define T VG_T_TYPE
25#endif
26
27typedef int vgButtons;
28typedef int vgModifiers;
29
30namespace vg {
31// Default values for button and modifiers.
32// This values are aligned with GLFW defines (for my comfort),
33// but they are loose from any platform library: simply initialize
34// the virtualGizmo with your values:
35// look at "onInit" in glWindow.cpp example.
37 enum {
41 };
42
43 enum {
49 };
50
53//
54// Base manipulator class
55//
59
60public:
69
70 // Call to initialize and on reshape
72 void viewportSize(int w, int h) { viewportSize(T(w), T(h)); }
73 void viewportSize(T w, T h) {
74 width = w; height = h;
75 minVal = T(width < height ? width*T(0.5) : height*T(0.5));
76 offset = tVec3(T(.5 * width), T(.5 * height), T(0));
77 }
78
79 void inline activateMouse(T x, T y) {
80 pos.x = x;
81 pos.y = y;
82 delta.x = delta.y = 0;
83 }
84 void inline deactivateMouse() {
85 if(delta.x == 0 && delta.y == 0) update();
86 delta.x = delta.y = 0;
87 }
88 void inline testRotModifier(int x, int y, vgModifiers mod) { }
89
90 // Call on mouse button event
91 // button: your mouse button
92 // mod: your modifier key -> CTRL, SHIFT, ALT, SUPER
93 // pressed: if Button is pressed (TRUE) or released (FALSE)
94 // x, y: mouse coordinates
96 void mouse( vgButtons button, vgModifiers mod, bool pressed, T x, T y)
97 {
98 if ( (button == tbControlButton) && pressed && (tbControlModifiers ? tbControlModifiers & mod : tbControlModifiers == mod) ) {
99 tbActive = true;
100 activateMouse(x,y);
101 }
102 else if ( button == tbControlButton && !pressed) {
104 tbActive = false;
105 }
106
107 if((button == tbRotationButton) && pressed) {
108 if (xRotationModifier & mod) { tbActive = true; rotationVector = tVec3(T(1), T(0), T(0)); activateMouse(x,y); }
109 else if (yRotationModifier & mod) { tbActive = true; rotationVector = tVec3(T(0), T(1), T(0)); activateMouse(x,y); }
110 else if (zRotationModifier & mod) { tbActive = true; rotationVector = tVec3(T(0), T(0), T(1)); activateMouse(x,y); }
111 } else if((button == tbRotationButton) && !pressed) {
112 deactivateMouse(); rotationVector = tVec3(T(1)); tbActive = false;
113 }
114
115 }
116
117 // Call on Mouse motion
119 void motion( T x, T y) {
120 delta.x = x - pos.x; delta.y = pos.y - y;
121 pos.x = x; pos.y = y;
122 update();
123 }
124 // Call on Pinching
126 void pinching( T d ) {
127 delta.y = d;
128 update();
129 }
130
131 // Call every rendering to implement continue spin rotation
133 void idle() { qtV = qtStep*qtV; }
134
135 // Call after changed settings
137 virtual void update() = 0;
139 {
140
141 if(!delta.x && !delta.y) {
142 qtStep = tQuat(T(1), T(0), T(0), T(0)); //no rotation
143 return;
144 }
145
146 tVec3 a(T(pos.x-delta.x), T(height - (pos.y+delta.y)), T(0));
147 tVec3 b(T(pos.x ), T(height - pos.y ), T(0));
148
149 auto vecFromPos = [&] (tVec3 &v) {
150 v -= offset;
151 v /= minVal;
152 const T len = length(v);
153 v.z = len>T(0) ? pow(T(2), -T(.5) * len) : T(1);
154 v = normalize(v);
155 };
156
157 vecFromPos(a);
158 vecFromPos(b);
159
160 tVec3 axis = cross(a, b);
161 axis = normalize(axis);
162
163 T AdotB = dot(a, b);
164 T angle = acos( AdotB>T(1) ? T(1) : (AdotB<-T(1) ? -T(1) : AdotB)); // clamp need!!! corss float is approximate to FLT_EPSILON
165
166 qtStep = normalize(angleAxis(angle * tbScale * fpsRatio, axis * rotationVector));
167 qtV = qtStep*qtV;
168
169 }
170
171 // Set the sensitivity for the virtualGizmo.
173 void setGizmoFeeling( T scale) { tbScale = scale; }
174 // Call with current fps (every rendering) to adjust "auto" sensitivity
176 void setGizmoFPS(T fps) { fpsRatio = T(60.0)/fps;}
177
178 // Apply rotation
180 inline void applyRotation(tMat4 &m) { m = m * mat4_cast(qtV); }
181
182 // Set the point around which the virtualGizmo will rotate.
184 void setRotationCenter( const tVec3& c) { rotationCenter = c; }
186
187 // Set the mouse button and modifier for rotation
193 // Set the mouse button and modifier for rotation around X axis
199 // Set the mouse button and modifier for rotation around Y axis
205 // Set the mouse button and modifier for rotation around Z axis
211
212 // get the rotation quaternion
214 tQuat &getRotation() { return qtV; }
215
216 // get the rotation increment
219
220 // get the rotation quaternion
222 void setRotation(const tQuat &q) { qtV = q; }
223
224 // get the rotation increment
226 void setStepRotation(const tQuat &q) { qtStep = q; }
227
228// Immediate mode helpers
230
231 // for imGuIZMO or immediate mode control
233 void motionImmediateLeftButton( T x, T y, T dx, T dy) {
234 tbActive = true;
235 delta = tVec2(dx,-dy);
236 pos = tVec2( x, y);
237 update();
238 }
239 // for imGuIZMO or immediate mode control
241 virtual void motionImmediateMode( T x, T y, T dx, T dy, vgModifiers mod) {
242 tbActive = true;
243 delta = tVec2(dx,-dy);
244 pos = tVec2( x, y);
245 if (xRotationModifier & mod) { rotationVector = tVec3(T(1), T(0), T(0)); }
246 else if (yRotationModifier & mod) { rotationVector = tVec3(T(0), T(1), T(0)); }
247 else if (zRotationModifier & mod) { rotationVector = tVec3(T(0), T(0), T(1)); }
248 update();
249 }
250
251 // return current transformations as 4x4 matrix.
253 virtual tMat4 getTransform() = 0;
255 virtual void applyTransform(tMat4 &model) = 0;
256
257protected:
258
260
261 // UI commands that this virtualGizmo responds to (defaults to left mouse button with no modifier key)
264
266
267 tQuat qtV = tQuat(T(1), T(0), T(0), T(0));
268 tQuat qtStep = tQuat(T(1), T(0), T(0), T(0));
269
271
272 // settings for the sensitivity
274 T tbScale = T(1); //base scale sensibility
275 T fpsRatio = T(1); //auto adjust by FPS (call idle with current FPS)
276
279
280 bool tbActive; // trackbal activated via mouse
281
283};
284
287//
288// virtualGizmoClass
289// trackball: simple mouse rotation control
290//
293TEMPLATE_TYPENAME_T class virtualGizmoClass : public VGIZMO_BASE_CLASS {
294
295public:
296
298
300 void motion( T x, T y) { if(this->tbActive) VGIZMO_BASE_CLASS::motion(x,y); }
301
303 void update() { this->updateGizmo(); }
304
306 void applyTransform(tMat4 &model) {
307 model = translate(model, -this->rotationCenter);
308 VGIZMO_BASE_CLASS::applyRotation(model);
309 model = translate(model, this->rotationCenter);
310 }
311
314 tMat4 trans, invTrans, rotation;
315 rotation = mat4_cast(this->qtV);
316
317 trans = translate(tMat4(T(1)),this->rotationCenter);
318 invTrans = translate(tMat4(T(1)),-this->rotationCenter);
319
320 return invTrans * rotation * trans;
321 }
322
323 // Set the speed for the virtualGizmo.
325 //void setGizmoScale( T scale) { scale = scale; }
326
327 // get the rotation quaternion
328 tQuat &getRotation() { return this->qtV; }
329};
330
333//
334// virtualGizmo3DClass
335// 3D trackball: rotation interface with pan and dolly operations
336//
339TEMPLATE_TYPENAME_T class virtualGizmo3DClass : public VGIZMO_BASE_CLASS {
340
341using VGIZMO_BASE_CLASS::delta;
342using VGIZMO_BASE_CLASS::qtV;
343
344public:
348
350 void mouse( vgButtons button, vgModifiers mod, bool pressed, int x, int y) { mouse(button, mod, pressed, T(x), T(y)); }
351 void mouse( vgButtons button, vgModifiers mod, bool pressed, T x, T y)
352 {
353 VGIZMO_BASE_CLASS::mouse(button, mod, pressed, x, y);
354 if ( button == dollyControlButton && pressed && (dollyControlModifiers ? dollyControlModifiers & mod : dollyControlModifiers == mod) ) {
355 dollyActive = true;
356 this->activateMouse(x,y);
357 }
358 else if ( button == dollyControlButton && !pressed) {
359 this->deactivateMouse();
360 dollyActive = false;
361 }
362
363 if ( button == panControlButton && pressed && (panControlModifiers ? panControlModifiers & mod : panControlModifiers == mod) ) {
364 panActive = true;
365 this->activateMouse(x,y);
366 }
367 else if ( button == panControlButton && !pressed) {
368 this->deactivateMouse();
369 panActive = false;
370 }
371 }
372
373 // Call on wheel (only for Dolly/Zoom)
375 void wheel( T x, T y) {
376 dolly.z += y * dollyScale * T(5);
377 }
378
380 void motion( int x, int y) { motion( T(x), T(y)); }
381 void motion( T x, T y) {
382 if( this->tbActive || dollyActive || panActive) VGIZMO_BASE_CLASS::motion(x,y);
383 }
384
386 void updatePan() {
387 tVec3 v(delta.x, delta.y, T(0));
388 pan += v * panScale;
389 }
390
392 void updateDolly() {
393 tVec3 v(T(0), T(0), delta.y);
394 dolly -= v * dollyScale;
395 }
396
398 void update() {
399 if (this->tbActive) VGIZMO_BASE_CLASS::updateGizmo();
401 if (panActive) updatePan();
402 }
403
406 m = translate(m, pan);
407 m = translate(m, dolly);
408 m = translate(m, -this->rotationCenter);
409 VGIZMO_BASE_CLASS::applyRotation(m);
410 m = translate(m, this->rotationCenter);
411 }
412
415 tMat4 trans, invTrans, rotation;
416 tMat4 panMat, dollyMat;
417
418 //create pan and dolly translations
419 panMat = translate(tMat4(T(1)),pan );
420 dollyMat = translate(tMat4(T(1)),dolly);
421
422 //create the virtualGizmo rotation
423 rotation = mat4_cast(qtV);
424
425 //create the translations to move the center of rotation to the origin and back
426 trans = translate(tMat4(T(1)), this->rotationCenter);
427 invTrans = translate(tMat4(T(1)),-this->rotationCenter);
428
429 //concatenate all the tranforms
430 return panMat * dollyMat * invTrans * rotation * trans;
431 }
432
433 // Set the mouse button and mods for dolly operation.
439 // Set the mouse button and optional mods for pan
447
448 // Set the speed for the dolly operation.
450 void setWheelScale( T scale) { wheelScale = scale; }
452 // Set the speed for the dolly operation.
454 void setDollyScale( T scale) { dollyScale = scale; }
456 // Set the speed for pan
458 void setPanScale( T scale) { panScale = scale; }
459 T getPanScale() { return panScale; }
460
461 // Set the Dolly to a specified distance.
463 void setDollyPosition(T pos) { dolly.z = pos; }
464 void setDollyPosition(const tVec3 &pos) { dolly.z = pos.z; }
465
466 // Set the Dolly to a specified distance.
468 void setPanPosition(const tVec3 &pos) { pan.x = pos.x; pan.y = pos.y;}
469
470 // Get dolly pos... use as Zoom factor
473
474 // Get Pan pos... use as Zoom factor
476 tVec3 &getPanPosition() { return pan; }
477
478 // Get Pan (xy) & Dolly (z) position
480 tVec3 getPosition() const { return tVec3(pan.x, pan.y, dolly.z); }
481 void setPosition(const tVec3 &p) { pan.x = p.x; pan.y = p.y; dolly.z = p.z; }
482
483 bool isDollyActive() { return dollyActive; }
484 bool isPanActive() { return panActive; }
485
486 void motionImmediateMode( T x, T y, T dx, T dy, vgModifiers mod) {
487 this->tbActive = true;
488 this->delta = tVec2(dx,-dy);
489 this->pos = tVec2( x, y);
490 if (dollyControlModifiers & mod) dollyActive = true;
491 else if (panControlModifiers & mod) panActive = true;
492 update();
493 }
494
495private:
496 // UI commands that this virtualGizmo responds to (defaults to left mouse button with no modifier key)
499
500 // Variable used to determine if the manipulator is presently tracking the mouse
503
506
507 T dollyScale = T(.01); //dolly scale
508 T panScale = T(.01); //pan scale
509 T wheelScale = T(5); //dolly multiply for wheel
510};
511
512#ifdef VGM_USES_TEMPLATE
513 #ifdef VGM_USES_DOUBLE_PRECISION
516 #else
519 #endif
520 #ifndef IMGUIZMO_USE_ONLY_ROT
522 #else
524 #endif
525#else
526 #ifndef IMGUIZMO_USE_ONLY_ROT
528 #else
530 #endif
533#endif
534} // end namespace vg::
535
536#undef T // if used T as #define, undef it
537#undef VGIZMO_H_FILE
void motion(int x, int y)
Definition vGizmo.h:380
void setPosition(const tVec3 &p)
Definition vGizmo.h:481
vgModifiers dollyControlModifiers
Definition vGizmo.h:498
void setDollyControl(vgButtons b, vgModifiers m=evNoModifier)
Definition vGizmo.h:435
void motionImmediateMode(T x, T y, T dx, T dy, vgModifiers mod)
Definition vGizmo.h:486
void setPanScale(T scale)
Definition vGizmo.h:458
void motion(T x, T y)
Definition vGizmo.h:381
void mouse(vgButtons button, vgModifiers mod, bool pressed, int x, int y)
Definition vGizmo.h:350
vgModifiers panControlModifiers
Definition vGizmo.h:498
tVec3 & getPanPosition()
Definition vGizmo.h:476
void setPanControl(vgButtons b, vgModifiers m=evNoModifier)
Definition vGizmo.h:441
void setDollyPosition(const tVec3 &pos)
Definition vGizmo.h:464
void mouse(vgButtons button, vgModifiers mod, bool pressed, T x, T y)
Definition vGizmo.h:351
void setDollyScale(T scale)
Definition vGizmo.h:454
void setPanPosition(const tVec3 &pos)
Definition vGizmo.h:468
tVec3 & getDollyPosition()
Definition vGizmo.h:472
void wheel(T x, T y)
Definition vGizmo.h:375
vgButtons panControlButton
Definition vGizmo.h:497
void applyTransform(tMat4 &m)
Definition vGizmo.h:405
tVec3 getPosition() const
Definition vGizmo.h:480
vgButtons dollyControlButton
Definition vGizmo.h:497
void setDollyPosition(T pos)
Definition vGizmo.h:463
void setWheelScale(T scale)
Definition vGizmo.h:450
vgModifiers xRotationModifier
Definition vGizmo.h:263
void mouse(vgButtons button, vgModifiers mod, bool pressed, T x, T y)
Definition vGizmo.h:96
void setGizmoRotXControl(vgButtons b, vgModifiers m=evNoModifier)
Definition vGizmo.h:195
vgButtons tbControlButton
Definition vGizmo.h:262
void setGizmoRotControl(vgButtons b, vgModifiers m=evNoModifier)
Definition vGizmo.h:189
void viewportSize(T w, T h)
Definition vGizmo.h:73
vgModifiers tbControlModifiers
Definition vGizmo.h:263
void setGizmoFPS(T fps)
Definition vGizmo.h:176
virtual void motionImmediateMode(T x, T y, T dx, T dy, vgModifiers mod)
Definition vGizmo.h:241
tVec3 & getRotationCenter()
Definition vGizmo.h:185
void motionImmediateLeftButton(T x, T y, T dx, T dy)
Definition vGizmo.h:233
virtual ~virtualGizmoBaseClass()
Definition vGizmo.h:68
void setRotationCenter(const tVec3 &c)
Definition vGizmo.h:184
void setStepRotation(const tQuat &q)
Definition vGizmo.h:226
void setGizmoRotZControl(vgButtons b, vgModifiers m=evNoModifier)
Definition vGizmo.h:207
void viewportSize(int w, int h)
Definition vGizmo.h:72
void setGizmoRotYControl(vgButtons b, vgModifiers m=evNoModifier)
Definition vGizmo.h:201
vgButtons tbRotationButton
Definition vGizmo.h:262
vgModifiers zRotationModifier
Definition vGizmo.h:263
void motion(T x, T y)
Definition vGizmo.h:119
void testRotModifier(int x, int y, vgModifiers mod)
Definition vGizmo.h:88
virtual void update()=0
vgModifiers yRotationModifier
Definition vGizmo.h:263
virtual void applyTransform(tMat4 &model)=0
void setGizmoFeeling(T scale)
Definition vGizmo.h:173
tQuat & getStepRotation()
Definition vGizmo.h:218
void setRotation(const tQuat &q)
Definition vGizmo.h:222
virtual tMat4 getTransform()=0
void applyRotation(tMat4 &m)
Definition vGizmo.h:180
void activateMouse(T x, T y)
Definition vGizmo.h:79
void applyTransform(tMat4 &model)
Definition vGizmo.h:306
void motion(T x, T y)
Definition vGizmo.h:300
tQuat & getRotation()
Definition vGizmo.h:328
#define T(t)
Definition vGizmo.h:30
virtualGizmo3DClass vGizmo3D
Definition vGizmo.h:532
@ evMiddleButton
Definition vGizmo.h:40
@ evLeftButton
Definition vGizmo.h:38
@ evRightButton
Definition vGizmo.h:39
virtualGizmo3DClass vImGuIZMO
Definition vGizmo.h:527
virtualGizmoClass vGizmo
Definition vGizmo.h:531
@ evSuperModifier
Definition vGizmo.h:48
@ evNoModifier
Definition vGizmo.h:44
@ evShiftModifier
Definition vGizmo.h:45
@ evAltModifier
Definition vGizmo.h:47
@ evControlModifier
Definition vGizmo.h:46
int vgButtons
Definition vGizmo.h:27
int vgModifiers
Definition vGizmo.h:28
vgm::VEC3_PRECISION tVec3
Definition vgMath.h:650
vgm::QUAT_PRECISION tQuat
Definition vgMath.h:652
vgm::VEC2_PRECISION tVec2
Definition vgMath.h:649
#define TEMPLATE_TYPENAME_T
Definition vgMath.h:79
vgm::MAT4_PRECISION tMat4
Definition vgMath.h:654