Browse Source

fix flatten crash

David Rose 17 years ago
parent
commit
e31be8e3f0
2 changed files with 42 additions and 36 deletions
  1. 19 13
      panda/src/pgraph/geomNode.cxx
  2. 23 23
      panda/src/pgraph/geomTransformer.cxx

+ 19 - 13
panda/src/pgraph/geomNode.cxx

@@ -124,11 +124,11 @@ apply_attribs_to_vertices(const AccumulatedAttribs &attribs, int attrib_types,
     // nodes during the traversal.
     size_t num_geoms = geoms->size();
     for (size_t i = 0; i < num_geoms; ++i) {
-      GeomEntry &entry = (*geoms)[i];
-      PT(Geom) new_geom = entry._geom.get_read_pointer()->make_copy();
+      GeomEntry *entry = &(*geoms)[i];
+      PT(Geom) new_geom = entry->_geom.get_read_pointer()->make_copy();
 
       AccumulatedAttribs geom_attribs = attribs;
-      entry._state = geom_attribs.collect(entry._state, attrib_types);
+      entry->_state = geom_attribs.collect(entry->_state, attrib_types);
       
       bool any_changed = false;
 
@@ -142,9 +142,9 @@ apply_attribs_to_vertices(const AccumulatedAttribs &attribs, int attrib_types,
           ra = ColorAttrib::make_off();
           override = -1;
         }
-        entry._state = entry._state->add_attrib(ra, override);
+        entry->_state = entry->_state->add_attrib(ra, override);
 
-        ra = entry._state->get_attrib(ColorAttrib::get_class_slot());
+        ra = entry->_state->get_attrib(ColorAttrib::get_class_slot());
         const ColorAttrib *ca = DCAST(ColorAttrib, ra);
         if (ca->get_color_type() != ColorAttrib::T_vertex) {
           if (transformer.remove_column(new_geom, InternalName::get_color())) {
@@ -160,14 +160,14 @@ apply_attribs_to_vertices(const AccumulatedAttribs &attribs, int attrib_types,
             // Now, if we have an "off" or "flat" color attribute, we
             // simply modify the color attribute, and leave the
             // vertices alone.
-            const RenderAttrib *ra = entry._state->get_attrib(ColorAttrib::get_class_slot());
+            const RenderAttrib *ra = entry->_state->get_attrib(ColorAttrib::get_class_slot());
             if (ra != (const RenderAttrib *)NULL) {
               const ColorAttrib *ca = DCAST(ColorAttrib, ra);
               if (ca->get_color_type() == ColorAttrib::T_off) {
-                entry._state = entry._state->set_attrib(ColorAttrib::make_vertex());
+                entry->_state = entry->_state->set_attrib(ColorAttrib::make_vertex());
                 // ColorAttrib::T_off means the color scale becomes
                 // the new color.
-                entry._state = entry._state->set_attrib(ColorAttrib::make_flat(csa->get_scale()));
+                entry->_state = entry->_state->set_attrib(ColorAttrib::make_flat(csa->get_scale()));
 
               } else if (ca->get_color_type() == ColorAttrib::T_flat) {
                 // ColorAttrib::T_flat means the color scale modulates
@@ -176,7 +176,7 @@ apply_attribs_to_vertices(const AccumulatedAttribs &attribs, int attrib_types,
                 const LVecBase4f &c2 = csa->get_scale();
                 Colorf color(c1[0] * c2[0], c1[1] * c2[1], 
                              c1[2] * c2[2], c1[3] * c2[3]);
-                entry._state = entry._state->set_attrib(ColorAttrib::make_flat(color));
+                entry->_state = entry->_state->set_attrib(ColorAttrib::make_flat(color));
 
               } else {
                 // Otherwise, we have vertex color, and we just scale
@@ -234,13 +234,13 @@ apply_attribs_to_vertices(const AccumulatedAttribs &attribs, int attrib_types,
           }
           
           if (!new_tma->is_empty()) {
-            entry._state = entry._state->add_attrib(new_tma);
+            entry->_state = entry->_state->add_attrib(new_tma);
           }
         }
       }
 
       if ((attrib_types & SceneGraphReducer::TT_other) != 0) {
-        entry._state = geom_attribs._other->compose(entry._state);
+        entry->_state = geom_attribs._other->compose(entry->_state);
       }
 
       // We handle cull_face last, since that might involve
@@ -261,7 +261,13 @@ apply_attribs_to_vertices(const AccumulatedAttribs &attribs, int attrib_types,
                 // it to reverse the normals on the duplicate copy.
                 PT(Geom) dup_geom = new_geom->reverse();
                 transformer.reverse_normals(dup_geom);
-                geoms->push_back(GeomEntry(dup_geom, entry._state));
+
+                geoms->push_back(GeomEntry(dup_geom, entry->_state));
+
+                // The above push_back() operation might have
+                // invalidated our old pointer into the list, so we
+                // reassign it now.
+                entry = &(*geoms)[i];
                 
               } else {
                 // If there are no normals, we can just doubleside it in
@@ -286,7 +292,7 @@ apply_attribs_to_vertices(const AccumulatedAttribs &attribs, int attrib_types,
       }
 
       if (any_changed) {
-        entry._geom = new_geom;
+        entry->_geom = new_geom;
       }
     }
   }

+ 23 - 23
panda/src/pgraph/geomTransformer.cxx

@@ -101,8 +101,8 @@ register_vertices(GeomNode *node, bool might_have_unused) {
   OPEN_ITERATE_CURRENT_AND_UPSTREAM(node->_cycler, current_thread) {
     GeomNode::CDStageWriter cdata(node->_cycler, pipeline_stage, current_thread);
     GeomNode::GeomList::iterator gi;
-    GeomNode::GeomList &geoms = *(cdata->modify_geoms());
-    for (gi = geoms.begin(); gi != geoms.end(); ++gi) {
+    PT(GeomNode::GeomList) geoms = cdata->modify_geoms();
+    for (gi = geoms->begin(); gi != geoms->end(); ++gi) {
       GeomNode::GeomEntry &entry = (*gi);
       PT(Geom) geom = entry._geom.get_write_pointer();
       register_vertices(geom, might_have_unused);
@@ -182,8 +182,8 @@ transform_vertices(GeomNode *node, const LMatrix4f &mat) {
   OPEN_ITERATE_CURRENT_AND_UPSTREAM(node->_cycler, current_thread) {
     GeomNode::CDStageWriter cdata(node->_cycler, pipeline_stage, current_thread);
     GeomNode::GeomList::iterator gi;
-    GeomNode::GeomList &geoms = *(cdata->modify_geoms());
-    for (gi = geoms.begin(); gi != geoms.end(); ++gi) {
+    PT(GeomNode::GeomList) geoms = cdata->modify_geoms();
+    for (gi = geoms->begin(); gi != geoms->end(); ++gi) {
       GeomNode::GeomEntry &entry = (*gi);
       PT(Geom) new_geom = entry._geom.get_read_pointer()->make_copy();
       if (transform_vertices(new_geom, mat)) {
@@ -284,8 +284,8 @@ transform_texcoords(GeomNode *node, const InternalName *from_name,
 
   GeomNode::CDWriter cdata(node->_cycler);
   GeomNode::GeomList::iterator gi;
-  GeomNode::GeomList &geoms = *(cdata->modify_geoms());
-  for (gi = geoms.begin(); gi != geoms.end(); ++gi) {
+  PT(GeomNode::GeomList) geoms = cdata->modify_geoms();
+  for (gi = geoms->begin(); gi != geoms->end(); ++gi) {
     GeomNode::GeomEntry &entry = (*gi);
     PT(Geom) new_geom = entry._geom.get_read_pointer()->make_copy();
     if (transform_texcoords(new_geom, from_name, to_name, mat)) {
@@ -349,8 +349,8 @@ set_color(GeomNode *node, const Colorf &color) {
 
   GeomNode::CDWriter cdata(node->_cycler);
   GeomNode::GeomList::iterator gi;
-  GeomNode::GeomList &geoms = *(cdata->modify_geoms());
-  for (gi = geoms.begin(); gi != geoms.end(); ++gi) {
+  PT(GeomNode::GeomList) geoms = cdata->modify_geoms();
+  for (gi = geoms->begin(); gi != geoms->end(); ++gi) {
     GeomNode::GeomEntry &entry = (*gi);
     PT(Geom) new_geom = entry._geom.get_read_pointer()->make_copy();
     if (set_color(new_geom, color)) {
@@ -417,8 +417,8 @@ transform_colors(GeomNode *node, const LVecBase4f &scale) {
 
   GeomNode::CDWriter cdata(node->_cycler);
   GeomNode::GeomList::iterator gi;
-  GeomNode::GeomList &geoms = *(cdata->modify_geoms());
-  for (gi = geoms.begin(); gi != geoms.end(); ++gi) {
+  PT(GeomNode::GeomList) geoms = cdata->modify_geoms();
+  for (gi = geoms->begin(); gi != geoms->end(); ++gi) {
     GeomNode::GeomEntry &entry = (*gi);
     PT(Geom) new_geom = entry._geom.get_read_pointer()->make_copy();
     if (transform_colors(new_geom, scale)) {
@@ -648,8 +648,8 @@ apply_texture_colors(GeomNode *node, const RenderState *state) {
 
   GeomNode::CDWriter cdata(node->_cycler);
   GeomNode::GeomList::iterator gi;
-  GeomNode::GeomList &geoms = *(cdata->modify_geoms());
-  for (gi = geoms.begin(); gi != geoms.end(); ++gi) {
+  PT(GeomNode::GeomList) geoms = cdata->modify_geoms();
+  for (gi = geoms->begin(); gi != geoms->end(); ++gi) {
     GeomNode::GeomEntry &entry = (*gi);
     CPT(RenderState) geom_state = state->compose(entry._state);
 
@@ -710,8 +710,8 @@ apply_state(GeomNode *node, const RenderState *state) {
 
   GeomNode::CDWriter cdata(node->_cycler);
   GeomNode::GeomList::iterator gi;
-  GeomNode::GeomList &geoms = *(cdata->modify_geoms());
-  for (gi = geoms.begin(); gi != geoms.end(); ++gi) {
+  PT(GeomNode::GeomList) geoms = cdata->modify_geoms();
+  for (gi = geoms->begin(); gi != geoms->end(); ++gi) {
     GeomNode::GeomEntry &entry = (*gi);
     CPT(RenderState) new_state = state->compose(entry._state);
     if (entry._state != new_state) {
@@ -798,8 +798,8 @@ remove_column(GeomNode *node, const InternalName *column) {
 
   GeomNode::CDWriter cdata(node->_cycler);
   GeomNode::GeomList::iterator gi;
-  GeomNode::GeomList &geoms = *(cdata->modify_geoms());
-  for (gi = geoms.begin(); gi != geoms.end(); ++gi) {
+  PT(GeomNode::GeomList) geoms = cdata->modify_geoms();
+  for (gi = geoms->begin(); gi != geoms->end(); ++gi) {
     GeomNode::GeomEntry &entry = (*gi);
     PT(Geom) new_geom = entry._geom.get_read_pointer()->make_copy();
     if (remove_column(new_geom, column)) {
@@ -848,7 +848,7 @@ make_compatible_state(GeomNode *node) {
   
   GeomNode::CDWriter cdata(node->_cycler);
   GeomNode::GeomList::iterator gi;
-  GeomNode::GeomList &geoms = *(cdata->modify_geoms());
+  PT(GeomNode::GeomList) geoms = cdata->modify_geoms();
 
   // For each geom, calculate a canonicalized RenderState, and 
   // classify all the geoms according to that.
@@ -856,8 +856,8 @@ make_compatible_state(GeomNode *node) {
   typedef pmap <CPT(RenderState), pvector<int> > StateTable;
   StateTable state_table;
   
-  for (int i = 0; i < (int)geoms.size(); i++) {
-    GeomNode::GeomEntry &entry = geoms[i];
+  for (int i = 0; i < (int)geoms->size(); i++) {
+    GeomNode::GeomEntry &entry = (*geoms)[i];
     CPT(RenderState) canon = entry._state->add_attrib(ColorAttrib::make_vertex(), -1);
     state_table[canon].push_back(i);
   }
@@ -874,7 +874,7 @@ make_compatible_state(GeomNode *node) {
     pvector<int> &indices = (*si).second;
     bool mismatch = false;
     for (int i = 1; i < (int)indices.size(); i++) {
-      if (geoms[indices[i]]._state != geoms[indices[0]]._state) {
+      if ((*geoms)[indices[i]]._state != (*geoms)[indices[0]]._state) {
         mismatch = true;
         break;
       }
@@ -888,7 +888,7 @@ make_compatible_state(GeomNode *node) {
     
     const RenderState *canon_state = (*si).first;
     for (int i = 0; i < (int)indices.size(); i++) {
-      GeomNode::GeomEntry &entry = geoms[indices[i]];
+      GeomNode::GeomEntry &entry = (*geoms)[indices[i]];
       const RenderAttrib *ra = entry._state->get_attrib(ColorAttrib::get_class_slot());
       if (ra == (RenderAttrib *)NULL) {
         ra = ColorAttrib::make_off();
@@ -1190,8 +1190,8 @@ collect_vertex_data(GeomNode *node, int collect_bits, bool format_only) {
 
   GeomNode::CDWriter cdata(node->_cycler);
   GeomNode::GeomList::iterator gi;
-  GeomNode::GeomList &geoms = *(cdata->modify_geoms());
-  for (gi = geoms.begin(); gi != geoms.end(); ++gi) {
+  PT(GeomNode::GeomList) geoms = cdata->modify_geoms();
+  for (gi = geoms->begin(); gi != geoms->end(); ++gi) {
     GeomNode::GeomEntry &entry = (*gi);
     PT(Geom) new_geom = entry._geom.get_read_pointer()->make_copy();
     entry._geom = new_geom;