gobj: Fix GeomPrimitive::offset_vertices() with strip cut index

This was called, among other things, by the egg-unify process, which could ruin the strip cut index.

At the same time, I've reimplemented the indexed case for offset_vertices() to make it a little bit more efficient.

Fixes #1122
This commit is contained in:
rdb 2021-03-22 11:35:03 +01:00
parent fe29aab568
commit 40b94c1f97

View File

@ -442,18 +442,50 @@ offset_vertices(int offset) {
consider_elevate_index_type(cdata, cdata->_max_vertex + offset); consider_elevate_index_type(cdata, cdata->_max_vertex + offset);
int strip_cut_index = get_strip_cut_index(cdata->_index_type); {
GeomVertexArrayDataHandle handle(cdata->_vertices.get_write_pointer(),
Thread::get_current_thread());
GeomVertexRewriter index(do_modify_vertices(cdata), 0); size_t num_rows = (size_t)handle.get_num_rows();
while (!index.is_at_end()) { unsigned char *ptr = handle.get_write_pointer();
int vertex = index.get_data1i(); switch (cdata->_index_type) {
case GeomEnums::NT_uint8:
for (size_t i = 0; i < num_rows; ++i) {
uint8_t &v = ((uint8_t *)ptr)[i];
if (v != 0xff) {
v += offset;
}
}
break;
if (vertex != strip_cut_index) { case GeomEnums::NT_uint16:
index.set_data1i(vertex + offset); for (size_t i = 0; i < num_rows; ++i) {
uint16_t &v = ((uint16_t *)ptr)[i];
if (v != 0xffff) {
v += offset;
}
}
break;
case GeomEnums::NT_uint32:
for (size_t i = 0; i < num_rows; ++i) {
uint32_t &v = ((uint32_t *)ptr)[i];
if (v != 0xffffffff) {
v += offset;
}
}
break;
default:
nassert_raise("unsupported index type");
break;
} }
} }
} else { cdata->_modified = Geom::get_next_modified();
cdata->_got_minmax = false;
}
else {
CDWriter cdata(_cycler, true); CDWriter cdata(_cycler, true);
cdata->_first_vertex += offset; cdata->_first_vertex += offset;