2 Copyright (C) 2003, 2010 - Wolfire Games
4 This file is part of Lugaru.
6 Lugaru is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 2
9 of the License, or (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15 See the GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 extern float multiplier;
26 extern float viewdistance;
28 extern float fadestart;
29 extern float texdetail;
32 extern bool visibleloading;
34 int Model::LineCheck(XYZ *p1, XYZ *p2, XYZ *p, XYZ *move, float *rotate)
37 static float distance;
38 static float olddistance;
39 static int intersecting;
40 static int firstintersecting;
46 *p1 = DoRotation(*p1, 0, -*rotate, 0);
48 *p2 = DoRotation(*p2, 0, -*rotate, 0);
49 if (!sphere_line_intersection(p1, p2, &boundingspherecenter, &boundingsphereradius))
51 firstintersecting = -1;
53 for (j = 0; j < TriangleNum; j++) {
54 intersecting = LineFacetd(p1, p2, &vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[1]], &vertex[Triangles[j].vertex[2]], &facenormals[j], &point);
55 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);
56 if ((distance < olddistance || firstintersecting == -1) && intersecting) {
57 olddistance = distance;
58 firstintersecting = j;
64 *p = DoRotation(*p, 0, *rotate, 0);
66 return firstintersecting;
69 int Model::LineCheckSlide(XYZ *p1, XYZ *p2, XYZ *p, XYZ *move, float *rotate)
72 static float distance;
73 static float olddistance;
74 static int intersecting;
75 static int firstintersecting;
80 if (!sphere_line_intersection(p1, p2, &boundingspherecenter, &boundingsphereradius))
82 firstintersecting = -1;
84 *p1 = DoRotation(*p1, 0, -*rotate, 0);
86 *p2 = DoRotation(*p2, 0, -*rotate, 0);
88 for (j = 0; j < TriangleNum; j++) {
89 intersecting = LineFacetd(p1, p2, &vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[1]], &vertex[Triangles[j].vertex[2]], &facenormals[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 = j;
97 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)));
98 *p2 -= facenormals[firstintersecting] * distance;
101 *p2 = DoRotation(*p2, 0, *rotate, 0);
103 return firstintersecting;
106 int Model::LineCheckPossible(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);
125 if (numpossible > 0 && numpossible < TriangleNum)
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];
139 *p = DoRotation(*p, 0, *rotate, 0);
141 return firstintersecting;
144 int Model::LineCheckSlidePossible(XYZ *p1, XYZ *p2, XYZ *p, XYZ *move, float *rotate)
147 static float distance;
148 static float olddistance;
149 static int intersecting;
150 static int firstintersecting;
155 if (!sphere_line_intersection(p1, p2, &boundingspherecenter, &boundingsphereradius))
157 firstintersecting = -1;
159 *p1 = DoRotation(*p1, 0, -*rotate, 0);
161 *p2 = DoRotation(*p2, 0, -*rotate, 0);
164 for (j = 0; j < numpossible; j++) {
165 if (possible[j] >= 0 && possible[j] < TriangleNum) {
166 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);
167 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);
168 if ((distance < olddistance || firstintersecting == -1) && intersecting) {
169 olddistance = distance;
170 firstintersecting = possible[j];
175 if (firstintersecting > 0) {
176 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)));
177 *p2 -= facenormals[firstintersecting] * distance;
181 *p2 = DoRotation(*p2, 0, *rotate, 0);
183 return firstintersecting;
186 int Model::SphereCheck(XYZ *p1, float radius, XYZ *p, XYZ *move, float *rotate)
189 static float distance;
190 static float olddistance;
191 static int intersecting;
192 static int firstintersecting;
195 static XYZ start, end;
197 firstintersecting = -1;
202 *p1 = DoRotation(*p1, 0, -*rotate, 0);
203 if (distsq(p1, &boundingspherecenter) > radius * radius + boundingsphereradius * boundingsphereradius)
206 for (i = 0; i < 4; i++) {
207 for (j = 0; j < TriangleNum; j++) {
209 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)));
210 if (distance < radius) {
211 point = *p1 - facenormals[j] * distance;
212 if (PointInTriangle( &point, facenormals[j], &vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[1]], &vertex[Triangles[j].vertex[2]]))
215 intersecting = sphere_line_intersection(&vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[1]], p1, &radius);
217 intersecting = sphere_line_intersection(&vertex[Triangles[j].vertex[1]], &vertex[Triangles[j].vertex[2]], p1, &radius);
219 intersecting = sphere_line_intersection(&vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[2]], p1, &radius);
221 *p1 += facenormals[j] * (distance - radius);
225 if(LineFacetd(&start,&end,&vertex[Triangles[j].vertex[0]],&vertex[Triangles[j].vertex[1]],&vertex[Triangles[j].vertex[2]],&facenormals[j],&point)){
226 p1->y=point.y+radius;
230 if ((distance < olddistance || firstintersecting == -1) && intersecting) {
231 olddistance = distance;
232 firstintersecting = j;
238 *p = DoRotation(*p, 0, *rotate, 0);
241 *p1 = DoRotation(*p1, 0, *rotate, 0);
243 return firstintersecting;
246 int Model::SphereCheckPossible(XYZ *p1, float radius, XYZ *move, float *rotate)
249 static float distance;
250 static float olddistance;
251 static int intersecting;
252 static int firstintersecting;
255 static XYZ start, end;
257 firstintersecting = -1;
265 *p1 = DoRotation(*p1, 0, -*rotate, 0);
266 if (distsq(p1, &boundingspherecenter) > radius * radius + boundingsphereradius * boundingsphereradius) {
271 for (j = 0; j < TriangleNum; j++) {
273 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)));
274 if (distance < radius) {
275 point = *p1 - facenormals[j] * distance;
276 if (PointInTriangle( &point, facenormals[j], &vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[1]], &vertex[Triangles[j].vertex[2]]))
279 intersecting = sphere_line_intersection(&vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[1]], p1, &radius);
281 intersecting = sphere_line_intersection(&vertex[Triangles[j].vertex[1]], &vertex[Triangles[j].vertex[2]], p1, &radius);
283 intersecting = sphere_line_intersection(&vertex[Triangles[j].vertex[0]], &vertex[Triangles[j].vertex[2]], p1, &radius);
285 //if(j>=0&&j<TriangleNum)
286 possible[numpossible] = j;
290 if ((distance < olddistance || firstintersecting == -1) && intersecting) {
291 olddistance = distance;
292 firstintersecting = j;
296 *p1 = DoRotation(*p1, 0, *rotate, 0);
298 return firstintersecting;
302 void Model::UpdateVertexArray()
304 if (type != normaltype && type != decalstype)
309 for (i = 0; i < TriangleNum; i++) {
311 vArray[j + 0] = Triangles[i].gx[0];
312 vArray[j + 1] = Triangles[i].gy[0];
313 vArray[j + 2] = normals[Triangles[i].vertex[0]].x;
314 vArray[j + 3] = normals[Triangles[i].vertex[0]].y;
315 vArray[j + 4] = normals[Triangles[i].vertex[0]].z;
316 vArray[j + 5] = vertex[Triangles[i].vertex[0]].x;
317 vArray[j + 6] = vertex[Triangles[i].vertex[0]].y;
318 vArray[j + 7] = vertex[Triangles[i].vertex[0]].z;
320 vArray[j + 8] = Triangles[i].gx[1];
321 vArray[j + 9] = Triangles[i].gy[1];
322 vArray[j + 10] = normals[Triangles[i].vertex[1]].x;
323 vArray[j + 11] = normals[Triangles[i].vertex[1]].y;
324 vArray[j + 12] = normals[Triangles[i].vertex[1]].z;
325 vArray[j + 13] = vertex[Triangles[i].vertex[1]].x;
326 vArray[j + 14] = vertex[Triangles[i].vertex[1]].y;
327 vArray[j + 15] = vertex[Triangles[i].vertex[1]].z;
329 vArray[j + 16] = Triangles[i].gx[2];
330 vArray[j + 17] = Triangles[i].gy[2];
331 vArray[j + 18] = normals[Triangles[i].vertex[2]].x;
332 vArray[j + 19] = normals[Triangles[i].vertex[2]].y;
333 vArray[j + 20] = normals[Triangles[i].vertex[2]].z;
334 vArray[j + 21] = vertex[Triangles[i].vertex[2]].x;
335 vArray[j + 22] = vertex[Triangles[i].vertex[2]].y;
336 vArray[j + 23] = vertex[Triangles[i].vertex[2]].z;
339 for (i = 0; i < TriangleNum; i++) {
341 vArray[j + 0] = Triangles[i].gx[0];
342 vArray[j + 1] = Triangles[i].gy[0];
343 vArray[j + 2] = facenormals[i].x * -1;
344 vArray[j + 3] = facenormals[i].y * -1;
345 vArray[j + 4] = facenormals[i].z * -1;
346 vArray[j + 5] = vertex[Triangles[i].vertex[0]].x;
347 vArray[j + 6] = vertex[Triangles[i].vertex[0]].y;
348 vArray[j + 7] = vertex[Triangles[i].vertex[0]].z;
350 vArray[j + 8] = Triangles[i].gx[1];
351 vArray[j + 9] = Triangles[i].gy[1];
352 vArray[j + 10] = facenormals[i].x * -1;
353 vArray[j + 11] = facenormals[i].y * -1;
354 vArray[j + 12] = facenormals[i].z * -1;
355 vArray[j + 13] = vertex[Triangles[i].vertex[1]].x;
356 vArray[j + 14] = vertex[Triangles[i].vertex[1]].y;
357 vArray[j + 15] = vertex[Triangles[i].vertex[1]].z;
359 vArray[j + 16] = Triangles[i].gx[2];
360 vArray[j + 17] = Triangles[i].gy[2];
361 vArray[j + 18] = facenormals[i].x * -1;
362 vArray[j + 19] = facenormals[i].y * -1;
363 vArray[j + 20] = facenormals[i].z * -1;
364 vArray[j + 21] = vertex[Triangles[i].vertex[2]].x;
365 vArray[j + 22] = vertex[Triangles[i].vertex[2]].y;
366 vArray[j + 23] = vertex[Triangles[i].vertex[2]].z;
371 void Model::UpdateVertexArrayNoTex()
373 if (type != normaltype && type != decalstype)
378 for (i = 0; i < TriangleNum; i++) {
380 vArray[j + 2] = normals[Triangles[i].vertex[0]].x;
381 vArray[j + 3] = normals[Triangles[i].vertex[0]].y;
382 vArray[j + 4] = normals[Triangles[i].vertex[0]].z;
383 vArray[j + 5] = vertex[Triangles[i].vertex[0]].x;
384 vArray[j + 6] = vertex[Triangles[i].vertex[0]].y;
385 vArray[j + 7] = vertex[Triangles[i].vertex[0]].z;
387 vArray[j + 10] = normals[Triangles[i].vertex[1]].x;
388 vArray[j + 11] = normals[Triangles[i].vertex[1]].y;
389 vArray[j + 12] = normals[Triangles[i].vertex[1]].z;
390 vArray[j + 13] = vertex[Triangles[i].vertex[1]].x;
391 vArray[j + 14] = vertex[Triangles[i].vertex[1]].y;
392 vArray[j + 15] = vertex[Triangles[i].vertex[1]].z;
394 vArray[j + 18] = normals[Triangles[i].vertex[2]].x;
395 vArray[j + 19] = normals[Triangles[i].vertex[2]].y;
396 vArray[j + 20] = normals[Triangles[i].vertex[2]].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;
402 for (i = 0; i < TriangleNum; i++) {
404 vArray[j + 2] = facenormals[i].x * -1;
405 vArray[j + 3] = facenormals[i].y * -1;
406 vArray[j + 4] = facenormals[i].z * -1;
407 vArray[j + 5] = vertex[Triangles[i].vertex[0]].x;
408 vArray[j + 6] = vertex[Triangles[i].vertex[0]].y;
409 vArray[j + 7] = vertex[Triangles[i].vertex[0]].z;
411 vArray[j + 10] = facenormals[i].x * -1;
412 vArray[j + 11] = facenormals[i].y * -1;
413 vArray[j + 12] = facenormals[i].z * -1;
414 vArray[j + 13] = vertex[Triangles[i].vertex[1]].x;
415 vArray[j + 14] = vertex[Triangles[i].vertex[1]].y;
416 vArray[j + 15] = vertex[Triangles[i].vertex[1]].z;
418 vArray[j + 18] = facenormals[i].x * -1;
419 vArray[j + 19] = facenormals[i].y * -1;
420 vArray[j + 20] = facenormals[i].z * -1;
421 vArray[j + 21] = vertex[Triangles[i].vertex[2]].x;
422 vArray[j + 22] = vertex[Triangles[i].vertex[2]].y;
423 vArray[j + 23] = vertex[Triangles[i].vertex[2]].z;
427 void Model::UpdateVertexArrayNoTexNoNorm()
429 if (type != normaltype && type != decalstype)
433 for (i = 0; i < TriangleNum; i++) {
435 vArray[j + 5] = vertex[Triangles[i].vertex[0]].x;
436 vArray[j + 6] = vertex[Triangles[i].vertex[0]].y;
437 vArray[j + 7] = vertex[Triangles[i].vertex[0]].z;
439 vArray[j + 13] = vertex[Triangles[i].vertex[1]].x;
440 vArray[j + 14] = vertex[Triangles[i].vertex[1]].y;
441 vArray[j + 15] = vertex[Triangles[i].vertex[1]].z;
443 vArray[j + 21] = vertex[Triangles[i].vertex[2]].x;
444 vArray[j + 22] = vertex[Triangles[i].vertex[2]].y;
445 vArray[j + 23] = vertex[Triangles[i].vertex[2]].z;
449 bool Model::loadnotex(const char *filename )
454 //~ int oldvertexNum, oldTriangleNum;
455 //~ oldvertexNum = vertexNum;
456 //~ oldTriangleNum = TriangleNum;
461 tfile = fopen( ConvertFileName(filename), "rb" );
462 // read model settings
464 fseek(tfile, 0, SEEK_SET);
465 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
467 // read the model data
472 owner = (int*)malloc(sizeof(int) * vertexNum);
473 possible = (int*)malloc(sizeof(int) * TriangleNum);
474 vertex = (XYZ*)malloc(sizeof(XYZ) * vertexNum);
475 Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle) * TriangleNum);
476 vArray = (GLfloat*)malloc(sizeof(GLfloat) * TriangleNum * 24);
478 for (i = 0; i < vertexNum; i++) {
479 funpackf(tfile, "Bf Bf Bf", &vertex[i].x, &vertex[i].y, &vertex[i].z);
482 for (i = 0; i < TriangleNum; i++) {
483 //funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
485 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
486 Triangles[i].vertex[ 0] = vertex[ 0];
487 Triangles[i].vertex[ 1] = vertex[ 2];
488 Triangles[i].vertex[ 2] = vertex[ 4];
489 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
490 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
497 for (i = 0; i < vertexNum; i++) {
502 boundingsphereradius = 0;
503 for (i = 0; i < vertexNum; i++) {
504 for (j = 0; j < vertexNum; j++) {
505 if (j != i && distsq(&vertex[j], &vertex[i]) / 2 > boundingsphereradius) {
506 boundingsphereradius = distsq(&vertex[j], &vertex[i]) / 2;
507 boundingspherecenter = (vertex[i] + vertex[j]) / 2;
511 boundingsphereradius = fast_sqrt(boundingsphereradius);
517 bool Model::load(const char *filename, bool texture )
524 LOG(std::string("Loading model...") + filename);
527 Game::LoadingScreen();
529 //~ int oldvertexNum, oldTriangleNum;
530 //~ oldvertexNum = vertexNum;
531 //~ oldTriangleNum = TriangleNum;
536 tfile = fopen( ConvertFileName(filename), "rb" );
537 // read model settings
540 fseek(tfile, 0, SEEK_SET);
541 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
543 // read the model data
548 owner = (int*)malloc(sizeof(int) * vertexNum);
549 possible = (int*)malloc(sizeof(int) * TriangleNum);
550 vertex = (XYZ*)malloc(sizeof(XYZ) * vertexNum);
551 normals = (XYZ*)malloc(sizeof(XYZ) * vertexNum);
552 facenormals = (XYZ*)malloc(sizeof(XYZ) * TriangleNum);
553 Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle) * TriangleNum);
554 vArray = (GLfloat*)malloc(sizeof(GLfloat) * TriangleNum * 24);
556 for (i = 0; i < vertexNum; i++) {
557 funpackf(tfile, "Bf Bf Bf", &vertex[i].x, &vertex[i].y, &vertex[i].z);
560 for (i = 0; i < TriangleNum; i++) {
561 //funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
563 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
564 Triangles[i].vertex[ 0] = vertex[ 0];
565 Triangles[i].vertex[ 1] = vertex[ 2];
566 Triangles[i].vertex[ 2] = vertex[ 4];
567 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
568 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
571 modelTexture.xsz = 0;
577 for (i = 0; i < vertexNum; i++) {
582 boundingsphereradius = 0;
583 for (i = 0; i < vertexNum; i++) {
584 for (j = 0; j < vertexNum; j++) {
585 if (j != i && distsq(&vertex[j], &vertex[i]) / 2 > boundingsphereradius) {
586 boundingsphereradius = distsq(&vertex[j], &vertex[i]) / 2;
587 boundingspherecenter = (vertex[i] + vertex[j]) / 2;
591 boundingsphereradius = fast_sqrt(boundingsphereradius);
596 bool Model::loaddecal(const char *filename, bool texture )
603 // Changing the filename so that its more os specific
604 char * FixedFN = ConvertFileName(filename);
606 LOG(std::string("Loading decal...") + FixedFN);
608 //~ int oldvertexNum, oldTriangleNum;
609 //~ oldvertexNum = vertexNum;
610 //~ oldTriangleNum = TriangleNum;
616 tfile = fopen( FixedFN, "rb" );
617 // read model settings
620 fseek(tfile, 0, SEEK_SET);
621 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
623 // read the model data
629 owner = (int*)malloc(sizeof(int) * vertexNum);
630 possible = (int*)malloc(sizeof(int) * TriangleNum);
631 vertex = (XYZ*)malloc(sizeof(XYZ) * vertexNum);
632 normals = (XYZ*)malloc(sizeof(XYZ) * vertexNum);
633 facenormals = (XYZ*)malloc(sizeof(XYZ) * TriangleNum);
634 Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle) * TriangleNum);
635 vArray = (GLfloat*)malloc(sizeof(GLfloat) * TriangleNum * 24);
638 for (i = 0; i < vertexNum; i++) {
639 funpackf(tfile, "Bf Bf Bf", &vertex[i].x, &vertex[i].y, &vertex[i].z);
642 for (i = 0; i < TriangleNum; i++) {
643 //funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
645 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
646 Triangles[i].vertex[ 0] = vertex[ 0];
647 Triangles[i].vertex[ 1] = vertex[ 2];
648 Triangles[i].vertex[ 2] = vertex[ 4];
649 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
650 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
654 modelTexture.xsz = 0;
660 for (i = 0; i < vertexNum; i++) {
664 boundingsphereradius = 0;
665 for (i = 0; i < vertexNum; i++) {
666 for (j = 0; j < vertexNum; j++) {
667 if (j != i && distsq(&vertex[j], &vertex[i]) / 2 > boundingsphereradius) {
668 boundingsphereradius = distsq(&vertex[j], &vertex[i]) / 2;
669 boundingspherecenter = (vertex[i] + vertex[j]) / 2;
673 boundingsphereradius = fast_sqrt(boundingsphereradius);
676 if (!decaltexcoords) {
677 decaltexcoords = (float***)malloc(sizeof(float**)*max_model_decals);
678 for (i = 0; i < max_model_decals; i++) {
679 decaltexcoords[i] = (float**)malloc(sizeof(float*) * 3);
680 for (j = 0; j < 3; j++) {
681 decaltexcoords[i][j] = (float*)malloc(sizeof(float) * 2);
684 //if(decalvertex)free(decalvertex);
685 decalvertex = (XYZ**)malloc(sizeof(XYZ*)*max_model_decals);
686 for (i = 0; i < max_model_decals; i++) {
687 decalvertex[i] = (XYZ*)malloc(sizeof(XYZ) * 3);
690 decaltype = (int*)malloc(sizeof(int) * max_model_decals);
691 decalopacity = (float*)malloc(sizeof(float) * max_model_decals);
692 decalrotation = (float*)malloc(sizeof(float) * max_model_decals);
693 decalalivetime = (float*)malloc(sizeof(float) * max_model_decals);
694 decalposition = (XYZ*)malloc(sizeof(XYZ) * max_model_decals);
700 bool Model::loadraw(char *filename )
707 LOG(std::string("Loading raw...") + filename);
709 //~ int oldvertexNum, oldTriangleNum;
710 //~ oldvertexNum = vertexNum;
711 //~ oldTriangleNum = TriangleNum;
716 tfile = fopen( ConvertFileName(filename), "rb" );
717 // read model settings
720 fseek(tfile, 0, SEEK_SET);
721 funpackf(tfile, "Bs Bs", &vertexNum, &TriangleNum);
723 // read the model data
728 owner = (int*)malloc(sizeof(int) * vertexNum);
729 possible = (int*)malloc(sizeof(int) * TriangleNum);
730 vertex = (XYZ*)malloc(sizeof(XYZ) * vertexNum);
731 Triangles = (TexturedTriangle*)malloc(sizeof(TexturedTriangle) * TriangleNum);
732 vArray = (GLfloat*)malloc(sizeof(GLfloat) * TriangleNum * 24);
735 for (i = 0; i < vertexNum; i++) {
736 funpackf(tfile, "Bf Bf Bf", &vertex[i].x, &vertex[i].y, &vertex[i].z);
739 for (i = 0; i < TriangleNum; i++) {
740 //funpackf(tfile, "Bi Bi Bi", &Triangles[i].vertex[0], &Triangles[i].vertex[1], &Triangles[i].vertex[2]);
742 funpackf(tfile, "Bs Bs Bs Bs Bs Bs", &vertex[ 0], &vertex[ 1], &vertex[ 2], &vertex[ 3], &vertex[ 4], &vertex[ 5]);
743 Triangles[i].vertex[ 0] = vertex[ 0];
744 Triangles[i].vertex[ 1] = vertex[ 2];
745 Triangles[i].vertex[ 2] = vertex[ 4];
746 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gx[0], &Triangles[i].gx[1], &Triangles[i].gx[2]);
747 funpackf(tfile, "Bf Bf Bf", &Triangles[i].gy[0], &Triangles[i].gy[1], &Triangles[i].gy[2]);
753 for (i = 0; i < vertexNum; i++) {
761 void Model::UniformTexCoords()
764 for (i = 0; i < TriangleNum; i++) {
765 Triangles[i].gy[0] = vertex[Triangles[i].vertex[0]].y;
766 Triangles[i].gy[1] = vertex[Triangles[i].vertex[1]].y;
767 Triangles[i].gy[2] = vertex[Triangles[i].vertex[2]].y;
768 Triangles[i].gx[0] = vertex[Triangles[i].vertex[0]].x;
769 Triangles[i].gx[1] = vertex[Triangles[i].vertex[1]].x;
770 Triangles[i].gx[2] = vertex[Triangles[i].vertex[2]].x;
776 void Model::FlipTexCoords()
779 for (i = 0; i < TriangleNum; i++) {
780 Triangles[i].gy[0] = -Triangles[i].gy[0];
781 Triangles[i].gy[1] = -Triangles[i].gy[1];
782 Triangles[i].gy[2] = -Triangles[i].gy[2];
787 void Model::ScaleTexCoords(float howmuch)
790 for (i = 0; i < TriangleNum; i++) {
791 Triangles[i].gx[0] *= howmuch;
792 Triangles[i].gx[1] *= howmuch;
793 Triangles[i].gx[2] *= howmuch;
794 Triangles[i].gy[0] *= howmuch;
795 Triangles[i].gy[1] *= howmuch;
796 Triangles[i].gy[2] *= howmuch;
801 void Model::Scale(float xscale, float yscale, float zscale)
804 for (i = 0; i < vertexNum; i++) {
805 vertex[i].x *= xscale;
806 vertex[i].y *= yscale;
807 vertex[i].z *= zscale;
813 boundingsphereradius = 0;
814 for (i = 0; i < vertexNum; i++) {
815 for (j = 0; j < vertexNum; j++) {
816 if (j != i && distsq(&vertex[j], &vertex[i]) / 2 > boundingsphereradius) {
817 boundingsphereradius = distsq(&vertex[j], &vertex[i]) / 2;
818 boundingspherecenter = (vertex[i] + vertex[j]) / 2;
822 boundingsphereradius = fast_sqrt(boundingsphereradius);
825 void Model::ScaleNormals(float xscale, float yscale, float zscale)
827 if (type != normaltype && type != decalstype)
830 for (i = 0; i < vertexNum; i++) {
831 normals[i].x *= xscale;
832 normals[i].y *= yscale;
833 normals[i].z *= zscale;
835 for (i = 0; i < TriangleNum; i++) {
836 facenormals[i].x *= xscale;
837 facenormals[i].y *= yscale;
838 facenormals[i].z *= zscale;
843 void Model::Translate(float xtrans, float ytrans, float ztrans)
846 for (i = 0; i < vertexNum; i++) {
847 vertex[i].x += xtrans;
848 vertex[i].y += ytrans;
849 vertex[i].z += ztrans;
854 boundingsphereradius = 0;
855 for (i = 0; i < vertexNum; i++) {
856 for (j = 0; j < vertexNum; j++) {
857 if (j != i && distsq(&vertex[j], &vertex[i]) / 2 > boundingsphereradius) {
858 boundingsphereradius = distsq(&vertex[j], &vertex[i]) / 2;
859 boundingspherecenter = (vertex[i] + vertex[j]) / 2;
863 boundingsphereradius = fast_sqrt(boundingsphereradius);
866 void Model::Rotate(float xang, float yang, float zang)
869 for (i = 0; i < vertexNum; i++) {
870 vertex[i] = DoRotation(vertex[i], xang, yang, zang);
875 boundingsphereradius = 0;
876 for (i = 0; i < vertexNum; i++) {
877 for (j = 0; j < vertexNum; j++) {
878 if (j != i && distsq(&vertex[j], &vertex[i]) / 2 > boundingsphereradius) {
879 boundingsphereradius = distsq(&vertex[j], &vertex[i]) / 2;
880 boundingspherecenter = (vertex[i] + vertex[j]) / 2;
884 boundingsphereradius = fast_sqrt(boundingsphereradius);
888 void Model::CalculateNormals(bool facenormalise)
891 Game::LoadingScreen();
893 if (type != normaltype && type != decalstype)
896 for (i = 0; i < vertexNum; i++) {
902 for (i = 0; i < TriangleNum; i++) {
903 CrossProduct(vertex[Triangles[i].vertex[1]] - vertex[Triangles[i].vertex[0]], vertex[Triangles[i].vertex[2]] - vertex[Triangles[i].vertex[0]], &facenormals[i]);
905 normals[Triangles[i].vertex[0]].x += facenormals[i].x;
906 normals[Triangles[i].vertex[0]].y += facenormals[i].y;
907 normals[Triangles[i].vertex[0]].z += facenormals[i].z;
909 normals[Triangles[i].vertex[1]].x += facenormals[i].x;
910 normals[Triangles[i].vertex[1]].y += facenormals[i].y;
911 normals[Triangles[i].vertex[1]].z += facenormals[i].z;
913 normals[Triangles[i].vertex[2]].x += facenormals[i].x;
914 normals[Triangles[i].vertex[2]].y += facenormals[i].y;
915 normals[Triangles[i].vertex[2]].z += facenormals[i].z;
917 Normalise(&facenormals[i]);
919 for (i = 0; i < vertexNum; i++) {
920 Normalise(&normals[i]);
923 UpdateVertexArrayNoTex();
926 void Model::drawimmediate()
929 glBegin(GL_TRIANGLES);
930 for (int i = 0; i < TriangleNum; i++) {
931 /*if(Triangles[i].vertex[0]<vertexNum&&Triangles[i].vertex[1]<vertexNum&&Triangles[i].vertex[2]<vertexNum&&Triangles[i].vertex[0]>=0&&Triangles[i].vertex[1]>=0&&Triangles[i].vertex[2]>=0){
932 if(isnormal(vertex[Triangles[i].vertex[0]].x)&&isnormal(vertex[Triangles[i].vertex[0]].y)&&isnormal(vertex[Triangles[i].vertex[0]].z)
933 &&isnormal(vertex[Triangles[i].vertex[1]].x)&&isnormal(vertex[Triangles[i].vertex[1]].y)&&isnormal(vertex[Triangles[i].vertex[1]].z)
934 &&isnormal(vertex[Triangles[i].vertex[2]].x)&&isnormal(vertex[Triangles[i].vertex[2]].y)&&isnormal(vertex[Triangles[i].vertex[2]].z)){
936 glTexCoord2f(Triangles[i].gx[0], Triangles[i].gy[0]);
938 glColor3f(normals[Triangles[i].vertex[0]].x, normals[Triangles[i].vertex[0]].y, normals[Triangles[i].vertex[0]].z);
940 glNormal3f(normals[Triangles[i].vertex[0]].x, normals[Triangles[i].vertex[0]].y, normals[Triangles[i].vertex[0]].z);
942 glNormal3f(facenormals[i].x, facenormals[i].y, facenormals[i].y);
943 glVertex3f(vertex[Triangles[i].vertex[0]].x, vertex[Triangles[i].vertex[0]].y, vertex[Triangles[i].vertex[0]].z);
945 glTexCoord2f(Triangles[i].gx[1], Triangles[i].gy[1]);
947 glColor3f(normals[Triangles[i].vertex[1]].x, normals[Triangles[i].vertex[1]].y, normals[Triangles[i].vertex[1]].z);
949 glNormal3f(normals[Triangles[i].vertex[1]].x, normals[Triangles[i].vertex[1]].y, normals[Triangles[i].vertex[1]].z);
951 glNormal3f(facenormals[i].x, facenormals[i].y, facenormals[i].y);
952 glVertex3f(vertex[Triangles[i].vertex[1]].x, vertex[Triangles[i].vertex[1]].y, vertex[Triangles[i].vertex[1]].z);
954 glTexCoord2f(Triangles[i].gx[2], Triangles[i].gy[2]);
956 glColor3f(normals[Triangles[i].vertex[2]].x, normals[Triangles[i].vertex[2]].y, normals[Triangles[i].vertex[2]].z);
958 glNormal3f(normals[Triangles[i].vertex[2]].x, normals[Triangles[i].vertex[2]].y, normals[Triangles[i].vertex[2]].z);
960 glNormal3f(facenormals[i].x, facenormals[i].y, facenormals[i].y);
961 glVertex3f(vertex[Triangles[i].vertex[2]].x, vertex[Triangles[i].vertex[2]].y, vertex[Triangles[i].vertex[2]].z);
970 if (type != normaltype && type != decalstype)
973 glEnableClientState(GL_NORMAL_ARRAY);
974 glEnableClientState(GL_VERTEX_ARRAY);
975 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
978 glInterleavedArrays( GL_T2F_N3F_V3F, 8 * sizeof(GLfloat), &vArray[0]);
980 glInterleavedArrays( GL_T2F_C3F_V3F, 8 * sizeof(GLfloat), &vArray[0]);
984 glLockArraysEXT( 0, TriangleNum * 3);
986 glDrawArrays(GL_TRIANGLES, 0, TriangleNum * 3);
993 glDisableClientState(GL_NORMAL_ARRAY);
995 glDisableClientState(GL_COLOR_ARRAY);
996 glDisableClientState(GL_VERTEX_ARRAY);
997 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1001 //TODO: phase out in favor of Texture
1002 void Model::drawdifftex(GLuint texture)
1004 glEnableClientState(GL_NORMAL_ARRAY);
1005 glEnableClientState(GL_VERTEX_ARRAY);
1006 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1008 glInterleavedArrays( GL_T2F_N3F_V3F, 8 * sizeof(GLfloat), &vArray[0]);
1010 glInterleavedArrays( GL_T2F_C3F_V3F, 8 * sizeof(GLfloat), &vArray[0]);
1012 glBindTexture(GL_TEXTURE_2D, (unsigned long)texture);
1013 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
1014 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
1018 glLockArraysEXT( 0, TriangleNum * 3);
1020 glDrawArrays(GL_TRIANGLES, 0, TriangleNum * 3);
1022 glUnlockArraysEXT();
1027 glDisableClientState(GL_NORMAL_ARRAY);
1029 glDisableClientState(GL_COLOR_ARRAY);
1030 glDisableClientState(GL_VERTEX_ARRAY);
1031 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1032 //drawdiffteximmediate(texture);
1035 void Model::drawdifftex(Texture texture)
1037 glEnableClientState(GL_NORMAL_ARRAY);
1038 glEnableClientState(GL_VERTEX_ARRAY);
1039 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1041 glInterleavedArrays( GL_T2F_N3F_V3F, 8 * sizeof(GLfloat), &vArray[0]);
1043 glInterleavedArrays( GL_T2F_C3F_V3F, 8 * sizeof(GLfloat), &vArray[0]);
1046 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
1047 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
1051 glLockArraysEXT( 0, TriangleNum * 3);
1053 glDrawArrays(GL_TRIANGLES, 0, TriangleNum * 3);
1055 glUnlockArraysEXT();
1060 glDisableClientState(GL_NORMAL_ARRAY);
1062 glDisableClientState(GL_COLOR_ARRAY);
1063 glDisableClientState(GL_VERTEX_ARRAY);
1064 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1065 //drawdiffteximmediate(texture);
1068 void Model::drawdiffteximmediate(GLuint texture)
1070 glBindTexture(GL_TEXTURE_2D, (unsigned long)texture);
1072 glBegin(GL_TRIANGLES);
1073 for (int i = 0; i < TriangleNum; i++) {
1074 /*if(Triangles[i].vertex[0]<vertexNum&&Triangles[i].vertex[1]<vertexNum&&Triangles[i].vertex[2]<vertexNum&&Triangles[i].vertex[0]>=0&&Triangles[i].vertex[1]>=0&&Triangles[i].vertex[2]>=0){
1075 if(isnormal(vertex[Triangles[i].vertex[0]].x)&&isnormal(vertex[Triangles[i].vertex[0]].y)&&isnormal(vertex[Triangles[i].vertex[0]].z)
1076 &&isnormal(vertex[Triangles[i].vertex[1]].x)&&isnormal(vertex[Triangles[i].vertex[1]].y)&&isnormal(vertex[Triangles[i].vertex[1]].z)
1077 &&isnormal(vertex[Triangles[i].vertex[2]].x)&&isnormal(vertex[Triangles[i].vertex[2]].y)&&isnormal(vertex[Triangles[i].vertex[2]].z)){
1078 */glTexCoord2f(Triangles[i].gx[0], Triangles[i].gy[0]);
1080 glColor3f(normals[Triangles[i].vertex[0]].x, normals[Triangles[i].vertex[0]].y, normals[Triangles[i].vertex[0]].z);
1081 if (!color && !flat)
1082 glNormal3f(normals[Triangles[i].vertex[0]].x, normals[Triangles[i].vertex[0]].y, normals[Triangles[i].vertex[0]].z);
1084 glNormal3f(facenormals[i].x, facenormals[i].y, facenormals[i].y);
1085 glVertex3f(vertex[Triangles[i].vertex[0]].x, vertex[Triangles[i].vertex[0]].y, vertex[Triangles[i].vertex[0]].z);
1087 glTexCoord2f(Triangles[i].gx[1], Triangles[i].gy[1]);
1089 glColor3f(normals[Triangles[i].vertex[1]].x, normals[Triangles[i].vertex[1]].y, normals[Triangles[i].vertex[1]].z);
1090 if (!color && !flat)
1091 glNormal3f(normals[Triangles[i].vertex[1]].x, normals[Triangles[i].vertex[1]].y, normals[Triangles[i].vertex[1]].z);
1093 glNormal3f(facenormals[i].x, facenormals[i].y, facenormals[i].y);
1094 glVertex3f(vertex[Triangles[i].vertex[1]].x, vertex[Triangles[i].vertex[1]].y, vertex[Triangles[i].vertex[1]].z);
1096 glTexCoord2f(Triangles[i].gx[2], Triangles[i].gy[2]);
1098 glColor3f(normals[Triangles[i].vertex[2]].x, normals[Triangles[i].vertex[2]].y, normals[Triangles[i].vertex[2]].z);
1099 if (!color && !flat)
1100 glNormal3f(normals[Triangles[i].vertex[2]].x, normals[Triangles[i].vertex[2]].y, normals[Triangles[i].vertex[2]].z);
1102 glNormal3f(facenormals[i].x, facenormals[i].y, facenormals[i].y);
1103 glVertex3f(vertex[Triangles[i].vertex[2]].x, vertex[Triangles[i].vertex[2]].y, vertex[Triangles[i].vertex[2]].z);
1110 void Model::drawdecals(Texture shadowtexture, Texture bloodtexture, Texture bloodtexture2, Texture breaktexture)
1113 if (type != decalstype)
1116 //~ static float distancemult;
1117 static int lasttype;
1118 //~ static float viewdistsquared;
1121 //~ viewdistsquared = viewdistance * viewdistance;
1126 glDisable(GL_LIGHTING);
1127 glDisable(GL_CULL_FACE);
1128 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1130 if (numdecals > max_model_decals)
1131 numdecals = max_model_decals;
1132 for (i = 0; i < numdecals; i++) {
1133 if (decaltype[i] == blooddecalfast && decalalivetime[i] < 2)
1134 decalalivetime[i] = 2;
1136 if (decaltype[i] == shadowdecal && decaltype[i] != lasttype) {
1137 shadowtexture.bind();
1140 glAlphaFunc(GL_GREATER, 0.0001);
1141 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1144 if (decaltype[i] == breakdecal && decaltype[i] != lasttype) {
1145 breaktexture.bind();
1148 glAlphaFunc(GL_GREATER, 0.0001);
1149 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1152 if ((decaltype[i] == blooddecal || decaltype[i] == blooddecalslow) && decaltype[i] != lasttype) {
1153 bloodtexture.bind();
1156 glAlphaFunc(GL_GREATER, 0.15);
1157 glBlendFunc(GL_ONE, GL_ZERO);
1160 if ((decaltype[i] == blooddecalfast) && decaltype[i] != lasttype) {
1161 bloodtexture2.bind();
1164 glAlphaFunc(GL_GREATER, 0.15);
1165 glBlendFunc(GL_ONE, GL_ZERO);
1168 if (decaltype[i] == shadowdecal) {
1169 glColor4f(1, 1, 1, decalopacity[i]);
1171 if (decaltype[i] == breakdecal) {
1172 glColor4f(1, 1, 1, decalopacity[i]);
1173 if (decalalivetime[i] > 58)
1174 glColor4f(1, 1, 1, decalopacity[i] * (60 - decalalivetime[i]) / 2);
1176 if ((decaltype[i] == blooddecal || decaltype[i] == blooddecalfast || decaltype[i] == blooddecalslow)) {
1177 glColor4f(1, 1, 1, decalopacity[i]);
1178 if (decalalivetime[i] < 4)
1179 glColor4f(1, 1, 1, decalopacity[i]*decalalivetime[i]*.25);
1180 if (decalalivetime[i] > 58)
1181 glColor4f(1, 1, 1, decalopacity[i] * (60 - decalalivetime[i]) / 2);
1183 lasttype = decaltype[i];
1184 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1185 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
1187 glMatrixMode(GL_MODELVIEW);
1189 glBegin(GL_TRIANGLES);
1190 for (int j = 0; j < 3; j++) {
1191 glTexCoord2f(decaltexcoords[i][j][0], decaltexcoords[i][j][1]);
1192 glVertex3f(decalvertex[i][j].x, decalvertex[i][j].y, decalvertex[i][j].z);
1197 for (i = numdecals - 1; i >= 0; i--) {
1198 decalalivetime[i] += multiplier;
1199 if (decaltype[i] == blooddecalslow)
1200 decalalivetime[i] -= multiplier * 2 / 3;
1201 if (decaltype[i] == blooddecalfast)
1202 decalalivetime[i] += multiplier * 4;
1203 if (decaltype[i] == shadowdecal)
1205 if ((decaltype[i] == blooddecal || decaltype[i] == blooddecalfast || decaltype[i] == blooddecalslow) && decalalivetime[i] >= 60)
1208 glAlphaFunc(GL_GREATER, 0.0001);
1209 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1213 void Model::DeleteDecal(int which)
1216 if (type != decalstype)
1218 decaltype[which] = decaltype[numdecals - 1];
1219 decalposition[which] = decalposition[numdecals - 1];
1220 for (int i = 0; i < 3; i++) {
1221 decalvertex[which][i] = decalvertex[numdecals - 1][i];
1222 decaltexcoords[which][i][0] = decaltexcoords[numdecals - 1][i][0];
1223 decaltexcoords[which][i][1] = decaltexcoords[numdecals - 1][i][1];
1225 decalrotation[which] = decalrotation[numdecals - 1];
1226 decalalivetime[which] = decalalivetime[numdecals - 1];
1227 decalopacity[which] = decalopacity[numdecals - 1];
1232 void Model::MakeDecal(int atype, XYZ *where, float *size, float *opacity, float *rotation)
1235 if (type != decalstype)
1238 static float placex, placez;
1240 //static XYZ point,point1,point2;
1241 static float distance;
1245 if (distsq(where, &boundingspherecenter) < (boundingsphereradius + *size) * (boundingsphereradius + *size))
1246 for (i = 0; i < TriangleNum; i++) {
1247 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)) {
1248 decalposition[numdecals] = *where;
1249 decaltype[numdecals] = atype;
1250 decalrotation[numdecals] = *rotation;
1251 decalalivetime[numdecals] = 0;
1252 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);
1253 decalopacity[numdecals] = *opacity - distance / 10;
1255 if (decalopacity[numdecals > 0]) {
1256 placex = vertex[Triangles[i].vertex[0]].x;
1257 placez = vertex[Triangles[i].vertex[0]].z;
1259 decaltexcoords[numdecals][0][0] = (placex - where->x) / (*size) / 2 + .5;
1260 decaltexcoords[numdecals][0][1] = (placez - where->z) / (*size) / 2 + .5;
1262 decalvertex[numdecals][0].x = placex;
1263 decalvertex[numdecals][0].z = placez;
1264 decalvertex[numdecals][0].y = vertex[Triangles[i].vertex[0]].y;
1267 placex = vertex[Triangles[i].vertex[1]].x;
1268 placez = vertex[Triangles[i].vertex[1]].z;
1270 decaltexcoords[numdecals][1][0] = (placex - where->x) / (*size) / 2 + .5;
1271 decaltexcoords[numdecals][1][1] = (placez - where->z) / (*size) / 2 + .5;
1273 decalvertex[numdecals][1].x = placex;
1274 decalvertex[numdecals][1].z = placez;
1275 decalvertex[numdecals][1].y = vertex[Triangles[i].vertex[1]].y;
1278 placex = vertex[Triangles[i].vertex[2]].x;
1279 placez = vertex[Triangles[i].vertex[2]].z;
1281 decaltexcoords[numdecals][2][0] = (placex - where->x) / (*size) / 2 + .5;
1282 decaltexcoords[numdecals][2][1] = (placez - where->z) / (*size) / 2 + .5;
1284 decalvertex[numdecals][2].x = placex;
1285 decalvertex[numdecals][2].z = placez;
1286 decalvertex[numdecals][2].y = vertex[Triangles[i].vertex[2]].y;
1288 if (!(decaltexcoords[numdecals][0][0] < 0 && decaltexcoords[numdecals][1][0] < 0 && decaltexcoords[numdecals][2][0] < 0))
1289 if (!(decaltexcoords[numdecals][0][1] < 0 && decaltexcoords[numdecals][1][1] < 0 && decaltexcoords[numdecals][2][1] < 0))
1290 if (!(decaltexcoords[numdecals][0][0] > 1 && decaltexcoords[numdecals][1][0] > 1 && decaltexcoords[numdecals][2][0] > 1))
1291 if (!(decaltexcoords[numdecals][0][1] > 1 && decaltexcoords[numdecals][1][1] > 1 && decaltexcoords[numdecals][2][1] > 1)) {
1292 if (decalrotation[numdecals]) {
1293 for (j = 0; j < 3; j++) {
1295 rot.x = decaltexcoords[numdecals][j][0] - .5;
1296 rot.z = decaltexcoords[numdecals][j][1] - .5;
1297 rot = DoRotation(rot, 0, -decalrotation[numdecals], 0);
1298 decaltexcoords[numdecals][j][0] = rot.x + .5;
1299 decaltexcoords[numdecals][j][1] = rot.z + .5;
1302 if (numdecals < max_model_decals - 1)
1311 void Model::MakeDecal(int atype, XYZ where, float size, float opacity, float rotation)
1314 if (type != decalstype)
1317 static float placex, placez;
1319 //static XYZ point,point1,point2;
1320 static float distance;
1324 if (distsq(&where, &boundingspherecenter) < (boundingsphereradius + size) * (boundingsphereradius + size))
1325 for (i = 0; i < TriangleNum; i++) {
1326 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))));
1327 if (distance < .02 && abs(facenormals[i].y) > abs(facenormals[i].x) && abs(facenormals[i].y) > abs(facenormals[i].z)) {
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]].z;
1338 decaltexcoords[numdecals][0][0] = (placex - where.x) / (size) / 2 + .5;
1339 decaltexcoords[numdecals][0][1] = (placez - where.z) / (size) / 2 + .5;
1341 decalvertex[numdecals][0].x = placex;
1342 decalvertex[numdecals][0].z = placez;
1343 decalvertex[numdecals][0].y = vertex[Triangles[i].vertex[0]].y;
1346 placex = vertex[Triangles[i].vertex[1]].x;
1347 placez = vertex[Triangles[i].vertex[1]].z;
1349 decaltexcoords[numdecals][1][0] = (placex - where.x) / (size) / 2 + .5;
1350 decaltexcoords[numdecals][1][1] = (placez - where.z) / (size) / 2 + .5;
1352 decalvertex[numdecals][1].x = placex;
1353 decalvertex[numdecals][1].z = placez;
1354 decalvertex[numdecals][1].y = vertex[Triangles[i].vertex[1]].y;
1357 placex = vertex[Triangles[i].vertex[2]].x;
1358 placez = vertex[Triangles[i].vertex[2]].z;
1360 decaltexcoords[numdecals][2][0] = (placex - where.x) / (size) / 2 + .5;
1361 decaltexcoords[numdecals][2][1] = (placez - where.z) / (size) / 2 + .5;
1363 decalvertex[numdecals][2].x = placex;
1364 decalvertex[numdecals][2].z = placez;
1365 decalvertex[numdecals][2].y = vertex[Triangles[i].vertex[2]].y;
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)
1385 } else if (distance < .02 && abs(facenormals[i].x) > abs(facenormals[i].y) && abs(facenormals[i].x) > abs(facenormals[i].z)) {
1386 decalposition[numdecals] = where;
1387 decaltype[numdecals] = atype;
1388 decalrotation[numdecals] = rotation;
1389 decalalivetime[numdecals] = 0;
1390 decalopacity[numdecals] = opacity - distance / 10;
1392 if (decalopacity[numdecals > 0]) {
1393 placex = vertex[Triangles[i].vertex[0]].y;
1394 placez = vertex[Triangles[i].vertex[0]].z;
1396 decaltexcoords[numdecals][0][0] = (placex - where.y) / (size) / 2 + .5;
1397 decaltexcoords[numdecals][0][1] = (placez - where.z) / (size) / 2 + .5;
1399 decalvertex[numdecals][0].x = vertex[Triangles[i].vertex[0]].x;
1400 decalvertex[numdecals][0].z = placez;
1401 decalvertex[numdecals][0].y = placex;
1404 placex = vertex[Triangles[i].vertex[1]].y;
1405 placez = vertex[Triangles[i].vertex[1]].z;
1407 decaltexcoords[numdecals][1][0] = (placex - where.y) / (size) / 2 + .5;
1408 decaltexcoords[numdecals][1][1] = (placez - where.z) / (size) / 2 + .5;
1410 decalvertex[numdecals][1].x = vertex[Triangles[i].vertex[1]].x;
1411 decalvertex[numdecals][1].z = placez;
1412 decalvertex[numdecals][1].y = placex;
1415 placex = vertex[Triangles[i].vertex[2]].y;
1416 placez = vertex[Triangles[i].vertex[2]].z;
1418 decaltexcoords[numdecals][2][0] = (placex - where.y) / (size) / 2 + .5;
1419 decaltexcoords[numdecals][2][1] = (placez - where.z) / (size) / 2 + .5;
1421 decalvertex[numdecals][2].x = vertex[Triangles[i].vertex[2]].x;
1422 decalvertex[numdecals][2].z = placez;
1423 decalvertex[numdecals][2].y = placex;
1425 if (!(decaltexcoords[numdecals][0][0] < 0 && decaltexcoords[numdecals][1][0] < 0 && decaltexcoords[numdecals][2][0] < 0))
1426 if (!(decaltexcoords[numdecals][0][1] < 0 && decaltexcoords[numdecals][1][1] < 0 && decaltexcoords[numdecals][2][1] < 0))
1427 if (!(decaltexcoords[numdecals][0][0] > 1 && decaltexcoords[numdecals][1][0] > 1 && decaltexcoords[numdecals][2][0] > 1))
1428 if (!(decaltexcoords[numdecals][0][1] > 1 && decaltexcoords[numdecals][1][1] > 1 && decaltexcoords[numdecals][2][1] > 1)) {
1429 if (decalrotation[numdecals]) {
1430 for (j = 0; j < 3; j++) {
1432 rot.x = decaltexcoords[numdecals][j][0] - .5;
1433 rot.z = decaltexcoords[numdecals][j][1] - .5;
1434 rot = DoRotation(rot, 0, -decalrotation[numdecals], 0);
1435 decaltexcoords[numdecals][j][0] = rot.x + .5;
1436 decaltexcoords[numdecals][j][1] = rot.z + .5;
1439 if (numdecals < max_model_decals - 1)
1443 } else if (distance < .02 && abs(facenormals[i].z) > abs(facenormals[i].y) && abs(facenormals[i].z) > abs(facenormals[i].x)) {
1444 decalposition[numdecals] = where;
1445 decaltype[numdecals] = atype;
1446 decalrotation[numdecals] = rotation;
1447 decalalivetime[numdecals] = 0;
1448 decalopacity[numdecals] = opacity - distance / 10;
1450 if (decalopacity[numdecals > 0]) {
1451 placex = vertex[Triangles[i].vertex[0]].x;
1452 placez = vertex[Triangles[i].vertex[0]].y;
1454 decaltexcoords[numdecals][0][0] = (placex - where.x) / (size) / 2 + .5;
1455 decaltexcoords[numdecals][0][1] = (placez - where.y) / (size) / 2 + .5;
1457 decalvertex[numdecals][0].x = placex;
1458 decalvertex[numdecals][0].z = vertex[Triangles[i].vertex[0]].z;
1459 decalvertex[numdecals][0].y = placez;
1462 placex = vertex[Triangles[i].vertex[1]].x;
1463 placez = vertex[Triangles[i].vertex[1]].y;
1465 decaltexcoords[numdecals][1][0] = (placex - where.x) / (size) / 2 + .5;
1466 decaltexcoords[numdecals][1][1] = (placez - where.y) / (size) / 2 + .5;
1468 decalvertex[numdecals][1].x = placex;
1469 decalvertex[numdecals][1].z = vertex[Triangles[i].vertex[1]].z;
1470 decalvertex[numdecals][1].y = placez;
1473 placex = vertex[Triangles[i].vertex[2]].x;
1474 placez = vertex[Triangles[i].vertex[2]].y;
1476 decaltexcoords[numdecals][2][0] = (placex - where.x) / (size) / 2 + .5;
1477 decaltexcoords[numdecals][2][1] = (placez - where.y) / (size) / 2 + .5;
1479 decalvertex[numdecals][2].x = placex;
1480 decalvertex[numdecals][2].z = vertex[Triangles[i].vertex[2]].z;
1481 decalvertex[numdecals][2].y = placez;
1483 if (!(decaltexcoords[numdecals][0][0] < 0 && decaltexcoords[numdecals][1][0] < 0 && decaltexcoords[numdecals][2][0] < 0))
1484 if (!(decaltexcoords[numdecals][0][1] < 0 && decaltexcoords[numdecals][1][1] < 0 && decaltexcoords[numdecals][2][1] < 0))
1485 if (!(decaltexcoords[numdecals][0][0] > 1 && decaltexcoords[numdecals][1][0] > 1 && decaltexcoords[numdecals][2][0] > 1))
1486 if (!(decaltexcoords[numdecals][0][1] > 1 && decaltexcoords[numdecals][1][1] > 1 && decaltexcoords[numdecals][2][1] > 1)) {
1487 if (decalrotation[numdecals]) {
1488 for (j = 0; j < 3; j++) {
1490 rot.x = decaltexcoords[numdecals][j][0] - .5;
1491 rot.z = decaltexcoords[numdecals][j][1] - .5;
1492 rot = DoRotation(rot, 0, -decalrotation[numdecals], 0);
1493 decaltexcoords[numdecals][j][0] = rot.x + .5;
1494 decaltexcoords[numdecals][j][1] = rot.z + .5;
1497 if (numdecals < max_model_decals - 1)
1509 textureptr.destroy();
1512 void Model::deallocate()
1546 if (decaltexcoords) {
1547 for (i = 0; i < max_model_decals; i++) {
1548 for (j = 0; j < 3; j++) {
1549 free(decaltexcoords[i][j]);
1551 free(decaltexcoords[i]);
1553 free(decaltexcoords);
1559 for (i = 0; i < max_model_decals; i++) {
1560 free(decalvertex[i]);
1573 free(decalrotation);
1576 free(decalalivetime);
1579 free(decalposition);
1586 vertexNum = 0, TriangleNum = 0;
1589 type = 0, oldtype = 0;
1599 memset(&modelTexture, 0, sizeof(modelTexture));
1603 boundingspherecenter = 0;
1604 boundingsphereradius = 0;