00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "indexedFaceSet.h"
00014 #include "vrmlAppearance.h"
00015 #include "vrmlNodeType.h"
00016 #include "vrmlNode.h"
00017 #include "pnotify.h"
00018
00019 #include "eggGroup.h"
00020 #include "eggVertex.h"
00021 #include "eggVertexPool.h"
00022 #include "eggPolygon.h"
00023
00024
00025
00026
00027
00028
00029 IndexedFaceSet::
00030 IndexedFaceSet(const VrmlNode *geometry, const VRMLAppearance &appearance) :
00031 _geometry(geometry), _appearance(appearance)
00032 {
00033 get_coord_values();
00034 get_polys();
00035 get_colors();
00036 _has_normals = get_normals();
00037 if (!_per_vertex_normals.empty()) {
00038 assign_per_vertex_normals();
00039 }
00040 get_uvs();
00041 if (!_per_vertex_uvs.empty()) {
00042 assign_per_vertex_uvs();
00043 }
00044 }
00045
00046
00047
00048
00049
00050
00051
00052 void IndexedFaceSet::
00053 convert_to_egg(EggGroup *group, const LMatrix4d &net_transform) {
00054 EggVertexPool *vpool = new EggVertexPool(group->get_name());
00055 group->add_child(vpool);
00056
00057 make_polys(vpool, group, net_transform);
00058 if (!_has_normals && _appearance._has_material) {
00059 compute_normals(group);
00060 }
00061 }
00062
00063
00064
00065
00066
00067
00068
00069 void IndexedFaceSet::
00070 get_coord_values() {
00071 const VrmlNode *coord = _geometry->get_value("coord")._sfnode._p;
00072
00073 if (coord != NULL) {
00074 const MFArray *point = coord->get_value("point")._mf;
00075 MFArray::const_iterator ci;
00076 for (ci = point->begin(); ci != point->end(); ++ci) {
00077 const double *p = (*ci)._sfvec;
00078 _coord_values.push_back(LVertexd(p[0], p[1], p[2]));
00079 }
00080 }
00081 }
00082
00083
00084
00085
00086
00087
00088
00089 void IndexedFaceSet::
00090 get_polys() {
00091 const MFArray *coordIndex = _geometry->get_value("coordIndex")._mf;
00092 VrmlPolygon poly;
00093
00094 MFArray::const_iterator ci;
00095 for (ci = coordIndex->begin(); ci != coordIndex->end(); ++ci) {
00096 if ((*ci)._sfint32 < 0) {
00097 _polys.push_back(poly);
00098 poly._verts.clear();
00099 } else {
00100 const LVertexd &p = _coord_values[(*ci)._sfint32];
00101 VrmlVertex vert;
00102 vert._index = (*ci)._sfint32;
00103 vert._pos = p;
00104 poly._verts.push_back(vert);
00105 }
00106 }
00107 }
00108
00109
00110
00111
00112
00113
00114
00115 void IndexedFaceSet::
00116 get_vrml_colors(const VrmlNode *color_node, double transparency,
00117 pvector<UnalignedLVecBase4> &color_list) {
00118 const MFArray *color = color_node->get_value("color")._mf;
00119 MFArray::const_iterator ci;
00120 for (ci = color->begin(); ci != color->end(); ++ci) {
00121 const double *p = (*ci)._sfvec;
00122 LColor color(p[0], p[1], p[2], 1.0 - transparency);
00123 color_list.push_back(color);
00124 }
00125 }
00126
00127
00128
00129
00130
00131
00132
00133 void IndexedFaceSet::
00134 get_vrml_normals(const VrmlNode *normal_node,
00135 pvector<LNormald> &normal_list) {
00136 const MFArray *point = normal_node->get_value("vector")._mf;
00137 MFArray::const_iterator ci;
00138 for (ci = point->begin(); ci != point->end(); ++ci) {
00139 const double *p = (*ci)._sfvec;
00140 LNormald normal(p[0], p[1], p[2]);
00141 normal_list.push_back(normal);
00142 }
00143 }
00144
00145
00146
00147
00148
00149
00150
00151 void IndexedFaceSet::
00152 get_vrml_uvs(const VrmlNode *texCoord_node,
00153 pvector<LTexCoordd> &uv_list) {
00154 const MFArray *point = texCoord_node->get_value("point")._mf;
00155 MFArray::const_iterator ci;
00156 for (ci = point->begin(); ci != point->end(); ++ci) {
00157 const double *p = (*ci)._sfvec;
00158 LTexCoordd uv(p[0], p[1]);
00159 uv_list.push_back(uv);
00160 }
00161 }
00162
00163
00164
00165
00166
00167
00168
00169 bool IndexedFaceSet::
00170 get_colors() {
00171 const VrmlNode *color = _geometry->get_value("color")._sfnode._p;
00172 if (color != NULL) {
00173
00174 pvector<UnalignedLVecBase4> color_list;
00175 get_vrml_colors(color, _appearance._transparency, color_list);
00176
00177 bool colorPerVertex = _geometry->get_value("colorPerVertex")._sfbool;
00178 MFArray *colorIndex = _geometry->get_value("colorIndex")._mf;
00179 if (colorPerVertex) {
00180 MFArray::const_iterator ci;
00181 size_t pi = 0;
00182 size_t pv = 0;
00183 for (ci = colorIndex->begin(); ci != colorIndex->end(); ++ci) {
00184 if ((*ci)._sfint32 < 0) {
00185
00186 if (pv != _polys[pi]._verts.size()) {
00187 cerr << "Color indices don't match up!\n";
00188 return false;
00189 }
00190 pi++;
00191 pv = 0;
00192 } else {
00193 if (pi >= _polys.size() || pv >= _polys[pi]._verts.size()) {
00194 cerr << "Color indices don't match up!\n";
00195 return false;
00196 }
00197 _polys[pi]._verts[pv]._attrib.set_color(color_list[(*ci)._sfint32]);
00198 pv++;
00199 }
00200 }
00201 if (pi != _polys.size()) {
00202 cerr << "Not enough color indices!\n";
00203 return false;
00204 }
00205 } else {
00206 if (!colorIndex->empty()) {
00207 MFArray::const_iterator ci;
00208 size_t pi = 0;
00209 if (colorIndex->size() != _polys.size()) {
00210 cerr << "Wrong number of color indices!\n";
00211 return false;
00212 }
00213 for (ci = colorIndex->begin(); ci != colorIndex->end(); ++ci) {
00214 if ((*ci)._sfint32 < 0 || (*ci)._sfint32 >= (int)color_list.size()) {
00215 cerr << "Invalid color index!\n";
00216 return false;
00217 }
00218 _polys[pi]._attrib.set_color(color_list[(*ci)._sfint32]);
00219 pi++;
00220 }
00221 } else {
00222 if (color_list.size() != _polys.size()) {
00223 cerr << "Wrong number of colors!\n";
00224 return false;
00225 }
00226 for (size_t pi = 0; pi < color_list.size(); pi++) {
00227 _polys[pi]._attrib.set_color(color_list[pi]);
00228 }
00229 }
00230 }
00231 return true;
00232 }
00233 return false;
00234 }
00235
00236
00237
00238
00239
00240
00241 bool IndexedFaceSet::
00242 get_normals() {
00243 const VrmlNode *normal = _geometry->get_value("normal")._sfnode._p;
00244 if (normal != NULL) {
00245
00246 pvector<LNormald> normal_list;
00247 get_vrml_normals(normal, normal_list);
00248
00249 bool normalPerVertex = _geometry->get_value("normalPerVertex")._sfbool;
00250 MFArray *normalIndex = _geometry->get_value("normalIndex")._mf;
00251 MFArray::const_iterator ci;
00252
00253 if (normalPerVertex &&
00254 normal_list.size() == _polys.size() &&
00255 normalIndex->empty()) {
00256
00257
00258
00259
00260 normalPerVertex = false;
00261 }
00262
00263 if (normalPerVertex) {
00264
00265 if (normalIndex->empty()) {
00266
00267
00268
00269
00270 for (size_t i = 0; i < normal_list.size(); i++) {
00271 VrmlFieldValue fv;
00272 fv._sfint32 = i;
00273 (*normalIndex).push_back(fv);
00274 }
00275 }
00276
00277
00278
00279
00280
00281
00282 bool linear_list = (normalIndex->size() == _coord_values.size());
00283 for (ci = normalIndex->begin();
00284 ci != normalIndex->end() && linear_list;
00285 ++ci) {
00286 linear_list = ((*ci)._sfint32 >= 0);
00287 }
00288
00289 if (linear_list) {
00290
00291
00292
00293 _per_vertex_normals.reserve(_coord_values.size());
00294
00295 for (ci = normalIndex->begin(); ci != normalIndex->end(); ++ci) {
00296 size_t vi = (*ci)._sfint32;
00297 nassertr(vi >= 0, false);
00298 if (vi >= normal_list.size()) {
00299 cerr << "Invalid normal index: " << vi << "\n";
00300 return false;
00301 }
00302 _per_vertex_normals.push_back(normal_list[vi]);
00303 }
00304 nassertr(_per_vertex_normals.size() == _coord_values.size(), false);
00305
00306 } else {
00307
00308
00309
00310
00311
00312 MFArray::const_iterator ci;
00313 size_t pi = 0;
00314 size_t pv = 0;
00315 for (ci = normalIndex->begin(); ci != normalIndex->end(); ++ci) {
00316 if ((*ci)._sfint32 < 0) {
00317
00318 if (pv != _polys[pi]._verts.size()) {
00319 cerr << "Normal indices don't match up!\n";
00320 return false;
00321 }
00322 pi++;
00323 pv = 0;
00324 } else {
00325 if (pi >= _polys.size() || pv >= _polys[pi]._verts.size()) {
00326 cerr << "Normal indices don't match up!\n";
00327 return false;
00328 }
00329 const LNormald &d = normal_list[(*ci)._sfint32];
00330 _polys[pi]._verts[pv]._attrib.set_normal(d);
00331 pv++;
00332 }
00333 }
00334 if (pi != _polys.size()) {
00335 cerr << "Not enough normal indices!\n";
00336 return false;
00337 }
00338 }
00339 } else {
00340 if (!normalIndex->empty()) {
00341 size_t pi = 0;
00342 if (normalIndex->size() != _polys.size()) {
00343 cerr << "Wrong number of normal indices!\n";
00344 return false;
00345 }
00346 for (ci = normalIndex->begin(); ci != normalIndex->end(); ++ci) {
00347 if ((*ci)._sfint32 < 0 || (*ci)._sfint32 >= (int)normal_list.size()) {
00348 cerr << "Invalid normal index!\n";
00349 return false;
00350 }
00351 const LNormald &d = normal_list[(*ci)._sfint32];
00352 _polys[pi]._attrib.set_normal(d);
00353 pi++;
00354 }
00355 } else {
00356 if (normal_list.size() != _polys.size()) {
00357 cerr << "Wrong number of normals!\n";
00358 return false;
00359 }
00360 for (size_t pi = 0; pi < normal_list.size(); pi++) {
00361 const LNormald &d = normal_list[pi];
00362 _polys[pi]._attrib.set_normal(d);
00363 }
00364 }
00365 }
00366 return true;
00367 }
00368 return false;
00369 }
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380 void IndexedFaceSet::
00381 assign_per_vertex_normals() {
00382 for (size_t pi = 0; pi < _polys.size(); pi++) {
00383 for (size_t pv = 0; pv < _polys[pi]._verts.size(); pv++) {
00384 VrmlVertex &vv = _polys[pi]._verts[pv];
00385 if (vv._index >= 0 && vv._index < (int)_per_vertex_normals.size()) {
00386 const LNormald &d = _per_vertex_normals[vv._index];
00387 vv._attrib.set_normal(d);
00388 }
00389 }
00390 }
00391 }
00392
00393
00394
00395
00396
00397
00398
00399 bool IndexedFaceSet::
00400 get_uvs() {
00401 const VrmlNode *texCoord = _geometry->get_value("texCoord")._sfnode._p;
00402 if (texCoord != NULL) {
00403
00404 pvector<LTexCoordd> uv_list;
00405 get_vrml_uvs(texCoord, uv_list);
00406
00407 MFArray *texCoordIndex = _geometry->get_value("texCoordIndex")._mf;
00408 MFArray::const_iterator ci;
00409
00410 if (texCoordIndex->empty()) {
00411
00412
00413
00414
00415 for (size_t i = 0; i < uv_list.size(); i++) {
00416 VrmlFieldValue fv;
00417 fv._sfint32 = i;
00418 (*texCoordIndex).push_back(fv);
00419 }
00420 }
00421
00422
00423
00424
00425
00426
00427 bool linear_list = (texCoordIndex->size() == _coord_values.size());
00428 for (ci = texCoordIndex->begin();
00429 ci != texCoordIndex->end() && linear_list;
00430 ++ci) {
00431 linear_list = ((*ci)._sfint32 >= 0);
00432 }
00433
00434 if (linear_list) {
00435
00436
00437
00438 _per_vertex_uvs.reserve(_coord_values.size());
00439
00440 for (ci = texCoordIndex->begin(); ci != texCoordIndex->end(); ++ci) {
00441 size_t vi = (*ci)._sfint32;
00442 nassertr(vi >= 0, false);
00443 if (vi >= uv_list.size()) {
00444 cerr << "Invalid texCoord index: " << vi << "\n";
00445 return false;
00446 }
00447 _per_vertex_uvs.push_back(uv_list[vi]);
00448 }
00449 nassertr(_per_vertex_uvs.size() == _coord_values.size(), false);
00450
00451 } else {
00452
00453
00454
00455
00456
00457 size_t pi = 0;
00458 size_t pv = 0;
00459 for (ci = texCoordIndex->begin(); ci != texCoordIndex->end(); ++ci) {
00460 if ((*ci)._sfint32 < 0) {
00461
00462 if (pv != _polys[pi]._verts.size()) {
00463 cerr << "texCoord indices don't match up!\n";
00464 return false;
00465 }
00466 pi++;
00467 pv = 0;
00468 } else {
00469 if (pi >= _polys.size() || pv >= _polys[pi]._verts.size()) {
00470 cerr << "texCoord indices don't match up!\n";
00471 return false;
00472 }
00473 _polys[pi]._verts[pv]._attrib.set_uv(uv_list[(*ci)._sfint32]);
00474 pv++;
00475 }
00476 }
00477 if (pi != _polys.size()) {
00478 cerr << "Not enough texCoord indices!\n";
00479 return false;
00480 }
00481 }
00482 return true;
00483 }
00484 return false;
00485 }
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496 void IndexedFaceSet::
00497 assign_per_vertex_uvs() {
00498 for (size_t pi = 0; pi < _polys.size(); pi++) {
00499 for (size_t pv = 0; pv < _polys[pi]._verts.size(); pv++) {
00500 VrmlVertex &vv = _polys[pi]._verts[pv];
00501 if (vv._index >= 0 && vv._index < (int)_per_vertex_uvs.size()) {
00502 const LTexCoordd &d = _per_vertex_uvs[vv._index];
00503 vv._attrib.set_uv(d);
00504 }
00505 }
00506 }
00507 }
00508
00509
00510
00511
00512
00513
00514
00515 void IndexedFaceSet::
00516 make_polys(EggVertexPool *vpool, EggGroup *group,
00517 const LMatrix4d &net_transform) {
00518 bool ccw = _geometry->get_value("ccw")._sfbool;
00519 bool solid = _geometry->get_value("solid")._sfbool;
00520
00521 for (size_t pi = 0; pi < _polys.size(); pi++) {
00522 EggPolygon *poly = new EggPolygon;
00523 group->add_child(poly);
00524 poly->copy_attributes(_polys[pi]._attrib);
00525
00526 if (!poly->has_color() && _appearance._has_material) {
00527 poly->set_color(_appearance._color);
00528 }
00529
00530 if (_appearance._tex != (EggTexture *)NULL) {
00531 poly->set_texture(_appearance._tex);
00532 }
00533
00534 if (!solid) {
00535 poly->set_bface_flag(true);
00536 }
00537
00538 if (ccw) {
00539
00540 for (int pv = 0; pv < (int)_polys[pi]._verts.size(); pv++) {
00541 EggVertex vert(_polys[pi]._verts[pv]._attrib);
00542 LVertexd pos =
00543 _polys[pi]._verts[pv]._pos * net_transform;
00544 vert.set_pos(pos);
00545
00546 poly->add_vertex(vpool->create_unique_vertex(vert));
00547 }
00548 } else {
00549
00550 for (int pv = (int)_polys[pi]._verts.size() - 1; pv >= 0; pv--) {
00551 EggVertex vert(_polys[pi]._verts[pv]._attrib);
00552 LVertexd pos =
00553 _polys[pi]._verts[pv]._pos * net_transform;
00554 vert.set_pos(pos);
00555
00556 poly->add_vertex(vpool->create_unique_vertex(vert));
00557 }
00558 }
00559 }
00560 }
00561
00562
00563
00564
00565
00566
00567
00568 void IndexedFaceSet::
00569 compute_normals(EggGroup *group) {
00570 const VrmlNode *normal = _geometry->get_value("normal")._sfnode._p;
00571 if (normal == NULL) {
00572
00573 double creaseAngle = _geometry->get_value("creaseAngle")._sffloat;
00574 if (creaseAngle == 0.0) {
00575 group->recompute_polygon_normals();
00576 } else {
00577 group->recompute_vertex_normals(rad_2_deg(creaseAngle));
00578 }
00579 }
00580 }