567 lines
22 KiB
C
567 lines
22 KiB
C
|
//------------------------------------------------------------------------------
|
||
|
// Copyright (c) 2018-2020 Michele Morrone
|
||
|
// All rights reserved.
|
||
|
//
|
||
|
// https://michelemorrone.eu - https://BrutPitt.com
|
||
|
//
|
||
|
// twitter: https://twitter.com/BrutPitt - github: https://github.com/BrutPitt
|
||
|
//
|
||
|
// mailto:brutpitt@gmail.com - mailto:me@michelemorrone.eu
|
||
|
//
|
||
|
// This software is distributed under the terms of the BSD 2-Clause license
|
||
|
//------------------------------------------------------------------------------
|
||
|
#pragma once
|
||
|
|
||
|
#define VGIZMO_H_FILE
|
||
|
#include "vgMath.h"
|
||
|
|
||
|
#ifdef VGM_USES_TEMPLATE
|
||
|
#define VGIZMO_BASE_CLASS virtualGizmoBaseClass<T>
|
||
|
#define imGuIZMO_BASE_CLASS virtualGizmoBaseClass<float>
|
||
|
#else
|
||
|
#define VGIZMO_BASE_CLASS virtualGizmoBaseClass
|
||
|
#define imGuIZMO_BASE_CLASS VGIZMO_BASE_CLASS
|
||
|
#define T VG_T_TYPE
|
||
|
#endif
|
||
|
|
||
|
typedef int vgButtons;
|
||
|
typedef int vgModifiers;
|
||
|
|
||
|
namespace vg {
|
||
|
// Default values for button and modifiers.
|
||
|
// This values are aligned with GLFW defines (for my comfort),
|
||
|
// but they are loose from any platform library: simply initialize
|
||
|
// the virtualGizmo with your values:
|
||
|
// look at "onInit" in glWindow.cpp example.
|
||
|
//////////////////////////////////////////////////////////////////////
|
||
|
enum {
|
||
|
evLeftButton ,
|
||
|
evRightButton ,
|
||
|
evMiddleButton
|
||
|
};
|
||
|
|
||
|
enum {
|
||
|
evNoModifier = 0,
|
||
|
evShiftModifier = 1 ,
|
||
|
evControlModifier = 1<<1,
|
||
|
evAltModifier = 1<<2,
|
||
|
evSuperModifier = 1<<3
|
||
|
};
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////
|
||
|
//////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Base manipulator class
|
||
|
//
|
||
|
//////////////////////////////////////////////////////////////////////
|
||
|
//////////////////////////////////////////////////////////////////////
|
||
|
TEMPLATE_TYPENAME_T class virtualGizmoBaseClass {
|
||
|
|
||
|
public:
|
||
|
virtualGizmoBaseClass() : tbActive(false), pos(0), delta(0),
|
||
|
tbControlButton(evLeftButton), tbControlModifiers(evNoModifier),
|
||
|
tbRotationButton(evRightButton), xRotationModifier(evShiftModifier),
|
||
|
yRotationModifier(evControlModifier), zRotationModifier(evAltModifier|evSuperModifier)
|
||
|
{
|
||
|
viewportSize(T(256), T(256)); //initial dummy value
|
||
|
}
|
||
|
virtual ~virtualGizmoBaseClass() {}
|
||
|
|
||
|
// Call to initialize and on reshape
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
void viewportSize(int w, int h) { viewportSize(T(w), T(h)); }
|
||
|
void viewportSize(T w, T h) {
|
||
|
width = w; height = h;
|
||
|
minVal = T(width < height ? width*T(0.5) : height*T(0.5));
|
||
|
offset = tVec3(T(.5 * width), T(.5 * height), T(0));
|
||
|
}
|
||
|
|
||
|
void inline activateMouse(T x, T y) {
|
||
|
pos.x = x;
|
||
|
pos.y = y;
|
||
|
delta.x = delta.y = 0;
|
||
|
}
|
||
|
void inline deactivateMouse() {
|
||
|
if(delta.x == 0 && delta.y == 0) update();
|
||
|
delta.x = delta.y = 0;
|
||
|
}
|
||
|
void inline testRotModifier(int x, int y, vgModifiers mod) { }
|
||
|
|
||
|
// Call on mouse button event
|
||
|
// button: your mouse button
|
||
|
// mod: your modifier key -> CTRL, SHIFT, ALT, SUPER
|
||
|
// pressed: if Button is pressed (TRUE) or released (FALSE)
|
||
|
// x, y: mouse coordinates
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
virtual void mouse( vgButtons button, vgModifiers mod, bool pressed, T x, T y)
|
||
|
{
|
||
|
if ( (button == tbControlButton) && pressed && (tbControlModifiers ? tbControlModifiers & mod : tbControlModifiers == mod) ) {
|
||
|
tbActive = true;
|
||
|
activateMouse(x,y);
|
||
|
}
|
||
|
else if ( button == tbControlButton && !pressed) {
|
||
|
deactivateMouse();
|
||
|
tbActive = false;
|
||
|
}
|
||
|
|
||
|
if((button == tbRotationButton) && pressed) {
|
||
|
if (xRotationModifier & mod) { tbActive = true; rotationVector = tVec3(T(1), T(0), T(0)); activateMouse(x,y); }
|
||
|
else if (yRotationModifier & mod) { tbActive = true; rotationVector = tVec3(T(0), T(1), T(0)); activateMouse(x,y); }
|
||
|
else if (zRotationModifier & mod) { tbActive = true; rotationVector = tVec3(T(0), T(0), T(1)); activateMouse(x,y); }
|
||
|
} else if((button == tbRotationButton) && !pressed) {
|
||
|
deactivateMouse(); rotationVector = tVec3(T(1)); tbActive = false;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
// Call on Mouse motion
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
virtual void motion( T x, T y) {
|
||
|
delta.x = x - pos.x; delta.y = pos.y - y;
|
||
|
pos.x = x; pos.y = y;
|
||
|
update();
|
||
|
}
|
||
|
// Call on Pinching
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
void pinching(T d, T z = T(0)) {
|
||
|
delta.y = d * z;
|
||
|
update();
|
||
|
}
|
||
|
|
||
|
// Call every rendering to implement continue spin rotation
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
void idle() { qtV = qtIdle*qtV; }
|
||
|
|
||
|
// Call after changed settings
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
virtual void update() = 0;
|
||
|
void updateGizmo()
|
||
|
{
|
||
|
|
||
|
if(!delta.x && !delta.y) {
|
||
|
qtIdle = qtStep = tQuat(T(1), T(0), T(0), T(0)); //no rotation
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
tVec3 a(T(pos.x-delta.x), T(height - (pos.y+delta.y)), T(0));
|
||
|
tVec3 b(T(pos.x ), T(height - pos.y ), T(0));
|
||
|
|
||
|
auto vecFromPos = [&] (tVec3 &v) {
|
||
|
v -= offset;
|
||
|
v /= minVal;
|
||
|
const T len = length(v);
|
||
|
v.z = len>T(0) ? pow(T(2), -T(.5) * len) : T(1);
|
||
|
v = normalize(v);
|
||
|
};
|
||
|
|
||
|
vecFromPos(a);
|
||
|
vecFromPos(b);
|
||
|
|
||
|
tVec3 axis = cross(a, b);
|
||
|
axis = normalize(axis);
|
||
|
|
||
|
T AdotB = dot(a, b);
|
||
|
T angle = acos( AdotB>T(1) ? T(1) : (AdotB<-T(1) ? -T(1) : AdotB)); // clamp need!!! corss float is approximate to FLT_EPSILON
|
||
|
|
||
|
qtStep = normalize(angleAxis(angle * tbScale * fpsRatio , axis * rotationVector));
|
||
|
qtIdle = normalize(angleAxis(angle * tbScale * fpsRatio * qIdleSpeedRatio, axis * rotationVector));
|
||
|
qtV = qtStep*qtV;
|
||
|
|
||
|
}
|
||
|
|
||
|
// Set the sensitivity for the virtualGizmo.
|
||
|
//////////////////////////////////////////////////////////////////
|
||
|
void setGizmoFeeling( T scale) { tbScale = scale; }
|
||
|
// Call with current fps (every rendering) to adjust "auto" sensitivity
|
||
|
//////////////////////////////////////////////////////////////////
|
||
|
void setGizmoFPS(T fps) { fpsRatio = T(60.0)/fps;}
|
||
|
|
||
|
// Apply rotation
|
||
|
//////////////////////////////////////////////////////////////////
|
||
|
inline void applyRotation(tMat4 &m) { m = m * mat4_cast(qtV); }
|
||
|
|
||
|
// Set the point around which the virtualGizmo will rotate.
|
||
|
//////////////////////////////////////////////////////////////////
|
||
|
void setRotationCenter( const tVec3& c) { rotationCenter = c; }
|
||
|
tVec3& getRotationCenter() { return rotationCenter; }
|
||
|
|
||
|
// Set the mouse button and modifier for rotation
|
||
|
//////////////////////////////////////////////////////////////////
|
||
|
void setGizmoRotControl( vgButtons b, vgModifiers m = evNoModifier) {
|
||
|
tbControlButton = b;
|
||
|
tbControlModifiers = m;
|
||
|
}
|
||
|
// Set the mouse button and modifier for rotation around X axis
|
||
|
//////////////////////////////////////////////////////////////////
|
||
|
void setGizmoRotXControl( vgButtons b, vgModifiers m = evNoModifier) {
|
||
|
tbRotationButton = b;
|
||
|
xRotationModifier = m;
|
||
|
}
|
||
|
// Set the mouse button and modifier for rotation around Y axis
|
||
|
//////////////////////////////////////////////////////////////////
|
||
|
void setGizmoRotYControl( vgButtons b, vgModifiers m = evNoModifier) {
|
||
|
tbRotationButton = b;
|
||
|
yRotationModifier = m;
|
||
|
}
|
||
|
// Set the mouse button and modifier for rotation around Z axis
|
||
|
//////////////////////////////////////////////////////////////////
|
||
|
void setGizmoRotZControl( vgButtons b, vgModifiers m = evNoModifier) {
|
||
|
tbRotationButton = b;
|
||
|
zRotationModifier = m;
|
||
|
}
|
||
|
|
||
|
// get the rotation quaternion
|
||
|
//////////////////////////////////////////////////////////////////
|
||
|
virtual tQuat &getRotation() { return qtV; }
|
||
|
|
||
|
// get the rotation increment
|
||
|
//////////////////////////////////////////////////////////////////
|
||
|
tQuat &getStepRotation() { return qtStep; }
|
||
|
|
||
|
// get the rotation quaternion
|
||
|
//////////////////////////////////////////////////////////////////
|
||
|
void setRotation(const tQuat &q) { qtV = q; }
|
||
|
|
||
|
// get the rotation increment
|
||
|
//////////////////////////////////////////////////////////////////
|
||
|
void setStepRotation(const tQuat &q) { qtStep = q; }
|
||
|
|
||
|
// attenuation<1.0 / increment>1.0 of rotation speed in idle
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
void setIdleRotSpeed(T f) { qIdleSpeedRatio = f; }
|
||
|
T getIdleRotSpeed() { return qIdleSpeedRatio; }
|
||
|
|
||
|
// return current transformations as 4x4 matrix.
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
virtual tMat4 getTransform() = 0;
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
virtual void applyTransform(tMat4 &model) = 0;
|
||
|
|
||
|
// Immediate mode helpers
|
||
|
//////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
// for imGuIZMO or immediate mode control
|
||
|
//////////////////////////////////////////////////////////////////
|
||
|
void motionImmediateLeftButton( T x, T y, T dx, T dy) {
|
||
|
tbActive = true;
|
||
|
delta = tVec2(dx,-dy);
|
||
|
pos = tVec2( x, y);
|
||
|
update();
|
||
|
}
|
||
|
// for imGuIZMO or immediate mode control
|
||
|
//////////////////////////////////////////////////////////////////
|
||
|
virtual void motionImmediateMode( T x, T y, T dx, T dy, vgModifiers mod) {
|
||
|
tbActive = true;
|
||
|
delta = tVec2(dx,-dy);
|
||
|
pos = tVec2( x, y);
|
||
|
if (xRotationModifier & mod) { rotationVector = tVec3(T(1), T(0), T(0)); }
|
||
|
else if (yRotationModifier & mod) { rotationVector = tVec3(T(0), T(1), T(0)); }
|
||
|
else if (zRotationModifier & mod) { rotationVector = tVec3(T(0), T(0), T(1)); }
|
||
|
update();
|
||
|
}
|
||
|
|
||
|
protected:
|
||
|
|
||
|
tVec2 pos, delta;
|
||
|
|
||
|
// UI commands that this virtualGizmo responds to (defaults to left mouse button with no modifier key)
|
||
|
vgButtons tbControlButton, tbRotationButton;
|
||
|
vgModifiers tbControlModifiers, xRotationModifier, yRotationModifier, zRotationModifier;
|
||
|
|
||
|
tVec3 rotationVector = tVec3(T(1));
|
||
|
|
||
|
tQuat qtV = tQuat(T(1), T(0), T(0), T(0));
|
||
|
tQuat qtStep = tQuat(T(1), T(0), T(0), T(0));
|
||
|
tQuat qtIdle = tQuat(T(1), T(0), T(0), T(0));
|
||
|
|
||
|
tVec3 rotationCenter = tVec3(T(0));
|
||
|
|
||
|
// settings for the sensitivity
|
||
|
//////////////////////////////////////////////////////////////////
|
||
|
T tbScale = T(1); //base scale sensibility
|
||
|
T fpsRatio = T(1); //auto adjust by FPS (call idle with current FPS)
|
||
|
T qIdleSpeedRatio = T(.33); //autoRotation factor to speedup/slowdown
|
||
|
|
||
|
T minVal;
|
||
|
tVec3 offset;
|
||
|
|
||
|
bool tbActive; // trackbal activated via mouse
|
||
|
|
||
|
T width, height;
|
||
|
};
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////
|
||
|
//////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// virtualGizmoClass
|
||
|
// trackball: simple mouse rotation control
|
||
|
//
|
||
|
//////////////////////////////////////////////////////////////////////
|
||
|
//////////////////////////////////////////////////////////////////////
|
||
|
TEMPLATE_TYPENAME_T class virtualGizmoClass : public VGIZMO_BASE_CLASS {
|
||
|
|
||
|
public:
|
||
|
|
||
|
virtualGizmoClass() { }
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////
|
||
|
void motion( T x, T y) { if(this->tbActive) VGIZMO_BASE_CLASS::motion(x,y); }
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////
|
||
|
void update() { this->updateGizmo(); }
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////
|
||
|
void applyTransform(tMat4 &model) {
|
||
|
model = translate(model, -this->rotationCenter);
|
||
|
VGIZMO_BASE_CLASS::applyRotation(model);
|
||
|
model = translate(model, this->rotationCenter);
|
||
|
}
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////
|
||
|
tMat4 getTransform() {
|
||
|
tMat4 trans, invTrans, rotation;
|
||
|
rotation = mat4_cast(this->qtV);
|
||
|
|
||
|
trans = translate(tMat4(T(1)),this->rotationCenter);
|
||
|
invTrans = translate(tMat4(T(1)),-this->rotationCenter);
|
||
|
|
||
|
return invTrans * rotation * trans;
|
||
|
}
|
||
|
|
||
|
// Set the speed for the virtualGizmo.
|
||
|
//////////////////////////////////////////////////////////////////
|
||
|
//void setGizmoScale( T scale) { scale = scale; }
|
||
|
|
||
|
// get the rotation quaternion
|
||
|
tQuat &getRotation() { return this->qtV; }
|
||
|
};
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////
|
||
|
//////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// virtualGizmo3DClass
|
||
|
// 3D trackball: rotation interface with pan and dolly operations
|
||
|
//
|
||
|
//////////////////////////////////////////////////////////////////////
|
||
|
//////////////////////////////////////////////////////////////////////
|
||
|
TEMPLATE_TYPENAME_T class virtualGizmo3DClass : public VGIZMO_BASE_CLASS {
|
||
|
|
||
|
using VGIZMO_BASE_CLASS::delta;
|
||
|
using VGIZMO_BASE_CLASS::qtV;
|
||
|
|
||
|
public:
|
||
|
//////////////////////////////////////////////////////////////////
|
||
|
virtualGizmo3DClass() : dollyControlButton(evRightButton), panControlButton(evMiddleButton), dollyActive(false),
|
||
|
dollyControlModifiers(evNoModifier), panControlModifiers(evNoModifier), panActive(false) { }
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////
|
||
|
void mouse( vgButtons button, vgModifiers mod, bool pressed, int x, int y) { mouse(button, mod, pressed, T(x), T(y)); }
|
||
|
void mouse( vgButtons button, vgModifiers mod, bool pressed, T x, T y)
|
||
|
{
|
||
|
VGIZMO_BASE_CLASS::mouse(button, mod, pressed, x, y);
|
||
|
if ( button == dollyControlButton && pressed && (dollyControlModifiers ? dollyControlModifiers & mod : dollyControlModifiers == mod) ) {
|
||
|
dollyActive = true;
|
||
|
this->activateMouse(x,y);
|
||
|
}
|
||
|
else if ( button == dollyControlButton && !pressed) {
|
||
|
this->deactivateMouse();
|
||
|
dollyActive = false;
|
||
|
}
|
||
|
|
||
|
if ( button == panControlButton && pressed && (panControlModifiers ? panControlModifiers & mod : panControlModifiers == mod) ) {
|
||
|
panActive = true;
|
||
|
this->activateMouse(x,y);
|
||
|
}
|
||
|
else if ( button == panControlButton && !pressed) {
|
||
|
this->deactivateMouse();
|
||
|
panActive = false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Call on wheel (only for Dolly/Zoom)
|
||
|
////////////////////////////////////////////////////////////////////////////
|
||
|
void wheel( T x, T y, T z=T(0)) {
|
||
|
povPanDollyFactor = z;
|
||
|
dolly.z += y * dollyScale * wheelScale * (povPanDollyFactor>T(0) ? povPanDollyFactor : T(1));
|
||
|
}
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////
|
||
|
void motion( int x, int y, T z=T(0)) { motion( T(x), T(y), z); }
|
||
|
void motion( T x, T y, T z=T(0)) {
|
||
|
povPanDollyFactor = z;
|
||
|
if( this->tbActive || dollyActive || panActive) VGIZMO_BASE_CLASS::motion(x,y);
|
||
|
}
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////
|
||
|
void updatePan() {
|
||
|
tVec3 v(delta.x, delta.y, T(0));
|
||
|
pan += v * panScale * (povPanDollyFactor>T(0) ? povPanDollyFactor : T(1));
|
||
|
}
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////
|
||
|
void updateDolly() {
|
||
|
tVec3 v(T(0), T(0), delta.y);
|
||
|
dolly -= v * dollyScale * (povPanDollyFactor>T(0) ? povPanDollyFactor : T(1));
|
||
|
}
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////
|
||
|
void update() {
|
||
|
if (this->tbActive) VGIZMO_BASE_CLASS::updateGizmo();
|
||
|
if (dollyActive) updateDolly();
|
||
|
if (panActive) updatePan();
|
||
|
}
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////
|
||
|
void applyTransform(tMat4 &m) {
|
||
|
m = translate(m, pan);
|
||
|
m = translate(m, dolly);
|
||
|
m = translate(m, -this->rotationCenter);
|
||
|
VGIZMO_BASE_CLASS::applyRotation(m);
|
||
|
m = translate(m, this->rotationCenter);
|
||
|
}
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////
|
||
|
tMat4 getTransform() {
|
||
|
tMat4 trans, invTrans, rotation;
|
||
|
tMat4 panMat, dollyMat;
|
||
|
|
||
|
//create pan and dolly translations
|
||
|
panMat = translate(tMat4(T(1)),pan );
|
||
|
dollyMat = translate(tMat4(T(1)),dolly);
|
||
|
|
||
|
//create the virtualGizmo rotation
|
||
|
rotation = mat4_cast(qtV);
|
||
|
|
||
|
//create the translations to move the center of rotation to the origin and back
|
||
|
trans = translate(tMat4(T(1)), this->rotationCenter);
|
||
|
invTrans = translate(tMat4(T(1)),-this->rotationCenter);
|
||
|
|
||
|
//concatenate all the tranforms
|
||
|
return panMat * dollyMat * invTrans * rotation * trans;
|
||
|
}
|
||
|
|
||
|
// Set the mouse button and mods for dolly operation.
|
||
|
//////////////////////////////////////////////////////////////////
|
||
|
void setDollyControl( vgButtons b, vgModifiers m = evNoModifier) {
|
||
|
dollyControlButton = b;
|
||
|
dollyControlModifiers = m;
|
||
|
}
|
||
|
// Set the mouse button and optional mods for pan
|
||
|
//////////////////////////////////////////////////////////////////
|
||
|
void setPanControl( vgButtons b, vgModifiers m = evNoModifier) {
|
||
|
panControlButton = b;
|
||
|
panControlModifiers = m;
|
||
|
}
|
||
|
int getPanControlButton() { return panControlButton; }
|
||
|
int getPanControlModifier() { return panControlModifiers; }
|
||
|
|
||
|
// Sensitivity for Wheel movements -> Normalized: less < 1 < more
|
||
|
//////////////////////////////////////////////////////////////////
|
||
|
void setNormalizedWheelScale( T scale) { wheelScale = scale*constWheelScale; }
|
||
|
void setWheelScale( T scale) { wheelScale = scale; }
|
||
|
T getNormalizedWheelScale() { return wheelScale/constWheelScale; }
|
||
|
T getWheelScale() { return wheelScale; }
|
||
|
// Sensitivity for Dolly movements -> Normalized: less < 1 < more
|
||
|
//////////////////////////////////////////////////////////////////
|
||
|
void setNormalizedDollyScale( T scale) { dollyScale = scale*constDollyScale; }
|
||
|
void setDollyScale( T scale) { dollyScale = scale; }
|
||
|
T getNormalizedDollyScale() { return dollyScale/constDollyScale; }
|
||
|
T getDollyScale() { return dollyScale; }
|
||
|
// Sensitivity for Pan movements -> Normalized: less < 1 < more
|
||
|
//////////////////////////////////////////////////////////////////
|
||
|
void setNormalizedPanScale( T scale) { panScale = scale*constPanScale; }
|
||
|
void setPanScale( T scale) { panScale = scale; }
|
||
|
T getNormalizedPanScale() { return panScale/constPanScale; }
|
||
|
T getPanScale() { return panScale; }
|
||
|
// Sensitivity for pan/dolly by distance -> Normalized: less < 1 < more
|
||
|
//////////////////////////////////////////////////////////////////
|
||
|
void setNormalizedDistScale( T scale) { distScale = scale*constDistScale; }
|
||
|
void setDistScale( T scale) { distScale = scale; }
|
||
|
T getNormalizedDistScale() { return distScale/constDistScale; }
|
||
|
T getDistScale() { return distScale; }
|
||
|
|
||
|
// Set the Dolly to a specified distance.
|
||
|
//////////////////////////////////////////////////////////////////
|
||
|
void setDollyPosition(T pos) { dolly.z = pos; }
|
||
|
void setDollyPosition(const tVec3 &pos) { dolly.z = pos.z; }
|
||
|
|
||
|
// Set the Dolly to a specified distance.
|
||
|
//////////////////////////////////////////////////////////////////
|
||
|
void setPanPosition(const tVec3 &pos) { pan.x = pos.x; pan.y = pos.y;}
|
||
|
|
||
|
// Get dolly pos... use as Zoom factor
|
||
|
//////////////////////////////////////////////////////////////////
|
||
|
tVec3 &getDollyPosition() { return dolly; }
|
||
|
|
||
|
// Get Pan pos... use as Zoom factor
|
||
|
//////////////////////////////////////////////////////////////////
|
||
|
tVec3 &getPanPosition() { return pan; }
|
||
|
|
||
|
// Get Pan (xy) & Dolly (z) position
|
||
|
//////////////////////////////////////////////////////////////////
|
||
|
tVec3 getPosition() const { return tVec3(pan.x, pan.y, dolly.z); }
|
||
|
void setPosition(const tVec3 &p) { pan.x = p.x; pan.y = p.y; dolly.z = p.z; }
|
||
|
|
||
|
bool isDollyActive() { return dollyActive; }
|
||
|
bool isPanActive() { return panActive; }
|
||
|
|
||
|
void motionImmediateMode( T x, T y, T dx, T dy, vgModifiers mod) {
|
||
|
this->tbActive = true;
|
||
|
this->delta = tVec2(dx,-dy);
|
||
|
this->pos = tVec2( x, y);
|
||
|
if (dollyControlModifiers & mod) dollyActive = true;
|
||
|
else if (panControlModifiers & mod) panActive = true;
|
||
|
update();
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
// UI commands that this virtualGizmo responds to (defaults to left mouse button with no modifier key)
|
||
|
vgButtons dollyControlButton, panControlButton;
|
||
|
vgModifiers dollyControlModifiers, panControlModifiers;
|
||
|
|
||
|
// Variable used to determine if the manipulator is presently tracking the mouse
|
||
|
bool dollyActive;
|
||
|
bool panActive;
|
||
|
|
||
|
tVec3 pan = tVec3(T(0));
|
||
|
tVec3 dolly = tVec3(T(0));
|
||
|
|
||
|
const T constDollyScale = T(.01);
|
||
|
const T constPanScale = T(.01); //pan scale
|
||
|
const T constWheelScale = T(7.5); //dolly multiply for wheel step
|
||
|
const T constDistScale = T( .1); //speed by distance sensibility
|
||
|
|
||
|
T dollyScale = constDollyScale; //dolly scale
|
||
|
T panScale = constPanScale ; //pan scale
|
||
|
T wheelScale = constWheelScale; //dolly multiply for wheel step
|
||
|
T distScale = constDistScale ; //speed by distance sensibility
|
||
|
|
||
|
T povPanDollyFactor = T(0); // internal use, maintain memory of current distance (pan/zoom speed by distance)
|
||
|
};
|
||
|
|
||
|
#ifdef VGM_USES_TEMPLATE
|
||
|
#ifdef VGM_USES_DOUBLE_PRECISION
|
||
|
using vGizmo = virtualGizmoClass<double>;
|
||
|
using vGizmo3D = virtualGizmo3DClass<double>;
|
||
|
#else
|
||
|
using vGizmo = virtualGizmoClass<float>;
|
||
|
using vGizmo3D = virtualGizmo3DClass<float>;
|
||
|
#endif
|
||
|
#ifndef IMGUIZMO_USE_ONLY_ROT
|
||
|
using vImGuIZMO = virtualGizmo3DClass<float>;
|
||
|
#else
|
||
|
using vImGuIZMO = virtualGizmoClass<float>;
|
||
|
#endif
|
||
|
#else
|
||
|
#ifndef IMGUIZMO_USE_ONLY_ROT
|
||
|
using vImGuIZMO = virtualGizmo3DClass;
|
||
|
#else
|
||
|
using vImGuIZMO = virtualGizmoClass;
|
||
|
#endif
|
||
|
using vGizmo = virtualGizmoClass;
|
||
|
using vGizmo3D = virtualGizmo3DClass;
|
||
|
#endif
|
||
|
} // end namespace vg::
|
||
|
|
||
|
#undef T // if used T as #define, undef it
|
||
|
#undef VGIZMO_H_FILE
|