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