浏览代码

*** empty log message ***

David Rose 24 年之前
父节点
当前提交
91cd7c0339

+ 58 - 14
panda/src/char/characterJoint.cxx

@@ -89,27 +89,43 @@ update_internals(PartGroup *parent, bool self_changed, bool) {
     net_changed = true;
     net_changed = true;
   }
   }
 
 
-  if (net_changed) {
+  if (net_changed && !_net_transform_arcs.empty()) {
     PT(TransformTransition) t = new TransformTransition(_net_transform);
     PT(TransformTransition) t = new TransformTransition(_net_transform);
 
 
-    ArcList::const_iterator ai;
-    for (ai = _net_transform_arcs.begin();
-	 ai != _net_transform_arcs.end();
-	 ++ai) {
+    ArcList::iterator ai;
+    ai = _net_transform_arcs.begin();
+    while (ai != _net_transform_arcs.end()) {
       NodeRelation *arc = *ai;
       NodeRelation *arc = *ai;
-      arc->set_transition(t);
+      if (arc->is_attached()) {
+	arc->set_transition(t);
+	++ai;
+      } else {
+	// The arc is now invalid; its geometry must have been
+	// removed.  Remove the arc from our set.
+	ArcList::iterator invalid = ai;
+	++ai;
+	_net_transform_arcs.erase(invalid);
+      }
     }
     }
   }
   }
 
 
-  if (self_changed) {
+  if (self_changed && !_local_transform_arcs.empty()) {
     PT(TransformTransition) t = new TransformTransition(_value);
     PT(TransformTransition) t = new TransformTransition(_value);
 
 
-    ArcList::const_iterator ai;
-    for (ai = _local_transform_arcs.begin();
-	 ai != _local_transform_arcs.end();
-	 ++ai) {
+    ArcList::iterator ai;
+    ai = _local_transform_arcs.begin();
+    while (ai != _local_transform_arcs.end()) {
       NodeRelation *arc = *ai;
       NodeRelation *arc = *ai;
-      arc->set_transition(t);
+      if (arc->is_attached()) {
+	arc->set_transition(t);
+	++ai;
+      } else {
+	// The arc is now invalid; its geometry must have been
+	// removed.  Remove the arc from our set.
+	ArcList::iterator invalid = ai;
+	++ai;
+	_local_transform_arcs.erase(invalid);
+      }
     }
     }
   }
   }
 }
 }
@@ -229,11 +245,39 @@ write_datagram(BamWriter *manager, Datagram &me)
 {
 {
   ArcList::iterator ai;
   ArcList::iterator ai;
 
 
+  // First, make sure all of our arcs are still valid, before we try
+  // to write them out.  Remove any invalid arcs.
+  ai = _net_transform_arcs.begin();
+  while (ai != _net_transform_arcs.end()) {
+    NodeRelation *arc = *ai;
+    if (arc->is_attached()) {
+      ++ai;
+    } else {
+      // The arc is now invalid; its geometry must have been
+      // removed.  Remove the arc from our set.
+      ArcList::iterator invalid = ai;
+      ++ai;
+      _net_transform_arcs.erase(invalid);
+    }
+  }
+  ai = _local_transform_arcs.begin();
+  while (ai != _local_transform_arcs.end()) {
+    NodeRelation *arc = *ai;
+    if (arc->is_attached()) {
+      ++ai;
+    } else {
+      // The arc is now invalid; its geometry must have been
+      // removed.  Remove the arc from our set.
+      ArcList::iterator invalid = ai;
+      ++ai;
+      _local_transform_arcs.erase(invalid);
+    }
+  }
+
   MovingPartMatrix::write_datagram(manager, me);
   MovingPartMatrix::write_datagram(manager, me);
   me.add_uint16(_net_transform_arcs.size());
   me.add_uint16(_net_transform_arcs.size());
 
 
-  for(ai = _net_transform_arcs.begin(); ai != _net_transform_arcs.end(); ai++)
-  {
+  for(ai = _net_transform_arcs.begin(); ai != _net_transform_arcs.end(); ai++) {
     manager->write_pointer(me, (*ai));
     manager->write_pointer(me, (*ai));
   }
   }
 
 

+ 43 - 47
panda/src/glgsg/glGraphicsStateGuardian.cxx

@@ -491,31 +491,27 @@ render_frame(const AllAttributesWrapper &initial_state) {
     if (_win->is_channel_defined(c)) {
     if (_win->is_channel_defined(c)) {
       GraphicsChannel *chan = _win->get_channel(c);
       GraphicsChannel *chan = _win->get_channel(c);
       if (chan->is_active()) {
       if (chan->is_active()) {
-    int num_layers = chan->get_num_layers();
-    for (int l = 0; l < num_layers; l++) {
-      GraphicsLayer *layer = chan->get_layer(l);
-      if (layer->is_active()) {
-        int num_drs = layer->get_num_drs();
-        for (int d = 0; d < num_drs; d++) {
-          DisplayRegion *dr = layer->get_dr(d);
-          if (dr == (DisplayRegion*)NULL)
-          {
-        cerr << "null camera layer " << endl;
-        exit(0);
-          }
-          Camera *cam = dr->get_camera();
-        
-          // For each display region, render from the camera's view.
-          if (dr->is_active() && cam != (Camera *)NULL && 
-          cam->is_active() && cam->get_scene() != (Node *)NULL) {
-        DisplayRegionStack old_dr = push_display_region(dr);
-        prepare_display_region();
-        render_scene(cam->get_scene(), cam, initial_state);
-        pop_display_region(old_dr);
-          }
-        }
-      }
-    }
+	int num_layers = chan->get_num_layers();
+	for (int l = 0; l < num_layers; l++) {
+	  GraphicsLayer *layer = chan->get_layer(l);
+	  if (layer->is_active()) {
+	    int num_drs = layer->get_num_drs();
+	    for (int d = 0; d < num_drs; d++) {
+	      DisplayRegion *dr = layer->get_dr(d);
+	      nassertv(dr != (DisplayRegion *)NULL);
+	      Camera *cam = dr->get_camera();
+	      
+	      // For each display region, render from the camera's view.
+	      if (dr->is_active() && cam != (Camera *)NULL && 
+		  cam->is_active() && cam->get_scene() != (Node *)NULL) {
+		DisplayRegionStack old_dr = push_display_region(dr);
+		prepare_display_region();
+		render_scene(cam->get_scene(), cam, initial_state);
+		pop_display_region(old_dr);
+	      }
+	    }
+	  }
+	}
       }
       }
     }
     }
   }
   }
@@ -523,28 +519,28 @@ render_frame(const AllAttributesWrapper &initial_state) {
   // Now we're done with the frame processing.  Clean up.
   // Now we're done with the frame processing.  Clean up.
 
 
   if(_lighting_enabled) {
   if(_lighting_enabled) {
-	  // Let's turn off all the lights we had on, and clear the light
-	  // cache--to force the lights to be reissued next frame, in case
-	  // their parameters or positions have changed between frames.
-
-	  for (int i = 0; i < _max_lights; i++) {
-		if (_light_enabled[i]) {
-		  enable_light(i, false);
-		}
-		_available_light_ids[i] = NULL;
-	  }
-
-	  // Also force the lighting state to unlit, so that issue_light()
-	  // will be guaranteed to be called next frame even if we have the
-	  // same set of light pointers we had this frame.
-	  NodeAttributes state;
-	  state.set_attribute(LightTransition::get_class_type(), new LightAttribute);
-	  set_state(state, false);
-
-	  // All this work to undo the lighting state each frame doesn't seem
-	  // ideal--there may be a better way.  Maybe if the lights were just
-	  // more aware of whether their parameters or positions have changed
-	  // at all?
+    // Let's turn off all the lights we had on, and clear the light
+    // cache--to force the lights to be reissued next frame, in case
+    // their parameters or positions have changed between frames.
+    
+    for (int i = 0; i < _max_lights; i++) {
+      if (_light_enabled[i]) {
+	enable_light(i, false);
+      }
+      _available_light_ids[i] = NULL;
+    }
+    
+    // Also force the lighting state to unlit, so that issue_light()
+    // will be guaranteed to be called next frame even if we have the
+    // same set of light pointers we had this frame.
+    NodeAttributes state;
+    state.set_attribute(LightTransition::get_class_type(), new LightAttribute);
+    set_state(state, false);
+    
+    // All this work to undo the lighting state each frame doesn't seem
+    // ideal--there may be a better way.  Maybe if the lights were just
+    // more aware of whether their parameters or positions have changed
+    // at all?
   }
   }
 
 
 #ifndef NDEBUG
 #ifndef NDEBUG

+ 15 - 0
panda/src/graph/nodeRelation.I

@@ -81,6 +81,21 @@ get_graph_type() const {
   return _graph_type;
   return _graph_type;
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: NodeRelation::is_attached
+//       Access: Public
+//  Description: Returns true if this arc is attached to the scene
+//               graph, false otherwise.  Normally, an arc should
+//               always be attached; generally you will only see an
+//               unattached arc if the arc (or some parent of the arc)
+//               has been disconnected from all nodes via
+//               remove_arc().
+////////////////////////////////////////////////////////////////////
+INLINE_GRAPH bool NodeRelation::
+is_attached() const {
+  return _attached;
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: NodeRelation::change_parent
 //     Function: NodeRelation::change_parent
 //       Access: Public
 //       Access: Public

+ 2 - 0
panda/src/graph/nodeRelation.h

@@ -80,6 +80,8 @@ PUBLISHED:
   INLINE_GRAPH int get_sort() const;
   INLINE_GRAPH int get_sort() const;
   INLINE_GRAPH TypeHandle get_graph_type() const;
   INLINE_GRAPH TypeHandle get_graph_type() const;
 
 
+  INLINE_GRAPH bool is_attached() const;
+
   void ref_parent();
   void ref_parent();
   void unref_parent();
   void unref_parent();