diff --git a/panda/src/gobj/geomVertexArrayData.I b/panda/src/gobj/geomVertexArrayData.I index a0acbbf39f..a10a8e285b 100644 --- a/panda/src/gobj/geomVertexArrayData.I +++ b/panda/src/gobj/geomVertexArrayData.I @@ -445,6 +445,7 @@ get_usage_hint() const { //////////////////////////////////////////////////////////////////// INLINE int GeomVertexArrayDataHandle:: get_num_rows() const { + nassertr(_object->_array_format->get_stride() != 0, 0); return get_data_size_bytes() / _object->_array_format->get_stride(); } diff --git a/panda/src/gobj/geomVertexFormat.cxx b/panda/src/gobj/geomVertexFormat.cxx index 9562a59b74..610f06c70d 100644 --- a/panda/src/gobj/geomVertexFormat.cxx +++ b/panda/src/gobj/geomVertexFormat.cxx @@ -375,6 +375,29 @@ clear_arrays() { _arrays.clear(); } +//////////////////////////////////////////////////////////////////// +// Function: GeomVertexFormat::remove_empty_arrays +// Access: Published +// Description: Removes the arrays that define no columns. +// +// This may not be called once the format has been +// registered. +//////////////////////////////////////////////////////////////////// +void GeomVertexFormat:: +remove_empty_arrays() { + nassertv(!is_registered()); + + Arrays orig_arrays; + orig_arrays.swap(_arrays); + Arrays::const_iterator ai; + for (ai = orig_arrays.begin(); ai != orig_arrays.end(); ++ai) { + GeomVertexArrayFormat *array_format = (*ai); + if (array_format->get_num_columns() != 0) { + _arrays.push_back(array_format); + } + } +} + //////////////////////////////////////////////////////////////////// // Function: GeomVertexFormat::get_num_columns // Access: Published @@ -510,13 +533,13 @@ get_column(const InternalName *name) const { // columns remaining in the array, the array is left // with a gap where the column used to be; if this // was the only column in the array, the array is -// removed. +// removed (unless keep_empty_array is true). // // This may not be called once the format has been // registered. //////////////////////////////////////////////////////////////////// void GeomVertexFormat:: -remove_column(const InternalName *name) { +remove_column(const InternalName *name, bool keep_empty_array) { nassertv(!_is_registered); // Since the format's not registered, it doesn't yet have an index @@ -537,7 +560,7 @@ remove_column(const InternalName *name) { array_format->remove_column(name); // Are there any columns remaining in the array? - if (array_format->get_num_columns() == 0) { + if (!keep_empty_array && array_format->get_num_columns() == 0) { // Remove the whole array. remove_array(array); } @@ -756,8 +779,12 @@ do_register() { if (!array_format->is_registered()) { array_format = GeomVertexArrayFormat::register_format(array_format); } - if (array_format->get_num_columns() == 0) { - // Don't keep an empty array. + + // Let's keep arrays with nonzero stride but no used columns; + // they're needed to preserve the isomorphic nature of matching + // formats. But we'll toss arrays with 0 stride, which add + // nothing of value and only cause problems later. + if (array_format->get_stride() == 0) { gobj_cat.warning() << "Dropping empty array from GeomVertexFormat.\n"; continue; diff --git a/panda/src/gobj/geomVertexFormat.h b/panda/src/gobj/geomVertexFormat.h index 10e4cf992c..aad2ae68a3 100644 --- a/panda/src/gobj/geomVertexFormat.h +++ b/panda/src/gobj/geomVertexFormat.h @@ -87,6 +87,7 @@ PUBLISHED: int add_array(const GeomVertexArrayFormat *array_format); void insert_array(int array, const GeomVertexArrayFormat *array_format); void clear_arrays(); + void remove_empty_arrays(); int get_num_columns() const; int get_array_with(int i) const; @@ -98,7 +99,7 @@ PUBLISHED: MAKE_SEQ(get_columns, get_num_columns, get_column); - void remove_column(const InternalName *name); + void remove_column(const InternalName *name, bool keep_empty_array = false); void pack_columns(); void align_columns_for_animation(); void maybe_align_columns_for_animation();