00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "eggVertex.h"
00020 #include "eggVertexPool.h"
00021 #include "eggParameters.h"
00022 #include "eggGroup.h"
00023 #include "eggMiscFuncs.h"
00024 #include "eggPrimitive.h"
00025
00026 #include <indent.h>
00027 #include <luse.h>
00028 #include <lmatrix.h>
00029 #include <pandabase.h>
00030
00031 #include <math.h>
00032 #include <algorithm>
00033
00034 TypeHandle EggVertex::_type_handle;
00035
00036
00037
00038
00039
00040
00041
00042 EggVertex::
00043 EggVertex() {
00044 _pool = NULL;
00045 _index = -1;
00046 _external_index = -1;
00047 set_pos(LPoint3d(0.0, 0.0, 0.0));
00048 test_pref_integrity();
00049 test_gref_integrity();
00050 }
00051
00052
00053
00054
00055
00056
00057
00058 EggVertex::
00059 EggVertex(const EggVertex ©)
00060 : EggObject(copy), EggAttributes(copy),
00061 _dxyzs(copy._dxyzs),
00062 _external_index(copy._external_index),
00063 _pos(copy._pos),
00064 _num_dimensions(copy._num_dimensions)
00065 {
00066 _pool = NULL;
00067 _index = -1;
00068 test_pref_integrity();
00069 test_gref_integrity();
00070 }
00071
00072
00073
00074
00075
00076
00077
00078
00079 EggVertex &EggVertex::
00080 operator = (const EggVertex ©) {
00081 EggObject::operator = (copy);
00082 EggAttributes::operator = (copy);
00083 _external_index = copy._external_index;
00084 _pos = copy._pos;
00085 _num_dimensions = copy._num_dimensions;
00086 _dxyzs = copy._dxyzs;
00087
00088 test_pref_integrity();
00089 test_gref_integrity();
00090
00091 return *this;
00092 }
00093
00094
00095
00096
00097
00098
00099 EggVertex::
00100 ~EggVertex() {
00101
00102
00103
00104 nassertv(_pool == NULL);
00105
00106
00107
00108 nassertv(_gref.empty());
00109 nassertv(_pref.empty());
00110 }
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120 class GroupRefEntry {
00121 public:
00122 GroupRefEntry(EggGroup *group, double membership)
00123 : _group(group), _membership(membership) { }
00124
00125 bool operator < (const GroupRefEntry &other) const {
00126 return _group->get_name() < other._group->get_name();
00127 }
00128 void output(ostream &out) const {
00129 out << _group->get_name() << ":" << _membership;
00130 }
00131
00132 EggGroup *_group;
00133 double _membership;
00134 };
00135
00136 INLINE ostream &operator << (ostream &out, const GroupRefEntry &gre) {
00137 gre.output(out);
00138 return out;
00139 }
00140
00141
00142
00143
00144
00145
00146
00147 void EggVertex::
00148 write(ostream &out, int indent_level) const {
00149 test_pref_integrity();
00150 test_gref_integrity();
00151
00152 indent(out, indent_level)
00153 << "<Vertex> " << _index << " {\n";
00154
00155
00156
00157 indent(out, indent_level+1);
00158 for (int i = 0; i < _num_dimensions; i++) {
00159 out << " " << _pos[i];
00160 }
00161 out << "\n";
00162
00163 EggAttributes::write(out, indent_level+2);
00164
00165 _dxyzs.write(out, indent_level+2);
00166
00167
00168
00169 if (!_gref.empty()) {
00170
00171 pset<GroupRefEntry> gre;
00172
00173 GroupRef::const_iterator gi;
00174 for (gi = _gref.begin(); gi != _gref.end(); ++gi) {
00175 gre.insert(GroupRefEntry(*gi, (*gi)->get_vertex_membership(this)));
00176 }
00177
00178
00179 write_long_list(out, indent_level + 2, gre.begin(), gre.end(), "// ",
00180 "", 72);
00181 }
00182
00183 indent(out, indent_level)
00184 << "}\n";
00185 }
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209 bool EggVertex::
00210 sorts_less_than(const EggVertex &other) const {
00211 if (_external_index != other._external_index) {
00212 return _external_index < other._external_index;
00213 }
00214 if (_num_dimensions != other._num_dimensions) {
00215 return _num_dimensions < other._num_dimensions;
00216 }
00217
00218 int compare =
00219 _pos.compare_to(other._pos, egg_parameters->_pos_threshold);
00220 if (compare != 0) {
00221 return compare < 0;
00222 }
00223 if (_dxyzs != other._dxyzs) {
00224 return _dxyzs < other._dxyzs;
00225 }
00226
00227 return EggAttributes::sorts_less_than(other);
00228 }
00229
00230
00231
00232
00233
00234
00235
00236
00237 int EggVertex::
00238 get_num_local_coord() const {
00239 test_pref_integrity();
00240
00241 PrimitiveRef::const_iterator pri;
00242
00243 int count = 0;
00244 for (pri = pref_begin(); pri != pref_end(); ++pri) {
00245 EggPrimitive *prim = *pri;
00246 count += (prim->is_local_coord() ? 1 : 0);
00247 }
00248 return count;
00249 }
00250
00251
00252
00253
00254
00255
00256
00257
00258 int EggVertex::
00259 get_num_global_coord() const {
00260 test_pref_integrity();
00261
00262 PrimitiveRef::const_iterator pri;
00263
00264 int count = 0;
00265 for (pri = pref_begin(); pri != pref_end(); ++pri) {
00266 EggPrimitive *prim = *pri;
00267 count += (prim->is_local_coord() ? 0 : 1);
00268 }
00269 return count;
00270 }
00271
00272
00273
00274
00275
00276
00277
00278
00279 void EggVertex::
00280 transform(const LMatrix4d &mat) {
00281 _pos = _pos * mat;
00282
00283 EggMorphVertexList::iterator mi;
00284 for (mi = _dxyzs.begin(); mi != _dxyzs.end(); ++mi) {
00285
00286
00287
00288 EggMorphVertex &morph = (EggMorphVertex &)(*mi);
00289
00290 morph.set_offset((*mi).get_offset() * mat);
00291 }
00292
00293 EggAttributes::transform(mat);
00294 }
00295
00296
00297
00298
00299
00300
00301
00302
00303 bool EggVertex::
00304 has_gref(const EggGroup *group) const {
00305 return _gref.count((EggGroup *)group) != 0;
00306 }
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321 void EggVertex::
00322 copy_grefs_from(const EggVertex &other) {
00323 if (&other == this) {
00324 return;
00325 }
00326 test_gref_integrity();
00327 other.test_gref_integrity();
00328
00329 clear_grefs();
00330 test_gref_integrity();
00331
00332 GroupRef::const_iterator gri;
00333
00334 for (gri = other.gref_begin(); gri != other.gref_end(); ++gri) {
00335 EggGroup *group = *gri;
00336 nassertv(group != NULL);
00337
00338 group->ref_vertex(this, group->get_vertex_membership(&other));
00339 }
00340 }
00341
00342
00343
00344
00345
00346
00347
00348 void EggVertex::
00349 clear_grefs() {
00350 GroupRef gref_copy = _gref;
00351 GroupRef::const_iterator gri;
00352 for (gri = gref_copy.begin(); gri != gref_copy.end(); ++gri) {
00353 EggGroup *group = *gri;
00354 nassertv(group != NULL);
00355 group->unref_vertex(this);
00356 }
00357
00358
00359 nassertv(_gref.empty());
00360 }
00361
00362
00363
00364
00365
00366
00367
00368 int EggVertex::
00369 has_pref(const EggPrimitive *prim) const {
00370 return _pref.count((EggPrimitive *)prim);
00371 }
00372
00373 #ifndef NDEBUG
00374
00375
00376
00377
00378
00379
00380
00381
00382 void EggVertex::
00383 test_gref_integrity() const {
00384 test_ref_count_integrity();
00385
00386 GroupRef::const_iterator gri;
00387
00388 for (gri = gref_begin(); gri != gref_end(); ++gri) {
00389 EggGroup *group = *gri;
00390 nassertv(group != NULL);
00391 group->test_ref_count_integrity();
00392
00393 double membership = group->get_vertex_membership(this);
00394 nassertv(membership != 0.0);
00395 }
00396 }
00397
00398
00399
00400
00401
00402
00403
00404
00405 void EggVertex::
00406 test_pref_integrity() const {
00407 test_ref_count_integrity();
00408
00409 PrimitiveRef::const_iterator pri;
00410
00411 for (pri = pref_begin(); pri != pref_end(); ++pri) {
00412 EggPrimitive *prim = *pri;
00413 nassertv(prim != NULL);
00414 prim->test_ref_count_integrity();
00415
00416 EggPrimitive::iterator vi;
00417 vi = find(prim->begin(), prim->end(), this);
00418 nassertv(vi != prim->end());
00419 }
00420 }
00421
00422 #endif // NDEBUG
00423
00424
00425
00426
00427
00428
00429 void EggVertex::
00430 output(ostream &out) const {
00431 if (get_pool() == NULL) {
00432 out << "(null):" << get_index();
00433 } else {
00434 out << get_pool()->get_name() << ":" << get_index();
00435 }
00436 }