fix texture loading
[cltracer.git] / objloader.cpp
blobef74a8147716862228b7265eb25f52b079d7abe2
2 /*
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 * Copyright (C) 2010 Pavel Herrmann (morpheus.ibis@gmail.com)
20 #include <cstdlib>
21 #include <cstring>
22 #include <fstream>
23 #include <vector>
24 #include <string>
27 #define ISWHITE(x) ((x==' ')||(x=='\t'))
29 using namespace std;
32 extern "C"{
33 #include "types.h"
34 #include "objloader.h"
36 struct vertex
38 float3 space;
39 float3 normal;
40 float2 texture;
44 int addstring( vector<string>& v,string s)
46 int l=v.size();
47 for (int i=0;i<l;i++)
48 if (s.compare(v[i])==0)
49 return i;
50 v.push_back(s);
51 return l;
57 int loadOBJ(char* filename, triangle_s ** out_tri, int * trinum, char*** mtllist, int * mtlnum, char** mtlfile)
59 vector<float3> vs;
60 vector<float3> vns;
61 vector<float2> vts;
62 vector<triangle_s> tris;
63 vector<string> mtls;
64 ifstream file;
65 file.open(filename,std::ios::in);
66 string line;
67 char* readpoint;
68 int currentmtl=-1;
69 int retval;
71 while (file.good())
73 getline(file,line);
74 if (line.length()==0)
75 continue;
76 readpoint=(char*) line.c_str();
77 while (ISWHITE(readpoint[0]))
78 readpoint++;
79 switch (readpoint[0])
81 case 'v':
82 switch(readpoint[1])
84 case '\t':
85 case ' ':
86 float3 v;
87 retval=sscanf(readpoint+2,"%f %f %f",&(v.x),&(v.y),&(v.z));
88 if (retval != 3)
89 return -1;
90 vs.push_back(v);
91 break;
92 case 'n':
93 float3 vn;
94 retval=sscanf(readpoint+3,"%f %f %f",&(vn.x),&(vn.y),&(vn.z));
95 if (retval != 3)
96 return -1;
97 vns.push_back(vn);
98 break;
99 case 't':
100 float2 vt;
101 retval=sscanf(readpoint+3,"%f %f",&(vt.x),&(vt.y));
102 if (retval != 2)
103 return -1;
104 vts.push_back(vt);
105 break;
107 break;
108 case 'f':
109 int currvertex[3];
110 vertex firstvtx,lastvtx,currvtx;
111 triangle_s temptri;
112 int t;
113 int n;
114 n=0;
115 readpoint+=2;
116 while (ISWHITE(readpoint[0]))
117 readpoint++;
118 while (readpoint[0]!=0)
120 for (int i=0;i<3;i++)
122 t=0;
123 while((!ISWHITE(readpoint[0]))&&(readpoint[0]!='/'))
125 if (readpoint[0]==0)
126 break;
127 t=t*10+(readpoint[0]-48);
128 readpoint++;
130 currvertex[i]=t;
131 while((ISWHITE(readpoint[0]))||(readpoint[0]=='/'))
133 if (readpoint[0]==0)
134 break;
135 readpoint++;
137 if (t==0)
138 goto nextline;
140 lastvtx=currvtx;
141 currvtx.space=vs.at(currvertex[0]-1);
142 currvtx.texture=vts.at(currvertex[1]-1);
143 currvtx.normal=vns.at(currvertex[2]-1);
144 if (n==0)
145 firstvtx=currvtx;
146 if (n>=2)
148 temptri.spaceCoords[0]=firstvtx.space;
149 temptri.textureCoords[0]=firstvtx.texture;
150 temptri.normalCoords[0]=firstvtx.normal;
151 temptri.spaceCoords[1]=lastvtx.space;
152 temptri.textureCoords[1]=lastvtx.texture;
153 temptri.normalCoords[1]=lastvtx.normal;
154 temptri.spaceCoords[2]=currvtx.space;
155 temptri.textureCoords[2]=currvtx.texture;
156 temptri.normalCoords[2]=currvtx.normal;
157 temptri.objectIndex=currentmtl;
158 tris.push_back(temptri);
160 n++;
162 break;
163 case 'u':
164 currentmtl=addstring(mtls,string(readpoint+7));
165 break;
166 case 'm':
167 sscanf(readpoint+6, "%as", mtlfile);
168 default:
169 break;
171 nextline:;
173 *trinum = tris.size();
174 *out_tri = (triangle_s*) malloc(sizeof(triangle_s)*(*trinum));
175 copy(tris.begin(),tris.end(),*out_tri);
176 *mtlnum = mtls.size();
177 *mtllist = (char**) malloc(sizeof(char*)*(*mtlnum));
178 for (int i=0;i<(*mtlnum);i++)
180 (*mtllist)[i] = (char*) malloc(sizeof(char)*(mtls.at(i).size()+1));
181 strcpy((*mtllist)[i],mtls.at(i).c_str());
186 int loadMTL (char* filename, int mtlnum, char** mtllist, struct mtl_def_s** out)
188 FILE * f = fopen(filename, "r");
189 if (f==NULL)
190 return 1;
191 char * line;
192 char * mtlname;
193 char * textures;
194 size_t length=0;
195 int read;
196 int texcount;
197 int pos;
198 int mtlidx;
199 *out = (struct mtl_def_s*) malloc(sizeof(struct mtl_def_s)*mtlnum);
200 while ( (read=getline(&line,&length,f))!=-1)
202 sscanf(line, "%as %d %n", &mtlname, &texcount, &pos);
203 line+=pos;
204 mtlidx=-1;
205 for (int i=0;i<mtlnum;i++)
207 if (!strcmp(mtlname,mtllist[i]))
208 mtlidx=i;
210 if (mtlidx==-1)
211 continue;
212 (*out)[mtlidx].texcount=texcount;
213 (*out)[mtlidx].texnames=(char**) malloc(sizeof(char*)*texcount);
214 for (int j=0;j<texcount;j++)
216 sscanf(line, "%as%n", &((*out)[mtlidx].texnames[j]), &pos);
217 line+=pos;