]> git.jsancho.org Git - lugaru.git/blob - Source/Models.cpp
ee55d9fbf3ef5894f269e109872d01ec43c7a3ab
[lugaru.git] / Source / Models.cpp
1 #include "Models.h"
2 //#include "altivec.h"
3 #include "Game.h"
4
5 extern float multiplier;
6 extern float viewdistance;
7 extern XYZ viewer;
8 extern float fadestart;
9 extern float texdetail;
10 extern bool decals;
11 extern int loadscreencolor;
12
13 #include "Game.h"
14 extern Game * pgame;
15 extern bool visibleloading;
16 //Functions
17 void *allocate_aligned(size_t pointer_size, size_t byte_alignment)
18 {
19         uintptr_t pointer = (uintptr_t)malloc(pointer_size + byte_alignment + 1);
20         uintptr_t aligned_pointer = (pointer + byte_alignment + 1);
21         aligned_pointer -= (aligned_pointer % byte_alignment);
22         *(uint8_t *)(aligned_pointer - 1) = (aligned_pointer - pointer);
23         return (void *)aligned_pointer;
24 }
25
26 void free_aligned(void *aligned_pointer)
27 {
28         free((uint8_t *)(aligned_pointer) - *((uint8_t *)(aligned_pointer) - 1));
29 }
30
31 void dealloc(void* param){
32         free(param);
33         param=0;
34 }
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(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( 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         /*if(owner)dealloc(owner);
427         if(possible)dealloc(possible);
428         if(vertex)dealloc(vertex);
429         if(normals)dealloc(normals);
430         if(facenormals)dealloc(facenormals);
431         if(Triangles)dealloc(Triangles);
432         if(vArray)dealloc(vArray);*/
433         deallocate();
434
435         numpossible=0;
436
437         owner = (int*)malloc(sizeof(int)*vertexNum);
438         possible = (int*)malloc(sizeof(int)*TriangleNum);
439         vertex = (XYZ*)malloc(sizeof(XYZ)*vertexNum);
440         Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle)*TriangleNum);
441         vArray = (GLfloat*)malloc(sizeof(GLfloat)*TriangleNum*24);
442
443         for(i=0;i<vertexNum;i++){
444                 funpackf(tfile, "Bf Bf Bf", &vertex[i].x,&vertex[i].y,&vertex[i].z);
445         }
446
447         for(i=0;i<TriangleNum;i++){
448                 //              funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
449                 short vertex[ 6];
450                 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
451                 Triangles[i].vertex[ 0] = vertex[ 0];
452                 Triangles[i].vertex[ 1] = vertex[ 2];
453                 Triangles[i].vertex[ 2] = vertex[ 4];
454                 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
455                 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
456         }
457
458         fclose(tfile);
459
460         UpdateVertexArray();
461
462         for(i=0;i<vertexNum;i++){
463                 owner[i]=-1;
464         }
465
466         static int j;
467         boundingsphereradius=0;
468         for(i=0;i<vertexNum;i++){
469                 for(j=0;j<vertexNum;j++){
470                         if(j!=i&&findDistancefast(&vertex[j],&vertex[i])/2>boundingsphereradius){
471                                 boundingsphereradius=findDistancefast(&vertex[j],&vertex[i])/2;
472                                 boundingspherecenter=(vertex[i]+vertex[j])/2;
473                         }
474                 }
475         }       
476         boundingsphereradius=fast_sqrt(boundingsphereradius);
477
478         return 1;
479 }
480
481
482 bool Model::load(char *filename,bool texture )
483 {
484         FILE                    *tfile;
485         long                            i;
486
487         LOGFUNC;
488
489         LOG(std::string("Loading model...") + filename);
490
491         if(visibleloading){
492                 loadscreencolor=2;
493                 pgame->LoadingScreen();
494         }
495
496         int oldvertexNum,oldTriangleNum;
497         oldvertexNum=vertexNum;
498         oldTriangleNum=TriangleNum;
499
500         type = normaltype;
501         color=0;
502
503         tfile=fopen( ConvertFileName(filename), "rb" );
504         // read model settings
505
506
507         fseek(tfile, 0, SEEK_SET);
508         funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
509
510         // read the model data
511         /*if(owner)dealloc(owner);
512         if(possible)dealloc(possible);
513         if(vertex)dealloc(vertex);
514         if(normals)dealloc(normals);
515         if(facenormals)dealloc(facenormals);
516         if(Triangles)dealloc(Triangles);
517         if(vArray)dealloc(vArray);*/
518         deallocate();
519
520         numpossible=0;
521
522         owner = (int*)malloc(sizeof(int)*vertexNum);
523         possible = (int*)malloc(sizeof(int)*TriangleNum);
524         vertex = (XYZ*)malloc(sizeof(XYZ)*vertexNum);
525         normals = (XYZ*)malloc(sizeof(XYZ)*vertexNum);
526         facenormals = (XYZ*)malloc(sizeof(XYZ)*TriangleNum);
527         Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle)*TriangleNum);
528         vArray = (GLfloat*)malloc(sizeof(GLfloat)*TriangleNum*24);
529
530         for(i=0;i<vertexNum;i++){
531                 funpackf(tfile, "Bf Bf Bf", &vertex[i].x,&vertex[i].y,&vertex[i].z);
532         }
533
534         for(i=0;i<TriangleNum;i++){
535                 //              funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
536                 short vertex[ 6];
537                 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
538                 Triangles[i].vertex[ 0] = vertex[ 0];
539                 Triangles[i].vertex[ 1] = vertex[ 2];
540                 Triangles[i].vertex[ 2] = vertex[ 4];
541                 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
542                 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
543         }
544
545         Texture.xsz=0;
546
547         fclose(tfile);
548
549         UpdateVertexArray();
550
551         for(i=0;i<vertexNum;i++){
552                 owner[i]=-1;
553         }
554
555         static int j;
556         boundingsphereradius=0;
557         for(i=0;i<vertexNum;i++){
558                 for(j=0;j<vertexNum;j++){
559                         if(j!=i&&findDistancefast(&vertex[j],&vertex[i])/2>boundingsphereradius){
560                                 boundingsphereradius=findDistancefast(&vertex[j],&vertex[i])/2;
561                                 boundingspherecenter=(vertex[i]+vertex[j])/2;
562                         }
563                 }
564         }       
565         boundingsphereradius=fast_sqrt(boundingsphereradius);
566
567         return 1;
568 }
569
570 bool Model::loaddecal(char *filename,bool texture )
571 {
572         FILE                    *tfile;
573         long                            i,j;
574
575         LOGFUNC;
576
577         LOG(std::string("Loading decal...") + filename);
578
579         int oldvertexNum,oldTriangleNum;
580         oldvertexNum=vertexNum;
581         oldTriangleNum=TriangleNum;
582
583         type = decalstype;
584         numdecals=0;
585         color=0;
586
587         tfile=fopen( filename, "rb" );
588         // read model settings
589
590
591         fseek(tfile, 0, SEEK_SET);
592         funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
593
594         // read the model data
595
596         /*if(owner)dealloc(owner);
597         if(possible)dealloc(possible);
598         if(vertex)dealloc(vertex);
599         if(normals)dealloc(normals);
600         if(facenormals)dealloc(facenormals);
601         if(Triangles)dealloc(Triangles);
602         if(vArray)dealloc(vArray);*/
603         deallocate();
604
605         numpossible=0;
606
607         owner = (int*)malloc(sizeof(int)*vertexNum);
608         possible = (int*)malloc(sizeof(int)*TriangleNum);
609         vertex = (XYZ*)malloc(sizeof(XYZ)*vertexNum);
610         normals = (XYZ*)malloc(sizeof(XYZ)*vertexNum);
611         facenormals = (XYZ*)malloc(sizeof(XYZ)*TriangleNum);
612         Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle)*TriangleNum);
613         vArray = (GLfloat*)malloc(sizeof(GLfloat)*TriangleNum*24);
614
615
616         for(i=0;i<vertexNum;i++){
617                 funpackf(tfile, "Bf Bf Bf", &vertex[i].x,&vertex[i].y,&vertex[i].z);
618         }
619
620         for(i=0;i<TriangleNum;i++){
621                 //              funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
622                 short vertex[ 6];
623                 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
624                 Triangles[i].vertex[ 0] = vertex[ 0];
625                 Triangles[i].vertex[ 1] = vertex[ 2];
626                 Triangles[i].vertex[ 2] = vertex[ 4];
627                 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
628                 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
629         }
630
631
632         Texture.xsz=0;
633
634         fclose(tfile);
635
636         UpdateVertexArray();
637
638         for(i=0;i<vertexNum;i++){
639                 owner[i]=-1;
640         }
641
642         boundingsphereradius=0;
643         for(i=0;i<vertexNum;i++){
644                 for(j=0;j<vertexNum;j++){
645                         if(j!=i&&findDistancefast(&vertex[j],&vertex[i])/2>boundingsphereradius){
646                                 boundingsphereradius=findDistancefast(&vertex[j],&vertex[i])/2;
647                                 boundingspherecenter=(vertex[i]+vertex[j])/2;
648                         }
649                 }
650         }       
651         boundingsphereradius=fast_sqrt(boundingsphereradius);
652
653         //allow decals
654         if(!decaltexcoords){
655                 decaltexcoords = (float***)malloc(sizeof(float**)*max_model_decals);
656                 for(i=0;i<max_model_decals;i++){
657                         decaltexcoords[i] = (float**)malloc(sizeof(float*)*3);
658                         for(j=0;j<3;j++){
659                                 decaltexcoords[i][j] = (float*)malloc(sizeof(float)*2);
660                         }
661                 }
662                 //if(decalvertex)free(decalvertex);
663                 decalvertex = (XYZ**)malloc(sizeof(XYZ*)*max_model_decals);
664                 for(i=0;i<max_model_decals;i++){
665                         decalvertex[i] = (XYZ*)malloc(sizeof(XYZ)*3);
666                 }
667
668                 decaltype = (int*)malloc(sizeof(int)*max_model_decals);
669                 decalopacity = (float*)malloc(sizeof(float)*max_model_decals);
670                 decalrotation = (float*)malloc(sizeof(float)*max_model_decals);
671                 decalalivetime = (float*)malloc(sizeof(float)*max_model_decals);
672                 decalposition = (XYZ*)malloc(sizeof(XYZ)*max_model_decals);
673         }
674
675         return 1;
676 }
677
678 bool Model::loadraw(char *filename )
679 {
680         FILE                    *tfile;
681         long                            i;
682
683         LOGFUNC;
684
685         LOG(std::string("Loading raw...") + filename);
686
687         int oldvertexNum,oldTriangleNum;
688         oldvertexNum=vertexNum;
689         oldTriangleNum=TriangleNum;
690
691         type = rawtype;
692         color=0;
693
694         tfile=fopen( filename, "rb" );
695         // read model settings
696
697
698         fseek(tfile, 0, SEEK_SET);
699         funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
700
701         // read the model data
702         /*if(owner)dealloc(owner);
703         if(possible)dealloc(possible);
704         if(vertex)dealloc(vertex);
705         if(normals)dealloc(normals);
706         if(facenormals)dealloc(facenormals);
707         if(Triangles)dealloc(Triangles);
708         if(vArray)dealloc(vArray);*/
709         deallocate();
710
711         numpossible=0;
712
713         owner = (int*)malloc(sizeof(int)*vertexNum);
714         possible = (int*)malloc(sizeof(int)*TriangleNum);
715         vertex = (XYZ*)malloc(sizeof(XYZ)*vertexNum);
716         Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle)*TriangleNum);
717         vArray = (GLfloat*)malloc(sizeof(GLfloat)*TriangleNum*24);
718
719
720         for(i=0;i<vertexNum;i++){
721                 funpackf(tfile, "Bf Bf Bf", &vertex[i].x,&vertex[i].y,&vertex[i].z);
722         }
723
724         for(i=0;i<TriangleNum;i++){
725                 //              funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
726                 short vertex[ 6];
727                 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
728                 Triangles[i].vertex[ 0] = vertex[ 0];
729                 Triangles[i].vertex[ 1] = vertex[ 2];
730                 Triangles[i].vertex[ 2] = vertex[ 4];
731                 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
732                 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
733         }
734
735
736         fclose(tfile);
737
738         for(i=0;i<vertexNum;i++){
739                 owner[i]=-1;
740         }
741
742         return 1;
743 }
744
745
746 void Model::UniformTexCoords()
747 {
748         static int i;
749         for(i=0; i<TriangleNum; i++){
750                 Triangles[i].gy[0]=vertex[Triangles[i].vertex[0]].y;
751                 Triangles[i].gy[1]=vertex[Triangles[i].vertex[1]].y;
752                 Triangles[i].gy[2]=vertex[Triangles[i].vertex[2]].y;            
753                 Triangles[i].gx[0]=vertex[Triangles[i].vertex[0]].x;
754                 Triangles[i].gx[1]=vertex[Triangles[i].vertex[1]].x;
755                 Triangles[i].gx[2]=vertex[Triangles[i].vertex[2]].x;            
756         }
757         UpdateVertexArray();
758 }
759
760
761 void Model::FlipTexCoords()
762 {
763         static int i;
764         for(i=0; i<TriangleNum; i++){
765                 Triangles[i].gy[0]=-Triangles[i].gy[0];
766                 Triangles[i].gy[1]=-Triangles[i].gy[1];
767                 Triangles[i].gy[2]=-Triangles[i].gy[2];         
768         }
769         UpdateVertexArray();
770 }
771
772 void Model::ScaleTexCoords(float howmuch)
773 {
774         static int i;
775         for(i=0; i<TriangleNum; i++){
776                 Triangles[i].gx[0]*=howmuch;
777                 Triangles[i].gx[1]*=howmuch;
778                 Triangles[i].gx[2]*=howmuch;    
779                 Triangles[i].gy[0]*=howmuch;
780                 Triangles[i].gy[1]*=howmuch;
781                 Triangles[i].gy[2]*=howmuch;            
782         }
783         UpdateVertexArray();
784 }
785
786 void Model::Scale(float xscale,float yscale,float zscale)
787 {
788         static int i;
789         for(i=0; i<vertexNum; i++){
790                 vertex[i].x*=xscale;
791                 vertex[i].y*=yscale;
792                 vertex[i].z*=zscale;
793         }
794         UpdateVertexArray();
795
796         static int j;
797
798         boundingsphereradius=0;
799         for(i=0;i<vertexNum;i++){
800                 for(j=0;j<vertexNum;j++){
801                         if(j!=i&&findDistancefast(&vertex[j],&vertex[i])/2>boundingsphereradius){
802                                 boundingsphereradius=findDistancefast(&vertex[j],&vertex[i])/2;
803                                 boundingspherecenter=(vertex[i]+vertex[j])/2;
804                         }
805                 }
806         }       
807         boundingsphereradius=fast_sqrt(boundingsphereradius);
808 }
809
810 void Model::ScaleNormals(float xscale,float yscale,float zscale)
811 {
812         if(type!=normaltype&&type!=decalstype)return;
813         static int i;
814         for(i=0; i<vertexNum; i++){
815                 normals[i].x*=xscale;
816                 normals[i].y*=yscale;
817                 normals[i].z*=zscale;
818         }
819         for(i=0; i<TriangleNum; i++){
820                 facenormals[i].x*=xscale;
821                 facenormals[i].y*=yscale;
822                 facenormals[i].z*=zscale;
823         }
824         UpdateVertexArray();
825 }
826
827 void Model::Translate(float xtrans,float ytrans,float ztrans)
828 {
829         static int i;
830         for(i=0; i<vertexNum; i++){
831                 vertex[i].x+=xtrans;
832                 vertex[i].y+=ytrans;
833                 vertex[i].z+=ztrans;
834         }
835         UpdateVertexArray();
836
837         static int j;
838         boundingsphereradius=0;
839         for(i=0;i<vertexNum;i++){
840                 for(j=0;j<vertexNum;j++){
841                         if(j!=i&&findDistancefast(&vertex[j],&vertex[i])/2>boundingsphereradius){
842                                 boundingsphereradius=findDistancefast(&vertex[j],&vertex[i])/2;
843                                 boundingspherecenter=(vertex[i]+vertex[j])/2;
844                         }
845                 }
846         }       
847         boundingsphereradius=fast_sqrt(boundingsphereradius);
848 }
849
850 void Model::Rotate(float xang,float yang,float zang)
851 {
852         static int i;
853         for(i=0; i<vertexNum; i++){
854                 vertex[i]=DoRotation(vertex[i],xang,yang,zang);
855         }
856         UpdateVertexArray();
857
858         static int j;
859         boundingsphereradius=0;
860         for(i=0;i<vertexNum;i++){
861                 for(j=0;j<vertexNum;j++){
862                         if(j!=i&&findDistancefast(&vertex[j],&vertex[i])/2>boundingsphereradius){
863                                 boundingsphereradius=findDistancefast(&vertex[j],&vertex[i])/2;
864                                 boundingspherecenter=(vertex[i]+vertex[j])/2;
865                         }
866                 }
867         }
868         boundingsphereradius=fast_sqrt(boundingsphereradius);   
869 }
870
871
872 void Model::CalculateNormals(bool facenormalise)
873 {
874         if(visibleloading){
875                 loadscreencolor=3;
876                 pgame->LoadingScreen();
877         }
878         static int i;
879         if(type!=normaltype&&type!=decalstype)return;
880
881         for(i=0; i<vertexNum; i++){
882                 normals[i].x=0;
883                 normals[i].y=0;
884                 normals[i].z=0;
885         }
886
887         for(i=0;i<TriangleNum;i++){
888                 CrossProduct(vertex[Triangles[i].vertex[1]]-vertex[Triangles[i].vertex[0]],vertex[Triangles[i].vertex[2]]-vertex[Triangles[i].vertex[0]],&facenormals[i]);
889
890                 normals[Triangles[i].vertex[0]].x+=facenormals[i].x;
891                 normals[Triangles[i].vertex[0]].y+=facenormals[i].y;
892                 normals[Triangles[i].vertex[0]].z+=facenormals[i].z;
893
894                 normals[Triangles[i].vertex[1]].x+=facenormals[i].x;
895                 normals[Triangles[i].vertex[1]].y+=facenormals[i].y;
896                 normals[Triangles[i].vertex[1]].z+=facenormals[i].z;
897
898                 normals[Triangles[i].vertex[2]].x+=facenormals[i].x;
899                 normals[Triangles[i].vertex[2]].y+=facenormals[i].y;
900                 normals[Triangles[i].vertex[2]].z+=facenormals[i].z;
901                 if(facenormalise)Normalise(&facenormals[i]);
902         }
903         for(i=0; i<vertexNum; i++){
904                 Normalise(&normals[i]);
905                 normals[i]*=-1;
906         }
907         UpdateVertexArrayNoTex();
908 }
909
910 void Model::drawimmediate()
911 {
912         glBindTexture(GL_TEXTURE_2D,(unsigned long)textureptr);
913         glBegin(GL_TRIANGLES);
914         for(int i=0;i<TriangleNum;i++){
915                 /*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){
916                 if(isnormal(vertex[Triangles[i].vertex[0]].x)&&isnormal(vertex[Triangles[i].vertex[0]].y)&&isnormal(vertex[Triangles[i].vertex[0]].z)
917                 &&isnormal(vertex[Triangles[i].vertex[1]].x)&&isnormal(vertex[Triangles[i].vertex[1]].y)&&isnormal(vertex[Triangles[i].vertex[1]].z)
918                 &&isnormal(vertex[Triangles[i].vertex[2]].x)&&isnormal(vertex[Triangles[i].vertex[2]].y)&&isnormal(vertex[Triangles[i].vertex[2]].z)){
919                 */
920                 glTexCoord2f(Triangles[i].gx[0],Triangles[i].gy[0]);
921                 if(color)glColor3f(normals[Triangles[i].vertex[0]].x,normals[Triangles[i].vertex[0]].y,normals[Triangles[i].vertex[0]].z);
922                 if(!color&&!flat)glNormal3f(normals[Triangles[i].vertex[0]].x,normals[Triangles[i].vertex[0]].y,normals[Triangles[i].vertex[0]].z);
923                 if(!color&&flat)glNormal3f(facenormals[i].x,facenormals[i].y,facenormals[i].y);
924                 glVertex3f(vertex[Triangles[i].vertex[0]].x,vertex[Triangles[i].vertex[0]].y,vertex[Triangles[i].vertex[0]].z);
925
926                 glTexCoord2f(Triangles[i].gx[1],Triangles[i].gy[1]);
927                 if(color)glColor3f(normals[Triangles[i].vertex[1]].x,normals[Triangles[i].vertex[1]].y,normals[Triangles[i].vertex[1]].z);
928                 if(!color&&!flat)glNormal3f(normals[Triangles[i].vertex[1]].x,normals[Triangles[i].vertex[1]].y,normals[Triangles[i].vertex[1]].z);
929                 if(!color&&flat)glNormal3f(facenormals[i].x,facenormals[i].y,facenormals[i].y);
930                 glVertex3f(vertex[Triangles[i].vertex[1]].x,vertex[Triangles[i].vertex[1]].y,vertex[Triangles[i].vertex[1]].z);
931
932                 glTexCoord2f(Triangles[i].gx[2],Triangles[i].gy[2]);
933                 if(color)glColor3f(normals[Triangles[i].vertex[2]].x,normals[Triangles[i].vertex[2]].y,normals[Triangles[i].vertex[2]].z);
934                 if(!color&&!flat)glNormal3f(normals[Triangles[i].vertex[2]].x,normals[Triangles[i].vertex[2]].y,normals[Triangles[i].vertex[2]].z);
935                 if(!color&&flat)glNormal3f(facenormals[i].x,facenormals[i].y,facenormals[i].y);
936                 glVertex3f(vertex[Triangles[i].vertex[2]].x,vertex[Triangles[i].vertex[2]].y,vertex[Triangles[i].vertex[2]].z);
937                 //}
938                 //}
939         }
940         glEnd();
941 }
942
943 void Model::draw()
944 {
945         if(type!=normaltype&&type!=decalstype)return;
946
947         glEnableClientState(GL_NORMAL_ARRAY);
948         glEnableClientState(GL_VERTEX_ARRAY);
949         glEnableClientState(GL_TEXTURE_COORD_ARRAY);
950
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         glBindTexture(GL_TEXTURE_2D,(unsigned long)textureptr);
954
955 #if PLATFORM_MACOSX
956         glLockArraysEXT( 0, TriangleNum*3);
957 #endif
958         glDrawArrays(GL_TRIANGLES, 0, TriangleNum*3);
959 #if PLATFORM_MACOSX
960         glUnlockArraysEXT();
961 #endif
962
963
964         if(!color)glDisableClientState(GL_NORMAL_ARRAY);
965         if(color)glDisableClientState(GL_COLOR_ARRAY);
966         glDisableClientState(GL_VERTEX_ARRAY);
967         glDisableClientState(GL_TEXTURE_COORD_ARRAY);
968         //drawimmediate();
969 }
970
971 void Model::drawdifftex(GLuint texture)
972 {
973         glEnableClientState(GL_NORMAL_ARRAY);
974         glEnableClientState(GL_VERTEX_ARRAY);
975         glEnableClientState(GL_TEXTURE_COORD_ARRAY);
976         if(!color)glInterleavedArrays( GL_T2F_N3F_V3F,8*sizeof(GLfloat),&vArray[0]);
977         if(color)glInterleavedArrays( GL_T2F_C3F_V3F,8*sizeof(GLfloat),&vArray[0]);
978
979         glBindTexture(GL_TEXTURE_2D,(unsigned long)texture);
980         glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
981         glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
982
983
984 #ifndef WIN32
985         glLockArraysEXT( 0, TriangleNum*3);
986 #endif
987         glDrawArrays(GL_TRIANGLES, 0, TriangleNum*3);
988 #ifndef WIN32
989         glUnlockArraysEXT();
990 #endif
991
992
993         if(!color)glDisableClientState(GL_NORMAL_ARRAY);
994         if(color)glDisableClientState(GL_COLOR_ARRAY);
995         glDisableClientState(GL_VERTEX_ARRAY);
996         glDisableClientState(GL_TEXTURE_COORD_ARRAY);
997         //drawdiffteximmediate(texture);
998 }
999
1000 void Model::drawdiffteximmediate(GLuint texture)
1001 {
1002         glBindTexture(GL_TEXTURE_2D,(unsigned long)texture);
1003
1004         glBegin(GL_TRIANGLES);
1005         for(int i=0;i<TriangleNum;i++){
1006                 /*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){
1007                 if(isnormal(vertex[Triangles[i].vertex[0]].x)&&isnormal(vertex[Triangles[i].vertex[0]].y)&&isnormal(vertex[Triangles[i].vertex[0]].z)
1008                 &&isnormal(vertex[Triangles[i].vertex[1]].x)&&isnormal(vertex[Triangles[i].vertex[1]].y)&&isnormal(vertex[Triangles[i].vertex[1]].z)
1009                 &&isnormal(vertex[Triangles[i].vertex[2]].x)&&isnormal(vertex[Triangles[i].vertex[2]].y)&&isnormal(vertex[Triangles[i].vertex[2]].z)){
1010                 */glTexCoord2f(Triangles[i].gx[0],Triangles[i].gy[0]);
1011                 if(color)glColor3f(normals[Triangles[i].vertex[0]].x,normals[Triangles[i].vertex[0]].y,normals[Triangles[i].vertex[0]].z);
1012                 if(!color&&!flat)glNormal3f(normals[Triangles[i].vertex[0]].x,normals[Triangles[i].vertex[0]].y,normals[Triangles[i].vertex[0]].z);
1013                 if(!color&&flat)glNormal3f(facenormals[i].x,facenormals[i].y,facenormals[i].y);
1014                 glVertex3f(vertex[Triangles[i].vertex[0]].x,vertex[Triangles[i].vertex[0]].y,vertex[Triangles[i].vertex[0]].z);
1015
1016                 glTexCoord2f(Triangles[i].gx[1],Triangles[i].gy[1]);
1017                 if(color)glColor3f(normals[Triangles[i].vertex[1]].x,normals[Triangles[i].vertex[1]].y,normals[Triangles[i].vertex[1]].z);
1018                 if(!color&&!flat)glNormal3f(normals[Triangles[i].vertex[1]].x,normals[Triangles[i].vertex[1]].y,normals[Triangles[i].vertex[1]].z);
1019                 if(!color&&flat)glNormal3f(facenormals[i].x,facenormals[i].y,facenormals[i].y);
1020                 glVertex3f(vertex[Triangles[i].vertex[1]].x,vertex[Triangles[i].vertex[1]].y,vertex[Triangles[i].vertex[1]].z);
1021
1022                 glTexCoord2f(Triangles[i].gx[2],Triangles[i].gy[2]);
1023                 if(color)glColor3f(normals[Triangles[i].vertex[2]].x,normals[Triangles[i].vertex[2]].y,normals[Triangles[i].vertex[2]].z);
1024                 if(!color&&!flat)glNormal3f(normals[Triangles[i].vertex[2]].x,normals[Triangles[i].vertex[2]].y,normals[Triangles[i].vertex[2]].z);
1025                 if(!color&&flat)glNormal3f(facenormals[i].x,facenormals[i].y,facenormals[i].y);
1026                 glVertex3f(vertex[Triangles[i].vertex[2]].x,vertex[Triangles[i].vertex[2]].y,vertex[Triangles[i].vertex[2]].z);
1027                 //}
1028                 //}
1029         }
1030         glEnd();
1031 }
1032
1033 void Model::drawdecals(GLuint shadowtexture,GLuint bloodtexture,GLuint bloodtexture2,GLuint breaktexture)
1034 {
1035         if(decals){
1036                 if(type!=decalstype)return;
1037                 static int i,j;
1038                 static float distancemult;
1039                 static int lasttype;
1040                 static float viewdistsquared;
1041                 static bool blend;
1042
1043                 viewdistsquared=viewdistance*viewdistance;
1044                 blend=1;
1045
1046                 lasttype=-1;
1047                 glEnable(GL_BLEND);
1048                 glDisable(GL_LIGHTING);
1049                 glDisable(GL_CULL_FACE);
1050                 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1051                 glDepthMask(0);
1052                 if(numdecals>max_model_decals)numdecals=max_model_decals;
1053                 for(i=0;i<numdecals;i++){
1054                         if(decaltype[i]==blooddecalfast&&decalalivetime[i]<2)decalalivetime[i]=2;
1055
1056                         if(decaltype[i]==shadowdecal&&decaltype[i]!=lasttype){
1057                                 glBindTexture( GL_TEXTURE_2D, shadowtexture);
1058                                 if(!blend){
1059                                         blend=1;
1060                                         glAlphaFunc(GL_GREATER, 0.0001);
1061                                         glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1062                                 }
1063                         }
1064                         if(decaltype[i]==breakdecal&&decaltype[i]!=lasttype){
1065                                 glBindTexture( GL_TEXTURE_2D, breaktexture);
1066                                 if(!blend){
1067                                         blend=1;
1068                                         glAlphaFunc(GL_GREATER, 0.0001);
1069                                         glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1070                                 }
1071                         }
1072                         if((decaltype[i]==blooddecal||decaltype[i]==blooddecalslow)&&decaltype[i]!=lasttype){
1073                                 glBindTexture( GL_TEXTURE_2D, bloodtexture);
1074                                 if(blend){
1075                                         blend=0;
1076                                         glAlphaFunc(GL_GREATER, 0.15);
1077                                         glBlendFunc(GL_ONE,GL_ZERO);
1078                                 }
1079                         }
1080                         if((decaltype[i]==blooddecalfast)&&decaltype[i]!=lasttype){
1081                                 glBindTexture( GL_TEXTURE_2D, bloodtexture2);
1082                                 if(blend){
1083                                         blend=0;
1084                                         glAlphaFunc(GL_GREATER, 0.15);
1085                                         glBlendFunc(GL_ONE,GL_ZERO);
1086                                 }
1087                         }
1088                         if(decaltype[i]==shadowdecal){
1089                                 glColor4f(1,1,1,decalopacity[i]);
1090                         }
1091                         if(decaltype[i]==breakdecal){
1092                                 glColor4f(1,1,1,decalopacity[i]);
1093                                 if(decalalivetime[i]>58)glColor4f(1,1,1,decalopacity[i]*(60-decalalivetime[i])/2);
1094                         }
1095                         if((decaltype[i]==blooddecal||decaltype[i]==blooddecalfast||decaltype[i]==blooddecalslow)){
1096                                 glColor4f(1,1,1,decalopacity[i]);
1097                                 if(decalalivetime[i]<4)glColor4f(1,1,1,decalopacity[i]*decalalivetime[i]*.25);
1098                                 if(decalalivetime[i]>58)glColor4f(1,1,1,decalopacity[i]*(60-decalalivetime[i])/2);
1099                         }
1100                         lasttype=decaltype[i];
1101                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1102                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); 
1103
1104                         glMatrixMode(GL_MODELVIEW);                                                     // Select The Modelview Matrix
1105                         glPushMatrix();
1106                                 glBegin(GL_TRIANGLES);
1107                                 for(int j=0;j<3;j++)
1108                                 {
1109                                         glTexCoord2f(decaltexcoords[i][j][0], decaltexcoords[i][j][1]); glVertex3f(decalvertex[i][j].x,decalvertex[i][j].y,decalvertex[i][j].z);
1110                                 }
1111                         glEnd();
1112                         glPopMatrix();
1113                 }
1114                 for(i=numdecals-1;i>=0;i--){
1115                         decalalivetime[i]+=multiplier;
1116                         if(decaltype[i]==blooddecalslow)decalalivetime[i]-=multiplier*2/3;
1117                         if(decaltype[i]==blooddecalfast)decalalivetime[i]+=multiplier*4;
1118                         if(decaltype[i]==shadowdecal)DeleteDecal(i);
1119                         if((decaltype[i]==blooddecal||decaltype[i]==blooddecalfast||decaltype[i]==blooddecalslow)&&decalalivetime[i]>=60)DeleteDecal(i);
1120                 }
1121                 glAlphaFunc(GL_GREATER, 0.0001);
1122                 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1123         }
1124 }
1125
1126 void Model::DeleteDecal(int which)
1127 {
1128         if(decals){
1129                 if(type!=decalstype)return;
1130                 decaltype[which]=decaltype[numdecals-1];
1131                 decalposition[which]=decalposition[numdecals-1];
1132                 for(int i=0;i<3;i++){
1133                         decalvertex[which][i]=decalvertex[numdecals-1][i];
1134                         decaltexcoords[which][i][0]=decaltexcoords[numdecals-1][i][0];
1135                         decaltexcoords[which][i][1]=decaltexcoords[numdecals-1][i][1];
1136                 }
1137                 decalrotation[which]=decalrotation[numdecals-1];
1138                 decalalivetime[which]=decalalivetime[numdecals-1];
1139                 decalopacity[which]=decalopacity[numdecals-1];
1140                 numdecals--;
1141         }
1142 }
1143
1144 void Model::MakeDecal(int atype, XYZ *where,float *size, float *opacity, float *rotation){
1145         if(decals){
1146                 if(type!=decalstype)return;
1147
1148                 static float placex,placez;
1149                 static XYZ rot;
1150                 //static XYZ point,point1,point2;
1151                 static float distance;
1152                 static int i,j;
1153
1154                 if(*opacity>0)
1155                         if(findDistancefast(where,&boundingspherecenter)<(boundingsphereradius+*size)*(boundingsphereradius+*size))
1156                                 for(i=0;i<TriangleNum;i++){
1157                                         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)){
1158                                                 decalposition[numdecals]=*where;
1159                                                 decaltype[numdecals]=atype;
1160                                                 decalrotation[numdecals]=*rotation;
1161                                                 decalalivetime[numdecals]=0;
1162                                                 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);
1163                                                 decalopacity[numdecals]=*opacity-distance/10;
1164
1165                                                 if(decalopacity[numdecals>0]){
1166                                                         placex=vertex[Triangles[i].vertex[0]].x;
1167                                                         placez=vertex[Triangles[i].vertex[0]].z;
1168
1169                                                         decaltexcoords[numdecals][0][0]=(placex-where->x)/(*size)/2+.5;
1170                                                         decaltexcoords[numdecals][0][1]=(placez-where->z)/(*size)/2+.5;
1171
1172                                                         decalvertex[numdecals][0].x=placex;
1173                                                         decalvertex[numdecals][0].z=placez;
1174                                                         decalvertex[numdecals][0].y=vertex[Triangles[i].vertex[0]].y;
1175
1176
1177                                                         placex=vertex[Triangles[i].vertex[1]].x;
1178                                                         placez=vertex[Triangles[i].vertex[1]].z;
1179
1180                                                         decaltexcoords[numdecals][1][0]=(placex-where->x)/(*size)/2+.5;
1181                                                         decaltexcoords[numdecals][1][1]=(placez-where->z)/(*size)/2+.5;
1182
1183                                                         decalvertex[numdecals][1].x=placex;
1184                                                         decalvertex[numdecals][1].z=placez;
1185                                                         decalvertex[numdecals][1].y=vertex[Triangles[i].vertex[1]].y;
1186
1187
1188                                                         placex=vertex[Triangles[i].vertex[2]].x;
1189                                                         placez=vertex[Triangles[i].vertex[2]].z;
1190
1191                                                         decaltexcoords[numdecals][2][0]=(placex-where->x)/(*size)/2+.5;
1192                                                         decaltexcoords[numdecals][2][1]=(placez-where->z)/(*size)/2+.5;
1193
1194                                                         decalvertex[numdecals][2].x=placex;
1195                                                         decalvertex[numdecals][2].z=placez;
1196                                                         decalvertex[numdecals][2].y=vertex[Triangles[i].vertex[2]].y;
1197
1198                                                         if(!(decaltexcoords[numdecals][0][0]<0&&decaltexcoords[numdecals][1][0]<0&&decaltexcoords[numdecals][2][0]<0))
1199                                                                 if(!(decaltexcoords[numdecals][0][1]<0&&decaltexcoords[numdecals][1][1]<0&&decaltexcoords[numdecals][2][1]<0))
1200                                                                         if(!(decaltexcoords[numdecals][0][0]>1&&decaltexcoords[numdecals][1][0]>1&&decaltexcoords[numdecals][2][0]>1))
1201                                                                                 if(!(decaltexcoords[numdecals][0][1]>1&&decaltexcoords[numdecals][1][1]>1&&decaltexcoords[numdecals][2][1]>1))
1202                                                                                 {
1203                                                                                         if(decalrotation[numdecals]){
1204                                                                                                 for(j=0;j<3;j++){                       
1205                                                                                                         rot.y=0;
1206                                                                                                         rot.x=decaltexcoords[numdecals][j][0]-.5;
1207                                                                                                         rot.z=decaltexcoords[numdecals][j][1]-.5;
1208                                                                                                         rot=DoRotation(rot,0,-decalrotation[numdecals],0);
1209                                                                                                         decaltexcoords[numdecals][j][0]=rot.x+.5;
1210                                                                                                         decaltexcoords[numdecals][j][1]=rot.z+.5;
1211                                                                                                 }
1212                                                                                         }
1213                                                                                         if(numdecals<max_model_decals-1)numdecals++;
1214                                                                                 }
1215                                                 }
1216                                         }
1217                                 }
1218         }
1219 }
1220
1221 void Model::MakeDecal(int atype, XYZ where,float size, float opacity, float rotation){
1222         if(decals){
1223                 if(type!=decalstype)return;
1224
1225                 static float placex,placez;
1226                 static XYZ rot;
1227                 //static XYZ point,point1,point2;
1228                 static float distance;
1229                 static int i,j;
1230
1231                 if(opacity>0)
1232                         if(findDistancefast(&where,&boundingspherecenter)<(boundingsphereradius+size)*(boundingsphereradius+size))
1233                                 for(i=0;i<TriangleNum;i++){
1234                                         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))));
1235                                         if(distance<.02&&abs(facenormals[i].y)>abs(facenormals[i].x)&&abs(facenormals[i].y)>abs(facenormals[i].z)){
1236                                                 decalposition[numdecals]=where;
1237                                                 decaltype[numdecals]=atype;
1238                                                 decalrotation[numdecals]=rotation;
1239                                                 decalalivetime[numdecals]=0;
1240                                                 decalopacity[numdecals]=opacity-distance/10;
1241
1242                                                 if(decalopacity[numdecals>0]){
1243                                                         placex=vertex[Triangles[i].vertex[0]].x;
1244                                                         placez=vertex[Triangles[i].vertex[0]].z;
1245
1246                                                         decaltexcoords[numdecals][0][0]=(placex-where.x)/(size)/2+.5;
1247                                                         decaltexcoords[numdecals][0][1]=(placez-where.z)/(size)/2+.5;
1248
1249                                                         decalvertex[numdecals][0].x=placex;
1250                                                         decalvertex[numdecals][0].z=placez;
1251                                                         decalvertex[numdecals][0].y=vertex[Triangles[i].vertex[0]].y;
1252
1253
1254                                                         placex=vertex[Triangles[i].vertex[1]].x;
1255                                                         placez=vertex[Triangles[i].vertex[1]].z;
1256
1257                                                         decaltexcoords[numdecals][1][0]=(placex-where.x)/(size)/2+.5;
1258                                                         decaltexcoords[numdecals][1][1]=(placez-where.z)/(size)/2+.5;
1259
1260                                                         decalvertex[numdecals][1].x=placex;
1261                                                         decalvertex[numdecals][1].z=placez;
1262                                                         decalvertex[numdecals][1].y=vertex[Triangles[i].vertex[1]].y;
1263
1264
1265                                                         placex=vertex[Triangles[i].vertex[2]].x;
1266                                                         placez=vertex[Triangles[i].vertex[2]].z;
1267
1268                                                         decaltexcoords[numdecals][2][0]=(placex-where.x)/(size)/2+.5;
1269                                                         decaltexcoords[numdecals][2][1]=(placez-where.z)/(size)/2+.5;
1270
1271                                                         decalvertex[numdecals][2].x=placex;
1272                                                         decalvertex[numdecals][2].z=placez;
1273                                                         decalvertex[numdecals][2].y=vertex[Triangles[i].vertex[2]].y;
1274
1275                                                         if(!(decaltexcoords[numdecals][0][0]<0&&decaltexcoords[numdecals][1][0]<0&&decaltexcoords[numdecals][2][0]<0))
1276                                                                 if(!(decaltexcoords[numdecals][0][1]<0&&decaltexcoords[numdecals][1][1]<0&&decaltexcoords[numdecals][2][1]<0))
1277                                                                         if(!(decaltexcoords[numdecals][0][0]>1&&decaltexcoords[numdecals][1][0]>1&&decaltexcoords[numdecals][2][0]>1))
1278                                                                                 if(!(decaltexcoords[numdecals][0][1]>1&&decaltexcoords[numdecals][1][1]>1&&decaltexcoords[numdecals][2][1]>1))
1279                                                                                 {
1280                                                                                         if(decalrotation[numdecals]){
1281                                                                                                 for(j=0;j<3;j++){                       
1282                                                                                                         rot.y=0;
1283                                                                                                         rot.x=decaltexcoords[numdecals][j][0]-.5;
1284                                                                                                         rot.z=decaltexcoords[numdecals][j][1]-.5;
1285                                                                                                         rot=DoRotation(rot,0,-decalrotation[numdecals],0);
1286                                                                                                         decaltexcoords[numdecals][j][0]=rot.x+.5;
1287                                                                                                         decaltexcoords[numdecals][j][1]=rot.z+.5;
1288                                                                                                 }
1289                                                                                         }
1290                                                                                         if(numdecals<max_model_decals-1)numdecals++;
1291                                                                                 }
1292                                                 }
1293                                         }
1294                                         else if(distance<.02&&abs(facenormals[i].x)>abs(facenormals[i].y)&&abs(facenormals[i].x)>abs(facenormals[i].z)){
1295                                                 decalposition[numdecals]=where;
1296                                                 decaltype[numdecals]=atype;
1297                                                 decalrotation[numdecals]=rotation;
1298                                                 decalalivetime[numdecals]=0;
1299                                                 decalopacity[numdecals]=opacity-distance/10;
1300
1301                                                 if(decalopacity[numdecals>0]){
1302                                                         placex=vertex[Triangles[i].vertex[0]].y;
1303                                                         placez=vertex[Triangles[i].vertex[0]].z;
1304
1305                                                         decaltexcoords[numdecals][0][0]=(placex-where.y)/(size)/2+.5;
1306                                                         decaltexcoords[numdecals][0][1]=(placez-where.z)/(size)/2+.5;
1307
1308                                                         decalvertex[numdecals][0].x=vertex[Triangles[i].vertex[0]].x;
1309                                                         decalvertex[numdecals][0].z=placez;
1310                                                         decalvertex[numdecals][0].y=placex;
1311
1312
1313                                                         placex=vertex[Triangles[i].vertex[1]].y;
1314                                                         placez=vertex[Triangles[i].vertex[1]].z;
1315
1316                                                         decaltexcoords[numdecals][1][0]=(placex-where.y)/(size)/2+.5;
1317                                                         decaltexcoords[numdecals][1][1]=(placez-where.z)/(size)/2+.5;
1318
1319                                                         decalvertex[numdecals][1].x=vertex[Triangles[i].vertex[1]].x;
1320                                                         decalvertex[numdecals][1].z=placez;
1321                                                         decalvertex[numdecals][1].y=placex;
1322
1323
1324                                                         placex=vertex[Triangles[i].vertex[2]].y;
1325                                                         placez=vertex[Triangles[i].vertex[2]].z;
1326
1327                                                         decaltexcoords[numdecals][2][0]=(placex-where.y)/(size)/2+.5;
1328                                                         decaltexcoords[numdecals][2][1]=(placez-where.z)/(size)/2+.5;
1329
1330                                                         decalvertex[numdecals][2].x=vertex[Triangles[i].vertex[2]].x;
1331                                                         decalvertex[numdecals][2].z=placez;
1332                                                         decalvertex[numdecals][2].y=placex;
1333
1334                                                         if(!(decaltexcoords[numdecals][0][0]<0&&decaltexcoords[numdecals][1][0]<0&&decaltexcoords[numdecals][2][0]<0))
1335                                                                 if(!(decaltexcoords[numdecals][0][1]<0&&decaltexcoords[numdecals][1][1]<0&&decaltexcoords[numdecals][2][1]<0))
1336                                                                         if(!(decaltexcoords[numdecals][0][0]>1&&decaltexcoords[numdecals][1][0]>1&&decaltexcoords[numdecals][2][0]>1))
1337                                                                                 if(!(decaltexcoords[numdecals][0][1]>1&&decaltexcoords[numdecals][1][1]>1&&decaltexcoords[numdecals][2][1]>1))
1338                                                                                 {
1339                                                                                         if(decalrotation[numdecals]){
1340                                                                                                 for(j=0;j<3;j++){                       
1341                                                                                                         rot.y=0;
1342                                                                                                         rot.x=decaltexcoords[numdecals][j][0]-.5;
1343                                                                                                         rot.z=decaltexcoords[numdecals][j][1]-.5;
1344                                                                                                         rot=DoRotation(rot,0,-decalrotation[numdecals],0);
1345                                                                                                         decaltexcoords[numdecals][j][0]=rot.x+.5;
1346                                                                                                         decaltexcoords[numdecals][j][1]=rot.z+.5;
1347                                                                                                 }
1348                                                                                         }
1349                                                                                         if(numdecals<max_model_decals-1)numdecals++;
1350                                                                                 }
1351                                                 }
1352                                         }
1353                                         else if(distance<.02&&abs(facenormals[i].z)>abs(facenormals[i].y)&&abs(facenormals[i].z)>abs(facenormals[i].x)){
1354                                                 decalposition[numdecals]=where;
1355                                                 decaltype[numdecals]=atype;
1356                                                 decalrotation[numdecals]=rotation;
1357                                                 decalalivetime[numdecals]=0;
1358                                                 decalopacity[numdecals]=opacity-distance/10;
1359
1360                                                 if(decalopacity[numdecals>0]){
1361                                                         placex=vertex[Triangles[i].vertex[0]].x;
1362                                                         placez=vertex[Triangles[i].vertex[0]].y;
1363
1364                                                         decaltexcoords[numdecals][0][0]=(placex-where.x)/(size)/2+.5;
1365                                                         decaltexcoords[numdecals][0][1]=(placez-where.y)/(size)/2+.5;
1366
1367                                                         decalvertex[numdecals][0].x=placex;
1368                                                         decalvertex[numdecals][0].z=vertex[Triangles[i].vertex[0]].z;
1369                                                         decalvertex[numdecals][0].y=placez;
1370
1371
1372                                                         placex=vertex[Triangles[i].vertex[1]].x;
1373                                                         placez=vertex[Triangles[i].vertex[1]].y;
1374
1375                                                         decaltexcoords[numdecals][1][0]=(placex-where.x)/(size)/2+.5;
1376                                                         decaltexcoords[numdecals][1][1]=(placez-where.y)/(size)/2+.5;
1377
1378                                                         decalvertex[numdecals][1].x=placex;
1379                                                         decalvertex[numdecals][1].z=vertex[Triangles[i].vertex[1]].z;
1380                                                         decalvertex[numdecals][1].y=placez;
1381
1382
1383                                                         placex=vertex[Triangles[i].vertex[2]].x;
1384                                                         placez=vertex[Triangles[i].vertex[2]].y;
1385
1386                                                         decaltexcoords[numdecals][2][0]=(placex-where.x)/(size)/2+.5;
1387                                                         decaltexcoords[numdecals][2][1]=(placez-where.y)/(size)/2+.5;
1388
1389                                                         decalvertex[numdecals][2].x=placex;
1390                                                         decalvertex[numdecals][2].z=vertex[Triangles[i].vertex[2]].z;
1391                                                         decalvertex[numdecals][2].y=placez;
1392
1393                                                         if(!(decaltexcoords[numdecals][0][0]<0&&decaltexcoords[numdecals][1][0]<0&&decaltexcoords[numdecals][2][0]<0))
1394                                                                 if(!(decaltexcoords[numdecals][0][1]<0&&decaltexcoords[numdecals][1][1]<0&&decaltexcoords[numdecals][2][1]<0))
1395                                                                         if(!(decaltexcoords[numdecals][0][0]>1&&decaltexcoords[numdecals][1][0]>1&&decaltexcoords[numdecals][2][0]>1))
1396                                                                                 if(!(decaltexcoords[numdecals][0][1]>1&&decaltexcoords[numdecals][1][1]>1&&decaltexcoords[numdecals][2][1]>1))
1397                                                                                 {
1398                                                                                         if(decalrotation[numdecals]){
1399                                                                                                 for(j=0;j<3;j++){                       
1400                                                                                                         rot.y=0;
1401                                                                                                         rot.x=decaltexcoords[numdecals][j][0]-.5;
1402                                                                                                         rot.z=decaltexcoords[numdecals][j][1]-.5;
1403                                                                                                         rot=DoRotation(rot,0,-decalrotation[numdecals],0);
1404                                                                                                         decaltexcoords[numdecals][j][0]=rot.x+.5;
1405                                                                                                         decaltexcoords[numdecals][j][1]=rot.z+.5;
1406                                                                                                 }
1407                                                                                         }
1408                                                                                         if(numdecals<max_model_decals-1)numdecals++;
1409                                                                                 }
1410                                                 }
1411                                         }
1412                                 }
1413         }
1414 }
1415
1416 Model::~Model()
1417 {
1418         deallocate();
1419
1420         if(textureptr) glDeleteTextures( 1, &textureptr );
1421 }
1422
1423 void Model::deallocate()
1424 {
1425         int i = 0, j = 0;
1426
1427         if(owner)dealloc(owner);
1428         owner = 0;
1429
1430         if(possible)dealloc(possible);
1431         possible = 0;
1432
1433         if(vertex)dealloc(vertex);
1434         vertex = 0;
1435
1436         if(normals)dealloc(normals);
1437         normals = 0;
1438
1439         if(facenormals)dealloc(facenormals);
1440         facenormals = 0;
1441
1442         if(Triangles)dealloc(Triangles);
1443         Triangles = 0;
1444
1445         if(vArray)dealloc(vArray);
1446         vArray = 0;
1447
1448
1449         //allow decals
1450         if(decaltexcoords)
1451         {
1452                 for(i=0;i<max_model_decals;i++)
1453                 {
1454                         for(j=0;j<3;j++)
1455                         {
1456                                 dealloc(decaltexcoords[i][j]);
1457                         }
1458                         dealloc(decaltexcoords[i]);
1459                 }
1460                 dealloc(decaltexcoords);
1461         }
1462         decaltexcoords = 0;
1463
1464
1465         if (decalvertex)
1466         {
1467                 for(i=0;i<max_model_decals;i++)
1468                 {
1469                         dealloc(decalvertex[i]);
1470                 }
1471                 dealloc(decalvertex);
1472         }
1473         decalvertex = 0;
1474
1475
1476         dealloc(decaltype);
1477         decaltype = 0;
1478
1479         dealloc(decalopacity);
1480         decalopacity = 0;
1481
1482         dealloc(decalrotation);
1483         decalrotation = 0;
1484
1485         dealloc(decalalivetime);
1486         decalalivetime = 0;
1487
1488         dealloc(decalposition);
1489         decalposition = 0;
1490
1491 };
1492
1493 Model::Model()
1494 {
1495         vertexNum = 0,TriangleNum = 0;
1496         hastexture = 0;
1497
1498         type = 0,oldtype = 0;
1499
1500         possible=0;
1501         owner=0;
1502         vertex=0;
1503         normals=0;
1504         facenormals=0;
1505         Triangles=0;
1506         vArray=0;
1507
1508         textureptr = 0;
1509         memset(&Texture, 0, sizeof(Texture));
1510         numpossible = 0;
1511         color = 0;
1512
1513         boundingspherecenter = 0;
1514         boundingsphereradius = 0;
1515
1516         decaltexcoords=0;
1517         decalvertex=0;
1518         decaltype=0;
1519         decalopacity=0;
1520         decalrotation=0;
1521         decalalivetime=0;
1522         decalposition=0;
1523
1524         numdecals = 0;
1525
1526         flat = 0;
1527
1528         type=nothing;
1529 }
1530