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;
32 extern bool visibleloading;
34 int Model::LineCheck(XYZ *p1,XYZ *p2, XYZ *p, XYZ *move, float *rotate)
37 static float distance;
38 static float olddistance;
39 static int intersecting;
40 static int firstintersecting;
45 if(*rotate)*p1=DoRotation(*p1,0,-*rotate,0);
46 if(*rotate)*p2=DoRotation(*p2,0,-*rotate,0);
47 if(!sphere_line_intersection(p1,p2,&boundingspherecenter,
48 &boundingsphereradius))return -1;
51 for (j=0;j<TriangleNum;j++){
52 intersecting=LineFacetd(p1,p2,&vertex[Triangles[j].vertex[0]],&vertex[Triangles[j].vertex[1]],&vertex[Triangles[j].vertex[2]],&facenormals[j],&point);
53 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);
54 if((distance<olddistance||firstintersecting==-1)&&intersecting){olddistance=distance; firstintersecting=j; *p=point;}
57 if(*rotate)*p=DoRotation(*p,0,*rotate,0);
59 return firstintersecting;
62 int Model::LineCheckSlide(XYZ *p1,XYZ *p2, XYZ *p, XYZ *move, float *rotate)
65 static float distance;
66 static float olddistance;
67 static int intersecting;
68 static int firstintersecting;
73 if(!sphere_line_intersection(p1,p2,&boundingspherecenter,
74 &boundingsphereradius))return -1;
76 if(*rotate)*p1=DoRotation(*p1,0,-*rotate,0);
77 if(*rotate)*p2=DoRotation(*p2,0,-*rotate,0);
79 for (j=0;j<TriangleNum;j++){
80 intersecting=LineFacetd(p1,p2,&vertex[Triangles[j].vertex[0]],&vertex[Triangles[j].vertex[1]],&vertex[Triangles[j].vertex[2]],&facenormals[j],&point);
81 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);
82 if((distance<olddistance||firstintersecting==-1)&&intersecting){olddistance=distance; firstintersecting=j;}
85 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)));
86 *p2-=facenormals[firstintersecting]*distance;
88 if(*rotate)*p2=DoRotation(*p2,0,*rotate,0);
90 return firstintersecting;
93 int Model::LineCheckPossible(XYZ *p1,XYZ *p2, XYZ *p, XYZ *move, float *rotate)
96 static float distance;
97 static float olddistance;
98 static int intersecting;
99 static int firstintersecting;
104 if(!sphere_line_intersection(p1,p2,&boundingspherecenter,
105 &boundingsphereradius))return -1;
106 firstintersecting=-1;
107 if(*rotate)*p1=DoRotation(*p1,0,-*rotate,0);
108 if(*rotate)*p2=DoRotation(*p2,0,-*rotate,0);
110 if(numpossible>0&&numpossible<TriangleNum)
111 for (j=0;j<numpossible;j++){
112 if(possible[j]>=0&&possible[j]<TriangleNum){
113 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);
114 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);
115 if((distance<olddistance||firstintersecting==-1)&&intersecting){olddistance=distance; firstintersecting=possible[j]; *p=point;}
119 if(*rotate)*p=DoRotation(*p,0,*rotate,0);
121 return firstintersecting;
124 int Model::LineCheckSlidePossible(XYZ *p1,XYZ *p2, XYZ *p, XYZ *move, float *rotate)
127 static float distance;
128 static float olddistance;
129 static int intersecting;
130 static int firstintersecting;
135 if(!sphere_line_intersection(p1,p2,&boundingspherecenter,
136 &boundingsphereradius))return -1;
137 firstintersecting=-1;
138 if(*rotate)*p1=DoRotation(*p1,0,-*rotate,0);
139 if(*rotate)*p2=DoRotation(*p2,0,-*rotate,0);
142 for (j=0;j<numpossible;j++){
143 if(possible[j]>=0&&possible[j]<TriangleNum){
144 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);
145 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);
146 if((distance<olddistance||firstintersecting==-1)&&intersecting){olddistance=distance; firstintersecting=possible[j];}
150 if(firstintersecting>0){
151 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)));
152 *p2-=facenormals[firstintersecting]*distance;
155 if(*rotate)*p2=DoRotation(*p2,0,*rotate,0);
157 return firstintersecting;
160 int Model::SphereCheck(XYZ *p1,float radius, XYZ *p, XYZ *move, float *rotate)
163 static float distance;
164 static float olddistance;
165 static int intersecting;
166 static int firstintersecting;
169 static XYZ start,end;
171 firstintersecting=-1;
175 if(*rotate)*p1=DoRotation(*p1,0,-*rotate,0);
176 if(findDistancefast(p1,&boundingspherecenter)>radius*radius+boundingsphereradius*boundingsphereradius)return -1;
179 for (j=0;j<TriangleNum;j++){
181 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)));
183 point=*p1-facenormals[j]*distance;
184 if(PointInTriangle( &point, facenormals[j], &vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[1]], &vertex[Triangles[j].vertex[2]]))intersecting=1;
185 if(!intersecting)intersecting=sphere_line_intersection(&vertex[Triangles[j].vertex[0]],
186 &vertex[Triangles[j].vertex[1]],
188 if(!intersecting)intersecting=sphere_line_intersection(&vertex[Triangles[j].vertex[1]],
189 &vertex[Triangles[j].vertex[2]],
191 if(!intersecting)intersecting=sphere_line_intersection(&vertex[Triangles[j].vertex[0]],
192 &vertex[Triangles[j].vertex[2]],
195 *p1+=facenormals[j]*(distance-radius);
199 if(LineFacetd(&start,&end,&vertex[Triangles[j].vertex[0]],&vertex[Triangles[j].vertex[1]],&vertex[Triangles[j].vertex[2]],&facenormals[j],&point)){
200 p1->y=point.y+radius;
204 if((distance<olddistance||firstintersecting==-1)&&intersecting){olddistance=distance; firstintersecting=j; *p=point;}
207 if(*rotate)*p=DoRotation(*p,0,*rotate,0);
209 if(*rotate)*p1=DoRotation(*p1,0,*rotate,0);
211 return firstintersecting;
214 int Model::SphereCheckPossible(XYZ *p1,float radius, XYZ *move, float *rotate)
217 static float distance;
218 static float olddistance;
219 static int intersecting;
220 static int firstintersecting;
223 static XYZ start,end;
225 firstintersecting=-1;
232 if(*rotate)*p1=DoRotation(*p1,0,-*rotate,0);
233 if(findDistancefast(p1,&boundingspherecenter)>radius*radius+boundingsphereradius*boundingsphereradius){*p1=oldp1; return -1;}
235 for (j=0;j<TriangleNum;j++){
237 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)));
239 point=*p1-facenormals[j]*distance;
240 if(PointInTriangle( &point, facenormals[j], &vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[1]], &vertex[Triangles[j].vertex[2]]))intersecting=1;
241 if(!intersecting)intersecting=sphere_line_intersection(&vertex[Triangles[j].vertex[0]],
242 &vertex[Triangles[j].vertex[1]],
244 if(!intersecting)intersecting=sphere_line_intersection(&vertex[Triangles[j].vertex[1]],
245 &vertex[Triangles[j].vertex[2]],
247 if(!intersecting)intersecting=sphere_line_intersection(&vertex[Triangles[j].vertex[0]],
248 &vertex[Triangles[j].vertex[2]],
251 //if(j>=0&&j<TriangleNum)
252 possible[numpossible]=j;
256 if((distance<olddistance||firstintersecting==-1)&&intersecting){olddistance=distance; firstintersecting=j;}
258 if(*rotate)*p1=DoRotation(*p1,0,*rotate,0);
260 return firstintersecting;
264 void Model::UpdateVertexArray(){
265 if(type!=normaltype&&type!=decalstype)return;
269 for(i=0;i<TriangleNum;i++){
271 vArray[j+0]=Triangles[i].gx[0];
272 vArray[j+1]=Triangles[i].gy[0];
273 vArray[j+2]=normals[Triangles[i].vertex[0]].x;
274 vArray[j+3]=normals[Triangles[i].vertex[0]].y;
275 vArray[j+4]=normals[Triangles[i].vertex[0]].z;
276 vArray[j+5]=vertex[Triangles[i].vertex[0]].x;
277 vArray[j+6]=vertex[Triangles[i].vertex[0]].y;
278 vArray[j+7]=vertex[Triangles[i].vertex[0]].z;
280 vArray[j+8]=Triangles[i].gx[1];
281 vArray[j+9]=Triangles[i].gy[1];
282 vArray[j+10]=normals[Triangles[i].vertex[1]].x;
283 vArray[j+11]=normals[Triangles[i].vertex[1]].y;
284 vArray[j+12]=normals[Triangles[i].vertex[1]].z;
285 vArray[j+13]=vertex[Triangles[i].vertex[1]].x;
286 vArray[j+14]=vertex[Triangles[i].vertex[1]].y;
287 vArray[j+15]=vertex[Triangles[i].vertex[1]].z;
289 vArray[j+16]=Triangles[i].gx[2];
290 vArray[j+17]=Triangles[i].gy[2];
291 vArray[j+18]=normals[Triangles[i].vertex[2]].x;
292 vArray[j+19]=normals[Triangles[i].vertex[2]].y;
293 vArray[j+20]=normals[Triangles[i].vertex[2]].z;
294 vArray[j+21]=vertex[Triangles[i].vertex[2]].x;
295 vArray[j+22]=vertex[Triangles[i].vertex[2]].y;
296 vArray[j+23]=vertex[Triangles[i].vertex[2]].z;
299 for(i=0;i<TriangleNum;i++){
301 vArray[j+0]=Triangles[i].gx[0];
302 vArray[j+1]=Triangles[i].gy[0];
303 vArray[j+2]=facenormals[i].x*-1;
304 vArray[j+3]=facenormals[i].y*-1;
305 vArray[j+4]=facenormals[i].z*-1;
306 vArray[j+5]=vertex[Triangles[i].vertex[0]].x;
307 vArray[j+6]=vertex[Triangles[i].vertex[0]].y;
308 vArray[j+7]=vertex[Triangles[i].vertex[0]].z;
310 vArray[j+8]=Triangles[i].gx[1];
311 vArray[j+9]=Triangles[i].gy[1];
312 vArray[j+10]=facenormals[i].x*-1;
313 vArray[j+11]=facenormals[i].y*-1;
314 vArray[j+12]=facenormals[i].z*-1;
315 vArray[j+13]=vertex[Triangles[i].vertex[1]].x;
316 vArray[j+14]=vertex[Triangles[i].vertex[1]].y;
317 vArray[j+15]=vertex[Triangles[i].vertex[1]].z;
319 vArray[j+16]=Triangles[i].gx[2];
320 vArray[j+17]=Triangles[i].gy[2];
321 vArray[j+18]=facenormals[i].x*-1;
322 vArray[j+19]=facenormals[i].y*-1;
323 vArray[j+20]=facenormals[i].z*-1;
324 vArray[j+21]=vertex[Triangles[i].vertex[2]].x;
325 vArray[j+22]=vertex[Triangles[i].vertex[2]].y;
326 vArray[j+23]=vertex[Triangles[i].vertex[2]].z;
331 void Model::UpdateVertexArrayNoTex(){
332 if(type!=normaltype&&type!=decalstype)return;
336 for(i=0;i<TriangleNum;i++){
338 vArray[j+2]=normals[Triangles[i].vertex[0]].x;
339 vArray[j+3]=normals[Triangles[i].vertex[0]].y;
340 vArray[j+4]=normals[Triangles[i].vertex[0]].z;
341 vArray[j+5]=vertex[Triangles[i].vertex[0]].x;
342 vArray[j+6]=vertex[Triangles[i].vertex[0]].y;
343 vArray[j+7]=vertex[Triangles[i].vertex[0]].z;
345 vArray[j+10]=normals[Triangles[i].vertex[1]].x;
346 vArray[j+11]=normals[Triangles[i].vertex[1]].y;
347 vArray[j+12]=normals[Triangles[i].vertex[1]].z;
348 vArray[j+13]=vertex[Triangles[i].vertex[1]].x;
349 vArray[j+14]=vertex[Triangles[i].vertex[1]].y;
350 vArray[j+15]=vertex[Triangles[i].vertex[1]].z;
352 vArray[j+18]=normals[Triangles[i].vertex[2]].x;
353 vArray[j+19]=normals[Triangles[i].vertex[2]].y;
354 vArray[j+20]=normals[Triangles[i].vertex[2]].z;
355 vArray[j+21]=vertex[Triangles[i].vertex[2]].x;
356 vArray[j+22]=vertex[Triangles[i].vertex[2]].y;
357 vArray[j+23]=vertex[Triangles[i].vertex[2]].z;
360 for(i=0;i<TriangleNum;i++){
362 vArray[j+2]=facenormals[i].x*-1;
363 vArray[j+3]=facenormals[i].y*-1;
364 vArray[j+4]=facenormals[i].z*-1;
365 vArray[j+5]=vertex[Triangles[i].vertex[0]].x;
366 vArray[j+6]=vertex[Triangles[i].vertex[0]].y;
367 vArray[j+7]=vertex[Triangles[i].vertex[0]].z;
369 vArray[j+10]=facenormals[i].x*-1;
370 vArray[j+11]=facenormals[i].y*-1;
371 vArray[j+12]=facenormals[i].z*-1;
372 vArray[j+13]=vertex[Triangles[i].vertex[1]].x;
373 vArray[j+14]=vertex[Triangles[i].vertex[1]].y;
374 vArray[j+15]=vertex[Triangles[i].vertex[1]].z;
376 vArray[j+18]=facenormals[i].x*-1;
377 vArray[j+19]=facenormals[i].y*-1;
378 vArray[j+20]=facenormals[i].z*-1;
379 vArray[j+21]=vertex[Triangles[i].vertex[2]].x;
380 vArray[j+22]=vertex[Triangles[i].vertex[2]].y;
381 vArray[j+23]=vertex[Triangles[i].vertex[2]].z;
385 void Model::UpdateVertexArrayNoTexNoNorm(){
386 if(type!=normaltype&&type!=decalstype)return;
389 for(i=0;i<TriangleNum;i++){
391 vArray[j+5]=vertex[Triangles[i].vertex[0]].x;
392 vArray[j+6]=vertex[Triangles[i].vertex[0]].y;
393 vArray[j+7]=vertex[Triangles[i].vertex[0]].z;
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+21]=vertex[Triangles[i].vertex[2]].x;
400 vArray[j+22]=vertex[Triangles[i].vertex[2]].y;
401 vArray[j+23]=vertex[Triangles[i].vertex[2]].z;
405 bool Model::loadnotex(const char *filename )
410 int oldvertexNum,oldTriangleNum;
411 oldvertexNum=vertexNum;
412 oldTriangleNum=TriangleNum;
417 tfile=fopen( ConvertFileName(filename), "rb" );
418 // read model settings
420 fseek(tfile, 0, SEEK_SET);
421 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
423 // read the model data
428 owner = (int*)malloc(sizeof(int)*vertexNum);
429 possible = (int*)malloc(sizeof(int)*TriangleNum);
430 vertex = (XYZ*)malloc(sizeof(XYZ)*vertexNum);
431 Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle)*TriangleNum);
432 vArray = (GLfloat*)malloc(sizeof(GLfloat)*TriangleNum*24);
434 for(i=0;i<vertexNum;i++){
435 funpackf(tfile, "Bf Bf Bf", &vertex[i].x,&vertex[i].y,&vertex[i].z);
438 for(i=0;i<TriangleNum;i++){
439 // funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
441 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
442 Triangles[i].vertex[ 0] = vertex[ 0];
443 Triangles[i].vertex[ 1] = vertex[ 2];
444 Triangles[i].vertex[ 2] = vertex[ 4];
445 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
446 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
453 for(i=0;i<vertexNum;i++){
458 boundingsphereradius=0;
459 for(i=0;i<vertexNum;i++){
460 for(j=0;j<vertexNum;j++){
461 if(j!=i&&findDistancefast(&vertex[j],&vertex[i])/2>boundingsphereradius){
462 boundingsphereradius=findDistancefast(&vertex[j],&vertex[i])/2;
463 boundingspherecenter=(vertex[i]+vertex[j])/2;
467 boundingsphereradius=fast_sqrt(boundingsphereradius);
473 bool Model::load(const char *filename,bool texture )
480 LOG(std::string("Loading model...") + filename);
483 Game::LoadingScreen();
485 int oldvertexNum,oldTriangleNum;
486 oldvertexNum=vertexNum;
487 oldTriangleNum=TriangleNum;
492 tfile=fopen( ConvertFileName(filename), "rb" );
493 // read model settings
496 fseek(tfile, 0, SEEK_SET);
497 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
499 // read the model data
504 owner = (int*)malloc(sizeof(int)*vertexNum);
505 possible = (int*)malloc(sizeof(int)*TriangleNum);
506 vertex = (XYZ*)malloc(sizeof(XYZ)*vertexNum);
507 normals = (XYZ*)malloc(sizeof(XYZ)*vertexNum);
508 facenormals = (XYZ*)malloc(sizeof(XYZ)*TriangleNum);
509 Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle)*TriangleNum);
510 vArray = (GLfloat*)malloc(sizeof(GLfloat)*TriangleNum*24);
512 for(i=0;i<vertexNum;i++){
513 funpackf(tfile, "Bf Bf Bf", &vertex[i].x,&vertex[i].y,&vertex[i].z);
516 for(i=0;i<TriangleNum;i++){
517 // funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
519 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
520 Triangles[i].vertex[ 0] = vertex[ 0];
521 Triangles[i].vertex[ 1] = vertex[ 2];
522 Triangles[i].vertex[ 2] = vertex[ 4];
523 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
524 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
533 for(i=0;i<vertexNum;i++){
538 boundingsphereradius=0;
539 for(i=0;i<vertexNum;i++){
540 for(j=0;j<vertexNum;j++){
541 if(j!=i&&findDistancefast(&vertex[j],&vertex[i])/2>boundingsphereradius){
542 boundingsphereradius=findDistancefast(&vertex[j],&vertex[i])/2;
543 boundingspherecenter=(vertex[i]+vertex[j])/2;
547 boundingsphereradius=fast_sqrt(boundingsphereradius);
552 bool Model::loaddecal(const char *filename,bool texture )
559 // Changing the filename so that its more os specific
560 char * FixedFN = ConvertFileName(filename);
562 LOG(std::string("Loading decal...") + FixedFN);
564 int oldvertexNum,oldTriangleNum;
565 oldvertexNum=vertexNum;
566 oldTriangleNum=TriangleNum;
572 tfile=fopen( FixedFN, "rb" );
573 // read model settings
576 fseek(tfile, 0, SEEK_SET);
577 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
579 // read the model data
585 owner = (int*)malloc(sizeof(int)*vertexNum);
586 possible = (int*)malloc(sizeof(int)*TriangleNum);
587 vertex = (XYZ*)malloc(sizeof(XYZ)*vertexNum);
588 normals = (XYZ*)malloc(sizeof(XYZ)*vertexNum);
589 facenormals = (XYZ*)malloc(sizeof(XYZ)*TriangleNum);
590 Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle)*TriangleNum);
591 vArray = (GLfloat*)malloc(sizeof(GLfloat)*TriangleNum*24);
594 for(i=0;i<vertexNum;i++){
595 funpackf(tfile, "Bf Bf Bf", &vertex[i].x,&vertex[i].y,&vertex[i].z);
598 for(i=0;i<TriangleNum;i++){
599 // funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
601 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
602 Triangles[i].vertex[ 0] = vertex[ 0];
603 Triangles[i].vertex[ 1] = vertex[ 2];
604 Triangles[i].vertex[ 2] = vertex[ 4];
605 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
606 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
616 for(i=0;i<vertexNum;i++){
620 boundingsphereradius=0;
621 for(i=0;i<vertexNum;i++){
622 for(j=0;j<vertexNum;j++){
623 if(j!=i&&findDistancefast(&vertex[j],&vertex[i])/2>boundingsphereradius){
624 boundingsphereradius=findDistancefast(&vertex[j],&vertex[i])/2;
625 boundingspherecenter=(vertex[i]+vertex[j])/2;
629 boundingsphereradius=fast_sqrt(boundingsphereradius);
633 decaltexcoords = (float***)malloc(sizeof(float**)*max_model_decals);
634 for(i=0;i<max_model_decals;i++){
635 decaltexcoords[i] = (float**)malloc(sizeof(float*)*3);
637 decaltexcoords[i][j] = (float*)malloc(sizeof(float)*2);
640 //if(decalvertex)free(decalvertex);
641 decalvertex = (XYZ**)malloc(sizeof(XYZ*)*max_model_decals);
642 for(i=0;i<max_model_decals;i++){
643 decalvertex[i] = (XYZ*)malloc(sizeof(XYZ)*3);
646 decaltype = (int*)malloc(sizeof(int)*max_model_decals);
647 decalopacity = (float*)malloc(sizeof(float)*max_model_decals);
648 decalrotation = (float*)malloc(sizeof(float)*max_model_decals);
649 decalalivetime = (float*)malloc(sizeof(float)*max_model_decals);
650 decalposition = (XYZ*)malloc(sizeof(XYZ)*max_model_decals);
656 bool Model::loadraw(char *filename )
663 LOG(std::string("Loading raw...") + filename);
665 int oldvertexNum,oldTriangleNum;
666 oldvertexNum=vertexNum;
667 oldTriangleNum=TriangleNum;
672 tfile=fopen( ConvertFileName(filename), "rb" );
673 // read model settings
676 fseek(tfile, 0, SEEK_SET);
677 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
679 // read the model data
684 owner = (int*)malloc(sizeof(int)*vertexNum);
685 possible = (int*)malloc(sizeof(int)*TriangleNum);
686 vertex = (XYZ*)malloc(sizeof(XYZ)*vertexNum);
687 Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle)*TriangleNum);
688 vArray = (GLfloat*)malloc(sizeof(GLfloat)*TriangleNum*24);
691 for(i=0;i<vertexNum;i++){
692 funpackf(tfile, "Bf Bf Bf", &vertex[i].x,&vertex[i].y,&vertex[i].z);
695 for(i=0;i<TriangleNum;i++){
696 // funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
698 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
699 Triangles[i].vertex[ 0] = vertex[ 0];
700 Triangles[i].vertex[ 1] = vertex[ 2];
701 Triangles[i].vertex[ 2] = vertex[ 4];
702 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
703 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
709 for(i=0;i<vertexNum;i++){
717 void Model::UniformTexCoords()
720 for(i=0; i<TriangleNum; i++){
721 Triangles[i].gy[0]=vertex[Triangles[i].vertex[0]].y;
722 Triangles[i].gy[1]=vertex[Triangles[i].vertex[1]].y;
723 Triangles[i].gy[2]=vertex[Triangles[i].vertex[2]].y;
724 Triangles[i].gx[0]=vertex[Triangles[i].vertex[0]].x;
725 Triangles[i].gx[1]=vertex[Triangles[i].vertex[1]].x;
726 Triangles[i].gx[2]=vertex[Triangles[i].vertex[2]].x;
732 void Model::FlipTexCoords()
735 for(i=0; i<TriangleNum; i++){
736 Triangles[i].gy[0]=-Triangles[i].gy[0];
737 Triangles[i].gy[1]=-Triangles[i].gy[1];
738 Triangles[i].gy[2]=-Triangles[i].gy[2];
743 void Model::ScaleTexCoords(float howmuch)
746 for(i=0; i<TriangleNum; i++){
747 Triangles[i].gx[0]*=howmuch;
748 Triangles[i].gx[1]*=howmuch;
749 Triangles[i].gx[2]*=howmuch;
750 Triangles[i].gy[0]*=howmuch;
751 Triangles[i].gy[1]*=howmuch;
752 Triangles[i].gy[2]*=howmuch;
757 void Model::Scale(float xscale,float yscale,float zscale)
760 for(i=0; i<vertexNum; i++){
769 boundingsphereradius=0;
770 for(i=0;i<vertexNum;i++){
771 for(j=0;j<vertexNum;j++){
772 if(j!=i&&findDistancefast(&vertex[j],&vertex[i])/2>boundingsphereradius){
773 boundingsphereradius=findDistancefast(&vertex[j],&vertex[i])/2;
774 boundingspherecenter=(vertex[i]+vertex[j])/2;
778 boundingsphereradius=fast_sqrt(boundingsphereradius);
781 void Model::ScaleNormals(float xscale,float yscale,float zscale)
783 if(type!=normaltype&&type!=decalstype)return;
785 for(i=0; i<vertexNum; i++){
786 normals[i].x*=xscale;
787 normals[i].y*=yscale;
788 normals[i].z*=zscale;
790 for(i=0; i<TriangleNum; i++){
791 facenormals[i].x*=xscale;
792 facenormals[i].y*=yscale;
793 facenormals[i].z*=zscale;
798 void Model::Translate(float xtrans,float ytrans,float ztrans)
801 for(i=0; i<vertexNum; i++){
809 boundingsphereradius=0;
810 for(i=0;i<vertexNum;i++){
811 for(j=0;j<vertexNum;j++){
812 if(j!=i&&findDistancefast(&vertex[j],&vertex[i])/2>boundingsphereradius){
813 boundingsphereradius=findDistancefast(&vertex[j],&vertex[i])/2;
814 boundingspherecenter=(vertex[i]+vertex[j])/2;
818 boundingsphereradius=fast_sqrt(boundingsphereradius);
821 void Model::Rotate(float xang,float yang,float zang)
824 for(i=0; i<vertexNum; i++){
825 vertex[i]=DoRotation(vertex[i],xang,yang,zang);
830 boundingsphereradius=0;
831 for(i=0;i<vertexNum;i++){
832 for(j=0;j<vertexNum;j++){
833 if(j!=i&&findDistancefast(&vertex[j],&vertex[i])/2>boundingsphereradius){
834 boundingsphereradius=findDistancefast(&vertex[j],&vertex[i])/2;
835 boundingspherecenter=(vertex[i]+vertex[j])/2;
839 boundingsphereradius=fast_sqrt(boundingsphereradius);
843 void Model::CalculateNormals(bool facenormalise)
846 Game::LoadingScreen();
848 if(type!=normaltype&&type!=decalstype)return;
850 for(i=0; i<vertexNum; i++){
856 for(i=0;i<TriangleNum;i++){
857 CrossProduct(vertex[Triangles[i].vertex[1]]-vertex[Triangles[i].vertex[0]],vertex[Triangles[i].vertex[2]]-vertex[Triangles[i].vertex[0]],&facenormals[i]);
859 normals[Triangles[i].vertex[0]].x+=facenormals[i].x;
860 normals[Triangles[i].vertex[0]].y+=facenormals[i].y;
861 normals[Triangles[i].vertex[0]].z+=facenormals[i].z;
863 normals[Triangles[i].vertex[1]].x+=facenormals[i].x;
864 normals[Triangles[i].vertex[1]].y+=facenormals[i].y;
865 normals[Triangles[i].vertex[1]].z+=facenormals[i].z;
867 normals[Triangles[i].vertex[2]].x+=facenormals[i].x;
868 normals[Triangles[i].vertex[2]].y+=facenormals[i].y;
869 normals[Triangles[i].vertex[2]].z+=facenormals[i].z;
870 if(facenormalise)Normalise(&facenormals[i]);
872 for(i=0; i<vertexNum; i++){
873 Normalise(&normals[i]);
876 UpdateVertexArrayNoTex();
879 void Model::drawimmediate()
881 glBindTexture(GL_TEXTURE_2D,(unsigned long)textureptr);
882 glBegin(GL_TRIANGLES);
883 for(int i=0;i<TriangleNum;i++){
884 /*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){
885 if(isnormal(vertex[Triangles[i].vertex[0]].x)&&isnormal(vertex[Triangles[i].vertex[0]].y)&&isnormal(vertex[Triangles[i].vertex[0]].z)
886 &&isnormal(vertex[Triangles[i].vertex[1]].x)&&isnormal(vertex[Triangles[i].vertex[1]].y)&&isnormal(vertex[Triangles[i].vertex[1]].z)
887 &&isnormal(vertex[Triangles[i].vertex[2]].x)&&isnormal(vertex[Triangles[i].vertex[2]].y)&&isnormal(vertex[Triangles[i].vertex[2]].z)){
889 glTexCoord2f(Triangles[i].gx[0],Triangles[i].gy[0]);
890 if(color)glColor3f(normals[Triangles[i].vertex[0]].x,normals[Triangles[i].vertex[0]].y,normals[Triangles[i].vertex[0]].z);
891 if(!color&&!flat)glNormal3f(normals[Triangles[i].vertex[0]].x,normals[Triangles[i].vertex[0]].y,normals[Triangles[i].vertex[0]].z);
892 if(!color&&flat)glNormal3f(facenormals[i].x,facenormals[i].y,facenormals[i].y);
893 glVertex3f(vertex[Triangles[i].vertex[0]].x,vertex[Triangles[i].vertex[0]].y,vertex[Triangles[i].vertex[0]].z);
895 glTexCoord2f(Triangles[i].gx[1],Triangles[i].gy[1]);
896 if(color)glColor3f(normals[Triangles[i].vertex[1]].x,normals[Triangles[i].vertex[1]].y,normals[Triangles[i].vertex[1]].z);
897 if(!color&&!flat)glNormal3f(normals[Triangles[i].vertex[1]].x,normals[Triangles[i].vertex[1]].y,normals[Triangles[i].vertex[1]].z);
898 if(!color&&flat)glNormal3f(facenormals[i].x,facenormals[i].y,facenormals[i].y);
899 glVertex3f(vertex[Triangles[i].vertex[1]].x,vertex[Triangles[i].vertex[1]].y,vertex[Triangles[i].vertex[1]].z);
901 glTexCoord2f(Triangles[i].gx[2],Triangles[i].gy[2]);
902 if(color)glColor3f(normals[Triangles[i].vertex[2]].x,normals[Triangles[i].vertex[2]].y,normals[Triangles[i].vertex[2]].z);
903 if(!color&&!flat)glNormal3f(normals[Triangles[i].vertex[2]].x,normals[Triangles[i].vertex[2]].y,normals[Triangles[i].vertex[2]].z);
904 if(!color&&flat)glNormal3f(facenormals[i].x,facenormals[i].y,facenormals[i].y);
905 glVertex3f(vertex[Triangles[i].vertex[2]].x,vertex[Triangles[i].vertex[2]].y,vertex[Triangles[i].vertex[2]].z);
914 if(type!=normaltype&&type!=decalstype)return;
916 glEnableClientState(GL_NORMAL_ARRAY);
917 glEnableClientState(GL_VERTEX_ARRAY);
918 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
920 if(!color)glInterleavedArrays( GL_T2F_N3F_V3F,8*sizeof(GLfloat),&vArray[0]);
921 if(color)glInterleavedArrays( GL_T2F_C3F_V3F,8*sizeof(GLfloat),&vArray[0]);
922 glBindTexture(GL_TEXTURE_2D,(unsigned long)textureptr);
925 glLockArraysEXT( 0, TriangleNum*3);
927 glDrawArrays(GL_TRIANGLES, 0, TriangleNum*3);
933 if(!color)glDisableClientState(GL_NORMAL_ARRAY);
934 if(color)glDisableClientState(GL_COLOR_ARRAY);
935 glDisableClientState(GL_VERTEX_ARRAY);
936 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
940 void Model::drawdifftex(GLuint texture)
942 glEnableClientState(GL_NORMAL_ARRAY);
943 glEnableClientState(GL_VERTEX_ARRAY);
944 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
945 if(!color)glInterleavedArrays( GL_T2F_N3F_V3F,8*sizeof(GLfloat),&vArray[0]);
946 if(color)glInterleavedArrays( GL_T2F_C3F_V3F,8*sizeof(GLfloat),&vArray[0]);
948 glBindTexture(GL_TEXTURE_2D,(unsigned long)texture);
949 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
950 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
954 glLockArraysEXT( 0, TriangleNum*3);
956 glDrawArrays(GL_TRIANGLES, 0, TriangleNum*3);
962 if(!color)glDisableClientState(GL_NORMAL_ARRAY);
963 if(color)glDisableClientState(GL_COLOR_ARRAY);
964 glDisableClientState(GL_VERTEX_ARRAY);
965 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
966 //drawdiffteximmediate(texture);
969 void Model::drawdiffteximmediate(GLuint texture)
971 glBindTexture(GL_TEXTURE_2D,(unsigned long)texture);
973 glBegin(GL_TRIANGLES);
974 for(int i=0;i<TriangleNum;i++){
975 /*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){
976 if(isnormal(vertex[Triangles[i].vertex[0]].x)&&isnormal(vertex[Triangles[i].vertex[0]].y)&&isnormal(vertex[Triangles[i].vertex[0]].z)
977 &&isnormal(vertex[Triangles[i].vertex[1]].x)&&isnormal(vertex[Triangles[i].vertex[1]].y)&&isnormal(vertex[Triangles[i].vertex[1]].z)
978 &&isnormal(vertex[Triangles[i].vertex[2]].x)&&isnormal(vertex[Triangles[i].vertex[2]].y)&&isnormal(vertex[Triangles[i].vertex[2]].z)){
979 */glTexCoord2f(Triangles[i].gx[0],Triangles[i].gy[0]);
980 if(color)glColor3f(normals[Triangles[i].vertex[0]].x,normals[Triangles[i].vertex[0]].y,normals[Triangles[i].vertex[0]].z);
981 if(!color&&!flat)glNormal3f(normals[Triangles[i].vertex[0]].x,normals[Triangles[i].vertex[0]].y,normals[Triangles[i].vertex[0]].z);
982 if(!color&&flat)glNormal3f(facenormals[i].x,facenormals[i].y,facenormals[i].y);
983 glVertex3f(vertex[Triangles[i].vertex[0]].x,vertex[Triangles[i].vertex[0]].y,vertex[Triangles[i].vertex[0]].z);
985 glTexCoord2f(Triangles[i].gx[1],Triangles[i].gy[1]);
986 if(color)glColor3f(normals[Triangles[i].vertex[1]].x,normals[Triangles[i].vertex[1]].y,normals[Triangles[i].vertex[1]].z);
987 if(!color&&!flat)glNormal3f(normals[Triangles[i].vertex[1]].x,normals[Triangles[i].vertex[1]].y,normals[Triangles[i].vertex[1]].z);
988 if(!color&&flat)glNormal3f(facenormals[i].x,facenormals[i].y,facenormals[i].y);
989 glVertex3f(vertex[Triangles[i].vertex[1]].x,vertex[Triangles[i].vertex[1]].y,vertex[Triangles[i].vertex[1]].z);
991 glTexCoord2f(Triangles[i].gx[2],Triangles[i].gy[2]);
992 if(color)glColor3f(normals[Triangles[i].vertex[2]].x,normals[Triangles[i].vertex[2]].y,normals[Triangles[i].vertex[2]].z);
993 if(!color&&!flat)glNormal3f(normals[Triangles[i].vertex[2]].x,normals[Triangles[i].vertex[2]].y,normals[Triangles[i].vertex[2]].z);
994 if(!color&&flat)glNormal3f(facenormals[i].x,facenormals[i].y,facenormals[i].y);
995 glVertex3f(vertex[Triangles[i].vertex[2]].x,vertex[Triangles[i].vertex[2]].y,vertex[Triangles[i].vertex[2]].z);
1002 void Model::drawdecals(GLuint shadowtexture,GLuint bloodtexture,GLuint bloodtexture2,GLuint breaktexture)
1005 if(type!=decalstype)return;
1007 static float distancemult;
1008 static int lasttype;
1009 static float viewdistsquared;
1012 viewdistsquared=viewdistance*viewdistance;
1017 glDisable(GL_LIGHTING);
1018 glDisable(GL_CULL_FACE);
1019 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1021 if(numdecals>max_model_decals)numdecals=max_model_decals;
1022 for(i=0;i<numdecals;i++){
1023 if(decaltype[i]==blooddecalfast&&decalalivetime[i]<2)decalalivetime[i]=2;
1025 if(decaltype[i]==shadowdecal&&decaltype[i]!=lasttype){
1026 glBindTexture( GL_TEXTURE_2D, shadowtexture);
1029 glAlphaFunc(GL_GREATER, 0.0001);
1030 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1033 if(decaltype[i]==breakdecal&&decaltype[i]!=lasttype){
1034 glBindTexture( GL_TEXTURE_2D, breaktexture);
1037 glAlphaFunc(GL_GREATER, 0.0001);
1038 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1041 if((decaltype[i]==blooddecal||decaltype[i]==blooddecalslow)&&decaltype[i]!=lasttype){
1042 glBindTexture( GL_TEXTURE_2D, bloodtexture);
1045 glAlphaFunc(GL_GREATER, 0.15);
1046 glBlendFunc(GL_ONE,GL_ZERO);
1049 if((decaltype[i]==blooddecalfast)&&decaltype[i]!=lasttype){
1050 glBindTexture( GL_TEXTURE_2D, bloodtexture2);
1053 glAlphaFunc(GL_GREATER, 0.15);
1054 glBlendFunc(GL_ONE,GL_ZERO);
1057 if(decaltype[i]==shadowdecal){
1058 glColor4f(1,1,1,decalopacity[i]);
1060 if(decaltype[i]==breakdecal){
1061 glColor4f(1,1,1,decalopacity[i]);
1062 if(decalalivetime[i]>58)glColor4f(1,1,1,decalopacity[i]*(60-decalalivetime[i])/2);
1064 if((decaltype[i]==blooddecal||decaltype[i]==blooddecalfast||decaltype[i]==blooddecalslow)){
1065 glColor4f(1,1,1,decalopacity[i]);
1066 if(decalalivetime[i]<4)glColor4f(1,1,1,decalopacity[i]*decalalivetime[i]*.25);
1067 if(decalalivetime[i]>58)glColor4f(1,1,1,decalopacity[i]*(60-decalalivetime[i])/2);
1069 lasttype=decaltype[i];
1070 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1071 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
1073 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
1075 glBegin(GL_TRIANGLES);
1076 for(int j=0;j<3;j++)
1078 glTexCoord2f(decaltexcoords[i][j][0], decaltexcoords[i][j][1]); glVertex3f(decalvertex[i][j].x,decalvertex[i][j].y,decalvertex[i][j].z);
1083 for(i=numdecals-1;i>=0;i--){
1084 decalalivetime[i]+=multiplier;
1085 if(decaltype[i]==blooddecalslow)decalalivetime[i]-=multiplier*2/3;
1086 if(decaltype[i]==blooddecalfast)decalalivetime[i]+=multiplier*4;
1087 if(decaltype[i]==shadowdecal)DeleteDecal(i);
1088 if((decaltype[i]==blooddecal||decaltype[i]==blooddecalfast||decaltype[i]==blooddecalslow)&&decalalivetime[i]>=60)DeleteDecal(i);
1090 glAlphaFunc(GL_GREATER, 0.0001);
1091 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1095 void Model::DeleteDecal(int which)
1098 if(type!=decalstype)return;
1099 decaltype[which]=decaltype[numdecals-1];
1100 decalposition[which]=decalposition[numdecals-1];
1101 for(int i=0;i<3;i++){
1102 decalvertex[which][i]=decalvertex[numdecals-1][i];
1103 decaltexcoords[which][i][0]=decaltexcoords[numdecals-1][i][0];
1104 decaltexcoords[which][i][1]=decaltexcoords[numdecals-1][i][1];
1106 decalrotation[which]=decalrotation[numdecals-1];
1107 decalalivetime[which]=decalalivetime[numdecals-1];
1108 decalopacity[which]=decalopacity[numdecals-1];
1113 void Model::MakeDecal(int atype, XYZ *where,float *size, float *opacity, float *rotation){
1115 if(type!=decalstype)return;
1117 static float placex,placez;
1119 //static XYZ point,point1,point2;
1120 static float distance;
1124 if(findDistancefast(where,&boundingspherecenter)<(boundingsphereradius+*size)*(boundingsphereradius+*size))
1125 for(i=0;i<TriangleNum;i++){
1126 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)){
1127 decalposition[numdecals]=*where;
1128 decaltype[numdecals]=atype;
1129 decalrotation[numdecals]=*rotation;
1130 decalalivetime[numdecals]=0;
1131 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);
1132 decalopacity[numdecals]=*opacity-distance/10;
1134 if(decalopacity[numdecals>0]){
1135 placex=vertex[Triangles[i].vertex[0]].x;
1136 placez=vertex[Triangles[i].vertex[0]].z;
1138 decaltexcoords[numdecals][0][0]=(placex-where->x)/(*size)/2+.5;
1139 decaltexcoords[numdecals][0][1]=(placez-where->z)/(*size)/2+.5;
1141 decalvertex[numdecals][0].x=placex;
1142 decalvertex[numdecals][0].z=placez;
1143 decalvertex[numdecals][0].y=vertex[Triangles[i].vertex[0]].y;
1146 placex=vertex[Triangles[i].vertex[1]].x;
1147 placez=vertex[Triangles[i].vertex[1]].z;
1149 decaltexcoords[numdecals][1][0]=(placex-where->x)/(*size)/2+.5;
1150 decaltexcoords[numdecals][1][1]=(placez-where->z)/(*size)/2+.5;
1152 decalvertex[numdecals][1].x=placex;
1153 decalvertex[numdecals][1].z=placez;
1154 decalvertex[numdecals][1].y=vertex[Triangles[i].vertex[1]].y;
1157 placex=vertex[Triangles[i].vertex[2]].x;
1158 placez=vertex[Triangles[i].vertex[2]].z;
1160 decaltexcoords[numdecals][2][0]=(placex-where->x)/(*size)/2+.5;
1161 decaltexcoords[numdecals][2][1]=(placez-where->z)/(*size)/2+.5;
1163 decalvertex[numdecals][2].x=placex;
1164 decalvertex[numdecals][2].z=placez;
1165 decalvertex[numdecals][2].y=vertex[Triangles[i].vertex[2]].y;
1167 if(!(decaltexcoords[numdecals][0][0]<0&&decaltexcoords[numdecals][1][0]<0&&decaltexcoords[numdecals][2][0]<0))
1168 if(!(decaltexcoords[numdecals][0][1]<0&&decaltexcoords[numdecals][1][1]<0&&decaltexcoords[numdecals][2][1]<0))
1169 if(!(decaltexcoords[numdecals][0][0]>1&&decaltexcoords[numdecals][1][0]>1&&decaltexcoords[numdecals][2][0]>1))
1170 if(!(decaltexcoords[numdecals][0][1]>1&&decaltexcoords[numdecals][1][1]>1&&decaltexcoords[numdecals][2][1]>1))
1172 if(decalrotation[numdecals]){
1175 rot.x=decaltexcoords[numdecals][j][0]-.5;
1176 rot.z=decaltexcoords[numdecals][j][1]-.5;
1177 rot=DoRotation(rot,0,-decalrotation[numdecals],0);
1178 decaltexcoords[numdecals][j][0]=rot.x+.5;
1179 decaltexcoords[numdecals][j][1]=rot.z+.5;
1182 if(numdecals<max_model_decals-1)numdecals++;
1190 void Model::MakeDecal(int atype, XYZ where,float size, float opacity, float rotation){
1192 if(type!=decalstype)return;
1194 static float placex,placez;
1196 //static XYZ point,point1,point2;
1197 static float distance;
1201 if(findDistancefast(&where,&boundingspherecenter)<(boundingsphereradius+size)*(boundingsphereradius+size))
1202 for(i=0;i<TriangleNum;i++){
1203 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))));
1204 if(distance<.02&&abs(facenormals[i].y)>abs(facenormals[i].x)&&abs(facenormals[i].y)>abs(facenormals[i].z)){
1205 decalposition[numdecals]=where;
1206 decaltype[numdecals]=atype;
1207 decalrotation[numdecals]=rotation;
1208 decalalivetime[numdecals]=0;
1209 decalopacity[numdecals]=opacity-distance/10;
1211 if(decalopacity[numdecals>0]){
1212 placex=vertex[Triangles[i].vertex[0]].x;
1213 placez=vertex[Triangles[i].vertex[0]].z;
1215 decaltexcoords[numdecals][0][0]=(placex-where.x)/(size)/2+.5;
1216 decaltexcoords[numdecals][0][1]=(placez-where.z)/(size)/2+.5;
1218 decalvertex[numdecals][0].x=placex;
1219 decalvertex[numdecals][0].z=placez;
1220 decalvertex[numdecals][0].y=vertex[Triangles[i].vertex[0]].y;
1223 placex=vertex[Triangles[i].vertex[1]].x;
1224 placez=vertex[Triangles[i].vertex[1]].z;
1226 decaltexcoords[numdecals][1][0]=(placex-where.x)/(size)/2+.5;
1227 decaltexcoords[numdecals][1][1]=(placez-where.z)/(size)/2+.5;
1229 decalvertex[numdecals][1].x=placex;
1230 decalvertex[numdecals][1].z=placez;
1231 decalvertex[numdecals][1].y=vertex[Triangles[i].vertex[1]].y;
1234 placex=vertex[Triangles[i].vertex[2]].x;
1235 placez=vertex[Triangles[i].vertex[2]].z;
1237 decaltexcoords[numdecals][2][0]=(placex-where.x)/(size)/2+.5;
1238 decaltexcoords[numdecals][2][1]=(placez-where.z)/(size)/2+.5;
1240 decalvertex[numdecals][2].x=placex;
1241 decalvertex[numdecals][2].z=placez;
1242 decalvertex[numdecals][2].y=vertex[Triangles[i].vertex[2]].y;
1244 if(!(decaltexcoords[numdecals][0][0]<0&&decaltexcoords[numdecals][1][0]<0&&decaltexcoords[numdecals][2][0]<0))
1245 if(!(decaltexcoords[numdecals][0][1]<0&&decaltexcoords[numdecals][1][1]<0&&decaltexcoords[numdecals][2][1]<0))
1246 if(!(decaltexcoords[numdecals][0][0]>1&&decaltexcoords[numdecals][1][0]>1&&decaltexcoords[numdecals][2][0]>1))
1247 if(!(decaltexcoords[numdecals][0][1]>1&&decaltexcoords[numdecals][1][1]>1&&decaltexcoords[numdecals][2][1]>1))
1249 if(decalrotation[numdecals]){
1252 rot.x=decaltexcoords[numdecals][j][0]-.5;
1253 rot.z=decaltexcoords[numdecals][j][1]-.5;
1254 rot=DoRotation(rot,0,-decalrotation[numdecals],0);
1255 decaltexcoords[numdecals][j][0]=rot.x+.5;
1256 decaltexcoords[numdecals][j][1]=rot.z+.5;
1259 if(numdecals<max_model_decals-1)numdecals++;
1263 else if(distance<.02&&abs(facenormals[i].x)>abs(facenormals[i].y)&&abs(facenormals[i].x)>abs(facenormals[i].z)){
1264 decalposition[numdecals]=where;
1265 decaltype[numdecals]=atype;
1266 decalrotation[numdecals]=rotation;
1267 decalalivetime[numdecals]=0;
1268 decalopacity[numdecals]=opacity-distance/10;
1270 if(decalopacity[numdecals>0]){
1271 placex=vertex[Triangles[i].vertex[0]].y;
1272 placez=vertex[Triangles[i].vertex[0]].z;
1274 decaltexcoords[numdecals][0][0]=(placex-where.y)/(size)/2+.5;
1275 decaltexcoords[numdecals][0][1]=(placez-where.z)/(size)/2+.5;
1277 decalvertex[numdecals][0].x=vertex[Triangles[i].vertex[0]].x;
1278 decalvertex[numdecals][0].z=placez;
1279 decalvertex[numdecals][0].y=placex;
1282 placex=vertex[Triangles[i].vertex[1]].y;
1283 placez=vertex[Triangles[i].vertex[1]].z;
1285 decaltexcoords[numdecals][1][0]=(placex-where.y)/(size)/2+.5;
1286 decaltexcoords[numdecals][1][1]=(placez-where.z)/(size)/2+.5;
1288 decalvertex[numdecals][1].x=vertex[Triangles[i].vertex[1]].x;
1289 decalvertex[numdecals][1].z=placez;
1290 decalvertex[numdecals][1].y=placex;
1293 placex=vertex[Triangles[i].vertex[2]].y;
1294 placez=vertex[Triangles[i].vertex[2]].z;
1296 decaltexcoords[numdecals][2][0]=(placex-where.y)/(size)/2+.5;
1297 decaltexcoords[numdecals][2][1]=(placez-where.z)/(size)/2+.5;
1299 decalvertex[numdecals][2].x=vertex[Triangles[i].vertex[2]].x;
1300 decalvertex[numdecals][2].z=placez;
1301 decalvertex[numdecals][2].y=placex;
1303 if(!(decaltexcoords[numdecals][0][0]<0&&decaltexcoords[numdecals][1][0]<0&&decaltexcoords[numdecals][2][0]<0))
1304 if(!(decaltexcoords[numdecals][0][1]<0&&decaltexcoords[numdecals][1][1]<0&&decaltexcoords[numdecals][2][1]<0))
1305 if(!(decaltexcoords[numdecals][0][0]>1&&decaltexcoords[numdecals][1][0]>1&&decaltexcoords[numdecals][2][0]>1))
1306 if(!(decaltexcoords[numdecals][0][1]>1&&decaltexcoords[numdecals][1][1]>1&&decaltexcoords[numdecals][2][1]>1))
1308 if(decalrotation[numdecals]){
1311 rot.x=decaltexcoords[numdecals][j][0]-.5;
1312 rot.z=decaltexcoords[numdecals][j][1]-.5;
1313 rot=DoRotation(rot,0,-decalrotation[numdecals],0);
1314 decaltexcoords[numdecals][j][0]=rot.x+.5;
1315 decaltexcoords[numdecals][j][1]=rot.z+.5;
1318 if(numdecals<max_model_decals-1)numdecals++;
1322 else if(distance<.02&&abs(facenormals[i].z)>abs(facenormals[i].y)&&abs(facenormals[i].z)>abs(facenormals[i].x)){
1323 decalposition[numdecals]=where;
1324 decaltype[numdecals]=atype;
1325 decalrotation[numdecals]=rotation;
1326 decalalivetime[numdecals]=0;
1327 decalopacity[numdecals]=opacity-distance/10;
1329 if(decalopacity[numdecals>0]){
1330 placex=vertex[Triangles[i].vertex[0]].x;
1331 placez=vertex[Triangles[i].vertex[0]].y;
1333 decaltexcoords[numdecals][0][0]=(placex-where.x)/(size)/2+.5;
1334 decaltexcoords[numdecals][0][1]=(placez-where.y)/(size)/2+.5;
1336 decalvertex[numdecals][0].x=placex;
1337 decalvertex[numdecals][0].z=vertex[Triangles[i].vertex[0]].z;
1338 decalvertex[numdecals][0].y=placez;
1341 placex=vertex[Triangles[i].vertex[1]].x;
1342 placez=vertex[Triangles[i].vertex[1]].y;
1344 decaltexcoords[numdecals][1][0]=(placex-where.x)/(size)/2+.5;
1345 decaltexcoords[numdecals][1][1]=(placez-where.y)/(size)/2+.5;
1347 decalvertex[numdecals][1].x=placex;
1348 decalvertex[numdecals][1].z=vertex[Triangles[i].vertex[1]].z;
1349 decalvertex[numdecals][1].y=placez;
1352 placex=vertex[Triangles[i].vertex[2]].x;
1353 placez=vertex[Triangles[i].vertex[2]].y;
1355 decaltexcoords[numdecals][2][0]=(placex-where.x)/(size)/2+.5;
1356 decaltexcoords[numdecals][2][1]=(placez-where.y)/(size)/2+.5;
1358 decalvertex[numdecals][2].x=placex;
1359 decalvertex[numdecals][2].z=vertex[Triangles[i].vertex[2]].z;
1360 decalvertex[numdecals][2].y=placez;
1362 if(!(decaltexcoords[numdecals][0][0]<0&&decaltexcoords[numdecals][1][0]<0&&decaltexcoords[numdecals][2][0]<0))
1363 if(!(decaltexcoords[numdecals][0][1]<0&&decaltexcoords[numdecals][1][1]<0&&decaltexcoords[numdecals][2][1]<0))
1364 if(!(decaltexcoords[numdecals][0][0]>1&&decaltexcoords[numdecals][1][0]>1&&decaltexcoords[numdecals][2][0]>1))
1365 if(!(decaltexcoords[numdecals][0][1]>1&&decaltexcoords[numdecals][1][1]>1&&decaltexcoords[numdecals][2][1]>1))
1367 if(decalrotation[numdecals]){
1370 rot.x=decaltexcoords[numdecals][j][0]-.5;
1371 rot.z=decaltexcoords[numdecals][j][1]-.5;
1372 rot=DoRotation(rot,0,-decalrotation[numdecals],0);
1373 decaltexcoords[numdecals][j][0]=rot.x+.5;
1374 decaltexcoords[numdecals][j][1]=rot.z+.5;
1377 if(numdecals<max_model_decals-1)numdecals++;
1389 glDeleteTextures( 1, &textureptr );
1392 void Model::deallocate()
1396 if(owner)free(owner);
1399 if(possible)free(possible);
1402 if(vertex)free(vertex);
1405 if(normals)free(normals);
1408 if(facenormals)free(facenormals);
1411 if(Triangles)free(Triangles);
1414 if(vArray)free(vArray);
1421 for(i=0;i<max_model_decals;i++)
1425 free(decaltexcoords[i][j]);
1427 free(decaltexcoords[i]);
1429 free(decaltexcoords);
1436 for(i=0;i<max_model_decals;i++)
1438 free(decalvertex[i]);
1451 free(decalrotation);
1454 free(decalalivetime);
1457 free(decalposition);
1464 vertexNum = 0,TriangleNum = 0;
1467 type = 0,oldtype = 0;
1478 memset(&Texture, 0, sizeof(Texture));
1482 boundingspherecenter = 0;
1483 boundingsphereradius = 0;