corrected CMake build
[nespa.git] / src / ModelType.cpp
blob29296cb449de8883119a2328078b104b2f9e6166
1 //By Karl Berg
2 //Last update Oct 17, 2003
3 //ModelType.cpp
4 //Loads, stores and displays .obj files on command
6 #include "ModelType.h"
8 bool useSmooth = 1;
9 bool useLights = 1;
11 ModelType::ModelType()
13 maxVerts.x = 0;
14 maxVerts.y = 0;
15 maxVerts.z = 0;
17 minVerts.x = 0;
18 minVerts.y = 0;
19 minVerts.z = 0;
21 myRadius = 0.0f;
22 myScale = 1.0f;
24 numObjects = 0;
25 tDispObj = NULL;
26 cDispObj = NULL;
28 FastSmooth = true;
31 ModelType::~ModelType()
33 DeleteModel();
36 void ModelType::Draw()
38 /* GLfloat n10Mat[] = { 1.00f, 1.00f, 1.00f, 1.00f };
39 GLfloat n05Mat[] = { 0.50f, 0.50f, 0.50f, 1.00f };
40 GLfloat n00Mat[] = { 0.00f, 0.00f, 0.00f, 1.00f };*/
41 GLfloat nullMat[] = { 0.00f, 0.00f, 0.00f, 1.00f };
44 glPushAttrib(GL_LINE_SMOOTH | GL_POLYGON_SMOOTH | GL_TEXTURE_2D | GL_BLEND);
45 // glEnable(GL_LINE_SMOOTH);
46 //glEnable(GL_POLYGON_SMOOTH);
47 glShadeModel(GL_SMOOTH);
48 // glEnable(GL_POLYGON_OFFSET_FILL);
49 // glEnable(GL_POLYGON_OFFSET_LINE);
50 glEnable(GL_BLEND);
51 glDisable(GL_CULL_FACE);
53 /*for (int i = 0; i < numObjects; i++)
56 glMaterialf(GL_FRONT, GL_SHININESS, 128 );
57 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
58 glMaterialfv(GL_FRONT, GL_SPECULAR, n10Mat);
59 glMaterialfv(GL_FRONT, GL_DIFFUSE, cDispObj[i].dMat);
60 glMaterialfv(GL_FRONT, GL_AMBIENT, cDispObj[i].aMat);
61 glColor3fv(cDispObj[i].dMat);
63 glCallList(cDispObj[i].DispList);
67 for (int i = 0; i < numObjects; i++)
70 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 64 /*cDispObj[i].SpecQty*/ );
71 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
72 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, cDispObj[i].sMat);
73 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, cDispObj[i].dMat);
74 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, cDispObj[i].aMat);
75 glPolygonOffset(1.0, 2.0);
76 glDepthMask(GL_TRUE);
78 if (cDispObj[i].hasTexts)
80 glBindTexture(GL_TEXTURE_2D, cDispObj[i].TextMap.texID);
81 glCallList(cDispObj[i].DispList);
82 glDepthMask(GL_FALSE);
83 if (cDispObj[i].hasEdges && useSmooth)
85 glPolygonOffset(1.0, 3.0);
86 if (FastSmooth)
87 glCallList(cDispObj[i].EdgeList);
88 else
90 glPolygonMode(GL_FRONT, GL_LINE);
91 glCallList(cDispObj[i].DispList);
92 glPolygonMode(GL_FRONT, GL_FILL);
96 else
98 glDisable(GL_TEXTURE_2D);
99 glCallList(cDispObj[i].DispList);
100 glDepthMask(GL_FALSE);
101 if (cDispObj[i].hasEdges && useSmooth)
103 glPolygonOffset(1.0, 3.0);
104 if (FastSmooth)
105 glCallList(cDispObj[i].EdgeList);
106 else
108 glPolygonMode(GL_FRONT, GL_LINE);
109 glCallList(cDispObj[i].DispList);
110 glPolygonMode(GL_FRONT, GL_FILL);
113 glEnable(GL_TEXTURE_2D);
116 if (useLights)
118 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
119 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, cDispObj[i].sMat);
120 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, nullMat);
121 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, nullMat);
122 glPolygonOffset(1.0, 1.0);
123 if (cDispObj[i].hasSpecs)
125 glBindTexture(GL_TEXTURE_2D, cDispObj[i].SpecMap.texID);
126 glCallList(cDispObj[i].DispList);
128 if (cDispObj[i].hasGlows)
130 glDisable(GL_LIGHTING);
131 glPolygonOffset(0.0, 0.0);
132 glBindTexture(GL_TEXTURE_2D, cDispObj[i].GlowMap.texID);
133 glCallList(cDispObj[i].DispList);
134 glEnable(GL_LIGHTING);
139 glPopAttrib();
142 bool ModelType::LoadObj(const char *filename, float Scale)
144 myScale = Scale;
146 const GLubyte *strRenderer;
147 strRenderer = glGetString (GL_RENDERER);
148 if ((strncmp((char*)strRenderer, "ATi Rage 128", 12) == 0) || (strncmp((char*)strRenderer, "ATI Rage 128", 12) == 0))
149 FastSmooth = false;
152 FastSmooth = false;
153 if (!ParseObj(filename))
154 return false;
156 // NormDispObj();
158 if (FastSmooth)
159 Build_Edge_List();
161 cDispObj = (OBJCModel*)malloc(sizeof(OBJCModel) * numObjects);
163 GenDispObj();
164 if (__E3D_ENGINE_DEBUG) printf("Completed loading model %s.\n\n", filename);
166 if (FastSmooth)
168 GenEdgeObj();
169 for (int i = 0; i < numObjects; i++)
171 if (tDispObj->group[i].objEdges != NULL)
173 Delete_Edge(tDispObj->group[i].objEdges);
174 tDispObj->group[i].objEdges = NULL;
179 for (int i = 0; i < numObjects; i++)
181 Delete_Face(tDispObj->group[i].objTngls);
182 Delete_Face(tDispObj->group[i].objQuads);
183 tDispObj->group[i].objTngls = NULL;
184 tDispObj->group[i].objQuads = NULL;
187 free(tDispObj);
188 tDispObj = NULL;
190 return true;
193 void ModelType::DeleteModel()
195 for (int i = 0; i < numObjects; i++)
197 glDeleteLists(cDispObj[i].DispList, 1);
198 glDeleteLists(cDispObj[i].EdgeList, 1);
200 DeleteTexture(cDispObj[i].TextMap);
201 DeleteTexture(cDispObj[i].GlowMap);
202 DeleteTexture(cDispObj[i].SpecMap);
206 void ModelType::Normalise_Vector(OBJVertex &vec)
208 float length;
210 length = sqrt((vec.x * vec.x) + (vec.y * vec.y) + (vec.z * vec.z));
212 if (length == 0.0f)
213 length = 1.0f;
215 vec.x /= length;
216 vec.y /= length;
217 vec.z /= length;
220 void ModelType::Calc_Norm_Vector(const OBJVertex& p1, const OBJVertex& p2, const OBJVertex& p3, OBJVertex &normal)
222 OBJVertex v1, v2;
224 v1.x = p1.x - p2.x;
225 v1.y = p1.y - p2.y;
226 v1.z = p1.z - p2.z;
228 v2.x = p2.x - p3.x;
229 v2.y = p2.y - p3.y;
230 v2.z = p2.z - p3.z;
232 normal.x = v1.y * v2.z - v1.z * v2.y;
233 normal.y = v1.z * v2.x - v1.x * v2.z;
234 normal.z = v1.x * v2.y - v1.y * v2.x;
236 Normalise_Vector(normal);
239 void ModelType::Delete_Edge(OBJEdge *currPtr)
241 if (currPtr->smlNext != NULL)
242 Delete_Edge(currPtr->smlNext);
243 if (currPtr->gtrNext != NULL)
244 Delete_Edge(currPtr->gtrNext);
245 currPtr->smlNext = NULL;
246 currPtr->gtrNext = NULL;
249 bool ModelType::Insert_Edge(OBJEdge *currPtr, OBJEdge *newEdge)
251 if (currPtr->gEdge < newEdge->gEdge)
253 if (currPtr->smlNext == NULL)
255 currPtr->smlNext = newEdge;
256 return true;
258 return Insert_Edge(currPtr->smlNext, newEdge);
261 if (currPtr->gEdge > newEdge->gEdge)
263 if (currPtr->gtrNext == NULL)
265 currPtr->gtrNext = newEdge;
266 return true;
268 return Insert_Edge(currPtr->gtrNext, newEdge);
271 if (currPtr->lEdge < newEdge->lEdge)
273 if (currPtr->smlNext == NULL)
275 currPtr->smlNext = newEdge;
276 return true;
278 return Insert_Edge(currPtr->smlNext, newEdge);
281 if (currPtr->lEdge > newEdge->lEdge)
283 if (currPtr->gtrNext == NULL)
285 currPtr->gtrNext = newEdge;
286 return true;
288 return Insert_Edge(currPtr->gtrNext, newEdge);
291 currPtr->lEdgeNorm.x += newEdge->lEdgeNorm.x;
292 currPtr->lEdgeNorm.y += newEdge->lEdgeNorm.y;
293 currPtr->lEdgeNorm.z += newEdge->lEdgeNorm.z;
294 currPtr->gEdgeNorm.x += newEdge->gEdgeNorm.x;
295 currPtr->gEdgeNorm.y += newEdge->gEdgeNorm.y;
296 currPtr->gEdgeNorm.z += newEdge->gEdgeNorm.z;
297 return false;
300 OBJEdge* ModelType::Add_New_Edge(OBJEdge *headPtr, int v1, int t1, const OBJVertex& n1, int v2, int t2, const OBJVertex& n2)
302 if (v1 == v2)
303 return headPtr;
305 OBJEdge *newEdge = (OBJEdge*)malloc(sizeof(OBJEdge));
306 if (v1 < v2)
308 newEdge->lEdge = v1;
309 newEdge->lEdgeText = t1;
310 newEdge->lEdgeNorm.x = n1.x;
311 newEdge->lEdgeNorm.y = n1.y;
312 newEdge->lEdgeNorm.z = n1.z;
313 newEdge->gEdge = v2;
314 newEdge->gEdgeText = t2;
315 newEdge->gEdgeNorm.x = n2.x;
316 newEdge->gEdgeNorm.y = n2.y;
317 newEdge->gEdgeNorm.z = n2.z;
319 else
321 newEdge->lEdge = v2;
322 newEdge->lEdgeText = t2;
323 newEdge->lEdgeNorm.x = n2.x;
324 newEdge->lEdgeNorm.y = n2.y;
325 newEdge->lEdgeNorm.z = n2.z;
326 newEdge->gEdge = v1;
327 newEdge->gEdgeText = t1;
328 newEdge->gEdgeNorm.x = n1.x;
329 newEdge->gEdgeNorm.y = n1.y;
330 newEdge->gEdgeNorm.z = n1.z;
332 newEdge->smlNext = NULL;
333 newEdge->gtrNext = NULL;
335 if (headPtr == NULL)
336 return newEdge;
338 if (!Insert_Edge(headPtr, newEdge))
339 free(newEdge);
341 return headPtr;
344 void ModelType::Build_Edge_List()
346 for (int i = 0; i < numObjects; i++)
348 OBJFace *currPtr;
350 currPtr = tDispObj->group[i].objTngls;
351 while (currPtr != NULL)
353 if (currPtr->NormType)
355 tDispObj->group[i].objEdges = Add_New_Edge(tDispObj->group[i].objEdges, currPtr->v1, currPtr->t1, tDispObj->objNorms[currPtr->n1],
356 currPtr->v2, currPtr->t2, tDispObj->objNorms[currPtr->n2]);
357 tDispObj->group[i].objEdges = Add_New_Edge(tDispObj->group[i].objEdges, currPtr->v2, currPtr->t2, tDispObj->objNorms[currPtr->n2],
358 currPtr->v3, currPtr->t3, tDispObj->objNorms[currPtr->n3]);
359 tDispObj->group[i].objEdges = Add_New_Edge(tDispObj->group[i].objEdges, currPtr->v3, currPtr->t3, tDispObj->objNorms[currPtr->n3],
360 currPtr->v1, currPtr->t1, tDispObj->objNorms[currPtr->n1]);
362 else
364 tDispObj->group[i].objEdges = Add_New_Edge(tDispObj->group[i].objEdges, currPtr->v1, currPtr->t1, currPtr->faceNorm,
365 currPtr->v2, currPtr->t2, currPtr->faceNorm);
366 tDispObj->group[i].objEdges = Add_New_Edge(tDispObj->group[i].objEdges, currPtr->v2, currPtr->t2, currPtr->faceNorm,
367 currPtr->v3, currPtr->t3, currPtr->faceNorm);
368 tDispObj->group[i].objEdges = Add_New_Edge(tDispObj->group[i].objEdges, currPtr->v3, currPtr->t3, currPtr->faceNorm,
369 currPtr->v1, currPtr->t1, currPtr->faceNorm);
371 currPtr = currPtr->next;
374 currPtr = tDispObj->group[i].objQuads;
375 while (currPtr != NULL)
377 if (currPtr->NormType)
379 tDispObj->group[i].objEdges = Add_New_Edge(tDispObj->group[i].objEdges, currPtr->v1, currPtr->t1, tDispObj->objNorms[currPtr->n1],
380 currPtr->v2, currPtr->t2, tDispObj->objNorms[currPtr->n2]);
381 tDispObj->group[i].objEdges = Add_New_Edge(tDispObj->group[i].objEdges, currPtr->v2, currPtr->t2, tDispObj->objNorms[currPtr->n2],
382 currPtr->v3, currPtr->t3, tDispObj->objNorms[currPtr->n3]);
383 tDispObj->group[i].objEdges = Add_New_Edge(tDispObj->group[i].objEdges, currPtr->v3, currPtr->t3, tDispObj->objNorms[currPtr->n3],
384 currPtr->v4, currPtr->t4, tDispObj->objNorms[currPtr->n4]);
385 tDispObj->group[i].objEdges = Add_New_Edge(tDispObj->group[i].objEdges, currPtr->v4, currPtr->t4, tDispObj->objNorms[currPtr->n4],
386 currPtr->v1, currPtr->t1, tDispObj->objNorms[currPtr->n1]);
388 else
390 tDispObj->group[i].objEdges = Add_New_Edge(tDispObj->group[i].objEdges, currPtr->v1, currPtr->t1, currPtr->faceNorm,
391 currPtr->v2, currPtr->t2, currPtr->faceNorm);
392 tDispObj->group[i].objEdges = Add_New_Edge(tDispObj->group[i].objEdges, currPtr->v2, currPtr->t2, currPtr->faceNorm,
393 currPtr->v3, currPtr->t3, currPtr->faceNorm);
394 tDispObj->group[i].objEdges = Add_New_Edge(tDispObj->group[i].objEdges, currPtr->v3, currPtr->t3, currPtr->faceNorm,
395 currPtr->v4, currPtr->t4, currPtr->faceNorm);
396 tDispObj->group[i].objEdges = Add_New_Edge(tDispObj->group[i].objEdges, currPtr->v4, currPtr->t4, currPtr->faceNorm,
397 currPtr->v1, currPtr->t1, currPtr->faceNorm);
399 currPtr = currPtr->next;
404 void ModelType::Delete_Face(OBJFace *headPtr)
406 OBJFace *currPtr = headPtr, *prevPtr;
407 while (currPtr != NULL)
409 prevPtr = currPtr;
410 currPtr = currPtr->next;
411 free(prevPtr);
415 void ModelType::Insert_Face(OBJFace *headPtr, OBJFace *newFace)
417 OBJFace *currPtr = headPtr;
418 while (currPtr->next != NULL)
419 currPtr = currPtr->next;
421 currPtr->next = newFace;
424 bool ModelType::LoadTGA_CMP(FILE *in_file, TextureImage &texture, GLubyte *imageData)
426 GLuint bytesPerPixel = texture.bpp / 8;
427 GLuint pixelcount = texture.height * texture.width;
428 GLuint currentpixel = 0;
429 GLuint currentbyte = 0;
430 GLubyte *colorbuffer = (GLubyte*)malloc(bytesPerPixel);
432 if (colorbuffer == NULL)
434 printf("error, unable to allocate memory!\n");
435 return false;
440 GLubyte chunkheader = 0;
441 if (fread(&chunkheader, sizeof(GLubyte), 1, in_file) == 0)
443 printf("error, could not read RLE header.\n");
444 free(colorbuffer);
445 return false;
448 if (chunkheader < 128)
450 short counter;
451 chunkheader++;
452 for (counter = 0; counter < chunkheader; counter++)
454 if (fread(colorbuffer, 1, bytesPerPixel, in_file) != bytesPerPixel)
456 printf("error, could not read image data.\n");
457 free(colorbuffer);
458 return false;
461 imageData[currentbyte ] = colorbuffer[2];
462 imageData[currentbyte + 1] = colorbuffer[1];
463 imageData[currentbyte + 2] = colorbuffer[0];
465 if (bytesPerPixel == 4)
466 imageData[currentbyte + 3] = colorbuffer[3];
468 currentbyte += bytesPerPixel;
469 currentpixel++;
471 if (currentpixel > pixelcount)
473 printf("error, too many pixels read.\n");
474 free(colorbuffer);
475 return false;
479 else
481 short counter;
482 chunkheader -= 127;
483 if (fread(colorbuffer, 1, bytesPerPixel, in_file) != bytesPerPixel)
485 printf("error, could not read from file.\n");
486 free(colorbuffer);
487 return false;
490 for (counter = 0; counter < chunkheader; counter++)
492 imageData[currentbyte ] = colorbuffer[2];
493 imageData[currentbyte + 1] = colorbuffer[1];
494 imageData[currentbyte + 2] = colorbuffer[0];
496 if (bytesPerPixel == 4)
497 imageData[currentbyte + 3] = colorbuffer[3];
499 currentbyte += bytesPerPixel;
500 currentpixel++;
502 if(currentpixel > pixelcount)
504 printf("error, too many pixels read.\n");
505 free(colorbuffer);
506 return false;
510 } while (currentpixel < pixelcount);
511 free(colorbuffer);
513 return true;
516 bool ModelType::LoadTGA_RAW(FILE *in_file, TextureImage &texture, GLubyte *imageData)
518 GLuint bytesPerPixel = texture.bpp / 8;
519 GLuint imageSize = texture.width * texture.height * bytesPerPixel;
520 GLuint temp;
522 if (fread(imageData, 1, imageSize, in_file) != imageSize)
524 printf("error, file appears to be damaged!\n");
525 return false;
528 for(int i = 0; i < int(imageSize); i += bytesPerPixel)
530 temp = imageData[i];
531 imageData[i] = imageData[i + 2];
532 imageData[i + 2] = temp;
535 return true;
538 bool ModelType::LoadTGA(TextureImage &texture, const char *filename, int UseMipMaps)
540 GLubyte RAW_Header[12] = { 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
541 GLubyte CMP_Header[12] = { 0, 0,10, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
542 GLubyte TGAcompare[12];
543 GLubyte header[6];
544 GLuint type = GL_RGBA;
545 GLubyte *imageData;
547 int fType = 0;
549 FILE *in_file = fopen(filename, "rb");
551 if (__E3D_ENGINE_DEBUG) printf("Loading texture %s: ", filename);
553 if (!in_file)
555 printf("error, file not found!\n");
556 return false;
559 if (fread(TGAcompare, 1, sizeof(TGAcompare), in_file) != sizeof(TGAcompare))
561 printf("error, invalid format!\n");
562 fclose(in_file);
563 return false;
566 if (memcmp(RAW_Header, TGAcompare, sizeof(TGAcompare)) == 0)
567 fType = 0;
568 else if (memcmp(CMP_Header, TGAcompare, sizeof(TGAcompare)) == 0)
569 fType = 1;
570 else
572 printf("error, invalid format!\n");
573 fclose(in_file);
574 return false;
577 if (fread(header, 1, sizeof(header), in_file) != sizeof(header))
579 printf("error, invalid format!\n");
580 fclose(in_file);
581 return false;
584 texture.width = header[1] * 256 + header[0];
585 texture.height = header[3] * 256 + header[2];
586 texture.bpp = header[4];
587 if (texture.width <= 0 || texture.height <= 0 || (texture.bpp != 24 && texture.bpp != 32))
589 printf("error, invalid format!\n");
590 fclose(in_file);
591 return false;
594 imageData = (GLubyte*)malloc(texture.width * texture.height * texture.bpp);
595 if (imageData == NULL)
597 printf("error, unable to allocate memory!\n");
598 fclose(in_file);
599 return false;
602 if (fType)
604 if (!LoadTGA_CMP(in_file, texture, imageData))
606 fclose(in_file);
607 free(imageData);
608 return false;
611 else
613 if (!LoadTGA_RAW(in_file, texture, imageData))
615 fclose(in_file);
616 free(imageData);
617 return false;
620 fclose(in_file);
622 glGenTextures(1, &texture.texID);
623 if (texture.bpp == 24)
624 type = GL_RGB;
626 glBindTexture(GL_TEXTURE_2D, texture.texID);
627 if (UseMipMaps)
629 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
630 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
631 gluBuild2DMipmaps(GL_TEXTURE_2D, 3, texture.width, texture.height, type, GL_UNSIGNED_BYTE, (GLvoid *)imageData);
633 else
635 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
636 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
637 glTexImage2D(GL_TEXTURE_2D, 0, type, texture.width, texture.height, 0, type, GL_UNSIGNED_BYTE, (GLvoid *)imageData);
640 free(imageData);
641 imageData = NULL;
643 /* printf("done.\n");
644 if (fType)
645 printf("-> Format of texture: RLE Compressed.\n");
646 else
647 printf("-> Format of texture: Uncompressed.\n");
648 printf("-> Width of texture: %d\n", (int)texture.width);
649 printf("-> Height of texture: %d\n", (int)texture.height);
650 printf("-> Bitdepth of texture: %d\n", (int)texture.bpp);*/
651 return true;
654 void ModelType::DeleteTexture(TextureImage &texture)
656 glDeleteTextures(1, &texture.texID);
659 bool ModelType::ParseMtl(const char *filename)
661 FILE *in_file;
662 char oneline[255];
663 int currMtrl = -1;
664 float cVal1, cVal2, cVal3;
665 int bVal;
666 char file[128];
667 sprintf(file,"data/ships/%s",filename);
668 if (__E3D_ENGINE_DEBUG) printf("Loading material library %s: ", filename);
669 in_file = fopen(file, "rt");
670 if (in_file == NULL)
672 printf("error, file not found!\n");
673 return false;
676 while (!feof(in_file))
678 if (better_fgets(oneline, 255, in_file) == NULL)
679 break;
681 if (strncmp(oneline, "newmtl", 6) == 0)
683 currMtrl++;
684 sscanf(oneline, "newmtl %s", tDispObj->mtrl[currMtrl].Name);
686 if (strncmp(oneline, "Ka", 2) == 0)
688 sscanf(oneline, "Ka %f %f %f", &cVal1, &cVal2, &cVal3);
689 tDispObj->mtrl[currMtrl].aCol.x = cVal1;
690 tDispObj->mtrl[currMtrl].aCol.y = cVal2;
691 tDispObj->mtrl[currMtrl].aCol.z = cVal3;
693 if (strncmp(oneline, "Kd", 2) == 0)
695 sscanf(oneline, "Kd %f %f %f", &cVal1, &cVal2, &cVal3);
696 tDispObj->mtrl[currMtrl].dCol.x = cVal1;
697 tDispObj->mtrl[currMtrl].dCol.y = cVal2;
698 tDispObj->mtrl[currMtrl].dCol.z = cVal3;
700 if (strncmp(oneline, "Ks", 2) == 0)
702 sscanf(oneline, "Ks %f %f %f", &cVal1, &cVal2, &cVal3);
703 tDispObj->mtrl[currMtrl].sCol.x = cVal1;
704 tDispObj->mtrl[currMtrl].sCol.y = cVal2;
705 tDispObj->mtrl[currMtrl].sCol.z = cVal3;
707 if (strncmp(oneline, "Tr", 2) == 0)
709 sscanf(oneline, "Tr %f", &cVal1);
710 tDispObj->mtrl[currMtrl].Opacity = cVal1;
712 if (strncmp(oneline, "Ns", 2) == 0)
714 sscanf(oneline, "Ns %f", &cVal1);
715 tDispObj->mtrl[currMtrl].Reflect = cVal1;
717 else if (strncmp(oneline, "map_Ka", 6) == 0)
718 sscanf(oneline, "map_Ka %s", tDispObj->mtrl[currMtrl].aTextName);
719 else if (strncmp(oneline, "map_Kd", 6) == 0)
720 sscanf(oneline, "map_Kd %s", tDispObj->mtrl[currMtrl].dTextName);
721 else if (strncmp(oneline, "map_Ks", 6) == 0)
722 sscanf(oneline, "map_Ks %s", tDispObj->mtrl[currMtrl].sTextName);
723 else if (sscanf(oneline, "Smooth %d", &bVal) == 1)
724 tDispObj->mtrl[currMtrl].SmthType = bVal;
725 else if (sscanf(oneline, "Normal %d", &bVal) == 1)
726 tDispObj->mtrl[currMtrl].NormType = bVal;
729 //printf("done.\n");
730 // printf("-> Number of materials: %d\n", ++currMtrl);
731 numObjects = currMtrl;
732 return true;
735 bool ModelType::ParseObj(const char *filename)
737 FILE *in_file;
738 char oneline[255];
739 char mtlname[255];
740 int currGroup = -1;
741 float x, y, z;
742 int iV1, iV2, iV3, iV4, iT1, iT2, iT3, iT4, iN1, iN2, iN3, iN4;
744 if (__E3D_ENGINE_DEBUG) printf("Loading model %s: ", filename);
745 in_file = fopen(filename, "rt");
746 if (in_file == NULL)
748 printf("error, file not found!\n");
749 return false;
751 // else
752 // printf("done.\n");
754 tDispObj = (OBJModel*)malloc(sizeof(OBJModel));
755 tDispObj->NumVerts = 0;
756 tDispObj->NumTexts = 0;
757 tDispObj->NumNorms = 0;
758 tDispObj->NumTngls = 0;
759 tDispObj->NumQuads = 0;
761 for (int i = 0; i < objMaxNumMats; i++)
763 tDispObj->group[i].objTngls = NULL;
764 tDispObj->group[i].objQuads = NULL;
765 tDispObj->group[i].objEdges = NULL;
766 tDispObj->group[i].matID = -1;
768 tDispObj->mtrl[i].Name[0] = '\0';
769 tDispObj->mtrl[i].aTextName[0] = '\0';
770 tDispObj->mtrl[i].dTextName[0] = '\0';
771 tDispObj->mtrl[i].sTextName[0] = '\0';
772 tDispObj->mtrl[i].NormType = 0;
773 tDispObj->mtrl[i].SmthType = 0;
774 tDispObj->mtrl[i].aCol.x = 1.0f;
775 tDispObj->mtrl[i].aCol.y = 1.0f;
776 tDispObj->mtrl[i].aCol.z = 1.0f;
777 tDispObj->mtrl[i].dCol.x = 1.0f;
778 tDispObj->mtrl[i].dCol.y = 1.0f;
779 tDispObj->mtrl[i].dCol.z = 1.0f;
780 tDispObj->mtrl[i].sCol.x = 1.0f;
781 tDispObj->mtrl[i].sCol.y = 1.0f;
782 tDispObj->mtrl[i].sCol.z = 1.0f;
783 tDispObj->mtrl[i].Reflect = 1.0f;
784 tDispObj->mtrl[i].Opacity = 1.0f;
787 while (!feof(in_file))
789 if (better_fgets(oneline, 255, in_file) == NULL)
790 break;
792 if (strncmp(oneline, "mtllib", 6) == 0)
794 if (sscanf(oneline, "mtllib %s", mtlname) == 1)
795 ParseMtl(mtlname);
798 if (strncmp(oneline, "usemtl", 6) == 0)
800 int matID = 0;
802 if ((sscanf(oneline, "usemtl %s", mtlname) == 1) && (numObjects != 0))
804 while (strncmp(mtlname, tDispObj->mtrl[matID].Name, 32) != 0)
806 matID++;
807 if (matID == numObjects)
808 break;
811 currGroup = matID;
812 tDispObj->group[currGroup].matID = matID;
815 if (sscanf(oneline, "v %f %f %f", &x, &y, &z) == 3)
817 x *= myScale;
818 y *= myScale;
819 z *= myScale;
820 tDispObj->objVerts[tDispObj->NumVerts].x = x;
821 tDispObj->objVerts[tDispObj->NumVerts].y = y;
822 tDispObj->objVerts[tDispObj->NumVerts].z = z;
823 tDispObj->NumVerts++;
824 if (x > maxVerts.x)
825 maxVerts.x = x;
826 if (y > maxVerts.y)
827 maxVerts.y = y;
828 if (z > maxVerts.z)
829 maxVerts.z = z;
830 if (x < minVerts.x)
831 minVerts.x = x;
832 if (y < minVerts.y)
833 minVerts.y = y;
834 if (z < minVerts.z)
835 minVerts.z = z;
837 else if (sscanf(oneline, "vt %f %f %f", &x, &y, &z) == 3)
839 tDispObj->objTexts[tDispObj->NumTexts].u = x;
840 tDispObj->objTexts[tDispObj->NumTexts].v = y;
841 tDispObj->objTexts[tDispObj->NumTexts].w = z;
842 tDispObj->NumTexts++;
844 else if (sscanf(oneline, "vt %f %f", &x, &y) == 2)
846 tDispObj->objTexts[tDispObj->NumTexts].u = x;
847 tDispObj->objTexts[tDispObj->NumTexts].v = y;
848 tDispObj->objTexts[tDispObj->NumTexts].w = 0.0f;
849 tDispObj->NumTexts++;
851 else if (sscanf(oneline, "vn %f %f %f", &x, &y, &z) == 3)
853 tDispObj->objNorms[tDispObj->NumNorms].x = x;
854 tDispObj->objNorms[tDispObj->NumNorms].y = y;
855 tDispObj->objNorms[tDispObj->NumNorms].z = z;
856 tDispObj->NumNorms++;
858 else if (sscanf(oneline, "f %d/%d/%d %d/%d/%d %d/%d/%d %d/%d/%d", &iV1, &iT1, &iN1, &iV2, &iT2, &iN2, &iV3, &iT3, &iN3, &iV4, &iT4, &iN4) == 12)
860 tDispObj->NumQuads++;
861 OBJFace *newFace = (OBJFace*)malloc(sizeof(OBJFace));
862 newFace->next = NULL;
864 newFace->v1 = (iV1 < 0) ? (tDispObj->NumVerts + iV1) : --iV1;
865 newFace->v2 = (iV2 < 0) ? (tDispObj->NumVerts + iV2) : --iV2;
866 newFace->v3 = (iV3 < 0) ? (tDispObj->NumVerts + iV3) : --iV3;
867 newFace->v4 = (iV4 < 0) ? (tDispObj->NumVerts + iV4) : --iV4;
869 newFace->t1 = (iT1 < 0) ? (tDispObj->NumTexts + iT1) : --iT1;
870 newFace->t2 = (iT2 < 0) ? (tDispObj->NumTexts + iT2) : --iT2;
871 newFace->t3 = (iT3 < 0) ? (tDispObj->NumTexts + iT3) : --iT3;
872 newFace->t4 = (iT4 < 0) ? (tDispObj->NumTexts + iT4) : --iT4;
874 newFace->n1 = (iN1 < 0) ? (tDispObj->NumNorms + iN1) : --iN1;
875 newFace->n2 = (iN2 < 0) ? (tDispObj->NumNorms + iN2) : --iN2;
876 newFace->n3 = (iN3 < 0) ? (tDispObj->NumNorms + iN3) : --iN3;
877 newFace->n4 = (iN4 < 0) ? (tDispObj->NumNorms + iN4) : --iN4;
879 newFace->NormType = 1;
880 if (currGroup == -1)
881 currGroup = numObjects;
882 if (tDispObj->group[currGroup].objQuads == NULL)
883 tDispObj->group[currGroup].objQuads = newFace;
884 else
885 Insert_Face(tDispObj->group[currGroup].objQuads, newFace);
887 else if (sscanf(oneline, "f %d/%d/%d %d/%d/%d %d/%d/%d", &iV1, &iT1, &iN1, &iV2, &iT2, &iN2, &iV3, &iT3, &iN3) == 9)
889 tDispObj->NumTngls++;
890 OBJFace *newFace = (OBJFace*)malloc(sizeof(OBJFace));
891 newFace->next = NULL;
893 newFace->v1 = (iV1 < 0) ? (tDispObj->NumVerts + iV1) : --iV1;
894 newFace->v2 = (iV2 < 0) ? (tDispObj->NumVerts + iV2) : --iV2;
895 newFace->v3 = (iV3 < 0) ? (tDispObj->NumVerts + iV3) : --iV3;
896 newFace->v4 = -1;
898 newFace->t1 = (iT1 < 0) ? (tDispObj->NumTexts + iT1) : --iT1;
899 newFace->t2 = (iT2 < 0) ? (tDispObj->NumTexts + iT2) : --iT2;
900 newFace->t3 = (iT3 < 0) ? (tDispObj->NumTexts + iT3) : --iT3;
901 newFace->t4 = -1;
903 newFace->n1 = (iN1 < 0) ? (tDispObj->NumNorms + iN1) : --iN1;
904 newFace->n2 = (iN2 < 0) ? (tDispObj->NumNorms + iN2) : --iN2;
905 newFace->n3 = (iN3 < 0) ? (tDispObj->NumNorms + iN3) : --iN3;
906 newFace->n4 = -1;
908 newFace->NormType = 1;
909 if (currGroup == -1)
910 currGroup = numObjects;
911 if (tDispObj->group[currGroup].objTngls == NULL)
912 tDispObj->group[currGroup].objTngls = newFace;
913 else
914 Insert_Face(tDispObj->group[currGroup].objTngls, newFace);
916 else if (sscanf(oneline, "f %d//%d %d//%d %d//%d %d//%d", &iV1, &iN1, &iV2, &iN2, &iV3, &iN3, &iV4, &iN4) == 8)
918 tDispObj->NumQuads++;
919 OBJFace *newFace = (OBJFace*)malloc(sizeof(OBJFace));
920 newFace->next = NULL;
922 newFace->v1 = (iV1 < 0) ? (tDispObj->NumVerts + iV1) : --iV1;
923 newFace->v2 = (iV2 < 0) ? (tDispObj->NumVerts + iV2) : --iV2;
924 newFace->v3 = (iV3 < 0) ? (tDispObj->NumVerts + iV3) : --iV3;
925 newFace->v4 = (iV4 < 0) ? (tDispObj->NumVerts + iV4) : --iV4;
927 newFace->t1 = -1;
928 newFace->t2 = -1;
929 newFace->t3 = -1;
930 newFace->t4 = -1;
932 newFace->n1 = (iN1 < 0) ? (tDispObj->NumNorms + iN1) : --iN1;
933 newFace->n2 = (iN2 < 0) ? (tDispObj->NumNorms + iN2) : --iN2;
934 newFace->n3 = (iN3 < 0) ? (tDispObj->NumNorms + iN3) : --iN3;
935 newFace->n4 = (iN4 < 0) ? (tDispObj->NumNorms + iN4) : --iN4;
937 newFace->NormType = 1;
938 if (currGroup == -1)
939 currGroup = numObjects;
940 if (tDispObj->group[currGroup].objQuads == NULL)
941 tDispObj->group[currGroup].objQuads = newFace;
942 else
943 Insert_Face(tDispObj->group[currGroup].objQuads, newFace);
945 else if (sscanf(oneline, "f %d/%d %d/%d %d/%d %d/%d", &iV1, &iT1, &iV2, &iT2, &iV3, &iT3, &iV4, &iT4) == 8)
947 tDispObj->NumQuads++;
948 OBJFace *newFace = (OBJFace*)malloc(sizeof(OBJFace));
949 newFace->next = NULL;
951 newFace->v1 = (iV1 < 0) ? (tDispObj->NumVerts + iV1) : --iV1;
952 newFace->v2 = (iV2 < 0) ? (tDispObj->NumVerts + iV2) : --iV2;
953 newFace->v3 = (iV3 < 0) ? (tDispObj->NumVerts + iV3) : --iV3;
954 newFace->v4 = (iV4 < 0) ? (tDispObj->NumVerts + iV4) : --iV4;
956 newFace->t1 = (iT1 < 0) ? (tDispObj->NumTexts + iT1) : --iT1;
957 newFace->t2 = (iT2 < 0) ? (tDispObj->NumTexts + iT2) : --iT2;
958 newFace->t3 = (iT3 < 0) ? (tDispObj->NumTexts + iT3) : --iT3;
959 newFace->t4 = (iT4 < 0) ? (tDispObj->NumTexts + iT4) : --iT4;
961 newFace->n1 = -1;
962 newFace->n2 = -1;
963 newFace->n3 = -1;
964 newFace->n4 = -1;
966 newFace->NormType = 0;
967 if (currGroup == -1)
968 currGroup = numObjects;
969 if (tDispObj->group[currGroup].objQuads == NULL)
970 tDispObj->group[currGroup].objQuads = newFace;
971 else
972 Insert_Face(tDispObj->group[currGroup].objQuads, newFace);
974 else if (sscanf(oneline, "f %d//%d %d//%d %d//%d", &iV1, &iN1, &iV2, &iN2, &iV3, &iN3) == 6)
976 tDispObj->NumTngls++;
977 OBJFace *newFace = (OBJFace*)malloc(sizeof(OBJFace));
978 newFace->next = NULL;
980 newFace->v1 = (iV1 < 0) ? (tDispObj->NumVerts + iV1) : --iV1;
981 newFace->v2 = (iV2 < 0) ? (tDispObj->NumVerts + iV2) : --iV2;
982 newFace->v3 = (iV3 < 0) ? (tDispObj->NumVerts + iV3) : --iV3;
983 newFace->v4 = -1;
985 newFace->t1 = -1;
986 newFace->t2 = -1;
987 newFace->t3 = -1;
988 newFace->t4 = -1;
990 newFace->n1 = (iN1 < 0) ? (tDispObj->NumNorms + iN1) : --iN1;
991 newFace->n2 = (iN2 < 0) ? (tDispObj->NumNorms + iN2) : --iN2;
992 newFace->n3 = (iN3 < 0) ? (tDispObj->NumNorms + iN3) : --iN3;
993 newFace->n4 = -1;
995 newFace->NormType = 1;
996 if (currGroup == -1)
997 currGroup = numObjects;
998 if (tDispObj->group[currGroup].objTngls == NULL)
999 tDispObj->group[currGroup].objTngls = newFace;
1000 else
1001 Insert_Face(tDispObj->group[currGroup].objTngls, newFace);
1003 else if (sscanf(oneline, "f %d/%d %d/%d %d/%d", &iV1, &iT1, &iV2, &iT2, &iV3, &iT3) == 6)
1005 tDispObj->NumTngls++;
1006 OBJFace *newFace = (OBJFace*)malloc(sizeof(OBJFace));
1007 newFace->next = NULL;
1009 newFace->v1 = (iV1 < 0) ? (tDispObj->NumVerts + iV1) : --iV1;
1010 newFace->v2 = (iV2 < 0) ? (tDispObj->NumVerts + iV2) : --iV2;
1011 newFace->v3 = (iV3 < 0) ? (tDispObj->NumVerts + iV3) : --iV3;
1012 newFace->v4 = -1;
1014 newFace->t1 = (iT1 < 0) ? (tDispObj->NumTexts + iT1) : --iT1;
1015 newFace->t2 = (iT2 < 0) ? (tDispObj->NumTexts + iT2) : --iT2;
1016 newFace->t3 = (iT3 < 0) ? (tDispObj->NumTexts + iT3) : --iT3;
1017 newFace->t4 = -1;
1019 newFace->n1 = -1;
1020 newFace->n2 = -1;
1021 newFace->n3 = -1;
1022 newFace->n4 = -1;
1024 newFace->NormType = 0;
1025 if (currGroup == -1)
1026 currGroup = numObjects;
1027 if (tDispObj->group[currGroup].objTngls == NULL)
1028 tDispObj->group[currGroup].objTngls = newFace;
1029 else
1030 Insert_Face(tDispObj->group[currGroup].objTngls, newFace);
1032 else if (sscanf(oneline, "f %d %d %d %d", &iV1, &iV2, &iV3, &iV4) == 4)
1034 tDispObj->NumQuads++;
1035 OBJFace *newFace = (OBJFace*)malloc(sizeof(OBJFace));
1036 newFace->next = NULL;
1038 newFace->v1 = (iV1 < 0) ? (tDispObj->NumVerts + iV1) : --iV1;
1039 newFace->v2 = (iV2 < 0) ? (tDispObj->NumVerts + iV2) : --iV2;
1040 newFace->v3 = (iV3 < 0) ? (tDispObj->NumVerts + iV3) : --iV3;
1041 newFace->v4 = (iV4 < 0) ? (tDispObj->NumVerts + iV4) : --iV4;
1043 newFace->t1 = -1;
1044 newFace->t2 = -1;
1045 newFace->t3 = -1;
1046 newFace->t4 = -1;
1048 newFace->n1 = -1;
1049 newFace->n2 = -1;
1050 newFace->n3 = -1;
1051 newFace->n4 = -1;
1053 newFace->NormType = 0;
1054 if (currGroup == -1)
1055 currGroup = numObjects;
1056 if (tDispObj->group[currGroup].objQuads == NULL)
1057 tDispObj->group[currGroup].objQuads = newFace;
1058 else
1059 Insert_Face(tDispObj->group[currGroup].objQuads, newFace);
1061 else if (sscanf(oneline, "f %d %d %d", &iV1, &iV2, &iV3) == 3)
1063 tDispObj->NumTngls++;
1064 OBJFace *newFace = (OBJFace*)malloc(sizeof(OBJFace));
1065 newFace->next = NULL;
1067 newFace->v1 = (iV1 < 0) ? (tDispObj->NumVerts + iV1) : --iV1;
1068 newFace->v2 = (iV2 < 0) ? (tDispObj->NumVerts + iV2) : --iV2;
1069 newFace->v3 = (iV3 < 0) ? (tDispObj->NumVerts + iV3) : --iV3;
1070 newFace->v4 = -1;
1072 newFace->t1 = -1;
1073 newFace->t2 = -1;
1074 newFace->t3 = -1;
1075 newFace->t4 = -1;
1077 newFace->n1 = -1;
1078 newFace->n2 = -1;
1079 newFace->n3 = -1;
1080 newFace->n4 = -1;
1082 newFace->NormType = 0;
1083 if (currGroup == -1)
1084 currGroup = numObjects;
1085 if (tDispObj->group[currGroup].objTngls == NULL)
1086 tDispObj->group[currGroup].objTngls = newFace;
1087 else
1088 Insert_Face(tDispObj->group[currGroup].objTngls, newFace);
1091 fclose(in_file);
1093 if (numObjects == 0)
1094 numObjects++;
1096 if (fabs(maxVerts.x) > myRadius)
1097 myRadius = fabs(maxVerts.x);
1098 if (fabs(maxVerts.y) > myRadius)
1099 myRadius = fabs(maxVerts.y);
1100 if (fabs(maxVerts.z) > myRadius)
1101 myRadius = fabs(maxVerts.z);
1102 if (fabs(minVerts.x) > myRadius)
1103 myRadius = fabs(maxVerts.x);
1104 if (fabs(minVerts.y) > myRadius)
1105 myRadius = fabs(maxVerts.y);
1106 if (fabs(minVerts.z) > myRadius)
1107 myRadius = fabs(maxVerts.z);
1109 // printf("-> Number of vertices: %d\n", tDispObj->NumVerts);
1110 // printf("-> Number of normals: %d\n", tDispObj->NumNorms);
1111 // printf("-> Number of tex coords: %d\n", tDispObj->NumTexts);
1112 // printf("-> Number of triangles: %d\n", tDispObj->NumTngls);
1113 // printf("-> Number of quads: %d\n", tDispObj->NumQuads);
1114 return true;
1117 void ModelType::DrawEdges(OBJEdge *theEdge)
1119 if (theEdge == NULL)
1120 return;
1122 Normalise_Vector(theEdge->lEdgeNorm);
1123 Normalise_Vector(theEdge->gEdgeNorm);
1125 glNormal3f(theEdge->lEdgeNorm.x, theEdge->lEdgeNorm.y, theEdge->lEdgeNorm.z);
1126 if (theEdge->lEdgeText >= 0)
1127 glTexCoord3f(tDispObj->objTexts[theEdge->lEdgeText].u, tDispObj->objTexts[theEdge->lEdgeText].v, tDispObj->objTexts[theEdge->lEdgeText].w);
1128 glVertex3d(tDispObj->objVerts[theEdge->lEdge].x, tDispObj->objVerts[theEdge->lEdge].y, tDispObj->objVerts[theEdge->lEdge].z);
1130 glNormal3f(theEdge->gEdgeNorm.x, theEdge->gEdgeNorm.y, theEdge->gEdgeNorm.z);
1131 if (theEdge->gEdgeText >= 0)
1132 glTexCoord3f(tDispObj->objTexts[theEdge->gEdgeText].u, tDispObj->objTexts[theEdge->gEdgeText].v, tDispObj->objTexts[theEdge->gEdgeText].w);
1133 glVertex3d(tDispObj->objVerts[theEdge->gEdge].x, tDispObj->objVerts[theEdge->gEdge].y, tDispObj->objVerts[theEdge->gEdge].z);
1135 DrawEdges(theEdge->smlNext);
1136 DrawEdges(theEdge->gtrNext);
1139 void ModelType::GenEdgeObj()
1141 for (int i = 0; i < numObjects; i++)
1143 if (!tDispObj->mtrl[i].SmthType)
1144 break;
1146 cDispObj[i].hasEdges = true;
1147 cDispObj[i].EdgeList = glGenLists(1);
1148 glNewList(cDispObj[i].EdgeList, GL_COMPILE);
1150 glBegin(GL_LINES);
1152 DrawEdges(tDispObj->group[i].objEdges);
1154 glEnd();
1156 glEndList();
1160 void ModelType::NormDispObj()
1162 OBJVertex myNormal;
1164 for (int i = 0; i < objMaxNumVerts; i++)
1166 tDispObj->objNorms[i].x = 0.0f;
1167 tDispObj->objNorms[i].y = 0.0f;
1168 tDispObj->objNorms[i].z = 0.0f;
1171 for (int i = 0; i < numObjects; i++)
1173 int currMat = tDispObj->group[i].matID;
1174 OBJFace *currPtr;
1176 currPtr = tDispObj->group[i].objTngls;
1177 while (currPtr != NULL)
1179 if (!currPtr->NormType)
1181 if (tDispObj->mtrl[currMat].NormType)
1183 Calc_Norm_Vector(tDispObj->objVerts[currPtr->v1], tDispObj->objVerts[currPtr->v2], tDispObj->objVerts[currPtr->v3], myNormal);
1184 tDispObj->objNorms[currPtr->v1].x += myNormal.x;
1185 tDispObj->objNorms[currPtr->v1].y += myNormal.y;
1186 tDispObj->objNorms[currPtr->v1].z += myNormal.z;
1187 tDispObj->objNorms[currPtr->v2].x += myNormal.x;
1188 tDispObj->objNorms[currPtr->v2].y += myNormal.y;
1189 tDispObj->objNorms[currPtr->v2].z += myNormal.z;
1190 tDispObj->objNorms[currPtr->v3].x += myNormal.x;
1191 tDispObj->objNorms[currPtr->v3].y += myNormal.y;
1192 tDispObj->objNorms[currPtr->v3].z += myNormal.z;
1193 currPtr->n1 = currPtr->v1;
1194 currPtr->n2 = currPtr->v2;
1195 currPtr->n3 = currPtr->v3;
1196 currPtr->NormType = 1;
1198 else
1200 Calc_Norm_Vector(tDispObj->objVerts[currPtr->v1], tDispObj->objVerts[currPtr->v2], tDispObj->objVerts[currPtr->v3], currPtr->faceNorm);
1203 currPtr = currPtr->next;
1206 currPtr = tDispObj->group[i].objQuads;
1207 while (currPtr != NULL)
1209 if (!currPtr->NormType)
1211 if (tDispObj->mtrl[currMat].NormType)
1213 Calc_Norm_Vector(tDispObj->objVerts[currPtr->v1], tDispObj->objVerts[currPtr->v2], tDispObj->objVerts[currPtr->v3], myNormal);
1214 tDispObj->objNorms[currPtr->v1].x += myNormal.x;
1215 tDispObj->objNorms[currPtr->v1].y += myNormal.y;
1216 tDispObj->objNorms[currPtr->v1].z += myNormal.z;
1217 tDispObj->objNorms[currPtr->v2].x += myNormal.x;
1218 tDispObj->objNorms[currPtr->v2].y += myNormal.y;
1219 tDispObj->objNorms[currPtr->v2].z += myNormal.z;
1220 tDispObj->objNorms[currPtr->v3].x += myNormal.x;
1221 tDispObj->objNorms[currPtr->v3].y += myNormal.y;
1222 tDispObj->objNorms[currPtr->v3].z += myNormal.z;
1223 tDispObj->objNorms[currPtr->v4].x += myNormal.x;
1224 tDispObj->objNorms[currPtr->v4].y += myNormal.y;
1225 tDispObj->objNorms[currPtr->v4].z += myNormal.z;
1226 currPtr->n1 = currPtr->v1;
1227 currPtr->n2 = currPtr->v2;
1228 currPtr->n3 = currPtr->v3;
1229 currPtr->n4 = currPtr->v4;
1230 currPtr->NormType = 1;
1232 else
1234 Calc_Norm_Vector(tDispObj->objVerts[currPtr->v1], tDispObj->objVerts[currPtr->v2], tDispObj->objVerts[currPtr->v3], currPtr->faceNorm);
1237 currPtr = currPtr->next;
1241 for (int i = 0; i < objMaxNumVerts; i++)
1243 Normalise_Vector(tDispObj->objNorms[i]);
1247 void ModelType::GenDispObj()
1249 for (int i = 0; i < numObjects; i++)
1251 OBJFace *currPtr;
1253 if (tDispObj->mtrl[i].dTextName[0] != '\0')
1254 cDispObj[i].hasTexts = LoadTGA(cDispObj[i].TextMap, tDispObj->mtrl[i].dTextName, 1);
1255 else
1256 cDispObj[i].hasTexts = false;
1257 if (tDispObj->mtrl[i].sTextName[0] != '\0')
1258 cDispObj[i].hasSpecs = LoadTGA(cDispObj[i].SpecMap, tDispObj->mtrl[i].sTextName, 1);
1259 else
1260 cDispObj[i].hasSpecs = false;
1261 if (tDispObj->mtrl[i].aTextName[0] != '\0')
1262 cDispObj[i].hasGlows = LoadTGA(cDispObj[i].GlowMap, tDispObj->mtrl[i].aTextName, 1);
1263 else
1264 cDispObj[i].hasGlows = false;
1266 cDispObj[i].SpecQty = tDispObj->mtrl[i].Reflect;
1267 cDispObj[i].dMat[0] = tDispObj->mtrl[i].dCol.x;
1268 cDispObj[i].dMat[1] = tDispObj->mtrl[i].dCol.y;
1269 cDispObj[i].dMat[2] = tDispObj->mtrl[i].dCol.z;
1270 cDispObj[i].dMat[3] = tDispObj->mtrl[i].Opacity;
1271 cDispObj[i].aMat[0] = tDispObj->mtrl[i].aCol.x;
1272 cDispObj[i].aMat[1] = tDispObj->mtrl[i].aCol.y;
1273 cDispObj[i].aMat[2] = tDispObj->mtrl[i].aCol.z;
1274 cDispObj[i].aMat[3] = tDispObj->mtrl[i].Opacity;
1275 cDispObj[i].sMat[0] = tDispObj->mtrl[i].sCol.x;
1276 cDispObj[i].sMat[1] = tDispObj->mtrl[i].sCol.y;
1277 cDispObj[i].sMat[2] = tDispObj->mtrl[i].sCol.z;
1278 cDispObj[i].sMat[3] = tDispObj->mtrl[i].Opacity;
1280 cDispObj[i].DispList = glGenLists(1);
1281 glNewList(cDispObj[i].DispList, GL_COMPILE);
1283 glBegin(GL_TRIANGLES);
1284 currPtr = tDispObj->group[i].objTngls;
1285 while (currPtr != NULL)
1287 if (!currPtr->NormType)
1288 glNormal3f(currPtr->faceNorm.x, currPtr->faceNorm.y, currPtr->faceNorm.z);
1289 else
1290 glNormal3f(tDispObj->objNorms[currPtr->n1].x, tDispObj->objNorms[currPtr->n1].y, tDispObj->objNorms[currPtr->n1].z);
1291 if (currPtr->t1 > 0)
1292 glTexCoord3f(tDispObj->objTexts[currPtr->t1].u, tDispObj->objTexts[currPtr->t1].v, tDispObj->objTexts[currPtr->t1].w);
1293 glVertex3f(tDispObj->objVerts[currPtr->v1].x, tDispObj->objVerts[currPtr->v1].y, tDispObj->objVerts[currPtr->v1].z);
1295 if (currPtr->NormType)
1296 glNormal3f(tDispObj->objNorms[currPtr->n2].x, tDispObj->objNorms[currPtr->n2].y, tDispObj->objNorms[currPtr->n2].z);
1297 if (currPtr->t2 > 0)
1298 glTexCoord3f(tDispObj->objTexts[currPtr->t2].u, tDispObj->objTexts[currPtr->t2].v, tDispObj->objTexts[currPtr->t2].w);
1299 glVertex3f(tDispObj->objVerts[currPtr->v2].x, tDispObj->objVerts[currPtr->v2].y, tDispObj->objVerts[currPtr->v2].z);
1301 if (currPtr->NormType)
1302 glNormal3f(tDispObj->objNorms[currPtr->n3].x, tDispObj->objNorms[currPtr->n3].y, tDispObj->objNorms[currPtr->n3].z);
1303 if (currPtr->t3 > 0)
1304 glTexCoord3f(tDispObj->objTexts[currPtr->t3].u, tDispObj->objTexts[currPtr->t3].v, tDispObj->objTexts[currPtr->t3].w);
1305 glVertex3f(tDispObj->objVerts[currPtr->v3].x, tDispObj->objVerts[currPtr->v3].y, tDispObj->objVerts[currPtr->v3].z);
1307 currPtr = currPtr->next;
1309 glEnd();
1311 glBegin(GL_QUADS);
1312 currPtr = tDispObj->group[i].objQuads;
1313 while (currPtr != NULL)
1315 if (!currPtr->NormType)
1316 glNormal3f(currPtr->faceNorm.x, currPtr->faceNorm.y, currPtr->faceNorm.z);
1317 else
1318 glNormal3f(tDispObj->objNorms[currPtr->n1].x, tDispObj->objNorms[currPtr->n1].y, tDispObj->objNorms[currPtr->n1].z);
1319 if (currPtr->t1 > 0)
1320 glTexCoord3f(tDispObj->objTexts[currPtr->t1].u, tDispObj->objTexts[currPtr->t1].v, tDispObj->objTexts[currPtr->t1].w);
1321 glVertex3f(tDispObj->objVerts[currPtr->v1].x, tDispObj->objVerts[currPtr->v1].y, tDispObj->objVerts[currPtr->v1].z);
1323 if (currPtr->NormType)
1324 glNormal3f(tDispObj->objNorms[currPtr->n2].x, tDispObj->objNorms[currPtr->n2].y, tDispObj->objNorms[currPtr->n2].z);
1325 if (currPtr->t2 > 0)
1326 glTexCoord3f(tDispObj->objTexts[currPtr->t2].u, tDispObj->objTexts[currPtr->t2].v, tDispObj->objTexts[currPtr->t2].w);
1327 glVertex3f(tDispObj->objVerts[currPtr->v2].x, tDispObj->objVerts[currPtr->v2].y, tDispObj->objVerts[currPtr->v2].z);
1329 if (currPtr->NormType)
1330 glNormal3f(tDispObj->objNorms[currPtr->n3].x, tDispObj->objNorms[currPtr->n3].y, tDispObj->objNorms[currPtr->n3].z);
1331 if (currPtr->t3 > 0)
1332 glTexCoord3f(tDispObj->objTexts[currPtr->t3].u, tDispObj->objTexts[currPtr->t3].v, tDispObj->objTexts[currPtr->t3].w);
1333 glVertex3f(tDispObj->objVerts[currPtr->v3].x, tDispObj->objVerts[currPtr->v3].y, tDispObj->objVerts[currPtr->v3].z);
1335 if (currPtr->NormType)
1336 glNormal3f(tDispObj->objNorms[currPtr->n4].x, tDispObj->objNorms[currPtr->n4].y, tDispObj->objNorms[currPtr->n4].z);
1337 if (currPtr->t4 > 0)
1338 glTexCoord3f(tDispObj->objTexts[currPtr->t4].u, tDispObj->objTexts[currPtr->t4].v, tDispObj->objTexts[currPtr->t4].w);
1339 glVertex3f(tDispObj->objVerts[currPtr->v4].x, tDispObj->objVerts[currPtr->v4].y, tDispObj->objVerts[currPtr->v4].z);
1341 currPtr = currPtr->next;
1343 glEnd();
1345 glEndList();
1349 char* better_fgets(char *line, int len, FILE *in_file)
1351 char *temp = line;
1352 int val;
1354 if (--len < 0)
1355 return NULL;
1357 if (len)
1361 val = getc(in_file);
1363 if (val == EOF)
1365 if (feof(in_file) && temp != line)
1366 break;
1367 else
1369 line = NULL;
1370 return NULL;
1373 *temp++ = val;
1374 } while (val != '\r' && val != '\n' && --len);
1376 *temp = '\0';
1378 return line;