mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 02:42:49 -04:00
automatically elevate geom indices to 32 bit if necessary
This commit is contained in:
parent
b600ff2aa5
commit
061e9c78f1
@ -142,32 +142,23 @@ set_usage_hint(GeomPrimitive::UsageHint usage_hint) {
|
||||
// Normally, this should be either NT_uint16 or
|
||||
// NT_uint32.
|
||||
//
|
||||
// The index type must be large enough to include all of
|
||||
// the index values in the primitive. It may be
|
||||
// automatically elevated, if necessary, to a larger
|
||||
// index type, by a subsequent call to add_index() that
|
||||
// names an index value that does not fit in the index
|
||||
// type you specify.
|
||||
//
|
||||
// Don't call this in a downstream thread unless you
|
||||
// don't mind it blowing away other changes you might
|
||||
// have recently made in an upstream thread.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GeomPrimitive::
|
||||
set_index_type(GeomPrimitive::NumericType index_type) {
|
||||
nassertv(get_max_vertex() <= get_highest_index_value(index_type));
|
||||
|
||||
CDWriter cdata(_cycler, true);
|
||||
cdata->_index_type = index_type;
|
||||
|
||||
if (cdata->_vertices != (GeomVertexArrayData *)NULL) {
|
||||
CPT(GeomVertexArrayFormat) new_format = get_index_format();
|
||||
|
||||
if (cdata->_vertices->get_array_format() != new_format) {
|
||||
PT(GeomVertexArrayData) new_vertices = make_index_data();
|
||||
new_vertices->set_num_rows(cdata->_vertices->get_num_rows());
|
||||
|
||||
GeomVertexReader from(cdata->_vertices, 0);
|
||||
GeomVertexWriter to(new_vertices, 0);
|
||||
|
||||
while (!from.is_at_end()) {
|
||||
to.set_data1i(from.get_data1i());
|
||||
}
|
||||
cdata->_vertices = new_vertices;
|
||||
cdata->_got_minmax = false;
|
||||
}
|
||||
}
|
||||
do_set_index_type(cdata, index_type);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -188,6 +179,8 @@ void GeomPrimitive::
|
||||
add_vertex(int vertex) {
|
||||
CDWriter cdata(_cycler, true);
|
||||
|
||||
consider_elevate_index_type(cdata, vertex);
|
||||
|
||||
int num_primitives = get_num_primitives();
|
||||
if (num_primitives > 0 &&
|
||||
requires_unused_vertices() &&
|
||||
@ -249,6 +242,8 @@ add_consecutive_vertices(int start, int num_vertices) {
|
||||
|
||||
CDWriter cdata(_cycler, true);
|
||||
|
||||
consider_elevate_index_type(cdata, end);
|
||||
|
||||
int num_primitives = get_num_primitives();
|
||||
if (num_primitives > 0 &&
|
||||
get_num_vertices() == get_primitive_end(num_primitives - 1)) {
|
||||
@ -382,6 +377,12 @@ clear_vertices() {
|
||||
CDWriter cdata(_cycler, true);
|
||||
cdata->_first_vertex = 0;
|
||||
cdata->_num_vertices = 0;
|
||||
|
||||
// Since we might have automatically elevated the index type by
|
||||
// adding vertices, we should automatically lower it again when we
|
||||
// call clear_vertices().
|
||||
cdata->_index_type = NT_uint16;
|
||||
|
||||
cdata->_vertices.clear();
|
||||
cdata->_ends.clear();
|
||||
cdata->_mins.clear();
|
||||
@ -403,6 +404,11 @@ clear_vertices() {
|
||||
void GeomPrimitive::
|
||||
offset_vertices(int offset) {
|
||||
if (is_indexed()) {
|
||||
{
|
||||
CDWriter cdata(_cycler, true);
|
||||
consider_elevate_index_type(cdata, get_max_vertex() + offset);
|
||||
}
|
||||
|
||||
GeomVertexRewriter index(modify_vertices(), 0);
|
||||
while (!index.is_at_end()) {
|
||||
index.set_data1i(index.get_data1i() + offset);
|
||||
@ -410,9 +416,13 @@ offset_vertices(int offset) {
|
||||
|
||||
} else {
|
||||
CDWriter cdata(_cycler, true);
|
||||
|
||||
cdata->_first_vertex += offset;
|
||||
cdata->_modified = Geom::get_next_modified();
|
||||
cdata->_got_minmax = false;
|
||||
|
||||
consider_elevate_index_type(cdata,
|
||||
cdata->_first_vertex + cdata->_num_vertices - 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1111,6 +1121,31 @@ clear_prepared(PreparedGraphicsObjects *prepared_objects) {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitive::get_highest_index_value
|
||||
// Access: Private, Static
|
||||
// Description: Returns the largest index value that can be stored in
|
||||
// an index of the indicated type.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int GeomPrimitive::
|
||||
get_highest_index_value(NumericType index_type) {
|
||||
switch (index_type) {
|
||||
case NT_uint8:
|
||||
return 0xff;
|
||||
|
||||
case NT_uint16:
|
||||
return 0xffff;
|
||||
|
||||
case NT_uint32:
|
||||
// We don't actually allow use of the sign bit, since all of our
|
||||
// functions receive an "int" instead of an "unsigned int".
|
||||
return 0x7fffffff;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitive::calc_tight_bounds
|
||||
// Access: Public, Virtual
|
||||
@ -1382,6 +1417,66 @@ do_make_indexed(CData *cdata) {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitive::consider_elevate_index_type
|
||||
// Access: Private
|
||||
// Description: If the indicated new vertex index won't fit in the
|
||||
// specified index type, automatically elevates the
|
||||
// index type to the next available size.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GeomPrimitive::
|
||||
consider_elevate_index_type(CData *cdata, int vertex) {
|
||||
switch (cdata->_index_type) {
|
||||
case NT_uint8:
|
||||
if (vertex > 0xff) {
|
||||
do_set_index_type(cdata, NT_uint16);
|
||||
}
|
||||
break;
|
||||
|
||||
case NT_uint16:
|
||||
if (vertex > 0xffff) {
|
||||
do_set_index_type(cdata, NT_uint32);
|
||||
}
|
||||
break;
|
||||
|
||||
case NT_uint32:
|
||||
// Not much we can do here.
|
||||
nassertv(vertex <= 0x7fffffff);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitive::do_set_index_type
|
||||
// Access: Private
|
||||
// Description: The private implementation of set_index_type().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GeomPrimitive::
|
||||
do_set_index_type(CData *cdata, GeomPrimitive::NumericType index_type) {
|
||||
cdata->_index_type = index_type;
|
||||
|
||||
if (cdata->_vertices != (GeomVertexArrayData *)NULL) {
|
||||
CPT(GeomVertexArrayFormat) new_format = get_index_format();
|
||||
|
||||
if (cdata->_vertices->get_array_format() != new_format) {
|
||||
PT(GeomVertexArrayData) new_vertices = make_index_data();
|
||||
new_vertices->set_num_rows(cdata->_vertices->get_num_rows());
|
||||
|
||||
GeomVertexReader from(cdata->_vertices, 0);
|
||||
GeomVertexWriter to(new_vertices, 0);
|
||||
|
||||
while (!from.is_at_end()) {
|
||||
to.set_data1i(from.get_data1i());
|
||||
}
|
||||
cdata->_vertices = new_vertices;
|
||||
cdata->_got_minmax = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitive::write_datagram
|
||||
// Access: Public, Virtual
|
||||
|
@ -184,6 +184,7 @@ protected:
|
||||
|
||||
private:
|
||||
void clear_prepared(PreparedGraphicsObjects *prepared_objects);
|
||||
static int get_highest_index_value(NumericType index_type);
|
||||
|
||||
public:
|
||||
virtual void draw(GraphicsStateGuardianBase *gsg,
|
||||
@ -207,6 +208,8 @@ private:
|
||||
|
||||
void recompute_minmax(CData *cdata);
|
||||
void do_make_indexed(CData *cdata);
|
||||
void consider_elevate_index_type(CData *cdata, int vertex);
|
||||
void do_set_index_type(CData *cdata, NumericType index_type);
|
||||
|
||||
private:
|
||||
// A GeomPrimitive keeps a list (actually, a map) of all the
|
||||
|
Loading…
x
Reference in New Issue
Block a user