From e31be8e3f003f09ca31e5b9524f1c52cbbeb3d22 Mon Sep 17 00:00:00 2001 From: David Rose Date: Wed, 10 Dec 2008 21:17:00 +0000 Subject: [PATCH] fix flatten crash --- panda/src/pgraph/geomNode.cxx | 32 +++++++++++-------- panda/src/pgraph/geomTransformer.cxx | 46 ++++++++++++++-------------- 2 files changed, 42 insertions(+), 36 deletions(-) diff --git a/panda/src/pgraph/geomNode.cxx b/panda/src/pgraph/geomNode.cxx index 7166efc117..c70982baef 100644 --- a/panda/src/pgraph/geomNode.cxx +++ b/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; } } } diff --git a/panda/src/pgraph/geomTransformer.cxx b/panda/src/pgraph/geomTransformer.cxx index bc07c95b6c..19618ef125 100644 --- a/panda/src/pgraph/geomTransformer.cxx +++ b/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 > 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 &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;