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