From 8898ad9b25fca6afe2374d293a981db02a83d7e9 Mon Sep 17 00:00:00 2001 From: "FWoltermann@gmail.com" Date: Thu, 31 May 2012 14:46:27 +0000 Subject: Committing the documentation to svn to have it accessible online --- .../html/_model_file_m_a_g_8cpp_source.html | 931 +++++++++++++++++++++ 1 file changed, 931 insertions(+) create mode 100644 Doc/doxygen/html/_model_file_m_a_g_8cpp_source.html (limited to 'Doc/doxygen/html/_model_file_m_a_g_8cpp_source.html') diff --git a/Doc/doxygen/html/_model_file_m_a_g_8cpp_source.html b/Doc/doxygen/html/_model_file_m_a_g_8cpp_source.html new file mode 100644 index 0000000..591c7d0 --- /dev/null +++ b/Doc/doxygen/html/_model_file_m_a_g_8cpp_source.html @@ -0,0 +1,931 @@ + + + + + +Starshatter_Open: D:/SRC/StarshatterSVN/Magic2/ModelFileMAG.cpp Source File + + + + + + + + + + + + + +
+
+ + + + + + +
+
Starshatter_Open +
+
Open source Starshatter engine
+
+
+ + + + + +
+
+ +
+
+
+ +
+ + + + +
+ +
+ +
+
+
ModelFileMAG.cpp
+
+
+Go to the documentation of this file.
1 /* Project Magic 2.0
+
2  Destroyer Studios LLC
+
3  Copyright © 1997-2004. All Rights Reserved.
+
4 
+
5  SUBSYSTEM: Magic.exe
+
6  FILE: ModelFileMAG.cpp
+
7  AUTHOR: John DiCamillo
+
8 
+
9 
+
10  OVERVIEW
+
11  ========
+
12  File loader for MAG format models
+
13 */
+
14 
+
15 #include "stdafx.h"
+
16 #include "Magic.h"
+
17 #include "MagicDoc.h"
+
18 #include "ModelFileMAG.h"
+
19 
+
20 #include "Bitmap.h"
+
21 #include "Polygon.h"
+
22 #include "List.h"
+
23 
+
24 // +--------------------------------------------------------------------+
+
25 
+
26 struct MaterialMag6 {
+ + +
29  float power; // highlight sharpness (big=shiny)
+
30  float brilliance; // diffuse power function
+
31  float bump; // bump level (0=none)
+
32  DWORD blend; // alpha blend type
+
33  bool shadow; // material casts shadow
+
34  bool luminous; // verts have their own lighting
+
35 
+ + + + +
40 
+ + + + +
45 
+ + + + +
50 };
+
51 
+
52 // +--------------------------------------------------------------------+
+
53 
+
54 ModelFileMAG::ModelFileMAG(const char* fname)
+
55  : ModelFile(fname)
+
56 {
+
57 }
+
58 
+ +
60 {
+
61 }
+
62 
+
63 // +--------------------------------------------------------------------+
+
64 
+
65 bool
+
66 ModelFileMAG::Load(Model* m, double scale)
+
67 {
+
68  if (m && scale > 0 && strlen(filename) > 0) {
+
69  ModelFile::Load(m, scale);
+
70 
+
71  bool result = false;
+
72  FILE* fp = fopen(filename, "rb");
+
73 
+
74  // check MAG file:
+
75  if (!fp) {
+
76  ::MessageBox(0, "File Open Failed:\nMagic could not open the requested file.", "ERROR", MB_OK);
+
77  return result;
+
78  }
+
79 
+
80  ZeroMemory(pname, 64);
+
81  strncpy(pname, filename, 63);
+
82 
+
83  char file_id[5];
+
84  fread(file_id, 4, 1, fp);
+
85  file_id[4] = '\0';
+
86  int version = 1;
+
87 
+
88  if (!strcmp(file_id, "MAG6")) {
+
89  version = 6;
+
90  }
+
91  else if (!strcmp(file_id, "MAG5")) {
+
92  version = 5;
+
93  }
+
94  else if (!strcmp(file_id, "MAG4")) {
+
95  version = 4;
+
96  }
+
97  else {
+
98  ::MessageBox(0, "File Open Failed:\nThe requested file uses an invalid format.", "ERROR", MB_OK);
+
99  fclose(fp);
+
100  return result;
+
101  }
+
102 
+
103  // get ready to load, delete existing model:
+
104  m->GetSurfaces().destroy();
+
105  m->GetMaterials().destroy();
+
106  *pnverts = 0;
+
107  *pnpolys = 0;
+
108 
+
109  // now load the model:
+
110  switch (version) {
+
111  case 4:
+
112  case 5:
+
113  result = LoadMag5(fp, m, scale);
+
114  break;
+
115 
+
116  case 6:
+
117  result = LoadMag6(fp, m, scale);
+
118  break;
+
119 
+
120  default:
+
121  break;
+
122  }
+
123 
+
124  fclose(fp);
+
125  return true;
+
126  }
+
127 
+
128  return false;
+
129 }
+
130 
+
131 // +--------------------------------------------------------------------+
+
132 
+
133 bool
+ +
135 {
+
136  if (m) {
+
137  ModelFile::Save(m);
+
138 
+
139  FILE* fp = fopen(filename, "wb");
+
140  if (!fp) {
+
141  ::MessageBox(0, "Save Failed:\nMagic could not open the file for writing.", "ERROR", MB_OK);
+
142  return FALSE;
+
143  }
+
144 
+
145  fwrite("MAG6", 4, 1, fp);
+
146 
+
147  int i = 0;
+
148  int ntex = 0;
+
149  int nmtls = 0;
+
150  int nsurfs = m->NumSurfaces();
+
151  List<Bitmap> textures;
+
152 
+
153  ListIter<Material> m_iter = m->GetMaterials();
+
154  while (++m_iter) {
+
155  Material* mtl = m_iter.value();
+
156  Bitmap* bmp = mtl->tex_diffuse;
+
157 
+
158  if (bmp && !textures.contains(bmp)) {
+
159  textures.append(bmp);
+
160  }
+
161 
+
162  bmp = mtl->tex_specular;
+
163 
+
164  if (bmp && !textures.contains(bmp)) {
+
165  textures.append(bmp);
+
166  }
+
167 
+
168  bmp = mtl->tex_emissive;
+
169 
+
170  if (bmp && !textures.contains(bmp)) {
+
171  textures.append(bmp);
+
172  }
+
173 
+
174  bmp = mtl->tex_bumpmap;
+
175 
+
176  if (bmp && !textures.contains(bmp)) {
+
177  textures.append(bmp);
+
178  }
+
179 
+
180  nmtls++;
+
181  }
+
182 
+
183  ListIter<Bitmap> t_iter = textures;
+
184  while (++t_iter) {
+
185  Bitmap* bmp = t_iter.value();
+
186  ntex += strlen(bmp->GetFilename()) + 1;
+
187  }
+
188 
+
189  nsurfs = m->GetSurfaces().size();
+
190 
+
191  fwrite(&ntex, 4, 1, fp);
+
192  fwrite(&nmtls, 4, 1, fp);
+
193  fwrite(&nsurfs, 4, 1, fp);
+
194 
+
195  if (ntex) {
+
196  t_iter.reset();
+
197  while (++t_iter) {
+
198  Bitmap* bmp = t_iter.value();
+
199 
+
200  fwrite(bmp->GetFilename(),
+
201  strlen(bmp->GetFilename()) + 1,
+
202  1,
+
203  fp);
+
204  }
+
205  }
+
206 
+
207  if (nmtls) {
+
208  m_iter.reset();
+
209  while (++m_iter) {
+
210  Material* mtl = m_iter.value();
+
211  MaterialMag6 m6;
+
212 
+
213  ZeroMemory(&m6, sizeof(m6));
+
214 
+
215  CopyMemory(m6.name, mtl->name, Material::NAMELEN);
+
216  CopyMemory(m6.shader, mtl->shader, Material::NAMELEN);
+
217 
+
218  m6.ambient_value = mtl->ambient_value;
+
219  m6.ambient_color = mtl->ambient_color;
+
220  m6.diffuse_value = mtl->diffuse_value;
+
221  m6.diffuse_color = mtl->diffuse_color;
+
222  m6.specular_value = mtl->specular_value;
+
223  m6.specular_color = mtl->specular_color;
+
224  m6.emissive_value = mtl->emissive_value;
+
225  m6.emissive_color = mtl->emissive_color;
+
226 
+
227  m6.power = mtl->power;
+
228  m6.brilliance = mtl->brilliance;
+
229  m6.bump = mtl->bump;
+
230  m6.blend = mtl->blend;
+
231  m6.shadow = mtl->shadow;
+
232  m6.luminous = mtl->luminous;
+
233 
+
234  if (mtl->tex_diffuse)
+
235  m6.tex_diffuse = textures.index(mtl->tex_diffuse) + 1;
+
236 
+
237  if (mtl->tex_specular)
+
238  m6.tex_specular = textures.index(mtl->tex_specular) + 1;
+
239 
+
240  if (mtl->tex_emissive)
+
241  m6.tex_emissive = textures.index(mtl->tex_emissive) + 1;
+
242 
+
243  if (mtl->tex_bumpmap)
+
244  m6.tex_bumpmap = textures.index(mtl->tex_bumpmap) + 1;
+
245 
+
246  fwrite(&m6, sizeof(m6), 1, fp);
+
247  }
+
248  }
+
249 
+
250  ListIter<Surface> s_iter = m->GetSurfaces();
+
251  while (++s_iter) {
+
252  Surface* s = s_iter.value();
+
253 
+
254  int nverts = s->NumVerts();
+
255  int npolys = s->NumPolys();
+
256  BYTE namelen = strlen(s->Name()) + 1;
+
257 
+
258  fwrite(&nverts, 4, 1, fp);
+
259  fwrite(&npolys, 4, 1, fp);
+
260  fwrite(&namelen, 1, 1, fp);
+
261  fwrite(s->Name(), 1, namelen, fp);
+
262 
+
263  VertexSet* vset = s->GetVertexSet();
+
264  Poly* polys = s->GetPolys();
+
265 
+
266  // write vertex set:
+
267  for (int v = 0; v < nverts; v++) {
+
268  fwrite(&vset->loc[v], sizeof(float), 3, fp);
+
269  fwrite(&vset->nrm[v], sizeof(float), 3, fp);
+
270  fwrite(&vset->tu[v], sizeof(float), 1, fp);
+
271  fwrite(&vset->tv[v], sizeof(float), 1, fp);
+
272  }
+
273 
+
274  // write polys:
+
275  for (int n = 0; n < npolys; n++) {
+
276  Poly& poly = polys[n];
+
277  BYTE poly_nverts = (BYTE) poly.nverts;
+
278  BYTE material_index = 0;
+
279  WORD poly_verts[8];
+
280 
+
281  m_iter.reset();
+
282  while (++m_iter && !material_index) {
+
283  if (poly.material == m_iter.value())
+
284  material_index = m_iter.index() + 1;
+
285  }
+
286 
+
287  for (int i = 0; i < poly_nverts; i++) {
+
288  poly_verts[i] = poly.verts[i];
+
289  }
+
290 
+
291  fwrite(&poly_nverts, sizeof(BYTE), 1, fp);
+
292  fwrite(&material_index, sizeof(BYTE), 1, fp);
+
293  fwrite(&poly_verts[0], sizeof(WORD), poly_nverts, fp);
+
294  }
+
295  }
+
296 
+
297  return true;
+
298  }
+
299 
+
300  return false;
+
301 }
+
302 
+
303 // +--------------------------------------------------------------------+
+
304 
+ +
306 {
+
307  double distance;
+
308  double normal_x;
+
309  double normal_y;
+
310  double normal_z;
+
311  double normal_w;
+
312 };
+
313 
+
314 static void LoadPlane(Plane& p, FILE* fp)
+
315 {
+
316  HomogenousPlane tmp;
+
317  fread(&tmp, sizeof(HomogenousPlane), 1, fp);
+
318 }
+
319 
+
320 static void LoadFlags(LPDWORD flags, FILE* fp)
+
321 {
+
322  DWORD magic_flags;
+
323  fread(&magic_flags, sizeof(DWORD), 1, fp);
+
324 
+
336  const DWORD magic_mask = 0x0fc3;
+
337 
+
338  *flags = magic_flags & magic_mask;
+
339 }
+
340 
+
341 // +--------------------------------------------------------------------+
+
342 
+
343 static int mcomp(const void* a, const void* b)
+
344 {
+
345  Poly* pa = (Poly*) a;
+
346  Poly* pb = (Poly*) b;
+
347 
+
348  if (pa->sortval == pb->sortval)
+
349  return 0;
+
350 
+
351  if (pa->sortval < pb->sortval)
+
352  return -1;
+
353 
+
354  return 1;
+
355 }
+
356 
+
357 bool
+
358 ModelFileMAG::LoadMag5(FILE* fp, Model* m, double scale)
+
359 {
+
360  bool result = false;
+
361  int ntex = 0;
+
362  int nsurfs = 0;
+
363  double radius = 0;
+
364 
+
365  fread(&ntex, sizeof(ntex), 1, fp);
+
366  fread(&nsurfs, sizeof(nsurfs), 1, fp);
+
367 
+
368  // create a default gray material:
+
369  Material* mtl = new Material;
+
370 
+
371  if (mtl) {
+
372  mtl->Ka = Color::DarkGray;
+
373  mtl->Kd = Color::LightGray;
+
374  mtl->Ks = ColorValue(0.1f,0.1f,0.1f);
+
375  mtl->power = 10.0f;
+
376 
+
377  mtl->ambient_value = 0.2f;
+ +
379  mtl->diffuse_value = 0.8f;
+ +
381  mtl->specular_value = 0.5f;
+ +
383  strcpy_s(mtl->name, "(default)");
+
384 
+
385  m->GetMaterials().append(mtl);
+
386  }
+
387 
+
388  // read texture list:
+
389  for (int i = 0; i < ntex; i++) {
+
390  Material* mtl = new Material;
+
391  char tname[32];
+
392 
+
393  if (mtl) {
+
394  mtl->Ka = ColorValue(0.5f,0.5f,0.5f);
+
395  mtl->Kd = ColorValue(1.0f,1.0f,1.0f);
+
396  mtl->Ks = ColorValue(0.2f,0.2f,0.2f);
+
397  mtl->power = 20.0f;
+
398 
+
399  mtl->ambient_value = 1.0f;
+
400  mtl->ambient_color = Color::Gray;
+
401  mtl->diffuse_value = 1.0f;
+ +
403  mtl->specular_value = 0.2f;
+ +
405 
+
406  fread(tname, 32, 1, fp);
+ +
408  strcpy_s(mtl->name, tname);
+
409 
+
410  char* dot = strrchr(mtl->name, '.');
+
411  if (dot)
+
412  *dot = 0;
+
413 
+
414  char* plus = strrchr(mtl->name, '+');
+
415  if (plus)
+
416  *plus = 0;
+
417 
+
418  m->GetMaterials().append(mtl);
+
419  }
+
420  }
+
421 
+
422  int nverts = 0;
+
423  int npolys = 0;
+
424 
+
425  fread(&nverts, 4, 1, fp);
+
426  fread(&npolys, 4, 1, fp);
+
427 
+
428  // plan on creating four verts per poly:
+
429  int mag_nverts = nverts;
+
430  int next_vert = nverts;
+
431 
+
432  nverts = npolys * 4;
+
433  Surface* s = new Surface;
+
434  VertexSet* vset = 0;
+
435  Poly* polys = 0;
+
436 
+
437  if (s) {
+
438  s->SetName("default");
+
439  s->CreateVerts(nverts);
+
440  s->CreatePolys(npolys);
+
441 
+
442  vset = s->GetVertexSet();
+
443  polys = s->GetPolys();
+
444 
+
445  ZeroMemory(vset->loc, nverts * sizeof(Vec3));
+
446  ZeroMemory(vset->diffuse, nverts * sizeof(DWORD));
+
447  ZeroMemory(vset->specular, nverts * sizeof(DWORD));
+
448  ZeroMemory(vset->tu, nverts * sizeof(float));
+
449  ZeroMemory(vset->tv, nverts * sizeof(float));
+
450  ZeroMemory(vset->rw, nverts * sizeof(float));
+
451 
+
452  // read vertex set:
+
453  int v;
+
454  for (v = 0; v < mag_nverts; v++) {
+
455  Vec3 vert, norm;
+
456  DWORD vstate;
+
457 
+
458  fread(&vert, sizeof(Vec3), 1, fp);
+
459  fread(&norm, sizeof(Vec3), 1, fp);
+
460  fread(&vstate, sizeof(DWORD), 1, fp);
+
461 
+
462  vert.SwapYZ();
+
463  vert *= (float) scale;
+
464 
+
465  norm.SwapYZ();
+
466 
+
467  vset->loc[v] = vert;
+
468  vset->nrm[v] = norm;
+
469 
+
470  double d = vert.length();
+
471  if (d > radius)
+
472  radius = (float) d;
+
473  }
+
474 
+
475  while (v < nverts)
+
476  vset->nrm[v++] = Vec3(1,0,0);
+
477 
+
478  // read polys:
+
479  Vec3 dummy_center;
+
480  DWORD dummy_flags;
+
481  DWORD dummy_color;
+
482  int texture_num;
+
483  int poly_nverts;
+
484  int vert_index_buffer[32];
+
485  float texture_index_buffer[32];
+
486 
+
487  for (int n = 0; n < npolys; n++) {
+
488  Poly& poly = polys[n];
+
489  poly.vertex_set = vset;
+
490 
+
491  fread(&dummy_flags, sizeof(DWORD), 1, fp);
+
492  fread(&dummy_center, sizeof(Vec3), 1, fp);
+
493  LoadPlane(poly.plane, fp);
+
494  fread(&dummy_color, sizeof(DWORD), 1, fp);
+
495  fread(&texture_num, sizeof(int), 1, fp);
+
496 
+
497  if (texture_num >= 0 && texture_num < ntex) {
+
498  texture_num++;
+
499 
+
500  poly.material = m->GetMaterials()[texture_num];
+
501  poly.sortval = texture_num;
+
502 
+
503  if (dummy_flags & 2) { // luminous
+
504  Material* mtl = m->GetMaterials()[texture_num];
+
505 
+
506  mtl->ambient_value = 0.0f;
+ +
508  mtl->diffuse_value = 0.0f;
+ +
510  mtl->specular_value = 0.0f;
+ +
512  mtl->emissive_value = 1.0f;
+ +
514 
+
515  mtl->Ka = ColorValue(0,0,0,0);
+
516  mtl->Kd = ColorValue(0,0,0,0);
+
517  mtl->Ks = ColorValue(0,0,0,0);
+
518  mtl->Ke = ColorValue(1,1,1,1);
+
519 
+
520  mtl->tex_emissive = mtl->tex_diffuse;
+
521  }
+
522  }
+
523  else {
+
524  poly.material = m->GetMaterials().first(); // default material
+
525  poly.sortval = 1000;
+
526  }
+
527 
+
528  // hack: store flat shaded flag in unused visible byte
+
529  poly.visible = (BYTE) (dummy_flags & 1);
+
530 
+
531  fread(&poly_nverts, sizeof(int), 1, fp);
+
532  fread(vert_index_buffer, sizeof(int), poly_nverts, fp);
+
533 
+
534  if (poly_nverts == 3)
+
535  s->AddIndices(3);
+
536 
+
537  else if (poly_nverts == 4)
+
538  s->AddIndices(6);
+
539 
+
540  poly.nverts = poly_nverts;
+
541  for (int vi = 0; vi < poly_nverts; vi++) {
+
542  int v = vert_index_buffer[vi];
+
543 
+
544  if (vset->rw[v] > 0) {
+
545  vset->CopyVertex(next_vert, v);
+
546  v = next_vert++;
+
547  }
+
548 
+
549  vset->rw[v] = 1;
+
550  poly.verts[vi] = v;
+
551  }
+
552 
+
553  fread(texture_index_buffer, sizeof(float), poly_nverts, fp); // tu's
+
554  for (int vi = 0; vi < poly_nverts; vi++) {
+
555  int v = poly.verts[vi];
+
556  vset->tu[v] = texture_index_buffer[vi];
+
557  }
+
558 
+
559  fread(texture_index_buffer, sizeof(float), poly_nverts, fp); // tv's
+
560  for (int vi = 0; vi < poly_nverts; vi++) {
+
561  int v = poly.verts[vi];
+
562  vset->tv[v] = texture_index_buffer[vi];
+
563  }
+
564 
+
565  DWORD unused[32];
+
566  fread(unused, 16, 1, fp);
+
567  }
+
568 
+
569  // pass 2 (adjust vertex normals for flat polys):
+
570  for (int n = 0; n < npolys; n++) {
+
571  Poly& poly = polys[n];
+
572 
+
573  poly.plane = Plane(vset->loc[poly.verts[0]],
+
574  vset->loc[poly.verts[2]],
+
575  vset->loc[poly.verts[1]]);
+
576 
+
577  // hack: retrieve flat shaded flag from unused visible byte
+
578  if (poly.visible) {
+
579  int poly_nverts = poly.nverts;
+
580 
+
581  for (int vi = 0; vi < poly_nverts; vi++) {
+
582  int v = poly.verts[vi];
+
583  vset->nrm[v] = poly.plane.normal;
+
584  }
+
585  }
+
586  }
+
587 
+
588  // sort the polys by material index:
+
589  qsort((void*) polys, npolys, sizeof(Poly), mcomp);
+
590 
+
591  // then assign them to cohesive segments:
+
592  Segment* segment = 0;
+
593 
+
594  for (int n = 0; n < npolys; n++) {
+
595  if (segment && segment->material == polys[n].material) {
+
596  segment->npolys++;
+
597  }
+
598  else {
+
599  segment = 0;
+
600  }
+
601 
+
602  if (!segment) {
+
603  segment = new Segment;
+
604 
+
605  segment->npolys = 1;
+
606  segment->polys = &polys[n];
+
607  segment->material = segment->polys->material;
+
608 
+
609  s->GetSegments().append(segment);
+
610  }
+
611  }
+
612 
+
613  s->BuildHull();
+
614  m->GetSurfaces().append(s);
+
615 
+
616  *pnverts = nverts;
+
617  *pnpolys = npolys;
+
618  *pradius = (float) radius;
+
619 
+
620  result = nverts && npolys;
+
621  }
+
622 
+
623  return result;
+
624 }
+
625 
+
626 // +--------------------------------------------------------------------+
+
627 
+
628 bool
+
629 ModelFileMAG::LoadMag6(FILE* fp, Model* m, double scale)
+
630 {
+
631  bool result = false;
+
632  int i = 0;
+
633  int ntex = 0;
+
634  int nmtls = 0;
+
635  int nsurfs = 0;
+
636  double radius = 0;
+
637  List<Bitmap> textures;
+
638 
+
639  fread(&ntex, sizeof(ntex), 1, fp); // size of texture block
+
640  fread(&nmtls, sizeof(nmtls), 1, fp); // number of materials
+
641  fread(&nsurfs, sizeof(nsurfs), 1, fp); // number of surfaces
+
642 
+
643  // read texture list:
+
644  if (ntex) {
+
645  char* buffer = new char[ntex];
+
646  char* p = buffer;
+
647  Bitmap* bmp = 0;
+
648 
+
649  fread(buffer, ntex, 1, fp);
+
650 
+
651  while (p < buffer + ntex) {
+ +
653  textures.append(bmp);
+
654 
+
655  p += strlen(p) + 1;
+
656  }
+
657 
+
658  delete [] buffer;
+
659  }
+
660 
+
661  for (i = 0; i < nmtls; i++) {
+
662  MaterialMag6 m6;
+
663  Material* mtl = new Material;
+
664 
+
665  fread(&m6, sizeof(m6), 1, fp);
+
666 
+
667  if (mtl) {
+
668  CopyMemory(mtl->name, m6.name, Material::NAMELEN);
+
669  CopyMemory(mtl->shader, m6.shader, Material::NAMELEN);
+
670 
+
671  mtl->ambient_value = m6.ambient_value;
+
672  mtl->ambient_color = m6.ambient_color;
+
673  mtl->diffuse_value = m6.diffuse_value;
+
674  mtl->diffuse_color = m6.diffuse_color;
+
675  mtl->specular_value = m6.specular_value;
+
676  mtl->specular_color = m6.specular_color;
+
677  mtl->emissive_value = m6.emissive_value;
+
678  mtl->emissive_color = m6.emissive_color;
+
679 
+
680  mtl->Ka = ColorValue(mtl->ambient_color) * mtl->ambient_value;
+
681  mtl->Kd = ColorValue(mtl->diffuse_color) * mtl->diffuse_value;
+
682  mtl->Ks = ColorValue(mtl->specular_color) * mtl->specular_value;
+
683  mtl->Ke = ColorValue(mtl->emissive_color) * mtl->emissive_value;
+
684 
+
685  mtl->power = m6.power;
+
686  mtl->brilliance = m6.brilliance;
+
687  mtl->bump = m6.bump;
+
688  mtl->blend = m6.blend;
+
689  mtl->shadow = m6.shadow;
+
690  mtl->luminous = m6.luminous;
+
691 
+
692  if (m6.tex_diffuse && m6.tex_diffuse <= textures.size())
+
693  mtl->tex_diffuse = textures[m6.tex_diffuse - 1];
+
694 
+
695  if (m6.tex_specular && m6.tex_specular <= textures.size())
+
696  mtl->tex_specular = textures[m6.tex_specular - 1];
+
697 
+
698  if (m6.tex_emissive && m6.tex_emissive <= textures.size())
+
699  mtl->tex_emissive = textures[m6.tex_emissive - 1];
+
700 
+
701  if (m6.tex_bumpmap && m6.tex_bumpmap <= textures.size())
+
702  mtl->tex_bumpmap = textures[m6.tex_bumpmap - 1];
+
703 
+
704  m->GetMaterials().append(mtl);
+
705  }
+
706  }
+
707 
+
708  for (i = 0; i < nsurfs; i++) {
+
709  int nverts = 0;
+
710  int npolys = 0;
+
711  BYTE namelen = 0;
+
712  char name[128];
+
713 
+
714  fread(&nverts, 4, 1, fp);
+
715  fread(&npolys, 4, 1, fp);
+
716  fread(&namelen, 1, 1, fp);
+
717  fread(name, 1, namelen, fp);
+
718 
+
719  Surface* surface = new Surface;
+
720  surface->SetName(name);
+
721  surface->CreateVerts(nverts);
+
722  surface->CreatePolys(npolys);
+
723 
+
724  VertexSet* vset = surface->GetVertexSet();
+
725  Poly* polys = surface->GetPolys();
+
726 
+
727  ZeroMemory(polys, sizeof(Poly) * npolys);
+
728 
+
729  // read vertex set:
+
730  for (int v = 0; v < nverts; v++) {
+
731  fread(&vset->loc[v], sizeof(float), 3, fp);
+
732  fread(&vset->nrm[v], sizeof(float), 3, fp);
+
733  fread(&vset->tu[v], sizeof(float), 1, fp);
+
734  fread(&vset->tv[v], sizeof(float), 1, fp);
+
735 
+
736  double d = vset->loc[v].length();
+
737  if (d > radius)
+
738  radius = d;
+
739  }
+
740 
+
741  // read polys:
+
742  for (int n = 0; n < npolys; n++) {
+
743  Poly& poly = polys[n];
+
744  BYTE poly_nverts = 0;
+
745  BYTE material_index = 0;
+
746  WORD poly_verts[8];
+
747 
+
748  fread(&poly_nverts, sizeof(BYTE), 1, fp);
+
749  fread(&material_index, sizeof(BYTE), 1, fp);
+
750  fread(&poly_verts[0], sizeof(WORD), poly_nverts, fp);
+
751 
+
752  if (poly_nverts >= 3) {
+
753  poly.nverts = poly_nverts;
+
754 
+
755  for (int i = 0; i < poly_nverts; i++) {
+
756  poly.verts[i] = poly_verts[i];
+
757  }
+
758  }
+
759  else {
+
760  poly.sortval = 666;
+
761  }
+
762 
+
763  if (material_index > 0) {
+
764  poly.material = m->GetMaterials()[material_index-1];
+
765  poly.sortval = material_index;
+
766  }
+
767  else if (m->NumMaterials()) {
+
768  poly.material = m->GetMaterials().first();
+
769  poly.sortval = 1;
+
770  }
+
771  else {
+
772  poly.sortval = 1000;
+
773  }
+
774 
+
775  if (poly.nverts == 3)
+
776  surface->AddIndices(3);
+
777 
+
778  else if (poly.nverts == 4)
+
779  surface->AddIndices(6);
+
780 
+
781  poly.vertex_set = vset;
+
782  poly.plane = Plane(vset->loc[poly.verts[0]],
+
783  vset->loc[poly.verts[2]],
+
784  vset->loc[poly.verts[1]]);
+
785  }
+
786 
+
787  // sort the polys by material index:
+
788  qsort((void*) polys, npolys, sizeof(Poly), mcomp);
+
789 
+
790  // then assign them to cohesive segments:
+
791  Segment* segment = 0;
+
792 
+
793  for (int n = 0; n < npolys; n++) {
+
794  if (segment && segment->material == polys[n].material) {
+
795  segment->npolys++;
+
796  }
+
797  else {
+
798  segment = 0;
+
799  }
+
800 
+
801  if (!segment) {
+
802  segment = new Segment;
+
803 
+
804  segment->npolys = 1;
+
805  segment->polys = &polys[n];
+
806  segment->material = segment->polys->material;
+
807 
+
808  surface->GetSegments().append(segment);
+
809  }
+
810  }
+
811 
+
812  surface->ComputeTangents();
+
813  surface->BuildHull();
+
814  m->GetSurfaces().append(surface);
+
815 
+
816  *pnverts = nverts;
+
817  *pnpolys = npolys;
+
818  *pradius = (float) radius;
+
819 
+
820  result = nverts && npolys;
+
821  }
+
822 
+
823  return result;
+
824 }
+
825 
+
+
+ + + + -- cgit v1.1