1 /*
2     GL-117
3     Copyright 2001, 2002 Thomas A. Drexl aka heptargon
4 
5     This file is part of GL-117.
6 
7     GL-117 is free software; you can redistribute it and/or modify
8     it under the terms of the GNU General Public License as published by
9     the Free Software Foundation; either version 2 of the License, or
10     (at your option) any later version.
11 
12     GL-117 is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.
16 
17     You should have received a copy of the GNU General Public License
18     along with GL-117; if not, write to the Free Software
19     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20 */
21 
22 /* This file includes the memory representation of any 3D model.
23    For a detailed description of the data structure look at model.h */
24 
25 #ifndef IS_MODEL_H
26 
27 #include <stdio.h>
28 #include <string.h>
29 #include <stdlib.h>
30 #include <math.h>
31 
32 #include "model.h"
33 
34 #include "gl.h"
35 #include "mathtab.h"
36 #include "loader_tga.h"
37 
38 
39 
CColor()40 CColor::CColor ()
41 {
42   memset (c, 255, 4 * sizeof (unsigned char));
43 }
44 
CColor(CColor * col)45 CColor::CColor (CColor *col)
46 {
47   memcpy (c, col->c, 4 * sizeof (unsigned char));
48 }
49 
CColor(short cr,short cg,short cb)50 CColor::CColor (short cr, short cg, short cb)
51 {
52   c [0] = cr; c [1] = cg; c [2] = cb; c [3] = 255;
53 }
54 
CColor(short cr,short cg,short cb,short ca)55 CColor::CColor (short cr, short cg, short cb, short ca)
56 {
57   c [0] = cr; c [1] = cg; c [2] = cb; c [3] = ca;
58 }
59 
~CColor()60 CColor::~CColor () {}
61 
setColor(CColor * col)62 void CColor::setColor (CColor *col)
63 {
64   memcpy (c, col->c, 4 * sizeof (unsigned char));
65 }
66 
setColor(short cr,short cg,short cb,short ca)67 void CColor::setColor (short cr, short cg, short cb, short ca)
68 {
69   c [0] = cr; c [1] = cg; c [2] = cb; c [3] = ca;
70 }
71 
setColor(short cr,short cg,short cb)72 void CColor::setColor (short cr, short cg, short cb)
73 {
74   c [0] = cr; c [1] = cg; c [2] = cb; c [3] = 255;
75 }
76 
isEqual(CColor * col)77 bool CColor::isEqual (CColor *col)
78 {
79   return memcmp (c, col->c, 4 * sizeof (unsigned char)) == 0;
80 }
81 
take(CColor * col)82 void CColor::take (CColor *col)
83 {
84   memcpy (c, col->c, 4 * sizeof (unsigned char));
85 }
86 
87 
88 
CTexture()89 CTexture::CTexture ()
90 {
91   texlight = 1.0F; width = 0; height = 0; textureID = -1; data = NULL;
92   texred = 1.0F; texgreen = 1.0F; texblue = 1.0F;
93   mipmap = true; quality = 0;
94 }
95 
~CTexture()96 CTexture::~CTexture ()
97 {
98   if (data != NULL) delete data;
99 }
100 
loadFromTGA(char * fname,int quality,int alphatype,int mipmap)101 int CTexture::loadFromTGA (char *fname, int quality, int alphatype, int mipmap) // only 24 bit TGA
102 {
103   int i, i2;
104 
105 #ifdef LOADER_TGA_H
106   data = tga_load (fname, &width, &height); // global 32 bpp texture buffer
107   if (!data) return 0;
108 #else
109   unsigned char skip;
110   FILE *in = fopen (fname, "rb");
111   if (!in) return 0;
112   fread (&skip, 1, 1, in);
113   fseek (in, 12, SEEK_SET);
114   fread (&width, 2, 1, in);
115   fread (&height, 2, 1, in);
116   fseek (in, 18 + skip, SEEK_SET);
117   unsigned char *buf = (unsigned char *) malloc (width * height * 3); // preload file buffer
118   if (buf == NULL) error_outofmemory ();
119   data = (unsigned char *) malloc (width * height * 4); // global 32 bpp texture buffer
120   if (data == NULL) error_outofmemory ();
121   fread (buf, width * height * 3, 1, in);
122 #endif
123 
124   long texl = 0;
125   long texr = 0;
126   long texg = 0;
127   long texb = 0;
128 
129   for (i = 0; i < height; i ++)
130     for (i2 = 0; i2 < width; i2 ++)
131     {
132       int n2 = (i * width + i2)*4;
133 
134       texl += (int) data [n2+2] + data [n2+1] + data [n2];
135       texr += (int) data [n2];
136       texg += (int) data [n2 + 1];
137       texb += (int) data [n2 + 2];
138 
139       if (alphatype == 0) // alpha=255 or 0
140       {
141         if (data [n2+0] + data [n2+1] + data [n2+2] < 30)
142           data [n2+3] = 0;
143         else
144           data [n2+3] = 255;
145       }
146       else if (alphatype == 1) // alpha=maxcolor
147       {
148         int max = (data [n2+0] > data [n2+1] ? data [n2+0] : data [n2+1]);
149         max = (max > data [n2+2] ? max : data [n2+2]);
150         data [n2+3] = max;
151       }
152       else if (alphatype == 2) // alpha=red
153       {
154         data [n2+3] = data [n2];
155       }
156       else if (alphatype == 3) // alpha=midcolor*6 or 0
157       {
158         int test = (data [n2] + data [n2 + 1] + data [n2 + 2]) * 2;
159         if (test > 255) test = 255;
160         else if (test < 30) test = 0;
161         data [n2+3] = (unsigned char) test;
162       }
163       else if (alphatype == 4) // alpha=red, color=white
164       {
165         data [n2+3] = data [n2+0];
166         data [n2+0] = 255;
167         data [n2+1] = 255;
168         data [n2+2] = 255;
169       }
170       else if (alphatype == 5) // alpha=red*2, color=black
171       {
172         int test = data [n2+0] * 2;
173         if (test > 255) test = 255;
174         data [n2+3] = test;
175         data [n2+0] = 0;
176         data [n2+1] = 0;
177         data [n2+2] = 0;
178       }
179       else if (alphatype == 6) // alpha=red, color=black
180       {
181         data [n2+3] = data [n2+0];
182         data [n2+0] = 0;
183         data [n2+1] = 0;
184         data [n2+2] = 0;
185       }
186     }
187 
188 #ifndef LOADER_TGA_H
189   free (buf);
190 #endif
191 
192   texlight = (float) texl / width / height / 3 / 256; // average brightness
193   texred = (float) texr / width / height / 256; // average red
194   texgreen = (float) texg / width / height / 256; // average green
195   texblue = (float) texb / width / height / 256; // average blue
196   strcpy (name, fname);
197   this->quality = quality;
198   this->mipmap = (mipmap != 0);
199   return 1;
200 }
201 
getColor(CColor * c,int x,int y)202 void CTexture::getColor (CColor *c, int x, int y)
203 {
204   if (x < 0) x = (int) -x % width;
205   if (y < 0) y = (int) -y % height;
206   if (x >= width) x = (int) x % width;
207   if (y >= height) y = (int) y % height;
208   int offs = y * width + x;
209   offs <<= 2;
210   c->c [0] = data [offs];
211   c->c [1] = data [offs + 1];
212   c->c [2] = data [offs + 2];
213   c->c [3] = data [offs + 3];
214 }
215 
216 
217 
CVector3()218 CVector3::CVector3 ()
219 {
220   x = y = z = 0;
221 }
222 
CVector3(float x,float y,float z)223 CVector3::CVector3 (float x, float y, float z)
224 {
225   this->x = x; this->y = y; this->z = z;
226 }
227 
CVector3(CVector3 * v)228 CVector3::CVector3 (CVector3 *v)
229 {
230   x = v->x; y = v->y; z = v->z;
231 }
232 
set(float x,float y,float z)233 void CVector3::set (float x, float y, float z)
234 {
235   this->x = x; this->y = y; this->z = z;
236 }
237 
neg()238 void CVector3::neg ()
239 {
240   x = -x; y = -y; z = -z;
241 }
242 
add(CVector3 * v)243 void CVector3::add (CVector3 *v)
244 {
245   x += v->x; y += v->y; z += v->z;
246 }
247 
sub(CVector3 * v)248 void CVector3::sub (CVector3 *v)
249 {
250   x -= v->x; y -= v->y; z -= v->z;
251 }
252 
mul(float fac)253 void CVector3::mul (float fac)
254 {
255   x *= fac; y *= fac; z *= fac;
256 }
257 
crossproduct(CVector3 * v)258 void CVector3::crossproduct (CVector3 *v)
259 {
260   float nx = y * v->z - z * v->y;
261   float ny = z * v->x - x * v->z;
262   float nz = x * v->y - y * v->x;
263   x = nx; y = ny; z = nz;
264 }
265 
dotproduct(CVector3 * v)266 float CVector3::dotproduct (CVector3 *v)
267 {
268   return x * v->x + y * v->y + z * v->z;
269 }
270 
length()271 float CVector3::length ()
272 {
273   return (float) sqrt (x * x + y * y + z * z);
274 }
275 
norm()276 void CVector3::norm ()
277 {
278   float d = sqrt (x * x + y * y + z * z);
279   if (d == 0) d = 1E-10;
280   x /= d; y /= d; z /= d;
281 }
282 
isEqual(CVector3 * v)283 bool CVector3::isEqual (CVector3 *v)
284 {
285   return x == v->x && y == v->y && z == v->z;
286 }
287 
isEqual(CVector3 * v,float tol)288 bool CVector3::isEqual (CVector3 *v, float tol)
289 {
290   return x >= v->x - tol && x <= v->x + tol &&
291          y >= v->y - tol && y <= v->y + tol &&
292          z >= v->z - tol && z <= v->z + tol;
293 }
294 
take(CVector3 * v)295 void CVector3::take (CVector3 *v)
296 {
297   x = v->x; y = v->y; z = v->z;
298 }
299 
300 
301 
isEqual(CVector2 * v)302 bool CVector2::isEqual (CVector2 *v)
303 {
304   return x == v->x && y == v->y;
305 }
306 
isEqual(CVector2 * v,float tol)307 bool CVector2::isEqual (CVector2 *v, float tol)
308 {
309   return x >= v->x - tol && x <= v->x + tol &&
310          y >= v->y - tol && y <= v->y + tol;
311 }
312 
take(CVector2 * v)313 void CVector2::take (CVector2 *v)
314 {
315   x = v->x; y = v->y;
316 }
317 
318 
319 
CVertex()320 CVertex::CVertex ()
321 {
322   triangles = 0;
323 }
324 
CVertex(CVertex * v)325 CVertex::CVertex (CVertex *v)
326 {
327   take (v);
328 }
329 
addNormal(CVector3 * n)330 void CVertex::addNormal (CVector3 *n)
331 {
332   triangles ++;
333   normal.x = (normal.x * (triangles - 1) + n->x) / (float) triangles;
334   normal.y = (normal.y * (triangles - 1) + n->y) / (float) triangles;
335   normal.z = (normal.z * (triangles - 1) + n->z) / (float) triangles;
336 }
337 
addColor(CColor * c)338 void CVertex::addColor (CColor *c)
339 {
340   triangles ++;
341   for (int i = 0; i < 4; i ++)
342   {
343     color.c [i] = (unsigned char) (((float) color.c [i] * (triangles - 1) + c->c [i]) / (float) triangles);
344   }
345 }
346 
take(CVertex * v)347 void CVertex::take (CVertex *v)
348 {
349   vector.take (&v->vector);
350   normal.take (&v->normal);
351   color.take (&v->color);
352   triangles = v->triangles;
353 }
354 
355 
356 
357 double pitab;
358 float sintab [360], costab [360];
359 
CRotation()360 CRotation::CRotation ()
361 {
362   a = b = c = 0;
363   calcRotation ();
364   pitab = 4 * atan (1);
365   for (int i = 0; i < 360; i ++)
366   {
367     sintab [i] = sin (pitab / 180 * i);
368     costab [i] = cos (pitab / 180 * i);
369   }
370 }
371 
~CRotation()372 CRotation::~CRotation () {}
373 
setAngles(short a,short b,short c)374 void CRotation::setAngles (short a, short b, short c)
375 {
376   a %= 360;
377   if (a < 0) a += 360;
378   b %= 360;
379   if (b < 0) b += 360;
380   c %= 360;
381   if (c < 0) c += 360;
382   this->a = a;
383   this->b = b;
384   this->c = c;
385 }
386 
addAngles(short a,short b,short c)387 void CRotation::addAngles (short a, short b, short c)
388 {
389   this->a += a;
390   this->b += b;
391   this->c += c;
392   this->a %= 360;
393   if (this->a < 0) this->a += 360;
394   this->b %= 360;
395   if (this->b < 0) this->b += 360;
396   this->c %= 360;
397   if (this->c < 0) this->c += 360;
398 }
399 
calcRotation()400 void CRotation::calcRotation ()
401 {
402   rot [0] [0] = costab [c] * costab [b];
403   rot [0] [1] = sintab [a] * sintab [b] * costab [c] - sintab [c] * costab [a];
404   rot [0] [2] = sintab [a] * sintab [c] + costab [a] * sintab [b] * costab [c];
405   rot [1] [0] = sintab [c] * costab [b];
406   rot [1] [1] = costab [c] * costab [a] + sintab [a] * sintab [b] * sintab [c];
407   rot [1] [2] = costab [a] * sintab [b] * sintab [c] - sintab [a] * costab [c];
408   rot [2] [0] = -sintab [b];
409   rot [2] [1] = sintab [a] * costab [b];
410   rot [2] [2] = costab [a] * costab [b];
411 }
412 
rotateX(CVector3 * v)413 float CRotation::rotateX (CVector3 *v)
414 {
415   return v->x * rot [0] [0] + v->y * rot [0] [1] + v->z * rot [0] [2];
416 }
417 
rotateY(CVector3 * v)418 float CRotation::rotateY (CVector3 *v)
419 {
420   return v->x * rot [1] [0] + v->y * rot [1] [1] + v->z * rot [1] [2];
421 }
422 
rotateZ(CVector3 * v)423 float CRotation::rotateZ (CVector3 *v)
424 {
425   return v->x * rot [2] [0] + v->y * rot [2] [1] + v->z * rot [2] [2];
426 }
427 
getsintab(int a)428 float CRotation::getsintab (int a)
429 {
430   if (a >= 0 && a < 360) return sintab [a];
431   return 0;
432 }
433 
getcostabntab(int a)434 float CRotation::getcostabntab (int a)
435 {
436   if (a >= 0 && a < 360) return costab [a];
437   return 0;
438 }
439 
take(CRotation * r)440 void CRotation::take (CRotation *r)
441 {
442   a = r->a; b = r->b; c = r->c;
443 }
444 
445 
446 
getNormal(CVector3 * n)447 void CTriangle::getNormal (CVector3 *n)
448 {
449   CVector3 dummy;
450   n->take (&v [1]->vector);
451   n->sub (&v [0]->vector);
452   dummy.take (&v [2]->vector);
453   dummy.sub (&v [0]->vector);
454   n->crossproduct (&dummy);
455 }
456 
setVertices(CVertex * a,CVertex * b,CVertex * c)457 void CTriangle::setVertices (CVertex *a, CVertex *b, CVertex *c)
458 {
459   int i;
460   CVector3 dummy;
461   v [0] = a; v [1] = b; v [2] = c;
462   getNormal (&dummy);
463   dummy.norm ();
464   if (dummy.z > 0) dummy.neg ();
465   for (i = 0; i < 3; i ++)
466   { v [i]->addNormal (&dummy); }
467 }
468 
469 
470 
getNormal(CVector3 * n)471 void CQuad::getNormal (CVector3 *n)
472 {
473   CVector3 dummy;
474   n->take (&v [1]->vector);
475   n->sub (&v [0]->vector);
476   dummy.take (&v [3]->vector);
477   dummy.sub (&v [0]->vector);
478   n->crossproduct (&dummy);
479 }
480 
setVertices(CVertex * a,CVertex * b,CVertex * c,CVertex * d)481 void CQuad::setVertices (CVertex *a, CVertex *b, CVertex *c, CVertex *d)
482 {
483   int i;
484   CVector3 dummy;
485   v [0] = a; v [1] = b; v [2] = c; v [3] = d;
486   getNormal (&dummy);
487   dummy.norm ();
488   if (dummy.z > 0) dummy.neg ();
489   for (i = 0; i < 4; i ++)
490   { v [i]->addNormal (&dummy); }
491 }
492 
493 
494 
CMaterial()495 CMaterial::CMaterial ()
496 {
497   uscale = 1;
498   vscale = 1;
499   uoffset = 0;
500   voffset = 0;
501   wrot = 0;
502   char tmp [255] = {0};
503   strcpy (filename, tmp);
504   strcpy (name, tmp);
505 }
506 
507 
508 
CObject()509 CObject::CObject ()
510 {
511   numVertices = 0;
512   numTriangles = 0;
513   numQuads = 0;
514   numTexVertex = 0;
515   material = NULL;
516   hasTexture = false;
517 }
518 
~CObject()519 CObject::~CObject ()
520 {
521 }
522 
addVertex(CVertex * w)523 int CObject::addVertex (CVertex *w)
524 {
525   int i;
526   for (i = 0; i < numVertices; i ++)
527     if (w->vector.isEqual (&vertex [i].vector, 1e-3F) && w->color.isEqual (&vertex [i].color)) break;
528   if (i == numVertices)
529   vertex [numVertices ++].take (w);
530   return i;
531 }
532 
setColor(CColor * col)533 void CObject::setColor (CColor *col)
534 {
535   int i;
536   for (i = 0; i < numVertices; i ++)
537     memcpy (vertex [i].color.c, col, 4 * sizeof (unsigned char));
538 }
539 
540 
541 
CModel()542 CModel::CModel ()
543 {
544   numObjects = 0;
545   numMaterials = 0;
546   shading = 0;
547   displaylist = true;
548   list1 = -1;
549   list2 = -1;
550   list3 = -1;
551   scale = 1.0F;
552   name [0] = '0';
553   nolight = false;
554   alpha = false;
555   light_ambient [0] = 0.3; light_ambient [1] = 0.3; light_ambient [2] = 0.3; light_ambient [3] = 1;
556   light_diffuse [0] = 0.9; light_diffuse [1] = 0.9; light_diffuse [2] = 0.9; light_diffuse [3] = 1;
557   light_ambient2 [0] = 0.2; light_ambient2 [1] = 0.2; light_ambient2 [2] = 0.2; light_ambient2 [3] = 1;
558   light_diffuse2 [0] = 0.1; light_diffuse2 [1] = 0.1; light_diffuse2 [2] = 0.1; light_diffuse [3] = 1;
559   numRefpoints = 0;
560   refpoint = NULL;
561   va = new VertexArray (VERTEXARRAY_V3N3C4T2);
562 }
563 
setName(char * name)564 void CModel::setName (char *name)
565 {
566   strcpy (this->name, name);
567 }
568 
addMaterial(CMaterial * material)569 void CModel::addMaterial (CMaterial *material)
570 {
571   this->material [numMaterials] = new CMaterial;
572   if (this->material [numMaterials] == NULL) exit (100);
573   if (material != NULL) memcpy (this->material [numMaterials], material, sizeof (CMaterial));
574   numMaterials ++;
575 }
576 
addObject(CObject * object)577 void CModel::addObject (CObject *object)
578 {
579   this->object [numObjects] = new CObject;
580   if (this->object [numObjects] == NULL) exit (101);
581   if (object != NULL) memcpy (this->object [numObjects], object, sizeof (CObject));
582   numObjects ++;
583   rotcol = 0;
584 }
585 
addRefPoint(CVector3 * tl)586 void CModel::addRefPoint (CVector3 *tl)
587 {
588   int i, i2;
589   if (refpoint == NULL)
590   {
591     refpoint = new CVector3 [10];
592   }
593   for (i = 0; i < numRefpoints; i ++)
594   {
595     if (tl->z < refpoint [i].z)
596     {
597       for (i2 = numRefpoints; i2 > i; i2 --)
598       {
599         refpoint [i2].take (&refpoint [i2 - 1]);
600       }
601       refpoint [i].take (tl);
602       goto fertigref1;
603     }
604   }
605   refpoint [numRefpoints].take (tl);
606 fertigref1:;
607   numRefpoints ++;
608 }
609 
~CModel()610 CModel::~CModel ()
611 {
612   int i;
613   for (i = 0; i < numMaterials; i ++)
614     delete material [i];
615   for (i = 0; i < numObjects; i ++)
616     delete object [i];
617   if (refpoint)
618   {
619     delete refpoint;
620   }
621 }
622 
setColor(CColor * col)623 void CModel::setColor (CColor *col)
624 {
625   int i;
626   for (i = 0; i < numObjects; i++)
627   {
628     object [i]->setColor (col);
629   }
630 }
631 
drawVertexNormals(CObject * cm,float zoom)632 void CModel::drawVertexNormals (CObject *cm, float zoom)
633 {
634   glColor3ub (255, 0, 0);
635   glBegin (GL_LINES);
636   for (int j = 0; j < cm->numVertices; j++)
637   if (cm->vertex [j].triangles > 0)
638   {
639     glVertex3f (cm->vertex [j].vector.x*zoom, cm->vertex [j].vector.y*zoom, cm->vertex [j].vector.z*zoom);
640     glVertex3f ((cm->vertex [j].vector.x + cm->vertex [j].normal.x / 5)*zoom, (cm->vertex [j].vector.y + cm->vertex [j].normal.y / 5)*zoom, (cm->vertex [j].vector.z + cm->vertex [j].normal.z / 5)*zoom);
641   }
642   glEnd ();
643 }
644 
rotateColor(int n)645 int CModel::rotateColor (int n)
646 {
647   if (n == 0) return 0;
648   rotcol ++;
649   if (rotcol > n) rotcol = 0;
650   return rotcol;
651 }
652 
scaleTexture(float fx,float fy)653 void CModel::scaleTexture (float fx, float fy)
654 {
655   int i;
656   for (i = 0; i < numObjects; i ++)
657   {
658     CObject *o = object [i];
659     int i2;
660     for (i2 = 0; i2 < o->numVertices; i2 ++)
661     {
662       o->vertex [i2].tex.x *= fx;
663       o->vertex [i2].tex.y *= fy;
664     }
665   }
666 }
667 
draw(CVector3 * tl,CVector3 * tl2,CRotation * rot,float zoom,float lum,int explode)668 void CModel::draw (CVector3 *tl, CVector3 *tl2, CRotation *rot, float zoom, float lum, int explode)
669 {
670   if (nolight) // if model wants to be rendered without light, call draw2
671   {
672     glDisable (GL_LIGHTING);
673     draw2 (tl, tl2, rot, zoom, explode);
674     glEnable (GL_LIGHTING);
675     return;
676   }
677 
678   if (tl == NULL) tl = &tlnull;
679   if (tl2 == NULL) tl2 = &tlnull;
680   if (rot == NULL) rot = &rotnull;
681 
682   int i, j;
683   CObject *cm;
684   float la [4] = { 0.2, 0.2, 0.2, 1.0};
685   if (lum >= 1)
686   {
687     float addl = lum;
688     if (addl >= 5) addl = 5;
689     la [0] = 0.2 * addl;
690     la [1] = 0.2 * addl;
691     la [2] = 0.2 * addl;
692   }
693   glLightfv (GL_LIGHT0, GL_AMBIENT, la);
694 
695   float ld [4] = { 0.7, 0.7, 0.7, 1.0};
696   if (lum != 1)
697   {
698     ld [0] *= lum;
699     ld [1] *= lum;
700     ld [2] *= lum;
701     if (ld [0] > 1.0) ld [0] = 1.0;
702     if (ld [1] > 1.0) ld [1] = 1.0;
703     if (ld [2] > 1.0) ld [2] = 1.0;
704   }
705   glLightfv (GL_LIGHT0, GL_DIFFUSE, ld);
706 
707   for (i = 0; i < numObjects; i ++)
708   {
709     if (numObjects <= 0) break;
710     cm = object [i];
711     if (cm->hasTexture)
712     {
713       if (antialiasing)
714         gl->enableLinearTexture (cm->material->texture->textureID);
715       else
716         gl->disableLinearTexture (cm->material->texture->textureID);
717     }
718   }
719 
720   zoom *= scale;
721   glPushMatrix ();
722   glTranslatef (tl->x + tl2->x, tl->y + tl2->y - 0.002 * explode * explode / timestep / timestep, tl->z + tl2->z);
723   float explodefac = (float) explode / 10 / timestep;
724 
725   if (showcollision)
726   {
727     glPushMatrix ();
728     glScalef (cubex, cubey, cubez);
729     glColor3ub (255, 0, 0);
730     glBegin (GL_LINE_STRIP);
731     glVertex3f (1, 1, 1);
732     glVertex3f (1, 1, -1);
733     glVertex3f (1, -1, -1);
734     glVertex3f (1, -1, 1);
735     glVertex3f (1, 1, 1);
736     glEnd ();
737     glBegin (GL_LINE_STRIP);
738     glVertex3f (-1, 1, 1);
739     glVertex3f (-1, 1, -1);
740     glVertex3f (-1, -1, -1);
741     glVertex3f (-1, -1, 1);
742     glVertex3f (-1, 1, 1);
743     glEnd ();
744     glBegin (GL_LINES);
745     glVertex3f (1, 1, 1);
746     glVertex3f (-1, 1, 1);
747     glVertex3f (1, -1, -1);
748     glVertex3f (-1, -1, -1);
749     glVertex3f (1, -1, 1);
750     glVertex3f (-1, -1, 1);
751     glVertex3f (1, 1, -1);
752     glVertex3f (-1, 1, -1);
753     glEnd ();
754     glPopMatrix ();
755   }
756 
757   glRotatef (rot->c+90, 0, -1, 0);
758   glRotatef (-rot->a+90, 0, 0, 1);
759   glRotatef (rot->b+180, 1, 0, 0);
760   glScalef (zoom, zoom, zoom);
761 
762   if (shading == 1)
763     glShadeModel (GL_FLAT);
764   else
765     glShadeModel (GL_SMOOTH);
766 
767   if (alpha)
768   { glEnable (GL_BLEND); glEnable (GL_ALPHA_TEST); glAlphaFunc (GL_GEQUAL, 0.2); }
769 
770 	for (i = 0; i < numObjects; i ++)
771 	{
772     if (numObjects <= 0) break;
773 	  cm = object [i];
774 	  if (cm->hasTexture)
775 	  {
776 		  glEnable (GL_TEXTURE_2D);
777 		  glColor4f (1, 1, 1, 1);
778 		  glBindTexture (GL_TEXTURE_2D, cm->material->texture->textureID);
779 	  }
780 	  else
781 	  {
782 		  glDisable (GL_TEXTURE_2D);
783 		  glColor4f (1, 1, 1, 1);
784 	  }
785 
786     if (cm->material != NULL)
787     {
788       if (cm->material->color.c [0] > 190 && cm->material->color.c [1] > 190 && cm->material->color.c [2] < 20)
789         glDisable (GL_LIGHTING);
790       else
791         glEnable (GL_LIGHTING);
792     }
793 
794     CVector3 shift;
795 
796     va->glBegin (GL_TRIANGLES);
797     for (j = 0; j < cm->numTriangles; j++)
798     {
799       CVertex *v = cm->triangle [j].v [0];
800       if (explode > 0)
801       {
802         shift.x = v->normal.x * explodefac;
803         shift.y = v->normal.y * explodefac;
804         shift.z = v->normal.z * explodefac;
805       }
806       for (int whichVertex = 0; whichVertex < 3; whichVertex ++)
807       {
808         v = cm->triangle [j].v [whichVertex];
809         va->glNormal3f (v->normal.x, v->normal.y, v->normal.z);
810         if (cm->hasTexture)
811         {
812           if (cm->vertex)
813           {
814             va->glTexCoord2f (v->tex.x, v->tex.y);
815             va->glColor4f (1, 1, 1, 1);
816           }
817         }
818         else
819         {
820           if (numMaterials/* && cm->material->textureID >= 0*/)
821           {
822             unsigned char *color = cm->material->color.c; /*material[cm->material->textureID]->color.c;*/
823             if (color [0] > 190 && color [1] > 190 && color [2] < 20)
824             {
825               rotateColor (30);
826               va->glColor4ub (color [0] + rotcol, color [1] + rotcol, color [2] + rotcol * 3, 255);
827             }
828             else
829             {
830               va->glColor4ub (color [0], color [1], color [2], color [3]);
831             }
832           }
833         }
834   //    glColor3ub (255, 255, 0);
835         va->glVertex3f (v->vector.x + shift.x, v->vector.y + shift.y, v->vector.z + shift.z);
836       }
837     }
838     va->glEnd ();
839 
840     va->glBegin (GL_QUADS);
841     for (j = 0; j < cm->numQuads; j++)
842     {
843       CVertex *v = cm->quad [j].v [0];
844       if (explode > 0)
845       {
846         shift.x = v->normal.x * explodefac;
847         shift.y = v->normal.y * explodefac;
848         shift.z = v->normal.z * explodefac;
849       }
850       for (int whichVertex = 0; whichVertex < 4; whichVertex++)
851       {
852         v = cm->quad [j].v [whichVertex];
853         va->glNormal3f (v->normal.x, v->normal.y, v->normal.z);
854         if (cm->hasTexture)
855         {
856           if (cm->vertex)
857           {
858             va->glTexCoord2f (v->tex.x, v->tex.y);
859             va->glColor4f (1, 1, 1, 1);
860           }
861         }
862         else
863         {
864           if (numMaterials && cm->material->texture->textureID >= 0)
865           {
866             unsigned char *pColor = material [cm->material->texture->textureID]->color.c;
867             va->glColor4ub (pColor [0], pColor [1], pColor [2], pColor [3]);
868           }
869         }
870         va->glVertex3f (v->vector.x + shift.x, v->vector.y + shift.y, v->vector.z + shift.z);
871       }
872     }
873     va->glEnd ();
874   }
875 
876   if (alpha)
877   { glDisable (GL_BLEND); glDisable (GL_ALPHA_TEST); }
878 
879   glPopMatrix ();
880 }
881 
draw2(CVector3 * tl,CVector3 * tl2,CRotation * rot,float zoom,int explode)882 void CModel::draw2 (CVector3 *tl, CVector3 *tl2, CRotation *rot, float zoom, int explode)
883 {
884   int i, j;
885   CObject *cm;
886 
887   for (i = 0; i < numObjects; i ++)
888   {
889     if (numObjects <= 0) break;
890     cm = object [i];
891     if (cm->hasTexture)
892     {
893       if (antialiasing)
894         gl->enableLinearTexture (cm->material->texture->textureID);
895       else
896         gl->disableLinearTexture (cm->material->texture->textureID);
897     }
898   }
899 
900   zoom *= scale;
901   glPushMatrix ();
902   glTranslatef (tl->x + tl2->x, tl->y + tl2->y - 0.002 * explode * explode / timestep / timestep, tl->z + tl2->z);
903   float explodefac = (float) explode / 10 / timestep;
904 
905   if (showcollision)
906   {
907     glPushMatrix ();
908     glScalef (cubex, cubey, cubez);
909     glColor3ub (255, 0, 0);
910     glBegin (GL_LINE_STRIP);
911     glVertex3f (1, 1, 1);
912     glVertex3f (1, 1, -1);
913     glVertex3f (1, -1, -1);
914     glVertex3f (1, -1, 1);
915     glVertex3f (1, 1, 1);
916     glEnd ();
917     glBegin (GL_LINE_STRIP);
918     glVertex3f (-1, 1, 1);
919     glVertex3f (-1, 1, -1);
920     glVertex3f (-1, -1, -1);
921     glVertex3f (-1, -1, 1);
922     glVertex3f (-1, 1, 1);
923     glEnd ();
924     glBegin (GL_LINES);
925     glVertex3f (1, 1, 1);
926     glVertex3f (-1, 1, 1);
927     glVertex3f (1, -1, -1);
928     glVertex3f (-1, -1, -1);
929     glVertex3f (1, -1, 1);
930     glVertex3f (-1, -1, 1);
931     glVertex3f (1, 1, -1);
932     glVertex3f (-1, 1, -1);
933     glEnd ();
934     glPopMatrix ();
935   }
936 
937   glRotatef (rot->c+90, 0, -1, 0);
938   glRotatef (-rot->a+90, 0, 0, 1);
939   glRotatef (rot->b+180, 1, 0, 0);
940   glScalef (zoom, zoom, zoom);
941 
942   bool listgen = false;
943   if (list2 == -1 && explode <= 0 && displaylist)
944   {
945     listgen = true;
946     gl->genList (&list2);
947   }
948   if (listgen || explode > 0 || !displaylist)
949   {
950 
951     if (shading == 1)
952       glShadeModel (GL_FLAT);
953     else
954       glShadeModel (GL_SMOOTH);
955 
956     if (alpha)
957     { glEnable (GL_BLEND); glEnable (GL_ALPHA_TEST); glAlphaFunc (GL_GEQUAL, 0.01); }
958 
959     for (i = 0; i < numObjects; i++)
960     {
961       if (numObjects <= 0) break;
962       cm = object [i];
963       if (cm->hasTexture)
964       {
965         glEnable (GL_TEXTURE_2D);
966         glColor4ub (255, 255, 255, 255);
967         glBindTexture (GL_TEXTURE_2D, cm->material->texture->textureID);
968       }
969       else
970       {
971         glDisable (GL_TEXTURE_2D);
972         glColor4ub (255, 255, 255, 255);
973       }
974 
975       CVector3 shift;
976 
977       va->glBegin (GL_TRIANGLES);
978       for (j = 0; j < cm->numTriangles; j++)
979       {
980         CVertex *v = cm->triangle [j].v [0];
981         if (explode > 0)
982         {
983           shift.x = v->normal.x * explodefac;
984           shift.y = v->normal.y * explodefac;
985           shift.z = v->normal.z * explodefac;
986         }
987         for (int whichVertex = 0; whichVertex < 3; whichVertex ++)
988         {
989           v = cm->triangle [j].v [whichVertex];
990           va->glNormal3f (v->normal.x, v->normal.y, v->normal.z);
991           if (cm->hasTexture)
992           {
993             if (cm->vertex)
994             {
995               va->glTexCoord2f (v->tex.x, v->tex.y);
996               va->glColor4f (1, 1, 1, 1);
997             }
998           }
999           else
1000           {
1001             unsigned char *pColor = v->color.c;
1002             va->glColor4ub (pColor [0], pColor [1], pColor [2], pColor [3]);
1003           }
1004           va->glVertex3f (v->vector.x + shift.x, v->vector.y + shift.y, v->vector.z + shift.z);
1005         }
1006       }
1007       va->glEnd ();
1008 
1009       va->glBegin (GL_QUADS);
1010       for (j = 0; j < cm->numQuads; j++)
1011       {
1012         CVertex *v = cm->quad [j].v [0];
1013         if (explode > 0)
1014         {
1015           shift.x = v->normal.x * explodefac;
1016           shift.y = v->normal.y * explodefac;
1017           shift.z = v->normal.z * explodefac;
1018         }
1019         for (int whichVertex = 0; whichVertex < 4; whichVertex ++)
1020         {
1021           v = cm->quad [j].v [whichVertex];
1022           va->glNormal3f (v->normal.x, v->normal.y, v->normal.z);
1023           if (cm->hasTexture)
1024           {
1025             if (cm->vertex)
1026             {
1027               va->glTexCoord2f (v->tex.x, v->tex.y);
1028               va->glColor4f (1, 1, 1, 1);
1029             }
1030           }
1031           else
1032           {
1033             unsigned char *pColor = v->color.c;
1034             va->glColor4ub (pColor [0], pColor [1], pColor [2], pColor [3]);
1035           }
1036           va->glVertex3f (v->vector.x + shift.x, v->vector.y + shift.y, v->vector.z + shift.z);
1037         }
1038       }
1039       va->glEnd ();
1040     }
1041 
1042     if (alpha)
1043     { glDisable (GL_BLEND); glDisable (GL_ALPHA_TEST); }
1044 
1045     if (listgen) glEndList ();
1046   }
1047   else glCallList (list2);
1048 
1049   glPopMatrix ();
1050 }
1051 
draw3(CVector3 * tl,CVector3 * tl2,CRotation * rot,float zoom,float lum,int explode)1052 void CModel::draw3 (CVector3 *tl, CVector3 *tl2, CRotation *rot, float zoom, float lum, int explode)
1053 {
1054   int i, j;
1055   CObject *cm;
1056 //  float mx=0, my=0, mz=0, ix=0, iy=0, iz=0;
1057   zoom *= scale;
1058   glPushMatrix ();
1059   glTranslatef (tl->x + tl2->x, tl->y + tl2->y - 0.002 * explode * explode / timestep / timestep, tl->z + tl2->z);
1060   float explodefac = (float) explode / 10 / timestep;
1061 
1062   if (showcollision)
1063   {
1064     glPushMatrix ();
1065     glScalef (cubex, cubey, cubez);
1066     glColor3ub (255, 0, 0);
1067     glBegin (GL_LINE_STRIP);
1068     glVertex3f (1, 1, 1);
1069     glVertex3f (1, 1, -1);
1070     glVertex3f (1, -1, -1);
1071     glVertex3f (1, -1, 1);
1072     glVertex3f (1, 1, 1);
1073     glEnd ();
1074     glBegin (GL_LINE_STRIP);
1075     glVertex3f (-1, 1, 1);
1076     glVertex3f (-1, 1, -1);
1077     glVertex3f (-1, -1, -1);
1078     glVertex3f (-1, -1, 1);
1079     glVertex3f (-1, 1, 1);
1080     glEnd ();
1081     glBegin (GL_LINES);
1082     glVertex3f (1, 1, 1);
1083     glVertex3f (-1, 1, 1);
1084     glVertex3f (1, -1, -1);
1085     glVertex3f (-1, -1, -1);
1086     glVertex3f (1, -1, 1);
1087     glVertex3f (-1, -1, 1);
1088     glVertex3f (1, 1, -1);
1089     glVertex3f (-1, 1, -1);
1090     glEnd ();
1091     glPopMatrix ();
1092   }
1093 
1094   glRotatef (rot->c+90, 0, -1, 0);
1095   glRotatef (-rot->a+90, 0, 0, 1);
1096   glRotatef (rot->b+180, 1, 0, 0);
1097   glScalef (zoom, zoom, zoom);
1098 
1099   if (alpha)
1100   { glEnable (GL_BLEND); glEnable (GL_ALPHA_TEST); glAlphaFunc (GL_GEQUAL, 0.2); }
1101 
1102   for (i = 0; i < numObjects; i++)
1103   {
1104     if (numObjects <= 0) break;
1105     cm = object [i];
1106     glDisable (GL_TEXTURE_2D);
1107     glColor3ub (255, 255, 255);
1108 
1109     CVector3 shift;
1110 
1111     va->glBegin (GL_TRIANGLES);
1112     for (j = 0; j < cm->numTriangles; j++)
1113     {
1114       CVertex *v = cm->triangle [j].v [0];
1115       if (explode > 0)
1116       {
1117         shift.x = v->normal.x * explodefac;
1118         shift.y = v->normal.y * explodefac;
1119         shift.z = v->normal.z * explodefac;
1120       }
1121       for (int whichVertex = 0; whichVertex < 3; whichVertex ++)
1122       {
1123         v = cm->triangle [j].v [whichVertex];
1124   //      glNormal3f (v->normal.x, v->normal.y, v->normal.z);
1125         unsigned char *pColor = v->color.c;
1126         float red = lum * pColor [0] / 256;
1127         float green = lum * pColor [1] / 256;
1128         float blue = lum * pColor [2] / 256;
1129         if (red >= 1.0) red = 1.0;
1130         if (green >= 1.0) green = 1.0;
1131         if (blue >= 1.0) blue = 1.0;
1132         va->glColor3f (red, green, blue);
1133         va->glVertex3f (v->vector.x + shift.x, v->vector.y + shift.y, v->vector.z + shift.z);
1134       }
1135     }
1136     va->glEnd ();
1137 
1138     va->glBegin (GL_QUADS);
1139     for (j = 0; j < cm->numQuads; j++)
1140     {
1141       CVertex *v = cm->quad [j].v [0];
1142       if (explode > 0)
1143       {
1144         shift.x = v->normal.x * explodefac;
1145         shift.y = v->normal.y * explodefac;
1146         shift.z = v->normal.z * explodefac;
1147       }
1148       for (int whichVertex = 0; whichVertex < 4; whichVertex ++)
1149       {
1150         v = cm->quad [j].v [whichVertex];
1151   //      glNormal3f (v->normal.x, v->normal.y, v->normal.z);
1152         unsigned char *pColor = v->color.c;
1153         float red = lum * pColor [0] / 256;
1154         float green = lum * pColor [1] / 256;
1155         float blue = lum * pColor [2] / 256;
1156         if (red >= 1.0) red = 1.0;
1157         if (green >= 1.0) green = 1.0;
1158         if (blue >= 1.0) blue = 1.0;
1159         va->glColor3f (red, green, blue);
1160         va->glVertex3f (v->vector.x + shift.x, v->vector.y + shift.y, v->vector.z + shift.z);
1161       }
1162     }
1163     va->glEnd ();
1164 
1165   }
1166 
1167   if (alpha)
1168   { glDisable (GL_BLEND); glDisable (GL_ALPHA_TEST); }
1169 
1170   glPopMatrix ();
1171 }
1172 
draw3(CVector3 * tl,CVector3 * tl2,CRotation * rot,float zoom,int explode)1173 void CModel::draw3 (CVector3 *tl, CVector3 *tl2, CRotation *rot, float zoom, int explode)
1174 {
1175   int i, j;
1176   CObject *cm;
1177 //  float mx=0, my=0, mz=0, ix=0, iy=0, iz=0;
1178   zoom *= scale;
1179   glPushMatrix ();
1180   glTranslatef (tl->x + tl2->x, tl->y + tl2->y - 0.002 * explode * explode / timestep / timestep, tl->z + tl2->z);
1181   float explodefac = (float) explode / 10 / timestep;
1182 
1183   if (showcollision)
1184   {
1185     glPushMatrix ();
1186     glScalef (cubex, cubey, cubez);
1187     glColor3ub (255, 0, 0);
1188     glBegin (GL_LINE_STRIP);
1189     glVertex3f (1, 1, 1);
1190     glVertex3f (1, 1, -1);
1191     glVertex3f (1, -1, -1);
1192     glVertex3f (1, -1, 1);
1193     glVertex3f (1, 1, 1);
1194     glEnd ();
1195     glBegin (GL_LINE_STRIP);
1196     glVertex3f (-1, 1, 1);
1197     glVertex3f (-1, 1, -1);
1198     glVertex3f (-1, -1, -1);
1199     glVertex3f (-1, -1, 1);
1200     glVertex3f (-1, 1, 1);
1201     glEnd ();
1202     glBegin (GL_LINES);
1203     glVertex3f (1, 1, 1);
1204     glVertex3f (-1, 1, 1);
1205     glVertex3f (1, -1, -1);
1206     glVertex3f (-1, -1, -1);
1207     glVertex3f (1, -1, 1);
1208     glVertex3f (-1, -1, 1);
1209     glVertex3f (1, 1, -1);
1210     glVertex3f (-1, 1, -1);
1211     glEnd ();
1212     glPopMatrix ();
1213   }
1214 
1215   glRotatef (rot->c+90, 0, -1, 0);
1216   glRotatef (-rot->a+90, 0, 0, 1);
1217   glRotatef (rot->b+180, 1, 0, 0);
1218   glScalef (zoom, zoom, zoom);
1219 
1220   bool listgen = false;
1221   if (list3 == -1 && explode <= 0 && displaylist)
1222   {
1223     listgen = true;
1224     gl->genList (&list3);
1225   }
1226   if (listgen || explode > 0 || !displaylist)
1227   {
1228 
1229     if (shading == 1)
1230       glShadeModel (GL_FLAT);
1231     else
1232       glShadeModel (GL_SMOOTH);
1233 
1234     if (alpha)
1235     { glEnable (GL_BLEND); glEnable (GL_ALPHA_TEST); glAlphaFunc (GL_GEQUAL, 0.2); }
1236 
1237     for (i = 0; i < numObjects; i++)
1238     {
1239       if (numObjects <= 0) break;
1240       cm = object [i];
1241       glDisable (GL_TEXTURE_2D);
1242       glColor3ub (255, 255, 255);
1243 
1244       CVector3 shift;
1245 
1246       va->glBegin (GL_TRIANGLES);
1247       for (j = 0; j < cm->numTriangles; j++)
1248       {
1249         CVertex *v = cm->triangle [j].v [0];
1250         if (explode > 0)
1251         {
1252           shift.x = v->normal.x * explodefac;
1253           shift.y = v->normal.y * explodefac;
1254           shift.z = v->normal.z * explodefac;
1255         }
1256         for (int whichVertex = 0; whichVertex < 3; whichVertex ++)
1257         {
1258           v = cm->triangle [j].v [whichVertex];
1259           va->glNormal3f (v->normal.x, v->normal.y, v->normal.z);
1260           if (cm->hasTexture && false)
1261           {
1262             if (cm->vertex)
1263             {
1264               va->glTexCoord2f (v->tex.x, v->tex.y);
1265               va->glColor4f (1, 1, 1, 1);
1266             }
1267           }
1268           else
1269           {
1270             unsigned char *pColor = v->color.c;
1271             va->glColor3ub (pColor[0], pColor[1], pColor[2]);
1272           }
1273           va->glVertex3f (v->vector.x + shift.x, v->vector.y + shift.y, v->vector.z + shift.z);
1274         }
1275       }
1276       va->glEnd ();
1277 
1278       va->glBegin (GL_QUADS);
1279       for (j = 0; j < cm->numQuads; j++)
1280       {
1281         CVertex *v = cm->quad [j].v [0];
1282         if (explode > 0)
1283         {
1284           shift.x = v->normal.x * explodefac;
1285           shift.y = v->normal.y * explodefac;
1286           shift.z = v->normal.z * explodefac;
1287         }
1288         for (int whichVertex = 0; whichVertex < 4; whichVertex ++)
1289         {
1290           v = cm->quad [j].v [whichVertex];
1291           va->glNormal3f (v->normal.x, v->normal.y, v->normal.z);
1292           if (cm->hasTexture && false)
1293           {
1294             if (cm->vertex)
1295             {
1296               va->glTexCoord2f (v->tex.x, v->tex.y);
1297               va->glColor4f (1, 1, 1, 1);
1298             }
1299           }
1300           else
1301           {
1302             unsigned char *pColor = v->color.c;
1303             va->glColor3ub (pColor[0], pColor[1], pColor[2]);
1304           }
1305           va->glVertex3f (v->vector.x + shift.x, v->vector.y + shift.y, v->vector.z + shift.z);
1306         }
1307       }
1308       va->glEnd ();
1309     }
1310 
1311     if (alpha)
1312     { glDisable (GL_BLEND); glDisable (GL_ALPHA_TEST); }
1313 
1314     if (listgen) glEndList ();
1315   }
1316   else glCallList (list3);
1317 
1318   glPopMatrix ();
1319 }
1320 
1321 
1322 
CSphere()1323 CSphere::CSphere () {}
1324 
CSphere(float radius,int segments,float dx,float dy,float dz)1325 CSphere::CSphere (float radius, int segments, float dx, float dy, float dz)
1326 {
1327   init (radius, segments, dx, dy, dz, 0);
1328 }
1329 
~CSphere()1330 CSphere::~CSphere () {}
1331 
random(int n)1332 int CSphere::random (int n)
1333 {
1334   if (n == 0) return 0;
1335   return rand () % n;
1336 }
1337 
init(float radius,int segments)1338 void CSphere::init (float radius, int segments)
1339 {
1340   init (radius, segments, 1, 1, 1, 0);
1341 }
1342 
init(float radius,int segments,float dx,float dy,float dz,int randomized)1343 void CSphere::init (float radius, int segments, float dx, float dy, float dz, int randomized)
1344 {
1345   CObject *co = new CObject;
1346   if (co == NULL) exit (100);
1347   co->vertex = new CVertex [segments * segments * 2 + 2];
1348   if (co->vertex == NULL) exit (100);
1349   co->triangle = new CTriangle [segments * 4];
1350   if (co->triangle == NULL) exit (100);
1351   co->quad = new CQuad [segments * segments * 2];
1352   if (co->quad == NULL) exit (100);
1353   this->radius = radius;
1354   this->segments = segments;
1355   this->dx = dx;
1356   this->dy = dy;
1357   this->dz = dz;
1358   int p [4];
1359   float step = 180.0 / segments;
1360   CRotation *rot = new CRotation ();
1361   if (rot == NULL) exit (100);
1362   CVertex *w = new CVertex ();
1363   if (w == NULL) exit (100);
1364   for (float i = 0; i < 180; i += step)
1365     for (float i2 = 0; i2 < 360; i2 += step)
1366     {
1367       int a = ((int) i) % 360, b = ((int) i2) % 360;
1368       float si = rot->getsintab (a), ci = rot->getcostabntab (a);
1369       float si2 = rot->getsintab (b), ci2 = rot->getcostabntab (b);
1370       w->vector.x = radius * si * ci2 * dx; w->vector.y = radius * si * si2 * dy; w->vector.z = radius * ci * dz;
1371       p [0] = co->addVertex (w);
1372       a = ((int) (i + step)) % 360;
1373       si = rot->getsintab (a); ci = rot->getcostabntab (a);
1374       si2 = rot->getsintab (b); ci2 = rot->getcostabntab (b);
1375       w->vector.x = radius * si * ci2 * dx; w->vector.y = radius * si * si2 * dy; w->vector.z = radius * ci * dz;
1376       if (a < 179 || i2 == 0) p [1] = co->addVertex (w);
1377       b = ((int) (i2 + step)) % 360;
1378       si = rot->getsintab (a); ci = rot->getcostabntab (a);
1379       si2 = rot->getsintab (b); ci2 = rot->getcostabntab (b);
1380       w->vector.x = radius * si * ci2 * dx; w->vector.y = radius * si * si2 * dy; w->vector.z = radius * ci * dz;
1381       if (a < 179) p [2] = co->addVertex (w);
1382       a = ((int) i) % 360;
1383       si = rot->getsintab (a); ci = rot->getcostabntab (a);
1384       si2 = rot->getsintab (b); ci2 = rot->getcostabntab (b);
1385       w->vector.x = radius * si * ci2 * dx; w->vector.y = radius * si * si2 * dy; w->vector.z = radius * ci * dz;
1386       p [3] = co->addVertex (w);
1387       if (i == 0 || i >= 180 - step - 1)
1388       {
1389         if (!random (randomized))
1390         {
1391           if (i == 0) co->triangle [co->numTriangles ++].setVertices (&co->vertex [p [0]], &co->vertex [p [1]], &co->vertex [p [2]]);
1392           else co->triangle [co->numTriangles ++].setVertices (&co->vertex [p [0]], &co->vertex [p [1]], &co->vertex [p [3]]);
1393         }
1394       }
1395       else
1396       {
1397         if (!random (randomized))
1398           co->quad [co->numQuads ++].setVertices (&co->vertex [p [0]], &co->vertex [p [1]], &co->vertex [p [2]], &co->vertex [p [3]]);
1399       }
1400     }
1401   delete rot;
1402   delete w;
1403   addObject (co);
1404   setColor (new CColor (128, 128, 128, 255));
1405   for (int i2 = 0; i2 < object [0]->numVertices / 2; i2 ++)
1406   {
1407     object [0]->vertex [i2].normal.neg ();
1408   }
1409 }
1410 
invertNormals()1411 void CSphere::invertNormals ()
1412 {
1413   for (int i = 0; i < object [0]->numVertices; i ++)
1414   {
1415     object [0]->vertex [i].normal.neg ();
1416   }
1417 }
1418 
setNorthPoleColor(CColor * c,float w)1419 void CSphere::setNorthPoleColor (CColor *c, float w)
1420 {
1421   int i, i2;
1422   for (i = 0; i < 4; i ++)
1423     object [0]->vertex [0].color.c [i] = c->c [i];
1424   int num = (int) (w * segments * segments / 2);
1425   num /= (segments * 2);
1426   num *= (segments * 2);
1427   for (i = 1; i <= num; i ++)
1428   {
1429     float weight = 1.0F - (float) ((int) ((i - 1) / (segments * 2)) * segments * 2) / (float) num;
1430     for (i2 = 0; i2 < 4; i2 ++)
1431       object [0]->vertex [i].color.c [i2] = (short) ((1.0F - weight) * object [0]->vertex [i].color.c [i2] + weight * c->c [i2]);
1432   }
1433 }
1434 
setSouthPoleColor(CColor * c,float w)1435 void CSphere::setSouthPoleColor (CColor *c, float w)
1436 {
1437   int i, i2;
1438   int max = (segments - 1) * segments * 2 + 1;
1439   for (i = 0; i < 4; i ++)
1440     object [0]->vertex [max].color.c [i] = c->c [i];
1441   int num = (int) (w * segments * segments / 2);
1442   num /= (segments * 2);
1443   num *= (segments * 2);
1444   for (i = 1; i <= num; i ++)
1445   {
1446     float weight = 1.0F - (float) ((int) ((i - 1) / (segments * 2)) * segments * 2) / (float) num;
1447     for (i2 = 0; i2 < 4; i2 ++)
1448       object [0]->vertex [max - i].color.c [i] = (short) ((1.0F - weight) * object [0]->vertex [max - i].color.c [i2] + weight * c->c [i2]);
1449   }
1450 }
1451 
setPoleColor(int phi,int theta,CColor * c,float w)1452 void CSphere::setPoleColor (int phi, int theta, CColor *c, float w)
1453 {
1454   int i, i2;
1455   for (i = 0; i < object [0]->numVertices; i ++)
1456   {
1457     int phi2 = ((i - 1) % (segments * 2)) * 360 / (segments * 2);
1458     int theta2 = ((i - 1) / (segments * 2) + 1) * 360 / (segments * 2);
1459     if (i == 0) { theta2 = 0; phi2 = 0; }
1460     int dphi = phi - phi2;
1461     if (dphi < -180) dphi += 360;
1462     else if (dphi > 180) dphi -= 360;
1463     int dtheta = theta - theta2;
1464     if (dtheta < -180) dtheta += 360;
1465     else if (dtheta > 180) dtheta -= 360;
1466     float alpha = sqrt ((float) (dphi*dphi+dtheta*dtheta));
1467     if (alpha < 180 * w)
1468     {
1469       float weight = 1.0 - alpha / 180.0 / w;
1470       for (i2 = 0; i2 < 4; i2 ++)
1471         object [0]->vertex [i].color.c [i2] = (short) ((1.0F - weight) * object [0]->vertex [i].color.c [i2] + weight * c->c [i2]);
1472     }
1473   }
1474 }
1475 
1476 
1477 
CSpherePart()1478 CSpherePart::CSpherePart () {}
1479 
CSpherePart(float radius,int segments,float phi)1480 CSpherePart::CSpherePart (float radius, int segments, float phi)
1481 {
1482   init (radius, segments, phi);
1483 }
1484 
~CSpherePart()1485 CSpherePart::~CSpherePart () {}
1486 
init(float radius,int segments)1487 void CSpherePart::init (float radius, int segments)
1488 {
1489   init (radius, segments, 10);
1490 }
1491 
init(float radius,int segments,float phi)1492 void CSpherePart::init (float radius, int segments, float phi)
1493 {
1494   CObject *co = new CObject;
1495   co->vertex = new CVertex [segments * 4 + 1];
1496   co->triangle = new CTriangle [segments];
1497   co->quad = new CQuad [segments * 3];
1498   this->radius = radius;
1499   this->segments = segments;
1500   float dx = 1, dy = 1, dz = 1;
1501   int p [4];
1502   float step = 360.0 / segments;
1503   float step2 = phi / 4;
1504   CRotation *rot = new CRotation ();
1505   CVertex *w = new CVertex ();
1506   for (float i = 0; i < phi; i += step2)
1507     for (float i2 = 0; i2 < 360; i2 += step)
1508     {
1509       int a = ((int) i) % 360, b = ((int) i2) % 360;
1510       float si = rot->getsintab (a), ci = rot->getcostabntab (a);
1511       float si2 = rot->getsintab (b), ci2 = rot->getcostabntab (b);
1512       w->vector.x = radius * si * ci2 * dx; w->vector.y = radius * si * si2 * dy; w->vector.z = radius * ci * dz;
1513       p [0] = co->addVertex (w);
1514       a = ((int) (i + step2)) % 360;
1515       si = rot->getsintab (a); ci = rot->getcostabntab (a);
1516       si2 = rot->getsintab (b); ci2 = rot->getcostabntab (b);
1517       w->vector.x = radius * si * ci2 * dx; w->vector.y = radius * si * si2 * dy; w->vector.z = radius * ci * dz;
1518       if (a < 179 || i2 == 0) p [1] = co->addVertex (w);
1519       b = ((int) (i2 + step)) % 360;
1520       si = rot->getsintab (a); ci = rot->getcostabntab (a);
1521       si2 = rot->getsintab (b); ci2 = rot->getcostabntab (b);
1522       w->vector.x = radius * si * ci2 * dx; w->vector.y = radius * si * si2 * dy; w->vector.z = radius * ci * dz;
1523       if (a < 179) p [2] = co->addVertex (w);
1524       a = ((int) i) % 360;
1525       si = rot->getsintab (a); ci = rot->getcostabntab (a);
1526       si2 = rot->getsintab (b); ci2 = rot->getcostabntab (b);
1527       w->vector.x = radius * si * ci2 * dx; w->vector.y = radius * si * si2 * dy; w->vector.z = radius * ci * dz;
1528       p [3] = co->addVertex (w);
1529       if (i == 0 || i >= 180 - step2 - 0.2)
1530       {
1531         if (i == 0) co->triangle [co->numTriangles ++].setVertices (&co->vertex [p [0]], &co->vertex [p [1]], &co->vertex [p [2]]);
1532         else co->triangle [co->numTriangles ++].setVertices (&co->vertex [p [0]], &co->vertex [p [1]], &co->vertex [p [3]]);
1533       }
1534       else
1535       {
1536         co->quad [co->numQuads ++].setVertices (&co->vertex [p [0]], &co->vertex [p [1]], &co->vertex [p [2]], &co->vertex [p [3]]);
1537       }
1538     }
1539   delete rot;
1540   delete w;
1541   addObject (co);
1542   setColor (new CColor (128, 128, 128, 255));
1543 }
1544 
setNorthPoleColor(CColor * c,float w)1545 void CSpherePart::setNorthPoleColor (CColor *c, float w)
1546 {
1547   int i, i2;
1548   for (i = 0; i < 4; i ++)
1549     object [0]->vertex [0].color.c [i] = c->c [i];
1550   int num = (int) (w * segments * 4 / 2);
1551   num /= (segments * 2);
1552   num *= (segments * 2);
1553   for (i = 1; i <= num; i ++)
1554   {
1555     float weight = 1.0F - (float) ((int) ((i - 1) / (segments * 2)) * 4 * 2) / (float) num;
1556     for (i2 = 0; i2 < 4; i2 ++)
1557       object [0]->vertex [i].color.c [i2] = (short) ((1.0F - weight) * object [0]->vertex [i].color.c [i2] + weight * c->c [i2]);
1558   }
1559 }
1560 
setSouthPoleColor(CColor * c,float w)1561 void CSpherePart::setSouthPoleColor (CColor *c, float w)
1562 {
1563 }
1564 
setPoleColor(int phi,int theta,CColor * c,float w)1565 void CSpherePart::setPoleColor (int phi, int theta, CColor *c, float w)
1566 {
1567 }
1568 
1569 #endif
1570 
1571