00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "geomVertexFormat.h"
00016 #include "geomVertexColumn.h"
00017 #include "geomVertexData.h"
00018 #include "geomVertexReader.h"
00019 #include "indent.h"
00020 #include "bamReader.h"
00021 #include "bamWriter.h"
00022 #include "indirectLess.h"
00023 #include "lightMutexHolder.h"
00024
00025 GeomVertexArrayFormat::Registry *GeomVertexArrayFormat::_registry = NULL;
00026 TypeHandle GeomVertexArrayFormat::_type_handle;
00027
00028
00029
00030
00031
00032
00033 GeomVertexArrayFormat::
00034 GeomVertexArrayFormat() :
00035 _is_registered(false),
00036 _stride(0),
00037 _total_bytes(0),
00038 _pad_to(1),
00039 _columns_unsorted(false)
00040 {
00041 }
00042
00043
00044
00045
00046
00047
00048 GeomVertexArrayFormat::
00049 GeomVertexArrayFormat(InternalName *name0, int num_components0,
00050 GeomVertexArrayFormat::NumericType numeric_type0,
00051 GeomVertexArrayFormat::Contents contents0) :
00052 _is_registered(false),
00053 _stride(0),
00054 _total_bytes(0),
00055 _pad_to(1),
00056 _columns_unsorted(false)
00057 {
00058 add_column(name0, num_components0, numeric_type0, contents0);
00059 }
00060
00061
00062
00063
00064
00065
00066 GeomVertexArrayFormat::
00067 GeomVertexArrayFormat(InternalName *name0, int num_components0,
00068 GeomVertexArrayFormat::NumericType numeric_type0,
00069 GeomVertexArrayFormat::Contents contents0,
00070 InternalName *name1, int num_components1,
00071 GeomVertexArrayFormat::NumericType numeric_type1,
00072 GeomVertexArrayFormat::Contents contents1) :
00073 _is_registered(false),
00074 _stride(0),
00075 _total_bytes(0),
00076 _pad_to(1),
00077 _columns_unsorted(false)
00078 {
00079 add_column(name0, num_components0, numeric_type0, contents0);
00080 add_column(name1, num_components1, numeric_type1, contents1);
00081 }
00082
00083
00084
00085
00086
00087
00088 GeomVertexArrayFormat::
00089 GeomVertexArrayFormat(InternalName *name0, int num_components0,
00090 GeomVertexArrayFormat::NumericType numeric_type0,
00091 GeomVertexArrayFormat::Contents contents0,
00092 InternalName *name1, int num_components1,
00093 GeomVertexArrayFormat::NumericType numeric_type1,
00094 GeomVertexArrayFormat::Contents contents1,
00095 InternalName *name2, int num_components2,
00096 GeomVertexArrayFormat::NumericType numeric_type2,
00097 GeomVertexArrayFormat::Contents contents2) :
00098 _is_registered(false),
00099 _stride(0),
00100 _total_bytes(0),
00101 _pad_to(1),
00102 _columns_unsorted(false)
00103 {
00104 add_column(name0, num_components0, numeric_type0, contents0);
00105 add_column(name1, num_components1, numeric_type1, contents1);
00106 add_column(name2, num_components2, numeric_type2, contents2);
00107 }
00108
00109
00110
00111
00112
00113
00114 GeomVertexArrayFormat::
00115 GeomVertexArrayFormat(InternalName *name0, int num_components0,
00116 GeomVertexArrayFormat::NumericType numeric_type0,
00117 GeomVertexArrayFormat::Contents contents0,
00118 InternalName *name1, int num_components1,
00119 GeomVertexArrayFormat::NumericType numeric_type1,
00120 GeomVertexArrayFormat::Contents contents1,
00121 InternalName *name2, int num_components2,
00122 GeomVertexArrayFormat::NumericType numeric_type2,
00123 GeomVertexArrayFormat::Contents contents2,
00124 InternalName *name3, int num_components3,
00125 GeomVertexArrayFormat::NumericType numeric_type3,
00126 GeomVertexArrayFormat::Contents contents3) :
00127 _is_registered(false),
00128 _stride(0),
00129 _total_bytes(0),
00130 _pad_to(1),
00131 _columns_unsorted(false)
00132 {
00133 add_column(name0, num_components0, numeric_type0, contents0);
00134 add_column(name1, num_components1, numeric_type1, contents1);
00135 add_column(name2, num_components2, numeric_type2, contents2);
00136 add_column(name3, num_components3, numeric_type3, contents3);
00137 }
00138
00139
00140
00141
00142
00143
00144 GeomVertexArrayFormat::
00145 GeomVertexArrayFormat(const GeomVertexArrayFormat ©) :
00146 _is_registered(false),
00147 _stride(copy._stride),
00148 _total_bytes(copy._total_bytes),
00149 _pad_to(copy._pad_to),
00150 _columns_unsorted(copy._columns_unsorted)
00151 {
00152 Columns::const_iterator dti;
00153 for (dti = copy._columns.begin(); dti != copy._columns.end(); ++dti) {
00154 add_column(*(*dti));
00155 }
00156 }
00157
00158
00159
00160
00161
00162
00163 void GeomVertexArrayFormat::
00164 operator = (const GeomVertexArrayFormat ©) {
00165 nassertv(!_is_registered);
00166 _stride = copy._stride;
00167 _total_bytes = copy._total_bytes;
00168 _pad_to = copy._pad_to;
00169
00170 _columns.clear();
00171 _columns_by_name.clear();
00172 _columns_unsorted = false;
00173 Columns::const_iterator dti;
00174 for (dti = copy._columns.begin(); dti != copy._columns.end(); ++dti) {
00175 add_column(*(*dti));
00176 }
00177 }
00178
00179
00180
00181
00182
00183
00184 GeomVertexArrayFormat::
00185 ~GeomVertexArrayFormat() {
00186
00187 nassertv(!is_registered());
00188
00189 Columns::iterator ci;
00190 for (ci = _columns.begin(); ci != _columns.end(); ++ci) {
00191 delete (*ci);
00192 }
00193 }
00194
00195
00196
00197
00198
00199
00200
00201
00202 bool GeomVertexArrayFormat::
00203 unref() const {
00204 Registry *registry = get_registry();
00205 LightMutexHolder holder(registry->_lock);
00206
00207 if (ReferenceCount::unref()) {
00208 return true;
00209 }
00210
00211 if (is_registered()) {
00212 registry->unregister_format((GeomVertexArrayFormat *)this);
00213 }
00214
00215 return false;
00216 }
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230 int GeomVertexArrayFormat::
00231 add_column(InternalName *name, int num_components,
00232 GeomVertexArrayFormat::NumericType numeric_type,
00233 GeomVertexArrayFormat::Contents contents, int start,
00234 int column_alignment) {
00235 if (start < 0) {
00236 start = _total_bytes;
00237 }
00238
00239 return add_column(GeomVertexColumn(name, num_components, numeric_type, contents,
00240 start, column_alignment));
00241 }
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259 int GeomVertexArrayFormat::
00260 add_column(const GeomVertexColumn &column) {
00261 nassertr(!_is_registered, -1);
00262
00263
00264 remove_column(column.get_name());
00265
00266
00267
00268 const GeomVertexColumn *orig_column = get_column(column.get_start(), column.get_total_bytes());
00269 while (orig_column != (const GeomVertexColumn *)NULL) {
00270 remove_column(orig_column->get_name());
00271 orig_column = get_column(column.get_start(), column.get_total_bytes());
00272 }
00273
00274 _total_bytes = max(_total_bytes, column.get_start() + column.get_total_bytes());
00275 _pad_to = max(_pad_to, column.get_column_alignment());
00276 _stride = max(_stride, _total_bytes);
00277 if (_pad_to > 1) {
00278 _stride = ((_stride + _pad_to - 1) / _pad_to) * _pad_to;
00279 }
00280
00281 GeomVertexColumn *new_column = new GeomVertexColumn(column);
00282
00283 if (!_columns.empty() && *new_column < *_columns.back()) {
00284 _columns_unsorted = true;
00285 }
00286
00287 int new_index = (int)_columns.size();
00288 _columns.push_back(new_column);
00289 _columns_by_name.insert(ColumnsByName::value_type(new_column->get_name(), new_column));
00290
00291 return new_index;
00292 }
00293
00294
00295
00296
00297
00298
00299
00300 void GeomVertexArrayFormat::
00301 remove_column(const InternalName *name) {
00302 nassertv(!_is_registered);
00303 ColumnsByName::iterator ni;
00304 ni = _columns_by_name.find(name);
00305 if (ni != _columns_by_name.end()) {
00306 GeomVertexColumn *column = (*ni).second;
00307 _columns_by_name.erase(ni);
00308
00309 Columns::iterator ci;
00310 ci = find(_columns.begin(), _columns.end(), column);
00311 nassertv(ci != _columns.end());
00312 _columns.erase(ci);
00313
00314 delete column;
00315
00316
00317
00318 if (_columns.empty()) {
00319 _total_bytes = 0;
00320 } else {
00321 consider_sort_columns();
00322 GeomVertexColumn *last = _columns.back();
00323 _total_bytes = last->get_start() + last->get_total_bytes();
00324 }
00325 }
00326 }
00327
00328
00329
00330
00331
00332
00333
00334 void GeomVertexArrayFormat::
00335 clear_columns() {
00336 nassertv(!_is_registered);
00337
00338 _columns.clear();
00339 _columns_by_name.clear();
00340 _columns_unsorted = false;
00341 _stride = 0;
00342 _total_bytes = 0;
00343 _pad_to = 1;
00344 }
00345
00346
00347
00348
00349
00350
00351 void GeomVertexArrayFormat::
00352 pack_columns() {
00353 nassertv(!_is_registered);
00354
00355 Columns orig_columns;
00356 orig_columns.swap(_columns);
00357 clear_columns();
00358
00359 Columns::const_iterator ci;
00360 for (ci = orig_columns.begin(); ci != orig_columns.end(); ++ci) {
00361 GeomVertexColumn *column = (*ci);
00362 add_column(column->get_name(), column->get_num_components(),
00363 column->get_numeric_type(), column->get_contents());
00364 }
00365 }
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379 void GeomVertexArrayFormat::
00380 align_columns_for_animation() {
00381 nassertv(!_is_registered);
00382
00383 Columns orig_columns;
00384 orig_columns.swap(_columns);
00385 clear_columns();
00386
00387 Columns::const_iterator ci;
00388 for (ci = orig_columns.begin(); ci != orig_columns.end(); ++ci) {
00389 GeomVertexColumn *column = (*ci);
00390 if ((column->get_contents() == C_point || column->get_contents() == C_vector) &&
00391 (column->get_numeric_type() == NT_float32 || column->get_numeric_type() == NT_float64) &&
00392 column->get_num_components() >= 3) {
00393 add_column(column->get_name(), 4, column->get_numeric_type(), column->get_contents(), -1, 16);
00394 } else {
00395 add_column(column->get_name(), column->get_num_components(),
00396 column->get_numeric_type(), column->get_contents());
00397 }
00398 }
00399 }
00400
00401
00402
00403
00404
00405
00406
00407
00408 const GeomVertexColumn *GeomVertexArrayFormat::
00409 get_column(const InternalName *name) const {
00410 ColumnsByName::const_iterator ni;
00411 ni = _columns_by_name.find(name);
00412 if (ni != _columns_by_name.end()) {
00413 return (*ni).second;
00414 }
00415 return NULL;
00416 }
00417
00418
00419
00420
00421
00422
00423
00424
00425 const GeomVertexColumn *GeomVertexArrayFormat::
00426 get_column(int start_byte, int num_bytes) const {
00427 consider_sort_columns();
00428 Columns::const_iterator ci;
00429 for (ci = _columns.begin(); ci != _columns.end(); ++ci) {
00430 const GeomVertexColumn *column = (*ci);
00431 if (column->overlaps_with(start_byte, num_bytes)) {
00432 return column;
00433 }
00434 }
00435
00436 return NULL;
00437 }
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449 bool GeomVertexArrayFormat::
00450 is_data_subset_of(const GeomVertexArrayFormat &other) const {
00451 if (_columns.size() > other._columns.size() ||
00452 get_stride() != other.get_stride()) {
00453 return false;
00454 }
00455
00456 consider_sort_columns();
00457 other.consider_sort_columns();
00458 size_t i = 0;
00459 size_t j = 0;
00460 while (i < _columns.size() && j < other._columns.size()) {
00461 if (*_columns[i] == *other._columns[j]) {
00462 ++i;
00463 }
00464 ++j;
00465 }
00466
00467
00468 return (i == _columns.size());
00469 }
00470
00471
00472
00473
00474
00475
00476
00477 int GeomVertexArrayFormat::
00478 count_unused_space() const {
00479 consider_sort_columns();
00480
00481 int unused_space = 0;
00482 int last_pos = 0;
00483
00484 Columns::const_iterator ci;
00485 for (ci = _columns.begin(); ci != _columns.end(); ++ci) {
00486 const GeomVertexColumn *column = (*ci);
00487 if (column->get_start() > last_pos) {
00488 unused_space += (column->get_start() - last_pos);
00489 }
00490 last_pos = column->get_start() + column->get_total_bytes();
00491 }
00492
00493 if (_stride > last_pos) {
00494 unused_space += (_stride - last_pos);
00495 }
00496
00497 return unused_space;
00498 }
00499
00500
00501
00502
00503
00504
00505 void GeomVertexArrayFormat::
00506 output(ostream &out) const {
00507 Columns::const_iterator ci;
00508 int last_pos = 0;
00509 out << "[";
00510 for (ci = _columns.begin(); ci != _columns.end(); ++ci) {
00511 const GeomVertexColumn *column = (*ci);
00512 if (column->get_start() > last_pos) {
00513 out << " (..." << (column->get_start() - last_pos) << "...)";
00514 }
00515 out << " " << *column;
00516 last_pos = column->get_start() + column->get_total_bytes();
00517 }
00518
00519 if (_stride > last_pos) {
00520 out << " ..." << (_stride - last_pos) << "...";
00521 }
00522
00523 out << " ]";
00524 }
00525
00526
00527
00528
00529
00530
00531 void GeomVertexArrayFormat::
00532 write(ostream &out, int indent_level) const {
00533 indent(out, indent_level)
00534 << "Array format (stride = " << get_stride() << "):\n";
00535 consider_sort_columns();
00536 Columns::const_iterator ci;
00537 for (ci = _columns.begin(); ci != _columns.end(); ++ci) {
00538 const GeomVertexColumn *column = (*ci);
00539 indent(out, indent_level + 2)
00540 << *column
00541 << " " << column->get_numeric_type()
00542 << " " << column->get_contents()
00543 << " start at " << column->get_start() << "\n";
00544 }
00545 }
00546
00547
00548
00549
00550
00551
00552 void GeomVertexArrayFormat::
00553 write_with_data(ostream &out, int indent_level,
00554 const GeomVertexArrayData *array_data) const {
00555 consider_sort_columns();
00556 int num_rows = array_data->get_num_rows();
00557
00558 GeomVertexReader reader(array_data);
00559
00560 for (int i = 0; i < num_rows; i++) {
00561 indent(out, indent_level)
00562 << "row " << i << ":\n";
00563 reader.set_row_unsafe(i);
00564 Columns::const_iterator ci;
00565 for (ci = _columns.begin(); ci != _columns.end(); ++ci) {
00566 const GeomVertexColumn *column = (*ci);
00567 int num_values = min(column->get_num_values(), 4);
00568 reader.set_column(0, column);
00569 const LVecBase4f &d = reader.get_data4f();
00570
00571 indent(out, indent_level + 2)
00572 << *column->get_name();
00573 for (int v = 0; v < num_values; v++) {
00574 out << " " << d[v];
00575 }
00576 out << "\n";
00577 }
00578 }
00579 }
00580
00581
00582
00583
00584
00585
00586 int GeomVertexArrayFormat::
00587 compare_to(const GeomVertexArrayFormat &other) const {
00588 if (_stride != other._stride) {
00589 return _stride - other._stride;
00590 }
00591 if (_total_bytes != other._total_bytes) {
00592 return _total_bytes - other._total_bytes;
00593 }
00594 if (_pad_to != other._pad_to) {
00595 return _pad_to - other._pad_to;
00596 }
00597 if (_columns.size() != other._columns.size()) {
00598 return (int)_columns.size() - (int)other._columns.size();
00599 }
00600 consider_sort_columns();
00601 other.consider_sort_columns();
00602 for (size_t i = 0; i < _columns.size(); i++) {
00603 int compare = _columns[i]->compare_to(*other._columns[i]);
00604 if (compare != 0) {
00605 return compare;
00606 }
00607 }
00608
00609 return 0;
00610 }
00611
00612
00613
00614
00615
00616
00617
00618
00619 void GeomVertexArrayFormat::
00620 sort_columns() {
00621 sort(_columns.begin(), _columns.end(), IndirectLess<GeomVertexColumn>());
00622 }
00623
00624
00625
00626
00627
00628
00629 void GeomVertexArrayFormat::
00630 make_registry() {
00631 if (_registry == (Registry *)NULL) {
00632 _registry = new Registry;
00633 }
00634 }
00635
00636
00637
00638
00639
00640
00641 void GeomVertexArrayFormat::
00642 do_register() {
00643 nassertv(!_is_registered);
00644 _is_registered = true;
00645 }
00646
00647
00648
00649
00650
00651
00652 void GeomVertexArrayFormat::
00653 do_unregister() {
00654 nassertv(_is_registered);
00655 _is_registered = false;
00656 }
00657
00658
00659
00660
00661
00662
00663
00664 void GeomVertexArrayFormat::
00665 register_with_read_factory() {
00666 BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
00667 }
00668
00669
00670
00671
00672
00673
00674
00675 void GeomVertexArrayFormat::
00676 write_datagram(BamWriter *manager, Datagram &dg) {
00677 TypedWritableReferenceCount::write_datagram(manager, dg);
00678
00679 dg.add_uint16(_stride);
00680 dg.add_uint16(_total_bytes);
00681 dg.add_uint8(_pad_to);
00682
00683 consider_sort_columns();
00684
00685 dg.add_uint16(_columns.size());
00686 Columns::iterator ci;
00687 for (ci = _columns.begin(); ci != _columns.end(); ++ci) {
00688 GeomVertexColumn *column = (*ci);
00689 column->write_datagram(manager, dg);
00690 }
00691 }
00692
00693
00694
00695
00696
00697
00698
00699
00700 int GeomVertexArrayFormat::
00701 complete_pointers(TypedWritable **p_list, BamReader *manager) {
00702 int pi = TypedWritableReferenceCount::complete_pointers(p_list, manager);
00703
00704 Columns::iterator ci;
00705 for (ci = _columns.begin(); ci != _columns.end(); ++ci) {
00706 GeomVertexColumn *column = (*ci);
00707 pi += column->complete_pointers(p_list + pi, manager);
00708 }
00709
00710 return pi;
00711 }
00712
00713
00714
00715
00716
00717
00718
00719
00720 void GeomVertexArrayFormat::
00721 finalize(BamReader *manager) {
00722
00723
00724
00725
00726 _columns_by_name.clear();
00727 Columns::iterator ci;
00728 for (ci = _columns.begin(); ci != _columns.end(); ++ci) {
00729 GeomVertexColumn *column = (*ci);
00730 _columns_by_name.insert(ColumnsByName::value_type(column->get_name(), column));
00731 }
00732 }
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743 TypedWritable *GeomVertexArrayFormat::
00744 make_from_bam(const FactoryParams ¶ms) {
00745 GeomVertexArrayFormat *object = new GeomVertexArrayFormat;
00746 DatagramIterator scan;
00747 BamReader *manager;
00748
00749 parse_params(params, scan, manager);
00750 object->fillin(scan, manager);
00751 manager->register_finalize(object);
00752
00753 return object;
00754 }
00755
00756
00757
00758
00759
00760
00761
00762
00763 void GeomVertexArrayFormat::
00764 fillin(DatagramIterator &scan, BamReader *manager) {
00765 TypedWritableReferenceCount::fillin(scan, manager);
00766 nassertv(!_is_registered);
00767
00768 _stride = scan.get_uint16();
00769 _total_bytes = scan.get_uint16();
00770 _pad_to = scan.get_uint8();
00771
00772 int num_columns = scan.get_uint16();
00773 _columns.reserve(num_columns);
00774 for (int i = 0; i < num_columns; ++i) {
00775 GeomVertexColumn *column = new GeomVertexColumn;
00776 column->fillin(scan, manager);
00777 _columns.push_back(column);
00778 }
00779 _columns_unsorted = false;
00780 }
00781
00782
00783
00784
00785
00786
00787 GeomVertexArrayFormat::Registry::
00788 Registry() {
00789 }
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806 CPT(GeomVertexArrayFormat) GeomVertexArrayFormat::Registry::
00807 register_format(GeomVertexArrayFormat *format) {
00808 if (format->is_registered()) {
00809 return format;
00810 }
00811
00812
00813
00814
00815 PT(GeomVertexArrayFormat) pt_format = format;
00816
00817 GeomVertexArrayFormat *new_format;
00818 {
00819 LightMutexHolder holder(_lock);
00820 ArrayFormats::iterator fi = _formats.insert(format).first;
00821 new_format = (*fi);
00822 if (!new_format->is_registered()) {
00823 new_format->do_register();
00824 }
00825 }
00826
00827 return new_format;
00828 }
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839 void GeomVertexArrayFormat::Registry::
00840 unregister_format(GeomVertexArrayFormat *format) {
00841 nassertv(format->is_registered());
00842 ArrayFormats::iterator fi = _formats.find(format);
00843 nassertv(fi != _formats.end());
00844 _formats.erase(fi);
00845 format->do_unregister();
00846 }