Browse Source

fix and speedup packing

Cary Sandvig 25 years ago
parent
commit
1c653114fe
3 changed files with 105 additions and 46 deletions
  1. 92 45
      panda/src/gui/guiFrame.cxx
  2. 12 1
      panda/src/gui/guiManager.cxx
  3. 1 0
      panda/src/gui/guiManager.h

+ 92 - 45
panda/src/gui/guiFrame.cxx

@@ -7,6 +7,36 @@
 
 
 TypeHandle GuiFrame::_type_handle;
 TypeHandle GuiFrame::_type_handle;
 
 
+class PosFrame {
+private:
+  LVector3f _pos;
+  LVector4f _frame;
+public:
+  PosFrame(GuiItem* i) : _pos(i->get_pos()), _frame(i->get_frame()) {}
+  PosFrame(void) {}
+  PosFrame(const PosFrame& c) : _pos(c._pos), _frame(c._frame) {}
+  inline PosFrame& operator=(const PosFrame& c) {
+    _pos = c._pos;
+    _frame = c._frame;
+    return *this;
+  }
+  inline void write(GuiItem* i) { i->set_pos(_pos); }
+  inline LVector3f get_pos(void) const { return _pos; }
+  inline LVector4f get_frame(void) const { return _frame; }
+  inline void set_pos(LVector3f p) {
+    LVector3f d = p - _pos;
+    float du = d.dot(LVector3f::up());
+    float dr = d.dot(LVector3f::right());
+    _frame[0] += dr;
+    _frame[1] += dr;
+    _frame[2] += du;
+    _frame[3] += du;
+    _pos = p;
+  }
+};
+
+typedef map<GuiItem*, PosFrame> UtilMap;
+
 GuiFrame::Boxes::iterator GuiFrame::find_box(GuiItem* item) {
 GuiFrame::Boxes::iterator GuiFrame::find_box(GuiItem* item) {
   bool found = false;
   bool found = false;
   Boxes::iterator ret = _items.end();
   Boxes::iterator ret = _items.end();
@@ -21,29 +51,38 @@ GuiFrame::Boxes::iterator GuiFrame::find_box(GuiItem* item) {
   return ret;
   return ret;
 }
 }
 
 
+#include <map>
+
 void GuiFrame::recompute_frame(void) {
 void GuiFrame::recompute_frame(void) {
   GuiItem::recompute_frame();
   GuiItem::recompute_frame();
 
 
   freeze();
   freeze();
 
 
   Boxes::iterator i;
   Boxes::iterator i;
+  UtilMap _map;
 
 
   // go thru and make sure everything is packed correctly.  This is a stupid
   // go thru and make sure everything is packed correctly.  This is a stupid
   // and brute-force algorithm.  Hopefully it will be replaced with something
   // and brute-force algorithm.  Hopefully it will be replaced with something
   // more ellegant later
   // more ellegant later
-    for (i=_items.begin(); i!=_items.end(); ++i) {
+  for (i=_items.begin(); i!=_items.end(); ++i) {
     GuiItem* here = (*i).get_item();
     GuiItem* here = (*i).get_item();
     here->recompute();
     here->recompute();
+    _map[here] = PosFrame(here);
+  }
+  for (i=_items.begin(); i!=_items.end(); ++i) {
+    GuiItem* here = (*i).get_item();
+    // here->recompute();
     int n = (*i).get_num_links();
     int n = (*i).get_num_links();
     if (n > 0) {
     if (n > 0) {
-      LVector4f ext_h = here->get_frame();
-      LVector3f pos_h = here->get_pos();
+      UtilMap::iterator ui = _map.find(here);
+      LVector4f ext_h = (*ui).second.get_frame();
+      LVector3f pos_h = (*ui).second.get_pos();
       for (int j=0; j<n; ++j) {
       for (int j=0; j<n; ++j) {
 	Packing pack = (*i).get_nth_packing(j);
 	Packing pack = (*i).get_nth_packing(j);
 	if (pack == NONE)
 	if (pack == NONE)
 	  continue;
 	  continue;
 	GuiItem* to = (*i).get_nth_to(j);
 	GuiItem* to = (*i).get_nth_to(j);
-	LVector4f ext_t = to->get_frame();
+	LVector4f ext_t = _map[to].get_frame();
 	float gap = (*i).get_nth_gap(j);
 	float gap = (*i).get_nth_gap(j);
 	switch (pack) {
 	switch (pack) {
 	case ABOVE:
 	case ABOVE:
@@ -51,9 +90,9 @@ void GuiFrame::recompute_frame(void) {
 	    // to(top) - here(bottom)
 	    // to(top) - here(bottom)
 	    float diff = ext_t[3] - ext_h[2] + gap;
 	    float diff = ext_t[3] - ext_h[2] + gap;
 	    LVector3f move = LVector3f::rfu(0., 0., diff);
 	    LVector3f move = LVector3f::rfu(0., 0., diff);
-	    here->set_pos(pos_h + move);
-	    ext_h = here->get_frame();
-	    pos_h = here->get_pos();
+	    (*ui).second.set_pos(pos_h + move);
+	    ext_h = (*ui).second.get_frame();
+	    pos_h = (*ui).second.get_pos();
 	  }
 	  }
 	  break;
 	  break;
 	case UNDER:
 	case UNDER:
@@ -61,9 +100,9 @@ void GuiFrame::recompute_frame(void) {
 	    // to(bottom) - here(top)
 	    // to(bottom) - here(top)
 	    float diff = ext_t[2] - ext_h[3] - gap;
 	    float diff = ext_t[2] - ext_h[3] - gap;
 	    LVector3f move = LVector3f::rfu(0., 0., diff);
 	    LVector3f move = LVector3f::rfu(0., 0., diff);
-	    here->set_pos(pos_h + move);
-	    ext_h = here->get_frame();
-	    pos_h = here->get_pos();
+	    (*ui).second.set_pos(pos_h + move);
+	    ext_h = (*ui).second.get_frame();
+	    pos_h = (*ui).second.get_pos();
 	  }
 	  }
 	  break;
 	  break;
 	case LEFT:
 	case LEFT:
@@ -71,9 +110,9 @@ void GuiFrame::recompute_frame(void) {
 	    // to(left) - here(right)
 	    // to(left) - here(right)
 	    float diff = ext_t[0] - ext_h[1] - gap;
 	    float diff = ext_t[0] - ext_h[1] - gap;
 	    LVector3f move = LVector3f::rfu(diff, 0., 0.);
 	    LVector3f move = LVector3f::rfu(diff, 0., 0.);
-	    here->set_pos(pos_h + move);
-	    ext_h = here->get_frame();
-	    pos_h = here->get_pos();
+	    (*ui).second.set_pos(pos_h + move);
+	    ext_h = (*ui).second.get_frame();
+	    pos_h = (*ui).second.get_pos();
 	  }
 	  }
 	  break;
 	  break;
 	case RIGHT:
 	case RIGHT:
@@ -81,9 +120,9 @@ void GuiFrame::recompute_frame(void) {
 	    // to(right) - here(left)
 	    // to(right) - here(left)
 	    float diff = ext_t[1] - ext_h[0] + gap;
 	    float diff = ext_t[1] - ext_h[0] + gap;
 	    LVector3f move = LVector3f::rfu(diff, 0., 0.);
 	    LVector3f move = LVector3f::rfu(diff, 0., 0.);
-	    here->set_pos(pos_h + move);
-	    ext_h = here->get_frame();
-	    pos_h = here->get_pos();
+	    (*ui).second.set_pos(pos_h + move);
+	    ext_h = (*ui).second.get_frame();
+	    pos_h = (*ui).second.get_pos();
 	  }
 	  }
 	  break;
 	  break;
 	case ALIGN_ABOVE:
 	case ALIGN_ABOVE:
@@ -91,9 +130,9 @@ void GuiFrame::recompute_frame(void) {
 	    // to(top) - here(top)
 	    // to(top) - here(top)
 	    float diff = ext_t[3] - ext_h[3];
 	    float diff = ext_t[3] - ext_h[3];
 	    LVector3f move = LVector3f::rfu(0., 0., diff);
 	    LVector3f move = LVector3f::rfu(0., 0., diff);
-	    here->set_pos(pos_h + move);
-	    ext_h = here->get_frame();
-	    pos_h = here->get_pos();
+	    (*ui).second.set_pos(pos_h + move);
+	    ext_h = (*ui).second.get_frame();
+	    pos_h = (*ui).second.get_pos();
 	  }
 	  }
 	  break;
 	  break;
 	case ALIGN_UNDER:
 	case ALIGN_UNDER:
@@ -101,9 +140,9 @@ void GuiFrame::recompute_frame(void) {
 	    // to(bottom) - here(bottom)
 	    // to(bottom) - here(bottom)
 	    float diff = ext_t[2] - ext_h[2];
 	    float diff = ext_t[2] - ext_h[2];
 	    LVector3f move = LVector3f::rfu(0., 0., diff);
 	    LVector3f move = LVector3f::rfu(0., 0., diff);
-	    here->set_pos(pos_h + move);
-	    ext_h = here->get_frame();
-	    pos_h = here->get_pos();
+	    (*ui).second.set_pos(pos_h + move);
+	    ext_h = (*ui).second.get_frame();
+	    pos_h = (*ui).second.get_pos();
 	  }
 	  }
 	  break;
 	  break;
 	case ALIGN_LEFT:
 	case ALIGN_LEFT:
@@ -111,9 +150,9 @@ void GuiFrame::recompute_frame(void) {
 	    // to(left) - here(left)
 	    // to(left) - here(left)
 	    float diff = ext_t[0] - ext_h[0];
 	    float diff = ext_t[0] - ext_h[0];
 	    LVector3f move = LVector3f::rfu(diff, 0., 0.);
 	    LVector3f move = LVector3f::rfu(diff, 0., 0.);
-	    here->set_pos(pos_h + move);
-	    ext_h = here->get_frame();
-	    pos_h = here->get_pos();
+	    (*ui).second.set_pos(pos_h + move);
+	    ext_h = (*ui).second.get_frame();
+	    pos_h = (*ui).second.get_pos();
 	  }
 	  }
 	  break;
 	  break;
 	case ALIGN_RIGHT:
 	case ALIGN_RIGHT:
@@ -121,9 +160,9 @@ void GuiFrame::recompute_frame(void) {
 	    // to(right) - here(right)
 	    // to(right) - here(right)
 	    float diff = ext_t[1] - ext_h[1];
 	    float diff = ext_t[1] - ext_h[1];
 	    LVector3f move = LVector3f::rfu(diff, 0., 0.);
 	    LVector3f move = LVector3f::rfu(diff, 0., 0.);
-	    here->set_pos(pos_h + move);
-	    ext_h = here->get_frame();
-	    pos_h = here->get_pos();
+	    (*ui).second.set_pos(pos_h + move);
+	    ext_h = (*ui).second.get_frame();
+	    pos_h = (*ui).second.get_pos();
 	  }
 	  }
 	  break;
 	  break;
 	default:
 	default:
@@ -138,13 +177,14 @@ void GuiFrame::recompute_frame(void) {
   _left = _bottom = 10000000.;
   _left = _bottom = 10000000.;
   _right = _top = -10000000.;
   _right = _top = -10000000.;
   for (i=_items.begin(); i!=_items.end(); ++i) {
   for (i=_items.begin(); i!=_items.end(); ++i) {
-    float tmp = (*i).get_item()->get_left();
+    UtilMap::iterator ui = _map.find((*i).get_item());
+    float tmp = ((*ui).second.get_frame())[0];
     _left = (_left<tmp)?_left:tmp;
     _left = (_left<tmp)?_left:tmp;
-    tmp = (*i).get_item()->get_right();
+    tmp = ((*ui).second.get_frame())[1];
     _right = (_right<tmp)?tmp:_right;
     _right = (_right<tmp)?tmp:_right;
-    tmp = (*i).get_item()->get_bottom();
+    tmp = ((*ui).second.get_frame())[2];
     _bottom = (_bottom<tmp)?_bottom:tmp;
     _bottom = (_bottom<tmp)?_bottom:tmp;
-    tmp = (*i).get_item()->get_top();
+    tmp = ((*ui).second.get_frame())[3];
     _top = (_top<tmp)?tmp:_top;
     _top = (_top<tmp)?tmp:_top;
   }
   }
   // now put it at the position it is supposed to be
   // now put it at the position it is supposed to be
@@ -154,19 +194,21 @@ void GuiFrame::recompute_frame(void) {
   LVector3f delta = _pos - pos;
   LVector3f delta = _pos - pos;
   for (i=_items.begin(); i!=_items.end(); ++i) {
   for (i=_items.begin(); i!=_items.end(); ++i) {
     GuiItem* foo = (*i).get_item();
     GuiItem* foo = (*i).get_item();
-    foo->set_pos(foo->get_pos() + delta);
+    UtilMap::iterator ui = _map.find(foo);
+    (*ui).second.set_pos((*ui).second.get_pos() + delta);
   }
   }
   // get the bounds again
   // get the bounds again
   _left = _bottom = 10000000.;
   _left = _bottom = 10000000.;
   _right = _top = -10000000.;
   _right = _top = -10000000.;
   for (i=_items.begin(); i!=_items.end(); ++i) {
   for (i=_items.begin(); i!=_items.end(); ++i) {
-    float tmp = (*i).get_item()->get_left();
+    UtilMap::iterator ui = _map.find((*i).get_item());
+    float tmp = ((*ui).second.get_frame())[0];
     _left = (_left<tmp)?_left:tmp;
     _left = (_left<tmp)?_left:tmp;
-    tmp = (*i).get_item()->get_right();
+    tmp = ((*ui).second.get_frame())[1];
     _right = (_right<tmp)?tmp:_right;
     _right = (_right<tmp)?tmp:_right;
-    tmp = (*i).get_item()->get_bottom();
+    tmp = ((*ui).second.get_frame())[2];
     _bottom = (_bottom<tmp)?_bottom:tmp;
     _bottom = (_bottom<tmp)?_bottom:tmp;
-    tmp = (*i).get_item()->get_top();
+    tmp = ((*ui).second.get_frame())[3];
     _top = (_top<tmp)?tmp:_top;
     _top = (_top<tmp)?tmp:_top;
   }
   }
   // check for alignment to the DisplayRegion
   // check for alignment to the DisplayRegion
@@ -191,22 +233,27 @@ void GuiFrame::recompute_frame(void) {
   LVector3f move = move_left + move_right + move_top + move_bottom;
   LVector3f move = move_left + move_right + move_top + move_bottom;
   for (i=_items.begin(); i!=_items.end(); ++i) {
   for (i=_items.begin(); i!=_items.end(); ++i) {
     GuiItem* foo = (*i).get_item();
     GuiItem* foo = (*i).get_item();
-    foo->set_pos(foo->get_pos() + move);
+    UtilMap::iterator ui = _map.find(foo);
+    (*ui).second.set_pos((*ui).second.get_pos() + move);
   }
   }
   // lastly, get the finial bounds
   // lastly, get the finial bounds
   _left = _bottom = 10000000.;
   _left = _bottom = 10000000.;
   _right = _top = -10000000.;
   _right = _top = -10000000.;
   for (i=_items.begin(); i!=_items.end(); ++i) {
   for (i=_items.begin(); i!=_items.end(); ++i) {
-    float tmp = (*i).get_item()->get_left();
+    UtilMap::iterator ui = _map.find((*i).get_item());
+    float tmp = ((*ui).second.get_frame())[0];
     _left = (_left<tmp)?_left:tmp;
     _left = (_left<tmp)?_left:tmp;
-    tmp = (*i).get_item()->get_right();
+    tmp = ((*ui).second.get_frame())[1];
     _right = (_right<tmp)?tmp:_right;
     _right = (_right<tmp)?tmp:_right;
-    tmp = (*i).get_item()->get_bottom();
+    tmp = ((*ui).second.get_frame())[2];
     _bottom = (_bottom<tmp)?_bottom:tmp;
     _bottom = (_bottom<tmp)?_bottom:tmp;
-    tmp = (*i).get_item()->get_top();
+    tmp = ((*ui).second.get_frame())[3];
     _top = (_top<tmp)?tmp:_top;
     _top = (_top<tmp)?tmp:_top;
   }
   }
-
+  for (i=_items.begin(); i!= _items.end(); ++i) {
+    GuiItem* foo = (*i).get_item();
+    _map[foo].write(foo);
+  }
   this->adjust_region();
   this->adjust_region();
   thaw();
   thaw();
 }
 }
@@ -362,8 +409,8 @@ void GuiFrame::set_scale(float x, float y, float z) {
 }
 }
 
 
 void GuiFrame::set_pos(const LVector3f& p) {
 void GuiFrame::set_pos(const LVector3f& p) {
-  for (Boxes::iterator i=_items.begin(); i!=_items.end(); ++i)
-    (*i).get_item()->set_pos(p);
+  //  for (Boxes::iterator i=_items.begin(); i!=_items.end(); ++i)
+  //    (*i).get_item()->set_pos(p);
   GuiItem::set_pos(p);
   GuiItem::set_pos(p);
   //  this->recompute_frame();
   //  this->recompute_frame();
 }
 }

+ 12 - 1
panda/src/gui/guiManager.cxx

@@ -219,7 +219,7 @@ void GuiManager::recompute_priorities(void) {
 }
 }
 
 
 INLINE bool in_range(float x, float a, float b) {
 INLINE bool in_range(float x, float a, float b) {
-  return ((x >= a) && (x <= b));
+  return ((x > a) && (x < b));
 }
 }
 
 
 INLINE bool overlap(MouseWatcherRegion* a, MouseWatcherRegion* b) {
 INLINE bool overlap(MouseWatcherRegion* a, MouseWatcherRegion* b) {
@@ -232,6 +232,17 @@ INLINE bool overlap(MouseWatcherRegion* a, MouseWatcherRegion* b) {
   return false;
   return false;
 }
 }
 
 
+bool GuiManager::is_sane(void) const {
+  for (RegionSet::const_iterator i=_regions.begin(); i!=_regions.end(); ++i)
+    for (RegionSet::const_iterator j=_regions.begin(); j!=_regions.end(); ++j) {
+      if ((*i) == (*j))
+	continue;
+      if (overlap((*i), (*j)))
+	return false;
+    }
+  return true;
+}
+
 void GuiManager::sanity_check(void) const {
 void GuiManager::sanity_check(void) const {
   for (RegionSet::const_iterator i=_regions.begin(); i!=_regions.end(); ++i)
   for (RegionSet::const_iterator i=_regions.begin(); i!=_regions.end(); ++i)
     for (RegionSet::const_iterator j=_regions.begin(); j!=_regions.end(); ++j) {
     for (RegionSet::const_iterator j=_regions.begin(); j!=_regions.end(); ++j) {

+ 1 - 0
panda/src/gui/guiManager.h

@@ -61,6 +61,7 @@ PUBLISHED:
   INLINE int get_start_draw_order(void) const;
   INLINE int get_start_draw_order(void) const;
   INLINE void set_start_draw_order(int);
   INLINE void set_start_draw_order(int);
 
 
+  bool is_sane(void) const;
   void sanity_check(void) const;
   void sanity_check(void) const;
 };
 };