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