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