Panda3D
 All Classes Functions Variables Enumerations
eggPrimitive.cxx
1 // Filename: eggPrimitive.cxx
2 // Created by: drose (16Jan99)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "eggPrimitive.h"
16 #include "eggVertexPool.h"
17 #include "eggMiscFuncs.h"
18 #include "eggTextureCollection.h"
19 #include "lexerDefs.h"
20 #include "config_egg.h"
21 
22 #include "indent.h"
23 #include "vector_int.h"
24 
25 TypeHandle EggPrimitive::_type_handle;
26 
27 
28 ////////////////////////////////////////////////////////////////////
29 // Function: EggPrimitive::determine_alpha_mode
30 // Access: Published, Virtual
31 // Description: Walks back up the hierarchy, looking for an EggGroup
32 // or EggPrimitive or some such object at this level or
33 // above this primitive that has an alpha_mode other than
34 // AM_unspecified. Returns a valid EggRenderMode pointer
35 // if one is found, or NULL otherwise.
36 ////////////////////////////////////////////////////////////////////
39  if (get_alpha_mode() != AM_unspecified) {
40  return this;
41  }
42 
44  if (result == (EggRenderMode *)NULL) {
45  int num_textures = get_num_textures();
46  for (int i = 0; i < num_textures && result == (EggRenderMode *)NULL; i++) {
47  EggTexture *egg_tex = get_texture(i);
48 
49  // We only want to consider the alpha mode on those textures
50  // that can affect the transparency of the polygon. This
51  // mostly depends on the envtype flag.
52  if (egg_tex->affects_polygon_alpha()) {
53  // This texture might affect the polygon alpha, so it gets to
54  // decide the polygon transparency mode.
55  if (egg_tex->get_alpha_mode() != AM_unspecified) {
56  result = get_texture(i);
57  }
58  }
59  }
60  }
61  return result;
62 }
63 
64 ////////////////////////////////////////////////////////////////////
65 // Function: EggPrimitive::determine_depth_write_mode
66 // Access: Published, Virtual
67 // Description: Walks back up the hierarchy, looking for an EggGroup
68 // or EggPrimitive or some such object at this level or
69 // above this node that has a depth_write_mode other than
70 // DWM_unspecified. Returns a valid EggRenderMode pointer
71 // if one is found, or NULL otherwise.
72 ////////////////////////////////////////////////////////////////////
75  if (get_depth_write_mode() != DWM_unspecified) {
76  return this;
77  }
78 
80  if (result == (EggRenderMode *)NULL) {
81  int num_textures = get_num_textures();
82  for (int i = 0; i < num_textures && result == (EggRenderMode *)NULL; i++) {
83  if (get_texture(i)->get_depth_write_mode() != DWM_unspecified) {
84  result = get_texture(i);
85  }
86  }
87  }
88  return result;
89 }
90 
91 ////////////////////////////////////////////////////////////////////
92 // Function: EggPrimitive::determine_depth_test_mode
93 // Access: Published, Virtual
94 // Description: Walks back up the hierarchy, looking for an EggGroup
95 // or EggPrimitive or some such object at this level or
96 // above this node that has a depth_test_mode other than
97 // DTM_unspecified. Returns a valid EggRenderMode pointer
98 // if one is found, or NULL otherwise.
99 ////////////////////////////////////////////////////////////////////
102  if (get_depth_test_mode() != DTM_unspecified) {
103  return this;
104  }
105 
107  if (result == (EggRenderMode *)NULL) {
108  int num_textures = get_num_textures();
109  for (int i = 0; i < num_textures && result == (EggRenderMode *)NULL; i++) {
110  if (get_texture(i)->get_depth_test_mode() != DTM_unspecified) {
111  result = get_texture(i);
112  }
113  }
114  }
115  return result;
116 }
117 
118 ////////////////////////////////////////////////////////////////////
119 // Function: EggPrimitive::determine_visibility_mode
120 // Access: Published, Virtual
121 // Description: Walks back up the hierarchy, looking for an EggGroup
122 // or EggPrimitive or some such object at this level or
123 // above this node that has a visibility_mode other than
124 // VM_unspecified. Returns a valid EggRenderMode pointer
125 // if one is found, or NULL otherwise.
126 ////////////////////////////////////////////////////////////////////
129  if (get_visibility_mode() != VM_unspecified) {
130  return this;
131  }
132 
134  if (result == (EggRenderMode *)NULL) {
135  int num_textures = get_num_textures();
136  for (int i = 0; i < num_textures && result == (EggRenderMode *)NULL; i++) {
137  if (get_texture(i)->get_visibility_mode() != VM_unspecified) {
138  result = get_texture(i);
139  }
140  }
141  }
142  return result;
143 }
144 
145 ////////////////////////////////////////////////////////////////////
146 // Function: EggPrimitive::determine_depth_offset
147 // Access: Published, Virtual
148 // Description: Walks back up the hierarchy, looking for an EggGroup
149 // or EggPrimitive or some such object at this level or
150 // above this primitive that has a depth_offset specified.
151 // Returns a valid EggRenderMode pointer if one is found,
152 // or NULL otherwise.
153 ////////////////////////////////////////////////////////////////////
156  if (has_depth_offset()) {
157  return this;
158  }
159 
161  if (result == (EggRenderMode *)NULL) {
162  int num_textures = get_num_textures();
163  for (int i = 0; i < num_textures && result == (EggRenderMode *)NULL; i++) {
164  if (get_texture(i)->has_depth_offset()) {
165  result = get_texture(i);
166  }
167  }
168  }
169  return result;
170 }
171 
172 ////////////////////////////////////////////////////////////////////
173 // Function: EggPrimitive::determine_draw_order
174 // Access: Published, Virtual
175 // Description: Walks back up the hierarchy, looking for an EggGroup
176 // or EggPrimitive or some such object at this level or
177 // above this primitive that has a draw_order specified.
178 // Returns a valid EggRenderMode pointer if one is found,
179 // or NULL otherwise.
180 ////////////////////////////////////////////////////////////////////
183  if (has_draw_order()) {
184  return this;
185  }
186 
188  if (result == (EggRenderMode *)NULL) {
189  int num_textures = get_num_textures();
190  for (int i = 0; i < num_textures && result == (EggRenderMode *)NULL; i++) {
191  if (get_texture(i)->has_draw_order()) {
192  result = get_texture(i);
193  }
194  }
195  }
196  return result;
197 }
198 
199 ////////////////////////////////////////////////////////////////////
200 // Function: EggPrimitive::determine_bin
201 // Access: Published, Virtual
202 // Description: Walks back up the hierarchy, looking for an EggGroup
203 // or EggPrimitive or some such object at this level or
204 // above this primitive that has a bin specified. Returns a
205 // valid EggRenderMode pointer if one is found, or NULL
206 // otherwise.
207 ////////////////////////////////////////////////////////////////////
210  if (has_bin()) {
211  return this;
212  }
213 
215  if (result == (EggRenderMode *)NULL) {
216  int num_textures = get_num_textures();
217  for (int i = 0; i < num_textures && result == (EggRenderMode *)NULL; i++) {
218  if (get_texture(i)->has_bin()) {
219  result = get_texture(i);
220  }
221  }
222  }
223  return result;
224 }
225 
226 
227 ////////////////////////////////////////////////////////////////////
228 // Function: EggPrimitive::get_shading
229 // Access: Published, Virtual
230 // Description: Returns the shading properties apparent on this
231 // particular primitive. This returns S_per_vertex if
232 // the vertices have colors or normals (and they are not
233 // all the same values), or for a simple primitive,
234 // S_overall otherwise. A composite primitive may also
235 // return S_per_face if the individual component
236 // primitives have colors or normals that are not all
237 // the same values.
238 //
239 // To get the most accurate results, you should call
240 // clear_shading() on all connected primitives (or on
241 // all primitives in the egg file), followed by
242 // get_shading() on each primitive. You may find it
243 // easiest to call these methods on the EggData root
244 // node (they are defined on EggGroupNode).
245 ////////////////////////////////////////////////////////////////////
246 EggPrimitive::Shading EggPrimitive::
247 get_shading() const {
248  if (empty()) {
249  return S_overall;
250  }
251 
252  if (has_vertex_normal()) {
253  // Check if the vertices all have the same normal.
254  const EggAttributes *first_vertex = get_vertex(0);
255  if (!first_vertex->has_normal()) {
256  first_vertex = this;
257  }
258  for (int i = 1; i < get_num_vertices(); i++) {
259  const EggAttributes *vertex = get_vertex(i);
260  if (!vertex->has_normal()) {
261  vertex = this;
262  }
263  if (!vertex->matches_normal(*first_vertex)) {
264  return S_per_vertex;
265  }
266  }
267  }
268 
269  if (has_vertex_color()) {
270  // Check if the vertices all have the same color.
271  const EggAttributes *first_vertex = get_vertex(0);
272  if (!first_vertex->has_color()) {
273  first_vertex = this;
274  }
275  for (int i = 1; i < get_num_vertices(); i++) {
276  const EggAttributes *vertex = get_vertex(i);
277  if (!vertex->has_color()) {
278  vertex = this;
279  }
280  if (!vertex->matches_color(*first_vertex)) {
281  return S_per_vertex;
282  }
283  }
284  }
285 
286  return S_overall;
287 }
288 
289 ////////////////////////////////////////////////////////////////////
290 // Function: EggPrimitive::copy_attributes
291 // Access: Published
292 // Description: Copies the rendering attributes from the indicated
293 // primitive.
294 ////////////////////////////////////////////////////////////////////
295 void EggPrimitive::
297  EggAttributes::operator = (other);
298 }
299 
300 ////////////////////////////////////////////////////////////////////
301 // Function: EggPrimitive::copy_attributes
302 // Access: Published
303 // Description: Copies the rendering attributes from the indicated
304 // primitive.
305 ////////////////////////////////////////////////////////////////////
306 void EggPrimitive::
308  EggAttributes::operator = (other);
309  _textures = other._textures;
310  set_material(other.get_material());
312 }
313 
314 ////////////////////////////////////////////////////////////////////
315 // Function: EggPrimitive::has_vertex_normal
316 // Access: Published
317 // Description: Returns true if any vertex on the primitive has a
318 // specific normal set, false otherwise.
319 //
320 // If you call unify_attributes() first, this will also
321 // return false even if all the vertices were set to the
322 // same value (since unify_attributes() removes
323 // redundant vertex properties).
324 ////////////////////////////////////////////////////////////////////
325 bool EggPrimitive::
327  Vertices::const_iterator vi;
328  for (vi = _vertices.begin(); vi != _vertices.end(); ++vi) {
329  if ((*vi)->has_normal()) {
330  return true;
331  }
332  }
333  return false;
334 }
335 
336 ////////////////////////////////////////////////////////////////////
337 // Function: EggPrimitive::has_vertex_color
338 // Access: Published
339 // Description: Returns true if any vertex on the primitive has a
340 // specific color set, false otherwise.
341 //
342 // If you call unify_attributes() first, this will also
343 // return false even if all the vertices were set to the
344 // same value (since unify_attributes() removes
345 // redundant vertex properties).
346 ////////////////////////////////////////////////////////////////////
347 bool EggPrimitive::
349  Vertices::const_iterator vi;
350  for (vi = _vertices.begin(); vi != _vertices.end(); ++vi) {
351  if ((*vi)->has_color()) {
352  return true;
353  }
354  }
355  return false;
356 }
357 
358 ////////////////////////////////////////////////////////////////////
359 // Function: EggPrimitive::unify_attributes
360 // Access: Published, Virtual
361 // Description: If the shading property is S_per_vertex, ensures that
362 // all vertices have a normal and a color, and the
363 // overall primitive does not.
364 //
365 // If the shading property is S_per_face, and this is a
366 // composite primitive, ensures that all components have
367 // a normal and a color, and the vertices and overall
368 // primitive do not. (If this is a simple primitive,
369 // S_per_face works the same as S_overall, below).
370 //
371 // If the shading property is S_overall, ensures that no
372 // vertices or components have a normal or a color, and
373 // the overall primitive does (if any exists at all).
374 //
375 // After this call, either the primitive will have
376 // normals or its vertices will, but not both. Ditto
377 // for colors.
378 //
379 // This may create redundant vertices in the vertex
380 // pool.
381 ////////////////////////////////////////////////////////////////////
382 void EggPrimitive::
383 unify_attributes(EggPrimitive::Shading shading) {
384  if (shading == S_unknown) {
385  shading = get_shading();
386  }
387 
388  // Does the primitive have an explicit color?
389  if (!has_color() && shading != S_overall) {
390  if (shading != S_per_vertex) {
391  // If there is no color set, first we check the vertices. If the
392  // vertices have a color, we inherit the color from there.
393  iterator pi;
394  for (pi = begin(); pi != end() && !has_color(); ++pi) {
395  EggVertex *vertex = (*pi);
396  if (vertex->has_color()) {
397  set_color(vertex->get_color());
398  }
399  }
400  }
401  if (!has_color()) {
402  // If we still don't have a color, the implicit color is white.
403  set_color(LColor(1.0f, 1.0f, 1.0f, 1.0f));
404  }
405  }
406 
407  switch (shading) {
408  case S_per_vertex:
409  // Propagate everything to the vertices.
410  {
411  iterator pi;
412  for (pi = begin(); pi != end(); ++pi) {
413  EggVertex *orig_vertex = (*pi);
414  PT(EggVertex) vertex = new EggVertex(*orig_vertex);
415  if (!vertex->has_normal() && has_normal()) {
416  vertex->copy_normal(*this);
417  }
418  if (!vertex->has_color() && has_color()) {
419  vertex->copy_color(*this);
420  }
421 
422  EggVertexPool *vertex_pool = orig_vertex->get_pool();
423  nassertv(vertex_pool != (EggVertexPool *)NULL);
424  vertex = vertex_pool->create_unique_vertex(*vertex);
425  vertex->copy_grefs_from(*orig_vertex);
426  replace(pi, vertex);
427  }
428  clear_normal();
429  clear_color();
430  }
431  break;
432 
433  case S_per_face:
434  case S_overall:
435  // Remove everything from the vertices.
436  {
437  iterator pi;
438  for (pi = begin(); pi != end(); ++pi) {
439  EggVertex *orig_vertex = (*pi);
440  PT(EggVertex) vertex = new EggVertex(*orig_vertex);
441  if (vertex->has_normal()) {
442  if (!has_normal()) {
443  copy_normal(*vertex);
444  }
445  vertex->clear_normal();
446  }
447  if (vertex->has_color()) {
448  if (!has_color()) {
449  copy_color(*vertex);
450  }
451  vertex->clear_color();
452  }
453 
454  EggVertexPool *vertex_pool = orig_vertex->get_pool();
455  nassertv(vertex_pool != (EggVertexPool *)NULL);
456  vertex = vertex_pool->create_unique_vertex(*vertex);
457  vertex->copy_grefs_from(*orig_vertex);
458  replace(pi, vertex);
459  }
460  }
461  break;
462 
463  case S_unknown:
464  break;
465  }
466 
467  if (!has_color() && shading == S_overall) {
468  set_color(LColor(1.0f, 1.0f, 1.0f, 1.0f));
469  }
470 }
471 
472 ////////////////////////////////////////////////////////////////////
473 // Function: EggPrimitive::apply_last_attribute
474 // Access: Published, Virtual
475 // Description: Sets the last vertex of the triangle (or each
476 // component) to the primitive normal and/or color, if
477 // the primitive is flat-shaded. This reflects the
478 // OpenGL convention of storing flat-shaded properties on
479 // the last vertex, although it is not usually a
480 // convention in Egg.
481 //
482 // This may introduce redundant vertices to the vertex
483 // pool.
484 ////////////////////////////////////////////////////////////////////
485 void EggPrimitive::
487  if (!empty()) {
488  do_apply_flat_attribute(size() - 1, this);
489  }
490 }
491 
492 ////////////////////////////////////////////////////////////////////
493 // Function: EggPrimitive::apply_first_attribute
494 // Access: Published, Virtual
495 // Description: Sets the first vertex of the triangle (or each
496 // component) to the primitive normal and/or color, if
497 // the primitive is flat-shaded. This reflects the
498 // DirectX convention of storing flat-shaded properties on
499 // the first vertex, although it is not usually a
500 // convention in Egg.
501 //
502 // This may introduce redundant vertices to the vertex
503 // pool.
504 ////////////////////////////////////////////////////////////////////
505 void EggPrimitive::
507  if (!empty()) {
508  do_apply_flat_attribute(0, this);
509  }
510 }
511 
512 ////////////////////////////////////////////////////////////////////
513 // Function: EggPrimitive::post_apply_flat_attribute
514 // Access: Published, Virtual
515 // Description: Intended as a followup to apply_last_attribute(),
516 // this also sets an attribute on the first vertices of
517 // the primitive, if they don't already have an
518 // attribute set, just so they end up with *something*.
519 ////////////////////////////////////////////////////////////////////
520 void EggPrimitive::
522  if (!empty()) {
523  for (int i = 0; i < (int)size(); i++) {
524  EggVertex *vertex = get_vertex(i);
525 
526  // Use set_normal() instead of copy_normal(), to avoid getting
527  // the morphs--we don't want them here, since we're just putting
528  // a bogus value on the normal anyway.
529 
530  if (has_normal() && !vertex->has_normal()) {
531  vertex->set_normal(get_normal());
532  }
533  if (has_color() && !vertex->has_color()) {
534  vertex->set_color(get_color());
535  }
536  }
537  }
538 }
539 
540 ////////////////////////////////////////////////////////////////////
541 // Function: EggPrimitive::reverse_vertex_ordering
542 // Access: Published, Virtual
543 // Description: Reverses the ordering of the vertices in this
544 // primitive, if appropriate, in order to change the
545 // direction the polygon appears to be facing. Does not
546 // adjust the surface normal, if any.
547 ////////////////////////////////////////////////////////////////////
548 void EggPrimitive::
550  // This really only makes sense for polygons. Lights don't care
551  // about vertex ordering, and NURBS surfaces have to do a bit more
552  // work in addition to this.
553  reverse(_vertices.begin(), _vertices.end());
554 }
555 
556 ////////////////////////////////////////////////////////////////////
557 // Function: EggPrimitive::cleanup
558 // Access: Published, Virtual
559 // Description: Cleans up modeling errors in whatever context this
560 // makes sense. For instance, for a polygon, this calls
561 // remove_doubled_verts(true). For a point, it calls
562 // remove_nonunique_verts(). Returns true if the
563 // primitive is valid, or false if it is degenerate.
564 ////////////////////////////////////////////////////////////////////
565 bool EggPrimitive::
567  return !empty();
568 }
569 
570 ////////////////////////////////////////////////////////////////////
571 // Function: EggPrimitive::remove_doubled_verts
572 // Access: Published
573 // Description: Certain kinds of primitives, particularly polygons,
574 // don't like to have the same vertex repeated
575 // consecutively. Unfortunately, some modeling programs
576 // (like MultiGen) make this an easy mistake to make.
577 //
578 // It's handy to have a function to remove these
579 // redundant vertices. If closed is true, it also
580 // checks that the first and last vertices are not the
581 // same.
582 //
583 // This function identifies repeated vertices by
584 // position only; it does not consider any other
585 // properties, such as color or UV, significant in
586 // differentiating vertices.
587 ////////////////////////////////////////////////////////////////////
588 void EggPrimitive::
589 remove_doubled_verts(bool closed) {
590  if (!_vertices.empty()) {
591  Vertices new_vertices;
592  Vertices::iterator vi, vlast;
593  vi = _vertices.begin();
594  new_vertices.push_back(*vi);
595  int num_removed = 0;
596 
597  vlast = vi;
598  ++vi;
599  while (vi != _vertices.end()) {
600  if ((*vi)->get_pos4() != (*vlast)->get_pos4()) {
601  new_vertices.push_back(*vi);
602  } else {
603  prepare_remove_vertex(*vi, vi - _vertices.begin() - num_removed,
604  _vertices.size() - num_removed);
605  num_removed++;
606  }
607  vlast = vi;
608  ++vi;
609  }
610  _vertices.swap(new_vertices);
611  }
612 
613  if (closed) {
614  // Then, if this is a polygon (which will be closed anyway),
615  // remove the vertex from the end if it's a repeat of the
616  // beginning.
617  while (_vertices.size() > 1 &&
618  _vertices.back()->get_pos4() == _vertices.front()->get_pos4()) {
619  prepare_remove_vertex(_vertices.back(), _vertices.size() - 1,
620  _vertices.size());
621  _vertices.pop_back();
622  }
623  }
624 }
625 
626 ////////////////////////////////////////////////////////////////////
627 // Function: EggPrimitive::remove_nonunique_verts
628 // Access: Published
629 // Description: Removes any multiple appearances of the same vertex
630 // from the primitive. This primarily makes sense for a
631 // point primitive, which is really a collection of
632 // points and which doesn't make sense to include the
633 // same point twice, in any order.
634 ////////////////////////////////////////////////////////////////////
635 void EggPrimitive::
637  Vertices::iterator vi, vj;
638  Vertices new_vertices;
639  int num_removed = 0;
640 
641  pset<EggVertex *> unique_vertices;
642  for (vi = _vertices.begin(); vi != _vertices.end(); ++vi) {
643  bool inserted = unique_vertices.insert(*vi).second;
644  if (inserted) {
645  new_vertices.push_back(*vi);
646  } else {
647  prepare_remove_vertex(*vi, vi - _vertices.begin() - num_removed,
648  _vertices.size() - num_removed);
649  num_removed++;
650  }
651  }
652 
653  _vertices.swap(new_vertices);
654 }
655 
656 ////////////////////////////////////////////////////////////////////
657 // Function: EggPrimitive::has_primitives
658 // Access: Published, Virtual
659 // Description: Returns true if there are any primitives
660 // (e.g. polygons) defined within this group or below,
661 // false otherwise.
662 ////////////////////////////////////////////////////////////////////
663 bool EggPrimitive::
664 has_primitives() const {
665  return true;
666 }
667 
668 ////////////////////////////////////////////////////////////////////
669 // Function: EggPrimitive::joint_has_primitives
670 // Access: Published, Virtual
671 // Description: Returns true if there are any primitives
672 // (e.g. polygons) defined within this group or below,
673 // but the search does not include nested joints.
674 ////////////////////////////////////////////////////////////////////
675 bool EggPrimitive::
677  return true;
678 }
679 
680 ////////////////////////////////////////////////////////////////////
681 // Function: EggPrimitive::has_normals
682 // Access: Published, Virtual
683 // Description: Returns true if any of the primitives (e.g. polygons)
684 // defined within this group or below have either face
685 // or vertex normals defined, false otherwise.
686 ////////////////////////////////////////////////////////////////////
687 bool EggPrimitive::
688 has_normals() const {
689  if (has_normal()) {
690  return true;
691  }
692 
693  const_iterator vi;
694  for (vi = begin(); vi != end(); ++vi) {
695  if ((*vi)->has_normal()) {
696  return true;
697  }
698  }
699 
700  return false;
701 }
702 
703 
704 ////////////////////////////////////////////////////////////////////
705 // Function: EggPrimitive::erase
706 // Access: Public
707 // Description: Part of the implementaion of the EggPrimitive as an
708 // STL container. Most of the rest of these functions
709 // are inline and declared in EggPrimitive.I.
710 ////////////////////////////////////////////////////////////////////
711 EggPrimitive::iterator EggPrimitive::
712 erase(iterator first, iterator last) {
713  iterator i;
714  int num_removed = 0;
715  for (i = first; i != last; ++i) {
716  prepare_remove_vertex(*i, first - _vertices.begin(),
717  _vertices.size() - num_removed);
718  num_removed++;
719  }
720  iterator result = _vertices.erase((Vertices::iterator &)first,
721  (Vertices::iterator &)last);
722  test_vref_integrity();
723  return result;
724 }
725 
726 ////////////////////////////////////////////////////////////////////
727 // Function: EggPrimitive::find
728 // Access: Public
729 // Description: Returns the iterator pointing to the indicated
730 // vertex, or end() if the vertex is not part of the
731 // primitive.
732 ////////////////////////////////////////////////////////////////////
733 EggPrimitive::iterator EggPrimitive::
734 find(EggVertex *vertex) {
735  PT_EggVertex vpt = vertex;
736  return ::find(begin(), end(), vpt);
737 }
738 
739 
740 ////////////////////////////////////////////////////////////////////
741 // Function: EggPrimitive::add_vertex
742 // Access: Published
743 // Description: Adds the indicated vertex to the end of the
744 // primitive's list of vertices, and returns it.
745 ////////////////////////////////////////////////////////////////////
748  prepare_add_vertex(vertex, _vertices.size(), _vertices.size() + 1);
749  _vertices.push_back(vertex);
750 
751  vertex->test_pref_integrity();
752  test_vref_integrity();
753 
754  return vertex;
755 }
756 
757 ////////////////////////////////////////////////////////////////////
758 // Function: EggPrimitive::remove_vertex
759 // Access: Published
760 // Description: Removes the indicated vertex from the
761 // primitive and returns it. If the vertex was not
762 // already in the primitive, does nothing and returns
763 // NULL.
764 ////////////////////////////////////////////////////////////////////
767  PT_EggVertex vpt = vertex;
768  iterator i = ::find(begin(), end(), vpt);
769  if (i == end()) {
770  return PT_EggVertex();
771  } else {
772  // erase() calls prepare_remove_vertex().
773  erase(i);
774 
775  vertex->test_pref_integrity();
776  test_vref_integrity();
777 
778  return vertex;
779  }
780 }
781 
782 
783 ////////////////////////////////////////////////////////////////////
784 // Function: EggPrimitive::copy_vertices
785 // Access: Published
786 // Description: Replaces the current primitive's list of vertices
787 // with a copy of the list of vertices on the other
788 // primitive.
789 ////////////////////////////////////////////////////////////////////
790 void EggPrimitive::
792  clear();
793  _vertices.reserve(other.size());
794 
795  iterator vi;
796  for (vi = other.begin(); vi != other.end(); ++vi) {
797  add_vertex(*vi);
798  }
799 
800  test_vref_integrity();
801  other.test_vref_integrity();
802 }
803 
804 #ifdef _DEBUG
805 
806 ////////////////////////////////////////////////////////////////////
807 // Function: EggPrimitive::test_vref_integrity
808 // Access: Published
809 // Description: Verifies that each vertex in the primitive exists and
810 // that it knows it is referenced by the primitive.
811 ////////////////////////////////////////////////////////////////////
812 void EggPrimitive::
813 test_vref_integrity() const {
815 
816  if ((int)size() <= egg_test_vref_integrity) {
817  // First, we need to know how many times each vertex appears.
818  // Usually, this will be only one, but it's possible for a vertex to
819  // appear more than once.
820  typedef pmap<const EggVertex *, int> VertexCount;
821  VertexCount _count;
822 
823  // Now count up the vertices.
824  iterator vi;
825  for (vi = begin(); vi != end(); ++vi) {
826  const EggVertex *vert = *vi;
827  vert->test_ref_count_integrity();
828 
829  VertexCount::iterator vci = _count.find(vert);
830  if (vci == _count.end()) {
831  _count[vert] = 1;
832  } else {
833  (*vci).second++;
834  }
835  }
836 
837  // Ok, now walk through the vertices found and make sure the vertex
838  // has the proper number of entries of this primitive in its pref.
839  VertexCount::iterator vci;
840  for (vci = _count.begin(); vci != _count.end(); ++vci) {
841  const EggVertex *vert = (*vci).first;
842 
843  int count = (*vci).second;
844  int vert_count = vert->has_pref(this);
845 
846  nassertv(count == vert_count);
847  }
848  }
849 }
850 
851 #endif // _DEBUG
852 
853 ////////////////////////////////////////////////////////////////////
854 // Function: EggPrimitive::prepare_add_vertex
855 // Access: Protected, Virtual
856 // Description: Marks the vertex as belonging to the primitive. This
857 // is an internal function called by the STL-like
858 // functions push_back() and insert(), in preparation
859 // for actually adding the vertex.
860 //
861 // i indicates the new position of the vertex in the
862 // list; n indicates the new number of vertices after
863 // the operation has completed.
864 ////////////////////////////////////////////////////////////////////
865 void EggPrimitive::
866 prepare_add_vertex(EggVertex *vertex, int i, int n) {
867  // We can't test integrity within this function, because it might be
868  // called when the primitive is in an incomplete state.
869 
870  // The vertex must have the same vertex pool as the vertices already
871  // added.
872  nassertv(empty() || vertex->get_pool() == get_pool());
873 
874  // Since a given vertex might appear more than once in a particular
875  // primitive, we can't conclude anything about data integrity by
876  // inspecting the return value of insert(). (In fact, the vertex's
877  // pref is a multiset, so the insert() will always succeed.)
878 
879  vertex->_pref.insert(this);
880 }
881 
882 
883 ////////////////////////////////////////////////////////////////////
884 // Function: EggPrimitive::prepare_remove_vertex
885 // Access: Protected, Virtual
886 // Description: Marks the vertex as removed from the primitive. This
887 // is an internal function called by the STL-like
888 // functions pop_back() and erase(), in preparation for
889 // actually doing the removal.
890 //
891 // i indicates the former position of the vertex in the
892 // list; n indicates the current number of vertices
893 // before the operation has completed.
894 //
895 // It is an error to attempt to remove a vertex that is
896 // not already a vertex of this primitive.
897 ////////////////////////////////////////////////////////////////////
898 void EggPrimitive::
899 prepare_remove_vertex(EggVertex *vertex, int i, int n) {
900  // We can't test integrity within this function, because it might be
901  // called when the primitive is in an incomplete state.
902 
903  // Now we must remove the primitive from the vertex's pref. We
904  // can't just use the simple erase() function, since that will
905  // remove all instances of this primitive from the pref; instead, we
906  // must find one instance and remove that.
907 
908  EggVertex::PrimitiveRef::iterator pri = vertex->_pref.find(this);
909 
910  // We should have found the primitive in the vertex's pref. If we
911  // did not, something's out of sync internally.
912  nassertv(pri != vertex->_pref.end());
913 
914  vertex->_pref.erase(pri);
915 }
916 
917 ////////////////////////////////////////////////////////////////////
918 // Function: EggPrimitive::write_body
919 // Access: Protected
920 // Description: Writes the attributes and the vertices referenced by
921 // the primitive to the indicated output stream in Egg
922 // format.
923 ////////////////////////////////////////////////////////////////////
924 void EggPrimitive::
925 write_body(ostream &out, int indent_level) const {
926  test_vref_integrity();
927 
928  EggAttributes::write(out, indent_level);
929  EggRenderMode::write(out, indent_level);
930 
931  int num_textures = get_num_textures();
932  for (int i = 0; i < num_textures; i++) {
933  EggTexture *texture = get_texture(i);
934 
935  indent(out, indent_level) << "<TRef> { ";
936  enquote_string(out, texture->get_name())
937  << " }\n";
938  }
939 
940  if (has_material()) {
941  EggMaterial *material = get_material();
942 
943  indent(out, indent_level) << "<MRef> { ";
944  enquote_string(out, material->get_name())
945  << " }\n";
946  }
947 
948  if (get_bface_flag()) {
949  indent(out, indent_level) << "<BFace> { 1 }\n";
950  }
951 
952  if (!empty()) {
953  EggVertexPool *pool = get_pool();
954 
955  // Make sure the vertices belong to some vertex pool.
956  nassertv(pool != NULL);
957 
958  // Make sure the vertex pool is named.
959  nassertv(pool->has_name());
960 
961  if ((int)size() < 10) {
962  // A simple primitive gets all its vertex indices written on one
963  // line.
964  indent(out, indent_level) << "<VertexRef> {";
965  const_iterator i;
966  for (i = begin(); i != end(); ++i) {
967  EggVertex *vert = *i;
968  vert->test_pref_integrity();
969 
970  // Make sure each vertex belongs to the same pool.
971  nassertv(vert->get_pool() == pool);
972 
973  out << " " << vert->get_index();
974  }
975  out << " <Ref> { ";
976  enquote_string(out, pool->get_name()) << " } }\n";
977 
978  } else {
979 
980  // A larger primitive gets its vertex indices written as
981  // multiple lines.
982  vector_int indices;
983  const_iterator i;
984  for (i = begin(); i != end(); ++i) {
985  EggVertex *vert = *i;
986  vert->test_pref_integrity();
987 
988  // Make sure each vertex belongs to the same pool.
989  nassertv(vert->get_pool() == pool);
990 
991  indices.push_back(vert->get_index());
992  }
993 
994  indent(out, indent_level) << "<VertexRef> {\n";
995  write_long_list(out, indent_level+2, indices.begin(), indices.end(),
996  "", "", 72);
997  indent(out, indent_level+2) << "<Ref> { ";
998  enquote_string(out, pool->get_name()) << " }\n";
999  indent(out, indent_level) << "}\n";
1000  }
1001  }
1002 }
1003 
1004 ////////////////////////////////////////////////////////////////////
1005 // Function: EggPrimitive::egg_start_parse_body
1006 // Access: Protected, Virtual
1007 // Description: This function is called within parse_egg(). It
1008 // should call the appropriate function on the lexer to
1009 // initialize the parser into the state associated with
1010 // this object. If the object cannot be parsed into
1011 // directly, it should return false.
1012 ////////////////////////////////////////////////////////////////////
1013 bool EggPrimitive::
1014 egg_start_parse_body() {
1015  egg_start_primitive_body();
1016  return true;
1017 }
1018 
1019 ////////////////////////////////////////////////////////////////////
1020 // Function: EggPrimitive::r_transform
1021 // Access: Protected, Virtual
1022 // Description: This is called from within the egg code by
1023 // transform(). It applies a transformation matrix
1024 // to the current node in some sensible way, then
1025 // continues down the tree.
1026 //
1027 // The first matrix is the transformation to apply; the
1028 // second is its inverse. The third parameter is the
1029 // coordinate system we are changing to, or CS_default
1030 // if we are not changing coordinate systems.
1031 ////////////////////////////////////////////////////////////////////
1032 void EggPrimitive::
1033 r_transform(const LMatrix4d &mat, const LMatrix4d &, CoordinateSystem) {
1035 }
1036 
1037 ////////////////////////////////////////////////////////////////////
1038 // Function: EggPrimitive::r_flatten_transforms
1039 // Access: Protected, Virtual
1040 // Description: The recursive implementation of flatten_transforms().
1041 ////////////////////////////////////////////////////////////////////
1042 void EggPrimitive::
1043 r_flatten_transforms() {
1044  if (is_local_coord()) {
1045  LMatrix4d mat = get_vertex_frame();
1047 
1048  // Transform each vertex by duplicating it in the vertex pool.
1049  size_t num_vertices = size();
1050  for (size_t i = 0; i < num_vertices; i++) {
1051  EggVertex *vertex = get_vertex(i);
1052  EggVertexPool *pool = vertex->get_pool();
1053 
1054  EggVertex new_vertex(*vertex);
1055  new_vertex.transform(mat);
1056  EggVertex *unique = pool->create_unique_vertex(new_vertex);
1057  unique->copy_grefs_from(*vertex);
1058 
1059  set_vertex(i, unique);
1060  }
1061  }
1062 }
1063 
1064 ////////////////////////////////////////////////////////////////////
1065 // Function: EggPrimitive::r_apply_texmats
1066 // Access: Protected, Virtual
1067 // Description: The recursive implementation of apply_texmats().
1068 ////////////////////////////////////////////////////////////////////
1069 void EggPrimitive::
1070 r_apply_texmats(EggTextureCollection &textures) {
1071  Textures new_textures;
1072  Textures::const_iterator ti;
1073  for (ti = _textures.begin(); ti != _textures.end(); ++ti) {
1074  EggTexture *texture = (*ti);
1075 
1076  if (!texture->has_transform()) {
1077  new_textures.push_back(texture);
1078 
1079  } else if (texture->transform_is_identity()) {
1080  // Now, what's the point of a texture with an identity
1081  // transform?
1082  texture->clear_transform();
1083  new_textures.push_back(texture);
1084 
1085  } else {
1086 
1087  // We've got a texture with a matrix applied. Save the matrix,
1088  // and get a new texture without the matrix.
1089  LMatrix4d mat = texture->get_transform3d();
1090  EggTexture new_texture(*texture);
1091  new_texture.clear_transform();
1092  EggTexture *unique = textures.create_unique_texture(new_texture, ~0);
1093 
1094  new_textures.push_back(unique);
1095  string uv_name = unique->get_uv_name();
1096 
1097  // Now apply the matrix to the vertex UV's. Create new vertices
1098  // as necessary.
1099  size_t num_vertices = size();
1100  for (size_t i = 0; i < num_vertices; i++) {
1101  EggVertex *vertex = get_vertex(i);
1102 
1103  const EggVertexUV *uv_obj = vertex->get_uv_obj(uv_name);
1104  if (uv_obj != (EggVertexUV *)NULL) {
1105  EggVertex new_vertex(*vertex);
1106  PT(EggVertexUV) new_uv_obj = new EggVertexUV(*uv_obj);
1107  LTexCoord3d uvw = uv_obj->get_uvw() * mat;
1108  if (uv_obj->has_w() || texture->has_transform3d()) {
1109  new_uv_obj->set_uvw(uvw);
1110  } else {
1111  new_uv_obj->set_uv(LTexCoordd(uvw[0], uvw[1]));
1112  }
1113  new_vertex.set_uv_obj(new_uv_obj);
1114 
1115  EggVertexPool *pool = vertex->get_pool();
1116  EggVertex *unique = pool->create_unique_vertex(new_vertex);
1117  unique->copy_grefs_from(*vertex);
1118 
1119  set_vertex(i, unique);
1120  }
1121  }
1122  }
1123  }
1124 
1125  _textures.swap(new_textures);
1126 }
1127 
1128 ////////////////////////////////////////////////////////////////////
1129 // Function: EggPrimitive::apply_attribute_to_vertex
1130 // Access: Protected
1131 // Description: This is used to implement apply_first_attribute() and
1132 // apply_last_attribute(). It copies the indicated
1133 // attributes to the specified vertex.
1134 ////////////////////////////////////////////////////////////////////
1135 void EggPrimitive::
1136 do_apply_flat_attribute(int vertex_index, EggAttributes *attrib) {
1137  // The significant_change flag is set if we have changed the
1138  // vertex in some important way, that will invalidate it for other
1139  // primitives that might share it. We don't consider *adding* a
1140  // normal where there wasn't one before to be significant, but we
1141  // do consider it significant to change a vertex's normal to
1142  // something different. Similarly for color.
1143  bool significant_change = false;
1144 
1145  EggVertex *orig_vertex = get_vertex(vertex_index);
1146  PT(EggVertex) new_vertex = new EggVertex(*orig_vertex);
1147 
1148  if (attrib->has_normal()) {
1149  new_vertex->copy_normal(*attrib);
1150 
1151  if (orig_vertex->has_normal() &&
1152  !orig_vertex->matches_normal(*new_vertex)) {
1153  significant_change = true;
1154  }
1155  } else if (has_normal()) {
1156  new_vertex->copy_normal(*this);
1157 
1158  if (orig_vertex->has_normal() &&
1159  !orig_vertex->matches_normal(*new_vertex)) {
1160  significant_change = true;
1161  }
1162  }
1163 
1164  if (attrib->has_color()) {
1165  new_vertex->copy_color(*attrib);
1166 
1167  if (orig_vertex->has_color() &&
1168  !orig_vertex->matches_color(*new_vertex)) {
1169  significant_change = true;
1170  }
1171  } else if (has_color()) {
1172  new_vertex->copy_color(*this);
1173 
1174  if (orig_vertex->has_color() &&
1175  !orig_vertex->matches_color(*new_vertex)) {
1176  significant_change = true;
1177  }
1178  }
1179 
1180  if (significant_change) {
1181  new_vertex = get_pool()->create_unique_vertex(*new_vertex);
1182  new_vertex->copy_grefs_from(*orig_vertex);
1183  set_vertex(vertex_index, new_vertex);
1184  } else {
1185  // Just copy the new attributes back into the pool.
1186  ((EggAttributes *)orig_vertex)->operator = (*new_vertex);
1187  }
1188 }
1189 
1190 ////////////////////////////////////////////////////////////////////
1191 // Function: EggPrimitive::set_connected_shading
1192 // Access: Private
1193 // Description: Recursively updates the connected_shading member in
1194 // all connected primitives.
1195 ////////////////////////////////////////////////////////////////////
1196 void EggPrimitive::
1197 set_connected_shading(EggPrimitive::Shading shading,
1198  const EggAttributes *neighbor) {
1199  ConnectedShadingNodes connected_nodes;
1200 
1201  r_set_connected_shading(0, shading, neighbor, connected_nodes);
1202 
1203  // Pick up any additional nodes we couldn't visit because of the
1204  // stack depth restrictions.
1205  while (!connected_nodes.empty()) {
1206  ConnectedShadingNodes next_nodes;
1207  next_nodes.swap(connected_nodes);
1208 
1209  ConnectedShadingNodes::iterator ni;
1210  for (ni = next_nodes.begin(); ni != next_nodes.end(); ++ni) {
1211  r_set_connected_shading(0, (*ni)._shading, (*ni)._neighbor, connected_nodes);
1212  }
1213  }
1214 }
1215 
1216 ////////////////////////////////////////////////////////////////////
1217 // Function: EggPrimitive::r_set_connected_shading
1218 // Access: Private
1219 // Description: Implements set_connected_shading, with some
1220 // restrictions to prevent stack overflow.
1221 ////////////////////////////////////////////////////////////////////
1222 void EggPrimitive::
1223 r_set_connected_shading(int stack_depth, EggPrimitive::Shading shading,
1224  const EggAttributes *neighbor,
1225  ConnectedShadingNodes &next_nodes) {
1226  if (stack_depth > egg_recursion_limit) {
1227  // Too deep. Limit recursion.
1228  ConnectedShadingNode next;
1229  next._shading = shading;
1230  next._neighbor = neighbor;
1231  next_nodes.push_back(next);
1232  return;
1233  }
1234 
1235  bool propagate = false;
1236 
1237  if (_connected_shading == S_unknown) {
1238  // We haven't visited this node before; propagate now.
1239  _connected_shading = get_shading();
1240  propagate = true;
1241  }
1242 
1243  if (shading > _connected_shading) {
1244  // More specific information just came in. Save it, and propagate
1245  // it to all connected primitives.
1246  _connected_shading = shading;
1247  propagate = true;
1248 
1249  } else if (shading == S_overall && _connected_shading == S_overall) {
1250  // If both neighbors are overall shaded, check if the two
1251  // neighbors have different properties. If they do, elevate to
1252  // per_face.
1253  bool matches_normal = this->matches_normal(*neighbor);
1254  bool matches_color = this->matches_color(*neighbor);
1255 
1256  if (!matches_color) {
1257  // Make a special case for not having an overall color: that's
1258  // implicitly white.
1259  if (!neighbor->has_color() && has_color() && _drgbas.empty() &&
1260  get_color() == LColor(1.0f, 1.0f, 1.0f, 1.0f)) {
1261  matches_color = true;
1262  } else if (!has_color() && neighbor->has_color() && neighbor->_drgbas.empty() &&
1263  neighbor->get_color() == LColor(1.0f, 1.0f, 1.0f, 1.0f)) {
1264  matches_color = true;
1265  }
1266  }
1267  if (!matches_normal || !matches_color) {
1268  _connected_shading = S_per_face;
1269  propagate = true;
1270  }
1271  }
1272 
1273  if (propagate) {
1274  Vertices::const_iterator vi;
1275  for (vi = _vertices.begin(); vi != _vertices.end(); ++vi) {
1276  EggVertex *vertex = (*vi);
1277  EggVertex::PrimitiveRef::const_iterator pi;
1278  for (pi = vertex->pref_begin();
1279  pi != vertex->pref_end();
1280  ++pi) {
1281  (*pi)->r_set_connected_shading(stack_depth + 1, _connected_shading, this,
1282  next_nodes);
1283  }
1284  }
1285  }
1286 }
A base class for any of a number of kinds of geometry primitives: polygons, point lights...
Definition: eggPrimitive.h:51
bool affects_polygon_alpha() const
Returns true if this texture&#39;s environment type or combine mode allows the texture to have an effect ...
Definition: eggTexture.cxx:571
VisibilityMode get_visibility_mode() const
Returns the visibility mode that was set, or VM_unspecified if nothing was set.
Definition: eggRenderMode.I:99
The set of UV&#39;s that may or may not be assigned to a vertex.
Definition: eggVertexUV.h:32
bool test_ref_count_integrity() const
Does some easy checks to make sure that the reference count isn&#39;t completely bogus.
PrimitiveRef::const_iterator pref_end() const
Returns an iterator that can, in conjunction with pref_begin(), be used to traverse the entire set of...
Definition: eggVertex.cxx:916
virtual void unify_attributes(Shading shading)
If the shading property is S_per_vertex, ensures that all vertices have a normal and a color...
void clear_transform()
Resets the transform to empty, identity.
Definition: eggTransform.I:125
bool matches_color(const EggAttributes &other) const
Returns true if this color matches that of the other EggAttributes object, include the morph list...
This is our own Panda specialization on the default STL map.
Definition: pmap.h:52
virtual EggRenderMode * determine_bin()
Walks back up the hierarchy, looking for an EggGroup or EggPrimitive or some such object at this leve...
const LMatrix4d & get_transform3d() const
Returns the overall transform as a 4x4 matrix.
Definition: eggTransform.I:251
EggTexture * create_unique_texture(const EggTexture &copy, int eq)
Creates a new texture if there is not already one equivalent (according to eq, see EggTexture::is_equ...
This is a 4-by-4 transform matrix.
Definition: lmatrix.h:4716
LColor get_color() const
Returns the color set on this particular attribute.
virtual Shading get_shading() const
Returns the shading properties apparent on this particular primitive.
bool has_depth_offset() const
Returns true if the depth-offset flag has been set for this particular object.
bool is_local_coord() const
Returns true if this node&#39;s vertices are not in the global coordinate space.
Definition: eggNode.I:109
virtual void apply_first_attribute()
Sets the first vertex of the triangle (or each component) to the primitive normal and/or color...
bool get_bface_flag() const
Retrieves the backfacing flag of the polygon.
Definition: eggPrimitive.I:301
void write(ostream &out, int indent_level) const
Writes the attributes to the indicated output stream in Egg format.
virtual void apply_last_attribute()
Sets the last vertex of the triangle (or each component) to the primitive normal and/or color...
virtual bool cleanup()
Cleans up modeling errors in whatever context this makes sense.
PrimitiveRef::const_iterator pref_begin() const
Returns an iterator that can, in conjunction with pref_end(), be used to traverse the entire set of p...
Definition: eggVertex.cxx:900
DepthWriteMode get_depth_write_mode() const
Returns the depth_write mode that was set, or DWM_unspecified if nothing was set. ...
Definition: eggRenderMode.I:47
void clear()
Removes all of the vertices from the primitive.
Definition: eggPrimitive.I:432
Defines a texture map that may be applied to geometry.
Definition: eggTexture.h:33
void set_vertex(int index, EggVertex *vertex)
Replaces a particular vertex based on its index number in the list of vertices.
Definition: eggPrimitive.I:455
virtual EggRenderMode * determine_draw_order()
Walks back up the hierarchy, looking for an EggGroup or EggPrimitive or some such object at this leve...
Definition: eggNode.cxx:190
void transform(const LMatrix4d &mat)
Applies the indicated transformation matrix to the attributes.
void copy_vertices(const EggPrimitive &other)
Replaces the current primitive&#39;s list of vertices with a copy of the list of vertices on the other pr...
virtual EggRenderMode * determine_depth_test_mode()
Walks back up the hierarchy, looking for an EggGroup or EggPrimitive or some such object at this leve...
Definition: eggNode.cxx:136
void copy_normal(const EggAttributes &other)
Sets this normal to be the same as the other&#39;s, include morphs.
Definition: eggAttributes.I:84
void copy_attributes(const EggAttributes &other)
Copies the rendering attributes from the indicated primitive.
const EggVertexUV * get_uv_obj(const string &name) const
Returns the named EggVertexUV object, which defines both the UV coordinate pair for this name and the...
Definition: eggVertex.cxx:286
This is a two-component point in space.
Definition: lpoint2.h:411
This is a collection of textures by TRef name.
virtual EggRenderMode * determine_alpha_mode()
Walks back up the hierarchy, looking for an EggGroup or EggPrimitive or some such object at this leve...
EggVertex * remove_vertex(EggVertex *vertex)
Removes the indicated vertex from the primitive and returns it.
EggTexture * get_texture() const
Returns the first texture on the primitive, if any, or NULL if there are no textures on the primitive...
Definition: eggPrimitive.I:182
bool matches_normal(const EggAttributes &other) const
Returns true if this normal matches that of the other EggAttributes object, include the morph list...
Definition: eggAttributes.I:65
bool has_name() const
Returns true if the Namable has a nonempty name set, false if the name is empty.
Definition: namable.I:75
bool has_bin() const
Returns true if a bin name has been set for this particular object.
bool has_vertex_color() const
Returns true if any vertex on the primitive has a specific color set, false otherwise.
bool has_vertex_normal() const
Returns true if any vertex on the primitive has a specific normal set, false otherwise.
void set_bface_flag(bool flag)
Sets the backfacing flag of the polygon.
Definition: eggPrimitive.I:289
This class stores miscellaneous rendering properties that is associated with geometry, and which may be set on the geometry primitive level, on the group above it, or indirectly via a texture.
Definition: eggRenderMode.h:36
void write(ostream &out, int indent_level) const
Writes the attributes to the indicated output stream in Egg format.
The set of attributes that may be applied to vertices as well as polygons, such as surface normal and...
Definition: eggAttributes.h:37
const string & get_uv_name() const
Returns the texcoord name that has been specified for this texture, or the empty string if no texcoor...
Definition: eggTexture.I:705
virtual EggRenderMode * determine_depth_test_mode()
Walks back up the hierarchy, looking for an EggGroup or EggPrimitive or some such object at this leve...
virtual void reverse_vertex_ordering()
Reverses the ordering of the vertices in this primitive, if appropriate, in order to change the direc...
void copy_color(const EggAttributes &other)
Sets this color to be the same as the other&#39;s, include morphs.
virtual bool joint_has_primitives() const
Returns true if there are any primitives (e.g.
virtual void post_apply_flat_attribute()
Intended as a followup to apply_last_attribute(), this also sets an attribute on the first vertices o...
EggMaterial * get_material() const
Returns a pointer to the applied material, or NULL if there is no material applied.
Definition: eggPrimitive.I:262
virtual EggRenderMode * determine_visibility_mode()
Walks back up the hierarchy, looking for an EggGroup or EggPrimitive or some such object at this leve...
Definition: eggNode.cxx:154
void set_material(EggMaterial *material)
Applies the indicated material to the primitive.
Definition: eggPrimitive.I:241
Any one-, two-, three-, or four-component vertex, possibly with attributes such as a normal...
Definition: eggVertex.h:41
const LMatrix4d & get_vertex_frame() const
Returns the coordinate frame of the vertices referenced by primitives at or under this node...
Definition: eggNode.I:135
void remove_nonunique_verts()
Removes any multiple appearances of the same vertex from the primitive.
int has_pref(const EggPrimitive *prim) const
Returns the number of times the vertex appears in the indicated primitive, or 0 if it does not appear...
Definition: eggVertex.cxx:941
iterator find(EggVertex *vertex)
Returns the iterator pointing to the indicated vertex, or end() if the vertex is not part of the prim...
bool has_draw_order() const
Returns true if the draw-order flag has been set for this particular object.
virtual EggRenderMode * determine_depth_offset()
Walks back up the hierarchy, looking for an EggGroup or EggPrimitive or some such object at this leve...
int get_num_textures() const
Returns the number of textures applied to the primitive.
Definition: eggPrimitive.I:218
virtual EggRenderMode * determine_depth_write_mode()
Walks back up the hierarchy, looking for an EggGroup or EggPrimitive or some such object at this leve...
Definition: eggNode.cxx:118
virtual EggRenderMode * determine_alpha_mode()
Walks back up the hierarchy, looking for an EggGroup or EggPrimitive or some such object at this leve...
Definition: eggNode.cxx:100
bool has_transform() const
Returns true if the transform is nonempty, false if it is empty (no transform components have been ad...
Definition: eggTransform.I:163
virtual EggRenderMode * determine_bin()
Walks back up the hierarchy, looking for an EggGroup or EggPrimitive or some such object at this leve...
Definition: eggNode.cxx:208
This is the base class for all three-component vectors and points.
Definition: lvecBase4.h:111
virtual EggRenderMode * determine_draw_order()
Walks back up the hierarchy, looking for an EggGroup or EggPrimitive or some such object at this leve...
DepthTestMode get_depth_test_mode() const
Returns the depth_test mode that was set, or DTM_unspecified if nothing was set.
Definition: eggRenderMode.I:73
AlphaMode get_alpha_mode() const
Returns the alpha mode that was set, or AM_unspecified if nothing was set.
This is a three-component point in space (as opposed to a three-component vector, which represents a ...
Definition: lpoint3.h:531
bool has_material() const
Returns true if the primitive is materiald (and get_material() will return a real pointer)...
Definition: eggPrimitive.I:275
virtual bool has_primitives() const
Returns true if there are any primitives (e.g.
void replace(iterator position, EggVertex *vertex)
Replaces the vertex at the indicated position with the indicated vertex.
Definition: eggPrimitive.I:413
virtual EggRenderMode * determine_visibility_mode()
Walks back up the hierarchy, looking for an EggGroup or EggPrimitive or some such object at this leve...
This is our own Panda specialization on the default STL set.
Definition: pset.h:52
void remove_doubled_verts(bool closed)
Certain kinds of primitives, particularly polygons, don&#39;t like to have the same vertex repeated conse...
void copy_grefs_from(const EggVertex &other)
Copies all the group references from the other vertex onto this one.
Definition: eggVertex.cxx:848
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
EggVertexPool * get_pool() const
Returns the vertex pool this vertex belongs in.
Definition: eggVertex.I:25
EggVertex * get_vertex(int index) const
Returns a particular index based on its index number.
Definition: eggPrimitive.I:466
virtual EggRenderMode * determine_depth_offset()
Walks back up the hierarchy, looking for an EggGroup or EggPrimitive or some such object at this leve...
Definition: eggNode.cxx:172
EggVertex * create_unique_vertex(const EggVertex &copy)
Creates a new vertex in the pool that is a copy of the indicated one and returns it.
A collection of vertices.
Definition: eggVertexPool.h:46
EggVertex * add_vertex(EggVertex *vertex)
Adds the indicated vertex to the end of the primitive&#39;s list of vertices, and returns it...
virtual EggRenderMode * determine_depth_write_mode()
Walks back up the hierarchy, looking for an EggGroup or EggPrimitive or some such object at this leve...
int get_index() const
Returns the index number of the vertex within its pool.
Definition: eggVertex.I:346
virtual bool has_normals() const
Returns true if any of the primitives (e.g.
bool transform_is_identity() const
Returns true if the described transform is identity, false otherwise.
Definition: eggTransform.I:262
EggVertexPool * get_pool() const
Returns the vertex pool associated with the vertices of the primitive, or NULL if the primitive has n...
Definition: eggPrimitive.I:480