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