diff --git a/panda/src/event/pointerEventList.cxx b/panda/src/event/pointerEventList.cxx index 466a07299d..df9183e018 100644 --- a/panda/src/event/pointerEventList.cxx +++ b/panda/src/event/pointerEventList.cxx @@ -18,12 +18,41 @@ #include "pointerEventList.h" #include "indent.h" +#include "config_event.h" #include "clockObject.h" #include "mathNumbers.h" #include TypeHandle PointerEventList::_type_handle; +//////////////////////////////////////////////////////////////////// +// Function: delta_angle +// Access: Static, Inline +// Description: Compute the difference between two angles. +// Returns a value in the range -180 to 180. +//////////////////////////////////////////////////////////////////// +INLINE double delta_angle(double angle1, double angle2) { + double deltang = angle2 - angle1; + while (deltang < -180.0) deltang += 360.0; + while (deltang > 180.0) deltang -= 360.0; + return deltang; +} + + +//////////////////////////////////////////////////////////////////// +// Function: delta_angle +// Access: Static, Inline +// Description: Compute the difference between two angles. +// Returns a value in the range -180 to 180. +//////////////////////////////////////////////////////////////////// +INLINE double normalize_angle(double angle) { + while (angle < 0.0) angle += 360.0; + while (angle > 360.0) angle -= 360.0; + return angle; +} + + + //////////////////////////////////////////////////////////////////// // Function: PointerEventList::output // Access: Public, Virtual @@ -82,14 +111,11 @@ add_event(bool in_win, int xpos, int ypos, int seq, double time) { double ddy = pe._dy; pe._length = sqrt(ddx*ddx + ddy*ddy); if (pe._length > 0.0) { - pe._direction = atan2(-ddy,ddx) * (180.0 / MathNumbers::pi); - if (pe._direction < 0.0) pe._direction += 360.0; + pe._direction = normalize_angle(atan2(-ddy,ddx) * (180.0 / MathNumbers::pi)); } else { pe._direction = _events.back()._direction; } - pe._rotation = pe._direction - _events.back()._direction; - if (pe._rotation > 180.0) pe._rotation -= 360.0; - if (pe._rotation < -180.0) pe._rotation += 360.0; + pe._rotation = delta_angle(_events.back()._direction, pe._direction); } else { pe._dx = 0; pe._dy = 0; @@ -123,9 +149,7 @@ encircles(int x, int y) const { continue; } double angle = atan2(dy,dx) * (180.0/MathNumbers::pi); - double deltang = angle - lastang; - if (deltang < -180.0) deltang += 360.0; - if (deltang > 180.0) deltang -= 360.0; + double deltang = delta_angle(lastang, angle); if (deltang * total < 0.0) { total = 0.0; } @@ -156,3 +180,79 @@ total_turns(double sec) const { } return tot; } + +//////////////////////////////////////////////////////////////////// +// Function: PointerEventList::match_pattern +// Access: Published +// Description: This function is not implemented yet. It is a work +// in progress. The intent is as follows: +// +// Returns a nonzero value if the mouse movements +// match the specified pattern. The higher the value, +// the better the match. The pattern is a sequence +// of compass directions (ie, "E", "NE", etc) separated +// by spaces. If rot is nonzero, then the pattern is +// rotated counterclockwise by the specified amount +// before testing. Seglen is the minimum length a +// mouse movement needs to be in order to be considered +// significant. +//////////////////////////////////////////////////////////////////// +double PointerEventList:: +match_pattern(const string &ascpat, double rot, double seglen) { + // Convert the pattern from ascii to a more usable form. + pvector pattern; + parse_pattern(ascpat, pattern); + + // Apply the rotation to the pattern. + for (size_t i=0; i &pattern) { + int chars = 0; + double dir = 180.0; + for (size_t i=0; i= 0.0) { + double offset = delta_angle(dir, ang); + double newang = dir + offset; + dir = normalize_angle((dir * chars + newang) / (chars + 1)); + chars += 1; + } else { + if ((c != ' ')&&(c != '\t')) { + event_cat.warning() << + "Invalid pattern in PointerEventList::match_pattern\n"; + pattern.clear(); + return; + } + if (chars > 0) { + pattern.push_back(dir); + } + chars = 0; + dir = 180.0; + } + } + if (chars > 0) { + pattern.push_back(dir); + } + + cerr << "Pattern: "; + for (int i=0; i<(int)pattern.size(); i++) { + cerr << pattern[i] << " "; + } + cerr << "\n"; +} diff --git a/panda/src/event/pointerEventList.h b/panda/src/event/pointerEventList.h index b5e16596a5..35970ce037 100644 --- a/panda/src/event/pointerEventList.h +++ b/panda/src/event/pointerEventList.h @@ -60,6 +60,7 @@ PUBLISHED: bool encircles(int x, int y) const; double total_turns(double sec) const; + double match_pattern(const string &pattern, double rot, double seglen); public: INLINE PointerEventList(const PointerEventList ©); @@ -70,6 +71,7 @@ public: void write(ostream &out, int indent_level = 0) const; private: + void parse_pattern(const string &ascpat, pvector &pattern); typedef pdeque Events; Events _events;