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