00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "xFileMesh.h"
00016 #include "xFileFace.h"
00017 #include "xFileVertex.h"
00018 #include "xFileNormal.h"
00019 #include "xFileMaterial.h"
00020 #include "xFileDataNode.h"
00021 #include "config_xfile.h"
00022 #include "string_utils.h"
00023 #include "eggVertexPool.h"
00024 #include "eggVertex.h"
00025 #include "eggPolygon.h"
00026 #include "eggGroupNode.h"
00027
00028
00029
00030
00031
00032
00033 XFileMesh::
00034 XFileMesh(CoordinateSystem cs) : _cs(cs) {
00035 _has_normals = false;
00036 _has_colors = false;
00037 _has_uvs = false;
00038 _has_materials = false;
00039 _egg_parent = NULL;
00040 }
00041
00042
00043
00044
00045
00046
00047 XFileMesh::
00048 ~XFileMesh() {
00049 clear();
00050 }
00051
00052
00053
00054
00055
00056
00057 void XFileMesh::
00058 clear() {
00059 Vertices::iterator vi;
00060 for (vi = _vertices.begin(); vi != _vertices.end(); ++vi) {
00061 XFileVertex *vertex = (*vi);
00062 delete vertex;
00063 }
00064 Normals::iterator ni;
00065 for (ni = _normals.begin(); ni != _normals.end(); ++ni) {
00066 XFileNormal *normal = (*ni);
00067 delete normal;
00068 }
00069 Materials::iterator mi;
00070 for (mi = _materials.begin(); mi != _materials.end(); ++mi) {
00071 XFileMaterial *material = (*mi);
00072 delete material;
00073 }
00074 Faces::iterator fi;
00075 for (fi = _faces.begin(); fi != _faces.end(); ++fi) {
00076 XFileFace *face = (*fi);
00077 delete face;
00078 }
00079
00080 _vertices.clear();
00081 _normals.clear();
00082 _materials.clear();
00083 _faces.clear();
00084
00085 _unique_vertices.clear();
00086 _unique_normals.clear();
00087 _unique_materials.clear();
00088
00089 _has_normals = false;
00090 _has_colors = false;
00091 _has_uvs = false;
00092 _has_materials = false;
00093 }
00094
00095
00096
00097
00098
00099
00100 void XFileMesh::
00101 add_polygon(EggPolygon *egg_poly) {
00102 XFileFace *face = new XFileFace;
00103 face->set_from_egg(this, egg_poly);
00104 _faces.push_back(face);
00105 }
00106
00107
00108
00109
00110
00111
00112
00113
00114 int XFileMesh::
00115 add_vertex(EggVertex *egg_vertex, EggPrimitive *egg_prim) {
00116 int next_index = _vertices.size();
00117 XFileVertex *vertex = new XFileVertex;
00118 vertex->set_from_egg(egg_vertex, egg_prim);
00119 if (vertex->_has_color) {
00120 _has_colors = true;
00121 }
00122 if (vertex->_has_uv) {
00123 _has_uvs = true;
00124 }
00125
00126 pair<UniqueVertices::iterator, bool> result =
00127 _unique_vertices.insert(UniqueVertices::value_type(vertex, next_index));
00128
00129 if (result.second) {
00130
00131 _vertices.push_back(vertex);
00132 return next_index;
00133 } else {
00134
00135
00136 delete vertex;
00137 return (*result.first).second;
00138 }
00139 }
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149 int XFileMesh::
00150 add_normal(EggVertex *egg_vertex, EggPrimitive *egg_prim) {
00151 int next_index = _normals.size();
00152 XFileNormal *normal = new XFileNormal;
00153 normal->set_from_egg(egg_vertex, egg_prim);
00154 if (normal->_has_normal) {
00155 _has_normals = true;
00156 }
00157
00158 pair<UniqueNormals::iterator, bool> result =
00159 _unique_normals.insert(UniqueNormals::value_type(normal, next_index));
00160
00161 if (result.second) {
00162
00163 _normals.push_back(normal);
00164 return next_index;
00165 } else {
00166
00167
00168 delete normal;
00169 return (*result.first).second;
00170 }
00171 }
00172
00173
00174
00175
00176
00177
00178
00179
00180 int XFileMesh::
00181 add_material(EggPrimitive *egg_prim) {
00182 int next_index = _materials.size();
00183 XFileMaterial *material = new XFileMaterial;
00184 material->set_from_egg(egg_prim);
00185 if (material->has_material()) {
00186 _has_materials = true;
00187 }
00188
00189 pair<UniqueMaterials::iterator, bool> result =
00190 _unique_materials.insert(UniqueMaterials::value_type(material, next_index));
00191
00192 if (result.second) {
00193
00194 _materials.push_back(material);
00195 return next_index;
00196 } else {
00197
00198
00199 delete material;
00200 return (*result.first).second;
00201 }
00202 }
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213 int XFileMesh::
00214 add_vertex(XFileVertex *vertex) {
00215 int next_index = _vertices.size();
00216 _unique_vertices.insert(UniqueVertices::value_type(vertex, next_index));
00217 _vertices.push_back(vertex);
00218 return next_index;
00219 }
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229 int XFileMesh::
00230 add_normal(XFileNormal *normal) {
00231 int next_index = _normals.size();
00232 _unique_normals.insert(UniqueNormals::value_type(normal, next_index));
00233 _normals.push_back(normal);
00234 return next_index;
00235 }
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245 int XFileMesh::
00246 add_material(XFileMaterial *material) {
00247 int next_index = _materials.size();
00248 _unique_materials.insert(UniqueMaterials::value_type(material, next_index));
00249 _materials.push_back(material);
00250 return next_index;
00251 }
00252
00253
00254
00255
00256
00257
00258
00259
00260 void XFileMesh::
00261 set_egg_parent(EggGroupNode *egg_parent) {
00262
00263 EggGroup *egg_group = new EggGroup(get_name());
00264 egg_parent->add_child(egg_group);
00265
00266 _egg_parent = egg_group;
00267 }
00268
00269
00270
00271
00272
00273
00274
00275
00276 bool XFileMesh::
00277 create_polygons(XFileToEggConverter *converter) {
00278 nassertr(_egg_parent != (EggGroupNode *)NULL, false);
00279
00280 EggVertexPool *vpool = new EggVertexPool(get_name());
00281 _egg_parent->add_child(vpool);
00282 Faces::const_iterator fi;
00283 for (fi = _faces.begin(); fi != _faces.end(); ++fi) {
00284 XFileFace *face = (*fi);
00285
00286 EggPolygon *egg_poly = new EggPolygon;
00287 _egg_parent->add_child(egg_poly);
00288
00289
00290 XFileFace::Vertices::reverse_iterator vi;
00291 for (vi = face->_vertices.rbegin(); vi != face->_vertices.rend(); ++vi) {
00292 int vertex_index = (*vi)._vertex_index;
00293 int normal_index = (*vi)._normal_index;
00294 if (vertex_index < 0 || vertex_index >= (int)_vertices.size()) {
00295 xfile_cat.warning()
00296 << "Vertex index out of range in Mesh " << get_name() << "\n";
00297 continue;
00298 }
00299 XFileVertex *vertex = _vertices[vertex_index];
00300 XFileNormal *normal = (XFileNormal *)NULL;
00301
00302 if (normal_index >= 0 && normal_index < (int)_normals.size()) {
00303 normal = _normals[normal_index];
00304 }
00305
00306
00307 EggVertex temp_vtx;
00308 temp_vtx.set_external_index(vertex_index);
00309 temp_vtx.set_pos(vertex->_point);
00310 if (vertex->_has_color) {
00311 temp_vtx.set_color(vertex->_color);
00312 }
00313 if (vertex->_has_uv) {
00314 LTexCoordd uv = vertex->_uv;
00315
00316 uv[1] = 1.0 - uv[1];
00317 temp_vtx.set_uv(uv);
00318 }
00319
00320 if (normal != (XFileNormal *)NULL && normal->_has_normal) {
00321 temp_vtx.set_normal(normal->_normal);
00322 }
00323
00324
00325
00326
00327
00328 double net_weight = 0.0;
00329 LMatrix4d weighted_transform(0.0, 0.0, 0.0, 0.0,
00330 0.0, 0.0, 0.0, 0.0,
00331 0.0, 0.0, 0.0, 0.0,
00332 0.0, 0.0, 0.0, 0.0);
00333 SkinWeights::const_iterator swi;
00334 for (swi = _skin_weights.begin(); swi != _skin_weights.end(); ++swi) {
00335 const SkinWeightsData &data = (*swi);
00336 WeightMap::const_iterator wmi = data._weight_map.find(vertex_index);
00337 if (wmi != data._weight_map.end()) {
00338 EggGroup *joint = converter->find_joint(data._joint_name);
00339 if (joint != (EggGroup *)NULL) {
00340 double weight = (*wmi).second;
00341 LMatrix4d mat = data._matrix_offset;
00342 mat *= joint->get_node_to_vertex();
00343 weighted_transform += mat * weight;
00344 net_weight += weight;
00345 }
00346 }
00347 }
00348
00349 if (net_weight == 0.0) {
00350
00351
00352 temp_vtx.transform(_egg_parent->get_node_to_vertex());
00353
00354 } else {
00355
00356
00357
00358 weighted_transform /= net_weight;
00359 temp_vtx.transform(weighted_transform);
00360 }
00361
00362
00363 EggVertex *egg_vtx = vpool->create_unique_vertex(temp_vtx);
00364 egg_poly->add_vertex(egg_vtx);
00365 }
00366
00367
00368 int material_index = face->_material_index;
00369 if (material_index >= 0 && material_index < (int)_materials.size()) {
00370 XFileMaterial *material = _materials[material_index];
00371 material->apply_to_egg(egg_poly, converter);
00372 }
00373 }
00374
00375
00376 EggVertexPool::iterator vi;
00377 for (vi = vpool->begin(); vi != vpool->end(); ++vi) {
00378 EggVertex *egg_vtx = (*vi);
00379 int vertex_index = egg_vtx->get_external_index();
00380
00381 SkinWeights::const_iterator swi;
00382 for (swi = _skin_weights.begin(); swi != _skin_weights.end(); ++swi) {
00383 const SkinWeightsData &data = (*swi);
00384 WeightMap::const_iterator wmi = data._weight_map.find(vertex_index);
00385 if (wmi != data._weight_map.end()) {
00386 EggGroup *joint = converter->find_joint(data._joint_name);
00387 if (joint != (EggGroup *)NULL) {
00388 double weight = (*wmi).second;
00389 joint->ref_vertex(egg_vtx, weight);
00390 }
00391 }
00392 }
00393 }
00394
00395 if (!has_normals()) {
00396
00397
00398
00399 _egg_parent->recompute_vertex_normals(180.0, _cs);
00400 }
00401
00402 return true;
00403 }
00404
00405
00406
00407
00408
00409
00410
00411 bool XFileMesh::
00412 has_normals() const {
00413 return _has_normals;
00414 }
00415
00416
00417
00418
00419
00420
00421
00422 bool XFileMesh::
00423 has_colors() const {
00424 return _has_colors;
00425 }
00426
00427
00428
00429
00430
00431
00432
00433 bool XFileMesh::
00434 has_uvs() const {
00435 return _has_uvs;
00436 }
00437
00438
00439
00440
00441
00442
00443
00444 bool XFileMesh::
00445 has_materials() const {
00446 return _has_materials;
00447 }
00448
00449
00450
00451
00452
00453
00454
00455 int XFileMesh::
00456 get_num_materials() const {
00457 return _materials.size();
00458 }
00459
00460
00461
00462
00463
00464
00465
00466 XFileMaterial *XFileMesh::
00467 get_material(int n) const {
00468 nassertr(n >= 0 && n < (int)_materials.size(), (XFileMaterial *)NULL);
00469 return _materials[n];
00470 }
00471
00472
00473
00474
00475
00476
00477 XFileDataNode *XFileMesh::
00478 make_x_mesh(XFileNode *x_parent, const string &suffix) {
00479 XFileDataNode *x_mesh = x_parent->add_Mesh("mesh" + suffix);
00480
00481
00482 XFileDataObject &x_vertices = (*x_mesh)["vertices"];
00483
00484 Vertices::const_iterator vi;
00485 for (vi = _vertices.begin(); vi != _vertices.end(); ++vi) {
00486 XFileVertex *vertex = (*vi);
00487 x_vertices.add_Vector(x_mesh->get_x_file(), vertex->_point);
00488 }
00489 (*x_mesh)["nVertices"] = x_vertices.size();
00490
00491
00492 XFileDataObject &x_faces = (*x_mesh)["faces"];
00493 Faces::const_iterator fi;
00494 for (fi = _faces.begin(); fi != _faces.end(); ++fi) {
00495 XFileFace *face = (*fi);
00496
00497 XFileDataObject &x_mesh_face = x_faces.add_MeshFace(x_mesh->get_x_file());
00498 XFileDataObject &x_faceVertexIndices = x_mesh_face["faceVertexIndices"];
00499 XFileFace::Vertices::const_iterator fvi;
00500 for (fvi = face->_vertices.begin();
00501 fvi != face->_vertices.end();
00502 ++fvi) {
00503 x_faceVertexIndices.add_int((*fvi)._vertex_index);
00504 }
00505 x_mesh_face["nFaceVertexIndices"] = x_faceVertexIndices.size();
00506 }
00507 (*x_mesh)["nFaces"] = x_faces.size();
00508
00509
00510
00511 if (has_normals()) {
00512
00513 make_x_normals(x_mesh, suffix);
00514 }
00515 if (has_colors()) {
00516
00517 make_x_colors(x_mesh, suffix);
00518 }
00519 if (has_uvs()) {
00520
00521 make_x_uvs(x_mesh, suffix);
00522 }
00523 if (has_materials()) {
00524
00525 make_x_material_list(x_mesh, suffix);
00526 }
00527
00528 return x_mesh;
00529 }
00530
00531
00532
00533
00534
00535
00536 XFileDataNode *XFileMesh::
00537 make_x_normals(XFileNode *x_mesh, const string &suffix) {
00538 XFileDataNode *x_meshNormals = x_mesh->add_MeshNormals("norms" + suffix);
00539
00540 XFileDataObject &x_normals = (*x_meshNormals)["normals"];
00541
00542 Normals::const_iterator ni;
00543 for (ni = _normals.begin(); ni != _normals.end(); ++ni) {
00544 XFileNormal *normal = (*ni);
00545 x_normals.add_Vector(x_mesh->get_x_file(), normal->_normal);
00546 }
00547 (*x_meshNormals)["nNormals"] = x_normals.size();
00548
00549
00550 XFileDataObject &x_faces = (*x_meshNormals)["faceNormals"];
00551 Faces::const_iterator fi;
00552 for (fi = _faces.begin(); fi != _faces.end(); ++fi) {
00553 XFileFace *face = (*fi);
00554
00555 XFileDataObject &x_normals_face = x_faces.add_MeshFace(x_mesh->get_x_file());
00556 XFileDataObject &x_faceVertexIndices = x_normals_face["faceVertexIndices"];
00557 XFileFace::Vertices::const_iterator fvi;
00558 for (fvi = face->_vertices.begin();
00559 fvi != face->_vertices.end();
00560 ++fvi) {
00561 x_faceVertexIndices.add_int((*fvi)._normal_index);
00562 }
00563 x_normals_face["nFaceVertexIndices"] = x_faceVertexIndices.size();
00564 }
00565 (*x_meshNormals)["nFaceNormals"] = x_faces.size();
00566
00567 return x_meshNormals;
00568 }
00569
00570
00571
00572
00573
00574
00575 XFileDataNode *XFileMesh::
00576 make_x_colors(XFileNode *x_mesh, const string &suffix) {
00577 XFileDataNode *x_meshColors = x_mesh->add_MeshVertexColors("colors" + suffix);
00578
00579 XFileDataObject &x_colors = (*x_meshColors)["vertexColors"];
00580
00581 Vertices::const_iterator vi;
00582 int i = 0;
00583 for (vi = _vertices.begin(); vi != _vertices.end(); ++vi) {
00584 XFileVertex *vertex = (*vi);
00585 const LColor &color = vertex->_color;
00586 x_colors.add_IndexedColor(x_mesh->get_x_file(), i, color);
00587 i++;
00588 }
00589
00590 (*x_meshColors)["nVertexColors"] = x_colors.size();
00591
00592 return x_meshColors;
00593 }
00594
00595
00596
00597
00598
00599
00600 XFileDataNode *XFileMesh::
00601 make_x_uvs(XFileNode *x_mesh, const string &suffix) {
00602 XFileDataNode *x_meshUvs = x_mesh->add_MeshTextureCoords("uvs" + suffix);
00603
00604 XFileDataObject &x_uvs = (*x_meshUvs)["textureCoords"];
00605
00606 Vertices::const_iterator vi;
00607 for (vi = _vertices.begin(); vi != _vertices.end(); ++vi) {
00608 XFileVertex *vertex = (*vi);
00609 x_uvs.add_Coords2d(x_mesh->get_x_file(), vertex->_uv);
00610 }
00611
00612 (*x_meshUvs)["nTextureCoords"] = x_uvs.size();
00613
00614 return x_meshUvs;
00615 }
00616
00617
00618
00619
00620
00621
00622 XFileDataNode *XFileMesh::
00623 make_x_material_list(XFileNode *x_mesh, const string &suffix) {
00624 XFileDataNode *x_meshMaterials =
00625 x_mesh->add_MeshMaterialList("materials" + suffix);
00626
00627
00628 XFileDataObject &x_indexes = (*x_meshMaterials)["faceIndexes"];
00629
00630 Faces::const_iterator fi;
00631 for (fi = _faces.begin(); fi != _faces.end(); ++fi) {
00632 XFileFace *face = (*fi);
00633 x_indexes.add_int(face->_material_index);
00634 }
00635
00636 (*x_meshMaterials)["nFaceIndexes"] = x_indexes.size();
00637
00638
00639
00640
00641 for (size_t i = 0; i < _materials.size(); i++) {
00642 XFileMaterial *material = _materials[i];
00643
00644 material->make_x_material(x_meshMaterials,
00645 suffix + "_" + format_string(i));
00646 }
00647
00648 (*x_meshMaterials)["nMaterials"] = (int)_materials.size();
00649
00650 return x_meshMaterials;
00651 }
00652
00653
00654
00655
00656
00657
00658
00659 bool XFileMesh::
00660 fill_mesh(XFileDataNode *obj) {
00661 clear();
00662
00663 int i, j;
00664
00665 const XFileDataObject &vertices = (*obj)["vertices"];
00666 for (i = 0; i < vertices.size(); i++) {
00667 XFileVertex *vertex = new XFileVertex;
00668 vertex->_point = vertices[i].vec3();
00669 add_vertex(vertex);
00670 }
00671
00672 const XFileDataObject &faces = (*obj)["faces"];
00673 for (i = 0; i < faces.size(); i++) {
00674 XFileFace *face = new XFileFace;
00675
00676 const XFileDataObject &faceIndices = faces[i]["faceVertexIndices"];
00677
00678 for (j = 0; j < faceIndices.size(); j++) {
00679 XFileFace::Vertex vertex;
00680 vertex._vertex_index = faceIndices[j].i();
00681 vertex._normal_index = -1;
00682
00683 face->_vertices.push_back(vertex);
00684 }
00685 _faces.push_back(face);
00686 }
00687
00688
00689 int num_objects = obj->get_num_objects();
00690 for (i = 0; i < num_objects; i++) {
00691 if (!fill_mesh_child(obj->get_object(i))) {
00692 return false;
00693 }
00694 }
00695
00696 return true;
00697 }
00698
00699
00700
00701
00702
00703
00704
00705 bool XFileMesh::
00706 fill_mesh_child(XFileDataNode *obj) {
00707 if (obj->is_standard_object("MeshNormals")) {
00708 if (!fill_normals(obj)) {
00709 return false;
00710 }
00711
00712 } else if (obj->is_standard_object("MeshVertexColors")) {
00713 if (!fill_colors(obj)) {
00714 return false;
00715 }
00716
00717 } else if (obj->is_standard_object("MeshTextureCoords")) {
00718 if (!fill_uvs(obj)) {
00719 return false;
00720 }
00721
00722 } else if (obj->is_standard_object("MeshMaterialList")) {
00723 if (!fill_material_list(obj)) {
00724 return false;
00725 }
00726
00727 } else if (obj->is_standard_object("XSkinMeshHeader")) {
00728
00729
00730 } else if (obj->is_standard_object("SkinWeights")) {
00731 if (!fill_skin_weights(obj)) {
00732 return false;
00733 }
00734
00735 } else {
00736 if (xfile_cat.is_debug()) {
00737 xfile_cat.debug()
00738 << "Ignoring mesh data object of unknown type: "
00739 << obj->get_template_name() << "\n";
00740 }
00741 }
00742
00743 return true;
00744 }
00745
00746
00747
00748
00749
00750
00751
00752 bool XFileMesh::
00753 fill_normals(XFileDataNode *obj) {
00754 int i, j;
00755
00756 const XFileDataObject &normals = (*obj)["normals"];
00757 for (i = 0; i < normals.size(); i++) {
00758 XFileNormal *normal = new XFileNormal;
00759 normal->_normal = normals[i].vec3();
00760 normal->_has_normal = true;
00761 add_normal(normal);
00762 }
00763
00764 const XFileDataObject &faceNormals = (*obj)["faceNormals"];
00765 if (faceNormals.size() != (int)_faces.size()) {
00766 xfile_cat.warning()
00767 << "Incorrect number of faces in MeshNormals within "
00768 << get_name() << "\n";
00769 }
00770
00771 int num_normals = min(faceNormals.size(), (int)_faces.size());
00772 for (i = 0; i < num_normals; i++) {
00773 XFileFace *face = _faces[i];
00774
00775 const XFileDataObject &faceIndices = faceNormals[i]["faceVertexIndices"];
00776
00777 if (faceIndices.size() != (int)face->_vertices.size()) {
00778 xfile_cat.warning()
00779 << "Incorrect number of vertices for face in MeshNormals within "
00780 << get_name() << "\n";
00781 }
00782
00783 int num_vertices = min(faceIndices.size(), (int)face->_vertices.size());
00784 for (j = 0; j < num_vertices; j++) {
00785 face->_vertices[j]._normal_index = faceIndices[j].i();
00786 }
00787 }
00788
00789 return true;
00790 }
00791
00792
00793
00794
00795
00796
00797
00798 bool XFileMesh::
00799 fill_colors(XFileDataNode *obj) {
00800 const XFileDataObject &vertexColors = (*obj)["vertexColors"];
00801 for (int i = 0; i < vertexColors.size(); i++) {
00802 int vertex_index = vertexColors[i]["index"].i();
00803 if (vertex_index < 0 || vertex_index >= (int)_vertices.size()) {
00804 xfile_cat.warning()
00805 << "Vertex index out of range in MeshVertexColors within "
00806 << get_name() << "\n";
00807 continue;
00808 }
00809
00810 XFileVertex *vertex = _vertices[vertex_index];
00811 vertex->_color = LCAST(PN_stdfloat, vertexColors[i]["indexColor"].vec4());
00812 vertex->_has_color = true;
00813 }
00814
00815 return true;
00816 }
00817
00818
00819
00820
00821
00822
00823
00824 bool XFileMesh::
00825 fill_uvs(XFileDataNode *obj) {
00826 const XFileDataObject &textureCoords = (*obj)["textureCoords"];
00827 if (textureCoords.size() != (int)_vertices.size()) {
00828 xfile_cat.warning()
00829 << "Wrong number of vertices in MeshTextureCoords within "
00830 << get_name() << "\n";
00831 }
00832
00833 int num_texcoords = min(textureCoords.size(), (int)_vertices.size());
00834 for (int i = 0; i < num_texcoords; i++) {
00835 XFileVertex *vertex = _vertices[i];
00836 vertex->_uv = textureCoords[i].vec2();
00837 vertex->_has_uv = true;
00838 }
00839
00840 return true;
00841 }
00842
00843
00844
00845
00846
00847
00848
00849 bool XFileMesh::
00850 fill_skin_weights(XFileDataNode *obj) {
00851
00852
00853 _skin_weights.push_back(SkinWeightsData());
00854 SkinWeightsData &data = _skin_weights.back();
00855
00856 data._joint_name = (*obj)["transformNodeName"].s();
00857
00858 const XFileDataObject &vertexIndices = (*obj)["vertexIndices"];
00859 const XFileDataObject &weights = (*obj)["weights"];
00860
00861 if (weights.size() != vertexIndices.size()) {
00862 xfile_cat.warning()
00863 << "Inconsistent number of vertices in SkinWeights within " << get_name() << "\n";
00864 }
00865
00866
00867 size_t num_weights = min(weights.size(), vertexIndices.size());
00868 for (size_t i = 0; i < num_weights; i++) {
00869 int vindex = vertexIndices[i].i();
00870 double weight = weights[i].d();
00871
00872 if (vindex < 0 || vindex > (int)_vertices.size()) {
00873 xfile_cat.warning()
00874 << "Illegal vertex index " << vindex << " in SkinWeights.\n";
00875 continue;
00876 }
00877 data._weight_map[vindex] = weight;
00878 }
00879
00880
00881 data._matrix_offset = (*obj)["matrixOffset"]["matrix"].mat4();
00882
00883 return true;
00884 }
00885
00886
00887
00888
00889
00890
00891
00892 bool XFileMesh::
00893 fill_material_list(XFileDataNode *obj) {
00894 const XFileDataObject &faceIndexes = (*obj)["faceIndexes"];
00895 if (faceIndexes.size() > (int)_faces.size()) {
00896 xfile_cat.warning()
00897 << "Too many faces in MeshMaterialList within " << get_name() << "\n";
00898 }
00899
00900 int material_index = -1;
00901 int i = 0;
00902 while (i < faceIndexes.size() && i < (int)_faces.size()) {
00903 XFileFace *face = _faces[i];
00904 material_index = faceIndexes[i].i();
00905 face->_material_index = material_index;
00906 i++;
00907 }
00908
00909
00910
00911 while (i < (int)_faces.size()) {
00912 XFileFace *face = _faces[i];
00913 face->_material_index = material_index;
00914 i++;
00915 }
00916
00917
00918
00919 int num_objects = obj->get_num_objects();
00920 for (i = 0; i < num_objects; i++) {
00921 XFileDataNode *child = obj->get_object(i);
00922 if (child->is_standard_object("Material")) {
00923 XFileMaterial *material = new XFileMaterial;
00924 if (!material->fill_material(child)) {
00925 delete material;
00926 return false;
00927 }
00928 add_material(material);
00929
00930 } else {
00931 if (xfile_cat.is_debug()) {
00932 xfile_cat.debug()
00933 << "Ignoring material list object of unknown type: "
00934 << child->get_template_name() << "\n";
00935 }
00936 }
00937 }
00938
00939 return true;
00940 }