28TypeHandle GeomVertexData::CDataCache::_type_handle;
29TypeHandle GeomVertexData::CacheEntry::_type_handle;
31TypeHandle GeomVertexDataPipelineReader::_type_handle;
32TypeHandle GeomVertexDataPipelineWriter::_type_handle;
34PStatCollector GeomVertexData::_convert_pcollector(
"*:Munge:Convert");
35PStatCollector GeomVertexData::_scale_color_pcollector(
"*:Munge:Scale color");
36PStatCollector GeomVertexData::_set_color_pcollector(
"*:Munge:Set color");
37PStatCollector GeomVertexData::_animation_pcollector(
"*:Animation");
46 _char_pcollector(_animation_pcollector,
"unnamed"),
47 _skinning_pcollector(_char_pcollector,
"Skinning"),
48 _morphs_pcollector(_char_pcollector,
"Morphs"),
49 _blends_pcollector(_char_pcollector,
"Calc blends")
65GeomVertexData(
const std::string &name,
67 GeomVertexData::UsageHint usage_hint) :
70 _skinning_pcollector(_char_pcollector,
"Skinning"),
71 _morphs_pcollector(_char_pcollector,
"Morphs"),
72 _blends_pcollector(_char_pcollector,
"Calc blends"),
85 _cycler(copy._cycler),
86 _char_pcollector(copy._char_pcollector),
87 _skinning_pcollector(copy._skinning_pcollector),
88 _morphs_pcollector(copy._morphs_pcollector),
89 _blends_pcollector(copy._blends_pcollector)
91 OPEN_ITERATE_ALL_STAGES(_cycler) {
92 CDStageWriter cdata(_cycler, pipeline_stage);
94 cdata->_animated_vertices =
nullptr;
95 cdata->_animated_vertices_modified =
UpdateSeq();
97 CLOSE_ITERATE_ALL_STAGES(_cycler);
110 _cycler(copy._cycler),
111 _char_pcollector(copy._char_pcollector),
112 _skinning_pcollector(copy._skinning_pcollector),
113 _morphs_pcollector(copy._morphs_pcollector),
114 _blends_pcollector(copy._blends_pcollector)
119 OPEN_ITERATE_ALL_STAGES(_cycler) {
122 UsageHint usage_hint = cdata->_usage_hint;
123 cdata->_arrays.clear();
124 cdata->_format = format;
126 for (
int i = 0; i < num_arrays; i++) {
129 cdata->_arrays.push_back(array.p());
133 cdata->_animated_vertices =
nullptr;
134 cdata->_animated_vertices_modified =
UpdateSeq();
136 CLOSE_ITERATE_ALL_STAGES(_cycler);
146 CopyOnWriteObject::operator = (copy);
151 _cycler = copy._cycler;
152 _char_pcollector = copy._char_pcollector;
153 _skinning_pcollector = copy._skinning_pcollector;
154 _morphs_pcollector = copy._morphs_pcollector;
155 _blends_pcollector = copy._blends_pcollector;
157 OPEN_ITERATE_ALL_STAGES(_cycler) {
160 cdata->_animated_vertices =
nullptr;
161 cdata->_animated_vertices_modified =
UpdateSeq();
163 CLOSE_ITERATE_ALL_STAGES(_cycler);
181 CDReader other_cdata(other._cycler);
183 if (cdata->_usage_hint != other_cdata->_usage_hint) {
184 return (
int)cdata->_usage_hint - (int)other_cdata->_usage_hint;
186 if (cdata->_format != other_cdata->_format) {
187 return cdata->_format < other_cdata->_format ? -1 : 1;
189 if (cdata->_transform_table != other_cdata->_transform_table) {
190 return cdata->_transform_table < other_cdata->_transform_table ? -1 : 1;
192 if (cdata->_transform_blend_table != other_cdata->_transform_blend_table) {
193 return cdata->_transform_blend_table < other_cdata->_transform_blend_table ? -1 : 1;
195 if (cdata->_slider_table != other_cdata->_slider_table) {
196 return cdata->_slider_table < other_cdata->_slider_table ? -1 : 1;
198 if (cdata->_arrays.size() != other_cdata->_arrays.size()) {
199 return (
int)cdata->_arrays.size() - (int)other_cdata->_arrays.size();
201 for (
size_t i = 0; i < cdata->_arrays.size(); ++i) {
202 if (cdata->_arrays[i] != other_cdata->_arrays[i]) {
203 return cdata->_arrays[i] < other_cdata->_arrays[i] ? -1 : 1;
218 _skinning_pcollector =
PStatCollector(_char_pcollector,
"Skinning");
220 _blends_pcollector =
PStatCollector(_char_pcollector,
"Calc blends");
232 CDWriter cdata(_cycler,
true);
233 cdata->_usage_hint = usage_hint;
236 for (ai = cdata->_arrays.begin();
237 ai != cdata->_arrays.end();
240 array_obj->set_usage_hint(usage_hint);
244 cdata->_animated_vertices_modified =
UpdateSeq();
259 CDLockedReader cdata(_cycler, current_thread);
261 if (format == cdata->_format) {
266 CDWriter cdataw(_cycler, cdata,
true);
273 cdataw->_format = format;
275 UsageHint usage_hint = cdataw->_usage_hint;
276 cdataw->_arrays.clear();
277 int num_arrays = cdataw->_format->get_num_arrays();
278 for (
int i = 0; i < num_arrays; i++) {
280 (cdataw->_format->get_array(i), usage_hint);
281 cdataw->_arrays.push_back(array.p());
286 copy_from(orig_data,
false, current_thread);
290 cdataw->_animated_vertices.clear();
308 if (format == cdata->_format) {
314 nassertv(format->
get_num_arrays() == cdata->_format->get_num_arrays());
316 nassertv(format->
get_array(ai)->get_stride() == cdata->_format->get_array(ai)->get_stride());
318 nassertv(cdata->_arrays.size() == cdata->_format->get_num_arrays());
321 CDWriter cdataw(_cycler, cdata,
true);
324 cdataw->_format = format;
326 for (
size_t ai = 0; ai < cdataw->_arrays.size(); ++ai) {
328 array_obj->_array_format = format->
get_array(ai);
333 cdataw->_animated_vertices.clear();
346 CDWriter cdata(_cycler,
true, current_thread);
347 nassertv(cdata->_format->get_num_arrays() == cdata->_arrays.size());
350 for (ai = cdata->_arrays.begin();
351 ai != cdata->_arrays.end();
354 array_obj->clear_rows();
358 cdata->_animated_vertices.clear();
374 CDWriter cdata(_cycler,
true, current_thread);
378 cdata->_animated_vertices_modified =
UpdateSeq();
390modify_transform_blend_table() {
391 CDWriter cdata(_cycler,
true);
395 cdata->_animated_vertices_modified =
UpdateSeq();
397 return cdata->_transform_blend_table.get_write_pointer();
414 cdata->_animated_vertices_modified =
UpdateSeq();
432 CDWriter cdata(_cycler,
true);
436 cdata->_animated_vertices_modified =
UpdateSeq();
448 bool resident =
true;
450 Arrays::const_iterator ai;
451 for (ai = cdata->_arrays.begin();
452 ai != cdata->_arrays.end();
454 if (!(*ai).get_read_pointer()->request_resident()) {
490 for (source_i = 0; source_i < num_arrays; ++source_i) {
494 bool array_done =
false;
498 dest_i < dest_num_arrays && !array_done;
504 if (keep_data_objects) {
507 modify_array_handle(dest_i)->copy_data_from(source->get_array_handle(source_i));
510 if (get_array(dest_i) != source->get_array(source_i)) {
511 set_array(dest_i, source->get_array(source_i));
516 done_arrays.insert(dest_i);
524 writer.check_array_writers();
525 writer.reserve_num_rows(num_rows);
526 writer.set_num_rows(num_rows);
530 for (source_i = 0; source_i < num_arrays; ++source_i) {
532 const unsigned char *array_data = array_handle->get_read_pointer(
true);
535 for (
int di = 0; di < num_columns; ++di) {
539 if (dest_i >= 0 && done_arrays.count(dest_i) == 0) {
545 nassertv(dest_column !=
nullptr);
550 unsigned char *dest_array_data = dest_handle->get_write_pointer();
552 bytewise_copy(dest_array_data + dest_column->
get_start(),
555 source_column, num_rows);
561 unsigned char *dest_array_data = dest_handle->get_write_pointer();
563 uint8_rgba_to_packed_argb
564 (dest_array_data + dest_column->
get_start(),
573 unsigned char *dest_array_data = dest_handle->get_write_pointer();
575 packed_argb_to_uint8_rgba
576 (dest_array_data + dest_column->
get_start(),
583 if (gobj_cat.is_debug()) {
585 <<
"generic copy " << *dest_column <<
" from "
586 << *source_column <<
"\n";
604 if (source_animation != dest_animation) {
609 if (blend_table !=
nullptr) {
622 LVecBase4 weights = LVecBase4::zero();
623 LVecBase4i indices(0, 0, 0, 0);
628 indices[i] = add_transform(transform_table, blend.
get_transform(i),
637 for (
size_t i = 0; i < 4; i++) {
639 indices[i] = add_transform(transform_table, blend2.
get_transform(i),
657 LVecBase4 weights = LVecBase4::zero();
660 int index = add_transform(transform_table, blend.
get_transform(i),
671 clear_transform_blend_table();
688 int source_row,
Thread *current_thread) {
691 reader.check_array_readers();
694 writer.check_array_writers();
712 PT(CacheEntry) entry;
714 CacheKey key(new_format);
717 Cache::const_iterator ci = _cache.find(&key);
718 if (ci == _cache.end()) {
722 entry = (*ci).second;
724 nassertr(entry->_source ==
this,
nullptr);
728 entry->refresh(current_thread);
730 CDCacheReader cdata(entry->_cycler);
731 if (cdata->_result !=
nullptr) {
732 return cdata->_result;
742 if (gobj_cat.is_debug()) {
745 <<
" to " << *new_format <<
"\n";
751 new_data->set_transform_blend_table(get_transform_blend_table());
754 new_data->copy_from(
this,
false);
757 if (entry ==
nullptr) {
764 bool inserted = ((
GeomVertexData *)
this)->_cache.insert(Cache::value_type(&entry->_key, entry)).second;
773 entry->record(current_thread);
777 CDCacheWriter cdata(entry->_cycler,
true, current_thread);
778 cdata->_result = new_data;
791scale_color(
const LVecBase4 &color_scale)
const {
793 get_format()->get_column(InternalName::get_color());
794 if (old_column ==
nullptr) {
800 while (!data.is_at_end()) {
801 LColor color = data.get_data4();
802 data.set_data4(color[0] * color_scale[0],
803 color[1] * color_scale[1],
804 color[2] * color_scale[2],
805 color[3] * color_scale[3]);
818scale_color(
const LVecBase4 &color_scale,
int num_components,
819 GeomVertexData::NumericType numeric_type,
820 GeomVertexData::Contents contents)
const {
821 int old_color_array =
get_format()->get_array_with(InternalName::get_color());
822 if (old_color_array == -1) {
824 return set_color(color_scale, num_components, numeric_type, contents);
829 if (gobj_cat.is_debug()) {
831 <<
"Scaling color for " << num_rows <<
" vertices by "
832 << color_scale <<
".\n";
837 (InternalName::get_color(), num_components, numeric_type, contents);
843 for (
int i = 0; i < num_rows; i++) {
844 LColor color = from.get_data4();
845 to.set_data4(color[0] * color_scale[0],
846 color[1] * color_scale[1],
847 color[2] * color_scale[2],
848 color[3] * color_scale[3]);
862set_color(
const LColor &color)
const {
864 get_format()->get_column(InternalName::get_color());
865 if (old_column ==
nullptr) {
870 do_set_color(new_data, color);
881set_color(
const LColor &color,
int num_components,
882 GeomVertexData::NumericType numeric_type,
883 GeomVertexData::Contents contents)
const {
884 if (gobj_cat.is_debug()) {
886 <<
"Setting color for " <<
get_num_rows() <<
" vertices to "
892 (InternalName::get_color(), num_components, numeric_type, contents);
894 do_set_color(new_data, color);
906reverse_normals()
const {
908 get_format()->get_column(InternalName::get_normal());
909 if (old_column ==
nullptr) {
915 while (!to.is_at_end()) {
916 to.set_data3(-to.get_data3());
940animate_vertices(
bool force,
Thread *current_thread)
const {
945 CDReader cdata(_cycler, current_thread);
946 if (cdata->_format->get_animation().get_animation_type() != AT_panda) {
957 CDLockedReader cdata(_cycler, current_thread);
958 if (cdata->_format->get_animation().get_animation_type() != AT_panda) {
965 if (!cdata->_transform_blend_table.is_null()) {
966 if (cdata->_slider_table !=
nullptr) {
968 std::max(cdata->_transform_blend_table.get_read_pointer()->get_modified(current_thread),
969 cdata->_slider_table->get_modified(current_thread));
971 modified = cdata->_transform_blend_table.get_read_pointer()->get_modified(current_thread);
974 }
else if (cdata->_slider_table !=
nullptr) {
975 modified = cdata->_slider_table->get_modified(current_thread);
983 if (cdata->_animated_vertices_modified == modified &&
984 cdata->_animated_vertices !=
nullptr) {
986 return cdata->_animated_vertices;
991 if (cdata->_animated_vertices !=
nullptr) {
992 return cdata->_animated_vertices;
998 cdataw->_animated_vertices_modified = modified;
999 ((
GeomVertexData *)
this)->update_animated_vertices(cdataw, current_thread);
1001 return cdataw->_animated_vertices;
1010void GeomVertexData::
1011clear_animated_vertices() {
1012 CDWriter cdata(_cycler,
true);
1013 cdata->_animated_vertices_modified.clear();
1014 cdata->_animated_vertices.clear();
1035 if (end_row <= begin_row) {
1045 do_transform_point_column(format, data, mat, begin_row, end_row);
1050 do_transform_vector_column(format, data, mat, begin_row, end_row);
1075 do_transform_point_column(format, data, mat, begin_row, end_row);
1085 do_transform_vector_column(format, data, mat, begin_row, end_row);
1094void GeomVertexData::
1104 if (!format->
get_array_info(InternalName::get_color(), array_index, column)) {
1105 nassert_raise(
"no color column");
1109 size_t stride = format->
get_array(array_index)->get_stride();
1111 GeomVertexColumn::Packer *packer = column->_packer;
1112 nassertv(packer !=
nullptr);
1115 unsigned char buffer[32];
1117#ifdef STDFLOAT_DOUBLE
1118 packer->set_data4d(buffer, color);
1120 packer->set_data4f(buffer, color);
1124 unsigned char *write_ptr = handle->get_write_pointer();
1125 unsigned char *end_ptr = write_ptr + handle->get_data_size_bytes();
1130 while (write_ptr < end_ptr) {
1131 write_ptr[0] = buffer[0];
1132 write_ptr[1] = buffer[1];
1133 write_ptr[2] = buffer[2];
1134 write_ptr[3] = buffer[3];
1135 write_ptr += stride;
1138 while (write_ptr < end_ptr) {
1139 memcpy(write_ptr, buffer, bufsize);
1140 write_ptr += stride;
1148void GeomVertexData::
1149bytewise_copy(
unsigned char *to,
int to_stride,
1150 const unsigned char *from,
int from_stride,
1153 if (gobj_cat.is_debug()) {
1155 <<
"bytewise_copy(" << (
void *)to <<
", " << to_stride
1156 <<
", " << (
const void *)from <<
", " << from_stride
1157 <<
", " << *from_type <<
", " << num_records <<
")\n";
1168 while (num_records > 0) {
1171 from += from_stride;
1188 GeomVertexData::NumericType numeric_type,
1189 GeomVertexData::Contents contents)
const {
1190 CDReader cdata(_cycler);
1194 bool removed_type_array =
false;
1195 int old_type_array = cdata->_format->get_array_with(name);
1196 if (old_type_array != -1) {
1201 new_format->remove_array(old_type_array);
1202 removed_type_array =
true;
1212 int new_type_array = -1;
1213 if (num_components != 0) {
1216 new_type_array = new_format->add_array(type_array_format);
1220 GeomVertexFormat::register_format(new_format);
1222 if (gobj_cat.is_debug()) {
1224 <<
"Replacing data type " << *name <<
"; converting "
1226 << *cdata->_format <<
" to " << *format <<
"\n";
1233 for (
int i = 0; i < num_arrays; ++i) {
1234 if (i == old_type_array) {
1235 if (!removed_type_array) {
1238 new_data->set_array(j, get_array(i));
1244 new_data->set_array(j, get_array(i));
1249 if (new_type_array != -1) {
1250 nassertr(j == new_type_array, new_data);
1257 new_data->set_array(j, new_array);
1266void GeomVertexData::
1267output(ostream &out)
const {
1272 nassertv(format !=
nullptr);
1279void GeomVertexData::
1280write(ostream &out,
int indent_level)
const {
1287 CDReader cdata(_cycler);
1288 format = cdata->_format;
1289 table = cdata->_transform_blend_table.get_read_pointer();
1291 nassertv(format !=
nullptr);
1292 format->write_with_data(out, indent_level + 2,
this);
1293 if (table !=
nullptr) {
1294 indent(out, indent_level)
1295 <<
"Transform blend table:\n";
1296 table->write(out, indent_level + 2);
1304void GeomVertexData::
1305describe_vertex(ostream &out,
int row)
const {
1308 out <<
"Vertex " << row <<
":\n";
1311 reader.set_row_unsafe(row);
1315 if (format->
get_animation().get_animation_type() == AT_panda) {
1316 tb_table = get_transform_blend_table();
1320 for (
int ci = 0; ci < num_columns; ++ci) {
1323 reader.set_column(ai, column);
1326 const LVecBase4 &d = reader.get_data4();
1329 for (
int v = 0; v < num_values; v++) {
1334 if (column->
get_name() == InternalName::get_transform_blend() &&
1335 tb_table !=
nullptr) {
1338 reader.set_column(ai, column);
1339 int bi = reader.get_data1i();
1340 if (bi >= 0 && (
size_t)bi < tb_table->get_num_blends()) {
1342 out <<
" " << blend <<
"\n";
1348 out <<
"\nraw data:\n";
1350 for (
int ai = 0; ai < num_arrays; ++ai) {
1353 nassertv(array !=
nullptr && aformat !=
nullptr);
1354 out <<
" " << *aformat <<
"\n";
1356 nassertv(handle !=
nullptr);
1357 const unsigned char *data = handle->get_read_pointer(
true);
1358 nassertv(data !=
nullptr);
1359 int stride = aformat->get_stride();
1360 int start = stride * row;
1361 if (data !=
nullptr) {
1363 dg.dump_hex(out, 4);
1375void GeomVertexData::
1378 for (Cache::iterator ci = _cache.begin();
1381 CacheEntry *entry = (*ci).second;
1397 for (Cache::iterator ci = _cache.begin();
1402 cdata->_result =
nullptr;
1409void GeomVertexData::
1410packed_argb_to_uint8_rgba(
unsigned char *to,
int to_stride,
1411 const unsigned char *from,
int from_stride,
1413 if (gobj_cat.is_debug()) {
1415 <<
"packed_argb_to_uint8_rgba(" << (
void *)to <<
", " << to_stride
1416 <<
", " << (
const void *)from <<
", " << from_stride
1417 <<
", " << num_records <<
")\n";
1420 while (num_records > 0) {
1421 uint32_t dword = *(
const uint32_t *)from;
1428 from += from_stride;
1436void GeomVertexData::
1437uint8_rgba_to_packed_argb(
unsigned char *to,
int to_stride,
1438 const unsigned char *from,
int from_stride,
1440 if (gobj_cat.is_debug()) {
1442 <<
"uint8_rgba_to_packed_argb(" << (
void *)to <<
", " << to_stride
1443 <<
", " << (
const void *)from <<
", " << from_stride
1444 <<
", " << num_records <<
")\n";
1447 while (num_records > 0) {
1448 *(uint32_t *)to =
pack_abcd(from[3], from[0], from[1], from[2]);
1451 from += from_stride;
1460void GeomVertexData::
1461update_animated_vertices(GeomVertexData::CData *cdata,
Thread *current_thread) {
1462 PStatTimer timer(_char_pcollector, current_thread);
1466 if (gobj_cat.is_debug()) {
1468 <<
"Animating " << num_rows <<
" vertices for " <<
get_name()
1475 if (cdata->_animated_vertices ==
nullptr) {
1476 new_format = orig_format->get_post_animated_format();
1477 cdata->_animated_vertices =
1487 new_data->copy_from(
this,
true);
1490 CPT(
SliderTable) slider_table = cdata->_slider_table;
1491 if (slider_table !=
nullptr) {
1494 for (
int mi = 0; mi < num_morphs; mi++) {
1497 const SparseArray &sliders = slider_table->find_sliders(slider_name);
1501 for (
int sni = 0; sni < num_slider_subranges; ++sni) {
1504 for (
int sn = slider_begin; sn < slider_end; ++sn) {
1505 const VertexSlider *slider = slider_table->get_slider(sn);
1506 const SparseArray &rows = slider_table->get_slider_rows(sn);
1509 PN_stdfloat slider_value = slider->get_slider();
1510 if (slider_value != 0.0f) {
1518 if (data.get_column()->get_num_values() == 4) {
1519 if (data.get_column()->has_homogeneous_coord()) {
1521 for (
int i = 0; i < num_subranges; ++i) {
1524 data.set_row_unsafe(begin);
1525 delta.set_row_unsafe(begin);
1526 for (
int j = begin; j < end; ++j) {
1527 LPoint4 vertex = data.get_data4();
1528 LPoint3 d = delta.get_data3();
1529 d *= slider_value * vertex[3];
1530 data.set_data4(vertex[0] + d[0],
1538 for (
int i = 0; i < num_subranges; ++i) {
1541 data.set_row_unsafe(begin);
1542 delta.set_row_unsafe(begin);
1543 for (
int j = begin; j < end; ++j) {
1544 const LPoint4 &vertex = data.get_data4();
1545 LPoint4 d = delta.get_data4();
1546 data.set_data4(vertex + d * slider_value);
1553 for (
int i = 0; i < num_subranges; ++i) {
1556 data.set_row_unsafe(begin);
1557 delta.set_row_unsafe(begin);
1558 for (
int j = begin; j < end; ++j) {
1559 const LPoint3 &vertex = data.get_data3();
1560 LPoint3 d = delta.get_data3();
1561 data.set_data3(vertex + d * slider_value);
1573 CPT(
TransformBlendTable) tb_table = cdata->_transform_blend_table.get_read_pointer(current_thread);
1574 if (tb_table !=
nullptr) {
1580 for (
int bi = 0; bi < num_blends; bi++) {
1581 tb_table->
get_blend(bi).update_blend(current_thread);
1591 int blend_array_index = orig_format->
get_array_with(InternalName::get_transform_blend());
1592 if (blend_array_index < 0) {
1595 <<
" has a transform_blend_table, but no transform_blend data.\n";
1601 if (blend_array_format->get_stride() == 2 &&
1602 blend_array_format->get_column(0)->get_component_bytes() == 2) {
1606 const unsigned short *blendt = (
const unsigned short *)blend_array_handle->get_read_pointer(
true);
1609 for (ci = 0; ci < new_format->get_num_points(); ci++) {
1612 for (
int i = 0; i < num_subranges; ++i) {
1615 nassertv(begin < end);
1617 int first_vertex = begin;
1618 int first_bi = blendt[first_vertex];
1620 while (first_vertex < end) {
1626 int next_vertex = first_vertex;
1627 int next_bi = first_bi;
1629 while (next_vertex < end) {
1630 next_bi = blendt[next_vertex];
1631 if (next_bi != first_bi) {
1640 tb_table->
get_blend(first_bi).get_blend(mat, current_thread);
1641 new_data->do_transform_point_column(new_format, data, mat, first_vertex, next_vertex);
1643 first_vertex = next_vertex;
1649 for (ci = 0; ci < new_format->get_num_vectors(); ci++) {
1652 for (
int i = 0; i < num_subranges; ++i) {
1655 nassertv(begin < end);
1657 int first_vertex = begin;
1658 int first_bi = blendt[first_vertex];
1660 while (first_vertex < end) {
1666 int next_vertex = first_vertex;
1667 int next_bi = first_bi;
1669 while (next_vertex < end) {
1670 next_bi = blendt[next_vertex];
1671 if (next_bi != first_bi) {
1680 tb_table->
get_blend(first_bi).get_blend(mat, current_thread);
1681 new_data->do_transform_vector_column(new_format, data, mat, first_vertex, next_vertex);
1683 first_vertex = next_vertex;
1693 nassertv(blendi.has_column());
1696 for (ci = 0; ci < new_format->get_num_points(); ci++) {
1699 for (
int i = 0; i < num_subranges; ++i) {
1702 nassertv(begin < end);
1703 blendi.set_row_unsafe(begin);
1705 int first_vertex = begin;
1706 int first_bi = blendi.get_data1i();
1708 while (first_vertex < end) {
1714 int next_vertex = first_vertex;
1715 int next_bi = first_bi;
1717 while (next_vertex < end) {
1718 next_bi = blendi.get_data1i();
1719 if (next_bi != first_bi) {
1728 tb_table->
get_blend(first_bi).get_blend(mat, current_thread);
1729 new_data->do_transform_point_column(new_format, data, mat, first_vertex, next_vertex);
1731 first_vertex = next_vertex;
1737 for (ci = 0; ci < new_format->get_num_vectors(); ci++) {
1740 for (
int i = 0; i < num_subranges; ++i) {
1743 nassertv(begin != end);
1744 blendi.set_row_unsafe(begin);
1746 int first_vertex = begin;
1747 int first_bi = blendi.get_data1i();
1749 while (first_vertex < end) {
1755 int next_vertex = first_vertex;
1756 int next_bi = first_bi;
1758 while (next_vertex < end) {
1759 next_bi = blendi.get_data1i();
1760 if (next_bi != first_bi) {
1769 tb_table->
get_blend(first_bi).get_blend(mat, current_thread);
1770 new_data->do_transform_vector_column(new_format, data, mat, first_vertex, next_vertex);
1772 first_vertex = next_vertex;
1785void GeomVertexData::
1787 const LMatrix4 &mat,
int begin_row,
int end_row) {
1791 if ((num_values == 3 || num_values == 4) &&
1797 size_t stride = data.get_stride();
1798 size_t num_rows = end_row - begin_row;
1800 datat += data_column->
get_start() + begin_row * stride;
1801 LMatrix4f matf = LCAST(
float, mat);
1803 if (num_values == 3) {
1804 table_xform_point3f(datat, num_rows, stride, matf);
1806 table_xform_vecbase4f(datat, num_rows, stride, matf);
1809 }
else if (num_values == 4) {
1812 data.set_row_unsafe(begin_row);
1813 for (
int j = begin_row; j < end_row; ++j) {
1814 LPoint4 vertex = data.get_data4();
1815 data.set_data4(vertex * mat);
1821 data.set_row_unsafe(begin_row);
1822 for (
int j = begin_row; j < end_row; ++j) {
1823 LPoint3 vertex = data.get_data3();
1824 data.set_data3(vertex * mat);
1832void GeomVertexData::
1834 const LMatrix4 &mat,
int begin_row,
int end_row) {
1839 bool normalize =
false;
1842 LVecBase3 scale_sq(mat.get_row3(0).length_squared(),
1843 mat.get_row3(1).length_squared(),
1844 mat.get_row3(2).length_squared());
1845 if (IS_THRESHOLD_EQUAL(scale_sq[0], scale_sq[1], 2.0e-3f) &&
1846 IS_THRESHOLD_EQUAL(scale_sq[0], scale_sq[2], 2.0e-3f)) {
1848 LVecBase3 scale, shear, hpr;
1849 if (IS_THRESHOLD_EQUAL(scale_sq[0], 1, 2.0e-3f)) {
1852 }
else if (decompose_matrix(mat.get_upper_3(), scale, shear, hpr)) {
1854 compose_matrix(xform, LVecBase3(1, 1, 1), shear, hpr, LVecBase3::zero());
1861 xform.invert_from(mat);
1862 xform.transpose_in_place();
1869 if ((num_values == 3 || num_values == 4) &&
1875 size_t stride = data.get_stride();
1876 size_t num_rows = end_row - begin_row;
1878 datat += data_column->
get_start() + begin_row * stride;
1879 LMatrix4f matf = LCAST(
float, xform);
1882 table_xform_normal3f(datat, num_rows, stride, matf);
1883 }
else if (num_values == 3) {
1884 table_xform_vector3f(datat, num_rows, stride, matf);
1886 table_xform_vecbase4f(datat, num_rows, stride, matf);
1891 data.set_row_unsafe(begin_row);
1894 for (
int j = begin_row; j < end_row; ++j) {
1895 LVector3 vector = data.get_data3();
1898 data.set_data3(vector);
1901 for (
int j = begin_row; j < end_row; ++j) {
1902 LVector3 vector = data.get_data3();
1903 data.set_data3(vector * xform);
1913void GeomVertexData::
1914table_xform_point3f(
unsigned char *datat,
size_t num_rows,
size_t stride,
1915 const LMatrix4f &matf) {
1918 for (
size_t i = 0; i < num_rows; ++i) {
1919 LPoint3f &vertex = *(LPoint3f *)(&datat[i * stride]);
1928void GeomVertexData::
1929table_xform_normal3f(
unsigned char *datat,
size_t num_rows,
size_t stride,
1930 const LMatrix4f &matf) {
1933 for (
size_t i = 0; i < num_rows; ++i) {
1934 LNormalf &vertex = *(LNormalf *)(&datat[i * stride]);
1944void GeomVertexData::
1945table_xform_vector3f(
unsigned char *datat,
size_t num_rows,
size_t stride,
1946 const LMatrix4f &matf) {
1949 for (
size_t i = 0; i < num_rows; ++i) {
1950 LVector3f &vertex = *(LVector3f *)(&datat[i * stride]);
1959void GeomVertexData::
1960table_xform_vecbase4f(
unsigned char *datat,
size_t num_rows,
size_t stride,
1961 const LMatrix4f &matf) {
1962#if defined(HAVE_EIGEN) && defined(LINMATH_ALIGN)
1965 if (((
size_t)datat & 0xf) != 0 || (stride & 0xf) != 0) {
1968 Eigen::Map<Eigen::Matrix<float, Eigen::Dynamic, 4, Eigen::RowMajor>, Eigen::Unaligned, Eigen::OuterStride<> > table((
float *)datat, num_rows, 4, Eigen::OuterStride<>(stride /
sizeof(
float)));
1969 for (
size_t i = 0; i < num_rows; ++i) {
1970 table.row(i) *= matf._m;
1979 for (
size_t i = 0; i < num_rows; ++i) {
1980 LVecBase4f &vertex = *(LVecBase4f *)(&datat[i * stride]);
2017 object->fillin(scan, manager);
2067 for (
size_t i = 0; i < cdata->_arrays.size(); ++i) {
2069 GeomVertexFormat::register_format(cdata->_format);
2071 cdata->_format = new_format;
2075 nassertv(new_array_format->is_data_subset_of(*array_obj->_array_format));
2077 manager->
change_pointer(array_obj->_array_format, new_array_format);
2078 array_obj->_array_format = new_array_format;
2081 if (cdata->_transform_table !=
nullptr) {
2083 TransformTable::register_table(cdata->_transform_table);
2084 manager->
change_pointer(cdata->_transform_table, new_transform_table);
2085 cdata->_transform_table = new_transform_table;
2088 if (cdata->_slider_table !=
nullptr) {
2090 SliderTable::register_table(cdata->_slider_table);
2092 cdata->_slider_table = new_slider_table;
2100void GeomVertexData::
2113 return new CDataCache(*
this);
2123 Cache::iterator ci = _source->_cache.find(&_key);
2124 nassertv(ci != _source->_cache.end());
2125 nassertv((*ci).second ==
this);
2126 _source->_cache.erase(ci);
2132void GeomVertexData::CacheEntry::
2133output(ostream &out)
const {
2134 out <<
"vertex data " << (
void *)_source <<
" to "
2143 return new CData(*
this);
2150void GeomVertexData::CData::
2156 Arrays::const_iterator ai;
2157 for (ai = _arrays.begin(); ai != _arrays.end(); ++ai) {
2162 manager->
write_pointer(dg, _transform_blend_table.get_read_pointer());
2170int GeomVertexData::CData::
2176 Arrays::iterator ai;
2177 for (ai = _arrays.begin(); ai != _arrays.end(); ++ai) {
2193 all_rows.
set_range(0, adata->get_num_rows());
2195 if (_slider_table !=
nullptr) {
2196 int num_sliders = _slider_table->get_num_sliders();
2197 for (
int i = 0; i < num_sliders; ++i) {
2198 ((
SliderTable *)_slider_table.p())->set_slider_rows(i, all_rows);
2201 if (!_transform_blend_table.is_null()) {
2202 _transform_blend_table.get_unsafe_pointer()->set_rows(all_rows);
2213void GeomVertexData::CData::
2216 _usage_hint = (UsageHint)scan.
get_uint8();
2219 _arrays.reserve(num_arrays);
2220 for (
size_t i = 0; i < num_arrays; ++i) {
2222 _arrays.push_back(
nullptr);
2233int GeomVertexDataPipelineBase::
2234get_num_bytes()
const {
2237 GeomVertexData::Arrays::const_iterator ai;
2238 for (ai = _cdata->_arrays.begin(); ai != _cdata->_arrays.end(); ++ai) {
2239 num_bytes += (*ai).get_read_pointer()->get_data_size_bytes();
2248int GeomVertexDataPipelineReader::
2249get_num_rows()
const {
2250 nassertr(_cdata->_format->get_num_arrays() == _cdata->_arrays.size(), 0);
2251 nassertr(_got_array_readers, 0);
2253 if (_cdata->_format->get_num_arrays() == 0) {
2259 int stride = _cdata->_format->get_array(0)->get_stride();
2260 return _array_readers[0]->get_data_size_bytes() / stride;
2266bool GeomVertexDataPipelineReader::
2270 GeomVertexDataPipelineReader::NumericType &numeric_type,
2271 int &start,
int &stride)
const {
2272 nassertr(_got_array_readers,
false);
2275 if (_cdata->_format->get_array_info(name, array_index, column)) {
2276 array_reader = _array_readers[array_index];
2280 stride = _cdata->_format->get_array(array_index)->get_stride();
2289bool GeomVertexDataPipelineReader::
2293 GeomVertexDataPipelineReader::NumericType &numeric_type,
2294 bool &normalized,
int &start,
int &stride,
int &divisor,
2295 int &num_elements,
int &element_stride)
const {
2296 nassertr(_got_array_readers,
false);
2299 if (_cdata->_format->get_array_info(name, array_index, column)) {
2300 array_reader = _array_readers[array_index];
2303 normalized = (column->
get_contents() == GeomEnums::C_color);
2305 stride = _cdata->_format->get_array(array_index)->get_stride();
2306 divisor = _cdata->_format->get_array(array_index)->get_divisor();
2317bool GeomVertexDataPipelineReader::
2320 GeomVertexDataPipelineReader::NumericType &numeric_type,
2321 int &start,
int &stride)
const {
2322 nassertr(_got_array_readers,
false);
2323 int array_index = _cdata->_format->get_vertex_array_index();
2324 if (array_index >= 0) {
2327 array_reader = _array_readers[array_index];
2331 stride = _cdata->_format->get_array(array_index)->get_stride();
2340bool GeomVertexDataPipelineReader::
2342 GeomVertexDataPipelineReader::NumericType &numeric_type,
2343 int &start,
int &stride)
const {
2344 nassertr(_got_array_readers,
false);
2345 int array_index = _cdata->_format->get_normal_array_index();
2346 if (array_index >= 0) {
2349 array_reader = _array_readers[array_index];
2352 stride = _cdata->_format->get_array(array_index)->get_stride();
2361bool GeomVertexDataPipelineReader::
2364 GeomVertexDataPipelineReader::NumericType &numeric_type,
2365 int &start,
int &stride)
const {
2366 nassertr(_got_array_readers,
false);
2367 int array_index = _cdata->_format->get_color_array_index();
2368 if (array_index >= 0) {
2371 array_reader = _array_readers[array_index];
2375 stride = _cdata->_format->get_array(array_index)->get_stride();
2384void GeomVertexDataPipelineReader::
2385make_array_readers() {
2386 nassertv(!_got_array_readers);
2388 _array_readers.reserve(_cdata->_arrays.size());
2389 GeomVertexData::Arrays::const_iterator ai;
2390 for (ai = _cdata->_arrays.begin(); ai != _cdata->_arrays.end(); ++ai) {
2394 _got_array_readers =
true;
2400int GeomVertexDataPipelineWriter::
2401get_num_rows()
const {
2402 nassertr(_cdata->_format->get_num_arrays() == _cdata->_arrays.size(), 0);
2403 nassertr(_got_array_writers, 0);
2405 if (_cdata->_format->get_num_arrays() == 0) {
2411 int stride = _cdata->_format->get_array(0)->get_stride();
2412 return _array_writers[0]->get_data_size_bytes() / stride;
2418bool GeomVertexDataPipelineWriter::
2419set_num_rows(
int n) {
2420 nassertr(_got_array_writers,
false);
2421 nassertr(_cdata->_format->get_num_arrays() == _cdata->_arrays.size(),
false);
2423 bool any_changed =
false;
2425 int color_array = -1;
2426 int orig_color_rows = -1;
2428 for (
size_t i = 0; i < _cdata->_arrays.size(); i++) {
2430 if (_array_writers[i]->get_object()->
has_column(InternalName::get_color())) {
2432 orig_color_rows = _array_writers[i]->get_num_rows();
2434 _array_writers[i]->set_num_rows(n);
2439 if (color_array >= 0 && orig_color_rows < n) {
2445 array_format->
get_column(InternalName::get_color());
2447 unsigned char *start =
2449 unsigned char *stop = start + array_writer->get_data_size_bytes();
2450 unsigned char *pointer = start + stride * orig_color_rows;
2457 case NT_packed_dcba:
2458 case NT_packed_dabc:
2459 while (pointer < stop) {
2466 while (pointer < stop) {
2467 PN_float32 *pi = (PN_float32 *)pointer;
2468 for (
int i = 0; i < num_values; i++) {
2476 while (pointer < stop) {
2477 PN_float64 *pi = (PN_float64 *)pointer;
2478 for (
int i = 0; i < num_values; i++) {
2490 nassertr(
false,
false);
2493 case NT_packed_ufloat:
2494 while (pointer < stop) {
2495 *(int32_t *)pointer = 0x781e03c0;
2503 _object->clear_cache_stage();
2505 _cdata->_animated_vertices.clear();
2514bool GeomVertexDataPipelineWriter::
2515unclean_set_num_rows(
int n) {
2516 nassertr(_got_array_writers,
false);
2517 nassertr(_cdata->_format->get_num_arrays() == _cdata->_arrays.size(),
false);
2519 bool any_changed =
false;
2521 for (
size_t i = 0; i < _cdata->_arrays.size(); i++) {
2530 _object->clear_cache_stage();
2532 _cdata->_animated_vertices.clear();
2541bool GeomVertexDataPipelineWriter::
2542reserve_num_rows(
int n) {
2543 nassertr(_got_array_writers,
false);
2544 nassertr(_cdata->_format->get_num_arrays() == _cdata->_arrays.size(),
false);
2546 bool any_changed =
false;
2548 for (
size_t i = 0; i < _cdata->_arrays.size(); i++) {
2561modify_array(
size_t i) {
2562 nassertr(i < _cdata->_arrays.size(),
nullptr);
2565 if (_got_array_writers) {
2566 new_data = _array_writers[i]->get_object();
2568 new_data = _cdata->_arrays[i].get_write_pointer();
2571 _object->clear_cache_stage();
2573 _cdata->_animated_vertices_modified =
UpdateSeq();
2581void GeomVertexDataPipelineWriter::
2583 nassertv(i < _cdata->_arrays.size());
2585 _object->clear_cache_stage();
2587 _cdata->_animated_vertices_modified =
UpdateSeq();
2589 if (_got_array_writers) {
2607 nassertv(source_format == dest_format);
2608 nassertv(source_row >= 0 && source_row < source.get_num_rows());
2609 nassertv(_got_array_writers);
2617 for (
size_t i = 0; i < num_arrays; ++i) {
2622 const unsigned char *source_array_data = source_array_handle->
get_read_pointer(
true);
2627 memcpy(dest_array_data + stride * dest_row,
2628 source_array_data + stride * source_row,
2636void GeomVertexDataPipelineWriter::
2637make_array_writers() {
2638 nassertv(!_got_array_writers);
2640 _array_writers.reserve(_cdata->_arrays.size());
2641 GeomVertexData::Arrays::iterator ai;
2642 for (ai = _cdata->_arrays.begin(); ai != _cdata->_arrays.end(); ++ai) {
2646 _object->clear_cache_stage();
2648 _cdata->_animated_vertices_modified =
UpdateSeq();
2650 _got_array_writers =
true;
2656void GeomVertexDataPipelineWriter::
2657delete_array_writers() {
2658 nassertv(_got_array_writers);
2660 _array_writers.clear();
2661 _got_array_writers =
false;
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void parse_params(const FactoryParams ¶ms, DatagramIterator &scan, BamReader *&manager)
Takes in a FactoryParams, passed from a WritableFactory into any TypedWritable's make function,...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
void register_finalize(TypedWritable *whom)
Should be called by an object reading itself from the Bam file to indicate that this particular objec...
bool change_pointer(const TypedWritable *orig_pointer, const TypedWritable *new_pointer)
Indicates that an object recently read from the bam stream should be replaced with a new object.
bool read_pointer(DatagramIterator &scan)
The interface for reading a pointer to another object from a Bam file.
int get_file_minor_ver() const
Returns the minor version number of the Bam file currently being read.
void read_cdata(DatagramIterator &scan, PipelineCyclerBase &cycler)
Reads in the indicated CycleData object.
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
void write_cdata(Datagram &packet, const PipelineCyclerBase &cycler)
Writes out the indicated CycleData object.
void write_pointer(Datagram &packet, const TypedWritable *dest)
The interface for writing a pointer to another object to a Bam file.
This base class provides basic reference counting, but also can be used with a CopyOnWritePointer to ...
This template class calls PipelineCycler::read() in the constructor and PipelineCycler::release_read(...
This template class calls PipelineCycler::read_unlocked(), and then provides a transparent read-only ...
This class is similar to CycleDataWriter, except it allows writing to a particular stage of the pipel...
This template class calls PipelineCycler::write() in the constructor and PipelineCycler::release_writ...
A single page of data maintained by a PipelineCycler.
virtual int complete_pointers(TypedWritable **p_list, BamReader *manager)
Receives an array of pointers, one for each time manager->read_pointer() was called in fillin().
A class to retrieve the individual data elements previously stored in a Datagram.
uint8_t get_uint8()
Extracts an unsigned 8-bit integer.
uint16_t get_uint16()
Extracts an unsigned 16-bit integer.
std::string get_string()
Extracts a variable-length string.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
void add_uint8(uint8_t value)
Adds an unsigned 8-bit integer to the datagram.
void add_uint16(uint16_t value)
Adds an unsigned 16-bit integer to the datagram.
void add_string(const std::string &str)
Adds a variable-length string to the datagram.
An instance of this class is passed to the Factory when requesting it to do its business and construc...
void register_factory(TypeHandle handle, CreateFunc *func, void *user_data=nullptr)
Registers a new kind of thing the Factory will be able to create.
This object describes how the vertex animation, if any, represented in a GeomVertexData is encoded.
get_animation_type
Returns the type of animation represented by this spec.
get_indexed_transforms
This is only meaningful for animation_type AT_hardware.
This data object is returned by GeomVertexArrayData::get_handle() or modify_handle().
const unsigned char * get_read_pointer(bool force) const
Returns a readable pointer to the beginning of the actual data stream, or NULL if the data is not cur...
unsigned char * get_write_pointer()
Returns a writable pointer to the beginning of the actual data stream.
This is the data for one array of a GeomVertexData structure.
This defines how a single column is interleaved within a vertex array stored within a Geom.
int get_num_values() const
Returns the number of numeric values of the column: the number of distinct numeric values that go int...
int get_start() const
Returns the byte within the array record at which this column starts.
NumericType get_numeric_type() const
Returns the token representing the numeric type of the data storage.
int get_element_stride() const
This value is only relevant for matrix types.
bool is_bytewise_equivalent(const GeomVertexColumn &other) const
Returns true if the data store of this column is exactly the same as that of the other,...
bool is_uint8_rgba() const
Returns true if this column is the standard OpenGL representation of 4-component color: C_color,...
int get_num_elements() const
Returns the number of times this column is repeated.
const InternalName * get_name() const
Returns the name of this particular data field, e.g.
bool is_packed_argb() const
Returns true if this column is the standard DirectX representation of 4-component color: C_color,...
Contents get_contents() const
Returns the token representing the semantic meaning of the stored value.
int get_total_bytes() const
Returns the number of bytes used by each element of the column: component_bytes * num_components.
Encapsulates the data from a GeomVertexData, pre-fetched for one stage of the pipeline.
Encapsulates the data from a GeomVertexData, pre-fetched for one stage of the pipeline.
void copy_row_from(int dest_row, const GeomVertexDataPipelineReader &source, int source_row)
Copies a single row of the data from the other array into the indicated row of this array.
virtual void evict_callback()
Called when the entry is evicted from the cache, this should clean up the owning object appropriately...
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
bool set_num_rows(int n)
Sets the length of the array to n rows in all of the various arrays (presumably by adding rows).
void copy_row_from(int dest_row, const GeomVertexData *source, int source_row, Thread *current_thread)
Copies a single row of the data from the other array into the indicated row of this array.
get_name
Returns the name passed to the constructor, if any.
int compare_to(const GeomVertexData &other) const
Returns 0 if the two objects are equivalent, even if they are not the same pointer.
void clear_cache_stage()
Removes all of the previously-cached results of convert_to(), at the current pipeline stage and upstr...
set_format
Changes the format of the vertex data.
virtual void finalize(BamReader *manager)
Called by the BamReader to perform any final actions needed for setting up the object after all objec...
bool has_column(const InternalName *name) const
Returns true if the data has the named column, false otherwise.
int get_num_rows() const
Returns the number of rows stored within all the arrays.
set_array
Replaces the indicated vertex data array with a completely new array.
bool reserve_num_rows(int n)
This ensures that enough memory space for n rows is allocated, so that you may increase the number of...
virtual int complete_pointers(TypedWritable **plist, BamReader *manager)
Receives an array of pointers, one for each time manager->read_pointer() was called in fillin().
void clear_rows()
Removes all of the rows from the arrays; functionally equivalent to set_num_rows(0) (but faster).
get_num_arrays
Returns the number of individual arrays stored within the data.
get_slider_table
Returns a const pointer to the SliderTable assigned to this data.
static void register_with_read_factory()
Tells the BamReader how to create objects of type GeomVertexData.
set_usage_hint
Changes the UsageHint hint for this vertex data, and for all of the arrays that share this data.
set_transform_table
Replaces the TransformTable on this vertex data with the indicated table.
static unsigned int unpack_abcd_b(uint32_t data)
Returns the second packed value from a DirectX-style NT_packed_abcd.
static unsigned int unpack_abcd_a(uint32_t data)
Returns the first packed value from a DirectX-style NT_packed_abcd.
set_slider_table
Replaces the SliderTable on this vertex data with the indicated table.
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
set_name
Changes the name of the vertex data.
void set_transform_blend_table(const TransformBlendTable *table)
Replaces the TransformBlendTable on this vertex data with the indicated table.
static uint32_t pack_abcd(unsigned int a, unsigned int b, unsigned int c, unsigned int d)
Packs four values in a DirectX-style NT_packed_abcd value.
static unsigned int unpack_abcd_c(uint32_t data)
Returns the third packed value from a DirectX-style NT_packed_abcd.
static unsigned int unpack_abcd_d(uint32_t data)
Returns the fourth packed value from a DirectX-style NT_packed_abcd.
void operator=(const GeomVertexData ©)
The copy assignment operator is not pipeline-safe.
get_format
Returns a pointer to the GeomVertexFormat structure that defines this data.
get_usage_hint
Returns the usage hint that was passed to the constructor, and which will be passed to each array dat...
bool unclean_set_num_rows(int n)
This method behaves like set_num_rows(), except the new data is not initialized.
void unclean_set_format(const GeomVertexFormat *format)
Changes the format of the vertex data, without reformatting the data to match.
bool request_resident() const
Returns true if the vertex data is currently resident in memory.
void copy_from(const GeomVertexData *source, bool keep_data_objects, Thread *current_thread=Thread::get_current_thread())
Copies all the data from the other array into the corresponding data types in this array,...
void transform_vertices(const LMatrix4 &mat)
Applies the indicated transform matrix to all of the vertices in the GeomVertexData.
virtual bool require_fully_complete() const
Some objects require all of their nested pointers to have been completed before the objects themselve...
This object provides a high-level interface for quickly reading a sequence of numeric values from a v...
bool set_column(int column)
Sets up the reader to use the nth data type of the GeomVertexFormat, numbering from 0.
bool is_at_end() const
Returns true if the reader is currently at the end of the list of vertices, false otherwise.
const LVecBase4 & get_data4()
Returns the data associated with the read row, expressed as a 4-component value, and advances the rea...
int get_data1i()
Returns the data associated with the read row, expressed as a 1-component value, and advances the rea...
This object provides the functionality of both a GeomVertexReader and a GeomVertexWriter,...
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
void set_data4i(int a, int b, int c, int d)
Sets the write row to a particular 4-component value, and advances the write row.
bool set_column(int column)
Sets up the writer to use the nth data type of the GeomVertexFormat, numbering from 0.
bool has_column() const
Returns true if a valid data type has been successfully set, or false if the data type does not exist...
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.
static UpdateSeq get_next_modified()
Returns a monotonically increasing sequence.
Encodes a string name in a hash table, mapping it to a pointer.
void release() const
Releases the lightMutex.
void acquire() const
Grabs the lightMutex if it is available.
Similar to MutexHolder, but for a light mutex.
A lightweight class that represents a single element that may be timed and/or counted via stats.
A lightweight class that can be used to automatically start and stop a PStatCollector around a sectio...
Stores the total set of VertexSliders that the vertices in a particular GeomVertexData object might d...
bool is_registered() const
Returns true if this table has been registered.
This class records a set of integers, where each integer is either present or not present in the set.
int get_subrange_begin(size_t n) const
Returns the first numeric element in the nth subrange.
void set_range(int low_bit, int size)
Sets the indicated range of bits on.
size_t get_num_subranges() const
Returns the number of separate subranges stored in the SparseArray.
int get_subrange_end(size_t n) const
Returns the last numeric element, plus one, in the nth subrange.
bool is_zero() const
Returns true if the entire bitmask is zero, false otherwise.
bool is_inverse() const
If this is true, the SparseArray is actually defined as a list of subranges of integers that are *not...
A thread; that is, a lightweight process.
get_current_thread
Returns a pointer to the currently-executing Thread object.
TypeHandle is the identifier used to differentiate C++ class types.
Base class for objects that can be written to and read from Bam files.
virtual void fillin(DatagramIterator &scan, BamReader *manager)
This internal function is intended to be called by each class's make_from_bam() method to read in all...
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
virtual int complete_pointers(TypedWritable **p_list, BamReader *manager)
Receives an array of pointers, one for each time manager->read_pointer() was called in fillin().
This is a sequence number that increments monotonically.
This is an abstract base class that retains some slider value, which is a linear value that typically...
This is our own Panda specialization on the default STL map.
This is our own Panda specialization on the default STL set.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.