rev |
line source |
nuclear@0
|
1 //#include <fstream>
|
nuclear@0
|
2 #include <windows.h>
|
nuclear@0
|
3 #include <string>
|
nuclear@0
|
4 #include <cassert>
|
nuclear@0
|
5 #include "sceneloader.h"
|
nuclear@0
|
6 #include "3dschunks.h"
|
nuclear@0
|
7 #include "typedefs.h"
|
nuclear@0
|
8
|
nuclear@0
|
9 using std::ifstream;
|
nuclear@0
|
10 using std::string;
|
nuclear@0
|
11
|
nuclear@0
|
12 namespace SceneLoader {
|
nuclear@0
|
13 GraphicsContext *gc;
|
nuclear@0
|
14 dword ReadCounter;
|
nuclear@0
|
15 Material *mat;
|
nuclear@0
|
16 dword MatCount;
|
nuclear@0
|
17
|
nuclear@0
|
18 bool eof = false;
|
nuclear@0
|
19
|
nuclear@0
|
20 string datapath = "";
|
nuclear@0
|
21
|
nuclear@0
|
22 string SceneFileName;
|
nuclear@0
|
23 string ObjectName;
|
nuclear@0
|
24
|
nuclear@0
|
25 bool SaveNormalFile = false;
|
nuclear@0
|
26 }
|
nuclear@0
|
27
|
nuclear@0
|
28 using namespace SceneLoader;
|
nuclear@0
|
29
|
nuclear@0
|
30 struct ChunkHeader {
|
nuclear@0
|
31 ChunkID id;
|
nuclear@0
|
32 dword size;
|
nuclear@0
|
33 };
|
nuclear@0
|
34
|
nuclear@0
|
35 struct Percent {
|
nuclear@0
|
36 int IntPercent;
|
nuclear@0
|
37 float FloatPercent;
|
nuclear@0
|
38
|
nuclear@0
|
39 Percent(int p = 0) {IntPercent = p; FloatPercent = (float)p / 100.0f; }
|
nuclear@0
|
40 Percent(float p) {FloatPercent = p; IntPercent = (int)(p * 100.0f); }
|
nuclear@0
|
41 };
|
nuclear@0
|
42
|
nuclear@0
|
43 struct TexMap {
|
nuclear@0
|
44 string filename;
|
nuclear@0
|
45 TextureType type;
|
nuclear@0
|
46 float intensity;
|
nuclear@0
|
47 float rotation;
|
nuclear@0
|
48 Vector2 offset;
|
nuclear@0
|
49 Vector2 scale;
|
nuclear@0
|
50 };
|
nuclear@0
|
51
|
nuclear@0
|
52 const dword HeaderSize = 6;
|
nuclear@0
|
53
|
nuclear@0
|
54 enum {OBJ_MESH, OBJ_PTLIGHT, OBJ_SPLIGHT, OBJ_CAMERA, OBJ_CURVE};
|
nuclear@0
|
55
|
nuclear@0
|
56 // local function prototypes
|
nuclear@0
|
57 byte ReadByte(HANDLE file);
|
nuclear@0
|
58 word ReadWord(HANDLE file);
|
nuclear@0
|
59 dword ReadDword(HANDLE file);
|
nuclear@0
|
60 float ReadFloat(HANDLE file);
|
nuclear@0
|
61 Vector3 ReadVector(HANDLE file, bool FlipYZ = true);
|
nuclear@0
|
62 string ReadString(HANDLE file);
|
nuclear@0
|
63 Color ReadColor(HANDLE file);
|
nuclear@0
|
64 Percent ReadPercent(HANDLE file);
|
nuclear@0
|
65 ChunkHeader ReadChunkHeader(HANDLE file);
|
nuclear@0
|
66 void SkipChunk(HANDLE file, const ChunkHeader &chunk);
|
nuclear@0
|
67 void SkipBytes(HANDLE file, dword bytes);
|
nuclear@0
|
68
|
nuclear@0
|
69 int ReadObject(HANDLE file, const ChunkHeader &ch, void **obj);
|
nuclear@0
|
70 int ReadLight(HANDLE file, const ChunkHeader &ch, Light **lt);
|
nuclear@0
|
71 Material ReadMaterial(HANDLE file, const ChunkHeader &ch);
|
nuclear@0
|
72 TexMap ReadTextureMap(HANDLE file, const ChunkHeader &ch);
|
nuclear@0
|
73
|
nuclear@0
|
74 Material *FindMaterial(string name);
|
nuclear@0
|
75
|
nuclear@0
|
76 bool LoadNormalsFromFile(const char *fname, Scene *scene);
|
nuclear@0
|
77 void SaveNormalsToFile(const char *fname, Scene *scene);
|
nuclear@0
|
78
|
nuclear@0
|
79
|
nuclear@0
|
80 void SceneLoader::SetGraphicsContext(GraphicsContext *gfx) {
|
nuclear@0
|
81 gc = gfx;
|
nuclear@0
|
82 }
|
nuclear@0
|
83
|
nuclear@0
|
84
|
nuclear@0
|
85 void SceneLoader::SetDataPath(const char *path) {
|
nuclear@0
|
86 datapath = path;
|
nuclear@0
|
87 }
|
nuclear@0
|
88
|
nuclear@0
|
89 void SceneLoader::SetNormalFileSaving(bool enable) {
|
nuclear@0
|
90 SaveNormalFile = enable;
|
nuclear@0
|
91 }
|
nuclear@0
|
92
|
nuclear@0
|
93
|
nuclear@0
|
94
|
nuclear@0
|
95 ////////////////////////////////////////
|
nuclear@0
|
96 // --==( function LoadScene )==-- //
|
nuclear@0
|
97 // ---------------------------------- //
|
nuclear@0
|
98 // Creates a Scene instance and loads //
|
nuclear@0
|
99 // the data from specified file //
|
nuclear@0
|
100 ////////////////////////////////////////
|
nuclear@0
|
101
|
nuclear@0
|
102 bool SceneLoader::LoadScene(const char *fname, Scene **scene) {
|
nuclear@0
|
103 if(!gc) return false;
|
nuclear@0
|
104
|
nuclear@0
|
105 if(!LoadMaterials(fname, &mat)) return false;
|
nuclear@0
|
106
|
nuclear@0
|
107 //ifstream file(fname);
|
nuclear@0
|
108 //if(!file.is_open()) return false;
|
nuclear@0
|
109 HANDLE file = CreateFile(fname, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL);
|
nuclear@0
|
110 assert(file != NULL);
|
nuclear@0
|
111 eof = false;
|
nuclear@0
|
112
|
nuclear@0
|
113 SceneFileName = string(fname);
|
nuclear@0
|
114
|
nuclear@0
|
115 ChunkHeader chunk;
|
nuclear@0
|
116 Scene *scn = new Scene(gc); // new scene instance
|
nuclear@0
|
117
|
nuclear@0
|
118 chunk = ReadChunkHeader(file);
|
nuclear@0
|
119 if(chunk.id != Chunk_3DSMain) {
|
nuclear@0
|
120 CloseHandle(file);
|
nuclear@0
|
121 return false;
|
nuclear@0
|
122 }
|
nuclear@0
|
123
|
nuclear@0
|
124 //while(!file.eof()) {
|
nuclear@0
|
125 while(!eof) {
|
nuclear@0
|
126
|
nuclear@0
|
127 chunk = ReadChunkHeader(file);
|
nuclear@0
|
128
|
nuclear@0
|
129 void *objptr;
|
nuclear@0
|
130 int type;
|
nuclear@0
|
131
|
nuclear@0
|
132 switch(chunk.id) {
|
nuclear@0
|
133 case Chunk_Main_3DEditor:
|
nuclear@0
|
134 break; // dont skip
|
nuclear@0
|
135
|
nuclear@0
|
136 case Chunk_Edit_AmbientColor:
|
nuclear@0
|
137 scn->SetAmbientLight(ReadColor(file));
|
nuclear@0
|
138 break;
|
nuclear@0
|
139
|
nuclear@0
|
140 case Chunk_Edit_Fog:
|
nuclear@0
|
141 // **TODO** find out chunk structure
|
nuclear@0
|
142 break;
|
nuclear@0
|
143
|
nuclear@0
|
144 case Chunk_Edit_Object:
|
nuclear@0
|
145 type = ReadObject(file, chunk, &objptr);
|
nuclear@0
|
146 switch(type) {
|
nuclear@0
|
147 case OBJ_MESH:
|
nuclear@0
|
148 {
|
nuclear@0
|
149 Object *object = (Object*)objptr;
|
nuclear@0
|
150 scn->AddObject(object);
|
nuclear@0
|
151 }
|
nuclear@0
|
152 break;
|
nuclear@0
|
153
|
nuclear@0
|
154 case OBJ_CAMERA:
|
nuclear@0
|
155 {
|
nuclear@0
|
156 Camera *cam = (Camera*)objptr;
|
nuclear@0
|
157 scn->AddCamera(cam);
|
nuclear@0
|
158 }
|
nuclear@0
|
159 break;
|
nuclear@0
|
160
|
nuclear@0
|
161 case OBJ_PTLIGHT:
|
nuclear@0
|
162 {
|
nuclear@0
|
163 PointLight *lt = (PointLight*)objptr;
|
nuclear@0
|
164 scn->AddLight(lt);
|
nuclear@0
|
165 }
|
nuclear@0
|
166 break;
|
nuclear@0
|
167
|
nuclear@0
|
168 case OBJ_SPLIGHT:
|
nuclear@0
|
169 {
|
nuclear@0
|
170 SpotLight *lt = (SpotLight*)objptr;
|
nuclear@0
|
171 scn->AddLight(lt);
|
nuclear@0
|
172 }
|
nuclear@0
|
173 break;
|
nuclear@0
|
174
|
nuclear@0
|
175 case OBJ_CURVE:
|
nuclear@0
|
176 {
|
nuclear@0
|
177 CatmullRomSpline *spline = (CatmullRomSpline*)objptr;
|
nuclear@0
|
178 scn->AddCurve(spline);
|
nuclear@0
|
179 }
|
nuclear@0
|
180 break;
|
nuclear@0
|
181 }
|
nuclear@0
|
182
|
nuclear@0
|
183 break;
|
nuclear@0
|
184
|
nuclear@0
|
185 default:
|
nuclear@0
|
186 SkipChunk(file, chunk);
|
nuclear@0
|
187 }
|
nuclear@0
|
188 }
|
nuclear@0
|
189
|
nuclear@0
|
190 CloseHandle(file);
|
nuclear@0
|
191
|
nuclear@0
|
192
|
nuclear@0
|
193 // check if there is a normals file in the same dir and load them, or else calculate them
|
nuclear@0
|
194 if(!LoadNormalsFromFile((SceneFileName + string(".normals")).c_str(), scn)) {
|
nuclear@0
|
195 std::list<Object*>::iterator objiter = scn->GetObjectsList()->begin();
|
nuclear@0
|
196 while(objiter != scn->GetObjectsList()->end()) {
|
nuclear@0
|
197 (*objiter++)->GetTriMesh()->CalculateNormals();
|
nuclear@0
|
198 }
|
nuclear@0
|
199 if(SaveNormalFile) SaveNormalsToFile((SceneFileName + string(".normals")).c_str(), scn);
|
nuclear@0
|
200 }
|
nuclear@0
|
201
|
nuclear@0
|
202 *scene = scn;
|
nuclear@0
|
203 return true;
|
nuclear@0
|
204 }
|
nuclear@0
|
205
|
nuclear@0
|
206
|
nuclear@0
|
207
|
nuclear@0
|
208 bool SceneLoader::LoadObject(const char *fname, const char *ObjectName, Object **obj) {
|
nuclear@0
|
209 if(!gc) return false;
|
nuclear@0
|
210
|
nuclear@0
|
211 if(!LoadMaterials(fname, &mat)) return false;
|
nuclear@0
|
212
|
nuclear@0
|
213 //ifstream file(fname);
|
nuclear@0
|
214 //if(!file.is_open()) return false;
|
nuclear@0
|
215 HANDLE file = CreateFile(fname, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL);
|
nuclear@0
|
216 assert(file != NULL);
|
nuclear@0
|
217 eof = false;
|
nuclear@0
|
218
|
nuclear@0
|
219 ChunkHeader chunk = ReadChunkHeader(file);
|
nuclear@0
|
220 if(chunk.id != Chunk_3DSMain) {
|
nuclear@0
|
221 CloseHandle(file);
|
nuclear@0
|
222 return false;
|
nuclear@0
|
223 }
|
nuclear@0
|
224
|
nuclear@0
|
225 while(!eof) {
|
nuclear@0
|
226
|
nuclear@0
|
227 chunk = ReadChunkHeader(file);
|
nuclear@0
|
228
|
nuclear@0
|
229 void *objptr;
|
nuclear@0
|
230 int type;
|
nuclear@0
|
231
|
nuclear@0
|
232 switch(chunk.id) {
|
nuclear@0
|
233 case Chunk_Main_3DEditor:
|
nuclear@0
|
234 break; // dont skip
|
nuclear@0
|
235
|
nuclear@0
|
236 case Chunk_Edit_Object:
|
nuclear@0
|
237 type = ReadObject(file, chunk, &objptr);
|
nuclear@0
|
238 if(type == OBJ_MESH) {
|
nuclear@0
|
239 Object *object = (Object*)objptr;
|
nuclear@0
|
240 if(!strcmp(object->name.c_str(), ObjectName)) {
|
nuclear@0
|
241 object->GetTriMesh()->CalculateNormals();
|
nuclear@0
|
242 *obj = object;
|
nuclear@0
|
243 CloseHandle(file);
|
nuclear@0
|
244 return true;
|
nuclear@0
|
245 }
|
nuclear@0
|
246 }
|
nuclear@0
|
247 break;
|
nuclear@0
|
248
|
nuclear@0
|
249 default:
|
nuclear@0
|
250 SkipChunk(file, chunk);
|
nuclear@0
|
251 }
|
nuclear@0
|
252 }
|
nuclear@0
|
253
|
nuclear@0
|
254 CloseHandle(file);
|
nuclear@0
|
255 return false;
|
nuclear@0
|
256 }
|
nuclear@0
|
257
|
nuclear@0
|
258
|
nuclear@0
|
259
|
nuclear@0
|
260 bool FindChunk(HANDLE file, word ChunkID) {
|
nuclear@0
|
261
|
nuclear@0
|
262 ChunkHeader chunk = ReadChunkHeader(file);
|
nuclear@0
|
263
|
nuclear@0
|
264 while(chunk.id != ChunkID) {
|
nuclear@0
|
265 SkipChunk(file, chunk);
|
nuclear@0
|
266 chunk = ReadChunkHeader(file);
|
nuclear@0
|
267 }
|
nuclear@0
|
268
|
nuclear@0
|
269 return chunk.id == ChunkID;
|
nuclear@0
|
270 }
|
nuclear@0
|
271
|
nuclear@0
|
272
|
nuclear@0
|
273
|
nuclear@0
|
274 bool SceneLoader::LoadMaterials(const char *fname, Material **materials) {
|
nuclear@0
|
275 if(!materials) return false;
|
nuclear@0
|
276
|
nuclear@0
|
277 //ifstream file(fname);
|
nuclear@0
|
278 //if(!file.is_open()) return false;
|
nuclear@0
|
279 HANDLE file = CreateFile(fname, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL);
|
nuclear@0
|
280 assert(file != NULL);
|
nuclear@0
|
281 eof = false;
|
nuclear@0
|
282
|
nuclear@0
|
283 ChunkHeader chunk;
|
nuclear@0
|
284
|
nuclear@0
|
285 chunk = ReadChunkHeader(file);
|
nuclear@0
|
286 if(chunk.id != Chunk_3DSMain) {
|
nuclear@0
|
287 CloseHandle(file);
|
nuclear@0
|
288 return false;
|
nuclear@0
|
289 }
|
nuclear@0
|
290
|
nuclear@0
|
291 if(!FindChunk(file, Chunk_Main_3DEditor)) {
|
nuclear@0
|
292 CloseHandle(file);
|
nuclear@0
|
293 return false;
|
nuclear@0
|
294 }
|
nuclear@0
|
295
|
nuclear@0
|
296 std::vector<Material> mats;
|
nuclear@0
|
297
|
nuclear@0
|
298 while(!eof) {
|
nuclear@0
|
299
|
nuclear@0
|
300 chunk = ReadChunkHeader(file);
|
nuclear@0
|
301
|
nuclear@0
|
302 if(chunk.id == Chunk_Edit_Material) {
|
nuclear@0
|
303 Material mat = ReadMaterial(file, chunk);
|
nuclear@0
|
304 mats.push_back(mat);
|
nuclear@0
|
305 } else {
|
nuclear@0
|
306 SkipChunk(file, chunk);
|
nuclear@0
|
307 }
|
nuclear@0
|
308 }
|
nuclear@0
|
309
|
nuclear@0
|
310 MatCount = (dword)mats.size();
|
nuclear@0
|
311
|
nuclear@0
|
312 if(*materials) delete [] *materials;
|
nuclear@0
|
313 Material *m = new Material[MatCount];
|
nuclear@0
|
314
|
nuclear@0
|
315 for(dword i=0; i<MatCount; i++) {
|
nuclear@0
|
316 m[i] = mats[i];
|
nuclear@0
|
317 }
|
nuclear@0
|
318
|
nuclear@0
|
319 *materials = m;
|
nuclear@0
|
320
|
nuclear@0
|
321 CloseHandle(file);
|
nuclear@0
|
322 return true;
|
nuclear@0
|
323 }
|
nuclear@0
|
324
|
nuclear@0
|
325
|
nuclear@0
|
326 TexMap ReadTextureMap(HANDLE file, const ChunkHeader &ch) {
|
nuclear@0
|
327 assert(ch.id == Chunk_Mat_TextureMap || ch.id == Chunk_Mat_TextureMap2 || ch.id == Chunk_Mat_OpacityMap || ch.id == Chunk_Mat_BumpMap || ch.id == Chunk_Mat_ReflectionMap || ch.id == Chunk_Mat_SelfIlluminationMap);
|
nuclear@0
|
328
|
nuclear@0
|
329 TexMap map;
|
nuclear@0
|
330 Percent p = ReadPercent(file);
|
nuclear@0
|
331 map.intensity = p.FloatPercent;
|
nuclear@0
|
332
|
nuclear@0
|
333 switch(ch.id) {
|
nuclear@0
|
334 case Chunk_Mat_TextureMap:
|
nuclear@0
|
335 map.type = TextureMap;
|
nuclear@0
|
336 break;
|
nuclear@0
|
337
|
nuclear@0
|
338 case Chunk_Mat_TextureMap2:
|
nuclear@0
|
339 map.type = DetailMap;
|
nuclear@0
|
340 break;
|
nuclear@0
|
341
|
nuclear@0
|
342 case Chunk_Mat_OpacityMap:
|
nuclear@0
|
343 map.type = OpacityMap;
|
nuclear@0
|
344 break;
|
nuclear@0
|
345
|
nuclear@0
|
346 case Chunk_Mat_BumpMap:
|
nuclear@0
|
347 map.type = BumpMap;
|
nuclear@0
|
348 break;
|
nuclear@0
|
349
|
nuclear@0
|
350 case Chunk_Mat_ReflectionMap:
|
nuclear@0
|
351 map.type = EnvironmentMap;
|
nuclear@0
|
352 break;
|
nuclear@0
|
353
|
nuclear@0
|
354 case Chunk_Mat_SelfIlluminationMap:
|
nuclear@0
|
355 map.type = LightMap;
|
nuclear@0
|
356 break;
|
nuclear@0
|
357 default:
|
nuclear@0
|
358 assert(0);
|
nuclear@0
|
359 }
|
nuclear@0
|
360
|
nuclear@0
|
361 ChunkHeader chunk = ReadChunkHeader(file);
|
nuclear@0
|
362 assert(chunk.id == Chunk_Map_FileName);
|
nuclear@0
|
363
|
nuclear@0
|
364 map.filename = ReadString(file);
|
nuclear@0
|
365 return map;
|
nuclear@0
|
366 }
|
nuclear@0
|
367
|
nuclear@0
|
368
|
nuclear@0
|
369
|
nuclear@0
|
370
|
nuclear@0
|
371
|
nuclear@0
|
372 Material ReadMaterial(HANDLE file, const ChunkHeader &ch) {
|
nuclear@0
|
373
|
nuclear@0
|
374 Material mat;
|
nuclear@0
|
375
|
nuclear@0
|
376 assert(ch.id == Chunk_Edit_Material);
|
nuclear@0
|
377
|
nuclear@0
|
378 ReadCounter = HeaderSize;
|
nuclear@0
|
379 dword ChunkSize = ch.size;
|
nuclear@0
|
380
|
nuclear@0
|
381 while(ReadCounter < ChunkSize) {
|
nuclear@0
|
382 ChunkHeader chunk = ReadChunkHeader(file);
|
nuclear@0
|
383
|
nuclear@0
|
384 Percent p;
|
nuclear@0
|
385 TexMap map;
|
nuclear@0
|
386
|
nuclear@0
|
387 switch(chunk.id) {
|
nuclear@0
|
388 case Chunk_Mat_Name:
|
nuclear@0
|
389 mat.name = ReadString(file);
|
nuclear@0
|
390 break;
|
nuclear@0
|
391
|
nuclear@0
|
392 case Chunk_Mat_AmbientColor:
|
nuclear@0
|
393 mat.Ambient = ReadColor(file);
|
nuclear@0
|
394 break;
|
nuclear@0
|
395
|
nuclear@0
|
396 case Chunk_Mat_DiffuseColor:
|
nuclear@0
|
397 mat.Diffuse = ReadColor(file);
|
nuclear@0
|
398 break;
|
nuclear@0
|
399
|
nuclear@0
|
400 case Chunk_Mat_SpecularColor:
|
nuclear@0
|
401 mat.Specular = ReadColor(file);
|
nuclear@0
|
402 break;
|
nuclear@0
|
403
|
nuclear@0
|
404 case Chunk_Mat_Specular:
|
nuclear@0
|
405 p = ReadPercent(file);
|
nuclear@0
|
406 mat.Power = (float)p.IntPercent;
|
nuclear@0
|
407 if(mat.Power > 0.0f) mat.SpecularEnable = true;
|
nuclear@0
|
408 break;
|
nuclear@0
|
409
|
nuclear@0
|
410 case Chunk_Mat_SpecularIntensity:
|
nuclear@0
|
411 p = ReadPercent(file);
|
nuclear@0
|
412 mat.Specular.r *= p.FloatPercent;
|
nuclear@0
|
413 mat.Specular.g *= p.FloatPercent;
|
nuclear@0
|
414 mat.Specular.b *= p.FloatPercent;
|
nuclear@0
|
415 break;
|
nuclear@0
|
416
|
nuclear@0
|
417 case Chunk_Mat_Transparency:
|
nuclear@0
|
418 p = ReadPercent(file);
|
nuclear@0
|
419 mat.Alpha = 1.0f - p.FloatPercent;
|
nuclear@0
|
420 break;
|
nuclear@0
|
421
|
nuclear@0
|
422 case Chunk_Mat_SelfIllumination:
|
nuclear@0
|
423 p = ReadPercent(file);
|
nuclear@0
|
424 mat.Emissive = Color(p.FloatPercent);
|
nuclear@0
|
425 break;
|
nuclear@0
|
426
|
nuclear@0
|
427 case Chunk_Mat_TextureMap:
|
nuclear@0
|
428 case Chunk_Mat_TextureMap2:
|
nuclear@0
|
429 case Chunk_Mat_OpacityMap:
|
nuclear@0
|
430 case Chunk_Mat_SelfIlluminationMap:
|
nuclear@0
|
431 map = ReadTextureMap(file, chunk);
|
nuclear@0
|
432 mat.SetTexture(gc->texman->LoadTexture((datapath + map.filename).c_str()), map.type);
|
nuclear@0
|
433 break;
|
nuclear@0
|
434
|
nuclear@0
|
435 case Chunk_Mat_ReflectionMap:
|
nuclear@0
|
436 map = ReadTextureMap(file, chunk);
|
nuclear@0
|
437 mat.SetTexture(gc->texman->LoadTexture((datapath + map.filename).c_str()), map.type);
|
nuclear@0
|
438 mat.EnvBlend = map.intensity;
|
nuclear@0
|
439 break;
|
nuclear@0
|
440
|
nuclear@0
|
441 case Chunk_Mat_BumpMap:
|
nuclear@0
|
442 map = ReadTextureMap(file, chunk);
|
nuclear@0
|
443 mat.SetTexture(gc->texman->LoadTexture((datapath + map.filename).c_str()), map.type);
|
nuclear@0
|
444 mat.BumpIntensity = map.intensity;
|
nuclear@0
|
445 break;
|
nuclear@0
|
446
|
nuclear@0
|
447 default:
|
nuclear@0
|
448 SkipChunk(file, chunk);
|
nuclear@0
|
449 }
|
nuclear@0
|
450 }
|
nuclear@0
|
451
|
nuclear@0
|
452 return mat;
|
nuclear@0
|
453 }
|
nuclear@0
|
454
|
nuclear@0
|
455
|
nuclear@0
|
456
|
nuclear@0
|
457
|
nuclear@0
|
458
|
nuclear@0
|
459 ////////////////////////////////////////////////////
|
nuclear@0
|
460 byte ReadByte(HANDLE file) {
|
nuclear@0
|
461 byte val;
|
nuclear@0
|
462 dword numread;
|
nuclear@0
|
463 ReadFile(file, &val, sizeof(byte), &numread, NULL);
|
nuclear@0
|
464 if(numread < sizeof(byte)) eof = true;
|
nuclear@0
|
465 ReadCounter++;
|
nuclear@0
|
466 return val;
|
nuclear@0
|
467 }
|
nuclear@0
|
468
|
nuclear@0
|
469 word ReadWord(HANDLE file) {
|
nuclear@0
|
470 word val;
|
nuclear@0
|
471 dword numread;
|
nuclear@0
|
472 ReadFile(file, &val, sizeof(word), &numread, NULL);
|
nuclear@0
|
473 if(numread < sizeof(word)) eof = true;
|
nuclear@0
|
474 ReadCounter += sizeof(word);
|
nuclear@0
|
475 return val;
|
nuclear@0
|
476 }
|
nuclear@0
|
477
|
nuclear@0
|
478 dword ReadDword(HANDLE file) {
|
nuclear@0
|
479 dword val;
|
nuclear@0
|
480 dword numread;
|
nuclear@0
|
481 ReadFile(file, &val, sizeof(dword), &numread, NULL);
|
nuclear@0
|
482 if(numread < sizeof(dword)) eof = true;
|
nuclear@0
|
483 ReadCounter += sizeof(dword);
|
nuclear@0
|
484 return val;
|
nuclear@0
|
485 }
|
nuclear@0
|
486
|
nuclear@0
|
487 float ReadFloat(HANDLE file) {
|
nuclear@0
|
488 float val;
|
nuclear@0
|
489 dword numread;
|
nuclear@0
|
490 ReadFile(file, &val, sizeof(float), &numread, NULL);
|
nuclear@0
|
491 if(numread < sizeof(float)) eof = true;
|
nuclear@0
|
492 ReadCounter += sizeof(float);
|
nuclear@0
|
493 return val;
|
nuclear@0
|
494 }
|
nuclear@0
|
495 /*
|
nuclear@0
|
496 byte ReadByte(HANDLE file) {
|
nuclear@0
|
497 byte val;
|
nuclear@0
|
498 file.read((char*)&val, 1);
|
nuclear@0
|
499 ReadCounter++;
|
nuclear@0
|
500 return val;
|
nuclear@0
|
501 }
|
nuclear@0
|
502
|
nuclear@0
|
503 word ReadWord(HANDLE file) {
|
nuclear@0
|
504 word val;
|
nuclear@0
|
505 file.read((char*)&val, sizeof(word));
|
nuclear@0
|
506 ReadCounter += sizeof(word);
|
nuclear@0
|
507 return val;
|
nuclear@0
|
508 }
|
nuclear@0
|
509
|
nuclear@0
|
510 dword ReadDword(HANDLE file) {
|
nuclear@0
|
511 dword val;
|
nuclear@0
|
512 file.read((char*)&val, sizeof(dword));
|
nuclear@0
|
513 ReadCounter += sizeof(dword);
|
nuclear@0
|
514 return val;
|
nuclear@0
|
515 }
|
nuclear@0
|
516
|
nuclear@0
|
517 float ReadFloat(HANDLE file) {
|
nuclear@0
|
518 float val;
|
nuclear@0
|
519 file.read((char*)&val, sizeof(float));
|
nuclear@0
|
520 ReadCounter += sizeof(float);
|
nuclear@0
|
521 return val;
|
nuclear@0
|
522 }
|
nuclear@0
|
523 */
|
nuclear@0
|
524 Vector3 ReadVector(HANDLE file, bool FlipYZ) {
|
nuclear@0
|
525 Vector3 vector;
|
nuclear@0
|
526 vector.x = ReadFloat(file);
|
nuclear@0
|
527 if(!FlipYZ) vector.y = ReadFloat(file);
|
nuclear@0
|
528 vector.z = ReadFloat(file);
|
nuclear@0
|
529 if(FlipYZ) vector.y = ReadFloat(file);
|
nuclear@0
|
530 return vector;
|
nuclear@0
|
531 }
|
nuclear@0
|
532
|
nuclear@0
|
533 string ReadString(HANDLE file) {
|
nuclear@0
|
534 string str;
|
nuclear@0
|
535 char c;
|
nuclear@0
|
536 while(c = (char)ReadByte(file)) {
|
nuclear@0
|
537 str.push_back(c);
|
nuclear@0
|
538 }
|
nuclear@0
|
539 str.push_back('\0');
|
nuclear@0
|
540 ReadCounter++;
|
nuclear@0
|
541
|
nuclear@0
|
542 return str;
|
nuclear@0
|
543 }
|
nuclear@0
|
544 /*
|
nuclear@0
|
545 string ReadString(HANDLE file) {
|
nuclear@0
|
546 string str;
|
nuclear@0
|
547 char c;
|
nuclear@0
|
548 while(c = file.get()) {
|
nuclear@0
|
549 str.push_back(c);
|
nuclear@0
|
550 ReadCounter++;
|
nuclear@0
|
551 }
|
nuclear@0
|
552 str.push_back('\0');
|
nuclear@0
|
553 ReadCounter++;
|
nuclear@0
|
554
|
nuclear@0
|
555 return str;
|
nuclear@0
|
556 }
|
nuclear@0
|
557 */
|
nuclear@0
|
558
|
nuclear@0
|
559 Color ReadColor(HANDLE file) {
|
nuclear@0
|
560 ChunkHeader chunk = ReadChunkHeader(file);
|
nuclear@0
|
561 if(chunk.id < 0x0010 || chunk.id > 0x0013) return Color(-1.0f, -1.0f, -1.0f);
|
nuclear@0
|
562
|
nuclear@0
|
563 Color color;
|
nuclear@0
|
564
|
nuclear@0
|
565 if(chunk.id == Chunk_Color_Byte3 || chunk.id == Chunk_Color_GammaByte3) {
|
nuclear@0
|
566 byte r = ReadByte(file);
|
nuclear@0
|
567 byte g = ReadByte(file);
|
nuclear@0
|
568 byte b = ReadByte(file);
|
nuclear@0
|
569 color = Color(r, g, b);
|
nuclear@0
|
570 } else {
|
nuclear@0
|
571 color.r = ReadFloat(file);
|
nuclear@0
|
572 color.g = ReadFloat(file);
|
nuclear@0
|
573 color.b = ReadFloat(file);
|
nuclear@0
|
574 }
|
nuclear@0
|
575
|
nuclear@0
|
576 return color;
|
nuclear@0
|
577 }
|
nuclear@0
|
578
|
nuclear@0
|
579 Percent ReadPercent(HANDLE file) {
|
nuclear@0
|
580 ChunkHeader chunk = ReadChunkHeader(file);
|
nuclear@0
|
581 Percent p;
|
nuclear@0
|
582 if(chunk.id != Chunk_PercentInt && chunk.id != Chunk_PercentFloat) return p;
|
nuclear@0
|
583
|
nuclear@0
|
584 if(chunk.id == Chunk_PercentInt) {
|
nuclear@0
|
585 p = Percent(ReadWord(file));
|
nuclear@0
|
586 } else {
|
nuclear@0
|
587 p = Percent(ReadFloat(file));
|
nuclear@0
|
588 }
|
nuclear@0
|
589
|
nuclear@0
|
590 return p;
|
nuclear@0
|
591 }
|
nuclear@0
|
592
|
nuclear@0
|
593
|
nuclear@0
|
594 ChunkHeader ReadChunkHeader(HANDLE file) {
|
nuclear@0
|
595 ChunkHeader chunk;
|
nuclear@0
|
596 chunk.id = (ChunkID)ReadWord(file);
|
nuclear@0
|
597 chunk.size = ReadDword(file);
|
nuclear@0
|
598 return chunk;
|
nuclear@0
|
599 }
|
nuclear@0
|
600
|
nuclear@0
|
601 void SkipChunk(HANDLE file, const ChunkHeader &chunk) {
|
nuclear@0
|
602 //file.ignore(chunk.size - HeaderSize);
|
nuclear@0
|
603 SetFilePointer(file, chunk.size - HeaderSize, 0, FILE_CURRENT);
|
nuclear@0
|
604 ReadCounter += chunk.size - HeaderSize;
|
nuclear@0
|
605 }
|
nuclear@0
|
606
|
nuclear@0
|
607 void SkipBytes(HANDLE file, dword bytes) {
|
nuclear@0
|
608 SetFilePointer(file, bytes, 0, FILE_CURRENT);
|
nuclear@0
|
609 ReadCounter += bytes;
|
nuclear@0
|
610 }
|
nuclear@0
|
611
|
nuclear@0
|
612 Material *FindMaterial(string name) {
|
nuclear@0
|
613 dword i=0;
|
nuclear@0
|
614 while(i < MatCount) {
|
nuclear@0
|
615 if(mat[i].name == name) return &mat[i];
|
nuclear@0
|
616 i++;
|
nuclear@0
|
617 }
|
nuclear@0
|
618
|
nuclear@0
|
619 return 0;
|
nuclear@0
|
620 }
|
nuclear@0
|
621
|
nuclear@0
|
622 ///////////////////// Read Object Function //////////////////////
|
nuclear@0
|
623 int ReadObject(HANDLE file, const ChunkHeader &ch, void **obj) {
|
nuclear@0
|
624 if(!obj || !gc) return -1;
|
nuclear@0
|
625
|
nuclear@0
|
626 ReadCounter = HeaderSize; // reset the global read counter
|
nuclear@0
|
627
|
nuclear@0
|
628 string name = ReadString(file);
|
nuclear@0
|
629
|
nuclear@0
|
630 ChunkHeader chunk;
|
nuclear@0
|
631 chunk = ReadChunkHeader(file);
|
nuclear@0
|
632 if(chunk.id == Chunk_Obj_TriMesh) {
|
nuclear@0
|
633 // object is a trimesh... load it
|
nuclear@0
|
634 Vertex *varray;
|
nuclear@0
|
635 Triangle *tarray;
|
nuclear@0
|
636 dword VertexCount=0, TriCount=0;
|
nuclear@0
|
637 Material mat;
|
nuclear@0
|
638 Base base;
|
nuclear@0
|
639 Vector3 translation;
|
nuclear@0
|
640
|
nuclear@0
|
641 bool curve = true;
|
nuclear@0
|
642
|
nuclear@0
|
643 dword ObjChunkSize = ch.size;
|
nuclear@0
|
644
|
nuclear@0
|
645 while(ReadCounter < ObjChunkSize) { // make sure we only read subchunks of this object chunk
|
nuclear@0
|
646 //assert(!file.eof());
|
nuclear@0
|
647 assert(!eof);
|
nuclear@0
|
648 chunk = ReadChunkHeader(file);
|
nuclear@0
|
649
|
nuclear@0
|
650 switch(chunk.id) {
|
nuclear@0
|
651 case Chunk_TriMesh_VertexList:
|
nuclear@0
|
652 VertexCount = (dword)ReadWord(file);
|
nuclear@0
|
653 varray = new Vertex[VertexCount];
|
nuclear@0
|
654
|
nuclear@0
|
655 for(dword i=0; i<VertexCount; i++) {
|
nuclear@0
|
656 varray[i].pos = ReadVector(file);
|
nuclear@0
|
657 }
|
nuclear@0
|
658
|
nuclear@0
|
659 break;
|
nuclear@0
|
660
|
nuclear@0
|
661 case Chunk_TriMesh_FaceDesc:
|
nuclear@0
|
662 curve = false; // it is a real object not a curve since it has triangles
|
nuclear@0
|
663 TriCount = (dword)ReadWord(file);
|
nuclear@0
|
664 tarray = new Triangle[TriCount];
|
nuclear@0
|
665
|
nuclear@0
|
666 for(dword i=0; i<TriCount; i++) {
|
nuclear@0
|
667 tarray[i].vertices[0] = (Index)ReadWord(file); //
|
nuclear@0
|
668 tarray[i].vertices[2] = (Index)ReadWord(file); // flip order to CW
|
nuclear@0
|
669 tarray[i].vertices[1] = (Index)ReadWord(file); //
|
nuclear@0
|
670 ReadWord(file); // discard edge visibility flags
|
nuclear@0
|
671 }
|
nuclear@0
|
672 break;
|
nuclear@0
|
673
|
nuclear@0
|
674 case Chunk_Face_Material:
|
nuclear@0
|
675 mat = *FindMaterial(ReadString(file));
|
nuclear@0
|
676
|
nuclear@0
|
677 SkipBytes(file, ReadWord(file)<<1);
|
nuclear@0
|
678 break;
|
nuclear@0
|
679
|
nuclear@0
|
680 case Chunk_TriMesh_TexCoords:
|
nuclear@0
|
681 assert((dword)ReadWord(file) == VertexCount);
|
nuclear@0
|
682
|
nuclear@0
|
683 for(dword i=0; i<VertexCount; i++) {
|
nuclear@0
|
684 varray[i].tex[0].u = varray[i].tex[1].u = ReadFloat(file);
|
nuclear@0
|
685 varray[i].tex[0].v = varray[i].tex[1].v = -ReadFloat(file);
|
nuclear@0
|
686 }
|
nuclear@0
|
687 break;
|
nuclear@0
|
688
|
nuclear@0
|
689 case Chunk_TriMesh_SmoothingGroup:
|
nuclear@0
|
690 // **TODO** abide by smoothing groups duplicate vertices, weld others etc
|
nuclear@0
|
691 SkipChunk(file, chunk);
|
nuclear@0
|
692 break;
|
nuclear@0
|
693
|
nuclear@0
|
694 case Chunk_TriMesh_WorldTransform:
|
nuclear@0
|
695 base.i = ReadVector(file);
|
nuclear@0
|
696 base.k = ReadVector(file); // flip
|
nuclear@0
|
697 base.j = ReadVector(file);
|
nuclear@0
|
698 translation = ReadVector(file);
|
nuclear@0
|
699 break;
|
nuclear@0
|
700
|
nuclear@0
|
701 default:
|
nuclear@0
|
702 SkipChunk(file, chunk);
|
nuclear@0
|
703 }
|
nuclear@0
|
704 }
|
nuclear@0
|
705
|
nuclear@0
|
706 if(curve) {
|
nuclear@0
|
707 CatmullRomSpline *spline = new CatmullRomSpline;
|
nuclear@0
|
708 spline->name = name;
|
nuclear@0
|
709 for(dword i=0; i<VertexCount; i++) {
|
nuclear@0
|
710 spline->AddControlPoint(varray[i].pos);
|
nuclear@0
|
711 }
|
nuclear@0
|
712
|
nuclear@0
|
713 *obj = spline;
|
nuclear@0
|
714 return OBJ_CURVE;
|
nuclear@0
|
715 } else {
|
nuclear@0
|
716
|
nuclear@0
|
717 base.i.Normalize();
|
nuclear@0
|
718 base.j.Normalize();
|
nuclear@0
|
719 base.k.Normalize();
|
nuclear@0
|
720 Matrix3x3 RotXForm = base.CreateRotationMatrix();
|
nuclear@0
|
721 RotXForm.OrthoNormalize();
|
nuclear@0
|
722
|
nuclear@0
|
723 for(dword i=0; i<VertexCount; i++) {
|
nuclear@0
|
724 varray[i].pos.Translate(-translation.x, -translation.y, -translation.z);
|
nuclear@0
|
725 varray[i].pos.Transform(RotXForm.Transposed());
|
nuclear@0
|
726 }
|
nuclear@0
|
727
|
nuclear@0
|
728 Object *object = new Object(gc);
|
nuclear@0
|
729 object->name = name;
|
nuclear@0
|
730 object->GetTriMesh()->SetData(varray, tarray, VertexCount, TriCount);
|
nuclear@0
|
731 object->material = mat;
|
nuclear@0
|
732 object->SetRotation(RotXForm);
|
nuclear@0
|
733 object->SetTranslation(translation.x, translation.y, translation.z);
|
nuclear@0
|
734 *obj = object;
|
nuclear@0
|
735
|
nuclear@0
|
736 return OBJ_MESH;
|
nuclear@0
|
737 }
|
nuclear@0
|
738 } else {
|
nuclear@0
|
739
|
nuclear@0
|
740 if(chunk.id == Chunk_Obj_Light) {
|
nuclear@0
|
741
|
nuclear@0
|
742 dword ObjChunkSize = ch.size;
|
nuclear@0
|
743
|
nuclear@0
|
744 Vector3 pos = ReadVector(file);
|
nuclear@0
|
745 Color color = ReadColor(file);
|
nuclear@0
|
746
|
nuclear@0
|
747 Vector3 SpotTarget;
|
nuclear@0
|
748 float InnerCone, OuterCone;
|
nuclear@0
|
749 bool spot = false;
|
nuclear@0
|
750 bool att = false;
|
nuclear@0
|
751 bool CastShadows = false;
|
nuclear@0
|
752 float AttEnd = 10000.0f;
|
nuclear@0
|
753 float Intensity = 1.0f;
|
nuclear@0
|
754
|
nuclear@0
|
755 while(ReadCounter < ObjChunkSize) {
|
nuclear@0
|
756
|
nuclear@0
|
757 chunk = ReadChunkHeader(file);
|
nuclear@0
|
758
|
nuclear@0
|
759 switch(chunk.id) {
|
nuclear@0
|
760 case Chunk_Light_SpotLight:
|
nuclear@0
|
761 spot = true;
|
nuclear@0
|
762 SpotTarget = ReadVector(file);
|
nuclear@0
|
763 InnerCone = ReadFloat(file) / 180.0f;
|
nuclear@0
|
764 OuterCone = ReadFloat(file) / 180.0f;
|
nuclear@0
|
765 break;
|
nuclear@0
|
766
|
nuclear@0
|
767 case Chunk_Light_Attenuation:
|
nuclear@0
|
768 att = true;
|
nuclear@0
|
769 break;
|
nuclear@0
|
770
|
nuclear@0
|
771 case Chunk_Light_AttenuationEnd:
|
nuclear@0
|
772 AttEnd = ReadFloat(file);
|
nuclear@0
|
773 break;
|
nuclear@0
|
774
|
nuclear@0
|
775 case Chunk_Light_Intensity:
|
nuclear@0
|
776 Intensity = ReadFloat(file);
|
nuclear@0
|
777 break;
|
nuclear@0
|
778
|
nuclear@0
|
779 case Chunk_Spot_CastShadows:
|
nuclear@0
|
780 CastShadows = true;
|
nuclear@0
|
781 break;
|
nuclear@0
|
782
|
nuclear@0
|
783 default:
|
nuclear@0
|
784 SkipChunk(file, chunk);
|
nuclear@0
|
785 }
|
nuclear@0
|
786 }
|
nuclear@0
|
787
|
nuclear@0
|
788 Light *light;
|
nuclear@0
|
789 if(spot) {
|
nuclear@0
|
790 light = new TargetSpotLight(pos, SpotTarget, InnerCone, OuterCone);
|
nuclear@0
|
791 } else {
|
nuclear@0
|
792 light = new PointLight(pos);
|
nuclear@0
|
793 }
|
nuclear@0
|
794 light->SetColor(color);
|
nuclear@0
|
795 light->SetShadowCasting(CastShadows);
|
nuclear@0
|
796 light->SetIntensity(Intensity);
|
nuclear@0
|
797 light->name = name;
|
nuclear@0
|
798
|
nuclear@0
|
799 *obj = light;
|
nuclear@0
|
800 return spot ? OBJ_SPLIGHT : OBJ_PTLIGHT;
|
nuclear@0
|
801 }
|
nuclear@0
|
802
|
nuclear@0
|
803 if(chunk.id == Chunk_Obj_Camera) {
|
nuclear@0
|
804 Camera *cam = new Camera;
|
nuclear@0
|
805 Vector3 pos = ReadVector(file);
|
nuclear@0
|
806 Vector3 targ = ReadVector(file);
|
nuclear@0
|
807 float roll = ReadFloat(file);
|
nuclear@0
|
808 float FOV = ReadFloat(file);
|
nuclear@0
|
809
|
nuclear@0
|
810 Vector3 up = VECTOR3_J;
|
nuclear@0
|
811 Vector3 view = targ - pos;
|
nuclear@0
|
812 up.Rotate(view.Normalized(), roll);
|
nuclear@0
|
813
|
nuclear@0
|
814 cam->SetCamera(pos, targ, up);
|
nuclear@0
|
815 cam->name = name;
|
nuclear@0
|
816 cam->SetFOV(DEGTORAD(FOV) / 1.33333f);
|
nuclear@0
|
817
|
nuclear@0
|
818 *obj = cam;
|
nuclear@0
|
819 return OBJ_CAMERA;
|
nuclear@0
|
820 }
|
nuclear@0
|
821 }
|
nuclear@0
|
822
|
nuclear@0
|
823 return -1; // should have already left by now, if not something is wrong
|
nuclear@0
|
824 }
|
nuclear@0
|
825
|
nuclear@0
|
826
|
nuclear@0
|
827 ////////////////////////////////////////////////////////////////////////////////
|
nuclear@0
|
828 // functions to save/load normals from file
|
nuclear@0
|
829
|
nuclear@0
|
830 void WriteByte(HANDLE file, byte val) {
|
nuclear@0
|
831 dword junk;
|
nuclear@0
|
832 WriteFile(file, &val, sizeof(byte), &junk, 0);
|
nuclear@0
|
833 }
|
nuclear@0
|
834
|
nuclear@0
|
835 void WriteDword(HANDLE file, dword val) {
|
nuclear@0
|
836 dword junk;
|
nuclear@0
|
837 WriteFile(file, &val, sizeof(dword), &junk, 0);
|
nuclear@0
|
838 assert(junk == sizeof(dword));
|
nuclear@0
|
839 }
|
nuclear@0
|
840
|
nuclear@0
|
841 void WriteFloat(HANDLE file, float val) {
|
nuclear@0
|
842 dword junk;
|
nuclear@0
|
843 WriteFile(file, &val, sizeof(float), &junk, 0);
|
nuclear@0
|
844 assert(junk == sizeof(float));
|
nuclear@0
|
845 }
|
nuclear@0
|
846
|
nuclear@0
|
847 void WriteString(HANDLE file, string str) {
|
nuclear@0
|
848 dword junk;
|
nuclear@0
|
849 for(dword i=0; i<(dword)str.size(); i++) {
|
nuclear@0
|
850 WriteFile(file, &str[i], sizeof(char), &junk, 0);
|
nuclear@0
|
851 }
|
nuclear@0
|
852 }
|
nuclear@0
|
853
|
nuclear@0
|
854
|
nuclear@0
|
855 void SaveNormalsToFile(const char *fname, Scene *scene) {
|
nuclear@0
|
856
|
nuclear@0
|
857 HANDLE file = CreateFile(fname, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
|
nuclear@0
|
858 assert(file);
|
nuclear@0
|
859
|
nuclear@0
|
860 WriteDword(file, (dword)scene->GetObjectsList()->size());
|
nuclear@0
|
861
|
nuclear@0
|
862 std::list<Object*>::iterator objiter = scene->GetObjectsList()->begin();
|
nuclear@0
|
863 while(objiter != scene->GetObjectsList()->end()) {
|
nuclear@0
|
864 WriteString(file, (*objiter)->name);
|
nuclear@0
|
865 dword VertexCount = (*objiter)->GetTriMesh()->GetVertexCount();
|
nuclear@0
|
866 WriteDword(file, VertexCount);
|
nuclear@0
|
867
|
nuclear@0
|
868 const Vertex *varray = (*objiter)->GetTriMesh()->GetVertexArray();
|
nuclear@0
|
869 for(dword i=0; i<VertexCount; i++) {
|
nuclear@0
|
870 WriteFloat(file, varray[i].normal.x);
|
nuclear@0
|
871 WriteFloat(file, varray[i].normal.y);
|
nuclear@0
|
872 WriteFloat(file, varray[i].normal.z);
|
nuclear@0
|
873 }
|
nuclear@0
|
874
|
nuclear@0
|
875 objiter++;
|
nuclear@0
|
876 }
|
nuclear@0
|
877
|
nuclear@0
|
878 CloseHandle(file);
|
nuclear@0
|
879 }
|
nuclear@0
|
880
|
nuclear@0
|
881 bool LoadNormalsFromFile(const char *fname, Scene *scene) {
|
nuclear@0
|
882
|
nuclear@0
|
883 HANDLE file = CreateFile(fname, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
|
nuclear@0
|
884 if(!file) return false;
|
nuclear@0
|
885
|
nuclear@0
|
886 eof = false;
|
nuclear@0
|
887 ReadCounter = 0;
|
nuclear@0
|
888
|
nuclear@0
|
889 dword FileSize = SetFilePointer(file, 0, 0, FILE_END) - SetFilePointer(file, 0, 0, FILE_BEGIN);
|
nuclear@0
|
890
|
nuclear@0
|
891 SetFilePointer(file, 0, 0, FILE_BEGIN);
|
nuclear@0
|
892
|
nuclear@0
|
893 dword ObjectCount = ReadDword(file);
|
nuclear@0
|
894 if(ObjectCount != scene->GetObjectsList()->size()) { // detect changes
|
nuclear@0
|
895 CloseHandle(file);
|
nuclear@0
|
896 return false;
|
nuclear@0
|
897 }
|
nuclear@0
|
898
|
nuclear@0
|
899 while(SceneLoader::ReadCounter < FileSize) {
|
nuclear@0
|
900 string name = ReadString(file);
|
nuclear@0
|
901 dword VertexCount = ReadDword(file);
|
nuclear@0
|
902
|
nuclear@0
|
903 Object *obj = scene->GetObject(name.c_str());
|
nuclear@0
|
904 if(!obj) {
|
nuclear@0
|
905 CloseHandle(file);
|
nuclear@0
|
906 return false;
|
nuclear@0
|
907 }
|
nuclear@0
|
908
|
nuclear@0
|
909 if(VertexCount != obj->GetTriMesh()->GetVertexCount()) { // again detect changes
|
nuclear@0
|
910 CloseHandle(file);
|
nuclear@0
|
911 return false;
|
nuclear@0
|
912 }
|
nuclear@0
|
913
|
nuclear@0
|
914 Vertex *varray = obj->GetTriMesh()->GetModVertexArray();
|
nuclear@0
|
915 for(dword i=0; i<VertexCount; i++) {
|
nuclear@0
|
916 varray[i].normal = ReadVector(file, false);
|
nuclear@0
|
917 }
|
nuclear@0
|
918 }
|
nuclear@0
|
919
|
nuclear@0
|
920 CloseHandle(file);
|
nuclear@0
|
921 return true;
|
nuclear@0
|
922 }
|
nuclear@0
|
923
|