From 1ad548c24c06a3f773cd58b1ec08a9acd66548d3 Mon Sep 17 00:00:00 2001 From: mtarini Date: Wed, 12 Nov 2008 16:33:40 +0000 Subject: [PATCH] Added animations and keys (so far, only used by the Navigator Mode) --- wrap/gui/trackball.cpp | 105 +++++++++++++++++++++++++++-------------- wrap/gui/trackball.h | 55 ++++++++++++++------- 2 files changed, 108 insertions(+), 52 deletions(-) diff --git a/wrap/gui/trackball.cpp b/wrap/gui/trackball.cpp index 69c70b97..ac57f410 100644 --- a/wrap/gui/trackball.cpp +++ b/wrap/gui/trackball.cpp @@ -125,7 +125,7 @@ Transform::Transform() { Trackball::Trackball(): current_button(0), current_mode(NULL), inactive_mode(NULL), dragging(false), spinnable(true), spinning(false), - history_size(10){ + history_size(10), last_time(0), fixedTimestepMode(false) { setDefaultMapping (); } @@ -141,17 +141,24 @@ Trackball::~Trackball() void Trackball::setDefaultMapping () { + idle_and_keys_mode = NULL; + inactive_mode = new InactiveMode (); modes.clear (); modes[0] = NULL; + + modes[BUTTON_MIDDLE | KEY_ALT] = modes[BUTTON_LEFT] = new SphereMode (); + modes[BUTTON_LEFT | KEY_CTRL] = new PanMode (); + modes[BUTTON_MIDDLE] = new PanMode (); + + modes[WHEEL] = modes[BUTTON_LEFT | KEY_SHIFT] = new ScaleMode (); + modes[BUTTON_LEFT | KEY_ALT] = new ZMode (); - modes[BUTTON_MIDDLE | KEY_ALT] = new SphereMode (); - modes[WHEEL] = new ScaleMode (); - SetCurrentAction (); + } void Trackball::SetIdentity() { @@ -171,9 +178,8 @@ void Trackball::DrawPostApply() { if(current_mode !=NULL){ current_mode->Draw(this); }else{ - assert(inactive_mode != NULL); - inactive_mode->Draw(this); - } + if (inactive_mode != NULL) inactive_mode->Draw(this); + } } void Trackball::Apply () { @@ -329,8 +335,7 @@ void Trackball::Reset() { if(mode!=NULL) mode->Reset(); } - assert(inactive_mode != NULL); - inactive_mode->Reset(); + if (inactive_mode != NULL) inactive_mode->Reset(); } //interface @@ -358,10 +363,40 @@ void Trackball::MouseMove(int x, int y) { current_mode->Apply(this, Point3f(float(x), float(y), 0)); } +bool Trackball::IsAnimating(unsigned int msec){ + bool res; + if(idle_and_keys_mode == NULL) res=false; else res=idle_and_keys_mode->IsAnimating(this); + + if (!fixedTimestepMode) { + if (msec==0) msec = clock()*1000/CLOCKS_PER_SEC; + if (!res) { + last_time = msec; + } + } + return res; +} + +void Trackball::Sync(unsigned int msec) { + if (!fixedTimestepMode) Animate(msec); +} + +void Trackball::Animate(unsigned int msec){ + unsigned int delta; + if (fixedTimestepMode) delta=msec; + else { + if (msec==0) msec = clock()*1000/CLOCKS_PER_SEC; + delta = msec -last_time; + last_time = msec; + } + if(idle_and_keys_mode == NULL) return; + idle_and_keys_mode->Animate(delta,this); +} + void Trackball::MouseUp(int /* x */, int /* y */, int button) { undo_track = track; - current_button &= (~button); - SetCurrentAction(); + ButtonUp(vcg::Trackball::Button(button)); + //current_button &= (~button); + //SetCurrentAction(); } // it assumes that a notch of 1.0 is a single step of the wheel @@ -373,8 +408,8 @@ void Trackball::MouseWheel(float notch) SetCurrentAction(); if (current_mode == NULL) { - ScaleMode scalemode; - scalemode.Apply (this, notch); + //ScaleMode scalemode; + //scalemode.Apply (this, notch); } else { @@ -399,34 +434,34 @@ void Trackball::MouseWheel(float notch, int button) SetCurrentAction (); } -void Trackball::ButtonDown(Trackball::Button button) { +void Trackball::ButtonDown(Trackball::Button button, unsigned int msec) { + Sync(msec); bool old_sticky=false, new_sticky=false; assert (modes.count (0)); - if ( ( modes.count (current_button) ) && ( modes[current_button] != NULL ) ) { - old_sticky = modes[current_button]->isSticky(); - } + + Button b=Button(current_button & MODIFIER_MASK); + if ( ( modes.count (b) ) && ( modes[b] != NULL ) ) old_sticky = modes[b]->isSticky(); + current_button |= button; - if ( ( modes.count (current_button) ) && ( modes[current_button] != NULL ) ) { - new_sticky = modes[current_button]->isSticky(); - } - if ( old_sticky || new_sticky) - return; - SetCurrentAction(); + b=Button(current_button & MODIFIER_MASK); + if ( ( modes.count (b) ) && ( modes[b] != NULL ) ) new_sticky = modes[b]->isSticky(); + + if ( !old_sticky && !new_sticky) SetCurrentAction(); + } void Trackball::ButtonUp(Trackball::Button button) { bool old_sticky=false, new_sticky=false; - assert ( modes.count (0) ); - if ( ( modes.count (current_button) ) && ( modes[current_button] != NULL ) ) { - old_sticky = modes[current_button]->isSticky(); - } + assert (modes.count (0)); + + Button b=Button(current_button & MODIFIER_MASK); + if ( ( modes.count (b) ) && ( modes[b] != NULL ) ) old_sticky = modes[b]->isSticky(); + current_button &= (~button); - if ( ( modes.count (current_button) ) && ( modes[current_button] != NULL ) ) { - new_sticky = modes[current_button]->isSticky(); - } - if ( old_sticky || new_sticky) - return; - SetCurrentAction(); + b=Button(current_button & MODIFIER_MASK); + if ( ( modes.count (b) ) && ( modes[b] != NULL ) ) new_sticky = modes[b]->isSticky(); + + if ( !old_sticky && !new_sticky) SetCurrentAction(); } void Trackball::Undo(){ @@ -457,10 +492,10 @@ void Trackball::SetCurrentAction () { //I use strict matching. assert (modes.count (0)); - if (!modes.count (current_button)) { + if (!modes.count (current_button & MODIFIER_MASK)) { current_mode = NULL; } else { - current_mode = modes[current_button]; + current_mode = modes[current_button & MODIFIER_MASK]; if(current_mode != NULL) current_mode->SetAction(); } diff --git a/wrap/gui/trackball.h b/wrap/gui/trackball.h index 6e964d53..7d668107 100644 --- a/wrap/gui/trackball.h +++ b/wrap/gui/trackball.h @@ -80,6 +80,7 @@ Adding copyright. #ifndef TRACKBALL_H #define TRACKBALL_H +#include #include #include #include @@ -165,13 +166,9 @@ mesh->Render(); */ class Trackball: public Transform { public: -// the drawing code has been moved to the trackmodes -// class DrawingHint { - -// DrawingHint DH; /// The componibile states of the manipulator system. - enum Button { BUTTON_NONE = 0x0000, ///< No mouse button pressed. + enum Button { BUTTON_NONE = 0x0000, ///< No button or key pressed. BUTTON_LEFT = 0x0001, ///< Left mouse button pressed. BUTTON_MIDDLE = 0x0002, ///< Middle mouse button pressed. BUTTON_RIGHT = 0x0004, ///< Right mouse button pressed. @@ -179,7 +176,14 @@ public: KEY_SHIFT = 0x0010, ///< Shift key pressed. KEY_CTRL = 0x0020, ///< Ctrl key pressed. KEY_ALT = 0x0040, ///< Alt key pressed. - HANDLE = 0x0080 ///< Application-defined state activated. + HANDLE = 0x0080, ///< Application-defined state activated. + MODIFIER_MASK = 0x00FF, ///< (mask to get modifiers only) + KEY_UP = 0x0100, ///< Up directional key + KEY_DOWN = 0x0200, ///< Down directional key + KEY_LEFT = 0x0400, ///< Left directional key + KEY_RIGHT = 0x0800, ///< Right directional key + KEY_PGUP = 0x1000, ///< PageUp directional key + KEY_PGDOWN = 0x2000, ///< PageDown directional key }; /*! @@ -331,7 +335,7 @@ public: @param button the new state. */ - void ButtonDown(Button button); + void ButtonDown(Button button, unsigned int msec=0); /*! @brief Undo function for manipulator system. @@ -348,19 +352,23 @@ public: */ void SetSensitivity(float s); - //spinning interface - /*! - @brief Currently not in use. - - @param on Currently not in use. - */ void SetSpinnable(bool on); + + + // returns if it is animating or not + // + bool IsAnimating(unsigned int msec=0); + + // Animate: either takes an absolute time (if default not specified, then it is automeasured) + // or a fixed delta + void Animate(unsigned int msec=0); + /*! @brief Currently not in use. @return A meaningless boolean value. */ - bool IsSpinnable(); + bool IsSpinnable(); /*! @brief Currently not in use. @@ -441,14 +449,16 @@ public: This function is called automatically when an user action begins. */ void SetCurrentAction(); - /// Current state composition. + /// Current state composition. Note: mask with MODIFIERS to get modifier buttons only int current_button; /// The selected manipulator. TrackMode *current_mode; - /// The inactive manipulator. It is drawed when Trackball is inactive. + /// The inactive manipulator. It is drawn when Trackball is inactive. TrackMode *inactive_mode; - + + // The manipulator to deal with timer events and key events + TrackMode *idle_and_keys_mode; /*! @brief Reset modes to default mapping. @@ -482,6 +492,8 @@ public: /// Currently not in use. int button_mask; + unsigned int last_time; + /// Currently not in use. Quaternionf spin; /// Currently not in use. @@ -494,8 +506,17 @@ public: /// Currently not in use. int history_size; + + void SetFixedTimesteps(bool mode){ + fixedTimestepMode=mode; + } + /// Manipulators needs full access to this class. friend class TrackMode; +private: + void Sync(unsigned int msec); + bool fixedTimestepMode; // if true, animations occurs at fixed time steps + };