15 #include "geomVertexData.h" 17 #include "geomVertexReader.h" 18 #include "geomVertexWriter.h" 19 #include "geomVertexRewriter.h" 20 #include "pStatTimer.h" 21 #include "bamReader.h" 22 #include "bamWriter.h" 27 TypeHandle GeomVertexData::CDataCache::_type_handle;
28 TypeHandle GeomVertexData::CacheEntry::_type_handle;
29 TypeHandle GeomVertexData::CData::_type_handle;
30 TypeHandle GeomVertexDataPipelineReader::_type_handle;
31 TypeHandle GeomVertexDataPipelineWriter::_type_handle;
33 PStatCollector GeomVertexData::_convert_pcollector(
"*:Munge:Convert");
34 PStatCollector GeomVertexData::_scale_color_pcollector(
"*:Munge:Scale color");
35 PStatCollector GeomVertexData::_set_color_pcollector(
"*:Munge:Set color");
36 PStatCollector GeomVertexData::_animation_pcollector(
"*:Animation");
47 _char_pcollector(_animation_pcollector,
"unnamed"),
48 _skinning_pcollector(_char_pcollector,
"Skinning"),
49 _morphs_pcollector(_char_pcollector,
"Morphs"),
50 _blends_pcollector(_char_pcollector,
"Calc blends")
70 GeomVertexData(
const string &name,
71 const GeomVertexFormat *format,
72 GeomVertexData::UsageHint usage_hint) :
75 _skinning_pcollector(_char_pcollector,
"Skinning"),
76 _morphs_pcollector(_char_pcollector,
"Morphs"),
77 _blends_pcollector(_char_pcollector,
"Calc blends")
79 nassertv(format->is_registered());
83 OPEN_ITERATE_ALL_STAGES(_cycler) {
84 CDStageWriter cdata(_cycler, pipeline_stage);
85 cdata->_format = format;
86 cdata->_usage_hint = usage_hint;
87 int num_arrays = format->get_num_arrays();
88 for (
int i = 0; i < num_arrays; i++) {
90 (format->get_array(i), usage_hint);
91 cdata->_arrays.push_back(array.p());
94 CLOSE_ITERATE_ALL_STAGES(_cycler);
106 _cycler(copy._cycler),
107 _char_pcollector(copy._char_pcollector),
108 _skinning_pcollector(copy._skinning_pcollector),
109 _morphs_pcollector(copy._morphs_pcollector),
110 _blends_pcollector(copy._blends_pcollector)
112 OPEN_ITERATE_ALL_STAGES(_cycler) {
113 CDStageWriter cdata(_cycler, pipeline_stage);
115 cdata->_animated_vertices = NULL;
116 cdata->_animated_vertices_modified =
UpdateSeq();
118 CLOSE_ITERATE_ALL_STAGES(_cycler);
131 const GeomVertexFormat *format) :
134 _cycler(copy._cycler),
135 _char_pcollector(copy._char_pcollector),
136 _skinning_pcollector(copy._skinning_pcollector),
137 _morphs_pcollector(copy._morphs_pcollector),
138 _blends_pcollector(copy._blends_pcollector)
140 nassertv(format->is_registered());
143 OPEN_ITERATE_ALL_STAGES(_cycler) {
146 UsageHint usage_hint = cdata->_usage_hint;
147 cdata->_arrays.clear();
148 cdata->_format = format;
149 int num_arrays = format->get_num_arrays();
150 for (
int i = 0; i < num_arrays; i++) {
152 (format->get_array(i), usage_hint);
153 cdata->_arrays.push_back(array.p());
157 cdata->_animated_vertices = NULL;
158 cdata->_animated_vertices_modified =
UpdateSeq();
160 CLOSE_ITERATE_ALL_STAGES(_cycler);
173 CopyOnWriteObject::operator = (copy);
178 _cycler = copy._cycler;
179 _char_pcollector = copy._char_pcollector;
180 _skinning_pcollector = copy._skinning_pcollector;
181 _morphs_pcollector = copy._morphs_pcollector;
182 _blends_pcollector = copy._blends_pcollector;
184 OPEN_ITERATE_ALL_STAGES(_cycler) {
187 cdata->_animated_vertices = NULL;
188 cdata->_animated_vertices_modified =
UpdateSeq();
190 CLOSE_ITERATE_ALL_STAGES(_cycler);
212 CDReader other_cdata(other._cycler);
214 if (cdata->_usage_hint != other_cdata->_usage_hint) {
215 return (
int)cdata->_usage_hint - (int)other_cdata->_usage_hint;
217 if (cdata->_format != other_cdata->_format) {
218 return cdata->_format < other_cdata->_format ? -1 : 1;
220 if (cdata->_transform_table != other_cdata->_transform_table) {
221 return cdata->_transform_table < other_cdata->_transform_table ? -1 : 1;
223 if (cdata->_transform_blend_table != other_cdata->_transform_blend_table) {
224 return cdata->_transform_blend_table < other_cdata->_transform_blend_table ? -1 : 1;
226 if (cdata->_slider_table != other_cdata->_slider_table) {
227 return cdata->_slider_table < other_cdata->_slider_table ? -1 : 1;
229 if (cdata->_arrays.size() != other_cdata->_arrays.size()) {
230 return (
int)cdata->_arrays.size() - (int)other_cdata->_arrays.size();
232 for (
size_t i = 0; i < cdata->_arrays.size(); ++i) {
233 if (cdata->_arrays[i] != other_cdata->_arrays[i]) {
234 return cdata->_arrays[i] < other_cdata->_arrays[i] ? -1 : 1;
251 _skinning_pcollector =
PStatCollector(_char_pcollector,
"Skinning");
253 _blends_pcollector =
PStatCollector(_char_pcollector,
"Calc blends");
270 cdata->_usage_hint = usage_hint;
273 for (ai = cdata->_arrays.begin();
274 ai != cdata->_arrays.end();
277 array_obj->set_usage_hint(usage_hint);
281 cdata->_animated_vertices_modified =
UpdateSeq();
298 nassertv(format->is_registered());
302 if (format == cdata->_format) {
307 CDWriter cdataw(_cycler, cdata,
true);
314 cdataw->_format = format;
316 UsageHint usage_hint = cdataw->_usage_hint;
317 cdataw->_arrays.clear();
318 int num_arrays = cdataw->_format->get_num_arrays();
319 for (
int i = 0; i < num_arrays; i++) {
321 (cdataw->_format->get_array(i), usage_hint);
322 cdataw->_arrays.push_back(array.p());
327 copy_from(orig_data,
false, current_thread);
331 cdataw->_animated_vertices.clear();
350 nassertv(format->is_registered());
354 if (format == cdata->_format) {
360 nassertv(format->get_num_arrays() == cdata->_format->get_num_arrays());
361 for (
int ai = 0; ai < format->get_num_arrays(); ++ai) {
362 nassertv(format->get_array(ai)->get_stride() == cdata->_format->get_array(ai)->get_stride());
364 nassertv(cdata->_arrays.size() == cdata->_format->get_num_arrays());
367 CDWriter cdataw(_cycler, cdata,
true);
370 cdataw->_format = format;
372 for (
size_t ai = 0; ai < cdataw->_arrays.size(); ++ai) {
374 array_obj->_array_format = format->get_array(ai);
379 cdataw->_animated_vertices.clear();
396 CDWriter cdata(_cycler,
true, current_thread);
397 nassertv(cdata->_format->get_num_arrays() == (int)cdata->_arrays.size());
400 for (ai = cdata->_arrays.begin();
401 ai != cdata->_arrays.end();
404 array_obj->clear_rows();
408 cdata->_animated_vertices.clear();
429 CDWriter cdata(_cycler,
true, current_thread);
433 cdata->_animated_vertices_modified =
UpdateSeq();
449 modify_transform_blend_table() {
454 cdata->_animated_vertices_modified =
UpdateSeq();
456 return cdata->_transform_blend_table.get_write_pointer();
478 cdata->_animated_vertices_modified =
UpdateSeq();
504 cdata->_animated_vertices_modified =
UpdateSeq();
518 bool resident =
true;
520 Arrays::const_iterator ai;
521 for (ai = cdata->_arrays.begin();
522 ai != cdata->_arrays.end();
524 if (!(*ai).get_read_pointer()->request_resident()) {
555 const GeomVertexFormat *source_format = source->
get_format();
556 const GeomVertexFormat *dest_format =
get_format();
559 int num_arrays = source_format->get_num_arrays();
566 for (source_i = 0; source_i < num_arrays; ++source_i) {
567 const GeomVertexArrayFormat *source_array_format =
568 source_format->get_array(source_i);
570 bool array_done =
false;
572 int dest_num_arrays = dest_format->get_num_arrays();
574 dest_i < dest_num_arrays && !array_done;
576 const GeomVertexArrayFormat *dest_array_format =
577 dest_format->get_array(dest_i);
578 if (dest_array_format->is_data_subset_of(*source_array_format)) {
580 if (keep_data_objects) {
585 dest_data->modify_handle()->copy_data_from(source_data->get_handle());
588 if (
get_array(dest_i) != source->get_array(source_i)) {
589 set_array(dest_i, source->get_array(source_i));
594 done_arrays.insert(dest_i);
604 for (source_i = 0; source_i < num_arrays; ++source_i) {
607 const unsigned char *array_data = array_handle->get_read_pointer(
true);
608 const GeomVertexArrayFormat *source_array_format = source_format->get_array(source_i);
609 int num_columns = source_array_format->get_num_columns();
610 for (
int di = 0; di < num_columns; ++di) {
611 const GeomVertexColumn *source_column = source_array_format->get_column(di);
613 int dest_i = dest_format->get_array_with(source_column->
get_name());
614 if (dest_i >= 0 && done_arrays.count(dest_i) == 0) {
616 const GeomVertexArrayFormat *dest_array_format =
617 dest_format->get_array(dest_i);
619 dest_array_format->get_column(source_column->
get_name());
626 unsigned char *dest_array_data = dest_handle->get_write_pointer();
628 bytewise_copy(dest_array_data + dest_column->
get_start(),
629 dest_array_format->get_stride(),
630 array_data + source_column->
get_start(), source_array_format->get_stride(),
631 source_column, num_rows);
638 unsigned char *dest_array_data = dest_handle->get_write_pointer();
640 uint8_rgba_to_packed_argb
641 (dest_array_data + dest_column->
get_start(),
642 dest_array_format->get_stride(),
643 array_data + source_column->
get_start(), source_array_format->get_stride(),
652 unsigned char *dest_array_data = dest_handle->get_write_pointer();
654 packed_argb_to_uint8_rgba
655 (dest_array_data + dest_column->
get_start(),
656 dest_array_format->get_stride(),
657 array_data + source_column->
get_start(), source_array_format->get_stride(),
662 if (gobj_cat.is_debug()) {
664 <<
"generic copy " << *dest_column <<
" from " 665 << *source_column <<
"\n";
683 if (source_animation != dest_animation) {
707 indices[i] = add_transform(transform_table, blend.
get_transform(i),
726 int index = add_transform(transform_table, blend.
get_transform(i),
728 nassertv(index <= 4);
737 clear_transform_blend_table();
758 int source_row,
Thread *current_thread) {
759 const GeomVertexFormat *source_format = source->
get_format();
760 const GeomVertexFormat *dest_format =
get_format();
761 nassertv(source_format == dest_format);
762 nassertv(source_row >= 0 && source_row < source->
get_num_rows());
769 int num_arrays = source_format->get_num_arrays();
771 for (
int i = 0; i < num_arrays; ++i) {
774 unsigned char *dest_array_data = dest_handle->get_write_pointer();
778 const unsigned char *source_array_data = source_array_handle->get_read_pointer(
true);
780 const GeomVertexArrayFormat *array_format = source_format->get_array(i);
781 int stride = array_format->get_stride();
783 memcpy(dest_array_data + stride * dest_row,
784 source_array_data + stride * source_row,
797 convert_to(
const GeomVertexFormat *new_format)
const {
812 Cache::const_iterator ci = _cache.find(&key);
813 if (ci == _cache.end()) {
817 entry = (*ci).second;
819 nassertr(entry->_source ==
this, NULL);
824 entry->refresh(current_thread);
828 return cdata->_result;
838 if (gobj_cat.is_debug()) {
841 <<
" to " << *new_format <<
"\n";
847 new_data->set_transform_blend_table(get_transform_blend_table());
850 new_data->copy_from(
this,
false);
855 #ifdef USE_MOVE_SEMANTICS 863 bool inserted = ((
GeomVertexData *)
this)->_cache.insert(Cache::value_type(&entry->_key, entry)).second;
874 entry->record(current_thread);
879 cdata->_result = new_data;
894 scale_color(
const LVecBase4 &color_scale)
const {
896 get_format()->get_column(InternalName::get_color());
905 data.
set_data4(color[0] * color_scale[0],
906 color[1] * color_scale[1],
907 color[2] * color_scale[2],
908 color[3] * color_scale[3]);
925 scale_color(
const LVecBase4 &color_scale,
int num_components,
926 GeomVertexData::NumericType numeric_type,
927 GeomVertexData::Contents contents)
const {
928 int old_color_array =
get_format()->get_array_with(InternalName::get_color());
929 if (old_color_array == -1) {
931 return set_color(color_scale, num_components, numeric_type, contents);
936 if (gobj_cat.is_debug()) {
938 <<
"Scaling color for " << num_rows <<
" vertices by " 939 << color_scale <<
".\n";
944 (InternalName::get_color(), num_components, numeric_type, contents);
950 for (
int i = 0; i < num_rows; i++) {
953 color[1] * color_scale[1],
954 color[2] * color_scale[2],
955 color[3] * color_scale[3]);
971 set_color(
const LColor &color)
const {
973 get_format()->get_column(InternalName::get_color());
998 set_color(
const LColor &color,
int num_components,
999 GeomVertexData::NumericType numeric_type,
1000 GeomVertexData::Contents contents)
const {
1001 if (gobj_cat.is_debug()) {
1003 <<
"Setting color for " <<
get_num_rows() <<
" vertices to " 1009 (InternalName::get_color(), num_components, numeric_type, contents);
1032 reverse_normals()
const {
1034 get_format()->get_column(InternalName::get_normal());
1073 animate_vertices(
bool force,
Thread *current_thread)
const {
1074 #ifdef DO_PIPELINING 1079 CDReader cdata(_cycler, current_thread);
1080 if (cdata->_format->get_animation().get_animation_type() != AT_panda) {
1084 #endif // DO_PIPELINING 1092 if (cdata->_format->get_animation().get_animation_type() != AT_panda) {
1099 if (!cdata->_transform_blend_table.is_null()) {
1100 if (cdata->_slider_table != (
SliderTable *)NULL) {
1102 max(cdata->_transform_blend_table.get_read_pointer()->get_modified(current_thread),
1103 cdata->_slider_table->get_modified(current_thread));
1105 modified = cdata->_transform_blend_table.get_read_pointer()->get_modified(current_thread);
1108 }
else if (cdata->_slider_table != (
SliderTable *)NULL) {
1109 modified = cdata->_slider_table->get_modified(current_thread);
1118 if (cdata->_animated_vertices_modified == modified &&
1121 return cdata->_animated_vertices;
1128 return cdata->_animated_vertices;
1134 cdataw->_animated_vertices_modified = modified;
1135 ((
GeomVertexData *)
this)->update_animated_vertices(cdataw, current_thread);
1137 return cdataw->_animated_vertices;
1149 void GeomVertexData::
1150 clear_animated_vertices() {
1152 cdata->_animated_vertices_modified.clear();
1153 cdata->_animated_vertices.clear();
1180 if (end_row <= begin_row) {
1185 const GeomVertexFormat *format =
get_format();
1188 for (ci = 0; ci < format->get_num_points(); ci++) {
1190 do_transform_point_column(format, data, mat, begin_row, end_row);
1193 for (ci = 0; ci < format->get_num_vectors(); ci++) {
1195 do_transform_vector_column(format, data, mat, begin_row, end_row);
1214 const GeomVertexFormat *format =
get_format();
1217 for (ci = 0; ci < format->get_num_points(); ci++) {
1223 do_transform_point_column(format, data, mat, begin_row, end_row);
1227 for (ci = 0; ci < format->get_num_vectors(); ci++) {
1233 do_transform_vector_column(format, data, mat, begin_row, end_row);
1243 void GeomVertexData::
1244 bytewise_copy(
unsigned char *to,
int to_stride,
1245 const unsigned char *from,
int from_stride,
1248 if (gobj_cat.is_debug()) {
1250 <<
"bytewise_copy(" << (
void *)to <<
", " << to_stride
1251 <<
", " << (
const void *)from <<
", " << from_stride
1252 <<
", " << *from_type <<
", " << num_records <<
")\n";
1263 while (num_records > 0) {
1266 from += from_stride;
1287 replace_column(InternalName *name,
int num_components,
1288 GeomVertexData::NumericType numeric_type,
1289 GeomVertexData::Contents contents)
const {
1291 PT(GeomVertexFormat) new_format =
new GeomVertexFormat(*cdata->_format);
1294 bool removed_type_array =
false;
1295 int old_type_array = cdata->_format->get_array_with(name);
1296 if (old_type_array != -1) {
1297 GeomVertexArrayFormat *array_format = new_format->modify_array(old_type_array);
1298 if (array_format->get_num_columns() == 1) {
1301 new_format->remove_array(old_type_array);
1302 removed_type_array =
true;
1307 array_format->remove_column(name);
1312 int new_type_array = -1;
1313 if (num_components != 0) {
1314 PT(GeomVertexArrayFormat) type_array_format =
1315 new GeomVertexArrayFormat(name, num_components, numeric_type, contents);
1316 new_type_array = new_format->add_array(type_array_format);
1319 CPT(GeomVertexFormat) format =
1320 GeomVertexFormat::register_format(new_format);
1322 if (gobj_cat.is_debug()) {
1324 <<
"Replacing data type " << *name <<
"; converting " 1326 << *cdata->_format <<
" to " << *format <<
"\n";
1333 for (
int i = 0; i < num_arrays; ++i) {
1334 if (i == old_type_array) {
1335 if (!removed_type_array) {
1349 if (new_type_array != -1) {
1350 nassertr(j == new_type_array, new_data);
1357 new_data->set_array(j, new_array);
1368 void GeomVertexData::
1369 output(ostream &out)
const {
1381 void GeomVertexData::
1382 write(ostream &out,
int indent_level)
const {
1384 indent(out, indent_level) <<
get_name() <<
"\n";
1386 get_format()->write_with_data(out, indent_level + 2,
this);
1389 indent(out, indent_level)
1390 <<
"Transform blend table:\n";
1391 table->write(out, indent_level + 2);
1401 void GeomVertexData::
1402 describe_vertex(ostream &out,
int row)
const {
1405 out <<
"Vertex " << row <<
":\n";
1409 const GeomVertexFormat *format =
get_format();
1412 if (format->get_animation().get_animation_type() == AT_panda) {
1413 tb_table = get_transform_blend_table();
1416 int num_columns = format->get_num_columns();
1417 for (
int ci = 0; ci < num_columns; ++ci) {
1418 int ai = format->get_array_with(ci);
1426 for (
int v = 0; v < num_values; v++) {
1431 if (column->
get_name() == InternalName::get_transform_blend() &&
1437 if (bi >= 0 && bi < tb_table->get_num_blends()) {
1439 out <<
" " << blend <<
"\n";
1445 out <<
"\nraw data:\n";
1446 int num_arrays = format->get_num_arrays();
1447 for (
int ai = 0; ai < num_arrays; ++ai) {
1449 const GeomVertexArrayFormat *aformat = format->get_array(ai);
1450 nassertv(array != NULL && aformat != NULL);
1451 out <<
" " << *aformat <<
"\n";
1454 const unsigned char *data = handle->get_read_pointer(
true);
1455 nassertv(data != NULL);
1456 int stride = aformat->get_stride();
1457 int start = stride * row;
1476 void GeomVertexData::
1479 for (Cache::iterator ci = _cache.begin();
1502 for (Cache::iterator ci = _cache.begin();
1507 cdata->_result = NULL;
1517 void GeomVertexData::
1518 packed_argb_to_uint8_rgba(
unsigned char *to,
int to_stride,
1519 const unsigned char *from,
int from_stride,
1521 if (gobj_cat.is_debug()) {
1523 <<
"packed_argb_to_uint8_rgba(" << (
void *)to <<
", " << to_stride
1524 <<
", " << (
const void *)from <<
", " << from_stride
1525 <<
", " << num_records <<
")\n";
1528 while (num_records > 0) {
1529 PN_uint32 dword = *(
const PN_uint32 *)from;
1536 from += from_stride;
1547 void GeomVertexData::
1548 uint8_rgba_to_packed_argb(
unsigned char *to,
int to_stride,
1549 const unsigned char *from,
int from_stride,
1551 if (gobj_cat.is_debug()) {
1553 <<
"uint8_rgba_to_packed_argb(" << (
void *)to <<
", " << to_stride
1554 <<
", " << (
const void *)from <<
", " << from_stride
1555 <<
", " << num_records <<
")\n";
1558 while (num_records > 0) {
1559 *(PN_uint32 *)to =
pack_abcd(from[3], from[0], from[1], from[2]);
1562 from += from_stride;
1574 void GeomVertexData::
1575 update_animated_vertices(GeomVertexData::CData *cdata,
Thread *current_thread) {
1576 PStatTimer timer(_char_pcollector, current_thread);
1580 if (gobj_cat.is_debug()) {
1582 <<
"Animating " << num_rows <<
" vertices for " <<
get_name()
1586 const GeomVertexFormat *orig_format = cdata->_format;
1587 CPT(GeomVertexFormat) new_format = orig_format;
1590 new_format = orig_format->get_post_animated_format();
1591 cdata->_animated_vertices =
1602 new_data->copy_from(
this,
true);
1605 CPT(
SliderTable) slider_table = cdata->_slider_table;
1608 int num_morphs = orig_format->get_num_morphs();
1609 for (
int mi = 0; mi < num_morphs; mi++) {
1610 CPT(InternalName) slider_name = orig_format->get_morph_slider(mi);
1612 const SparseArray &sliders = slider_table->find_sliders(slider_name);
1616 for (
int sni = 0; sni < num_slider_subranges; ++sni) {
1619 for (
int sn = slider_begin; sn < slider_end; ++sn) {
1620 const VertexSlider *slider = slider_table->get_slider(sn);
1621 const SparseArray &rows = slider_table->get_slider_rows(sn);
1624 PN_stdfloat slider_value = slider->get_slider();
1625 if (slider_value != 0.0f) {
1626 CPT(InternalName) base_name = orig_format->get_morph_base(mi);
1627 CPT(InternalName) delta_name = orig_format->get_morph_delta(mi);
1636 for (
int i = 0; i < num_subranges; ++i) {
1641 for (
int j = begin; j < end; ++j) {
1644 d *= slider_value * vertex[3];
1653 for (
int i = 0; i < num_subranges; ++i) {
1658 for (
int j = begin; j < end; ++j) {
1661 data.
set_data4(vertex + d * slider_value);
1668 for (
int i = 0; i < num_subranges; ++i) {
1673 for (
int j = begin; j < end; ++j) {
1676 data.
set_data3(vertex + d * slider_value);
1694 int num_blends = tb_table->get_num_blends();
1695 for (
int bi = 0; bi < num_blends; bi++) {
1696 tb_table->get_blend(bi).update_blend(current_thread);
1706 int blend_array_index = orig_format->get_array_with(InternalName::get_transform_blend());
1707 if (blend_array_index < 0) {
1710 <<
" has a transform_blend_table, but no transform_blend data.\n";
1714 CPT(GeomVertexArrayFormat) blend_array_format = orig_format->get_array(blend_array_index);
1716 if (blend_array_format->get_stride() == 2 &&
1717 blend_array_format->get_column(0)->get_component_bytes() == 2) {
1720 CPT(
GeomVertexArrayDataHandle) blend_array_handle = cdata->_arrays[blend_array_index].get_read_pointer()->get_handle(current_thread);
1721 const unsigned short *blendt = (
const unsigned short *)blend_array_handle->get_read_pointer(
true);
1724 for (ci = 0; ci < new_format->get_num_points(); ci++) {
1727 for (
int i = 0; i < num_subranges; ++i) {
1730 nassertv(begin < end);
1732 int first_vertex = begin;
1733 int first_bi = blendt[first_vertex];
1735 while (first_vertex < end) {
1741 int next_vertex = first_vertex;
1742 int next_bi = first_bi;
1744 while (next_vertex < end) {
1745 next_bi = blendt[next_vertex];
1746 if (next_bi != first_bi) {
1755 tb_table->get_blend(first_bi).get_blend(mat, current_thread);
1756 new_data->do_transform_point_column(new_format, data, mat, first_vertex, next_vertex);
1758 first_vertex = next_vertex;
1764 for (ci = 0; ci < new_format->get_num_vectors(); ci++) {
1767 for (
int i = 0; i < num_subranges; ++i) {
1770 nassertv(begin < end);
1772 int first_vertex = begin;
1773 int first_bi = blendt[first_vertex];
1775 while (first_vertex < end) {
1781 int next_vertex = first_vertex;
1782 int next_bi = first_bi;
1784 while (next_vertex < end) {
1785 next_bi = blendt[next_vertex];
1786 if (next_bi != first_bi) {
1795 tb_table->get_blend(first_bi).get_blend(mat, current_thread);
1796 new_data->do_transform_vector_column(new_format, data, mat, first_vertex, next_vertex);
1798 first_vertex = next_vertex;
1811 for (ci = 0; ci < new_format->get_num_points(); ci++) {
1814 for (
int i = 0; i < num_subranges; ++i) {
1817 nassertv(begin < end);
1820 int first_vertex = begin;
1823 while (first_vertex < end) {
1829 int next_vertex = first_vertex;
1830 int next_bi = first_bi;
1832 while (next_vertex < end) {
1834 if (next_bi != first_bi) {
1843 tb_table->get_blend(first_bi).get_blend(mat, current_thread);
1844 new_data->do_transform_point_column(new_format, data, mat, first_vertex, next_vertex);
1846 first_vertex = next_vertex;
1852 for (ci = 0; ci < new_format->get_num_vectors(); ci++) {
1855 for (
int i = 0; i < num_subranges; ++i) {
1858 nassertv(begin != end);
1861 int first_vertex = begin;
1864 while (first_vertex < end) {
1870 int next_vertex = first_vertex;
1871 int next_bi = first_bi;
1873 while (next_vertex < end) {
1875 if (next_bi != first_bi) {
1884 tb_table->get_blend(first_bi).get_blend(mat, current_thread);
1885 new_data->do_transform_vector_column(new_format, data, mat, first_vertex, next_vertex);
1887 first_vertex = next_vertex;
1903 void GeomVertexData::
1905 const LMatrix4 &mat,
int begin_row,
int end_row) {
1909 if ((num_values == 3 || num_values == 4) &&
1916 size_t num_rows = end_row - begin_row;
1918 datat += data_column->
get_start() + begin_row * stride;
1921 if (num_values == 3) {
1922 table_xform_point3f(datat, num_rows, stride, matf);
1924 table_xform_vecbase4f(datat, num_rows, stride, matf);
1927 }
else if (num_values == 4) {
1932 for (
int j = begin_row; j < end_row; ++j) {
1942 for (
int j = begin_row; j < end_row; ++j) {
1955 void GeomVertexData::
1957 const LMatrix4 &mat,
int begin_row,
int end_row) {
1962 bool normalize =
false;
1966 if (decompose_matrix(mat.
get_upper_3(), scale, shear, hpr) &&
1967 IS_NEARLY_EQUAL(scale[0], scale[1]) &&
1968 IS_NEARLY_EQUAL(scale[0], scale[2])) {
1969 if (scale[0] == 1) {
1981 xform.transpose_in_place();
1988 if ((num_values == 3 || num_values == 4) &&
1995 size_t num_rows = end_row - begin_row;
1997 datat += data_column->
get_start() + begin_row * stride;
2001 table_xform_normal3f(datat, num_rows, stride, matf);
2002 }
else if (num_values == 3) {
2003 table_xform_vector3f(datat, num_rows, stride, matf);
2005 table_xform_vecbase4f(datat, num_rows, stride, matf);
2013 for (
int j = begin_row; j < end_row; ++j) {
2020 for (
int j = begin_row; j < end_row; ++j) {
2034 void GeomVertexData::
2035 table_xform_point3f(
unsigned char *datat,
size_t num_rows,
size_t stride,
2039 for (
size_t i = 0; i < num_rows; ++i) {
2052 void GeomVertexData::
2053 table_xform_normal3f(
unsigned char *datat,
size_t num_rows,
size_t stride,
2057 for (
size_t i = 0; i < num_rows; ++i) {
2070 void GeomVertexData::
2071 table_xform_vector3f(
unsigned char *datat,
size_t num_rows,
size_t stride,
2075 for (
size_t i = 0; i < num_rows; ++i) {
2087 void GeomVertexData::
2088 table_xform_vecbase4f(
unsigned char *datat,
size_t num_rows,
size_t stride,
2090 #if defined(HAVE_EIGEN) && defined(LINMATH_ALIGN) 2093 if (((
size_t)datat & 0xf) != 0 || (stride & 0xf) != 0) {
2096 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)));
2097 for (
size_t i = 0; i < num_rows; ++i) {
2098 table.row(i) *= matf._m;
2102 #endif // HAVE_EIGEN 2107 for (
size_t i = 0; i < num_rows; ++i) {
2152 parse_params(params, scan, manager);
2153 object->fillin(scan, manager);
2212 for (
size_t i = 0; i < cdata->_arrays.size(); ++i) {
2213 CPT(GeomVertexFormat) new_format =
2214 GeomVertexFormat::register_format(cdata->_format);
2216 cdata->_format = new_format;
2218 CPT(GeomVertexArrayFormat) new_array_format = new_format->get_array(i);
2220 nassertv(new_array_format->is_data_subset_of(*array_obj->_array_format));
2222 manager->
change_pointer(array_obj->_array_format, new_array_format);
2223 array_obj->_array_format = new_array_format;
2228 TransformTable::register_table(cdata->_transform_table);
2229 manager->
change_pointer(cdata->_transform_table, new_transform_table);
2230 cdata->_transform_table = new_transform_table;
2233 if (cdata->_slider_table != (
SliderTable *)NULL) {
2235 SliderTable::register_table(cdata->_slider_table);
2237 cdata->_slider_table = new_slider_table;
2248 void GeomVertexData::
2263 return new CDataCache(*
this);
2275 Cache::iterator ci = _source->_cache.find(&_key);
2276 nassertv(ci != _source->_cache.end());
2277 nassertv((*ci).second ==
this);
2278 _source->_cache.erase(ci);
2286 void GeomVertexData::CacheEntry::
2287 output(ostream &out)
const {
2288 out <<
"vertex data " << (
void *)_source <<
" to " 2299 return new CData(*
this);
2308 void GeomVertexData::CData::
2314 Arrays::const_iterator ai;
2315 for (ai = _arrays.begin(); ai != _arrays.end(); ++ai) {
2320 manager->
write_pointer(dg, _transform_blend_table.get_read_pointer());
2331 int GeomVertexData::CData::
2335 _format = DCAST(GeomVertexFormat, p_list[pi++]);
2337 Arrays::iterator ai;
2338 for (ai = _arrays.begin(); ai != _arrays.end(); ++ai) {
2355 all_rows.
set_range(0, adata->get_num_rows());
2358 int num_sliders = _slider_table->get_num_sliders();
2359 for (
int i = 0; i < num_sliders; ++i) {
2360 ((
SliderTable *)_slider_table.p())->set_slider_rows(i, all_rows);
2363 if (!_transform_blend_table.is_null()) {
2364 _transform_blend_table.get_unsafe_pointer()->set_rows(all_rows);
2378 void GeomVertexData::CData::
2381 _usage_hint = (UsageHint)scan.
get_uint8();
2384 _arrays.reserve(num_arrays);
2385 for (
size_t i = 0; i < num_arrays; ++i) {
2387 _arrays.push_back(NULL);
2400 int GeomVertexDataPipelineBase::
2401 get_num_bytes()
const {
2404 GeomVertexData::Arrays::const_iterator ai;
2405 for (ai = _cdata->_arrays.begin(); ai != _cdata->_arrays.end(); ++ai) {
2406 num_bytes += (*ai).get_read_pointer()->get_data_size_bytes();
2417 int GeomVertexDataPipelineReader::
2418 get_num_rows()
const {
2419 nassertr(_cdata->_format->get_num_arrays() == (int)_cdata->_arrays.size(), 0);
2420 nassertr(_got_array_readers, 0);
2422 if (_cdata->_format->get_num_arrays() == 0) {
2428 int stride = _cdata->_format->get_array(0)->get_stride();
2429 return _array_readers[0]->get_data_size_bytes() / stride;
2437 bool GeomVertexDataPipelineReader::
2438 get_array_info(
const InternalName *name,
2441 GeomVertexDataPipelineReader::NumericType &numeric_type,
2442 int &start,
int &stride)
const {
2443 nassertr(_got_array_readers,
false);
2446 if (_cdata->_format->get_array_info(name, array_index, column)) {
2447 array_reader = _array_readers[array_index];
2451 stride = _cdata->_format->get_array(array_index)->get_stride();
2462 bool GeomVertexDataPipelineReader::
2463 get_array_info(
const InternalName *name,
2466 GeomVertexDataPipelineReader::NumericType &numeric_type,
2467 int &start,
int &stride,
int &divisor,
2468 int &num_elements,
int &element_stride)
const {
2469 nassertr(_got_array_readers,
false);
2472 if (_cdata->_format->get_array_info(name, array_index, column)) {
2473 array_reader = _array_readers[array_index];
2477 stride = _cdata->_format->get_array(array_index)->get_stride();
2478 divisor = _cdata->_format->get_array(array_index)->get_divisor();
2491 bool GeomVertexDataPipelineReader::
2494 GeomVertexDataPipelineReader::NumericType &numeric_type,
2495 int &start,
int &stride)
const {
2496 nassertr(_got_array_readers,
false);
2497 int array_index = _cdata->_format->get_vertex_array_index();
2498 if (array_index >= 0) {
2501 array_reader = _array_readers[array_index];
2505 stride = _cdata->_format->get_array(array_index)->get_stride();
2516 bool GeomVertexDataPipelineReader::
2518 GeomVertexDataPipelineReader::NumericType &numeric_type,
2519 int &start,
int &stride)
const {
2520 nassertr(_got_array_readers,
false);
2521 int array_index = _cdata->_format->get_normal_array_index();
2522 if (array_index >= 0) {
2525 array_reader = _array_readers[array_index];
2528 stride = _cdata->_format->get_array(array_index)->get_stride();
2539 bool GeomVertexDataPipelineReader::
2542 GeomVertexDataPipelineReader::NumericType &numeric_type,
2543 int &start,
int &stride)
const {
2544 nassertr(_got_array_readers,
false);
2545 int array_index = _cdata->_format->get_color_array_index();
2546 if (array_index >= 0) {
2549 array_reader = _array_readers[array_index];
2553 stride = _cdata->_format->get_array(array_index)->get_stride();
2564 void GeomVertexDataPipelineReader::
2565 make_array_readers() {
2566 nassertv(!_got_array_readers);
2568 _array_readers.reserve(_cdata->_arrays.size());
2569 GeomVertexData::Arrays::const_iterator ai;
2570 for (ai = _cdata->_arrays.begin(); ai != _cdata->_arrays.end(); ++ai) {
2572 _array_readers.push_back(array_obj->get_handle(_current_thread));
2575 _got_array_readers =
true;
2583 void GeomVertexDataPipelineReader::
2584 delete_array_readers() {
2585 nassertv(_got_array_readers);
2587 _array_readers.clear();
2588 _got_array_readers =
false;
2596 int GeomVertexDataPipelineWriter::
2597 get_num_rows()
const {
2598 nassertr(_cdata->_format->get_num_arrays() == (int)_cdata->_arrays.size(), 0);
2599 nassertr(_got_array_writers, 0);
2601 if (_cdata->_format->get_num_arrays() == 0) {
2607 int stride = _cdata->_format->get_array(0)->get_stride();
2608 return _array_writers[0]->get_data_size_bytes() / stride;
2616 bool GeomVertexDataPipelineWriter::
2617 set_num_rows(
int n) {
2618 nassertr(_got_array_writers,
false);
2619 nassertr(_cdata->_format->get_num_arrays() == (int)_cdata->_arrays.size(),
false);
2621 bool any_changed =
false;
2623 int color_array = -1;
2624 int orig_color_rows = -1;
2626 for (
size_t i = 0; i < _cdata->_arrays.size(); i++) {
2628 if (_array_writers[i]->get_object()->has_column(InternalName::get_color())) {
2630 orig_color_rows = _array_writers[i]->get_num_rows();
2632 _array_writers[i]->set_num_rows(n);
2637 if (color_array >= 0 && orig_color_rows < n) {
2641 const GeomVertexArrayFormat *array_format = array_writer->get_array_format();
2643 array_format->get_column(InternalName::get_color());
2644 int stride = array_format->get_stride();
2645 unsigned char *start =
2647 unsigned char *stop = start + array_writer->get_data_size_bytes();
2648 unsigned char *pointer = start + stride * orig_color_rows;
2652 case NT_packed_dcba:
2653 case NT_packed_dabc:
2657 while (pointer < stop) {
2664 while (pointer < stop) {
2665 PN_float32 *pi = (PN_float32 *)pointer;
2666 for (
int i = 0; i < num_values; i++) {
2674 while (pointer < stop) {
2675 PN_float64 *pi = (PN_float64 *)pointer;
2676 for (
int i = 0; i < num_values; i++) {
2685 nassertr(
false,
false);
2690 _object->clear_cache_stage();
2692 _cdata->_animated_vertices.clear();
2703 bool GeomVertexDataPipelineWriter::
2704 unclean_set_num_rows(
int n) {
2705 nassertr(_got_array_writers,
false);
2706 nassertr(_cdata->_format->get_num_arrays() == (int)_cdata->_arrays.size(),
false);
2708 bool any_changed =
false;
2710 for (
size_t i = 0; i < _cdata->_arrays.size(); i++) {
2719 _object->clear_cache_stage();
2721 _cdata->_animated_vertices.clear();
2732 bool GeomVertexDataPipelineWriter::
2733 reserve_num_rows(
int n) {
2734 nassertr(_got_array_writers,
false);
2735 nassertr(_cdata->_format->get_num_arrays() == (int)_cdata->_arrays.size(),
false);
2737 bool any_changed =
false;
2739 for (
size_t i = 0; i < _cdata->_arrays.size(); i++) {
2754 modify_array(
int i) {
2755 nassertr(i >= 0 && i < (
int)_cdata->_arrays.size(), NULL);
2758 if (_got_array_writers) {
2759 new_data = _array_writers[i]->get_object();
2761 new_data = _cdata->_arrays[i].get_write_pointer();
2764 _object->clear_cache_stage();
2766 _cdata->_animated_vertices_modified =
UpdateSeq();
2776 void GeomVertexDataPipelineWriter::
2778 nassertv(i >= 0 && i < (
int)_cdata->_arrays.size());
2780 _object->clear_cache_stage();
2782 _cdata->_animated_vertices_modified =
UpdateSeq();
2784 if (_got_array_writers) {
2785 _array_writers[i] = _cdata->_arrays[i].get_write_pointer()->modify_handle(_current_thread);
2794 void GeomVertexDataPipelineWriter::
2795 make_array_writers() {
2796 nassertv(!_got_array_writers);
2798 _array_writers.reserve(_cdata->_arrays.size());
2799 GeomVertexData::Arrays::iterator ai;
2800 for (ai = _cdata->_arrays.begin(); ai != _cdata->_arrays.end(); ++ai) {
2802 _array_writers.push_back(array_obj->modify_handle(_current_thread));
2805 _object->clear_cache_stage();
2807 _cdata->_animated_vertices_modified =
UpdateSeq();
2809 _got_array_writers =
true;
2817 void GeomVertexDataPipelineWriter::
2818 delete_array_writers() {
2819 nassertv(_got_array_writers);
2821 _array_writers.clear();
2822 _got_array_writers =
false;
const SliderTable * get_slider_table() const
Returns a const pointer to the SliderTable assigned to this data.
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...
This class records a set of integers, where each integer is either present or not present in the set...
bool is_at_end() const
Returns true if the reader or writer is currently at the end of the list of vertices, false otherwise.
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...
void add_uint8(PN_uint8 value)
Adds an unsigned 8-bit integer to the datagram.
This is the base class for all three-component vectors and points.
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.
void add_string(const string &str)
Adds a variable-length string to the datagram.
bool unclean_set_num_rows(int n)
This method behaves like set_num_rows(), except the new data is not initialized.
int get_num_arrays() const
Returns the number of individual arrays stored within the data.
void set_format(const GeomVertexFormat *format)
Changes the format of the vertex data.
void unclean_set_format(const GeomVertexFormat *format)
Changes the format of the vertex data, without reformatting the data to match.
void set_transform_table(const TransformTable *table)
Replaces the TransformTable on this vertex data with the indicated table.
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 set_data3(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z)
Sets the write row to a particular 3-component value, and advances the write row. ...
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...
static PN_uint32 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.
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.
void dump_hex(ostream &out, unsigned int indent=0) const
Writes a representation of the entire datagram contents, as a sequence of hex (and ASCII) values...
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, irrespective of name or start position within the record.
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.
bool has_homogeneous_coord() const
Returns true if this Contents type is one that includes a homogeneous coordinate in the fourth compon...
Base class for objects that can be written to and read from Bam files.
size_t get_stride() const
Returns the per-row stride (bytes between consecutive rows) of the underlying vertex array...
void write_cdata(Datagram &packet, const PipelineCyclerBase &cycler)
Writes out the indicated CycleData object.
GeomVertexArrayDataHandle * get_array_handle() const
Returns the write handle to the array object that the rewriter is currently processing.
bool is_zero() const
Returns true if the entire bitmask is zero, false otherwise.
LMatrix3f get_upper_3() const
Retrieves the upper 3x3 submatrix.
bool is_packed_argb() const
Returns true if this column is the standard DirectX representation of 4-component color: C_color...
void set_array(int i, const GeomVertexArrayData *array)
Replaces the indicated vertex data array with a completely new array.
const LVecBase4 & get_data4()
Returns the data associated with the read row, expressed as a 4-component value, and advances the rea...
bool get_indexed_transforms() const
This is only meaningful for animation_type AT_hardware.
This is a three-component vector distance (as opposed to a three-component point, which represents a ...
void set_usage_hint(UsageHint usage_hint)
Changes the UsageHint hint for this vertex data, and for all of the arrays that share this data...
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...
void set_slider_table(const SliderTable *table)
Replaces the SliderTable on this vertex data with the indicated table.
This is a three-component point in space (as opposed to a three-component vector, which represents a ...
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
PN_uint8 get_uint8()
Extracts an unsigned 8-bit integer.
static const LVecBase3f & zero()
Returns a zero-length vector.
This data object is returned by GeomVertexArrayData::get_handle() or modify_handle().
bool request_resident() const
Returns true if the vertex data is currently resident in memory.
This is the base class for all three-component vectors and points.
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...
PN_uint16 get_uint16()
Extracts an unsigned 16-bit integer.
static Thread * get_current_thread()
Returns a pointer to the currently-executing Thread object.
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
int get_subrange_end(int n) const
Returns the last numeric element, plus one, in the nth subrange.
This template class calls PipelineCycler::read_unlocked(), and then provides a transparent read-only ...
int get_num_elements() const
Returns the number of times this column is repeated.
void set_transform_blend_table(const TransformBlendTable *table)
Replaces the TransformBlendTable 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...
bool is_at_end() const
Returns true if the writer is currently at the end of the list of vertices, false otherwise...
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 set_row_unsafe(int row)
Sets the start row to the indicated value, without internal checks.
int get_subrange_begin(int n) const
Returns the first numeric element in the nth subrange.
int get_element_stride() const
This value is only relevant for matrix types.
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 4-by-4 transform matrix.
static unsigned int unpack_abcd_c(PN_uint32 data)
Returns the third packed value from a DirectX-style NT_packed_abcd.
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
Similar to MutexHolder, but for a light mutex.
const GeomVertexFormat * get_format() const
Returns a pointer to the GeomVertexFormat structure that defines this data.
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...
bool has_column() const
Returns true if a valid data type has been successfully set, or false if the data type does not exist...
UsageHint get_usage_hint() const
Returns the usage hint that was passed to the constructor, and which will be passed to each array dat...
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 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...
bool invert_from(const LMatrix4f &other)
Computes the inverse of the other matrix, and stores the result in this matrix.
const LVecBase3 & get_data3()
Returns the data associated with the read row, expressed as a 3-component value, and advances the rea...
AnimationType get_animation_type() const
Returns the type of animation represented by this spec.
void operator=(const GeomVertexData ©)
The copy assignment operator is not pipeline-safe.
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...
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()...
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...
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...
void register_factory(TypeHandle handle, CreateFunc *func)
Registers a new kind of thing the Factory will be able to create.
int get_num_subranges() const
Returns the number of separate subranges stored in the SparseArray.
void add_uint16(PN_uint16 value)
Adds an unsigned 16-bit integer to the datagram.
int get_start() const
Returns the byte within the array record at which this column starts.
This is the base class for all three-component vectors and points.
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.
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 ...
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
bool has_column() const
Returns true if a valid data type has been successfully set, or false if the data type does not exist...
This is a four-component point in space.
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...
static unsigned int unpack_abcd_d(PN_uint32 data)
Returns the fourth packed value from a DirectX-style NT_packed_abcd.
void clear_rows()
Removes all of the rows from the arrays; functionally equivalent to set_num_rows(0) (but faster)...
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.
bool set_column(int column)
Sets up the writer to use the nth data type of the GeomVertexFormat, numbering from 0...
static unsigned int unpack_abcd_b(PN_uint32 data)
Returns the second packed value from a DirectX-style NT_packed_abcd.
void set_row_unsafe(int row)
Sets the start row to the indicated value, without internal checks.
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.
static unsigned int unpack_abcd_a(PN_uint32 data)
Returns the first packed value from a DirectX-style NT_packed_abcd.
int get_total_bytes() const
Returns the number of bytes used by each element of the column: component_bytes * num_components...
const GeomVertexColumn * get_column() const
Returns the description of the data type that the rewriter is working on.
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.
bool normalize()
Normalizes the vector in place.
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...
void set_name(const string &name)
Changes the name of the vertex data.
const string & get_name() const
Returns the name passed to the constructor, if any.
This object provides the functionality of both a GeomVertexReader and a GeomVertexWriter, combined together into one convenient package.
This is the data for one array of a GeomVertexData structure.
static const LVecBase4f & zero()
Returns a zero-length vector.
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.
void read_pointer(DatagramIterator &scan)
The interface for reading a pointer to another object from a Bam file.
static void register_with_read_factory()
Tells the BamReader how to create objects of type GeomVertexData.