Sure, here it is! /Anders
On 2/19/07, Robert Osfield <[EMAIL PROTECTED]> wrote:
HI Anders, Could you tweak the code to avoid this issue and submit it? Cheers, Robert. On 2/19/07, Anders Backman <[EMAIL PROTECTED]> wrote: > At line 247 there is what seems to be a bugin the DirectX loader > > First there is a check that a string is not empty: > > if (token.size() == 0) > continue; > > Then the second character is accessed, but in the previous check there is > nothing that claims this to be true. > > 247: Material * material = _obj->findMaterial(token[1]); > > > If this line (247) is changed to Material * material = > _obj->findMaterial(token[0]); > > instead it works just fine with the .x models I have (not that many though, > so its not a complete test). > Although, the code should slightly more robust. > > /Anders > > -- > > > ________________________________________________________________ > Anders Backman Email: [EMAIL PROTECTED] > HPC2N/VRlab Phone: +46 (0)90-786 9936 > Umea university Cellular: +46 (0)70-392 64 67 > S-901 87 UMEA SWEDEN Fax: +46 90-786 6126 > http://www.cs.umu.se/~andersb > _______________________________________________ > osg-users mailing list > osg-users@openscenegraph.net > http://openscenegraph.net/mailman/listinfo/osg-users > http://www.openscenegraph.org/ > _______________________________________________ osg-users mailing list osg-users@openscenegraph.net http://openscenegraph.net/mailman/listinfo/osg-users http://www.openscenegraph.org/
-- ________________________________________________________________ Anders Backman Email: [EMAIL PROTECTED] HPC2N/VRlab Phone: +46 (0)90-786 9936 Umea university Cellular: +46 (0)70-392 64 67 S-901 87 UMEA SWEDEN Fax: +46 90-786 6126 http://www.cs.umu.se/~andersb
// -*-c++-*- /* * $Id: mesh.cpp 5224 2006-07-04 09:13:15Z robert $ * * Loader for DirectX .x files. * Copyright (c)2002-2006 Ulrich Hertlein <[EMAIL PROTECTED]> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #if defined(_MSC_VER) && (_MSC_VER <= 1200) #pragma warning (disable : 4786) #endif #include "mesh.h" #include "directx.h" #include <iostream> #include <osg/Notify> using namespace DX; using namespace std; /********************************************************************** * * DirectX mesh. * **********************************************************************/ Mesh::Mesh(Object * obj) { _obj = obj; _normals = 0; _textureCoords = 0; _materialList = 0; } void Mesh::clear() { if (_normals) { delete _normals; _normals = 0; } if (_textureCoords) { delete _textureCoords; _textureCoords = 0; } if (_materialList) { delete _materialList; _materialList = 0; } } bool Mesh::generateNormals(float /*creaseAngle*/) { //cerr << "*** generateNormals\n"; // Forget old normals if (_normals) { delete _normals; _normals = 0; } /* * Calculate per-face normals from face vertices. */ vector<Vector> faceNormals; faceNormals.resize(_faces.size()); unsigned int fi; for (fi = 0; fi < _faces.size(); fi++) { vector<Vector> poly; unsigned int n = _faces[fi].size(); if (n < 3) continue; for (unsigned int i = 0; i < n; i++) { unsigned int idx = _faces[fi][i]; poly.push_back(_vertices[idx]); } // Edge vectors Vector e0; e0.x = poly[1].x - poly[0].x; e0.y = poly[1].y - poly[0].y; e0.z = poly[1].z - poly[0].z; Vector e1; e1.x = poly[2].x - poly[0].x; e1.y = poly[2].y - poly[0].y; e1.z = poly[2].z - poly[0].z; // Cross-product of e0,e1 Vector normal; normal.x = e0.y * e1.z - e0.z * e1.y; normal.y = e0.z * e1.x - e0.x * e1.z; normal.z = e0.x * e1.y - e0.y * e1.x; normal.normalize(); // Add to per-face normals faceNormals[fi] = normal; } /* * Calculate per-vertex normals as average of all per-face normals that * share this vertex. The index of the vertex normal is identical to the * vertex index for now. This means each vertex only has a single normal... */ _normals = new MeshNormals; _normals->normals.resize(_vertices.size()); for (unsigned int vi = 0; vi < _vertices.size(); vi++) { Vector normal = { 0.0f, 0.0f, 0.0f }; unsigned int polyCount = 0; // Collect normals of polygons that share this vertex for (unsigned int fi = 0; fi < _faces.size(); fi++) for (unsigned int i = 0; i < _faces[fi].size(); i++) { unsigned int idx = _faces[fi][i]; if (idx == vi) { normal.x += faceNormals[fi].x; normal.y += faceNormals[fi].y; normal.z += faceNormals[fi].z; polyCount++; } } //osg::notify(osg::INFO) << "vertex " << vi << " used by " << polyCount << " faces\n"; if (polyCount > 1) { float polyCountRecip = 1.0f / (float) polyCount; normal.x *= polyCountRecip; normal.y *= polyCountRecip; normal.z *= polyCountRecip; normal.normalize(); } // Add vertex normal _normals->normals[vi] = normal; } // Copy face mesh to normals mesh _normals->faceNormals.resize(_faces.size()); for (fi = 0; fi < _faces.size(); fi++) _normals->faceNormals[fi] = _faces[fi]; return true; } // Parse 'Mesh' void Mesh::parseMesh(ifstream& fin) { char buf[256]; vector<string> token; unsigned int nVertices = 0, nFaces = 0; //cerr << "*** Mesh\n"; while (fin.getline(buf, sizeof(buf))) { // Tokenize token.clear(); tokenize(buf, token); if (token.size() == 0) continue; //cerr << "*** Mesh token=" << token[0] << endl; if (strrchr(buf, '}') != 0) { break; } else if (strrchr(buf, '{') != 0) { if (token[0] == "MeshMaterialList") parseMeshMaterialList(fin); else if (token[0] == "MeshNormals") parseMeshNormals(fin); else if (token[0] == "MeshTextureCoords") readMeshTexCoords(fin); else { //cerr << "!!! Mesh: Begin section " << token[0] << endl; _obj->parseSection(fin); } } else if (nVertices == 0) { // Vertices nVertices = atoi(token[0].c_str()); readVector(fin, _vertices, nVertices); if (nVertices != _vertices.size()) { osg::notify(osg::WARN) << "DirectX loader: Error reading vertices; " << _vertices.size() << " instead of " << nVertices << endl; } } else if (nFaces == 0) { // Faces nFaces = atoi(token[0].c_str()); readMeshFace(fin, _faces, nFaces); if (nFaces != _faces.size()) { osg::notify(osg::WARN) << "DirectX loader: Error reading mesh; " << _faces.size() << " instead of " << nFaces << endl; } } else osg::notify(osg::INFO) << "!!! " << buf << endl; } } // Parse 'MeshMaterialList' void Mesh::parseMeshMaterialList(ifstream& fin) { char buf[256]; vector<string> token; unsigned int nMaterials = 0, nFaceIndices = 0; //cerr << "*** MeshMaterialList\n"; while (fin.getline(buf, sizeof(buf))) { // Tokenize token.clear(); tokenize(buf, token); if (token.size() == 0) continue; // dgm - check for "{ <material name> }" for a // material which was declared globally #if 1 Material * material = _obj->findMaterial(token[0]); if (material) { _materialList->material.push_back(*material); continue; } #else bool found = false; if (token.size() > 2) { std::vector<Material>::iterator itr; for (itr = _globalMaterials.begin(); itr != _globalMaterials.end(); ++itr) { if ( (*itr).name == token[1]) { if (!_materialList) _materialList = new MeshMaterialList; _materialList->material.push_back(*itr); found = true; break; } } } if (found) continue; #endif if (strrchr(buf, '}') != 0) break; else if (strrchr(buf, '{') != 0) { if (token[0] == "Material") { Material mm; parseMaterial(fin, mm); _materialList->material.push_back(mm); //cerr << "num mat=" << _materialList->material.size() << endl; } else { //cerr << "!!! MeshMaterialList: Begin section " << token[0] << endl; _obj->parseSection(fin); } } else if (nMaterials == 0) { // Create MeshMaterialList if (!_materialList) _materialList = new MeshMaterialList; // Materials nMaterials = atoi(token[0].c_str()); //cerr << "expecting num Materials=" << nMaterials << endl; } else if (nFaceIndices == 0) { // Face indices nFaceIndices = atoi(token[0].c_str()); readIndexList(fin, _materialList->faceIndices, nFaceIndices); if (nFaceIndices != _materialList->faceIndices.size()) { osg::notify(osg::WARN) << "DirectX loader: Error reading face indices; " << nFaceIndices << " instead of " << _materialList->faceIndices.size() << endl; } } } if (nMaterials != _materialList->material.size()) { osg::notify(osg::WARN) << "DirectX loader: Error reading material list; " << nMaterials << " instead of " << _materialList->material.size() << endl; } } // Parse 'MeshNormals' void Mesh::parseMeshNormals(ifstream& fin) { char buf[256]; vector<string> token; unsigned int nNormals = 0, nFaceNormals = 0; //cerr << "*** MeshNormals\n"; while (fin.getline(buf, sizeof(buf))) { // Tokenize token.clear(); tokenize(buf, token); if (token.size() == 0) continue; if (strrchr(buf, '}') != 0) break; else if (nNormals == 0) { // Create MeshNormals if (!_normals) _normals = new MeshNormals; // Normals nNormals = atoi(token[0].c_str()); readVector(fin, _normals->normals, nNormals); if (nNormals != _normals->normals.size()) { osg::notify(osg::WARN) << "DirectX loader: Error reading normals; " << nNormals << " instead of " << _normals->normals.size() << endl; } #define NORMALIZE_NORMALS #ifdef NORMALIZE_NORMALS for (unsigned int i = 0; i < _normals->normals.size(); i++) _normals->normals[i].normalize(); #endif } else if (nFaceNormals == 0) { // Face normals nFaceNormals = atoi(token[0].c_str()); readMeshFace(fin, _normals->faceNormals, nFaceNormals); if (nFaceNormals != _normals->faceNormals.size()) { osg::notify(osg::WARN) << "DirectX loader: Error reading face normals; " << nFaceNormals << " instead of " << _normals->faceNormals.size() << endl; } } } } // Read 'MeshTextureCoords' void Mesh::readMeshTexCoords(ifstream& fin) { char buf[256]; vector<string> token; unsigned int nTextureCoords = 0; //cerr << "*** MeshTextureCoords\n"; while (fin.getline(buf, sizeof(buf))) { // Tokenize token.clear(); tokenize(buf, token); if (token.size() == 0) continue; if (strrchr(buf, '}') != 0) break; // Create MeshTextureCoords if (!_textureCoords) _textureCoords = new MeshTextureCoords; // Texture coords nTextureCoords = atoi(token[0].c_str()); readCoords2d(fin, *_textureCoords, nTextureCoords); if (nTextureCoords != _textureCoords->size()) { osg::notify(osg::INFO) << "DirectX loader: Error reading texcoords; " << _textureCoords->size() << " instead of " << nTextureCoords << endl; delete _textureCoords; _textureCoords = 0; } } }
_______________________________________________ osg-users mailing list osg-users@openscenegraph.net http://openscenegraph.net/mailman/listinfo/osg-users http://www.openscenegraph.org/