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;
157 static XYZ start, end;
159 firstintersecting = -1;
164 *p1 = DoRotation(*p1, 0, -*rotate, 0);
165 if (distsq(p1, &boundingspherecenter) > radius * radius + boundingsphereradius * boundingsphereradius)
168 for (i = 0; i < 4; i++) {
169 for (j = 0; j < TriangleNum; j++) {
171 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)));
172 if (distance < radius) {
173 point = *p1 - facenormals[j] * distance;
174 if (PointInTriangle( &point, facenormals[j], &vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[1]], &vertex[Triangles[j].vertex[2]]))
177 intersecting = sphere_line_intersection(&vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[1]], p1, &radius);
179 intersecting = sphere_line_intersection(&vertex[Triangles[j].vertex[1]], &vertex[Triangles[j].vertex[2]], p1, &radius);
181 intersecting = sphere_line_intersection(&vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[2]], p1, &radius);
183 *p1 += facenormals[j] * (distance - radius);
186 if ((distance < olddistance || firstintersecting == -1) && intersecting) {
187 olddistance = distance;
188 firstintersecting = j;
194 *p = DoRotation(*p, 0, *rotate, 0);
197 *p1 = DoRotation(*p1, 0, *rotate, 0);
199 return firstintersecting;
202 int Model::SphereCheckPossible(XYZ *p1, float radius, XYZ *move, float *rotate)
205 static float distance;
206 static float olddistance;
207 static int intersecting;
208 static int firstintersecting;
211 static XYZ start, end;
213 firstintersecting = -1;
221 *p1 = DoRotation(*p1, 0, -*rotate, 0);
222 if (distsq(p1, &boundingspherecenter) > radius * radius + boundingsphereradius * boundingsphereradius) {
227 for (j = 0; j < TriangleNum; j++) {
229 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)));
230 if (distance < radius) {
231 point = *p1 - facenormals[j] * distance;
232 if (PointInTriangle( &point, facenormals[j], &vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[1]], &vertex[Triangles[j].vertex[2]]))
235 intersecting = sphere_line_intersection(&vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[1]], p1, &radius);
237 intersecting = sphere_line_intersection(&vertex[Triangles[j].vertex[1]], &vertex[Triangles[j].vertex[2]], p1, &radius);
239 intersecting = sphere_line_intersection(&vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[2]], p1, &radius);
241 possible[numpossible] = j;
245 if ((distance < olddistance || firstintersecting == -1) && intersecting) {
246 olddistance = distance;
247 firstintersecting = j;
251 *p1 = DoRotation(*p1, 0, *rotate, 0);
253 return firstintersecting;
257 void Model::UpdateVertexArray()
259 if (type != normaltype && type != decalstype)
264 for (i = 0; i < TriangleNum; i++) {
266 vArray[j + 0] = Triangles[i].gx[0];
267 vArray[j + 1] = Triangles[i].gy[0];
268 vArray[j + 2] = normals[Triangles[i].vertex[0]].x;
269 vArray[j + 3] = normals[Triangles[i].vertex[0]].y;
270 vArray[j + 4] = normals[Triangles[i].vertex[0]].z;
271 vArray[j + 5] = vertex[Triangles[i].vertex[0]].x;
272 vArray[j + 6] = vertex[Triangles[i].vertex[0]].y;
273 vArray[j + 7] = vertex[Triangles[i].vertex[0]].z;
275 vArray[j + 8] = Triangles[i].gx[1];
276 vArray[j + 9] = Triangles[i].gy[1];
277 vArray[j + 10] = normals[Triangles[i].vertex[1]].x;
278 vArray[j + 11] = normals[Triangles[i].vertex[1]].y;
279 vArray[j + 12] = normals[Triangles[i].vertex[1]].z;
280 vArray[j + 13] = vertex[Triangles[i].vertex[1]].x;
281 vArray[j + 14] = vertex[Triangles[i].vertex[1]].y;
282 vArray[j + 15] = vertex[Triangles[i].vertex[1]].z;
284 vArray[j + 16] = Triangles[i].gx[2];
285 vArray[j + 17] = Triangles[i].gy[2];
286 vArray[j + 18] = normals[Triangles[i].vertex[2]].x;
287 vArray[j + 19] = normals[Triangles[i].vertex[2]].y;
288 vArray[j + 20] = normals[Triangles[i].vertex[2]].z;
289 vArray[j + 21] = vertex[Triangles[i].vertex[2]].x;
290 vArray[j + 22] = vertex[Triangles[i].vertex[2]].y;
291 vArray[j + 23] = vertex[Triangles[i].vertex[2]].z;
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] = facenormals[i].x * -1;
299 vArray[j + 3] = facenormals[i].y * -1;
300 vArray[j + 4] = facenormals[i].z * -1;
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] = facenormals[i].x * -1;
308 vArray[j + 11] = facenormals[i].y * -1;
309 vArray[j + 12] = facenormals[i].z * -1;
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] = facenormals[i].x * -1;
317 vArray[j + 19] = facenormals[i].y * -1;
318 vArray[j + 20] = facenormals[i].z * -1;
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;
326 void Model::UpdateVertexArrayNoTex()
328 if (type != normaltype && type != decalstype)
333 for (i = 0; i < TriangleNum; i++) {
335 vArray[j + 2] = normals[Triangles[i].vertex[0]].x;
336 vArray[j + 3] = normals[Triangles[i].vertex[0]].y;
337 vArray[j + 4] = normals[Triangles[i].vertex[0]].z;
338 vArray[j + 5] = vertex[Triangles[i].vertex[0]].x;
339 vArray[j + 6] = vertex[Triangles[i].vertex[0]].y;
340 vArray[j + 7] = vertex[Triangles[i].vertex[0]].z;
342 vArray[j + 10] = normals[Triangles[i].vertex[1]].x;
343 vArray[j + 11] = normals[Triangles[i].vertex[1]].y;
344 vArray[j + 12] = normals[Triangles[i].vertex[1]].z;
345 vArray[j + 13] = vertex[Triangles[i].vertex[1]].x;
346 vArray[j + 14] = vertex[Triangles[i].vertex[1]].y;
347 vArray[j + 15] = vertex[Triangles[i].vertex[1]].z;
349 vArray[j + 18] = normals[Triangles[i].vertex[2]].x;
350 vArray[j + 19] = normals[Triangles[i].vertex[2]].y;
351 vArray[j + 20] = normals[Triangles[i].vertex[2]].z;
352 vArray[j + 21] = vertex[Triangles[i].vertex[2]].x;
353 vArray[j + 22] = vertex[Triangles[i].vertex[2]].y;
354 vArray[j + 23] = vertex[Triangles[i].vertex[2]].z;
357 for (i = 0; i < TriangleNum; i++) {
359 vArray[j + 2] = facenormals[i].x * -1;
360 vArray[j + 3] = facenormals[i].y * -1;
361 vArray[j + 4] = facenormals[i].z * -1;
362 vArray[j + 5] = vertex[Triangles[i].vertex[0]].x;
363 vArray[j + 6] = vertex[Triangles[i].vertex[0]].y;
364 vArray[j + 7] = vertex[Triangles[i].vertex[0]].z;
366 vArray[j + 10] = facenormals[i].x * -1;
367 vArray[j + 11] = facenormals[i].y * -1;
368 vArray[j + 12] = facenormals[i].z * -1;
369 vArray[j + 13] = vertex[Triangles[i].vertex[1]].x;
370 vArray[j + 14] = vertex[Triangles[i].vertex[1]].y;
371 vArray[j + 15] = vertex[Triangles[i].vertex[1]].z;
373 vArray[j + 18] = facenormals[i].x * -1;
374 vArray[j + 19] = facenormals[i].y * -1;
375 vArray[j + 20] = facenormals[i].z * -1;
376 vArray[j + 21] = vertex[Triangles[i].vertex[2]].x;
377 vArray[j + 22] = vertex[Triangles[i].vertex[2]].y;
378 vArray[j + 23] = vertex[Triangles[i].vertex[2]].z;
382 void Model::UpdateVertexArrayNoTexNoNorm()
384 if (type != normaltype && type != decalstype)
388 for (i = 0; i < TriangleNum; i++) {
390 vArray[j + 5] = vertex[Triangles[i].vertex[0]].x;
391 vArray[j + 6] = vertex[Triangles[i].vertex[0]].y;
392 vArray[j + 7] = vertex[Triangles[i].vertex[0]].z;
394 vArray[j + 13] = vertex[Triangles[i].vertex[1]].x;
395 vArray[j + 14] = vertex[Triangles[i].vertex[1]].y;
396 vArray[j + 15] = vertex[Triangles[i].vertex[1]].z;
398 vArray[j + 21] = vertex[Triangles[i].vertex[2]].x;
399 vArray[j + 22] = vertex[Triangles[i].vertex[2]].y;
400 vArray[j + 23] = vertex[Triangles[i].vertex[2]].z;
404 bool Model::loadnotex(const char *filename )
409 //~ int oldvertexNum, oldTriangleNum;
410 //~ oldvertexNum = vertexNum;
411 //~ oldTriangleNum = TriangleNum;
416 tfile = fopen( ConvertFileName(filename), "rb" );
417 // read model settings
419 fseek(tfile, 0, SEEK_SET);
420 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
422 // read the model data
427 owner = (int*)malloc(sizeof(int) * vertexNum);
428 possible = (int*)malloc(sizeof(int) * TriangleNum);
429 vertex = (XYZ*)malloc(sizeof(XYZ) * vertexNum);
430 Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle) * TriangleNum);
431 vArray = (GLfloat*)malloc(sizeof(GLfloat) * TriangleNum * 24);
433 for (i = 0; i < vertexNum; i++) {
434 funpackf(tfile, "Bf Bf Bf", &vertex[i].x, &vertex[i].y, &vertex[i].z);
437 for (i = 0; i < TriangleNum; i++) {
438 //funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
440 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
441 Triangles[i].vertex[ 0] = vertex[ 0];
442 Triangles[i].vertex[ 1] = vertex[ 2];
443 Triangles[i].vertex[ 2] = vertex[ 4];
444 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
445 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
452 for (i = 0; i < vertexNum; i++) {
457 boundingsphereradius = 0;
458 for (i = 0; i < vertexNum; i++) {
459 for (j = 0; j < vertexNum; j++) {
460 if (j != i && distsq(&vertex[j], &vertex[i]) / 2 > boundingsphereradius) {
461 boundingsphereradius = distsq(&vertex[j], &vertex[i]) / 2;
462 boundingspherecenter = (vertex[i] + vertex[j]) / 2;
466 boundingsphereradius = fast_sqrt(boundingsphereradius);
472 bool Model::load(const char *filename, bool texture )
479 LOG(std::string("Loading model...") + filename);
482 Game::LoadingScreen();
484 //~ int oldvertexNum, oldTriangleNum;
485 //~ oldvertexNum = vertexNum;
486 //~ oldTriangleNum = TriangleNum;
491 tfile = fopen( ConvertFileName(filename), "rb" );
492 // read model settings
495 fseek(tfile, 0, SEEK_SET);
496 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
498 // read the model data
503 owner = (int*)malloc(sizeof(int) * vertexNum);
504 possible = (int*)malloc(sizeof(int) * TriangleNum);
505 vertex = (XYZ*)malloc(sizeof(XYZ) * vertexNum);
506 normals = (XYZ*)malloc(sizeof(XYZ) * vertexNum);
507 facenormals = (XYZ*)malloc(sizeof(XYZ) * TriangleNum);
508 Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle) * TriangleNum);
509 vArray = (GLfloat*)malloc(sizeof(GLfloat) * TriangleNum * 24);
511 for (i = 0; i < vertexNum; i++) {
512 funpackf(tfile, "Bf Bf Bf", &vertex[i].x, &vertex[i].y, &vertex[i].z);
515 for (i = 0; i < TriangleNum; i++) {
516 //funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
518 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
519 Triangles[i].vertex[ 0] = vertex[ 0];
520 Triangles[i].vertex[ 1] = vertex[ 2];
521 Triangles[i].vertex[ 2] = vertex[ 4];
522 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
523 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
526 modelTexture.xsz = 0;
532 for (i = 0; i < vertexNum; i++) {
537 boundingsphereradius = 0;
538 for (i = 0; i < vertexNum; i++) {
539 for (j = 0; j < vertexNum; j++) {
540 if (j != i && distsq(&vertex[j], &vertex[i]) / 2 > boundingsphereradius) {
541 boundingsphereradius = distsq(&vertex[j], &vertex[i]) / 2;
542 boundingspherecenter = (vertex[i] + vertex[j]) / 2;
546 boundingsphereradius = fast_sqrt(boundingsphereradius);
551 bool Model::loaddecal(const char *filename, bool texture )
558 // Changing the filename so that its more os specific
559 char * FixedFN = ConvertFileName(filename);
561 LOG(std::string("Loading decal...") + FixedFN);
567 tfile = fopen( FixedFN, "rb" );
568 // read model settings
571 fseek(tfile, 0, SEEK_SET);
572 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
574 // read the model data
580 owner = (int*)malloc(sizeof(int) * vertexNum);
581 possible = (int*)malloc(sizeof(int) * TriangleNum);
582 vertex = (XYZ*)malloc(sizeof(XYZ) * vertexNum);
583 normals = (XYZ*)malloc(sizeof(XYZ) * vertexNum);
584 facenormals = (XYZ*)malloc(sizeof(XYZ) * TriangleNum);
585 Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle) * TriangleNum);
586 vArray = (GLfloat*)malloc(sizeof(GLfloat) * TriangleNum * 24);
589 for (i = 0; i < vertexNum; i++) {
590 funpackf(tfile, "Bf Bf Bf", &vertex[i].x, &vertex[i].y, &vertex[i].z);
593 for (i = 0; i < TriangleNum; i++) {
594 //funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
596 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
597 Triangles[i].vertex[ 0] = vertex[ 0];
598 Triangles[i].vertex[ 1] = vertex[ 2];
599 Triangles[i].vertex[ 2] = vertex[ 4];
600 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
601 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
605 modelTexture.xsz = 0;
611 for (i = 0; i < vertexNum; i++) {
615 boundingsphereradius = 0;
616 for (i = 0; i < vertexNum; i++) {
617 for (j = 0; j < vertexNum; j++) {
618 if (j != i && distsq(&vertex[j], &vertex[i]) / 2 > boundingsphereradius) {
619 boundingsphereradius = distsq(&vertex[j], &vertex[i]) / 2;
620 boundingspherecenter = (vertex[i] + vertex[j]) / 2;
624 boundingsphereradius = fast_sqrt(boundingsphereradius);
627 if (!decaltexcoords) {
628 decaltexcoords = (float***)malloc(sizeof(float**)*max_model_decals);
629 for (i = 0; i < max_model_decals; i++) {
630 decaltexcoords[i] = (float**)malloc(sizeof(float*) * 3);
631 for (j = 0; j < 3; j++) {
632 decaltexcoords[i][j] = (float*)malloc(sizeof(float) * 2);
635 decalvertex = (XYZ**)malloc(sizeof(XYZ*)*max_model_decals);
636 for (i = 0; i < max_model_decals; i++) {
637 decalvertex[i] = (XYZ*)malloc(sizeof(XYZ) * 3);
640 decaltype = (int*)malloc(sizeof(int) * max_model_decals);
641 decalopacity = (float*)malloc(sizeof(float) * max_model_decals);
642 decalrotation = (float*)malloc(sizeof(float) * max_model_decals);
643 decalalivetime = (float*)malloc(sizeof(float) * max_model_decals);
644 decalposition = (XYZ*)malloc(sizeof(XYZ) * max_model_decals);
650 bool Model::loadraw(char *filename )
657 LOG(std::string("Loading raw...") + filename);
659 //~ int oldvertexNum, oldTriangleNum;
660 //~ oldvertexNum = vertexNum;
661 //~ oldTriangleNum = TriangleNum;
666 tfile = fopen( ConvertFileName(filename), "rb" );
667 // read model settings
670 fseek(tfile, 0, SEEK_SET);
671 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
673 // read the model data
678 owner = (int*)malloc(sizeof(int) * vertexNum);
679 possible = (int*)malloc(sizeof(int) * TriangleNum);
680 vertex = (XYZ*)malloc(sizeof(XYZ) * vertexNum);
681 Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle) * TriangleNum);
682 vArray = (GLfloat*)malloc(sizeof(GLfloat) * TriangleNum * 24);
685 for (i = 0; i < vertexNum; i++) {
686 funpackf(tfile, "Bf Bf Bf", &vertex[i].x, &vertex[i].y, &vertex[i].z);
689 for (i = 0; i < TriangleNum; i++) {
690 //funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
692 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
693 Triangles[i].vertex[ 0] = vertex[ 0];
694 Triangles[i].vertex[ 1] = vertex[ 2];
695 Triangles[i].vertex[ 2] = vertex[ 4];
696 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
697 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
703 for (i = 0; i < vertexNum; i++) {
711 void Model::UniformTexCoords()
714 for (i = 0; i < TriangleNum; i++) {
715 Triangles[i].gy[0] = vertex[Triangles[i].vertex[0]].y;
716 Triangles[i].gy[1] = vertex[Triangles[i].vertex[1]].y;
717 Triangles[i].gy[2] = vertex[Triangles[i].vertex[2]].y;
718 Triangles[i].gx[0] = vertex[Triangles[i].vertex[0]].x;
719 Triangles[i].gx[1] = vertex[Triangles[i].vertex[1]].x;
720 Triangles[i].gx[2] = vertex[Triangles[i].vertex[2]].x;
726 void Model::FlipTexCoords()
729 for (i = 0; i < TriangleNum; i++) {
730 Triangles[i].gy[0] = -Triangles[i].gy[0];
731 Triangles[i].gy[1] = -Triangles[i].gy[1];
732 Triangles[i].gy[2] = -Triangles[i].gy[2];
737 void Model::ScaleTexCoords(float howmuch)
740 for (i = 0; i < TriangleNum; i++) {
741 Triangles[i].gx[0] *= howmuch;
742 Triangles[i].gx[1] *= howmuch;
743 Triangles[i].gx[2] *= howmuch;
744 Triangles[i].gy[0] *= howmuch;
745 Triangles[i].gy[1] *= howmuch;
746 Triangles[i].gy[2] *= howmuch;
751 void Model::Scale(float xscale, float yscale, float zscale)
754 for (i = 0; i < vertexNum; i++) {
755 vertex[i].x *= xscale;
756 vertex[i].y *= yscale;
757 vertex[i].z *= zscale;
763 boundingsphereradius = 0;
764 for (i = 0; i < vertexNum; i++) {
765 for (j = 0; j < vertexNum; j++) {
766 if (j != i && distsq(&vertex[j], &vertex[i]) / 2 > boundingsphereradius) {
767 boundingsphereradius = distsq(&vertex[j], &vertex[i]) / 2;
768 boundingspherecenter = (vertex[i] + vertex[j]) / 2;
772 boundingsphereradius = fast_sqrt(boundingsphereradius);
775 void Model::ScaleNormals(float xscale, float yscale, float zscale)
777 if (type != normaltype && type != decalstype)
780 for (i = 0; i < vertexNum; i++) {
781 normals[i].x *= xscale;
782 normals[i].y *= yscale;
783 normals[i].z *= zscale;
785 for (i = 0; i < TriangleNum; i++) {
786 facenormals[i].x *= xscale;
787 facenormals[i].y *= yscale;
788 facenormals[i].z *= zscale;
793 void Model::Translate(float xtrans, float ytrans, float ztrans)
796 for (i = 0; i < vertexNum; i++) {
797 vertex[i].x += xtrans;
798 vertex[i].y += ytrans;
799 vertex[i].z += ztrans;
804 boundingsphereradius = 0;
805 for (i = 0; i < vertexNum; i++) {
806 for (j = 0; j < vertexNum; j++) {
807 if (j != i && distsq(&vertex[j], &vertex[i]) / 2 > boundingsphereradius) {
808 boundingsphereradius = distsq(&vertex[j], &vertex[i]) / 2;
809 boundingspherecenter = (vertex[i] + vertex[j]) / 2;
813 boundingsphereradius = fast_sqrt(boundingsphereradius);
816 void Model::Rotate(float xang, float yang, float zang)
819 for (i = 0; i < vertexNum; i++) {
820 vertex[i] = DoRotation(vertex[i], xang, yang, zang);
825 boundingsphereradius = 0;
826 for (i = 0; i < vertexNum; i++) {
827 for (j = 0; j < vertexNum; j++) {
828 if (j != i && distsq(&vertex[j], &vertex[i]) / 2 > boundingsphereradius) {
829 boundingsphereradius = distsq(&vertex[j], &vertex[i]) / 2;
830 boundingspherecenter = (vertex[i] + vertex[j]) / 2;
834 boundingsphereradius = fast_sqrt(boundingsphereradius);
838 void Model::CalculateNormals(bool facenormalise)
841 Game::LoadingScreen();
843 if (type != normaltype && type != decalstype)
846 for (i = 0; i < vertexNum; i++) {
852 for (i = 0; i < TriangleNum; i++) {
853 CrossProduct(vertex[Triangles[i].vertex[1]] - vertex[Triangles[i].vertex[0]], vertex[Triangles[i].vertex[2]] - vertex[Triangles[i].vertex[0]], &facenormals[i]);
855 normals[Triangles[i].vertex[0]].x += facenormals[i].x;
856 normals[Triangles[i].vertex[0]].y += facenormals[i].y;
857 normals[Triangles[i].vertex[0]].z += facenormals[i].z;
859 normals[Triangles[i].vertex[1]].x += facenormals[i].x;
860 normals[Triangles[i].vertex[1]].y += facenormals[i].y;
861 normals[Triangles[i].vertex[1]].z += facenormals[i].z;
863 normals[Triangles[i].vertex[2]].x += facenormals[i].x;
864 normals[Triangles[i].vertex[2]].y += facenormals[i].y;
865 normals[Triangles[i].vertex[2]].z += facenormals[i].z;
867 Normalise(&facenormals[i]);
869 for (i = 0; i < vertexNum; i++) {
870 Normalise(&normals[i]);
873 UpdateVertexArrayNoTex();
876 void Model::drawimmediate()
879 glBegin(GL_TRIANGLES);
880 for (int i = 0; i < TriangleNum; i++) {
881 glTexCoord2f(Triangles[i].gx[0], Triangles[i].gy[0]);
883 glColor3f(normals[Triangles[i].vertex[0]].x, normals[Triangles[i].vertex[0]].y, normals[Triangles[i].vertex[0]].z);
885 glNormal3f(normals[Triangles[i].vertex[0]].x, normals[Triangles[i].vertex[0]].y, normals[Triangles[i].vertex[0]].z);
887 glNormal3f(facenormals[i].x, facenormals[i].y, facenormals[i].y);
888 glVertex3f(vertex[Triangles[i].vertex[0]].x, vertex[Triangles[i].vertex[0]].y, vertex[Triangles[i].vertex[0]].z);
890 glTexCoord2f(Triangles[i].gx[1], Triangles[i].gy[1]);
892 glColor3f(normals[Triangles[i].vertex[1]].x, normals[Triangles[i].vertex[1]].y, normals[Triangles[i].vertex[1]].z);
894 glNormal3f(normals[Triangles[i].vertex[1]].x, normals[Triangles[i].vertex[1]].y, normals[Triangles[i].vertex[1]].z);
896 glNormal3f(facenormals[i].x, facenormals[i].y, facenormals[i].y);
897 glVertex3f(vertex[Triangles[i].vertex[1]].x, vertex[Triangles[i].vertex[1]].y, vertex[Triangles[i].vertex[1]].z);
899 glTexCoord2f(Triangles[i].gx[2], Triangles[i].gy[2]);
901 glColor3f(normals[Triangles[i].vertex[2]].x, normals[Triangles[i].vertex[2]].y, normals[Triangles[i].vertex[2]].z);
903 glNormal3f(normals[Triangles[i].vertex[2]].x, normals[Triangles[i].vertex[2]].y, normals[Triangles[i].vertex[2]].z);
905 glNormal3f(facenormals[i].x, facenormals[i].y, facenormals[i].y);
906 glVertex3f(vertex[Triangles[i].vertex[2]].x, vertex[Triangles[i].vertex[2]].y, vertex[Triangles[i].vertex[2]].z);
913 if (type != normaltype && type != decalstype)
916 glEnableClientState(GL_NORMAL_ARRAY);
917 glEnableClientState(GL_VERTEX_ARRAY);
918 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
921 glInterleavedArrays( GL_T2F_N3F_V3F, 8 * sizeof(GLfloat), &vArray[0]);
923 glInterleavedArrays( GL_T2F_C3F_V3F, 8 * sizeof(GLfloat), &vArray[0]);
926 glDrawArrays(GL_TRIANGLES, 0, TriangleNum * 3);
929 glDisableClientState(GL_NORMAL_ARRAY);
931 glDisableClientState(GL_COLOR_ARRAY);
932 glDisableClientState(GL_VERTEX_ARRAY);
933 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
936 //TODO: phase out in favor of Texture
937 void Model::drawdifftex(GLuint texture)
939 glEnableClientState(GL_NORMAL_ARRAY);
940 glEnableClientState(GL_VERTEX_ARRAY);
941 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
943 glInterleavedArrays( GL_T2F_N3F_V3F, 8 * sizeof(GLfloat), &vArray[0]);
945 glInterleavedArrays( GL_T2F_C3F_V3F, 8 * sizeof(GLfloat), &vArray[0]);
947 glBindTexture(GL_TEXTURE_2D, (unsigned long)texture);
948 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
949 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
953 glLockArraysEXT( 0, TriangleNum * 3);
955 glDrawArrays(GL_TRIANGLES, 0, TriangleNum * 3);
962 glDisableClientState(GL_NORMAL_ARRAY);
964 glDisableClientState(GL_COLOR_ARRAY);
965 glDisableClientState(GL_VERTEX_ARRAY);
966 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
969 void Model::drawdifftex(Texture texture)
971 glEnableClientState(GL_NORMAL_ARRAY);
972 glEnableClientState(GL_VERTEX_ARRAY);
973 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
975 glInterleavedArrays( GL_T2F_N3F_V3F, 8 * sizeof(GLfloat), &vArray[0]);
977 glInterleavedArrays( GL_T2F_C3F_V3F, 8 * sizeof(GLfloat), &vArray[0]);
980 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
981 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
985 glLockArraysEXT( 0, TriangleNum * 3);
987 glDrawArrays(GL_TRIANGLES, 0, TriangleNum * 3);
994 glDisableClientState(GL_NORMAL_ARRAY);
996 glDisableClientState(GL_COLOR_ARRAY);
997 glDisableClientState(GL_VERTEX_ARRAY);
998 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1001 void Model::drawdecals(Texture shadowtexture, Texture bloodtexture, Texture bloodtexture2, Texture breaktexture)
1004 if (type != decalstype)
1007 static int lasttype;
1014 glDisable(GL_LIGHTING);
1015 glDisable(GL_CULL_FACE);
1016 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1018 if (numdecals > max_model_decals)
1019 numdecals = max_model_decals;
1020 for (i = 0; i < numdecals; i++) {
1021 if (decaltype[i] == blooddecalfast && decalalivetime[i] < 2)
1022 decalalivetime[i] = 2;
1024 if (decaltype[i] == shadowdecal && decaltype[i] != lasttype) {
1025 shadowtexture.bind();
1028 glAlphaFunc(GL_GREATER, 0.0001);
1029 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1032 if (decaltype[i] == breakdecal && decaltype[i] != lasttype) {
1033 breaktexture.bind();
1036 glAlphaFunc(GL_GREATER, 0.0001);
1037 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1040 if ((decaltype[i] == blooddecal || decaltype[i] == blooddecalslow) && decaltype[i] != lasttype) {
1041 bloodtexture.bind();
1044 glAlphaFunc(GL_GREATER, 0.15);
1045 glBlendFunc(GL_ONE, GL_ZERO);
1048 if ((decaltype[i] == blooddecalfast) && decaltype[i] != lasttype) {
1049 bloodtexture2.bind();
1052 glAlphaFunc(GL_GREATER, 0.15);
1053 glBlendFunc(GL_ONE, GL_ZERO);
1056 if (decaltype[i] == shadowdecal) {
1057 glColor4f(1, 1, 1, decalopacity[i]);
1059 if (decaltype[i] == breakdecal) {
1060 glColor4f(1, 1, 1, decalopacity[i]);
1061 if (decalalivetime[i] > 58)
1062 glColor4f(1, 1, 1, decalopacity[i] * (60 - decalalivetime[i]) / 2);
1064 if ((decaltype[i] == blooddecal || decaltype[i] == blooddecalfast || decaltype[i] == blooddecalslow)) {
1065 glColor4f(1, 1, 1, decalopacity[i]);
1066 if (decalalivetime[i] < 4)
1067 glColor4f(1, 1, 1, decalopacity[i]*decalalivetime[i]*.25);
1068 if (decalalivetime[i] > 58)
1069 glColor4f(1, 1, 1, decalopacity[i] * (60 - decalalivetime[i]) / 2);
1071 lasttype = decaltype[i];
1072 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1073 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
1075 glMatrixMode(GL_MODELVIEW);
1077 glBegin(GL_TRIANGLES);
1078 for (int j = 0; j < 3; j++) {
1079 glTexCoord2f(decaltexcoords[i][j][0], decaltexcoords[i][j][1]);
1080 glVertex3f(decalvertex[i][j].x, decalvertex[i][j].y, decalvertex[i][j].z);
1085 for (i = numdecals - 1; i >= 0; i--) {
1086 decalalivetime[i] += multiplier;
1087 if (decaltype[i] == blooddecalslow)
1088 decalalivetime[i] -= multiplier * 2 / 3;
1089 if (decaltype[i] == blooddecalfast)
1090 decalalivetime[i] += multiplier * 4;
1091 if (decaltype[i] == shadowdecal)
1093 if ((decaltype[i] == blooddecal || decaltype[i] == blooddecalfast || decaltype[i] == blooddecalslow) && decalalivetime[i] >= 60)
1096 glAlphaFunc(GL_GREATER, 0.0001);
1097 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1101 void Model::DeleteDecal(int which)
1104 if (type != decalstype)
1106 decaltype[which] = decaltype[numdecals - 1];
1107 decalposition[which] = decalposition[numdecals - 1];
1108 for (int i = 0; i < 3; i++) {
1109 decalvertex[which][i] = decalvertex[numdecals - 1][i];
1110 decaltexcoords[which][i][0] = decaltexcoords[numdecals - 1][i][0];
1111 decaltexcoords[which][i][1] = decaltexcoords[numdecals - 1][i][1];
1113 decalrotation[which] = decalrotation[numdecals - 1];
1114 decalalivetime[which] = decalalivetime[numdecals - 1];
1115 decalopacity[which] = decalopacity[numdecals - 1];
1120 void Model::MakeDecal(int atype, XYZ *where, float *size, float *opacity, float *rotation)
1123 if (type != decalstype)
1126 static float placex, placez;
1128 static float distance;
1132 if (distsq(where, &boundingspherecenter) < (boundingsphereradius + *size) * (boundingsphereradius + *size))
1133 for (i = 0; i < TriangleNum; i++) {
1134 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)) {
1135 decalposition[numdecals] = *where;
1136 decaltype[numdecals] = atype;
1137 decalrotation[numdecals] = *rotation;
1138 decalalivetime[numdecals] = 0;
1139 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);
1140 decalopacity[numdecals] = *opacity - distance / 10;
1142 if (decalopacity[numdecals > 0]) {
1143 placex = vertex[Triangles[i].vertex[0]].x;
1144 placez = vertex[Triangles[i].vertex[0]].z;
1146 decaltexcoords[numdecals][0][0] = (placex - where->x) / (*size) / 2 + .5;
1147 decaltexcoords[numdecals][0][1] = (placez - where->z) / (*size) / 2 + .5;
1149 decalvertex[numdecals][0].x = placex;
1150 decalvertex[numdecals][0].z = placez;
1151 decalvertex[numdecals][0].y = vertex[Triangles[i].vertex[0]].y;
1154 placex = vertex[Triangles[i].vertex[1]].x;
1155 placez = vertex[Triangles[i].vertex[1]].z;
1157 decaltexcoords[numdecals][1][0] = (placex - where->x) / (*size) / 2 + .5;
1158 decaltexcoords[numdecals][1][1] = (placez - where->z) / (*size) / 2 + .5;
1160 decalvertex[numdecals][1].x = placex;
1161 decalvertex[numdecals][1].z = placez;
1162 decalvertex[numdecals][1].y = vertex[Triangles[i].vertex[1]].y;
1165 placex = vertex[Triangles[i].vertex[2]].x;
1166 placez = vertex[Triangles[i].vertex[2]].z;
1168 decaltexcoords[numdecals][2][0] = (placex - where->x) / (*size) / 2 + .5;
1169 decaltexcoords[numdecals][2][1] = (placez - where->z) / (*size) / 2 + .5;
1171 decalvertex[numdecals][2].x = placex;
1172 decalvertex[numdecals][2].z = placez;
1173 decalvertex[numdecals][2].y = vertex[Triangles[i].vertex[2]].y;
1175 if (!(decaltexcoords[numdecals][0][0] < 0 && decaltexcoords[numdecals][1][0] < 0 && decaltexcoords[numdecals][2][0] < 0))
1176 if (!(decaltexcoords[numdecals][0][1] < 0 && decaltexcoords[numdecals][1][1] < 0 && decaltexcoords[numdecals][2][1] < 0))
1177 if (!(decaltexcoords[numdecals][0][0] > 1 && decaltexcoords[numdecals][1][0] > 1 && decaltexcoords[numdecals][2][0] > 1))
1178 if (!(decaltexcoords[numdecals][0][1] > 1 && decaltexcoords[numdecals][1][1] > 1 && decaltexcoords[numdecals][2][1] > 1)) {
1179 if (decalrotation[numdecals]) {
1180 for (j = 0; j < 3; j++) {
1182 rot.x = decaltexcoords[numdecals][j][0] - .5;
1183 rot.z = decaltexcoords[numdecals][j][1] - .5;
1184 rot = DoRotation(rot, 0, -decalrotation[numdecals], 0);
1185 decaltexcoords[numdecals][j][0] = rot.x + .5;
1186 decaltexcoords[numdecals][j][1] = rot.z + .5;
1189 if (numdecals < max_model_decals - 1)
1198 void Model::MakeDecal(int atype, XYZ where, float size, float opacity, float rotation)
1201 if (type != decalstype)
1204 static float placex, placez;
1206 static float distance;
1210 if (distsq(&where, &boundingspherecenter) < (boundingsphereradius + size) * (boundingsphereradius + size))
1211 for (i = 0; i < TriangleNum; i++) {
1212 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))));
1213 if (distance < .02 && abs(facenormals[i].y) > abs(facenormals[i].x) && abs(facenormals[i].y) > abs(facenormals[i].z)) {
1214 decalposition[numdecals] = where;
1215 decaltype[numdecals] = atype;
1216 decalrotation[numdecals] = rotation;
1217 decalalivetime[numdecals] = 0;
1218 decalopacity[numdecals] = opacity - distance / 10;
1220 if (decalopacity[numdecals > 0]) {
1221 placex = vertex[Triangles[i].vertex[0]].x;
1222 placez = vertex[Triangles[i].vertex[0]].z;
1224 decaltexcoords[numdecals][0][0] = (placex - where.x) / (size) / 2 + .5;
1225 decaltexcoords[numdecals][0][1] = (placez - where.z) / (size) / 2 + .5;
1227 decalvertex[numdecals][0].x = placex;
1228 decalvertex[numdecals][0].z = placez;
1229 decalvertex[numdecals][0].y = vertex[Triangles[i].vertex[0]].y;
1232 placex = vertex[Triangles[i].vertex[1]].x;
1233 placez = vertex[Triangles[i].vertex[1]].z;
1235 decaltexcoords[numdecals][1][0] = (placex - where.x) / (size) / 2 + .5;
1236 decaltexcoords[numdecals][1][1] = (placez - where.z) / (size) / 2 + .5;
1238 decalvertex[numdecals][1].x = placex;
1239 decalvertex[numdecals][1].z = placez;
1240 decalvertex[numdecals][1].y = vertex[Triangles[i].vertex[1]].y;
1243 placex = vertex[Triangles[i].vertex[2]].x;
1244 placez = vertex[Triangles[i].vertex[2]].z;
1246 decaltexcoords[numdecals][2][0] = (placex - where.x) / (size) / 2 + .5;
1247 decaltexcoords[numdecals][2][1] = (placez - where.z) / (size) / 2 + .5;
1249 decalvertex[numdecals][2].x = placex;
1250 decalvertex[numdecals][2].z = placez;
1251 decalvertex[numdecals][2].y = vertex[Triangles[i].vertex[2]].y;
1253 if (!(decaltexcoords[numdecals][0][0] < 0 && decaltexcoords[numdecals][1][0] < 0 && decaltexcoords[numdecals][2][0] < 0))
1254 if (!(decaltexcoords[numdecals][0][1] < 0 && decaltexcoords[numdecals][1][1] < 0 && decaltexcoords[numdecals][2][1] < 0))
1255 if (!(decaltexcoords[numdecals][0][0] > 1 && decaltexcoords[numdecals][1][0] > 1 && decaltexcoords[numdecals][2][0] > 1))
1256 if (!(decaltexcoords[numdecals][0][1] > 1 && decaltexcoords[numdecals][1][1] > 1 && decaltexcoords[numdecals][2][1] > 1)) {
1257 if (decalrotation[numdecals]) {
1258 for (j = 0; j < 3; j++) {
1260 rot.x = decaltexcoords[numdecals][j][0] - .5;
1261 rot.z = decaltexcoords[numdecals][j][1] - .5;
1262 rot = DoRotation(rot, 0, -decalrotation[numdecals], 0);
1263 decaltexcoords[numdecals][j][0] = rot.x + .5;
1264 decaltexcoords[numdecals][j][1] = rot.z + .5;
1267 if (numdecals < max_model_decals - 1)
1271 } else if (distance < .02 && abs(facenormals[i].x) > abs(facenormals[i].y) && abs(facenormals[i].x) > abs(facenormals[i].z)) {
1272 decalposition[numdecals] = where;
1273 decaltype[numdecals] = atype;
1274 decalrotation[numdecals] = rotation;
1275 decalalivetime[numdecals] = 0;
1276 decalopacity[numdecals] = opacity - distance / 10;
1278 if (decalopacity[numdecals > 0]) {
1279 placex = vertex[Triangles[i].vertex[0]].y;
1280 placez = vertex[Triangles[i].vertex[0]].z;
1282 decaltexcoords[numdecals][0][0] = (placex - where.y) / (size) / 2 + .5;
1283 decaltexcoords[numdecals][0][1] = (placez - where.z) / (size) / 2 + .5;
1285 decalvertex[numdecals][0].x = vertex[Triangles[i].vertex[0]].x;
1286 decalvertex[numdecals][0].z = placez;
1287 decalvertex[numdecals][0].y = placex;
1290 placex = vertex[Triangles[i].vertex[1]].y;
1291 placez = vertex[Triangles[i].vertex[1]].z;
1293 decaltexcoords[numdecals][1][0] = (placex - where.y) / (size) / 2 + .5;
1294 decaltexcoords[numdecals][1][1] = (placez - where.z) / (size) / 2 + .5;
1296 decalvertex[numdecals][1].x = vertex[Triangles[i].vertex[1]].x;
1297 decalvertex[numdecals][1].z = placez;
1298 decalvertex[numdecals][1].y = placex;
1301 placex = vertex[Triangles[i].vertex[2]].y;
1302 placez = vertex[Triangles[i].vertex[2]].z;
1304 decaltexcoords[numdecals][2][0] = (placex - where.y) / (size) / 2 + .5;
1305 decaltexcoords[numdecals][2][1] = (placez - where.z) / (size) / 2 + .5;
1307 decalvertex[numdecals][2].x = vertex[Triangles[i].vertex[2]].x;
1308 decalvertex[numdecals][2].z = placez;
1309 decalvertex[numdecals][2].y = placex;
1311 if (!(decaltexcoords[numdecals][0][0] < 0 && decaltexcoords[numdecals][1][0] < 0 && decaltexcoords[numdecals][2][0] < 0))
1312 if (!(decaltexcoords[numdecals][0][1] < 0 && decaltexcoords[numdecals][1][1] < 0 && decaltexcoords[numdecals][2][1] < 0))
1313 if (!(decaltexcoords[numdecals][0][0] > 1 && decaltexcoords[numdecals][1][0] > 1 && decaltexcoords[numdecals][2][0] > 1))
1314 if (!(decaltexcoords[numdecals][0][1] > 1 && decaltexcoords[numdecals][1][1] > 1 && decaltexcoords[numdecals][2][1] > 1)) {
1315 if (decalrotation[numdecals]) {
1316 for (j = 0; j < 3; j++) {
1318 rot.x = decaltexcoords[numdecals][j][0] - .5;
1319 rot.z = decaltexcoords[numdecals][j][1] - .5;
1320 rot = DoRotation(rot, 0, -decalrotation[numdecals], 0);
1321 decaltexcoords[numdecals][j][0] = rot.x + .5;
1322 decaltexcoords[numdecals][j][1] = rot.z + .5;
1325 if (numdecals < max_model_decals - 1)
1329 } else if (distance < .02 && abs(facenormals[i].z) > abs(facenormals[i].y) && abs(facenormals[i].z) > abs(facenormals[i].x)) {
1330 decalposition[numdecals] = where;
1331 decaltype[numdecals] = atype;
1332 decalrotation[numdecals] = rotation;
1333 decalalivetime[numdecals] = 0;
1334 decalopacity[numdecals] = opacity - distance / 10;
1336 if (decalopacity[numdecals > 0]) {
1337 placex = vertex[Triangles[i].vertex[0]].x;
1338 placez = vertex[Triangles[i].vertex[0]].y;
1340 decaltexcoords[numdecals][0][0] = (placex - where.x) / (size) / 2 + .5;
1341 decaltexcoords[numdecals][0][1] = (placez - where.y) / (size) / 2 + .5;
1343 decalvertex[numdecals][0].x = placex;
1344 decalvertex[numdecals][0].z = vertex[Triangles[i].vertex[0]].z;
1345 decalvertex[numdecals][0].y = placez;
1348 placex = vertex[Triangles[i].vertex[1]].x;
1349 placez = vertex[Triangles[i].vertex[1]].y;
1351 decaltexcoords[numdecals][1][0] = (placex - where.x) / (size) / 2 + .5;
1352 decaltexcoords[numdecals][1][1] = (placez - where.y) / (size) / 2 + .5;
1354 decalvertex[numdecals][1].x = placex;
1355 decalvertex[numdecals][1].z = vertex[Triangles[i].vertex[1]].z;
1356 decalvertex[numdecals][1].y = placez;
1359 placex = vertex[Triangles[i].vertex[2]].x;
1360 placez = vertex[Triangles[i].vertex[2]].y;
1362 decaltexcoords[numdecals][2][0] = (placex - where.x) / (size) / 2 + .5;
1363 decaltexcoords[numdecals][2][1] = (placez - where.y) / (size) / 2 + .5;
1365 decalvertex[numdecals][2].x = placex;
1366 decalvertex[numdecals][2].z = vertex[Triangles[i].vertex[2]].z;
1367 decalvertex[numdecals][2].y = placez;
1369 if (!(decaltexcoords[numdecals][0][0] < 0 && decaltexcoords[numdecals][1][0] < 0 && decaltexcoords[numdecals][2][0] < 0))
1370 if (!(decaltexcoords[numdecals][0][1] < 0 && decaltexcoords[numdecals][1][1] < 0 && decaltexcoords[numdecals][2][1] < 0))
1371 if (!(decaltexcoords[numdecals][0][0] > 1 && decaltexcoords[numdecals][1][0] > 1 && decaltexcoords[numdecals][2][0] > 1))
1372 if (!(decaltexcoords[numdecals][0][1] > 1 && decaltexcoords[numdecals][1][1] > 1 && decaltexcoords[numdecals][2][1] > 1)) {
1373 if (decalrotation[numdecals]) {
1374 for (j = 0; j < 3; j++) {
1376 rot.x = decaltexcoords[numdecals][j][0] - .5;
1377 rot.z = decaltexcoords[numdecals][j][1] - .5;
1378 rot = DoRotation(rot, 0, -decalrotation[numdecals], 0);
1379 decaltexcoords[numdecals][j][0] = rot.x + .5;
1380 decaltexcoords[numdecals][j][1] = rot.z + .5;
1383 if (numdecals < max_model_decals - 1)
1395 textureptr.destroy();
1398 void Model::deallocate()
1432 if (decaltexcoords) {
1433 for (i = 0; i < max_model_decals; i++) {
1434 for (j = 0; j < 3; j++) {
1435 free(decaltexcoords[i][j]);
1437 free(decaltexcoords[i]);
1439 free(decaltexcoords);
1445 for (i = 0; i < max_model_decals; i++) {
1446 free(decalvertex[i]);
1459 free(decalrotation);
1462 free(decalalivetime);
1465 free(decalposition);
1472 vertexNum = 0, TriangleNum = 0;
1475 type = 0, oldtype = 0;
1485 memset(&modelTexture, 0, sizeof(modelTexture));
1489 boundingspherecenter = 0;
1490 boundingsphereradius = 0;