mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 10:54:24 -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
|
// Normally, this should be either NT_uint16 or
|
||||||
// NT_uint32.
|
// 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 call this in a downstream thread unless you
|
||||||
// don't mind it blowing away other changes you might
|
// don't mind it blowing away other changes you might
|
||||||
// have recently made in an upstream thread.
|
// have recently made in an upstream thread.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void GeomPrimitive::
|
void GeomPrimitive::
|
||||||
set_index_type(GeomPrimitive::NumericType index_type) {
|
set_index_type(GeomPrimitive::NumericType index_type) {
|
||||||
|
nassertv(get_max_vertex() <= get_highest_index_value(index_type));
|
||||||
|
|
||||||
CDWriter cdata(_cycler, true);
|
CDWriter cdata(_cycler, true);
|
||||||
cdata->_index_type = index_type;
|
do_set_index_type(cdata, 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -188,6 +179,8 @@ void GeomPrimitive::
|
|||||||
add_vertex(int vertex) {
|
add_vertex(int vertex) {
|
||||||
CDWriter cdata(_cycler, true);
|
CDWriter cdata(_cycler, true);
|
||||||
|
|
||||||
|
consider_elevate_index_type(cdata, vertex);
|
||||||
|
|
||||||
int num_primitives = get_num_primitives();
|
int num_primitives = get_num_primitives();
|
||||||
if (num_primitives > 0 &&
|
if (num_primitives > 0 &&
|
||||||
requires_unused_vertices() &&
|
requires_unused_vertices() &&
|
||||||
@ -249,6 +242,8 @@ add_consecutive_vertices(int start, int num_vertices) {
|
|||||||
|
|
||||||
CDWriter cdata(_cycler, true);
|
CDWriter cdata(_cycler, true);
|
||||||
|
|
||||||
|
consider_elevate_index_type(cdata, end);
|
||||||
|
|
||||||
int num_primitives = get_num_primitives();
|
int num_primitives = get_num_primitives();
|
||||||
if (num_primitives > 0 &&
|
if (num_primitives > 0 &&
|
||||||
get_num_vertices() == get_primitive_end(num_primitives - 1)) {
|
get_num_vertices() == get_primitive_end(num_primitives - 1)) {
|
||||||
@ -382,6 +377,12 @@ clear_vertices() {
|
|||||||
CDWriter cdata(_cycler, true);
|
CDWriter cdata(_cycler, true);
|
||||||
cdata->_first_vertex = 0;
|
cdata->_first_vertex = 0;
|
||||||
cdata->_num_vertices = 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->_vertices.clear();
|
||||||
cdata->_ends.clear();
|
cdata->_ends.clear();
|
||||||
cdata->_mins.clear();
|
cdata->_mins.clear();
|
||||||
@ -403,6 +404,11 @@ clear_vertices() {
|
|||||||
void GeomPrimitive::
|
void GeomPrimitive::
|
||||||
offset_vertices(int offset) {
|
offset_vertices(int offset) {
|
||||||
if (is_indexed()) {
|
if (is_indexed()) {
|
||||||
|
{
|
||||||
|
CDWriter cdata(_cycler, true);
|
||||||
|
consider_elevate_index_type(cdata, get_max_vertex() + offset);
|
||||||
|
}
|
||||||
|
|
||||||
GeomVertexRewriter index(modify_vertices(), 0);
|
GeomVertexRewriter index(modify_vertices(), 0);
|
||||||
while (!index.is_at_end()) {
|
while (!index.is_at_end()) {
|
||||||
index.set_data1i(index.get_data1i() + offset);
|
index.set_data1i(index.get_data1i() + offset);
|
||||||
@ -410,9 +416,13 @@ offset_vertices(int offset) {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
CDWriter cdata(_cycler, true);
|
CDWriter cdata(_cycler, true);
|
||||||
|
|
||||||
cdata->_first_vertex += offset;
|
cdata->_first_vertex += offset;
|
||||||
cdata->_modified = Geom::get_next_modified();
|
cdata->_modified = Geom::get_next_modified();
|
||||||
cdata->_got_minmax = false;
|
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
|
// Function: GeomPrimitive::calc_tight_bounds
|
||||||
// Access: Public, Virtual
|
// 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
|
// Function: GeomPrimitive::write_datagram
|
||||||
// Access: Public, Virtual
|
// Access: Public, Virtual
|
||||||
|
@ -184,6 +184,7 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void clear_prepared(PreparedGraphicsObjects *prepared_objects);
|
void clear_prepared(PreparedGraphicsObjects *prepared_objects);
|
||||||
|
static int get_highest_index_value(NumericType index_type);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual void draw(GraphicsStateGuardianBase *gsg,
|
virtual void draw(GraphicsStateGuardianBase *gsg,
|
||||||
@ -207,6 +208,8 @@ private:
|
|||||||
|
|
||||||
void recompute_minmax(CData *cdata);
|
void recompute_minmax(CData *cdata);
|
||||||
void do_make_indexed(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:
|
private:
|
||||||
// A GeomPrimitive keeps a list (actually, a map) of all the
|
// A GeomPrimitive keeps a list (actually, a map) of all the
|
||||||
|
Loading…
x
Reference in New Issue
Block a user