00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "eggCompositePrimitive.h"
00016 #include "eggGroupNode.h"
00017 #include "eggVertexPool.h"
00018
00019 TypeHandle EggCompositePrimitive::_type_handle;
00020
00021
00022
00023
00024
00025
00026
00027 EggCompositePrimitive::
00028 ~EggCompositePrimitive() {
00029
00030
00031 nassertv(_components.empty());
00032 }
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 EggPrimitive::Shading EggCompositePrimitive::
00054 get_shading() const {
00055 Shading basic_shading = EggPrimitive::get_shading();
00056 if (basic_shading == S_per_vertex) {
00057 return basic_shading;
00058 }
00059 if (_components.empty()) {
00060 return S_overall;
00061 }
00062
00063
00064 {
00065 const EggAttributes *first_component = get_component(0);
00066 if (!first_component->has_normal()) {
00067 first_component = this;
00068 }
00069 for (int i = 1; i < get_num_components(); i++) {
00070 const EggAttributes *component = get_component(i);
00071 if (!component->has_normal()) {
00072 component = this;
00073 }
00074 if (!component->matches_normal(*first_component)) {
00075 return S_per_face;
00076 }
00077 }
00078 }
00079
00080
00081 {
00082 const EggAttributes *first_component = get_component(0);
00083 if (!first_component->has_color()) {
00084 first_component = this;
00085 }
00086 for (int i = 1; i < get_num_components(); i++) {
00087 const EggAttributes *component = get_component(i);
00088 if (!component->has_color()) {
00089 component = this;
00090 }
00091 if (!component->matches_color(*first_component)) {
00092 return S_per_face;
00093 }
00094 }
00095 }
00096
00097 return S_overall;
00098 }
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115 PT(EggCompositePrimitive) EggCompositePrimitive::
00116 triangulate_in_place() {
00117 EggGroupNode *parent = get_parent();
00118 nassertr(parent != (EggGroupNode *)NULL, this);
00119
00120 PT(EggCompositePrimitive) save_me = this;
00121 parent->remove_child(this);
00122 do_triangulate(parent);
00123
00124 return save_me;
00125 }
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151 void EggCompositePrimitive::
00152 unify_attributes(EggPrimitive::Shading shading) {
00153 if (shading == S_unknown) {
00154 shading = get_shading();
00155 }
00156
00157 switch (shading) {
00158 case S_per_vertex:
00159
00160 {
00161 Components::iterator ci;
00162 for (ci = _components.begin(); ci != _components.end(); ++ci) {
00163 EggAttributes *component = (*ci);
00164 if (component->has_normal()) {
00165 if (!has_normal()) {
00166 copy_normal(*component);
00167 }
00168 component->clear_normal();
00169 }
00170 if (component->has_color()) {
00171 if (!has_color()) {
00172 copy_color(*component);
00173 }
00174 component->clear_color();
00175 }
00176 }
00177
00178
00179 if (!has_color()) {
00180 set_color(LColor(1.0f, 1.0f, 1.0f, 1.0f));
00181 }
00182
00183 iterator pi;
00184 for (pi = begin(); pi != end(); ++pi) {
00185 EggVertex *orig_vertex = (*pi);
00186 PT(EggVertex) vertex = new EggVertex(*orig_vertex);
00187 if (!vertex->has_normal() && has_normal()) {
00188 vertex->copy_normal(*this);
00189 }
00190 if (!vertex->has_color() && has_color()) {
00191 vertex->copy_color(*this);
00192 }
00193
00194 EggVertexPool *vertex_pool = orig_vertex->get_pool();
00195 nassertv(vertex_pool != (EggVertexPool *)NULL);
00196 vertex = vertex_pool->create_unique_vertex(*vertex);
00197 vertex->copy_grefs_from(*orig_vertex);
00198 replace(pi, vertex);
00199 }
00200 clear_normal();
00201 clear_color();
00202 }
00203 break;
00204
00205 case S_per_face:
00206
00207 {
00208 iterator pi;
00209 for (pi = begin(); pi != end(); ++pi) {
00210 EggVertex *orig_vertex = (*pi);
00211 if (orig_vertex->has_normal() || orig_vertex->has_color()) {
00212 if (orig_vertex->has_normal() && !has_normal()) {
00213 copy_normal(*orig_vertex);
00214 }
00215 if (orig_vertex->has_color() && !has_color()) {
00216 copy_color(*orig_vertex);
00217 }
00218
00219 PT(EggVertex) vertex = new EggVertex(*orig_vertex);
00220 vertex->clear_normal();
00221 vertex->clear_color();
00222
00223 EggVertexPool *vertex_pool = orig_vertex->get_pool();
00224 nassertv(vertex_pool != (EggVertexPool *)NULL);
00225 vertex = vertex_pool->create_unique_vertex(*vertex);
00226 vertex->copy_grefs_from(*orig_vertex);
00227 replace(pi, vertex);
00228 }
00229 }
00230
00231
00232 if (!has_color()) {
00233 set_color(LColor(1.0f, 1.0f, 1.0f, 1.0f));
00234 }
00235
00236 Components::iterator ci;
00237 for (ci = _components.begin(); ci != _components.end(); ++ci) {
00238 EggAttributes *component = (*ci);
00239 if (!component->has_normal() && has_normal()) {
00240 component->copy_normal(*this);
00241 }
00242 if (!component->has_color() && has_color()) {
00243 component->copy_color(*this);
00244 }
00245 }
00246 clear_normal();
00247 clear_color();
00248 }
00249 break;
00250
00251 case S_overall:
00252
00253 {
00254 iterator pi;
00255 for (pi = begin(); pi != end(); ++pi) {
00256 EggVertex *orig_vertex = (*pi);
00257 PT(EggVertex) vertex = new EggVertex(*orig_vertex);
00258 if (vertex->has_normal()) {
00259 if (!has_normal()) {
00260 copy_normal(*vertex);
00261 }
00262 vertex->clear_normal();
00263 }
00264 if (vertex->has_color()) {
00265 if (!has_color()) {
00266 copy_color(*vertex);
00267 }
00268 vertex->clear_color();
00269 }
00270
00271 EggVertexPool *vertex_pool = orig_vertex->get_pool();
00272 nassertv(vertex_pool != (EggVertexPool *)NULL);
00273 vertex = vertex_pool->create_unique_vertex(*vertex);
00274 vertex->copy_grefs_from(*orig_vertex);
00275 replace(pi, vertex);
00276 }
00277 Components::iterator ci;
00278 for (ci = _components.begin(); ci != _components.end(); ++ci) {
00279 EggAttributes *component = (*ci);
00280 if (component->has_normal()) {
00281 if (!has_normal()) {
00282 copy_normal(*component);
00283 }
00284 component->clear_normal();
00285 }
00286 if (component->has_color()) {
00287 if (!has_color()) {
00288 copy_color(*component);
00289 }
00290 component->clear_color();
00291 }
00292 }
00293
00294
00295 if (!has_color()) {
00296 set_color(LColor(1.0f, 1.0f, 1.0f, 1.0f));
00297 }
00298 }
00299 break;
00300
00301 case S_unknown:
00302 break;
00303 }
00304 }
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319 void EggCompositePrimitive::
00320 apply_last_attribute() {
00321
00322
00323 int num_lead_vertices = get_num_lead_vertices();
00324 for (int i = 0; i < get_num_components(); i++) {
00325 EggAttributes *component = get_component(i);
00326 do_apply_flat_attribute(i + num_lead_vertices, component);
00327 }
00328 }
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343 void EggCompositePrimitive::
00344 apply_first_attribute() {
00345
00346
00347 for (int i = 0; i < get_num_components(); i++) {
00348 EggAttributes *component = get_component(i);
00349 do_apply_flat_attribute(i, component);
00350 }
00351 }
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361 void EggCompositePrimitive::
00362 post_apply_flat_attribute() {
00363 if (!empty()) {
00364 int num_lead_vertices = get_num_lead_vertices();
00365 for (int i = 0; i < (int)size(); i++) {
00366 EggVertex *vertex = get_vertex(i);
00367 EggAttributes *component = get_component(max(i - num_lead_vertices, 0));
00368
00369
00370
00371
00372
00373 if (component->has_normal() && !vertex->has_normal()) {
00374 vertex->set_normal(component->get_normal());
00375 } else if (has_normal() && !vertex->has_normal()) {
00376 vertex->set_normal(get_normal());
00377 }
00378
00379 if (component->has_color() && !vertex->has_color()) {
00380 vertex->set_color(component->get_color());
00381 } else if (has_color() && !vertex->has_color()) {
00382 vertex->set_color(get_color());
00383 }
00384 }
00385 }
00386 }
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397 bool EggCompositePrimitive::
00398 cleanup() {
00399 return (int)size() >= get_num_lead_vertices() + 1;
00400 }
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414 void EggCompositePrimitive::
00415 prepare_add_vertex(EggVertex *vertex, int i, int n) {
00416 EggPrimitive::prepare_add_vertex(vertex, i, n);
00417
00418 int num_lead_vertices = get_num_lead_vertices();
00419 if (n >= num_lead_vertices + 1) {
00420 i = max(i - num_lead_vertices, 0);
00421 nassertv(i <= (int)_components.size());
00422 _components.insert(_components.begin() + i, new EggAttributes(*this));
00423 }
00424 }
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442 void EggCompositePrimitive::
00443 prepare_remove_vertex(EggVertex *vertex, int i, int n) {
00444 EggPrimitive::prepare_remove_vertex(vertex, i, n);
00445
00446 int num_lead_vertices = get_num_lead_vertices();
00447 if (n >= num_lead_vertices + 1) {
00448 i = max(i - num_lead_vertices, 0);
00449 nassertv(i < (int)_components.size());
00450 delete _components[i];
00451 _components.erase(_components.begin() + i);
00452 }
00453 }
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470 bool EggCompositePrimitive::
00471 do_triangulate(EggGroupNode *container) const {
00472 container->add_child((EggCompositePrimitive *)this);
00473 return true;
00474 }
00475
00476
00477
00478
00479
00480
00481
00482
00483 void EggCompositePrimitive::
00484 write_body(ostream &out, int indent_level) const {
00485 EggPrimitive::write_body(out, indent_level);
00486
00487 for (int i = 0; i < get_num_components(); i++) {
00488 const EggAttributes *attrib = get_component(i);
00489 if (attrib->compare_to(*this) != 0 &&
00490 (attrib->has_color() || attrib->has_normal())) {
00491 indent(out, indent_level)
00492 << "<Component> " << i << " {\n";
00493 attrib->write(out, indent_level + 2);
00494 indent(out, indent_level) << "}\n";
00495 }
00496 }
00497 }