00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "geomVertexFormat.h"
00016 #include "geomVertexData.h"
00017 #include "geomMunger.h"
00018 #include "lightReMutexHolder.h"
00019 #include "indent.h"
00020 #include "bamReader.h"
00021 #include "bamWriter.h"
00022
00023 GeomVertexFormat::Registry *GeomVertexFormat::_registry = NULL;
00024 TypeHandle GeomVertexFormat::_type_handle;
00025
00026
00027
00028
00029
00030
00031 GeomVertexFormat::
00032 GeomVertexFormat() :
00033 _is_registered(false),
00034 _post_animated_format(NULL)
00035 {
00036 }
00037
00038
00039
00040
00041
00042
00043 GeomVertexFormat::
00044 GeomVertexFormat(const GeomVertexArrayFormat *array_format) :
00045 _is_registered(false),
00046 _post_animated_format(NULL)
00047 {
00048 add_array(array_format);
00049 }
00050
00051
00052
00053
00054
00055
00056 GeomVertexFormat::
00057 GeomVertexFormat(const GeomVertexFormat ©) :
00058 _is_registered(false),
00059 _animation(copy._animation),
00060 _arrays(copy._arrays),
00061 _post_animated_format(NULL)
00062 {
00063 }
00064
00065
00066
00067
00068
00069
00070 void GeomVertexFormat::
00071 operator = (const GeomVertexFormat ©) {
00072 nassertv(!is_registered());
00073
00074 _animation = copy._animation;
00075 _arrays = copy._arrays;
00076 }
00077
00078
00079
00080
00081
00082
00083 GeomVertexFormat::
00084 ~GeomVertexFormat() {
00085
00086 nassertv(!is_registered());
00087 }
00088
00089
00090
00091
00092
00093
00094
00095
00096 bool GeomVertexFormat::
00097 unref() const {
00098 Registry *registry = get_registry();
00099 LightReMutexHolder holder(registry->_lock);
00100
00101 if (ReferenceCount::unref()) {
00102 return true;
00103 }
00104
00105 if (is_registered()) {
00106 registry->unregister_format((GeomVertexFormat *)this);
00107 }
00108
00109 return false;
00110 }
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125 CPT(GeomVertexFormat) GeomVertexFormat::
00126 get_post_animated_format() const {
00127 nassertr(is_registered(), NULL);
00128
00129 if (_post_animated_format == (GeomVertexFormat *)NULL) {
00130 PT(GeomVertexFormat) new_format = new GeomVertexFormat(*this);
00131 new_format->remove_column(InternalName::get_transform_blend());
00132
00133 int num_morphs = get_num_morphs();
00134 for (int mi = 0; mi < num_morphs; mi++) {
00135 CPT(InternalName) delta_name = get_morph_delta(mi);
00136 new_format->remove_column(delta_name);
00137 }
00138
00139 new_format->_animation.set_none();
00140
00141 CPT(GeomVertexFormat) registered =
00142 GeomVertexFormat::register_format(new_format);
00143 ((GeomVertexFormat *)this)->_post_animated_format = registered;
00144 if (_post_animated_format != this) {
00145
00146
00147 _post_animated_format->ref();
00148 }
00149 }
00150
00151 _post_animated_format->test_ref_count_integrity();
00152
00153 return _post_animated_format;
00154 }
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170 CPT(GeomVertexFormat) GeomVertexFormat::
00171 get_union_format(const GeomVertexFormat *other) const {
00172 nassertr(is_registered() && other->is_registered(), NULL);
00173
00174 PT(GeomVertexFormat) new_format = new GeomVertexFormat;
00175
00176
00177
00178
00179 if (_animation.get_animation_type() != AT_none) {
00180 new_format->set_animation(_animation);
00181 } else {
00182 new_format->set_animation(other->get_animation());
00183 }
00184
00185
00186 typedef pset< CPT(InternalName) > ColumnNames;
00187 ColumnNames column_names;
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202 size_t num_arrays = max(_arrays.size(), other->_arrays.size());
00203 for (size_t ai = 0; ai < num_arrays; ++ai) {
00204 PT(GeomVertexArrayFormat) new_array = new GeomVertexArrayFormat;
00205
00206
00207 if (ai < _arrays.size()) {
00208 GeomVertexArrayFormat *array_format = _arrays[ai];
00209 int num_columns = array_format->get_num_columns();
00210 for (int i = 0; i < num_columns; ++i) {
00211 const GeomVertexColumn *column_a = array_format->get_column(i);
00212 bool inserted = column_names.insert(column_a->get_name()).second;
00213 if (inserted) {
00214 const GeomVertexColumn *column_b = other->get_column(column_a->get_name());
00215 if (column_b != (GeomVertexColumn *)NULL &&
00216 column_b->get_total_bytes() > column_a->get_total_bytes()) {
00217
00218 new_array->add_column(column_b->get_name(),
00219 column_b->get_num_components(),
00220 column_b->get_numeric_type(),
00221 column_b->get_contents());
00222 } else {
00223
00224 new_array->add_column(column_a->get_name(),
00225 column_a->get_num_components(),
00226 column_a->get_numeric_type(),
00227 column_a->get_contents());
00228 }
00229 }
00230 }
00231 }
00232
00233
00234 if (ai < other->_arrays.size()) {
00235 GeomVertexArrayFormat *array_format = other->_arrays[ai];
00236 int num_columns = array_format->get_num_columns();
00237 for (int i = 0; i < num_columns; ++i) {
00238 const GeomVertexColumn *column_a = array_format->get_column(i);
00239 bool inserted = column_names.insert(column_a->get_name()).second;
00240 if (inserted) {
00241 const GeomVertexColumn *column_b = get_column(column_a->get_name());
00242 if (column_b != (GeomVertexColumn *)NULL &&
00243 column_b->get_total_bytes() > column_a->get_total_bytes()) {
00244
00245 new_array->add_column(column_b->get_name(),
00246 column_b->get_num_components(),
00247 column_b->get_numeric_type(),
00248 column_b->get_contents());
00249 } else {
00250
00251 new_array->add_column(column_a->get_name(),
00252 column_a->get_num_components(),
00253 column_a->get_numeric_type(),
00254 column_a->get_contents());
00255 }
00256 }
00257 }
00258 }
00259
00260 if (new_array->get_num_columns() != 0) {
00261 new_format->add_array(new_array);
00262 }
00263 }
00264
00265
00266 return GeomVertexFormat::register_format(new_format);
00267 }
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279 GeomVertexArrayFormat *GeomVertexFormat::
00280 modify_array(int array) {
00281 nassertr(!is_registered(), NULL);
00282 nassertr(array >= 0 && array < (int)_arrays.size(), NULL);
00283
00284 if (_arrays[array]->is_registered() ||
00285 _arrays[array]->get_ref_count() > 1) {
00286 _arrays[array] = new GeomVertexArrayFormat(*_arrays[array]);
00287 }
00288
00289 return _arrays[array];
00290 }
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300 void GeomVertexFormat::
00301 set_array(int array, const GeomVertexArrayFormat *format) {
00302 nassertv(!is_registered());
00303 nassertv(array >= 0 && array < (int)_arrays.size());
00304 _arrays[array] = (GeomVertexArrayFormat *)format;
00305 }
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315 void GeomVertexFormat::
00316 remove_array(int array) {
00317 nassertv(!is_registered());
00318
00319 nassertv(array >= 0 && array < (int)_arrays.size());
00320 _arrays.erase(_arrays.begin() + array);
00321 }
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334 int GeomVertexFormat::
00335 add_array(const GeomVertexArrayFormat *array_format) {
00336 nassertr(!is_registered(), -1);
00337
00338 int new_array = (int)_arrays.size();
00339 _arrays.push_back((GeomVertexArrayFormat *)array_format);
00340 return new_array;
00341 }
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354 void GeomVertexFormat::
00355 insert_array(int array, const GeomVertexArrayFormat *array_format) {
00356 nassertv(!is_registered());
00357 nassertv(array >= 0 && array <= (int)_arrays.size());
00358
00359 _arrays.insert(_arrays.begin() + array, (GeomVertexArrayFormat *)array_format);
00360 }
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371 void GeomVertexFormat::
00372 clear_arrays() {
00373 nassertv(!is_registered());
00374
00375 _arrays.clear();
00376 }
00377
00378
00379
00380
00381
00382
00383
00384 int GeomVertexFormat::
00385 get_num_columns() const {
00386 int num_columns = 0;
00387 Arrays::const_iterator ai;
00388 for (ai = _arrays.begin(); ai != _arrays.end(); ++ai) {
00389 num_columns += (*ai)->get_num_columns();
00390 }
00391 return num_columns;
00392 }
00393
00394
00395
00396
00397
00398
00399
00400 const GeomVertexColumn *GeomVertexFormat::
00401 get_column(int i) const {
00402 Arrays::const_iterator ai;
00403 for (ai = _arrays.begin(); ai != _arrays.end(); ++ai) {
00404 if (i < (*ai)->get_num_columns()) {
00405 return (*ai)->get_column(i);
00406 }
00407 i -= (*ai)->get_num_columns();
00408 }
00409
00410 return NULL;
00411 }
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425 int GeomVertexFormat::
00426 get_array_with(int i) const {
00427 int array_index = 0;
00428 for (array_index = 0; array_index < (int)_arrays.size(); array_index++) {
00429 if (i < _arrays[array_index]->get_num_columns()) {
00430 return array_index;
00431 }
00432 i -= _arrays[array_index]->get_num_columns();
00433 }
00434
00435 return -1;
00436 }
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454 int GeomVertexFormat::
00455 get_array_with(const InternalName *name) const {
00456 nassertr(_is_registered, -1);
00457
00458 DataTypesByName::const_iterator ai;
00459 ai = _columns_by_name.find(name);
00460 if (ai != _columns_by_name.end()) {
00461 return (*ai).second._array_index;
00462 }
00463 return -1;
00464 }
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474 const GeomVertexColumn *GeomVertexFormat::
00475 get_column(const InternalName *name) const {
00476 if (!_is_registered) {
00477
00478
00479 Arrays::const_iterator ai;
00480 for (ai = _arrays.begin(); ai != _arrays.end(); ++ai) {
00481 const GeomVertexColumn *column = (*ai)->get_column(name);
00482 if (column != (GeomVertexColumn *)NULL) {
00483 return column;
00484 }
00485 }
00486 return NULL;
00487
00488 } else {
00489
00490
00491
00492 DataTypesByName::const_iterator ai;
00493 ai = _columns_by_name.find(name);
00494 if (ai != _columns_by_name.end()) {
00495 int array_index = (*ai).second._array_index;
00496 int column_index = (*ai).second._column_index;
00497
00498 nassertr(array_index >= 0 && array_index < (int)_arrays.size(), NULL);
00499 return _arrays[array_index]->get_column(column_index);
00500 }
00501 return NULL;
00502 }
00503 }
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518 void GeomVertexFormat::
00519 remove_column(const InternalName *name) {
00520 nassertv(!_is_registered);
00521
00522
00523
00524
00525 for (int array = 0; array < (int)_arrays.size(); ++array) {
00526 GeomVertexArrayFormat *array_format = _arrays[array];
00527
00528 if (array_format->get_column(name) != (GeomVertexColumn *)NULL) {
00529
00530 if (array_format->is_registered() ||
00531 array_format->get_ref_count() > 1) {
00532
00533 _arrays[array] = new GeomVertexArrayFormat(*array_format);
00534 array_format = _arrays[array];
00535 }
00536
00537 array_format->remove_column(name);
00538
00539
00540 if (array_format->get_num_columns() == 0) {
00541
00542 remove_array(array);
00543 }
00544 return;
00545 }
00546 }
00547
00548
00549
00550 }
00551
00552
00553
00554
00555
00556
00557 void GeomVertexFormat::
00558 pack_columns() {
00559 nassertv(!_is_registered);
00560 Arrays::iterator ai;
00561 for (ai = _arrays.begin(); ai != _arrays.end(); ++ai) {
00562 if ((*ai)->is_registered()) {
00563 (*ai) = new GeomVertexArrayFormat(*(*ai));
00564 }
00565 (*ai)->pack_columns();
00566 }
00567 }
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579 void GeomVertexFormat::
00580 align_columns_for_animation() {
00581 nassertv(!_is_registered);
00582 Arrays::iterator ai;
00583 for (ai = _arrays.begin(); ai != _arrays.end(); ++ai) {
00584 if ((*ai)->is_registered()) {
00585 (*ai) = new GeomVertexArrayFormat(*(*ai));
00586 }
00587 (*ai)->align_columns_for_animation();
00588 }
00589 }
00590
00591
00592
00593
00594
00595
00596
00597
00598 void GeomVertexFormat::
00599 maybe_align_columns_for_animation() {
00600 if (_animation.get_animation_type() == AT_panda && vertex_animation_align_16) {
00601 align_columns_for_animation();
00602 }
00603 }
00604
00605
00606
00607
00608
00609
00610 void GeomVertexFormat::
00611 output(ostream &out) const {
00612 if (_arrays.empty()) {
00613 out << "(empty)";
00614
00615 } else {
00616 Arrays::const_iterator ai;
00617 ai = _arrays.begin();
00618 out << *(*ai);
00619 ++ai;
00620 while (ai != _arrays.end()) {
00621 out << ", " << *(*ai);
00622 ++ai;
00623 }
00624 }
00625
00626 if (_animation.get_animation_type() != AT_none) {
00627 out << ", anim " << _animation;
00628 }
00629 }
00630
00631
00632
00633
00634
00635
00636 void GeomVertexFormat::
00637 write(ostream &out, int indent_level) const {
00638 for (size_t i = 0; i < _arrays.size(); i++) {
00639 indent(out, indent_level)
00640 << "Array " << i << ":\n";
00641 _arrays[i]->write(out, indent_level + 2);
00642 }
00643
00644 if (_animation.get_animation_type() != AT_none) {
00645 indent(out, indent_level)
00646 << "anim " << _animation << "\n";
00647 }
00648 }
00649
00650
00651
00652
00653
00654
00655 void GeomVertexFormat::
00656 write_with_data(ostream &out, int indent_level,
00657 const GeomVertexData *data) const {
00658 indent(out, indent_level)
00659 << data->get_num_rows() << " rows.\n";
00660 for (size_t i = 0; i < _arrays.size(); i++) {
00661 CPT(GeomVertexArrayDataHandle) handle = data->get_array(i)->get_handle();
00662 const unsigned char *array_data = handle->get_read_pointer(true);
00663 indent(out, indent_level)
00664 << "Array " << i << " (" << (void *)array_data << ", "
00665 << *_arrays[i] << "):\n";
00666 _arrays[i]->write_with_data(out, indent_level + 2, data->get_array(i));
00667 }
00668 }
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683 bool GeomVertexFormat::
00684 get_array_info(const InternalName *name, int &array_index,
00685 const GeomVertexColumn *&column) const {
00686 nassertr(_is_registered, false);
00687
00688 DataTypesByName::const_iterator ai;
00689 ai = _columns_by_name.find(name);
00690 if (ai != _columns_by_name.end()) {
00691 array_index = (*ai).second._array_index;
00692 column = _arrays[array_index]->get_column((*ai).second._column_index);
00693 return true;
00694 }
00695
00696 array_index = -1;
00697 column = NULL;
00698
00699 return false;
00700 }
00701
00702
00703
00704
00705
00706
00707 int GeomVertexFormat::
00708 compare_to(const GeomVertexFormat &other) const {
00709 int compare = _animation.compare_to(other._animation);
00710 if (compare != 0) {
00711 return compare;
00712 }
00713
00714 if (_arrays.size() != other._arrays.size()) {
00715 return (int)_arrays.size() - (int)other._arrays.size();
00716 }
00717
00718 for (size_t i = 0; i < _arrays.size(); i++) {
00719 int compare = _arrays[i]->compare_to(*other._arrays[i]);
00720 if (compare != 0) {
00721 return compare;
00722 }
00723 }
00724
00725 return 0;
00726 }
00727
00728
00729
00730
00731
00732
00733 void GeomVertexFormat::
00734 make_registry() {
00735 if (_registry == (Registry *)NULL) {
00736 _registry = new Registry;
00737 _registry->make_standard_formats();
00738 }
00739 }
00740
00741
00742
00743
00744
00745
00746 void GeomVertexFormat::
00747 do_register() {
00748 nassertv(!is_registered());
00749 nassertv(_columns_by_name.empty());
00750
00751 Arrays orig_arrays;
00752 orig_arrays.swap(_arrays);
00753 Arrays::const_iterator ai;
00754 for (ai = orig_arrays.begin(); ai != orig_arrays.end(); ++ai) {
00755 CPT(GeomVertexArrayFormat) array_format = (*ai);
00756 if (!array_format->is_registered()) {
00757 array_format = GeomVertexArrayFormat::register_format(array_format);
00758 }
00759 if (array_format->get_num_columns() == 0) {
00760
00761 gobj_cat.warning()
00762 << "Dropping empty array from GeomVertexFormat.\n";
00763 continue;
00764 }
00765
00766 int array = (int)_arrays.size();
00767 _arrays.push_back((GeomVertexArrayFormat *)array_format.p());
00768
00769
00770 int num_columns = array_format->get_num_columns();
00771 for (int i = 0; i < num_columns; i++) {
00772 const GeomVertexColumn *column = array_format->get_column(i);
00773 pair<DataTypesByName::iterator, bool> result;
00774 result = _columns_by_name.insert(DataTypesByName::value_type(column->get_name(), DataTypeRecord()));
00775 if (!result.second) {
00776 gobj_cat.warning()
00777 << "Column " << *column->get_name() << " repeated in format.\n";
00778 } else {
00779 DataTypeRecord &record = (*result.first).second;
00780 record._array_index = array;
00781 record._column_index = i;
00782 }
00783 }
00784 }
00785
00786
00787
00788 DataTypesByName::iterator ni;
00789 for (ni = _columns_by_name.begin();
00790 ni != _columns_by_name.end();
00791 ++ni) {
00792 const DataTypeRecord &record = (*ni).second;
00793 const GeomVertexColumn *column = _arrays[record._array_index]->get_column(record._column_index);
00794
00795 switch (column->get_contents()) {
00796 case C_point:
00797
00798 _points.push_back(column->get_name());
00799 break;
00800
00801 case C_vector:
00802
00803 _vectors.push_back(column->get_name());
00804 break;
00805
00806 case C_texcoord:
00807
00808 _texcoords.push_back(column->get_name());
00809 break;
00810
00811 case C_morph_delta:
00812 {
00813
00814 MorphRecord morph;
00815 morph._delta = column->get_name();
00816
00817
00818 int n = morph._delta->find_ancestor("morph");
00819 if (n < 0) {
00820 gobj_cat.warning()
00821 << "vertex format defines " << *column->get_name()
00822 << ", which is stored as a C_morph_delta, but its name does not include \"morph\".\n";
00823 } else {
00824 morph._slider = InternalName::make(morph._delta->get_net_basename(n - 1));
00825 morph._base = morph._delta->get_ancestor(n + 1);
00826
00827 if (_columns_by_name.find(morph._base) == _columns_by_name.end()) {
00828 gobj_cat.warning()
00829 << "vertex format defines "
00830 << *column->get_name() << " but does not define "
00831 << *morph._base << "\n";
00832 } else {
00833 _morphs.push_back(morph);
00834 }
00835 }
00836 }
00837 break;
00838
00839 default:
00840
00841
00842 break;
00843 }
00844 }
00845
00846 _is_registered = true;
00847
00848 get_array_info(InternalName::get_vertex(), _vertex_array_index,
00849 _vertex_column);
00850 get_array_info(InternalName::get_normal(), _normal_array_index,
00851 _normal_column);
00852 get_array_info(InternalName::get_color(), _color_array_index,
00853 _color_column);
00854 }
00855
00856
00857
00858
00859
00860
00861 void GeomVertexFormat::
00862 do_unregister() {
00863 nassertv(_is_registered);
00864 _is_registered = false;
00865
00866 _columns_by_name.clear();
00867 _points.clear();
00868 _vectors.clear();
00869 _texcoords.clear();
00870 _morphs.clear();
00871
00872 if (_post_animated_format != (GeomVertexFormat *)NULL &&
00873 _post_animated_format != this) {
00874 unref_delete(_post_animated_format);
00875 }
00876 _post_animated_format = NULL;
00877 }
00878
00879
00880
00881
00882
00883
00884
00885 void GeomVertexFormat::
00886 register_with_read_factory() {
00887 BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
00888 }
00889
00890
00891
00892
00893
00894
00895
00896 void GeomVertexFormat::
00897 write_datagram(BamWriter *manager, Datagram &dg) {
00898 TypedWritableReferenceCount::write_datagram(manager, dg);
00899
00900 _animation.write_datagram(manager, dg);
00901
00902 dg.add_uint16(_arrays.size());
00903 Arrays::const_iterator ai;
00904 for (ai = _arrays.begin(); ai != _arrays.end(); ++ai) {
00905 manager->write_pointer(dg, *ai);
00906 }
00907 }
00908
00909
00910
00911
00912
00913
00914
00915
00916 int GeomVertexFormat::
00917 complete_pointers(TypedWritable **p_list, BamReader *manager) {
00918 int pi = TypedWritableReferenceCount::complete_pointers(p_list, manager);
00919
00920 Arrays::iterator ai;
00921 for (ai = _arrays.begin(); ai != _arrays.end(); ++ai) {
00922 (*ai) = DCAST(GeomVertexArrayFormat, p_list[pi++]);
00923 }
00924
00925 return pi;
00926 }
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937 TypedWritable *GeomVertexFormat::
00938 make_from_bam(const FactoryParams ¶ms) {
00939 GeomVertexFormat *object = new GeomVertexFormat;
00940 DatagramIterator scan;
00941 BamReader *manager;
00942
00943 parse_params(params, scan, manager);
00944 object->fillin(scan, manager);
00945
00946 return object;
00947 }
00948
00949
00950
00951
00952
00953
00954
00955
00956 void GeomVertexFormat::
00957 fillin(DatagramIterator &scan, BamReader *manager) {
00958 TypedWritableReferenceCount::fillin(scan, manager);
00959
00960 _animation.fillin(scan, manager);
00961
00962 int num_arrays = scan.get_uint16();
00963 _arrays.reserve(num_arrays);
00964 for (int i = 0; i < num_arrays; i++) {
00965 manager->read_pointer(scan);
00966 _arrays.push_back(NULL);
00967 }
00968 }
00969
00970
00971
00972
00973
00974
00975 GeomVertexFormat::Registry::
00976 Registry() {
00977 }
00978
00979
00980
00981
00982
00983
00984 void GeomVertexFormat::Registry::
00985 make_standard_formats() {
00986 _v3 = register_format(new GeomVertexArrayFormat
00987 (InternalName::get_vertex(), 3,
00988 NT_stdfloat, C_point));
00989
00990 _v3n3 = register_format(new GeomVertexArrayFormat
00991 (InternalName::get_vertex(), 3,
00992 NT_stdfloat, C_point,
00993 InternalName::get_normal(), 3,
00994 NT_stdfloat, C_vector));
00995
00996 _v3t2 = register_format(new GeomVertexArrayFormat
00997 (InternalName::get_vertex(), 3,
00998 NT_stdfloat, C_point,
00999 InternalName::get_texcoord(), 2,
01000 NT_stdfloat, C_texcoord));
01001
01002 _v3n3t2 = register_format(new GeomVertexArrayFormat
01003 (InternalName::get_vertex(), 3,
01004 NT_stdfloat, C_point,
01005 InternalName::get_normal(), 3,
01006 NT_stdfloat, C_vector,
01007 InternalName::get_texcoord(), 2,
01008 NT_stdfloat, C_texcoord));
01009
01010
01011 _v3cp = register_format(new GeomVertexArrayFormat
01012 (InternalName::get_vertex(), 3,
01013 NT_stdfloat, C_point,
01014 InternalName::get_color(), 1,
01015 NT_packed_dabc, C_color));
01016
01017 _v3n3cp = register_format(new GeomVertexArrayFormat
01018 (InternalName::get_vertex(), 3,
01019 NT_stdfloat, C_point,
01020 InternalName::get_normal(), 3,
01021 NT_stdfloat, C_vector,
01022 InternalName::get_color(), 1,
01023 NT_packed_dabc, C_color));
01024
01025 _v3cpt2 = register_format(new GeomVertexArrayFormat
01026 (InternalName::get_vertex(), 3,
01027 NT_stdfloat, C_point,
01028 InternalName::get_color(), 1,
01029 NT_packed_dabc, C_color,
01030 InternalName::get_texcoord(), 2,
01031 NT_stdfloat, C_texcoord));
01032
01033 _v3n3cpt2 = register_format(new GeomVertexArrayFormat
01034 (InternalName::get_vertex(), 3,
01035 NT_stdfloat, C_point,
01036 InternalName::get_normal(), 3,
01037 NT_stdfloat, C_vector,
01038 InternalName::get_color(), 1,
01039 NT_packed_dabc, C_color,
01040 InternalName::get_texcoord(), 2,
01041 NT_stdfloat, C_texcoord));
01042
01043
01044
01045
01046 _v3c4 = register_format(new GeomVertexArrayFormat
01047 (InternalName::get_vertex(), 3,
01048 NT_stdfloat, C_point,
01049 InternalName::get_color(), 4,
01050 NT_uint8, C_color));
01051
01052 _v3n3c4 = register_format(new GeomVertexArrayFormat
01053 (InternalName::get_vertex(), 3,
01054 NT_stdfloat, C_point,
01055 InternalName::get_normal(), 3,
01056 NT_stdfloat, C_vector,
01057 InternalName::get_color(), 4,
01058 NT_uint8, C_color));
01059
01060 _v3c4t2 = register_format(new GeomVertexArrayFormat
01061 (InternalName::get_vertex(), 3,
01062 NT_stdfloat, C_point,
01063 InternalName::get_color(), 4,
01064 NT_uint8, C_color,
01065 InternalName::get_texcoord(), 2,
01066 NT_stdfloat, C_texcoord));
01067
01068 _v3n3c4t2 = register_format(new GeomVertexArrayFormat
01069 (InternalName::get_vertex(), 3,
01070 NT_stdfloat, C_point,
01071 InternalName::get_normal(), 3,
01072 NT_stdfloat, C_vector,
01073 InternalName::get_color(), 4,
01074 NT_uint8, C_color,
01075 InternalName::get_texcoord(), 2,
01076 NT_stdfloat, C_texcoord));
01077 }
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094 CPT(GeomVertexFormat) GeomVertexFormat::Registry::
01095 register_format(GeomVertexFormat *format) {
01096 if (format->is_registered()) {
01097 return format;
01098 }
01099
01100
01101
01102
01103 PT(GeomVertexFormat) pt_format = format;
01104
01105 GeomVertexFormat *new_format;
01106 {
01107 LightReMutexHolder holder(_lock);
01108 Formats::iterator fi = _formats.insert(format).first;
01109 new_format = (*fi);
01110 if (!new_format->is_registered()) {
01111 new_format->do_register();
01112 if (new_format->get_num_arrays() == 0) {
01113 gobj_cat.warning()
01114 << "Empty GeomVertexFormat registered.\n";
01115 }
01116 }
01117 }
01118
01119 return new_format;
01120 }
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131 void GeomVertexFormat::Registry::
01132 unregister_format(GeomVertexFormat *format) {
01133 nassertv(format->is_registered());
01134 Formats::iterator fi = _formats.find(format);
01135 nassertv(fi != _formats.end());
01136 _formats.erase(fi);
01137 format->do_unregister();
01138 }