00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "eggPrimitive.h"
00016 #include "eggVertexPool.h"
00017 #include "eggMiscFuncs.h"
00018 #include "eggTextureCollection.h"
00019 #include "lexerDefs.h"
00020 #include "config_egg.h"
00021
00022 #include "indent.h"
00023 #include "vector_int.h"
00024
00025 TypeHandle EggPrimitive::_type_handle;
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 EggRenderMode *EggPrimitive::
00038 determine_alpha_mode() {
00039 if (get_alpha_mode() != AM_unspecified) {
00040 return this;
00041 }
00042
00043 EggRenderMode *result = EggNode::determine_alpha_mode();
00044 if (result == (EggRenderMode *)NULL) {
00045 int num_textures = get_num_textures();
00046 for (int i = 0; i < num_textures && result == (EggRenderMode *)NULL; i++) {
00047 EggTexture *egg_tex = get_texture(i);
00048
00049
00050
00051
00052 if (egg_tex->affects_polygon_alpha()) {
00053
00054
00055 if (egg_tex->get_alpha_mode() != AM_unspecified) {
00056 result = get_texture(i);
00057 }
00058 }
00059 }
00060 }
00061 return result;
00062 }
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 EggRenderMode *EggPrimitive::
00074 determine_depth_write_mode() {
00075 if (get_depth_write_mode() != DWM_unspecified) {
00076 return this;
00077 }
00078
00079 EggRenderMode *result = EggNode::determine_depth_write_mode();
00080 if (result == (EggRenderMode *)NULL) {
00081 int num_textures = get_num_textures();
00082 for (int i = 0; i < num_textures && result == (EggRenderMode *)NULL; i++) {
00083 if (get_texture(i)->get_depth_write_mode() != DWM_unspecified) {
00084 result = get_texture(i);
00085 }
00086 }
00087 }
00088 return result;
00089 }
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100 EggRenderMode *EggPrimitive::
00101 determine_depth_test_mode() {
00102 if (get_depth_test_mode() != DTM_unspecified) {
00103 return this;
00104 }
00105
00106 EggRenderMode *result = EggNode::determine_depth_test_mode();
00107 if (result == (EggRenderMode *)NULL) {
00108 int num_textures = get_num_textures();
00109 for (int i = 0; i < num_textures && result == (EggRenderMode *)NULL; i++) {
00110 if (get_texture(i)->get_depth_test_mode() != DTM_unspecified) {
00111 result = get_texture(i);
00112 }
00113 }
00114 }
00115 return result;
00116 }
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127 EggRenderMode *EggPrimitive::
00128 determine_visibility_mode() {
00129 if (get_visibility_mode() != VM_unspecified) {
00130 return this;
00131 }
00132
00133 EggRenderMode *result = EggNode::determine_visibility_mode();
00134 if (result == (EggRenderMode *)NULL) {
00135 int num_textures = get_num_textures();
00136 for (int i = 0; i < num_textures && result == (EggRenderMode *)NULL; i++) {
00137 if (get_texture(i)->get_visibility_mode() != VM_unspecified) {
00138 result = get_texture(i);
00139 }
00140 }
00141 }
00142 return result;
00143 }
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154 EggRenderMode *EggPrimitive::
00155 determine_depth_offset() {
00156 if (has_depth_offset()) {
00157 return this;
00158 }
00159
00160 EggRenderMode *result = EggNode::determine_depth_offset();
00161 if (result == (EggRenderMode *)NULL) {
00162 int num_textures = get_num_textures();
00163 for (int i = 0; i < num_textures && result == (EggRenderMode *)NULL; i++) {
00164 if (get_texture(i)->has_depth_offset()) {
00165 result = get_texture(i);
00166 }
00167 }
00168 }
00169 return result;
00170 }
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181 EggRenderMode *EggPrimitive::
00182 determine_draw_order() {
00183 if (has_draw_order()) {
00184 return this;
00185 }
00186
00187 EggRenderMode *result = EggNode::determine_draw_order();
00188 if (result == (EggRenderMode *)NULL) {
00189 int num_textures = get_num_textures();
00190 for (int i = 0; i < num_textures && result == (EggRenderMode *)NULL; i++) {
00191 if (get_texture(i)->has_draw_order()) {
00192 result = get_texture(i);
00193 }
00194 }
00195 }
00196 return result;
00197 }
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208 EggRenderMode *EggPrimitive::
00209 determine_bin() {
00210 if (has_bin()) {
00211 return this;
00212 }
00213
00214 EggRenderMode *result = EggNode::determine_bin();
00215 if (result == (EggRenderMode *)NULL) {
00216 int num_textures = get_num_textures();
00217 for (int i = 0; i < num_textures && result == (EggRenderMode *)NULL; i++) {
00218 if (get_texture(i)->has_bin()) {
00219 result = get_texture(i);
00220 }
00221 }
00222 }
00223 return result;
00224 }
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246 EggPrimitive::Shading EggPrimitive::
00247 get_shading() const {
00248 if (empty()) {
00249 return S_overall;
00250 }
00251
00252 if (has_vertex_normal()) {
00253
00254 const EggAttributes *first_vertex = get_vertex(0);
00255 if (!first_vertex->has_normal()) {
00256 first_vertex = this;
00257 }
00258 for (int i = 1; i < get_num_vertices(); i++) {
00259 const EggAttributes *vertex = get_vertex(i);
00260 if (!vertex->has_normal()) {
00261 vertex = this;
00262 }
00263 if (!vertex->matches_normal(*first_vertex)) {
00264 return S_per_vertex;
00265 }
00266 }
00267 }
00268
00269 if (has_vertex_color()) {
00270
00271 const EggAttributes *first_vertex = get_vertex(0);
00272 if (!first_vertex->has_color()) {
00273 first_vertex = this;
00274 }
00275 for (int i = 1; i < get_num_vertices(); i++) {
00276 const EggAttributes *vertex = get_vertex(i);
00277 if (!vertex->has_color()) {
00278 vertex = this;
00279 }
00280 if (!vertex->matches_color(*first_vertex)) {
00281 return S_per_vertex;
00282 }
00283 }
00284 }
00285
00286 return S_overall;
00287 }
00288
00289
00290
00291
00292
00293
00294
00295 void EggPrimitive::
00296 copy_attributes(const EggAttributes &other) {
00297 EggAttributes::operator = (other);
00298 }
00299
00300
00301
00302
00303
00304
00305
00306 void EggPrimitive::
00307 copy_attributes(const EggPrimitive &other) {
00308 EggAttributes::operator = (other);
00309 _textures = other._textures;
00310 set_material(other.get_material());
00311 set_bface_flag(other.get_bface_flag());
00312 }
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325 bool EggPrimitive::
00326 has_vertex_normal() const {
00327 Vertices::const_iterator vi;
00328 for (vi = _vertices.begin(); vi != _vertices.end(); ++vi) {
00329 if ((*vi)->has_normal()) {
00330 return true;
00331 }
00332 }
00333 return false;
00334 }
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347 bool EggPrimitive::
00348 has_vertex_color() const {
00349 Vertices::const_iterator vi;
00350 for (vi = _vertices.begin(); vi != _vertices.end(); ++vi) {
00351 if ((*vi)->has_color()) {
00352 return true;
00353 }
00354 }
00355 return false;
00356 }
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382 void EggPrimitive::
00383 unify_attributes(EggPrimitive::Shading shading) {
00384 if (shading == S_unknown) {
00385 shading = get_shading();
00386 }
00387
00388
00389 if (!has_color() && shading != S_overall) {
00390 if (shading != S_per_vertex) {
00391
00392
00393 iterator pi;
00394 for (pi = begin(); pi != end() && !has_color(); ++pi) {
00395 EggVertex *vertex = (*pi);
00396 if (vertex->has_color()) {
00397 set_color(vertex->get_color());
00398 }
00399 }
00400 }
00401 if (!has_color()) {
00402
00403 set_color(LColor(1.0f, 1.0f, 1.0f, 1.0f));
00404 }
00405 }
00406
00407 switch (shading) {
00408 case S_per_vertex:
00409
00410 {
00411 iterator pi;
00412 for (pi = begin(); pi != end(); ++pi) {
00413 EggVertex *orig_vertex = (*pi);
00414 PT(EggVertex) vertex = new EggVertex(*orig_vertex);
00415 if (!vertex->has_normal() && has_normal()) {
00416 vertex->copy_normal(*this);
00417 }
00418 if (!vertex->has_color() && has_color()) {
00419 vertex->copy_color(*this);
00420 }
00421
00422 EggVertexPool *vertex_pool = orig_vertex->get_pool();
00423 nassertv(vertex_pool != (EggVertexPool *)NULL);
00424 vertex = vertex_pool->create_unique_vertex(*vertex);
00425 vertex->copy_grefs_from(*orig_vertex);
00426 replace(pi, vertex);
00427 }
00428 clear_normal();
00429 clear_color();
00430 }
00431 break;
00432
00433 case S_per_face:
00434 case S_overall:
00435
00436 {
00437 iterator pi;
00438 for (pi = begin(); pi != end(); ++pi) {
00439 EggVertex *orig_vertex = (*pi);
00440 PT(EggVertex) vertex = new EggVertex(*orig_vertex);
00441 if (vertex->has_normal()) {
00442 if (!has_normal()) {
00443 copy_normal(*vertex);
00444 }
00445 vertex->clear_normal();
00446 }
00447 if (vertex->has_color()) {
00448 if (!has_color()) {
00449 copy_color(*vertex);
00450 }
00451 vertex->clear_color();
00452 }
00453
00454 EggVertexPool *vertex_pool = orig_vertex->get_pool();
00455 nassertv(vertex_pool != (EggVertexPool *)NULL);
00456 vertex = vertex_pool->create_unique_vertex(*vertex);
00457 vertex->copy_grefs_from(*orig_vertex);
00458 replace(pi, vertex);
00459 }
00460 }
00461 break;
00462
00463 case S_unknown:
00464 break;
00465 }
00466
00467 if (!has_color() && shading == S_overall) {
00468 set_color(LColor(1.0f, 1.0f, 1.0f, 1.0f));
00469 }
00470 }
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485 void EggPrimitive::
00486 apply_last_attribute() {
00487 if (!empty()) {
00488 do_apply_flat_attribute(size() - 1, this);
00489 }
00490 }
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505 void EggPrimitive::
00506 apply_first_attribute() {
00507 if (!empty()) {
00508 do_apply_flat_attribute(0, this);
00509 }
00510 }
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520 void EggPrimitive::
00521 post_apply_flat_attribute() {
00522 if (!empty()) {
00523 for (int i = 0; i < (int)size(); i++) {
00524 EggVertex *vertex = get_vertex(i);
00525
00526
00527
00528
00529
00530 if (has_normal() && !vertex->has_normal()) {
00531 vertex->set_normal(get_normal());
00532 }
00533 if (has_color() && !vertex->has_color()) {
00534 vertex->set_color(get_color());
00535 }
00536 }
00537 }
00538 }
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548 void EggPrimitive::
00549 reverse_vertex_ordering() {
00550
00551
00552
00553 reverse(_vertices.begin(), _vertices.end());
00554 }
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565 bool EggPrimitive::
00566 cleanup() {
00567 return !empty();
00568 }
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588 void EggPrimitive::
00589 remove_doubled_verts(bool closed) {
00590 if (!_vertices.empty()) {
00591 Vertices new_vertices;
00592 Vertices::iterator vi, vlast;
00593 vi = _vertices.begin();
00594 new_vertices.push_back(*vi);
00595 int num_removed = 0;
00596
00597 vlast = vi;
00598 ++vi;
00599 while (vi != _vertices.end()) {
00600 if ((*vi)->get_pos4() != (*vlast)->get_pos4()) {
00601 new_vertices.push_back(*vi);
00602 } else {
00603 prepare_remove_vertex(*vi, vi - _vertices.begin() - num_removed,
00604 _vertices.size() - num_removed);
00605 num_removed++;
00606 }
00607 vlast = vi;
00608 ++vi;
00609 }
00610 _vertices.swap(new_vertices);
00611 }
00612
00613 if (closed) {
00614
00615
00616
00617 while (_vertices.size() > 1 &&
00618 _vertices.back()->get_pos4() == _vertices.front()->get_pos4()) {
00619 prepare_remove_vertex(_vertices.back(), _vertices.size() - 1,
00620 _vertices.size());
00621 _vertices.pop_back();
00622 }
00623 }
00624 }
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635 void EggPrimitive::
00636 remove_nonunique_verts() {
00637 Vertices::iterator vi, vj;
00638 Vertices new_vertices;
00639 int num_removed = 0;
00640
00641 pset<EggVertex *> unique_vertices;
00642 for (vi = _vertices.begin(); vi != _vertices.end(); ++vi) {
00643 bool inserted = unique_vertices.insert(*vi).second;
00644 if (inserted) {
00645 new_vertices.push_back(*vi);
00646 } else {
00647 prepare_remove_vertex(*vi, vi - _vertices.begin() - num_removed,
00648 _vertices.size() - num_removed);
00649 num_removed++;
00650 }
00651 }
00652
00653 _vertices.swap(new_vertices);
00654 }
00655
00656
00657
00658
00659
00660
00661
00662
00663 bool EggPrimitive::
00664 has_primitives() const {
00665 return true;
00666 }
00667
00668
00669
00670
00671
00672
00673
00674
00675 bool EggPrimitive::
00676 joint_has_primitives() const {
00677 return true;
00678 }
00679
00680
00681
00682
00683
00684
00685
00686
00687 bool EggPrimitive::
00688 has_normals() const {
00689 if (has_normal()) {
00690 return true;
00691 }
00692
00693 const_iterator vi;
00694 for (vi = begin(); vi != end(); ++vi) {
00695 if ((*vi)->has_normal()) {
00696 return true;
00697 }
00698 }
00699
00700 return false;
00701 }
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711 EggPrimitive::iterator EggPrimitive::
00712 erase(iterator first, iterator last) {
00713 iterator i;
00714 int num_removed = 0;
00715 for (i = first; i != last; ++i) {
00716 prepare_remove_vertex(*i, first - _vertices.begin(),
00717 _vertices.size() - num_removed);
00718 num_removed++;
00719 }
00720 iterator result = _vertices.erase((Vertices::iterator &)first,
00721 (Vertices::iterator &)last);
00722 test_vref_integrity();
00723 return result;
00724 }
00725
00726
00727
00728
00729
00730
00731
00732
00733 EggPrimitive::iterator EggPrimitive::
00734 find(EggVertex *vertex) {
00735 PT_EggVertex vpt = vertex;
00736 return ::find(begin(), end(), vpt);
00737 }
00738
00739
00740
00741
00742
00743
00744
00745
00746 EggVertex *EggPrimitive::
00747 add_vertex(EggVertex *vertex) {
00748 prepare_add_vertex(vertex, _vertices.size(), _vertices.size() + 1);
00749 _vertices.push_back(vertex);
00750
00751 vertex->test_pref_integrity();
00752 test_vref_integrity();
00753
00754 return vertex;
00755 }
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765 EggVertex *EggPrimitive::
00766 remove_vertex(EggVertex *vertex) {
00767 PT_EggVertex vpt = vertex;
00768 iterator i = ::find(begin(), end(), vpt);
00769 if (i == end()) {
00770 return PT_EggVertex();
00771 } else {
00772
00773 erase(i);
00774
00775 vertex->test_pref_integrity();
00776 test_vref_integrity();
00777
00778 return vertex;
00779 }
00780 }
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790 void EggPrimitive::
00791 copy_vertices(const EggPrimitive &other) {
00792 clear();
00793 _vertices.reserve(other.size());
00794
00795 iterator vi;
00796 for (vi = other.begin(); vi != other.end(); ++vi) {
00797 add_vertex(*vi);
00798 }
00799
00800 test_vref_integrity();
00801 other.test_vref_integrity();
00802 }
00803
00804 #ifdef _DEBUG
00805
00806
00807
00808
00809
00810
00811
00812 void EggPrimitive::
00813 test_vref_integrity() const {
00814 test_ref_count_integrity();
00815
00816 if ((int)size() <= egg_test_vref_integrity) {
00817
00818
00819
00820 typedef pmap<const EggVertex *, int> VertexCount;
00821 VertexCount _count;
00822
00823
00824 iterator vi;
00825 for (vi = begin(); vi != end(); ++vi) {
00826 const EggVertex *vert = *vi;
00827 vert->test_ref_count_integrity();
00828
00829 VertexCount::iterator vci = _count.find(vert);
00830 if (vci == _count.end()) {
00831 _count[vert] = 1;
00832 } else {
00833 (*vci).second++;
00834 }
00835 }
00836
00837
00838
00839 VertexCount::iterator vci;
00840 for (vci = _count.begin(); vci != _count.end(); ++vci) {
00841 const EggVertex *vert = (*vci).first;
00842
00843 int count = (*vci).second;
00844 int vert_count = vert->has_pref(this);
00845
00846 nassertv(count == vert_count);
00847 }
00848 }
00849 }
00850
00851 #endif // _DEBUG
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865 void EggPrimitive::
00866 prepare_add_vertex(EggVertex *vertex, int i, int n) {
00867
00868
00869
00870
00871
00872 nassertv(empty() || vertex->get_pool() == get_pool());
00873
00874
00875
00876
00877
00878
00879 vertex->_pref.insert(this);
00880 }
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898 void EggPrimitive::
00899 prepare_remove_vertex(EggVertex *vertex, int i, int n) {
00900
00901
00902
00903
00904
00905
00906
00907
00908 EggVertex::PrimitiveRef::iterator pri = vertex->_pref.find(this);
00909
00910
00911
00912 nassertv(pri != vertex->_pref.end());
00913
00914 vertex->_pref.erase(pri);
00915 }
00916
00917
00918
00919
00920
00921
00922
00923
00924 void EggPrimitive::
00925 write_body(ostream &out, int indent_level) const {
00926 test_vref_integrity();
00927
00928 EggAttributes::write(out, indent_level);
00929 EggRenderMode::write(out, indent_level);
00930
00931 int num_textures = get_num_textures();
00932 for (int i = 0; i < num_textures; i++) {
00933 EggTexture *texture = get_texture(i);
00934
00935 indent(out, indent_level) << "<TRef> { ";
00936 enquote_string(out, texture->get_name())
00937 << " }\n";
00938 }
00939
00940 if (has_material()) {
00941 EggMaterial *material = get_material();
00942
00943 indent(out, indent_level) << "<MRef> { ";
00944 enquote_string(out, material->get_name())
00945 << " }\n";
00946 }
00947
00948 if (get_bface_flag()) {
00949 indent(out, indent_level) << "<BFace> { 1 }\n";
00950 }
00951
00952 if (!empty()) {
00953 EggVertexPool *pool = get_pool();
00954
00955
00956 nassertv(pool != NULL);
00957
00958
00959 nassertv(pool->has_name());
00960
00961 if ((int)size() < 10) {
00962
00963
00964 indent(out, indent_level) << "<VertexRef> {";
00965 const_iterator i;
00966 for (i = begin(); i != end(); ++i) {
00967 EggVertex *vert = *i;
00968 vert->test_pref_integrity();
00969
00970
00971 nassertv(vert->get_pool() == pool);
00972
00973 out << " " << vert->get_index();
00974 }
00975 out << " <Ref> { ";
00976 enquote_string(out, pool->get_name()) << " } }\n";
00977
00978 } else {
00979
00980
00981
00982 vector_int indices;
00983 const_iterator i;
00984 for (i = begin(); i != end(); ++i) {
00985 EggVertex *vert = *i;
00986 vert->test_pref_integrity();
00987
00988
00989 nassertv(vert->get_pool() == pool);
00990
00991 indices.push_back(vert->get_index());
00992 }
00993
00994 indent(out, indent_level) << "<VertexRef> {\n";
00995 write_long_list(out, indent_level+2, indices.begin(), indices.end(),
00996 "", "", 72);
00997 indent(out, indent_level+2) << "<Ref> { ";
00998 enquote_string(out, pool->get_name()) << " }\n";
00999 indent(out, indent_level) << "}\n";
01000 }
01001 }
01002 }
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013 bool EggPrimitive::
01014 egg_start_parse_body() {
01015 egg_start_primitive_body();
01016 return true;
01017 }
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032 void EggPrimitive::
01033 r_transform(const LMatrix4d &mat, const LMatrix4d &, CoordinateSystem) {
01034 EggAttributes::transform(mat);
01035 }
01036
01037
01038
01039
01040
01041
01042 void EggPrimitive::
01043 r_flatten_transforms() {
01044 if (is_local_coord()) {
01045 LMatrix4d mat = get_vertex_frame();
01046 EggAttributes::transform(mat);
01047
01048
01049 size_t num_vertices = size();
01050 for (size_t i = 0; i < num_vertices; i++) {
01051 EggVertex *vertex = get_vertex(i);
01052 EggVertexPool *pool = vertex->get_pool();
01053
01054 EggVertex new_vertex(*vertex);
01055 new_vertex.transform(mat);
01056 EggVertex *unique = pool->create_unique_vertex(new_vertex);
01057 unique->copy_grefs_from(*vertex);
01058
01059 set_vertex(i, unique);
01060 }
01061 }
01062 }
01063
01064
01065
01066
01067
01068
01069 void EggPrimitive::
01070 r_apply_texmats(EggTextureCollection &textures) {
01071 Textures new_textures;
01072 Textures::const_iterator ti;
01073 for (ti = _textures.begin(); ti != _textures.end(); ++ti) {
01074 EggTexture *texture = (*ti);
01075
01076 if (!texture->has_transform()) {
01077 new_textures.push_back(texture);
01078
01079 } else if (texture->transform_is_identity()) {
01080
01081
01082 texture->clear_transform();
01083 new_textures.push_back(texture);
01084
01085 } else {
01086
01087
01088
01089 LMatrix4d mat = texture->get_transform3d();
01090 EggTexture new_texture(*texture);
01091 new_texture.clear_transform();
01092 EggTexture *unique = textures.create_unique_texture(new_texture, ~0);
01093
01094 new_textures.push_back(unique);
01095 string uv_name = unique->get_uv_name();
01096
01097
01098
01099 size_t num_vertices = size();
01100 for (size_t i = 0; i < num_vertices; i++) {
01101 EggVertex *vertex = get_vertex(i);
01102
01103 const EggVertexUV *uv_obj = vertex->get_uv_obj(uv_name);
01104 if (uv_obj != (EggVertexUV *)NULL) {
01105 EggVertex new_vertex(*vertex);
01106 PT(EggVertexUV) new_uv_obj = new EggVertexUV(*uv_obj);
01107 LTexCoord3d uvw = uv_obj->get_uvw() * mat;
01108 if (uv_obj->has_w() || texture->has_transform3d()) {
01109 new_uv_obj->set_uvw(uvw);
01110 } else {
01111 new_uv_obj->set_uv(LTexCoordd(uvw[0], uvw[1]));
01112 }
01113 new_vertex.set_uv_obj(new_uv_obj);
01114
01115 EggVertexPool *pool = vertex->get_pool();
01116 EggVertex *unique = pool->create_unique_vertex(new_vertex);
01117 unique->copy_grefs_from(*vertex);
01118
01119 set_vertex(i, unique);
01120 }
01121 }
01122 }
01123 }
01124
01125 _textures.swap(new_textures);
01126 }
01127
01128
01129
01130
01131
01132
01133
01134
01135 void EggPrimitive::
01136 do_apply_flat_attribute(int vertex_index, EggAttributes *attrib) {
01137
01138
01139
01140
01141
01142
01143 bool significant_change = false;
01144
01145 EggVertex *orig_vertex = get_vertex(vertex_index);
01146 PT(EggVertex) new_vertex = new EggVertex(*orig_vertex);
01147
01148 if (attrib->has_normal()) {
01149 new_vertex->copy_normal(*attrib);
01150
01151 if (orig_vertex->has_normal() &&
01152 !orig_vertex->matches_normal(*new_vertex)) {
01153 significant_change = true;
01154 }
01155 } else if (has_normal()) {
01156 new_vertex->copy_normal(*this);
01157
01158 if (orig_vertex->has_normal() &&
01159 !orig_vertex->matches_normal(*new_vertex)) {
01160 significant_change = true;
01161 }
01162 }
01163
01164 if (attrib->has_color()) {
01165 new_vertex->copy_color(*attrib);
01166
01167 if (orig_vertex->has_color() &&
01168 !orig_vertex->matches_color(*new_vertex)) {
01169 significant_change = true;
01170 }
01171 } else if (has_color()) {
01172 new_vertex->copy_color(*this);
01173
01174 if (orig_vertex->has_color() &&
01175 !orig_vertex->matches_color(*new_vertex)) {
01176 significant_change = true;
01177 }
01178 }
01179
01180 if (significant_change) {
01181 new_vertex = get_pool()->create_unique_vertex(*new_vertex);
01182 new_vertex->copy_grefs_from(*orig_vertex);
01183 set_vertex(vertex_index, new_vertex);
01184 } else {
01185
01186 ((EggAttributes *)orig_vertex)->operator = (*new_vertex);
01187 }
01188 }
01189
01190
01191
01192
01193
01194
01195
01196 void EggPrimitive::
01197 set_connected_shading(EggPrimitive::Shading shading,
01198 const EggAttributes *neighbor) {
01199 ConnectedShadingNodes connected_nodes;
01200
01201 r_set_connected_shading(0, shading, neighbor, connected_nodes);
01202
01203
01204
01205 while (!connected_nodes.empty()) {
01206 ConnectedShadingNodes next_nodes;
01207 next_nodes.swap(connected_nodes);
01208
01209 ConnectedShadingNodes::iterator ni;
01210 for (ni = next_nodes.begin(); ni != next_nodes.end(); ++ni) {
01211 r_set_connected_shading(0, (*ni)._shading, (*ni)._neighbor, connected_nodes);
01212 }
01213 }
01214 }
01215
01216
01217
01218
01219
01220
01221
01222 void EggPrimitive::
01223 r_set_connected_shading(int stack_depth, EggPrimitive::Shading shading,
01224 const EggAttributes *neighbor,
01225 ConnectedShadingNodes &next_nodes) {
01226 if (stack_depth > egg_recursion_limit) {
01227
01228 ConnectedShadingNode next;
01229 next._shading = shading;
01230 next._neighbor = neighbor;
01231 next_nodes.push_back(next);
01232 return;
01233 }
01234
01235 bool propagate = false;
01236
01237 if (_connected_shading == S_unknown) {
01238
01239 _connected_shading = get_shading();
01240 propagate = true;
01241 }
01242
01243 if (shading > _connected_shading) {
01244
01245
01246 _connected_shading = shading;
01247 propagate = true;
01248
01249 } else if (shading == S_overall && _connected_shading == S_overall) {
01250
01251
01252
01253 bool matches_normal = this->matches_normal(*neighbor);
01254 bool matches_color = this->matches_color(*neighbor);
01255
01256 if (!matches_color) {
01257
01258
01259 if (!neighbor->has_color() && has_color() && _drgbas.empty() &&
01260 get_color() == LColor(1.0f, 1.0f, 1.0f, 1.0f)) {
01261 matches_color = true;
01262 } else if (!has_color() && neighbor->has_color() && neighbor->_drgbas.empty() &&
01263 neighbor->get_color() == LColor(1.0f, 1.0f, 1.0f, 1.0f)) {
01264 matches_color = true;
01265 }
01266 }
01267 if (!matches_normal || !matches_color) {
01268 _connected_shading = S_per_face;
01269 propagate = true;
01270 }
01271 }
01272
01273 if (propagate) {
01274 Vertices::const_iterator vi;
01275 for (vi = _vertices.begin(); vi != _vertices.end(); ++vi) {
01276 EggVertex *vertex = (*vi);
01277 EggVertex::PrimitiveRef::const_iterator pi;
01278 for (pi = vertex->pref_begin();
01279 pi != vertex->pref_end();
01280 ++pi) {
01281 (*pi)->r_set_connected_shading(stack_depth + 1, _connected_shading, this,
01282 next_nodes);
01283 }
01284 }
01285 }
01286 }