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();
308 if (format == cdata->_format) {
314 nassertv(format->
get_num_arrays() == cdata->_format->get_num_arrays());
316 nassertv(format->
get_array(ai)->get_stride() == cdata->_format->get_array(ai)->get_stride());
318 nassertv(cdata->_arrays.size() == cdata->_format->get_num_arrays());
321 CDWriter cdataw(_cycler, cdata,
true);
324 cdataw->_format = format;
326 for (
size_t ai = 0; ai < cdataw->_arrays.size(); ++ai) {
328 array_obj->_array_format = format->
get_array(ai);
333 cdataw->_animated_vertices.clear();
346 CDWriter cdata(_cycler,
true, current_thread);
347 nassertv(cdata->_format->get_num_arrays() == cdata->_arrays.size());
350 for (ai = cdata->_arrays.begin();
351 ai != cdata->_arrays.end();
354 array_obj->clear_rows();
358 cdata->_animated_vertices.clear();
374 CDWriter cdata(_cycler,
true, current_thread);
378 cdata->_animated_vertices_modified =
UpdateSeq();
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),
671 clear_transform_blend_table();
688 int source_row,
Thread *current_thread) {
691 reader.check_array_readers();
694 writer.check_array_writers();
712 PT(CacheEntry) entry;
714 CacheKey key(new_format);
717 Cache::const_iterator ci = _cache.find(&key);
718 if (ci == _cache.end()) {
722 entry = (*ci).second;
724 nassertr(entry->_source ==
this,
nullptr);
728 entry->refresh(current_thread);
730 CDCacheReader cdata(entry->_cycler);
731 if (cdata->_result !=
nullptr) {
732 return cdata->_result;
742 if (gobj_cat.is_debug()) {
745 <<
" to " << *new_format <<
"\n";
751 new_data->set_transform_blend_table(get_transform_blend_table());
754 new_data->copy_from(
this,
false);
757 if (entry ==
nullptr) {
764 bool inserted = ((
GeomVertexData *)
this)->_cache.insert(Cache::value_type(&entry->_key, entry)).second;
773 entry->record(current_thread);
777 CDCacheWriter cdata(entry->_cycler,
true, current_thread);
778 cdata->_result = new_data;
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";
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);
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;