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