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.
25 extern float multiplier;
26 extern float viewdistance;
28 extern float fadestart;
29 extern float texdetail;
31 extern int loadscreencolor;
34 extern bool visibleloading;
36 int Model::LineCheck(XYZ *p1,XYZ *p2, XYZ *p, XYZ *move, float *rotate)
39 static float distance;
40 static float olddistance;
41 static int intersecting;
42 static int firstintersecting;
47 if(*rotate)*p1=DoRotation(*p1,0,-*rotate,0);
48 if(*rotate)*p2=DoRotation(*p2,0,-*rotate,0);
49 if(!sphere_line_intersection(p1,p2,&boundingspherecenter,
50 &boundingsphereradius))return -1;
53 for (j=0;j<TriangleNum;j++){
54 intersecting=LineFacetd(p1,p2,&vertex[Triangles[j].vertex[0]],&vertex[Triangles[j].vertex[1]],&vertex[Triangles[j].vertex[2]],&facenormals[j],&point);
55 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);
56 if((distance<olddistance||firstintersecting==-1)&&intersecting){olddistance=distance; firstintersecting=j; *p=point;}
59 if(*rotate)*p=DoRotation(*p,0,*rotate,0);
61 return firstintersecting;
64 int Model::LineCheckSlide(XYZ *p1,XYZ *p2, XYZ *p, XYZ *move, float *rotate)
67 static float distance;
68 static float olddistance;
69 static int intersecting;
70 static int firstintersecting;
75 if(!sphere_line_intersection(p1,p2,&boundingspherecenter,
76 &boundingsphereradius))return -1;
78 if(*rotate)*p1=DoRotation(*p1,0,-*rotate,0);
79 if(*rotate)*p2=DoRotation(*p2,0,-*rotate,0);
81 for (j=0;j<TriangleNum;j++){
82 intersecting=LineFacetd(p1,p2,&vertex[Triangles[j].vertex[0]],&vertex[Triangles[j].vertex[1]],&vertex[Triangles[j].vertex[2]],&facenormals[j],&point);
83 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);
84 if((distance<olddistance||firstintersecting==-1)&&intersecting){olddistance=distance; firstintersecting=j;}
87 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)));
88 *p2-=facenormals[firstintersecting]*distance;
90 if(*rotate)*p2=DoRotation(*p2,0,*rotate,0);
92 return firstintersecting;
95 int Model::LineCheckPossible(XYZ *p1,XYZ *p2, XYZ *p, XYZ *move, float *rotate)
98 static float distance;
99 static float olddistance;
100 static int intersecting;
101 static int firstintersecting;
106 if(!sphere_line_intersection(p1,p2,&boundingspherecenter,
107 &boundingsphereradius))return -1;
108 firstintersecting=-1;
109 if(*rotate)*p1=DoRotation(*p1,0,-*rotate,0);
110 if(*rotate)*p2=DoRotation(*p2,0,-*rotate,0);
112 if(numpossible>0&&numpossible<TriangleNum)
113 for (j=0;j<numpossible;j++){
114 if(possible[j]>=0&&possible[j]<TriangleNum){
115 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);
116 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);
117 if((distance<olddistance||firstintersecting==-1)&&intersecting){olddistance=distance; firstintersecting=possible[j]; *p=point;}
121 if(*rotate)*p=DoRotation(*p,0,*rotate,0);
123 return firstintersecting;
126 int Model::LineCheckSlidePossible(XYZ *p1,XYZ *p2, XYZ *p, XYZ *move, float *rotate)
129 static float distance;
130 static float olddistance;
131 static int intersecting;
132 static int firstintersecting;
137 if(!sphere_line_intersection(p1,p2,&boundingspherecenter,
138 &boundingsphereradius))return -1;
139 firstintersecting=-1;
140 if(*rotate)*p1=DoRotation(*p1,0,-*rotate,0);
141 if(*rotate)*p2=DoRotation(*p2,0,-*rotate,0);
144 for (j=0;j<numpossible;j++){
145 if(possible[j]>=0&&possible[j]<TriangleNum){
146 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);
147 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);
148 if((distance<olddistance||firstintersecting==-1)&&intersecting){olddistance=distance; firstintersecting=possible[j];}
152 if(firstintersecting>0){
153 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)));
154 *p2-=facenormals[firstintersecting]*distance;
157 if(*rotate)*p2=DoRotation(*p2,0,*rotate,0);
159 return firstintersecting;
162 int Model::SphereCheck(XYZ *p1,float radius, XYZ *p, XYZ *move, float *rotate)
165 static float distance;
166 static float olddistance;
167 static int intersecting;
168 static int firstintersecting;
171 static XYZ start,end;
173 firstintersecting=-1;
177 if(*rotate)*p1=DoRotation(*p1,0,-*rotate,0);
178 if(findDistancefast(p1,&boundingspherecenter)>radius*radius+boundingsphereradius*boundingsphereradius)return -1;
181 for (j=0;j<TriangleNum;j++){
183 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)));
185 point=*p1-facenormals[j]*distance;
186 if(PointInTriangle( &point, facenormals[j], &vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[1]], &vertex[Triangles[j].vertex[2]]))intersecting=1;
187 if(!intersecting)intersecting=sphere_line_intersection(&vertex[Triangles[j].vertex[0]],
188 &vertex[Triangles[j].vertex[1]],
190 if(!intersecting)intersecting=sphere_line_intersection(&vertex[Triangles[j].vertex[1]],
191 &vertex[Triangles[j].vertex[2]],
193 if(!intersecting)intersecting=sphere_line_intersection(&vertex[Triangles[j].vertex[0]],
194 &vertex[Triangles[j].vertex[2]],
197 *p1+=facenormals[j]*(distance-radius);
201 if(LineFacetd(&start,&end,&vertex[Triangles[j].vertex[0]],&vertex[Triangles[j].vertex[1]],&vertex[Triangles[j].vertex[2]],&facenormals[j],&point)){
202 p1->y=point.y+radius;
206 if((distance<olddistance||firstintersecting==-1)&&intersecting){olddistance=distance; firstintersecting=j; *p=point;}
209 if(*rotate)*p=DoRotation(*p,0,*rotate,0);
211 if(*rotate)*p1=DoRotation(*p1,0,*rotate,0);
213 return firstintersecting;
216 int Model::SphereCheckPossible(XYZ *p1,float radius, XYZ *move, float *rotate)
219 static float distance;
220 static float olddistance;
221 static int intersecting;
222 static int firstintersecting;
225 static XYZ start,end;
227 firstintersecting=-1;
234 if(*rotate)*p1=DoRotation(*p1,0,-*rotate,0);
235 if(findDistancefast(p1,&boundingspherecenter)>radius*radius+boundingsphereradius*boundingsphereradius){*p1=oldp1; return -1;}
237 for (j=0;j<TriangleNum;j++){
239 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)));
241 point=*p1-facenormals[j]*distance;
242 if(PointInTriangle( &point, facenormals[j], &vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[1]], &vertex[Triangles[j].vertex[2]]))intersecting=1;
243 if(!intersecting)intersecting=sphere_line_intersection(&vertex[Triangles[j].vertex[0]],
244 &vertex[Triangles[j].vertex[1]],
246 if(!intersecting)intersecting=sphere_line_intersection(&vertex[Triangles[j].vertex[1]],
247 &vertex[Triangles[j].vertex[2]],
249 if(!intersecting)intersecting=sphere_line_intersection(&vertex[Triangles[j].vertex[0]],
250 &vertex[Triangles[j].vertex[2]],
253 //if(j>=0&&j<TriangleNum)
254 possible[numpossible]=j;
258 if((distance<olddistance||firstintersecting==-1)&&intersecting){olddistance=distance; firstintersecting=j;}
260 if(*rotate)*p1=DoRotation(*p1,0,*rotate,0);
262 return firstintersecting;
266 void Model::UpdateVertexArray(){
267 if(type!=normaltype&&type!=decalstype)return;
271 for(i=0;i<TriangleNum;i++){
273 vArray[j+0]=Triangles[i].gx[0];
274 vArray[j+1]=Triangles[i].gy[0];
275 vArray[j+2]=normals[Triangles[i].vertex[0]].x;
276 vArray[j+3]=normals[Triangles[i].vertex[0]].y;
277 vArray[j+4]=normals[Triangles[i].vertex[0]].z;
278 vArray[j+5]=vertex[Triangles[i].vertex[0]].x;
279 vArray[j+6]=vertex[Triangles[i].vertex[0]].y;
280 vArray[j+7]=vertex[Triangles[i].vertex[0]].z;
282 vArray[j+8]=Triangles[i].gx[1];
283 vArray[j+9]=Triangles[i].gy[1];
284 vArray[j+10]=normals[Triangles[i].vertex[1]].x;
285 vArray[j+11]=normals[Triangles[i].vertex[1]].y;
286 vArray[j+12]=normals[Triangles[i].vertex[1]].z;
287 vArray[j+13]=vertex[Triangles[i].vertex[1]].x;
288 vArray[j+14]=vertex[Triangles[i].vertex[1]].y;
289 vArray[j+15]=vertex[Triangles[i].vertex[1]].z;
291 vArray[j+16]=Triangles[i].gx[2];
292 vArray[j+17]=Triangles[i].gy[2];
293 vArray[j+18]=normals[Triangles[i].vertex[2]].x;
294 vArray[j+19]=normals[Triangles[i].vertex[2]].y;
295 vArray[j+20]=normals[Triangles[i].vertex[2]].z;
296 vArray[j+21]=vertex[Triangles[i].vertex[2]].x;
297 vArray[j+22]=vertex[Triangles[i].vertex[2]].y;
298 vArray[j+23]=vertex[Triangles[i].vertex[2]].z;
301 for(i=0;i<TriangleNum;i++){
303 vArray[j+0]=Triangles[i].gx[0];
304 vArray[j+1]=Triangles[i].gy[0];
305 vArray[j+2]=facenormals[i].x*-1;
306 vArray[j+3]=facenormals[i].y*-1;
307 vArray[j+4]=facenormals[i].z*-1;
308 vArray[j+5]=vertex[Triangles[i].vertex[0]].x;
309 vArray[j+6]=vertex[Triangles[i].vertex[0]].y;
310 vArray[j+7]=vertex[Triangles[i].vertex[0]].z;
312 vArray[j+8]=Triangles[i].gx[1];
313 vArray[j+9]=Triangles[i].gy[1];
314 vArray[j+10]=facenormals[i].x*-1;
315 vArray[j+11]=facenormals[i].y*-1;
316 vArray[j+12]=facenormals[i].z*-1;
317 vArray[j+13]=vertex[Triangles[i].vertex[1]].x;
318 vArray[j+14]=vertex[Triangles[i].vertex[1]].y;
319 vArray[j+15]=vertex[Triangles[i].vertex[1]].z;
321 vArray[j+16]=Triangles[i].gx[2];
322 vArray[j+17]=Triangles[i].gy[2];
323 vArray[j+18]=facenormals[i].x*-1;
324 vArray[j+19]=facenormals[i].y*-1;
325 vArray[j+20]=facenormals[i].z*-1;
326 vArray[j+21]=vertex[Triangles[i].vertex[2]].x;
327 vArray[j+22]=vertex[Triangles[i].vertex[2]].y;
328 vArray[j+23]=vertex[Triangles[i].vertex[2]].z;
333 void Model::UpdateVertexArrayNoTex(){
334 if(type!=normaltype&&type!=decalstype)return;
338 for(i=0;i<TriangleNum;i++){
340 vArray[j+2]=normals[Triangles[i].vertex[0]].x;
341 vArray[j+3]=normals[Triangles[i].vertex[0]].y;
342 vArray[j+4]=normals[Triangles[i].vertex[0]].z;
343 vArray[j+5]=vertex[Triangles[i].vertex[0]].x;
344 vArray[j+6]=vertex[Triangles[i].vertex[0]].y;
345 vArray[j+7]=vertex[Triangles[i].vertex[0]].z;
347 vArray[j+10]=normals[Triangles[i].vertex[1]].x;
348 vArray[j+11]=normals[Triangles[i].vertex[1]].y;
349 vArray[j+12]=normals[Triangles[i].vertex[1]].z;
350 vArray[j+13]=vertex[Triangles[i].vertex[1]].x;
351 vArray[j+14]=vertex[Triangles[i].vertex[1]].y;
352 vArray[j+15]=vertex[Triangles[i].vertex[1]].z;
354 vArray[j+18]=normals[Triangles[i].vertex[2]].x;
355 vArray[j+19]=normals[Triangles[i].vertex[2]].y;
356 vArray[j+20]=normals[Triangles[i].vertex[2]].z;
357 vArray[j+21]=vertex[Triangles[i].vertex[2]].x;
358 vArray[j+22]=vertex[Triangles[i].vertex[2]].y;
359 vArray[j+23]=vertex[Triangles[i].vertex[2]].z;
362 for(i=0;i<TriangleNum;i++){
364 vArray[j+2]=facenormals[i].x*-1;
365 vArray[j+3]=facenormals[i].y*-1;
366 vArray[j+4]=facenormals[i].z*-1;
367 vArray[j+5]=vertex[Triangles[i].vertex[0]].x;
368 vArray[j+6]=vertex[Triangles[i].vertex[0]].y;
369 vArray[j+7]=vertex[Triangles[i].vertex[0]].z;
371 vArray[j+10]=facenormals[i].x*-1;
372 vArray[j+11]=facenormals[i].y*-1;
373 vArray[j+12]=facenormals[i].z*-1;
374 vArray[j+13]=vertex[Triangles[i].vertex[1]].x;
375 vArray[j+14]=vertex[Triangles[i].vertex[1]].y;
376 vArray[j+15]=vertex[Triangles[i].vertex[1]].z;
378 vArray[j+18]=facenormals[i].x*-1;
379 vArray[j+19]=facenormals[i].y*-1;
380 vArray[j+20]=facenormals[i].z*-1;
381 vArray[j+21]=vertex[Triangles[i].vertex[2]].x;
382 vArray[j+22]=vertex[Triangles[i].vertex[2]].y;
383 vArray[j+23]=vertex[Triangles[i].vertex[2]].z;
387 void Model::UpdateVertexArrayNoTexNoNorm(){
388 if(type!=normaltype&&type!=decalstype)return;
391 for(i=0;i<TriangleNum;i++){
393 vArray[j+5]=vertex[Triangles[i].vertex[0]].x;
394 vArray[j+6]=vertex[Triangles[i].vertex[0]].y;
395 vArray[j+7]=vertex[Triangles[i].vertex[0]].z;
397 vArray[j+13]=vertex[Triangles[i].vertex[1]].x;
398 vArray[j+14]=vertex[Triangles[i].vertex[1]].y;
399 vArray[j+15]=vertex[Triangles[i].vertex[1]].z;
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 bool Model::loadnotex(const char *filename )
412 int oldvertexNum,oldTriangleNum;
413 oldvertexNum=vertexNum;
414 oldTriangleNum=TriangleNum;
419 tfile=fopen( ConvertFileName(filename), "rb" );
420 // read model settings
422 fseek(tfile, 0, SEEK_SET);
423 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
425 // read the model data
430 owner = (int*)malloc(sizeof(int)*vertexNum);
431 possible = (int*)malloc(sizeof(int)*TriangleNum);
432 vertex = (XYZ*)malloc(sizeof(XYZ)*vertexNum);
433 Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle)*TriangleNum);
434 vArray = (GLfloat*)malloc(sizeof(GLfloat)*TriangleNum*24);
436 for(i=0;i<vertexNum;i++){
437 funpackf(tfile, "Bf Bf Bf", &vertex[i].x,&vertex[i].y,&vertex[i].z);
440 for(i=0;i<TriangleNum;i++){
441 // funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
443 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
444 Triangles[i].vertex[ 0] = vertex[ 0];
445 Triangles[i].vertex[ 1] = vertex[ 2];
446 Triangles[i].vertex[ 2] = vertex[ 4];
447 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
448 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
455 for(i=0;i<vertexNum;i++){
460 boundingsphereradius=0;
461 for(i=0;i<vertexNum;i++){
462 for(j=0;j<vertexNum;j++){
463 if(j!=i&&findDistancefast(&vertex[j],&vertex[i])/2>boundingsphereradius){
464 boundingsphereradius=findDistancefast(&vertex[j],&vertex[i])/2;
465 boundingspherecenter=(vertex[i]+vertex[j])/2;
469 boundingsphereradius=fast_sqrt(boundingsphereradius);
475 bool Model::load(const char *filename,bool texture )
482 LOG(std::string("Loading model...") + filename);
486 pgame->LoadingScreen();
489 int oldvertexNum,oldTriangleNum;
490 oldvertexNum=vertexNum;
491 oldTriangleNum=TriangleNum;
496 tfile=fopen( ConvertFileName(filename), "rb" );
497 // read model settings
500 fseek(tfile, 0, SEEK_SET);
501 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
503 // read the model data
508 owner = (int*)malloc(sizeof(int)*vertexNum);
509 possible = (int*)malloc(sizeof(int)*TriangleNum);
510 vertex = (XYZ*)malloc(sizeof(XYZ)*vertexNum);
511 normals = (XYZ*)malloc(sizeof(XYZ)*vertexNum);
512 facenormals = (XYZ*)malloc(sizeof(XYZ)*TriangleNum);
513 Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle)*TriangleNum);
514 vArray = (GLfloat*)malloc(sizeof(GLfloat)*TriangleNum*24);
516 for(i=0;i<vertexNum;i++){
517 funpackf(tfile, "Bf Bf Bf", &vertex[i].x,&vertex[i].y,&vertex[i].z);
520 for(i=0;i<TriangleNum;i++){
521 // funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
523 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
524 Triangles[i].vertex[ 0] = vertex[ 0];
525 Triangles[i].vertex[ 1] = vertex[ 2];
526 Triangles[i].vertex[ 2] = vertex[ 4];
527 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
528 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
537 for(i=0;i<vertexNum;i++){
542 boundingsphereradius=0;
543 for(i=0;i<vertexNum;i++){
544 for(j=0;j<vertexNum;j++){
545 if(j!=i&&findDistancefast(&vertex[j],&vertex[i])/2>boundingsphereradius){
546 boundingsphereradius=findDistancefast(&vertex[j],&vertex[i])/2;
547 boundingspherecenter=(vertex[i]+vertex[j])/2;
551 boundingsphereradius=fast_sqrt(boundingsphereradius);
556 bool Model::loaddecal(const char *filename,bool texture )
563 // Changing the filename so that its more os specific
564 char * FixedFN = ConvertFileName(filename);
566 LOG(std::string("Loading decal...") + FixedFN);
568 int oldvertexNum,oldTriangleNum;
569 oldvertexNum=vertexNum;
570 oldTriangleNum=TriangleNum;
576 tfile=fopen( FixedFN, "rb" );
577 // read model settings
580 fseek(tfile, 0, SEEK_SET);
581 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
583 // read the model data
589 owner = (int*)malloc(sizeof(int)*vertexNum);
590 possible = (int*)malloc(sizeof(int)*TriangleNum);
591 vertex = (XYZ*)malloc(sizeof(XYZ)*vertexNum);
592 normals = (XYZ*)malloc(sizeof(XYZ)*vertexNum);
593 facenormals = (XYZ*)malloc(sizeof(XYZ)*TriangleNum);
594 Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle)*TriangleNum);
595 vArray = (GLfloat*)malloc(sizeof(GLfloat)*TriangleNum*24);
598 for(i=0;i<vertexNum;i++){
599 funpackf(tfile, "Bf Bf Bf", &vertex[i].x,&vertex[i].y,&vertex[i].z);
602 for(i=0;i<TriangleNum;i++){
603 // funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
605 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
606 Triangles[i].vertex[ 0] = vertex[ 0];
607 Triangles[i].vertex[ 1] = vertex[ 2];
608 Triangles[i].vertex[ 2] = vertex[ 4];
609 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
610 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
620 for(i=0;i<vertexNum;i++){
624 boundingsphereradius=0;
625 for(i=0;i<vertexNum;i++){
626 for(j=0;j<vertexNum;j++){
627 if(j!=i&&findDistancefast(&vertex[j],&vertex[i])/2>boundingsphereradius){
628 boundingsphereradius=findDistancefast(&vertex[j],&vertex[i])/2;
629 boundingspherecenter=(vertex[i]+vertex[j])/2;
633 boundingsphereradius=fast_sqrt(boundingsphereradius);
637 decaltexcoords = (float***)malloc(sizeof(float**)*max_model_decals);
638 for(i=0;i<max_model_decals;i++){
639 decaltexcoords[i] = (float**)malloc(sizeof(float*)*3);
641 decaltexcoords[i][j] = (float*)malloc(sizeof(float)*2);
644 //if(decalvertex)free(decalvertex);
645 decalvertex = (XYZ**)malloc(sizeof(XYZ*)*max_model_decals);
646 for(i=0;i<max_model_decals;i++){
647 decalvertex[i] = (XYZ*)malloc(sizeof(XYZ)*3);
650 decaltype = (int*)malloc(sizeof(int)*max_model_decals);
651 decalopacity = (float*)malloc(sizeof(float)*max_model_decals);
652 decalrotation = (float*)malloc(sizeof(float)*max_model_decals);
653 decalalivetime = (float*)malloc(sizeof(float)*max_model_decals);
654 decalposition = (XYZ*)malloc(sizeof(XYZ)*max_model_decals);
660 bool Model::loadraw(char *filename )
667 LOG(std::string("Loading raw...") + filename);
669 int oldvertexNum,oldTriangleNum;
670 oldvertexNum=vertexNum;
671 oldTriangleNum=TriangleNum;
676 tfile=fopen( ConvertFileName(filename), "rb" );
677 // read model settings
680 fseek(tfile, 0, SEEK_SET);
681 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
683 // read the model data
688 owner = (int*)malloc(sizeof(int)*vertexNum);
689 possible = (int*)malloc(sizeof(int)*TriangleNum);
690 vertex = (XYZ*)malloc(sizeof(XYZ)*vertexNum);
691 Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle)*TriangleNum);
692 vArray = (GLfloat*)malloc(sizeof(GLfloat)*TriangleNum*24);
695 for(i=0;i<vertexNum;i++){
696 funpackf(tfile, "Bf Bf Bf", &vertex[i].x,&vertex[i].y,&vertex[i].z);
699 for(i=0;i<TriangleNum;i++){
700 // funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
702 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
703 Triangles[i].vertex[ 0] = vertex[ 0];
704 Triangles[i].vertex[ 1] = vertex[ 2];
705 Triangles[i].vertex[ 2] = vertex[ 4];
706 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
707 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
713 for(i=0;i<vertexNum;i++){
721 void Model::UniformTexCoords()
724 for(i=0; i<TriangleNum; i++){
725 Triangles[i].gy[0]=vertex[Triangles[i].vertex[0]].y;
726 Triangles[i].gy[1]=vertex[Triangles[i].vertex[1]].y;
727 Triangles[i].gy[2]=vertex[Triangles[i].vertex[2]].y;
728 Triangles[i].gx[0]=vertex[Triangles[i].vertex[0]].x;
729 Triangles[i].gx[1]=vertex[Triangles[i].vertex[1]].x;
730 Triangles[i].gx[2]=vertex[Triangles[i].vertex[2]].x;
736 void Model::FlipTexCoords()
739 for(i=0; i<TriangleNum; i++){
740 Triangles[i].gy[0]=-Triangles[i].gy[0];
741 Triangles[i].gy[1]=-Triangles[i].gy[1];
742 Triangles[i].gy[2]=-Triangles[i].gy[2];
747 void Model::ScaleTexCoords(float howmuch)
750 for(i=0; i<TriangleNum; i++){
751 Triangles[i].gx[0]*=howmuch;
752 Triangles[i].gx[1]*=howmuch;
753 Triangles[i].gx[2]*=howmuch;
754 Triangles[i].gy[0]*=howmuch;
755 Triangles[i].gy[1]*=howmuch;
756 Triangles[i].gy[2]*=howmuch;
761 void Model::Scale(float xscale,float yscale,float zscale)
764 for(i=0; i<vertexNum; i++){
773 boundingsphereradius=0;
774 for(i=0;i<vertexNum;i++){
775 for(j=0;j<vertexNum;j++){
776 if(j!=i&&findDistancefast(&vertex[j],&vertex[i])/2>boundingsphereradius){
777 boundingsphereradius=findDistancefast(&vertex[j],&vertex[i])/2;
778 boundingspherecenter=(vertex[i]+vertex[j])/2;
782 boundingsphereradius=fast_sqrt(boundingsphereradius);
785 void Model::ScaleNormals(float xscale,float yscale,float zscale)
787 if(type!=normaltype&&type!=decalstype)return;
789 for(i=0; i<vertexNum; i++){
790 normals[i].x*=xscale;
791 normals[i].y*=yscale;
792 normals[i].z*=zscale;
794 for(i=0; i<TriangleNum; i++){
795 facenormals[i].x*=xscale;
796 facenormals[i].y*=yscale;
797 facenormals[i].z*=zscale;
802 void Model::Translate(float xtrans,float ytrans,float ztrans)
805 for(i=0; i<vertexNum; i++){
813 boundingsphereradius=0;
814 for(i=0;i<vertexNum;i++){
815 for(j=0;j<vertexNum;j++){
816 if(j!=i&&findDistancefast(&vertex[j],&vertex[i])/2>boundingsphereradius){
817 boundingsphereradius=findDistancefast(&vertex[j],&vertex[i])/2;
818 boundingspherecenter=(vertex[i]+vertex[j])/2;
822 boundingsphereradius=fast_sqrt(boundingsphereradius);
825 void Model::Rotate(float xang,float yang,float zang)
828 for(i=0; i<vertexNum; i++){
829 vertex[i]=DoRotation(vertex[i],xang,yang,zang);
834 boundingsphereradius=0;
835 for(i=0;i<vertexNum;i++){
836 for(j=0;j<vertexNum;j++){
837 if(j!=i&&findDistancefast(&vertex[j],&vertex[i])/2>boundingsphereradius){
838 boundingsphereradius=findDistancefast(&vertex[j],&vertex[i])/2;
839 boundingspherecenter=(vertex[i]+vertex[j])/2;
843 boundingsphereradius=fast_sqrt(boundingsphereradius);
847 void Model::CalculateNormals(bool facenormalise)
851 pgame->LoadingScreen();
854 if(type!=normaltype&&type!=decalstype)return;
856 for(i=0; i<vertexNum; i++){
862 for(i=0;i<TriangleNum;i++){
863 CrossProduct(vertex[Triangles[i].vertex[1]]-vertex[Triangles[i].vertex[0]],vertex[Triangles[i].vertex[2]]-vertex[Triangles[i].vertex[0]],&facenormals[i]);
865 normals[Triangles[i].vertex[0]].x+=facenormals[i].x;
866 normals[Triangles[i].vertex[0]].y+=facenormals[i].y;
867 normals[Triangles[i].vertex[0]].z+=facenormals[i].z;
869 normals[Triangles[i].vertex[1]].x+=facenormals[i].x;
870 normals[Triangles[i].vertex[1]].y+=facenormals[i].y;
871 normals[Triangles[i].vertex[1]].z+=facenormals[i].z;
873 normals[Triangles[i].vertex[2]].x+=facenormals[i].x;
874 normals[Triangles[i].vertex[2]].y+=facenormals[i].y;
875 normals[Triangles[i].vertex[2]].z+=facenormals[i].z;
876 if(facenormalise)Normalise(&facenormals[i]);
878 for(i=0; i<vertexNum; i++){
879 Normalise(&normals[i]);
882 UpdateVertexArrayNoTex();
885 void Model::drawimmediate()
887 glBindTexture(GL_TEXTURE_2D,(unsigned long)textureptr);
888 glBegin(GL_TRIANGLES);
889 for(int i=0;i<TriangleNum;i++){
890 /*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){
891 if(isnormal(vertex[Triangles[i].vertex[0]].x)&&isnormal(vertex[Triangles[i].vertex[0]].y)&&isnormal(vertex[Triangles[i].vertex[0]].z)
892 &&isnormal(vertex[Triangles[i].vertex[1]].x)&&isnormal(vertex[Triangles[i].vertex[1]].y)&&isnormal(vertex[Triangles[i].vertex[1]].z)
893 &&isnormal(vertex[Triangles[i].vertex[2]].x)&&isnormal(vertex[Triangles[i].vertex[2]].y)&&isnormal(vertex[Triangles[i].vertex[2]].z)){
895 glTexCoord2f(Triangles[i].gx[0],Triangles[i].gy[0]);
896 if(color)glColor3f(normals[Triangles[i].vertex[0]].x,normals[Triangles[i].vertex[0]].y,normals[Triangles[i].vertex[0]].z);
897 if(!color&&!flat)glNormal3f(normals[Triangles[i].vertex[0]].x,normals[Triangles[i].vertex[0]].y,normals[Triangles[i].vertex[0]].z);
898 if(!color&&flat)glNormal3f(facenormals[i].x,facenormals[i].y,facenormals[i].y);
899 glVertex3f(vertex[Triangles[i].vertex[0]].x,vertex[Triangles[i].vertex[0]].y,vertex[Triangles[i].vertex[0]].z);
901 glTexCoord2f(Triangles[i].gx[1],Triangles[i].gy[1]);
902 if(color)glColor3f(normals[Triangles[i].vertex[1]].x,normals[Triangles[i].vertex[1]].y,normals[Triangles[i].vertex[1]].z);
903 if(!color&&!flat)glNormal3f(normals[Triangles[i].vertex[1]].x,normals[Triangles[i].vertex[1]].y,normals[Triangles[i].vertex[1]].z);
904 if(!color&&flat)glNormal3f(facenormals[i].x,facenormals[i].y,facenormals[i].y);
905 glVertex3f(vertex[Triangles[i].vertex[1]].x,vertex[Triangles[i].vertex[1]].y,vertex[Triangles[i].vertex[1]].z);
907 glTexCoord2f(Triangles[i].gx[2],Triangles[i].gy[2]);
908 if(color)glColor3f(normals[Triangles[i].vertex[2]].x,normals[Triangles[i].vertex[2]].y,normals[Triangles[i].vertex[2]].z);
909 if(!color&&!flat)glNormal3f(normals[Triangles[i].vertex[2]].x,normals[Triangles[i].vertex[2]].y,normals[Triangles[i].vertex[2]].z);
910 if(!color&&flat)glNormal3f(facenormals[i].x,facenormals[i].y,facenormals[i].y);
911 glVertex3f(vertex[Triangles[i].vertex[2]].x,vertex[Triangles[i].vertex[2]].y,vertex[Triangles[i].vertex[2]].z);
920 if(type!=normaltype&&type!=decalstype)return;
922 glEnableClientState(GL_NORMAL_ARRAY);
923 glEnableClientState(GL_VERTEX_ARRAY);
924 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
926 if(!color)glInterleavedArrays( GL_T2F_N3F_V3F,8*sizeof(GLfloat),&vArray[0]);
927 if(color)glInterleavedArrays( GL_T2F_C3F_V3F,8*sizeof(GLfloat),&vArray[0]);
928 glBindTexture(GL_TEXTURE_2D,(unsigned long)textureptr);
931 glLockArraysEXT( 0, TriangleNum*3);
933 glDrawArrays(GL_TRIANGLES, 0, TriangleNum*3);
939 if(!color)glDisableClientState(GL_NORMAL_ARRAY);
940 if(color)glDisableClientState(GL_COLOR_ARRAY);
941 glDisableClientState(GL_VERTEX_ARRAY);
942 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
946 void Model::drawdifftex(GLuint texture)
948 glEnableClientState(GL_NORMAL_ARRAY);
949 glEnableClientState(GL_VERTEX_ARRAY);
950 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
951 if(!color)glInterleavedArrays( GL_T2F_N3F_V3F,8*sizeof(GLfloat),&vArray[0]);
952 if(color)glInterleavedArrays( GL_T2F_C3F_V3F,8*sizeof(GLfloat),&vArray[0]);
954 glBindTexture(GL_TEXTURE_2D,(unsigned long)texture);
955 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
956 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
960 glLockArraysEXT( 0, TriangleNum*3);
962 glDrawArrays(GL_TRIANGLES, 0, TriangleNum*3);
968 if(!color)glDisableClientState(GL_NORMAL_ARRAY);
969 if(color)glDisableClientState(GL_COLOR_ARRAY);
970 glDisableClientState(GL_VERTEX_ARRAY);
971 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
972 //drawdiffteximmediate(texture);
975 void Model::drawdiffteximmediate(GLuint texture)
977 glBindTexture(GL_TEXTURE_2D,(unsigned long)texture);
979 glBegin(GL_TRIANGLES);
980 for(int i=0;i<TriangleNum;i++){
981 /*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){
982 if(isnormal(vertex[Triangles[i].vertex[0]].x)&&isnormal(vertex[Triangles[i].vertex[0]].y)&&isnormal(vertex[Triangles[i].vertex[0]].z)
983 &&isnormal(vertex[Triangles[i].vertex[1]].x)&&isnormal(vertex[Triangles[i].vertex[1]].y)&&isnormal(vertex[Triangles[i].vertex[1]].z)
984 &&isnormal(vertex[Triangles[i].vertex[2]].x)&&isnormal(vertex[Triangles[i].vertex[2]].y)&&isnormal(vertex[Triangles[i].vertex[2]].z)){
985 */glTexCoord2f(Triangles[i].gx[0],Triangles[i].gy[0]);
986 if(color)glColor3f(normals[Triangles[i].vertex[0]].x,normals[Triangles[i].vertex[0]].y,normals[Triangles[i].vertex[0]].z);
987 if(!color&&!flat)glNormal3f(normals[Triangles[i].vertex[0]].x,normals[Triangles[i].vertex[0]].y,normals[Triangles[i].vertex[0]].z);
988 if(!color&&flat)glNormal3f(facenormals[i].x,facenormals[i].y,facenormals[i].y);
989 glVertex3f(vertex[Triangles[i].vertex[0]].x,vertex[Triangles[i].vertex[0]].y,vertex[Triangles[i].vertex[0]].z);
991 glTexCoord2f(Triangles[i].gx[1],Triangles[i].gy[1]);
992 if(color)glColor3f(normals[Triangles[i].vertex[1]].x,normals[Triangles[i].vertex[1]].y,normals[Triangles[i].vertex[1]].z);
993 if(!color&&!flat)glNormal3f(normals[Triangles[i].vertex[1]].x,normals[Triangles[i].vertex[1]].y,normals[Triangles[i].vertex[1]].z);
994 if(!color&&flat)glNormal3f(facenormals[i].x,facenormals[i].y,facenormals[i].y);
995 glVertex3f(vertex[Triangles[i].vertex[1]].x,vertex[Triangles[i].vertex[1]].y,vertex[Triangles[i].vertex[1]].z);
997 glTexCoord2f(Triangles[i].gx[2],Triangles[i].gy[2]);
998 if(color)glColor3f(normals[Triangles[i].vertex[2]].x,normals[Triangles[i].vertex[2]].y,normals[Triangles[i].vertex[2]].z);
999 if(!color&&!flat)glNormal3f(normals[Triangles[i].vertex[2]].x,normals[Triangles[i].vertex[2]].y,normals[Triangles[i].vertex[2]].z);
1000 if(!color&&flat)glNormal3f(facenormals[i].x,facenormals[i].y,facenormals[i].y);
1001 glVertex3f(vertex[Triangles[i].vertex[2]].x,vertex[Triangles[i].vertex[2]].y,vertex[Triangles[i].vertex[2]].z);
1008 void Model::drawdecals(GLuint shadowtexture,GLuint bloodtexture,GLuint bloodtexture2,GLuint breaktexture)
1011 if(type!=decalstype)return;
1013 static float distancemult;
1014 static int lasttype;
1015 static float viewdistsquared;
1018 viewdistsquared=viewdistance*viewdistance;
1023 glDisable(GL_LIGHTING);
1024 glDisable(GL_CULL_FACE);
1025 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1027 if(numdecals>max_model_decals)numdecals=max_model_decals;
1028 for(i=0;i<numdecals;i++){
1029 if(decaltype[i]==blooddecalfast&&decalalivetime[i]<2)decalalivetime[i]=2;
1031 if(decaltype[i]==shadowdecal&&decaltype[i]!=lasttype){
1032 glBindTexture( GL_TEXTURE_2D, shadowtexture);
1035 glAlphaFunc(GL_GREATER, 0.0001);
1036 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1039 if(decaltype[i]==breakdecal&&decaltype[i]!=lasttype){
1040 glBindTexture( GL_TEXTURE_2D, breaktexture);
1043 glAlphaFunc(GL_GREATER, 0.0001);
1044 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1047 if((decaltype[i]==blooddecal||decaltype[i]==blooddecalslow)&&decaltype[i]!=lasttype){
1048 glBindTexture( GL_TEXTURE_2D, bloodtexture);
1051 glAlphaFunc(GL_GREATER, 0.15);
1052 glBlendFunc(GL_ONE,GL_ZERO);
1055 if((decaltype[i]==blooddecalfast)&&decaltype[i]!=lasttype){
1056 glBindTexture( GL_TEXTURE_2D, bloodtexture2);
1059 glAlphaFunc(GL_GREATER, 0.15);
1060 glBlendFunc(GL_ONE,GL_ZERO);
1063 if(decaltype[i]==shadowdecal){
1064 glColor4f(1,1,1,decalopacity[i]);
1066 if(decaltype[i]==breakdecal){
1067 glColor4f(1,1,1,decalopacity[i]);
1068 if(decalalivetime[i]>58)glColor4f(1,1,1,decalopacity[i]*(60-decalalivetime[i])/2);
1070 if((decaltype[i]==blooddecal||decaltype[i]==blooddecalfast||decaltype[i]==blooddecalslow)){
1071 glColor4f(1,1,1,decalopacity[i]);
1072 if(decalalivetime[i]<4)glColor4f(1,1,1,decalopacity[i]*decalalivetime[i]*.25);
1073 if(decalalivetime[i]>58)glColor4f(1,1,1,decalopacity[i]*(60-decalalivetime[i])/2);
1075 lasttype=decaltype[i];
1076 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1077 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
1079 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
1081 glBegin(GL_TRIANGLES);
1082 for(int j=0;j<3;j++)
1084 glTexCoord2f(decaltexcoords[i][j][0], decaltexcoords[i][j][1]); glVertex3f(decalvertex[i][j].x,decalvertex[i][j].y,decalvertex[i][j].z);
1089 for(i=numdecals-1;i>=0;i--){
1090 decalalivetime[i]+=multiplier;
1091 if(decaltype[i]==blooddecalslow)decalalivetime[i]-=multiplier*2/3;
1092 if(decaltype[i]==blooddecalfast)decalalivetime[i]+=multiplier*4;
1093 if(decaltype[i]==shadowdecal)DeleteDecal(i);
1094 if((decaltype[i]==blooddecal||decaltype[i]==blooddecalfast||decaltype[i]==blooddecalslow)&&decalalivetime[i]>=60)DeleteDecal(i);
1096 glAlphaFunc(GL_GREATER, 0.0001);
1097 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1101 void Model::DeleteDecal(int which)
1104 if(type!=decalstype)return;
1105 decaltype[which]=decaltype[numdecals-1];
1106 decalposition[which]=decalposition[numdecals-1];
1107 for(int i=0;i<3;i++){
1108 decalvertex[which][i]=decalvertex[numdecals-1][i];
1109 decaltexcoords[which][i][0]=decaltexcoords[numdecals-1][i][0];
1110 decaltexcoords[which][i][1]=decaltexcoords[numdecals-1][i][1];
1112 decalrotation[which]=decalrotation[numdecals-1];
1113 decalalivetime[which]=decalalivetime[numdecals-1];
1114 decalopacity[which]=decalopacity[numdecals-1];
1119 void Model::MakeDecal(int atype, XYZ *where,float *size, float *opacity, float *rotation){
1121 if(type!=decalstype)return;
1123 static float placex,placez;
1125 //static XYZ point,point1,point2;
1126 static float distance;
1130 if(findDistancefast(where,&boundingspherecenter)<(boundingsphereradius+*size)*(boundingsphereradius+*size))
1131 for(i=0;i<TriangleNum;i++){
1132 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)){
1133 decalposition[numdecals]=*where;
1134 decaltype[numdecals]=atype;
1135 decalrotation[numdecals]=*rotation;
1136 decalalivetime[numdecals]=0;
1137 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);
1138 decalopacity[numdecals]=*opacity-distance/10;
1140 if(decalopacity[numdecals>0]){
1141 placex=vertex[Triangles[i].vertex[0]].x;
1142 placez=vertex[Triangles[i].vertex[0]].z;
1144 decaltexcoords[numdecals][0][0]=(placex-where->x)/(*size)/2+.5;
1145 decaltexcoords[numdecals][0][1]=(placez-where->z)/(*size)/2+.5;
1147 decalvertex[numdecals][0].x=placex;
1148 decalvertex[numdecals][0].z=placez;
1149 decalvertex[numdecals][0].y=vertex[Triangles[i].vertex[0]].y;
1152 placex=vertex[Triangles[i].vertex[1]].x;
1153 placez=vertex[Triangles[i].vertex[1]].z;
1155 decaltexcoords[numdecals][1][0]=(placex-where->x)/(*size)/2+.5;
1156 decaltexcoords[numdecals][1][1]=(placez-where->z)/(*size)/2+.5;
1158 decalvertex[numdecals][1].x=placex;
1159 decalvertex[numdecals][1].z=placez;
1160 decalvertex[numdecals][1].y=vertex[Triangles[i].vertex[1]].y;
1163 placex=vertex[Triangles[i].vertex[2]].x;
1164 placez=vertex[Triangles[i].vertex[2]].z;
1166 decaltexcoords[numdecals][2][0]=(placex-where->x)/(*size)/2+.5;
1167 decaltexcoords[numdecals][2][1]=(placez-where->z)/(*size)/2+.5;
1169 decalvertex[numdecals][2].x=placex;
1170 decalvertex[numdecals][2].z=placez;
1171 decalvertex[numdecals][2].y=vertex[Triangles[i].vertex[2]].y;
1173 if(!(decaltexcoords[numdecals][0][0]<0&&decaltexcoords[numdecals][1][0]<0&&decaltexcoords[numdecals][2][0]<0))
1174 if(!(decaltexcoords[numdecals][0][1]<0&&decaltexcoords[numdecals][1][1]<0&&decaltexcoords[numdecals][2][1]<0))
1175 if(!(decaltexcoords[numdecals][0][0]>1&&decaltexcoords[numdecals][1][0]>1&&decaltexcoords[numdecals][2][0]>1))
1176 if(!(decaltexcoords[numdecals][0][1]>1&&decaltexcoords[numdecals][1][1]>1&&decaltexcoords[numdecals][2][1]>1))
1178 if(decalrotation[numdecals]){
1181 rot.x=decaltexcoords[numdecals][j][0]-.5;
1182 rot.z=decaltexcoords[numdecals][j][1]-.5;
1183 rot=DoRotation(rot,0,-decalrotation[numdecals],0);
1184 decaltexcoords[numdecals][j][0]=rot.x+.5;
1185 decaltexcoords[numdecals][j][1]=rot.z+.5;
1188 if(numdecals<max_model_decals-1)numdecals++;
1196 void Model::MakeDecal(int atype, XYZ where,float size, float opacity, float rotation){
1198 if(type!=decalstype)return;
1200 static float placex,placez;
1202 //static XYZ point,point1,point2;
1203 static float distance;
1207 if(findDistancefast(&where,&boundingspherecenter)<(boundingsphereradius+size)*(boundingsphereradius+size))
1208 for(i=0;i<TriangleNum;i++){
1209 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))));
1210 if(distance<.02&&abs(facenormals[i].y)>abs(facenormals[i].x)&&abs(facenormals[i].y)>abs(facenormals[i].z)){
1211 decalposition[numdecals]=where;
1212 decaltype[numdecals]=atype;
1213 decalrotation[numdecals]=rotation;
1214 decalalivetime[numdecals]=0;
1215 decalopacity[numdecals]=opacity-distance/10;
1217 if(decalopacity[numdecals>0]){
1218 placex=vertex[Triangles[i].vertex[0]].x;
1219 placez=vertex[Triangles[i].vertex[0]].z;
1221 decaltexcoords[numdecals][0][0]=(placex-where.x)/(size)/2+.5;
1222 decaltexcoords[numdecals][0][1]=(placez-where.z)/(size)/2+.5;
1224 decalvertex[numdecals][0].x=placex;
1225 decalvertex[numdecals][0].z=placez;
1226 decalvertex[numdecals][0].y=vertex[Triangles[i].vertex[0]].y;
1229 placex=vertex[Triangles[i].vertex[1]].x;
1230 placez=vertex[Triangles[i].vertex[1]].z;
1232 decaltexcoords[numdecals][1][0]=(placex-where.x)/(size)/2+.5;
1233 decaltexcoords[numdecals][1][1]=(placez-where.z)/(size)/2+.5;
1235 decalvertex[numdecals][1].x=placex;
1236 decalvertex[numdecals][1].z=placez;
1237 decalvertex[numdecals][1].y=vertex[Triangles[i].vertex[1]].y;
1240 placex=vertex[Triangles[i].vertex[2]].x;
1241 placez=vertex[Triangles[i].vertex[2]].z;
1243 decaltexcoords[numdecals][2][0]=(placex-where.x)/(size)/2+.5;
1244 decaltexcoords[numdecals][2][1]=(placez-where.z)/(size)/2+.5;
1246 decalvertex[numdecals][2].x=placex;
1247 decalvertex[numdecals][2].z=placez;
1248 decalvertex[numdecals][2].y=vertex[Triangles[i].vertex[2]].y;
1250 if(!(decaltexcoords[numdecals][0][0]<0&&decaltexcoords[numdecals][1][0]<0&&decaltexcoords[numdecals][2][0]<0))
1251 if(!(decaltexcoords[numdecals][0][1]<0&&decaltexcoords[numdecals][1][1]<0&&decaltexcoords[numdecals][2][1]<0))
1252 if(!(decaltexcoords[numdecals][0][0]>1&&decaltexcoords[numdecals][1][0]>1&&decaltexcoords[numdecals][2][0]>1))
1253 if(!(decaltexcoords[numdecals][0][1]>1&&decaltexcoords[numdecals][1][1]>1&&decaltexcoords[numdecals][2][1]>1))
1255 if(decalrotation[numdecals]){
1258 rot.x=decaltexcoords[numdecals][j][0]-.5;
1259 rot.z=decaltexcoords[numdecals][j][1]-.5;
1260 rot=DoRotation(rot,0,-decalrotation[numdecals],0);
1261 decaltexcoords[numdecals][j][0]=rot.x+.5;
1262 decaltexcoords[numdecals][j][1]=rot.z+.5;
1265 if(numdecals<max_model_decals-1)numdecals++;
1269 else if(distance<.02&&abs(facenormals[i].x)>abs(facenormals[i].y)&&abs(facenormals[i].x)>abs(facenormals[i].z)){
1270 decalposition[numdecals]=where;
1271 decaltype[numdecals]=atype;
1272 decalrotation[numdecals]=rotation;
1273 decalalivetime[numdecals]=0;
1274 decalopacity[numdecals]=opacity-distance/10;
1276 if(decalopacity[numdecals>0]){
1277 placex=vertex[Triangles[i].vertex[0]].y;
1278 placez=vertex[Triangles[i].vertex[0]].z;
1280 decaltexcoords[numdecals][0][0]=(placex-where.y)/(size)/2+.5;
1281 decaltexcoords[numdecals][0][1]=(placez-where.z)/(size)/2+.5;
1283 decalvertex[numdecals][0].x=vertex[Triangles[i].vertex[0]].x;
1284 decalvertex[numdecals][0].z=placez;
1285 decalvertex[numdecals][0].y=placex;
1288 placex=vertex[Triangles[i].vertex[1]].y;
1289 placez=vertex[Triangles[i].vertex[1]].z;
1291 decaltexcoords[numdecals][1][0]=(placex-where.y)/(size)/2+.5;
1292 decaltexcoords[numdecals][1][1]=(placez-where.z)/(size)/2+.5;
1294 decalvertex[numdecals][1].x=vertex[Triangles[i].vertex[1]].x;
1295 decalvertex[numdecals][1].z=placez;
1296 decalvertex[numdecals][1].y=placex;
1299 placex=vertex[Triangles[i].vertex[2]].y;
1300 placez=vertex[Triangles[i].vertex[2]].z;
1302 decaltexcoords[numdecals][2][0]=(placex-where.y)/(size)/2+.5;
1303 decaltexcoords[numdecals][2][1]=(placez-where.z)/(size)/2+.5;
1305 decalvertex[numdecals][2].x=vertex[Triangles[i].vertex[2]].x;
1306 decalvertex[numdecals][2].z=placez;
1307 decalvertex[numdecals][2].y=placex;
1309 if(!(decaltexcoords[numdecals][0][0]<0&&decaltexcoords[numdecals][1][0]<0&&decaltexcoords[numdecals][2][0]<0))
1310 if(!(decaltexcoords[numdecals][0][1]<0&&decaltexcoords[numdecals][1][1]<0&&decaltexcoords[numdecals][2][1]<0))
1311 if(!(decaltexcoords[numdecals][0][0]>1&&decaltexcoords[numdecals][1][0]>1&&decaltexcoords[numdecals][2][0]>1))
1312 if(!(decaltexcoords[numdecals][0][1]>1&&decaltexcoords[numdecals][1][1]>1&&decaltexcoords[numdecals][2][1]>1))
1314 if(decalrotation[numdecals]){
1317 rot.x=decaltexcoords[numdecals][j][0]-.5;
1318 rot.z=decaltexcoords[numdecals][j][1]-.5;
1319 rot=DoRotation(rot,0,-decalrotation[numdecals],0);
1320 decaltexcoords[numdecals][j][0]=rot.x+.5;
1321 decaltexcoords[numdecals][j][1]=rot.z+.5;
1324 if(numdecals<max_model_decals-1)numdecals++;
1328 else if(distance<.02&&abs(facenormals[i].z)>abs(facenormals[i].y)&&abs(facenormals[i].z)>abs(facenormals[i].x)){
1329 decalposition[numdecals]=where;
1330 decaltype[numdecals]=atype;
1331 decalrotation[numdecals]=rotation;
1332 decalalivetime[numdecals]=0;
1333 decalopacity[numdecals]=opacity-distance/10;
1335 if(decalopacity[numdecals>0]){
1336 placex=vertex[Triangles[i].vertex[0]].x;
1337 placez=vertex[Triangles[i].vertex[0]].y;
1339 decaltexcoords[numdecals][0][0]=(placex-where.x)/(size)/2+.5;
1340 decaltexcoords[numdecals][0][1]=(placez-where.y)/(size)/2+.5;
1342 decalvertex[numdecals][0].x=placex;
1343 decalvertex[numdecals][0].z=vertex[Triangles[i].vertex[0]].z;
1344 decalvertex[numdecals][0].y=placez;
1347 placex=vertex[Triangles[i].vertex[1]].x;
1348 placez=vertex[Triangles[i].vertex[1]].y;
1350 decaltexcoords[numdecals][1][0]=(placex-where.x)/(size)/2+.5;
1351 decaltexcoords[numdecals][1][1]=(placez-where.y)/(size)/2+.5;
1353 decalvertex[numdecals][1].x=placex;
1354 decalvertex[numdecals][1].z=vertex[Triangles[i].vertex[1]].z;
1355 decalvertex[numdecals][1].y=placez;
1358 placex=vertex[Triangles[i].vertex[2]].x;
1359 placez=vertex[Triangles[i].vertex[2]].y;
1361 decaltexcoords[numdecals][2][0]=(placex-where.x)/(size)/2+.5;
1362 decaltexcoords[numdecals][2][1]=(placez-where.y)/(size)/2+.5;
1364 decalvertex[numdecals][2].x=placex;
1365 decalvertex[numdecals][2].z=vertex[Triangles[i].vertex[2]].z;
1366 decalvertex[numdecals][2].y=placez;
1368 if(!(decaltexcoords[numdecals][0][0]<0&&decaltexcoords[numdecals][1][0]<0&&decaltexcoords[numdecals][2][0]<0))
1369 if(!(decaltexcoords[numdecals][0][1]<0&&decaltexcoords[numdecals][1][1]<0&&decaltexcoords[numdecals][2][1]<0))
1370 if(!(decaltexcoords[numdecals][0][0]>1&&decaltexcoords[numdecals][1][0]>1&&decaltexcoords[numdecals][2][0]>1))
1371 if(!(decaltexcoords[numdecals][0][1]>1&&decaltexcoords[numdecals][1][1]>1&&decaltexcoords[numdecals][2][1]>1))
1373 if(decalrotation[numdecals]){
1376 rot.x=decaltexcoords[numdecals][j][0]-.5;
1377 rot.z=decaltexcoords[numdecals][j][1]-.5;
1378 rot=DoRotation(rot,0,-decalrotation[numdecals],0);
1379 decaltexcoords[numdecals][j][0]=rot.x+.5;
1380 decaltexcoords[numdecals][j][1]=rot.z+.5;
1383 if(numdecals<max_model_decals-1)numdecals++;
1395 if(textureptr) glDeleteTextures( 1, &textureptr );
1398 void Model::deallocate()
1402 if(owner)free(owner);
1405 if(possible)free(possible);
1408 if(vertex)free(vertex);
1411 if(normals)free(normals);
1414 if(facenormals)free(facenormals);
1417 if(Triangles)free(Triangles);
1420 if(vArray)free(vArray);
1427 for(i=0;i<max_model_decals;i++)
1431 free(decaltexcoords[i][j]);
1433 free(decaltexcoords[i]);
1435 free(decaltexcoords);
1442 for(i=0;i<max_model_decals;i++)
1444 free(decalvertex[i]);
1457 free(decalrotation);
1460 free(decalalivetime);
1463 free(decalposition);
1470 vertexNum = 0,TriangleNum = 0;
1473 type = 0,oldtype = 0;
1484 memset(&Texture, 0, sizeof(Texture));
1488 boundingspherecenter = 0;
1489 boundingsphereradius = 0;