2 Copyright (C) 2003, 2010 - Wolfire Games
4 This file is part of Lugaru.
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.
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.
15 See the GNU General Public License for more details.
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.
24 //#include "altivec.h"
26 extern float multiplier;
27 extern float viewdistance;
29 extern float fadestart;
30 extern float texdetail;
32 extern int loadscreencolor;
35 extern bool visibleloading;
37 void *allocate_aligned(size_t pointer_size, size_t byte_alignment)
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;
46 void free_aligned(void *aligned_pointer)
48 free((uint8_t *)(aligned_pointer) - *((uint8_t *)(aligned_pointer) - 1));
51 void dealloc(void* param){
56 int Model::LineCheck(XYZ *p1,XYZ *p2, XYZ *p, XYZ *move, float *rotate)
59 static float distance;
60 static float olddistance;
61 static int intersecting;
62 static int firstintersecting;
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;
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;}
79 if(*rotate)*p=DoRotation(*p,0,*rotate,0);
81 return firstintersecting;
84 int Model::LineCheckSlide(XYZ *p1,XYZ *p2, XYZ *p, XYZ *move, float *rotate)
87 static float distance;
88 static float olddistance;
89 static int intersecting;
90 static int firstintersecting;
95 if(!sphere_line_intersection(p1,p2,&boundingspherecenter,
96 &boundingsphereradius))return -1;
98 if(*rotate)*p1=DoRotation(*p1,0,-*rotate,0);
99 if(*rotate)*p2=DoRotation(*p2,0,-*rotate,0);
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;}
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;
110 if(*rotate)*p2=DoRotation(*p2,0,*rotate,0);
112 return firstintersecting;
115 int Model::LineCheckPossible(XYZ *p1,XYZ *p2, XYZ *p, XYZ *move, float *rotate)
118 static float distance;
119 static float olddistance;
120 static int intersecting;
121 static int firstintersecting;
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);
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;}
141 if(*rotate)*p=DoRotation(*p,0,*rotate,0);
143 return firstintersecting;
146 int Model::LineCheckSlidePossible(XYZ *p1,XYZ *p2, XYZ *p, XYZ *move, float *rotate)
149 static float distance;
150 static float olddistance;
151 static int intersecting;
152 static int firstintersecting;
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);
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];}
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;
177 if(*rotate)*p2=DoRotation(*p2,0,*rotate,0);
179 return firstintersecting;
182 int Model::SphereCheck(XYZ *p1,float radius, XYZ *p, XYZ *move, float *rotate)
185 static float distance;
186 static float olddistance;
187 static int intersecting;
188 static int firstintersecting;
191 static XYZ start,end;
193 firstintersecting=-1;
197 if(*rotate)*p1=DoRotation(*p1,0,-*rotate,0);
198 if(findDistancefast(p1,&boundingspherecenter)>radius*radius+boundingsphereradius*boundingsphereradius)return -1;
201 for (j=0;j<TriangleNum;j++){
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)));
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]],
210 if(!intersecting)intersecting=sphere_line_intersection(&vertex[Triangles[j].vertex[1]],
211 &vertex[Triangles[j].vertex[2]],
213 if(!intersecting)intersecting=sphere_line_intersection(&vertex[Triangles[j].vertex[0]],
214 &vertex[Triangles[j].vertex[2]],
217 *p1+=facenormals[j]*(distance-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;
226 if((distance<olddistance||firstintersecting==-1)&&intersecting){olddistance=distance; firstintersecting=j; *p=point;}
229 if(*rotate)*p=DoRotation(*p,0,*rotate,0);
231 if(*rotate)*p1=DoRotation(*p1,0,*rotate,0);
233 return firstintersecting;
236 int Model::SphereCheckPossible(XYZ *p1,float radius, XYZ *move, float *rotate)
239 static float distance;
240 static float olddistance;
241 static int intersecting;
242 static int firstintersecting;
245 static XYZ start,end;
247 firstintersecting=-1;
254 if(*rotate)*p1=DoRotation(*p1,0,-*rotate,0);
255 if(findDistancefast(p1,&boundingspherecenter)>radius*radius+boundingsphereradius*boundingsphereradius){*p1=oldp1; return -1;}
257 for (j=0;j<TriangleNum;j++){
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)));
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]],
266 if(!intersecting)intersecting=sphere_line_intersection(&vertex[Triangles[j].vertex[1]],
267 &vertex[Triangles[j].vertex[2]],
269 if(!intersecting)intersecting=sphere_line_intersection(&vertex[Triangles[j].vertex[0]],
270 &vertex[Triangles[j].vertex[2]],
273 //if(j>=0&&j<TriangleNum)
274 possible[numpossible]=j;
278 if((distance<olddistance||firstintersecting==-1)&&intersecting){olddistance=distance; firstintersecting=j;}
280 if(*rotate)*p1=DoRotation(*p1,0,*rotate,0);
282 return firstintersecting;
286 void Model::UpdateVertexArray(){
287 if(type!=normaltype&&type!=decalstype)return;
291 for(i=0;i<TriangleNum;i++){
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;
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;
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;
321 for(i=0;i<TriangleNum;i++){
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;
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;
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;
353 void Model::UpdateVertexArrayNoTex(){
354 if(type!=normaltype&&type!=decalstype)return;
358 for(i=0;i<TriangleNum;i++){
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;
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;
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;
382 for(i=0;i<TriangleNum;i++){
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;
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;
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;
407 void Model::UpdateVertexArrayNoTexNoNorm(){
408 if(type!=normaltype&&type!=decalstype)return;
411 for(i=0;i<TriangleNum;i++){
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;
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;
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;
427 bool Model::loadnotex(const char *filename )
432 int oldvertexNum,oldTriangleNum;
433 oldvertexNum=vertexNum;
434 oldTriangleNum=TriangleNum;
439 tfile=fopen( ConvertFileName(filename), "rb" );
440 // read model settings
442 fseek(tfile, 0, SEEK_SET);
443 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
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);*/
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);
463 for(i=0;i<vertexNum;i++){
464 funpackf(tfile, "Bf Bf Bf", &vertex[i].x,&vertex[i].y,&vertex[i].z);
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]);
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]);
482 for(i=0;i<vertexNum;i++){
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;
496 boundingsphereradius=fast_sqrt(boundingsphereradius);
502 bool Model::load(const char *filename,bool texture )
509 LOG(std::string("Loading model...") + filename);
513 pgame->LoadingScreen();
516 int oldvertexNum,oldTriangleNum;
517 oldvertexNum=vertexNum;
518 oldTriangleNum=TriangleNum;
523 tfile=fopen( ConvertFileName(filename), "rb" );
524 // read model settings
527 fseek(tfile, 0, SEEK_SET);
528 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
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);*/
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);
550 for(i=0;i<vertexNum;i++){
551 funpackf(tfile, "Bf Bf Bf", &vertex[i].x,&vertex[i].y,&vertex[i].z);
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]);
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]);
571 for(i=0;i<vertexNum;i++){
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;
585 boundingsphereradius=fast_sqrt(boundingsphereradius);
590 bool Model::loaddecal(const char *filename,bool texture )
597 // Changing the filename so that its more os specific
598 char * FixedFN = ConvertFileName(filename);
600 LOG(std::string("Loading decal...") + FixedFN);
602 int oldvertexNum,oldTriangleNum;
603 oldvertexNum=vertexNum;
604 oldTriangleNum=TriangleNum;
610 tfile=fopen( FixedFN, "rb" );
611 // read model settings
614 fseek(tfile, 0, SEEK_SET);
615 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
617 // read the model data
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);*/
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);
639 for(i=0;i<vertexNum;i++){
640 funpackf(tfile, "Bf Bf Bf", &vertex[i].x,&vertex[i].y,&vertex[i].z);
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]);
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]);
661 for(i=0;i<vertexNum;i++){
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;
674 boundingsphereradius=fast_sqrt(boundingsphereradius);
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);
682 decaltexcoords[i][j] = (float*)malloc(sizeof(float)*2);
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);
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);
701 bool Model::loadraw(char *filename )
708 LOG(std::string("Loading raw...") + filename);
710 int oldvertexNum,oldTriangleNum;
711 oldvertexNum=vertexNum;
712 oldTriangleNum=TriangleNum;
717 tfile=fopen( ConvertFileName(filename), "rb" );
718 // read model settings
721 fseek(tfile, 0, SEEK_SET);
722 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
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);*/
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);
743 for(i=0;i<vertexNum;i++){
744 funpackf(tfile, "Bf Bf Bf", &vertex[i].x,&vertex[i].y,&vertex[i].z);
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]);
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]);
761 for(i=0;i<vertexNum;i++){
769 void Model::UniformTexCoords()
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;
784 void Model::FlipTexCoords()
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];
795 void Model::ScaleTexCoords(float howmuch)
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;
809 void Model::Scale(float xscale,float yscale,float zscale)
812 for(i=0; i<vertexNum; i++){
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;
830 boundingsphereradius=fast_sqrt(boundingsphereradius);
833 void Model::ScaleNormals(float xscale,float yscale,float zscale)
835 if(type!=normaltype&&type!=decalstype)return;
837 for(i=0; i<vertexNum; i++){
838 normals[i].x*=xscale;
839 normals[i].y*=yscale;
840 normals[i].z*=zscale;
842 for(i=0; i<TriangleNum; i++){
843 facenormals[i].x*=xscale;
844 facenormals[i].y*=yscale;
845 facenormals[i].z*=zscale;
850 void Model::Translate(float xtrans,float ytrans,float ztrans)
853 for(i=0; i<vertexNum; i++){
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;
870 boundingsphereradius=fast_sqrt(boundingsphereradius);
873 void Model::Rotate(float xang,float yang,float zang)
876 for(i=0; i<vertexNum; i++){
877 vertex[i]=DoRotation(vertex[i],xang,yang,zang);
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;
891 boundingsphereradius=fast_sqrt(boundingsphereradius);
895 void Model::CalculateNormals(bool facenormalise)
899 pgame->LoadingScreen();
902 if(type!=normaltype&&type!=decalstype)return;
904 for(i=0; i<vertexNum; i++){
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]);
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;
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;
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]);
926 for(i=0; i<vertexNum; i++){
927 Normalise(&normals[i]);
930 UpdateVertexArrayNoTex();
933 void Model::drawimmediate()
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)){
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);
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);
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);
968 if(type!=normaltype&&type!=decalstype)return;
970 glEnableClientState(GL_NORMAL_ARRAY);
971 glEnableClientState(GL_VERTEX_ARRAY);
972 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
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);
979 glLockArraysEXT( 0, TriangleNum*3);
981 glDrawArrays(GL_TRIANGLES, 0, TriangleNum*3);
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);
994 void Model::drawdifftex(GLuint texture)
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]);
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 );
1008 glLockArraysEXT( 0, TriangleNum*3);
1010 glDrawArrays(GL_TRIANGLES, 0, TriangleNum*3);
1012 glUnlockArraysEXT();
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);
1023 void Model::drawdiffteximmediate(GLuint texture)
1025 glBindTexture(GL_TEXTURE_2D,(unsigned long)texture);
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);
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);
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);
1056 void Model::drawdecals(GLuint shadowtexture,GLuint bloodtexture,GLuint bloodtexture2,GLuint breaktexture)
1059 if(type!=decalstype)return;
1061 static float distancemult;
1062 static int lasttype;
1063 static float viewdistsquared;
1066 viewdistsquared=viewdistance*viewdistance;
1071 glDisable(GL_LIGHTING);
1072 glDisable(GL_CULL_FACE);
1073 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
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;
1079 if(decaltype[i]==shadowdecal&&decaltype[i]!=lasttype){
1080 glBindTexture( GL_TEXTURE_2D, shadowtexture);
1083 glAlphaFunc(GL_GREATER, 0.0001);
1084 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1087 if(decaltype[i]==breakdecal&&decaltype[i]!=lasttype){
1088 glBindTexture( GL_TEXTURE_2D, breaktexture);
1091 glAlphaFunc(GL_GREATER, 0.0001);
1092 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1095 if((decaltype[i]==blooddecal||decaltype[i]==blooddecalslow)&&decaltype[i]!=lasttype){
1096 glBindTexture( GL_TEXTURE_2D, bloodtexture);
1099 glAlphaFunc(GL_GREATER, 0.15);
1100 glBlendFunc(GL_ONE,GL_ZERO);
1103 if((decaltype[i]==blooddecalfast)&&decaltype[i]!=lasttype){
1104 glBindTexture( GL_TEXTURE_2D, bloodtexture2);
1107 glAlphaFunc(GL_GREATER, 0.15);
1108 glBlendFunc(GL_ONE,GL_ZERO);
1111 if(decaltype[i]==shadowdecal){
1112 glColor4f(1,1,1,decalopacity[i]);
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);
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);
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);
1127 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
1129 glBegin(GL_TRIANGLES);
1130 for(int j=0;j<3;j++)
1132 glTexCoord2f(decaltexcoords[i][j][0], decaltexcoords[i][j][1]); glVertex3f(decalvertex[i][j].x,decalvertex[i][j].y,decalvertex[i][j].z);
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);
1144 glAlphaFunc(GL_GREATER, 0.0001);
1145 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1149 void Model::DeleteDecal(int which)
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];
1160 decalrotation[which]=decalrotation[numdecals-1];
1161 decalalivetime[which]=decalalivetime[numdecals-1];
1162 decalopacity[which]=decalopacity[numdecals-1];
1167 void Model::MakeDecal(int atype, XYZ *where,float *size, float *opacity, float *rotation){
1169 if(type!=decalstype)return;
1171 static float placex,placez;
1173 //static XYZ point,point1,point2;
1174 static float distance;
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;
1188 if(decalopacity[numdecals>0]){
1189 placex=vertex[Triangles[i].vertex[0]].x;
1190 placez=vertex[Triangles[i].vertex[0]].z;
1192 decaltexcoords[numdecals][0][0]=(placex-where->x)/(*size)/2+.5;
1193 decaltexcoords[numdecals][0][1]=(placez-where->z)/(*size)/2+.5;
1195 decalvertex[numdecals][0].x=placex;
1196 decalvertex[numdecals][0].z=placez;
1197 decalvertex[numdecals][0].y=vertex[Triangles[i].vertex[0]].y;
1200 placex=vertex[Triangles[i].vertex[1]].x;
1201 placez=vertex[Triangles[i].vertex[1]].z;
1203 decaltexcoords[numdecals][1][0]=(placex-where->x)/(*size)/2+.5;
1204 decaltexcoords[numdecals][1][1]=(placez-where->z)/(*size)/2+.5;
1206 decalvertex[numdecals][1].x=placex;
1207 decalvertex[numdecals][1].z=placez;
1208 decalvertex[numdecals][1].y=vertex[Triangles[i].vertex[1]].y;
1211 placex=vertex[Triangles[i].vertex[2]].x;
1212 placez=vertex[Triangles[i].vertex[2]].z;
1214 decaltexcoords[numdecals][2][0]=(placex-where->x)/(*size)/2+.5;
1215 decaltexcoords[numdecals][2][1]=(placez-where->z)/(*size)/2+.5;
1217 decalvertex[numdecals][2].x=placex;
1218 decalvertex[numdecals][2].z=placez;
1219 decalvertex[numdecals][2].y=vertex[Triangles[i].vertex[2]].y;
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))
1226 if(decalrotation[numdecals]){
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;
1236 if(numdecals<max_model_decals-1)numdecals++;
1244 void Model::MakeDecal(int atype, XYZ where,float size, float opacity, float rotation){
1246 if(type!=decalstype)return;
1248 static float placex,placez;
1250 //static XYZ point,point1,point2;
1251 static float distance;
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;
1265 if(decalopacity[numdecals>0]){
1266 placex=vertex[Triangles[i].vertex[0]].x;
1267 placez=vertex[Triangles[i].vertex[0]].z;
1269 decaltexcoords[numdecals][0][0]=(placex-where.x)/(size)/2+.5;
1270 decaltexcoords[numdecals][0][1]=(placez-where.z)/(size)/2+.5;
1272 decalvertex[numdecals][0].x=placex;
1273 decalvertex[numdecals][0].z=placez;
1274 decalvertex[numdecals][0].y=vertex[Triangles[i].vertex[0]].y;
1277 placex=vertex[Triangles[i].vertex[1]].x;
1278 placez=vertex[Triangles[i].vertex[1]].z;
1280 decaltexcoords[numdecals][1][0]=(placex-where.x)/(size)/2+.5;
1281 decaltexcoords[numdecals][1][1]=(placez-where.z)/(size)/2+.5;
1283 decalvertex[numdecals][1].x=placex;
1284 decalvertex[numdecals][1].z=placez;
1285 decalvertex[numdecals][1].y=vertex[Triangles[i].vertex[1]].y;
1288 placex=vertex[Triangles[i].vertex[2]].x;
1289 placez=vertex[Triangles[i].vertex[2]].z;
1291 decaltexcoords[numdecals][2][0]=(placex-where.x)/(size)/2+.5;
1292 decaltexcoords[numdecals][2][1]=(placez-where.z)/(size)/2+.5;
1294 decalvertex[numdecals][2].x=placex;
1295 decalvertex[numdecals][2].z=placez;
1296 decalvertex[numdecals][2].y=vertex[Triangles[i].vertex[2]].y;
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))
1303 if(decalrotation[numdecals]){
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;
1313 if(numdecals<max_model_decals-1)numdecals++;
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;
1324 if(decalopacity[numdecals>0]){
1325 placex=vertex[Triangles[i].vertex[0]].y;
1326 placez=vertex[Triangles[i].vertex[0]].z;
1328 decaltexcoords[numdecals][0][0]=(placex-where.y)/(size)/2+.5;
1329 decaltexcoords[numdecals][0][1]=(placez-where.z)/(size)/2+.5;
1331 decalvertex[numdecals][0].x=vertex[Triangles[i].vertex[0]].x;
1332 decalvertex[numdecals][0].z=placez;
1333 decalvertex[numdecals][0].y=placex;
1336 placex=vertex[Triangles[i].vertex[1]].y;
1337 placez=vertex[Triangles[i].vertex[1]].z;
1339 decaltexcoords[numdecals][1][0]=(placex-where.y)/(size)/2+.5;
1340 decaltexcoords[numdecals][1][1]=(placez-where.z)/(size)/2+.5;
1342 decalvertex[numdecals][1].x=vertex[Triangles[i].vertex[1]].x;
1343 decalvertex[numdecals][1].z=placez;
1344 decalvertex[numdecals][1].y=placex;
1347 placex=vertex[Triangles[i].vertex[2]].y;
1348 placez=vertex[Triangles[i].vertex[2]].z;
1350 decaltexcoords[numdecals][2][0]=(placex-where.y)/(size)/2+.5;
1351 decaltexcoords[numdecals][2][1]=(placez-where.z)/(size)/2+.5;
1353 decalvertex[numdecals][2].x=vertex[Triangles[i].vertex[2]].x;
1354 decalvertex[numdecals][2].z=placez;
1355 decalvertex[numdecals][2].y=placex;
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))
1362 if(decalrotation[numdecals]){
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;
1372 if(numdecals<max_model_decals-1)numdecals++;
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;
1383 if(decalopacity[numdecals>0]){
1384 placex=vertex[Triangles[i].vertex[0]].x;
1385 placez=vertex[Triangles[i].vertex[0]].y;
1387 decaltexcoords[numdecals][0][0]=(placex-where.x)/(size)/2+.5;
1388 decaltexcoords[numdecals][0][1]=(placez-where.y)/(size)/2+.5;
1390 decalvertex[numdecals][0].x=placex;
1391 decalvertex[numdecals][0].z=vertex[Triangles[i].vertex[0]].z;
1392 decalvertex[numdecals][0].y=placez;
1395 placex=vertex[Triangles[i].vertex[1]].x;
1396 placez=vertex[Triangles[i].vertex[1]].y;
1398 decaltexcoords[numdecals][1][0]=(placex-where.x)/(size)/2+.5;
1399 decaltexcoords[numdecals][1][1]=(placez-where.y)/(size)/2+.5;
1401 decalvertex[numdecals][1].x=placex;
1402 decalvertex[numdecals][1].z=vertex[Triangles[i].vertex[1]].z;
1403 decalvertex[numdecals][1].y=placez;
1406 placex=vertex[Triangles[i].vertex[2]].x;
1407 placez=vertex[Triangles[i].vertex[2]].y;
1409 decaltexcoords[numdecals][2][0]=(placex-where.x)/(size)/2+.5;
1410 decaltexcoords[numdecals][2][1]=(placez-where.y)/(size)/2+.5;
1412 decalvertex[numdecals][2].x=placex;
1413 decalvertex[numdecals][2].z=vertex[Triangles[i].vertex[2]].z;
1414 decalvertex[numdecals][2].y=placez;
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))
1421 if(decalrotation[numdecals]){
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;
1431 if(numdecals<max_model_decals-1)numdecals++;
1443 if(textureptr) glDeleteTextures( 1, &textureptr );
1446 void Model::deallocate()
1450 if(owner)dealloc(owner);
1453 if(possible)dealloc(possible);
1456 if(vertex)dealloc(vertex);
1459 if(normals)dealloc(normals);
1462 if(facenormals)dealloc(facenormals);
1465 if(Triangles)dealloc(Triangles);
1468 if(vArray)dealloc(vArray);
1475 for(i=0;i<max_model_decals;i++)
1479 dealloc(decaltexcoords[i][j]);
1481 dealloc(decaltexcoords[i]);
1483 dealloc(decaltexcoords);
1490 for(i=0;i<max_model_decals;i++)
1492 dealloc(decalvertex[i]);
1494 dealloc(decalvertex);
1502 dealloc(decalopacity);
1505 dealloc(decalrotation);
1508 dealloc(decalalivetime);
1511 dealloc(decalposition);
1518 vertexNum = 0,TriangleNum = 0;
1521 type = 0,oldtype = 0;
1532 memset(&Texture, 0, sizeof(Texture));
1536 boundingspherecenter = 0;
1537 boundingsphereradius = 0;