2 Copyright (C) 2003, 2010 - Wolfire Games
4 This file is part of Lugaru.
6 Lugaru is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 2
9 of the License, or (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15 See the GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 extern float multiplier;
26 extern float viewdistance;
28 extern float fadestart;
29 extern float texdetail;
32 extern bool visibleloading;
34 int Model::LineCheck(XYZ *p1, XYZ *p2, XYZ *p, XYZ *move, float *rotate)
37 static float distance;
38 static float olddistance;
39 static int intersecting;
40 static int firstintersecting;
45 if (*rotate)*p1 = DoRotation(*p1, 0, -*rotate, 0);
46 if (*rotate)*p2 = DoRotation(*p2, 0, -*rotate, 0);
47 if (!sphere_line_intersection(p1, p2, &boundingspherecenter,
48 &boundingsphereradius))return -1;
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;
61 if (*rotate)*p = DoRotation(*p, 0, *rotate, 0);
63 return firstintersecting;
66 int Model::LineCheckSlide(XYZ *p1, XYZ *p2, XYZ *p, XYZ *move, float *rotate)
69 static float distance;
70 static float olddistance;
71 static int intersecting;
72 static int firstintersecting;
77 if (!sphere_line_intersection(p1, p2, &boundingspherecenter,
78 &boundingsphereradius))return -1;
79 firstintersecting = -1;
80 if (*rotate)*p1 = DoRotation(*p1, 0, -*rotate, 0);
81 if (*rotate)*p2 = DoRotation(*p2, 0, -*rotate, 0);
83 for (j = 0; j < TriangleNum; j++) {
84 intersecting = LineFacetd(p1, p2, &vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[1]], &vertex[Triangles[j].vertex[2]], &facenormals[j], &point);
85 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);
86 if ((distance < olddistance || firstintersecting == -1) && intersecting) {
87 olddistance = distance;
88 firstintersecting = j;
92 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)));
93 *p2 -= facenormals[firstintersecting] * distance;
95 if (*rotate)*p2 = DoRotation(*p2, 0, *rotate, 0);
97 return firstintersecting;
100 int Model::LineCheckPossible(XYZ *p1, XYZ *p2, XYZ *p, XYZ *move, float *rotate)
103 static float distance;
104 static float olddistance;
105 static int intersecting;
106 static int firstintersecting;
111 if (!sphere_line_intersection(p1, p2, &boundingspherecenter,
112 &boundingsphereradius))return -1;
113 firstintersecting = -1;
114 if (*rotate)*p1 = DoRotation(*p1, 0, -*rotate, 0);
115 if (*rotate)*p2 = DoRotation(*p2, 0, -*rotate, 0);
117 if (numpossible > 0 && numpossible < TriangleNum)
118 for (j = 0; j < numpossible; j++) {
119 if (possible[j] >= 0 && possible[j] < TriangleNum) {
120 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);
121 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);
122 if ((distance < olddistance || firstintersecting == -1) && intersecting) {
123 olddistance = distance;
124 firstintersecting = possible[j];
130 if (*rotate)*p = DoRotation(*p, 0, *rotate, 0);
132 return firstintersecting;
135 int Model::LineCheckSlidePossible(XYZ *p1, XYZ *p2, XYZ *p, XYZ *move, float *rotate)
138 static float distance;
139 static float olddistance;
140 static int intersecting;
141 static int firstintersecting;
146 if (!sphere_line_intersection(p1, p2, &boundingspherecenter,
147 &boundingsphereradius))return -1;
148 firstintersecting = -1;
149 if (*rotate)*p1 = DoRotation(*p1, 0, -*rotate, 0);
150 if (*rotate)*p2 = DoRotation(*p2, 0, -*rotate, 0);
153 for (j = 0; j < numpossible; j++) {
154 if (possible[j] >= 0 && possible[j] < TriangleNum) {
155 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);
156 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);
157 if ((distance < olddistance || firstintersecting == -1) && intersecting) {
158 olddistance = distance;
159 firstintersecting = possible[j];
164 if (firstintersecting > 0) {
165 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)));
166 *p2 -= facenormals[firstintersecting] * distance;
169 if (*rotate)*p2 = DoRotation(*p2, 0, *rotate, 0);
171 return firstintersecting;
174 int Model::SphereCheck(XYZ *p1, float radius, XYZ *p, XYZ *move, float *rotate)
177 static float distance;
178 static float olddistance;
179 static int intersecting;
180 static int firstintersecting;
183 static XYZ start, end;
185 firstintersecting = -1;
189 if (*rotate)*p1 = DoRotation(*p1, 0, -*rotate, 0);
190 if (distsq(p1, &boundingspherecenter) > radius * radius + boundingsphereradius * boundingsphereradius)return -1;
192 for (i = 0; i < 4; i++) {
193 for (j = 0; j < TriangleNum; j++) {
195 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)));
196 if (distance < radius) {
197 point = *p1 - facenormals[j] * distance;
198 if (PointInTriangle( &point, facenormals[j], &vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[1]], &vertex[Triangles[j].vertex[2]]))intersecting = 1;
199 if (!intersecting)intersecting = sphere_line_intersection(&vertex[Triangles[j].vertex[0]],
200 &vertex[Triangles[j].vertex[1]],
202 if (!intersecting)intersecting = sphere_line_intersection(&vertex[Triangles[j].vertex[1]],
203 &vertex[Triangles[j].vertex[2]],
205 if (!intersecting)intersecting = sphere_line_intersection(&vertex[Triangles[j].vertex[0]],
206 &vertex[Triangles[j].vertex[2]],
209 *p1 += facenormals[j] * (distance - radius);
213 if(LineFacetd(&start,&end,&vertex[Triangles[j].vertex[0]],&vertex[Triangles[j].vertex[1]],&vertex[Triangles[j].vertex[2]],&facenormals[j],&point)){
214 p1->y=point.y+radius;
218 if ((distance < olddistance || firstintersecting == -1) && intersecting) {
219 olddistance = distance;
220 firstintersecting = j;
225 if (*rotate)*p = DoRotation(*p, 0, *rotate, 0);
227 if (*rotate)*p1 = DoRotation(*p1, 0, *rotate, 0);
229 return firstintersecting;
232 int Model::SphereCheckPossible(XYZ *p1, float radius, XYZ *move, float *rotate)
235 static float distance;
236 static float olddistance;
237 static int intersecting;
238 static int firstintersecting;
241 static XYZ start, end;
243 firstintersecting = -1;
250 if (*rotate)*p1 = DoRotation(*p1, 0, -*rotate, 0);
251 if (distsq(p1, &boundingspherecenter) > radius * radius + boundingsphereradius * boundingsphereradius) {
256 for (j = 0; j < TriangleNum; j++) {
258 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)));
259 if (distance < radius) {
260 point = *p1 - facenormals[j] * distance;
261 if (PointInTriangle( &point, facenormals[j], &vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[1]], &vertex[Triangles[j].vertex[2]]))intersecting = 1;
262 if (!intersecting)intersecting = sphere_line_intersection(&vertex[Triangles[j].vertex[0]],
263 &vertex[Triangles[j].vertex[1]],
265 if (!intersecting)intersecting = sphere_line_intersection(&vertex[Triangles[j].vertex[1]],
266 &vertex[Triangles[j].vertex[2]],
268 if (!intersecting)intersecting = sphere_line_intersection(&vertex[Triangles[j].vertex[0]],
269 &vertex[Triangles[j].vertex[2]],
272 //if(j>=0&&j<TriangleNum)
273 possible[numpossible] = j;
277 if ((distance < olddistance || firstintersecting == -1) && intersecting) {
278 olddistance = distance;
279 firstintersecting = j;
282 if (*rotate)*p1 = DoRotation(*p1, 0, *rotate, 0);
284 return firstintersecting;
288 void Model::UpdateVertexArray()
290 if (type != normaltype && type != decalstype)return;
294 for (i = 0; i < TriangleNum; i++) {
296 vArray[j + 0] = Triangles[i].gx[0];
297 vArray[j + 1] = Triangles[i].gy[0];
298 vArray[j + 2] = normals[Triangles[i].vertex[0]].x;
299 vArray[j + 3] = normals[Triangles[i].vertex[0]].y;
300 vArray[j + 4] = normals[Triangles[i].vertex[0]].z;
301 vArray[j + 5] = vertex[Triangles[i].vertex[0]].x;
302 vArray[j + 6] = vertex[Triangles[i].vertex[0]].y;
303 vArray[j + 7] = vertex[Triangles[i].vertex[0]].z;
305 vArray[j + 8] = Triangles[i].gx[1];
306 vArray[j + 9] = Triangles[i].gy[1];
307 vArray[j + 10] = normals[Triangles[i].vertex[1]].x;
308 vArray[j + 11] = normals[Triangles[i].vertex[1]].y;
309 vArray[j + 12] = normals[Triangles[i].vertex[1]].z;
310 vArray[j + 13] = vertex[Triangles[i].vertex[1]].x;
311 vArray[j + 14] = vertex[Triangles[i].vertex[1]].y;
312 vArray[j + 15] = vertex[Triangles[i].vertex[1]].z;
314 vArray[j + 16] = Triangles[i].gx[2];
315 vArray[j + 17] = Triangles[i].gy[2];
316 vArray[j + 18] = normals[Triangles[i].vertex[2]].x;
317 vArray[j + 19] = normals[Triangles[i].vertex[2]].y;
318 vArray[j + 20] = normals[Triangles[i].vertex[2]].z;
319 vArray[j + 21] = vertex[Triangles[i].vertex[2]].x;
320 vArray[j + 22] = vertex[Triangles[i].vertex[2]].y;
321 vArray[j + 23] = vertex[Triangles[i].vertex[2]].z;
324 for (i = 0; i < TriangleNum; i++) {
326 vArray[j + 0] = Triangles[i].gx[0];
327 vArray[j + 1] = Triangles[i].gy[0];
328 vArray[j + 2] = facenormals[i].x * -1;
329 vArray[j + 3] = facenormals[i].y * -1;
330 vArray[j + 4] = facenormals[i].z * -1;
331 vArray[j + 5] = vertex[Triangles[i].vertex[0]].x;
332 vArray[j + 6] = vertex[Triangles[i].vertex[0]].y;
333 vArray[j + 7] = vertex[Triangles[i].vertex[0]].z;
335 vArray[j + 8] = Triangles[i].gx[1];
336 vArray[j + 9] = Triangles[i].gy[1];
337 vArray[j + 10] = facenormals[i].x * -1;
338 vArray[j + 11] = facenormals[i].y * -1;
339 vArray[j + 12] = facenormals[i].z * -1;
340 vArray[j + 13] = vertex[Triangles[i].vertex[1]].x;
341 vArray[j + 14] = vertex[Triangles[i].vertex[1]].y;
342 vArray[j + 15] = vertex[Triangles[i].vertex[1]].z;
344 vArray[j + 16] = Triangles[i].gx[2];
345 vArray[j + 17] = Triangles[i].gy[2];
346 vArray[j + 18] = facenormals[i].x * -1;
347 vArray[j + 19] = facenormals[i].y * -1;
348 vArray[j + 20] = facenormals[i].z * -1;
349 vArray[j + 21] = vertex[Triangles[i].vertex[2]].x;
350 vArray[j + 22] = vertex[Triangles[i].vertex[2]].y;
351 vArray[j + 23] = vertex[Triangles[i].vertex[2]].z;
356 void Model::UpdateVertexArrayNoTex()
358 if (type != normaltype && type != decalstype)return;
362 for (i = 0; i < TriangleNum; i++) {
364 vArray[j + 2] = normals[Triangles[i].vertex[0]].x;
365 vArray[j + 3] = normals[Triangles[i].vertex[0]].y;
366 vArray[j + 4] = normals[Triangles[i].vertex[0]].z;
367 vArray[j + 5] = vertex[Triangles[i].vertex[0]].x;
368 vArray[j + 6] = vertex[Triangles[i].vertex[0]].y;
369 vArray[j + 7] = vertex[Triangles[i].vertex[0]].z;
371 vArray[j + 10] = normals[Triangles[i].vertex[1]].x;
372 vArray[j + 11] = normals[Triangles[i].vertex[1]].y;
373 vArray[j + 12] = normals[Triangles[i].vertex[1]].z;
374 vArray[j + 13] = vertex[Triangles[i].vertex[1]].x;
375 vArray[j + 14] = vertex[Triangles[i].vertex[1]].y;
376 vArray[j + 15] = vertex[Triangles[i].vertex[1]].z;
378 vArray[j + 18] = normals[Triangles[i].vertex[2]].x;
379 vArray[j + 19] = normals[Triangles[i].vertex[2]].y;
380 vArray[j + 20] = normals[Triangles[i].vertex[2]].z;
381 vArray[j + 21] = vertex[Triangles[i].vertex[2]].x;
382 vArray[j + 22] = vertex[Triangles[i].vertex[2]].y;
383 vArray[j + 23] = vertex[Triangles[i].vertex[2]].z;
386 for (i = 0; i < TriangleNum; i++) {
388 vArray[j + 2] = facenormals[i].x * -1;
389 vArray[j + 3] = facenormals[i].y * -1;
390 vArray[j + 4] = facenormals[i].z * -1;
391 vArray[j + 5] = vertex[Triangles[i].vertex[0]].x;
392 vArray[j + 6] = vertex[Triangles[i].vertex[0]].y;
393 vArray[j + 7] = vertex[Triangles[i].vertex[0]].z;
395 vArray[j + 10] = facenormals[i].x * -1;
396 vArray[j + 11] = facenormals[i].y * -1;
397 vArray[j + 12] = facenormals[i].z * -1;
398 vArray[j + 13] = vertex[Triangles[i].vertex[1]].x;
399 vArray[j + 14] = vertex[Triangles[i].vertex[1]].y;
400 vArray[j + 15] = vertex[Triangles[i].vertex[1]].z;
402 vArray[j + 18] = facenormals[i].x * -1;
403 vArray[j + 19] = facenormals[i].y * -1;
404 vArray[j + 20] = facenormals[i].z * -1;
405 vArray[j + 21] = vertex[Triangles[i].vertex[2]].x;
406 vArray[j + 22] = vertex[Triangles[i].vertex[2]].y;
407 vArray[j + 23] = vertex[Triangles[i].vertex[2]].z;
411 void Model::UpdateVertexArrayNoTexNoNorm()
413 if (type != normaltype && type != decalstype)return;
416 for (i = 0; i < TriangleNum; i++) {
418 vArray[j + 5] = vertex[Triangles[i].vertex[0]].x;
419 vArray[j + 6] = vertex[Triangles[i].vertex[0]].y;
420 vArray[j + 7] = vertex[Triangles[i].vertex[0]].z;
422 vArray[j + 13] = vertex[Triangles[i].vertex[1]].x;
423 vArray[j + 14] = vertex[Triangles[i].vertex[1]].y;
424 vArray[j + 15] = vertex[Triangles[i].vertex[1]].z;
426 vArray[j + 21] = vertex[Triangles[i].vertex[2]].x;
427 vArray[j + 22] = vertex[Triangles[i].vertex[2]].y;
428 vArray[j + 23] = vertex[Triangles[i].vertex[2]].z;
432 bool Model::loadnotex(const char *filename )
437 int oldvertexNum, oldTriangleNum;
438 oldvertexNum = vertexNum;
439 oldTriangleNum = TriangleNum;
444 tfile = fopen( ConvertFileName(filename), "rb" );
445 // read model settings
447 fseek(tfile, 0, SEEK_SET);
448 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
450 // read the model data
455 owner = (int*)malloc(sizeof(int) * vertexNum);
456 possible = (int*)malloc(sizeof(int) * TriangleNum);
457 vertex = (XYZ*)malloc(sizeof(XYZ) * vertexNum);
458 Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle) * TriangleNum);
459 vArray = (GLfloat*)malloc(sizeof(GLfloat) * TriangleNum * 24);
461 for (i = 0; i < vertexNum; i++) {
462 funpackf(tfile, "Bf Bf Bf", &vertex[i].x, &vertex[i].y, &vertex[i].z);
465 for (i = 0; i < TriangleNum; i++) {
466 // funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
468 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
469 Triangles[i].vertex[ 0] = vertex[ 0];
470 Triangles[i].vertex[ 1] = vertex[ 2];
471 Triangles[i].vertex[ 2] = vertex[ 4];
472 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
473 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
480 for (i = 0; i < vertexNum; i++) {
485 boundingsphereradius = 0;
486 for (i = 0; i < vertexNum; i++) {
487 for (j = 0; j < vertexNum; j++) {
488 if (j != i && distsq(&vertex[j], &vertex[i]) / 2 > boundingsphereradius) {
489 boundingsphereradius = distsq(&vertex[j], &vertex[i]) / 2;
490 boundingspherecenter = (vertex[i] + vertex[j]) / 2;
494 boundingsphereradius = fast_sqrt(boundingsphereradius);
500 bool Model::load(const char *filename, bool texture )
507 LOG(std::string("Loading model...") + filename);
510 Game::LoadingScreen();
512 int oldvertexNum, oldTriangleNum;
513 oldvertexNum = vertexNum;
514 oldTriangleNum = TriangleNum;
519 tfile = fopen( ConvertFileName(filename), "rb" );
520 // read model settings
523 fseek(tfile, 0, SEEK_SET);
524 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
526 // read the model data
531 owner = (int*)malloc(sizeof(int) * vertexNum);
532 possible = (int*)malloc(sizeof(int) * TriangleNum);
533 vertex = (XYZ*)malloc(sizeof(XYZ) * vertexNum);
534 normals = (XYZ*)malloc(sizeof(XYZ) * vertexNum);
535 facenormals = (XYZ*)malloc(sizeof(XYZ) * TriangleNum);
536 Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle) * TriangleNum);
537 vArray = (GLfloat*)malloc(sizeof(GLfloat) * TriangleNum * 24);
539 for (i = 0; i < vertexNum; i++) {
540 funpackf(tfile, "Bf Bf Bf", &vertex[i].x, &vertex[i].y, &vertex[i].z);
543 for (i = 0; i < TriangleNum; i++) {
544 // funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
546 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
547 Triangles[i].vertex[ 0] = vertex[ 0];
548 Triangles[i].vertex[ 1] = vertex[ 2];
549 Triangles[i].vertex[ 2] = vertex[ 4];
550 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
551 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
554 modelTexture.xsz = 0;
560 for (i = 0; i < vertexNum; i++) {
565 boundingsphereradius = 0;
566 for (i = 0; i < vertexNum; i++) {
567 for (j = 0; j < vertexNum; j++) {
568 if (j != i && distsq(&vertex[j], &vertex[i]) / 2 > boundingsphereradius) {
569 boundingsphereradius = distsq(&vertex[j], &vertex[i]) / 2;
570 boundingspherecenter = (vertex[i] + vertex[j]) / 2;
574 boundingsphereradius = fast_sqrt(boundingsphereradius);
579 bool Model::loaddecal(const char *filename, bool texture )
586 // Changing the filename so that its more os specific
587 char * FixedFN = ConvertFileName(filename);
589 LOG(std::string("Loading decal...") + FixedFN);
591 int oldvertexNum, oldTriangleNum;
592 oldvertexNum = vertexNum;
593 oldTriangleNum = TriangleNum;
599 tfile = fopen( FixedFN, "rb" );
600 // read model settings
603 fseek(tfile, 0, SEEK_SET);
604 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
606 // read the model data
612 owner = (int*)malloc(sizeof(int) * vertexNum);
613 possible = (int*)malloc(sizeof(int) * TriangleNum);
614 vertex = (XYZ*)malloc(sizeof(XYZ) * vertexNum);
615 normals = (XYZ*)malloc(sizeof(XYZ) * vertexNum);
616 facenormals = (XYZ*)malloc(sizeof(XYZ) * TriangleNum);
617 Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle) * TriangleNum);
618 vArray = (GLfloat*)malloc(sizeof(GLfloat) * TriangleNum * 24);
621 for (i = 0; i < vertexNum; i++) {
622 funpackf(tfile, "Bf Bf Bf", &vertex[i].x, &vertex[i].y, &vertex[i].z);
625 for (i = 0; i < TriangleNum; i++) {
626 // funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
628 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
629 Triangles[i].vertex[ 0] = vertex[ 0];
630 Triangles[i].vertex[ 1] = vertex[ 2];
631 Triangles[i].vertex[ 2] = vertex[ 4];
632 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
633 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
637 modelTexture.xsz = 0;
643 for (i = 0; i < vertexNum; i++) {
647 boundingsphereradius = 0;
648 for (i = 0; i < vertexNum; i++) {
649 for (j = 0; j < vertexNum; j++) {
650 if (j != i && distsq(&vertex[j], &vertex[i]) / 2 > boundingsphereradius) {
651 boundingsphereradius = distsq(&vertex[j], &vertex[i]) / 2;
652 boundingspherecenter = (vertex[i] + vertex[j]) / 2;
656 boundingsphereradius = fast_sqrt(boundingsphereradius);
659 if (!decaltexcoords) {
660 decaltexcoords = (float***)malloc(sizeof(float**)*max_model_decals);
661 for (i = 0; i < max_model_decals; i++) {
662 decaltexcoords[i] = (float**)malloc(sizeof(float*) * 3);
663 for (j = 0; j < 3; j++) {
664 decaltexcoords[i][j] = (float*)malloc(sizeof(float) * 2);
667 //if(decalvertex)free(decalvertex);
668 decalvertex = (XYZ**)malloc(sizeof(XYZ*)*max_model_decals);
669 for (i = 0; i < max_model_decals; i++) {
670 decalvertex[i] = (XYZ*)malloc(sizeof(XYZ) * 3);
673 decaltype = (int*)malloc(sizeof(int) * max_model_decals);
674 decalopacity = (float*)malloc(sizeof(float) * max_model_decals);
675 decalrotation = (float*)malloc(sizeof(float) * max_model_decals);
676 decalalivetime = (float*)malloc(sizeof(float) * max_model_decals);
677 decalposition = (XYZ*)malloc(sizeof(XYZ) * max_model_decals);
683 bool Model::loadraw(char *filename )
690 LOG(std::string("Loading raw...") + filename);
692 int oldvertexNum, oldTriangleNum;
693 oldvertexNum = vertexNum;
694 oldTriangleNum = TriangleNum;
699 tfile = fopen( ConvertFileName(filename), "rb" );
700 // read model settings
703 fseek(tfile, 0, SEEK_SET);
704 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
706 // read the model data
711 owner = (int*)malloc(sizeof(int) * vertexNum);
712 possible = (int*)malloc(sizeof(int) * TriangleNum);
713 vertex = (XYZ*)malloc(sizeof(XYZ) * vertexNum);
714 Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle) * TriangleNum);
715 vArray = (GLfloat*)malloc(sizeof(GLfloat) * TriangleNum * 24);
718 for (i = 0; i < vertexNum; i++) {
719 funpackf(tfile, "Bf Bf Bf", &vertex[i].x, &vertex[i].y, &vertex[i].z);
722 for (i = 0; i < TriangleNum; i++) {
723 // funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
725 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
726 Triangles[i].vertex[ 0] = vertex[ 0];
727 Triangles[i].vertex[ 1] = vertex[ 2];
728 Triangles[i].vertex[ 2] = vertex[ 4];
729 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
730 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
736 for (i = 0; i < vertexNum; i++) {
744 void Model::UniformTexCoords()
747 for (i = 0; i < TriangleNum; i++) {
748 Triangles[i].gy[0] = vertex[Triangles[i].vertex[0]].y;
749 Triangles[i].gy[1] = vertex[Triangles[i].vertex[1]].y;
750 Triangles[i].gy[2] = vertex[Triangles[i].vertex[2]].y;
751 Triangles[i].gx[0] = vertex[Triangles[i].vertex[0]].x;
752 Triangles[i].gx[1] = vertex[Triangles[i].vertex[1]].x;
753 Triangles[i].gx[2] = vertex[Triangles[i].vertex[2]].x;
759 void Model::FlipTexCoords()
762 for (i = 0; i < TriangleNum; i++) {
763 Triangles[i].gy[0] = -Triangles[i].gy[0];
764 Triangles[i].gy[1] = -Triangles[i].gy[1];
765 Triangles[i].gy[2] = -Triangles[i].gy[2];
770 void Model::ScaleTexCoords(float howmuch)
773 for (i = 0; i < TriangleNum; i++) {
774 Triangles[i].gx[0] *= howmuch;
775 Triangles[i].gx[1] *= howmuch;
776 Triangles[i].gx[2] *= howmuch;
777 Triangles[i].gy[0] *= howmuch;
778 Triangles[i].gy[1] *= howmuch;
779 Triangles[i].gy[2] *= howmuch;
784 void Model::Scale(float xscale, float yscale, float zscale)
787 for (i = 0; i < vertexNum; i++) {
788 vertex[i].x *= xscale;
789 vertex[i].y *= yscale;
790 vertex[i].z *= zscale;
796 boundingsphereradius = 0;
797 for (i = 0; i < vertexNum; i++) {
798 for (j = 0; j < vertexNum; j++) {
799 if (j != i && distsq(&vertex[j], &vertex[i]) / 2 > boundingsphereradius) {
800 boundingsphereradius = distsq(&vertex[j], &vertex[i]) / 2;
801 boundingspherecenter = (vertex[i] + vertex[j]) / 2;
805 boundingsphereradius = fast_sqrt(boundingsphereradius);
808 void Model::ScaleNormals(float xscale, float yscale, float zscale)
810 if (type != normaltype && type != decalstype)return;
812 for (i = 0; i < vertexNum; i++) {
813 normals[i].x *= xscale;
814 normals[i].y *= yscale;
815 normals[i].z *= zscale;
817 for (i = 0; i < TriangleNum; i++) {
818 facenormals[i].x *= xscale;
819 facenormals[i].y *= yscale;
820 facenormals[i].z *= zscale;
825 void Model::Translate(float xtrans, float ytrans, float ztrans)
828 for (i = 0; i < vertexNum; i++) {
829 vertex[i].x += xtrans;
830 vertex[i].y += ytrans;
831 vertex[i].z += ztrans;
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);
848 void Model::Rotate(float xang, float yang, float zang)
851 for (i = 0; i < vertexNum; i++) {
852 vertex[i] = DoRotation(vertex[i], xang, yang, zang);
857 boundingsphereradius = 0;
858 for (i = 0; i < vertexNum; i++) {
859 for (j = 0; j < vertexNum; j++) {
860 if (j != i && distsq(&vertex[j], &vertex[i]) / 2 > boundingsphereradius) {
861 boundingsphereradius = distsq(&vertex[j], &vertex[i]) / 2;
862 boundingspherecenter = (vertex[i] + vertex[j]) / 2;
866 boundingsphereradius = fast_sqrt(boundingsphereradius);
870 void Model::CalculateNormals(bool facenormalise)
873 Game::LoadingScreen();
875 if (type != normaltype && type != decalstype)return;
877 for (i = 0; i < vertexNum; i++) {
883 for (i = 0; i < TriangleNum; i++) {
884 CrossProduct(vertex[Triangles[i].vertex[1]] - vertex[Triangles[i].vertex[0]], vertex[Triangles[i].vertex[2]] - vertex[Triangles[i].vertex[0]], &facenormals[i]);
886 normals[Triangles[i].vertex[0]].x += facenormals[i].x;
887 normals[Triangles[i].vertex[0]].y += facenormals[i].y;
888 normals[Triangles[i].vertex[0]].z += facenormals[i].z;
890 normals[Triangles[i].vertex[1]].x += facenormals[i].x;
891 normals[Triangles[i].vertex[1]].y += facenormals[i].y;
892 normals[Triangles[i].vertex[1]].z += facenormals[i].z;
894 normals[Triangles[i].vertex[2]].x += facenormals[i].x;
895 normals[Triangles[i].vertex[2]].y += facenormals[i].y;
896 normals[Triangles[i].vertex[2]].z += facenormals[i].z;
897 if (facenormalise)Normalise(&facenormals[i]);
899 for (i = 0; i < vertexNum; i++) {
900 Normalise(&normals[i]);
903 UpdateVertexArrayNoTex();
906 void Model::drawimmediate()
909 glBegin(GL_TRIANGLES);
910 for (int i = 0; i < TriangleNum; i++) {
911 /*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){
912 if(isnormal(vertex[Triangles[i].vertex[0]].x)&&isnormal(vertex[Triangles[i].vertex[0]].y)&&isnormal(vertex[Triangles[i].vertex[0]].z)
913 &&isnormal(vertex[Triangles[i].vertex[1]].x)&&isnormal(vertex[Triangles[i].vertex[1]].y)&&isnormal(vertex[Triangles[i].vertex[1]].z)
914 &&isnormal(vertex[Triangles[i].vertex[2]].x)&&isnormal(vertex[Triangles[i].vertex[2]].y)&&isnormal(vertex[Triangles[i].vertex[2]].z)){
916 glTexCoord2f(Triangles[i].gx[0], Triangles[i].gy[0]);
917 if (color)glColor3f(normals[Triangles[i].vertex[0]].x, normals[Triangles[i].vertex[0]].y, normals[Triangles[i].vertex[0]].z);
918 if (!color && !flat)glNormal3f(normals[Triangles[i].vertex[0]].x, normals[Triangles[i].vertex[0]].y, normals[Triangles[i].vertex[0]].z);
919 if (!color && flat)glNormal3f(facenormals[i].x, facenormals[i].y, facenormals[i].y);
920 glVertex3f(vertex[Triangles[i].vertex[0]].x, vertex[Triangles[i].vertex[0]].y, vertex[Triangles[i].vertex[0]].z);
922 glTexCoord2f(Triangles[i].gx[1], Triangles[i].gy[1]);
923 if (color)glColor3f(normals[Triangles[i].vertex[1]].x, normals[Triangles[i].vertex[1]].y, normals[Triangles[i].vertex[1]].z);
924 if (!color && !flat)glNormal3f(normals[Triangles[i].vertex[1]].x, normals[Triangles[i].vertex[1]].y, normals[Triangles[i].vertex[1]].z);
925 if (!color && flat)glNormal3f(facenormals[i].x, facenormals[i].y, facenormals[i].y);
926 glVertex3f(vertex[Triangles[i].vertex[1]].x, vertex[Triangles[i].vertex[1]].y, vertex[Triangles[i].vertex[1]].z);
928 glTexCoord2f(Triangles[i].gx[2], Triangles[i].gy[2]);
929 if (color)glColor3f(normals[Triangles[i].vertex[2]].x, normals[Triangles[i].vertex[2]].y, normals[Triangles[i].vertex[2]].z);
930 if (!color && !flat)glNormal3f(normals[Triangles[i].vertex[2]].x, normals[Triangles[i].vertex[2]].y, normals[Triangles[i].vertex[2]].z);
931 if (!color && flat)glNormal3f(facenormals[i].x, facenormals[i].y, facenormals[i].y);
932 glVertex3f(vertex[Triangles[i].vertex[2]].x, vertex[Triangles[i].vertex[2]].y, vertex[Triangles[i].vertex[2]].z);
941 if (type != normaltype && type != decalstype)return;
943 glEnableClientState(GL_NORMAL_ARRAY);
944 glEnableClientState(GL_VERTEX_ARRAY);
945 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
947 if (!color)glInterleavedArrays( GL_T2F_N3F_V3F, 8 * sizeof(GLfloat), &vArray[0]);
948 if (color)glInterleavedArrays( GL_T2F_C3F_V3F, 8 * sizeof(GLfloat), &vArray[0]);
952 glLockArraysEXT( 0, TriangleNum * 3);
954 glDrawArrays(GL_TRIANGLES, 0, TriangleNum * 3);
960 if (!color)glDisableClientState(GL_NORMAL_ARRAY);
961 if (color)glDisableClientState(GL_COLOR_ARRAY);
962 glDisableClientState(GL_VERTEX_ARRAY);
963 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
967 //TODO: phase out in favor of Texture
968 void Model::drawdifftex(GLuint texture)
970 glEnableClientState(GL_NORMAL_ARRAY);
971 glEnableClientState(GL_VERTEX_ARRAY);
972 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
973 if (!color)glInterleavedArrays( GL_T2F_N3F_V3F, 8 * sizeof(GLfloat), &vArray[0]);
974 if (color)glInterleavedArrays( GL_T2F_C3F_V3F, 8 * sizeof(GLfloat), &vArray[0]);
976 glBindTexture(GL_TEXTURE_2D, (unsigned long)texture);
977 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
978 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
982 glLockArraysEXT( 0, TriangleNum * 3);
984 glDrawArrays(GL_TRIANGLES, 0, TriangleNum * 3);
990 if (!color)glDisableClientState(GL_NORMAL_ARRAY);
991 if (color)glDisableClientState(GL_COLOR_ARRAY);
992 glDisableClientState(GL_VERTEX_ARRAY);
993 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
994 //drawdiffteximmediate(texture);
997 void Model::drawdifftex(Texture texture)
999 glEnableClientState(GL_NORMAL_ARRAY);
1000 glEnableClientState(GL_VERTEX_ARRAY);
1001 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1002 if (!color)glInterleavedArrays( GL_T2F_N3F_V3F, 8 * sizeof(GLfloat), &vArray[0]);
1003 if (color)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();
1019 if (!color)glDisableClientState(GL_NORMAL_ARRAY);
1020 if (color)glDisableClientState(GL_COLOR_ARRAY);
1021 glDisableClientState(GL_VERTEX_ARRAY);
1022 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1023 //drawdiffteximmediate(texture);
1026 void Model::drawdiffteximmediate(GLuint texture)
1028 glBindTexture(GL_TEXTURE_2D, (unsigned long)texture);
1030 glBegin(GL_TRIANGLES);
1031 for (int i = 0; i < TriangleNum; i++) {
1032 /*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){
1033 if(isnormal(vertex[Triangles[i].vertex[0]].x)&&isnormal(vertex[Triangles[i].vertex[0]].y)&&isnormal(vertex[Triangles[i].vertex[0]].z)
1034 &&isnormal(vertex[Triangles[i].vertex[1]].x)&&isnormal(vertex[Triangles[i].vertex[1]].y)&&isnormal(vertex[Triangles[i].vertex[1]].z)
1035 &&isnormal(vertex[Triangles[i].vertex[2]].x)&&isnormal(vertex[Triangles[i].vertex[2]].y)&&isnormal(vertex[Triangles[i].vertex[2]].z)){
1036 */glTexCoord2f(Triangles[i].gx[0], Triangles[i].gy[0]);
1037 if (color)glColor3f(normals[Triangles[i].vertex[0]].x, normals[Triangles[i].vertex[0]].y, normals[Triangles[i].vertex[0]].z);
1038 if (!color && !flat)glNormal3f(normals[Triangles[i].vertex[0]].x, normals[Triangles[i].vertex[0]].y, normals[Triangles[i].vertex[0]].z);
1039 if (!color && flat)glNormal3f(facenormals[i].x, facenormals[i].y, facenormals[i].y);
1040 glVertex3f(vertex[Triangles[i].vertex[0]].x, vertex[Triangles[i].vertex[0]].y, vertex[Triangles[i].vertex[0]].z);
1042 glTexCoord2f(Triangles[i].gx[1], Triangles[i].gy[1]);
1043 if (color)glColor3f(normals[Triangles[i].vertex[1]].x, normals[Triangles[i].vertex[1]].y, normals[Triangles[i].vertex[1]].z);
1044 if (!color && !flat)glNormal3f(normals[Triangles[i].vertex[1]].x, normals[Triangles[i].vertex[1]].y, normals[Triangles[i].vertex[1]].z);
1045 if (!color && flat)glNormal3f(facenormals[i].x, facenormals[i].y, facenormals[i].y);
1046 glVertex3f(vertex[Triangles[i].vertex[1]].x, vertex[Triangles[i].vertex[1]].y, vertex[Triangles[i].vertex[1]].z);
1048 glTexCoord2f(Triangles[i].gx[2], Triangles[i].gy[2]);
1049 if (color)glColor3f(normals[Triangles[i].vertex[2]].x, normals[Triangles[i].vertex[2]].y, normals[Triangles[i].vertex[2]].z);
1050 if (!color && !flat)glNormal3f(normals[Triangles[i].vertex[2]].x, normals[Triangles[i].vertex[2]].y, normals[Triangles[i].vertex[2]].z);
1051 if (!color && flat)glNormal3f(facenormals[i].x, facenormals[i].y, facenormals[i].y);
1052 glVertex3f(vertex[Triangles[i].vertex[2]].x, vertex[Triangles[i].vertex[2]].y, vertex[Triangles[i].vertex[2]].z);
1059 void Model::drawdecals(Texture shadowtexture, Texture bloodtexture, Texture bloodtexture2, Texture breaktexture)
1062 if (type != decalstype)return;
1064 static float distancemult;
1065 static int lasttype;
1066 static float viewdistsquared;
1069 viewdistsquared = viewdistance * viewdistance;
1074 glDisable(GL_LIGHTING);
1075 glDisable(GL_CULL_FACE);
1076 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1078 if (numdecals > max_model_decals)numdecals = max_model_decals;
1079 for (i = 0; i < numdecals; i++) {
1080 if (decaltype[i] == blooddecalfast && decalalivetime[i] < 2)decalalivetime[i] = 2;
1082 if (decaltype[i] == shadowdecal && decaltype[i] != lasttype) {
1083 shadowtexture.bind();
1086 glAlphaFunc(GL_GREATER, 0.0001);
1087 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1090 if (decaltype[i] == breakdecal && decaltype[i] != lasttype) {
1091 breaktexture.bind();
1094 glAlphaFunc(GL_GREATER, 0.0001);
1095 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1098 if ((decaltype[i] == blooddecal || decaltype[i] == blooddecalslow) && decaltype[i] != lasttype) {
1099 bloodtexture.bind();
1102 glAlphaFunc(GL_GREATER, 0.15);
1103 glBlendFunc(GL_ONE, GL_ZERO);
1106 if ((decaltype[i] == blooddecalfast) && decaltype[i] != lasttype) {
1107 bloodtexture2.bind();
1110 glAlphaFunc(GL_GREATER, 0.15);
1111 glBlendFunc(GL_ONE, GL_ZERO);
1114 if (decaltype[i] == shadowdecal) {
1115 glColor4f(1, 1, 1, decalopacity[i]);
1117 if (decaltype[i] == breakdecal) {
1118 glColor4f(1, 1, 1, decalopacity[i]);
1119 if (decalalivetime[i] > 58)glColor4f(1, 1, 1, decalopacity[i] * (60 - decalalivetime[i]) / 2);
1121 if ((decaltype[i] == blooddecal || decaltype[i] == blooddecalfast || decaltype[i] == blooddecalslow)) {
1122 glColor4f(1, 1, 1, decalopacity[i]);
1123 if (decalalivetime[i] < 4)glColor4f(1, 1, 1, decalopacity[i]*decalalivetime[i]*.25);
1124 if (decalalivetime[i] > 58)glColor4f(1, 1, 1, decalopacity[i] * (60 - decalalivetime[i]) / 2);
1126 lasttype = decaltype[i];
1127 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1128 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
1130 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
1132 glBegin(GL_TRIANGLES);
1133 for (int j = 0; j < 3; j++) {
1134 glTexCoord2f(decaltexcoords[i][j][0], decaltexcoords[i][j][1]);
1135 glVertex3f(decalvertex[i][j].x, decalvertex[i][j].y, decalvertex[i][j].z);
1140 for (i = numdecals - 1; i >= 0; i--) {
1141 decalalivetime[i] += multiplier;
1142 if (decaltype[i] == blooddecalslow)decalalivetime[i] -= multiplier * 2 / 3;
1143 if (decaltype[i] == blooddecalfast)decalalivetime[i] += multiplier * 4;
1144 if (decaltype[i] == shadowdecal)DeleteDecal(i);
1145 if ((decaltype[i] == blooddecal || decaltype[i] == blooddecalfast || decaltype[i] == blooddecalslow) && decalalivetime[i] >= 60)DeleteDecal(i);
1147 glAlphaFunc(GL_GREATER, 0.0001);
1148 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1152 void Model::DeleteDecal(int which)
1155 if (type != decalstype)return;
1156 decaltype[which] = decaltype[numdecals - 1];
1157 decalposition[which] = decalposition[numdecals - 1];
1158 for (int i = 0; i < 3; i++) {
1159 decalvertex[which][i] = decalvertex[numdecals - 1][i];
1160 decaltexcoords[which][i][0] = decaltexcoords[numdecals - 1][i][0];
1161 decaltexcoords[which][i][1] = decaltexcoords[numdecals - 1][i][1];
1163 decalrotation[which] = decalrotation[numdecals - 1];
1164 decalalivetime[which] = decalalivetime[numdecals - 1];
1165 decalopacity[which] = decalopacity[numdecals - 1];
1170 void Model::MakeDecal(int atype, XYZ *where, float *size, float *opacity, float *rotation)
1173 if (type != decalstype)return;
1175 static float placex, placez;
1177 //static XYZ point,point1,point2;
1178 static float distance;
1182 if (distsq(where, &boundingspherecenter) < (boundingsphereradius + *size) * (boundingsphereradius + *size))
1183 for (i = 0; i < TriangleNum; i++) {
1184 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)) {
1185 decalposition[numdecals] = *where;
1186 decaltype[numdecals] = atype;
1187 decalrotation[numdecals] = *rotation;
1188 decalalivetime[numdecals] = 0;
1189 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);
1190 decalopacity[numdecals] = *opacity - distance / 10;
1192 if (decalopacity[numdecals > 0]) {
1193 placex = vertex[Triangles[i].vertex[0]].x;
1194 placez = vertex[Triangles[i].vertex[0]].z;
1196 decaltexcoords[numdecals][0][0] = (placex - where->x) / (*size) / 2 + .5;
1197 decaltexcoords[numdecals][0][1] = (placez - where->z) / (*size) / 2 + .5;
1199 decalvertex[numdecals][0].x = placex;
1200 decalvertex[numdecals][0].z = placez;
1201 decalvertex[numdecals][0].y = vertex[Triangles[i].vertex[0]].y;
1204 placex = vertex[Triangles[i].vertex[1]].x;
1205 placez = vertex[Triangles[i].vertex[1]].z;
1207 decaltexcoords[numdecals][1][0] = (placex - where->x) / (*size) / 2 + .5;
1208 decaltexcoords[numdecals][1][1] = (placez - where->z) / (*size) / 2 + .5;
1210 decalvertex[numdecals][1].x = placex;
1211 decalvertex[numdecals][1].z = placez;
1212 decalvertex[numdecals][1].y = vertex[Triangles[i].vertex[1]].y;
1215 placex = vertex[Triangles[i].vertex[2]].x;
1216 placez = vertex[Triangles[i].vertex[2]].z;
1218 decaltexcoords[numdecals][2][0] = (placex - where->x) / (*size) / 2 + .5;
1219 decaltexcoords[numdecals][2][1] = (placez - where->z) / (*size) / 2 + .5;
1221 decalvertex[numdecals][2].x = placex;
1222 decalvertex[numdecals][2].z = placez;
1223 decalvertex[numdecals][2].y = vertex[Triangles[i].vertex[2]].y;
1225 if (!(decaltexcoords[numdecals][0][0] < 0 && decaltexcoords[numdecals][1][0] < 0 && decaltexcoords[numdecals][2][0] < 0))
1226 if (!(decaltexcoords[numdecals][0][1] < 0 && decaltexcoords[numdecals][1][1] < 0 && decaltexcoords[numdecals][2][1] < 0))
1227 if (!(decaltexcoords[numdecals][0][0] > 1 && decaltexcoords[numdecals][1][0] > 1 && decaltexcoords[numdecals][2][0] > 1))
1228 if (!(decaltexcoords[numdecals][0][1] > 1 && decaltexcoords[numdecals][1][1] > 1 && decaltexcoords[numdecals][2][1] > 1)) {
1229 if (decalrotation[numdecals]) {
1230 for (j = 0; j < 3; j++) {
1232 rot.x = decaltexcoords[numdecals][j][0] - .5;
1233 rot.z = decaltexcoords[numdecals][j][1] - .5;
1234 rot = DoRotation(rot, 0, -decalrotation[numdecals], 0);
1235 decaltexcoords[numdecals][j][0] = rot.x + .5;
1236 decaltexcoords[numdecals][j][1] = rot.z + .5;
1239 if (numdecals < max_model_decals - 1)numdecals++;
1247 void Model::MakeDecal(int atype, XYZ where, float size, float opacity, float rotation)
1250 if (type != decalstype)return;
1252 static float placex, placez;
1254 //static XYZ point,point1,point2;
1255 static float distance;
1259 if (distsq(&where, &boundingspherecenter) < (boundingsphereradius + size) * (boundingsphereradius + size))
1260 for (i = 0; i < TriangleNum; i++) {
1261 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))));
1262 if (distance < .02 && abs(facenormals[i].y) > abs(facenormals[i].x) && abs(facenormals[i].y) > abs(facenormals[i].z)) {
1263 decalposition[numdecals] = where;
1264 decaltype[numdecals] = atype;
1265 decalrotation[numdecals] = rotation;
1266 decalalivetime[numdecals] = 0;
1267 decalopacity[numdecals] = opacity - distance / 10;
1269 if (decalopacity[numdecals > 0]) {
1270 placex = vertex[Triangles[i].vertex[0]].x;
1271 placez = vertex[Triangles[i].vertex[0]].z;
1273 decaltexcoords[numdecals][0][0] = (placex - where.x) / (size) / 2 + .5;
1274 decaltexcoords[numdecals][0][1] = (placez - where.z) / (size) / 2 + .5;
1276 decalvertex[numdecals][0].x = placex;
1277 decalvertex[numdecals][0].z = placez;
1278 decalvertex[numdecals][0].y = vertex[Triangles[i].vertex[0]].y;
1281 placex = vertex[Triangles[i].vertex[1]].x;
1282 placez = vertex[Triangles[i].vertex[1]].z;
1284 decaltexcoords[numdecals][1][0] = (placex - where.x) / (size) / 2 + .5;
1285 decaltexcoords[numdecals][1][1] = (placez - where.z) / (size) / 2 + .5;
1287 decalvertex[numdecals][1].x = placex;
1288 decalvertex[numdecals][1].z = placez;
1289 decalvertex[numdecals][1].y = vertex[Triangles[i].vertex[1]].y;
1292 placex = vertex[Triangles[i].vertex[2]].x;
1293 placez = vertex[Triangles[i].vertex[2]].z;
1295 decaltexcoords[numdecals][2][0] = (placex - where.x) / (size) / 2 + .5;
1296 decaltexcoords[numdecals][2][1] = (placez - where.z) / (size) / 2 + .5;
1298 decalvertex[numdecals][2].x = placex;
1299 decalvertex[numdecals][2].z = placez;
1300 decalvertex[numdecals][2].y = vertex[Triangles[i].vertex[2]].y;
1302 if (!(decaltexcoords[numdecals][0][0] < 0 && decaltexcoords[numdecals][1][0] < 0 && decaltexcoords[numdecals][2][0] < 0))
1303 if (!(decaltexcoords[numdecals][0][1] < 0 && decaltexcoords[numdecals][1][1] < 0 && decaltexcoords[numdecals][2][1] < 0))
1304 if (!(decaltexcoords[numdecals][0][0] > 1 && decaltexcoords[numdecals][1][0] > 1 && decaltexcoords[numdecals][2][0] > 1))
1305 if (!(decaltexcoords[numdecals][0][1] > 1 && decaltexcoords[numdecals][1][1] > 1 && decaltexcoords[numdecals][2][1] > 1)) {
1306 if (decalrotation[numdecals]) {
1307 for (j = 0; j < 3; j++) {
1309 rot.x = decaltexcoords[numdecals][j][0] - .5;
1310 rot.z = decaltexcoords[numdecals][j][1] - .5;
1311 rot = DoRotation(rot, 0, -decalrotation[numdecals], 0);
1312 decaltexcoords[numdecals][j][0] = rot.x + .5;
1313 decaltexcoords[numdecals][j][1] = rot.z + .5;
1316 if (numdecals < max_model_decals - 1)numdecals++;
1319 } else if (distance < .02 && abs(facenormals[i].x) > abs(facenormals[i].y) && abs(facenormals[i].x) > abs(facenormals[i].z)) {
1320 decalposition[numdecals] = where;
1321 decaltype[numdecals] = atype;
1322 decalrotation[numdecals] = rotation;
1323 decalalivetime[numdecals] = 0;
1324 decalopacity[numdecals] = opacity - distance / 10;
1326 if (decalopacity[numdecals > 0]) {
1327 placex = vertex[Triangles[i].vertex[0]].y;
1328 placez = vertex[Triangles[i].vertex[0]].z;
1330 decaltexcoords[numdecals][0][0] = (placex - where.y) / (size) / 2 + .5;
1331 decaltexcoords[numdecals][0][1] = (placez - where.z) / (size) / 2 + .5;
1333 decalvertex[numdecals][0].x = vertex[Triangles[i].vertex[0]].x;
1334 decalvertex[numdecals][0].z = placez;
1335 decalvertex[numdecals][0].y = placex;
1338 placex = vertex[Triangles[i].vertex[1]].y;
1339 placez = vertex[Triangles[i].vertex[1]].z;
1341 decaltexcoords[numdecals][1][0] = (placex - where.y) / (size) / 2 + .5;
1342 decaltexcoords[numdecals][1][1] = (placez - where.z) / (size) / 2 + .5;
1344 decalvertex[numdecals][1].x = vertex[Triangles[i].vertex[1]].x;
1345 decalvertex[numdecals][1].z = placez;
1346 decalvertex[numdecals][1].y = placex;
1349 placex = vertex[Triangles[i].vertex[2]].y;
1350 placez = vertex[Triangles[i].vertex[2]].z;
1352 decaltexcoords[numdecals][2][0] = (placex - where.y) / (size) / 2 + .5;
1353 decaltexcoords[numdecals][2][1] = (placez - where.z) / (size) / 2 + .5;
1355 decalvertex[numdecals][2].x = vertex[Triangles[i].vertex[2]].x;
1356 decalvertex[numdecals][2].z = placez;
1357 decalvertex[numdecals][2].y = placex;
1359 if (!(decaltexcoords[numdecals][0][0] < 0 && decaltexcoords[numdecals][1][0] < 0 && decaltexcoords[numdecals][2][0] < 0))
1360 if (!(decaltexcoords[numdecals][0][1] < 0 && decaltexcoords[numdecals][1][1] < 0 && decaltexcoords[numdecals][2][1] < 0))
1361 if (!(decaltexcoords[numdecals][0][0] > 1 && decaltexcoords[numdecals][1][0] > 1 && decaltexcoords[numdecals][2][0] > 1))
1362 if (!(decaltexcoords[numdecals][0][1] > 1 && decaltexcoords[numdecals][1][1] > 1 && decaltexcoords[numdecals][2][1] > 1)) {
1363 if (decalrotation[numdecals]) {
1364 for (j = 0; j < 3; j++) {
1366 rot.x = decaltexcoords[numdecals][j][0] - .5;
1367 rot.z = decaltexcoords[numdecals][j][1] - .5;
1368 rot = DoRotation(rot, 0, -decalrotation[numdecals], 0);
1369 decaltexcoords[numdecals][j][0] = rot.x + .5;
1370 decaltexcoords[numdecals][j][1] = rot.z + .5;
1373 if (numdecals < max_model_decals - 1)numdecals++;
1376 } else if (distance < .02 && abs(facenormals[i].z) > abs(facenormals[i].y) && abs(facenormals[i].z) > abs(facenormals[i].x)) {
1377 decalposition[numdecals] = where;
1378 decaltype[numdecals] = atype;
1379 decalrotation[numdecals] = rotation;
1380 decalalivetime[numdecals] = 0;
1381 decalopacity[numdecals] = opacity - distance / 10;
1383 if (decalopacity[numdecals > 0]) {
1384 placex = vertex[Triangles[i].vertex[0]].x;
1385 placez = vertex[Triangles[i].vertex[0]].y;
1387 decaltexcoords[numdecals][0][0] = (placex - where.x) / (size) / 2 + .5;
1388 decaltexcoords[numdecals][0][1] = (placez - where.y) / (size) / 2 + .5;
1390 decalvertex[numdecals][0].x = placex;
1391 decalvertex[numdecals][0].z = vertex[Triangles[i].vertex[0]].z;
1392 decalvertex[numdecals][0].y = placez;
1395 placex = vertex[Triangles[i].vertex[1]].x;
1396 placez = vertex[Triangles[i].vertex[1]].y;
1398 decaltexcoords[numdecals][1][0] = (placex - where.x) / (size) / 2 + .5;
1399 decaltexcoords[numdecals][1][1] = (placez - where.y) / (size) / 2 + .5;
1401 decalvertex[numdecals][1].x = placex;
1402 decalvertex[numdecals][1].z = vertex[Triangles[i].vertex[1]].z;
1403 decalvertex[numdecals][1].y = placez;
1406 placex = vertex[Triangles[i].vertex[2]].x;
1407 placez = vertex[Triangles[i].vertex[2]].y;
1409 decaltexcoords[numdecals][2][0] = (placex - where.x) / (size) / 2 + .5;
1410 decaltexcoords[numdecals][2][1] = (placez - where.y) / (size) / 2 + .5;
1412 decalvertex[numdecals][2].x = placex;
1413 decalvertex[numdecals][2].z = vertex[Triangles[i].vertex[2]].z;
1414 decalvertex[numdecals][2].y = placez;
1416 if (!(decaltexcoords[numdecals][0][0] < 0 && decaltexcoords[numdecals][1][0] < 0 && decaltexcoords[numdecals][2][0] < 0))
1417 if (!(decaltexcoords[numdecals][0][1] < 0 && decaltexcoords[numdecals][1][1] < 0 && decaltexcoords[numdecals][2][1] < 0))
1418 if (!(decaltexcoords[numdecals][0][0] > 1 && decaltexcoords[numdecals][1][0] > 1 && decaltexcoords[numdecals][2][0] > 1))
1419 if (!(decaltexcoords[numdecals][0][1] > 1 && decaltexcoords[numdecals][1][1] > 1 && decaltexcoords[numdecals][2][1] > 1)) {
1420 if (decalrotation[numdecals]) {
1421 for (j = 0; j < 3; j++) {
1423 rot.x = decaltexcoords[numdecals][j][0] - .5;
1424 rot.z = decaltexcoords[numdecals][j][1] - .5;
1425 rot = DoRotation(rot, 0, -decalrotation[numdecals], 0);
1426 decaltexcoords[numdecals][j][0] = rot.x + .5;
1427 decaltexcoords[numdecals][j][1] = rot.z + .5;
1430 if (numdecals < max_model_decals - 1)numdecals++;
1441 textureptr.destroy();
1444 void Model::deallocate()
1448 if (owner)free(owner);
1451 if (possible)free(possible);
1454 if (vertex)free(vertex);
1457 if (normals)free(normals);
1460 if (facenormals)free(facenormals);
1463 if (Triangles)free(Triangles);
1466 if (vArray)free(vArray);
1471 if (decaltexcoords) {
1472 for (i = 0; i < max_model_decals; i++) {
1473 for (j = 0; j < 3; j++) {
1474 free(decaltexcoords[i][j]);
1476 free(decaltexcoords[i]);
1478 free(decaltexcoords);
1484 for (i = 0; i < max_model_decals; i++) {
1485 free(decalvertex[i]);
1498 free(decalrotation);
1501 free(decalalivetime);
1504 free(decalposition);
1511 vertexNum = 0, TriangleNum = 0;
1514 type = 0, oldtype = 0;
1524 memset(&modelTexture, 0, sizeof(modelTexture));
1528 boundingspherecenter = 0;
1529 boundingsphereradius = 0;