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"
23 #include "vector_int.h"
46 for (
int i = 0; i < num_textures && result == (
EggRenderMode *)NULL; i++) {
82 for (
int i = 0; i < num_textures && result == (
EggRenderMode *)NULL; i++) {
109 for (
int i = 0; i < num_textures && result == (
EggRenderMode *)NULL; i++) {
136 for (
int i = 0; i < num_textures && result == (
EggRenderMode *)NULL; i++) {
163 for (
int i = 0; i < num_textures && result == (
EggRenderMode *)NULL; i++) {
190 for (
int i = 0; i < num_textures && result == (
EggRenderMode *)NULL; i++) {
217 for (
int i = 0; i < num_textures && result == (
EggRenderMode *)NULL; i++) {
255 if (!first_vertex->has_normal()) {
258 for (
int i = 1; i < get_num_vertices(); i++) {
260 if (!vertex->has_normal()) {
272 if (!first_vertex->has_color()) {
275 for (
int i = 1; i < get_num_vertices(); i++) {
277 if (!vertex->has_color()) {
297 EggAttributes::operator = (other);
308 EggAttributes::operator = (other);
309 _textures = other._textures;
327 Vertices::const_iterator vi;
328 for (vi = _vertices.begin(); vi != _vertices.end(); ++vi) {
329 if ((*vi)->has_normal()) {
349 Vertices::const_iterator vi;
350 for (vi = _vertices.begin(); vi != _vertices.end(); ++vi) {
351 if ((*vi)->has_color()) {
384 if (shading == S_unknown) {
389 if (!has_color() && shading != S_overall) {
390 if (shading != S_per_vertex) {
394 for (pi = begin(); pi != end() && !has_color(); ++pi) {
396 if (vertex->has_color()) {
403 set_color(
LColor(1.0f, 1.0f, 1.0f, 1.0f));
412 for (pi = begin(); pi != end(); ++pi) {
415 if (!vertex->has_normal() && has_normal()) {
416 vertex->copy_normal(*
this);
418 if (!vertex->has_color() && has_color()) {
419 vertex->copy_color(*
this);
438 for (pi = begin(); pi != end(); ++pi) {
441 if (vertex->has_normal()) {
445 vertex->clear_normal();
447 if (vertex->has_color()) {
451 vertex->clear_color();
467 if (!has_color() && shading == S_overall) {
468 set_color(
LColor(1.0f, 1.0f, 1.0f, 1.0f));
488 do_apply_flat_attribute(size() - 1,
this);
508 do_apply_flat_attribute(0,
this);
523 for (
int i = 0; i < (int)size(); i++) {
530 if (has_normal() && !vertex->has_normal()) {
531 vertex->set_normal(get_normal());
533 if (has_color() && !vertex->has_color()) {
553 reverse(_vertices.begin(), _vertices.end());
590 if (!_vertices.empty()) {
591 Vertices new_vertices;
592 Vertices::iterator vi, vlast;
593 vi = _vertices.begin();
594 new_vertices.push_back(*vi);
599 while (vi != _vertices.end()) {
600 if ((*vi)->get_pos4() != (*vlast)->get_pos4()) {
601 new_vertices.push_back(*vi);
603 prepare_remove_vertex(*vi, vi - _vertices.begin() - num_removed,
604 _vertices.size() - num_removed);
610 _vertices.swap(new_vertices);
617 while (_vertices.size() > 1 &&
618 _vertices.back()->get_pos4() == _vertices.front()->get_pos4()) {
619 prepare_remove_vertex(_vertices.back(), _vertices.size() - 1,
621 _vertices.pop_back();
637 Vertices::iterator vi, vj;
638 Vertices new_vertices;
642 for (vi = _vertices.begin(); vi != _vertices.end(); ++vi) {
643 bool inserted = unique_vertices.insert(*vi).second;
645 new_vertices.push_back(*vi);
647 prepare_remove_vertex(*vi, vi - _vertices.begin() - num_removed,
648 _vertices.size() - num_removed);
653 _vertices.swap(new_vertices);
694 for (vi = begin(); vi != end(); ++vi) {
695 if ((*vi)->has_normal()) {
711 EggPrimitive::iterator EggPrimitive::
712 erase(iterator first, iterator last) {
715 for (i = first; i != last; ++i) {
716 prepare_remove_vertex(*i, first - _vertices.begin(),
717 _vertices.size() - num_removed);
720 iterator result = _vertices.erase((Vertices::iterator &)first,
721 (Vertices::iterator &)last);
722 test_vref_integrity();
735 PT_EggVertex vpt = vertex;
736 return ::find(begin(), end(), vpt);
748 prepare_add_vertex(vertex, _vertices.size(), _vertices.size() + 1);
749 _vertices.push_back(vertex);
751 vertex->test_pref_integrity();
752 test_vref_integrity();
767 PT_EggVertex vpt = vertex;
768 iterator i =
::find(begin(), end(), vpt);
770 return PT_EggVertex();
775 vertex->test_pref_integrity();
776 test_vref_integrity();
793 _vertices.reserve(other.size());
796 for (vi = other.begin(); vi != other.end(); ++vi) {
800 test_vref_integrity();
801 other.test_vref_integrity();
813 test_vref_integrity()
const {
816 if ((
int)size() <= egg_test_vref_integrity) {
825 for (vi = begin(); vi != end(); ++vi) {
829 VertexCount::iterator vci = _count.find(vert);
830 if (vci == _count.end()) {
839 VertexCount::iterator vci;
840 for (vci = _count.begin(); vci != _count.end(); ++vci) {
843 int count = (*vci).second;
844 int vert_count = vert->
has_pref(
this);
846 nassertv(count == vert_count);
866 prepare_add_vertex(
EggVertex *vertex,
int i,
int n) {
879 vertex->_pref.insert(
this);
899 prepare_remove_vertex(
EggVertex *vertex,
int i,
int n) {
908 EggVertex::PrimitiveRef::iterator pri = vertex->_pref.find(
this);
912 nassertv(pri != vertex->_pref.end());
914 vertex->_pref.erase(pri);
925 write_body(ostream &out,
int indent_level)
const {
926 test_vref_integrity();
932 for (
int i = 0; i < num_textures; i++) {
935 indent(out, indent_level) <<
"<TRef> { ";
936 enquote_string(out, texture->get_name())
943 indent(out, indent_level) <<
"<MRef> { ";
944 enquote_string(out, material->get_name())
949 indent(out, indent_level) <<
"<BFace> { 1 }\n";
956 nassertv(pool != NULL);
961 if ((
int)size() < 10) {
964 indent(out, indent_level) <<
"<VertexRef> {";
966 for (i = begin(); i != end(); ++i) {
968 vert->test_pref_integrity();
976 enquote_string(out, pool->get_name()) <<
" } }\n";
984 for (i = begin(); i != end(); ++i) {
986 vert->test_pref_integrity();
994 indent(out, indent_level) <<
"<VertexRef> {\n";
995 write_long_list(out, indent_level+2, indices.begin(), indices.end(),
997 indent(out, indent_level+2) <<
"<Ref> { ";
998 enquote_string(out, pool->get_name()) <<
" }\n";
999 indent(out, indent_level) <<
"}\n";
1014 egg_start_parse_body() {
1015 egg_start_primitive_body();
1043 r_flatten_transforms() {
1049 size_t num_vertices = size();
1050 for (
size_t i = 0; i < num_vertices; i++) {
1055 new_vertex.transform(mat);
1071 Textures new_textures;
1072 Textures::const_iterator ti;
1073 for (ti = _textures.begin(); ti != _textures.end(); ++ti) {
1077 new_textures.push_back(texture);
1083 new_textures.push_back(texture);
1091 new_texture.clear_transform();
1094 new_textures.push_back(unique);
1099 size_t num_vertices = size();
1100 for (
size_t i = 0; i < num_vertices; i++) {
1108 if (uv_obj->has_w() || texture->has_transform3d()) {
1109 new_uv_obj->set_uvw(uvw);
1111 new_uv_obj->set_uv(
LTexCoordd(uvw[0], uvw[1]));
1113 new_vertex.set_uv_obj(new_uv_obj);
1125 _textures.swap(new_textures);
1136 do_apply_flat_attribute(
int vertex_index,
EggAttributes *attrib) {
1143 bool significant_change =
false;
1148 if (attrib->has_normal()) {
1151 if (orig_vertex->has_normal() &&
1152 !orig_vertex->matches_normal(*new_vertex)) {
1153 significant_change =
true;
1155 }
else if (has_normal()) {
1156 new_vertex->copy_normal(*
this);
1158 if (orig_vertex->has_normal() &&
1159 !orig_vertex->matches_normal(*new_vertex)) {
1160 significant_change =
true;
1164 if (attrib->has_color()) {
1165 new_vertex->copy_color(*attrib);
1167 if (orig_vertex->has_color() &&
1168 !orig_vertex->matches_color(*new_vertex)) {
1169 significant_change =
true;
1171 }
else if (has_color()) {
1172 new_vertex->copy_color(*
this);
1174 if (orig_vertex->has_color() &&
1175 !orig_vertex->matches_color(*new_vertex)) {
1176 significant_change =
true;
1180 if (significant_change) {
1197 set_connected_shading(EggPrimitive::Shading shading,
1199 ConnectedShadingNodes connected_nodes;
1201 r_set_connected_shading(0, shading, neighbor, connected_nodes);
1205 while (!connected_nodes.empty()) {
1206 ConnectedShadingNodes next_nodes;
1207 next_nodes.swap(connected_nodes);
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);
1223 r_set_connected_shading(
int stack_depth, EggPrimitive::Shading shading,
1225 ConnectedShadingNodes &next_nodes) {
1226 if (stack_depth > egg_recursion_limit) {
1228 ConnectedShadingNode next;
1229 next._shading = shading;
1230 next._neighbor = neighbor;
1231 next_nodes.push_back(next);
1235 bool propagate =
false;
1237 if (_connected_shading == S_unknown) {
1243 if (shading > _connected_shading) {
1246 _connected_shading = shading;
1249 }
else if (shading == S_overall && _connected_shading == S_overall) {
1256 if (!matches_color) {
1259 if (!neighbor->has_color() && has_color() && _drgbas.empty() &&
1261 matches_color =
true;
1262 }
else if (!has_color() && neighbor->has_color() && neighbor->_drgbas.empty() &&
1264 matches_color =
true;
1267 if (!matches_normal || !matches_color) {
1268 _connected_shading = S_per_face;
1274 Vertices::const_iterator vi;
1275 for (vi = _vertices.begin(); vi != _vertices.end(); ++vi) {
1277 EggVertex::PrimitiveRef::const_iterator pi;
1281 (*pi)->r_set_connected_shading(stack_depth + 1, _connected_shading,
this,
A base class for any of a number of kinds of geometry primitives: polygons, point lights...
bool affects_polygon_alpha() const
Returns true if this texture's environment type or combine mode allows the texture to have an effect ...
VisibilityMode get_visibility_mode() const
Returns the visibility mode that was set, or VM_unspecified if nothing was set.
The set of UV's that may or may not be assigned to a vertex.
bool test_ref_count_integrity() const
Does some easy checks to make sure that the reference count isn'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...
virtual void unify_attributes(Shading shading)
If the shading property is S_per_vertex, ensures that all vertices have a normal and a color...
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.
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 ©, 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.
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's vertices are not in the global coordinate space.
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.
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...
DepthWriteMode get_depth_write_mode() const
Returns the depth_write mode that was set, or DWM_unspecified if nothing was set. ...
void clear()
Removes all of the vertices from the primitive.
Defines a texture map that may be applied to geometry.
void set_vertex(int index, EggVertex *vertex)
Replaces a particular vertex based on its index number in the list of vertices.
virtual EggRenderMode * determine_draw_order()
Walks back up the hierarchy, looking for an EggGroup or EggPrimitive or some such object at this leve...
void transform(const LMatrix4d &mat)
Applies the indicated transformation matrix to the attributes.
void copy_vertices(const EggPrimitive &other)
Replaces the current primitive'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...
void copy_normal(const EggAttributes &other)
Sets this normal to be the same as the other's, include morphs.
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...
This is a two-component point in space.
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...
bool matches_normal(const EggAttributes &other) const
Returns true if this normal matches that of the other EggAttributes object, include the morph list...
bool has_name() const
Returns true if the Namable has a nonempty name set, false if the name is empty.
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.
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.
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...
const string & get_uv_name() const
Returns the texcoord name that has been specified for this texture, or the empty string if no texcoor...
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'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.
virtual EggRenderMode * determine_visibility_mode()
Walks back up the hierarchy, looking for an EggGroup or EggPrimitive or some such object at this leve...
void set_material(EggMaterial *material)
Applies the indicated material to the primitive.
Any one-, two-, three-, or four-component vertex, possibly with attributes such as a normal...
const LMatrix4d & get_vertex_frame() const
Returns the coordinate frame of the vertices referenced by primitives at or under this node...
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...
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.
virtual EggRenderMode * determine_depth_write_mode()
Walks back up the hierarchy, looking for an EggGroup or EggPrimitive or some such object at this leve...
virtual EggRenderMode * determine_alpha_mode()
Walks back up the hierarchy, looking for an EggGroup or EggPrimitive or some such object at this leve...
virtual EggRenderMode * determine_bin()
Walks back up the hierarchy, looking for an EggGroup or EggPrimitive or some such object at this leve...
This is the base class for all three-component vectors and points.
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.
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 ...
bool has_material() const
Returns true if the primitive is materiald (and get_material() will return a real pointer)...
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.
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.
void remove_doubled_verts(bool closed)
Certain kinds of primitives, particularly polygons, don'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.
TypeHandle is the identifier used to differentiate C++ class types.
EggVertexPool * get_pool() const
Returns the vertex pool this vertex belongs in.
EggVertex * get_vertex(int index) const
Returns a particular index based on its index number.
virtual EggRenderMode * determine_depth_offset()
Walks back up the hierarchy, looking for an EggGroup or EggPrimitive or some such object at this leve...
EggVertex * create_unique_vertex(const EggVertex ©)
Creates a new vertex in the pool that is a copy of the indicated one and returns it.
A collection of vertices.
EggVertex * add_vertex(EggVertex *vertex)
Adds the indicated vertex to the end of the primitive'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.
virtual bool has_normals() const
Returns true if any of the primitives (e.g.
EggVertexPool * get_pool() const
Returns the vertex pool associated with the vertices of the primitive, or NULL if the primitive has n...