2 Copyright (C) 2003, 2010 - Wolfire Games
4 This file is part of Lugaru.
6 Lugaru is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 Lugaru is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with Lugaru. If not, see <http://www.gnu.org/licenses/>.
23 extern float multiplier;
24 extern float viewdistance;
26 extern float fadestart;
27 extern float texdetail;
30 extern bool visibleloading;
32 int Model::LineCheck(XYZ *p1, XYZ *p2, XYZ *p, XYZ *move, float *rotate)
35 static float distance;
36 static float olddistance;
37 static int intersecting;
38 static int firstintersecting;
44 *p1 = DoRotation(*p1, 0, -*rotate, 0);
46 *p2 = DoRotation(*p2, 0, -*rotate, 0);
47 if (!sphere_line_intersection(p1, p2, &boundingspherecenter, &boundingsphereradius))
49 firstintersecting = -1;
51 for (j = 0; j < TriangleNum; j++) {
52 intersecting = LineFacetd(p1, p2, &vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[1]], &vertex[Triangles[j].vertex[2]], &facenormals[j], &point);
53 distance = (point.x - p1->x) * (point.x - p1->x) + (point.y - p1->y) * (point.y - p1->y) + (point.z - p1->z) * (point.z - p1->z);
54 if ((distance < olddistance || firstintersecting == -1) && intersecting) {
55 olddistance = distance;
56 firstintersecting = j;
62 *p = DoRotation(*p, 0, *rotate, 0);
64 return firstintersecting;
67 int Model::LineCheckPossible(XYZ *p1, XYZ *p2, XYZ *p, XYZ *move, float *rotate)
70 static float distance;
71 static float olddistance;
72 static int intersecting;
73 static int firstintersecting;
78 if (!sphere_line_intersection(p1, p2, &boundingspherecenter, &boundingsphereradius))
80 firstintersecting = -1;
82 *p1 = DoRotation(*p1, 0, -*rotate, 0);
84 *p2 = DoRotation(*p2, 0, -*rotate, 0);
86 if (numpossible > 0 && numpossible < TriangleNum)
87 for (j = 0; j < numpossible; j++) {
88 if (possible[j] >= 0 && possible[j] < TriangleNum) {
89 intersecting = LineFacetd(p1, p2, &vertex[Triangles[possible[j]].vertex[0]], &vertex[Triangles[possible[j]].vertex[1]], &vertex[Triangles[possible[j]].vertex[2]], &facenormals[possible[j]], &point);
90 distance = (point.x - p1->x) * (point.x - p1->x) + (point.y - p1->y) * (point.y - p1->y) + (point.z - p1->z) * (point.z - p1->z);
91 if ((distance < olddistance || firstintersecting == -1) && intersecting) {
92 olddistance = distance;
93 firstintersecting = possible[j];
100 *p = DoRotation(*p, 0, *rotate, 0);
102 return firstintersecting;
105 int Model::LineCheckSlidePossible(XYZ *p1, XYZ *p2, XYZ *p, XYZ *move, float *rotate)
108 static float distance;
109 static float olddistance;
110 static int intersecting;
111 static int firstintersecting;
116 if (!sphere_line_intersection(p1, p2, &boundingspherecenter, &boundingsphereradius))
118 firstintersecting = -1;
120 *p1 = DoRotation(*p1, 0, -*rotate, 0);
122 *p2 = DoRotation(*p2, 0, -*rotate, 0);
125 for (j = 0; j < numpossible; j++) {
126 if (possible[j] >= 0 && possible[j] < TriangleNum) {
127 intersecting = LineFacetd(p1, p2, &vertex[Triangles[possible[j]].vertex[0]], &vertex[Triangles[possible[j]].vertex[1]], &vertex[Triangles[possible[j]].vertex[2]], &facenormals[possible[j]], &point);
128 distance = (point.x - p1->x) * (point.x - p1->x) + (point.y - p1->y) * (point.y - p1->y) + (point.z - p1->z) * (point.z - p1->z);
129 if ((distance < olddistance || firstintersecting == -1) && intersecting) {
130 olddistance = distance;
131 firstintersecting = possible[j];
136 if (firstintersecting > 0) {
137 distance = abs((facenormals[firstintersecting].x * p2->x) + (facenormals[firstintersecting].y * p2->y) + (facenormals[firstintersecting].z * p2->z) - ((facenormals[firstintersecting].x * vertex[Triangles[firstintersecting].vertex[0]].x) + (facenormals[firstintersecting].y * vertex[Triangles[firstintersecting].vertex[0]].y) + (facenormals[firstintersecting].z * vertex[Triangles[firstintersecting].vertex[0]].z)));
138 *p2 -= facenormals[firstintersecting] * distance;
142 *p2 = DoRotation(*p2, 0, *rotate, 0);
144 return firstintersecting;
147 int Model::SphereCheck(XYZ *p1, float radius, XYZ *p, XYZ *move, float *rotate)
150 static float distance;
151 static float olddistance;
152 static int intersecting;
153 static int firstintersecting;
156 static XYZ start, end;
158 firstintersecting = -1;
163 *p1 = DoRotation(*p1, 0, -*rotate, 0);
164 if (distsq(p1, &boundingspherecenter) > radius * radius + boundingsphereradius * boundingsphereradius)
167 for (i = 0; i < 4; i++) {
168 for (j = 0; j < TriangleNum; j++) {
170 distance = abs((facenormals[j].x * p1->x) + (facenormals[j].y * p1->y) + (facenormals[j].z * p1->z) - ((facenormals[j].x * vertex[Triangles[j].vertex[0]].x) + (facenormals[j].y * vertex[Triangles[j].vertex[0]].y) + (facenormals[j].z * vertex[Triangles[j].vertex[0]].z)));
171 if (distance < radius) {
172 point = *p1 - facenormals[j] * distance;
173 if (PointInTriangle( &point, facenormals[j], &vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[1]], &vertex[Triangles[j].vertex[2]]))
176 intersecting = sphere_line_intersection(&vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[1]], p1, &radius);
178 intersecting = sphere_line_intersection(&vertex[Triangles[j].vertex[1]], &vertex[Triangles[j].vertex[2]], p1, &radius);
180 intersecting = sphere_line_intersection(&vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[2]], p1, &radius);
182 *p1 += facenormals[j] * (distance - radius);
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;
210 static XYZ start, end;
212 firstintersecting = -1;
220 *p1 = DoRotation(*p1, 0, -*rotate, 0);
221 if (distsq(p1, &boundingspherecenter) > radius * radius + boundingsphereradius * boundingsphereradius) {
226 for (j = 0; j < TriangleNum; j++) {
228 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)));
229 if (distance < radius) {
230 point = *p1 - facenormals[j] * distance;
231 if (PointInTriangle( &point, facenormals[j], &vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[1]], &vertex[Triangles[j].vertex[2]]))
234 intersecting = sphere_line_intersection(&vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[1]], p1, &radius);
236 intersecting = sphere_line_intersection(&vertex[Triangles[j].vertex[1]], &vertex[Triangles[j].vertex[2]], p1, &radius);
238 intersecting = sphere_line_intersection(&vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[2]], p1, &radius);
240 possible[numpossible] = j;
244 if ((distance < olddistance || firstintersecting == -1) && intersecting) {
245 olddistance = distance;
246 firstintersecting = j;
250 *p1 = DoRotation(*p1, 0, *rotate, 0);
252 return firstintersecting;
256 void Model::UpdateVertexArray()
258 if (type != normaltype && type != decalstype)
263 for (i = 0; i < TriangleNum; i++) {
265 vArray[j + 0] = Triangles[i].gx[0];
266 vArray[j + 1] = Triangles[i].gy[0];
267 vArray[j + 2] = normals[Triangles[i].vertex[0]].x;
268 vArray[j + 3] = normals[Triangles[i].vertex[0]].y;
269 vArray[j + 4] = normals[Triangles[i].vertex[0]].z;
270 vArray[j + 5] = vertex[Triangles[i].vertex[0]].x;
271 vArray[j + 6] = vertex[Triangles[i].vertex[0]].y;
272 vArray[j + 7] = vertex[Triangles[i].vertex[0]].z;
274 vArray[j + 8] = Triangles[i].gx[1];
275 vArray[j + 9] = Triangles[i].gy[1];
276 vArray[j + 10] = normals[Triangles[i].vertex[1]].x;
277 vArray[j + 11] = normals[Triangles[i].vertex[1]].y;
278 vArray[j + 12] = normals[Triangles[i].vertex[1]].z;
279 vArray[j + 13] = vertex[Triangles[i].vertex[1]].x;
280 vArray[j + 14] = vertex[Triangles[i].vertex[1]].y;
281 vArray[j + 15] = vertex[Triangles[i].vertex[1]].z;
283 vArray[j + 16] = Triangles[i].gx[2];
284 vArray[j + 17] = Triangles[i].gy[2];
285 vArray[j + 18] = normals[Triangles[i].vertex[2]].x;
286 vArray[j + 19] = normals[Triangles[i].vertex[2]].y;
287 vArray[j + 20] = normals[Triangles[i].vertex[2]].z;
288 vArray[j + 21] = vertex[Triangles[i].vertex[2]].x;
289 vArray[j + 22] = vertex[Triangles[i].vertex[2]].y;
290 vArray[j + 23] = vertex[Triangles[i].vertex[2]].z;
293 for (i = 0; i < TriangleNum; i++) {
295 vArray[j + 0] = Triangles[i].gx[0];
296 vArray[j + 1] = Triangles[i].gy[0];
297 vArray[j + 2] = facenormals[i].x * -1;
298 vArray[j + 3] = facenormals[i].y * -1;
299 vArray[j + 4] = facenormals[i].z * -1;
300 vArray[j + 5] = vertex[Triangles[i].vertex[0]].x;
301 vArray[j + 6] = vertex[Triangles[i].vertex[0]].y;
302 vArray[j + 7] = vertex[Triangles[i].vertex[0]].z;
304 vArray[j + 8] = Triangles[i].gx[1];
305 vArray[j + 9] = Triangles[i].gy[1];
306 vArray[j + 10] = facenormals[i].x * -1;
307 vArray[j + 11] = facenormals[i].y * -1;
308 vArray[j + 12] = facenormals[i].z * -1;
309 vArray[j + 13] = vertex[Triangles[i].vertex[1]].x;
310 vArray[j + 14] = vertex[Triangles[i].vertex[1]].y;
311 vArray[j + 15] = vertex[Triangles[i].vertex[1]].z;
313 vArray[j + 16] = Triangles[i].gx[2];
314 vArray[j + 17] = Triangles[i].gy[2];
315 vArray[j + 18] = facenormals[i].x * -1;
316 vArray[j + 19] = facenormals[i].y * -1;
317 vArray[j + 20] = facenormals[i].z * -1;
318 vArray[j + 21] = vertex[Triangles[i].vertex[2]].x;
319 vArray[j + 22] = vertex[Triangles[i].vertex[2]].y;
320 vArray[j + 23] = vertex[Triangles[i].vertex[2]].z;
325 void Model::UpdateVertexArrayNoTex()
327 if (type != normaltype && type != decalstype)
332 for (i = 0; i < TriangleNum; i++) {
334 vArray[j + 2] = normals[Triangles[i].vertex[0]].x;
335 vArray[j + 3] = normals[Triangles[i].vertex[0]].y;
336 vArray[j + 4] = normals[Triangles[i].vertex[0]].z;
337 vArray[j + 5] = vertex[Triangles[i].vertex[0]].x;
338 vArray[j + 6] = vertex[Triangles[i].vertex[0]].y;
339 vArray[j + 7] = vertex[Triangles[i].vertex[0]].z;
341 vArray[j + 10] = normals[Triangles[i].vertex[1]].x;
342 vArray[j + 11] = normals[Triangles[i].vertex[1]].y;
343 vArray[j + 12] = normals[Triangles[i].vertex[1]].z;
344 vArray[j + 13] = vertex[Triangles[i].vertex[1]].x;
345 vArray[j + 14] = vertex[Triangles[i].vertex[1]].y;
346 vArray[j + 15] = vertex[Triangles[i].vertex[1]].z;
348 vArray[j + 18] = normals[Triangles[i].vertex[2]].x;
349 vArray[j + 19] = normals[Triangles[i].vertex[2]].y;
350 vArray[j + 20] = normals[Triangles[i].vertex[2]].z;
351 vArray[j + 21] = vertex[Triangles[i].vertex[2]].x;
352 vArray[j + 22] = vertex[Triangles[i].vertex[2]].y;
353 vArray[j + 23] = vertex[Triangles[i].vertex[2]].z;
356 for (i = 0; i < TriangleNum; i++) {
358 vArray[j + 2] = facenormals[i].x * -1;
359 vArray[j + 3] = facenormals[i].y * -1;
360 vArray[j + 4] = facenormals[i].z * -1;
361 vArray[j + 5] = vertex[Triangles[i].vertex[0]].x;
362 vArray[j + 6] = vertex[Triangles[i].vertex[0]].y;
363 vArray[j + 7] = vertex[Triangles[i].vertex[0]].z;
365 vArray[j + 10] = facenormals[i].x * -1;
366 vArray[j + 11] = facenormals[i].y * -1;
367 vArray[j + 12] = facenormals[i].z * -1;
368 vArray[j + 13] = vertex[Triangles[i].vertex[1]].x;
369 vArray[j + 14] = vertex[Triangles[i].vertex[1]].y;
370 vArray[j + 15] = vertex[Triangles[i].vertex[1]].z;
372 vArray[j + 18] = facenormals[i].x * -1;
373 vArray[j + 19] = facenormals[i].y * -1;
374 vArray[j + 20] = facenormals[i].z * -1;
375 vArray[j + 21] = vertex[Triangles[i].vertex[2]].x;
376 vArray[j + 22] = vertex[Triangles[i].vertex[2]].y;
377 vArray[j + 23] = vertex[Triangles[i].vertex[2]].z;
381 void Model::UpdateVertexArrayNoTexNoNorm()
383 if (type != normaltype && type != decalstype)
387 for (i = 0; i < TriangleNum; i++) {
389 vArray[j + 5] = vertex[Triangles[i].vertex[0]].x;
390 vArray[j + 6] = vertex[Triangles[i].vertex[0]].y;
391 vArray[j + 7] = vertex[Triangles[i].vertex[0]].z;
393 vArray[j + 13] = vertex[Triangles[i].vertex[1]].x;
394 vArray[j + 14] = vertex[Triangles[i].vertex[1]].y;
395 vArray[j + 15] = vertex[Triangles[i].vertex[1]].z;
397 vArray[j + 21] = vertex[Triangles[i].vertex[2]].x;
398 vArray[j + 22] = vertex[Triangles[i].vertex[2]].y;
399 vArray[j + 23] = vertex[Triangles[i].vertex[2]].z;
403 bool Model::loadnotex(const char *filename )
408 //~ int oldvertexNum, oldTriangleNum;
409 //~ oldvertexNum = vertexNum;
410 //~ oldTriangleNum = TriangleNum;
415 tfile = fopen( ConvertFileName(filename), "rb" );
416 // read model settings
418 fseek(tfile, 0, SEEK_SET);
419 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
421 // read the model data
426 owner = (int*)malloc(sizeof(int) * vertexNum);
427 possible = (int*)malloc(sizeof(int) * TriangleNum);
428 vertex = (XYZ*)malloc(sizeof(XYZ) * vertexNum);
429 Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle) * TriangleNum);
430 vArray = (GLfloat*)malloc(sizeof(GLfloat) * TriangleNum * 24);
432 for (i = 0; i < vertexNum; i++) {
433 funpackf(tfile, "Bf Bf Bf", &vertex[i].x, &vertex[i].y, &vertex[i].z);
436 for (i = 0; i < TriangleNum; i++) {
437 //funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
439 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
440 Triangles[i].vertex[ 0] = vertex[ 0];
441 Triangles[i].vertex[ 1] = vertex[ 2];
442 Triangles[i].vertex[ 2] = vertex[ 4];
443 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
444 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
451 for (i = 0; i < vertexNum; i++) {
456 boundingsphereradius = 0;
457 for (i = 0; i < vertexNum; i++) {
458 for (j = 0; j < vertexNum; j++) {
459 if (j != i && distsq(&vertex[j], &vertex[i]) / 2 > boundingsphereradius) {
460 boundingsphereradius = distsq(&vertex[j], &vertex[i]) / 2;
461 boundingspherecenter = (vertex[i] + vertex[j]) / 2;
465 boundingsphereradius = fast_sqrt(boundingsphereradius);
471 bool Model::load(const char *filename, bool texture )
478 LOG(std::string("Loading model...") + filename);
481 Game::LoadingScreen();
483 //~ int oldvertexNum, oldTriangleNum;
484 //~ oldvertexNum = vertexNum;
485 //~ oldTriangleNum = TriangleNum;
490 tfile = fopen( ConvertFileName(filename), "rb" );
491 // read model settings
494 fseek(tfile, 0, SEEK_SET);
495 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
497 // read the model data
502 owner = (int*)malloc(sizeof(int) * vertexNum);
503 possible = (int*)malloc(sizeof(int) * TriangleNum);
504 vertex = (XYZ*)malloc(sizeof(XYZ) * vertexNum);
505 normals = (XYZ*)malloc(sizeof(XYZ) * vertexNum);
506 facenormals = (XYZ*)malloc(sizeof(XYZ) * TriangleNum);
507 Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle) * TriangleNum);
508 vArray = (GLfloat*)malloc(sizeof(GLfloat) * TriangleNum * 24);
510 for (i = 0; i < vertexNum; i++) {
511 funpackf(tfile, "Bf Bf Bf", &vertex[i].x, &vertex[i].y, &vertex[i].z);
514 for (i = 0; i < TriangleNum; i++) {
515 //funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
517 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
518 Triangles[i].vertex[ 0] = vertex[ 0];
519 Triangles[i].vertex[ 1] = vertex[ 2];
520 Triangles[i].vertex[ 2] = vertex[ 4];
521 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
522 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
525 modelTexture.xsz = 0;
531 for (i = 0; i < vertexNum; i++) {
536 boundingsphereradius = 0;
537 for (i = 0; i < vertexNum; i++) {
538 for (j = 0; j < vertexNum; j++) {
539 if (j != i && distsq(&vertex[j], &vertex[i]) / 2 > boundingsphereradius) {
540 boundingsphereradius = distsq(&vertex[j], &vertex[i]) / 2;
541 boundingspherecenter = (vertex[i] + vertex[j]) / 2;
545 boundingsphereradius = fast_sqrt(boundingsphereradius);
550 bool Model::loaddecal(const char *filename, bool texture )
557 // Changing the filename so that its more os specific
558 char * FixedFN = ConvertFileName(filename);
560 LOG(std::string("Loading decal...") + FixedFN);
566 tfile = fopen( FixedFN, "rb" );
567 // read model settings
570 fseek(tfile, 0, SEEK_SET);
571 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
573 // read the model data
579 owner = (int*)malloc(sizeof(int) * vertexNum);
580 possible = (int*)malloc(sizeof(int) * TriangleNum);
581 vertex = (XYZ*)malloc(sizeof(XYZ) * vertexNum);
582 normals = (XYZ*)malloc(sizeof(XYZ) * vertexNum);
583 facenormals = (XYZ*)malloc(sizeof(XYZ) * TriangleNum);
584 Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle) * TriangleNum);
585 vArray = (GLfloat*)malloc(sizeof(GLfloat) * TriangleNum * 24);
588 for (i = 0; i < vertexNum; i++) {
589 funpackf(tfile, "Bf Bf Bf", &vertex[i].x, &vertex[i].y, &vertex[i].z);
592 for (i = 0; i < TriangleNum; i++) {
593 //funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
595 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
596 Triangles[i].vertex[ 0] = vertex[ 0];
597 Triangles[i].vertex[ 1] = vertex[ 2];
598 Triangles[i].vertex[ 2] = vertex[ 4];
599 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
600 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
604 modelTexture.xsz = 0;
610 for (i = 0; i < vertexNum; i++) {
614 boundingsphereradius = 0;
615 for (i = 0; i < vertexNum; i++) {
616 for (j = 0; j < vertexNum; j++) {
617 if (j != i && distsq(&vertex[j], &vertex[i]) / 2 > boundingsphereradius) {
618 boundingsphereradius = distsq(&vertex[j], &vertex[i]) / 2;
619 boundingspherecenter = (vertex[i] + vertex[j]) / 2;
623 boundingsphereradius = fast_sqrt(boundingsphereradius);
626 if (!decaltexcoords) {
627 decaltexcoords = (float***)malloc(sizeof(float**)*max_model_decals);
628 for (i = 0; i < max_model_decals; i++) {
629 decaltexcoords[i] = (float**)malloc(sizeof(float*) * 3);
630 for (j = 0; j < 3; j++) {
631 decaltexcoords[i][j] = (float*)malloc(sizeof(float) * 2);
634 decalvertex = (XYZ**)malloc(sizeof(XYZ*)*max_model_decals);
635 for (i = 0; i < max_model_decals; i++) {
636 decalvertex[i] = (XYZ*)malloc(sizeof(XYZ) * 3);
639 decaltype = (int*)malloc(sizeof(int) * max_model_decals);
640 decalopacity = (float*)malloc(sizeof(float) * max_model_decals);
641 decalrotation = (float*)malloc(sizeof(float) * max_model_decals);
642 decalalivetime = (float*)malloc(sizeof(float) * max_model_decals);
643 decalposition = (XYZ*)malloc(sizeof(XYZ) * max_model_decals);
649 bool Model::loadraw(char *filename )
656 LOG(std::string("Loading raw...") + filename);
658 //~ int oldvertexNum, oldTriangleNum;
659 //~ oldvertexNum = vertexNum;
660 //~ oldTriangleNum = TriangleNum;
665 tfile = fopen( ConvertFileName(filename), "rb" );
666 // read model settings
669 fseek(tfile, 0, SEEK_SET);
670 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
672 // read the model data
677 owner = (int*)malloc(sizeof(int) * vertexNum);
678 possible = (int*)malloc(sizeof(int) * TriangleNum);
679 vertex = (XYZ*)malloc(sizeof(XYZ) * vertexNum);
680 Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle) * TriangleNum);
681 vArray = (GLfloat*)malloc(sizeof(GLfloat) * TriangleNum * 24);
684 for (i = 0; i < vertexNum; i++) {
685 funpackf(tfile, "Bf Bf Bf", &vertex[i].x, &vertex[i].y, &vertex[i].z);
688 for (i = 0; i < TriangleNum; i++) {
689 //funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
691 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
692 Triangles[i].vertex[ 0] = vertex[ 0];
693 Triangles[i].vertex[ 1] = vertex[ 2];
694 Triangles[i].vertex[ 2] = vertex[ 4];
695 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
696 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
702 for (i = 0; i < vertexNum; i++) {
710 void Model::UniformTexCoords()
713 for (i = 0; i < TriangleNum; i++) {
714 Triangles[i].gy[0] = vertex[Triangles[i].vertex[0]].y;
715 Triangles[i].gy[1] = vertex[Triangles[i].vertex[1]].y;
716 Triangles[i].gy[2] = vertex[Triangles[i].vertex[2]].y;
717 Triangles[i].gx[0] = vertex[Triangles[i].vertex[0]].x;
718 Triangles[i].gx[1] = vertex[Triangles[i].vertex[1]].x;
719 Triangles[i].gx[2] = vertex[Triangles[i].vertex[2]].x;
725 void Model::FlipTexCoords()
728 for (i = 0; i < TriangleNum; i++) {
729 Triangles[i].gy[0] = -Triangles[i].gy[0];
730 Triangles[i].gy[1] = -Triangles[i].gy[1];
731 Triangles[i].gy[2] = -Triangles[i].gy[2];
736 void Model::ScaleTexCoords(float howmuch)
739 for (i = 0; i < TriangleNum; i++) {
740 Triangles[i].gx[0] *= howmuch;
741 Triangles[i].gx[1] *= howmuch;
742 Triangles[i].gx[2] *= howmuch;
743 Triangles[i].gy[0] *= howmuch;
744 Triangles[i].gy[1] *= howmuch;
745 Triangles[i].gy[2] *= howmuch;
750 void Model::Scale(float xscale, float yscale, float zscale)
753 for (i = 0; i < vertexNum; i++) {
754 vertex[i].x *= xscale;
755 vertex[i].y *= yscale;
756 vertex[i].z *= zscale;
762 boundingsphereradius = 0;
763 for (i = 0; i < vertexNum; i++) {
764 for (j = 0; j < vertexNum; j++) {
765 if (j != i && distsq(&vertex[j], &vertex[i]) / 2 > boundingsphereradius) {
766 boundingsphereradius = distsq(&vertex[j], &vertex[i]) / 2;
767 boundingspherecenter = (vertex[i] + vertex[j]) / 2;
771 boundingsphereradius = fast_sqrt(boundingsphereradius);
774 void Model::ScaleNormals(float xscale, float yscale, float zscale)
776 if (type != normaltype && type != decalstype)
779 for (i = 0; i < vertexNum; i++) {
780 normals[i].x *= xscale;
781 normals[i].y *= yscale;
782 normals[i].z *= zscale;
784 for (i = 0; i < TriangleNum; i++) {
785 facenormals[i].x *= xscale;
786 facenormals[i].y *= yscale;
787 facenormals[i].z *= zscale;
792 void Model::Translate(float xtrans, float ytrans, float ztrans)
795 for (i = 0; i < vertexNum; i++) {
796 vertex[i].x += xtrans;
797 vertex[i].y += ytrans;
798 vertex[i].z += ztrans;
803 boundingsphereradius = 0;
804 for (i = 0; i < vertexNum; i++) {
805 for (j = 0; j < vertexNum; j++) {
806 if (j != i && distsq(&vertex[j], &vertex[i]) / 2 > boundingsphereradius) {
807 boundingsphereradius = distsq(&vertex[j], &vertex[i]) / 2;
808 boundingspherecenter = (vertex[i] + vertex[j]) / 2;
812 boundingsphereradius = fast_sqrt(boundingsphereradius);
815 void Model::Rotate(float xang, float yang, float zang)
818 for (i = 0; i < vertexNum; i++) {
819 vertex[i] = DoRotation(vertex[i], xang, yang, zang);
824 boundingsphereradius = 0;
825 for (i = 0; i < vertexNum; i++) {
826 for (j = 0; j < vertexNum; j++) {
827 if (j != i && distsq(&vertex[j], &vertex[i]) / 2 > boundingsphereradius) {
828 boundingsphereradius = distsq(&vertex[j], &vertex[i]) / 2;
829 boundingspherecenter = (vertex[i] + vertex[j]) / 2;
833 boundingsphereradius = fast_sqrt(boundingsphereradius);
837 void Model::CalculateNormals(bool facenormalise)
840 Game::LoadingScreen();
842 if (type != normaltype && type != decalstype)
845 for (i = 0; i < vertexNum; i++) {
851 for (i = 0; i < TriangleNum; i++) {
852 CrossProduct(vertex[Triangles[i].vertex[1]] - vertex[Triangles[i].vertex[0]], vertex[Triangles[i].vertex[2]] - vertex[Triangles[i].vertex[0]], &facenormals[i]);
854 normals[Triangles[i].vertex[0]].x += facenormals[i].x;
855 normals[Triangles[i].vertex[0]].y += facenormals[i].y;
856 normals[Triangles[i].vertex[0]].z += facenormals[i].z;
858 normals[Triangles[i].vertex[1]].x += facenormals[i].x;
859 normals[Triangles[i].vertex[1]].y += facenormals[i].y;
860 normals[Triangles[i].vertex[1]].z += facenormals[i].z;
862 normals[Triangles[i].vertex[2]].x += facenormals[i].x;
863 normals[Triangles[i].vertex[2]].y += facenormals[i].y;
864 normals[Triangles[i].vertex[2]].z += facenormals[i].z;
866 Normalise(&facenormals[i]);
868 for (i = 0; i < vertexNum; i++) {
869 Normalise(&normals[i]);
872 UpdateVertexArrayNoTex();
875 void Model::drawimmediate()
878 glBegin(GL_TRIANGLES);
879 for (int i = 0; i < TriangleNum; i++) {
880 glTexCoord2f(Triangles[i].gx[0], Triangles[i].gy[0]);
882 glColor3f(normals[Triangles[i].vertex[0]].x, normals[Triangles[i].vertex[0]].y, normals[Triangles[i].vertex[0]].z);
884 glNormal3f(normals[Triangles[i].vertex[0]].x, normals[Triangles[i].vertex[0]].y, normals[Triangles[i].vertex[0]].z);
886 glNormal3f(facenormals[i].x, facenormals[i].y, facenormals[i].y);
887 glVertex3f(vertex[Triangles[i].vertex[0]].x, vertex[Triangles[i].vertex[0]].y, vertex[Triangles[i].vertex[0]].z);
889 glTexCoord2f(Triangles[i].gx[1], Triangles[i].gy[1]);
891 glColor3f(normals[Triangles[i].vertex[1]].x, normals[Triangles[i].vertex[1]].y, normals[Triangles[i].vertex[1]].z);
893 glNormal3f(normals[Triangles[i].vertex[1]].x, normals[Triangles[i].vertex[1]].y, normals[Triangles[i].vertex[1]].z);
895 glNormal3f(facenormals[i].x, facenormals[i].y, facenormals[i].y);
896 glVertex3f(vertex[Triangles[i].vertex[1]].x, vertex[Triangles[i].vertex[1]].y, vertex[Triangles[i].vertex[1]].z);
898 glTexCoord2f(Triangles[i].gx[2], Triangles[i].gy[2]);
900 glColor3f(normals[Triangles[i].vertex[2]].x, normals[Triangles[i].vertex[2]].y, normals[Triangles[i].vertex[2]].z);
902 glNormal3f(normals[Triangles[i].vertex[2]].x, normals[Triangles[i].vertex[2]].y, normals[Triangles[i].vertex[2]].z);
904 glNormal3f(facenormals[i].x, facenormals[i].y, facenormals[i].y);
905 glVertex3f(vertex[Triangles[i].vertex[2]].x, vertex[Triangles[i].vertex[2]].y, vertex[Triangles[i].vertex[2]].z);
912 if (type != normaltype && type != decalstype)
915 glEnableClientState(GL_NORMAL_ARRAY);
916 glEnableClientState(GL_VERTEX_ARRAY);
917 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
920 glInterleavedArrays( GL_T2F_N3F_V3F, 8 * sizeof(GLfloat), &vArray[0]);
922 glInterleavedArrays( GL_T2F_C3F_V3F, 8 * sizeof(GLfloat), &vArray[0]);
926 glLockArraysEXT( 0, TriangleNum * 3);
928 glDrawArrays(GL_TRIANGLES, 0, TriangleNum * 3);
935 glDisableClientState(GL_NORMAL_ARRAY);
937 glDisableClientState(GL_COLOR_ARRAY);
938 glDisableClientState(GL_VERTEX_ARRAY);
939 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
943 //TODO: phase out in favor of Texture
944 void Model::drawdifftex(GLuint texture)
946 glEnableClientState(GL_NORMAL_ARRAY);
947 glEnableClientState(GL_VERTEX_ARRAY);
948 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
950 glInterleavedArrays( GL_T2F_N3F_V3F, 8 * sizeof(GLfloat), &vArray[0]);
952 glInterleavedArrays( GL_T2F_C3F_V3F, 8 * sizeof(GLfloat), &vArray[0]);
954 glBindTexture(GL_TEXTURE_2D, (unsigned long)texture);
955 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
956 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
960 glLockArraysEXT( 0, TriangleNum * 3);
962 glDrawArrays(GL_TRIANGLES, 0, TriangleNum * 3);
969 glDisableClientState(GL_NORMAL_ARRAY);
971 glDisableClientState(GL_COLOR_ARRAY);
972 glDisableClientState(GL_VERTEX_ARRAY);
973 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
976 void Model::drawdifftex(Texture texture)
978 glEnableClientState(GL_NORMAL_ARRAY);
979 glEnableClientState(GL_VERTEX_ARRAY);
980 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
982 glInterleavedArrays( GL_T2F_N3F_V3F, 8 * sizeof(GLfloat), &vArray[0]);
984 glInterleavedArrays( GL_T2F_C3F_V3F, 8 * sizeof(GLfloat), &vArray[0]);
987 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
988 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
992 glLockArraysEXT( 0, TriangleNum * 3);
994 glDrawArrays(GL_TRIANGLES, 0, TriangleNum * 3);
1001 glDisableClientState(GL_NORMAL_ARRAY);
1003 glDisableClientState(GL_COLOR_ARRAY);
1004 glDisableClientState(GL_VERTEX_ARRAY);
1005 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1008 void Model::drawdecals(Texture shadowtexture, Texture bloodtexture, Texture bloodtexture2, Texture breaktexture)
1011 if (type != decalstype)
1014 static int lasttype;
1021 glDisable(GL_LIGHTING);
1022 glDisable(GL_CULL_FACE);
1023 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1025 if (numdecals > max_model_decals)
1026 numdecals = max_model_decals;
1027 for (i = 0; i < numdecals; i++) {
1028 if (decaltype[i] == blooddecalfast && decalalivetime[i] < 2)
1029 decalalivetime[i] = 2;
1031 if (decaltype[i] == shadowdecal && decaltype[i] != lasttype) {
1032 shadowtexture.bind();
1035 glAlphaFunc(GL_GREATER, 0.0001);
1036 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1039 if (decaltype[i] == breakdecal && decaltype[i] != lasttype) {
1040 breaktexture.bind();
1043 glAlphaFunc(GL_GREATER, 0.0001);
1044 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1047 if ((decaltype[i] == blooddecal || decaltype[i] == blooddecalslow) && decaltype[i] != lasttype) {
1048 bloodtexture.bind();
1051 glAlphaFunc(GL_GREATER, 0.15);
1052 glBlendFunc(GL_ONE, GL_ZERO);
1055 if ((decaltype[i] == blooddecalfast) && decaltype[i] != lasttype) {
1056 bloodtexture2.bind();
1059 glAlphaFunc(GL_GREATER, 0.15);
1060 glBlendFunc(GL_ONE, GL_ZERO);
1063 if (decaltype[i] == shadowdecal) {
1064 glColor4f(1, 1, 1, decalopacity[i]);
1066 if (decaltype[i] == breakdecal) {
1067 glColor4f(1, 1, 1, decalopacity[i]);
1068 if (decalalivetime[i] > 58)
1069 glColor4f(1, 1, 1, decalopacity[i] * (60 - decalalivetime[i]) / 2);
1071 if ((decaltype[i] == blooddecal || decaltype[i] == blooddecalfast || decaltype[i] == blooddecalslow)) {
1072 glColor4f(1, 1, 1, decalopacity[i]);
1073 if (decalalivetime[i] < 4)
1074 glColor4f(1, 1, 1, decalopacity[i]*decalalivetime[i]*.25);
1075 if (decalalivetime[i] > 58)
1076 glColor4f(1, 1, 1, decalopacity[i] * (60 - decalalivetime[i]) / 2);
1078 lasttype = decaltype[i];
1079 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1080 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
1082 glMatrixMode(GL_MODELVIEW);
1084 glBegin(GL_TRIANGLES);
1085 for (int j = 0; j < 3; j++) {
1086 glTexCoord2f(decaltexcoords[i][j][0], decaltexcoords[i][j][1]);
1087 glVertex3f(decalvertex[i][j].x, decalvertex[i][j].y, decalvertex[i][j].z);
1092 for (i = numdecals - 1; i >= 0; i--) {
1093 decalalivetime[i] += multiplier;
1094 if (decaltype[i] == blooddecalslow)
1095 decalalivetime[i] -= multiplier * 2 / 3;
1096 if (decaltype[i] == blooddecalfast)
1097 decalalivetime[i] += multiplier * 4;
1098 if (decaltype[i] == shadowdecal)
1100 if ((decaltype[i] == blooddecal || decaltype[i] == blooddecalfast || decaltype[i] == blooddecalslow) && decalalivetime[i] >= 60)
1103 glAlphaFunc(GL_GREATER, 0.0001);
1104 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1108 void Model::DeleteDecal(int which)
1111 if (type != decalstype)
1113 decaltype[which] = decaltype[numdecals - 1];
1114 decalposition[which] = decalposition[numdecals - 1];
1115 for (int i = 0; i < 3; i++) {
1116 decalvertex[which][i] = decalvertex[numdecals - 1][i];
1117 decaltexcoords[which][i][0] = decaltexcoords[numdecals - 1][i][0];
1118 decaltexcoords[which][i][1] = decaltexcoords[numdecals - 1][i][1];
1120 decalrotation[which] = decalrotation[numdecals - 1];
1121 decalalivetime[which] = decalalivetime[numdecals - 1];
1122 decalopacity[which] = decalopacity[numdecals - 1];
1127 void Model::MakeDecal(int atype, XYZ *where, float *size, float *opacity, float *rotation)
1130 if (type != decalstype)
1133 static float placex, placez;
1135 static float distance;
1139 if (distsq(where, &boundingspherecenter) < (boundingsphereradius + *size) * (boundingsphereradius + *size))
1140 for (i = 0; i < TriangleNum; i++) {
1141 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)) {
1142 decalposition[numdecals] = *where;
1143 decaltype[numdecals] = atype;
1144 decalrotation[numdecals] = *rotation;
1145 decalalivetime[numdecals] = 0;
1146 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);
1147 decalopacity[numdecals] = *opacity - distance / 10;
1149 if (decalopacity[numdecals > 0]) {
1150 placex = vertex[Triangles[i].vertex[0]].x;
1151 placez = vertex[Triangles[i].vertex[0]].z;
1153 decaltexcoords[numdecals][0][0] = (placex - where->x) / (*size) / 2 + .5;
1154 decaltexcoords[numdecals][0][1] = (placez - where->z) / (*size) / 2 + .5;
1156 decalvertex[numdecals][0].x = placex;
1157 decalvertex[numdecals][0].z = placez;
1158 decalvertex[numdecals][0].y = vertex[Triangles[i].vertex[0]].y;
1161 placex = vertex[Triangles[i].vertex[1]].x;
1162 placez = vertex[Triangles[i].vertex[1]].z;
1164 decaltexcoords[numdecals][1][0] = (placex - where->x) / (*size) / 2 + .5;
1165 decaltexcoords[numdecals][1][1] = (placez - where->z) / (*size) / 2 + .5;
1167 decalvertex[numdecals][1].x = placex;
1168 decalvertex[numdecals][1].z = placez;
1169 decalvertex[numdecals][1].y = vertex[Triangles[i].vertex[1]].y;
1172 placex = vertex[Triangles[i].vertex[2]].x;
1173 placez = vertex[Triangles[i].vertex[2]].z;
1175 decaltexcoords[numdecals][2][0] = (placex - where->x) / (*size) / 2 + .5;
1176 decaltexcoords[numdecals][2][1] = (placez - where->z) / (*size) / 2 + .5;
1178 decalvertex[numdecals][2].x = placex;
1179 decalvertex[numdecals][2].z = placez;
1180 decalvertex[numdecals][2].y = vertex[Triangles[i].vertex[2]].y;
1182 if (!(decaltexcoords[numdecals][0][0] < 0 && decaltexcoords[numdecals][1][0] < 0 && decaltexcoords[numdecals][2][0] < 0))
1183 if (!(decaltexcoords[numdecals][0][1] < 0 && decaltexcoords[numdecals][1][1] < 0 && decaltexcoords[numdecals][2][1] < 0))
1184 if (!(decaltexcoords[numdecals][0][0] > 1 && decaltexcoords[numdecals][1][0] > 1 && decaltexcoords[numdecals][2][0] > 1))
1185 if (!(decaltexcoords[numdecals][0][1] > 1 && decaltexcoords[numdecals][1][1] > 1 && decaltexcoords[numdecals][2][1] > 1)) {
1186 if (decalrotation[numdecals]) {
1187 for (j = 0; j < 3; j++) {
1189 rot.x = decaltexcoords[numdecals][j][0] - .5;
1190 rot.z = decaltexcoords[numdecals][j][1] - .5;
1191 rot = DoRotation(rot, 0, -decalrotation[numdecals], 0);
1192 decaltexcoords[numdecals][j][0] = rot.x + .5;
1193 decaltexcoords[numdecals][j][1] = rot.z + .5;
1196 if (numdecals < max_model_decals - 1)
1205 void Model::MakeDecal(int atype, XYZ where, float size, float opacity, float rotation)
1208 if (type != decalstype)
1211 static float placex, placez;
1213 static float distance;
1217 if (distsq(&where, &boundingspherecenter) < (boundingsphereradius + size) * (boundingsphereradius + size))
1218 for (i = 0; i < TriangleNum; i++) {
1219 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))));
1220 if (distance < .02 && abs(facenormals[i].y) > abs(facenormals[i].x) && abs(facenormals[i].y) > abs(facenormals[i].z)) {
1221 decalposition[numdecals] = where;
1222 decaltype[numdecals] = atype;
1223 decalrotation[numdecals] = rotation;
1224 decalalivetime[numdecals] = 0;
1225 decalopacity[numdecals] = opacity - distance / 10;
1227 if (decalopacity[numdecals > 0]) {
1228 placex = vertex[Triangles[i].vertex[0]].x;
1229 placez = vertex[Triangles[i].vertex[0]].z;
1231 decaltexcoords[numdecals][0][0] = (placex - where.x) / (size) / 2 + .5;
1232 decaltexcoords[numdecals][0][1] = (placez - where.z) / (size) / 2 + .5;
1234 decalvertex[numdecals][0].x = placex;
1235 decalvertex[numdecals][0].z = placez;
1236 decalvertex[numdecals][0].y = vertex[Triangles[i].vertex[0]].y;
1239 placex = vertex[Triangles[i].vertex[1]].x;
1240 placez = vertex[Triangles[i].vertex[1]].z;
1242 decaltexcoords[numdecals][1][0] = (placex - where.x) / (size) / 2 + .5;
1243 decaltexcoords[numdecals][1][1] = (placez - where.z) / (size) / 2 + .5;
1245 decalvertex[numdecals][1].x = placex;
1246 decalvertex[numdecals][1].z = placez;
1247 decalvertex[numdecals][1].y = vertex[Triangles[i].vertex[1]].y;
1250 placex = vertex[Triangles[i].vertex[2]].x;
1251 placez = vertex[Triangles[i].vertex[2]].z;
1253 decaltexcoords[numdecals][2][0] = (placex - where.x) / (size) / 2 + .5;
1254 decaltexcoords[numdecals][2][1] = (placez - where.z) / (size) / 2 + .5;
1256 decalvertex[numdecals][2].x = placex;
1257 decalvertex[numdecals][2].z = placez;
1258 decalvertex[numdecals][2].y = vertex[Triangles[i].vertex[2]].y;
1260 if (!(decaltexcoords[numdecals][0][0] < 0 && decaltexcoords[numdecals][1][0] < 0 && decaltexcoords[numdecals][2][0] < 0))
1261 if (!(decaltexcoords[numdecals][0][1] < 0 && decaltexcoords[numdecals][1][1] < 0 && decaltexcoords[numdecals][2][1] < 0))
1262 if (!(decaltexcoords[numdecals][0][0] > 1 && decaltexcoords[numdecals][1][0] > 1 && decaltexcoords[numdecals][2][0] > 1))
1263 if (!(decaltexcoords[numdecals][0][1] > 1 && decaltexcoords[numdecals][1][1] > 1 && decaltexcoords[numdecals][2][1] > 1)) {
1264 if (decalrotation[numdecals]) {
1265 for (j = 0; j < 3; j++) {
1267 rot.x = decaltexcoords[numdecals][j][0] - .5;
1268 rot.z = decaltexcoords[numdecals][j][1] - .5;
1269 rot = DoRotation(rot, 0, -decalrotation[numdecals], 0);
1270 decaltexcoords[numdecals][j][0] = rot.x + .5;
1271 decaltexcoords[numdecals][j][1] = rot.z + .5;
1274 if (numdecals < max_model_decals - 1)
1278 } else if (distance < .02 && abs(facenormals[i].x) > abs(facenormals[i].y) && abs(facenormals[i].x) > abs(facenormals[i].z)) {
1279 decalposition[numdecals] = where;
1280 decaltype[numdecals] = atype;
1281 decalrotation[numdecals] = rotation;
1282 decalalivetime[numdecals] = 0;
1283 decalopacity[numdecals] = opacity - distance / 10;
1285 if (decalopacity[numdecals > 0]) {
1286 placex = vertex[Triangles[i].vertex[0]].y;
1287 placez = vertex[Triangles[i].vertex[0]].z;
1289 decaltexcoords[numdecals][0][0] = (placex - where.y) / (size) / 2 + .5;
1290 decaltexcoords[numdecals][0][1] = (placez - where.z) / (size) / 2 + .5;
1292 decalvertex[numdecals][0].x = vertex[Triangles[i].vertex[0]].x;
1293 decalvertex[numdecals][0].z = placez;
1294 decalvertex[numdecals][0].y = placex;
1297 placex = vertex[Triangles[i].vertex[1]].y;
1298 placez = vertex[Triangles[i].vertex[1]].z;
1300 decaltexcoords[numdecals][1][0] = (placex - where.y) / (size) / 2 + .5;
1301 decaltexcoords[numdecals][1][1] = (placez - where.z) / (size) / 2 + .5;
1303 decalvertex[numdecals][1].x = vertex[Triangles[i].vertex[1]].x;
1304 decalvertex[numdecals][1].z = placez;
1305 decalvertex[numdecals][1].y = placex;
1308 placex = vertex[Triangles[i].vertex[2]].y;
1309 placez = vertex[Triangles[i].vertex[2]].z;
1311 decaltexcoords[numdecals][2][0] = (placex - where.y) / (size) / 2 + .5;
1312 decaltexcoords[numdecals][2][1] = (placez - where.z) / (size) / 2 + .5;
1314 decalvertex[numdecals][2].x = vertex[Triangles[i].vertex[2]].x;
1315 decalvertex[numdecals][2].z = placez;
1316 decalvertex[numdecals][2].y = placex;
1318 if (!(decaltexcoords[numdecals][0][0] < 0 && decaltexcoords[numdecals][1][0] < 0 && decaltexcoords[numdecals][2][0] < 0))
1319 if (!(decaltexcoords[numdecals][0][1] < 0 && decaltexcoords[numdecals][1][1] < 0 && decaltexcoords[numdecals][2][1] < 0))
1320 if (!(decaltexcoords[numdecals][0][0] > 1 && decaltexcoords[numdecals][1][0] > 1 && decaltexcoords[numdecals][2][0] > 1))
1321 if (!(decaltexcoords[numdecals][0][1] > 1 && decaltexcoords[numdecals][1][1] > 1 && decaltexcoords[numdecals][2][1] > 1)) {
1322 if (decalrotation[numdecals]) {
1323 for (j = 0; j < 3; j++) {
1325 rot.x = decaltexcoords[numdecals][j][0] - .5;
1326 rot.z = decaltexcoords[numdecals][j][1] - .5;
1327 rot = DoRotation(rot, 0, -decalrotation[numdecals], 0);
1328 decaltexcoords[numdecals][j][0] = rot.x + .5;
1329 decaltexcoords[numdecals][j][1] = rot.z + .5;
1332 if (numdecals < max_model_decals - 1)
1336 } else if (distance < .02 && abs(facenormals[i].z) > abs(facenormals[i].y) && abs(facenormals[i].z) > abs(facenormals[i].x)) {
1337 decalposition[numdecals] = where;
1338 decaltype[numdecals] = atype;
1339 decalrotation[numdecals] = rotation;
1340 decalalivetime[numdecals] = 0;
1341 decalopacity[numdecals] = opacity - distance / 10;
1343 if (decalopacity[numdecals > 0]) {
1344 placex = vertex[Triangles[i].vertex[0]].x;
1345 placez = vertex[Triangles[i].vertex[0]].y;
1347 decaltexcoords[numdecals][0][0] = (placex - where.x) / (size) / 2 + .5;
1348 decaltexcoords[numdecals][0][1] = (placez - where.y) / (size) / 2 + .5;
1350 decalvertex[numdecals][0].x = placex;
1351 decalvertex[numdecals][0].z = vertex[Triangles[i].vertex[0]].z;
1352 decalvertex[numdecals][0].y = placez;
1355 placex = vertex[Triangles[i].vertex[1]].x;
1356 placez = vertex[Triangles[i].vertex[1]].y;
1358 decaltexcoords[numdecals][1][0] = (placex - where.x) / (size) / 2 + .5;
1359 decaltexcoords[numdecals][1][1] = (placez - where.y) / (size) / 2 + .5;
1361 decalvertex[numdecals][1].x = placex;
1362 decalvertex[numdecals][1].z = vertex[Triangles[i].vertex[1]].z;
1363 decalvertex[numdecals][1].y = placez;
1366 placex = vertex[Triangles[i].vertex[2]].x;
1367 placez = vertex[Triangles[i].vertex[2]].y;
1369 decaltexcoords[numdecals][2][0] = (placex - where.x) / (size) / 2 + .5;
1370 decaltexcoords[numdecals][2][1] = (placez - where.y) / (size) / 2 + .5;
1372 decalvertex[numdecals][2].x = placex;
1373 decalvertex[numdecals][2].z = vertex[Triangles[i].vertex[2]].z;
1374 decalvertex[numdecals][2].y = placez;
1376 if (!(decaltexcoords[numdecals][0][0] < 0 && decaltexcoords[numdecals][1][0] < 0 && decaltexcoords[numdecals][2][0] < 0))
1377 if (!(decaltexcoords[numdecals][0][1] < 0 && decaltexcoords[numdecals][1][1] < 0 && decaltexcoords[numdecals][2][1] < 0))
1378 if (!(decaltexcoords[numdecals][0][0] > 1 && decaltexcoords[numdecals][1][0] > 1 && decaltexcoords[numdecals][2][0] > 1))
1379 if (!(decaltexcoords[numdecals][0][1] > 1 && decaltexcoords[numdecals][1][1] > 1 && decaltexcoords[numdecals][2][1] > 1)) {
1380 if (decalrotation[numdecals]) {
1381 for (j = 0; j < 3; j++) {
1383 rot.x = decaltexcoords[numdecals][j][0] - .5;
1384 rot.z = decaltexcoords[numdecals][j][1] - .5;
1385 rot = DoRotation(rot, 0, -decalrotation[numdecals], 0);
1386 decaltexcoords[numdecals][j][0] = rot.x + .5;
1387 decaltexcoords[numdecals][j][1] = rot.z + .5;
1390 if (numdecals < max_model_decals - 1)
1402 textureptr.destroy();
1405 void Model::deallocate()
1439 if (decaltexcoords) {
1440 for (i = 0; i < max_model_decals; i++) {
1441 for (j = 0; j < 3; j++) {
1442 free(decaltexcoords[i][j]);
1444 free(decaltexcoords[i]);
1446 free(decaltexcoords);
1452 for (i = 0; i < max_model_decals; i++) {
1453 free(decalvertex[i]);
1466 free(decalrotation);
1469 free(decalalivetime);
1472 free(decalposition);
1479 vertexNum = 0, TriangleNum = 0;
1482 type = 0, oldtype = 0;
1492 memset(&modelTexture, 0, sizeof(modelTexture));
1496 boundingspherecenter = 0;
1497 boundingsphereradius = 0;