Panda3D
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
The set of UV&#39;s that may or may not be assigned to a vertex.
Definition: eggVertexUV.h:32
AlphaMode get_alpha_mode() const
Returns the alpha mode that was set, or AM_unspecified if nothing was set.
bool transform_is_identity() const
Returns true if the described transform is identity, false otherwise.
Definition: eggTransform.I:262
VisibilityMode get_visibility_mode() const
Returns the visibility mode that was set, or VM_unspecified if nothing was set.
Definition: eggRenderMode.I:99
virtual void unify_attributes(Shading shading)
If the shading property is S_per_vertex, ensures that all vertices have a normal and a color...
const LMatrix4d & get_transform3d() const
Returns the overall transform as a 4x4 matrix.
Definition: eggTransform.I:251
void clear_transform()
Resets the transform to empty, identity.
Definition: eggTransform.I:125
This is our own Panda specialization on the default STL map.
Definition: pmap.h:52
int get_num_textures() const
Returns the number of textures applied to the primitive.
Definition: eggPrimitive.I:218
virtual EggRenderMode * determine_bin()
Walks back up the hierarchy, looking for an EggGroup or EggPrimitive or some such object at this leve...
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
bool has_bin() const
Returns true if a bin name has been set for this particular object.
virtual void apply_first_attribute()
Sets the first vertex of the triangle (or each component) to the primitive normal and/or color...
EggVertexPool * get_pool() const
Returns the vertex pool this vertex belongs in.
Definition: eggVertex.I:25
virtual void apply_last_attribute()
Sets the last vertex of the triangle (or each component) to the primitive normal and/or color...
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
virtual bool cleanup()
Cleans up modeling errors in whatever context this makes sense.
const LTexCoord3d & get_uvw() const
Returns the texture coordinate triple, if get_num_dimensions() is 3.
Definition: eggVertexUV.I:88
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
bool has_vertex_color() const
Returns true if any vertex on the primitive has a specific color set, false otherwise.
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
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
void copy_attributes(const EggAttributes &other)
Copies the rendering attributes from the indicated primitive.
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 test_ref_count_integrity() const
Does some easy checks to make sure that the reference count isn&#39;t completely bogus.
This is a two-component point in space.
Definition: lpoint2.h:424
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.
LColor get_color() const
Returns the color set on this particular attribute.
bool matches_color(const EggAttributes &other) const
Returns true if this color matches that of the other EggAttributes object, include the morph list...
bool has_vertex_normal() const
Returns true if any vertex on the primitive has a specific normal set, false otherwise.
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
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
This is our own Panda specialization on the default STL vector.
Definition: pvector.h:39
void set_bface_flag(bool flag)
Sets the backfacing flag of the polygon.
Definition: eggPrimitive.I:289
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
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
The set of attributes that may be applied to vertices as well as polygons, such as surface normal and...
Definition: eggAttributes.h:37
int get_index() const
Returns the index number of the vertex within its pool.
Definition: eggVertex.I:346
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 bool has_primitives() const
Returns true if there are any primitives (e.g.
bool has_w() const
Returns true if the texture coordinate has a third, w component, false if it is just a normal 2-d tex...
Definition: eggVertexUV.I:63
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 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.
void set_uv_obj(EggVertexUV *vertex_uv)
Sets the indicated EggVertexUV on the vertex.
Definition: eggVertex.cxx:364
virtual void post_apply_flat_attribute()
Intended as a followup to apply_last_attribute(), this also sets an attribute on the first vertices o...
void transform(const LMatrix4d &mat)
Applies the indicated transformation matrix to the vertex.
Definition: eggVertex.cxx:755
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
void remove_nonunique_verts()
Removes any multiple appearances of the same vertex from the primitive.
virtual bool joint_has_primitives() const
Returns true if there are any primitives (e.g.
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
iterator find(EggVertex *vertex)
Returns the iterator pointing to the indicated vertex, or end() if the vertex is not part of the prim...
virtual EggRenderMode * determine_depth_offset()
Walks back up the hierarchy, looking for an EggGroup or EggPrimitive or some such object at this leve...
virtual bool has_normals() const
Returns true if any of the primitives (e.g.
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
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
bool has_draw_order() const
Returns true if the draw-order flag has been set for this particular object.
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_bin()
Walks back up the hierarchy, looking for an EggGroup or EggPrimitive or some such object at this leve...
Definition: eggNode.cxx:208
bool has_transform3d() const
Returns true if the transform is specified as a 3-d transform, e.g.
Definition: eggTransform.I:210
void write(ostream &out, int indent_level) const
Writes the attributes to the indicated output stream in Egg format.
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...
void write(ostream &out, int indent_level) const
Writes the attributes to the indicated output stream in Egg format.
This is a three-component point in space (as opposed to a three-component vector, which represents a ...
Definition: lpoint3.h:544
bool has_depth_offset() const
Returns true if the depth-offset flag has been set for this particular object.
virtual Shading get_shading() const
Returns the shading properties apparent on this particular primitive.
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
bool has_name() const
Returns true if the Namable has a nonempty name set, false if the name is empty.
Definition: namable.I:75
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
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
bool get_bface_flag() const
Retrieves the backfacing flag of the polygon.
Definition: eggPrimitive.I:301
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
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...
bool has_material() const
Returns true if the primitive is materiald (and get_material() will return a real pointer)...
Definition: eggPrimitive.I:275
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
EggVertex * get_vertex(int index) const
Returns a particular index based on its index number.
Definition: eggPrimitive.I:466
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
virtual EggRenderMode * determine_depth_write_mode()
Walks back up the hierarchy, looking for an EggGroup or EggPrimitive or some such object at this leve...
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