28 TypeHandle GeomVertexData::CDataCache::_type_handle;
29 TypeHandle GeomVertexData::CacheEntry::_type_handle;
30 TypeHandle GeomVertexData::CData::_type_handle;
31 TypeHandle GeomVertexDataPipelineReader::_type_handle;
32 TypeHandle GeomVertexDataPipelineWriter::_type_handle;
34 PStatCollector GeomVertexData::_convert_pcollector(
"*:Munge:Convert");
35 PStatCollector GeomVertexData::_scale_color_pcollector(
"*:Munge:Scale color");
36 PStatCollector GeomVertexData::_set_color_pcollector(
"*:Munge:Set color");
37 PStatCollector 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")
65 GeomVertexData(
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();
303 Thread *current_thread = Thread::get_current_thread();
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();
345 Thread *current_thread = Thread::get_current_thread();
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();
371 Thread *current_thread = Thread::get_current_thread();
374 CDWriter cdata(_cycler,
true, current_thread);
378 cdata->_animated_vertices_modified =
UpdateSeq();
390 modify_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),
662 nassertv(index <= 4);
671 clear_transform_blend_table();
688 int source_row,
Thread *current_thread) {
691 reader.check_array_readers();
694 writer.check_array_writers();
704 Thread *current_thread = Thread::get_current_thread();
706 if (new_format == get_format()) {
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()) {
744 <<
"Converting " <<
get_num_rows() <<
" rows from " << *get_format()
745 <<
" to " << *new_format <<
"\n";
751 new_data->set_transform_blend_table(get_transform_blend_table());
752 new_data->set_slider_table(get_slider_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;
791 scale_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]);
818 scale_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]);
862 set_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);
881 set_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);
906 reverse_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());
940 animate_vertices(
bool force,
Thread *current_thread)
const {
945 CDReader cdata(_cycler, current_thread);
946 if (cdata->_format->get_animation().get_animation_type() != AT_panda) {
950 #endif // DO_PIPELINING 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;
1010 void GeomVertexData::
1011 clear_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);
1094 void 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;
1148 void GeomVertexData::
1149 bytewise_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";
1232 int num_arrays = get_num_arrays();
1233 for (
int i = 0; i < num_arrays; ++i) {
1234 if (i == old_type_array) {
1235 if (!removed_type_array) {
1249 if (new_type_array != -1) {
1250 nassertr(j == new_type_array, new_data);
1255 (format->
get_array(j), get_usage_hint());
1257 new_data->set_array(j, new_array);
1266 void GeomVertexData::
1267 output(ostream &out)
const {
1277 void GeomVertexData::
1278 write(ostream &out,
int indent_level)
const {
1282 get_format()->write_with_data(out, indent_level + 2,
this);
1284 if (table !=
nullptr) {
1285 indent(out, indent_level)
1286 <<
"Transform blend table:\n";
1287 table->write(out, indent_level + 2);
1295 void GeomVertexData::
1296 describe_vertex(ostream &out,
int row)
const {
1299 out <<
"Vertex " << row <<
":\n";
1302 reader.set_row_unsafe(row);
1306 if (format->
get_animation().get_animation_type() == AT_panda) {
1307 tb_table = get_transform_blend_table();
1311 for (
int ci = 0; ci < num_columns; ++ci) {
1314 reader.set_column(ai, column);
1317 const LVecBase4 &d = reader.get_data4();
1320 for (
int v = 0; v < num_values; v++) {
1325 if (column->
get_name() == InternalName::get_transform_blend() &&
1326 tb_table !=
nullptr) {
1329 reader.set_column(ai, column);
1330 int bi = reader.get_data1i();
1331 if (bi >= 0 && (
size_t)bi < tb_table->get_num_blends()) {
1333 out <<
" " << blend <<
"\n";
1339 out <<
"\nraw data:\n";
1341 for (
int ai = 0; ai < num_arrays; ++ai) {
1344 nassertv(array !=
nullptr && aformat !=
nullptr);
1345 out <<
" " << *aformat <<
"\n";
1347 nassertv(handle !=
nullptr);
1348 const unsigned char *data = handle->get_read_pointer(
true);
1349 nassertv(data !=
nullptr);
1350 int stride = aformat->get_stride();
1351 int start = stride * row;
1352 if (data !=
nullptr) {
1354 dg.dump_hex(out, 4);
1366 void GeomVertexData::
1369 for (Cache::iterator ci = _cache.begin();
1372 CacheEntry *entry = (*ci).second;
1388 for (Cache::iterator ci = _cache.begin();
1393 cdata->_result =
nullptr;
1400 void GeomVertexData::
1401 packed_argb_to_uint8_rgba(
unsigned char *to,
int to_stride,
1402 const unsigned char *from,
int from_stride,
1404 if (gobj_cat.is_debug()) {
1406 <<
"packed_argb_to_uint8_rgba(" << (
void *)to <<
", " << to_stride
1407 <<
", " << (
const void *)from <<
", " << from_stride
1408 <<
", " << num_records <<
")\n";
1411 while (num_records > 0) {
1412 uint32_t dword = *(
const uint32_t *)from;
1419 from += from_stride;
1427 void GeomVertexData::
1428 uint8_rgba_to_packed_argb(
unsigned char *to,
int to_stride,
1429 const unsigned char *from,
int from_stride,
1431 if (gobj_cat.is_debug()) {
1433 <<
"uint8_rgba_to_packed_argb(" << (
void *)to <<
", " << to_stride
1434 <<
", " << (
const void *)from <<
", " << from_stride
1435 <<
", " << num_records <<
")\n";
1438 while (num_records > 0) {
1439 *(uint32_t *)to =
pack_abcd(from[3], from[0], from[1], from[2]);
1442 from += from_stride;
1451 void GeomVertexData::
1452 update_animated_vertices(GeomVertexData::CData *cdata,
Thread *current_thread) {
1453 PStatTimer timer(_char_pcollector, current_thread);
1457 if (gobj_cat.is_debug()) {
1459 <<
"Animating " << num_rows <<
" vertices for " <<
get_name()
1466 if (cdata->_animated_vertices ==
nullptr) {
1467 new_format = orig_format->get_post_animated_format();
1468 cdata->_animated_vertices =
1478 new_data->copy_from(
this,
true);
1482 if (slider_table !=
nullptr) {
1485 for (
int mi = 0; mi < num_morphs; mi++) {
1488 const SparseArray &sliders = slider_table->find_sliders(slider_name);
1492 for (
int sni = 0; sni < num_slider_subranges; ++sni) {
1495 for (
int sn = slider_begin; sn < slider_end; ++sn) {
1496 const VertexSlider *slider = slider_table->get_slider(sn);
1497 const SparseArray &rows = slider_table->get_slider_rows(sn);
1500 PN_stdfloat slider_value = slider->get_slider();
1501 if (slider_value != 0.0f) {
1509 if (data.get_column()->get_num_values() == 4) {
1510 if (data.get_column()->has_homogeneous_coord()) {
1512 for (
int i = 0; i < num_subranges; ++i) {
1515 data.set_row_unsafe(begin);
1516 delta.set_row_unsafe(begin);
1517 for (
int j = begin; j < end; ++j) {
1518 LPoint4 vertex = data.get_data4();
1519 LPoint3 d = delta.get_data3();
1520 d *= slider_value * vertex[3];
1521 data.set_data4(vertex[0] + d[0],
1529 for (
int i = 0; i < num_subranges; ++i) {
1532 data.set_row_unsafe(begin);
1533 delta.set_row_unsafe(begin);
1534 for (
int j = begin; j < end; ++j) {
1535 const LPoint4 &vertex = data.get_data4();
1536 LPoint4 d = delta.get_data4();
1537 data.set_data4(vertex + d * slider_value);
1544 for (
int i = 0; i < num_subranges; ++i) {
1547 data.set_row_unsafe(begin);
1548 delta.set_row_unsafe(begin);
1549 for (
int j = begin; j < end; ++j) {
1550 const LPoint3 &vertex = data.get_data3();
1551 LPoint3 d = delta.get_data3();
1552 data.set_data3(vertex + d * slider_value);
1565 if (tb_table !=
nullptr) {
1571 for (
int bi = 0; bi < num_blends; bi++) {
1572 tb_table->
get_blend(bi).update_blend(current_thread);
1582 int blend_array_index = orig_format->
get_array_with(InternalName::get_transform_blend());
1583 if (blend_array_index < 0) {
1586 <<
" has a transform_blend_table, but no transform_blend data.\n";
1592 if (blend_array_format->get_stride() == 2 &&
1593 blend_array_format->get_column(0)->get_component_bytes() == 2) {
1597 const unsigned short *blendt = (
const unsigned short *)blend_array_handle->
get_read_pointer(
true);
1600 for (ci = 0; ci < new_format->get_num_points(); ci++) {
1603 for (
int i = 0; i < num_subranges; ++i) {
1606 nassertv(begin < end);
1608 int first_vertex = begin;
1609 int first_bi = blendt[first_vertex];
1611 while (first_vertex < end) {
1617 int next_vertex = first_vertex;
1618 int next_bi = first_bi;
1620 while (next_vertex < end) {
1621 next_bi = blendt[next_vertex];
1622 if (next_bi != first_bi) {
1631 tb_table->
get_blend(first_bi).get_blend(mat, current_thread);
1632 new_data->do_transform_point_column(new_format, data, mat, first_vertex, next_vertex);
1634 first_vertex = next_vertex;
1640 for (ci = 0; ci < new_format->get_num_vectors(); ci++) {
1643 for (
int i = 0; i < num_subranges; ++i) {
1646 nassertv(begin < end);
1648 int first_vertex = begin;
1649 int first_bi = blendt[first_vertex];
1651 while (first_vertex < end) {
1657 int next_vertex = first_vertex;
1658 int next_bi = first_bi;
1660 while (next_vertex < end) {
1661 next_bi = blendt[next_vertex];
1662 if (next_bi != first_bi) {
1671 tb_table->
get_blend(first_bi).get_blend(mat, current_thread);
1672 new_data->do_transform_vector_column(new_format, data, mat, first_vertex, next_vertex);
1674 first_vertex = next_vertex;
1684 nassertv(blendi.has_column());
1687 for (ci = 0; ci < new_format->get_num_points(); ci++) {
1690 for (
int i = 0; i < num_subranges; ++i) {
1693 nassertv(begin < end);
1694 blendi.set_row_unsafe(begin);
1696 int first_vertex = begin;
1697 int first_bi = blendi.get_data1i();
1699 while (first_vertex < end) {
1705 int next_vertex = first_vertex;
1706 int next_bi = first_bi;
1708 while (next_vertex < end) {
1709 next_bi = blendi.get_data1i();
1710 if (next_bi != first_bi) {
1719 tb_table->
get_blend(first_bi).get_blend(mat, current_thread);
1720 new_data->do_transform_point_column(new_format, data, mat, first_vertex, next_vertex);
1722 first_vertex = next_vertex;
1728 for (ci = 0; ci < new_format->get_num_vectors(); ci++) {
1731 for (
int i = 0; i < num_subranges; ++i) {
1734 nassertv(begin != end);
1735 blendi.set_row_unsafe(begin);
1737 int first_vertex = begin;
1738 int first_bi = blendi.get_data1i();
1740 while (first_vertex < end) {
1746 int next_vertex = first_vertex;
1747 int next_bi = first_bi;
1749 while (next_vertex < end) {
1750 next_bi = blendi.get_data1i();
1751 if (next_bi != first_bi) {
1760 tb_table->
get_blend(first_bi).get_blend(mat, current_thread);
1761 new_data->do_transform_vector_column(new_format, data, mat, first_vertex, next_vertex);
1763 first_vertex = next_vertex;
1776 void GeomVertexData::
1778 const LMatrix4 &mat,
int begin_row,
int end_row) {
1782 if ((num_values == 3 || num_values == 4) &&
1788 size_t stride = data.get_stride();
1789 size_t num_rows = end_row - begin_row;
1791 datat += data_column->
get_start() + begin_row * stride;
1792 LMatrix4f matf = LCAST(
float, mat);
1794 if (num_values == 3) {
1795 table_xform_point3f(datat, num_rows, stride, matf);
1797 table_xform_vecbase4f(datat, num_rows, stride, matf);
1800 }
else if (num_values == 4) {
1803 data.set_row_unsafe(begin_row);
1804 for (
int j = begin_row; j < end_row; ++j) {
1805 LPoint4 vertex = data.get_data4();
1806 data.set_data4(vertex * mat);
1812 data.set_row_unsafe(begin_row);
1813 for (
int j = begin_row; j < end_row; ++j) {
1814 LPoint3 vertex = data.get_data3();
1815 data.set_data3(vertex * mat);
1823 void GeomVertexData::
1825 const LMatrix4 &mat,
int begin_row,
int end_row) {
1830 bool normalize =
false;
1833 LVecBase3 scale_sq(mat.get_row3(0).length_squared(),
1834 mat.get_row3(1).length_squared(),
1835 mat.get_row3(2).length_squared());
1836 if (IS_THRESHOLD_EQUAL(scale_sq[0], scale_sq[1], 2.0e-3f) &&
1837 IS_THRESHOLD_EQUAL(scale_sq[0], scale_sq[2], 2.0e-3f)) {
1839 LVecBase3 scale, shear, hpr;
1840 if (IS_THRESHOLD_EQUAL(scale_sq[0], 1, 2.0e-3f)) {
1843 }
else if (decompose_matrix(mat.get_upper_3(), scale, shear, hpr)) {
1845 compose_matrix(xform, LVecBase3(1, 1, 1), shear, hpr, LVecBase3::zero());
1852 xform.invert_from(mat);
1853 xform.transpose_in_place();
1860 if ((num_values == 3 || num_values == 4) &&
1866 size_t stride = data.get_stride();
1867 size_t num_rows = end_row - begin_row;
1869 datat += data_column->
get_start() + begin_row * stride;
1870 LMatrix4f matf = LCAST(
float, xform);
1873 table_xform_normal3f(datat, num_rows, stride, matf);
1874 }
else if (num_values == 3) {
1875 table_xform_vector3f(datat, num_rows, stride, matf);
1877 table_xform_vecbase4f(datat, num_rows, stride, matf);
1882 data.set_row_unsafe(begin_row);
1885 for (
int j = begin_row; j < end_row; ++j) {
1886 LVector3 vector = data.get_data3();
1889 data.set_data3(vector);
1892 for (
int j = begin_row; j < end_row; ++j) {
1893 LVector3 vector = data.get_data3();
1894 data.set_data3(vector * xform);
1904 void GeomVertexData::
1905 table_xform_point3f(
unsigned char *datat,
size_t num_rows,
size_t stride,
1906 const LMatrix4f &matf) {
1909 for (
size_t i = 0; i < num_rows; ++i) {
1910 LPoint3f &vertex = *(LPoint3f *)(&datat[i * stride]);
1919 void GeomVertexData::
1920 table_xform_normal3f(
unsigned char *datat,
size_t num_rows,
size_t stride,
1921 const LMatrix4f &matf) {
1924 for (
size_t i = 0; i < num_rows; ++i) {
1925 LNormalf &vertex = *(LNormalf *)(&datat[i * stride]);
1935 void GeomVertexData::
1936 table_xform_vector3f(
unsigned char *datat,
size_t num_rows,
size_t stride,
1937 const LMatrix4f &matf) {
1940 for (
size_t i = 0; i < num_rows; ++i) {
1941 LVector3f &vertex = *(LVector3f *)(&datat[i * stride]);
1950 void GeomVertexData::
1951 table_xform_vecbase4f(
unsigned char *datat,
size_t num_rows,
size_t stride,
1952 const LMatrix4f &matf) {
1953 #if defined(HAVE_EIGEN) && defined(LINMATH_ALIGN) 1956 if (((
size_t)datat & 0xf) != 0 || (stride & 0xf) != 0) {
1959 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)));
1960 for (
size_t i = 0; i < num_rows; ++i) {
1961 table.row(i) *= matf._m;
1965 #endif // HAVE_EIGEN 1970 for (
size_t i = 0; i < num_rows; ++i) {
1971 LVecBase4f &vertex = *(LVecBase4f *)(&datat[i * stride]);
2008 object->fillin(scan, manager);
2058 for (
size_t i = 0; i < cdata->_arrays.size(); ++i) {
2060 GeomVertexFormat::register_format(cdata->_format);
2062 cdata->_format = new_format;
2066 nassertv(new_array_format->is_data_subset_of(*array_obj->_array_format));
2068 manager->
change_pointer(array_obj->_array_format, new_array_format);
2069 array_obj->_array_format = new_array_format;
2072 if (cdata->_transform_table !=
nullptr) {
2074 TransformTable::register_table(cdata->_transform_table);
2075 manager->
change_pointer(cdata->_transform_table, new_transform_table);
2076 cdata->_transform_table = new_transform_table;
2079 if (cdata->_slider_table !=
nullptr) {
2081 SliderTable::register_table(cdata->_slider_table);
2083 cdata->_slider_table = new_slider_table;
2091 void GeomVertexData::
2104 return new CDataCache(*
this);
2114 Cache::iterator ci = _source->_cache.find(&_key);
2115 nassertv(ci != _source->_cache.end());
2116 nassertv((*ci).second ==
this);
2117 _source->_cache.erase(ci);
2123 void GeomVertexData::CacheEntry::
2124 output(ostream &out)
const {
2125 out <<
"vertex data " << (
void *)_source <<
" to " 2134 return new CData(*
this);
2141 void GeomVertexData::CData::
2147 Arrays::const_iterator ai;
2148 for (ai = _arrays.begin(); ai != _arrays.end(); ++ai) {
2153 manager->
write_pointer(dg, _transform_blend_table.get_read_pointer());
2161 int GeomVertexData::CData::
2167 Arrays::iterator ai;
2168 for (ai = _arrays.begin(); ai != _arrays.end(); ++ai) {
2184 all_rows.
set_range(0, adata->get_num_rows());
2186 if (_slider_table !=
nullptr) {
2187 int num_sliders = _slider_table->get_num_sliders();
2188 for (
int i = 0; i < num_sliders; ++i) {
2189 ((
SliderTable *)_slider_table.p())->set_slider_rows(i, all_rows);
2192 if (!_transform_blend_table.is_null()) {
2193 _transform_blend_table.get_unsafe_pointer()->set_rows(all_rows);
2204 void GeomVertexData::CData::
2207 _usage_hint = (UsageHint)scan.
get_uint8();
2210 _arrays.reserve(num_arrays);
2211 for (
size_t i = 0; i < num_arrays; ++i) {
2213 _arrays.push_back(
nullptr);
2224 int GeomVertexDataPipelineBase::
2225 get_num_bytes()
const {
2228 GeomVertexData::Arrays::const_iterator ai;
2229 for (ai = _cdata->_arrays.begin(); ai != _cdata->_arrays.end(); ++ai) {
2230 num_bytes += (*ai).get_read_pointer()->get_data_size_bytes();
2239 int GeomVertexDataPipelineReader::
2240 get_num_rows()
const {
2241 nassertr(_cdata->_format->get_num_arrays() == _cdata->_arrays.size(), 0);
2242 nassertr(_got_array_readers, 0);
2244 if (_cdata->_format->get_num_arrays() == 0) {
2250 int stride = _cdata->_format->get_array(0)->get_stride();
2251 return _array_readers[0]->get_data_size_bytes() / stride;
2257 bool GeomVertexDataPipelineReader::
2261 GeomVertexDataPipelineReader::NumericType &numeric_type,
2262 int &start,
int &stride)
const {
2263 nassertr(_got_array_readers,
false);
2266 if (_cdata->_format->get_array_info(name, array_index, column)) {
2267 array_reader = _array_readers[array_index];
2271 stride = _cdata->_format->get_array(array_index)->get_stride();
2280 bool GeomVertexDataPipelineReader::
2284 GeomVertexDataPipelineReader::NumericType &numeric_type,
2285 bool &normalized,
int &start,
int &stride,
int &divisor,
2286 int &num_elements,
int &element_stride)
const {
2287 nassertr(_got_array_readers,
false);
2290 if (_cdata->_format->get_array_info(name, array_index, column)) {
2291 array_reader = _array_readers[array_index];
2294 normalized = (column->
get_contents() == GeomEnums::C_color);
2296 stride = _cdata->_format->get_array(array_index)->get_stride();
2297 divisor = _cdata->_format->get_array(array_index)->get_divisor();
2308 bool GeomVertexDataPipelineReader::
2311 GeomVertexDataPipelineReader::NumericType &numeric_type,
2312 int &start,
int &stride)
const {
2313 nassertr(_got_array_readers,
false);
2314 int array_index = _cdata->_format->get_vertex_array_index();
2315 if (array_index >= 0) {
2318 array_reader = _array_readers[array_index];
2322 stride = _cdata->_format->get_array(array_index)->get_stride();
2331 bool GeomVertexDataPipelineReader::
2333 GeomVertexDataPipelineReader::NumericType &numeric_type,
2334 int &start,
int &stride)
const {
2335 nassertr(_got_array_readers,
false);
2336 int array_index = _cdata->_format->get_normal_array_index();
2337 if (array_index >= 0) {
2340 array_reader = _array_readers[array_index];
2343 stride = _cdata->_format->get_array(array_index)->get_stride();
2352 bool GeomVertexDataPipelineReader::
2355 GeomVertexDataPipelineReader::NumericType &numeric_type,
2356 int &start,
int &stride)
const {
2357 nassertr(_got_array_readers,
false);
2358 int array_index = _cdata->_format->get_color_array_index();
2359 if (array_index >= 0) {
2362 array_reader = _array_readers[array_index];
2366 stride = _cdata->_format->get_array(array_index)->get_stride();
2375 void GeomVertexDataPipelineReader::
2376 make_array_readers() {
2377 nassertv(!_got_array_readers);
2379 _array_readers.reserve(_cdata->_arrays.size());
2380 GeomVertexData::Arrays::const_iterator ai;
2381 for (ai = _cdata->_arrays.begin(); ai != _cdata->_arrays.end(); ++ai) {
2385 _got_array_readers =
true;
2391 int GeomVertexDataPipelineWriter::
2392 get_num_rows()
const {
2393 nassertr(_cdata->_format->get_num_arrays() == _cdata->_arrays.size(), 0);
2394 nassertr(_got_array_writers, 0);
2396 if (_cdata->_format->get_num_arrays() == 0) {
2402 int stride = _cdata->_format->get_array(0)->get_stride();
2403 return _array_writers[0]->get_data_size_bytes() / stride;
2409 bool GeomVertexDataPipelineWriter::
2410 set_num_rows(
int n) {
2411 nassertr(_got_array_writers,
false);
2412 nassertr(_cdata->_format->get_num_arrays() == _cdata->_arrays.size(),
false);
2414 bool any_changed =
false;
2416 int color_array = -1;
2417 int orig_color_rows = -1;
2419 for (
size_t i = 0; i < _cdata->_arrays.size(); i++) {
2421 if (_array_writers[i]->get_object()->has_column(InternalName::get_color())) {
2423 orig_color_rows = _array_writers[i]->get_num_rows();
2425 _array_writers[i]->set_num_rows(n);
2430 if (color_array >= 0 && orig_color_rows < n) {
2436 array_format->
get_column(InternalName::get_color());
2438 unsigned char *start =
2440 unsigned char *stop = start + array_writer->get_data_size_bytes();
2441 unsigned char *pointer = start + stride * orig_color_rows;
2448 case NT_packed_dcba:
2449 case NT_packed_dabc:
2450 while (pointer < stop) {
2457 while (pointer < stop) {
2458 PN_float32 *pi = (PN_float32 *)pointer;
2459 for (
int i = 0; i < num_values; i++) {
2467 while (pointer < stop) {
2468 PN_float64 *pi = (PN_float64 *)pointer;
2469 for (
int i = 0; i < num_values; i++) {
2481 nassertr(
false,
false);
2484 case NT_packed_ufloat:
2485 while (pointer < stop) {
2486 *(int32_t *)pointer = 0x781e03c0;
2494 _object->clear_cache_stage();
2496 _cdata->_animated_vertices.clear();
2505 bool GeomVertexDataPipelineWriter::
2506 unclean_set_num_rows(
int n) {
2507 nassertr(_got_array_writers,
false);
2508 nassertr(_cdata->_format->get_num_arrays() == _cdata->_arrays.size(),
false);
2510 bool any_changed =
false;
2512 for (
size_t i = 0; i < _cdata->_arrays.size(); i++) {
2521 _object->clear_cache_stage();
2523 _cdata->_animated_vertices.clear();
2532 bool GeomVertexDataPipelineWriter::
2533 reserve_num_rows(
int n) {
2534 nassertr(_got_array_writers,
false);
2535 nassertr(_cdata->_format->get_num_arrays() == _cdata->_arrays.size(),
false);
2537 bool any_changed =
false;
2539 for (
size_t i = 0; i < _cdata->_arrays.size(); i++) {
2552 modify_array(
size_t i) {
2553 nassertr(i < _cdata->_arrays.size(),
nullptr);
2556 if (_got_array_writers) {
2557 new_data = _array_writers[i]->get_object();
2559 new_data = _cdata->_arrays[i].get_write_pointer();
2562 _object->clear_cache_stage();
2564 _cdata->_animated_vertices_modified =
UpdateSeq();
2572 void GeomVertexDataPipelineWriter::
2574 nassertv(i < _cdata->_arrays.size());
2576 _object->clear_cache_stage();
2578 _cdata->_animated_vertices_modified =
UpdateSeq();
2580 if (_got_array_writers) {
2598 nassertv(source_format == dest_format);
2599 nassertv(source_row >= 0 && source_row < source.get_num_rows());
2600 nassertv(_got_array_writers);
2608 for (
size_t i = 0; i < num_arrays; ++i) {
2613 const unsigned char *source_array_data = source_array_handle->
get_read_pointer(
true);
2618 memcpy(dest_array_data + stride * dest_row,
2619 source_array_data + stride * source_row,
2627 void GeomVertexDataPipelineWriter::
2628 make_array_writers() {
2629 nassertv(!_got_array_writers);
2631 _array_writers.reserve(_cdata->_arrays.size());
2632 GeomVertexData::Arrays::iterator ai;
2633 for (ai = _cdata->_arrays.begin(); ai != _cdata->_arrays.end(); ++ai) {
2637 _object->clear_cache_stage();
2639 _cdata->_animated_vertices_modified =
UpdateSeq();
2641 _got_array_writers =
true;
2647 void GeomVertexDataPipelineWriter::
2648 delete_array_writers() {
2649 nassertv(_got_array_writers);
2651 _array_writers.clear();
2652 _got_array_writers =
false;
get_animation_type
Returns the type of animation represented by this spec.
set_transform_table
Replaces the TransformTable on this vertex data with the indicated table.
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,...
static unsigned int unpack_abcd_d(uint32_t data)
Returns the fourth packed value from a DirectX-style NT_packed_abcd.
This class records a set of integers, where each integer is either present or not present in the set.
bool is_uint8_rgba() const
Returns true if this column is the standard OpenGL representation of 4-component color: C_color,...
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.
Contents get_contents() const
Returns the token representing the semantic meaning of the stored value.
void transform_vertices(const LMatrix4 &mat)
Applies the indicated transform matrix to all of the vertices in the GeomVertexData.
bool unclean_set_num_rows(int n)
This method behaves like set_num_rows(), except the new data is not initialized.
uint8_t get_uint8()
Extracts an unsigned 8-bit integer.
void unclean_set_format(const GeomVertexFormat *format)
Changes the format of the vertex data, without reformatting the data to match.
bool set_column(int column)
Sets up the reader to use the nth data type of the GeomVertexFormat, numbering from 0.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
void read_cdata(DatagramIterator &scan, PipelineCyclerBase &cycler)
Reads in the indicated CycleData object.
This object describes how the vertex animation, if any, represented in a GeomVertexData is encoded.
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.
NumericType get_numeric_type() const
Returns the token representing the numeric type of the data storage.
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,...
int get_array() const
Returns the array index containing the data type that the writer is working on.
This class is similar to CycleDataWriter, except it allows writing to a particular stage of the pipel...
A single page of data maintained by a PipelineCycler.
Base class for objects that can be written to and read from Bam files.
void write_cdata(Datagram &packet, const PipelineCyclerBase &cycler)
Writes out the indicated CycleData object.
bool is_zero() const
Returns true if the entire bitmask is zero, false otherwise.
bool is_packed_argb() const
Returns true if this column is the standard DirectX representation of 4-component color: C_color,...
static unsigned int unpack_abcd_b(uint32_t data)
Returns the second packed value from a DirectX-style NT_packed_abcd.
const LVecBase4 & get_data4()
Returns the data associated with the read row, expressed as a 4-component value, and advances the rea...
This is an abstract base class that retains some slider value, which is a linear value that typically...
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.
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
This data object is returned by GeomVertexArrayData::get_handle() or modify_handle().
static unsigned int unpack_abcd_c(uint32_t data)
Returns the third packed value from a DirectX-style NT_packed_abcd.
bool request_resident() const
Returns true if the vertex data is currently resident in memory.
Encapsulates the data from a GeomVertexData, pre-fetched for one stage of the pipeline.
set_format
Changes the format of the vertex data.
std::string get_string()
Extracts a variable-length string.
int get_file_minor_ver() const
Returns the minor version number of the Bam file currently being read.
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...
This defines how a single column is interleaved within a vertex array stored within a Geom.
set_array
Replaces the indicated vertex data array with a completely new array.
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
This template class calls PipelineCycler::read_unlocked(), and then provides a transparent read-only ...
set_name
Changes the name of the vertex data.
int get_num_elements() const
Returns the number of times this column is repeated.
CPT(GeomVertexData) GeomVertexData
Returns a new GeomVertexData that represents the same contents as this one, with all data types match...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_format
Returns a pointer to the GeomVertexFormat structure that defines this data.
void set_transform_blend_table(const TransformBlendTable *table)
Replaces the TransformBlendTable on this vertex data with the indicated table.
set_slider_table
Replaces the SliderTable on this vertex data with the indicated table.
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...
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 parse_params(const FactoryParams ¶ms, DatagramIterator &scan, BamReader *&manager)
Takes in a FactoryParams, passed from a WritableFactory into any TypedWritable's make function,...
void add_uint16(uint16_t value)
Adds an unsigned 16-bit integer to the datagram.
get_current_thread
Returns a pointer to the currently-executing Thread object.
int get_element_stride() const
This value is only relevant for matrix types.
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.
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().
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
Similar to MutexHolder, but for a light mutex.
void acquire() const
Grabs the lightMutex if it is available.
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.
virtual bool require_fully_complete() const
Some objects require all of their nested pointers to have been completed before the objects themselve...
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
This template class calls PipelineCycler::read() in the constructor and PipelineCycler::release_read(...
void add_string(const std::string &str)
Adds a variable-length string to the datagram.
void release() const
Releases the lightMutex.
An instance of this class is passed to the Factory when requesting it to do its business and construc...
int get_num_values() const
Returns the number of numeric values of the column: the number of distinct numeric values that go int...
void register_factory(TypeHandle handle, CreateFunc *func, void *user_data=nullptr)
Registers a new kind of thing the Factory will be able to create.
void operator=(const GeomVertexData ©)
The copy assignment operator is not pipeline-safe.
PT(CopyOnWriteObject) GeomVertexData
Required to implement CopyOnWriteObject.
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.
virtual void evict_callback()
Called when the entry is evicted from the cache, this should clean up the owning object appropriately...
size_t get_num_subranges() const
Returns the number of separate subranges stored in the SparseArray.
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).
bool is_inverse() const
If this is true, the SparseArray is actually defined as a list of subranges of integers that are *not...
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().
get_indexed_transforms
This is only meaningful for animation_type AT_hardware.
void register_finalize(TypedWritable *whom)
Should be called by an object reading itself from the Bam file to indicate that this particular objec...
This template class calls PipelineCycler::write() in the constructor and PipelineCycler::release_writ...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
int get_num_rows() const
Returns the number of rows stored within all the arrays.
unsigned char * get_write_pointer()
Returns a writable pointer to the beginning of the actual data stream.
int get_data1i()
Returns the data associated with the read row, expressed as a 1-component value, and advances the rea...
Encodes a string name in a hash table, mapping it to a pointer.
int get_start() const
Returns the byte within the array record at which this column starts.
static unsigned int unpack_abcd_a(uint32_t data)
Returns the first packed value from a DirectX-style NT_packed_abcd.
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.
bool is_registered() const
Returns true if this table has been registered.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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...
void set_range(int low_bit, int size)
Sets the indicated range of bits on.
This base class provides basic reference counting, but also can be used with a CopyOnWritePointer to ...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
set_usage_hint
Changes the UsageHint hint for this vertex data, and for all of the arrays that share this data.
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.
uint16_t get_uint16()
Extracts an unsigned 16-bit integer.
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
int get_subrange_begin(size_t n) const
Returns the first numeric element in the nth subrange.
bool has_column() const
Returns true if a valid data type has been successfully set, or false if the data type does not exist...
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...
void clear_rows()
Removes all of the rows from the arrays; functionally equivalent to set_num_rows(0) (but faster).
bool read_pointer(DatagramIterator &scan)
The interface for reading a pointer to another object from a Bam file.
static UpdateSeq get_next_modified()
Returns a monotonically increasing sequence.
bool is_at_end() const
Returns true if the reader is currently at the end of the list of vertices, false otherwise.
int compare_to(const GeomVertexData &other) const
Returns 0 if the two objects are equivalent, even if they are not the same pointer.
get_usage_hint
Returns the usage hint that was passed to the constructor, and which will be passed to each array dat...
void add_uint8(uint8_t value)
Adds an unsigned 8-bit integer to the datagram.
bool set_column(int column)
Sets up the writer to use the nth data type of the GeomVertexFormat, numbering from 0.
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.
A class to retrieve the individual data elements previously stored in a Datagram.
const InternalName * get_name() const
Returns the name of this particular data field, e.g.
get_name
Returns the name passed to the constructor, if any.
int get_total_bytes() const
Returns the number of bytes used by each element of the column: component_bytes * num_components.
TypeHandle is the identifier used to differentiate C++ class types.
This is a sequence number that increments monotonically.
bool set_num_rows(int n)
Sets the length of the array to n rows.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
virtual void finalize(BamReader *manager)
Called by the BamReader to perform any final actions needed for setting up the object after all objec...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This object provides the functionality of both a GeomVertexReader and a GeomVertexWriter,...
This is the data for one array of a GeomVertexData structure.
void clear_cache_stage()
Removes all of the previously-cached results of convert_to(), at the current pipeline stage and upstr...
void write_pointer(Datagram &packet, const TypedWritable *dest)
The interface for writing a pointer to another object to a Bam file.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
static void register_with_read_factory()
Tells the BamReader how to create objects of type GeomVertexData.