2 Copyright (C) 2003, 2010 - Wolfire Games
3 Copyright (C) 2010-2016 - Lugaru contributors (see AUTHORS file)
5 This file is part of Lugaru.
7 Lugaru is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 Lugaru is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with Lugaru. If not, see <http://www.gnu.org/licenses/>.
24 extern float multiplier;
25 extern float viewdistance;
27 extern float fadestart;
28 extern float texdetail;
31 extern bool visibleloading;
33 int Model::LineCheck(XYZ *p1, XYZ *p2, XYZ *p, XYZ *move, float *rotate)
36 static float distance;
37 static float olddistance;
38 static int intersecting;
39 static int firstintersecting;
45 *p1 = DoRotation(*p1, 0, -*rotate, 0);
47 *p2 = DoRotation(*p2, 0, -*rotate, 0);
48 if (!sphere_line_intersection(p1, p2, &boundingspherecenter, &boundingsphereradius))
50 firstintersecting = -1;
52 for (j = 0; j < TriangleNum; j++) {
53 intersecting = LineFacetd(p1, p2, &vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[1]], &vertex[Triangles[j].vertex[2]], &facenormals[j], &point);
54 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);
55 if ((distance < olddistance || firstintersecting == -1) && intersecting) {
56 olddistance = distance;
57 firstintersecting = j;
63 *p = DoRotation(*p, 0, *rotate, 0);
65 return firstintersecting;
68 int Model::LineCheckPossible(XYZ *p1, XYZ *p2, XYZ *p, XYZ *move, float *rotate)
71 static float distance;
72 static float olddistance;
73 static int intersecting;
74 static int firstintersecting;
79 if (!sphere_line_intersection(p1, p2, &boundingspherecenter, &boundingsphereradius))
81 firstintersecting = -1;
83 *p1 = DoRotation(*p1, 0, -*rotate, 0);
85 *p2 = DoRotation(*p2, 0, -*rotate, 0);
87 if (numpossible > 0 && numpossible < TriangleNum)
88 for (j = 0; j < numpossible; j++) {
89 if (possible[j] >= 0 && possible[j] < TriangleNum) {
90 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);
91 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);
92 if ((distance < olddistance || firstintersecting == -1) && intersecting) {
93 olddistance = distance;
94 firstintersecting = possible[j];
101 *p = DoRotation(*p, 0, *rotate, 0);
103 return firstintersecting;
106 int Model::LineCheckSlidePossible(XYZ *p1, XYZ *p2, XYZ *p, XYZ *move, float *rotate)
109 static float distance;
110 static float olddistance;
111 static int intersecting;
112 static int firstintersecting;
117 if (!sphere_line_intersection(p1, p2, &boundingspherecenter, &boundingsphereradius))
119 firstintersecting = -1;
121 *p1 = DoRotation(*p1, 0, -*rotate, 0);
123 *p2 = DoRotation(*p2, 0, -*rotate, 0);
126 for (j = 0; j < numpossible; j++) {
127 if (possible[j] >= 0 && possible[j] < TriangleNum) {
128 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);
129 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);
130 if ((distance < olddistance || firstintersecting == -1) && intersecting) {
131 olddistance = distance;
132 firstintersecting = possible[j];
137 if (firstintersecting > 0) {
138 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)));
139 *p2 -= facenormals[firstintersecting] * distance;
143 *p2 = DoRotation(*p2, 0, *rotate, 0);
145 return firstintersecting;
148 int Model::SphereCheck(XYZ *p1, float radius, XYZ *p, XYZ *move, float *rotate)
151 static float distance;
152 static float olddistance;
153 static int intersecting;
154 static int firstintersecting;
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);
185 if ((distance < olddistance || firstintersecting == -1) && intersecting) {
186 olddistance = distance;
187 firstintersecting = j;
193 *p = DoRotation(*p, 0, *rotate, 0);
196 *p1 = DoRotation(*p1, 0, *rotate, 0);
198 return firstintersecting;
201 int Model::SphereCheckPossible(XYZ *p1, float radius, XYZ *move, float *rotate)
204 static float distance;
205 static float olddistance;
206 static int intersecting;
207 static int firstintersecting;
211 firstintersecting = -1;
219 *p1 = DoRotation(*p1, 0, -*rotate, 0);
220 if (distsq(p1, &boundingspherecenter) > radius * radius + boundingsphereradius * boundingsphereradius) {
225 for (j = 0; j < TriangleNum; j++) {
227 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)));
228 if (distance < radius) {
229 point = *p1 - facenormals[j] * distance;
230 if (PointInTriangle( &point, facenormals[j], &vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[1]], &vertex[Triangles[j].vertex[2]]))
233 intersecting = sphere_line_intersection(&vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[1]], p1, &radius);
235 intersecting = sphere_line_intersection(&vertex[Triangles[j].vertex[1]], &vertex[Triangles[j].vertex[2]], p1, &radius);
237 intersecting = sphere_line_intersection(&vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[2]], p1, &radius);
239 possible[numpossible] = j;
243 if ((distance < olddistance || firstintersecting == -1) && intersecting) {
244 olddistance = distance;
245 firstintersecting = j;
249 *p1 = DoRotation(*p1, 0, *rotate, 0);
251 return firstintersecting;
255 void Model::UpdateVertexArray()
257 if (type != normaltype && type != decalstype)
262 for (i = 0; i < TriangleNum; i++) {
264 vArray[j + 0] = Triangles[i].gx[0];
265 vArray[j + 1] = Triangles[i].gy[0];
266 vArray[j + 2] = normals[Triangles[i].vertex[0]].x;
267 vArray[j + 3] = normals[Triangles[i].vertex[0]].y;
268 vArray[j + 4] = normals[Triangles[i].vertex[0]].z;
269 vArray[j + 5] = vertex[Triangles[i].vertex[0]].x;
270 vArray[j + 6] = vertex[Triangles[i].vertex[0]].y;
271 vArray[j + 7] = vertex[Triangles[i].vertex[0]].z;
273 vArray[j + 8] = Triangles[i].gx[1];
274 vArray[j + 9] = Triangles[i].gy[1];
275 vArray[j + 10] = normals[Triangles[i].vertex[1]].x;
276 vArray[j + 11] = normals[Triangles[i].vertex[1]].y;
277 vArray[j + 12] = normals[Triangles[i].vertex[1]].z;
278 vArray[j + 13] = vertex[Triangles[i].vertex[1]].x;
279 vArray[j + 14] = vertex[Triangles[i].vertex[1]].y;
280 vArray[j + 15] = vertex[Triangles[i].vertex[1]].z;
282 vArray[j + 16] = Triangles[i].gx[2];
283 vArray[j + 17] = Triangles[i].gy[2];
284 vArray[j + 18] = normals[Triangles[i].vertex[2]].x;
285 vArray[j + 19] = normals[Triangles[i].vertex[2]].y;
286 vArray[j + 20] = normals[Triangles[i].vertex[2]].z;
287 vArray[j + 21] = vertex[Triangles[i].vertex[2]].x;
288 vArray[j + 22] = vertex[Triangles[i].vertex[2]].y;
289 vArray[j + 23] = vertex[Triangles[i].vertex[2]].z;
292 for (i = 0; i < TriangleNum; i++) {
294 vArray[j + 0] = Triangles[i].gx[0];
295 vArray[j + 1] = Triangles[i].gy[0];
296 vArray[j + 2] = facenormals[i].x * -1;
297 vArray[j + 3] = facenormals[i].y * -1;
298 vArray[j + 4] = facenormals[i].z * -1;
299 vArray[j + 5] = vertex[Triangles[i].vertex[0]].x;
300 vArray[j + 6] = vertex[Triangles[i].vertex[0]].y;
301 vArray[j + 7] = vertex[Triangles[i].vertex[0]].z;
303 vArray[j + 8] = Triangles[i].gx[1];
304 vArray[j + 9] = Triangles[i].gy[1];
305 vArray[j + 10] = facenormals[i].x * -1;
306 vArray[j + 11] = facenormals[i].y * -1;
307 vArray[j + 12] = facenormals[i].z * -1;
308 vArray[j + 13] = vertex[Triangles[i].vertex[1]].x;
309 vArray[j + 14] = vertex[Triangles[i].vertex[1]].y;
310 vArray[j + 15] = vertex[Triangles[i].vertex[1]].z;
312 vArray[j + 16] = Triangles[i].gx[2];
313 vArray[j + 17] = Triangles[i].gy[2];
314 vArray[j + 18] = facenormals[i].x * -1;
315 vArray[j + 19] = facenormals[i].y * -1;
316 vArray[j + 20] = facenormals[i].z * -1;
317 vArray[j + 21] = vertex[Triangles[i].vertex[2]].x;
318 vArray[j + 22] = vertex[Triangles[i].vertex[2]].y;
319 vArray[j + 23] = vertex[Triangles[i].vertex[2]].z;
324 void Model::UpdateVertexArrayNoTex()
326 if (type != normaltype && type != decalstype)
331 for (i = 0; i < TriangleNum; i++) {
333 vArray[j + 2] = normals[Triangles[i].vertex[0]].x;
334 vArray[j + 3] = normals[Triangles[i].vertex[0]].y;
335 vArray[j + 4] = normals[Triangles[i].vertex[0]].z;
336 vArray[j + 5] = vertex[Triangles[i].vertex[0]].x;
337 vArray[j + 6] = vertex[Triangles[i].vertex[0]].y;
338 vArray[j + 7] = vertex[Triangles[i].vertex[0]].z;
340 vArray[j + 10] = normals[Triangles[i].vertex[1]].x;
341 vArray[j + 11] = normals[Triangles[i].vertex[1]].y;
342 vArray[j + 12] = normals[Triangles[i].vertex[1]].z;
343 vArray[j + 13] = vertex[Triangles[i].vertex[1]].x;
344 vArray[j + 14] = vertex[Triangles[i].vertex[1]].y;
345 vArray[j + 15] = vertex[Triangles[i].vertex[1]].z;
347 vArray[j + 18] = normals[Triangles[i].vertex[2]].x;
348 vArray[j + 19] = normals[Triangles[i].vertex[2]].y;
349 vArray[j + 20] = normals[Triangles[i].vertex[2]].z;
350 vArray[j + 21] = vertex[Triangles[i].vertex[2]].x;
351 vArray[j + 22] = vertex[Triangles[i].vertex[2]].y;
352 vArray[j + 23] = vertex[Triangles[i].vertex[2]].z;
355 for (i = 0; i < TriangleNum; i++) {
357 vArray[j + 2] = facenormals[i].x * -1;
358 vArray[j + 3] = facenormals[i].y * -1;
359 vArray[j + 4] = facenormals[i].z * -1;
360 vArray[j + 5] = vertex[Triangles[i].vertex[0]].x;
361 vArray[j + 6] = vertex[Triangles[i].vertex[0]].y;
362 vArray[j + 7] = vertex[Triangles[i].vertex[0]].z;
364 vArray[j + 10] = facenormals[i].x * -1;
365 vArray[j + 11] = facenormals[i].y * -1;
366 vArray[j + 12] = facenormals[i].z * -1;
367 vArray[j + 13] = vertex[Triangles[i].vertex[1]].x;
368 vArray[j + 14] = vertex[Triangles[i].vertex[1]].y;
369 vArray[j + 15] = vertex[Triangles[i].vertex[1]].z;
371 vArray[j + 18] = facenormals[i].x * -1;
372 vArray[j + 19] = facenormals[i].y * -1;
373 vArray[j + 20] = facenormals[i].z * -1;
374 vArray[j + 21] = vertex[Triangles[i].vertex[2]].x;
375 vArray[j + 22] = vertex[Triangles[i].vertex[2]].y;
376 vArray[j + 23] = vertex[Triangles[i].vertex[2]].z;
380 void Model::UpdateVertexArrayNoTexNoNorm()
382 if (type != normaltype && type != decalstype)
386 for (i = 0; i < TriangleNum; i++) {
388 vArray[j + 5] = vertex[Triangles[i].vertex[0]].x;
389 vArray[j + 6] = vertex[Triangles[i].vertex[0]].y;
390 vArray[j + 7] = vertex[Triangles[i].vertex[0]].z;
392 vArray[j + 13] = vertex[Triangles[i].vertex[1]].x;
393 vArray[j + 14] = vertex[Triangles[i].vertex[1]].y;
394 vArray[j + 15] = vertex[Triangles[i].vertex[1]].z;
396 vArray[j + 21] = vertex[Triangles[i].vertex[2]].x;
397 vArray[j + 22] = vertex[Triangles[i].vertex[2]].y;
398 vArray[j + 23] = vertex[Triangles[i].vertex[2]].z;
402 bool Model::loadnotex(const char *filename )
407 //~ int oldvertexNum, oldTriangleNum;
408 //~ oldvertexNum = vertexNum;
409 //~ oldTriangleNum = TriangleNum;
414 tfile = fopen( ConvertFileName(filename), "rb" );
415 // read model settings
417 fseek(tfile, 0, SEEK_SET);
418 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
420 // read the model data
425 owner = (int*)malloc(sizeof(int) * vertexNum);
426 possible = (int*)malloc(sizeof(int) * TriangleNum);
427 vertex = (XYZ*)malloc(sizeof(XYZ) * vertexNum);
428 Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle) * TriangleNum);
429 vArray = (GLfloat*)malloc(sizeof(GLfloat) * TriangleNum * 24);
431 for (i = 0; i < vertexNum; i++) {
432 funpackf(tfile, "Bf Bf Bf", &vertex[i].x, &vertex[i].y, &vertex[i].z);
435 for (i = 0; i < TriangleNum; i++) {
436 //funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
438 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
439 Triangles[i].vertex[ 0] = vertex[ 0];
440 Triangles[i].vertex[ 1] = vertex[ 2];
441 Triangles[i].vertex[ 2] = vertex[ 4];
442 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
443 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
450 for (i = 0; i < vertexNum; i++) {
455 boundingsphereradius = 0;
456 for (i = 0; i < vertexNum; i++) {
457 for (j = 0; j < vertexNum; j++) {
458 if (j != i && distsq(&vertex[j], &vertex[i]) / 2 > boundingsphereradius) {
459 boundingsphereradius = distsq(&vertex[j], &vertex[i]) / 2;
460 boundingspherecenter = (vertex[i] + vertex[j]) / 2;
464 boundingsphereradius = fast_sqrt(boundingsphereradius);
470 bool Model::load(const char *filename, bool texture )
477 LOG(std::string("Loading model...") + filename);
480 Game::LoadingScreen();
482 //~ int oldvertexNum, oldTriangleNum;
483 //~ oldvertexNum = vertexNum;
484 //~ oldTriangleNum = TriangleNum;
489 tfile = fopen( ConvertFileName(filename), "rb" );
490 // read model settings
493 fseek(tfile, 0, SEEK_SET);
494 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
496 // read the model data
501 owner = (int*)malloc(sizeof(int) * vertexNum);
502 possible = (int*)malloc(sizeof(int) * TriangleNum);
503 vertex = (XYZ*)malloc(sizeof(XYZ) * vertexNum);
504 normals = (XYZ*)malloc(sizeof(XYZ) * vertexNum);
505 facenormals = (XYZ*)malloc(sizeof(XYZ) * TriangleNum);
506 Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle) * TriangleNum);
507 vArray = (GLfloat*)malloc(sizeof(GLfloat) * TriangleNum * 24);
509 for (i = 0; i < vertexNum; i++) {
510 funpackf(tfile, "Bf Bf Bf", &vertex[i].x, &vertex[i].y, &vertex[i].z);
513 for (i = 0; i < TriangleNum; i++) {
514 //funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
516 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
517 Triangles[i].vertex[ 0] = vertex[ 0];
518 Triangles[i].vertex[ 1] = vertex[ 2];
519 Triangles[i].vertex[ 2] = vertex[ 4];
520 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
521 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
524 modelTexture.xsz = 0;
530 for (i = 0; i < vertexNum; i++) {
535 boundingsphereradius = 0;
536 for (i = 0; i < vertexNum; i++) {
537 for (j = 0; j < vertexNum; j++) {
538 if (j != i && distsq(&vertex[j], &vertex[i]) / 2 > boundingsphereradius) {
539 boundingsphereradius = distsq(&vertex[j], &vertex[i]) / 2;
540 boundingspherecenter = (vertex[i] + vertex[j]) / 2;
544 boundingsphereradius = fast_sqrt(boundingsphereradius);
549 bool Model::loaddecal(const char *filename, bool texture )
556 // Changing the filename so that its more os specific
557 char * FixedFN = ConvertFileName(filename);
559 LOG(std::string("Loading decal...") + FixedFN);
565 tfile = fopen( FixedFN, "rb" );
566 // read model settings
569 fseek(tfile, 0, SEEK_SET);
570 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
572 // read the model data
578 owner = (int*)malloc(sizeof(int) * vertexNum);
579 possible = (int*)malloc(sizeof(int) * TriangleNum);
580 vertex = (XYZ*)malloc(sizeof(XYZ) * vertexNum);
581 normals = (XYZ*)malloc(sizeof(XYZ) * vertexNum);
582 facenormals = (XYZ*)malloc(sizeof(XYZ) * TriangleNum);
583 Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle) * TriangleNum);
584 vArray = (GLfloat*)malloc(sizeof(GLfloat) * TriangleNum * 24);
587 for (i = 0; i < vertexNum; i++) {
588 funpackf(tfile, "Bf Bf Bf", &vertex[i].x, &vertex[i].y, &vertex[i].z);
591 for (i = 0; i < TriangleNum; i++) {
592 //funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
594 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
595 Triangles[i].vertex[ 0] = vertex[ 0];
596 Triangles[i].vertex[ 1] = vertex[ 2];
597 Triangles[i].vertex[ 2] = vertex[ 4];
598 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
599 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
603 modelTexture.xsz = 0;
609 for (i = 0; i < vertexNum; i++) {
613 boundingsphereradius = 0;
614 for (i = 0; i < vertexNum; i++) {
615 for (j = 0; j < vertexNum; j++) {
616 if (j != i && distsq(&vertex[j], &vertex[i]) / 2 > boundingsphereradius) {
617 boundingsphereradius = distsq(&vertex[j], &vertex[i]) / 2;
618 boundingspherecenter = (vertex[i] + vertex[j]) / 2;
622 boundingsphereradius = fast_sqrt(boundingsphereradius);
625 if (!decaltexcoords) {
626 decaltexcoords = (float***)malloc(sizeof(float**)*max_model_decals);
627 for (i = 0; i < max_model_decals; i++) {
628 decaltexcoords[i] = (float**)malloc(sizeof(float*) * 3);
629 for (j = 0; j < 3; j++) {
630 decaltexcoords[i][j] = (float*)malloc(sizeof(float) * 2);
633 decalvertex = (XYZ**)malloc(sizeof(XYZ*)*max_model_decals);
634 for (i = 0; i < max_model_decals; i++) {
635 decalvertex[i] = (XYZ*)malloc(sizeof(XYZ) * 3);
638 decaltype = (int*)malloc(sizeof(int) * max_model_decals);
639 decalopacity = (float*)malloc(sizeof(float) * max_model_decals);
640 decalrotation = (float*)malloc(sizeof(float) * max_model_decals);
641 decalalivetime = (float*)malloc(sizeof(float) * max_model_decals);
642 decalposition = (XYZ*)malloc(sizeof(XYZ) * max_model_decals);
648 bool Model::loadraw(char *filename )
655 LOG(std::string("Loading raw...") + filename);
657 //~ int oldvertexNum, oldTriangleNum;
658 //~ oldvertexNum = vertexNum;
659 //~ oldTriangleNum = TriangleNum;
664 tfile = fopen( ConvertFileName(filename), "rb" );
665 // read model settings
668 fseek(tfile, 0, SEEK_SET);
669 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
671 // read the model data
676 owner = (int*)malloc(sizeof(int) * vertexNum);
677 possible = (int*)malloc(sizeof(int) * TriangleNum);
678 vertex = (XYZ*)malloc(sizeof(XYZ) * vertexNum);
679 Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle) * TriangleNum);
680 vArray = (GLfloat*)malloc(sizeof(GLfloat) * TriangleNum * 24);
683 for (i = 0; i < vertexNum; i++) {
684 funpackf(tfile, "Bf Bf Bf", &vertex[i].x, &vertex[i].y, &vertex[i].z);
687 for (i = 0; i < TriangleNum; i++) {
688 //funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
690 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
691 Triangles[i].vertex[ 0] = vertex[ 0];
692 Triangles[i].vertex[ 1] = vertex[ 2];
693 Triangles[i].vertex[ 2] = vertex[ 4];
694 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
695 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
701 for (i = 0; i < vertexNum; i++) {
709 void Model::UniformTexCoords()
712 for (i = 0; i < TriangleNum; i++) {
713 Triangles[i].gy[0] = vertex[Triangles[i].vertex[0]].y;
714 Triangles[i].gy[1] = vertex[Triangles[i].vertex[1]].y;
715 Triangles[i].gy[2] = vertex[Triangles[i].vertex[2]].y;
716 Triangles[i].gx[0] = vertex[Triangles[i].vertex[0]].x;
717 Triangles[i].gx[1] = vertex[Triangles[i].vertex[1]].x;
718 Triangles[i].gx[2] = vertex[Triangles[i].vertex[2]].x;
724 void Model::FlipTexCoords()
727 for (i = 0; i < TriangleNum; i++) {
728 Triangles[i].gy[0] = -Triangles[i].gy[0];
729 Triangles[i].gy[1] = -Triangles[i].gy[1];
730 Triangles[i].gy[2] = -Triangles[i].gy[2];
735 void Model::ScaleTexCoords(float howmuch)
738 for (i = 0; i < TriangleNum; i++) {
739 Triangles[i].gx[0] *= howmuch;
740 Triangles[i].gx[1] *= howmuch;
741 Triangles[i].gx[2] *= howmuch;
742 Triangles[i].gy[0] *= howmuch;
743 Triangles[i].gy[1] *= howmuch;
744 Triangles[i].gy[2] *= howmuch;
749 void Model::Scale(float xscale, float yscale, float zscale)
752 for (i = 0; i < vertexNum; i++) {
753 vertex[i].x *= xscale;
754 vertex[i].y *= yscale;
755 vertex[i].z *= zscale;
761 boundingsphereradius = 0;
762 for (i = 0; i < vertexNum; i++) {
763 for (j = 0; j < vertexNum; j++) {
764 if (j != i && distsq(&vertex[j], &vertex[i]) / 2 > boundingsphereradius) {
765 boundingsphereradius = distsq(&vertex[j], &vertex[i]) / 2;
766 boundingspherecenter = (vertex[i] + vertex[j]) / 2;
770 boundingsphereradius = fast_sqrt(boundingsphereradius);
773 void Model::ScaleNormals(float xscale, float yscale, float zscale)
775 if (type != normaltype && type != decalstype)
778 for (i = 0; i < vertexNum; i++) {
779 normals[i].x *= xscale;
780 normals[i].y *= yscale;
781 normals[i].z *= zscale;
783 for (i = 0; i < TriangleNum; i++) {
784 facenormals[i].x *= xscale;
785 facenormals[i].y *= yscale;
786 facenormals[i].z *= zscale;
791 void Model::Translate(float xtrans, float ytrans, float ztrans)
794 for (i = 0; i < vertexNum; i++) {
795 vertex[i].x += xtrans;
796 vertex[i].y += ytrans;
797 vertex[i].z += ztrans;
802 boundingsphereradius = 0;
803 for (i = 0; i < vertexNum; i++) {
804 for (j = 0; j < vertexNum; j++) {
805 if (j != i && distsq(&vertex[j], &vertex[i]) / 2 > boundingsphereradius) {
806 boundingsphereradius = distsq(&vertex[j], &vertex[i]) / 2;
807 boundingspherecenter = (vertex[i] + vertex[j]) / 2;
811 boundingsphereradius = fast_sqrt(boundingsphereradius);
814 void Model::Rotate(float xang, float yang, float zang)
817 for (i = 0; i < vertexNum; i++) {
818 vertex[i] = DoRotation(vertex[i], xang, yang, zang);
823 boundingsphereradius = 0;
824 for (i = 0; i < vertexNum; i++) {
825 for (j = 0; j < vertexNum; j++) {
826 if (j != i && distsq(&vertex[j], &vertex[i]) / 2 > boundingsphereradius) {
827 boundingsphereradius = distsq(&vertex[j], &vertex[i]) / 2;
828 boundingspherecenter = (vertex[i] + vertex[j]) / 2;
832 boundingsphereradius = fast_sqrt(boundingsphereradius);
836 void Model::CalculateNormals(bool facenormalise)
839 Game::LoadingScreen();
841 if (type != normaltype && type != decalstype)
844 for (i = 0; i < vertexNum; i++) {
850 for (i = 0; i < TriangleNum; i++) {
851 CrossProduct(vertex[Triangles[i].vertex[1]] - vertex[Triangles[i].vertex[0]], vertex[Triangles[i].vertex[2]] - vertex[Triangles[i].vertex[0]], &facenormals[i]);
853 normals[Triangles[i].vertex[0]].x += facenormals[i].x;
854 normals[Triangles[i].vertex[0]].y += facenormals[i].y;
855 normals[Triangles[i].vertex[0]].z += facenormals[i].z;
857 normals[Triangles[i].vertex[1]].x += facenormals[i].x;
858 normals[Triangles[i].vertex[1]].y += facenormals[i].y;
859 normals[Triangles[i].vertex[1]].z += facenormals[i].z;
861 normals[Triangles[i].vertex[2]].x += facenormals[i].x;
862 normals[Triangles[i].vertex[2]].y += facenormals[i].y;
863 normals[Triangles[i].vertex[2]].z += facenormals[i].z;
865 Normalise(&facenormals[i]);
867 for (i = 0; i < vertexNum; i++) {
868 Normalise(&normals[i]);
871 UpdateVertexArrayNoTex();
874 void Model::drawimmediate()
877 glBegin(GL_TRIANGLES);
878 for (int i = 0; i < TriangleNum; i++) {
879 glTexCoord2f(Triangles[i].gx[0], Triangles[i].gy[0]);
881 glColor3f(normals[Triangles[i].vertex[0]].x, normals[Triangles[i].vertex[0]].y, normals[Triangles[i].vertex[0]].z);
883 glNormal3f(normals[Triangles[i].vertex[0]].x, normals[Triangles[i].vertex[0]].y, normals[Triangles[i].vertex[0]].z);
885 glNormal3f(facenormals[i].x, facenormals[i].y, facenormals[i].y);
886 glVertex3f(vertex[Triangles[i].vertex[0]].x, vertex[Triangles[i].vertex[0]].y, vertex[Triangles[i].vertex[0]].z);
888 glTexCoord2f(Triangles[i].gx[1], Triangles[i].gy[1]);
890 glColor3f(normals[Triangles[i].vertex[1]].x, normals[Triangles[i].vertex[1]].y, normals[Triangles[i].vertex[1]].z);
892 glNormal3f(normals[Triangles[i].vertex[1]].x, normals[Triangles[i].vertex[1]].y, normals[Triangles[i].vertex[1]].z);
894 glNormal3f(facenormals[i].x, facenormals[i].y, facenormals[i].y);
895 glVertex3f(vertex[Triangles[i].vertex[1]].x, vertex[Triangles[i].vertex[1]].y, vertex[Triangles[i].vertex[1]].z);
897 glTexCoord2f(Triangles[i].gx[2], Triangles[i].gy[2]);
899 glColor3f(normals[Triangles[i].vertex[2]].x, normals[Triangles[i].vertex[2]].y, normals[Triangles[i].vertex[2]].z);
901 glNormal3f(normals[Triangles[i].vertex[2]].x, normals[Triangles[i].vertex[2]].y, normals[Triangles[i].vertex[2]].z);
903 glNormal3f(facenormals[i].x, facenormals[i].y, facenormals[i].y);
904 glVertex3f(vertex[Triangles[i].vertex[2]].x, vertex[Triangles[i].vertex[2]].y, vertex[Triangles[i].vertex[2]].z);
911 if (type != normaltype && type != decalstype)
914 glEnableClientState(GL_NORMAL_ARRAY);
915 glEnableClientState(GL_VERTEX_ARRAY);
916 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
919 glInterleavedArrays( GL_T2F_N3F_V3F, 8 * sizeof(GLfloat), &vArray[0]);
921 glInterleavedArrays( GL_T2F_C3F_V3F, 8 * sizeof(GLfloat), &vArray[0]);
924 glDrawArrays(GL_TRIANGLES, 0, TriangleNum * 3);
927 glDisableClientState(GL_NORMAL_ARRAY);
929 glDisableClientState(GL_COLOR_ARRAY);
930 glDisableClientState(GL_VERTEX_ARRAY);
931 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
934 //TODO: phase out in favor of Texture
935 void Model::drawdifftex(GLuint texture)
937 glEnableClientState(GL_NORMAL_ARRAY);
938 glEnableClientState(GL_VERTEX_ARRAY);
939 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
941 glInterleavedArrays( GL_T2F_N3F_V3F, 8 * sizeof(GLfloat), &vArray[0]);
943 glInterleavedArrays( GL_T2F_C3F_V3F, 8 * sizeof(GLfloat), &vArray[0]);
945 glBindTexture(GL_TEXTURE_2D, (unsigned long)texture);
946 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
947 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
951 glLockArraysEXT( 0, TriangleNum * 3);
953 glDrawArrays(GL_TRIANGLES, 0, TriangleNum * 3);
960 glDisableClientState(GL_NORMAL_ARRAY);
962 glDisableClientState(GL_COLOR_ARRAY);
963 glDisableClientState(GL_VERTEX_ARRAY);
964 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
967 void Model::drawdifftex(Texture texture)
969 glEnableClientState(GL_NORMAL_ARRAY);
970 glEnableClientState(GL_VERTEX_ARRAY);
971 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
973 glInterleavedArrays( GL_T2F_N3F_V3F, 8 * sizeof(GLfloat), &vArray[0]);
975 glInterleavedArrays( GL_T2F_C3F_V3F, 8 * sizeof(GLfloat), &vArray[0]);
978 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
979 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
983 glLockArraysEXT( 0, TriangleNum * 3);
985 glDrawArrays(GL_TRIANGLES, 0, TriangleNum * 3);
992 glDisableClientState(GL_NORMAL_ARRAY);
994 glDisableClientState(GL_COLOR_ARRAY);
995 glDisableClientState(GL_VERTEX_ARRAY);
996 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
999 void Model::drawdecals(Texture shadowtexture, Texture bloodtexture, Texture bloodtexture2, Texture breaktexture)
1002 if (type != decalstype)
1005 static int lasttype;
1012 glDisable(GL_LIGHTING);
1013 glDisable(GL_CULL_FACE);
1014 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1016 if (numdecals > max_model_decals)
1017 numdecals = max_model_decals;
1018 for (i = 0; i < numdecals; i++) {
1019 if (decaltype[i] == blooddecalfast && decalalivetime[i] < 2)
1020 decalalivetime[i] = 2;
1022 if (decaltype[i] == shadowdecal && decaltype[i] != lasttype) {
1023 shadowtexture.bind();
1026 glAlphaFunc(GL_GREATER, 0.0001);
1027 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1030 if (decaltype[i] == breakdecal && decaltype[i] != lasttype) {
1031 breaktexture.bind();
1034 glAlphaFunc(GL_GREATER, 0.0001);
1035 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1038 if ((decaltype[i] == blooddecal || decaltype[i] == blooddecalslow) && decaltype[i] != lasttype) {
1039 bloodtexture.bind();
1042 glAlphaFunc(GL_GREATER, 0.15);
1043 glBlendFunc(GL_ONE, GL_ZERO);
1046 if ((decaltype[i] == blooddecalfast) && decaltype[i] != lasttype) {
1047 bloodtexture2.bind();
1050 glAlphaFunc(GL_GREATER, 0.15);
1051 glBlendFunc(GL_ONE, GL_ZERO);
1054 if (decaltype[i] == shadowdecal) {
1055 glColor4f(1, 1, 1, decalopacity[i]);
1057 if (decaltype[i] == breakdecal) {
1058 glColor4f(1, 1, 1, decalopacity[i]);
1059 if (decalalivetime[i] > 58)
1060 glColor4f(1, 1, 1, decalopacity[i] * (60 - decalalivetime[i]) / 2);
1062 if ((decaltype[i] == blooddecal || decaltype[i] == blooddecalfast || decaltype[i] == blooddecalslow)) {
1063 glColor4f(1, 1, 1, decalopacity[i]);
1064 if (decalalivetime[i] < 4)
1065 glColor4f(1, 1, 1, decalopacity[i]*decalalivetime[i]*.25);
1066 if (decalalivetime[i] > 58)
1067 glColor4f(1, 1, 1, decalopacity[i] * (60 - decalalivetime[i]) / 2);
1069 lasttype = decaltype[i];
1070 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1071 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
1073 glMatrixMode(GL_MODELVIEW);
1075 glBegin(GL_TRIANGLES);
1076 for (int j = 0; j < 3; j++) {
1077 glTexCoord2f(decaltexcoords[i][j][0], decaltexcoords[i][j][1]);
1078 glVertex3f(decalvertex[i][j].x, decalvertex[i][j].y, decalvertex[i][j].z);
1083 for (i = numdecals - 1; i >= 0; i--) {
1084 decalalivetime[i] += multiplier;
1085 if (decaltype[i] == blooddecalslow)
1086 decalalivetime[i] -= multiplier * 2 / 3;
1087 if (decaltype[i] == blooddecalfast)
1088 decalalivetime[i] += multiplier * 4;
1089 if (decaltype[i] == shadowdecal)
1091 if ((decaltype[i] == blooddecal || decaltype[i] == blooddecalfast || decaltype[i] == blooddecalslow) && decalalivetime[i] >= 60)
1094 glAlphaFunc(GL_GREATER, 0.0001);
1095 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1099 void Model::DeleteDecal(int which)
1102 if (type != decalstype)
1104 decaltype[which] = decaltype[numdecals - 1];
1105 decalposition[which] = decalposition[numdecals - 1];
1106 for (int i = 0; i < 3; i++) {
1107 decalvertex[which][i] = decalvertex[numdecals - 1][i];
1108 decaltexcoords[which][i][0] = decaltexcoords[numdecals - 1][i][0];
1109 decaltexcoords[which][i][1] = decaltexcoords[numdecals - 1][i][1];
1111 decalrotation[which] = decalrotation[numdecals - 1];
1112 decalalivetime[which] = decalalivetime[numdecals - 1];
1113 decalopacity[which] = decalopacity[numdecals - 1];
1118 void Model::MakeDecal(int atype, XYZ *where, float *size, float *opacity, float *rotation)
1121 if (type != decalstype)
1124 static float placex, placez;
1126 static float distance;
1130 if (distsq(where, &boundingspherecenter) < (boundingsphereradius + *size) * (boundingsphereradius + *size))
1131 for (i = 0; i < TriangleNum; i++) {
1132 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)) {
1133 decalposition[numdecals] = *where;
1134 decaltype[numdecals] = atype;
1135 decalrotation[numdecals] = *rotation;
1136 decalalivetime[numdecals] = 0;
1137 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);
1138 decalopacity[numdecals] = *opacity - distance / 10;
1140 if (decalopacity[numdecals > 0]) {
1141 placex = vertex[Triangles[i].vertex[0]].x;
1142 placez = vertex[Triangles[i].vertex[0]].z;
1144 decaltexcoords[numdecals][0][0] = (placex - where->x) / (*size) / 2 + .5;
1145 decaltexcoords[numdecals][0][1] = (placez - where->z) / (*size) / 2 + .5;
1147 decalvertex[numdecals][0].x = placex;
1148 decalvertex[numdecals][0].z = placez;
1149 decalvertex[numdecals][0].y = vertex[Triangles[i].vertex[0]].y;
1152 placex = vertex[Triangles[i].vertex[1]].x;
1153 placez = vertex[Triangles[i].vertex[1]].z;
1155 decaltexcoords[numdecals][1][0] = (placex - where->x) / (*size) / 2 + .5;
1156 decaltexcoords[numdecals][1][1] = (placez - where->z) / (*size) / 2 + .5;
1158 decalvertex[numdecals][1].x = placex;
1159 decalvertex[numdecals][1].z = placez;
1160 decalvertex[numdecals][1].y = vertex[Triangles[i].vertex[1]].y;
1163 placex = vertex[Triangles[i].vertex[2]].x;
1164 placez = vertex[Triangles[i].vertex[2]].z;
1166 decaltexcoords[numdecals][2][0] = (placex - where->x) / (*size) / 2 + .5;
1167 decaltexcoords[numdecals][2][1] = (placez - where->z) / (*size) / 2 + .5;
1169 decalvertex[numdecals][2].x = placex;
1170 decalvertex[numdecals][2].z = placez;
1171 decalvertex[numdecals][2].y = vertex[Triangles[i].vertex[2]].y;
1173 if (!(decaltexcoords[numdecals][0][0] < 0 && decaltexcoords[numdecals][1][0] < 0 && decaltexcoords[numdecals][2][0] < 0))
1174 if (!(decaltexcoords[numdecals][0][1] < 0 && decaltexcoords[numdecals][1][1] < 0 && decaltexcoords[numdecals][2][1] < 0))
1175 if (!(decaltexcoords[numdecals][0][0] > 1 && decaltexcoords[numdecals][1][0] > 1 && decaltexcoords[numdecals][2][0] > 1))
1176 if (!(decaltexcoords[numdecals][0][1] > 1 && decaltexcoords[numdecals][1][1] > 1 && decaltexcoords[numdecals][2][1] > 1)) {
1177 if (decalrotation[numdecals]) {
1178 for (j = 0; j < 3; j++) {
1180 rot.x = decaltexcoords[numdecals][j][0] - .5;
1181 rot.z = decaltexcoords[numdecals][j][1] - .5;
1182 rot = DoRotation(rot, 0, -decalrotation[numdecals], 0);
1183 decaltexcoords[numdecals][j][0] = rot.x + .5;
1184 decaltexcoords[numdecals][j][1] = rot.z + .5;
1187 if (numdecals < max_model_decals - 1)
1196 void Model::MakeDecal(int atype, XYZ where, float size, float opacity, float rotation)
1199 if (type != decalstype)
1202 static float placex, placez;
1204 static float distance;
1208 if (distsq(&where, &boundingspherecenter) < (boundingsphereradius + size) * (boundingsphereradius + size))
1209 for (i = 0; i < TriangleNum; i++) {
1210 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))));
1211 if (distance < .02 && abs(facenormals[i].y) > abs(facenormals[i].x) && abs(facenormals[i].y) > abs(facenormals[i].z)) {
1212 decalposition[numdecals] = where;
1213 decaltype[numdecals] = atype;
1214 decalrotation[numdecals] = rotation;
1215 decalalivetime[numdecals] = 0;
1216 decalopacity[numdecals] = opacity - distance / 10;
1218 if (decalopacity[numdecals > 0]) {
1219 placex = vertex[Triangles[i].vertex[0]].x;
1220 placez = vertex[Triangles[i].vertex[0]].z;
1222 decaltexcoords[numdecals][0][0] = (placex - where.x) / (size) / 2 + .5;
1223 decaltexcoords[numdecals][0][1] = (placez - where.z) / (size) / 2 + .5;
1225 decalvertex[numdecals][0].x = placex;
1226 decalvertex[numdecals][0].z = placez;
1227 decalvertex[numdecals][0].y = vertex[Triangles[i].vertex[0]].y;
1230 placex = vertex[Triangles[i].vertex[1]].x;
1231 placez = vertex[Triangles[i].vertex[1]].z;
1233 decaltexcoords[numdecals][1][0] = (placex - where.x) / (size) / 2 + .5;
1234 decaltexcoords[numdecals][1][1] = (placez - where.z) / (size) / 2 + .5;
1236 decalvertex[numdecals][1].x = placex;
1237 decalvertex[numdecals][1].z = placez;
1238 decalvertex[numdecals][1].y = vertex[Triangles[i].vertex[1]].y;
1241 placex = vertex[Triangles[i].vertex[2]].x;
1242 placez = vertex[Triangles[i].vertex[2]].z;
1244 decaltexcoords[numdecals][2][0] = (placex - where.x) / (size) / 2 + .5;
1245 decaltexcoords[numdecals][2][1] = (placez - where.z) / (size) / 2 + .5;
1247 decalvertex[numdecals][2].x = placex;
1248 decalvertex[numdecals][2].z = placez;
1249 decalvertex[numdecals][2].y = vertex[Triangles[i].vertex[2]].y;
1251 if (!(decaltexcoords[numdecals][0][0] < 0 && decaltexcoords[numdecals][1][0] < 0 && decaltexcoords[numdecals][2][0] < 0))
1252 if (!(decaltexcoords[numdecals][0][1] < 0 && decaltexcoords[numdecals][1][1] < 0 && decaltexcoords[numdecals][2][1] < 0))
1253 if (!(decaltexcoords[numdecals][0][0] > 1 && decaltexcoords[numdecals][1][0] > 1 && decaltexcoords[numdecals][2][0] > 1))
1254 if (!(decaltexcoords[numdecals][0][1] > 1 && decaltexcoords[numdecals][1][1] > 1 && decaltexcoords[numdecals][2][1] > 1)) {
1255 if (decalrotation[numdecals]) {
1256 for (j = 0; j < 3; j++) {
1258 rot.x = decaltexcoords[numdecals][j][0] - .5;
1259 rot.z = decaltexcoords[numdecals][j][1] - .5;
1260 rot = DoRotation(rot, 0, -decalrotation[numdecals], 0);
1261 decaltexcoords[numdecals][j][0] = rot.x + .5;
1262 decaltexcoords[numdecals][j][1] = rot.z + .5;
1265 if (numdecals < max_model_decals - 1)
1269 } else if (distance < .02 && abs(facenormals[i].x) > abs(facenormals[i].y) && abs(facenormals[i].x) > abs(facenormals[i].z)) {
1270 decalposition[numdecals] = where;
1271 decaltype[numdecals] = atype;
1272 decalrotation[numdecals] = rotation;
1273 decalalivetime[numdecals] = 0;
1274 decalopacity[numdecals] = opacity - distance / 10;
1276 if (decalopacity[numdecals > 0]) {
1277 placex = vertex[Triangles[i].vertex[0]].y;
1278 placez = vertex[Triangles[i].vertex[0]].z;
1280 decaltexcoords[numdecals][0][0] = (placex - where.y) / (size) / 2 + .5;
1281 decaltexcoords[numdecals][0][1] = (placez - where.z) / (size) / 2 + .5;
1283 decalvertex[numdecals][0].x = vertex[Triangles[i].vertex[0]].x;
1284 decalvertex[numdecals][0].z = placez;
1285 decalvertex[numdecals][0].y = placex;
1288 placex = vertex[Triangles[i].vertex[1]].y;
1289 placez = vertex[Triangles[i].vertex[1]].z;
1291 decaltexcoords[numdecals][1][0] = (placex - where.y) / (size) / 2 + .5;
1292 decaltexcoords[numdecals][1][1] = (placez - where.z) / (size) / 2 + .5;
1294 decalvertex[numdecals][1].x = vertex[Triangles[i].vertex[1]].x;
1295 decalvertex[numdecals][1].z = placez;
1296 decalvertex[numdecals][1].y = placex;
1299 placex = vertex[Triangles[i].vertex[2]].y;
1300 placez = vertex[Triangles[i].vertex[2]].z;
1302 decaltexcoords[numdecals][2][0] = (placex - where.y) / (size) / 2 + .5;
1303 decaltexcoords[numdecals][2][1] = (placez - where.z) / (size) / 2 + .5;
1305 decalvertex[numdecals][2].x = vertex[Triangles[i].vertex[2]].x;
1306 decalvertex[numdecals][2].z = placez;
1307 decalvertex[numdecals][2].y = placex;
1309 if (!(decaltexcoords[numdecals][0][0] < 0 && decaltexcoords[numdecals][1][0] < 0 && decaltexcoords[numdecals][2][0] < 0))
1310 if (!(decaltexcoords[numdecals][0][1] < 0 && decaltexcoords[numdecals][1][1] < 0 && decaltexcoords[numdecals][2][1] < 0))
1311 if (!(decaltexcoords[numdecals][0][0] > 1 && decaltexcoords[numdecals][1][0] > 1 && decaltexcoords[numdecals][2][0] > 1))
1312 if (!(decaltexcoords[numdecals][0][1] > 1 && decaltexcoords[numdecals][1][1] > 1 && decaltexcoords[numdecals][2][1] > 1)) {
1313 if (decalrotation[numdecals]) {
1314 for (j = 0; j < 3; j++) {
1316 rot.x = decaltexcoords[numdecals][j][0] - .5;
1317 rot.z = decaltexcoords[numdecals][j][1] - .5;
1318 rot = DoRotation(rot, 0, -decalrotation[numdecals], 0);
1319 decaltexcoords[numdecals][j][0] = rot.x + .5;
1320 decaltexcoords[numdecals][j][1] = rot.z + .5;
1323 if (numdecals < max_model_decals - 1)
1327 } else if (distance < .02 && abs(facenormals[i].z) > abs(facenormals[i].y) && abs(facenormals[i].z) > abs(facenormals[i].x)) {
1328 decalposition[numdecals] = where;
1329 decaltype[numdecals] = atype;
1330 decalrotation[numdecals] = rotation;
1331 decalalivetime[numdecals] = 0;
1332 decalopacity[numdecals] = opacity - distance / 10;
1334 if (decalopacity[numdecals > 0]) {
1335 placex = vertex[Triangles[i].vertex[0]].x;
1336 placez = vertex[Triangles[i].vertex[0]].y;
1338 decaltexcoords[numdecals][0][0] = (placex - where.x) / (size) / 2 + .5;
1339 decaltexcoords[numdecals][0][1] = (placez - where.y) / (size) / 2 + .5;
1341 decalvertex[numdecals][0].x = placex;
1342 decalvertex[numdecals][0].z = vertex[Triangles[i].vertex[0]].z;
1343 decalvertex[numdecals][0].y = placez;
1346 placex = vertex[Triangles[i].vertex[1]].x;
1347 placez = vertex[Triangles[i].vertex[1]].y;
1349 decaltexcoords[numdecals][1][0] = (placex - where.x) / (size) / 2 + .5;
1350 decaltexcoords[numdecals][1][1] = (placez - where.y) / (size) / 2 + .5;
1352 decalvertex[numdecals][1].x = placex;
1353 decalvertex[numdecals][1].z = vertex[Triangles[i].vertex[1]].z;
1354 decalvertex[numdecals][1].y = placez;
1357 placex = vertex[Triangles[i].vertex[2]].x;
1358 placez = vertex[Triangles[i].vertex[2]].y;
1360 decaltexcoords[numdecals][2][0] = (placex - where.x) / (size) / 2 + .5;
1361 decaltexcoords[numdecals][2][1] = (placez - where.y) / (size) / 2 + .5;
1363 decalvertex[numdecals][2].x = placex;
1364 decalvertex[numdecals][2].z = vertex[Triangles[i].vertex[2]].z;
1365 decalvertex[numdecals][2].y = placez;
1367 if (!(decaltexcoords[numdecals][0][0] < 0 && decaltexcoords[numdecals][1][0] < 0 && decaltexcoords[numdecals][2][0] < 0))
1368 if (!(decaltexcoords[numdecals][0][1] < 0 && decaltexcoords[numdecals][1][1] < 0 && decaltexcoords[numdecals][2][1] < 0))
1369 if (!(decaltexcoords[numdecals][0][0] > 1 && decaltexcoords[numdecals][1][0] > 1 && decaltexcoords[numdecals][2][0] > 1))
1370 if (!(decaltexcoords[numdecals][0][1] > 1 && decaltexcoords[numdecals][1][1] > 1 && decaltexcoords[numdecals][2][1] > 1)) {
1371 if (decalrotation[numdecals]) {
1372 for (j = 0; j < 3; j++) {
1374 rot.x = decaltexcoords[numdecals][j][0] - .5;
1375 rot.z = decaltexcoords[numdecals][j][1] - .5;
1376 rot = DoRotation(rot, 0, -decalrotation[numdecals], 0);
1377 decaltexcoords[numdecals][j][0] = rot.x + .5;
1378 decaltexcoords[numdecals][j][1] = rot.z + .5;
1381 if (numdecals < max_model_decals - 1)
1393 textureptr.destroy();
1396 void Model::deallocate()
1430 if (decaltexcoords) {
1431 for (i = 0; i < max_model_decals; i++) {
1432 for (j = 0; j < 3; j++) {
1433 free(decaltexcoords[i][j]);
1435 free(decaltexcoords[i]);
1437 free(decaltexcoords);
1443 for (i = 0; i < max_model_decals; i++) {
1444 free(decalvertex[i]);
1457 free(decalrotation);
1460 free(decalalivetime);
1463 free(decalposition);
1470 vertexNum = 0, TriangleNum = 0;
1473 type = 0, oldtype = 0;
1483 memset(&modelTexture, 0, sizeof(modelTexture));
1487 boundingspherecenter = 0;
1488 boundingsphereradius = 0;