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.
23 //#include "altivec.h"
26 extern float multiplier;
27 extern float viewdistance;
29 extern float fadestart;
30 extern float texdetail;
32 extern int loadscreencolor;
36 extern bool visibleloading;
38 void *allocate_aligned(size_t pointer_size, size_t byte_alignment)
40 uintptr_t pointer = (uintptr_t)malloc(pointer_size + byte_alignment + 1);
41 uintptr_t aligned_pointer = (pointer + byte_alignment + 1);
42 aligned_pointer -= (aligned_pointer % byte_alignment);
43 *(uint8_t *)(aligned_pointer - 1) = (aligned_pointer - pointer);
44 return (void *)aligned_pointer;
47 void free_aligned(void *aligned_pointer)
49 free((uint8_t *)(aligned_pointer) - *((uint8_t *)(aligned_pointer) - 1));
52 void dealloc(void* param){
57 int Model::LineCheck(XYZ *p1,XYZ *p2, XYZ *p, XYZ *move, float *rotate)
60 static float distance;
61 static float olddistance;
62 static int intersecting;
63 static int firstintersecting;
68 if(*rotate)*p1=DoRotation(*p1,0,-*rotate,0);
69 if(*rotate)*p2=DoRotation(*p2,0,-*rotate,0);
70 if(!sphere_line_intersection(p1,p2,&boundingspherecenter,
71 &boundingsphereradius))return -1;
74 for (j=0;j<TriangleNum;j++){
75 intersecting=LineFacetd(p1,p2,&vertex[Triangles[j].vertex[0]],&vertex[Triangles[j].vertex[1]],&vertex[Triangles[j].vertex[2]],&facenormals[j],&point);
76 distance=(point.x-p1->x)*(point.x-p1->x)+(point.y-p1->y)*(point.y-p1->y)+(point.z-p1->z)*(point.z-p1->z);
77 if((distance<olddistance||firstintersecting==-1)&&intersecting){olddistance=distance; firstintersecting=j; *p=point;}
80 if(*rotate)*p=DoRotation(*p,0,*rotate,0);
82 return firstintersecting;
85 int Model::LineCheckSlide(XYZ *p1,XYZ *p2, XYZ *p, XYZ *move, float *rotate)
88 static float distance;
89 static float olddistance;
90 static int intersecting;
91 static int firstintersecting;
96 if(!sphere_line_intersection(p1,p2,&boundingspherecenter,
97 &boundingsphereradius))return -1;
99 if(*rotate)*p1=DoRotation(*p1,0,-*rotate,0);
100 if(*rotate)*p2=DoRotation(*p2,0,-*rotate,0);
102 for (j=0;j<TriangleNum;j++){
103 intersecting=LineFacetd(p1,p2,&vertex[Triangles[j].vertex[0]],&vertex[Triangles[j].vertex[1]],&vertex[Triangles[j].vertex[2]],&facenormals[j],&point);
104 distance=(point.x-p1->x)*(point.x-p1->x)+(point.y-p1->y)*(point.y-p1->y)+(point.z-p1->z)*(point.z-p1->z);
105 if((distance<olddistance||firstintersecting==-1)&&intersecting){olddistance=distance; firstintersecting=j;}
108 distance=abs((facenormals[firstintersecting].x*p2->x)+(facenormals[firstintersecting].y*p2->y)+(facenormals[firstintersecting].z*p2->z)-((facenormals[firstintersecting].x*vertex[Triangles[firstintersecting].vertex[0]].x)+(facenormals[firstintersecting].y*vertex[Triangles[firstintersecting].vertex[0]].y)+(facenormals[firstintersecting].z*vertex[Triangles[firstintersecting].vertex[0]].z)));
109 *p2-=facenormals[firstintersecting]*distance;
111 if(*rotate)*p2=DoRotation(*p2,0,*rotate,0);
113 return firstintersecting;
116 int Model::LineCheckPossible(XYZ *p1,XYZ *p2, XYZ *p, XYZ *move, float *rotate)
119 static float distance;
120 static float olddistance;
121 static int intersecting;
122 static int firstintersecting;
127 if(!sphere_line_intersection(p1,p2,&boundingspherecenter,
128 &boundingsphereradius))return -1;
129 firstintersecting=-1;
130 if(*rotate)*p1=DoRotation(*p1,0,-*rotate,0);
131 if(*rotate)*p2=DoRotation(*p2,0,-*rotate,0);
133 if(numpossible>0&&numpossible<TriangleNum)
134 for (j=0;j<numpossible;j++){
135 if(possible[j]>=0&&possible[j]<TriangleNum){
136 intersecting=LineFacetd(p1,p2,&vertex[Triangles[possible[j]].vertex[0]],&vertex[Triangles[possible[j]].vertex[1]],&vertex[Triangles[possible[j]].vertex[2]],&facenormals[possible[j]],&point);
137 distance=(point.x-p1->x)*(point.x-p1->x)+(point.y-p1->y)*(point.y-p1->y)+(point.z-p1->z)*(point.z-p1->z);
138 if((distance<olddistance||firstintersecting==-1)&&intersecting){olddistance=distance; firstintersecting=possible[j]; *p=point;}
142 if(*rotate)*p=DoRotation(*p,0,*rotate,0);
144 return firstintersecting;
147 int Model::LineCheckSlidePossible(XYZ *p1,XYZ *p2, XYZ *p, XYZ *move, float *rotate)
150 static float distance;
151 static float olddistance;
152 static int intersecting;
153 static int firstintersecting;
158 if(!sphere_line_intersection(p1,p2,&boundingspherecenter,
159 &boundingsphereradius))return -1;
160 firstintersecting=-1;
161 if(*rotate)*p1=DoRotation(*p1,0,-*rotate,0);
162 if(*rotate)*p2=DoRotation(*p2,0,-*rotate,0);
165 for (j=0;j<numpossible;j++){
166 if(possible[j]>=0&&possible[j]<TriangleNum){
167 intersecting=LineFacetd(p1,p2,&vertex[Triangles[possible[j]].vertex[0]],&vertex[Triangles[possible[j]].vertex[1]],&vertex[Triangles[possible[j]].vertex[2]],&facenormals[possible[j]],&point);
168 distance=(point.x-p1->x)*(point.x-p1->x)+(point.y-p1->y)*(point.y-p1->y)+(point.z-p1->z)*(point.z-p1->z);
169 if((distance<olddistance||firstintersecting==-1)&&intersecting){olddistance=distance; firstintersecting=possible[j];}
173 if(firstintersecting>0){
174 distance=abs((facenormals[firstintersecting].x*p2->x)+(facenormals[firstintersecting].y*p2->y)+(facenormals[firstintersecting].z*p2->z)-((facenormals[firstintersecting].x*vertex[Triangles[firstintersecting].vertex[0]].x)+(facenormals[firstintersecting].y*vertex[Triangles[firstintersecting].vertex[0]].y)+(facenormals[firstintersecting].z*vertex[Triangles[firstintersecting].vertex[0]].z)));
175 *p2-=facenormals[firstintersecting]*distance;
178 if(*rotate)*p2=DoRotation(*p2,0,*rotate,0);
180 return firstintersecting;
183 int Model::SphereCheck(XYZ *p1,float radius, XYZ *p, XYZ *move, float *rotate)
186 static float distance;
187 static float olddistance;
188 static int intersecting;
189 static int firstintersecting;
192 static XYZ start,end;
194 firstintersecting=-1;
198 if(*rotate)*p1=DoRotation(*p1,0,-*rotate,0);
199 if(findDistancefast(p1,&boundingspherecenter)>radius*radius+boundingsphereradius*boundingsphereradius)return -1;
202 for (j=0;j<TriangleNum;j++){
204 distance=abs((facenormals[j].x*p1->x)+(facenormals[j].y*p1->y)+(facenormals[j].z*p1->z)-((facenormals[j].x*vertex[Triangles[j].vertex[0]].x)+(facenormals[j].y*vertex[Triangles[j].vertex[0]].y)+(facenormals[j].z*vertex[Triangles[j].vertex[0]].z)));
206 point=*p1-facenormals[j]*distance;
207 if(PointInTriangle( &point, facenormals[j], &vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[1]], &vertex[Triangles[j].vertex[2]]))intersecting=1;
208 if(!intersecting)intersecting=sphere_line_intersection(&vertex[Triangles[j].vertex[0]],
209 &vertex[Triangles[j].vertex[1]],
211 if(!intersecting)intersecting=sphere_line_intersection(&vertex[Triangles[j].vertex[1]],
212 &vertex[Triangles[j].vertex[2]],
214 if(!intersecting)intersecting=sphere_line_intersection(&vertex[Triangles[j].vertex[0]],
215 &vertex[Triangles[j].vertex[2]],
218 *p1+=facenormals[j]*(distance-radius);
222 if(LineFacetd(&start,&end,&vertex[Triangles[j].vertex[0]],&vertex[Triangles[j].vertex[1]],&vertex[Triangles[j].vertex[2]],&facenormals[j],&point)){
223 p1->y=point.y+radius;
227 if((distance<olddistance||firstintersecting==-1)&&intersecting){olddistance=distance; firstintersecting=j; *p=point;}
230 if(*rotate)*p=DoRotation(*p,0,*rotate,0);
232 if(*rotate)*p1=DoRotation(*p1,0,*rotate,0);
234 return firstintersecting;
237 int Model::SphereCheckPossible(XYZ *p1,float radius, XYZ *move, float *rotate)
240 static float distance;
241 static float olddistance;
242 static int intersecting;
243 static int firstintersecting;
246 static XYZ start,end;
248 firstintersecting=-1;
255 if(*rotate)*p1=DoRotation(*p1,0,-*rotate,0);
256 if(findDistancefast(p1,&boundingspherecenter)>radius*radius+boundingsphereradius*boundingsphereradius){*p1=oldp1; return -1;}
258 for (j=0;j<TriangleNum;j++){
260 distance=abs((facenormals[j].x*p1->x)+(facenormals[j].y*p1->y)+(facenormals[j].z*p1->z)-((facenormals[j].x*vertex[Triangles[j].vertex[0]].x)+(facenormals[j].y*vertex[Triangles[j].vertex[0]].y)+(facenormals[j].z*vertex[Triangles[j].vertex[0]].z)));
262 point=*p1-facenormals[j]*distance;
263 if(PointInTriangle( &point, facenormals[j], &vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[1]], &vertex[Triangles[j].vertex[2]]))intersecting=1;
264 if(!intersecting)intersecting=sphere_line_intersection(&vertex[Triangles[j].vertex[0]],
265 &vertex[Triangles[j].vertex[1]],
267 if(!intersecting)intersecting=sphere_line_intersection(&vertex[Triangles[j].vertex[1]],
268 &vertex[Triangles[j].vertex[2]],
270 if(!intersecting)intersecting=sphere_line_intersection(&vertex[Triangles[j].vertex[0]],
271 &vertex[Triangles[j].vertex[2]],
274 //if(j>=0&&j<TriangleNum)
275 possible[numpossible]=j;
279 if((distance<olddistance||firstintersecting==-1)&&intersecting){olddistance=distance; firstintersecting=j;}
281 if(*rotate)*p1=DoRotation(*p1,0,*rotate,0);
283 return firstintersecting;
287 void Model::UpdateVertexArray(){
288 if(type!=normaltype&&type!=decalstype)return;
292 for(i=0;i<TriangleNum;i++){
294 vArray[j+0]=Triangles[i].gx[0];
295 vArray[j+1]=Triangles[i].gy[0];
296 vArray[j+2]=normals[Triangles[i].vertex[0]].x;
297 vArray[j+3]=normals[Triangles[i].vertex[0]].y;
298 vArray[j+4]=normals[Triangles[i].vertex[0]].z;
299 vArray[j+5]=vertex[Triangles[i].vertex[0]].x;
300 vArray[j+6]=vertex[Triangles[i].vertex[0]].y;
301 vArray[j+7]=vertex[Triangles[i].vertex[0]].z;
303 vArray[j+8]=Triangles[i].gx[1];
304 vArray[j+9]=Triangles[i].gy[1];
305 vArray[j+10]=normals[Triangles[i].vertex[1]].x;
306 vArray[j+11]=normals[Triangles[i].vertex[1]].y;
307 vArray[j+12]=normals[Triangles[i].vertex[1]].z;
308 vArray[j+13]=vertex[Triangles[i].vertex[1]].x;
309 vArray[j+14]=vertex[Triangles[i].vertex[1]].y;
310 vArray[j+15]=vertex[Triangles[i].vertex[1]].z;
312 vArray[j+16]=Triangles[i].gx[2];
313 vArray[j+17]=Triangles[i].gy[2];
314 vArray[j+18]=normals[Triangles[i].vertex[2]].x;
315 vArray[j+19]=normals[Triangles[i].vertex[2]].y;
316 vArray[j+20]=normals[Triangles[i].vertex[2]].z;
317 vArray[j+21]=vertex[Triangles[i].vertex[2]].x;
318 vArray[j+22]=vertex[Triangles[i].vertex[2]].y;
319 vArray[j+23]=vertex[Triangles[i].vertex[2]].z;
322 for(i=0;i<TriangleNum;i++){
324 vArray[j+0]=Triangles[i].gx[0];
325 vArray[j+1]=Triangles[i].gy[0];
326 vArray[j+2]=facenormals[i].x*-1;
327 vArray[j+3]=facenormals[i].y*-1;
328 vArray[j+4]=facenormals[i].z*-1;
329 vArray[j+5]=vertex[Triangles[i].vertex[0]].x;
330 vArray[j+6]=vertex[Triangles[i].vertex[0]].y;
331 vArray[j+7]=vertex[Triangles[i].vertex[0]].z;
333 vArray[j+8]=Triangles[i].gx[1];
334 vArray[j+9]=Triangles[i].gy[1];
335 vArray[j+10]=facenormals[i].x*-1;
336 vArray[j+11]=facenormals[i].y*-1;
337 vArray[j+12]=facenormals[i].z*-1;
338 vArray[j+13]=vertex[Triangles[i].vertex[1]].x;
339 vArray[j+14]=vertex[Triangles[i].vertex[1]].y;
340 vArray[j+15]=vertex[Triangles[i].vertex[1]].z;
342 vArray[j+16]=Triangles[i].gx[2];
343 vArray[j+17]=Triangles[i].gy[2];
344 vArray[j+18]=facenormals[i].x*-1;
345 vArray[j+19]=facenormals[i].y*-1;
346 vArray[j+20]=facenormals[i].z*-1;
347 vArray[j+21]=vertex[Triangles[i].vertex[2]].x;
348 vArray[j+22]=vertex[Triangles[i].vertex[2]].y;
349 vArray[j+23]=vertex[Triangles[i].vertex[2]].z;
354 void Model::UpdateVertexArrayNoTex(){
355 if(type!=normaltype&&type!=decalstype)return;
359 for(i=0;i<TriangleNum;i++){
361 vArray[j+2]=normals[Triangles[i].vertex[0]].x;
362 vArray[j+3]=normals[Triangles[i].vertex[0]].y;
363 vArray[j+4]=normals[Triangles[i].vertex[0]].z;
364 vArray[j+5]=vertex[Triangles[i].vertex[0]].x;
365 vArray[j+6]=vertex[Triangles[i].vertex[0]].y;
366 vArray[j+7]=vertex[Triangles[i].vertex[0]].z;
368 vArray[j+10]=normals[Triangles[i].vertex[1]].x;
369 vArray[j+11]=normals[Triangles[i].vertex[1]].y;
370 vArray[j+12]=normals[Triangles[i].vertex[1]].z;
371 vArray[j+13]=vertex[Triangles[i].vertex[1]].x;
372 vArray[j+14]=vertex[Triangles[i].vertex[1]].y;
373 vArray[j+15]=vertex[Triangles[i].vertex[1]].z;
375 vArray[j+18]=normals[Triangles[i].vertex[2]].x;
376 vArray[j+19]=normals[Triangles[i].vertex[2]].y;
377 vArray[j+20]=normals[Triangles[i].vertex[2]].z;
378 vArray[j+21]=vertex[Triangles[i].vertex[2]].x;
379 vArray[j+22]=vertex[Triangles[i].vertex[2]].y;
380 vArray[j+23]=vertex[Triangles[i].vertex[2]].z;
383 for(i=0;i<TriangleNum;i++){
385 vArray[j+2]=facenormals[i].x*-1;
386 vArray[j+3]=facenormals[i].y*-1;
387 vArray[j+4]=facenormals[i].z*-1;
388 vArray[j+5]=vertex[Triangles[i].vertex[0]].x;
389 vArray[j+6]=vertex[Triangles[i].vertex[0]].y;
390 vArray[j+7]=vertex[Triangles[i].vertex[0]].z;
392 vArray[j+10]=facenormals[i].x*-1;
393 vArray[j+11]=facenormals[i].y*-1;
394 vArray[j+12]=facenormals[i].z*-1;
395 vArray[j+13]=vertex[Triangles[i].vertex[1]].x;
396 vArray[j+14]=vertex[Triangles[i].vertex[1]].y;
397 vArray[j+15]=vertex[Triangles[i].vertex[1]].z;
399 vArray[j+18]=facenormals[i].x*-1;
400 vArray[j+19]=facenormals[i].y*-1;
401 vArray[j+20]=facenormals[i].z*-1;
402 vArray[j+21]=vertex[Triangles[i].vertex[2]].x;
403 vArray[j+22]=vertex[Triangles[i].vertex[2]].y;
404 vArray[j+23]=vertex[Triangles[i].vertex[2]].z;
408 void Model::UpdateVertexArrayNoTexNoNorm(){
409 if(type!=normaltype&&type!=decalstype)return;
412 for(i=0;i<TriangleNum;i++){
414 vArray[j+5]=vertex[Triangles[i].vertex[0]].x;
415 vArray[j+6]=vertex[Triangles[i].vertex[0]].y;
416 vArray[j+7]=vertex[Triangles[i].vertex[0]].z;
418 vArray[j+13]=vertex[Triangles[i].vertex[1]].x;
419 vArray[j+14]=vertex[Triangles[i].vertex[1]].y;
420 vArray[j+15]=vertex[Triangles[i].vertex[1]].z;
422 vArray[j+21]=vertex[Triangles[i].vertex[2]].x;
423 vArray[j+22]=vertex[Triangles[i].vertex[2]].y;
424 vArray[j+23]=vertex[Triangles[i].vertex[2]].z;
428 bool Model::loadnotex(char *filename )
433 int oldvertexNum,oldTriangleNum;
434 oldvertexNum=vertexNum;
435 oldTriangleNum=TriangleNum;
440 tfile=fopen( filename, "rb" );
441 // read model settings
443 fseek(tfile, 0, SEEK_SET);
444 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
446 // read the model data
447 /*if(owner)dealloc(owner);
448 if(possible)dealloc(possible);
449 if(vertex)dealloc(vertex);
450 if(normals)dealloc(normals);
451 if(facenormals)dealloc(facenormals);
452 if(Triangles)dealloc(Triangles);
453 if(vArray)dealloc(vArray);*/
458 owner = (int*)malloc(sizeof(int)*vertexNum);
459 possible = (int*)malloc(sizeof(int)*TriangleNum);
460 vertex = (XYZ*)malloc(sizeof(XYZ)*vertexNum);
461 Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle)*TriangleNum);
462 vArray = (GLfloat*)malloc(sizeof(GLfloat)*TriangleNum*24);
464 for(i=0;i<vertexNum;i++){
465 funpackf(tfile, "Bf Bf Bf", &vertex[i].x,&vertex[i].y,&vertex[i].z);
468 for(i=0;i<TriangleNum;i++){
469 // funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
471 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
472 Triangles[i].vertex[ 0] = vertex[ 0];
473 Triangles[i].vertex[ 1] = vertex[ 2];
474 Triangles[i].vertex[ 2] = vertex[ 4];
475 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
476 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
483 for(i=0;i<vertexNum;i++){
488 boundingsphereradius=0;
489 for(i=0;i<vertexNum;i++){
490 for(j=0;j<vertexNum;j++){
491 if(j!=i&&findDistancefast(&vertex[j],&vertex[i])/2>boundingsphereradius){
492 boundingsphereradius=findDistancefast(&vertex[j],&vertex[i])/2;
493 boundingspherecenter=(vertex[i]+vertex[j])/2;
497 boundingsphereradius=fast_sqrt(boundingsphereradius);
503 bool Model::load(char *filename,bool texture )
510 LOG(std::string("Loading model...") + filename);
514 pgame->LoadingScreen();
517 int oldvertexNum,oldTriangleNum;
518 oldvertexNum=vertexNum;
519 oldTriangleNum=TriangleNum;
524 tfile=fopen( ConvertFileName(filename), "rb" );
525 // read model settings
528 fseek(tfile, 0, SEEK_SET);
529 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
531 // read the model data
532 /*if(owner)dealloc(owner);
533 if(possible)dealloc(possible);
534 if(vertex)dealloc(vertex);
535 if(normals)dealloc(normals);
536 if(facenormals)dealloc(facenormals);
537 if(Triangles)dealloc(Triangles);
538 if(vArray)dealloc(vArray);*/
543 owner = (int*)malloc(sizeof(int)*vertexNum);
544 possible = (int*)malloc(sizeof(int)*TriangleNum);
545 vertex = (XYZ*)malloc(sizeof(XYZ)*vertexNum);
546 normals = (XYZ*)malloc(sizeof(XYZ)*vertexNum);
547 facenormals = (XYZ*)malloc(sizeof(XYZ)*TriangleNum);
548 Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle)*TriangleNum);
549 vArray = (GLfloat*)malloc(sizeof(GLfloat)*TriangleNum*24);
551 for(i=0;i<vertexNum;i++){
552 funpackf(tfile, "Bf Bf Bf", &vertex[i].x,&vertex[i].y,&vertex[i].z);
555 for(i=0;i<TriangleNum;i++){
556 // funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
558 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
559 Triangles[i].vertex[ 0] = vertex[ 0];
560 Triangles[i].vertex[ 1] = vertex[ 2];
561 Triangles[i].vertex[ 2] = vertex[ 4];
562 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
563 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
572 for(i=0;i<vertexNum;i++){
577 boundingsphereradius=0;
578 for(i=0;i<vertexNum;i++){
579 for(j=0;j<vertexNum;j++){
580 if(j!=i&&findDistancefast(&vertex[j],&vertex[i])/2>boundingsphereradius){
581 boundingsphereradius=findDistancefast(&vertex[j],&vertex[i])/2;
582 boundingspherecenter=(vertex[i]+vertex[j])/2;
586 boundingsphereradius=fast_sqrt(boundingsphereradius);
591 bool Model::loaddecal(char *filename,bool texture )
598 LOG(std::string("Loading decal...") + filename);
600 int oldvertexNum,oldTriangleNum;
601 oldvertexNum=vertexNum;
602 oldTriangleNum=TriangleNum;
608 tfile=fopen( filename, "rb" );
609 // read model settings
612 fseek(tfile, 0, SEEK_SET);
613 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
615 // read the model data
617 /*if(owner)dealloc(owner);
618 if(possible)dealloc(possible);
619 if(vertex)dealloc(vertex);
620 if(normals)dealloc(normals);
621 if(facenormals)dealloc(facenormals);
622 if(Triangles)dealloc(Triangles);
623 if(vArray)dealloc(vArray);*/
628 owner = (int*)malloc(sizeof(int)*vertexNum);
629 possible = (int*)malloc(sizeof(int)*TriangleNum);
630 vertex = (XYZ*)malloc(sizeof(XYZ)*vertexNum);
631 normals = (XYZ*)malloc(sizeof(XYZ)*vertexNum);
632 facenormals = (XYZ*)malloc(sizeof(XYZ)*TriangleNum);
633 Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle)*TriangleNum);
634 vArray = (GLfloat*)malloc(sizeof(GLfloat)*TriangleNum*24);
637 for(i=0;i<vertexNum;i++){
638 funpackf(tfile, "Bf Bf Bf", &vertex[i].x,&vertex[i].y,&vertex[i].z);
641 for(i=0;i<TriangleNum;i++){
642 // funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
644 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
645 Triangles[i].vertex[ 0] = vertex[ 0];
646 Triangles[i].vertex[ 1] = vertex[ 2];
647 Triangles[i].vertex[ 2] = vertex[ 4];
648 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
649 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
659 for(i=0;i<vertexNum;i++){
663 boundingsphereradius=0;
664 for(i=0;i<vertexNum;i++){
665 for(j=0;j<vertexNum;j++){
666 if(j!=i&&findDistancefast(&vertex[j],&vertex[i])/2>boundingsphereradius){
667 boundingsphereradius=findDistancefast(&vertex[j],&vertex[i])/2;
668 boundingspherecenter=(vertex[i]+vertex[j])/2;
672 boundingsphereradius=fast_sqrt(boundingsphereradius);
676 decaltexcoords = (float***)malloc(sizeof(float**)*max_model_decals);
677 for(i=0;i<max_model_decals;i++){
678 decaltexcoords[i] = (float**)malloc(sizeof(float*)*3);
680 decaltexcoords[i][j] = (float*)malloc(sizeof(float)*2);
683 //if(decalvertex)free(decalvertex);
684 decalvertex = (XYZ**)malloc(sizeof(XYZ*)*max_model_decals);
685 for(i=0;i<max_model_decals;i++){
686 decalvertex[i] = (XYZ*)malloc(sizeof(XYZ)*3);
689 decaltype = (int*)malloc(sizeof(int)*max_model_decals);
690 decalopacity = (float*)malloc(sizeof(float)*max_model_decals);
691 decalrotation = (float*)malloc(sizeof(float)*max_model_decals);
692 decalalivetime = (float*)malloc(sizeof(float)*max_model_decals);
693 decalposition = (XYZ*)malloc(sizeof(XYZ)*max_model_decals);
699 bool Model::loadraw(char *filename )
706 LOG(std::string("Loading raw...") + filename);
708 int oldvertexNum,oldTriangleNum;
709 oldvertexNum=vertexNum;
710 oldTriangleNum=TriangleNum;
715 tfile=fopen( filename, "rb" );
716 // read model settings
719 fseek(tfile, 0, SEEK_SET);
720 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
722 // read the model data
723 /*if(owner)dealloc(owner);
724 if(possible)dealloc(possible);
725 if(vertex)dealloc(vertex);
726 if(normals)dealloc(normals);
727 if(facenormals)dealloc(facenormals);
728 if(Triangles)dealloc(Triangles);
729 if(vArray)dealloc(vArray);*/
734 owner = (int*)malloc(sizeof(int)*vertexNum);
735 possible = (int*)malloc(sizeof(int)*TriangleNum);
736 vertex = (XYZ*)malloc(sizeof(XYZ)*vertexNum);
737 Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle)*TriangleNum);
738 vArray = (GLfloat*)malloc(sizeof(GLfloat)*TriangleNum*24);
741 for(i=0;i<vertexNum;i++){
742 funpackf(tfile, "Bf Bf Bf", &vertex[i].x,&vertex[i].y,&vertex[i].z);
745 for(i=0;i<TriangleNum;i++){
746 // funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
748 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
749 Triangles[i].vertex[ 0] = vertex[ 0];
750 Triangles[i].vertex[ 1] = vertex[ 2];
751 Triangles[i].vertex[ 2] = vertex[ 4];
752 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
753 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
759 for(i=0;i<vertexNum;i++){
767 void Model::UniformTexCoords()
770 for(i=0; i<TriangleNum; i++){
771 Triangles[i].gy[0]=vertex[Triangles[i].vertex[0]].y;
772 Triangles[i].gy[1]=vertex[Triangles[i].vertex[1]].y;
773 Triangles[i].gy[2]=vertex[Triangles[i].vertex[2]].y;
774 Triangles[i].gx[0]=vertex[Triangles[i].vertex[0]].x;
775 Triangles[i].gx[1]=vertex[Triangles[i].vertex[1]].x;
776 Triangles[i].gx[2]=vertex[Triangles[i].vertex[2]].x;
782 void Model::FlipTexCoords()
785 for(i=0; i<TriangleNum; i++){
786 Triangles[i].gy[0]=-Triangles[i].gy[0];
787 Triangles[i].gy[1]=-Triangles[i].gy[1];
788 Triangles[i].gy[2]=-Triangles[i].gy[2];
793 void Model::ScaleTexCoords(float howmuch)
796 for(i=0; i<TriangleNum; i++){
797 Triangles[i].gx[0]*=howmuch;
798 Triangles[i].gx[1]*=howmuch;
799 Triangles[i].gx[2]*=howmuch;
800 Triangles[i].gy[0]*=howmuch;
801 Triangles[i].gy[1]*=howmuch;
802 Triangles[i].gy[2]*=howmuch;
807 void Model::Scale(float xscale,float yscale,float zscale)
810 for(i=0; i<vertexNum; i++){
819 boundingsphereradius=0;
820 for(i=0;i<vertexNum;i++){
821 for(j=0;j<vertexNum;j++){
822 if(j!=i&&findDistancefast(&vertex[j],&vertex[i])/2>boundingsphereradius){
823 boundingsphereradius=findDistancefast(&vertex[j],&vertex[i])/2;
824 boundingspherecenter=(vertex[i]+vertex[j])/2;
828 boundingsphereradius=fast_sqrt(boundingsphereradius);
831 void Model::ScaleNormals(float xscale,float yscale,float zscale)
833 if(type!=normaltype&&type!=decalstype)return;
835 for(i=0; i<vertexNum; i++){
836 normals[i].x*=xscale;
837 normals[i].y*=yscale;
838 normals[i].z*=zscale;
840 for(i=0; i<TriangleNum; i++){
841 facenormals[i].x*=xscale;
842 facenormals[i].y*=yscale;
843 facenormals[i].z*=zscale;
848 void Model::Translate(float xtrans,float ytrans,float ztrans)
851 for(i=0; i<vertexNum; i++){
859 boundingsphereradius=0;
860 for(i=0;i<vertexNum;i++){
861 for(j=0;j<vertexNum;j++){
862 if(j!=i&&findDistancefast(&vertex[j],&vertex[i])/2>boundingsphereradius){
863 boundingsphereradius=findDistancefast(&vertex[j],&vertex[i])/2;
864 boundingspherecenter=(vertex[i]+vertex[j])/2;
868 boundingsphereradius=fast_sqrt(boundingsphereradius);
871 void Model::Rotate(float xang,float yang,float zang)
874 for(i=0; i<vertexNum; i++){
875 vertex[i]=DoRotation(vertex[i],xang,yang,zang);
880 boundingsphereradius=0;
881 for(i=0;i<vertexNum;i++){
882 for(j=0;j<vertexNum;j++){
883 if(j!=i&&findDistancefast(&vertex[j],&vertex[i])/2>boundingsphereradius){
884 boundingsphereradius=findDistancefast(&vertex[j],&vertex[i])/2;
885 boundingspherecenter=(vertex[i]+vertex[j])/2;
889 boundingsphereradius=fast_sqrt(boundingsphereradius);
893 void Model::CalculateNormals(bool facenormalise)
897 pgame->LoadingScreen();
900 if(type!=normaltype&&type!=decalstype)return;
902 for(i=0; i<vertexNum; i++){
908 for(i=0;i<TriangleNum;i++){
909 CrossProduct(vertex[Triangles[i].vertex[1]]-vertex[Triangles[i].vertex[0]],vertex[Triangles[i].vertex[2]]-vertex[Triangles[i].vertex[0]],&facenormals[i]);
911 normals[Triangles[i].vertex[0]].x+=facenormals[i].x;
912 normals[Triangles[i].vertex[0]].y+=facenormals[i].y;
913 normals[Triangles[i].vertex[0]].z+=facenormals[i].z;
915 normals[Triangles[i].vertex[1]].x+=facenormals[i].x;
916 normals[Triangles[i].vertex[1]].y+=facenormals[i].y;
917 normals[Triangles[i].vertex[1]].z+=facenormals[i].z;
919 normals[Triangles[i].vertex[2]].x+=facenormals[i].x;
920 normals[Triangles[i].vertex[2]].y+=facenormals[i].y;
921 normals[Triangles[i].vertex[2]].z+=facenormals[i].z;
922 if(facenormalise)Normalise(&facenormals[i]);
924 for(i=0; i<vertexNum; i++){
925 Normalise(&normals[i]);
928 UpdateVertexArrayNoTex();
931 void Model::drawimmediate()
933 glBindTexture(GL_TEXTURE_2D,(unsigned long)textureptr);
934 glBegin(GL_TRIANGLES);
935 for(int i=0;i<TriangleNum;i++){
936 /*if(Triangles[i].vertex[0]<vertexNum&&Triangles[i].vertex[1]<vertexNum&&Triangles[i].vertex[2]<vertexNum&&Triangles[i].vertex[0]>=0&&Triangles[i].vertex[1]>=0&&Triangles[i].vertex[2]>=0){
937 if(isnormal(vertex[Triangles[i].vertex[0]].x)&&isnormal(vertex[Triangles[i].vertex[0]].y)&&isnormal(vertex[Triangles[i].vertex[0]].z)
938 &&isnormal(vertex[Triangles[i].vertex[1]].x)&&isnormal(vertex[Triangles[i].vertex[1]].y)&&isnormal(vertex[Triangles[i].vertex[1]].z)
939 &&isnormal(vertex[Triangles[i].vertex[2]].x)&&isnormal(vertex[Triangles[i].vertex[2]].y)&&isnormal(vertex[Triangles[i].vertex[2]].z)){
941 glTexCoord2f(Triangles[i].gx[0],Triangles[i].gy[0]);
942 if(color)glColor3f(normals[Triangles[i].vertex[0]].x,normals[Triangles[i].vertex[0]].y,normals[Triangles[i].vertex[0]].z);
943 if(!color&&!flat)glNormal3f(normals[Triangles[i].vertex[0]].x,normals[Triangles[i].vertex[0]].y,normals[Triangles[i].vertex[0]].z);
944 if(!color&&flat)glNormal3f(facenormals[i].x,facenormals[i].y,facenormals[i].y);
945 glVertex3f(vertex[Triangles[i].vertex[0]].x,vertex[Triangles[i].vertex[0]].y,vertex[Triangles[i].vertex[0]].z);
947 glTexCoord2f(Triangles[i].gx[1],Triangles[i].gy[1]);
948 if(color)glColor3f(normals[Triangles[i].vertex[1]].x,normals[Triangles[i].vertex[1]].y,normals[Triangles[i].vertex[1]].z);
949 if(!color&&!flat)glNormal3f(normals[Triangles[i].vertex[1]].x,normals[Triangles[i].vertex[1]].y,normals[Triangles[i].vertex[1]].z);
950 if(!color&&flat)glNormal3f(facenormals[i].x,facenormals[i].y,facenormals[i].y);
951 glVertex3f(vertex[Triangles[i].vertex[1]].x,vertex[Triangles[i].vertex[1]].y,vertex[Triangles[i].vertex[1]].z);
953 glTexCoord2f(Triangles[i].gx[2],Triangles[i].gy[2]);
954 if(color)glColor3f(normals[Triangles[i].vertex[2]].x,normals[Triangles[i].vertex[2]].y,normals[Triangles[i].vertex[2]].z);
955 if(!color&&!flat)glNormal3f(normals[Triangles[i].vertex[2]].x,normals[Triangles[i].vertex[2]].y,normals[Triangles[i].vertex[2]].z);
956 if(!color&&flat)glNormal3f(facenormals[i].x,facenormals[i].y,facenormals[i].y);
957 glVertex3f(vertex[Triangles[i].vertex[2]].x,vertex[Triangles[i].vertex[2]].y,vertex[Triangles[i].vertex[2]].z);
966 if(type!=normaltype&&type!=decalstype)return;
968 glEnableClientState(GL_NORMAL_ARRAY);
969 glEnableClientState(GL_VERTEX_ARRAY);
970 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
972 if(!color)glInterleavedArrays( GL_T2F_N3F_V3F,8*sizeof(GLfloat),&vArray[0]);
973 if(color)glInterleavedArrays( GL_T2F_C3F_V3F,8*sizeof(GLfloat),&vArray[0]);
974 glBindTexture(GL_TEXTURE_2D,(unsigned long)textureptr);
977 glLockArraysEXT( 0, TriangleNum*3);
979 glDrawArrays(GL_TRIANGLES, 0, TriangleNum*3);
985 if(!color)glDisableClientState(GL_NORMAL_ARRAY);
986 if(color)glDisableClientState(GL_COLOR_ARRAY);
987 glDisableClientState(GL_VERTEX_ARRAY);
988 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
992 void Model::drawdifftex(GLuint texture)
994 glEnableClientState(GL_NORMAL_ARRAY);
995 glEnableClientState(GL_VERTEX_ARRAY);
996 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
997 if(!color)glInterleavedArrays( GL_T2F_N3F_V3F,8*sizeof(GLfloat),&vArray[0]);
998 if(color)glInterleavedArrays( GL_T2F_C3F_V3F,8*sizeof(GLfloat),&vArray[0]);
1000 glBindTexture(GL_TEXTURE_2D,(unsigned long)texture);
1001 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
1002 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
1006 glLockArraysEXT( 0, TriangleNum*3);
1008 glDrawArrays(GL_TRIANGLES, 0, TriangleNum*3);
1010 glUnlockArraysEXT();
1014 if(!color)glDisableClientState(GL_NORMAL_ARRAY);
1015 if(color)glDisableClientState(GL_COLOR_ARRAY);
1016 glDisableClientState(GL_VERTEX_ARRAY);
1017 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1018 //drawdiffteximmediate(texture);
1021 void Model::drawdiffteximmediate(GLuint texture)
1023 glBindTexture(GL_TEXTURE_2D,(unsigned long)texture);
1025 glBegin(GL_TRIANGLES);
1026 for(int i=0;i<TriangleNum;i++){
1027 /*if(Triangles[i].vertex[0]<vertexNum&&Triangles[i].vertex[1]<vertexNum&&Triangles[i].vertex[2]<vertexNum&&Triangles[i].vertex[0]>=0&&Triangles[i].vertex[1]>=0&&Triangles[i].vertex[2]>=0){
1028 if(isnormal(vertex[Triangles[i].vertex[0]].x)&&isnormal(vertex[Triangles[i].vertex[0]].y)&&isnormal(vertex[Triangles[i].vertex[0]].z)
1029 &&isnormal(vertex[Triangles[i].vertex[1]].x)&&isnormal(vertex[Triangles[i].vertex[1]].y)&&isnormal(vertex[Triangles[i].vertex[1]].z)
1030 &&isnormal(vertex[Triangles[i].vertex[2]].x)&&isnormal(vertex[Triangles[i].vertex[2]].y)&&isnormal(vertex[Triangles[i].vertex[2]].z)){
1031 */glTexCoord2f(Triangles[i].gx[0],Triangles[i].gy[0]);
1032 if(color)glColor3f(normals[Triangles[i].vertex[0]].x,normals[Triangles[i].vertex[0]].y,normals[Triangles[i].vertex[0]].z);
1033 if(!color&&!flat)glNormal3f(normals[Triangles[i].vertex[0]].x,normals[Triangles[i].vertex[0]].y,normals[Triangles[i].vertex[0]].z);
1034 if(!color&&flat)glNormal3f(facenormals[i].x,facenormals[i].y,facenormals[i].y);
1035 glVertex3f(vertex[Triangles[i].vertex[0]].x,vertex[Triangles[i].vertex[0]].y,vertex[Triangles[i].vertex[0]].z);
1037 glTexCoord2f(Triangles[i].gx[1],Triangles[i].gy[1]);
1038 if(color)glColor3f(normals[Triangles[i].vertex[1]].x,normals[Triangles[i].vertex[1]].y,normals[Triangles[i].vertex[1]].z);
1039 if(!color&&!flat)glNormal3f(normals[Triangles[i].vertex[1]].x,normals[Triangles[i].vertex[1]].y,normals[Triangles[i].vertex[1]].z);
1040 if(!color&&flat)glNormal3f(facenormals[i].x,facenormals[i].y,facenormals[i].y);
1041 glVertex3f(vertex[Triangles[i].vertex[1]].x,vertex[Triangles[i].vertex[1]].y,vertex[Triangles[i].vertex[1]].z);
1043 glTexCoord2f(Triangles[i].gx[2],Triangles[i].gy[2]);
1044 if(color)glColor3f(normals[Triangles[i].vertex[2]].x,normals[Triangles[i].vertex[2]].y,normals[Triangles[i].vertex[2]].z);
1045 if(!color&&!flat)glNormal3f(normals[Triangles[i].vertex[2]].x,normals[Triangles[i].vertex[2]].y,normals[Triangles[i].vertex[2]].z);
1046 if(!color&&flat)glNormal3f(facenormals[i].x,facenormals[i].y,facenormals[i].y);
1047 glVertex3f(vertex[Triangles[i].vertex[2]].x,vertex[Triangles[i].vertex[2]].y,vertex[Triangles[i].vertex[2]].z);
1054 void Model::drawdecals(GLuint shadowtexture,GLuint bloodtexture,GLuint bloodtexture2,GLuint breaktexture)
1057 if(type!=decalstype)return;
1059 static float distancemult;
1060 static int lasttype;
1061 static float viewdistsquared;
1064 viewdistsquared=viewdistance*viewdistance;
1069 glDisable(GL_LIGHTING);
1070 glDisable(GL_CULL_FACE);
1071 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1073 if(numdecals>max_model_decals)numdecals=max_model_decals;
1074 for(i=0;i<numdecals;i++){
1075 if(decaltype[i]==blooddecalfast&&decalalivetime[i]<2)decalalivetime[i]=2;
1077 if(decaltype[i]==shadowdecal&&decaltype[i]!=lasttype){
1078 glBindTexture( GL_TEXTURE_2D, shadowtexture);
1081 glAlphaFunc(GL_GREATER, 0.0001);
1082 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1085 if(decaltype[i]==breakdecal&&decaltype[i]!=lasttype){
1086 glBindTexture( GL_TEXTURE_2D, breaktexture);
1089 glAlphaFunc(GL_GREATER, 0.0001);
1090 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1093 if((decaltype[i]==blooddecal||decaltype[i]==blooddecalslow)&&decaltype[i]!=lasttype){
1094 glBindTexture( GL_TEXTURE_2D, bloodtexture);
1097 glAlphaFunc(GL_GREATER, 0.15);
1098 glBlendFunc(GL_ONE,GL_ZERO);
1101 if((decaltype[i]==blooddecalfast)&&decaltype[i]!=lasttype){
1102 glBindTexture( GL_TEXTURE_2D, bloodtexture2);
1105 glAlphaFunc(GL_GREATER, 0.15);
1106 glBlendFunc(GL_ONE,GL_ZERO);
1109 if(decaltype[i]==shadowdecal){
1110 glColor4f(1,1,1,decalopacity[i]);
1112 if(decaltype[i]==breakdecal){
1113 glColor4f(1,1,1,decalopacity[i]);
1114 if(decalalivetime[i]>58)glColor4f(1,1,1,decalopacity[i]*(60-decalalivetime[i])/2);
1116 if((decaltype[i]==blooddecal||decaltype[i]==blooddecalfast||decaltype[i]==blooddecalslow)){
1117 glColor4f(1,1,1,decalopacity[i]);
1118 if(decalalivetime[i]<4)glColor4f(1,1,1,decalopacity[i]*decalalivetime[i]*.25);
1119 if(decalalivetime[i]>58)glColor4f(1,1,1,decalopacity[i]*(60-decalalivetime[i])/2);
1121 lasttype=decaltype[i];
1122 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1123 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
1125 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
1127 glBegin(GL_TRIANGLES);
1128 for(int j=0;j<3;j++)
1130 glTexCoord2f(decaltexcoords[i][j][0], decaltexcoords[i][j][1]); glVertex3f(decalvertex[i][j].x,decalvertex[i][j].y,decalvertex[i][j].z);
1135 for(i=numdecals-1;i>=0;i--){
1136 decalalivetime[i]+=multiplier;
1137 if(decaltype[i]==blooddecalslow)decalalivetime[i]-=multiplier*2/3;
1138 if(decaltype[i]==blooddecalfast)decalalivetime[i]+=multiplier*4;
1139 if(decaltype[i]==shadowdecal)DeleteDecal(i);
1140 if((decaltype[i]==blooddecal||decaltype[i]==blooddecalfast||decaltype[i]==blooddecalslow)&&decalalivetime[i]>=60)DeleteDecal(i);
1142 glAlphaFunc(GL_GREATER, 0.0001);
1143 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1147 void Model::DeleteDecal(int which)
1150 if(type!=decalstype)return;
1151 decaltype[which]=decaltype[numdecals-1];
1152 decalposition[which]=decalposition[numdecals-1];
1153 for(int i=0;i<3;i++){
1154 decalvertex[which][i]=decalvertex[numdecals-1][i];
1155 decaltexcoords[which][i][0]=decaltexcoords[numdecals-1][i][0];
1156 decaltexcoords[which][i][1]=decaltexcoords[numdecals-1][i][1];
1158 decalrotation[which]=decalrotation[numdecals-1];
1159 decalalivetime[which]=decalalivetime[numdecals-1];
1160 decalopacity[which]=decalopacity[numdecals-1];
1165 void Model::MakeDecal(int atype, XYZ *where,float *size, float *opacity, float *rotation){
1167 if(type!=decalstype)return;
1169 static float placex,placez;
1171 //static XYZ point,point1,point2;
1172 static float distance;
1176 if(findDistancefast(where,&boundingspherecenter)<(boundingsphereradius+*size)*(boundingsphereradius+*size))
1177 for(i=0;i<TriangleNum;i++){
1178 if(facenormals[i].y<-.1&&(vertex[Triangles[i].vertex[0]].y<where->y||vertex[Triangles[i].vertex[1]].y<where->y||vertex[Triangles[i].vertex[2]].y<where->y)){
1179 decalposition[numdecals]=*where;
1180 decaltype[numdecals]=atype;
1181 decalrotation[numdecals]=*rotation;
1182 decalalivetime[numdecals]=0;
1183 distance=abs(((facenormals[i].x*where->x)+(facenormals[i].y*where->y)+(facenormals[i].z*where->z)-((facenormals[i].x*vertex[Triangles[i].vertex[0]].x)+(facenormals[i].y*vertex[Triangles[i].vertex[0]].y)+(facenormals[i].z*vertex[Triangles[i].vertex[0]].z)))/facenormals[i].y);
1184 decalopacity[numdecals]=*opacity-distance/10;
1186 if(decalopacity[numdecals>0]){
1187 placex=vertex[Triangles[i].vertex[0]].x;
1188 placez=vertex[Triangles[i].vertex[0]].z;
1190 decaltexcoords[numdecals][0][0]=(placex-where->x)/(*size)/2+.5;
1191 decaltexcoords[numdecals][0][1]=(placez-where->z)/(*size)/2+.5;
1193 decalvertex[numdecals][0].x=placex;
1194 decalvertex[numdecals][0].z=placez;
1195 decalvertex[numdecals][0].y=vertex[Triangles[i].vertex[0]].y;
1198 placex=vertex[Triangles[i].vertex[1]].x;
1199 placez=vertex[Triangles[i].vertex[1]].z;
1201 decaltexcoords[numdecals][1][0]=(placex-where->x)/(*size)/2+.5;
1202 decaltexcoords[numdecals][1][1]=(placez-where->z)/(*size)/2+.5;
1204 decalvertex[numdecals][1].x=placex;
1205 decalvertex[numdecals][1].z=placez;
1206 decalvertex[numdecals][1].y=vertex[Triangles[i].vertex[1]].y;
1209 placex=vertex[Triangles[i].vertex[2]].x;
1210 placez=vertex[Triangles[i].vertex[2]].z;
1212 decaltexcoords[numdecals][2][0]=(placex-where->x)/(*size)/2+.5;
1213 decaltexcoords[numdecals][2][1]=(placez-where->z)/(*size)/2+.5;
1215 decalvertex[numdecals][2].x=placex;
1216 decalvertex[numdecals][2].z=placez;
1217 decalvertex[numdecals][2].y=vertex[Triangles[i].vertex[2]].y;
1219 if(!(decaltexcoords[numdecals][0][0]<0&&decaltexcoords[numdecals][1][0]<0&&decaltexcoords[numdecals][2][0]<0))
1220 if(!(decaltexcoords[numdecals][0][1]<0&&decaltexcoords[numdecals][1][1]<0&&decaltexcoords[numdecals][2][1]<0))
1221 if(!(decaltexcoords[numdecals][0][0]>1&&decaltexcoords[numdecals][1][0]>1&&decaltexcoords[numdecals][2][0]>1))
1222 if(!(decaltexcoords[numdecals][0][1]>1&&decaltexcoords[numdecals][1][1]>1&&decaltexcoords[numdecals][2][1]>1))
1224 if(decalrotation[numdecals]){
1227 rot.x=decaltexcoords[numdecals][j][0]-.5;
1228 rot.z=decaltexcoords[numdecals][j][1]-.5;
1229 rot=DoRotation(rot,0,-decalrotation[numdecals],0);
1230 decaltexcoords[numdecals][j][0]=rot.x+.5;
1231 decaltexcoords[numdecals][j][1]=rot.z+.5;
1234 if(numdecals<max_model_decals-1)numdecals++;
1242 void Model::MakeDecal(int atype, XYZ where,float size, float opacity, float rotation){
1244 if(type!=decalstype)return;
1246 static float placex,placez;
1248 //static XYZ point,point1,point2;
1249 static float distance;
1253 if(findDistancefast(&where,&boundingspherecenter)<(boundingsphereradius+size)*(boundingsphereradius+size))
1254 for(i=0;i<TriangleNum;i++){
1255 distance=abs(((facenormals[i].x*where.x)+(facenormals[i].y*where.y)+(facenormals[i].z*where.z)-((facenormals[i].x*vertex[Triangles[i].vertex[0]].x)+(facenormals[i].y*vertex[Triangles[i].vertex[0]].y)+(facenormals[i].z*vertex[Triangles[i].vertex[0]].z))));
1256 if(distance<.02&&abs(facenormals[i].y)>abs(facenormals[i].x)&&abs(facenormals[i].y)>abs(facenormals[i].z)){
1257 decalposition[numdecals]=where;
1258 decaltype[numdecals]=atype;
1259 decalrotation[numdecals]=rotation;
1260 decalalivetime[numdecals]=0;
1261 decalopacity[numdecals]=opacity-distance/10;
1263 if(decalopacity[numdecals>0]){
1264 placex=vertex[Triangles[i].vertex[0]].x;
1265 placez=vertex[Triangles[i].vertex[0]].z;
1267 decaltexcoords[numdecals][0][0]=(placex-where.x)/(size)/2+.5;
1268 decaltexcoords[numdecals][0][1]=(placez-where.z)/(size)/2+.5;
1270 decalvertex[numdecals][0].x=placex;
1271 decalvertex[numdecals][0].z=placez;
1272 decalvertex[numdecals][0].y=vertex[Triangles[i].vertex[0]].y;
1275 placex=vertex[Triangles[i].vertex[1]].x;
1276 placez=vertex[Triangles[i].vertex[1]].z;
1278 decaltexcoords[numdecals][1][0]=(placex-where.x)/(size)/2+.5;
1279 decaltexcoords[numdecals][1][1]=(placez-where.z)/(size)/2+.5;
1281 decalvertex[numdecals][1].x=placex;
1282 decalvertex[numdecals][1].z=placez;
1283 decalvertex[numdecals][1].y=vertex[Triangles[i].vertex[1]].y;
1286 placex=vertex[Triangles[i].vertex[2]].x;
1287 placez=vertex[Triangles[i].vertex[2]].z;
1289 decaltexcoords[numdecals][2][0]=(placex-where.x)/(size)/2+.5;
1290 decaltexcoords[numdecals][2][1]=(placez-where.z)/(size)/2+.5;
1292 decalvertex[numdecals][2].x=placex;
1293 decalvertex[numdecals][2].z=placez;
1294 decalvertex[numdecals][2].y=vertex[Triangles[i].vertex[2]].y;
1296 if(!(decaltexcoords[numdecals][0][0]<0&&decaltexcoords[numdecals][1][0]<0&&decaltexcoords[numdecals][2][0]<0))
1297 if(!(decaltexcoords[numdecals][0][1]<0&&decaltexcoords[numdecals][1][1]<0&&decaltexcoords[numdecals][2][1]<0))
1298 if(!(decaltexcoords[numdecals][0][0]>1&&decaltexcoords[numdecals][1][0]>1&&decaltexcoords[numdecals][2][0]>1))
1299 if(!(decaltexcoords[numdecals][0][1]>1&&decaltexcoords[numdecals][1][1]>1&&decaltexcoords[numdecals][2][1]>1))
1301 if(decalrotation[numdecals]){
1304 rot.x=decaltexcoords[numdecals][j][0]-.5;
1305 rot.z=decaltexcoords[numdecals][j][1]-.5;
1306 rot=DoRotation(rot,0,-decalrotation[numdecals],0);
1307 decaltexcoords[numdecals][j][0]=rot.x+.5;
1308 decaltexcoords[numdecals][j][1]=rot.z+.5;
1311 if(numdecals<max_model_decals-1)numdecals++;
1315 else if(distance<.02&&abs(facenormals[i].x)>abs(facenormals[i].y)&&abs(facenormals[i].x)>abs(facenormals[i].z)){
1316 decalposition[numdecals]=where;
1317 decaltype[numdecals]=atype;
1318 decalrotation[numdecals]=rotation;
1319 decalalivetime[numdecals]=0;
1320 decalopacity[numdecals]=opacity-distance/10;
1322 if(decalopacity[numdecals>0]){
1323 placex=vertex[Triangles[i].vertex[0]].y;
1324 placez=vertex[Triangles[i].vertex[0]].z;
1326 decaltexcoords[numdecals][0][0]=(placex-where.y)/(size)/2+.5;
1327 decaltexcoords[numdecals][0][1]=(placez-where.z)/(size)/2+.5;
1329 decalvertex[numdecals][0].x=vertex[Triangles[i].vertex[0]].x;
1330 decalvertex[numdecals][0].z=placez;
1331 decalvertex[numdecals][0].y=placex;
1334 placex=vertex[Triangles[i].vertex[1]].y;
1335 placez=vertex[Triangles[i].vertex[1]].z;
1337 decaltexcoords[numdecals][1][0]=(placex-where.y)/(size)/2+.5;
1338 decaltexcoords[numdecals][1][1]=(placez-where.z)/(size)/2+.5;
1340 decalvertex[numdecals][1].x=vertex[Triangles[i].vertex[1]].x;
1341 decalvertex[numdecals][1].z=placez;
1342 decalvertex[numdecals][1].y=placex;
1345 placex=vertex[Triangles[i].vertex[2]].y;
1346 placez=vertex[Triangles[i].vertex[2]].z;
1348 decaltexcoords[numdecals][2][0]=(placex-where.y)/(size)/2+.5;
1349 decaltexcoords[numdecals][2][1]=(placez-where.z)/(size)/2+.5;
1351 decalvertex[numdecals][2].x=vertex[Triangles[i].vertex[2]].x;
1352 decalvertex[numdecals][2].z=placez;
1353 decalvertex[numdecals][2].y=placex;
1355 if(!(decaltexcoords[numdecals][0][0]<0&&decaltexcoords[numdecals][1][0]<0&&decaltexcoords[numdecals][2][0]<0))
1356 if(!(decaltexcoords[numdecals][0][1]<0&&decaltexcoords[numdecals][1][1]<0&&decaltexcoords[numdecals][2][1]<0))
1357 if(!(decaltexcoords[numdecals][0][0]>1&&decaltexcoords[numdecals][1][0]>1&&decaltexcoords[numdecals][2][0]>1))
1358 if(!(decaltexcoords[numdecals][0][1]>1&&decaltexcoords[numdecals][1][1]>1&&decaltexcoords[numdecals][2][1]>1))
1360 if(decalrotation[numdecals]){
1363 rot.x=decaltexcoords[numdecals][j][0]-.5;
1364 rot.z=decaltexcoords[numdecals][j][1]-.5;
1365 rot=DoRotation(rot,0,-decalrotation[numdecals],0);
1366 decaltexcoords[numdecals][j][0]=rot.x+.5;
1367 decaltexcoords[numdecals][j][1]=rot.z+.5;
1370 if(numdecals<max_model_decals-1)numdecals++;
1374 else if(distance<.02&&abs(facenormals[i].z)>abs(facenormals[i].y)&&abs(facenormals[i].z)>abs(facenormals[i].x)){
1375 decalposition[numdecals]=where;
1376 decaltype[numdecals]=atype;
1377 decalrotation[numdecals]=rotation;
1378 decalalivetime[numdecals]=0;
1379 decalopacity[numdecals]=opacity-distance/10;
1381 if(decalopacity[numdecals>0]){
1382 placex=vertex[Triangles[i].vertex[0]].x;
1383 placez=vertex[Triangles[i].vertex[0]].y;
1385 decaltexcoords[numdecals][0][0]=(placex-where.x)/(size)/2+.5;
1386 decaltexcoords[numdecals][0][1]=(placez-where.y)/(size)/2+.5;
1388 decalvertex[numdecals][0].x=placex;
1389 decalvertex[numdecals][0].z=vertex[Triangles[i].vertex[0]].z;
1390 decalvertex[numdecals][0].y=placez;
1393 placex=vertex[Triangles[i].vertex[1]].x;
1394 placez=vertex[Triangles[i].vertex[1]].y;
1396 decaltexcoords[numdecals][1][0]=(placex-where.x)/(size)/2+.5;
1397 decaltexcoords[numdecals][1][1]=(placez-where.y)/(size)/2+.5;
1399 decalvertex[numdecals][1].x=placex;
1400 decalvertex[numdecals][1].z=vertex[Triangles[i].vertex[1]].z;
1401 decalvertex[numdecals][1].y=placez;
1404 placex=vertex[Triangles[i].vertex[2]].x;
1405 placez=vertex[Triangles[i].vertex[2]].y;
1407 decaltexcoords[numdecals][2][0]=(placex-where.x)/(size)/2+.5;
1408 decaltexcoords[numdecals][2][1]=(placez-where.y)/(size)/2+.5;
1410 decalvertex[numdecals][2].x=placex;
1411 decalvertex[numdecals][2].z=vertex[Triangles[i].vertex[2]].z;
1412 decalvertex[numdecals][2].y=placez;
1414 if(!(decaltexcoords[numdecals][0][0]<0&&decaltexcoords[numdecals][1][0]<0&&decaltexcoords[numdecals][2][0]<0))
1415 if(!(decaltexcoords[numdecals][0][1]<0&&decaltexcoords[numdecals][1][1]<0&&decaltexcoords[numdecals][2][1]<0))
1416 if(!(decaltexcoords[numdecals][0][0]>1&&decaltexcoords[numdecals][1][0]>1&&decaltexcoords[numdecals][2][0]>1))
1417 if(!(decaltexcoords[numdecals][0][1]>1&&decaltexcoords[numdecals][1][1]>1&&decaltexcoords[numdecals][2][1]>1))
1419 if(decalrotation[numdecals]){
1422 rot.x=decaltexcoords[numdecals][j][0]-.5;
1423 rot.z=decaltexcoords[numdecals][j][1]-.5;
1424 rot=DoRotation(rot,0,-decalrotation[numdecals],0);
1425 decaltexcoords[numdecals][j][0]=rot.x+.5;
1426 decaltexcoords[numdecals][j][1]=rot.z+.5;
1429 if(numdecals<max_model_decals-1)numdecals++;
1441 if(textureptr) glDeleteTextures( 1, &textureptr );
1444 void Model::deallocate()
1448 if(owner)dealloc(owner);
1451 if(possible)dealloc(possible);
1454 if(vertex)dealloc(vertex);
1457 if(normals)dealloc(normals);
1460 if(facenormals)dealloc(facenormals);
1463 if(Triangles)dealloc(Triangles);
1466 if(vArray)dealloc(vArray);
1473 for(i=0;i<max_model_decals;i++)
1477 dealloc(decaltexcoords[i][j]);
1479 dealloc(decaltexcoords[i]);
1481 dealloc(decaltexcoords);
1488 for(i=0;i<max_model_decals;i++)
1490 dealloc(decalvertex[i]);
1492 dealloc(decalvertex);
1500 dealloc(decalopacity);
1503 dealloc(decalrotation);
1506 dealloc(decalalivetime);
1509 dealloc(decalposition);
1516 vertexNum = 0,TriangleNum = 0;
1519 type = 0,oldtype = 0;
1530 memset(&Texture, 0, sizeof(Texture));
1534 boundingspherecenter = 0;
1535 boundingsphereradius = 0;