34 PStatCollector GeomTransformer::_apply_vertex_collector(
"*:Flatten:apply:vertex");
35 PStatCollector GeomTransformer::_apply_texcoord_collector(
"*:Flatten:apply:texcoord");
36 PStatCollector GeomTransformer::_apply_set_color_collector(
"*:Flatten:apply:set color");
37 PStatCollector GeomTransformer::_apply_scale_color_collector(
"*:Flatten:apply:scale color");
38 PStatCollector GeomTransformer::_apply_texture_color_collector(
"*:Flatten:apply:texture color");
39 PStatCollector GeomTransformer::_apply_set_format_collector(
"*:Flatten:apply:set format");
41 TypeHandle GeomTransformer::NewCollectedData::_type_handle;
49 _max_collect_vertices(max_collect_vertices)
58 _max_collect_vertices(copy._max_collect_vertices)
76 VertexDataAssoc &assoc = _vdata_assoc[geom->get_vertex_data()];
77 assoc._geoms.push_back(geom);
78 if (might_have_unused) {
79 assoc._might_have_unused =
true;
89 Thread *current_thread = Thread::get_current_thread();
90 OPEN_ITERATE_CURRENT_AND_UPSTREAM(node->_cycler, current_thread) {
92 GeomNode::GeomList::iterator gi;
94 for (gi = geoms->begin(); gi != geoms->end(); ++gi) {
96 PT(
Geom) geom = entry._geom.get_write_pointer();
100 CLOSE_ITERATE_CURRENT_AND_UPSTREAM(node->_cycler);
111 nassertr(geom !=
nullptr,
false);
114 sv._vertex_data = geom->get_vertex_data();
116 NewVertexData &new_data = _vertices[sv];
117 if (new_data._vdata.is_null()) {
120 new_vdata->transform_vertices(mat);
121 new_data._vdata = new_vdata;
125 if (sv._vertex_data->get_ref_count() > 1) {
126 _vdata_assoc[new_data._vdata]._might_have_unused =
true;
127 _vdata_assoc[sv._vertex_data]._might_have_unused =
true;
143 bool any_changed =
false;
145 Thread *current_thread = Thread::get_current_thread();
146 OPEN_ITERATE_CURRENT_AND_UPSTREAM(node->_cycler, current_thread) {
148 GeomNode::GeomList::iterator gi;
150 for (gi = geoms->begin(); gi != geoms->end(); ++gi) {
152 PT(
Geom) new_geom = entry._geom.get_read_pointer()->make_copy();
154 entry._geom = std::move(new_geom);
159 CLOSE_ITERATE_CURRENT_AND_UPSTREAM(node->_cycler);
162 node->mark_internal_bounds_stale();
178 nassertr(geom !=
nullptr,
false);
182 st._from = from_name;
184 st._vertex_data = geom->get_vertex_data();
186 NewVertexData &new_data = _texcoords[st];
187 if (new_data._vdata.is_null()) {
188 if (!st._vertex_data->has_column(from_name)) {
196 if (st._vertex_data->has_column(to_name)) {
200 st._vertex_data->get_format()->get_column(from_name);
201 new_vdata = st._vertex_data->replace_column
213 const LPoint4 &coord = fdata.
get_data4();
216 new_data._vdata = new_vdata;
220 if (st._vertex_data->get_ref_count() > 1) {
221 _vdata_assoc[new_data._vdata]._might_have_unused =
true;
222 _vdata_assoc[st._vertex_data]._might_have_unused =
true;
239 bool any_changed =
false;
242 GeomNode::GeomList::iterator gi;
244 for (gi = geoms->begin(); gi != geoms->end(); ++gi) {
246 PT(
Geom) new_geom = entry._geom.get_read_pointer()->make_copy();
248 entry._geom = new_geom;
267 sc._vertex_data = geom->get_vertex_data();
269 NewVertexData &new_data = _fcolors[sc];
270 if (new_data._vdata.is_null()) {
272 if (sc._vertex_data->has_column(InternalName::get_color())) {
273 new_data._vdata = sc._vertex_data->set_color(color);
275 new_data._vdata = sc._vertex_data->set_color
276 (color, 1, Geom::NT_packed_dabc, Geom::C_color);
281 if (sc._vertex_data->get_ref_count() > 1) {
282 _vdata_assoc[new_data._vdata]._might_have_unused =
true;
283 _vdata_assoc[sc._vertex_data]._might_have_unused =
true;
297 bool any_changed =
false;
300 GeomNode::GeomList::iterator gi;
302 for (gi = geoms->begin(); gi != geoms->end(); ++gi) {
304 PT(
Geom) new_geom = entry._geom.get_read_pointer()->make_copy();
306 entry._geom = new_geom;
320 PStatTimer timer(_apply_scale_color_collector);
322 nassertr(geom !=
nullptr,
false);
326 sc._vertex_data = geom->get_vertex_data();
328 NewVertexData &new_data = _tcolors[sc];
329 if (new_data._vdata.is_null()) {
331 if (sc._vertex_data->has_column(InternalName::get_color())) {
332 new_data._vdata = sc._vertex_data->scale_color(scale);
334 new_data._vdata = sc._vertex_data->set_color
335 (scale, 1, Geom::NT_packed_dabc, Geom::C_color);
340 if (sc._vertex_data->get_ref_count() > 1) {
341 _vdata_assoc[new_data._vdata]._might_have_unused =
true;
342 _vdata_assoc[sc._vertex_data]._might_have_unused =
true;
358 bool any_changed =
false;
361 GeomNode::GeomList::iterator gi;
363 for (gi = geoms->begin(); gi != geoms->end(); ++gi) {
365 PT(
Geom) new_geom = entry._geom.get_read_pointer()->make_copy();
367 entry._geom = new_geom;
384 bool keep_vertex_color) {
385 PStatTimer timer(_apply_texture_color_collector);
387 nassertr(geom !=
nullptr,
false);
390 if (peeker ==
nullptr) {
394 if (peeker->get_x_size() == 1 &&
395 peeker->get_y_size() == 1 &&
396 peeker->get_z_size() == 1) {
400 peeker->lookup(color, 0.0f, 0.0f);
401 color.set(color[0] * base_color[0],
402 color[1] * base_color[1],
403 color[2] * base_color[2],
404 color[3] * base_color[3]);
405 if (keep_vertex_color) {
412 bool got_mat =
false;
413 LMatrix4 mat = LMatrix4::ident_mat();
414 if (tma !=
nullptr && tma->has_stage(ts)) {
415 mat = tma->get_mat(ts);
416 got_mat = !mat.almost_equal(LMatrix4::ident_mat());
454 SourceTextureColors stc;
458 stc._base_color = base_color;
459 stc._keep_vertex_color = keep_vertex_color;
460 stc._vertex_data = geom->get_vertex_data();
462 NewVertexData &new_data = _tex_colors[stc];
463 if (new_data._vdata.is_null()) {
469 if (stc._vertex_data->has_column(InternalName::get_color())) {
474 (LColor(1.0f, 1.0f, 1.0f, 1.0f), 1, Geom::NT_packed_dabc, Geom::C_color));
475 keep_vertex_color =
false;
481 if (column ==
nullptr) {
490 if (keep_vertex_color) {
495 if (got_mat || tex3d) {
496 while (!gtexcoord.is_at_end()) {
497 LTexCoord3 p = gtexcoord.get_data3();
498 LColor c = gcolor.get_data4();
501 peeker->lookup(color, p[0], p[1], p[2]);
502 color.set(color[0] * base_color[0] * c[0],
503 color[1] * base_color[1] * c[1],
504 color[2] * base_color[2] * c[2],
505 color[3] * base_color[3] * c[3]);
506 gcolor.set_data4(color);
509 while (!gtexcoord.is_at_end()) {
510 LTexCoord p = gtexcoord.get_data2();
511 LColor c = gcolor.get_data4();
513 peeker->lookup(color, p[0], p[1]);
514 color.set(color[0] * base_color[0] * c[0],
515 color[1] * base_color[1] * c[1],
516 color[2] * base_color[2] * c[2],
517 color[3] * base_color[3] * c[3]);
518 gcolor.set_data4(color);
526 if (got_mat || tex3d) {
527 while (!gtexcoord.is_at_end()) {
528 LTexCoord3 p = gtexcoord.get_data3();
531 peeker->lookup(color, p[0], p[1], p[2]);
532 color.set(color[0] * base_color[0],
533 color[1] * base_color[1],
534 color[2] * base_color[2],
535 color[3] * base_color[3]);
536 gcolor.set_data4(color);
539 while (!gtexcoord.is_at_end()) {
540 LTexCoord p = gtexcoord.get_data2();
542 peeker->lookup(color, p[0], p[1]);
543 color.set(color[0] * base_color[0],
544 color[1] * base_color[1],
545 color[2] * base_color[2],
546 color[3] * base_color[3]);
547 gcolor.set_data4(color);
552 new_data._vdata = vdata;
556 if (stc._vertex_data->get_ref_count() > 1) {
557 _vdata_assoc[new_data._vdata]._might_have_unused =
true;
558 _vdata_assoc[stc._vertex_data]._might_have_unused =
true;
578 bool any_changed =
false;
581 GeomNode::GeomList::iterator gi;
583 for (gi = geoms->begin(); gi != geoms->end(); ++gi) {
585 CPT(
RenderState) geom_state = state->compose(entry._state);
590 if (ta2->get_num_on_stages() > 0) {
592 Texture *tex = ta2->get_on_texture(ts);
596 LColor base_color(1.0f, 1.0f, 1.0f, 1.0f);
597 bool keep_vertex_color =
true;
598 if (ca !=
nullptr && ca->get_color_type() == ColorAttrib::T_flat) {
599 base_color = ca->get_color();
600 keep_vertex_color =
false;
603 PT(
Geom) new_geom = entry._geom.get_read_pointer()->make_copy();
605 entry._geom = new_geom;
608 if (new_geom->get_vertex_data()->has_column(InternalName::get_color())) {
610 CPT(
RenderState) color_state = entry._state->set_attrib(ColorAttrib::make_vertex());
611 if (entry._state != color_state) {
612 entry._state = color_state;
619 CPT(
RenderState) no_tex_state = entry._state->remove_attrib(TextureAttrib::get_class_slot());
620 if (entry._state != no_tex_state) {
621 entry._state = no_tex_state;
637 bool any_changed =
false;
640 GeomNode::GeomList::iterator gi;
642 for (gi = geoms->begin(); gi != geoms->end(); ++gi) {
644 CPT(
RenderState) new_state = state->compose(entry._state);
645 if (entry._state != new_state) {
646 entry._state = new_state;
660 PStatTimer timer(_apply_set_format_collector);
662 nassertr(geom !=
nullptr,
false);
665 sf._format = new_format;
666 sf._vertex_data = geom->get_vertex_data();
668 NewVertexData &new_data = _format[sf];
669 if (new_data._vdata.is_null()) {
670 if (sf._vertex_data->get_format() == new_format) {
677 new_vdata->set_format(new_format);
678 new_data._vdata = new_vdata;
682 if (sf._vertex_data->get_ref_count() > 1) {
683 _vdata_assoc[new_data._vdata]._might_have_unused =
true;
684 _vdata_assoc[sf._vertex_data]._might_have_unused =
true;
697 if (!format->has_column(column)) {
702 new_format->remove_column(column);
703 new_format->pack_columns();
704 format = GeomVertexFormat::register_format(new_format);
716 bool any_changed =
false;
719 GeomNode::GeomList::iterator gi;
721 for (gi = geoms->begin(); gi != geoms->end(); ++gi) {
723 PT(
Geom) new_geom = entry._geom.get_read_pointer()->make_copy();
725 entry._geom = new_geom;
752 StateTable state_table;
754 for (
int i = 0; i < (int)geoms->size(); i++) {
756 CPT(
RenderState) canon = entry._state->remove_attrib(ColorAttrib::get_class_slot());
757 state_table[canon].push_back(i);
762 bool any_changed =
false;
763 StateTable::iterator si;
764 for (si = state_table.begin(); si != state_table.end(); si++) {
770 bool mismatch =
false;
771 for (
int i = 1; i < (int)indices.size(); i++) {
772 if ((*geoms)[indices[i]]._state != (*geoms)[indices[0]]._state) {
786 for (
int i = 0; i < (int)indices.size(); i++) {
788 const RenderAttrib *ra = entry._state->get_attrib_def(ColorAttrib::get_class_slot());
792 if (!entry._geom.get_read_pointer()->get_vertex_data()->has_column(InternalName::get_color())) {
793 PT(
Geom) new_geom = entry._geom.get_read_pointer()->make_copy();
794 if (
set_color(new_geom, LColor(1,1,1,1))) {
795 entry._geom = new_geom;
802 PT(
Geom) new_geom = entry._geom.get_read_pointer()->make_copy();
804 entry._geom = new_geom;
807 entry._state = canon_state->add_attrib(ColorAttrib::make_vertex());
821 nassertr(geom !=
nullptr,
false);
823 NewVertexData &new_data = _reversed_normals[orig_data];
824 if (new_data._vdata.is_null()) {
825 new_data._vdata = orig_data->reverse_normals();
828 if (new_data._vdata == orig_data) {
834 if (orig_data->get_ref_count() > 1) {
835 _vdata_assoc[new_data._vdata]._might_have_unused =
true;
836 _vdata_assoc[orig_data]._might_have_unused =
true;
859 for (
int i = 0; i < num_geoms; ++i) {
860 CPT(
Geom) orig_geom = node->get_geom(i);
861 bool has_normals = (orig_geom->get_vertex_data()->has_column(InternalName::get_normal()));
865 PT(
Geom) new_geom = orig_geom->reverse();
873 node->modify_geom(i)->doubleside_in_place();
877 return (num_geoms != 0);
896 for (
int i = 0; i < num_geoms; ++i) {
897 PT(
Geom) geom = node->modify_geom(i);
898 geom->reverse_in_place();
902 return (num_geoms != 0);
914 VertexDataAssocMap::iterator vi;
915 for (vi = _vdata_assoc.begin(); vi != _vdata_assoc.end(); ++vi) {
917 VertexDataAssoc &assoc = (*vi).second;
918 if (assoc._might_have_unused) {
919 assoc.remove_unused_vertices(vdata);
922 _vdata_assoc.clear();
928 _reversed_normals.clear();
946 if (vdata->get_num_rows() > _max_collect_vertices) {
954 if ((collect_bits & SceneGraphReducer::CVD_name) != 0) {
955 key._name = vdata->get_name();
957 if ((collect_bits & SceneGraphReducer::CVD_format) != 0) {
958 key._format = format;
960 if ((collect_bits & SceneGraphReducer::CVD_usage_hint) != 0) {
961 key._usage_hint = vdata->get_usage_hint();
963 key._usage_hint = Geom::UH_unspecified;
965 if ((collect_bits & SceneGraphReducer::CVD_animation_type) != 0) {
966 key._animation_type = format->get_animation().get_animation_type();
968 key._animation_type = Geom::AT_none;
971 AlreadyCollectedMap::const_iterator ai;
972 ai = _already_collected_map.find(vdata);
973 if (ai != _already_collected_map.end()) {
975 const AlreadyCollectedData &acd = (*ai).second;
976 SourceGeom source_geom;
977 source_geom._geom = geom;
978 source_geom._vertex_offset = acd._vertex_offset;
979 acd._ncd->_source_geoms.push_back(source_geom);
984 NewCollectedMap::iterator ni = _new_collected_map.find(key);
985 NewCollectedData *ncd;
986 if (ni != _new_collected_map.end()) {
992 ncd =
new NewCollectedData(vdata);
993 _new_collected_list.push_back(ncd);
994 _new_collected_map[key] = ncd;
997 if (ncd->_new_format != format) {
998 ncd->_new_format = format->get_union_format(ncd->_new_format);
1001 int this_num_vertices = vdata->get_num_rows();
1004 ncd->_num_vertices + this_num_vertices > _max_collect_vertices) {
1007 ncd =
new NewCollectedData(vdata);
1008 _new_collected_list.push_back(ncd);
1009 _new_collected_map[key] = ncd;
1012 int vertex_offset = ncd->_num_vertices;
1014 AlreadyCollectedData &acd = _already_collected_map[vdata];
1016 acd._vertex_offset = vertex_offset;
1018 SourceGeom source_geom;
1019 source_geom._geom = geom;
1020 source_geom._vertex_offset = vertex_offset;
1021 ncd->_source_geoms.push_back(source_geom);
1023 SourceData source_data;
1024 source_data._vdata = vdata;
1025 source_data._num_vertices = this_num_vertices;
1027 ncd->_source_datas.push_back(source_data);
1028 ncd->_num_vertices += this_num_vertices;
1048 int num_adjusted = 0;
1052 GeomNode::GeomList::iterator gi;
1054 for (gi = geoms->begin(); gi != geoms->end(); ++gi) {
1056 PT(
Geom) new_geom = entry._geom.get_read_pointer()->make_copy();
1057 entry._geom = new_geom;
1059 if ((collect_bits & SceneGraphReducer::CVD_avoid_dynamic) != 0 &&
1060 new_geom->get_vertex_data()->get_usage_hint() < Geom::UH_static) {
1063 if (dynamic ==
nullptr) {
1073 if (dynamic !=
nullptr) {
1078 return num_adjusted;
1092 int num_adjusted = 0;
1094 NewCollectedList::iterator nci;
1095 for (nci = _new_collected_list.begin();
1096 nci != _new_collected_list.end();
1098 NewCollectedData *ncd = (*nci);
1100 num_adjusted += ncd->apply_format_only_changes();
1102 num_adjusted += ncd->apply_collect_changes();
1107 _new_collected_list.clear();
1108 _new_collected_map.clear();
1109 _already_collected_map.clear();
1111 return num_adjusted;
1128 vdata = munger->premunge_data(vdata);
1129 CPT(
Geom) pgeom = geom;
1130 munger->premunge_geom(pgeom, vdata);
1132 PT(
Geom) geom_copy = pgeom->make_copy();
1133 geom_copy->set_vertex_data(vdata);
1141 GeomTransformer::NewCollectedData::
1144 _vdata_name = source_data->
get_name();
1154 int GeomTransformer::NewCollectedData::
1155 apply_format_only_changes() {
1156 int num_modified = 0;
1164 SourceGeoms::iterator sgi;
1165 for (sgi = _source_geoms.begin(); sgi != _source_geoms.end(); ++sgi) {
1166 SourceGeom &sg = (*sgi);
1169 if (orig_data->get_format() != _new_format) {
1170 VDataMap::iterator mi = vdata_map.find(orig_data);
1171 if (mi != vdata_map.end()) {
1173 sg._geom->set_vertex_data((*mi).second);
1177 CPT(
GeomVertexData) new_data = orig_data->convert_to(_new_format);
1178 vdata_map[orig_data] = new_data;
1181 sg._geom->set_vertex_data(new_data);
1186 return num_modified;
1193 int GeomTransformer::NewCollectedData::
1194 apply_collect_changes() {
1195 if (_num_vertices == 0) {
1202 _new_data->unclean_set_num_rows(_num_vertices);
1205 int vertex_offset = 0;
1206 SourceDatas::iterator sdi;
1207 for (sdi = _source_datas.begin(); sdi != _source_datas.end(); ++sdi) {
1208 SourceData &sd = (*sdi);
1211 if (_new_format != vdata->get_format()) {
1215 vdata = vdata->convert_to(_new_format);
1218 append_vdata(vdata, vertex_offset);
1219 vertex_offset += sd._num_vertices;
1222 nassertr(vertex_offset == _num_vertices, 0);
1224 if (_new_btable !=
nullptr) {
1225 _new_btable->set_rows(_new_btable_rows);
1226 _new_data->set_transform_blend_table(_new_btable);
1232 _new_btable.clear();
1233 _new_btable_rows.clear();
1242 void GeomTransformer::NewCollectedData::
1247 size_t stride = (size_t)_new_format->get_array(i)->get_stride();
1248 size_t start_byte = (size_t)vertex_offset * stride;
1249 size_t copy_bytes = old_handle->get_data_size_bytes();
1250 nassertv(start_byte + copy_bytes <= new_handle->get_data_size_bytes());
1252 new_handle->copy_subdata_from(start_byte, copy_bytes, old_handle, 0, copy_bytes);
1261 _new_data->get_transform_table() !=
nullptr) {
1270 temp_table->add_transform(identity_transform);
1271 old_table = TransformTable::register_table(temp_table);
1278 AddedTransforms added_transforms;
1280 int num_old_transforms = old_table->get_num_transforms();
1281 for (
int i = 0; i < num_old_transforms; i++) {
1282 added_transforms[old_table->get_transform(i)] = i;
1289 if (_new_data->get_transform_table() !=
nullptr) {
1290 new_table =
new TransformTable(*_new_data->get_transform_table());
1298 IndexMap transform_map;
1301 transform_map.reserve(num_transforms);
1302 for (
int ti = 0; ti < num_transforms; ++ti) {
1304 AddedTransforms::iterator ai = added_transforms.find(transform);
1305 if (ai != added_transforms.end()) {
1307 transform_map.push_back((*ai).second);
1310 int tj = new_table->add_transform(transform);
1311 transform_map.push_back(tj);
1312 added_transforms[transform] = tj;
1315 _new_data->set_transform_table(TransformTable::register_table(new_table));
1321 if (index.has_column()) {
1322 int num_values = index.get_column()->get_num_values();
1325 index.set_row_unsafe(vertex_offset);
1326 for (
int ci = 0; ci < num_rows; ++ci) {
1327 LVecBase4i indices = index.get_data4i();
1328 for (
int i = 0; i < num_values; i++) {
1329 nassertv(indices[i] >= 0 && indices[i] < (
int)transform_map.size());
1330 indices[i] = transform_map[indices[i]];
1332 index.set_data4i(indices);
1337 if (vdata->get_transform_blend_table() !=
nullptr) {
1347 if (_new_btable ==
nullptr) {
1353 new_rows <<= vertex_offset;
1354 _new_btable_rows |= new_rows;
1359 int num_blends = old_btable->get_num_blends();
1360 blend_map.reserve(num_blends);
1361 for (
int bi = 0; bi < num_blends; ++bi) {
1362 int bj = _new_btable->add_blend(old_btable->get_blend(bi));
1363 blend_map.push_back(bj);
1369 if (index.has_column()) {
1371 index.set_row_unsafe(vertex_offset);
1373 for (
int ci = 0; ci < num_rows; ++ci) {
1374 int orig_index = index.get_data1i();
1375 nassertv(orig_index >= 0 && orig_index < (
int)blend_map.size());
1376 int new_index = blend_map[orig_index];
1377 index.set_data1i(new_index);
1390 if (_new_data->get_slider_table() !=
nullptr) {
1391 new_sliders =
new SliderTable(*_new_data->get_slider_table());
1396 for (
int si = 0; si < num_sliders; ++si) {
1398 new_rows <<= vertex_offset;
1399 new_sliders->add_slider(old_sliders->
get_slider(si), new_rows);
1401 _new_data->set_slider_table(SliderTable::register_table(new_sliders));
1408 void GeomTransformer::NewCollectedData::
1410 SourceGeoms::iterator sgi;
1411 for (sgi = _source_geoms.begin(); sgi != _source_geoms.end(); ++sgi) {
1412 SourceGeom &sg = (*sgi);
1413 sg._geom->offset_vertices(_new_data, sg._vertex_offset);
1420 void GeomTransformer::VertexDataAssoc::
1422 if (_geoms.empty()) {
1430 bool any_referenced =
false;
1431 GeomList::iterator gi;
1432 for (gi = _geoms.begin(); gi != _geoms.end(); ++gi) {
1434 if (geom->get_vertex_data() != vdata) {
1438 any_referenced =
true;
1439 int num_primitives = geom->get_num_primitives();
1440 for (
int i = 0; i < num_primitives; ++i) {
1442 reader.get_referenced_vertices(referenced_vertices);
1446 if (!any_referenced) {
1452 if (num_vertices <= new_num_vertices) {
1454 nassertv(num_vertices == new_num_vertices);
1459 int *remap_array = (
int *)alloca(
sizeof(
int) * num_vertices);
1463 for (index = 0; index < num_vertices; ++index) {
1464 if (referenced_vertices.
get_bit(index)) {
1465 while (next_index <= index) {
1466 remap_array[next_index] = new_index;
1472 while (next_index < num_vertices) {
1473 remap_array[next_index] = new_num_vertices - 1;
1479 new_vdata->unclean_set_num_rows(new_num_vertices);
1482 nassertv(num_arrays == new_vdata->get_num_arrays());
1485 reader.check_array_readers();
1487 writer.check_array_writers();
1489 for (
size_t a = 0; a < num_arrays; ++a) {
1493 int stride = array_reader->get_array_format()->get_stride();
1494 nassertv(stride == array_writer->get_array_format()->get_stride());
1498 for (index = 0; index < num_vertices; ++index) {
1499 if (referenced_vertices.
get_bit(index)) {
1502 index * stride, stride);
1510 if (!tbtable.is_null()) {
1514 for (
int si = 0; si < num_subranges; ++si) {
1517 nassertv(from >= 0 && from < num_vertices && to > from && to <= num_vertices);
1518 int new_from = remap_array[from];
1519 int new_to = remap_array[to - 1] + 1;
1520 nassertv(new_from >= 0 && new_from < new_num_vertices && new_to >= new_from && new_to <= new_num_vertices);
1521 new_rows.
set_range(new_from, new_to - new_from);
1523 tbtable->set_rows(new_rows);
1527 for (gi = _geoms.begin(); gi != _geoms.end(); ++gi) {
1529 if (geom->get_vertex_data() != vdata) {
1533 int num_primitives = geom->get_num_primitives();
1534 for (
int i = 0; i < num_primitives; ++i) {
1536 prim->make_indexed();
1540 while (!rewriter.is_at_end()) {
1541 index = rewriter.get_data1i();
1542 nassertv(index >= 0 && index < num_vertices);
1543 new_index = remap_array[index];
1544 nassertv(new_index >= 0 && new_index < new_num_vertices);
1545 rewriter.set_data1i(new_index);
get_geom_state
Returns the RenderState associated with the nth geom of the node.
This class records a set of integers, where each integer is either present or not present in the set.
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is our own Panda specialization on the default STL map.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Contents get_contents() const
Returns the token representing the semantic meaning of the stored value.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the base class for a number of render attributes (other than transform) that may be set on sc...
bool get_bit(int index) const
Returns true if the nth bit is set, false if it is cleared.
NumericType get_numeric_type() const
Returns the token representing the numeric type of the data storage.
Objects of this class are used to convert vertex data from a Geom into a format suitable for passing ...
This class is similar to CycleDataWriter, except it allows writing to a particular stage of the pipel...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
get_color
If the type is T_flat or T_off, this returns the color that will be applied to geometry.
This is an abstract base class for a family of classes that represent the fundamental geometry primit...
const SparseArray & get_slider_rows(size_t n) const
Returns the set of rows (vertices) governed by the nth slider in the table.
const LVecBase4 & get_data4()
Returns the data associated with the read row, expressed as a 4-component value, and advances the rea...
A lightweight class that can be used to automatically start and stop a PStatCollector around a sectio...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This data object is returned by GeomVertexArrayData::get_handle() or modify_handle().
Encapsulates the data from a GeomVertexData, pre-fetched for one stage of the pipeline.
This defines how a single column is interleaved within a vertex array stored within a Geom.
Indicates the set of TextureStages and their associated Textures that should be applied to (or remove...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A dynamic array with an unlimited number of bits.
get_format
Returns a pointer to the GeomVertexFormat structure that defines this data.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A lightweight class that represents a single element that may be timed and/or counted via stats.
Stores the total set of VertexSliders that the vertices in a particular GeomVertexData object might d...
get_current_thread
Returns a pointer to the currently-executing Thread object.
get_num_sliders
Returns the number of sliders in the table.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
int get_num_on_bits() const
Returns the number of bits that are set to 1 in the array.
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A container for geometry primitives.
void set_data4(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z, PN_stdfloat w)
Sets the write row to a particular 4-component value, and advances the write row.
size_t get_num_subranges() const
Returns the number of separate subranges stored in the SparseArray.
This template class calls PipelineCycler::write() in the constructor and PipelineCycler::release_writ...
int get_num_rows() const
Returns the number of rows stored within all the arrays.
Encodes a string name in a hash table, mapping it to a pointer.
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
An instance of this object is returned by Texture::peek().
Applies a transform matrix to UV's before they are rendered.
void set_range(int low_bit, int size)
Sets the indicated range of bits on.
int get_subrange_begin(size_t n) const
Returns the first numeric element in the nth subrange.
void set_vertex_data(const GeomVertexData *data)
Replaces the Geom's underlying vertex data table with a completely new table.
get_num_geoms
Returns the number of geoms in the node.
A thread; that is, a lightweight process.
This object provides a high-level interface for quickly reading a sequence of numeric values from a v...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void copy_subdata_from(size_t to_start, size_t to_size, const GeomVertexArrayDataHandle *other, size_t from_start, size_t from_size)
Copies a portion of the data array from the other object into a portion of the data array of this obj...
bool is_at_end() const
Returns true if the reader is currently at the end of the list of vertices, false otherwise.
This is similar to RefCountObj, but it implements a CopyOnWriteObject inheritance instead of a Refere...
get_slider_table
Returns a const pointer to the SliderTable assigned to this data.
get_num_arrays
Returns the number of individual arrays stored within the data.
get_usage_hint
Returns the usage hint that was passed to the constructor, and which will be passed to each array dat...
Indicates what color should be applied to renderable geometry.
int get_subrange_end(size_t n) const
Returns the last numeric element, plus one, in the nth subrange.
Encapsulates the data from a GeomVertexData, pre-fetched for one stage of the pipeline.
get_name
Returns the name passed to the constructor, if any.
TypeHandle is the identifier used to differentiate C++ class types.
get_slider
Returns the nth slider in the table.
int get_num_components() const
Returns the number of components of the column: the number of instances of the NumericType in each el...
Encapsulates the data from a GeomPrimitive, pre-fetched for one stage of the pipeline.
Defines the properties of a named stage of the multitexture pipeline.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_color_type
Returns the type of color specified by this ColorAttrib.
get_texcoord_name
See set_texcoord_name.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A node that holds Geom objects, renderable pieces of geometry.
void add_geom(Geom *geom, const RenderState *state=RenderState::make_empty())
Adds a new Geom to the node.
This object provides the functionality of both a GeomVertexReader and a GeomVertexWriter,...
get_transform_table
Returns a const pointer to the TransformTable assigned to this data.
This is the data for one array of a GeomVertexData structure.