Panda3D
|
00001 // Filename: eggVertex.cxx 00002 // Created by: drose (16Jan99) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #include "eggVertex.h" 00016 #include "eggVertexPool.h" 00017 #include "eggParameters.h" 00018 #include "eggGroup.h" 00019 #include "eggMiscFuncs.h" 00020 #include "eggPrimitive.h" 00021 00022 #include "indent.h" 00023 #include "luse.h" 00024 #include "lmatrix.h" 00025 #include "pandabase.h" 00026 00027 #include <math.h> 00028 #include <algorithm> 00029 00030 TypeHandle EggVertex::_type_handle; 00031 00032 00033 //////////////////////////////////////////////////////////////////// 00034 // Function: EggVertex::Constructor 00035 // Access: Published 00036 // Description: 00037 //////////////////////////////////////////////////////////////////// 00038 EggVertex:: 00039 EggVertex() { 00040 _pool = NULL; 00041 _forward_reference = false; 00042 _index = -1; 00043 _external_index = -1; 00044 set_pos(LPoint3d(0.0, 0.0, 0.0)); 00045 test_pref_integrity(); 00046 test_gref_integrity(); 00047 } 00048 00049 //////////////////////////////////////////////////////////////////// 00050 // Function: EggVertex::Copy constructor 00051 // Access: Published 00052 // Description: Copies all properties of the vertex except its vertex 00053 // pool, index number, and group membership. 00054 //////////////////////////////////////////////////////////////////// 00055 EggVertex:: 00056 EggVertex(const EggVertex ©) 00057 : EggObject(copy), EggAttributes(copy), 00058 _dxyzs(copy._dxyzs), 00059 _external_index(copy._external_index), 00060 _pos(copy._pos), 00061 _num_dimensions(copy._num_dimensions), 00062 _uv_map(copy._uv_map), 00063 _aux_map(copy._aux_map) 00064 { 00065 _pool = NULL; 00066 _forward_reference = false; 00067 _index = -1; 00068 test_pref_integrity(); 00069 test_gref_integrity(); 00070 } 00071 00072 00073 //////////////////////////////////////////////////////////////////// 00074 // Function: EggVertex::Copy assignment operator 00075 // Access: Published 00076 // Description: Copies all properties of the vertex except its vertex 00077 // pool, index number, and group membership. 00078 //////////////////////////////////////////////////////////////////// 00079 EggVertex &EggVertex:: 00080 operator = (const EggVertex ©) { 00081 EggObject::operator = (copy); 00082 EggAttributes::operator = (copy); 00083 _dxyzs = copy._dxyzs; 00084 _external_index = copy._external_index; 00085 _pos = copy._pos; 00086 _num_dimensions = copy._num_dimensions; 00087 _uv_map = copy._uv_map; 00088 _aux_map = copy._aux_map; 00089 00090 test_pref_integrity(); 00091 test_gref_integrity(); 00092 00093 return *this; 00094 } 00095 00096 //////////////////////////////////////////////////////////////////// 00097 // Function: EggVertex::Destructor 00098 // Access: Published, Virtual 00099 // Description: 00100 //////////////////////////////////////////////////////////////////// 00101 EggVertex:: 00102 ~EggVertex() { 00103 // We should never destruct a vertex while it still thinks it 00104 // belongs to a VertexPool. If we do, we've probably lost a 00105 // reference count somewhere. 00106 nassertv(_pool == NULL); 00107 00108 // Also, a vertex shouldn't be destructed while it's being 00109 // referenced by a group or a primitive, for the same reason. 00110 nassertv(_gref.empty()); 00111 nassertv(_pref.empty()); 00112 } 00113 00114 //////////////////////////////////////////////////////////////////// 00115 // Function: EggVertex::has_uv 00116 // Access: Published 00117 // Description: Returns true if the vertex has the named UV 00118 // coordinate pair, and the named UV coordinate pair is 00119 // 2-d, false otherwise. 00120 //////////////////////////////////////////////////////////////////// 00121 bool EggVertex:: 00122 has_uv(const string &name) const { 00123 UVMap::const_iterator ui = _uv_map.find(EggVertexUV::filter_name(name)); 00124 if (ui != _uv_map.end()) { 00125 EggVertexUV *uv_obj = (*ui).second; 00126 return !uv_obj->has_w(); 00127 } 00128 return false; 00129 } 00130 00131 //////////////////////////////////////////////////////////////////// 00132 // Function: EggVertex::has_uvw 00133 // Access: Published 00134 // Description: Returns true if the vertex has the named UV 00135 // coordinate triple, and the named UV coordinate triple is 00136 // 3-d, false otherwise. 00137 //////////////////////////////////////////////////////////////////// 00138 bool EggVertex:: 00139 has_uvw(const string &name) const { 00140 UVMap::const_iterator ui = _uv_map.find(EggVertexUV::filter_name(name)); 00141 if (ui != _uv_map.end()) { 00142 EggVertexUV *uv_obj = (*ui).second; 00143 return uv_obj->has_w(); 00144 } 00145 return false; 00146 } 00147 00148 //////////////////////////////////////////////////////////////////// 00149 // Function: EggVertex::has_aux 00150 // Access: Published 00151 // Description: Returns true if the vertex has the named 00152 // auxiliary data quadruple. 00153 //////////////////////////////////////////////////////////////////// 00154 bool EggVertex:: 00155 has_aux(const string &name) const { 00156 AuxMap::const_iterator xi = _aux_map.find(name); 00157 if (xi != _aux_map.end()) { 00158 EggVertexAux *aux_obj = (*xi).second; 00159 return true; 00160 } 00161 return false; 00162 } 00163 00164 //////////////////////////////////////////////////////////////////// 00165 // Function: EggVertex::get_uv 00166 // Access: Published 00167 // Description: Returns the named UV coordinate pair on the vertex. 00168 // It is an error to call this if has_uv(name) 00169 // returned false. 00170 //////////////////////////////////////////////////////////////////// 00171 LTexCoordd EggVertex:: 00172 get_uv(const string &name) const { 00173 UVMap::const_iterator ui = _uv_map.find(EggVertexUV::filter_name(name)); 00174 nassertr(ui != _uv_map.end(), LTexCoordd::zero()); 00175 return (*ui).second->get_uv(); 00176 } 00177 00178 //////////////////////////////////////////////////////////////////// 00179 // Function: EggVertex::get_uvw 00180 // Access: Published 00181 // Description: Returns the named UV coordinate triple on the vertex. 00182 // It is an error to call this if has_uvw(name) 00183 // returned false. 00184 //////////////////////////////////////////////////////////////////// 00185 const LTexCoord3d &EggVertex:: 00186 get_uvw(const string &name) const { 00187 UVMap::const_iterator ui = _uv_map.find(EggVertexUV::filter_name(name)); 00188 nassertr(ui != _uv_map.end(), LTexCoord3d::zero()); 00189 return (*ui).second->get_uvw(); 00190 } 00191 00192 //////////////////////////////////////////////////////////////////// 00193 // Function: EggVertex::get_aux 00194 // Access: Published 00195 // Description: Returns the named auxiliary data quadruple on the 00196 // vertex. It is an error to call this if has_aux(name) 00197 // returned false. 00198 //////////////////////////////////////////////////////////////////// 00199 const LVecBase4d &EggVertex:: 00200 get_aux(const string &name) const { 00201 AuxMap::const_iterator xi = _aux_map.find(name); 00202 nassertr(xi != _aux_map.end(), LVecBase4d::zero()); 00203 return (*xi).second->get_aux(); 00204 } 00205 00206 //////////////////////////////////////////////////////////////////// 00207 // Function: EggVertex::set_uv 00208 // Access: Published 00209 // Description: Sets the indicated UV coordinate pair on the vertex. 00210 // This replaces any UV coordinate pair with the same 00211 // name already on the vertex, but preserves UV morphs. 00212 //////////////////////////////////////////////////////////////////// 00213 void EggVertex:: 00214 set_uv(const string &name, const LTexCoordd &uv) { 00215 string fname = EggVertexUV::filter_name(name); 00216 PT(EggVertexUV) &uv_obj = _uv_map[fname]; 00217 00218 if (uv_obj.is_null()) { 00219 uv_obj = new EggVertexUV(fname, uv); 00220 } else { 00221 uv_obj = new EggVertexUV(*uv_obj); 00222 uv_obj->set_uv(uv); 00223 } 00224 00225 nassertv(get_uv(fname) == uv); 00226 } 00227 00228 //////////////////////////////////////////////////////////////////// 00229 // Function: EggVertex::set_uvw 00230 // Access: Published 00231 // Description: Sets the indicated UV coordinate triple on the vertex. 00232 // This replaces any UV coordinate pair or triple with 00233 // the same name already on the vertex, but preserves UV 00234 // morphs. 00235 //////////////////////////////////////////////////////////////////// 00236 void EggVertex:: 00237 set_uvw(const string &name, const LTexCoord3d &uvw) { 00238 string fname = EggVertexUV::filter_name(name); 00239 PT(EggVertexUV) &uv_obj = _uv_map[fname]; 00240 00241 if (uv_obj.is_null()) { 00242 uv_obj = new EggVertexUV(fname, uvw); 00243 } else { 00244 uv_obj = new EggVertexUV(*uv_obj); 00245 uv_obj->set_uvw(uvw); 00246 } 00247 00248 nassertv(get_uvw(fname) == uvw); 00249 } 00250 00251 //////////////////////////////////////////////////////////////////// 00252 // Function: EggVertex::set_aux 00253 // Access: Published 00254 // Description: Sets the indicated auxiliary data quadruple on the 00255 // vertex. This replaces any auxiliary data with the 00256 // same name already on the vertex. 00257 //////////////////////////////////////////////////////////////////// 00258 void EggVertex:: 00259 set_aux(const string &name, const LVecBase4d &aux) { 00260 PT(EggVertexAux) &aux_obj = _aux_map[name]; 00261 00262 if (aux_obj.is_null()) { 00263 aux_obj = new EggVertexAux(name, aux); 00264 } else { 00265 aux_obj = new EggVertexAux(*aux_obj); 00266 aux_obj->set_aux(aux); 00267 } 00268 00269 nassertv(get_aux(name) == aux); 00270 } 00271 00272 //////////////////////////////////////////////////////////////////// 00273 // Function: EggVertex::get_uv_obj 00274 // Access: Published 00275 // Description: Returns the named EggVertexUV object, which defines 00276 // both the UV coordinate pair for this name and the UV 00277 // morphs. This object might be shared between multiple 00278 // vertices. You should not attempt to modify this 00279 // object; instead, call modify_uv_object to return a 00280 // modifiable pointer. 00281 //////////////////////////////////////////////////////////////////// 00282 const EggVertexUV *EggVertex:: 00283 get_uv_obj(const string &name) const { 00284 UVMap::const_iterator ui = _uv_map.find(EggVertexUV::filter_name(name)); 00285 if (ui != _uv_map.end()) { 00286 return (*ui).second; 00287 } 00288 return NULL; 00289 } 00290 00291 //////////////////////////////////////////////////////////////////// 00292 // Function: EggVertex::get_aux_obj 00293 // Access: Published 00294 // Description: Returns the named EggVertexAux object, which defines 00295 // the auxiliary data for this name. This object might 00296 // be shared between multiple vertices. You should not 00297 // attempt to modify this object; instead, call 00298 // modify_aux_object to return a modifiable pointer. 00299 //////////////////////////////////////////////////////////////////// 00300 const EggVertexAux *EggVertex:: 00301 get_aux_obj(const string &name) const { 00302 AuxMap::const_iterator xi = _aux_map.find(name); 00303 if (xi != _aux_map.end()) { 00304 return (*xi).second; 00305 } 00306 return NULL; 00307 } 00308 00309 //////////////////////////////////////////////////////////////////// 00310 // Function: EggVertex::modify_uv_obj 00311 // Access: Published 00312 // Description: Returns a modifiable pointer to the named EggVertexUV 00313 // object, which defines both the UV coordinate pair for 00314 // this name and the UV morphs. Returns NULL if there 00315 // is no such named UV object. 00316 //////////////////////////////////////////////////////////////////// 00317 EggVertexUV *EggVertex:: 00318 modify_uv_obj(const string &name) { 00319 UVMap::iterator ui = _uv_map.find(EggVertexUV::filter_name(name)); 00320 if (ui != _uv_map.end()) { 00321 if ((*ui).second->get_ref_count() != 1) { 00322 // Copy on write. 00323 (*ui).second = new EggVertexUV(*(*ui).second); 00324 } 00325 return (*ui).second; 00326 } 00327 00328 return NULL; 00329 } 00330 00331 //////////////////////////////////////////////////////////////////// 00332 // Function: EggVertex::modify_aux_obj 00333 // Access: Published 00334 // Description: Returns a modifiable pointer to the named EggVertexAux 00335 // object, which defines the auxiliary data for 00336 // this name. Returns NULL if there is no such 00337 // named UV object. 00338 //////////////////////////////////////////////////////////////////// 00339 EggVertexAux *EggVertex:: 00340 modify_aux_obj(const string &name) { 00341 AuxMap::iterator xi = _aux_map.find(name); 00342 if (xi != _aux_map.end()) { 00343 if ((*xi).second->get_ref_count() != 1) { 00344 // Copy on write. 00345 (*xi).second = new EggVertexAux(*(*xi).second); 00346 } 00347 return (*xi).second; 00348 } 00349 00350 return NULL; 00351 } 00352 00353 //////////////////////////////////////////////////////////////////// 00354 // Function: EggVertex::set_uv_obj 00355 // Access: Published 00356 // Description: Sets the indicated EggVertexUV on the vertex. 00357 // This replaces any UV coordinate pair with the same 00358 // name already on the vertex, including UV morphs. 00359 //////////////////////////////////////////////////////////////////// 00360 void EggVertex:: 00361 set_uv_obj(EggVertexUV *uv) { 00362 _uv_map[uv->get_name()] = uv; 00363 } 00364 00365 //////////////////////////////////////////////////////////////////// 00366 // Function: EggVertex::set_aux_obj 00367 // Access: Published 00368 // Description: Sets the indicated EggVertexAux on the vertex. 00369 // This replaces any auxiliary data with the same 00370 // name already on the vertex. 00371 //////////////////////////////////////////////////////////////////// 00372 void EggVertex:: 00373 set_aux_obj(EggVertexAux *aux) { 00374 _aux_map[aux->get_name()] = aux; 00375 } 00376 00377 //////////////////////////////////////////////////////////////////// 00378 // Function: EggVertex::clear_uv 00379 // Access: Published 00380 // Description: Removes the named UV coordinate pair from the vertex, 00381 // along with any UV morphs. 00382 /////////////////////////////////////////////////////////////////// 00383 void EggVertex:: 00384 clear_uv(const string &name) { 00385 _uv_map.erase(EggVertexUV::filter_name(name)); 00386 } 00387 00388 //////////////////////////////////////////////////////////////////// 00389 // Function: EggVertex::clear_aux 00390 // Access: Published 00391 // Description: Removes the named auxiliary data from the vertex. 00392 /////////////////////////////////////////////////////////////////// 00393 void EggVertex:: 00394 clear_aux(const string &name) { 00395 _aux_map.erase(name); 00396 } 00397 00398 00399 /////////////////////////////////////////////////////////////////// 00400 // Class : GroupRefEntry 00401 // Description : A temporary class used in EggVertex::write(), below, 00402 // to hold the groups that reference each vertex prior 00403 // to outputting them as a formatted list. 00404 //////////////////////////////////////////////////////////////////// 00405 class GroupRefEntry { 00406 public: 00407 GroupRefEntry(EggGroup *group, double membership) 00408 : _group(group), _membership(membership) { } 00409 00410 bool operator < (const GroupRefEntry &other) const { 00411 return _group->get_name() < other._group->get_name(); 00412 } 00413 void output(ostream &out) const { 00414 out << _group->get_name() << ":" << _membership; 00415 } 00416 00417 EggGroup *_group; 00418 double _membership; 00419 }; 00420 00421 INLINE ostream &operator << (ostream &out, const GroupRefEntry &gre) { 00422 gre.output(out); 00423 return out; 00424 } 00425 00426 //////////////////////////////////////////////////////////////////// 00427 // Function: EggVertex::write 00428 // Access: Published 00429 // Description: Writes the vertex to the indicated output stream in 00430 // Egg format. 00431 //////////////////////////////////////////////////////////////////// 00432 void EggVertex:: 00433 write(ostream &out, int indent_level) const { 00434 test_pref_integrity(); 00435 test_gref_integrity(); 00436 00437 indent(out, indent_level) 00438 << "<Vertex> " << _index << " {\n"; 00439 00440 // Now output the position. This might have any number of 00441 // dimensions up to 4. 00442 indent(out, indent_level+1); 00443 for (int i = 0; i < _num_dimensions; i++) { 00444 out << " " << _pos[i]; 00445 } 00446 out << "\n"; 00447 00448 UVMap::const_iterator ui; 00449 for (ui = _uv_map.begin(); ui != _uv_map.end(); ++ui) { 00450 (*ui).second->write(out, indent_level + 2); 00451 } 00452 00453 AuxMap::const_iterator xi; 00454 for (xi = _aux_map.begin(); xi != _aux_map.end(); ++xi) { 00455 (*xi).second->write(out, indent_level + 2); 00456 } 00457 00458 EggAttributes::write(out, indent_level+2); 00459 00460 _dxyzs.write(out, indent_level + 2, "<Dxyz>", 3); 00461 00462 // If the vertex is referenced by one or more groups, write that as 00463 // a helpful comment. 00464 if (!_gref.empty()) { 00465 // We need to build a list of group entries. 00466 pset<GroupRefEntry> gre; 00467 00468 GroupRef::const_iterator gi; 00469 for (gi = _gref.begin(); gi != _gref.end(); ++gi) { 00470 gre.insert(GroupRefEntry(*gi, (*gi)->get_vertex_membership(this))); 00471 } 00472 00473 // Now output the list. 00474 write_long_list(out, indent_level + 2, gre.begin(), gre.end(), "// ", 00475 "", 72); 00476 } 00477 00478 indent(out, indent_level) 00479 << "}\n"; 00480 } 00481 00482 00483 //////////////////////////////////////////////////////////////////// 00484 // Function: EggVertex::compare_to 00485 // Access: Published 00486 // Description: An ordering operator to compare two vertices for 00487 // sorting order. This imposes an arbitrary ordering 00488 // useful to identify unique vertices. 00489 // 00490 // Group membership is not considered in this 00491 // comparison. This is somewhat problematic, but cannot 00492 // easily be helped, because considering group 00493 // membership would make it difficult to add and remove 00494 // groups from vertices. It also makes it impossible to 00495 // meaningfully compare with a concrete EggVertex object 00496 // (which cannot have group memberships). 00497 // 00498 // However, this is not altogether bad, because two 00499 // vertices that are identical in all other properties 00500 // should generally also be identical in group 00501 // memberships, else the vertices will tend to fly apart 00502 // when the joints animate. 00503 //////////////////////////////////////////////////////////////////// 00504 int EggVertex:: 00505 compare_to(const EggVertex &other) const { 00506 if (_external_index != other._external_index) { 00507 return (int)_external_index - (int)other._external_index; 00508 } 00509 if (_num_dimensions != other._num_dimensions) { 00510 return (int)_num_dimensions - (int)other._num_dimensions; 00511 } 00512 00513 int compare = 00514 _pos.compare_to(other._pos, egg_parameters->_pos_threshold); 00515 if (compare != 0) { 00516 return compare; 00517 } 00518 compare = _dxyzs.compare_to(other._dxyzs, egg_parameters->_pos_threshold); 00519 if (compare != 0) { 00520 return compare; 00521 } 00522 00523 // Merge-compare the uv maps. 00524 UVMap::const_iterator ai, bi; 00525 ai = _uv_map.begin(); 00526 bi = other._uv_map.begin(); 00527 while (ai != _uv_map.end() && bi != other._uv_map.end()) { 00528 if ((*ai).first < (*bi).first) { 00529 return -1; 00530 00531 } else if ((*bi).first < (*ai).first) { 00532 return 1; 00533 00534 } else { 00535 int compare = (*ai).second->compare_to(*(*bi).second); 00536 if (compare != 0) { 00537 return compare; 00538 } 00539 } 00540 ++ai; 00541 ++bi; 00542 } 00543 if (bi != other._uv_map.end()) { 00544 return -1; 00545 } 00546 if (ai != _uv_map.end()) { 00547 return 1; 00548 } 00549 00550 // Merge-compare the aux maps. 00551 AuxMap::const_iterator ci, di; 00552 ci = _aux_map.begin(); 00553 di = other._aux_map.begin(); 00554 while (ci != _aux_map.end() && di != other._aux_map.end()) { 00555 if ((*ci).first < (*di).first) { 00556 return -1; 00557 00558 } else if ((*di).first < (*ci).first) { 00559 return 1; 00560 00561 } else { 00562 int compare = (*ci).second->compare_to(*(*di).second); 00563 if (compare != 0) { 00564 return compare; 00565 } 00566 } 00567 ++ci; 00568 ++di; 00569 } 00570 if (di != other._aux_map.end()) { 00571 return -1; 00572 } 00573 if (ci != _aux_map.end()) { 00574 return 1; 00575 } 00576 00577 return EggAttributes::compare_to(other); 00578 } 00579 00580 //////////////////////////////////////////////////////////////////// 00581 // Function: EggVertex::get_num_local_coord 00582 // Access: Published 00583 // Description: Returns the number of primitives that own this vertex 00584 // whose vertices are interpreted to be in a local 00585 // coordinate system. 00586 //////////////////////////////////////////////////////////////////// 00587 int EggVertex:: 00588 get_num_local_coord() const { 00589 test_pref_integrity(); 00590 00591 PrimitiveRef::const_iterator pri; 00592 00593 int count = 0; 00594 for (pri = pref_begin(); pri != pref_end(); ++pri) { 00595 EggPrimitive *prim = *pri; 00596 count += (prim->is_local_coord() ? 1 : 0); 00597 } 00598 return count; 00599 } 00600 00601 //////////////////////////////////////////////////////////////////// 00602 // Function: EggVertex::get_num_global_coord 00603 // Access: Published 00604 // Description: Returns the number of primitives that own this vertex 00605 // whose vertices are interpreted in the global 00606 // coordinate system. 00607 //////////////////////////////////////////////////////////////////// 00608 int EggVertex:: 00609 get_num_global_coord() const { 00610 test_pref_integrity(); 00611 00612 PrimitiveRef::const_iterator pri; 00613 00614 int count = 0; 00615 for (pri = pref_begin(); pri != pref_end(); ++pri) { 00616 EggPrimitive *prim = *pri; 00617 count += (prim->is_local_coord() ? 0 : 1); 00618 } 00619 return count; 00620 } 00621 00622 00623 //////////////////////////////////////////////////////////////////// 00624 // Function: EggVertex::transform 00625 // Access: Published, Virtual 00626 // Description: Applies the indicated transformation matrix to the 00627 // vertex. 00628 //////////////////////////////////////////////////////////////////// 00629 void EggVertex:: 00630 transform(const LMatrix4d &mat) { 00631 _pos = _pos * mat; 00632 00633 EggMorphVertexList::iterator mi; 00634 for (mi = _dxyzs.begin(); mi != _dxyzs.end(); ++mi) { 00635 // We can safely cast the morph object to a non-const, because 00636 // we're not changing its name, which is the only thing the set 00637 // cares about preserving. 00638 EggMorphVertex &morph = (EggMorphVertex &)(*mi); 00639 00640 morph.set_offset((*mi).get_offset() * mat); 00641 } 00642 00643 UVMap::iterator ui; 00644 for (ui = _uv_map.begin(); ui != _uv_map.end(); ++ui) { 00645 (*ui).second->transform(mat); 00646 } 00647 00648 EggAttributes::transform(mat); 00649 } 00650 00651 00652 //////////////////////////////////////////////////////////////////// 00653 // Function: EggVertex::gref_begin 00654 // Access: Public 00655 // Description: Returns an iterator that can, in conjunction with 00656 // gref_end(), be used to traverse the entire set of 00657 // groups that reference this vertex. Each iterator 00658 // returns a pointer to a group. 00659 // 00660 // This interface is not safe to use outside of 00661 // PANDAEGG.DLL. 00662 //////////////////////////////////////////////////////////////////// 00663 EggVertex::GroupRef::const_iterator EggVertex:: 00664 gref_begin() const { 00665 return _gref.begin(); 00666 } 00667 00668 //////////////////////////////////////////////////////////////////// 00669 // Function: EggVertex::gref_end 00670 // Access: Public 00671 // Description: Returns an iterator that can, in conjunction with 00672 // gref_begin(), be used to traverse the entire set of 00673 // groups that reference this vertex. Each iterator 00674 // returns a pointer to a group. 00675 // 00676 // This interface is not safe to use outside of 00677 // PANDAEGG.DLL. 00678 //////////////////////////////////////////////////////////////////// 00679 EggVertex::GroupRef::const_iterator EggVertex:: 00680 gref_end() const { 00681 return _gref.end(); 00682 } 00683 00684 //////////////////////////////////////////////////////////////////// 00685 // Function: EggVertex::gref_size 00686 // Access: Public 00687 // Description: Returns the number of elements between gref_begin() 00688 // and gref_end(). 00689 // 00690 // This interface is not safe to use outside of 00691 // PANDAEGG.DLL. 00692 //////////////////////////////////////////////////////////////////// 00693 EggVertex::GroupRef::size_type EggVertex:: 00694 gref_size() const { 00695 return _gref.size(); 00696 } 00697 00698 //////////////////////////////////////////////////////////////////// 00699 // Function: EggVertex::has_gref 00700 // Access: Published 00701 // Description: Returns true if the indicated group references this 00702 // vertex, false otherwise. 00703 //////////////////////////////////////////////////////////////////// 00704 bool EggVertex:: 00705 has_gref(const EggGroup *group) const { 00706 return _gref.count((EggGroup *)group) != 0; 00707 } 00708 00709 //////////////////////////////////////////////////////////////////// 00710 // Function: EggVertex::copy_grefs_from 00711 // Access: Published 00712 // Description: Copies all the group references from the other vertex 00713 // onto this one. This assigns the current vertex to 00714 // exactly the same groups, with exactly the same 00715 // memberships, as the given one. 00716 // 00717 // Warning: only an EggVertex allocated from the free 00718 // store may have groups assigned to it. Do not attempt 00719 // to call this on a temporary concrete EggVertex 00720 // object; a core dump will certainly result. 00721 //////////////////////////////////////////////////////////////////// 00722 void EggVertex:: 00723 copy_grefs_from(const EggVertex &other) { 00724 if (&other == this) { 00725 return; 00726 } 00727 test_gref_integrity(); 00728 other.test_gref_integrity(); 00729 00730 clear_grefs(); 00731 test_gref_integrity(); 00732 00733 GroupRef::const_iterator gri; 00734 00735 for (gri = other.gref_begin(); gri != other.gref_end(); ++gri) { 00736 EggGroup *group = *gri; 00737 nassertv(group != NULL); 00738 00739 group->ref_vertex(this, group->get_vertex_membership(&other)); 00740 } 00741 } 00742 00743 //////////////////////////////////////////////////////////////////// 00744 // Function: EggVertex::clear_grefs 00745 // Access: Published 00746 // Description: Removes all group references from the vertex, so that 00747 // it is not assigned to any group. 00748 //////////////////////////////////////////////////////////////////// 00749 void EggVertex:: 00750 clear_grefs() { 00751 GroupRef gref_copy = _gref; 00752 GroupRef::const_iterator gri; 00753 for (gri = gref_copy.begin(); gri != gref_copy.end(); ++gri) { 00754 EggGroup *group = *gri; 00755 nassertv(group != NULL); 00756 group->unref_vertex(this); 00757 } 00758 00759 // Now we should have no more refs. 00760 nassertv(_gref.empty()); 00761 } 00762 00763 //////////////////////////////////////////////////////////////////// 00764 // Function: EggVertex::pref_begin 00765 // Access: Public 00766 // Description: Returns an iterator that can, in conjunction with 00767 // pref_end(), be used to traverse the entire set of 00768 // primitives that reference this vertex. Each iterator 00769 // returns a pointer to a primitive. 00770 // 00771 // This interface is not safe to use outside of 00772 // PANDAEGG.DLL. 00773 //////////////////////////////////////////////////////////////////// 00774 EggVertex::PrimitiveRef::const_iterator EggVertex:: 00775 pref_begin() const { 00776 return _pref.begin(); 00777 } 00778 00779 //////////////////////////////////////////////////////////////////// 00780 // Function: EggVertex::pref_end 00781 // Access: Public 00782 // Description: Returns an iterator that can, in conjunction with 00783 // pref_begin(), be used to traverse the entire set of 00784 // primitives that reference this vertex. Each iterator 00785 // returns a pointer to a primitive. 00786 // 00787 // This interface is not safe to use outside of 00788 // PANDAEGG.DLL. 00789 //////////////////////////////////////////////////////////////////// 00790 EggVertex::PrimitiveRef::const_iterator EggVertex:: 00791 pref_end() const { 00792 return _pref.end(); 00793 } 00794 00795 //////////////////////////////////////////////////////////////////// 00796 // Function: EggVertex::pref_size 00797 // Access: Public 00798 // Description: Returns the number of elements between pref_begin() 00799 // and pref_end(). 00800 // 00801 // This interface is not safe to use outside of 00802 // PANDAEGG.DLL. 00803 //////////////////////////////////////////////////////////////////// 00804 EggVertex::GroupRef::size_type EggVertex:: 00805 pref_size() const { 00806 return _pref.size(); 00807 } 00808 00809 //////////////////////////////////////////////////////////////////// 00810 // Function: EggVertex::has_pref 00811 // Access: Published 00812 // Description: Returns the number of times the vertex appears in the 00813 // indicated primitive, or 0 if it does not appear. 00814 //////////////////////////////////////////////////////////////////// 00815 int EggVertex:: 00816 has_pref(const EggPrimitive *prim) const { 00817 return _pref.count((EggPrimitive *)prim); 00818 } 00819 00820 #ifdef _DEBUG 00821 00822 //////////////////////////////////////////////////////////////////// 00823 // Function: EggVertex::test_gref_integrity 00824 // Access: Published 00825 // Description: Verifies that the gref list is correct and that all 00826 // the groups included actually exist and do reference 00827 // the vertex. 00828 //////////////////////////////////////////////////////////////////// 00829 void EggVertex:: 00830 test_gref_integrity() const { 00831 test_ref_count_integrity(); 00832 00833 GroupRef::const_iterator gri; 00834 00835 for (gri = gref_begin(); gri != gref_end(); ++gri) { 00836 EggGroup *group = *gri; 00837 nassertv(group != NULL); 00838 group->test_ref_count_integrity(); 00839 00840 double membership = group->get_vertex_membership(this); 00841 nassertv(membership != 0.0); 00842 } 00843 } 00844 00845 //////////////////////////////////////////////////////////////////// 00846 // Function: EggVertex::test_pref_integrity 00847 // Access: Published 00848 // Description: Verifies that the pref list is correct and that all 00849 // the primitives included actually exist and do 00850 // reference the vertex. 00851 //////////////////////////////////////////////////////////////////// 00852 void EggVertex:: 00853 test_pref_integrity() const { 00854 test_ref_count_integrity(); 00855 00856 PrimitiveRef::const_iterator pri; 00857 00858 for (pri = pref_begin(); pri != pref_end(); ++pri) { 00859 EggPrimitive *prim = *pri; 00860 nassertv(prim != NULL); 00861 prim->test_ref_count_integrity(); 00862 00863 EggPrimitive::iterator vi; 00864 vi = find(prim->begin(), prim->end(), this); 00865 nassertv(vi != prim->end()); 00866 } 00867 } 00868 00869 #endif // NDEBUG 00870 00871 //////////////////////////////////////////////////////////////////// 00872 // Function: EggVertex::output 00873 // Access: Published 00874 // Description: 00875 //////////////////////////////////////////////////////////////////// 00876 void EggVertex:: 00877 output(ostream &out) const { 00878 if (get_pool() == NULL) { 00879 out << "(null):" << get_index(); 00880 } else { 00881 out << get_pool()->get_name() << ":" << get_index(); 00882 } 00883 }