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 modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 Lugaru 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. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with Lugaru. If not, see <http://www.gnu.org/licenses/>.
23 extern float multiplier;
24 extern float viewdistance;
26 extern float fadestart;
27 extern float texdetail;
30 extern bool visibleloading;
32 int Model::LineCheck(XYZ *p1, XYZ *p2, XYZ *p, XYZ *move, float *rotate)
35 static float distance;
36 static float olddistance;
37 static int intersecting;
38 static int firstintersecting;
44 *p1 = DoRotation(*p1, 0, -*rotate, 0);
46 *p2 = DoRotation(*p2, 0, -*rotate, 0);
47 if (!sphere_line_intersection(p1, p2, &boundingspherecenter, &boundingsphereradius))
49 firstintersecting = -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) {
55 olddistance = distance;
56 firstintersecting = j;
62 *p = DoRotation(*p, 0, *rotate, 0);
64 return firstintersecting;
67 int Model::LineCheckPossible(XYZ *p1, XYZ *p2, XYZ *p, XYZ *move, float *rotate)
70 static float distance;
71 static float olddistance;
72 static int intersecting;
73 static int firstintersecting;
78 if (!sphere_line_intersection(p1, p2, &boundingspherecenter, &boundingsphereradius))
80 firstintersecting = -1;
82 *p1 = DoRotation(*p1, 0, -*rotate, 0);
84 *p2 = DoRotation(*p2, 0, -*rotate, 0);
86 if (numpossible > 0 && numpossible < TriangleNum)
87 for (j = 0; j < numpossible; j++) {
88 if (possible[j] >= 0 && possible[j] < TriangleNum) {
89 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);
90 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);
91 if ((distance < olddistance || firstintersecting == -1) && intersecting) {
92 olddistance = distance;
93 firstintersecting = possible[j];
100 *p = DoRotation(*p, 0, *rotate, 0);
102 return firstintersecting;
105 int Model::LineCheckSlidePossible(XYZ *p1, XYZ *p2, XYZ *p, XYZ *move, float *rotate)
108 static float distance;
109 static float olddistance;
110 static int intersecting;
111 static int firstintersecting;
116 if (!sphere_line_intersection(p1, p2, &boundingspherecenter, &boundingsphereradius))
118 firstintersecting = -1;
120 *p1 = DoRotation(*p1, 0, -*rotate, 0);
122 *p2 = DoRotation(*p2, 0, -*rotate, 0);
125 for (j = 0; j < numpossible; j++) {
126 if (possible[j] >= 0 && possible[j] < TriangleNum) {
127 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);
128 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);
129 if ((distance < olddistance || firstintersecting == -1) && intersecting) {
130 olddistance = distance;
131 firstintersecting = possible[j];
136 if (firstintersecting > 0) {
137 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)));
138 *p2 -= facenormals[firstintersecting] * distance;
142 *p2 = DoRotation(*p2, 0, *rotate, 0);
144 return firstintersecting;
147 int Model::SphereCheck(XYZ *p1, float radius, XYZ *p, XYZ *move, float *rotate)
150 static float distance;
151 static float olddistance;
152 static int intersecting;
153 static int firstintersecting;
156 static XYZ start, end;
158 firstintersecting = -1;
163 *p1 = DoRotation(*p1, 0, -*rotate, 0);
164 if (distsq(p1, &boundingspherecenter) > radius * radius + boundingsphereradius * boundingsphereradius)
167 for (i = 0; i < 4; i++) {
168 for (j = 0; j < TriangleNum; j++) {
170 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)));
171 if (distance < radius) {
172 point = *p1 - facenormals[j] * distance;
173 if (PointInTriangle( &point, facenormals[j], &vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[1]], &vertex[Triangles[j].vertex[2]]))
176 intersecting = sphere_line_intersection(&vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[1]], p1, &radius);
178 intersecting = sphere_line_intersection(&vertex[Triangles[j].vertex[1]], &vertex[Triangles[j].vertex[2]], p1, &radius);
180 intersecting = sphere_line_intersection(&vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[2]], p1, &radius);
182 *p1 += facenormals[j] * (distance - radius);
186 if(LineFacetd(&start,&end,&vertex[Triangles[j].vertex[0]],&vertex[Triangles[j].vertex[1]],&vertex[Triangles[j].vertex[2]],&facenormals[j],&point)){
187 p1->y=point.y+radius;
191 if ((distance < olddistance || firstintersecting == -1) && intersecting) {
192 olddistance = distance;
193 firstintersecting = j;
199 *p = DoRotation(*p, 0, *rotate, 0);
202 *p1 = DoRotation(*p1, 0, *rotate, 0);
204 return firstintersecting;
207 int Model::SphereCheckPossible(XYZ *p1, float radius, XYZ *move, float *rotate)
210 static float distance;
211 static float olddistance;
212 static int intersecting;
213 static int firstintersecting;
216 static XYZ start, end;
218 firstintersecting = -1;
226 *p1 = DoRotation(*p1, 0, -*rotate, 0);
227 if (distsq(p1, &boundingspherecenter) > radius * radius + boundingsphereradius * boundingsphereradius) {
232 for (j = 0; j < TriangleNum; j++) {
234 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)));
235 if (distance < radius) {
236 point = *p1 - facenormals[j] * distance;
237 if (PointInTriangle( &point, facenormals[j], &vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[1]], &vertex[Triangles[j].vertex[2]]))
240 intersecting = sphere_line_intersection(&vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[1]], p1, &radius);
242 intersecting = sphere_line_intersection(&vertex[Triangles[j].vertex[1]], &vertex[Triangles[j].vertex[2]], p1, &radius);
244 intersecting = sphere_line_intersection(&vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[2]], p1, &radius);
246 //if(j>=0&&j<TriangleNum)
247 possible[numpossible] = j;
251 if ((distance < olddistance || firstintersecting == -1) && intersecting) {
252 olddistance = distance;
253 firstintersecting = j;
257 *p1 = DoRotation(*p1, 0, *rotate, 0);
259 return firstintersecting;
263 void Model::UpdateVertexArray()
265 if (type != normaltype && type != decalstype)
270 for (i = 0; i < TriangleNum; i++) {
272 vArray[j + 0] = Triangles[i].gx[0];
273 vArray[j + 1] = Triangles[i].gy[0];
274 vArray[j + 2] = normals[Triangles[i].vertex[0]].x;
275 vArray[j + 3] = normals[Triangles[i].vertex[0]].y;
276 vArray[j + 4] = normals[Triangles[i].vertex[0]].z;
277 vArray[j + 5] = vertex[Triangles[i].vertex[0]].x;
278 vArray[j + 6] = vertex[Triangles[i].vertex[0]].y;
279 vArray[j + 7] = vertex[Triangles[i].vertex[0]].z;
281 vArray[j + 8] = Triangles[i].gx[1];
282 vArray[j + 9] = Triangles[i].gy[1];
283 vArray[j + 10] = normals[Triangles[i].vertex[1]].x;
284 vArray[j + 11] = normals[Triangles[i].vertex[1]].y;
285 vArray[j + 12] = normals[Triangles[i].vertex[1]].z;
286 vArray[j + 13] = vertex[Triangles[i].vertex[1]].x;
287 vArray[j + 14] = vertex[Triangles[i].vertex[1]].y;
288 vArray[j + 15] = vertex[Triangles[i].vertex[1]].z;
290 vArray[j + 16] = Triangles[i].gx[2];
291 vArray[j + 17] = Triangles[i].gy[2];
292 vArray[j + 18] = normals[Triangles[i].vertex[2]].x;
293 vArray[j + 19] = normals[Triangles[i].vertex[2]].y;
294 vArray[j + 20] = normals[Triangles[i].vertex[2]].z;
295 vArray[j + 21] = vertex[Triangles[i].vertex[2]].x;
296 vArray[j + 22] = vertex[Triangles[i].vertex[2]].y;
297 vArray[j + 23] = vertex[Triangles[i].vertex[2]].z;
300 for (i = 0; i < TriangleNum; i++) {
302 vArray[j + 0] = Triangles[i].gx[0];
303 vArray[j + 1] = Triangles[i].gy[0];
304 vArray[j + 2] = facenormals[i].x * -1;
305 vArray[j + 3] = facenormals[i].y * -1;
306 vArray[j + 4] = facenormals[i].z * -1;
307 vArray[j + 5] = vertex[Triangles[i].vertex[0]].x;
308 vArray[j + 6] = vertex[Triangles[i].vertex[0]].y;
309 vArray[j + 7] = vertex[Triangles[i].vertex[0]].z;
311 vArray[j + 8] = Triangles[i].gx[1];
312 vArray[j + 9] = Triangles[i].gy[1];
313 vArray[j + 10] = facenormals[i].x * -1;
314 vArray[j + 11] = facenormals[i].y * -1;
315 vArray[j + 12] = facenormals[i].z * -1;
316 vArray[j + 13] = vertex[Triangles[i].vertex[1]].x;
317 vArray[j + 14] = vertex[Triangles[i].vertex[1]].y;
318 vArray[j + 15] = vertex[Triangles[i].vertex[1]].z;
320 vArray[j + 16] = Triangles[i].gx[2];
321 vArray[j + 17] = Triangles[i].gy[2];
322 vArray[j + 18] = facenormals[i].x * -1;
323 vArray[j + 19] = facenormals[i].y * -1;
324 vArray[j + 20] = facenormals[i].z * -1;
325 vArray[j + 21] = vertex[Triangles[i].vertex[2]].x;
326 vArray[j + 22] = vertex[Triangles[i].vertex[2]].y;
327 vArray[j + 23] = vertex[Triangles[i].vertex[2]].z;
332 void Model::UpdateVertexArrayNoTex()
334 if (type != normaltype && type != decalstype)
339 for (i = 0; i < TriangleNum; i++) {
341 vArray[j + 2] = normals[Triangles[i].vertex[0]].x;
342 vArray[j + 3] = normals[Triangles[i].vertex[0]].y;
343 vArray[j + 4] = normals[Triangles[i].vertex[0]].z;
344 vArray[j + 5] = vertex[Triangles[i].vertex[0]].x;
345 vArray[j + 6] = vertex[Triangles[i].vertex[0]].y;
346 vArray[j + 7] = vertex[Triangles[i].vertex[0]].z;
348 vArray[j + 10] = normals[Triangles[i].vertex[1]].x;
349 vArray[j + 11] = normals[Triangles[i].vertex[1]].y;
350 vArray[j + 12] = normals[Triangles[i].vertex[1]].z;
351 vArray[j + 13] = vertex[Triangles[i].vertex[1]].x;
352 vArray[j + 14] = vertex[Triangles[i].vertex[1]].y;
353 vArray[j + 15] = vertex[Triangles[i].vertex[1]].z;
355 vArray[j + 18] = normals[Triangles[i].vertex[2]].x;
356 vArray[j + 19] = normals[Triangles[i].vertex[2]].y;
357 vArray[j + 20] = normals[Triangles[i].vertex[2]].z;
358 vArray[j + 21] = vertex[Triangles[i].vertex[2]].x;
359 vArray[j + 22] = vertex[Triangles[i].vertex[2]].y;
360 vArray[j + 23] = vertex[Triangles[i].vertex[2]].z;
363 for (i = 0; i < TriangleNum; i++) {
365 vArray[j + 2] = facenormals[i].x * -1;
366 vArray[j + 3] = facenormals[i].y * -1;
367 vArray[j + 4] = facenormals[i].z * -1;
368 vArray[j + 5] = vertex[Triangles[i].vertex[0]].x;
369 vArray[j + 6] = vertex[Triangles[i].vertex[0]].y;
370 vArray[j + 7] = vertex[Triangles[i].vertex[0]].z;
372 vArray[j + 10] = facenormals[i].x * -1;
373 vArray[j + 11] = facenormals[i].y * -1;
374 vArray[j + 12] = facenormals[i].z * -1;
375 vArray[j + 13] = vertex[Triangles[i].vertex[1]].x;
376 vArray[j + 14] = vertex[Triangles[i].vertex[1]].y;
377 vArray[j + 15] = vertex[Triangles[i].vertex[1]].z;
379 vArray[j + 18] = facenormals[i].x * -1;
380 vArray[j + 19] = facenormals[i].y * -1;
381 vArray[j + 20] = facenormals[i].z * -1;
382 vArray[j + 21] = vertex[Triangles[i].vertex[2]].x;
383 vArray[j + 22] = vertex[Triangles[i].vertex[2]].y;
384 vArray[j + 23] = vertex[Triangles[i].vertex[2]].z;
388 void Model::UpdateVertexArrayNoTexNoNorm()
390 if (type != normaltype && type != decalstype)
394 for (i = 0; i < TriangleNum; i++) {
396 vArray[j + 5] = vertex[Triangles[i].vertex[0]].x;
397 vArray[j + 6] = vertex[Triangles[i].vertex[0]].y;
398 vArray[j + 7] = vertex[Triangles[i].vertex[0]].z;
400 vArray[j + 13] = vertex[Triangles[i].vertex[1]].x;
401 vArray[j + 14] = vertex[Triangles[i].vertex[1]].y;
402 vArray[j + 15] = vertex[Triangles[i].vertex[1]].z;
404 vArray[j + 21] = vertex[Triangles[i].vertex[2]].x;
405 vArray[j + 22] = vertex[Triangles[i].vertex[2]].y;
406 vArray[j + 23] = vertex[Triangles[i].vertex[2]].z;
410 bool Model::loadnotex(const char *filename )
415 //~ int oldvertexNum, oldTriangleNum;
416 //~ oldvertexNum = vertexNum;
417 //~ oldTriangleNum = TriangleNum;
422 tfile = fopen( ConvertFileName(filename), "rb" );
423 // read model settings
425 fseek(tfile, 0, SEEK_SET);
426 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
428 // read the model data
433 owner = (int*)malloc(sizeof(int) * vertexNum);
434 possible = (int*)malloc(sizeof(int) * TriangleNum);
435 vertex = (XYZ*)malloc(sizeof(XYZ) * vertexNum);
436 Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle) * TriangleNum);
437 vArray = (GLfloat*)malloc(sizeof(GLfloat) * TriangleNum * 24);
439 for (i = 0; i < vertexNum; i++) {
440 funpackf(tfile, "Bf Bf Bf", &vertex[i].x, &vertex[i].y, &vertex[i].z);
443 for (i = 0; i < TriangleNum; i++) {
444 //funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
446 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
447 Triangles[i].vertex[ 0] = vertex[ 0];
448 Triangles[i].vertex[ 1] = vertex[ 2];
449 Triangles[i].vertex[ 2] = vertex[ 4];
450 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
451 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
458 for (i = 0; i < vertexNum; i++) {
463 boundingsphereradius = 0;
464 for (i = 0; i < vertexNum; i++) {
465 for (j = 0; j < vertexNum; j++) {
466 if (j != i && distsq(&vertex[j], &vertex[i]) / 2 > boundingsphereradius) {
467 boundingsphereradius = distsq(&vertex[j], &vertex[i]) / 2;
468 boundingspherecenter = (vertex[i] + vertex[j]) / 2;
472 boundingsphereradius = fast_sqrt(boundingsphereradius);
478 bool Model::load(const char *filename, bool texture )
485 LOG(std::string("Loading model...") + filename);
488 Game::LoadingScreen();
490 //~ int oldvertexNum, oldTriangleNum;
491 //~ oldvertexNum = vertexNum;
492 //~ oldTriangleNum = TriangleNum;
497 tfile = fopen( ConvertFileName(filename), "rb" );
498 // read model settings
501 fseek(tfile, 0, SEEK_SET);
502 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
504 // read the model data
509 owner = (int*)malloc(sizeof(int) * vertexNum);
510 possible = (int*)malloc(sizeof(int) * TriangleNum);
511 vertex = (XYZ*)malloc(sizeof(XYZ) * vertexNum);
512 normals = (XYZ*)malloc(sizeof(XYZ) * vertexNum);
513 facenormals = (XYZ*)malloc(sizeof(XYZ) * TriangleNum);
514 Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle) * TriangleNum);
515 vArray = (GLfloat*)malloc(sizeof(GLfloat) * TriangleNum * 24);
517 for (i = 0; i < vertexNum; i++) {
518 funpackf(tfile, "Bf Bf Bf", &vertex[i].x, &vertex[i].y, &vertex[i].z);
521 for (i = 0; i < TriangleNum; i++) {
522 //funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
524 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
525 Triangles[i].vertex[ 0] = vertex[ 0];
526 Triangles[i].vertex[ 1] = vertex[ 2];
527 Triangles[i].vertex[ 2] = vertex[ 4];
528 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
529 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
532 modelTexture.xsz = 0;
538 for (i = 0; i < vertexNum; i++) {
543 boundingsphereradius = 0;
544 for (i = 0; i < vertexNum; i++) {
545 for (j = 0; j < vertexNum; j++) {
546 if (j != i && distsq(&vertex[j], &vertex[i]) / 2 > boundingsphereradius) {
547 boundingsphereradius = distsq(&vertex[j], &vertex[i]) / 2;
548 boundingspherecenter = (vertex[i] + vertex[j]) / 2;
552 boundingsphereradius = fast_sqrt(boundingsphereradius);
557 bool Model::loaddecal(const char *filename, bool texture )
564 // Changing the filename so that its more os specific
565 char * FixedFN = ConvertFileName(filename);
567 LOG(std::string("Loading decal...") + FixedFN);
569 //~ int oldvertexNum, oldTriangleNum;
570 //~ oldvertexNum = vertexNum;
571 //~ oldTriangleNum = TriangleNum;
577 tfile = fopen( FixedFN, "rb" );
578 // read model settings
581 fseek(tfile, 0, SEEK_SET);
582 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
584 // read the model data
590 owner = (int*)malloc(sizeof(int) * vertexNum);
591 possible = (int*)malloc(sizeof(int) * TriangleNum);
592 vertex = (XYZ*)malloc(sizeof(XYZ) * vertexNum);
593 normals = (XYZ*)malloc(sizeof(XYZ) * vertexNum);
594 facenormals = (XYZ*)malloc(sizeof(XYZ) * TriangleNum);
595 Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle) * TriangleNum);
596 vArray = (GLfloat*)malloc(sizeof(GLfloat) * TriangleNum * 24);
599 for (i = 0; i < vertexNum; i++) {
600 funpackf(tfile, "Bf Bf Bf", &vertex[i].x, &vertex[i].y, &vertex[i].z);
603 for (i = 0; i < TriangleNum; i++) {
604 //funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
606 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
607 Triangles[i].vertex[ 0] = vertex[ 0];
608 Triangles[i].vertex[ 1] = vertex[ 2];
609 Triangles[i].vertex[ 2] = vertex[ 4];
610 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
611 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
615 modelTexture.xsz = 0;
621 for (i = 0; i < vertexNum; i++) {
625 boundingsphereradius = 0;
626 for (i = 0; i < vertexNum; i++) {
627 for (j = 0; j < vertexNum; j++) {
628 if (j != i && distsq(&vertex[j], &vertex[i]) / 2 > boundingsphereradius) {
629 boundingsphereradius = distsq(&vertex[j], &vertex[i]) / 2;
630 boundingspherecenter = (vertex[i] + vertex[j]) / 2;
634 boundingsphereradius = fast_sqrt(boundingsphereradius);
637 if (!decaltexcoords) {
638 decaltexcoords = (float***)malloc(sizeof(float**)*max_model_decals);
639 for (i = 0; i < max_model_decals; i++) {
640 decaltexcoords[i] = (float**)malloc(sizeof(float*) * 3);
641 for (j = 0; j < 3; j++) {
642 decaltexcoords[i][j] = (float*)malloc(sizeof(float) * 2);
645 //if(decalvertex)free(decalvertex);
646 decalvertex = (XYZ**)malloc(sizeof(XYZ*)*max_model_decals);
647 for (i = 0; i < max_model_decals; i++) {
648 decalvertex[i] = (XYZ*)malloc(sizeof(XYZ) * 3);
651 decaltype = (int*)malloc(sizeof(int) * max_model_decals);
652 decalopacity = (float*)malloc(sizeof(float) * max_model_decals);
653 decalrotation = (float*)malloc(sizeof(float) * max_model_decals);
654 decalalivetime = (float*)malloc(sizeof(float) * max_model_decals);
655 decalposition = (XYZ*)malloc(sizeof(XYZ) * max_model_decals);
661 bool Model::loadraw(char *filename )
668 LOG(std::string("Loading raw...") + filename);
670 //~ int oldvertexNum, oldTriangleNum;
671 //~ oldvertexNum = vertexNum;
672 //~ oldTriangleNum = TriangleNum;
677 tfile = fopen( ConvertFileName(filename), "rb" );
678 // read model settings
681 fseek(tfile, 0, SEEK_SET);
682 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
684 // read the model data
689 owner = (int*)malloc(sizeof(int) * vertexNum);
690 possible = (int*)malloc(sizeof(int) * TriangleNum);
691 vertex = (XYZ*)malloc(sizeof(XYZ) * vertexNum);
692 Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle) * TriangleNum);
693 vArray = (GLfloat*)malloc(sizeof(GLfloat) * TriangleNum * 24);
696 for (i = 0; i < vertexNum; i++) {
697 funpackf(tfile, "Bf Bf Bf", &vertex[i].x, &vertex[i].y, &vertex[i].z);
700 for (i = 0; i < TriangleNum; i++) {
701 //funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
703 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
704 Triangles[i].vertex[ 0] = vertex[ 0];
705 Triangles[i].vertex[ 1] = vertex[ 2];
706 Triangles[i].vertex[ 2] = vertex[ 4];
707 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
708 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
714 for (i = 0; i < vertexNum; i++) {
722 void Model::UniformTexCoords()
725 for (i = 0; i < TriangleNum; i++) {
726 Triangles[i].gy[0] = vertex[Triangles[i].vertex[0]].y;
727 Triangles[i].gy[1] = vertex[Triangles[i].vertex[1]].y;
728 Triangles[i].gy[2] = vertex[Triangles[i].vertex[2]].y;
729 Triangles[i].gx[0] = vertex[Triangles[i].vertex[0]].x;
730 Triangles[i].gx[1] = vertex[Triangles[i].vertex[1]].x;
731 Triangles[i].gx[2] = vertex[Triangles[i].vertex[2]].x;
737 void Model::FlipTexCoords()
740 for (i = 0; i < TriangleNum; i++) {
741 Triangles[i].gy[0] = -Triangles[i].gy[0];
742 Triangles[i].gy[1] = -Triangles[i].gy[1];
743 Triangles[i].gy[2] = -Triangles[i].gy[2];
748 void Model::ScaleTexCoords(float howmuch)
751 for (i = 0; i < TriangleNum; i++) {
752 Triangles[i].gx[0] *= howmuch;
753 Triangles[i].gx[1] *= howmuch;
754 Triangles[i].gx[2] *= howmuch;
755 Triangles[i].gy[0] *= howmuch;
756 Triangles[i].gy[1] *= howmuch;
757 Triangles[i].gy[2] *= howmuch;
762 void Model::Scale(float xscale, float yscale, float zscale)
765 for (i = 0; i < vertexNum; i++) {
766 vertex[i].x *= xscale;
767 vertex[i].y *= yscale;
768 vertex[i].z *= zscale;
774 boundingsphereradius = 0;
775 for (i = 0; i < vertexNum; i++) {
776 for (j = 0; j < vertexNum; j++) {
777 if (j != i && distsq(&vertex[j], &vertex[i]) / 2 > boundingsphereradius) {
778 boundingsphereradius = distsq(&vertex[j], &vertex[i]) / 2;
779 boundingspherecenter = (vertex[i] + vertex[j]) / 2;
783 boundingsphereradius = fast_sqrt(boundingsphereradius);
786 void Model::ScaleNormals(float xscale, float yscale, float zscale)
788 if (type != normaltype && type != decalstype)
791 for (i = 0; i < vertexNum; i++) {
792 normals[i].x *= xscale;
793 normals[i].y *= yscale;
794 normals[i].z *= zscale;
796 for (i = 0; i < TriangleNum; i++) {
797 facenormals[i].x *= xscale;
798 facenormals[i].y *= yscale;
799 facenormals[i].z *= zscale;
804 void Model::Translate(float xtrans, float ytrans, float ztrans)
807 for (i = 0; i < vertexNum; i++) {
808 vertex[i].x += xtrans;
809 vertex[i].y += ytrans;
810 vertex[i].z += ztrans;
815 boundingsphereradius = 0;
816 for (i = 0; i < vertexNum; i++) {
817 for (j = 0; j < vertexNum; j++) {
818 if (j != i && distsq(&vertex[j], &vertex[i]) / 2 > boundingsphereradius) {
819 boundingsphereradius = distsq(&vertex[j], &vertex[i]) / 2;
820 boundingspherecenter = (vertex[i] + vertex[j]) / 2;
824 boundingsphereradius = fast_sqrt(boundingsphereradius);
827 void Model::Rotate(float xang, float yang, float zang)
830 for (i = 0; i < vertexNum; i++) {
831 vertex[i] = DoRotation(vertex[i], xang, yang, zang);
836 boundingsphereradius = 0;
837 for (i = 0; i < vertexNum; i++) {
838 for (j = 0; j < vertexNum; j++) {
839 if (j != i && distsq(&vertex[j], &vertex[i]) / 2 > boundingsphereradius) {
840 boundingsphereradius = distsq(&vertex[j], &vertex[i]) / 2;
841 boundingspherecenter = (vertex[i] + vertex[j]) / 2;
845 boundingsphereradius = fast_sqrt(boundingsphereradius);
849 void Model::CalculateNormals(bool facenormalise)
852 Game::LoadingScreen();
854 if (type != normaltype && type != decalstype)
857 for (i = 0; i < vertexNum; i++) {
863 for (i = 0; i < TriangleNum; i++) {
864 CrossProduct(vertex[Triangles[i].vertex[1]] - vertex[Triangles[i].vertex[0]], vertex[Triangles[i].vertex[2]] - vertex[Triangles[i].vertex[0]], &facenormals[i]);
866 normals[Triangles[i].vertex[0]].x += facenormals[i].x;
867 normals[Triangles[i].vertex[0]].y += facenormals[i].y;
868 normals[Triangles[i].vertex[0]].z += facenormals[i].z;
870 normals[Triangles[i].vertex[1]].x += facenormals[i].x;
871 normals[Triangles[i].vertex[1]].y += facenormals[i].y;
872 normals[Triangles[i].vertex[1]].z += facenormals[i].z;
874 normals[Triangles[i].vertex[2]].x += facenormals[i].x;
875 normals[Triangles[i].vertex[2]].y += facenormals[i].y;
876 normals[Triangles[i].vertex[2]].z += facenormals[i].z;
878 Normalise(&facenormals[i]);
880 for (i = 0; i < vertexNum; i++) {
881 Normalise(&normals[i]);
884 UpdateVertexArrayNoTex();
887 void Model::drawimmediate()
890 glBegin(GL_TRIANGLES);
891 for (int i = 0; i < TriangleNum; i++) {
892 /*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){
893 if(isnormal(vertex[Triangles[i].vertex[0]].x)&&isnormal(vertex[Triangles[i].vertex[0]].y)&&isnormal(vertex[Triangles[i].vertex[0]].z)
894 &&isnormal(vertex[Triangles[i].vertex[1]].x)&&isnormal(vertex[Triangles[i].vertex[1]].y)&&isnormal(vertex[Triangles[i].vertex[1]].z)
895 &&isnormal(vertex[Triangles[i].vertex[2]].x)&&isnormal(vertex[Triangles[i].vertex[2]].y)&&isnormal(vertex[Triangles[i].vertex[2]].z)){
897 glTexCoord2f(Triangles[i].gx[0], Triangles[i].gy[0]);
899 glColor3f(normals[Triangles[i].vertex[0]].x, normals[Triangles[i].vertex[0]].y, normals[Triangles[i].vertex[0]].z);
901 glNormal3f(normals[Triangles[i].vertex[0]].x, normals[Triangles[i].vertex[0]].y, normals[Triangles[i].vertex[0]].z);
903 glNormal3f(facenormals[i].x, facenormals[i].y, facenormals[i].y);
904 glVertex3f(vertex[Triangles[i].vertex[0]].x, vertex[Triangles[i].vertex[0]].y, vertex[Triangles[i].vertex[0]].z);
906 glTexCoord2f(Triangles[i].gx[1], Triangles[i].gy[1]);
908 glColor3f(normals[Triangles[i].vertex[1]].x, normals[Triangles[i].vertex[1]].y, normals[Triangles[i].vertex[1]].z);
910 glNormal3f(normals[Triangles[i].vertex[1]].x, normals[Triangles[i].vertex[1]].y, normals[Triangles[i].vertex[1]].z);
912 glNormal3f(facenormals[i].x, facenormals[i].y, facenormals[i].y);
913 glVertex3f(vertex[Triangles[i].vertex[1]].x, vertex[Triangles[i].vertex[1]].y, vertex[Triangles[i].vertex[1]].z);
915 glTexCoord2f(Triangles[i].gx[2], Triangles[i].gy[2]);
917 glColor3f(normals[Triangles[i].vertex[2]].x, normals[Triangles[i].vertex[2]].y, normals[Triangles[i].vertex[2]].z);
919 glNormal3f(normals[Triangles[i].vertex[2]].x, normals[Triangles[i].vertex[2]].y, normals[Triangles[i].vertex[2]].z);
921 glNormal3f(facenormals[i].x, facenormals[i].y, facenormals[i].y);
922 glVertex3f(vertex[Triangles[i].vertex[2]].x, vertex[Triangles[i].vertex[2]].y, vertex[Triangles[i].vertex[2]].z);
931 if (type != normaltype && type != decalstype)
934 glEnableClientState(GL_NORMAL_ARRAY);
935 glEnableClientState(GL_VERTEX_ARRAY);
936 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
939 glInterleavedArrays( GL_T2F_N3F_V3F, 8 * sizeof(GLfloat), &vArray[0]);
941 glInterleavedArrays( GL_T2F_C3F_V3F, 8 * sizeof(GLfloat), &vArray[0]);
945 glLockArraysEXT( 0, TriangleNum * 3);
947 glDrawArrays(GL_TRIANGLES, 0, TriangleNum * 3);
954 glDisableClientState(GL_NORMAL_ARRAY);
956 glDisableClientState(GL_COLOR_ARRAY);
957 glDisableClientState(GL_VERTEX_ARRAY);
958 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
962 //TODO: phase out in favor of Texture
963 void Model::drawdifftex(GLuint texture)
965 glEnableClientState(GL_NORMAL_ARRAY);
966 glEnableClientState(GL_VERTEX_ARRAY);
967 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
969 glInterleavedArrays( GL_T2F_N3F_V3F, 8 * sizeof(GLfloat), &vArray[0]);
971 glInterleavedArrays( GL_T2F_C3F_V3F, 8 * sizeof(GLfloat), &vArray[0]);
973 glBindTexture(GL_TEXTURE_2D, (unsigned long)texture);
974 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
975 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
979 glLockArraysEXT( 0, TriangleNum * 3);
981 glDrawArrays(GL_TRIANGLES, 0, TriangleNum * 3);
988 glDisableClientState(GL_NORMAL_ARRAY);
990 glDisableClientState(GL_COLOR_ARRAY);
991 glDisableClientState(GL_VERTEX_ARRAY);
992 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
995 void Model::drawdifftex(Texture texture)
997 glEnableClientState(GL_NORMAL_ARRAY);
998 glEnableClientState(GL_VERTEX_ARRAY);
999 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1001 glInterleavedArrays( GL_T2F_N3F_V3F, 8 * sizeof(GLfloat), &vArray[0]);
1003 glInterleavedArrays( GL_T2F_C3F_V3F, 8 * sizeof(GLfloat), &vArray[0]);
1006 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
1007 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
1011 glLockArraysEXT( 0, TriangleNum * 3);
1013 glDrawArrays(GL_TRIANGLES, 0, TriangleNum * 3);
1015 glUnlockArraysEXT();
1020 glDisableClientState(GL_NORMAL_ARRAY);
1022 glDisableClientState(GL_COLOR_ARRAY);
1023 glDisableClientState(GL_VERTEX_ARRAY);
1024 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1027 void Model::drawdecals(Texture shadowtexture, Texture bloodtexture, Texture bloodtexture2, Texture breaktexture)
1030 if (type != decalstype)
1033 //~ static float distancemult;
1034 static int lasttype;
1035 //~ static float viewdistsquared;
1038 //~ viewdistsquared = viewdistance * viewdistance;
1043 glDisable(GL_LIGHTING);
1044 glDisable(GL_CULL_FACE);
1045 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1047 if (numdecals > max_model_decals)
1048 numdecals = max_model_decals;
1049 for (i = 0; i < numdecals; i++) {
1050 if (decaltype[i] == blooddecalfast && decalalivetime[i] < 2)
1051 decalalivetime[i] = 2;
1053 if (decaltype[i] == shadowdecal && decaltype[i] != lasttype) {
1054 shadowtexture.bind();
1057 glAlphaFunc(GL_GREATER, 0.0001);
1058 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1061 if (decaltype[i] == breakdecal && decaltype[i] != lasttype) {
1062 breaktexture.bind();
1065 glAlphaFunc(GL_GREATER, 0.0001);
1066 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1069 if ((decaltype[i] == blooddecal || decaltype[i] == blooddecalslow) && decaltype[i] != lasttype) {
1070 bloodtexture.bind();
1073 glAlphaFunc(GL_GREATER, 0.15);
1074 glBlendFunc(GL_ONE, GL_ZERO);
1077 if ((decaltype[i] == blooddecalfast) && decaltype[i] != lasttype) {
1078 bloodtexture2.bind();
1081 glAlphaFunc(GL_GREATER, 0.15);
1082 glBlendFunc(GL_ONE, GL_ZERO);
1085 if (decaltype[i] == shadowdecal) {
1086 glColor4f(1, 1, 1, decalopacity[i]);
1088 if (decaltype[i] == breakdecal) {
1089 glColor4f(1, 1, 1, decalopacity[i]);
1090 if (decalalivetime[i] > 58)
1091 glColor4f(1, 1, 1, decalopacity[i] * (60 - decalalivetime[i]) / 2);
1093 if ((decaltype[i] == blooddecal || decaltype[i] == blooddecalfast || decaltype[i] == blooddecalslow)) {
1094 glColor4f(1, 1, 1, decalopacity[i]);
1095 if (decalalivetime[i] < 4)
1096 glColor4f(1, 1, 1, decalopacity[i]*decalalivetime[i]*.25);
1097 if (decalalivetime[i] > 58)
1098 glColor4f(1, 1, 1, decalopacity[i] * (60 - decalalivetime[i]) / 2);
1100 lasttype = decaltype[i];
1101 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1102 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
1104 glMatrixMode(GL_MODELVIEW);
1106 glBegin(GL_TRIANGLES);
1107 for (int j = 0; j < 3; j++) {
1108 glTexCoord2f(decaltexcoords[i][j][0], decaltexcoords[i][j][1]);
1109 glVertex3f(decalvertex[i][j].x, decalvertex[i][j].y, decalvertex[i][j].z);
1114 for (i = numdecals - 1; i >= 0; i--) {
1115 decalalivetime[i] += multiplier;
1116 if (decaltype[i] == blooddecalslow)
1117 decalalivetime[i] -= multiplier * 2 / 3;
1118 if (decaltype[i] == blooddecalfast)
1119 decalalivetime[i] += multiplier * 4;
1120 if (decaltype[i] == shadowdecal)
1122 if ((decaltype[i] == blooddecal || decaltype[i] == blooddecalfast || decaltype[i] == blooddecalslow) && decalalivetime[i] >= 60)
1125 glAlphaFunc(GL_GREATER, 0.0001);
1126 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1130 void Model::DeleteDecal(int which)
1133 if (type != decalstype)
1135 decaltype[which] = decaltype[numdecals - 1];
1136 decalposition[which] = decalposition[numdecals - 1];
1137 for (int i = 0; i < 3; i++) {
1138 decalvertex[which][i] = decalvertex[numdecals - 1][i];
1139 decaltexcoords[which][i][0] = decaltexcoords[numdecals - 1][i][0];
1140 decaltexcoords[which][i][1] = decaltexcoords[numdecals - 1][i][1];
1142 decalrotation[which] = decalrotation[numdecals - 1];
1143 decalalivetime[which] = decalalivetime[numdecals - 1];
1144 decalopacity[which] = decalopacity[numdecals - 1];
1149 void Model::MakeDecal(int atype, XYZ *where, float *size, float *opacity, float *rotation)
1152 if (type != decalstype)
1155 static float placex, placez;
1157 //static XYZ point,point1,point2;
1158 static float distance;
1162 if (distsq(where, &boundingspherecenter) < (boundingsphereradius + *size) * (boundingsphereradius + *size))
1163 for (i = 0; i < TriangleNum; i++) {
1164 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)) {
1165 decalposition[numdecals] = *where;
1166 decaltype[numdecals] = atype;
1167 decalrotation[numdecals] = *rotation;
1168 decalalivetime[numdecals] = 0;
1169 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);
1170 decalopacity[numdecals] = *opacity - distance / 10;
1172 if (decalopacity[numdecals > 0]) {
1173 placex = vertex[Triangles[i].vertex[0]].x;
1174 placez = vertex[Triangles[i].vertex[0]].z;
1176 decaltexcoords[numdecals][0][0] = (placex - where->x) / (*size) / 2 + .5;
1177 decaltexcoords[numdecals][0][1] = (placez - where->z) / (*size) / 2 + .5;
1179 decalvertex[numdecals][0].x = placex;
1180 decalvertex[numdecals][0].z = placez;
1181 decalvertex[numdecals][0].y = vertex[Triangles[i].vertex[0]].y;
1184 placex = vertex[Triangles[i].vertex[1]].x;
1185 placez = vertex[Triangles[i].vertex[1]].z;
1187 decaltexcoords[numdecals][1][0] = (placex - where->x) / (*size) / 2 + .5;
1188 decaltexcoords[numdecals][1][1] = (placez - where->z) / (*size) / 2 + .5;
1190 decalvertex[numdecals][1].x = placex;
1191 decalvertex[numdecals][1].z = placez;
1192 decalvertex[numdecals][1].y = vertex[Triangles[i].vertex[1]].y;
1195 placex = vertex[Triangles[i].vertex[2]].x;
1196 placez = vertex[Triangles[i].vertex[2]].z;
1198 decaltexcoords[numdecals][2][0] = (placex - where->x) / (*size) / 2 + .5;
1199 decaltexcoords[numdecals][2][1] = (placez - where->z) / (*size) / 2 + .5;
1201 decalvertex[numdecals][2].x = placex;
1202 decalvertex[numdecals][2].z = placez;
1203 decalvertex[numdecals][2].y = vertex[Triangles[i].vertex[2]].y;
1205 if (!(decaltexcoords[numdecals][0][0] < 0 && decaltexcoords[numdecals][1][0] < 0 && decaltexcoords[numdecals][2][0] < 0))
1206 if (!(decaltexcoords[numdecals][0][1] < 0 && decaltexcoords[numdecals][1][1] < 0 && decaltexcoords[numdecals][2][1] < 0))
1207 if (!(decaltexcoords[numdecals][0][0] > 1 && decaltexcoords[numdecals][1][0] > 1 && decaltexcoords[numdecals][2][0] > 1))
1208 if (!(decaltexcoords[numdecals][0][1] > 1 && decaltexcoords[numdecals][1][1] > 1 && decaltexcoords[numdecals][2][1] > 1)) {
1209 if (decalrotation[numdecals]) {
1210 for (j = 0; j < 3; j++) {
1212 rot.x = decaltexcoords[numdecals][j][0] - .5;
1213 rot.z = decaltexcoords[numdecals][j][1] - .5;
1214 rot = DoRotation(rot, 0, -decalrotation[numdecals], 0);
1215 decaltexcoords[numdecals][j][0] = rot.x + .5;
1216 decaltexcoords[numdecals][j][1] = rot.z + .5;
1219 if (numdecals < max_model_decals - 1)
1228 void Model::MakeDecal(int atype, XYZ where, float size, float opacity, float rotation)
1231 if (type != decalstype)
1234 static float placex, placez;
1236 //static XYZ point,point1,point2;
1237 static float distance;
1241 if (distsq(&where, &boundingspherecenter) < (boundingsphereradius + size) * (boundingsphereradius + size))
1242 for (i = 0; i < TriangleNum; i++) {
1243 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))));
1244 if (distance < .02 && abs(facenormals[i].y) > abs(facenormals[i].x) && abs(facenormals[i].y) > abs(facenormals[i].z)) {
1245 decalposition[numdecals] = where;
1246 decaltype[numdecals] = atype;
1247 decalrotation[numdecals] = rotation;
1248 decalalivetime[numdecals] = 0;
1249 decalopacity[numdecals] = opacity - distance / 10;
1251 if (decalopacity[numdecals > 0]) {
1252 placex = vertex[Triangles[i].vertex[0]].x;
1253 placez = vertex[Triangles[i].vertex[0]].z;
1255 decaltexcoords[numdecals][0][0] = (placex - where.x) / (size) / 2 + .5;
1256 decaltexcoords[numdecals][0][1] = (placez - where.z) / (size) / 2 + .5;
1258 decalvertex[numdecals][0].x = placex;
1259 decalvertex[numdecals][0].z = placez;
1260 decalvertex[numdecals][0].y = vertex[Triangles[i].vertex[0]].y;
1263 placex = vertex[Triangles[i].vertex[1]].x;
1264 placez = vertex[Triangles[i].vertex[1]].z;
1266 decaltexcoords[numdecals][1][0] = (placex - where.x) / (size) / 2 + .5;
1267 decaltexcoords[numdecals][1][1] = (placez - where.z) / (size) / 2 + .5;
1269 decalvertex[numdecals][1].x = placex;
1270 decalvertex[numdecals][1].z = placez;
1271 decalvertex[numdecals][1].y = vertex[Triangles[i].vertex[1]].y;
1274 placex = vertex[Triangles[i].vertex[2]].x;
1275 placez = vertex[Triangles[i].vertex[2]].z;
1277 decaltexcoords[numdecals][2][0] = (placex - where.x) / (size) / 2 + .5;
1278 decaltexcoords[numdecals][2][1] = (placez - where.z) / (size) / 2 + .5;
1280 decalvertex[numdecals][2].x = placex;
1281 decalvertex[numdecals][2].z = placez;
1282 decalvertex[numdecals][2].y = vertex[Triangles[i].vertex[2]].y;
1284 if (!(decaltexcoords[numdecals][0][0] < 0 && decaltexcoords[numdecals][1][0] < 0 && decaltexcoords[numdecals][2][0] < 0))
1285 if (!(decaltexcoords[numdecals][0][1] < 0 && decaltexcoords[numdecals][1][1] < 0 && decaltexcoords[numdecals][2][1] < 0))
1286 if (!(decaltexcoords[numdecals][0][0] > 1 && decaltexcoords[numdecals][1][0] > 1 && decaltexcoords[numdecals][2][0] > 1))
1287 if (!(decaltexcoords[numdecals][0][1] > 1 && decaltexcoords[numdecals][1][1] > 1 && decaltexcoords[numdecals][2][1] > 1)) {
1288 if (decalrotation[numdecals]) {
1289 for (j = 0; j < 3; j++) {
1291 rot.x = decaltexcoords[numdecals][j][0] - .5;
1292 rot.z = decaltexcoords[numdecals][j][1] - .5;
1293 rot = DoRotation(rot, 0, -decalrotation[numdecals], 0);
1294 decaltexcoords[numdecals][j][0] = rot.x + .5;
1295 decaltexcoords[numdecals][j][1] = rot.z + .5;
1298 if (numdecals < max_model_decals - 1)
1302 } else if (distance < .02 && abs(facenormals[i].x) > abs(facenormals[i].y) && abs(facenormals[i].x) > abs(facenormals[i].z)) {
1303 decalposition[numdecals] = where;
1304 decaltype[numdecals] = atype;
1305 decalrotation[numdecals] = rotation;
1306 decalalivetime[numdecals] = 0;
1307 decalopacity[numdecals] = opacity - distance / 10;
1309 if (decalopacity[numdecals > 0]) {
1310 placex = vertex[Triangles[i].vertex[0]].y;
1311 placez = vertex[Triangles[i].vertex[0]].z;
1313 decaltexcoords[numdecals][0][0] = (placex - where.y) / (size) / 2 + .5;
1314 decaltexcoords[numdecals][0][1] = (placez - where.z) / (size) / 2 + .5;
1316 decalvertex[numdecals][0].x = vertex[Triangles[i].vertex[0]].x;
1317 decalvertex[numdecals][0].z = placez;
1318 decalvertex[numdecals][0].y = placex;
1321 placex = vertex[Triangles[i].vertex[1]].y;
1322 placez = vertex[Triangles[i].vertex[1]].z;
1324 decaltexcoords[numdecals][1][0] = (placex - where.y) / (size) / 2 + .5;
1325 decaltexcoords[numdecals][1][1] = (placez - where.z) / (size) / 2 + .5;
1327 decalvertex[numdecals][1].x = vertex[Triangles[i].vertex[1]].x;
1328 decalvertex[numdecals][1].z = placez;
1329 decalvertex[numdecals][1].y = placex;
1332 placex = vertex[Triangles[i].vertex[2]].y;
1333 placez = vertex[Triangles[i].vertex[2]].z;
1335 decaltexcoords[numdecals][2][0] = (placex - where.y) / (size) / 2 + .5;
1336 decaltexcoords[numdecals][2][1] = (placez - where.z) / (size) / 2 + .5;
1338 decalvertex[numdecals][2].x = vertex[Triangles[i].vertex[2]].x;
1339 decalvertex[numdecals][2].z = placez;
1340 decalvertex[numdecals][2].y = placex;
1342 if (!(decaltexcoords[numdecals][0][0] < 0 && decaltexcoords[numdecals][1][0] < 0 && decaltexcoords[numdecals][2][0] < 0))
1343 if (!(decaltexcoords[numdecals][0][1] < 0 && decaltexcoords[numdecals][1][1] < 0 && decaltexcoords[numdecals][2][1] < 0))
1344 if (!(decaltexcoords[numdecals][0][0] > 1 && decaltexcoords[numdecals][1][0] > 1 && decaltexcoords[numdecals][2][0] > 1))
1345 if (!(decaltexcoords[numdecals][0][1] > 1 && decaltexcoords[numdecals][1][1] > 1 && decaltexcoords[numdecals][2][1] > 1)) {
1346 if (decalrotation[numdecals]) {
1347 for (j = 0; j < 3; j++) {
1349 rot.x = decaltexcoords[numdecals][j][0] - .5;
1350 rot.z = decaltexcoords[numdecals][j][1] - .5;
1351 rot = DoRotation(rot, 0, -decalrotation[numdecals], 0);
1352 decaltexcoords[numdecals][j][0] = rot.x + .5;
1353 decaltexcoords[numdecals][j][1] = rot.z + .5;
1356 if (numdecals < max_model_decals - 1)
1360 } else if (distance < .02 && abs(facenormals[i].z) > abs(facenormals[i].y) && abs(facenormals[i].z) > abs(facenormals[i].x)) {
1361 decalposition[numdecals] = where;
1362 decaltype[numdecals] = atype;
1363 decalrotation[numdecals] = rotation;
1364 decalalivetime[numdecals] = 0;
1365 decalopacity[numdecals] = opacity - distance / 10;
1367 if (decalopacity[numdecals > 0]) {
1368 placex = vertex[Triangles[i].vertex[0]].x;
1369 placez = vertex[Triangles[i].vertex[0]].y;
1371 decaltexcoords[numdecals][0][0] = (placex - where.x) / (size) / 2 + .5;
1372 decaltexcoords[numdecals][0][1] = (placez - where.y) / (size) / 2 + .5;
1374 decalvertex[numdecals][0].x = placex;
1375 decalvertex[numdecals][0].z = vertex[Triangles[i].vertex[0]].z;
1376 decalvertex[numdecals][0].y = placez;
1379 placex = vertex[Triangles[i].vertex[1]].x;
1380 placez = vertex[Triangles[i].vertex[1]].y;
1382 decaltexcoords[numdecals][1][0] = (placex - where.x) / (size) / 2 + .5;
1383 decaltexcoords[numdecals][1][1] = (placez - where.y) / (size) / 2 + .5;
1385 decalvertex[numdecals][1].x = placex;
1386 decalvertex[numdecals][1].z = vertex[Triangles[i].vertex[1]].z;
1387 decalvertex[numdecals][1].y = placez;
1390 placex = vertex[Triangles[i].vertex[2]].x;
1391 placez = vertex[Triangles[i].vertex[2]].y;
1393 decaltexcoords[numdecals][2][0] = (placex - where.x) / (size) / 2 + .5;
1394 decaltexcoords[numdecals][2][1] = (placez - where.y) / (size) / 2 + .5;
1396 decalvertex[numdecals][2].x = placex;
1397 decalvertex[numdecals][2].z = vertex[Triangles[i].vertex[2]].z;
1398 decalvertex[numdecals][2].y = placez;
1400 if (!(decaltexcoords[numdecals][0][0] < 0 && decaltexcoords[numdecals][1][0] < 0 && decaltexcoords[numdecals][2][0] < 0))
1401 if (!(decaltexcoords[numdecals][0][1] < 0 && decaltexcoords[numdecals][1][1] < 0 && decaltexcoords[numdecals][2][1] < 0))
1402 if (!(decaltexcoords[numdecals][0][0] > 1 && decaltexcoords[numdecals][1][0] > 1 && decaltexcoords[numdecals][2][0] > 1))
1403 if (!(decaltexcoords[numdecals][0][1] > 1 && decaltexcoords[numdecals][1][1] > 1 && decaltexcoords[numdecals][2][1] > 1)) {
1404 if (decalrotation[numdecals]) {
1405 for (j = 0; j < 3; j++) {
1407 rot.x = decaltexcoords[numdecals][j][0] - .5;
1408 rot.z = decaltexcoords[numdecals][j][1] - .5;
1409 rot = DoRotation(rot, 0, -decalrotation[numdecals], 0);
1410 decaltexcoords[numdecals][j][0] = rot.x + .5;
1411 decaltexcoords[numdecals][j][1] = rot.z + .5;
1414 if (numdecals < max_model_decals - 1)
1426 textureptr.destroy();
1429 void Model::deallocate()
1463 if (decaltexcoords) {
1464 for (i = 0; i < max_model_decals; i++) {
1465 for (j = 0; j < 3; j++) {
1466 free(decaltexcoords[i][j]);
1468 free(decaltexcoords[i]);
1470 free(decaltexcoords);
1476 for (i = 0; i < max_model_decals; i++) {
1477 free(decalvertex[i]);
1490 free(decalrotation);
1493 free(decalalivetime);
1496 free(decalposition);
1503 vertexNum = 0, TriangleNum = 0;
1506 type = 0, oldtype = 0;
1516 memset(&modelTexture, 0, sizeof(modelTexture));
1520 boundingspherecenter = 0;
1521 boundingsphereradius = 0;