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