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;
33 extern bool visibleloading;
35 int Model::LineCheck(XYZ *p1,XYZ *p2, XYZ *p, XYZ *move, float *rotate)
38 static float distance;
39 static float olddistance;
40 static int intersecting;
41 static int firstintersecting;
46 if(*rotate)*p1=DoRotation(*p1,0,-*rotate,0);
47 if(*rotate)*p2=DoRotation(*p2,0,-*rotate,0);
48 if(!sphere_line_intersection(p1,p2,&boundingspherecenter,
49 &boundingsphereradius))return -1;
52 for (j=0;j<TriangleNum;j++){
53 intersecting=LineFacetd(p1,p2,&vertex[Triangles[j].vertex[0]],&vertex[Triangles[j].vertex[1]],&vertex[Triangles[j].vertex[2]],&facenormals[j],&point);
54 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);
55 if((distance<olddistance||firstintersecting==-1)&&intersecting){olddistance=distance; firstintersecting=j; *p=point;}
58 if(*rotate)*p=DoRotation(*p,0,*rotate,0);
60 return firstintersecting;
63 int Model::LineCheckSlide(XYZ *p1,XYZ *p2, XYZ *p, XYZ *move, float *rotate)
66 static float distance;
67 static float olddistance;
68 static int intersecting;
69 static int firstintersecting;
74 if(!sphere_line_intersection(p1,p2,&boundingspherecenter,
75 &boundingsphereradius))return -1;
77 if(*rotate)*p1=DoRotation(*p1,0,-*rotate,0);
78 if(*rotate)*p2=DoRotation(*p2,0,-*rotate,0);
80 for (j=0;j<TriangleNum;j++){
81 intersecting=LineFacetd(p1,p2,&vertex[Triangles[j].vertex[0]],&vertex[Triangles[j].vertex[1]],&vertex[Triangles[j].vertex[2]],&facenormals[j],&point);
82 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);
83 if((distance<olddistance||firstintersecting==-1)&&intersecting){olddistance=distance; firstintersecting=j;}
86 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)));
87 *p2-=facenormals[firstintersecting]*distance;
89 if(*rotate)*p2=DoRotation(*p2,0,*rotate,0);
91 return firstintersecting;
94 int Model::LineCheckPossible(XYZ *p1,XYZ *p2, XYZ *p, XYZ *move, float *rotate)
97 static float distance;
98 static float olddistance;
99 static int intersecting;
100 static int firstintersecting;
105 if(!sphere_line_intersection(p1,p2,&boundingspherecenter,
106 &boundingsphereradius))return -1;
107 firstintersecting=-1;
108 if(*rotate)*p1=DoRotation(*p1,0,-*rotate,0);
109 if(*rotate)*p2=DoRotation(*p2,0,-*rotate,0);
111 if(numpossible>0&&numpossible<TriangleNum)
112 for (j=0;j<numpossible;j++){
113 if(possible[j]>=0&&possible[j]<TriangleNum){
114 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);
115 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);
116 if((distance<olddistance||firstintersecting==-1)&&intersecting){olddistance=distance; firstintersecting=possible[j]; *p=point;}
120 if(*rotate)*p=DoRotation(*p,0,*rotate,0);
122 return firstintersecting;
125 int Model::LineCheckSlidePossible(XYZ *p1,XYZ *p2, XYZ *p, XYZ *move, float *rotate)
128 static float distance;
129 static float olddistance;
130 static int intersecting;
131 static int firstintersecting;
136 if(!sphere_line_intersection(p1,p2,&boundingspherecenter,
137 &boundingsphereradius))return -1;
138 firstintersecting=-1;
139 if(*rotate)*p1=DoRotation(*p1,0,-*rotate,0);
140 if(*rotate)*p2=DoRotation(*p2,0,-*rotate,0);
143 for (j=0;j<numpossible;j++){
144 if(possible[j]>=0&&possible[j]<TriangleNum){
145 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);
146 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);
147 if((distance<olddistance||firstintersecting==-1)&&intersecting){olddistance=distance; firstintersecting=possible[j];}
151 if(firstintersecting>0){
152 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)));
153 *p2-=facenormals[firstintersecting]*distance;
156 if(*rotate)*p2=DoRotation(*p2,0,*rotate,0);
158 return firstintersecting;
161 int Model::SphereCheck(XYZ *p1,float radius, XYZ *p, XYZ *move, float *rotate)
164 static float distance;
165 static float olddistance;
166 static int intersecting;
167 static int firstintersecting;
170 static XYZ start,end;
172 firstintersecting=-1;
176 if(*rotate)*p1=DoRotation(*p1,0,-*rotate,0);
177 if(findDistancefast(p1,&boundingspherecenter)>radius*radius+boundingsphereradius*boundingsphereradius)return -1;
180 for (j=0;j<TriangleNum;j++){
182 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)));
184 point=*p1-facenormals[j]*distance;
185 if(PointInTriangle( &point, facenormals[j], &vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[1]], &vertex[Triangles[j].vertex[2]]))intersecting=1;
186 if(!intersecting)intersecting=sphere_line_intersection(&vertex[Triangles[j].vertex[0]],
187 &vertex[Triangles[j].vertex[1]],
189 if(!intersecting)intersecting=sphere_line_intersection(&vertex[Triangles[j].vertex[1]],
190 &vertex[Triangles[j].vertex[2]],
192 if(!intersecting)intersecting=sphere_line_intersection(&vertex[Triangles[j].vertex[0]],
193 &vertex[Triangles[j].vertex[2]],
196 *p1+=facenormals[j]*(distance-radius);
200 if(LineFacetd(&start,&end,&vertex[Triangles[j].vertex[0]],&vertex[Triangles[j].vertex[1]],&vertex[Triangles[j].vertex[2]],&facenormals[j],&point)){
201 p1->y=point.y+radius;
205 if((distance<olddistance||firstintersecting==-1)&&intersecting){olddistance=distance; firstintersecting=j; *p=point;}
208 if(*rotate)*p=DoRotation(*p,0,*rotate,0);
210 if(*rotate)*p1=DoRotation(*p1,0,*rotate,0);
212 return firstintersecting;
215 int Model::SphereCheckPossible(XYZ *p1,float radius, XYZ *move, float *rotate)
218 static float distance;
219 static float olddistance;
220 static int intersecting;
221 static int firstintersecting;
224 static XYZ start,end;
226 firstintersecting=-1;
233 if(*rotate)*p1=DoRotation(*p1,0,-*rotate,0);
234 if(findDistancefast(p1,&boundingspherecenter)>radius*radius+boundingsphereradius*boundingsphereradius){*p1=oldp1; return -1;}
236 for (j=0;j<TriangleNum;j++){
238 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)));
240 point=*p1-facenormals[j]*distance;
241 if(PointInTriangle( &point, facenormals[j], &vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[1]], &vertex[Triangles[j].vertex[2]]))intersecting=1;
242 if(!intersecting)intersecting=sphere_line_intersection(&vertex[Triangles[j].vertex[0]],
243 &vertex[Triangles[j].vertex[1]],
245 if(!intersecting)intersecting=sphere_line_intersection(&vertex[Triangles[j].vertex[1]],
246 &vertex[Triangles[j].vertex[2]],
248 if(!intersecting)intersecting=sphere_line_intersection(&vertex[Triangles[j].vertex[0]],
249 &vertex[Triangles[j].vertex[2]],
252 //if(j>=0&&j<TriangleNum)
253 possible[numpossible]=j;
257 if((distance<olddistance||firstintersecting==-1)&&intersecting){olddistance=distance; firstintersecting=j;}
259 if(*rotate)*p1=DoRotation(*p1,0,*rotate,0);
261 return firstintersecting;
265 void Model::UpdateVertexArray(){
266 if(type!=normaltype&&type!=decalstype)return;
270 for(i=0;i<TriangleNum;i++){
272 vArray[j+0]=Triangles[i].gx[0];
273 vArray[j+1]=Triangles[i].gy[0];
274 vArray[j+2]=normals[Triangles[i].vertex[0]].x;
275 vArray[j+3]=normals[Triangles[i].vertex[0]].y;
276 vArray[j+4]=normals[Triangles[i].vertex[0]].z;
277 vArray[j+5]=vertex[Triangles[i].vertex[0]].x;
278 vArray[j+6]=vertex[Triangles[i].vertex[0]].y;
279 vArray[j+7]=vertex[Triangles[i].vertex[0]].z;
281 vArray[j+8]=Triangles[i].gx[1];
282 vArray[j+9]=Triangles[i].gy[1];
283 vArray[j+10]=normals[Triangles[i].vertex[1]].x;
284 vArray[j+11]=normals[Triangles[i].vertex[1]].y;
285 vArray[j+12]=normals[Triangles[i].vertex[1]].z;
286 vArray[j+13]=vertex[Triangles[i].vertex[1]].x;
287 vArray[j+14]=vertex[Triangles[i].vertex[1]].y;
288 vArray[j+15]=vertex[Triangles[i].vertex[1]].z;
290 vArray[j+16]=Triangles[i].gx[2];
291 vArray[j+17]=Triangles[i].gy[2];
292 vArray[j+18]=normals[Triangles[i].vertex[2]].x;
293 vArray[j+19]=normals[Triangles[i].vertex[2]].y;
294 vArray[j+20]=normals[Triangles[i].vertex[2]].z;
295 vArray[j+21]=vertex[Triangles[i].vertex[2]].x;
296 vArray[j+22]=vertex[Triangles[i].vertex[2]].y;
297 vArray[j+23]=vertex[Triangles[i].vertex[2]].z;
300 for(i=0;i<TriangleNum;i++){
302 vArray[j+0]=Triangles[i].gx[0];
303 vArray[j+1]=Triangles[i].gy[0];
304 vArray[j+2]=facenormals[i].x*-1;
305 vArray[j+3]=facenormals[i].y*-1;
306 vArray[j+4]=facenormals[i].z*-1;
307 vArray[j+5]=vertex[Triangles[i].vertex[0]].x;
308 vArray[j+6]=vertex[Triangles[i].vertex[0]].y;
309 vArray[j+7]=vertex[Triangles[i].vertex[0]].z;
311 vArray[j+8]=Triangles[i].gx[1];
312 vArray[j+9]=Triangles[i].gy[1];
313 vArray[j+10]=facenormals[i].x*-1;
314 vArray[j+11]=facenormals[i].y*-1;
315 vArray[j+12]=facenormals[i].z*-1;
316 vArray[j+13]=vertex[Triangles[i].vertex[1]].x;
317 vArray[j+14]=vertex[Triangles[i].vertex[1]].y;
318 vArray[j+15]=vertex[Triangles[i].vertex[1]].z;
320 vArray[j+16]=Triangles[i].gx[2];
321 vArray[j+17]=Triangles[i].gy[2];
322 vArray[j+18]=facenormals[i].x*-1;
323 vArray[j+19]=facenormals[i].y*-1;
324 vArray[j+20]=facenormals[i].z*-1;
325 vArray[j+21]=vertex[Triangles[i].vertex[2]].x;
326 vArray[j+22]=vertex[Triangles[i].vertex[2]].y;
327 vArray[j+23]=vertex[Triangles[i].vertex[2]].z;
332 void Model::UpdateVertexArrayNoTex(){
333 if(type!=normaltype&&type!=decalstype)return;
337 for(i=0;i<TriangleNum;i++){
339 vArray[j+2]=normals[Triangles[i].vertex[0]].x;
340 vArray[j+3]=normals[Triangles[i].vertex[0]].y;
341 vArray[j+4]=normals[Triangles[i].vertex[0]].z;
342 vArray[j+5]=vertex[Triangles[i].vertex[0]].x;
343 vArray[j+6]=vertex[Triangles[i].vertex[0]].y;
344 vArray[j+7]=vertex[Triangles[i].vertex[0]].z;
346 vArray[j+10]=normals[Triangles[i].vertex[1]].x;
347 vArray[j+11]=normals[Triangles[i].vertex[1]].y;
348 vArray[j+12]=normals[Triangles[i].vertex[1]].z;
349 vArray[j+13]=vertex[Triangles[i].vertex[1]].x;
350 vArray[j+14]=vertex[Triangles[i].vertex[1]].y;
351 vArray[j+15]=vertex[Triangles[i].vertex[1]].z;
353 vArray[j+18]=normals[Triangles[i].vertex[2]].x;
354 vArray[j+19]=normals[Triangles[i].vertex[2]].y;
355 vArray[j+20]=normals[Triangles[i].vertex[2]].z;
356 vArray[j+21]=vertex[Triangles[i].vertex[2]].x;
357 vArray[j+22]=vertex[Triangles[i].vertex[2]].y;
358 vArray[j+23]=vertex[Triangles[i].vertex[2]].z;
361 for(i=0;i<TriangleNum;i++){
363 vArray[j+2]=facenormals[i].x*-1;
364 vArray[j+3]=facenormals[i].y*-1;
365 vArray[j+4]=facenormals[i].z*-1;
366 vArray[j+5]=vertex[Triangles[i].vertex[0]].x;
367 vArray[j+6]=vertex[Triangles[i].vertex[0]].y;
368 vArray[j+7]=vertex[Triangles[i].vertex[0]].z;
370 vArray[j+10]=facenormals[i].x*-1;
371 vArray[j+11]=facenormals[i].y*-1;
372 vArray[j+12]=facenormals[i].z*-1;
373 vArray[j+13]=vertex[Triangles[i].vertex[1]].x;
374 vArray[j+14]=vertex[Triangles[i].vertex[1]].y;
375 vArray[j+15]=vertex[Triangles[i].vertex[1]].z;
377 vArray[j+18]=facenormals[i].x*-1;
378 vArray[j+19]=facenormals[i].y*-1;
379 vArray[j+20]=facenormals[i].z*-1;
380 vArray[j+21]=vertex[Triangles[i].vertex[2]].x;
381 vArray[j+22]=vertex[Triangles[i].vertex[2]].y;
382 vArray[j+23]=vertex[Triangles[i].vertex[2]].z;
386 void Model::UpdateVertexArrayNoTexNoNorm(){
387 if(type!=normaltype&&type!=decalstype)return;
390 for(i=0;i<TriangleNum;i++){
392 vArray[j+5]=vertex[Triangles[i].vertex[0]].x;
393 vArray[j+6]=vertex[Triangles[i].vertex[0]].y;
394 vArray[j+7]=vertex[Triangles[i].vertex[0]].z;
396 vArray[j+13]=vertex[Triangles[i].vertex[1]].x;
397 vArray[j+14]=vertex[Triangles[i].vertex[1]].y;
398 vArray[j+15]=vertex[Triangles[i].vertex[1]].z;
400 vArray[j+21]=vertex[Triangles[i].vertex[2]].x;
401 vArray[j+22]=vertex[Triangles[i].vertex[2]].y;
402 vArray[j+23]=vertex[Triangles[i].vertex[2]].z;
406 bool Model::loadnotex(const char *filename )
411 int oldvertexNum,oldTriangleNum;
412 oldvertexNum=vertexNum;
413 oldTriangleNum=TriangleNum;
418 tfile=fopen( ConvertFileName(filename), "rb" );
419 // read model settings
421 fseek(tfile, 0, SEEK_SET);
422 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
424 // read the model data
429 owner = (int*)malloc(sizeof(int)*vertexNum);
430 possible = (int*)malloc(sizeof(int)*TriangleNum);
431 vertex = (XYZ*)malloc(sizeof(XYZ)*vertexNum);
432 Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle)*TriangleNum);
433 vArray = (GLfloat*)malloc(sizeof(GLfloat)*TriangleNum*24);
435 for(i=0;i<vertexNum;i++){
436 funpackf(tfile, "Bf Bf Bf", &vertex[i].x,&vertex[i].y,&vertex[i].z);
439 for(i=0;i<TriangleNum;i++){
440 // funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
442 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
443 Triangles[i].vertex[ 0] = vertex[ 0];
444 Triangles[i].vertex[ 1] = vertex[ 2];
445 Triangles[i].vertex[ 2] = vertex[ 4];
446 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
447 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
454 for(i=0;i<vertexNum;i++){
459 boundingsphereradius=0;
460 for(i=0;i<vertexNum;i++){
461 for(j=0;j<vertexNum;j++){
462 if(j!=i&&findDistancefast(&vertex[j],&vertex[i])/2>boundingsphereradius){
463 boundingsphereradius=findDistancefast(&vertex[j],&vertex[i])/2;
464 boundingspherecenter=(vertex[i]+vertex[j])/2;
468 boundingsphereradius=fast_sqrt(boundingsphereradius);
474 bool Model::load(const char *filename,bool texture )
481 LOG(std::string("Loading model...") + filename);
484 pgame->LoadingScreen();
486 int oldvertexNum,oldTriangleNum;
487 oldvertexNum=vertexNum;
488 oldTriangleNum=TriangleNum;
493 tfile=fopen( ConvertFileName(filename), "rb" );
494 // read model settings
497 fseek(tfile, 0, SEEK_SET);
498 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
500 // read the model data
505 owner = (int*)malloc(sizeof(int)*vertexNum);
506 possible = (int*)malloc(sizeof(int)*TriangleNum);
507 vertex = (XYZ*)malloc(sizeof(XYZ)*vertexNum);
508 normals = (XYZ*)malloc(sizeof(XYZ)*vertexNum);
509 facenormals = (XYZ*)malloc(sizeof(XYZ)*TriangleNum);
510 Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle)*TriangleNum);
511 vArray = (GLfloat*)malloc(sizeof(GLfloat)*TriangleNum*24);
513 for(i=0;i<vertexNum;i++){
514 funpackf(tfile, "Bf Bf Bf", &vertex[i].x,&vertex[i].y,&vertex[i].z);
517 for(i=0;i<TriangleNum;i++){
518 // funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
520 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
521 Triangles[i].vertex[ 0] = vertex[ 0];
522 Triangles[i].vertex[ 1] = vertex[ 2];
523 Triangles[i].vertex[ 2] = vertex[ 4];
524 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
525 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
534 for(i=0;i<vertexNum;i++){
539 boundingsphereradius=0;
540 for(i=0;i<vertexNum;i++){
541 for(j=0;j<vertexNum;j++){
542 if(j!=i&&findDistancefast(&vertex[j],&vertex[i])/2>boundingsphereradius){
543 boundingsphereradius=findDistancefast(&vertex[j],&vertex[i])/2;
544 boundingspherecenter=(vertex[i]+vertex[j])/2;
548 boundingsphereradius=fast_sqrt(boundingsphereradius);
553 bool Model::loaddecal(const char *filename,bool texture )
560 // Changing the filename so that its more os specific
561 char * FixedFN = ConvertFileName(filename);
563 LOG(std::string("Loading decal...") + FixedFN);
565 int oldvertexNum,oldTriangleNum;
566 oldvertexNum=vertexNum;
567 oldTriangleNum=TriangleNum;
573 tfile=fopen( FixedFN, "rb" );
574 // read model settings
577 fseek(tfile, 0, SEEK_SET);
578 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
580 // read the model data
586 owner = (int*)malloc(sizeof(int)*vertexNum);
587 possible = (int*)malloc(sizeof(int)*TriangleNum);
588 vertex = (XYZ*)malloc(sizeof(XYZ)*vertexNum);
589 normals = (XYZ*)malloc(sizeof(XYZ)*vertexNum);
590 facenormals = (XYZ*)malloc(sizeof(XYZ)*TriangleNum);
591 Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle)*TriangleNum);
592 vArray = (GLfloat*)malloc(sizeof(GLfloat)*TriangleNum*24);
595 for(i=0;i<vertexNum;i++){
596 funpackf(tfile, "Bf Bf Bf", &vertex[i].x,&vertex[i].y,&vertex[i].z);
599 for(i=0;i<TriangleNum;i++){
600 // funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
602 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
603 Triangles[i].vertex[ 0] = vertex[ 0];
604 Triangles[i].vertex[ 1] = vertex[ 2];
605 Triangles[i].vertex[ 2] = vertex[ 4];
606 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
607 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
617 for(i=0;i<vertexNum;i++){
621 boundingsphereradius=0;
622 for(i=0;i<vertexNum;i++){
623 for(j=0;j<vertexNum;j++){
624 if(j!=i&&findDistancefast(&vertex[j],&vertex[i])/2>boundingsphereradius){
625 boundingsphereradius=findDistancefast(&vertex[j],&vertex[i])/2;
626 boundingspherecenter=(vertex[i]+vertex[j])/2;
630 boundingsphereradius=fast_sqrt(boundingsphereradius);
634 decaltexcoords = (float***)malloc(sizeof(float**)*max_model_decals);
635 for(i=0;i<max_model_decals;i++){
636 decaltexcoords[i] = (float**)malloc(sizeof(float*)*3);
638 decaltexcoords[i][j] = (float*)malloc(sizeof(float)*2);
641 //if(decalvertex)free(decalvertex);
642 decalvertex = (XYZ**)malloc(sizeof(XYZ*)*max_model_decals);
643 for(i=0;i<max_model_decals;i++){
644 decalvertex[i] = (XYZ*)malloc(sizeof(XYZ)*3);
647 decaltype = (int*)malloc(sizeof(int)*max_model_decals);
648 decalopacity = (float*)malloc(sizeof(float)*max_model_decals);
649 decalrotation = (float*)malloc(sizeof(float)*max_model_decals);
650 decalalivetime = (float*)malloc(sizeof(float)*max_model_decals);
651 decalposition = (XYZ*)malloc(sizeof(XYZ)*max_model_decals);
657 bool Model::loadraw(char *filename )
664 LOG(std::string("Loading raw...") + filename);
666 int oldvertexNum,oldTriangleNum;
667 oldvertexNum=vertexNum;
668 oldTriangleNum=TriangleNum;
673 tfile=fopen( ConvertFileName(filename), "rb" );
674 // read model settings
677 fseek(tfile, 0, SEEK_SET);
678 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
680 // read the model data
685 owner = (int*)malloc(sizeof(int)*vertexNum);
686 possible = (int*)malloc(sizeof(int)*TriangleNum);
687 vertex = (XYZ*)malloc(sizeof(XYZ)*vertexNum);
688 Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle)*TriangleNum);
689 vArray = (GLfloat*)malloc(sizeof(GLfloat)*TriangleNum*24);
692 for(i=0;i<vertexNum;i++){
693 funpackf(tfile, "Bf Bf Bf", &vertex[i].x,&vertex[i].y,&vertex[i].z);
696 for(i=0;i<TriangleNum;i++){
697 // funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
699 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
700 Triangles[i].vertex[ 0] = vertex[ 0];
701 Triangles[i].vertex[ 1] = vertex[ 2];
702 Triangles[i].vertex[ 2] = vertex[ 4];
703 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
704 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
710 for(i=0;i<vertexNum;i++){
718 void Model::UniformTexCoords()
721 for(i=0; i<TriangleNum; i++){
722 Triangles[i].gy[0]=vertex[Triangles[i].vertex[0]].y;
723 Triangles[i].gy[1]=vertex[Triangles[i].vertex[1]].y;
724 Triangles[i].gy[2]=vertex[Triangles[i].vertex[2]].y;
725 Triangles[i].gx[0]=vertex[Triangles[i].vertex[0]].x;
726 Triangles[i].gx[1]=vertex[Triangles[i].vertex[1]].x;
727 Triangles[i].gx[2]=vertex[Triangles[i].vertex[2]].x;
733 void Model::FlipTexCoords()
736 for(i=0; i<TriangleNum; i++){
737 Triangles[i].gy[0]=-Triangles[i].gy[0];
738 Triangles[i].gy[1]=-Triangles[i].gy[1];
739 Triangles[i].gy[2]=-Triangles[i].gy[2];
744 void Model::ScaleTexCoords(float howmuch)
747 for(i=0; i<TriangleNum; i++){
748 Triangles[i].gx[0]*=howmuch;
749 Triangles[i].gx[1]*=howmuch;
750 Triangles[i].gx[2]*=howmuch;
751 Triangles[i].gy[0]*=howmuch;
752 Triangles[i].gy[1]*=howmuch;
753 Triangles[i].gy[2]*=howmuch;
758 void Model::Scale(float xscale,float yscale,float zscale)
761 for(i=0; i<vertexNum; i++){
770 boundingsphereradius=0;
771 for(i=0;i<vertexNum;i++){
772 for(j=0;j<vertexNum;j++){
773 if(j!=i&&findDistancefast(&vertex[j],&vertex[i])/2>boundingsphereradius){
774 boundingsphereradius=findDistancefast(&vertex[j],&vertex[i])/2;
775 boundingspherecenter=(vertex[i]+vertex[j])/2;
779 boundingsphereradius=fast_sqrt(boundingsphereradius);
782 void Model::ScaleNormals(float xscale,float yscale,float zscale)
784 if(type!=normaltype&&type!=decalstype)return;
786 for(i=0; i<vertexNum; i++){
787 normals[i].x*=xscale;
788 normals[i].y*=yscale;
789 normals[i].z*=zscale;
791 for(i=0; i<TriangleNum; i++){
792 facenormals[i].x*=xscale;
793 facenormals[i].y*=yscale;
794 facenormals[i].z*=zscale;
799 void Model::Translate(float xtrans,float ytrans,float ztrans)
802 for(i=0; i<vertexNum; i++){
810 boundingsphereradius=0;
811 for(i=0;i<vertexNum;i++){
812 for(j=0;j<vertexNum;j++){
813 if(j!=i&&findDistancefast(&vertex[j],&vertex[i])/2>boundingsphereradius){
814 boundingsphereradius=findDistancefast(&vertex[j],&vertex[i])/2;
815 boundingspherecenter=(vertex[i]+vertex[j])/2;
819 boundingsphereradius=fast_sqrt(boundingsphereradius);
822 void Model::Rotate(float xang,float yang,float zang)
825 for(i=0; i<vertexNum; i++){
826 vertex[i]=DoRotation(vertex[i],xang,yang,zang);
831 boundingsphereradius=0;
832 for(i=0;i<vertexNum;i++){
833 for(j=0;j<vertexNum;j++){
834 if(j!=i&&findDistancefast(&vertex[j],&vertex[i])/2>boundingsphereradius){
835 boundingsphereradius=findDistancefast(&vertex[j],&vertex[i])/2;
836 boundingspherecenter=(vertex[i]+vertex[j])/2;
840 boundingsphereradius=fast_sqrt(boundingsphereradius);
844 void Model::CalculateNormals(bool facenormalise)
847 pgame->LoadingScreen();
849 if(type!=normaltype&&type!=decalstype)return;
851 for(i=0; i<vertexNum; i++){
857 for(i=0;i<TriangleNum;i++){
858 CrossProduct(vertex[Triangles[i].vertex[1]]-vertex[Triangles[i].vertex[0]],vertex[Triangles[i].vertex[2]]-vertex[Triangles[i].vertex[0]],&facenormals[i]);
860 normals[Triangles[i].vertex[0]].x+=facenormals[i].x;
861 normals[Triangles[i].vertex[0]].y+=facenormals[i].y;
862 normals[Triangles[i].vertex[0]].z+=facenormals[i].z;
864 normals[Triangles[i].vertex[1]].x+=facenormals[i].x;
865 normals[Triangles[i].vertex[1]].y+=facenormals[i].y;
866 normals[Triangles[i].vertex[1]].z+=facenormals[i].z;
868 normals[Triangles[i].vertex[2]].x+=facenormals[i].x;
869 normals[Triangles[i].vertex[2]].y+=facenormals[i].y;
870 normals[Triangles[i].vertex[2]].z+=facenormals[i].z;
871 if(facenormalise)Normalise(&facenormals[i]);
873 for(i=0; i<vertexNum; i++){
874 Normalise(&normals[i]);
877 UpdateVertexArrayNoTex();
880 void Model::drawimmediate()
882 glBindTexture(GL_TEXTURE_2D,(unsigned long)textureptr);
883 glBegin(GL_TRIANGLES);
884 for(int i=0;i<TriangleNum;i++){
885 /*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){
886 if(isnormal(vertex[Triangles[i].vertex[0]].x)&&isnormal(vertex[Triangles[i].vertex[0]].y)&&isnormal(vertex[Triangles[i].vertex[0]].z)
887 &&isnormal(vertex[Triangles[i].vertex[1]].x)&&isnormal(vertex[Triangles[i].vertex[1]].y)&&isnormal(vertex[Triangles[i].vertex[1]].z)
888 &&isnormal(vertex[Triangles[i].vertex[2]].x)&&isnormal(vertex[Triangles[i].vertex[2]].y)&&isnormal(vertex[Triangles[i].vertex[2]].z)){
890 glTexCoord2f(Triangles[i].gx[0],Triangles[i].gy[0]);
891 if(color)glColor3f(normals[Triangles[i].vertex[0]].x,normals[Triangles[i].vertex[0]].y,normals[Triangles[i].vertex[0]].z);
892 if(!color&&!flat)glNormal3f(normals[Triangles[i].vertex[0]].x,normals[Triangles[i].vertex[0]].y,normals[Triangles[i].vertex[0]].z);
893 if(!color&&flat)glNormal3f(facenormals[i].x,facenormals[i].y,facenormals[i].y);
894 glVertex3f(vertex[Triangles[i].vertex[0]].x,vertex[Triangles[i].vertex[0]].y,vertex[Triangles[i].vertex[0]].z);
896 glTexCoord2f(Triangles[i].gx[1],Triangles[i].gy[1]);
897 if(color)glColor3f(normals[Triangles[i].vertex[1]].x,normals[Triangles[i].vertex[1]].y,normals[Triangles[i].vertex[1]].z);
898 if(!color&&!flat)glNormal3f(normals[Triangles[i].vertex[1]].x,normals[Triangles[i].vertex[1]].y,normals[Triangles[i].vertex[1]].z);
899 if(!color&&flat)glNormal3f(facenormals[i].x,facenormals[i].y,facenormals[i].y);
900 glVertex3f(vertex[Triangles[i].vertex[1]].x,vertex[Triangles[i].vertex[1]].y,vertex[Triangles[i].vertex[1]].z);
902 glTexCoord2f(Triangles[i].gx[2],Triangles[i].gy[2]);
903 if(color)glColor3f(normals[Triangles[i].vertex[2]].x,normals[Triangles[i].vertex[2]].y,normals[Triangles[i].vertex[2]].z);
904 if(!color&&!flat)glNormal3f(normals[Triangles[i].vertex[2]].x,normals[Triangles[i].vertex[2]].y,normals[Triangles[i].vertex[2]].z);
905 if(!color&&flat)glNormal3f(facenormals[i].x,facenormals[i].y,facenormals[i].y);
906 glVertex3f(vertex[Triangles[i].vertex[2]].x,vertex[Triangles[i].vertex[2]].y,vertex[Triangles[i].vertex[2]].z);
915 if(type!=normaltype&&type!=decalstype)return;
917 glEnableClientState(GL_NORMAL_ARRAY);
918 glEnableClientState(GL_VERTEX_ARRAY);
919 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
921 if(!color)glInterleavedArrays( GL_T2F_N3F_V3F,8*sizeof(GLfloat),&vArray[0]);
922 if(color)glInterleavedArrays( GL_T2F_C3F_V3F,8*sizeof(GLfloat),&vArray[0]);
923 glBindTexture(GL_TEXTURE_2D,(unsigned long)textureptr);
926 glLockArraysEXT( 0, TriangleNum*3);
928 glDrawArrays(GL_TRIANGLES, 0, TriangleNum*3);
934 if(!color)glDisableClientState(GL_NORMAL_ARRAY);
935 if(color)glDisableClientState(GL_COLOR_ARRAY);
936 glDisableClientState(GL_VERTEX_ARRAY);
937 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
941 void Model::drawdifftex(GLuint texture)
943 glEnableClientState(GL_NORMAL_ARRAY);
944 glEnableClientState(GL_VERTEX_ARRAY);
945 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
946 if(!color)glInterleavedArrays( GL_T2F_N3F_V3F,8*sizeof(GLfloat),&vArray[0]);
947 if(color)glInterleavedArrays( GL_T2F_C3F_V3F,8*sizeof(GLfloat),&vArray[0]);
949 glBindTexture(GL_TEXTURE_2D,(unsigned long)texture);
950 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
951 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
955 glLockArraysEXT( 0, TriangleNum*3);
957 glDrawArrays(GL_TRIANGLES, 0, TriangleNum*3);
963 if(!color)glDisableClientState(GL_NORMAL_ARRAY);
964 if(color)glDisableClientState(GL_COLOR_ARRAY);
965 glDisableClientState(GL_VERTEX_ARRAY);
966 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
967 //drawdiffteximmediate(texture);
970 void Model::drawdiffteximmediate(GLuint texture)
972 glBindTexture(GL_TEXTURE_2D,(unsigned long)texture);
974 glBegin(GL_TRIANGLES);
975 for(int i=0;i<TriangleNum;i++){
976 /*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){
977 if(isnormal(vertex[Triangles[i].vertex[0]].x)&&isnormal(vertex[Triangles[i].vertex[0]].y)&&isnormal(vertex[Triangles[i].vertex[0]].z)
978 &&isnormal(vertex[Triangles[i].vertex[1]].x)&&isnormal(vertex[Triangles[i].vertex[1]].y)&&isnormal(vertex[Triangles[i].vertex[1]].z)
979 &&isnormal(vertex[Triangles[i].vertex[2]].x)&&isnormal(vertex[Triangles[i].vertex[2]].y)&&isnormal(vertex[Triangles[i].vertex[2]].z)){
980 */glTexCoord2f(Triangles[i].gx[0],Triangles[i].gy[0]);
981 if(color)glColor3f(normals[Triangles[i].vertex[0]].x,normals[Triangles[i].vertex[0]].y,normals[Triangles[i].vertex[0]].z);
982 if(!color&&!flat)glNormal3f(normals[Triangles[i].vertex[0]].x,normals[Triangles[i].vertex[0]].y,normals[Triangles[i].vertex[0]].z);
983 if(!color&&flat)glNormal3f(facenormals[i].x,facenormals[i].y,facenormals[i].y);
984 glVertex3f(vertex[Triangles[i].vertex[0]].x,vertex[Triangles[i].vertex[0]].y,vertex[Triangles[i].vertex[0]].z);
986 glTexCoord2f(Triangles[i].gx[1],Triangles[i].gy[1]);
987 if(color)glColor3f(normals[Triangles[i].vertex[1]].x,normals[Triangles[i].vertex[1]].y,normals[Triangles[i].vertex[1]].z);
988 if(!color&&!flat)glNormal3f(normals[Triangles[i].vertex[1]].x,normals[Triangles[i].vertex[1]].y,normals[Triangles[i].vertex[1]].z);
989 if(!color&&flat)glNormal3f(facenormals[i].x,facenormals[i].y,facenormals[i].y);
990 glVertex3f(vertex[Triangles[i].vertex[1]].x,vertex[Triangles[i].vertex[1]].y,vertex[Triangles[i].vertex[1]].z);
992 glTexCoord2f(Triangles[i].gx[2],Triangles[i].gy[2]);
993 if(color)glColor3f(normals[Triangles[i].vertex[2]].x,normals[Triangles[i].vertex[2]].y,normals[Triangles[i].vertex[2]].z);
994 if(!color&&!flat)glNormal3f(normals[Triangles[i].vertex[2]].x,normals[Triangles[i].vertex[2]].y,normals[Triangles[i].vertex[2]].z);
995 if(!color&&flat)glNormal3f(facenormals[i].x,facenormals[i].y,facenormals[i].y);
996 glVertex3f(vertex[Triangles[i].vertex[2]].x,vertex[Triangles[i].vertex[2]].y,vertex[Triangles[i].vertex[2]].z);
1003 void Model::drawdecals(GLuint shadowtexture,GLuint bloodtexture,GLuint bloodtexture2,GLuint breaktexture)
1006 if(type!=decalstype)return;
1008 static float distancemult;
1009 static int lasttype;
1010 static float viewdistsquared;
1013 viewdistsquared=viewdistance*viewdistance;
1018 glDisable(GL_LIGHTING);
1019 glDisable(GL_CULL_FACE);
1020 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1022 if(numdecals>max_model_decals)numdecals=max_model_decals;
1023 for(i=0;i<numdecals;i++){
1024 if(decaltype[i]==blooddecalfast&&decalalivetime[i]<2)decalalivetime[i]=2;
1026 if(decaltype[i]==shadowdecal&&decaltype[i]!=lasttype){
1027 glBindTexture( GL_TEXTURE_2D, shadowtexture);
1030 glAlphaFunc(GL_GREATER, 0.0001);
1031 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1034 if(decaltype[i]==breakdecal&&decaltype[i]!=lasttype){
1035 glBindTexture( GL_TEXTURE_2D, breaktexture);
1038 glAlphaFunc(GL_GREATER, 0.0001);
1039 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1042 if((decaltype[i]==blooddecal||decaltype[i]==blooddecalslow)&&decaltype[i]!=lasttype){
1043 glBindTexture( GL_TEXTURE_2D, bloodtexture);
1046 glAlphaFunc(GL_GREATER, 0.15);
1047 glBlendFunc(GL_ONE,GL_ZERO);
1050 if((decaltype[i]==blooddecalfast)&&decaltype[i]!=lasttype){
1051 glBindTexture( GL_TEXTURE_2D, bloodtexture2);
1054 glAlphaFunc(GL_GREATER, 0.15);
1055 glBlendFunc(GL_ONE,GL_ZERO);
1058 if(decaltype[i]==shadowdecal){
1059 glColor4f(1,1,1,decalopacity[i]);
1061 if(decaltype[i]==breakdecal){
1062 glColor4f(1,1,1,decalopacity[i]);
1063 if(decalalivetime[i]>58)glColor4f(1,1,1,decalopacity[i]*(60-decalalivetime[i])/2);
1065 if((decaltype[i]==blooddecal||decaltype[i]==blooddecalfast||decaltype[i]==blooddecalslow)){
1066 glColor4f(1,1,1,decalopacity[i]);
1067 if(decalalivetime[i]<4)glColor4f(1,1,1,decalopacity[i]*decalalivetime[i]*.25);
1068 if(decalalivetime[i]>58)glColor4f(1,1,1,decalopacity[i]*(60-decalalivetime[i])/2);
1070 lasttype=decaltype[i];
1071 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1072 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
1074 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
1076 glBegin(GL_TRIANGLES);
1077 for(int j=0;j<3;j++)
1079 glTexCoord2f(decaltexcoords[i][j][0], decaltexcoords[i][j][1]); glVertex3f(decalvertex[i][j].x,decalvertex[i][j].y,decalvertex[i][j].z);
1084 for(i=numdecals-1;i>=0;i--){
1085 decalalivetime[i]+=multiplier;
1086 if(decaltype[i]==blooddecalslow)decalalivetime[i]-=multiplier*2/3;
1087 if(decaltype[i]==blooddecalfast)decalalivetime[i]+=multiplier*4;
1088 if(decaltype[i]==shadowdecal)DeleteDecal(i);
1089 if((decaltype[i]==blooddecal||decaltype[i]==blooddecalfast||decaltype[i]==blooddecalslow)&&decalalivetime[i]>=60)DeleteDecal(i);
1091 glAlphaFunc(GL_GREATER, 0.0001);
1092 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1096 void Model::DeleteDecal(int which)
1099 if(type!=decalstype)return;
1100 decaltype[which]=decaltype[numdecals-1];
1101 decalposition[which]=decalposition[numdecals-1];
1102 for(int i=0;i<3;i++){
1103 decalvertex[which][i]=decalvertex[numdecals-1][i];
1104 decaltexcoords[which][i][0]=decaltexcoords[numdecals-1][i][0];
1105 decaltexcoords[which][i][1]=decaltexcoords[numdecals-1][i][1];
1107 decalrotation[which]=decalrotation[numdecals-1];
1108 decalalivetime[which]=decalalivetime[numdecals-1];
1109 decalopacity[which]=decalopacity[numdecals-1];
1114 void Model::MakeDecal(int atype, XYZ *where,float *size, float *opacity, float *rotation){
1116 if(type!=decalstype)return;
1118 static float placex,placez;
1120 //static XYZ point,point1,point2;
1121 static float distance;
1125 if(findDistancefast(where,&boundingspherecenter)<(boundingsphereradius+*size)*(boundingsphereradius+*size))
1126 for(i=0;i<TriangleNum;i++){
1127 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)){
1128 decalposition[numdecals]=*where;
1129 decaltype[numdecals]=atype;
1130 decalrotation[numdecals]=*rotation;
1131 decalalivetime[numdecals]=0;
1132 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);
1133 decalopacity[numdecals]=*opacity-distance/10;
1135 if(decalopacity[numdecals>0]){
1136 placex=vertex[Triangles[i].vertex[0]].x;
1137 placez=vertex[Triangles[i].vertex[0]].z;
1139 decaltexcoords[numdecals][0][0]=(placex-where->x)/(*size)/2+.5;
1140 decaltexcoords[numdecals][0][1]=(placez-where->z)/(*size)/2+.5;
1142 decalvertex[numdecals][0].x=placex;
1143 decalvertex[numdecals][0].z=placez;
1144 decalvertex[numdecals][0].y=vertex[Triangles[i].vertex[0]].y;
1147 placex=vertex[Triangles[i].vertex[1]].x;
1148 placez=vertex[Triangles[i].vertex[1]].z;
1150 decaltexcoords[numdecals][1][0]=(placex-where->x)/(*size)/2+.5;
1151 decaltexcoords[numdecals][1][1]=(placez-where->z)/(*size)/2+.5;
1153 decalvertex[numdecals][1].x=placex;
1154 decalvertex[numdecals][1].z=placez;
1155 decalvertex[numdecals][1].y=vertex[Triangles[i].vertex[1]].y;
1158 placex=vertex[Triangles[i].vertex[2]].x;
1159 placez=vertex[Triangles[i].vertex[2]].z;
1161 decaltexcoords[numdecals][2][0]=(placex-where->x)/(*size)/2+.5;
1162 decaltexcoords[numdecals][2][1]=(placez-where->z)/(*size)/2+.5;
1164 decalvertex[numdecals][2].x=placex;
1165 decalvertex[numdecals][2].z=placez;
1166 decalvertex[numdecals][2].y=vertex[Triangles[i].vertex[2]].y;
1168 if(!(decaltexcoords[numdecals][0][0]<0&&decaltexcoords[numdecals][1][0]<0&&decaltexcoords[numdecals][2][0]<0))
1169 if(!(decaltexcoords[numdecals][0][1]<0&&decaltexcoords[numdecals][1][1]<0&&decaltexcoords[numdecals][2][1]<0))
1170 if(!(decaltexcoords[numdecals][0][0]>1&&decaltexcoords[numdecals][1][0]>1&&decaltexcoords[numdecals][2][0]>1))
1171 if(!(decaltexcoords[numdecals][0][1]>1&&decaltexcoords[numdecals][1][1]>1&&decaltexcoords[numdecals][2][1]>1))
1173 if(decalrotation[numdecals]){
1176 rot.x=decaltexcoords[numdecals][j][0]-.5;
1177 rot.z=decaltexcoords[numdecals][j][1]-.5;
1178 rot=DoRotation(rot,0,-decalrotation[numdecals],0);
1179 decaltexcoords[numdecals][j][0]=rot.x+.5;
1180 decaltexcoords[numdecals][j][1]=rot.z+.5;
1183 if(numdecals<max_model_decals-1)numdecals++;
1191 void Model::MakeDecal(int atype, XYZ where,float size, float opacity, float rotation){
1193 if(type!=decalstype)return;
1195 static float placex,placez;
1197 //static XYZ point,point1,point2;
1198 static float distance;
1202 if(findDistancefast(&where,&boundingspherecenter)<(boundingsphereradius+size)*(boundingsphereradius+size))
1203 for(i=0;i<TriangleNum;i++){
1204 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))));
1205 if(distance<.02&&abs(facenormals[i].y)>abs(facenormals[i].x)&&abs(facenormals[i].y)>abs(facenormals[i].z)){
1206 decalposition[numdecals]=where;
1207 decaltype[numdecals]=atype;
1208 decalrotation[numdecals]=rotation;
1209 decalalivetime[numdecals]=0;
1210 decalopacity[numdecals]=opacity-distance/10;
1212 if(decalopacity[numdecals>0]){
1213 placex=vertex[Triangles[i].vertex[0]].x;
1214 placez=vertex[Triangles[i].vertex[0]].z;
1216 decaltexcoords[numdecals][0][0]=(placex-where.x)/(size)/2+.5;
1217 decaltexcoords[numdecals][0][1]=(placez-where.z)/(size)/2+.5;
1219 decalvertex[numdecals][0].x=placex;
1220 decalvertex[numdecals][0].z=placez;
1221 decalvertex[numdecals][0].y=vertex[Triangles[i].vertex[0]].y;
1224 placex=vertex[Triangles[i].vertex[1]].x;
1225 placez=vertex[Triangles[i].vertex[1]].z;
1227 decaltexcoords[numdecals][1][0]=(placex-where.x)/(size)/2+.5;
1228 decaltexcoords[numdecals][1][1]=(placez-where.z)/(size)/2+.5;
1230 decalvertex[numdecals][1].x=placex;
1231 decalvertex[numdecals][1].z=placez;
1232 decalvertex[numdecals][1].y=vertex[Triangles[i].vertex[1]].y;
1235 placex=vertex[Triangles[i].vertex[2]].x;
1236 placez=vertex[Triangles[i].vertex[2]].z;
1238 decaltexcoords[numdecals][2][0]=(placex-where.x)/(size)/2+.5;
1239 decaltexcoords[numdecals][2][1]=(placez-where.z)/(size)/2+.5;
1241 decalvertex[numdecals][2].x=placex;
1242 decalvertex[numdecals][2].z=placez;
1243 decalvertex[numdecals][2].y=vertex[Triangles[i].vertex[2]].y;
1245 if(!(decaltexcoords[numdecals][0][0]<0&&decaltexcoords[numdecals][1][0]<0&&decaltexcoords[numdecals][2][0]<0))
1246 if(!(decaltexcoords[numdecals][0][1]<0&&decaltexcoords[numdecals][1][1]<0&&decaltexcoords[numdecals][2][1]<0))
1247 if(!(decaltexcoords[numdecals][0][0]>1&&decaltexcoords[numdecals][1][0]>1&&decaltexcoords[numdecals][2][0]>1))
1248 if(!(decaltexcoords[numdecals][0][1]>1&&decaltexcoords[numdecals][1][1]>1&&decaltexcoords[numdecals][2][1]>1))
1250 if(decalrotation[numdecals]){
1253 rot.x=decaltexcoords[numdecals][j][0]-.5;
1254 rot.z=decaltexcoords[numdecals][j][1]-.5;
1255 rot=DoRotation(rot,0,-decalrotation[numdecals],0);
1256 decaltexcoords[numdecals][j][0]=rot.x+.5;
1257 decaltexcoords[numdecals][j][1]=rot.z+.5;
1260 if(numdecals<max_model_decals-1)numdecals++;
1264 else if(distance<.02&&abs(facenormals[i].x)>abs(facenormals[i].y)&&abs(facenormals[i].x)>abs(facenormals[i].z)){
1265 decalposition[numdecals]=where;
1266 decaltype[numdecals]=atype;
1267 decalrotation[numdecals]=rotation;
1268 decalalivetime[numdecals]=0;
1269 decalopacity[numdecals]=opacity-distance/10;
1271 if(decalopacity[numdecals>0]){
1272 placex=vertex[Triangles[i].vertex[0]].y;
1273 placez=vertex[Triangles[i].vertex[0]].z;
1275 decaltexcoords[numdecals][0][0]=(placex-where.y)/(size)/2+.5;
1276 decaltexcoords[numdecals][0][1]=(placez-where.z)/(size)/2+.5;
1278 decalvertex[numdecals][0].x=vertex[Triangles[i].vertex[0]].x;
1279 decalvertex[numdecals][0].z=placez;
1280 decalvertex[numdecals][0].y=placex;
1283 placex=vertex[Triangles[i].vertex[1]].y;
1284 placez=vertex[Triangles[i].vertex[1]].z;
1286 decaltexcoords[numdecals][1][0]=(placex-where.y)/(size)/2+.5;
1287 decaltexcoords[numdecals][1][1]=(placez-where.z)/(size)/2+.5;
1289 decalvertex[numdecals][1].x=vertex[Triangles[i].vertex[1]].x;
1290 decalvertex[numdecals][1].z=placez;
1291 decalvertex[numdecals][1].y=placex;
1294 placex=vertex[Triangles[i].vertex[2]].y;
1295 placez=vertex[Triangles[i].vertex[2]].z;
1297 decaltexcoords[numdecals][2][0]=(placex-where.y)/(size)/2+.5;
1298 decaltexcoords[numdecals][2][1]=(placez-where.z)/(size)/2+.5;
1300 decalvertex[numdecals][2].x=vertex[Triangles[i].vertex[2]].x;
1301 decalvertex[numdecals][2].z=placez;
1302 decalvertex[numdecals][2].y=placex;
1304 if(!(decaltexcoords[numdecals][0][0]<0&&decaltexcoords[numdecals][1][0]<0&&decaltexcoords[numdecals][2][0]<0))
1305 if(!(decaltexcoords[numdecals][0][1]<0&&decaltexcoords[numdecals][1][1]<0&&decaltexcoords[numdecals][2][1]<0))
1306 if(!(decaltexcoords[numdecals][0][0]>1&&decaltexcoords[numdecals][1][0]>1&&decaltexcoords[numdecals][2][0]>1))
1307 if(!(decaltexcoords[numdecals][0][1]>1&&decaltexcoords[numdecals][1][1]>1&&decaltexcoords[numdecals][2][1]>1))
1309 if(decalrotation[numdecals]){
1312 rot.x=decaltexcoords[numdecals][j][0]-.5;
1313 rot.z=decaltexcoords[numdecals][j][1]-.5;
1314 rot=DoRotation(rot,0,-decalrotation[numdecals],0);
1315 decaltexcoords[numdecals][j][0]=rot.x+.5;
1316 decaltexcoords[numdecals][j][1]=rot.z+.5;
1319 if(numdecals<max_model_decals-1)numdecals++;
1323 else if(distance<.02&&abs(facenormals[i].z)>abs(facenormals[i].y)&&abs(facenormals[i].z)>abs(facenormals[i].x)){
1324 decalposition[numdecals]=where;
1325 decaltype[numdecals]=atype;
1326 decalrotation[numdecals]=rotation;
1327 decalalivetime[numdecals]=0;
1328 decalopacity[numdecals]=opacity-distance/10;
1330 if(decalopacity[numdecals>0]){
1331 placex=vertex[Triangles[i].vertex[0]].x;
1332 placez=vertex[Triangles[i].vertex[0]].y;
1334 decaltexcoords[numdecals][0][0]=(placex-where.x)/(size)/2+.5;
1335 decaltexcoords[numdecals][0][1]=(placez-where.y)/(size)/2+.5;
1337 decalvertex[numdecals][0].x=placex;
1338 decalvertex[numdecals][0].z=vertex[Triangles[i].vertex[0]].z;
1339 decalvertex[numdecals][0].y=placez;
1342 placex=vertex[Triangles[i].vertex[1]].x;
1343 placez=vertex[Triangles[i].vertex[1]].y;
1345 decaltexcoords[numdecals][1][0]=(placex-where.x)/(size)/2+.5;
1346 decaltexcoords[numdecals][1][1]=(placez-where.y)/(size)/2+.5;
1348 decalvertex[numdecals][1].x=placex;
1349 decalvertex[numdecals][1].z=vertex[Triangles[i].vertex[1]].z;
1350 decalvertex[numdecals][1].y=placez;
1353 placex=vertex[Triangles[i].vertex[2]].x;
1354 placez=vertex[Triangles[i].vertex[2]].y;
1356 decaltexcoords[numdecals][2][0]=(placex-where.x)/(size)/2+.5;
1357 decaltexcoords[numdecals][2][1]=(placez-where.y)/(size)/2+.5;
1359 decalvertex[numdecals][2].x=placex;
1360 decalvertex[numdecals][2].z=vertex[Triangles[i].vertex[2]].z;
1361 decalvertex[numdecals][2].y=placez;
1363 if(!(decaltexcoords[numdecals][0][0]<0&&decaltexcoords[numdecals][1][0]<0&&decaltexcoords[numdecals][2][0]<0))
1364 if(!(decaltexcoords[numdecals][0][1]<0&&decaltexcoords[numdecals][1][1]<0&&decaltexcoords[numdecals][2][1]<0))
1365 if(!(decaltexcoords[numdecals][0][0]>1&&decaltexcoords[numdecals][1][0]>1&&decaltexcoords[numdecals][2][0]>1))
1366 if(!(decaltexcoords[numdecals][0][1]>1&&decaltexcoords[numdecals][1][1]>1&&decaltexcoords[numdecals][2][1]>1))
1368 if(decalrotation[numdecals]){
1371 rot.x=decaltexcoords[numdecals][j][0]-.5;
1372 rot.z=decaltexcoords[numdecals][j][1]-.5;
1373 rot=DoRotation(rot,0,-decalrotation[numdecals],0);
1374 decaltexcoords[numdecals][j][0]=rot.x+.5;
1375 decaltexcoords[numdecals][j][1]=rot.z+.5;
1378 if(numdecals<max_model_decals-1)numdecals++;
1390 if(textureptr) glDeleteTextures( 1, &textureptr );
1393 void Model::deallocate()
1397 if(owner)free(owner);
1400 if(possible)free(possible);
1403 if(vertex)free(vertex);
1406 if(normals)free(normals);
1409 if(facenormals)free(facenormals);
1412 if(Triangles)free(Triangles);
1415 if(vArray)free(vArray);
1422 for(i=0;i<max_model_decals;i++)
1426 free(decaltexcoords[i][j]);
1428 free(decaltexcoords[i]);
1430 free(decaltexcoords);
1437 for(i=0;i<max_model_decals;i++)
1439 free(decalvertex[i]);
1452 free(decalrotation);
1455 free(decalalivetime);
1458 free(decalposition);
1465 vertexNum = 0,TriangleNum = 0;
1468 type = 0,oldtype = 0;
1479 memset(&Texture, 0, sizeof(Texture));
1483 boundingspherecenter = 0;
1484 boundingsphereradius = 0;