]> git.jsancho.org Git - lugaru.git/blob - Source/Models.cpp
0b8105396bd4f00204e73440c319a0783707d65f
[lugaru.git] / Source / Models.cpp
1 /*
2 Copyright (C) 2003, 2010 - Wolfire Games
3
4 This file is part of Lugaru.
5
6 Lugaru is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 Lugaru is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with Lugaru.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "Game.h"
21 #include "Models.h"
22
23 extern float multiplier;
24 extern float viewdistance;
25 extern XYZ viewer;
26 extern float fadestart;
27 extern float texdetail;
28 extern bool decals;
29
30 extern bool visibleloading;
31
32 int Model::LineCheck(XYZ *p1, XYZ *p2, XYZ *p, XYZ *move, float *rotate)
33 {
34     static int j;
35     static float distance;
36     static float olddistance;
37     static int intersecting;
38     static int firstintersecting;
39     static XYZ point;
40
41     *p1 = *p1 - *move;
42     *p2 = *p2 - *move;
43     if (*rotate)
44         *p1 = DoRotation(*p1, 0, -*rotate, 0);
45     if (*rotate)
46         *p2 = DoRotation(*p2, 0, -*rotate, 0);
47     if (!sphere_line_intersection(p1, p2, &boundingspherecenter, &boundingsphereradius))
48         return -1;
49     firstintersecting = -1;
50
51     for (j = 0; j < TriangleNum; j++) {
52         intersecting = LineFacetd(p1, p2, &vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[1]], &vertex[Triangles[j].vertex[2]], &facenormals[j], &point);
53         distance = (point.x - p1->x) * (point.x - p1->x) + (point.y - p1->y) * (point.y - p1->y) + (point.z - p1->z) * (point.z - p1->z);
54         if ((distance < olddistance || firstintersecting == -1) && intersecting) {
55             olddistance = distance;
56             firstintersecting = j;
57             *p = point;
58         }
59     }
60
61     if (*rotate)
62         *p = DoRotation(*p, 0, *rotate, 0);
63     *p = *p + *move;
64     return firstintersecting;
65 }
66
67 int Model::LineCheckPossible(XYZ *p1, XYZ *p2, XYZ *p, XYZ *move, float *rotate)
68 {
69     static int j;
70     static float distance;
71     static float olddistance;
72     static int intersecting;
73     static int firstintersecting;
74     static XYZ point;
75
76     *p1 = *p1 - *move;
77     *p2 = *p2 - *move;
78     if (!sphere_line_intersection(p1, p2, &boundingspherecenter, &boundingsphereradius))
79         return -1;
80     firstintersecting = -1;
81     if (*rotate)
82         *p1 = DoRotation(*p1, 0, -*rotate, 0);
83     if (*rotate)
84         *p2 = DoRotation(*p2, 0, -*rotate, 0);
85
86     if (numpossible > 0 && numpossible < TriangleNum)
87         for (j = 0; j < numpossible; j++) {
88             if (possible[j] >= 0 && possible[j] < TriangleNum) {
89                 intersecting = LineFacetd(p1, p2, &vertex[Triangles[possible[j]].vertex[0]], &vertex[Triangles[possible[j]].vertex[1]], &vertex[Triangles[possible[j]].vertex[2]], &facenormals[possible[j]], &point);
90                 distance = (point.x - p1->x) * (point.x - p1->x) + (point.y - p1->y) * (point.y - p1->y) + (point.z - p1->z) * (point.z - p1->z);
91                 if ((distance < olddistance || firstintersecting == -1) && intersecting) {
92                     olddistance = distance;
93                     firstintersecting = possible[j];
94                     *p = point;
95                 }
96             }
97         }
98
99     if (*rotate)
100         *p = DoRotation(*p, 0, *rotate, 0);
101     *p = *p + *move;
102     return firstintersecting;
103 }
104
105 int Model::LineCheckSlidePossible(XYZ *p1, XYZ *p2, XYZ *p, XYZ *move, float *rotate)
106 {
107     static int j;
108     static float distance;
109     static float olddistance;
110     static int intersecting;
111     static int firstintersecting;
112     static XYZ point;
113
114     *p1 = *p1 - *move;
115     *p2 = *p2 - *move;
116     if (!sphere_line_intersection(p1, p2, &boundingspherecenter, &boundingsphereradius))
117         return -1;
118     firstintersecting = -1;
119     if (*rotate)
120         *p1 = DoRotation(*p1, 0, -*rotate, 0);
121     if (*rotate)
122         *p2 = DoRotation(*p2, 0, -*rotate, 0);
123
124     if (numpossible)
125         for (j = 0; j < numpossible; j++) {
126             if (possible[j] >= 0 && possible[j] < TriangleNum) {
127                 intersecting = LineFacetd(p1, p2, &vertex[Triangles[possible[j]].vertex[0]], &vertex[Triangles[possible[j]].vertex[1]], &vertex[Triangles[possible[j]].vertex[2]], &facenormals[possible[j]], &point);
128                 distance = (point.x - p1->x) * (point.x - p1->x) + (point.y - p1->y) * (point.y - p1->y) + (point.z - p1->z) * (point.z - p1->z);
129                 if ((distance < olddistance || firstintersecting == -1) && intersecting) {
130                     olddistance = distance;
131                     firstintersecting = possible[j];
132                 }
133             }
134         }
135
136     if (firstintersecting > 0) {
137         distance = abs((facenormals[firstintersecting].x * p2->x) + (facenormals[firstintersecting].y * p2->y) + (facenormals[firstintersecting].z * p2->z) - ((facenormals[firstintersecting].x * vertex[Triangles[firstintersecting].vertex[0]].x) + (facenormals[firstintersecting].y * vertex[Triangles[firstintersecting].vertex[0]].y) + (facenormals[firstintersecting].z * vertex[Triangles[firstintersecting].vertex[0]].z)));
138         *p2 -= facenormals[firstintersecting] * distance;
139     }
140
141     if (*rotate)
142         *p2 = DoRotation(*p2, 0, *rotate, 0);
143     *p2 = *p2 + *move;
144     return firstintersecting;
145 }
146
147 int Model::SphereCheck(XYZ *p1, float radius, XYZ *p, XYZ *move, float *rotate)
148 {
149     static int i, j;
150     static float distance;
151     static float olddistance;
152     static int intersecting;
153     static int firstintersecting;
154     static XYZ point;
155     static XYZ oldp1;
156     static XYZ start, end;
157
158     firstintersecting = -1;
159
160     oldp1 = *p1;
161     *p1 = *p1 - *move;
162     if (*rotate)
163         *p1 = DoRotation(*p1, 0, -*rotate, 0);
164     if (distsq(p1, &boundingspherecenter) > radius * radius + boundingsphereradius * boundingsphereradius)
165         return -1;
166
167     for (i = 0; i < 4; i++) {
168         for (j = 0; j < TriangleNum; j++) {
169             intersecting = 0;
170             distance = abs((facenormals[j].x * p1->x) + (facenormals[j].y * p1->y) + (facenormals[j].z * p1->z) - ((facenormals[j].x * vertex[Triangles[j].vertex[0]].x) + (facenormals[j].y * vertex[Triangles[j].vertex[0]].y) + (facenormals[j].z * vertex[Triangles[j].vertex[0]].z)));
171             if (distance < radius) {
172                 point = *p1 - facenormals[j] * distance;
173                 if (PointInTriangle( &point, facenormals[j], &vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[1]], &vertex[Triangles[j].vertex[2]]))
174                     intersecting = 1;
175                 if (!intersecting)
176                     intersecting = sphere_line_intersection(&vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[1]], p1, &radius);
177                 if (!intersecting)
178                     intersecting = sphere_line_intersection(&vertex[Triangles[j].vertex[1]], &vertex[Triangles[j].vertex[2]], p1, &radius);
179                 if (!intersecting)
180                     intersecting = sphere_line_intersection(&vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[2]], p1, &radius);
181                 if (intersecting) {
182                     *p1 += facenormals[j] * (distance - radius);
183                     /*start=*p1;
184                     end=*p1;
185                     end.y-=radius;
186                     if(LineFacetd(&start,&end,&vertex[Triangles[j].vertex[0]],&vertex[Triangles[j].vertex[1]],&vertex[Triangles[j].vertex[2]],&facenormals[j],&point)){
187                     p1->y=point.y+radius;
188                     }*/
189                 }
190             }
191             if ((distance < olddistance || firstintersecting == -1) && intersecting) {
192                 olddistance = distance;
193                 firstintersecting = j;
194                 *p = point;
195             }
196         }
197     }
198     if (*rotate)
199         *p = DoRotation(*p, 0, *rotate, 0);
200     *p = *p + *move;
201     if (*rotate)
202         *p1 = DoRotation(*p1, 0, *rotate, 0);
203     *p1 += *move;
204     return firstintersecting;
205 }
206
207 int Model::SphereCheckPossible(XYZ *p1, float radius, XYZ *move, float *rotate)
208 {
209     static int j;
210     static float distance;
211     static float olddistance;
212     static int intersecting;
213     static int firstintersecting;
214     static XYZ point;
215     static XYZ oldp1;
216     static XYZ start, end;
217
218     firstintersecting = -1;
219
220     oldp1 = *p1;
221     *p1 = *p1 - *move;
222
223     numpossible = 0;
224
225     if (*rotate)
226         *p1 = DoRotation(*p1, 0, -*rotate, 0);
227     if (distsq(p1, &boundingspherecenter) > radius * radius + boundingsphereradius * boundingsphereradius) {
228         *p1 = oldp1;
229         return -1;
230     }
231
232     for (j = 0; j < TriangleNum; j++) {
233         intersecting = 0;
234         distance = abs((facenormals[j].x * p1->x) + (facenormals[j].y * p1->y) + (facenormals[j].z * p1->z) - ((facenormals[j].x * vertex[Triangles[j].vertex[0]].x) + (facenormals[j].y * vertex[Triangles[j].vertex[0]].y) + (facenormals[j].z * vertex[Triangles[j].vertex[0]].z)));
235         if (distance < radius) {
236             point = *p1 - facenormals[j] * distance;
237             if (PointInTriangle( &point, facenormals[j], &vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[1]], &vertex[Triangles[j].vertex[2]]))
238                 intersecting = 1;
239             if (!intersecting)
240                 intersecting = sphere_line_intersection(&vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[1]], p1, &radius);
241             if (!intersecting)
242                 intersecting = sphere_line_intersection(&vertex[Triangles[j].vertex[1]], &vertex[Triangles[j].vertex[2]], p1, &radius);
243             if (!intersecting)
244                 intersecting = sphere_line_intersection(&vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[2]], p1, &radius);
245             if (intersecting) {
246                 //if(j>=0&&j<TriangleNum)
247                 possible[numpossible] = j;
248                 numpossible++;
249             }
250         }
251         if ((distance < olddistance || firstintersecting == -1) && intersecting) {
252             olddistance = distance;
253             firstintersecting = j;
254         }
255     }
256     if (*rotate)
257         *p1 = DoRotation(*p1, 0, *rotate, 0);
258     *p1 += *move;
259     return firstintersecting;
260 }
261
262
263 void Model::UpdateVertexArray()
264 {
265     if (type != normaltype && type != decalstype)
266         return;
267     static int i;
268     static int j;
269     if (!flat)
270         for (i = 0; i < TriangleNum; i++) {
271             j = i * 24;
272             vArray[j + 0] = Triangles[i].gx[0];
273             vArray[j + 1] = Triangles[i].gy[0];
274             vArray[j + 2] = normals[Triangles[i].vertex[0]].x;
275             vArray[j + 3] = normals[Triangles[i].vertex[0]].y;
276             vArray[j + 4] = normals[Triangles[i].vertex[0]].z;
277             vArray[j + 5] = vertex[Triangles[i].vertex[0]].x;
278             vArray[j + 6] = vertex[Triangles[i].vertex[0]].y;
279             vArray[j + 7] = vertex[Triangles[i].vertex[0]].z;
280
281             vArray[j + 8] = Triangles[i].gx[1];
282             vArray[j + 9] = Triangles[i].gy[1];
283             vArray[j + 10] = normals[Triangles[i].vertex[1]].x;
284             vArray[j + 11] = normals[Triangles[i].vertex[1]].y;
285             vArray[j + 12] = normals[Triangles[i].vertex[1]].z;
286             vArray[j + 13] = vertex[Triangles[i].vertex[1]].x;
287             vArray[j + 14] = vertex[Triangles[i].vertex[1]].y;
288             vArray[j + 15] = vertex[Triangles[i].vertex[1]].z;
289
290             vArray[j + 16] = Triangles[i].gx[2];
291             vArray[j + 17] = Triangles[i].gy[2];
292             vArray[j + 18] = normals[Triangles[i].vertex[2]].x;
293             vArray[j + 19] = normals[Triangles[i].vertex[2]].y;
294             vArray[j + 20] = normals[Triangles[i].vertex[2]].z;
295             vArray[j + 21] = vertex[Triangles[i].vertex[2]].x;
296             vArray[j + 22] = vertex[Triangles[i].vertex[2]].y;
297             vArray[j + 23] = vertex[Triangles[i].vertex[2]].z;
298         }
299     if (flat)
300         for (i = 0; i < TriangleNum; i++) {
301             j = i * 24;
302             vArray[j + 0] = Triangles[i].gx[0];
303             vArray[j + 1] = Triangles[i].gy[0];
304             vArray[j + 2] = facenormals[i].x * -1;
305             vArray[j + 3] = facenormals[i].y * -1;
306             vArray[j + 4] = facenormals[i].z * -1;
307             vArray[j + 5] = vertex[Triangles[i].vertex[0]].x;
308             vArray[j + 6] = vertex[Triangles[i].vertex[0]].y;
309             vArray[j + 7] = vertex[Triangles[i].vertex[0]].z;
310
311             vArray[j + 8] = Triangles[i].gx[1];
312             vArray[j + 9] = Triangles[i].gy[1];
313             vArray[j + 10] = facenormals[i].x * -1;
314             vArray[j + 11] = facenormals[i].y * -1;
315             vArray[j + 12] = facenormals[i].z * -1;
316             vArray[j + 13] = vertex[Triangles[i].vertex[1]].x;
317             vArray[j + 14] = vertex[Triangles[i].vertex[1]].y;
318             vArray[j + 15] = vertex[Triangles[i].vertex[1]].z;
319
320             vArray[j + 16] = Triangles[i].gx[2];
321             vArray[j + 17] = Triangles[i].gy[2];
322             vArray[j + 18] = facenormals[i].x * -1;
323             vArray[j + 19] = facenormals[i].y * -1;
324             vArray[j + 20] = facenormals[i].z * -1;
325             vArray[j + 21] = vertex[Triangles[i].vertex[2]].x;
326             vArray[j + 22] = vertex[Triangles[i].vertex[2]].y;
327             vArray[j + 23] = vertex[Triangles[i].vertex[2]].z;
328
329         }
330 }
331
332 void Model::UpdateVertexArrayNoTex()
333 {
334     if (type != normaltype && type != decalstype)
335         return;
336     static int i;
337     static int j;
338     if (!flat)
339         for (i = 0; i < TriangleNum; i++) {
340             j = i * 24;
341             vArray[j + 2] = normals[Triangles[i].vertex[0]].x;
342             vArray[j + 3] = normals[Triangles[i].vertex[0]].y;
343             vArray[j + 4] = normals[Triangles[i].vertex[0]].z;
344             vArray[j + 5] = vertex[Triangles[i].vertex[0]].x;
345             vArray[j + 6] = vertex[Triangles[i].vertex[0]].y;
346             vArray[j + 7] = vertex[Triangles[i].vertex[0]].z;
347
348             vArray[j + 10] = normals[Triangles[i].vertex[1]].x;
349             vArray[j + 11] = normals[Triangles[i].vertex[1]].y;
350             vArray[j + 12] = normals[Triangles[i].vertex[1]].z;
351             vArray[j + 13] = vertex[Triangles[i].vertex[1]].x;
352             vArray[j + 14] = vertex[Triangles[i].vertex[1]].y;
353             vArray[j + 15] = vertex[Triangles[i].vertex[1]].z;
354
355             vArray[j + 18] = normals[Triangles[i].vertex[2]].x;
356             vArray[j + 19] = normals[Triangles[i].vertex[2]].y;
357             vArray[j + 20] = normals[Triangles[i].vertex[2]].z;
358             vArray[j + 21] = vertex[Triangles[i].vertex[2]].x;
359             vArray[j + 22] = vertex[Triangles[i].vertex[2]].y;
360             vArray[j + 23] = vertex[Triangles[i].vertex[2]].z;
361         }
362     if (flat)
363         for (i = 0; i < TriangleNum; i++) {
364             j = i * 24;
365             vArray[j + 2] = facenormals[i].x * -1;
366             vArray[j + 3] = facenormals[i].y * -1;
367             vArray[j + 4] = facenormals[i].z * -1;
368             vArray[j + 5] = vertex[Triangles[i].vertex[0]].x;
369             vArray[j + 6] = vertex[Triangles[i].vertex[0]].y;
370             vArray[j + 7] = vertex[Triangles[i].vertex[0]].z;
371
372             vArray[j + 10] = facenormals[i].x * -1;
373             vArray[j + 11] = facenormals[i].y * -1;
374             vArray[j + 12] = facenormals[i].z * -1;
375             vArray[j + 13] = vertex[Triangles[i].vertex[1]].x;
376             vArray[j + 14] = vertex[Triangles[i].vertex[1]].y;
377             vArray[j + 15] = vertex[Triangles[i].vertex[1]].z;
378
379             vArray[j + 18] = facenormals[i].x * -1;
380             vArray[j + 19] = facenormals[i].y * -1;
381             vArray[j + 20] = facenormals[i].z * -1;
382             vArray[j + 21] = vertex[Triangles[i].vertex[2]].x;
383             vArray[j + 22] = vertex[Triangles[i].vertex[2]].y;
384             vArray[j + 23] = vertex[Triangles[i].vertex[2]].z;
385         }
386 }
387
388 void Model::UpdateVertexArrayNoTexNoNorm()
389 {
390     if (type != normaltype && type != decalstype)
391         return;
392     static int i;
393     static int j;
394     for (i = 0; i < TriangleNum; i++) {
395         j = i * 24;
396         vArray[j + 5] = vertex[Triangles[i].vertex[0]].x;
397         vArray[j + 6] = vertex[Triangles[i].vertex[0]].y;
398         vArray[j + 7] = vertex[Triangles[i].vertex[0]].z;
399
400         vArray[j + 13] = vertex[Triangles[i].vertex[1]].x;
401         vArray[j + 14] = vertex[Triangles[i].vertex[1]].y;
402         vArray[j + 15] = vertex[Triangles[i].vertex[1]].z;
403
404         vArray[j + 21] = vertex[Triangles[i].vertex[2]].x;
405         vArray[j + 22] = vertex[Triangles[i].vertex[2]].y;
406         vArray[j + 23] = vertex[Triangles[i].vertex[2]].z;
407     }
408 }
409
410 bool Model::loadnotex(const char *filename )
411 {
412     FILE *tfile;
413     long i;
414
415     //~ int oldvertexNum, oldTriangleNum;
416     //~ oldvertexNum = vertexNum;
417     //~ oldTriangleNum = TriangleNum;
418
419     type = notextype;
420     color = 0;
421
422     tfile = fopen( ConvertFileName(filename), "rb" );
423     // read model settings
424
425     fseek(tfile, 0, SEEK_SET);
426     funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
427
428     // read the model data
429     deallocate();
430
431     numpossible = 0;
432
433     owner = (int*)malloc(sizeof(int) * vertexNum);
434     possible = (int*)malloc(sizeof(int) * TriangleNum);
435     vertex = (XYZ*)malloc(sizeof(XYZ) * vertexNum);
436     Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle) * TriangleNum);
437     vArray = (GLfloat*)malloc(sizeof(GLfloat) * TriangleNum * 24);
438
439     for (i = 0; i < vertexNum; i++) {
440         funpackf(tfile, "Bf Bf Bf", &vertex[i].x, &vertex[i].y, &vertex[i].z);
441     }
442
443     for (i = 0; i < TriangleNum; i++) {
444         //funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
445         short vertex[ 6];
446         funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
447         Triangles[i].vertex[ 0] = vertex[ 0];
448         Triangles[i].vertex[ 1] = vertex[ 2];
449         Triangles[i].vertex[ 2] = vertex[ 4];
450         funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
451         funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
452     }
453
454     fclose(tfile);
455
456     UpdateVertexArray();
457
458     for (i = 0; i < vertexNum; i++) {
459         owner[i] = -1;
460     }
461
462     static int j;
463     boundingsphereradius = 0;
464     for (i = 0; i < vertexNum; i++) {
465         for (j = 0; j < vertexNum; j++) {
466             if (j != i && distsq(&vertex[j], &vertex[i]) / 2 > boundingsphereradius) {
467                 boundingsphereradius = distsq(&vertex[j], &vertex[i]) / 2;
468                 boundingspherecenter = (vertex[i] + vertex[j]) / 2;
469             }
470         }
471     }
472     boundingsphereradius = fast_sqrt(boundingsphereradius);
473
474     return 1;
475 }
476
477
478 bool Model::load(const char *filename, bool texture )
479 {
480     FILE *tfile;
481     long i;
482
483     LOGFUNC;
484
485     LOG(std::string("Loading model...") + filename);
486
487     if (visibleloading)
488         Game::LoadingScreen();
489
490     //~ int oldvertexNum, oldTriangleNum;
491     //~ oldvertexNum = vertexNum;
492     //~ oldTriangleNum = TriangleNum;
493
494     type = normaltype;
495     color = 0;
496
497     tfile = fopen( ConvertFileName(filename), "rb" );
498     // read model settings
499
500
501     fseek(tfile, 0, SEEK_SET);
502     funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
503
504     // read the model data
505     deallocate();
506
507     numpossible = 0;
508
509     owner = (int*)malloc(sizeof(int) * vertexNum);
510     possible = (int*)malloc(sizeof(int) * TriangleNum);
511     vertex = (XYZ*)malloc(sizeof(XYZ) * vertexNum);
512     normals = (XYZ*)malloc(sizeof(XYZ) * vertexNum);
513     facenormals = (XYZ*)malloc(sizeof(XYZ) * TriangleNum);
514     Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle) * TriangleNum);
515     vArray = (GLfloat*)malloc(sizeof(GLfloat) * TriangleNum * 24);
516
517     for (i = 0; i < vertexNum; i++) {
518         funpackf(tfile, "Bf Bf Bf", &vertex[i].x, &vertex[i].y, &vertex[i].z);
519     }
520
521     for (i = 0; i < TriangleNum; i++) {
522         //funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
523         short vertex[ 6];
524         funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
525         Triangles[i].vertex[ 0] = vertex[ 0];
526         Triangles[i].vertex[ 1] = vertex[ 2];
527         Triangles[i].vertex[ 2] = vertex[ 4];
528         funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
529         funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
530     }
531
532     modelTexture.xsz = 0;
533
534     fclose(tfile);
535
536     UpdateVertexArray();
537
538     for (i = 0; i < vertexNum; i++) {
539         owner[i] = -1;
540     }
541
542     static int j;
543     boundingsphereradius = 0;
544     for (i = 0; i < vertexNum; i++) {
545         for (j = 0; j < vertexNum; j++) {
546             if (j != i && distsq(&vertex[j], &vertex[i]) / 2 > boundingsphereradius) {
547                 boundingsphereradius = distsq(&vertex[j], &vertex[i]) / 2;
548                 boundingspherecenter = (vertex[i] + vertex[j]) / 2;
549             }
550         }
551     }
552     boundingsphereradius = fast_sqrt(boundingsphereradius);
553
554     return 1;
555 }
556
557 bool Model::loaddecal(const char *filename, bool texture )
558 {
559     FILE *tfile;
560     long i, j;
561
562     LOGFUNC;
563
564     // Changing the filename so that its more os specific
565     char * FixedFN = ConvertFileName(filename);
566
567     LOG(std::string("Loading decal...") + FixedFN);
568
569     //~ int oldvertexNum, oldTriangleNum;
570     //~ oldvertexNum = vertexNum;
571     //~ oldTriangleNum = TriangleNum;
572
573     type = decalstype;
574     numdecals = 0;
575     color = 0;
576
577     tfile = fopen( FixedFN, "rb" );
578     // read model settings
579
580
581     fseek(tfile, 0, SEEK_SET);
582     funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
583
584     // read the model data
585
586     deallocate();
587
588     numpossible = 0;
589
590     owner = (int*)malloc(sizeof(int) * vertexNum);
591     possible = (int*)malloc(sizeof(int) * TriangleNum);
592     vertex = (XYZ*)malloc(sizeof(XYZ) * vertexNum);
593     normals = (XYZ*)malloc(sizeof(XYZ) * vertexNum);
594     facenormals = (XYZ*)malloc(sizeof(XYZ) * TriangleNum);
595     Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle) * TriangleNum);
596     vArray = (GLfloat*)malloc(sizeof(GLfloat) * TriangleNum * 24);
597
598
599     for (i = 0; i < vertexNum; i++) {
600         funpackf(tfile, "Bf Bf Bf", &vertex[i].x, &vertex[i].y, &vertex[i].z);
601     }
602
603     for (i = 0; i < TriangleNum; i++) {
604         //funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
605         short vertex[ 6];
606         funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
607         Triangles[i].vertex[ 0] = vertex[ 0];
608         Triangles[i].vertex[ 1] = vertex[ 2];
609         Triangles[i].vertex[ 2] = vertex[ 4];
610         funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
611         funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
612     }
613
614
615     modelTexture.xsz = 0;
616
617     fclose(tfile);
618
619     UpdateVertexArray();
620
621     for (i = 0; i < vertexNum; i++) {
622         owner[i] = -1;
623     }
624
625     boundingsphereradius = 0;
626     for (i = 0; i < vertexNum; i++) {
627         for (j = 0; j < vertexNum; j++) {
628             if (j != i && distsq(&vertex[j], &vertex[i]) / 2 > boundingsphereradius) {
629                 boundingsphereradius = distsq(&vertex[j], &vertex[i]) / 2;
630                 boundingspherecenter = (vertex[i] + vertex[j]) / 2;
631             }
632         }
633     }
634     boundingsphereradius = fast_sqrt(boundingsphereradius);
635
636     //allow decals
637     if (!decaltexcoords) {
638         decaltexcoords = (float***)malloc(sizeof(float**)*max_model_decals);
639         for (i = 0; i < max_model_decals; i++) {
640             decaltexcoords[i] = (float**)malloc(sizeof(float*) * 3);
641             for (j = 0; j < 3; j++) {
642                 decaltexcoords[i][j] = (float*)malloc(sizeof(float) * 2);
643             }
644         }
645         //if(decalvertex)free(decalvertex);
646         decalvertex = (XYZ**)malloc(sizeof(XYZ*)*max_model_decals);
647         for (i = 0; i < max_model_decals; i++) {
648             decalvertex[i] = (XYZ*)malloc(sizeof(XYZ) * 3);
649         }
650
651         decaltype = (int*)malloc(sizeof(int) * max_model_decals);
652         decalopacity = (float*)malloc(sizeof(float) * max_model_decals);
653         decalrotation = (float*)malloc(sizeof(float) * max_model_decals);
654         decalalivetime = (float*)malloc(sizeof(float) * max_model_decals);
655         decalposition = (XYZ*)malloc(sizeof(XYZ) * max_model_decals);
656     }
657
658     return 1;
659 }
660
661 bool Model::loadraw(char *filename )
662 {
663     FILE *tfile;
664     long i;
665
666     LOGFUNC;
667
668     LOG(std::string("Loading raw...") + filename);
669
670     //~ int oldvertexNum, oldTriangleNum;
671     //~ oldvertexNum = vertexNum;
672     //~ oldTriangleNum = TriangleNum;
673
674     type = rawtype;
675     color = 0;
676
677     tfile = fopen( ConvertFileName(filename), "rb" );
678     // read model settings
679
680
681     fseek(tfile, 0, SEEK_SET);
682     funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
683
684     // read the model data
685     deallocate();
686
687     numpossible = 0;
688
689     owner = (int*)malloc(sizeof(int) * vertexNum);
690     possible = (int*)malloc(sizeof(int) * TriangleNum);
691     vertex = (XYZ*)malloc(sizeof(XYZ) * vertexNum);
692     Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle) * TriangleNum);
693     vArray = (GLfloat*)malloc(sizeof(GLfloat) * TriangleNum * 24);
694
695
696     for (i = 0; i < vertexNum; i++) {
697         funpackf(tfile, "Bf Bf Bf", &vertex[i].x, &vertex[i].y, &vertex[i].z);
698     }
699
700     for (i = 0; i < TriangleNum; i++) {
701         //funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
702         short vertex[ 6];
703         funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
704         Triangles[i].vertex[ 0] = vertex[ 0];
705         Triangles[i].vertex[ 1] = vertex[ 2];
706         Triangles[i].vertex[ 2] = vertex[ 4];
707         funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
708         funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
709     }
710
711
712     fclose(tfile);
713
714     for (i = 0; i < vertexNum; i++) {
715         owner[i] = -1;
716     }
717
718     return 1;
719 }
720
721
722 void Model::UniformTexCoords()
723 {
724     static int i;
725     for (i = 0; i < TriangleNum; i++) {
726         Triangles[i].gy[0] = vertex[Triangles[i].vertex[0]].y;
727         Triangles[i].gy[1] = vertex[Triangles[i].vertex[1]].y;
728         Triangles[i].gy[2] = vertex[Triangles[i].vertex[2]].y;
729         Triangles[i].gx[0] = vertex[Triangles[i].vertex[0]].x;
730         Triangles[i].gx[1] = vertex[Triangles[i].vertex[1]].x;
731         Triangles[i].gx[2] = vertex[Triangles[i].vertex[2]].x;
732     }
733     UpdateVertexArray();
734 }
735
736
737 void Model::FlipTexCoords()
738 {
739     static int i;
740     for (i = 0; i < TriangleNum; i++) {
741         Triangles[i].gy[0] = -Triangles[i].gy[0];
742         Triangles[i].gy[1] = -Triangles[i].gy[1];
743         Triangles[i].gy[2] = -Triangles[i].gy[2];
744     }
745     UpdateVertexArray();
746 }
747
748 void Model::ScaleTexCoords(float howmuch)
749 {
750     static int i;
751     for (i = 0; i < TriangleNum; i++) {
752         Triangles[i].gx[0] *= howmuch;
753         Triangles[i].gx[1] *= howmuch;
754         Triangles[i].gx[2] *= howmuch;
755         Triangles[i].gy[0] *= howmuch;
756         Triangles[i].gy[1] *= howmuch;
757         Triangles[i].gy[2] *= howmuch;
758     }
759     UpdateVertexArray();
760 }
761
762 void Model::Scale(float xscale, float yscale, float zscale)
763 {
764     static int i;
765     for (i = 0; i < vertexNum; i++) {
766         vertex[i].x *= xscale;
767         vertex[i].y *= yscale;
768         vertex[i].z *= zscale;
769     }
770     UpdateVertexArray();
771
772     static int j;
773
774     boundingsphereradius = 0;
775     for (i = 0; i < vertexNum; i++) {
776         for (j = 0; j < vertexNum; j++) {
777             if (j != i && distsq(&vertex[j], &vertex[i]) / 2 > boundingsphereradius) {
778                 boundingsphereradius = distsq(&vertex[j], &vertex[i]) / 2;
779                 boundingspherecenter = (vertex[i] + vertex[j]) / 2;
780             }
781         }
782     }
783     boundingsphereradius = fast_sqrt(boundingsphereradius);
784 }
785
786 void Model::ScaleNormals(float xscale, float yscale, float zscale)
787 {
788     if (type != normaltype && type != decalstype)
789         return;
790     static int i;
791     for (i = 0; i < vertexNum; i++) {
792         normals[i].x *= xscale;
793         normals[i].y *= yscale;
794         normals[i].z *= zscale;
795     }
796     for (i = 0; i < TriangleNum; i++) {
797         facenormals[i].x *= xscale;
798         facenormals[i].y *= yscale;
799         facenormals[i].z *= zscale;
800     }
801     UpdateVertexArray();
802 }
803
804 void Model::Translate(float xtrans, float ytrans, float ztrans)
805 {
806     static int i;
807     for (i = 0; i < vertexNum; i++) {
808         vertex[i].x += xtrans;
809         vertex[i].y += ytrans;
810         vertex[i].z += ztrans;
811     }
812     UpdateVertexArray();
813
814     static int j;
815     boundingsphereradius = 0;
816     for (i = 0; i < vertexNum; i++) {
817         for (j = 0; j < vertexNum; j++) {
818             if (j != i && distsq(&vertex[j], &vertex[i]) / 2 > boundingsphereradius) {
819                 boundingsphereradius = distsq(&vertex[j], &vertex[i]) / 2;
820                 boundingspherecenter = (vertex[i] + vertex[j]) / 2;
821             }
822         }
823     }
824     boundingsphereradius = fast_sqrt(boundingsphereradius);
825 }
826
827 void Model::Rotate(float xang, float yang, float zang)
828 {
829     static int i;
830     for (i = 0; i < vertexNum; i++) {
831         vertex[i] = DoRotation(vertex[i], xang, yang, zang);
832     }
833     UpdateVertexArray();
834
835     static int j;
836     boundingsphereradius = 0;
837     for (i = 0; i < vertexNum; i++) {
838         for (j = 0; j < vertexNum; j++) {
839             if (j != i && distsq(&vertex[j], &vertex[i]) / 2 > boundingsphereradius) {
840                 boundingsphereradius = distsq(&vertex[j], &vertex[i]) / 2;
841                 boundingspherecenter = (vertex[i] + vertex[j]) / 2;
842             }
843         }
844     }
845     boundingsphereradius = fast_sqrt(boundingsphereradius);
846 }
847
848
849 void Model::CalculateNormals(bool facenormalise)
850 {
851     if (visibleloading)
852         Game::LoadingScreen();
853     static int i;
854     if (type != normaltype && type != decalstype)
855         return;
856
857     for (i = 0; i < vertexNum; i++) {
858         normals[i].x = 0;
859         normals[i].y = 0;
860         normals[i].z = 0;
861     }
862
863     for (i = 0; i < TriangleNum; i++) {
864         CrossProduct(vertex[Triangles[i].vertex[1]] - vertex[Triangles[i].vertex[0]], vertex[Triangles[i].vertex[2]] - vertex[Triangles[i].vertex[0]], &facenormals[i]);
865
866         normals[Triangles[i].vertex[0]].x += facenormals[i].x;
867         normals[Triangles[i].vertex[0]].y += facenormals[i].y;
868         normals[Triangles[i].vertex[0]].z += facenormals[i].z;
869
870         normals[Triangles[i].vertex[1]].x += facenormals[i].x;
871         normals[Triangles[i].vertex[1]].y += facenormals[i].y;
872         normals[Triangles[i].vertex[1]].z += facenormals[i].z;
873
874         normals[Triangles[i].vertex[2]].x += facenormals[i].x;
875         normals[Triangles[i].vertex[2]].y += facenormals[i].y;
876         normals[Triangles[i].vertex[2]].z += facenormals[i].z;
877         if (facenormalise)
878             Normalise(&facenormals[i]);
879     }
880     for (i = 0; i < vertexNum; i++) {
881         Normalise(&normals[i]);
882         normals[i] *= -1;
883     }
884     UpdateVertexArrayNoTex();
885 }
886
887 void Model::drawimmediate()
888 {
889     textureptr.bind();
890     glBegin(GL_TRIANGLES);
891     for (int i = 0; i < TriangleNum; i++) {
892         /*if(Triangles[i].vertex[0]<vertexNum&&Triangles[i].vertex[1]<vertexNum&&Triangles[i].vertex[2]<vertexNum&&Triangles[i].vertex[0]>=0&&Triangles[i].vertex[1]>=0&&Triangles[i].vertex[2]>=0){
893         if(isnormal(vertex[Triangles[i].vertex[0]].x)&&isnormal(vertex[Triangles[i].vertex[0]].y)&&isnormal(vertex[Triangles[i].vertex[0]].z)
894         &&isnormal(vertex[Triangles[i].vertex[1]].x)&&isnormal(vertex[Triangles[i].vertex[1]].y)&&isnormal(vertex[Triangles[i].vertex[1]].z)
895         &&isnormal(vertex[Triangles[i].vertex[2]].x)&&isnormal(vertex[Triangles[i].vertex[2]].y)&&isnormal(vertex[Triangles[i].vertex[2]].z)){
896         */
897         glTexCoord2f(Triangles[i].gx[0], Triangles[i].gy[0]);
898         if (color)
899             glColor3f(normals[Triangles[i].vertex[0]].x, normals[Triangles[i].vertex[0]].y, normals[Triangles[i].vertex[0]].z);
900         if (!color && !flat)
901             glNormal3f(normals[Triangles[i].vertex[0]].x, normals[Triangles[i].vertex[0]].y, normals[Triangles[i].vertex[0]].z);
902         if (!color && flat)
903             glNormal3f(facenormals[i].x, facenormals[i].y, facenormals[i].y);
904         glVertex3f(vertex[Triangles[i].vertex[0]].x, vertex[Triangles[i].vertex[0]].y, vertex[Triangles[i].vertex[0]].z);
905
906         glTexCoord2f(Triangles[i].gx[1], Triangles[i].gy[1]);
907         if (color)
908             glColor3f(normals[Triangles[i].vertex[1]].x, normals[Triangles[i].vertex[1]].y, normals[Triangles[i].vertex[1]].z);
909         if (!color && !flat)
910             glNormal3f(normals[Triangles[i].vertex[1]].x, normals[Triangles[i].vertex[1]].y, normals[Triangles[i].vertex[1]].z);
911         if (!color && flat)
912             glNormal3f(facenormals[i].x, facenormals[i].y, facenormals[i].y);
913         glVertex3f(vertex[Triangles[i].vertex[1]].x, vertex[Triangles[i].vertex[1]].y, vertex[Triangles[i].vertex[1]].z);
914
915         glTexCoord2f(Triangles[i].gx[2], Triangles[i].gy[2]);
916         if (color)
917             glColor3f(normals[Triangles[i].vertex[2]].x, normals[Triangles[i].vertex[2]].y, normals[Triangles[i].vertex[2]].z);
918         if (!color && !flat)
919             glNormal3f(normals[Triangles[i].vertex[2]].x, normals[Triangles[i].vertex[2]].y, normals[Triangles[i].vertex[2]].z);
920         if (!color && flat)
921             glNormal3f(facenormals[i].x, facenormals[i].y, facenormals[i].y);
922         glVertex3f(vertex[Triangles[i].vertex[2]].x, vertex[Triangles[i].vertex[2]].y, vertex[Triangles[i].vertex[2]].z);
923         //}
924         //}
925     }
926     glEnd();
927 }
928
929 void Model::draw()
930 {
931     if (type != normaltype && type != decalstype)
932         return;
933
934     glEnableClientState(GL_NORMAL_ARRAY);
935     glEnableClientState(GL_VERTEX_ARRAY);
936     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
937
938     if (!color)
939         glInterleavedArrays( GL_T2F_N3F_V3F, 8 * sizeof(GLfloat), &vArray[0]);
940     if (color)
941         glInterleavedArrays( GL_T2F_C3F_V3F, 8 * sizeof(GLfloat), &vArray[0]);
942     textureptr.bind();
943
944 #if PLATFORM_MACOSX
945     glLockArraysEXT( 0, TriangleNum * 3);
946 #endif
947     glDrawArrays(GL_TRIANGLES, 0, TriangleNum * 3);
948 #if PLATFORM_MACOSX
949     glUnlockArraysEXT();
950 #endif
951
952
953     if (!color)
954         glDisableClientState(GL_NORMAL_ARRAY);
955     if (color)
956         glDisableClientState(GL_COLOR_ARRAY);
957     glDisableClientState(GL_VERTEX_ARRAY);
958     glDisableClientState(GL_TEXTURE_COORD_ARRAY);
959     //drawimmediate();
960 }
961
962 //TODO: phase out in favor of Texture
963 void Model::drawdifftex(GLuint texture)
964 {
965     glEnableClientState(GL_NORMAL_ARRAY);
966     glEnableClientState(GL_VERTEX_ARRAY);
967     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
968     if (!color)
969         glInterleavedArrays( GL_T2F_N3F_V3F, 8 * sizeof(GLfloat), &vArray[0]);
970     if (color)
971         glInterleavedArrays( GL_T2F_C3F_V3F, 8 * sizeof(GLfloat), &vArray[0]);
972
973     glBindTexture(GL_TEXTURE_2D, (unsigned long)texture);
974     glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
975     glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
976
977
978 #ifndef WIN32
979     glLockArraysEXT( 0, TriangleNum * 3);
980 #endif
981     glDrawArrays(GL_TRIANGLES, 0, TriangleNum * 3);
982 #ifndef WIN32
983     glUnlockArraysEXT();
984 #endif
985
986
987     if (!color)
988         glDisableClientState(GL_NORMAL_ARRAY);
989     if (color)
990         glDisableClientState(GL_COLOR_ARRAY);
991     glDisableClientState(GL_VERTEX_ARRAY);
992     glDisableClientState(GL_TEXTURE_COORD_ARRAY);
993 }
994
995 void Model::drawdifftex(Texture texture)
996 {
997     glEnableClientState(GL_NORMAL_ARRAY);
998     glEnableClientState(GL_VERTEX_ARRAY);
999     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1000     if (!color)
1001         glInterleavedArrays( GL_T2F_N3F_V3F, 8 * sizeof(GLfloat), &vArray[0]);
1002     if (color)
1003         glInterleavedArrays( GL_T2F_C3F_V3F, 8 * sizeof(GLfloat), &vArray[0]);
1004
1005     texture.bind();
1006     glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
1007     glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
1008
1009
1010 #ifndef WIN32
1011     glLockArraysEXT( 0, TriangleNum * 3);
1012 #endif
1013     glDrawArrays(GL_TRIANGLES, 0, TriangleNum * 3);
1014 #ifndef WIN32
1015     glUnlockArraysEXT();
1016 #endif
1017
1018
1019     if (!color)
1020         glDisableClientState(GL_NORMAL_ARRAY);
1021     if (color)
1022         glDisableClientState(GL_COLOR_ARRAY);
1023     glDisableClientState(GL_VERTEX_ARRAY);
1024     glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1025 }
1026
1027 void Model::drawdecals(Texture shadowtexture, Texture bloodtexture, Texture bloodtexture2, Texture breaktexture)
1028 {
1029     if (decals) {
1030         if (type != decalstype)
1031             return;
1032         static int i;
1033         //~ static float distancemult;
1034         static int lasttype;
1035         //~ static float viewdistsquared;
1036         static bool blend;
1037
1038         //~ viewdistsquared = viewdistance * viewdistance;
1039         blend = 1;
1040
1041         lasttype = -1;
1042         glEnable(GL_BLEND);
1043         glDisable(GL_LIGHTING);
1044         glDisable(GL_CULL_FACE);
1045         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1046         glDepthMask(0);
1047         if (numdecals > max_model_decals)
1048             numdecals = max_model_decals;
1049         for (i = 0; i < numdecals; i++) {
1050             if (decaltype[i] == blooddecalfast && decalalivetime[i] < 2)
1051                 decalalivetime[i] = 2;
1052
1053             if (decaltype[i] == shadowdecal && decaltype[i] != lasttype) {
1054                 shadowtexture.bind();
1055                 if (!blend) {
1056                     blend = 1;
1057                     glAlphaFunc(GL_GREATER, 0.0001);
1058                     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1059                 }
1060             }
1061             if (decaltype[i] == breakdecal && decaltype[i] != lasttype) {
1062                 breaktexture.bind();
1063                 if (!blend) {
1064                     blend = 1;
1065                     glAlphaFunc(GL_GREATER, 0.0001);
1066                     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1067                 }
1068             }
1069             if ((decaltype[i] == blooddecal || decaltype[i] == blooddecalslow) && decaltype[i] != lasttype) {
1070                 bloodtexture.bind();
1071                 if (blend) {
1072                     blend = 0;
1073                     glAlphaFunc(GL_GREATER, 0.15);
1074                     glBlendFunc(GL_ONE, GL_ZERO);
1075                 }
1076             }
1077             if ((decaltype[i] == blooddecalfast) && decaltype[i] != lasttype) {
1078                 bloodtexture2.bind();
1079                 if (blend) {
1080                     blend = 0;
1081                     glAlphaFunc(GL_GREATER, 0.15);
1082                     glBlendFunc(GL_ONE, GL_ZERO);
1083                 }
1084             }
1085             if (decaltype[i] == shadowdecal) {
1086                 glColor4f(1, 1, 1, decalopacity[i]);
1087             }
1088             if (decaltype[i] == breakdecal) {
1089                 glColor4f(1, 1, 1, decalopacity[i]);
1090                 if (decalalivetime[i] > 58)
1091                     glColor4f(1, 1, 1, decalopacity[i] * (60 - decalalivetime[i]) / 2);
1092             }
1093             if ((decaltype[i] == blooddecal || decaltype[i] == blooddecalfast || decaltype[i] == blooddecalslow)) {
1094                 glColor4f(1, 1, 1, decalopacity[i]);
1095                 if (decalalivetime[i] < 4)
1096                     glColor4f(1, 1, 1, decalopacity[i]*decalalivetime[i]*.25);
1097                 if (decalalivetime[i] > 58)
1098                     glColor4f(1, 1, 1, decalopacity[i] * (60 - decalalivetime[i]) / 2);
1099             }
1100             lasttype = decaltype[i];
1101             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1102             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
1103
1104             glMatrixMode(GL_MODELVIEW);
1105             glPushMatrix();
1106             glBegin(GL_TRIANGLES);
1107             for (int j = 0; j < 3; j++) {
1108                 glTexCoord2f(decaltexcoords[i][j][0], decaltexcoords[i][j][1]);
1109                 glVertex3f(decalvertex[i][j].x, decalvertex[i][j].y, decalvertex[i][j].z);
1110             }
1111             glEnd();
1112             glPopMatrix();
1113         }
1114         for (i = numdecals - 1; i >= 0; i--) {
1115             decalalivetime[i] += multiplier;
1116             if (decaltype[i] == blooddecalslow)
1117                 decalalivetime[i] -= multiplier * 2 / 3;
1118             if (decaltype[i] == blooddecalfast)
1119                 decalalivetime[i] += multiplier * 4;
1120             if (decaltype[i] == shadowdecal)
1121                 DeleteDecal(i);
1122             if ((decaltype[i] == blooddecal || decaltype[i] == blooddecalfast || decaltype[i] == blooddecalslow) && decalalivetime[i] >= 60)
1123                 DeleteDecal(i);
1124         }
1125         glAlphaFunc(GL_GREATER, 0.0001);
1126         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1127     }
1128 }
1129
1130 void Model::DeleteDecal(int which)
1131 {
1132     if (decals) {
1133         if (type != decalstype)
1134             return;
1135         decaltype[which] = decaltype[numdecals - 1];
1136         decalposition[which] = decalposition[numdecals - 1];
1137         for (int i = 0; i < 3; i++) {
1138             decalvertex[which][i] = decalvertex[numdecals - 1][i];
1139             decaltexcoords[which][i][0] = decaltexcoords[numdecals - 1][i][0];
1140             decaltexcoords[which][i][1] = decaltexcoords[numdecals - 1][i][1];
1141         }
1142         decalrotation[which] = decalrotation[numdecals - 1];
1143         decalalivetime[which] = decalalivetime[numdecals - 1];
1144         decalopacity[which] = decalopacity[numdecals - 1];
1145         numdecals--;
1146     }
1147 }
1148
1149 void Model::MakeDecal(int atype, XYZ *where, float *size, float *opacity, float *rotation)
1150 {
1151     if (decals) {
1152         if (type != decalstype)
1153             return;
1154
1155         static float placex, placez;
1156         static XYZ rot;
1157         //static XYZ point,point1,point2;
1158         static float distance;
1159         static int i, j;
1160
1161         if (*opacity > 0)
1162             if (distsq(where, &boundingspherecenter) < (boundingsphereradius + *size) * (boundingsphereradius + *size))
1163                 for (i = 0; i < TriangleNum; i++) {
1164                     if (facenormals[i].y < -.1 && (vertex[Triangles[i].vertex[0]].y < where->y || vertex[Triangles[i].vertex[1]].y < where->y || vertex[Triangles[i].vertex[2]].y < where->y)) {
1165                         decalposition[numdecals] = *where;
1166                         decaltype[numdecals] = atype;
1167                         decalrotation[numdecals] = *rotation;
1168                         decalalivetime[numdecals] = 0;
1169                         distance = abs(((facenormals[i].x * where->x) + (facenormals[i].y * where->y) + (facenormals[i].z * where->z) - ((facenormals[i].x * vertex[Triangles[i].vertex[0]].x) + (facenormals[i].y * vertex[Triangles[i].vertex[0]].y) + (facenormals[i].z * vertex[Triangles[i].vertex[0]].z))) / facenormals[i].y);
1170                         decalopacity[numdecals] = *opacity - distance / 10;
1171
1172                         if (decalopacity[numdecals > 0]) {
1173                             placex = vertex[Triangles[i].vertex[0]].x;
1174                             placez = vertex[Triangles[i].vertex[0]].z;
1175
1176                             decaltexcoords[numdecals][0][0] = (placex - where->x) / (*size) / 2 + .5;
1177                             decaltexcoords[numdecals][0][1] = (placez - where->z) / (*size) / 2 + .5;
1178
1179                             decalvertex[numdecals][0].x = placex;
1180                             decalvertex[numdecals][0].z = placez;
1181                             decalvertex[numdecals][0].y = vertex[Triangles[i].vertex[0]].y;
1182
1183
1184                             placex = vertex[Triangles[i].vertex[1]].x;
1185                             placez = vertex[Triangles[i].vertex[1]].z;
1186
1187                             decaltexcoords[numdecals][1][0] = (placex - where->x) / (*size) / 2 + .5;
1188                             decaltexcoords[numdecals][1][1] = (placez - where->z) / (*size) / 2 + .5;
1189
1190                             decalvertex[numdecals][1].x = placex;
1191                             decalvertex[numdecals][1].z = placez;
1192                             decalvertex[numdecals][1].y = vertex[Triangles[i].vertex[1]].y;
1193
1194
1195                             placex = vertex[Triangles[i].vertex[2]].x;
1196                             placez = vertex[Triangles[i].vertex[2]].z;
1197
1198                             decaltexcoords[numdecals][2][0] = (placex - where->x) / (*size) / 2 + .5;
1199                             decaltexcoords[numdecals][2][1] = (placez - where->z) / (*size) / 2 + .5;
1200
1201                             decalvertex[numdecals][2].x = placex;
1202                             decalvertex[numdecals][2].z = placez;
1203                             decalvertex[numdecals][2].y = vertex[Triangles[i].vertex[2]].y;
1204
1205                             if (!(decaltexcoords[numdecals][0][0] < 0 && decaltexcoords[numdecals][1][0] < 0 && decaltexcoords[numdecals][2][0] < 0))
1206                                 if (!(decaltexcoords[numdecals][0][1] < 0 && decaltexcoords[numdecals][1][1] < 0 && decaltexcoords[numdecals][2][1] < 0))
1207                                     if (!(decaltexcoords[numdecals][0][0] > 1 && decaltexcoords[numdecals][1][0] > 1 && decaltexcoords[numdecals][2][0] > 1))
1208                                         if (!(decaltexcoords[numdecals][0][1] > 1 && decaltexcoords[numdecals][1][1] > 1 && decaltexcoords[numdecals][2][1] > 1)) {
1209                                             if (decalrotation[numdecals]) {
1210                                                 for (j = 0; j < 3; j++) {
1211                                                     rot.y = 0;
1212                                                     rot.x = decaltexcoords[numdecals][j][0] - .5;
1213                                                     rot.z = decaltexcoords[numdecals][j][1] - .5;
1214                                                     rot = DoRotation(rot, 0, -decalrotation[numdecals], 0);
1215                                                     decaltexcoords[numdecals][j][0] = rot.x + .5;
1216                                                     decaltexcoords[numdecals][j][1] = rot.z + .5;
1217                                                 }
1218                                             }
1219                                             if (numdecals < max_model_decals - 1)
1220                                                 numdecals++;
1221                                         }
1222                         }
1223                     }
1224                 }
1225     }
1226 }
1227
1228 void Model::MakeDecal(int atype, XYZ where, float size, float opacity, float rotation)
1229 {
1230     if (decals) {
1231         if (type != decalstype)
1232             return;
1233
1234         static float placex, placez;
1235         static XYZ rot;
1236         //static XYZ point,point1,point2;
1237         static float distance;
1238         static int i, j;
1239
1240         if (opacity > 0)
1241             if (distsq(&where, &boundingspherecenter) < (boundingsphereradius + size) * (boundingsphereradius + size))
1242                 for (i = 0; i < TriangleNum; i++) {
1243                     distance = abs(((facenormals[i].x * where.x) + (facenormals[i].y * where.y) + (facenormals[i].z * where.z) - ((facenormals[i].x * vertex[Triangles[i].vertex[0]].x) + (facenormals[i].y * vertex[Triangles[i].vertex[0]].y) + (facenormals[i].z * vertex[Triangles[i].vertex[0]].z))));
1244                     if (distance < .02 && abs(facenormals[i].y) > abs(facenormals[i].x) && abs(facenormals[i].y) > abs(facenormals[i].z)) {
1245                         decalposition[numdecals] = where;
1246                         decaltype[numdecals] = atype;
1247                         decalrotation[numdecals] = rotation;
1248                         decalalivetime[numdecals] = 0;
1249                         decalopacity[numdecals] = opacity - distance / 10;
1250
1251                         if (decalopacity[numdecals > 0]) {
1252                             placex = vertex[Triangles[i].vertex[0]].x;
1253                             placez = vertex[Triangles[i].vertex[0]].z;
1254
1255                             decaltexcoords[numdecals][0][0] = (placex - where.x) / (size) / 2 + .5;
1256                             decaltexcoords[numdecals][0][1] = (placez - where.z) / (size) / 2 + .5;
1257
1258                             decalvertex[numdecals][0].x = placex;
1259                             decalvertex[numdecals][0].z = placez;
1260                             decalvertex[numdecals][0].y = vertex[Triangles[i].vertex[0]].y;
1261
1262
1263                             placex = vertex[Triangles[i].vertex[1]].x;
1264                             placez = vertex[Triangles[i].vertex[1]].z;
1265
1266                             decaltexcoords[numdecals][1][0] = (placex - where.x) / (size) / 2 + .5;
1267                             decaltexcoords[numdecals][1][1] = (placez - where.z) / (size) / 2 + .5;
1268
1269                             decalvertex[numdecals][1].x = placex;
1270                             decalvertex[numdecals][1].z = placez;
1271                             decalvertex[numdecals][1].y = vertex[Triangles[i].vertex[1]].y;
1272
1273
1274                             placex = vertex[Triangles[i].vertex[2]].x;
1275                             placez = vertex[Triangles[i].vertex[2]].z;
1276
1277                             decaltexcoords[numdecals][2][0] = (placex - where.x) / (size) / 2 + .5;
1278                             decaltexcoords[numdecals][2][1] = (placez - where.z) / (size) / 2 + .5;
1279
1280                             decalvertex[numdecals][2].x = placex;
1281                             decalvertex[numdecals][2].z = placez;
1282                             decalvertex[numdecals][2].y = vertex[Triangles[i].vertex[2]].y;
1283
1284                             if (!(decaltexcoords[numdecals][0][0] < 0 && decaltexcoords[numdecals][1][0] < 0 && decaltexcoords[numdecals][2][0] < 0))
1285                                 if (!(decaltexcoords[numdecals][0][1] < 0 && decaltexcoords[numdecals][1][1] < 0 && decaltexcoords[numdecals][2][1] < 0))
1286                                     if (!(decaltexcoords[numdecals][0][0] > 1 && decaltexcoords[numdecals][1][0] > 1 && decaltexcoords[numdecals][2][0] > 1))
1287                                         if (!(decaltexcoords[numdecals][0][1] > 1 && decaltexcoords[numdecals][1][1] > 1 && decaltexcoords[numdecals][2][1] > 1)) {
1288                                             if (decalrotation[numdecals]) {
1289                                                 for (j = 0; j < 3; j++) {
1290                                                     rot.y = 0;
1291                                                     rot.x = decaltexcoords[numdecals][j][0] - .5;
1292                                                     rot.z = decaltexcoords[numdecals][j][1] - .5;
1293                                                     rot = DoRotation(rot, 0, -decalrotation[numdecals], 0);
1294                                                     decaltexcoords[numdecals][j][0] = rot.x + .5;
1295                                                     decaltexcoords[numdecals][j][1] = rot.z + .5;
1296                                                 }
1297                                             }
1298                                             if (numdecals < max_model_decals - 1)
1299                                                 numdecals++;
1300                                         }
1301                         }
1302                     } else if (distance < .02 && abs(facenormals[i].x) > abs(facenormals[i].y) && abs(facenormals[i].x) > abs(facenormals[i].z)) {
1303                         decalposition[numdecals] = where;
1304                         decaltype[numdecals] = atype;
1305                         decalrotation[numdecals] = rotation;
1306                         decalalivetime[numdecals] = 0;
1307                         decalopacity[numdecals] = opacity - distance / 10;
1308
1309                         if (decalopacity[numdecals > 0]) {
1310                             placex = vertex[Triangles[i].vertex[0]].y;
1311                             placez = vertex[Triangles[i].vertex[0]].z;
1312
1313                             decaltexcoords[numdecals][0][0] = (placex - where.y) / (size) / 2 + .5;
1314                             decaltexcoords[numdecals][0][1] = (placez - where.z) / (size) / 2 + .5;
1315
1316                             decalvertex[numdecals][0].x = vertex[Triangles[i].vertex[0]].x;
1317                             decalvertex[numdecals][0].z = placez;
1318                             decalvertex[numdecals][0].y = placex;
1319
1320
1321                             placex = vertex[Triangles[i].vertex[1]].y;
1322                             placez = vertex[Triangles[i].vertex[1]].z;
1323
1324                             decaltexcoords[numdecals][1][0] = (placex - where.y) / (size) / 2 + .5;
1325                             decaltexcoords[numdecals][1][1] = (placez - where.z) / (size) / 2 + .5;
1326
1327                             decalvertex[numdecals][1].x = vertex[Triangles[i].vertex[1]].x;
1328                             decalvertex[numdecals][1].z = placez;
1329                             decalvertex[numdecals][1].y = placex;
1330
1331
1332                             placex = vertex[Triangles[i].vertex[2]].y;
1333                             placez = vertex[Triangles[i].vertex[2]].z;
1334
1335                             decaltexcoords[numdecals][2][0] = (placex - where.y) / (size) / 2 + .5;
1336                             decaltexcoords[numdecals][2][1] = (placez - where.z) / (size) / 2 + .5;
1337
1338                             decalvertex[numdecals][2].x = vertex[Triangles[i].vertex[2]].x;
1339                             decalvertex[numdecals][2].z = placez;
1340                             decalvertex[numdecals][2].y = placex;
1341
1342                             if (!(decaltexcoords[numdecals][0][0] < 0 && decaltexcoords[numdecals][1][0] < 0 && decaltexcoords[numdecals][2][0] < 0))
1343                                 if (!(decaltexcoords[numdecals][0][1] < 0 && decaltexcoords[numdecals][1][1] < 0 && decaltexcoords[numdecals][2][1] < 0))
1344                                     if (!(decaltexcoords[numdecals][0][0] > 1 && decaltexcoords[numdecals][1][0] > 1 && decaltexcoords[numdecals][2][0] > 1))
1345                                         if (!(decaltexcoords[numdecals][0][1] > 1 && decaltexcoords[numdecals][1][1] > 1 && decaltexcoords[numdecals][2][1] > 1)) {
1346                                             if (decalrotation[numdecals]) {
1347                                                 for (j = 0; j < 3; j++) {
1348                                                     rot.y = 0;
1349                                                     rot.x = decaltexcoords[numdecals][j][0] - .5;
1350                                                     rot.z = decaltexcoords[numdecals][j][1] - .5;
1351                                                     rot = DoRotation(rot, 0, -decalrotation[numdecals], 0);
1352                                                     decaltexcoords[numdecals][j][0] = rot.x + .5;
1353                                                     decaltexcoords[numdecals][j][1] = rot.z + .5;
1354                                                 }
1355                                             }
1356                                             if (numdecals < max_model_decals - 1)
1357                                                 numdecals++;
1358                                         }
1359                         }
1360                     } else if (distance < .02 && abs(facenormals[i].z) > abs(facenormals[i].y) && abs(facenormals[i].z) > abs(facenormals[i].x)) {
1361                         decalposition[numdecals] = where;
1362                         decaltype[numdecals] = atype;
1363                         decalrotation[numdecals] = rotation;
1364                         decalalivetime[numdecals] = 0;
1365                         decalopacity[numdecals] = opacity - distance / 10;
1366
1367                         if (decalopacity[numdecals > 0]) {
1368                             placex = vertex[Triangles[i].vertex[0]].x;
1369                             placez = vertex[Triangles[i].vertex[0]].y;
1370
1371                             decaltexcoords[numdecals][0][0] = (placex - where.x) / (size) / 2 + .5;
1372                             decaltexcoords[numdecals][0][1] = (placez - where.y) / (size) / 2 + .5;
1373
1374                             decalvertex[numdecals][0].x = placex;
1375                             decalvertex[numdecals][0].z = vertex[Triangles[i].vertex[0]].z;
1376                             decalvertex[numdecals][0].y = placez;
1377
1378
1379                             placex = vertex[Triangles[i].vertex[1]].x;
1380                             placez = vertex[Triangles[i].vertex[1]].y;
1381
1382                             decaltexcoords[numdecals][1][0] = (placex - where.x) / (size) / 2 + .5;
1383                             decaltexcoords[numdecals][1][1] = (placez - where.y) / (size) / 2 + .5;
1384
1385                             decalvertex[numdecals][1].x = placex;
1386                             decalvertex[numdecals][1].z = vertex[Triangles[i].vertex[1]].z;
1387                             decalvertex[numdecals][1].y = placez;
1388
1389
1390                             placex = vertex[Triangles[i].vertex[2]].x;
1391                             placez = vertex[Triangles[i].vertex[2]].y;
1392
1393                             decaltexcoords[numdecals][2][0] = (placex - where.x) / (size) / 2 + .5;
1394                             decaltexcoords[numdecals][2][1] = (placez - where.y) / (size) / 2 + .5;
1395
1396                             decalvertex[numdecals][2].x = placex;
1397                             decalvertex[numdecals][2].z = vertex[Triangles[i].vertex[2]].z;
1398                             decalvertex[numdecals][2].y = placez;
1399
1400                             if (!(decaltexcoords[numdecals][0][0] < 0 && decaltexcoords[numdecals][1][0] < 0 && decaltexcoords[numdecals][2][0] < 0))
1401                                 if (!(decaltexcoords[numdecals][0][1] < 0 && decaltexcoords[numdecals][1][1] < 0 && decaltexcoords[numdecals][2][1] < 0))
1402                                     if (!(decaltexcoords[numdecals][0][0] > 1 && decaltexcoords[numdecals][1][0] > 1 && decaltexcoords[numdecals][2][0] > 1))
1403                                         if (!(decaltexcoords[numdecals][0][1] > 1 && decaltexcoords[numdecals][1][1] > 1 && decaltexcoords[numdecals][2][1] > 1)) {
1404                                             if (decalrotation[numdecals]) {
1405                                                 for (j = 0; j < 3; j++) {
1406                                                     rot.y = 0;
1407                                                     rot.x = decaltexcoords[numdecals][j][0] - .5;
1408                                                     rot.z = decaltexcoords[numdecals][j][1] - .5;
1409                                                     rot = DoRotation(rot, 0, -decalrotation[numdecals], 0);
1410                                                     decaltexcoords[numdecals][j][0] = rot.x + .5;
1411                                                     decaltexcoords[numdecals][j][1] = rot.z + .5;
1412                                                 }
1413                                             }
1414                                             if (numdecals < max_model_decals - 1)
1415                                                 numdecals++;
1416                                         }
1417                         }
1418                     }
1419                 }
1420     }
1421 }
1422
1423 Model::~Model()
1424 {
1425     deallocate();
1426     textureptr.destroy();
1427 }
1428
1429 void Model::deallocate()
1430 {
1431     int i = 0, j = 0;
1432
1433     if (owner)
1434         free(owner);
1435     owner = 0;
1436
1437     if (possible)
1438         free(possible);
1439     possible = 0;
1440
1441     if (vertex)
1442         free(vertex);
1443     vertex = 0;
1444
1445     if (normals)
1446         free(normals);
1447     normals = 0;
1448
1449     if (facenormals)
1450         free(facenormals);
1451     facenormals = 0;
1452
1453     if (Triangles)
1454         free(Triangles);
1455     Triangles = 0;
1456
1457     if (vArray)
1458         free(vArray);
1459     vArray = 0;
1460
1461
1462     //allow decals
1463     if (decaltexcoords) {
1464         for (i = 0; i < max_model_decals; i++) {
1465             for (j = 0; j < 3; j++) {
1466                 free(decaltexcoords[i][j]);
1467             }
1468             free(decaltexcoords[i]);
1469         }
1470         free(decaltexcoords);
1471     }
1472     decaltexcoords = 0;
1473
1474
1475     if (decalvertex) {
1476         for (i = 0; i < max_model_decals; i++) {
1477             free(decalvertex[i]);
1478         }
1479         free(decalvertex);
1480     }
1481     decalvertex = 0;
1482
1483
1484     free(decaltype);
1485     decaltype = 0;
1486
1487     free(decalopacity);
1488     decalopacity = 0;
1489
1490     free(decalrotation);
1491     decalrotation = 0;
1492
1493     free(decalalivetime);
1494     decalalivetime = 0;
1495
1496     free(decalposition);
1497     decalposition = 0;
1498
1499 };
1500
1501 Model::Model()
1502 {
1503     vertexNum = 0, TriangleNum = 0;
1504     hastexture = 0;
1505
1506     type = 0, oldtype = 0;
1507
1508     possible = 0;
1509     owner = 0;
1510     vertex = 0;
1511     normals = 0;
1512     facenormals = 0;
1513     Triangles = 0;
1514     vArray = 0;
1515
1516     memset(&modelTexture, 0, sizeof(modelTexture));
1517     numpossible = 0;
1518     color = 0;
1519
1520     boundingspherecenter = 0;
1521     boundingsphereradius = 0;
1522
1523     decaltexcoords = 0;
1524     decalvertex = 0;
1525     decaltype = 0;
1526     decalopacity = 0;
1527     decalrotation = 0;
1528     decalalivetime = 0;
1529     decalposition = 0;
1530
1531     numdecals = 0;
1532
1533     flat = 0;
1534
1535     type = nothing;
1536 }
1537