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()
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]);
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 //TODO: phase out in favor of Texture
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::drawdifftex(Texture texture)
972 glEnableClientState(GL_NORMAL_ARRAY);
973 glEnableClientState(GL_VERTEX_ARRAY);
974 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
975 if(!color)glInterleavedArrays( GL_T2F_N3F_V3F,8*sizeof(GLfloat),&vArray[0]);
976 if(color)glInterleavedArrays( GL_T2F_C3F_V3F,8*sizeof(GLfloat),&vArray[0]);
979 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
980 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
984 glLockArraysEXT( 0, TriangleNum*3);
986 glDrawArrays(GL_TRIANGLES, 0, TriangleNum*3);
992 if(!color)glDisableClientState(GL_NORMAL_ARRAY);
993 if(color)glDisableClientState(GL_COLOR_ARRAY);
994 glDisableClientState(GL_VERTEX_ARRAY);
995 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
996 //drawdiffteximmediate(texture);
999 void Model::drawdiffteximmediate(GLuint texture)
1001 glBindTexture(GL_TEXTURE_2D,(unsigned long)texture);
1003 glBegin(GL_TRIANGLES);
1004 for(int i=0;i<TriangleNum;i++){
1005 /*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){
1006 if(isnormal(vertex[Triangles[i].vertex[0]].x)&&isnormal(vertex[Triangles[i].vertex[0]].y)&&isnormal(vertex[Triangles[i].vertex[0]].z)
1007 &&isnormal(vertex[Triangles[i].vertex[1]].x)&&isnormal(vertex[Triangles[i].vertex[1]].y)&&isnormal(vertex[Triangles[i].vertex[1]].z)
1008 &&isnormal(vertex[Triangles[i].vertex[2]].x)&&isnormal(vertex[Triangles[i].vertex[2]].y)&&isnormal(vertex[Triangles[i].vertex[2]].z)){
1009 */glTexCoord2f(Triangles[i].gx[0],Triangles[i].gy[0]);
1010 if(color)glColor3f(normals[Triangles[i].vertex[0]].x,normals[Triangles[i].vertex[0]].y,normals[Triangles[i].vertex[0]].z);
1011 if(!color&&!flat)glNormal3f(normals[Triangles[i].vertex[0]].x,normals[Triangles[i].vertex[0]].y,normals[Triangles[i].vertex[0]].z);
1012 if(!color&&flat)glNormal3f(facenormals[i].x,facenormals[i].y,facenormals[i].y);
1013 glVertex3f(vertex[Triangles[i].vertex[0]].x,vertex[Triangles[i].vertex[0]].y,vertex[Triangles[i].vertex[0]].z);
1015 glTexCoord2f(Triangles[i].gx[1],Triangles[i].gy[1]);
1016 if(color)glColor3f(normals[Triangles[i].vertex[1]].x,normals[Triangles[i].vertex[1]].y,normals[Triangles[i].vertex[1]].z);
1017 if(!color&&!flat)glNormal3f(normals[Triangles[i].vertex[1]].x,normals[Triangles[i].vertex[1]].y,normals[Triangles[i].vertex[1]].z);
1018 if(!color&&flat)glNormal3f(facenormals[i].x,facenormals[i].y,facenormals[i].y);
1019 glVertex3f(vertex[Triangles[i].vertex[1]].x,vertex[Triangles[i].vertex[1]].y,vertex[Triangles[i].vertex[1]].z);
1021 glTexCoord2f(Triangles[i].gx[2],Triangles[i].gy[2]);
1022 if(color)glColor3f(normals[Triangles[i].vertex[2]].x,normals[Triangles[i].vertex[2]].y,normals[Triangles[i].vertex[2]].z);
1023 if(!color&&!flat)glNormal3f(normals[Triangles[i].vertex[2]].x,normals[Triangles[i].vertex[2]].y,normals[Triangles[i].vertex[2]].z);
1024 if(!color&&flat)glNormal3f(facenormals[i].x,facenormals[i].y,facenormals[i].y);
1025 glVertex3f(vertex[Triangles[i].vertex[2]].x,vertex[Triangles[i].vertex[2]].y,vertex[Triangles[i].vertex[2]].z);
1032 void Model::drawdecals(Texture shadowtexture,Texture bloodtexture,Texture bloodtexture2,Texture breaktexture)
1035 if(type!=decalstype)return;
1037 static float distancemult;
1038 static int lasttype;
1039 static float viewdistsquared;
1042 viewdistsquared=viewdistance*viewdistance;
1047 glDisable(GL_LIGHTING);
1048 glDisable(GL_CULL_FACE);
1049 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1051 if(numdecals>max_model_decals)numdecals=max_model_decals;
1052 for(i=0;i<numdecals;i++){
1053 if(decaltype[i]==blooddecalfast&&decalalivetime[i]<2)decalalivetime[i]=2;
1055 if(decaltype[i]==shadowdecal&&decaltype[i]!=lasttype){
1056 shadowtexture.bind();
1059 glAlphaFunc(GL_GREATER, 0.0001);
1060 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1063 if(decaltype[i]==breakdecal&&decaltype[i]!=lasttype){
1064 breaktexture.bind();
1067 glAlphaFunc(GL_GREATER, 0.0001);
1068 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1071 if((decaltype[i]==blooddecal||decaltype[i]==blooddecalslow)&&decaltype[i]!=lasttype){
1072 bloodtexture.bind();
1075 glAlphaFunc(GL_GREATER, 0.15);
1076 glBlendFunc(GL_ONE,GL_ZERO);
1079 if((decaltype[i]==blooddecalfast)&&decaltype[i]!=lasttype){
1080 bloodtexture2.bind();
1083 glAlphaFunc(GL_GREATER, 0.15);
1084 glBlendFunc(GL_ONE,GL_ZERO);
1087 if(decaltype[i]==shadowdecal){
1088 glColor4f(1,1,1,decalopacity[i]);
1090 if(decaltype[i]==breakdecal){
1091 glColor4f(1,1,1,decalopacity[i]);
1092 if(decalalivetime[i]>58)glColor4f(1,1,1,decalopacity[i]*(60-decalalivetime[i])/2);
1094 if((decaltype[i]==blooddecal||decaltype[i]==blooddecalfast||decaltype[i]==blooddecalslow)){
1095 glColor4f(1,1,1,decalopacity[i]);
1096 if(decalalivetime[i]<4)glColor4f(1,1,1,decalopacity[i]*decalalivetime[i]*.25);
1097 if(decalalivetime[i]>58)glColor4f(1,1,1,decalopacity[i]*(60-decalalivetime[i])/2);
1099 lasttype=decaltype[i];
1100 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1101 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
1103 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
1105 glBegin(GL_TRIANGLES);
1106 for(int j=0;j<3;j++)
1108 glTexCoord2f(decaltexcoords[i][j][0], decaltexcoords[i][j][1]); glVertex3f(decalvertex[i][j].x,decalvertex[i][j].y,decalvertex[i][j].z);
1113 for(i=numdecals-1;i>=0;i--){
1114 decalalivetime[i]+=multiplier;
1115 if(decaltype[i]==blooddecalslow)decalalivetime[i]-=multiplier*2/3;
1116 if(decaltype[i]==blooddecalfast)decalalivetime[i]+=multiplier*4;
1117 if(decaltype[i]==shadowdecal)DeleteDecal(i);
1118 if((decaltype[i]==blooddecal||decaltype[i]==blooddecalfast||decaltype[i]==blooddecalslow)&&decalalivetime[i]>=60)DeleteDecal(i);
1120 glAlphaFunc(GL_GREATER, 0.0001);
1121 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1125 void Model::DeleteDecal(int which)
1128 if(type!=decalstype)return;
1129 decaltype[which]=decaltype[numdecals-1];
1130 decalposition[which]=decalposition[numdecals-1];
1131 for(int i=0;i<3;i++){
1132 decalvertex[which][i]=decalvertex[numdecals-1][i];
1133 decaltexcoords[which][i][0]=decaltexcoords[numdecals-1][i][0];
1134 decaltexcoords[which][i][1]=decaltexcoords[numdecals-1][i][1];
1136 decalrotation[which]=decalrotation[numdecals-1];
1137 decalalivetime[which]=decalalivetime[numdecals-1];
1138 decalopacity[which]=decalopacity[numdecals-1];
1143 void Model::MakeDecal(int atype, XYZ *where,float *size, float *opacity, float *rotation){
1145 if(type!=decalstype)return;
1147 static float placex,placez;
1149 //static XYZ point,point1,point2;
1150 static float distance;
1154 if(findDistancefast(where,&boundingspherecenter)<(boundingsphereradius+*size)*(boundingsphereradius+*size))
1155 for(i=0;i<TriangleNum;i++){
1156 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)){
1157 decalposition[numdecals]=*where;
1158 decaltype[numdecals]=atype;
1159 decalrotation[numdecals]=*rotation;
1160 decalalivetime[numdecals]=0;
1161 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);
1162 decalopacity[numdecals]=*opacity-distance/10;
1164 if(decalopacity[numdecals>0]){
1165 placex=vertex[Triangles[i].vertex[0]].x;
1166 placez=vertex[Triangles[i].vertex[0]].z;
1168 decaltexcoords[numdecals][0][0]=(placex-where->x)/(*size)/2+.5;
1169 decaltexcoords[numdecals][0][1]=(placez-where->z)/(*size)/2+.5;
1171 decalvertex[numdecals][0].x=placex;
1172 decalvertex[numdecals][0].z=placez;
1173 decalvertex[numdecals][0].y=vertex[Triangles[i].vertex[0]].y;
1176 placex=vertex[Triangles[i].vertex[1]].x;
1177 placez=vertex[Triangles[i].vertex[1]].z;
1179 decaltexcoords[numdecals][1][0]=(placex-where->x)/(*size)/2+.5;
1180 decaltexcoords[numdecals][1][1]=(placez-where->z)/(*size)/2+.5;
1182 decalvertex[numdecals][1].x=placex;
1183 decalvertex[numdecals][1].z=placez;
1184 decalvertex[numdecals][1].y=vertex[Triangles[i].vertex[1]].y;
1187 placex=vertex[Triangles[i].vertex[2]].x;
1188 placez=vertex[Triangles[i].vertex[2]].z;
1190 decaltexcoords[numdecals][2][0]=(placex-where->x)/(*size)/2+.5;
1191 decaltexcoords[numdecals][2][1]=(placez-where->z)/(*size)/2+.5;
1193 decalvertex[numdecals][2].x=placex;
1194 decalvertex[numdecals][2].z=placez;
1195 decalvertex[numdecals][2].y=vertex[Triangles[i].vertex[2]].y;
1197 if(!(decaltexcoords[numdecals][0][0]<0&&decaltexcoords[numdecals][1][0]<0&&decaltexcoords[numdecals][2][0]<0))
1198 if(!(decaltexcoords[numdecals][0][1]<0&&decaltexcoords[numdecals][1][1]<0&&decaltexcoords[numdecals][2][1]<0))
1199 if(!(decaltexcoords[numdecals][0][0]>1&&decaltexcoords[numdecals][1][0]>1&&decaltexcoords[numdecals][2][0]>1))
1200 if(!(decaltexcoords[numdecals][0][1]>1&&decaltexcoords[numdecals][1][1]>1&&decaltexcoords[numdecals][2][1]>1))
1202 if(decalrotation[numdecals]){
1205 rot.x=decaltexcoords[numdecals][j][0]-.5;
1206 rot.z=decaltexcoords[numdecals][j][1]-.5;
1207 rot=DoRotation(rot,0,-decalrotation[numdecals],0);
1208 decaltexcoords[numdecals][j][0]=rot.x+.5;
1209 decaltexcoords[numdecals][j][1]=rot.z+.5;
1212 if(numdecals<max_model_decals-1)numdecals++;
1220 void Model::MakeDecal(int atype, XYZ where,float size, float opacity, float rotation){
1222 if(type!=decalstype)return;
1224 static float placex,placez;
1226 //static XYZ point,point1,point2;
1227 static float distance;
1231 if(findDistancefast(&where,&boundingspherecenter)<(boundingsphereradius+size)*(boundingsphereradius+size))
1232 for(i=0;i<TriangleNum;i++){
1233 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))));
1234 if(distance<.02&&abs(facenormals[i].y)>abs(facenormals[i].x)&&abs(facenormals[i].y)>abs(facenormals[i].z)){
1235 decalposition[numdecals]=where;
1236 decaltype[numdecals]=atype;
1237 decalrotation[numdecals]=rotation;
1238 decalalivetime[numdecals]=0;
1239 decalopacity[numdecals]=opacity-distance/10;
1241 if(decalopacity[numdecals>0]){
1242 placex=vertex[Triangles[i].vertex[0]].x;
1243 placez=vertex[Triangles[i].vertex[0]].z;
1245 decaltexcoords[numdecals][0][0]=(placex-where.x)/(size)/2+.5;
1246 decaltexcoords[numdecals][0][1]=(placez-where.z)/(size)/2+.5;
1248 decalvertex[numdecals][0].x=placex;
1249 decalvertex[numdecals][0].z=placez;
1250 decalvertex[numdecals][0].y=vertex[Triangles[i].vertex[0]].y;
1253 placex=vertex[Triangles[i].vertex[1]].x;
1254 placez=vertex[Triangles[i].vertex[1]].z;
1256 decaltexcoords[numdecals][1][0]=(placex-where.x)/(size)/2+.5;
1257 decaltexcoords[numdecals][1][1]=(placez-where.z)/(size)/2+.5;
1259 decalvertex[numdecals][1].x=placex;
1260 decalvertex[numdecals][1].z=placez;
1261 decalvertex[numdecals][1].y=vertex[Triangles[i].vertex[1]].y;
1264 placex=vertex[Triangles[i].vertex[2]].x;
1265 placez=vertex[Triangles[i].vertex[2]].z;
1267 decaltexcoords[numdecals][2][0]=(placex-where.x)/(size)/2+.5;
1268 decaltexcoords[numdecals][2][1]=(placez-where.z)/(size)/2+.5;
1270 decalvertex[numdecals][2].x=placex;
1271 decalvertex[numdecals][2].z=placez;
1272 decalvertex[numdecals][2].y=vertex[Triangles[i].vertex[2]].y;
1274 if(!(decaltexcoords[numdecals][0][0]<0&&decaltexcoords[numdecals][1][0]<0&&decaltexcoords[numdecals][2][0]<0))
1275 if(!(decaltexcoords[numdecals][0][1]<0&&decaltexcoords[numdecals][1][1]<0&&decaltexcoords[numdecals][2][1]<0))
1276 if(!(decaltexcoords[numdecals][0][0]>1&&decaltexcoords[numdecals][1][0]>1&&decaltexcoords[numdecals][2][0]>1))
1277 if(!(decaltexcoords[numdecals][0][1]>1&&decaltexcoords[numdecals][1][1]>1&&decaltexcoords[numdecals][2][1]>1))
1279 if(decalrotation[numdecals]){
1282 rot.x=decaltexcoords[numdecals][j][0]-.5;
1283 rot.z=decaltexcoords[numdecals][j][1]-.5;
1284 rot=DoRotation(rot,0,-decalrotation[numdecals],0);
1285 decaltexcoords[numdecals][j][0]=rot.x+.5;
1286 decaltexcoords[numdecals][j][1]=rot.z+.5;
1289 if(numdecals<max_model_decals-1)numdecals++;
1293 else if(distance<.02&&abs(facenormals[i].x)>abs(facenormals[i].y)&&abs(facenormals[i].x)>abs(facenormals[i].z)){
1294 decalposition[numdecals]=where;
1295 decaltype[numdecals]=atype;
1296 decalrotation[numdecals]=rotation;
1297 decalalivetime[numdecals]=0;
1298 decalopacity[numdecals]=opacity-distance/10;
1300 if(decalopacity[numdecals>0]){
1301 placex=vertex[Triangles[i].vertex[0]].y;
1302 placez=vertex[Triangles[i].vertex[0]].z;
1304 decaltexcoords[numdecals][0][0]=(placex-where.y)/(size)/2+.5;
1305 decaltexcoords[numdecals][0][1]=(placez-where.z)/(size)/2+.5;
1307 decalvertex[numdecals][0].x=vertex[Triangles[i].vertex[0]].x;
1308 decalvertex[numdecals][0].z=placez;
1309 decalvertex[numdecals][0].y=placex;
1312 placex=vertex[Triangles[i].vertex[1]].y;
1313 placez=vertex[Triangles[i].vertex[1]].z;
1315 decaltexcoords[numdecals][1][0]=(placex-where.y)/(size)/2+.5;
1316 decaltexcoords[numdecals][1][1]=(placez-where.z)/(size)/2+.5;
1318 decalvertex[numdecals][1].x=vertex[Triangles[i].vertex[1]].x;
1319 decalvertex[numdecals][1].z=placez;
1320 decalvertex[numdecals][1].y=placex;
1323 placex=vertex[Triangles[i].vertex[2]].y;
1324 placez=vertex[Triangles[i].vertex[2]].z;
1326 decaltexcoords[numdecals][2][0]=(placex-where.y)/(size)/2+.5;
1327 decaltexcoords[numdecals][2][1]=(placez-where.z)/(size)/2+.5;
1329 decalvertex[numdecals][2].x=vertex[Triangles[i].vertex[2]].x;
1330 decalvertex[numdecals][2].z=placez;
1331 decalvertex[numdecals][2].y=placex;
1333 if(!(decaltexcoords[numdecals][0][0]<0&&decaltexcoords[numdecals][1][0]<0&&decaltexcoords[numdecals][2][0]<0))
1334 if(!(decaltexcoords[numdecals][0][1]<0&&decaltexcoords[numdecals][1][1]<0&&decaltexcoords[numdecals][2][1]<0))
1335 if(!(decaltexcoords[numdecals][0][0]>1&&decaltexcoords[numdecals][1][0]>1&&decaltexcoords[numdecals][2][0]>1))
1336 if(!(decaltexcoords[numdecals][0][1]>1&&decaltexcoords[numdecals][1][1]>1&&decaltexcoords[numdecals][2][1]>1))
1338 if(decalrotation[numdecals]){
1341 rot.x=decaltexcoords[numdecals][j][0]-.5;
1342 rot.z=decaltexcoords[numdecals][j][1]-.5;
1343 rot=DoRotation(rot,0,-decalrotation[numdecals],0);
1344 decaltexcoords[numdecals][j][0]=rot.x+.5;
1345 decaltexcoords[numdecals][j][1]=rot.z+.5;
1348 if(numdecals<max_model_decals-1)numdecals++;
1352 else if(distance<.02&&abs(facenormals[i].z)>abs(facenormals[i].y)&&abs(facenormals[i].z)>abs(facenormals[i].x)){
1353 decalposition[numdecals]=where;
1354 decaltype[numdecals]=atype;
1355 decalrotation[numdecals]=rotation;
1356 decalalivetime[numdecals]=0;
1357 decalopacity[numdecals]=opacity-distance/10;
1359 if(decalopacity[numdecals>0]){
1360 placex=vertex[Triangles[i].vertex[0]].x;
1361 placez=vertex[Triangles[i].vertex[0]].y;
1363 decaltexcoords[numdecals][0][0]=(placex-where.x)/(size)/2+.5;
1364 decaltexcoords[numdecals][0][1]=(placez-where.y)/(size)/2+.5;
1366 decalvertex[numdecals][0].x=placex;
1367 decalvertex[numdecals][0].z=vertex[Triangles[i].vertex[0]].z;
1368 decalvertex[numdecals][0].y=placez;
1371 placex=vertex[Triangles[i].vertex[1]].x;
1372 placez=vertex[Triangles[i].vertex[1]].y;
1374 decaltexcoords[numdecals][1][0]=(placex-where.x)/(size)/2+.5;
1375 decaltexcoords[numdecals][1][1]=(placez-where.y)/(size)/2+.5;
1377 decalvertex[numdecals][1].x=placex;
1378 decalvertex[numdecals][1].z=vertex[Triangles[i].vertex[1]].z;
1379 decalvertex[numdecals][1].y=placez;
1382 placex=vertex[Triangles[i].vertex[2]].x;
1383 placez=vertex[Triangles[i].vertex[2]].y;
1385 decaltexcoords[numdecals][2][0]=(placex-where.x)/(size)/2+.5;
1386 decaltexcoords[numdecals][2][1]=(placez-where.y)/(size)/2+.5;
1388 decalvertex[numdecals][2].x=placex;
1389 decalvertex[numdecals][2].z=vertex[Triangles[i].vertex[2]].z;
1390 decalvertex[numdecals][2].y=placez;
1392 if(!(decaltexcoords[numdecals][0][0]<0&&decaltexcoords[numdecals][1][0]<0&&decaltexcoords[numdecals][2][0]<0))
1393 if(!(decaltexcoords[numdecals][0][1]<0&&decaltexcoords[numdecals][1][1]<0&&decaltexcoords[numdecals][2][1]<0))
1394 if(!(decaltexcoords[numdecals][0][0]>1&&decaltexcoords[numdecals][1][0]>1&&decaltexcoords[numdecals][2][0]>1))
1395 if(!(decaltexcoords[numdecals][0][1]>1&&decaltexcoords[numdecals][1][1]>1&&decaltexcoords[numdecals][2][1]>1))
1397 if(decalrotation[numdecals]){
1400 rot.x=decaltexcoords[numdecals][j][0]-.5;
1401 rot.z=decaltexcoords[numdecals][j][1]-.5;
1402 rot=DoRotation(rot,0,-decalrotation[numdecals],0);
1403 decaltexcoords[numdecals][j][0]=rot.x+.5;
1404 decaltexcoords[numdecals][j][1]=rot.z+.5;
1407 if(numdecals<max_model_decals-1)numdecals++;
1418 textureptr.destroy();
1421 void Model::deallocate()
1425 if(owner)free(owner);
1428 if(possible)free(possible);
1431 if(vertex)free(vertex);
1434 if(normals)free(normals);
1437 if(facenormals)free(facenormals);
1440 if(Triangles)free(Triangles);
1443 if(vArray)free(vArray);
1450 for(i=0;i<max_model_decals;i++)
1454 free(decaltexcoords[i][j]);
1456 free(decaltexcoords[i]);
1458 free(decaltexcoords);
1465 for(i=0;i<max_model_decals;i++)
1467 free(decalvertex[i]);
1480 free(decalrotation);
1483 free(decalalivetime);
1486 free(decalposition);
1493 vertexNum = 0,TriangleNum = 0;
1496 type = 0,oldtype = 0;
1506 memset(&modelTexture, 0, sizeof(modelTexture));
1510 boundingspherecenter = 0;
1511 boundingsphereradius = 0;