/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2004 Robert Osfield * * This library is open source and may be redistributed and/or modified under * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or * (at your option) any later version. The full license is in LICENSE file * included with this distribution, and on the openscenegraph.org website. * * 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 * OpenSceneGraph Public License for more details. */ #include #include #include #include #include "obj.h" #include #include #include #include using namespace obj; static std::string strip( const std::string& ss ) { std::string result; result.assign( ss.begin() + ss.find_first_not_of( ' ' ), ss.begin() + 1 + ss.find_last_not_of( ' ' ) ); return( result ); } /* * parse a subset of texture options, following * http://local.wasp.uwa.edu.au/~pbourke/dataformats/mtl/ */ static std::string parseTexture( const std::string& ss, Material& mat) { std::string s(ss); for (;;) { if (s[0] != '-') break; int n; if (s[1] == 's' || s[1] == 'o') { float x, y, z; if (sscanf(s.c_str(), "%*s %f %f %f%n", &x, &y, &z, &n) != 3) { break; } if (s[1] == 's') { // texture scale mat.uScale = x; mat.vScale = y; } else if (s[1] == 'o') { // texture offset mat.uOffset = x; mat.vOffset = y; } } else if (s[1] == 'm' && s[2] == 'm') { // texture color offset and gain float base, gain; if (sscanf(s.c_str(), "%*s %f %f%n", &base, &gain, &n) != 2) { break; } // UNUSED } else if (s[1] == 'b' && s[2] == 'm') { // blend multiplier float mult; if (sscanf(s.c_str(), "%*s %f%n", &mult, &n) != 2) { break; } // UNUSED } else break; s = strip(s.substr(n)); } return s; } bool Model::readline(std::istream& fin, char* line, const int LINE_SIZE) { if (LINE_SIZE<1) return false; bool eatWhiteSpaceAtStart = true; bool changeTabsToSpaces = true; char* ptr = line; char* end = line+LINE_SIZE-1; bool skipNewline = false; while (fin && ptrline && *(ptr-1)==' ') { --ptr; } *ptr = 0; if (changeTabsToSpaces) { for(ptr = line; *ptr != 0; ++ptr) { if (*ptr == '\t') *ptr=' '; } } return true; } std::string Model::lastComponent(const char* linep) { std::string line = std::string(linep); int space = line.find_last_of(" "); if (space >= 0) { line = line.substr(space+1); } return line; } bool Model::readMTL(std::istream& fin) { osg::notify(osg::INFO)<<"Reading MTL file"<0) { if (strncmp(line,"newmtl ",7)==0) { std::string materialName(line+7); material = & materialMap[materialName]; material->name = materialName; } else if (material) { if (strncmp(line,"Ka ",3)==0) { unsigned int fieldsRead = sscanf(line+3,"%f %f %f %f", &r, &g, &b, &a); if (fieldsRead==1) { material->ambient[ 0 ] = r; } else if (fieldsRead==2) { material->ambient[ 0 ] = r; material->ambient[ 1 ] = g; } else if (fieldsRead==3) { material->ambient[ 0 ] = r; material->ambient[ 1 ] = g; material->ambient[ 2 ] = b; } else if (fieldsRead==4) { material->ambient[ 0 ] = r; material->ambient[ 1 ] = g; material->ambient[ 2 ] = b; material->ambient[ 3 ] = a; } } else if (strncmp(line,"Kd ",3)==0) { unsigned int fieldsRead = sscanf(line+3,"%f %f %f %f", &r, &g, &b, &a); if (fieldsRead==1) { material->diffuse[ 0 ] = r; } else if (fieldsRead==2) { material->diffuse[ 0 ] = r; material->diffuse[ 1 ] = g; } else if (fieldsRead==3) { material->diffuse[ 0 ] = r; material->diffuse[ 1 ] = g; material->diffuse[ 2 ] = b; } else if (fieldsRead==4) { material->diffuse[ 0 ] = r; material->diffuse[ 1 ] = g; material->diffuse[ 2 ] = b; material->diffuse[ 3 ] = a; } } else if (strncmp(line,"Ks ",3)==0) { unsigned int fieldsRead = sscanf(line+3,"%f %f %f %f", &r, &g, &b, &a); if (fieldsRead==1) { material->specular[ 0 ] = r; } else if (fieldsRead==2) { material->specular[ 0 ] = r; material->specular[ 1 ] = g; } else if (fieldsRead==3) { material->specular[ 0 ] = r; material->specular[ 1 ] = g; material->specular[ 2 ] = b; } else if (fieldsRead==4) { material->specular[ 0 ] = r; material->specular[ 1 ] = g; material->specular[ 2 ] = b; material->specular[ 3 ] = a; } } else if (strncmp(line,"Ke ",3)==0) { unsigned int fieldsRead = sscanf(line+3,"%f %f %f %f", &r, &g, &b, &a); if (fieldsRead==1) { material->emissive[ 0 ] = r; } else if (fieldsRead==2) { material->emissive[ 0 ] = r; material->emissive[ 1 ] = g; } else if (fieldsRead==3) { material->emissive[ 0 ] = r; material->emissive[ 1 ] = g; material->emissive[ 2 ] = b; } else if (fieldsRead==4) { material->emissive[ 0 ] = r; material->emissive[ 1 ] = g; material->emissive[ 2 ] = b; material->emissive[ 3 ] = a; } } else if (strncmp(line,"Tf ",3)==0) { unsigned int fieldsRead = sscanf(line+3,"%f %f %f %f", &r, &g, &b, &a); if (fieldsRead==1) { material->Tf[ 0 ] = r; } else if (fieldsRead==2) { material->Tf[ 0 ] = r; material->Tf[ 1 ] = g; } else if (fieldsRead==3) { material->Tf[ 0 ] = r; material->Tf[ 1 ] = g; material->Tf[ 2 ] = b; } else if (fieldsRead==4) { material->Tf[ 0 ] = r; material->Tf[ 1 ] = g; material->Tf[ 2 ] = b; material->Tf[ 3 ] = a; } } else if (strncmp(line,"sharpness ",10)==0) { float sharpness = 0.0f; unsigned int fieldsRead = sscanf(line+10,"%f", &sharpness); if (fieldsRead==1) material->sharpness = sharpness; } else if (strncmp(line,"illum ",6)==0) { int illum = 0; unsigned int fieldsRead = sscanf(line+6,"%d", &illum); if (fieldsRead==1) material->illum = illum; } else if (strncmp(line,"Ns ",3)==0) { int Ns = 0; unsigned int fieldsRead = sscanf(line+3,"%d", &Ns); if (fieldsRead==1) material->Ns = Ns; } else if (strncmp(line,"Ni ",3)==0) { int Ni = 0; unsigned int fieldsRead = sscanf(line+3,"%d", &Ni); if (fieldsRead==1) material->Ni = Ni; } else if (strncmp(line,"Tr ",3)==0) { float alpha=1.0f; unsigned int fieldsRead = sscanf(line+3,"%f", &alpha); if (fieldsRead==1) { material->ambient[3] = alpha; material->diffuse[3] = alpha; material->specular[3] = alpha; material->emissive[3] = alpha; } } else if (strncmp(line,"d ",2)==0) { float alpha=1.0f; unsigned int fieldsRead = sscanf(line+2,"%f", &alpha); if (fieldsRead==1) { material->ambient[3] = alpha; material->diffuse[3] = alpha; material->specular[3] = alpha; material->emissive[3] = alpha; } } else if (strncmp(line,"map_Ka ",7)==0) { material->map_Ka = parseTexture(strip(line+7), *material); } else if (strncmp(line,"map_Kd ",7)==0) { material->map_Kd = parseTexture(strip(line+7), *material); } else if (strncmp(line,"map_Ks ",7)==0) { material->map_Ks = parseTexture(strip(line+7), *material); } else if (strncmp(line,"map_opacity ",12)==0) { material->map_opacity = parseTexture(strip(line+12), *material); } else if (strcmp(line,"refl")==0 || strncmp(line,"refl ",5)==0) { material->textureReflection = true; } else { osg::notify(osg::NOTICE) <<"*** line not handled *** :"<0) { if (strncmp(line,"v ",2)==0) { unsigned int fieldsRead = sscanf(line+2,"%f %f %f %f", &x, &y, &z, &w); if (fieldsRead==1) vertices.push_back(osg::Vec3(x,0.0f,0.0f)); else if (fieldsRead==2) vertices.push_back(osg::Vec3(x,y,0.0f)); else if (fieldsRead==3) vertices.push_back(osg::Vec3(x,y,z)); else if (fieldsRead>=4) vertices.push_back(osg::Vec3(x/w,y/w,z/w)); } else if (strncmp(line,"vn ",3)==0) { unsigned int fieldsRead = sscanf(line+3,"%f %f %f", &x, &y, &z); if (fieldsRead==1) normals.push_back(osg::Vec3(x,0.0f,0.0f)); else if (fieldsRead==2) normals.push_back(osg::Vec3(x,y,0.0f)); else if (fieldsRead==3) normals.push_back(osg::Vec3(x,y,z)); } else if (strncmp(line,"vt ",3)==0) { unsigned int fieldsRead = sscanf(line+3,"%f %f %f", &x, &y, &z); if (fieldsRead==1) texcoords.push_back(osg::Vec2(x,0.0f)); else if (fieldsRead==2) texcoords.push_back(osg::Vec2(x,y)); else if (fieldsRead==3) texcoords.push_back(osg::Vec2(x,y)); } else if (strncmp(line,"l ",2)==0 || strncmp(line,"p ",2)==0 || strncmp(line,"f ",2)==0) { char* ptr = line+2; Element* element = new Element( (line[0]=='p') ? Element::POINTS : (line[0]=='l') ? Element::POLYLINE : Element::POLYGON ); // osg::notify(osg::NOTICE)<<"face"<first; ElementList& el = itr->second; osg::notify(osg::NOTICE)<<"ElementState "<