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.
24 //#include "altivec.h"
26 extern float multiplier;
27 extern float viewdistance;
29 extern float fadestart;
30 extern float texdetail;
32 extern int loadscreencolor;
35 extern bool visibleloading;
37 void *allocate_aligned(size_t pointer_size, size_t byte_alignment)
39 uintptr_t pointer = (uintptr_t)malloc(pointer_size + byte_alignment + 1);
40 uintptr_t aligned_pointer = (pointer + byte_alignment + 1);
41 aligned_pointer -= (aligned_pointer % byte_alignment);
42 *(uint8_t *)(aligned_pointer - 1) = (aligned_pointer - pointer);
43 return (void *)aligned_pointer;
46 void free_aligned(void *aligned_pointer)
48 free((uint8_t *)(aligned_pointer) - *((uint8_t *)(aligned_pointer) - 1));
51 void dealloc(void* param){
56 int Model::LineCheck(XYZ *p1,XYZ *p2, XYZ *p, XYZ *move, float *rotate)
59 static float distance;
60 static float olddistance;
61 static int intersecting;
62 static int firstintersecting;
67 if(*rotate)*p1=DoRotation(*p1,0,-*rotate,0);
68 if(*rotate)*p2=DoRotation(*p2,0,-*rotate,0);
69 if(!sphere_line_intersection(p1,p2,&boundingspherecenter,
70 &boundingsphereradius))return -1;
73 for (j=0;j<TriangleNum;j++){
74 intersecting=LineFacetd(p1,p2,&vertex[Triangles[j].vertex[0]],&vertex[Triangles[j].vertex[1]],&vertex[Triangles[j].vertex[2]],&facenormals[j],&point);
75 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);
76 if((distance<olddistance||firstintersecting==-1)&&intersecting){olddistance=distance; firstintersecting=j; *p=point;}
79 if(*rotate)*p=DoRotation(*p,0,*rotate,0);
81 return firstintersecting;
84 int Model::LineCheckSlide(XYZ *p1,XYZ *p2, XYZ *p, XYZ *move, float *rotate)
87 static float distance;
88 static float olddistance;
89 static int intersecting;
90 static int firstintersecting;
95 if(!sphere_line_intersection(p1,p2,&boundingspherecenter,
96 &boundingsphereradius))return -1;
98 if(*rotate)*p1=DoRotation(*p1,0,-*rotate,0);
99 if(*rotate)*p2=DoRotation(*p2,0,-*rotate,0);
101 for (j=0;j<TriangleNum;j++){
102 intersecting=LineFacetd(p1,p2,&vertex[Triangles[j].vertex[0]],&vertex[Triangles[j].vertex[1]],&vertex[Triangles[j].vertex[2]],&facenormals[j],&point);
103 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);
104 if((distance<olddistance||firstintersecting==-1)&&intersecting){olddistance=distance; firstintersecting=j;}
107 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)));
108 *p2-=facenormals[firstintersecting]*distance;
110 if(*rotate)*p2=DoRotation(*p2,0,*rotate,0);
112 return firstintersecting;
115 int Model::LineCheckPossible(XYZ *p1,XYZ *p2, XYZ *p, XYZ *move, float *rotate)
118 static float distance;
119 static float olddistance;
120 static int intersecting;
121 static int firstintersecting;
126 if(!sphere_line_intersection(p1,p2,&boundingspherecenter,
127 &boundingsphereradius))return -1;
128 firstintersecting=-1;
129 if(*rotate)*p1=DoRotation(*p1,0,-*rotate,0);
130 if(*rotate)*p2=DoRotation(*p2,0,-*rotate,0);
132 if(numpossible>0&&numpossible<TriangleNum)
133 for (j=0;j<numpossible;j++){
134 if(possible[j]>=0&&possible[j]<TriangleNum){
135 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);
136 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);
137 if((distance<olddistance||firstintersecting==-1)&&intersecting){olddistance=distance; firstintersecting=possible[j]; *p=point;}
141 if(*rotate)*p=DoRotation(*p,0,*rotate,0);
143 return firstintersecting;
146 int Model::LineCheckSlidePossible(XYZ *p1,XYZ *p2, XYZ *p, XYZ *move, float *rotate)
149 static float distance;
150 static float olddistance;
151 static int intersecting;
152 static int firstintersecting;
157 if(!sphere_line_intersection(p1,p2,&boundingspherecenter,
158 &boundingsphereradius))return -1;
159 firstintersecting=-1;
160 if(*rotate)*p1=DoRotation(*p1,0,-*rotate,0);
161 if(*rotate)*p2=DoRotation(*p2,0,-*rotate,0);
164 for (j=0;j<numpossible;j++){
165 if(possible[j]>=0&&possible[j]<TriangleNum){
166 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);
167 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);
168 if((distance<olddistance||firstintersecting==-1)&&intersecting){olddistance=distance; firstintersecting=possible[j];}
172 if(firstintersecting>0){
173 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)));
174 *p2-=facenormals[firstintersecting]*distance;
177 if(*rotate)*p2=DoRotation(*p2,0,*rotate,0);
179 return firstintersecting;
182 int Model::SphereCheck(XYZ *p1,float radius, XYZ *p, XYZ *move, float *rotate)
185 static float distance;
186 static float olddistance;
187 static int intersecting;
188 static int firstintersecting;
191 static XYZ start,end;
193 firstintersecting=-1;
197 if(*rotate)*p1=DoRotation(*p1,0,-*rotate,0);
198 if(findDistancefast(p1,&boundingspherecenter)>radius*radius+boundingsphereradius*boundingsphereradius)return -1;
201 for (j=0;j<TriangleNum;j++){
203 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)));
205 point=*p1-facenormals[j]*distance;
206 if(PointInTriangle( &point, facenormals[j], &vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[1]], &vertex[Triangles[j].vertex[2]]))intersecting=1;
207 if(!intersecting)intersecting=sphere_line_intersection(&vertex[Triangles[j].vertex[0]],
208 &vertex[Triangles[j].vertex[1]],
210 if(!intersecting)intersecting=sphere_line_intersection(&vertex[Triangles[j].vertex[1]],
211 &vertex[Triangles[j].vertex[2]],
213 if(!intersecting)intersecting=sphere_line_intersection(&vertex[Triangles[j].vertex[0]],
214 &vertex[Triangles[j].vertex[2]],
217 *p1+=facenormals[j]*(distance-radius);
221 if(LineFacetd(&start,&end,&vertex[Triangles[j].vertex[0]],&vertex[Triangles[j].vertex[1]],&vertex[Triangles[j].vertex[2]],&facenormals[j],&point)){
222 p1->y=point.y+radius;
226 if((distance<olddistance||firstintersecting==-1)&&intersecting){olddistance=distance; firstintersecting=j; *p=point;}
229 if(*rotate)*p=DoRotation(*p,0,*rotate,0);
231 if(*rotate)*p1=DoRotation(*p1,0,*rotate,0);
233 return firstintersecting;
236 int Model::SphereCheckPossible(XYZ *p1,float radius, XYZ *move, float *rotate)
239 static float distance;
240 static float olddistance;
241 static int intersecting;
242 static int firstintersecting;
245 static XYZ start,end;
247 firstintersecting=-1;
254 if(*rotate)*p1=DoRotation(*p1,0,-*rotate,0);
255 if(findDistancefast(p1,&boundingspherecenter)>radius*radius+boundingsphereradius*boundingsphereradius){*p1=oldp1; return -1;}
257 for (j=0;j<TriangleNum;j++){
259 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)));
261 point=*p1-facenormals[j]*distance;
262 if(PointInTriangle( &point, facenormals[j], &vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[1]], &vertex[Triangles[j].vertex[2]]))intersecting=1;
263 if(!intersecting)intersecting=sphere_line_intersection(&vertex[Triangles[j].vertex[0]],
264 &vertex[Triangles[j].vertex[1]],
266 if(!intersecting)intersecting=sphere_line_intersection(&vertex[Triangles[j].vertex[1]],
267 &vertex[Triangles[j].vertex[2]],
269 if(!intersecting)intersecting=sphere_line_intersection(&vertex[Triangles[j].vertex[0]],
270 &vertex[Triangles[j].vertex[2]],
273 //if(j>=0&&j<TriangleNum)
274 possible[numpossible]=j;
278 if((distance<olddistance||firstintersecting==-1)&&intersecting){olddistance=distance; firstintersecting=j;}
280 if(*rotate)*p1=DoRotation(*p1,0,*rotate,0);
282 return firstintersecting;
286 void Model::UpdateVertexArray(){
287 if(type!=normaltype&&type!=decalstype)return;
291 for(i=0;i<TriangleNum;i++){
293 vArray[j+0]=Triangles[i].gx[0];
294 vArray[j+1]=Triangles[i].gy[0];
295 vArray[j+2]=normals[Triangles[i].vertex[0]].x;
296 vArray[j+3]=normals[Triangles[i].vertex[0]].y;
297 vArray[j+4]=normals[Triangles[i].vertex[0]].z;
298 vArray[j+5]=vertex[Triangles[i].vertex[0]].x;
299 vArray[j+6]=vertex[Triangles[i].vertex[0]].y;
300 vArray[j+7]=vertex[Triangles[i].vertex[0]].z;
302 vArray[j+8]=Triangles[i].gx[1];
303 vArray[j+9]=Triangles[i].gy[1];
304 vArray[j+10]=normals[Triangles[i].vertex[1]].x;
305 vArray[j+11]=normals[Triangles[i].vertex[1]].y;
306 vArray[j+12]=normals[Triangles[i].vertex[1]].z;
307 vArray[j+13]=vertex[Triangles[i].vertex[1]].x;
308 vArray[j+14]=vertex[Triangles[i].vertex[1]].y;
309 vArray[j+15]=vertex[Triangles[i].vertex[1]].z;
311 vArray[j+16]=Triangles[i].gx[2];
312 vArray[j+17]=Triangles[i].gy[2];
313 vArray[j+18]=normals[Triangles[i].vertex[2]].x;
314 vArray[j+19]=normals[Triangles[i].vertex[2]].y;
315 vArray[j+20]=normals[Triangles[i].vertex[2]].z;
316 vArray[j+21]=vertex[Triangles[i].vertex[2]].x;
317 vArray[j+22]=vertex[Triangles[i].vertex[2]].y;
318 vArray[j+23]=vertex[Triangles[i].vertex[2]].z;
321 for(i=0;i<TriangleNum;i++){
323 vArray[j+0]=Triangles[i].gx[0];
324 vArray[j+1]=Triangles[i].gy[0];
325 vArray[j+2]=facenormals[i].x*-1;
326 vArray[j+3]=facenormals[i].y*-1;
327 vArray[j+4]=facenormals[i].z*-1;
328 vArray[j+5]=vertex[Triangles[i].vertex[0]].x;
329 vArray[j+6]=vertex[Triangles[i].vertex[0]].y;
330 vArray[j+7]=vertex[Triangles[i].vertex[0]].z;
332 vArray[j+8]=Triangles[i].gx[1];
333 vArray[j+9]=Triangles[i].gy[1];
334 vArray[j+10]=facenormals[i].x*-1;
335 vArray[j+11]=facenormals[i].y*-1;
336 vArray[j+12]=facenormals[i].z*-1;
337 vArray[j+13]=vertex[Triangles[i].vertex[1]].x;
338 vArray[j+14]=vertex[Triangles[i].vertex[1]].y;
339 vArray[j+15]=vertex[Triangles[i].vertex[1]].z;
341 vArray[j+16]=Triangles[i].gx[2];
342 vArray[j+17]=Triangles[i].gy[2];
343 vArray[j+18]=facenormals[i].x*-1;
344 vArray[j+19]=facenormals[i].y*-1;
345 vArray[j+20]=facenormals[i].z*-1;
346 vArray[j+21]=vertex[Triangles[i].vertex[2]].x;
347 vArray[j+22]=vertex[Triangles[i].vertex[2]].y;
348 vArray[j+23]=vertex[Triangles[i].vertex[2]].z;
353 void Model::UpdateVertexArrayNoTex(){
354 if(type!=normaltype&&type!=decalstype)return;
358 for(i=0;i<TriangleNum;i++){
360 vArray[j+2]=normals[Triangles[i].vertex[0]].x;
361 vArray[j+3]=normals[Triangles[i].vertex[0]].y;
362 vArray[j+4]=normals[Triangles[i].vertex[0]].z;
363 vArray[j+5]=vertex[Triangles[i].vertex[0]].x;
364 vArray[j+6]=vertex[Triangles[i].vertex[0]].y;
365 vArray[j+7]=vertex[Triangles[i].vertex[0]].z;
367 vArray[j+10]=normals[Triangles[i].vertex[1]].x;
368 vArray[j+11]=normals[Triangles[i].vertex[1]].y;
369 vArray[j+12]=normals[Triangles[i].vertex[1]].z;
370 vArray[j+13]=vertex[Triangles[i].vertex[1]].x;
371 vArray[j+14]=vertex[Triangles[i].vertex[1]].y;
372 vArray[j+15]=vertex[Triangles[i].vertex[1]].z;
374 vArray[j+18]=normals[Triangles[i].vertex[2]].x;
375 vArray[j+19]=normals[Triangles[i].vertex[2]].y;
376 vArray[j+20]=normals[Triangles[i].vertex[2]].z;
377 vArray[j+21]=vertex[Triangles[i].vertex[2]].x;
378 vArray[j+22]=vertex[Triangles[i].vertex[2]].y;
379 vArray[j+23]=vertex[Triangles[i].vertex[2]].z;
382 for(i=0;i<TriangleNum;i++){
384 vArray[j+2]=facenormals[i].x*-1;
385 vArray[j+3]=facenormals[i].y*-1;
386 vArray[j+4]=facenormals[i].z*-1;
387 vArray[j+5]=vertex[Triangles[i].vertex[0]].x;
388 vArray[j+6]=vertex[Triangles[i].vertex[0]].y;
389 vArray[j+7]=vertex[Triangles[i].vertex[0]].z;
391 vArray[j+10]=facenormals[i].x*-1;
392 vArray[j+11]=facenormals[i].y*-1;
393 vArray[j+12]=facenormals[i].z*-1;
394 vArray[j+13]=vertex[Triangles[i].vertex[1]].x;
395 vArray[j+14]=vertex[Triangles[i].vertex[1]].y;
396 vArray[j+15]=vertex[Triangles[i].vertex[1]].z;
398 vArray[j+18]=facenormals[i].x*-1;
399 vArray[j+19]=facenormals[i].y*-1;
400 vArray[j+20]=facenormals[i].z*-1;
401 vArray[j+21]=vertex[Triangles[i].vertex[2]].x;
402 vArray[j+22]=vertex[Triangles[i].vertex[2]].y;
403 vArray[j+23]=vertex[Triangles[i].vertex[2]].z;
407 void Model::UpdateVertexArrayNoTexNoNorm(){
408 if(type!=normaltype&&type!=decalstype)return;
411 for(i=0;i<TriangleNum;i++){
413 vArray[j+5]=vertex[Triangles[i].vertex[0]].x;
414 vArray[j+6]=vertex[Triangles[i].vertex[0]].y;
415 vArray[j+7]=vertex[Triangles[i].vertex[0]].z;
417 vArray[j+13]=vertex[Triangles[i].vertex[1]].x;
418 vArray[j+14]=vertex[Triangles[i].vertex[1]].y;
419 vArray[j+15]=vertex[Triangles[i].vertex[1]].z;
421 vArray[j+21]=vertex[Triangles[i].vertex[2]].x;
422 vArray[j+22]=vertex[Triangles[i].vertex[2]].y;
423 vArray[j+23]=vertex[Triangles[i].vertex[2]].z;
427 bool Model::loadnotex(char *filename )
432 int oldvertexNum,oldTriangleNum;
433 oldvertexNum=vertexNum;
434 oldTriangleNum=TriangleNum;
439 tfile=fopen( filename, "rb" );
440 // read model settings
442 fseek(tfile, 0, SEEK_SET);
443 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
445 // read the model data
446 /*if(owner)dealloc(owner);
447 if(possible)dealloc(possible);
448 if(vertex)dealloc(vertex);
449 if(normals)dealloc(normals);
450 if(facenormals)dealloc(facenormals);
451 if(Triangles)dealloc(Triangles);
452 if(vArray)dealloc(vArray);*/
457 owner = (int*)malloc(sizeof(int)*vertexNum);
458 possible = (int*)malloc(sizeof(int)*TriangleNum);
459 vertex = (XYZ*)malloc(sizeof(XYZ)*vertexNum);
460 Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle)*TriangleNum);
461 vArray = (GLfloat*)malloc(sizeof(GLfloat)*TriangleNum*24);
463 for(i=0;i<vertexNum;i++){
464 funpackf(tfile, "Bf Bf Bf", &vertex[i].x,&vertex[i].y,&vertex[i].z);
467 for(i=0;i<TriangleNum;i++){
468 // funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
470 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
471 Triangles[i].vertex[ 0] = vertex[ 0];
472 Triangles[i].vertex[ 1] = vertex[ 2];
473 Triangles[i].vertex[ 2] = vertex[ 4];
474 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
475 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
482 for(i=0;i<vertexNum;i++){
487 boundingsphereradius=0;
488 for(i=0;i<vertexNum;i++){
489 for(j=0;j<vertexNum;j++){
490 if(j!=i&&findDistancefast(&vertex[j],&vertex[i])/2>boundingsphereradius){
491 boundingsphereradius=findDistancefast(&vertex[j],&vertex[i])/2;
492 boundingspherecenter=(vertex[i]+vertex[j])/2;
496 boundingsphereradius=fast_sqrt(boundingsphereradius);
502 bool Model::load(char *filename,bool texture )
509 LOG(std::string("Loading model...") + filename);
513 pgame->LoadingScreen();
516 int oldvertexNum,oldTriangleNum;
517 oldvertexNum=vertexNum;
518 oldTriangleNum=TriangleNum;
523 tfile=fopen( ConvertFileName(filename), "rb" );
524 // read model settings
527 fseek(tfile, 0, SEEK_SET);
528 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
530 // read the model data
531 /*if(owner)dealloc(owner);
532 if(possible)dealloc(possible);
533 if(vertex)dealloc(vertex);
534 if(normals)dealloc(normals);
535 if(facenormals)dealloc(facenormals);
536 if(Triangles)dealloc(Triangles);
537 if(vArray)dealloc(vArray);*/
542 owner = (int*)malloc(sizeof(int)*vertexNum);
543 possible = (int*)malloc(sizeof(int)*TriangleNum);
544 vertex = (XYZ*)malloc(sizeof(XYZ)*vertexNum);
545 normals = (XYZ*)malloc(sizeof(XYZ)*vertexNum);
546 facenormals = (XYZ*)malloc(sizeof(XYZ)*TriangleNum);
547 Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle)*TriangleNum);
548 vArray = (GLfloat*)malloc(sizeof(GLfloat)*TriangleNum*24);
550 for(i=0;i<vertexNum;i++){
551 funpackf(tfile, "Bf Bf Bf", &vertex[i].x,&vertex[i].y,&vertex[i].z);
554 for(i=0;i<TriangleNum;i++){
555 // funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
557 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
558 Triangles[i].vertex[ 0] = vertex[ 0];
559 Triangles[i].vertex[ 1] = vertex[ 2];
560 Triangles[i].vertex[ 2] = vertex[ 4];
561 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
562 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
571 for(i=0;i<vertexNum;i++){
576 boundingsphereradius=0;
577 for(i=0;i<vertexNum;i++){
578 for(j=0;j<vertexNum;j++){
579 if(j!=i&&findDistancefast(&vertex[j],&vertex[i])/2>boundingsphereradius){
580 boundingsphereradius=findDistancefast(&vertex[j],&vertex[i])/2;
581 boundingspherecenter=(vertex[i]+vertex[j])/2;
585 boundingsphereradius=fast_sqrt(boundingsphereradius);
590 bool Model::loaddecal(char *filename,bool texture )
597 LOG(std::string("Loading decal...") + filename);
599 int oldvertexNum,oldTriangleNum;
600 oldvertexNum=vertexNum;
601 oldTriangleNum=TriangleNum;
607 tfile=fopen( filename, "rb" );
608 // read model settings
611 fseek(tfile, 0, SEEK_SET);
612 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
614 // read the model data
616 /*if(owner)dealloc(owner);
617 if(possible)dealloc(possible);
618 if(vertex)dealloc(vertex);
619 if(normals)dealloc(normals);
620 if(facenormals)dealloc(facenormals);
621 if(Triangles)dealloc(Triangles);
622 if(vArray)dealloc(vArray);*/
627 owner = (int*)malloc(sizeof(int)*vertexNum);
628 possible = (int*)malloc(sizeof(int)*TriangleNum);
629 vertex = (XYZ*)malloc(sizeof(XYZ)*vertexNum);
630 normals = (XYZ*)malloc(sizeof(XYZ)*vertexNum);
631 facenormals = (XYZ*)malloc(sizeof(XYZ)*TriangleNum);
632 Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle)*TriangleNum);
633 vArray = (GLfloat*)malloc(sizeof(GLfloat)*TriangleNum*24);
636 for(i=0;i<vertexNum;i++){
637 funpackf(tfile, "Bf Bf Bf", &vertex[i].x,&vertex[i].y,&vertex[i].z);
640 for(i=0;i<TriangleNum;i++){
641 // funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
643 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
644 Triangles[i].vertex[ 0] = vertex[ 0];
645 Triangles[i].vertex[ 1] = vertex[ 2];
646 Triangles[i].vertex[ 2] = vertex[ 4];
647 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
648 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
658 for(i=0;i<vertexNum;i++){
662 boundingsphereradius=0;
663 for(i=0;i<vertexNum;i++){
664 for(j=0;j<vertexNum;j++){
665 if(j!=i&&findDistancefast(&vertex[j],&vertex[i])/2>boundingsphereradius){
666 boundingsphereradius=findDistancefast(&vertex[j],&vertex[i])/2;
667 boundingspherecenter=(vertex[i]+vertex[j])/2;
671 boundingsphereradius=fast_sqrt(boundingsphereradius);
675 decaltexcoords = (float***)malloc(sizeof(float**)*max_model_decals);
676 for(i=0;i<max_model_decals;i++){
677 decaltexcoords[i] = (float**)malloc(sizeof(float*)*3);
679 decaltexcoords[i][j] = (float*)malloc(sizeof(float)*2);
682 //if(decalvertex)free(decalvertex);
683 decalvertex = (XYZ**)malloc(sizeof(XYZ*)*max_model_decals);
684 for(i=0;i<max_model_decals;i++){
685 decalvertex[i] = (XYZ*)malloc(sizeof(XYZ)*3);
688 decaltype = (int*)malloc(sizeof(int)*max_model_decals);
689 decalopacity = (float*)malloc(sizeof(float)*max_model_decals);
690 decalrotation = (float*)malloc(sizeof(float)*max_model_decals);
691 decalalivetime = (float*)malloc(sizeof(float)*max_model_decals);
692 decalposition = (XYZ*)malloc(sizeof(XYZ)*max_model_decals);
698 bool Model::loadraw(char *filename )
705 LOG(std::string("Loading raw...") + filename);
707 int oldvertexNum,oldTriangleNum;
708 oldvertexNum=vertexNum;
709 oldTriangleNum=TriangleNum;
714 tfile=fopen( filename, "rb" );
715 // read model settings
718 fseek(tfile, 0, SEEK_SET);
719 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
721 // read the model data
722 /*if(owner)dealloc(owner);
723 if(possible)dealloc(possible);
724 if(vertex)dealloc(vertex);
725 if(normals)dealloc(normals);
726 if(facenormals)dealloc(facenormals);
727 if(Triangles)dealloc(Triangles);
728 if(vArray)dealloc(vArray);*/
733 owner = (int*)malloc(sizeof(int)*vertexNum);
734 possible = (int*)malloc(sizeof(int)*TriangleNum);
735 vertex = (XYZ*)malloc(sizeof(XYZ)*vertexNum);
736 Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle)*TriangleNum);
737 vArray = (GLfloat*)malloc(sizeof(GLfloat)*TriangleNum*24);
740 for(i=0;i<vertexNum;i++){
741 funpackf(tfile, "Bf Bf Bf", &vertex[i].x,&vertex[i].y,&vertex[i].z);
744 for(i=0;i<TriangleNum;i++){
745 // funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
747 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
748 Triangles[i].vertex[ 0] = vertex[ 0];
749 Triangles[i].vertex[ 1] = vertex[ 2];
750 Triangles[i].vertex[ 2] = vertex[ 4];
751 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
752 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
758 for(i=0;i<vertexNum;i++){
766 void Model::UniformTexCoords()
769 for(i=0; i<TriangleNum; i++){
770 Triangles[i].gy[0]=vertex[Triangles[i].vertex[0]].y;
771 Triangles[i].gy[1]=vertex[Triangles[i].vertex[1]].y;
772 Triangles[i].gy[2]=vertex[Triangles[i].vertex[2]].y;
773 Triangles[i].gx[0]=vertex[Triangles[i].vertex[0]].x;
774 Triangles[i].gx[1]=vertex[Triangles[i].vertex[1]].x;
775 Triangles[i].gx[2]=vertex[Triangles[i].vertex[2]].x;
781 void Model::FlipTexCoords()
784 for(i=0; i<TriangleNum; i++){
785 Triangles[i].gy[0]=-Triangles[i].gy[0];
786 Triangles[i].gy[1]=-Triangles[i].gy[1];
787 Triangles[i].gy[2]=-Triangles[i].gy[2];
792 void Model::ScaleTexCoords(float howmuch)
795 for(i=0; i<TriangleNum; i++){
796 Triangles[i].gx[0]*=howmuch;
797 Triangles[i].gx[1]*=howmuch;
798 Triangles[i].gx[2]*=howmuch;
799 Triangles[i].gy[0]*=howmuch;
800 Triangles[i].gy[1]*=howmuch;
801 Triangles[i].gy[2]*=howmuch;
806 void Model::Scale(float xscale,float yscale,float zscale)
809 for(i=0; i<vertexNum; i++){
818 boundingsphereradius=0;
819 for(i=0;i<vertexNum;i++){
820 for(j=0;j<vertexNum;j++){
821 if(j!=i&&findDistancefast(&vertex[j],&vertex[i])/2>boundingsphereradius){
822 boundingsphereradius=findDistancefast(&vertex[j],&vertex[i])/2;
823 boundingspherecenter=(vertex[i]+vertex[j])/2;
827 boundingsphereradius=fast_sqrt(boundingsphereradius);
830 void Model::ScaleNormals(float xscale,float yscale,float zscale)
832 if(type!=normaltype&&type!=decalstype)return;
834 for(i=0; i<vertexNum; i++){
835 normals[i].x*=xscale;
836 normals[i].y*=yscale;
837 normals[i].z*=zscale;
839 for(i=0; i<TriangleNum; i++){
840 facenormals[i].x*=xscale;
841 facenormals[i].y*=yscale;
842 facenormals[i].z*=zscale;
847 void Model::Translate(float xtrans,float ytrans,float ztrans)
850 for(i=0; i<vertexNum; i++){
858 boundingsphereradius=0;
859 for(i=0;i<vertexNum;i++){
860 for(j=0;j<vertexNum;j++){
861 if(j!=i&&findDistancefast(&vertex[j],&vertex[i])/2>boundingsphereradius){
862 boundingsphereradius=findDistancefast(&vertex[j],&vertex[i])/2;
863 boundingspherecenter=(vertex[i]+vertex[j])/2;
867 boundingsphereradius=fast_sqrt(boundingsphereradius);
870 void Model::Rotate(float xang,float yang,float zang)
873 for(i=0; i<vertexNum; i++){
874 vertex[i]=DoRotation(vertex[i],xang,yang,zang);
879 boundingsphereradius=0;
880 for(i=0;i<vertexNum;i++){
881 for(j=0;j<vertexNum;j++){
882 if(j!=i&&findDistancefast(&vertex[j],&vertex[i])/2>boundingsphereradius){
883 boundingsphereradius=findDistancefast(&vertex[j],&vertex[i])/2;
884 boundingspherecenter=(vertex[i]+vertex[j])/2;
888 boundingsphereradius=fast_sqrt(boundingsphereradius);
892 void Model::CalculateNormals(bool facenormalise)
896 pgame->LoadingScreen();
899 if(type!=normaltype&&type!=decalstype)return;
901 for(i=0; i<vertexNum; i++){
907 for(i=0;i<TriangleNum;i++){
908 CrossProduct(vertex[Triangles[i].vertex[1]]-vertex[Triangles[i].vertex[0]],vertex[Triangles[i].vertex[2]]-vertex[Triangles[i].vertex[0]],&facenormals[i]);
910 normals[Triangles[i].vertex[0]].x+=facenormals[i].x;
911 normals[Triangles[i].vertex[0]].y+=facenormals[i].y;
912 normals[Triangles[i].vertex[0]].z+=facenormals[i].z;
914 normals[Triangles[i].vertex[1]].x+=facenormals[i].x;
915 normals[Triangles[i].vertex[1]].y+=facenormals[i].y;
916 normals[Triangles[i].vertex[1]].z+=facenormals[i].z;
918 normals[Triangles[i].vertex[2]].x+=facenormals[i].x;
919 normals[Triangles[i].vertex[2]].y+=facenormals[i].y;
920 normals[Triangles[i].vertex[2]].z+=facenormals[i].z;
921 if(facenormalise)Normalise(&facenormals[i]);
923 for(i=0; i<vertexNum; i++){
924 Normalise(&normals[i]);
927 UpdateVertexArrayNoTex();
930 void Model::drawimmediate()
932 glBindTexture(GL_TEXTURE_2D,(unsigned long)textureptr);
933 glBegin(GL_TRIANGLES);
934 for(int i=0;i<TriangleNum;i++){
935 /*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){
936 if(isnormal(vertex[Triangles[i].vertex[0]].x)&&isnormal(vertex[Triangles[i].vertex[0]].y)&&isnormal(vertex[Triangles[i].vertex[0]].z)
937 &&isnormal(vertex[Triangles[i].vertex[1]].x)&&isnormal(vertex[Triangles[i].vertex[1]].y)&&isnormal(vertex[Triangles[i].vertex[1]].z)
938 &&isnormal(vertex[Triangles[i].vertex[2]].x)&&isnormal(vertex[Triangles[i].vertex[2]].y)&&isnormal(vertex[Triangles[i].vertex[2]].z)){
940 glTexCoord2f(Triangles[i].gx[0],Triangles[i].gy[0]);
941 if(color)glColor3f(normals[Triangles[i].vertex[0]].x,normals[Triangles[i].vertex[0]].y,normals[Triangles[i].vertex[0]].z);
942 if(!color&&!flat)glNormal3f(normals[Triangles[i].vertex[0]].x,normals[Triangles[i].vertex[0]].y,normals[Triangles[i].vertex[0]].z);
943 if(!color&&flat)glNormal3f(facenormals[i].x,facenormals[i].y,facenormals[i].y);
944 glVertex3f(vertex[Triangles[i].vertex[0]].x,vertex[Triangles[i].vertex[0]].y,vertex[Triangles[i].vertex[0]].z);
946 glTexCoord2f(Triangles[i].gx[1],Triangles[i].gy[1]);
947 if(color)glColor3f(normals[Triangles[i].vertex[1]].x,normals[Triangles[i].vertex[1]].y,normals[Triangles[i].vertex[1]].z);
948 if(!color&&!flat)glNormal3f(normals[Triangles[i].vertex[1]].x,normals[Triangles[i].vertex[1]].y,normals[Triangles[i].vertex[1]].z);
949 if(!color&&flat)glNormal3f(facenormals[i].x,facenormals[i].y,facenormals[i].y);
950 glVertex3f(vertex[Triangles[i].vertex[1]].x,vertex[Triangles[i].vertex[1]].y,vertex[Triangles[i].vertex[1]].z);
952 glTexCoord2f(Triangles[i].gx[2],Triangles[i].gy[2]);
953 if(color)glColor3f(normals[Triangles[i].vertex[2]].x,normals[Triangles[i].vertex[2]].y,normals[Triangles[i].vertex[2]].z);
954 if(!color&&!flat)glNormal3f(normals[Triangles[i].vertex[2]].x,normals[Triangles[i].vertex[2]].y,normals[Triangles[i].vertex[2]].z);
955 if(!color&&flat)glNormal3f(facenormals[i].x,facenormals[i].y,facenormals[i].y);
956 glVertex3f(vertex[Triangles[i].vertex[2]].x,vertex[Triangles[i].vertex[2]].y,vertex[Triangles[i].vertex[2]].z);
965 if(type!=normaltype&&type!=decalstype)return;
967 glEnableClientState(GL_NORMAL_ARRAY);
968 glEnableClientState(GL_VERTEX_ARRAY);
969 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
971 if(!color)glInterleavedArrays( GL_T2F_N3F_V3F,8*sizeof(GLfloat),&vArray[0]);
972 if(color)glInterleavedArrays( GL_T2F_C3F_V3F,8*sizeof(GLfloat),&vArray[0]);
973 glBindTexture(GL_TEXTURE_2D,(unsigned long)textureptr);
976 glLockArraysEXT( 0, TriangleNum*3);
978 glDrawArrays(GL_TRIANGLES, 0, TriangleNum*3);
984 if(!color)glDisableClientState(GL_NORMAL_ARRAY);
985 if(color)glDisableClientState(GL_COLOR_ARRAY);
986 glDisableClientState(GL_VERTEX_ARRAY);
987 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
991 void Model::drawdifftex(GLuint texture)
993 glEnableClientState(GL_NORMAL_ARRAY);
994 glEnableClientState(GL_VERTEX_ARRAY);
995 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
996 if(!color)glInterleavedArrays( GL_T2F_N3F_V3F,8*sizeof(GLfloat),&vArray[0]);
997 if(color)glInterleavedArrays( GL_T2F_C3F_V3F,8*sizeof(GLfloat),&vArray[0]);
999 glBindTexture(GL_TEXTURE_2D,(unsigned long)texture);
1000 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
1001 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
1005 glLockArraysEXT( 0, TriangleNum*3);
1007 glDrawArrays(GL_TRIANGLES, 0, TriangleNum*3);
1009 glUnlockArraysEXT();
1013 if(!color)glDisableClientState(GL_NORMAL_ARRAY);
1014 if(color)glDisableClientState(GL_COLOR_ARRAY);
1015 glDisableClientState(GL_VERTEX_ARRAY);
1016 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1017 //drawdiffteximmediate(texture);
1020 void Model::drawdiffteximmediate(GLuint texture)
1022 glBindTexture(GL_TEXTURE_2D,(unsigned long)texture);
1024 glBegin(GL_TRIANGLES);
1025 for(int i=0;i<TriangleNum;i++){
1026 /*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){
1027 if(isnormal(vertex[Triangles[i].vertex[0]].x)&&isnormal(vertex[Triangles[i].vertex[0]].y)&&isnormal(vertex[Triangles[i].vertex[0]].z)
1028 &&isnormal(vertex[Triangles[i].vertex[1]].x)&&isnormal(vertex[Triangles[i].vertex[1]].y)&&isnormal(vertex[Triangles[i].vertex[1]].z)
1029 &&isnormal(vertex[Triangles[i].vertex[2]].x)&&isnormal(vertex[Triangles[i].vertex[2]].y)&&isnormal(vertex[Triangles[i].vertex[2]].z)){
1030 */glTexCoord2f(Triangles[i].gx[0],Triangles[i].gy[0]);
1031 if(color)glColor3f(normals[Triangles[i].vertex[0]].x,normals[Triangles[i].vertex[0]].y,normals[Triangles[i].vertex[0]].z);
1032 if(!color&&!flat)glNormal3f(normals[Triangles[i].vertex[0]].x,normals[Triangles[i].vertex[0]].y,normals[Triangles[i].vertex[0]].z);
1033 if(!color&&flat)glNormal3f(facenormals[i].x,facenormals[i].y,facenormals[i].y);
1034 glVertex3f(vertex[Triangles[i].vertex[0]].x,vertex[Triangles[i].vertex[0]].y,vertex[Triangles[i].vertex[0]].z);
1036 glTexCoord2f(Triangles[i].gx[1],Triangles[i].gy[1]);
1037 if(color)glColor3f(normals[Triangles[i].vertex[1]].x,normals[Triangles[i].vertex[1]].y,normals[Triangles[i].vertex[1]].z);
1038 if(!color&&!flat)glNormal3f(normals[Triangles[i].vertex[1]].x,normals[Triangles[i].vertex[1]].y,normals[Triangles[i].vertex[1]].z);
1039 if(!color&&flat)glNormal3f(facenormals[i].x,facenormals[i].y,facenormals[i].y);
1040 glVertex3f(vertex[Triangles[i].vertex[1]].x,vertex[Triangles[i].vertex[1]].y,vertex[Triangles[i].vertex[1]].z);
1042 glTexCoord2f(Triangles[i].gx[2],Triangles[i].gy[2]);
1043 if(color)glColor3f(normals[Triangles[i].vertex[2]].x,normals[Triangles[i].vertex[2]].y,normals[Triangles[i].vertex[2]].z);
1044 if(!color&&!flat)glNormal3f(normals[Triangles[i].vertex[2]].x,normals[Triangles[i].vertex[2]].y,normals[Triangles[i].vertex[2]].z);
1045 if(!color&&flat)glNormal3f(facenormals[i].x,facenormals[i].y,facenormals[i].y);
1046 glVertex3f(vertex[Triangles[i].vertex[2]].x,vertex[Triangles[i].vertex[2]].y,vertex[Triangles[i].vertex[2]].z);
1053 void Model::drawdecals(GLuint shadowtexture,GLuint bloodtexture,GLuint bloodtexture2,GLuint breaktexture)
1056 if(type!=decalstype)return;
1058 static float distancemult;
1059 static int lasttype;
1060 static float viewdistsquared;
1063 viewdistsquared=viewdistance*viewdistance;
1068 glDisable(GL_LIGHTING);
1069 glDisable(GL_CULL_FACE);
1070 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1072 if(numdecals>max_model_decals)numdecals=max_model_decals;
1073 for(i=0;i<numdecals;i++){
1074 if(decaltype[i]==blooddecalfast&&decalalivetime[i]<2)decalalivetime[i]=2;
1076 if(decaltype[i]==shadowdecal&&decaltype[i]!=lasttype){
1077 glBindTexture( GL_TEXTURE_2D, shadowtexture);
1080 glAlphaFunc(GL_GREATER, 0.0001);
1081 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1084 if(decaltype[i]==breakdecal&&decaltype[i]!=lasttype){
1085 glBindTexture( GL_TEXTURE_2D, breaktexture);
1088 glAlphaFunc(GL_GREATER, 0.0001);
1089 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1092 if((decaltype[i]==blooddecal||decaltype[i]==blooddecalslow)&&decaltype[i]!=lasttype){
1093 glBindTexture( GL_TEXTURE_2D, bloodtexture);
1096 glAlphaFunc(GL_GREATER, 0.15);
1097 glBlendFunc(GL_ONE,GL_ZERO);
1100 if((decaltype[i]==blooddecalfast)&&decaltype[i]!=lasttype){
1101 glBindTexture( GL_TEXTURE_2D, bloodtexture2);
1104 glAlphaFunc(GL_GREATER, 0.15);
1105 glBlendFunc(GL_ONE,GL_ZERO);
1108 if(decaltype[i]==shadowdecal){
1109 glColor4f(1,1,1,decalopacity[i]);
1111 if(decaltype[i]==breakdecal){
1112 glColor4f(1,1,1,decalopacity[i]);
1113 if(decalalivetime[i]>58)glColor4f(1,1,1,decalopacity[i]*(60-decalalivetime[i])/2);
1115 if((decaltype[i]==blooddecal||decaltype[i]==blooddecalfast||decaltype[i]==blooddecalslow)){
1116 glColor4f(1,1,1,decalopacity[i]);
1117 if(decalalivetime[i]<4)glColor4f(1,1,1,decalopacity[i]*decalalivetime[i]*.25);
1118 if(decalalivetime[i]>58)glColor4f(1,1,1,decalopacity[i]*(60-decalalivetime[i])/2);
1120 lasttype=decaltype[i];
1121 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1122 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
1124 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
1126 glBegin(GL_TRIANGLES);
1127 for(int j=0;j<3;j++)
1129 glTexCoord2f(decaltexcoords[i][j][0], decaltexcoords[i][j][1]); glVertex3f(decalvertex[i][j].x,decalvertex[i][j].y,decalvertex[i][j].z);
1134 for(i=numdecals-1;i>=0;i--){
1135 decalalivetime[i]+=multiplier;
1136 if(decaltype[i]==blooddecalslow)decalalivetime[i]-=multiplier*2/3;
1137 if(decaltype[i]==blooddecalfast)decalalivetime[i]+=multiplier*4;
1138 if(decaltype[i]==shadowdecal)DeleteDecal(i);
1139 if((decaltype[i]==blooddecal||decaltype[i]==blooddecalfast||decaltype[i]==blooddecalslow)&&decalalivetime[i]>=60)DeleteDecal(i);
1141 glAlphaFunc(GL_GREATER, 0.0001);
1142 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1146 void Model::DeleteDecal(int which)
1149 if(type!=decalstype)return;
1150 decaltype[which]=decaltype[numdecals-1];
1151 decalposition[which]=decalposition[numdecals-1];
1152 for(int i=0;i<3;i++){
1153 decalvertex[which][i]=decalvertex[numdecals-1][i];
1154 decaltexcoords[which][i][0]=decaltexcoords[numdecals-1][i][0];
1155 decaltexcoords[which][i][1]=decaltexcoords[numdecals-1][i][1];
1157 decalrotation[which]=decalrotation[numdecals-1];
1158 decalalivetime[which]=decalalivetime[numdecals-1];
1159 decalopacity[which]=decalopacity[numdecals-1];
1164 void Model::MakeDecal(int atype, XYZ *where,float *size, float *opacity, float *rotation){
1166 if(type!=decalstype)return;
1168 static float placex,placez;
1170 //static XYZ point,point1,point2;
1171 static float distance;
1175 if(findDistancefast(where,&boundingspherecenter)<(boundingsphereradius+*size)*(boundingsphereradius+*size))
1176 for(i=0;i<TriangleNum;i++){
1177 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)){
1178 decalposition[numdecals]=*where;
1179 decaltype[numdecals]=atype;
1180 decalrotation[numdecals]=*rotation;
1181 decalalivetime[numdecals]=0;
1182 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);
1183 decalopacity[numdecals]=*opacity-distance/10;
1185 if(decalopacity[numdecals>0]){
1186 placex=vertex[Triangles[i].vertex[0]].x;
1187 placez=vertex[Triangles[i].vertex[0]].z;
1189 decaltexcoords[numdecals][0][0]=(placex-where->x)/(*size)/2+.5;
1190 decaltexcoords[numdecals][0][1]=(placez-where->z)/(*size)/2+.5;
1192 decalvertex[numdecals][0].x=placex;
1193 decalvertex[numdecals][0].z=placez;
1194 decalvertex[numdecals][0].y=vertex[Triangles[i].vertex[0]].y;
1197 placex=vertex[Triangles[i].vertex[1]].x;
1198 placez=vertex[Triangles[i].vertex[1]].z;
1200 decaltexcoords[numdecals][1][0]=(placex-where->x)/(*size)/2+.5;
1201 decaltexcoords[numdecals][1][1]=(placez-where->z)/(*size)/2+.5;
1203 decalvertex[numdecals][1].x=placex;
1204 decalvertex[numdecals][1].z=placez;
1205 decalvertex[numdecals][1].y=vertex[Triangles[i].vertex[1]].y;
1208 placex=vertex[Triangles[i].vertex[2]].x;
1209 placez=vertex[Triangles[i].vertex[2]].z;
1211 decaltexcoords[numdecals][2][0]=(placex-where->x)/(*size)/2+.5;
1212 decaltexcoords[numdecals][2][1]=(placez-where->z)/(*size)/2+.5;
1214 decalvertex[numdecals][2].x=placex;
1215 decalvertex[numdecals][2].z=placez;
1216 decalvertex[numdecals][2].y=vertex[Triangles[i].vertex[2]].y;
1218 if(!(decaltexcoords[numdecals][0][0]<0&&decaltexcoords[numdecals][1][0]<0&&decaltexcoords[numdecals][2][0]<0))
1219 if(!(decaltexcoords[numdecals][0][1]<0&&decaltexcoords[numdecals][1][1]<0&&decaltexcoords[numdecals][2][1]<0))
1220 if(!(decaltexcoords[numdecals][0][0]>1&&decaltexcoords[numdecals][1][0]>1&&decaltexcoords[numdecals][2][0]>1))
1221 if(!(decaltexcoords[numdecals][0][1]>1&&decaltexcoords[numdecals][1][1]>1&&decaltexcoords[numdecals][2][1]>1))
1223 if(decalrotation[numdecals]){
1226 rot.x=decaltexcoords[numdecals][j][0]-.5;
1227 rot.z=decaltexcoords[numdecals][j][1]-.5;
1228 rot=DoRotation(rot,0,-decalrotation[numdecals],0);
1229 decaltexcoords[numdecals][j][0]=rot.x+.5;
1230 decaltexcoords[numdecals][j][1]=rot.z+.5;
1233 if(numdecals<max_model_decals-1)numdecals++;
1241 void Model::MakeDecal(int atype, XYZ where,float size, float opacity, float rotation){
1243 if(type!=decalstype)return;
1245 static float placex,placez;
1247 //static XYZ point,point1,point2;
1248 static float distance;
1252 if(findDistancefast(&where,&boundingspherecenter)<(boundingsphereradius+size)*(boundingsphereradius+size))
1253 for(i=0;i<TriangleNum;i++){
1254 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))));
1255 if(distance<.02&&abs(facenormals[i].y)>abs(facenormals[i].x)&&abs(facenormals[i].y)>abs(facenormals[i].z)){
1256 decalposition[numdecals]=where;
1257 decaltype[numdecals]=atype;
1258 decalrotation[numdecals]=rotation;
1259 decalalivetime[numdecals]=0;
1260 decalopacity[numdecals]=opacity-distance/10;
1262 if(decalopacity[numdecals>0]){
1263 placex=vertex[Triangles[i].vertex[0]].x;
1264 placez=vertex[Triangles[i].vertex[0]].z;
1266 decaltexcoords[numdecals][0][0]=(placex-where.x)/(size)/2+.5;
1267 decaltexcoords[numdecals][0][1]=(placez-where.z)/(size)/2+.5;
1269 decalvertex[numdecals][0].x=placex;
1270 decalvertex[numdecals][0].z=placez;
1271 decalvertex[numdecals][0].y=vertex[Triangles[i].vertex[0]].y;
1274 placex=vertex[Triangles[i].vertex[1]].x;
1275 placez=vertex[Triangles[i].vertex[1]].z;
1277 decaltexcoords[numdecals][1][0]=(placex-where.x)/(size)/2+.5;
1278 decaltexcoords[numdecals][1][1]=(placez-where.z)/(size)/2+.5;
1280 decalvertex[numdecals][1].x=placex;
1281 decalvertex[numdecals][1].z=placez;
1282 decalvertex[numdecals][1].y=vertex[Triangles[i].vertex[1]].y;
1285 placex=vertex[Triangles[i].vertex[2]].x;
1286 placez=vertex[Triangles[i].vertex[2]].z;
1288 decaltexcoords[numdecals][2][0]=(placex-where.x)/(size)/2+.5;
1289 decaltexcoords[numdecals][2][1]=(placez-where.z)/(size)/2+.5;
1291 decalvertex[numdecals][2].x=placex;
1292 decalvertex[numdecals][2].z=placez;
1293 decalvertex[numdecals][2].y=vertex[Triangles[i].vertex[2]].y;
1295 if(!(decaltexcoords[numdecals][0][0]<0&&decaltexcoords[numdecals][1][0]<0&&decaltexcoords[numdecals][2][0]<0))
1296 if(!(decaltexcoords[numdecals][0][1]<0&&decaltexcoords[numdecals][1][1]<0&&decaltexcoords[numdecals][2][1]<0))
1297 if(!(decaltexcoords[numdecals][0][0]>1&&decaltexcoords[numdecals][1][0]>1&&decaltexcoords[numdecals][2][0]>1))
1298 if(!(decaltexcoords[numdecals][0][1]>1&&decaltexcoords[numdecals][1][1]>1&&decaltexcoords[numdecals][2][1]>1))
1300 if(decalrotation[numdecals]){
1303 rot.x=decaltexcoords[numdecals][j][0]-.5;
1304 rot.z=decaltexcoords[numdecals][j][1]-.5;
1305 rot=DoRotation(rot,0,-decalrotation[numdecals],0);
1306 decaltexcoords[numdecals][j][0]=rot.x+.5;
1307 decaltexcoords[numdecals][j][1]=rot.z+.5;
1310 if(numdecals<max_model_decals-1)numdecals++;
1314 else if(distance<.02&&abs(facenormals[i].x)>abs(facenormals[i].y)&&abs(facenormals[i].x)>abs(facenormals[i].z)){
1315 decalposition[numdecals]=where;
1316 decaltype[numdecals]=atype;
1317 decalrotation[numdecals]=rotation;
1318 decalalivetime[numdecals]=0;
1319 decalopacity[numdecals]=opacity-distance/10;
1321 if(decalopacity[numdecals>0]){
1322 placex=vertex[Triangles[i].vertex[0]].y;
1323 placez=vertex[Triangles[i].vertex[0]].z;
1325 decaltexcoords[numdecals][0][0]=(placex-where.y)/(size)/2+.5;
1326 decaltexcoords[numdecals][0][1]=(placez-where.z)/(size)/2+.5;
1328 decalvertex[numdecals][0].x=vertex[Triangles[i].vertex[0]].x;
1329 decalvertex[numdecals][0].z=placez;
1330 decalvertex[numdecals][0].y=placex;
1333 placex=vertex[Triangles[i].vertex[1]].y;
1334 placez=vertex[Triangles[i].vertex[1]].z;
1336 decaltexcoords[numdecals][1][0]=(placex-where.y)/(size)/2+.5;
1337 decaltexcoords[numdecals][1][1]=(placez-where.z)/(size)/2+.5;
1339 decalvertex[numdecals][1].x=vertex[Triangles[i].vertex[1]].x;
1340 decalvertex[numdecals][1].z=placez;
1341 decalvertex[numdecals][1].y=placex;
1344 placex=vertex[Triangles[i].vertex[2]].y;
1345 placez=vertex[Triangles[i].vertex[2]].z;
1347 decaltexcoords[numdecals][2][0]=(placex-where.y)/(size)/2+.5;
1348 decaltexcoords[numdecals][2][1]=(placez-where.z)/(size)/2+.5;
1350 decalvertex[numdecals][2].x=vertex[Triangles[i].vertex[2]].x;
1351 decalvertex[numdecals][2].z=placez;
1352 decalvertex[numdecals][2].y=placex;
1354 if(!(decaltexcoords[numdecals][0][0]<0&&decaltexcoords[numdecals][1][0]<0&&decaltexcoords[numdecals][2][0]<0))
1355 if(!(decaltexcoords[numdecals][0][1]<0&&decaltexcoords[numdecals][1][1]<0&&decaltexcoords[numdecals][2][1]<0))
1356 if(!(decaltexcoords[numdecals][0][0]>1&&decaltexcoords[numdecals][1][0]>1&&decaltexcoords[numdecals][2][0]>1))
1357 if(!(decaltexcoords[numdecals][0][1]>1&&decaltexcoords[numdecals][1][1]>1&&decaltexcoords[numdecals][2][1]>1))
1359 if(decalrotation[numdecals]){
1362 rot.x=decaltexcoords[numdecals][j][0]-.5;
1363 rot.z=decaltexcoords[numdecals][j][1]-.5;
1364 rot=DoRotation(rot,0,-decalrotation[numdecals],0);
1365 decaltexcoords[numdecals][j][0]=rot.x+.5;
1366 decaltexcoords[numdecals][j][1]=rot.z+.5;
1369 if(numdecals<max_model_decals-1)numdecals++;
1373 else if(distance<.02&&abs(facenormals[i].z)>abs(facenormals[i].y)&&abs(facenormals[i].z)>abs(facenormals[i].x)){
1374 decalposition[numdecals]=where;
1375 decaltype[numdecals]=atype;
1376 decalrotation[numdecals]=rotation;
1377 decalalivetime[numdecals]=0;
1378 decalopacity[numdecals]=opacity-distance/10;
1380 if(decalopacity[numdecals>0]){
1381 placex=vertex[Triangles[i].vertex[0]].x;
1382 placez=vertex[Triangles[i].vertex[0]].y;
1384 decaltexcoords[numdecals][0][0]=(placex-where.x)/(size)/2+.5;
1385 decaltexcoords[numdecals][0][1]=(placez-where.y)/(size)/2+.5;
1387 decalvertex[numdecals][0].x=placex;
1388 decalvertex[numdecals][0].z=vertex[Triangles[i].vertex[0]].z;
1389 decalvertex[numdecals][0].y=placez;
1392 placex=vertex[Triangles[i].vertex[1]].x;
1393 placez=vertex[Triangles[i].vertex[1]].y;
1395 decaltexcoords[numdecals][1][0]=(placex-where.x)/(size)/2+.5;
1396 decaltexcoords[numdecals][1][1]=(placez-where.y)/(size)/2+.5;
1398 decalvertex[numdecals][1].x=placex;
1399 decalvertex[numdecals][1].z=vertex[Triangles[i].vertex[1]].z;
1400 decalvertex[numdecals][1].y=placez;
1403 placex=vertex[Triangles[i].vertex[2]].x;
1404 placez=vertex[Triangles[i].vertex[2]].y;
1406 decaltexcoords[numdecals][2][0]=(placex-where.x)/(size)/2+.5;
1407 decaltexcoords[numdecals][2][1]=(placez-where.y)/(size)/2+.5;
1409 decalvertex[numdecals][2].x=placex;
1410 decalvertex[numdecals][2].z=vertex[Triangles[i].vertex[2]].z;
1411 decalvertex[numdecals][2].y=placez;
1413 if(!(decaltexcoords[numdecals][0][0]<0&&decaltexcoords[numdecals][1][0]<0&&decaltexcoords[numdecals][2][0]<0))
1414 if(!(decaltexcoords[numdecals][0][1]<0&&decaltexcoords[numdecals][1][1]<0&&decaltexcoords[numdecals][2][1]<0))
1415 if(!(decaltexcoords[numdecals][0][0]>1&&decaltexcoords[numdecals][1][0]>1&&decaltexcoords[numdecals][2][0]>1))
1416 if(!(decaltexcoords[numdecals][0][1]>1&&decaltexcoords[numdecals][1][1]>1&&decaltexcoords[numdecals][2][1]>1))
1418 if(decalrotation[numdecals]){
1421 rot.x=decaltexcoords[numdecals][j][0]-.5;
1422 rot.z=decaltexcoords[numdecals][j][1]-.5;
1423 rot=DoRotation(rot,0,-decalrotation[numdecals],0);
1424 decaltexcoords[numdecals][j][0]=rot.x+.5;
1425 decaltexcoords[numdecals][j][1]=rot.z+.5;
1428 if(numdecals<max_model_decals-1)numdecals++;
1440 if(textureptr) glDeleteTextures( 1, &textureptr );
1443 void Model::deallocate()
1447 if(owner)dealloc(owner);
1450 if(possible)dealloc(possible);
1453 if(vertex)dealloc(vertex);
1456 if(normals)dealloc(normals);
1459 if(facenormals)dealloc(facenormals);
1462 if(Triangles)dealloc(Triangles);
1465 if(vArray)dealloc(vArray);
1472 for(i=0;i<max_model_decals;i++)
1476 dealloc(decaltexcoords[i][j]);
1478 dealloc(decaltexcoords[i]);
1480 dealloc(decaltexcoords);
1487 for(i=0;i<max_model_decals;i++)
1489 dealloc(decalvertex[i]);
1491 dealloc(decalvertex);
1499 dealloc(decalopacity);
1502 dealloc(decalrotation);
1505 dealloc(decalalivetime);
1508 dealloc(decalposition);
1515 vertexNum = 0,TriangleNum = 0;
1518 type = 0,oldtype = 0;
1529 memset(&Texture, 0, sizeof(Texture));
1533 boundingspherecenter = 0;
1534 boundingsphereradius = 0;