Pārlūkot izejas kodu

*** empty log message ***

David Rose 25 gadi atpakaļ
vecāks
revīzija
fe6255f3e1

+ 3 - 1
panda/src/collide/collisionHandler.h

@@ -27,10 +27,12 @@ public:
   virtual void end_group();
 
 
-public:
+PUBLISHED:
   static TypeHandle get_class_type() {
     return _type_handle;
   }
+
+public:
   static void init_type() {
     TypedReferenceCount::init_type();
     register_type(_type_handle, "CollisionHandler",

+ 1 - 0
panda/src/collide/collisionHandlerPhysical.cxx

@@ -50,6 +50,7 @@ set_mat(const LMatrix4f &mat) const {
 
   } else if (_drive_interface != (DriveInterface *)NULL) {
     _drive_interface->set_mat(mat);
+    _drive_interface->force_dgraph();
 
   } else {
     collide_cat.error()

+ 44 - 5
panda/src/collide/collisionTraverser.cxx

@@ -57,6 +57,7 @@ CollisionTraverser::
 ////////////////////////////////////////////////////////////////////
 void CollisionTraverser::
 add_collider(CollisionNode *node, CollisionHandler *handler) {
+  nassertv(_ordered_colliders.size() == _colliders.size());
   nassertv(node != (CollisionNode *)NULL);
   nassertv(handler != (CollisionHandler *)NULL);
 
@@ -88,6 +89,7 @@ add_collider(CollisionNode *node, CollisionHandler *handler) {
   } else {
     // We hadn't already known about this collider.
     _colliders.insert(Colliders::value_type(node, handler));
+    _ordered_colliders.push_back(node);
 
     Handlers::iterator hi = _handlers.find(handler);
     if (hi == _handlers.end()) {
@@ -96,6 +98,8 @@ add_collider(CollisionNode *node, CollisionHandler *handler) {
       (*hi).second++;
     }
   }
+
+  nassertv(_ordered_colliders.size() == _colliders.size());
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -109,6 +113,8 @@ add_collider(CollisionNode *node, CollisionHandler *handler) {
 ////////////////////////////////////////////////////////////////////
 bool CollisionTraverser::
 remove_collider(CollisionNode *node) {
+  nassertr(_ordered_colliders.size() == _colliders.size(), false);
+
   Colliders::iterator ci = _colliders.find(node);
   if (ci == _colliders.end()) {
     // We didn't know about this node.
@@ -127,6 +133,13 @@ remove_collider(CollisionNode *node) {
   }
 
   _colliders.erase(ci);
+
+  OrderedColliders::iterator oci = 
+    find(_ordered_colliders.begin(), _ordered_colliders.end(), node);
+  nassertr(oci != _ordered_colliders.end(), false);
+  _ordered_colliders.erase(oci);
+
+  nassertr(_ordered_colliders.size() == _colliders.size(), false);
   return true;
 }
 
@@ -143,6 +156,31 @@ has_collider(CollisionNode *node) const {
   return (ci != _colliders.end());
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: CollisionTraverser::get_num_colliders
+//       Access: Public
+//  Description: Returns the number of CollisionNodes that have been
+//               added to the traverser via add_collider().
+////////////////////////////////////////////////////////////////////
+int CollisionTraverser::
+get_num_colliders() const {
+  nassertr(_ordered_colliders.size() == _colliders.size(), 0);
+  return _ordered_colliders.size();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CollisionTraverser::get_collider
+//       Access: Public
+//  Description: Returns the nth CollisionNode that has been
+//               added to the traverser via add_collider().
+////////////////////////////////////////////////////////////////////
+CollisionNode *CollisionTraverser::
+get_collider(int n) const {
+  nassertr(_ordered_colliders.size() == _colliders.size(), NULL);
+  nassertr(n >= 0 && n < (int)_ordered_colliders.size(), NULL);
+  return _ordered_colliders[n];
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: CollisionTraverser::get_handler
 //       Access: Public
@@ -168,6 +206,7 @@ get_handler(CollisionNode *node) const {
 void CollisionTraverser::
 clear_colliders() {
   _colliders.clear();
+  _ordered_colliders.clear();
 }
 
 
@@ -245,10 +284,9 @@ prepare_colliders(CollisionLevelState &level_state) {
   level_state.clear();
   level_state.reserve(_colliders.size());
 
-  Colliders::iterator ci = _colliders.begin();
-  while (ci != _colliders.end()) {
-    CollisionNode *cnode = (*ci).first;
-    ++ci;
+  int i = 0;
+  while (i < (int)_ordered_colliders.size()) {
+    CollisionNode *cnode = _ordered_colliders[i];
 
     CollisionLevelState::ColliderDef def;
     def._node = cnode;
@@ -261,7 +299,7 @@ prepare_colliders(CollisionLevelState &level_state) {
 	<< "Collider " << *cnode
 	<< " has become NaN.  Dropping from traverser.\n";
       // This is safe to do while traversing the list of colliders,
-      // because we have already incremented ci, above.
+      // because we do not increment i in this case.
       remove_collider(cnode);
     } else
 #endif
@@ -272,6 +310,7 @@ prepare_colliders(CollisionLevelState &level_state) {
 	  def._collider = collider;
 	  level_state.prepare_collider(def);
 	}
+	i++;
       }
   }
 }

+ 4 - 0
panda/src/collide/collisionTraverser.h

@@ -37,6 +37,8 @@ PUBLISHED:
   void add_collider(CollisionNode *node, CollisionHandler *handler);
   bool remove_collider(CollisionNode *node);
   bool has_collider(CollisionNode *node) const;
+  int get_num_colliders() const;
+  CollisionNode *get_collider(int n) const;
   CollisionHandler *get_handler(CollisionNode *node) const;
   void clear_colliders();
 
@@ -79,6 +81,8 @@ private:
 
   typedef map<PT(CollisionNode), PT(CollisionHandler)> Colliders;
   Colliders _colliders;
+  typedef vector<CollisionNode *> OrderedColliders;
+  OrderedColliders _ordered_colliders;
 
   typedef map<PT(CollisionHandler), int> Handlers;
   Handlers _handlers;

+ 0 - 3
panda/src/dgraph/dataGraphTraversal.cxx

@@ -91,9 +91,6 @@ reached_node(Node *node, AllAttributesWrapper &state, NullLevelState &) {
 ////////////////////////////////////////////////////////////////////
 void traverse_data_graph(Node *root) {
   DataGraphVisitor dgv;
-  df_traverse(root, dgv, AllAttributesWrapper(), 
-	      NullLevelState(), RenderRelation::get_class_type());
-
   df_traverse(root, dgv, AllAttributesWrapper(), 
 	      NullLevelState(), DataRelation::get_class_type());
 }

+ 25 - 0
panda/src/tform/driveInterface.cxx

@@ -17,6 +17,10 @@
 #include <modifierButtonDataAttribute.h>
 #include <keyboardButton.h>
 #include <mouseButton.h>
+#include <dataGraphTraversal.h>
+#include <allAttributesWrapper.h>
+#include <dftraverser.h>
+#include <dataRelation.h>
 
 TypeHandle DriveInterface::_type_handle;
 
@@ -577,6 +581,27 @@ get_mat() const {
   return _mat;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: DriveInterface::force_dgraph
+//       Access: Public
+//  Description: This is a special kludge for DriveInterface to allow
+//               us to avoid the one-frame latency after a collision.
+//               It forces an immediate partial data flow for all data
+//               graph nodes below this node, causing all data nodes
+//               that depend on this matrix to be updated immediately.
+////////////////////////////////////////////////////////////////////
+void DriveInterface::
+force_dgraph() {
+  _transform->set_value(_mat);
+  int num_children = get_num_children(DataRelation::get_class_type());
+  for (int i = 0; i < num_children; i++) {
+    DataGraphVisitor dgv;
+    df_traverse(get_child(DataRelation::get_class_type(), i),
+		dgv, AllAttributesWrapper(_attrib), 
+		NullLevelState(), DataRelation::get_class_type());
+  }
+}
+
 
 ////////////////////////////////////////////////////////////////////
 //     Function: DriveInterface::apply

+ 1 - 0
panda/src/tform/driveInterface.h

@@ -85,6 +85,7 @@ PUBLISHED:
   void set_mat(const LMatrix4f &mat);
   const LMatrix4f &get_mat() const;
 
+  void force_dgraph();
 
 private:
   void apply(double x, double y, bool any_button);