15 #include "eggVertex.h"
16 #include "eggVertexPool.h"
17 #include "eggParameters.h"
19 #include "eggMiscFuncs.h"
20 #include "eggPrimitive.h"
25 #include "pandabase.h"
41 _forward_reference =
false;
44 _external_index2 = -1;
46 test_pref_integrity();
47 test_gref_integrity();
60 _external_index(copy._external_index),
61 _external_index2(copy._external_index2),
63 _num_dimensions(copy._num_dimensions),
64 _uv_map(copy._uv_map),
65 _aux_map(copy._aux_map)
68 _forward_reference =
false;
70 test_pref_integrity();
71 test_gref_integrity();
83 EggObject::operator = (copy);
84 EggAttributes::operator = (copy);
86 _external_index = copy._external_index;
87 _external_index2 = copy._external_index2;
89 _num_dimensions = copy._num_dimensions;
90 _uv_map = copy._uv_map;
91 _aux_map = copy._aux_map;
93 test_pref_integrity();
94 test_gref_integrity();
109 nassertv(_pool == NULL);
113 nassertv(_gref.empty());
114 nassertv(_pref.empty());
127 if (ui != _uv_map.end()) {
129 return !uv_obj->
has_w();
144 if (ui != _uv_map.end()) {
146 return uv_obj->
has_w();
159 AuxMap::const_iterator xi = _aux_map.find(name);
160 if (xi != _aux_map.end()) {
178 return (*ui).second->get_uv();
192 return (*ui).second->get_uvw();
204 AuxMap::const_iterator xi = _aux_map.find(name);
206 return (*xi).second->get_aux();
221 if (uv_obj.is_null()) {
228 nassertv(
get_uv(fname) == uv);
244 if (uv_obj.is_null()) {
248 uv_obj->set_uvw(uvw);
251 nassertv(
get_uvw(fname) == uvw);
265 if (aux_obj.is_null()) {
269 aux_obj->set_aux(aux);
272 nassertv(
get_aux(name) == aux);
288 if (ui != _uv_map.end()) {
305 AuxMap::const_iterator xi = _aux_map.find(name);
306 if (xi != _aux_map.end()) {
323 if (ui != _uv_map.end()) {
324 if ((*ui).second->get_ref_count() != 1) {
344 AuxMap::iterator xi = _aux_map.find(name);
345 if (xi != _aux_map.end()) {
346 if ((*xi).second->get_ref_count() != 1) {
365 _uv_map[uv->get_name()] = uv;
377 _aux_map[aux->get_name()] = aux;
398 _aux_map.erase(name);
415 nassertr(pool == second->get_pool(), NULL);
423 middle = pool->make_new_vertex();
426 middle->
set_pos4((first->get_pos4() + second->get_pos4()) / 2);
428 if (first->has_normal() && second->has_normal()) {
429 LNormald normal = (first->get_normal() + second->get_normal()) / 2;
431 middle->set_normal(normal);
433 if (first->has_color() && second->has_color()) {
434 middle->set_color((first->get_color() + second->get_color()) / 2);
439 const_uv_iterator it;
440 for (it = first->uv_begin(); it != first->uv_end(); ++it) {
442 const EggVertexUV *second_uv = second->get_uv_obj(it->first);
444 if (first_uv != NULL && second_uv != NULL) {
445 middle->set_uv_obj(EggVertexUV::make_average(first_uv, second_uv));
450 const_aux_iterator ai;
451 for (ai = first->aux_begin(); ai != first->aux_end(); ++ai) {
453 const EggVertexAux *second_aux = second->get_aux_obj(ai->first);
455 if (first_aux != NULL && second_aux != NULL) {
456 middle->set_aux_obj(EggVertexAux::make_average(first_aux, second_aux));
461 EggMorphVertexList::const_iterator vi, vi2;
462 for (vi = first->_dxyzs.begin(); vi != first->_dxyzs.end(); ++vi) {
463 for (vi2 = second->_dxyzs.begin(); vi2 != second->_dxyzs.end(); ++vi2) {
464 if (vi->get_name() == vi2->get_name()) {
466 (vi->get_offset() + vi2->get_offset()) / 2));
472 EggMorphNormalList::const_iterator ni, ni2;
473 for (ni = first->_dxyzs.begin(); ni != first->_dxyzs.end(); ++ni) {
474 for (ni2 = second->_dxyzs.begin(); ni2 != second->_dxyzs.end(); ++ni2) {
475 if (ni->get_name() == ni2->get_name()) {
477 (ni->get_offset() + ni2->get_offset()) / 2));
483 EggMorphColorList::const_iterator ci, ci2;
484 for (ci = first->_drgbas.begin(); ci != first->_drgbas.end(); ++ci) {
485 for (ci2 = second->_drgbas.begin(); ci2 != second->_drgbas.end(); ++ci2) {
486 if (ci->get_name() == ci2->get_name()) {
488 (ci->get_offset() + ci2->get_offset()) / 2));
495 GroupRef::iterator gi;
496 for (gi = first->_gref.begin(); gi != first->_gref.end(); ++gi) {
498 if (second->_gref.count(group)) {
511 for (gi = second->_gref.begin(); gi != second->_gref.end(); ++gi) {
513 if (second->_gref.count(group) == 0) {
530 : _group(group), _membership(membership) { }
533 return _group->get_name() < other._group->get_name();
535 void output(ostream &out)
const {
536 out << _group->get_name() <<
":" << _membership;
543 INLINE ostream &operator << (ostream &out,
const GroupRefEntry &gre) {
555 write(ostream &out,
int indent_level)
const {
556 test_pref_integrity();
557 test_gref_integrity();
559 indent(out, indent_level)
560 <<
"<Vertex> " << _index <<
" {\n";
564 indent(out, indent_level+1);
565 for (
int i = 0; i < _num_dimensions; i++) {
566 out <<
" " << _pos[i];
570 UVMap::const_iterator ui;
571 for (ui = _uv_map.begin(); ui != _uv_map.end(); ++ui) {
572 (*ui).second->write(out, indent_level + 2);
575 AuxMap::const_iterator xi;
576 for (xi = _aux_map.begin(); xi != _aux_map.end(); ++xi) {
577 (*xi).second->write(out, indent_level + 2);
582 _dxyzs.write(out, indent_level + 2,
"<Dxyz>", 3);
586 if (!_gref.empty()) {
590 GroupRef::const_iterator gi;
591 for (gi = _gref.begin(); gi != _gref.end(); ++gi) {
592 gre.insert(
GroupRefEntry(*gi, (*gi)->get_vertex_membership(
this)));
596 write_long_list(out, indent_level + 2, gre.begin(), gre.end(),
"// ",
600 indent(out, indent_level)
628 if (_external_index != other._external_index) {
629 return (
int)_external_index - (int)other._external_index;
631 if (_external_index2 != other._external_index2) {
632 return (
int)_external_index2 - (int)other._external_index2;
634 if (_num_dimensions != other._num_dimensions) {
635 return (
int)_num_dimensions - (int)other._num_dimensions;
639 _pos.
compare_to(other._pos, egg_parameters->_pos_threshold);
643 compare = _dxyzs.
compare_to(other._dxyzs, egg_parameters->_pos_threshold);
649 UVMap::const_iterator ai, bi;
650 ai = _uv_map.begin();
651 bi = other._uv_map.begin();
652 while (ai != _uv_map.end() && bi != other._uv_map.end()) {
653 if ((*ai).first < (*bi).first) {
656 }
else if ((*bi).first < (*ai).first) {
660 int compare = (*ai).second->compare_to(*(*bi).second);
668 if (bi != other._uv_map.end()) {
671 if (ai != _uv_map.end()) {
676 AuxMap::const_iterator ci, di;
677 ci = _aux_map.begin();
678 di = other._aux_map.begin();
679 while (ci != _aux_map.end() && di != other._aux_map.end()) {
680 if ((*ci).first < (*di).first) {
683 }
else if ((*di).first < (*ci).first) {
687 int compare = (*ci).second->compare_to(*(*di).second);
695 if (di != other._aux_map.end()) {
698 if (ci != _aux_map.end()) {
714 test_pref_integrity();
716 PrimitiveRef::const_iterator pri;
735 test_pref_integrity();
737 PrimitiveRef::const_iterator pri;
758 EggMorphVertexList::iterator mi;
759 for (mi = _dxyzs.begin(); mi != _dxyzs.end(); ++mi) {
765 morph.set_offset((*mi).get_offset() * mat);
769 for (ui = _uv_map.begin(); ui != _uv_map.end(); ++ui) {
770 (*ui).second->transform(mat);
790 return _gref.begin();
831 return _gref.count((
EggGroup *)group) != 0;
849 if (&other ==
this) {
852 test_gref_integrity();
853 other.test_gref_integrity();
856 test_gref_integrity();
858 GroupRef::const_iterator gri;
862 nassertv(group != NULL);
877 GroupRef::const_iterator gri;
878 for (gri = gref_copy.begin(); gri != gref_copy.end(); ++gri) {
880 nassertv(group != NULL);
885 nassertv(_gref.empty());
899 EggVertex::PrimitiveRef::const_iterator
EggVertex::
901 return _pref.begin();
915 EggVertex::PrimitiveRef::const_iterator
EggVertex::
955 test_gref_integrity()
const {
958 GroupRef::const_iterator gri;
962 nassertv(group != NULL);
966 nassertv(membership != 0.0);
978 test_pref_integrity()
const {
981 PrimitiveRef::const_iterator pri;
985 nassertv(prim != NULL);
988 EggPrimitive::iterator vi;
989 vi = find(prim->begin(), prim->end(),
this);
990 nassertv(vi != prim->end());
1002 output(ostream &out)
const {
A base class for any of a number of kinds of geometry primitives: polygons, point lights...
void set_uvw(const string &name, const LTexCoord3d &texCoord)
Sets the indicated UV coordinate triple on the vertex.
const LTexCoord3d & get_uvw(const string &name) const
Returns the named UV coordinate triple on the vertex.
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...
static const LPoint2d & zero()
Returns a zero-length point.
LTexCoordd get_uv() const
Returns the unnamed UV coordinate pair on the vertex.
This is a 4-by-4 transform matrix.
void write(ostream &out, int indent_level) const
Writes the vertex to the indicated output stream in Egg format.
void clear_aux()
Removes all auxiliary data from the vertex.
bool is_local_coord() const
Returns true if this node's vertices are not in the global coordinate space.
void write(ostream &out, int indent_level) const
Writes the attributes to the indicated output stream in Egg format.
void set_pos(double pos)
Sets the vertex position.
bool has_uv() const
Returns true if the vertex has an unnamed UV coordinate pair, false otherwise.
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...
void transform(const LMatrix4d &mat)
Applies the indicated transformation matrix to the attributes.
void set_pos4(const LPoint4d &pos)
This special flavor of set_pos() sets the vertex as a four-component value, but does not change the s...
static string filter_name(const string &name)
Returns the actual name that should be set for a given name string.
static const LVecBase4d & zero()
Returns a zero-length vector.
This is the base class for all three-component vectors and points.
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...
GroupRef::const_iterator gref_end() const
Returns an iterator that can, in conjunction with gref_begin(), be used to traverse the entire set of...
int compare_to(const EggAttributes &other) const
An ordering operator to compare two vertices for sorting order.
This is a two-component point in space.
const LVecBase4d & get_aux(const string &name) const
Returns the named auxiliary data quadruple on the vertex.
void clear_grefs()
Removes all group references from the vertex, so that it is not assigned to any group.
GroupRef::const_iterator gref_begin() const
Returns an iterator that can, in conjunction with gref_end(), be used to traverse the entire set of g...
A single <Dxyz> or <Duv> or some such entry.
int compare_to(const EggVertex &other) const
An ordering operator to compare two vertices for sorting order.
EggVertex & operator=(const EggVertex ©)
Copies all properties of the vertex except its vertex pool, index number, and group membership...
int compare_to(const EggMorphList< MorphType > &other, double threshold) const
compare_to() compares a different space than the operator methods, which only check the morph's name...
bool has_aux() const
Returns true if the vertex has any auxiliary data, false otherwise.
void set_aux(const string &name, const LVecBase4d &aux)
Sets the indicated auxiliary data quadruple on the vertex.
void unref_vertex(EggVertex *vert)
Removes the vertex from the set of those referenced by the group.
bool normalize()
Normalizes the vector in place.
const EggVertexAux * get_aux_obj(const string &name) const
Returns the named EggVertexAux object, which defines the auxiliary data for this name.
The main glue of the egg hierarchy, this corresponds to the <Group>, <Instance>, and <Joint> type nod...
int get_num_local_coord() const
Returns the number of primitives that own this vertex whose vertices are interpreted to be in a local...
The set of attributes that may be applied to vertices as well as polygons, such as surface normal and...
void clear_uv()
Removes all UV coordinate pairs from the vertex.
void set_uv_obj(EggVertexUV *vertex_uv)
Sets the indicated EggVertexUV on the vertex.
PrimitiveRef::size_type pref_size() const
Returns the number of elements between pref_begin() and pref_end().
void transform(const LMatrix4d &mat)
Applies the indicated transformation matrix to the vertex.
Any one-, two-, three-, or four-component vertex, possibly with attributes such as a normal...
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...
void set_vertex_membership(EggVertex *vert, double membership)
Explicitly sets the net membership of the indicated vertex in this group to the given value...
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...
static const LPoint3d & zero()
Returns a zero-length point.
bool has_gref(const EggGroup *group) const
Returns true if the indicated group references this vertex, false otherwise.
The set of named auxiliary data that may or may not be assigned to a vertex.
double get_vertex_membership(const EggVertex *vert) const
Returns the amount of membership of the indicated vertex in this group.
This is a three-component vector distance (as opposed to a three-component point, which represents a ...
This is a three-component point in space (as opposed to a three-component vector, which represents a ...
EggVertexUV * modify_uv_obj(const string &name)
Returns a modifiable pointer to the named EggVertexUV object, which defines both the UV coordinate pa...
void set_aux_obj(EggVertexAux *vertex_aux)
Sets the indicated EggVertexAux on the vertex.
void ref_vertex(EggVertex *vert, double membership=1.0)
Adds the vertex to the set of those referenced by the group, at the indicated membership level...
This is our own Panda specialization on the default STL set.
void copy_grefs_from(const EggVertex &other)
Copies all the group references from the other vertex onto this one.
int compare_to(const LVecBase4d &other) const
This flavor of compare_to uses a default threshold value based on the numeric type.
bool has_uvw(const string &name) const
Returns true if the vertex has the named UV coordinate triple, and the named UV coordinate triple is ...
TypeHandle is the identifier used to differentiate C++ class types.
EggVertexPool * get_pool() const
Returns the vertex pool this vertex belongs in.
GroupRef::size_type gref_size() const
Returns the number of elements between gref_begin() and gref_end().
int get_num_global_coord() const
Returns the number of primitives that own this vertex whose vertices are interpreted in the global co...
void set_uv(const LTexCoordd &texCoord)
Replaces the unnamed UV coordinate pair on the vertex with the indicated value.
EggVertexAux * modify_aux_obj(const string &name)
Returns a modifiable pointer to the named EggVertexAux object, which defines the auxiliary data for t...
A collection of vertices.
The highest-level base class in the egg directory.
A temporary class used in EggVertex::write(), below, to hold the groups that reference each vertex pr...
int get_index() const
Returns the index number of the vertex within its pool.