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