1 // -*-c++-*- 2 3 /* 4 * $Id$ 5 * 6 * Loader for DirectX .x files. 7 * Copyright (c)2002-2006 Ulrich Hertlein <u.hertlein@sandbox.de> 8 * 9 * This library is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU Lesser General Public 11 * License as published by the Free Software Foundation; either 12 * version 2.1 of the License, or (at your option) any later version. 13 * 14 * This library is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * Lesser General Public License for more details. 18 * 19 * You should have received a copy of the GNU Lesser General Public 20 * License along with this library; if not, write to the Free Software 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 */ 23 24 25 #if defined(_MSC_VER) && (_MSC_VER <= 1200) 26 #pragma warning (disable : 4786) 27 #endif 28 29 #include "types.h" 30 31 #include <iostream> 32 #include <string.h> 33 #include <stdlib.h> 34 35 using namespace std; 36 37 38 namespace DX { 39 40 // Tokenize a string tokenize(const string & str,vector<string> & tokens,const string & delimiters)41 void tokenize(const string & str, vector<string> & tokens, const string & delimiters) 42 { 43 string::size_type lastPos = str.find_first_not_of(delimiters, 0); 44 string::size_type pos = str.find_first_of(delimiters, lastPos); 45 46 while (string::npos != pos || string::npos != lastPos) { 47 tokens.push_back(str.substr(lastPos, pos - lastPos)); 48 lastPos = str.find_first_not_of(delimiters, pos); 49 pos = str.find_first_of(delimiters, lastPos); 50 } 51 } 52 53 // Read 'TextureFilename' readTexFilename(istream & fin,TextureFilename & texture)54 void readTexFilename(istream & fin, TextureFilename & texture) 55 { 56 char buf[256]; 57 vector<string> token; 58 59 //cerr << "*** TexFilename\n"; 60 while (fin.getline(buf, sizeof(buf))) { 61 62 // Tokenize 63 token.clear(); 64 tokenize(buf, token); 65 if (token.size() == 0) 66 continue; 67 if (token[0] == "}") 68 break; 69 70 // Strip " if present 71 std::string line = buf; 72 std::string::size_type pos = line.find('"'); 73 if (pos != string::npos) { 74 std::string::size_type end = line.rfind('"'); 75 int len = (end != std::string::npos ? (end-pos-1) : (line.size()-pos)); 76 texture = line.substr(pos+1, len); 77 } 78 else 79 texture = token[0]; 80 //cerr << "* tex='" << texture << "'" << endl; 81 } 82 } 83 84 // Read 'Coords2d' readCoords2d(istream & fin,vector<Coords2d> & v,unsigned int count)85 void readCoords2d(istream & fin, vector<Coords2d> & v, unsigned int count) 86 { 87 char buf[256]; 88 vector<string> token; 89 90 unsigned int i = 0; 91 92 //cerr << "*** Coords2d\n"; 93 while (i < count && fin.getline(buf, sizeof(buf))) { 94 95 // Tokenize 96 token.clear(); 97 tokenize(buf, token); 98 if (token.size() == 0) 99 continue; 100 101 Coords2d c; 102 c.u = osg::asciiToFloat(token[0].c_str()); 103 c.v = osg::asciiToFloat(token[1].c_str()); 104 v.push_back(c); 105 i++; 106 } 107 } 108 109 // Read 'Vector' readVector(istream & fin,vector<Vector> & v,unsigned int count)110 void readVector(istream & fin, vector<Vector> & v, unsigned int count) 111 { 112 char buf[256]; 113 vector<string> token; 114 115 unsigned int i = 0; 116 117 //cerr << "*** Vector\n"; 118 while (i < count && fin.getline(buf, sizeof(buf))) { 119 120 // Tokenize 121 token.clear(); 122 tokenize(buf, token); 123 if (token.size() == 0) 124 continue; 125 126 Vector vec; 127 vec.x = osg::asciiToFloat(token[0].c_str()); 128 vec.y = osg::asciiToFloat(token[1].c_str()); 129 vec.z = osg::asciiToFloat(token[2].c_str()); 130 v.push_back(vec); 131 i++; 132 } 133 } 134 135 // Parse 'Material' parseMaterial(istream & fin,Material & material)136 void parseMaterial(istream & fin, Material & material) 137 { 138 char buf[256]; 139 vector<string> token; 140 141 unsigned int i = 0; 142 143 //cerr << "*** Material\n"; 144 while (fin.getline(buf, sizeof(buf))) { 145 146 // Tokenize 147 token.clear(); 148 tokenize(buf, token); 149 if (token.size() == 0) 150 continue; 151 if (token[0] == "}") 152 break; 153 if (token[0] == "TextureFilename") { 154 TextureFilename tf; 155 readTexFilename(fin, tf); 156 material.texture.push_back(tf); 157 //cerr << "* num tex=" << material.texture.size() << endl; 158 } else { 159 switch (i) { 160 case 0: { 161 // ColorRGBA 162 material.faceColor.red = osg::asciiToFloat(token[0].c_str()); 163 material.faceColor.green = osg::asciiToFloat(token[1].c_str()); 164 material.faceColor.blue = osg::asciiToFloat(token[2].c_str()); 165 material.faceColor.alpha = osg::asciiToFloat(token[3].c_str()); 166 i++; 167 } break; 168 case 1: { 169 // Power 170 material.power = osg::asciiToFloat(token[0].c_str()); 171 i++; 172 } break; 173 case 2: { 174 // ColorRGB 175 material.specularColor.red = osg::asciiToFloat(token[0].c_str()); 176 material.specularColor.green = osg::asciiToFloat(token[1].c_str()); 177 material.specularColor.blue = osg::asciiToFloat(token[2].c_str()); 178 i++; 179 } break; 180 case 3: { 181 // ColorRGB 182 material.emissiveColor.red = osg::asciiToFloat(token[0].c_str()); 183 material.emissiveColor.green = osg::asciiToFloat(token[1].c_str()); 184 material.emissiveColor.blue = osg::asciiToFloat(token[2].c_str()); 185 i++; 186 } break; 187 } 188 } 189 } 190 } 191 192 // Read index list readIndexList(istream & fin,vector<unsigned int> & v,unsigned int count)193 void readIndexList(istream & fin, vector<unsigned int> & v, unsigned int count) 194 { 195 char buf[256]; 196 vector<string> token; 197 198 unsigned int i = 0; 199 200 //cerr << "*** IndexList\n"; 201 while (i < count && fin.getline(buf, sizeof(buf))) { 202 203 // Tokenize 204 token.clear(); 205 tokenize(buf, token); 206 if (token.size() == 0) 207 continue; 208 209 unsigned int idx = atoi(token[0].c_str()); 210 v.push_back(idx); 211 i++; 212 } 213 } 214 215 // Read 'MeshFace' readMeshFace(istream & fin,vector<MeshFace> & v,unsigned int count)216 void readMeshFace(istream & fin, vector<MeshFace> & v, unsigned int count) 217 { 218 char buf[256]; 219 vector<string> token; 220 221 unsigned int i = 0; 222 223 //cerr << "*** MeshFace\n"; 224 while (i < count && fin.getline(buf, sizeof(buf))) { 225 226 // Tokenize 227 token.clear(); 228 tokenize(buf, token); 229 if (token.size() == 0) 230 continue; 231 232 MeshFace mf; 233 unsigned int n = atoi(token[0].c_str()); 234 235 for (unsigned int j = 0; j < n; j++) { 236 unsigned int idx = atoi(token[j+1].c_str()); 237 mf.push_back(idx); 238 } 239 v.push_back(mf); 240 i++; 241 } 242 } 243 244 } 245