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