39 TypeHandle GeomPrimitivePipelineReader::_type_handle;
41 PStatCollector GeomPrimitive::_decompose_pcollector(
"*:Munge:Decompose");
42 PStatCollector GeomPrimitive::_doubleside_pcollector(
"*:Munge:Doubleside");
43 PStatCollector GeomPrimitive::_reverse_pcollector(
"*:Munge:Reverse");
44 PStatCollector GeomPrimitive::_rotate_pcollector(
"*:Munge:Rotate");
65 GeomPrimitive(GeomPrimitive::UsageHint usage_hint) {
66 CDWriter cdata(_cycler,
true);
67 cdata->_usage_hint = usage_hint;
87 CopyOnWriteObject::operator = (copy);
88 _cycler = copy._cycler;
106 return GR_indexed_other;
121 cdata->_usage_hint = usage_hint;
123 if (!cdata->_vertices.is_null()) {
125 cdata->_usage_hint = usage_hint;
143 nassertv(
get_max_vertex() <= get_highest_index_value(index_type));
146 if (cdata->_index_type != index_type) {
147 do_set_index_type(cdata, index_type);
164 if (gobj_cat.is_spam()) {
166 <<
this <<
".add_vertex(" << vertex <<
")\n";
169 consider_elevate_index_type(cdata, vertex);
171 if (requires_unused_vertices()) {
173 if (num_primitives > 0 &&
177 if (cdata->_vertices.is_null()) {
178 do_make_indexed(cdata);
180 append_unused_vertices(cdata->_vertices.get_write_pointer(), vertex);
184 if (cdata->_vertices.is_null()) {
187 nassertv(cdata->_num_vertices != -1);
188 if (cdata->_num_vertices == 0) {
189 cdata->_first_vertex = vertex;
190 cdata->_num_vertices = 1;
192 cdata->_got_minmax =
false;
195 }
else if (vertex == cdata->_first_vertex + cdata->_num_vertices) {
196 ++cdata->_num_vertices;
198 cdata->_got_minmax =
false;
203 do_make_indexed(cdata);
209 int num_rows = handle.get_num_rows();
210 handle.set_num_rows(num_rows + 1);
213 switch (cdata->_index_type) {
214 case GeomEnums::NT_uint8:
215 ((uint8_t *)ptr)[num_rows] = vertex;
217 case GeomEnums::NT_uint16:
218 ((uint16_t *)ptr)[num_rows] = vertex;
220 case GeomEnums::NT_uint32:
221 ((uint32_t *)ptr)[num_rows] = vertex;
224 nassert_raise(
"unsupported index type");
230 cdata->_got_minmax =
false;
242 if (num_vertices == 0) {
245 int end = (start + num_vertices) - 1;
249 consider_elevate_index_type(cdata, end);
252 if (num_primitives > 0 &&
256 if (cdata->_vertices.is_null()) {
257 do_make_indexed(cdata);
259 append_unused_vertices(cdata->_vertices.get_write_pointer(), start);
262 if (cdata->_vertices.is_null()) {
265 nassertv(cdata->_num_vertices != -1);
266 if (cdata->_num_vertices == 0) {
267 cdata->_first_vertex = start;
268 cdata->_num_vertices = num_vertices;
270 cdata->_got_minmax =
false;
273 }
else if (start == cdata->_first_vertex + cdata->_num_vertices) {
274 cdata->_num_vertices += num_vertices;
276 cdata->_got_minmax =
false;
281 do_make_indexed(cdata);
285 int old_num_rows = array_obj->get_num_rows();
286 array_obj->set_num_rows(old_num_rows + num_vertices);
291 for (
int v = start; v <= end; ++v) {
296 cdata->_got_minmax =
false;
334 if (gobj_cat.is_debug()) {
336 <<
this <<
".reserve_num_vertices(" << num_vertices <<
")\n";
340 consider_elevate_index_type(cdata, num_vertices);
341 do_make_indexed(cdata);
343 array_obj->reserve_num_rows(num_vertices);
359 if (num_vertices_per_primitive == 0) {
364 if (cdata->_ends.empty()) {
372 if (cdata->_ends.get_ref_count() > 1) {
374 new_ends.v() = cdata->_ends.v();
375 cdata->_ends = new_ends;
388 nassertr((num_vertices + num_unused_vertices_per_primitive) % (num_vertices_per_primitive + num_unused_vertices_per_primitive) == 0,
false)
407 cdata->_first_vertex = 0;
408 cdata->_num_vertices = 0;
413 cdata->_index_type = NT_uint16;
415 cdata->_vertices.clear();
416 cdata->_ends.clear();
417 cdata->_mins.clear();
418 cdata->_maxs.clear();
420 cdata->_got_minmax =
false;
438 if (!cdata->_got_minmax) {
439 recompute_minmax(cdata);
440 nassertv(cdata->_got_minmax);
443 consider_elevate_index_type(cdata, cdata->_max_vertex + offset);
451 if (vertex != strip_cut_index) {
459 cdata->_first_vertex += offset;
461 cdata->_got_minmax =
false;
463 consider_elevate_index_type(cdata,
464 cdata->_first_vertex + cdata->_num_vertices - 1);
481 if (offset == 0 || end_row <= begin_row) {
485 nassertv(begin_row >= 0 && end_row >= 0);
503 for (
int j = begin_row; j < end_row; ++j) {
505 if (vertex != strip_cut_index) {
506 max_vertex = max(max_vertex, vertex);
511 consider_elevate_index_type(cdata, max_vertex + offset);
515 for (
int j = begin_row; j < end_row; ++j) {
517 if (vertex != strip_cut_index) {
527 cdata->_first_vertex += offset;
529 cdata->_got_minmax =
false;
531 consider_elevate_index_type(cdata,
532 cdata->_first_vertex + cdata->_num_vertices - 1);
545 int num_vertices, dest_start;
548 num_vertices = reader.get_num_vertices();
549 int strip_cut_index = reader.get_strip_cut_index();
552 data_writer.check_array_writers();
553 dest_start = data_writer.get_num_rows();
554 data_writer.set_num_rows(dest_start + num_vertices);
557 data_reader.check_array_readers();
559 for (
int i = 0; i < num_vertices; ++i) {
561 nassertd(v != strip_cut_index)
continue;
587 CopiedIndices copied_indices;
593 for (
int i = 0; i < num_vertices; ++i) {
595 if (v == strip_cut_index) {
601 std::pair<CopiedIndices::iterator, bool> result =
602 copied_indices.insert(CopiedIndices::value_type(v, (
int)copied_indices.size()));
603 int v2 = (*result.first).second + dest_start;
629 do_make_indexed(cdata);
647 if (num_vertices_per_primitive == 0) {
651 nassertr(n >= 0 && n <= (
int)cdata->_ends.size(), -1);
655 return cdata->_ends[n - 1] + num_unused_vertices_per_primitive;
661 return n * (num_vertices_per_primitive + num_unused_vertices_per_primitive);
673 if (num_vertices_per_primitive == 0) {
677 nassertr(n >= 0 && n < (
int)cdata->_ends.size(), -1);
678 return cdata->_ends[n];
684 return n * (num_vertices_per_primitive + num_unused_vertices_per_primitive) + num_vertices_per_primitive;
696 if (num_vertices_per_primitive == 0) {
700 nassertr(n >= 0 && n < (
int)cdata->_ends.size(), 0);
702 return cdata->_ends[0];
705 return cdata->_ends[n] - cdata->_ends[n - 1] - num_unused_vertices_per_primitive;
711 return num_vertices_per_primitive;
725 if (num_primitives > 0) {
741 nassertr(n >= 0 && n < mins->get_num_rows(), -1);
759 nassertr(n >= 0 && n < maxs->get_num_rows(), -1);
781 if (gobj_cat.is_debug()) {
783 <<
"Decomposing " << get_type() <<
": " << (
void *)
this <<
"\n";
787 return decompose_impl();
801 if (gobj_cat.is_debug()) {
803 <<
"Rotating " << get_type() <<
": " << (
void *)
this <<
"\n";
809 if (rotated_vertices ==
nullptr) {
815 new_prim->set_vertices(rotated_vertices);
818 case SM_flat_first_vertex:
819 new_prim->set_shade_model(SM_flat_last_vertex);
822 case SM_flat_last_vertex:
823 new_prim->set_shade_model(SM_flat_first_vertex);
845 if (gobj_cat.is_debug()) {
847 <<
"Doublesiding " << get_type() <<
": " << (
void *)
this <<
"\n";
851 return doubleside_impl();
866 if (gobj_cat.is_debug()) {
868 <<
"Reversing " << get_type() <<
": " << (
void *)
this <<
"\n";
872 return reverse_impl();
884 match_shade_model(GeomPrimitive::ShadeModel shade_model)
const {
886 if (this_shade_model == shade_model) {
891 if (this_shade_model == SM_uniform || shade_model == SM_uniform) {
896 if ((this_shade_model == SM_flat_first_vertex && shade_model == SM_flat_last_vertex) ||
897 (this_shade_model == SM_flat_last_vertex && shade_model == SM_flat_first_vertex)) {
900 if (rotated.p() ==
this) {
918 make_points()
const {
928 reader.get_referenced_vertices(bits);
939 new_index.set_data1i(p);
950 points->set_vertices(new_vertices);
967 if (prim_type == PT_lines) {
971 }
else if (prim_type != PT_polygons && prim_type != PT_patches) {
976 if (prim_type == PT_polygons && !
is_exact_type(GeomTriangles::get_class_type())) {
979 return decompose()->make_lines();
987 new_vertices->unclean_set_num_rows(num_primitives * verts_per_prim * 2);
991 for (
int i = 0; i < num_primitives; ++i) {
997 for (
int vi = begin; vi < end - 1; vi++) {
1006 lines->set_vertices(new_vertices);
1021 make_patches()
const {
1027 int num_vertices_per_patch = prim->get_num_vertices_per_primitive();
1031 if (prim->is_indexed()) {
1032 patches->set_vertices(prim->get_vertices());
1034 patches->set_nonindexed_vertices(prim->get_first_vertex(),
1035 prim->get_num_vertices());
1048 make_adjacency()
const {
1057 get_num_bytes()
const {
1058 CDReader cdata(_cycler);
1059 int num_bytes = cdata->_ends.size() *
sizeof(int) +
sizeof(
GeomPrimitive);
1060 if (!cdata->_vertices.is_null()) {
1061 num_bytes += cdata->_vertices.get_read_pointer()->get_data_size_bytes();
1072 bool GeomPrimitive::
1073 request_resident(
Thread *current_thread)
const {
1074 CDReader cdata(_cycler, current_thread);
1076 bool resident =
true;
1078 if (!cdata->_vertices.is_null() &&
1079 !cdata->_vertices.get_read_pointer(current_thread)->request_resident(current_thread)) {
1084 if (!cdata->_mins.is_null() &&
1085 !cdata->_mins.get_read_pointer(current_thread)->request_resident(current_thread)) {
1088 if (!cdata->_maxs.is_null() &&
1089 !cdata->_maxs.get_read_pointer(current_thread)->request_resident(current_thread)) {
1100 void GeomPrimitive::
1101 output(std::ostream &out)
const {
1109 void GeomPrimitive::
1110 write(std::ostream &out,
int indent_level)
const {
1111 indent(out, indent_level)
1114 out <<
" (indexed)";
1116 out <<
" (nonindexed)";
1122 for (
int i = 0; i < num_primitives; ++i) {
1123 indent(out, indent_level + 2)
1127 for (
int vi = begin; vi < end; vi++) {
1131 if (end < num_vertices) {
1132 for (
int ui = 0; ui < num_unused_vertices_per_primitive; ++ui) {
1133 if (end + ui < num_vertices) {
1164 modify_vertices(
int num_vertices) {
1165 CDWriter cdata(_cycler,
true);
1167 cdata->_num_vertices = num_vertices;
1191 cdata->_num_vertices = num_vertices;
1196 cdata->_index_type = format->
get_column(0)->get_numeric_type();
1199 cdata->_got_minmax =
false;
1215 nassertv(num_vertices != -1);
1217 cdata->_vertices =
nullptr;
1218 cdata->_first_vertex = first_vertex;
1219 cdata->_num_vertices = num_vertices;
1222 cdata->_got_minmax =
false;
1225 recompute_minmax(cdata);
1249 cdata->_got_minmax =
false;
1251 if (cdata->_ends.get_ref_count() > 1) {
1253 new_ends.v() = cdata->_ends.v();
1254 cdata->_ends = new_ends;
1256 return cdata->_ends;
1278 cdata->_ends = ends;
1281 cdata->_got_minmax =
false;
1303 cdata->_min_vertex = min_vertex;
1304 cdata->_max_vertex = max_vertex;
1305 cdata->_mins = mins;
1306 cdata->_maxs = maxs;
1309 cdata->_got_minmax =
true;
1323 cdata->_got_minmax =
false;
1391 Contexts::const_iterator ci;
1392 ci = _contexts.find(prepared_objects);
1393 if (ci != _contexts.end()) {
1415 Contexts::const_iterator ci;
1416 ci = _contexts.find(prepared_objects);
1417 if (ci != _contexts.end()) {
1418 return (*ci).second;
1422 if (ibc !=
nullptr) {
1423 _contexts[prepared_objects] = ibc;
1434 Contexts::iterator ci;
1435 ci = _contexts.find(prepared_objects);
1436 if (ci != _contexts.end()) {
1457 int num_freed = (int)_contexts.size();
1459 Contexts::const_iterator ci;
1460 for (ci = temp.begin(); ci != temp.end(); ++ci) {
1468 nassertr(_contexts.empty(), num_freed);
1479 switch (index_type) {
1483 if (cformat ==
nullptr) {
1484 cformat = make_index_format(NT_uint8);
1491 if (cformat ==
nullptr) {
1492 cformat = make_index_format(NT_uint16);
1499 if (cformat ==
nullptr) {
1500 cformat = make_index_format(NT_uint32);
1507 <<
"Not a valid index type: " << index_type <<
"\n";
1520 void GeomPrimitive::
1522 Contexts::iterator ci;
1523 ci = _contexts.find(prepared_objects);
1524 if (ci != _contexts.end()) {
1525 _contexts.erase(ci);
1529 nassert_raise(
"unknown PreparedGraphicsObjects");
1538 get_highest_index_value(NumericType index_type) {
1541 switch (index_type) {
1551 return 0x7fffffff - 1;
1568 switch (index_type) {
1593 PN_stdfloat &sq_center_dist,
bool &found_any,
1595 bool got_mat,
const LMatrix4 &mat,
1597 Thread *current_thread)
const {
1604 CDReader cdata(_cycler, current_thread);
1607 if (cdata->_vertices.is_null()) {
1609 nassertv(cdata->_num_vertices != -1);
1610 if (cdata->_num_vertices == 0) {
1616 while (!found_any && i < cdata->_num_vertices) {
1617 reader.
set_row(cdata->_first_vertex + i);
1618 LPoint3 first_vertex = mat.xform_point_general(reader.
get_data3());
1619 if (!first_vertex.is_nan()) {
1620 min_point = first_vertex;
1621 max_point = first_vertex;
1622 sq_center_dist = first_vertex.length_squared();
1628 for (; i < cdata->_num_vertices; ++i) {
1632 LPoint3 vertex = mat.xform_point_general(reader.
get_data3());
1634 min_point.set(min(min_point[0], vertex[0]),
1635 min(min_point[1], vertex[1]),
1636 min(min_point[2], vertex[2]));
1637 max_point.set(max(max_point[0], vertex[0]),
1638 max(max_point[1], vertex[1]),
1639 max(max_point[2], vertex[2]));
1640 sq_center_dist = max(sq_center_dist, vertex.length_squared());
1644 while (!found_any && i < cdata->_num_vertices) {
1645 reader.
set_row(cdata->_first_vertex + i);
1646 LPoint3 first_vertex = reader.
get_data3();
1647 if (!first_vertex.is_nan()) {
1648 min_point = first_vertex;
1649 max_point = first_vertex;
1650 sq_center_dist = first_vertex.length_squared();
1656 for (; i < cdata->_num_vertices; ++i) {
1660 const LVecBase3 &vertex = reader.
get_data3();
1662 min_point.set(min(min_point[0], vertex[0]),
1663 min(min_point[1], vertex[1]),
1664 min(min_point[2], vertex[2]));
1665 max_point.set(max(max_point[0], vertex[0]),
1666 max(max_point[1], vertex[1]),
1667 max(max_point[2], vertex[2]));
1668 sq_center_dist = max(sq_center_dist, vertex.length_squared());
1674 GeomVertexReader index(cdata->_vertices.get_read_pointer(), 0, current_thread);
1683 while (!found_any && !index.
is_at_end()) {
1685 if (ii != strip_cut_index) {
1687 LPoint3 first_vertex = mat.xform_point_general(reader.
get_data3());
1688 if (!first_vertex.is_nan()) {
1689 min_point = first_vertex;
1690 max_point = first_vertex;
1691 sq_center_dist = first_vertex.length_squared();
1699 if (ii == strip_cut_index) {
1705 LPoint3 vertex = mat.xform_point_general(reader.
get_data3());
1707 min_point.set(min(min_point[0], vertex[0]),
1708 min(min_point[1], vertex[1]),
1709 min(min_point[2], vertex[2]));
1710 max_point.set(max(max_point[0], vertex[0]),
1711 max(max_point[1], vertex[1]),
1712 max(max_point[2], vertex[2]));
1713 sq_center_dist = max(sq_center_dist, vertex.length_squared());
1717 while (!found_any && !index.
is_at_end()) {
1719 if (ii != strip_cut_index) {
1721 LVecBase3 first_vertex = reader.
get_data3();
1722 if (!first_vertex.is_nan()) {
1723 min_point = first_vertex;
1724 max_point = first_vertex;
1725 sq_center_dist = first_vertex.length_squared();
1733 if (ii == strip_cut_index) {
1739 const LVecBase3 &vertex = reader.
get_data3();
1741 min_point.set(min(min_point[0], vertex[0]),
1742 min(min_point[1], vertex[1]),
1743 min(min_point[2], vertex[2]));
1744 max_point.set(max(max_point[0], vertex[0]),
1745 max(max_point[1], vertex[1]),
1746 max(max_point[2], vertex[2]));
1747 sq_center_dist = max(sq_center_dist, vertex.length_squared());
1763 Thread *current_thread)
const {
1764 GeomVertexReader reader(vertex_data, InternalName::get_vertex(), current_thread);
1774 CDReader cdata(_cycler, current_thread);
1776 if (cdata->_vertices.is_null()) {
1778 nassertv(cdata->_num_vertices != -1);
1779 if (cdata->_num_vertices == 0) {
1784 for (
int i = 0; i < cdata->_num_vertices; ++i) {
1786 const LVecBase3 &vertex = reader.
get_data3();
1788 sq_radius = max(sq_radius, (vertex - center).length_squared());
1793 GeomVertexReader index(cdata->_vertices.get_read_pointer(), 0, current_thread);
1803 if (ii == strip_cut_index) {
1807 const LVecBase3 &vertex = reader.
get_data3();
1809 sq_radius = max(sq_radius, (vertex - center).length_squared());
1825 decompose_impl()
const {
1833 rotate_impl()
const {
1835 nassertr(
false,
nullptr);
1843 doubleside_impl()
const {
1851 reverse_impl()
const {
1859 bool GeomPrimitive::
1860 requires_unused_vertices()
const {
1873 void GeomPrimitive::
1880 void GeomPrimitive::
1881 recompute_minmax(GeomPrimitive::CData *cdata) {
1882 if (cdata->_vertices.is_null()) {
1885 nassertv(cdata->_num_vertices != -1);
1886 cdata->_min_vertex = cdata->_first_vertex;
1887 cdata->_max_vertex = cdata->_first_vertex + cdata->_num_vertices - 1;
1888 cdata->_mins.clear();
1889 cdata->_maxs.clear();
1892 int num_vertices = cdata->_vertices.get_read_pointer()->get_num_rows();
1894 if (num_vertices == 0) {
1896 cdata->_min_vertex = 0;
1897 cdata->_max_vertex = 0;
1898 cdata->_mins.clear();
1899 cdata->_maxs.clear();
1906 cdata->_mins = make_index_data();
1907 cdata->_maxs = make_index_data();
1920 unsigned int vertex = index.get_data1i();
1921 cdata->_min_vertex = vertex;
1922 cdata->_max_vertex = vertex;
1923 unsigned int min_prim = vertex;
1924 unsigned int max_prim = vertex;
1928 for (
int vi = 1; vi < num_vertices; ++vi) {
1929 nassertv(!index.is_at_end());
1930 nassertv(pi < (
int)cdata->_ends.size());
1932 unsigned int vertex;
1934 if (vi == cdata->_ends[pi]) {
1937 if (num_unused_vertices > 0) {
1938 vi += num_unused_vertices;
1939 index.set_row_unsafe(vi);
1941 vertex = index.get_data1i();
1943 mins.set_data1i(min_prim);
1944 maxs.set_data1i(max_prim);
1950 vertex = index.get_data1i();
1951 min_prim = min(min_prim, vertex);
1952 max_prim = max(max_prim, vertex);
1955 cdata->_min_vertex = min(cdata->_min_vertex, vertex);
1956 cdata->_max_vertex = max(cdata->_max_vertex, vertex);
1959 mins.set_data1i(min_prim);
1960 maxs.set_data1i(max_prim);
1961 nassertv(mins.get_array_data()->get_num_rows() == (
int)cdata->_ends.size());
1968 cdata->_mins.clear();
1969 cdata->_maxs.clear();
1971 unsigned int vertex = index.get_data1i();
1972 cdata->_min_vertex = vertex;
1973 cdata->_max_vertex = vertex;
1975 for (
int vi = 1; vi < num_vertices; ++vi) {
1976 nassertv(!index.is_at_end());
1977 unsigned int vertex = index.get_data1i();
1978 cdata->_min_vertex = min(cdata->_min_vertex, vertex);
1979 cdata->_max_vertex = max(cdata->_max_vertex, vertex);
1984 cdata->_got_minmax =
true;
1990 void GeomPrimitive::
1991 do_make_indexed(CData *cdata) {
1992 if (cdata->_vertices.is_null()) {
1993 if (gobj_cat.is_debug()) {
1995 <<
this <<
".make_indexed()\n";
1998 nassertv(cdata->_num_vertices != -1);
1999 cdata->_vertices = make_index_data();
2005 for (
int i = 0; i < cdata->_num_vertices; ++i) {
2006 index.set_data1i(i + cdata->_first_vertex);
2008 cdata->_num_vertices = -1;
2016 void GeomPrimitive::
2017 consider_elevate_index_type(CData *cdata,
int vertex) {
2021 switch (cdata->_index_type) {
2023 if (vertex >= 0xff) {
2024 do_set_index_type(cdata, NT_uint16);
2029 if (vertex >= 0xffff) {
2030 do_set_index_type(cdata, NT_uint32);
2036 nassertv(vertex < 0x7fffffff);
2047 void GeomPrimitive::
2048 do_set_index_type(CData *cdata, GeomPrimitive::NumericType index_type) {
2052 cdata->_index_type = index_type;
2054 if (gobj_cat.is_debug()) {
2056 <<
this <<
".set_index_type(" << index_type <<
")\n";
2059 if (!cdata->_vertices.is_null()) {
2063 if (array_obj->get_array_format() != new_format) {
2065 new_vertices->set_num_rows(array_obj->get_num_rows());
2070 while (!from.is_at_end()) {
2071 int index = from.get_data1i();
2072 if (index == old_strip_cut_index) {
2073 index = new_strip_cut_index;
2075 to.set_data1i(index);
2077 cdata->_vertices = new_vertices;
2078 cdata->_got_minmax =
false;
2087 do_modify_vertices(GeomPrimitive::CData *cdata) {
2088 if (cdata->_vertices.is_null()) {
2089 do_make_indexed(cdata);
2095 cdata->_got_minmax =
false;
2118 if (vertices !=
nullptr) {
2127 void GeomPrimitive::
2140 return new CData(*
this);
2147 void GeomPrimitive::CData::
2156 WRITE_PTA(manager, dg, IPD_int::write_datagram, _ends);
2163 int GeomPrimitive::CData::
2183 void GeomPrimitive::CData::
2185 _shade_model = (ShadeModel)scan.
get_uint8();
2188 _index_type = (NumericType)scan.
get_uint8();
2189 _usage_hint = (UsageHint)scan.
get_uint8();
2192 READ_PTA(manager, scan, IPD_int::read_datagram, _ends);
2195 _got_minmax =
false;
2203 if (!_cdata->_got_minmax) {
2207 #ifdef DO_PIPELINING
2211 false, _current_thread);
2213 #ifdef DO_PIPELINING
2217 if (!fresh_cdata->_got_minmax) {
2219 ((
GeomPrimitive *)_object.p())->recompute_minmax(fresh_cdata);
2220 nassertv(fresh_cdata->_got_minmax);
2229 nassertv(_cdata->_got_minmax);
2235 int GeomPrimitivePipelineReader::
2236 get_first_vertex()
const {
2237 if (_vertices.is_null()) {
2238 return _cdata->_first_vertex;
2241 size_t size = _vertices_cdata->_buffer.get_size();
2247 return index.get_data1i();
2255 if (!_vertices.is_null()) {
2257 nassertr(i >= 0 && i < get_num_vertices(), -1);
2259 const unsigned char *ptr = get_read_pointer(
true);
2260 switch (_cdata->_index_type) {
2261 case GeomEnums::NT_uint8:
2262 return ((uint8_t *)ptr)[i];
2264 case GeomEnums::NT_uint16:
2265 return ((uint16_t *)ptr)[i];
2267 case GeomEnums::NT_uint32:
2268 return ((uint32_t *)ptr)[i];
2271 nassert_raise(
"unsupported index type");
2277 return _cdata->_first_vertex + i;
2284 int GeomPrimitivePipelineReader::
2285 get_num_primitives()
const {
2286 int num_vertices_per_primitive = _object->get_num_vertices_per_primitive();
2288 if (num_vertices_per_primitive == 0) {
2291 return _cdata->_ends.size();
2296 return (get_num_vertices() / num_vertices_per_primitive);
2306 int num_vertices = get_num_vertices();
2309 int strip_cut_index = get_strip_cut_index();
2310 const unsigned char *ptr = get_read_pointer(
true);
2311 switch (get_index_type()) {
2312 case GeomEnums::NT_uint8:
2313 for (
int vi = 0; vi < num_vertices; ++vi) {
2314 int index = ((
const uint8_t *)ptr)[vi];
2315 if (index != strip_cut_index) {
2320 case GeomEnums::NT_uint16:
2321 for (
int vi = 0; vi < num_vertices; ++vi) {
2322 int index = ((
const uint16_t *)ptr)[vi];
2323 if (index != strip_cut_index) {
2328 case GeomEnums::NT_uint32:
2329 for (
int vi = 0; vi < num_vertices; ++vi) {
2330 int index = ((
const uint32_t *)ptr)[vi];
2331 if (index != strip_cut_index) {
2337 nassert_raise(
"unsupported index type");
2342 bits.
set_range(get_first_vertex(), num_vertices);
2349 bool GeomPrimitivePipelineReader::
2351 if (get_num_vertices() != 0 &&
2352 data_reader->get_num_arrays() > 0 &&
2353 get_max_vertex() >= data_reader->get_num_rows()) {
2357 << get_object()->get_type() <<
" references vertices up to "
2358 << get_max_vertex() <<
", but GeomVertexData has only "
2359 << data_reader->get_num_rows() <<
" rows!\n";